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

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 36d69e1 was 36d69e1, checked in by andyfaff, 7 years ago

MAINT: refactor IgorReader?.py

  • Property mode set to 100644
File size: 8.8 KB
RevLine 
[7d6351e]1"""
2    IGOR 2D reduced file reader
3"""
[0997158f]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#############################################################################
[a7a5886]14import os
[36d69e1]15
[b699768]16from sas.sascalc.dataloader.data_info import Data2D
17from sas.sascalc.dataloader.data_info import Detector
18from sas.sascalc.dataloader.manipulations import reader2D_converter
[36d69e1]19import numpy as np
[b99ac227]20
21# Look for unit converter
22has_converter = True
23try:
[b699768]24    from sas.sascalc.data_util.nxsunit import Converter
[b99ac227]25except:
26    has_converter = False
27
[7d6351e]28
[bb03739]29class Reader:
[11a0319]30    """ Simple data reader for Igor data files """
[b99ac227]31    ## File type
[7d6351e]32    type_name = "IGOR 2D"
[28caa03]33    ## Wildcards
[b99ac227]34    type = ["IGOR 2D files (*.ASC)|*.ASC"]
35    ## Extension
36    ext=['.ASC', '.asc']
37
[7d6351e]38    def read(self, filename=None):
[11a0319]39        """ Read file """
[b99ac227]40        if not os.path.isfile(filename):
[36d69e1]41            raise ValueError("Specified file %s is not a regular "
42                             "file" % filename)
[11a0319]43       
[b99ac227]44        output = Data2D()
[36d69e1]45
[b99ac227]46        output.filename = os.path.basename(filename)
47        detector = Detector()
[36d69e1]48        if len(output.detector):
49            print(str(output.detector[0]))
[b99ac227]50        output.detector.append(detector)
[36d69e1]51
52        data_conv_q = data_conv_i = None
[f55af70]53       
[36d69e1]54        if has_converter and output.Q_unit != '1/A':
[ca10d8e]55            data_conv_q = Converter('1/A')
[f55af70]56            # Test it
57            data_conv_q(1.0, output.Q_unit)
58           
[36d69e1]59        if has_converter and output.I_unit != '1/cm':
[ca10d8e]60            data_conv_i = Converter('1/cm')
[f55af70]61            # Test it
[7d6351e]62            data_conv_i(1.0, output.I_unit)
[11a0319]63
[36d69e1]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)
[b99ac227]156
[36d69e1]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)
[b99ac227]160
[36d69e1]161        xmax = np.max(qx)
162        xmin = np.min(qx)
163        ymax = np.max(qy)
164        ymin = np.min(qy)
[b99ac227]165
[36d69e1]166        # calculate edge offset in q.
[11a0319]167        theta = 0.25 / distance / 100.0
[36d69e1]168        xstep = 4.0 * np.pi / wavelength * np.sin(theta / 2.0)
[11a0319]169       
170        theta = 0.25 / distance / 100.0
[36d69e1]171        ystep = 4.0 * np.pi/ wavelength * np.sin(theta / 2.0)
[11a0319]172       
[b99ac227]173        # Store all data ######################################
174        # Store wavelength
[36d69e1]175        if has_converter and output.source.wavelength_unit != 'A':
[b99ac227]176            conv = Converter('A')
177            wavelength = conv(wavelength, units=output.source.wavelength_unit)
178        output.source.wavelength = wavelength
179
180        # Store distance
[36d69e1]181        if has_converter and detector.distance_unit != 'm':
[b99ac227]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
[11a0319]188       
[36d69e1]189        # Store pixel size (mm)
[b99ac227]190        pixel = 5.0
[36d69e1]191        if has_converter and detector.pixel_size_unit != 'mm':
[b99ac227]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
[11a0319]196 
[b99ac227]197        # Store beam center in distance units
[7d6351e]198        detector.beam_center.x = center_x * pixel
199        detector.beam_center.y = center_y * pixel
[b99ac227]200       
201        # Store limits of the image (2D array)
[36d69e1]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':
[b99ac227]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
[36d69e1]217        output.x_bins = qx.tolist()
218        output.y_bins = qy.tolist()
[b99ac227]219       
220        # Units
221        if data_conv_q is not None:
[b568ec1b]222            output.xaxis("\\rm{Q_{x}}", output.Q_unit)
223            output.yaxis("\\rm{Q_{y}}", output.Q_unit)
[b99ac227]224        else:
[b568ec1b]225            output.xaxis("\\rm{Q_{x}}", 'A^{-1}')
226            output.yaxis("\\rm{Q_{y}}", 'A^{-1}')
[b99ac227]227           
228        if data_conv_i is not None:
[0e2aa40]229            output.zaxis("\\rm{Intensity}", output.I_unit)
[b99ac227]230        else:
[7d6351e]231            output.zaxis("\\rm{Intensity}", "cm^{-1}")
[b99ac227]232   
[fe78c7b]233        # Store loading process information
234        output.meta_data['loader'] = self.type_name
[eadf1f9]235        output = reader2D_converter(output)
236
[16d8e5f]237        return output
Note: See TracBrowser for help on using the repository browser.