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

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 f68d503 was ed2276f, checked in by GitHub <noreply@…>, 8 years ago

Merge branch 'master' into numpy_import

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