source: sasview/DataLoader/readers/red2d_reader.py @ fc292d3

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.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since fc292d3 was a7a5886, checked in by Gervaise Alina <gervyh@…>, 14 years ago

working pylint

  • Property mode set to 100644
File size: 11.0 KB
RevLine 
[0997158f]1
2#####################################################################
3#This software was developed by the University of Tennessee as part of the
4#Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
5#project funded by the US National Science Foundation.
6#See the license text in license.txt
7#copyright 2008, University of Tennessee
8######################################################################
9
[3cd95c8]10"""
11    TXT/IGOR 2D Q Map file reader
12"""
13
14
[a7a5886]15import os
16#import sys
[3cd95c8]17import numpy
[a7a5886]18import math
19#import logging
[3cd95c8]20from DataLoader.data_info import Data2D, Detector
21
22# Look for unit converter
23has_converter = True
24try:
25    from data_util.nxsunit import Converter
26except:
27    has_converter = False
[d2539aa]28   
29def check_point(x_point):
30    """
31    check point validity
32    """
33    # set zero for non_floats
34    try:
35        return float(x_point)
36    except:
37        return 0
38       
[3cd95c8]39class Reader:
40    """ Simple data reader for Igor data files """
41    ## File type
42    type_name = "IGOR/DAT 2D Q_map"   
43    ## Wildcards
44    type = ["IGOR/DAT 2D file in Q_map (*.dat)|*.DAT"]
45    ## Extension
46    ext=['.DAT', '.dat']
47
48    def read(self,filename=None):
49        """ Read file """
50        if not os.path.isfile(filename):
51            raise ValueError, \
52            "Specified file %s is not a regular file" % filename
[952afaa]53
[3cd95c8]54        # Read file
55        f = open(filename,'r')
56        buf = f.read()
[952afaa]57        f.close()     
[3cd95c8]58        # Instantiate data object
59        output = Data2D()
60        output.filename = os.path.basename(filename)
61        detector = Detector()
62        if len(output.detector)>0: print str(output.detector[0])
63        output.detector.append(detector)
64               
65        # Get content
66        dataStarted = False
67       
68        ## Defaults     
69        lines = buf.split('\n')
70        itot = 0
71        x = []
72        y = []
73       
74        ncounts = 0
75       
76        wavelength   = None
77        distance     = None
78        transmission = None
79       
80        pixel_x = None
81        pixel_y = None
82       
83        i_x    = 0
84        i_y    = -1
85        pixels = 0
86       
87        isInfo   = False
88        isCenter = False
89
90        data_conv_q = None
91        data_conv_i = None
92       
93        # Set units: This is the unit assumed for Q and I in the data file.
94        if has_converter == True and output.Q_unit != '1/A':
95            data_conv_q = Converter('1/A')
96            # Test it
97            data_conv_q(1.0, output.Q_unit)
98           
99        if has_converter == True and output.I_unit != '1/cm':
100            data_conv_i = Converter('1/cm')
101            # Test it
102            data_conv_i(1.0, output.I_unit)           
103       
[952afaa]104             
105        # Remove the last lines before the for loop if the lines are empty
106        # to calculate the exact number of data points
107        count = 0
108        while (len(lines[len(lines)-(count+1)].lstrip().rstrip()) < 1):
109            del lines[len(lines)-(count+1)]
110            count = count + 1
111
112        #Read Header and find the dimensions of 2D data
113        line_num = 0
[3cd95c8]114        for line in lines:     
[952afaa]115            line_num += 1
[3cd95c8]116            ## Reading the header applies only to IGOR/NIST 2D q_map data files
117            # Find setup info line
118            if isInfo:
119                isInfo = False
120                line_toks = line.split()
121                # Wavelength in Angstrom
122                try:
123                    wavelength = float(line_toks[1])
124                    # Units
[a7a5886]125                    if has_converter == True and \
126                    output.source.wavelength_unit != 'A':
[3cd95c8]127                        conv = Converter('A')
[a7a5886]128                        wavelength = conv(wavelength,
129                                          units=output.source.wavelength_unit)
[3cd95c8]130                except:
131                    #Not required
132                    pass
133                # Distance in mm
134                try:
135                    distance = float(line_toks[3])
136                    # Units
[a7a5886]137                    if has_converter == True and detector.distance_unit != 'm':
[3cd95c8]138                        conv = Converter('m')
139                        distance = conv(distance, units=detector.distance_unit)
140                except:
141                    #Not required
142                    pass
143               
144                # Distance in meters
145                try:
146                    transmission = float(line_toks[4])
147                except:
148                    #Not required
149                    pass
150                                           
[a7a5886]151            if line.count("LAMBDA") > 0:
[3cd95c8]152                isInfo = True
153               
154            # Find center info line
155            if isCenter:
156                isCenter = False               
157                line_toks = line.split()
158                # Center in bin number
159                center_x = float(line_toks[0])
160                center_y = float(line_toks[1])
161
[a7a5886]162            if line.count("BCENT") > 0:
[3cd95c8]163                isCenter = True
164                       
165            # Find data start
[a7a5886]166            if line.count("Data columns") or line.count("ASCII data") > 0:
[3cd95c8]167                dataStarted = True
168                continue
169
170            ## Read and get data.   
171            if dataStarted == True:
[952afaa]172                line_toks = line.split()             
[3cd95c8]173                if len(line_toks) == 0:
174                    #empty line
175                    continue
[952afaa]176                # the number of columns must be stayed same
177                col_num = len(line_toks)
178                break
179        # Make numpy array to remove header lines using index
180        lines_array = numpy.array(lines)
181
182        # index for lines_array
183        lines_index = numpy.arange(len(lines))
184       
185        # get the data lines
[a7a5886]186        data_lines = lines_array[lines_index >= (line_num - 1)]
[952afaa]187        # Now we get the total number of rows (i.e., # of data points)
188        row_num = len(data_lines)
189        # make it as list again to control the separators
190        data_list = " ".join(data_lines.tolist())
191        # split all data to one big list w/" "separator
192        data_list = data_list.split()
193 
[a7a5886]194        # Check if the size is consistent with data, otherwise
195        #try the tab(\t) separator
196        # (this may be removed once get the confidence
197        #the former working all cases).
[952afaa]198        if len(data_list) != (len(data_lines)) * col_num:
199            data_list = "\t".join(data_lines.tolist())
200            data_list = data_list.split()
[d2539aa]201
[952afaa]202        # Change it(string) into float
[d2539aa]203        #data_list = map(float,data_list)
204        data_list1 = map(check_point,data_list)
205     
[952afaa]206        # numpy array form
[d2539aa]207        data_array = numpy.array(data_list1)
[a7a5886]208        # Redimesion based on the row_num and col_num,
209        #otherwise raise an error.
[952afaa]210        try:
[a7a5886]211            data_point = data_array.reshape(row_num, col_num).transpose()
[952afaa]212        except:
[a7a5886]213            msg = "red2d_reader: Can't read this file: Not a proper file format"
214            raise ValueError, msg
[952afaa]215       
216        ## Get the all data: Let's HARDcoding; Todo find better way
217        # Defaults
218        dqx_data = numpy.zeros(0)
219        dqy_data = numpy.zeros(0)
220        qz_data = numpy.zeros(row_num)
221        mask = numpy.ones(row_num,dtype=bool)
222        # Get from the array
223        qx_data = data_point[0]
224        qy_data = data_point[1]
225        data = data_point[2]
[a7a5886]226        if col_num > 3: qz_data = data_point[3]
227        if col_num > 4: dqx_data = data_point[4]
228        if col_num > 5: dqy_data = data_point[5]
229        if col_num > 6: mask[data_point[6] < 1] = False
[952afaa]230        q_data = numpy.sqrt(qx_data*qx_data+qy_data*qy_data+qz_data*qz_data)
231           
232        # Extra protection(it is needed for some data files):
[32e8c78]233        # If all mask elements are False, put all True
234        if not mask.any(): mask[mask==False] = True   
[d2539aa]235           
[3cd95c8]236        # Store limits of the image in q space
237        xmin    = numpy.min(qx_data)
238        xmax    = numpy.max(qx_data)
239        ymin    = numpy.min(qy_data)
240        ymax    = numpy.max(qy_data)
241
242        # units
243        if has_converter == True and output.Q_unit != '1/A':
244            xmin = data_conv_q(xmin, units=output.Q_unit)
245            xmax = data_conv_q(xmax, units=output.Q_unit)
246            ymin = data_conv_q(ymin, units=output.Q_unit)
247            ymax = data_conv_q(ymax, units=output.Q_unit)
248           
249        ## calculate the range of the qx and qy_data
250        x_size = math.fabs(xmax - xmin)
251        y_size = math.fabs(ymax - ymin)
252       
253        # calculate the number of pixels in the each axes
254        npix_y = math.floor(math.sqrt(len(data)))
255        npix_x = math.floor(len(data)/npix_y)
256       
257        # calculate the size of bins     
258        xstep = x_size/(npix_x-1)
259        ystep = y_size/(npix_y-1)
260       
261        # store x and y axis bin centers in q space
262        x_bins  = numpy.arange(xmin,xmax+xstep,xstep)
263        y_bins  = numpy.arange(ymin,ymax+ystep,ystep)
264       
265        # get the limits of q values
266        xmin = xmin - xstep/2
267        xmax = xmax + xstep/2
268        ymin = ymin - ystep/2
269        ymax = ymax + ystep/2
270       
271        #Store data in outputs 
272        #TODO: Check the lengths
273        output.data     = data
274        output.err_data = numpy.sqrt(numpy.abs(data))
275        output.qx_data  = qx_data
276        output.qy_data  = qy_data             
277        output.q_data   = q_data
278        output.mask     = mask
279       
280        output.x_bins = x_bins
281        output.y_bins = y_bins
282               
283        output.xmin = xmin
284        output.xmax = xmax
285        output.ymin = ymin
286        output.ymax = ymax
287       
288        output.source.wavelength = wavelength
289       
290        # Store pixel size in mm
291        detector.pixel_size.x = pixel_x
292        detector.pixel_size.y = pixel_y
293       
294        # Store the sample to detector distance
295        detector.distance = distance
296       
[59a2dab]297        # optional data: if all of dq data == 0, do not pass to output
298        if len(dqx_data) == len(qx_data) and dqx_data.any()!=0: 
[a7a5886]299            # if no dqx_data, do not pass dqy_data.
300            #(1 axis dq is not supported yet).
[59a2dab]301            if len(dqy_data) == len(qy_data) and dqy_data.any()!=0:
302                output.dqx_data = dqx_data
303                output.dqy_data = dqy_data
[3cd95c8]304       
305        # Units of axes
306        if data_conv_q is not None:
307            output.xaxis("\\rm{Q_{x}}", output.Q_unit)
308            output.yaxis("\\rm{Q_{y}}", output.Q_unit)
309        else:
310            output.xaxis("\\rm{Q_{x}}", 'A^{-1}')
311            output.yaxis("\\rm{Q_{y}}", 'A^{-1}')           
312        if data_conv_i is not None:
313            output.zaxis("\\rm{Intensity}", output.I_unit)
314        else:
315            output.zaxis("\\rm{Intensity}","cm^{-1}")
316   
317        # Store loading process information
318        output.meta_data['loader'] = self.type_name
319
320        return output
321   
322if __name__ == "__main__": 
323    reader = Reader()
324    print reader.read("../test/exp18_14_igor_2dqxqy.dat") 
[952afaa]325       
326
Note: See TracBrowser for help on using the repository browser.