source: sasview/src/sas/sascalc/dataloader/readers/abs_reader.py @ d04ac05

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalcmagnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since d04ac05 was 46cf4c9, checked in by Paul Kienzle <pkienzle@…>, 7 years ago

use decoded stream for .abs reader; assume nxsunit exists

  • Property mode set to 100644
File size: 8.3 KB
Line 
1"""
2    IGOR 1D data reader
3"""
4#####################################################################
5# This software was developed by the University of Tennessee as part of the
6# Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
7# project funded by the US National Science Foundation.
8# See the license text in license.txt
9# copyright 2008, University of Tennessee
10######################################################################
11
12import logging
13
14import numpy as np
15
16from sas.sascalc.data_util.nxsunit import Converter
17from ..file_reader_base_class import FileReader
18from ..data_info import DataInfo, plottable_1D, Data1D, Detector
19from ..loader_exceptions import FileContentsException, DefaultReaderException
20
21logger = logging.getLogger(__name__)
22
23
24class Reader(FileReader):
25    """
26    Class to load IGOR reduced .ABS files
27    """
28    # File type
29    type_name = "IGOR 1D"
30    # Wildcards
31    type = ["IGOR 1D files (*.abs)|*.abs"]
32    # List of allowed extensions
33    ext = ['.abs']
34
35    def get_file_contents(self):
36        """
37        Get the contents of the file
38
39        :raise RuntimeError: when the file can't be opened
40        :raise ValueError: when the length of the data vectors are inconsistent
41        """
42        buff = self.readall()
43        filepath = self.f_open.name
44        lines = buff.splitlines()
45        self.output = []
46        self.current_datainfo = DataInfo()
47        self.current_datainfo.filename = filepath
48        self.reset_data_list(len(lines))
49        detector = Detector()
50        data_line = 0
51        self.reset_data_list(len(lines))
52        self.current_datainfo.detector.append(detector)
53        self.current_datainfo.filename = filepath
54
55        is_info = False
56        is_center = False
57        is_data_started = False
58
59        base_q_unit = '1/A'
60        base_i_unit = '1/cm'
61        data_conv_q = Converter(base_q_unit)
62        data_conv_i = Converter(base_i_unit)
63
64        for line in lines:
65            # Information line 1
66            if is_info:
67                is_info = False
68                line_toks = line.split()
69
70                # Wavelength in Angstrom
71                try:
72                    value = float(line_toks[1])
73                    if self.current_datainfo.source.wavelength_unit != 'A':
74                        conv = Converter('A')
75                        self.current_datainfo.source.wavelength = conv(value,
76                            units=self.current_datainfo.source.wavelength_unit)
77                    else:
78                        self.current_datainfo.source.wavelength = value
79                except KeyError:
80                    msg = "ABSReader cannot read wavelength from %s" % filepath
81                    self.current_datainfo.errors.append(msg)
82
83                # Detector distance in meters
84                try:
85                    value = float(line_toks[3])
86                    if detector.distance_unit != 'm':
87                        conv = Converter('m')
88                        detector.distance = conv(value,
89                                        units=detector.distance_unit)
90                    else:
91                        detector.distance = value
92                except Exception:
93                    msg = "ABSReader cannot read SDD from %s" % filepath
94                    self.current_datainfo.errors.append(msg)
95
96                # Transmission
97                try:
98                    self.current_datainfo.sample.transmission = \
99                        float(line_toks[4])
100                except ValueError:
101                    # Transmission isn't always in the header
102                    pass
103
104                # Sample thickness in mm
105                try:
106                    value = float(line_toks[5])
107                    if self.current_datainfo.sample.thickness_unit != 'cm':
108                        conv = Converter('cm')
109                        self.current_datainfo.sample.thickness = conv(value,
110                            units=self.current_datainfo.sample.thickness_unit)
111                    else:
112                        self.current_datainfo.sample.thickness = value
113                except ValueError:
114                    # Thickness is not a mandatory entry
115                    pass
116
117            # MON CNT  LAMBDA  DET ANG  DET DIST  TRANS  THICK  AVE   STEP
118            if line.count("LAMBDA") > 0:
119                is_info = True
120
121            # Find center info line
122            if is_center:
123                is_center = False
124                line_toks = line.split()
125                # Center in bin number
126                center_x = float(line_toks[0])
127                center_y = float(line_toks[1])
128
129                # Bin size
130                if detector.pixel_size_unit != 'mm':
131                    conv = Converter('mm')
132                    detector.pixel_size.x = conv(5.08,
133                                        units=detector.pixel_size_unit)
134                    detector.pixel_size.y = conv(5.08,
135                                        units=detector.pixel_size_unit)
136                else:
137                    detector.pixel_size.x = 5.08
138                    detector.pixel_size.y = 5.08
139
140                # Store beam center in distance units
141                # Det 640 x 640 mm
142                if detector.beam_center_unit != 'mm':
143                    conv = Converter('mm')
144                    detector.beam_center.x = conv(center_x * 5.08,
145                                     units=detector.beam_center_unit)
146                    detector.beam_center.y = conv(center_y * 5.08,
147                                     units=detector.beam_center_unit)
148                else:
149                    detector.beam_center.x = center_x * 5.08
150                    detector.beam_center.y = center_y * 5.08
151
152                # Detector type
153                try:
154                    detector.name = line_toks[7]
155                except:
156                    # Detector name is not a mandatory entry
157                    pass
158
159            # BCENT(X,Y)  A1(mm)  A2(mm)  A1A2DIST(m)  DL/L  BSTOP(mm)  DET_TYP
160            if line.count("BCENT") > 0:
161                is_center = True
162
163            # Parse the data
164            if is_data_started:
165                toks = line.split()
166
167                try:
168                    _x = float(toks[0])
169                    _y = float(toks[1])
170                    _dy = float(toks[2])
171                    _dx = float(toks[3])
172
173                    if data_conv_q is not None:
174                        _x = data_conv_q(_x, units=base_q_unit)
175                        _dx = data_conv_q(_dx, units=base_q_unit)
176
177                    if data_conv_i is not None:
178                        _y = data_conv_i(_y, units=base_i_unit)
179                        _dy = data_conv_i(_dy, units=base_i_unit)
180
181                    self.current_dataset.x[data_line] = _x
182                    self.current_dataset.y[data_line] = _y
183                    self.current_dataset.dy[data_line] = _dy
184                    self.current_dataset.dx[data_line] = _dx
185                    data_line += 1
186
187                except ValueError:
188                    # Could not read this data line. If we are here
189                    # it is because we are in the data section. Just
190                    # skip it.
191                    pass
192
193            # The 6 columns are | Q (1/A) | I(Q) (1/cm) | std. dev.
194            # I(Q) (1/cm) | sigmaQ | meanQ | ShadowFactor|
195            if line.count("The 6 columns") > 0:
196                is_data_started = True
197
198        self.remove_empty_q_values(True, True)
199
200        # Sanity check
201        if not len(self.current_dataset.y) == len(self.current_dataset.dy):
202            self.set_all_to_none()
203            msg = "abs_reader: y and dy have different length"
204            raise ValueError(msg)
205        # If the data length is zero, consider this as
206        # though we were not able to read the file.
207        if len(self.current_dataset.x) == 0:
208            self.set_all_to_none()
209            raise ValueError("ascii_reader: could not load file")
210
211        if data_conv_q is not None:
212            self.current_dataset.xaxis("\\rm{Q}", base_q_unit)
213        else:
214            self.current_dataset.xaxis("\\rm{Q}", 'A^{-1}')
215        if data_conv_i is not None:
216            self.current_dataset.yaxis("\\rm{Intensity}", base_i_unit)
217        else:
218            self.current_dataset.yaxis("\\rm{Intensity}", "cm^{-1}")
219
220        # Store loading process information
221        self.current_datainfo.meta_data['loader'] = self.type_name
222        self.send_to_output()
Note: See TracBrowser for help on using the repository browser.