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

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since a6ee176 was a1b8fee, checked in by andyfaff, 8 years ago

MAINT: from future import print_function

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