source: sasview/src/sas/sascalc/dataloader/readers/IgorReader.py @ a2573fc

Last change on this file since a2573fc was dd11014, checked in by ajj, 8 years ago

Fixing PR #55 broken merge

  • Property mode set to 100644
File size: 8.8 KB
Line 
1"""
2    IGOR 2D reduced file 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#If you use DANSE applications to do scientific research that leads to
9#publication, we ask that you acknowledge the use of the software with the
10#following sentence:
11#This work benefited from DANSE software developed under NSF award DMR-0520547.
12#copyright 2008, University of Tennessee
13#############################################################################
14import os
15
16from sas.sascalc.dataloader.data_info import Data2D
17from sas.sascalc.dataloader.data_info import Detector
18from sas.sascalc.dataloader.manipulations import reader2D_converter
19import numpy as np
20
21# Look for unit converter
22has_converter = True
23try:
24    from sas.sascalc.data_util.nxsunit import Converter
25except:
26    has_converter = False
27
28
29class Reader:
30    """ Simple data reader for Igor data files """
31    ## File type
32    type_name = "IGOR 2D"
33    ## Wildcards
34    type = ["IGOR 2D files (*.ASC)|*.ASC"]
35    ## Extension
36    ext=['.ASC', '.asc']
37
38    def read(self, filename=None):
39        """ Read file """
40        if not os.path.isfile(filename):
41            raise ValueError("Specified file %s is not a regular "
42                             "file" % filename)
43       
44        output = Data2D()
45
46        output.filename = os.path.basename(filename)
47        detector = Detector()
48        if len(output.detector):
49            print(str(output.detector[0]))
50        output.detector.append(detector)
51
52        data_conv_q = data_conv_i = None
53       
54        if has_converter and output.Q_unit != '1/A':
55            data_conv_q = Converter('1/A')
56            # Test it
57            data_conv_q(1.0, output.Q_unit)
58           
59        if has_converter and output.I_unit != '1/cm':
60            data_conv_i = Converter('1/cm')
61            # Test it
62            data_conv_i(1.0, output.I_unit)
63
64        data_row = 0
65        wavelength = distance = center_x = center_y = None
66        dataStarted = isInfo = isCenter = False
67
68        with open(filename, 'r') as f:
69            for line in f:
70                data_row += 1
71                # Find setup info line
72                if isInfo:
73                    isInfo = False
74                    line_toks = line.split()
75                    # Wavelength in Angstrom
76                    try:
77                        wavelength = float(line_toks[1])
78                    except ValueError:
79                        msg = "IgorReader: can't read this file, missing wavelength"
80                        raise ValueError(msg)
81                    # Distance in meters
82                    try:
83                        distance = float(line_toks[3])
84                    except ValueError:
85                        msg = "IgorReader: can't read this file, missing distance"
86                        raise ValueError(msg)
87
88                    # Distance in meters
89                    try:
90                        transmission = float(line_toks[4])
91                    except:
92                        msg = "IgorReader: can't read this file, "
93                        msg += "missing transmission"
94                        raise ValueError(msg)
95
96                if line.count("LAMBDA"):
97                    isInfo = True
98
99                # Find center info line
100                if isCenter:
101                    isCenter = False
102                    line_toks = line.split()
103
104                    # Center in bin number: Must subtract 1 because
105                    # the index starts from 1
106                    center_x = float(line_toks[0]) - 1
107                    center_y = float(line_toks[1]) - 1
108
109                if line.count("BCENT"):
110                    isCenter = True
111
112                # Find data start
113                if line.count("***"):
114                    # now have to continue to blank line
115                    dataStarted = True
116
117                    # Check that we have all the info
118                    if (wavelength is None
119                            or distance is None
120                            or center_x is None
121                            or center_y is None):
122                        msg = "IgorReader:Missing information in data file"
123                        raise ValueError(msg)
124
125                if dataStarted:
126                    if len(line.rstrip()):
127                        continue
128                    else:
129                        break
130
131        # The data is loaded in row major order (last index changing most
132        # rapidly). However, the original data is in column major order (first
133        # index changing most rapidly). The swap to column major order is done
134        # in reader2D_converter at the end of this method.
135        data = np.loadtxt(filename, skiprows=data_row)
136        size_x = size_y = int(np.rint(np.sqrt(data.size)))
137        output.data = np.reshape(data, (size_x, size_y))
138        output.err_data = np.zeros_like(output.data)
139
140        # Det 640 x 640 mm
141        # Q = 4 * pi/lambda * sin(theta/2)
142        # Bin size is 0.5 cm
143        # Removed +1 from theta = (i_x - center_x + 1)*0.5 / distance
144        # / 100.0 and
145        # Removed +1 from theta = (i_y - center_y + 1)*0.5 /
146        # distance / 100.0
147        # ToDo: Need  complete check if the following
148        # convert process is consistent with fitting.py.
149
150        # calculate qx, qy bin centers of each pixel in the image
151        theta = (np.arange(size_x) - center_x) * 0.5 / distance / 100.
152        qx = 4 * np.pi / wavelength * np.sin(theta/2)
153
154        theta = (np.arange(size_y) - center_y) * 0.5 / distance / 100.
155        qy = 4 * np.pi / wavelength * np.sin(theta/2)
156
157        if has_converter and output.Q_unit != '1/A':
158            qx = data_conv_q(qx, units=output.Q_unit)
159            qy = data_conv_q(qx, units=output.Q_unit)
160
161        xmax = np.max(qx)
162        xmin = np.min(qx)
163        ymax = np.max(qy)
164        ymin = np.min(qy)
165
166        # calculate edge offset in q.
167        theta = 0.25 / distance / 100.0
168        xstep = 4.0 * np.pi / wavelength * np.sin(theta / 2.0)
169       
170        theta = 0.25 / distance / 100.0
171        ystep = 4.0 * np.pi/ wavelength * np.sin(theta / 2.0)
172       
173        # Store all data ######################################
174        # Store wavelength
175        if has_converter and output.source.wavelength_unit != 'A':
176            conv = Converter('A')
177            wavelength = conv(wavelength, units=output.source.wavelength_unit)
178        output.source.wavelength = wavelength
179
180        # Store distance
181        if has_converter and detector.distance_unit != 'm':
182            conv = Converter('m')
183            distance = conv(distance, units=detector.distance_unit)
184        detector.distance = distance
185 
186        # Store transmission
187        output.sample.transmission = transmission
188       
189        # Store pixel size (mm)
190        pixel = 5.0
191        if has_converter and detector.pixel_size_unit != 'mm':
192            conv = Converter('mm')
193            pixel = conv(pixel, units=detector.pixel_size_unit)
194        detector.pixel_size.x = pixel
195        detector.pixel_size.y = pixel
196 
197        # Store beam center in distance units
198        detector.beam_center.x = center_x * pixel
199        detector.beam_center.y = center_y * pixel
200       
201        # Store limits of the image (2D array)
202        xmin -= xstep / 2.0
203        xmax += xstep / 2.0
204        ymin -= ystep / 2.0
205        ymax += ystep / 2.0
206        if has_converter and output.Q_unit != '1/A':
207            xmin = data_conv_q(xmin, units=output.Q_unit)
208            xmax = data_conv_q(xmax, units=output.Q_unit)
209            ymin = data_conv_q(ymin, units=output.Q_unit)
210            ymax = data_conv_q(ymax, units=output.Q_unit)
211        output.xmin = xmin
212        output.xmax = xmax
213        output.ymin = ymin
214        output.ymax = ymax
215       
216        # Store x and y axis bin centers
217        output.x_bins = qx.tolist()
218        output.y_bins = qy.tolist()
219       
220        # Units
221        if data_conv_q is not None:
222            output.xaxis("\\rm{Q_{x}}", output.Q_unit)
223            output.yaxis("\\rm{Q_{y}}", output.Q_unit)
224        else:
225            output.xaxis("\\rm{Q_{x}}", 'A^{-1}')
226            output.yaxis("\\rm{Q_{y}}", 'A^{-1}')
227           
228        if data_conv_i is not None:
229            output.zaxis("\\rm{Intensity}", output.I_unit)
230        else:
231            output.zaxis("\\rm{Intensity}", "cm^{-1}")
232   
233        # Store loading process information
234        output.meta_data['loader'] = self.type_name
235        output = reader2D_converter(output)
236
237        return output
Note: See TracBrowser for help on using the repository browser.