source: sasview/DataLoader/readers/red2d_reader.py @ 6450d8c

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 6450d8c was 0997158f, checked in by Gervaise Alina <gervyh@…>, 15 years ago

working on documentation

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