source: sasview/src/sas/sascalc/dataloader/readers/anton_paar_saxs_reader.py

ESS_GUI
Last change on this file was a5bd87a, checked in by Paul Kienzle <pkienzle@…>, 7 years ago

use decoded stream for anton-paar saxs reader

  • Property mode set to 100644
File size: 7.2 KB
RevLine 
[80c5d46]1"""
2    CanSAS 2D data reader for reading HDF5 formatted CanSAS files.
3"""
4
5import numpy as np
6import re
7import os
8import sys
9
10from sas.sascalc.dataloader.readers.xml_reader import XMLreader
[fafe52a]11from sas.sascalc.dataloader.data_info import plottable_1D, Data1D, DataInfo, Sample, Source
[80c5d46]12from sas.sascalc.dataloader.data_info import Process, Aperture, Collimation, TransmissionSpectrum, Detector
[fafe52a]13from sas.sascalc.dataloader.loader_exceptions import FileContentsException, DataReaderException
[80c5d46]14
15class Reader(XMLreader):
16    """
[fafe52a]17    A class for reading in Anton Paar .pdh files
[80c5d46]18    """
19
20    ## Logged warnings or messages
21    logging = None
22    ## List of errors for the current data set
23    errors = None
24    ## Raw file contents to be processed
25    raw_data = None
26    ## For recursion and saving purposes, remember parent objects
27    parent_list = None
28    ## Data type name
29    type_name = "Anton Paar SAXSess"
30    ## Wildcards
31    type = ["Anton Paar SAXSess Files (*.pdh)|*.pdh"]
32    ## List of allowed extensions
33    ext = ['.pdh', '.PDH']
34    ## Flag to bypass extension check
35    allow_all = False
36
[a235f715]37    def reset_state(self):
[fafe52a]38        self.current_dataset = plottable_1D(np.empty(0), np.empty(0), np.empty(0), np.empty(0))
39        self.current_datainfo = DataInfo()
[80c5d46]40        self.datasets = []
41        self.raw_data = None
42        self.errors = set()
43        self.logging = []
44        self.output = []
45        self.detector = Detector()
46        self.collimation = Collimation()
47        self.aperture = Aperture()
48        self.process = Process()
49        self.source = Source()
50        self.sample = Sample()
51        self.trans_spectrum = TransmissionSpectrum()
52        self.upper = 5
53        self.lower = 5
54
[fafe52a]55    def get_file_contents(self):
[80c5d46]56        """
57            This is the general read method that all SasView data_loaders must have.
58
59            :param filename: A path for an XML formatted Anton Paar SAXSess data file.
60            :return: List of Data1D objects or a list of errors.
61            """
62
63        ## Reinitialize the class when loading a new data file to reset all class variables
[a235f715]64        self.reset_state()
[a5bd87a]65        buff = self.readall()
[fafe52a]66        self.raw_data = buff.splitlines()
67        self.read_data()
[80c5d46]68
69    def read_data(self):
[fafe52a]70        correctly_loaded = True
71        error_message = ""
72
[80c5d46]73        q_unit = "1/nm"
74        i_unit = "1/um^2"
[fafe52a]75        try:
76            self.current_datainfo.title = self.raw_data[0]
77            self.current_datainfo.meta_data["Keywords"] = self.raw_data[1]
78            line3 = self.raw_data[2].split()
79            line4 = self.raw_data[3].split()
80            line5 = self.raw_data[4].split()
81            self.data_points = int(line3[0])
82            self.lower = 5
83            self.upper = self.lower + self.data_points
84            self.source.radiation = 'x-ray'
85            normal = float(line4[3])
86            self.current_datainfo.source.radiation = "x-ray"
87            self.current_datainfo.source.name = "Anton Paar SAXSess Instrument"
88            self.current_datainfo.source.wavelength = float(line4[4])
89            xvals = []
90            yvals = []
91            dyvals = []
92            for i in range(self.lower, self.upper):
93                index = i - self.lower
94                data = self.raw_data[i].split()
95                xvals.insert(index, normal * float(data[0]))
96                yvals.insert(index, normal * float(data[1]))
97                dyvals.insert(index, normal * float(data[2]))
98        except Exception as e:
99            error_message = "Couldn't load {}.\n".format(self.f_open.name)
100            error_message += e.message
101            raise FileContentsException(error_message)
[a235f715]102        self.current_dataset.x = np.append(self.current_dataset.x, xvals)
103        self.current_dataset.y = np.append(self.current_dataset.y, yvals)
104        self.current_dataset.dy = np.append(self.current_dataset.dy, dyvals)
105        if self.data_points != self.current_dataset.x.size:
[fafe52a]106            error_message += "Not all data points could be loaded.\n"
107            correctly_loaded = False
[a235f715]108        if self.current_dataset.x.size != self.current_dataset.y.size:
[fafe52a]109            error_message += "The x and y data sets are not the same size.\n"
110            correctly_loaded = False
[a235f715]111        if self.current_dataset.y.size != self.current_dataset.dy.size:
[fafe52a]112            error_message += "The y and dy datasets are not the same size.\n"
113            correctly_loaded = False
114
[a235f715]115        self.current_dataset.xaxis("Q", q_unit)
116        self.current_dataset.yaxis("Intensity", i_unit)
117        xml_intermediate = self.raw_data[self.upper:]
118        xml = ''.join(xml_intermediate)
[fafe52a]119        try:
120            self.set_xml_string(xml)
121            dom = self.xmlroot.xpath('/fileinfo')
122            self._parse_child(dom)
123        except Exception as e:
124            # Data loaded but XML metadata has an error
125            error_message += "Data points have been loaded but there was an "
126            error_message += "error reading XML metadata: " + e.message
127            correctly_loaded = False
128        self.send_to_output()
129        if not correctly_loaded:
130            raise DataReaderException(error_message)
[a235f715]131
132    def _parse_child(self, dom, parent=''):
133        """
134        Recursive method for stepping through the embedded XML
135        :param dom: XML node with or without children
136        """
137        for node in dom:
138            tagname = node.tag
139            value = node.text
140            attr = node.attrib
141            key = attr.get("key", '')
142            if len(node.getchildren()) > 1:
143                self._parse_child(node, key)
144                if key == "SampleDetector":
[fafe52a]145                    self.current_datainfo.detector.append(self.detector)
[a235f715]146                    self.detector = Detector()
147            else:
148                if key == "value":
149                    if parent == "Wavelength":
[fafe52a]150                        self.current_datainfo.source.wavelength = value
[a235f715]151                    elif parent == "SampleDetector":
152                        self.detector.distance = value
153                    elif parent == "Temperature":
[fafe52a]154                        self.current_datainfo.sample.temperature = value
[a235f715]155                    elif parent == "CounterSlitLength":
156                        self.detector.slit_length = value
157                elif key == "unit":
158                    value = value.replace("_", "")
159                    if parent == "Wavelength":
[fafe52a]160                        self.current_datainfo.source.wavelength_unit = value
[a235f715]161                    elif parent == "SampleDetector":
162                        self.detector.distance_unit = value
163                    elif parent == "X":
164                        self.current_dataset.xaxis(self.current_dataset._xaxis, value)
165                    elif parent == "Y":
166                        self.current_dataset.yaxis(self.current_dataset._yaxis, value)
167                    elif parent == "Temperature":
[fafe52a]168                        self.current_datainfo.sample.temperature_unit = value
[a235f715]169                    elif parent == "CounterSlitLength":
170                        self.detector.slit_length_unit = value
171                elif key == "quantity":
172                    if parent == "X":
173                        self.current_dataset.xaxis(value, self.current_dataset._xunit)
174                    elif parent == "Y":
175                        self.current_dataset.yaxis(value, self.current_dataset._yunit)
Note: See TracBrowser for help on using the repository browser.