source: sasview/DataLoader/readers/danse_reader.py @ 6e0e2d85

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 6e0e2d85 was fe78c7b, checked in by Mathieu Doucet <doucetm@…>, 15 years ago

DataLoader?: exception no longer raised when units are wrong for an entry; the entry is not loaded and an error is logged instead. Loader info is now stored.

  • Property mode set to 100644
File size: 10.2 KB
Line 
1"""
2    DANSE/SANS file reader
3"""
4
5"""
6This software was developed by the University of Tennessee as part of the
7Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
8project funded by the US National Science Foundation.
9
10If you use DANSE applications to do scientific research that leads to
11publication, we ask that you acknowledge the use of the software with the
12following sentence:
13
14"This work benefited from DANSE software developed under NSF award DMR-0520547."
15
16copyright 2008, University of Tennessee
17"""
18
19import math
20import os
21import copy
22import numpy
23import logging
24from DataLoader.data_info import Data2D, Detector
25
26# Look for unit converter
27has_converter = True
28try:
29    from data_util.nxsunit import Converter
30except:
31    has_converter = False
32
33class Reader:
34    """
35        Example data manipulation
36    """
37    ## File type
38    type_name = "DANSE"   
39    ## Wildcards
40    type = ["DANSE files (*.sans)|*.sans"]
41    ## Extension
42    ext  = ['.sans', '.SANS']   
43       
44    def read(self, filename=None):
45        """
46            Open and read the data in a file
47            @param file: path of the file
48        """
49       
50        read_it = False
51        for item in self.ext:
52            if filename.lower().find(item)>=0:
53                read_it = True
54               
55        if read_it:
56            try:
57                 datafile = open(filename, 'r')
58            except :
59                raise  RuntimeError,"danse_reader cannot open %s"%(filename)
60           
61           
62            # defaults
63            # wavelength in Angstrom
64            wavelength = 10.0
65            # Distance in meter
66            distance   = 11.0
67            # Pixel number of center in x
68            center_x   = 65
69            # Pixel number of center in y
70            center_y   = 65
71            # Pixel size [mm]
72            pixel      = 5.0
73            # Size in x, in pixels
74            size_x     = 128
75            # Size in y, in pixels
76            size_y     = 128
77            # Format version
78            fversion   = 1.0
79           
80            output = Data2D()
81            output.filename = os.path.basename(filename)
82            detector = Detector()
83            output.detector.append(detector)
84           
85            output.data = numpy.zeros([size_x,size_y])
86            output.err_data = numpy.zeros([size_x,size_y])
87           
88            data_conv_q = None
89            data_conv_i = None
90           
91            if has_converter == True and output.Q_unit != '1/A':
92                data_conv_q = Converter('1/A')
93                # Test it
94                data_conv_q(1.0, output.Q_unit)
95               
96            if has_converter == True and output.I_unit != '1/cm':
97                data_conv_i = Converter('1/cm')
98                # Test it
99                data_conv_i(1.0, output.I_unit)           
100       
101            read_on = True
102            while read_on:
103                line = datafile.readline()
104                if line.find("DATA:")>=0:
105                    read_on = False
106                    break
107                toks = line.split(':')
108                if toks[0]=="FORMATVERSION":
109                    fversion = float(toks[1])
110                if toks[0]=="WAVELENGTH":   
111                    wavelength = float(toks[1])               
112                elif toks[0]=="DISTANCE":
113                    distance = float(toks[1])
114                elif toks[0]=="CENTER_X":
115                    center_x = float(toks[1])
116                elif toks[0]=="CENTER_Y":
117                    center_y = float(toks[1])
118                elif toks[0]=="PIXELSIZE":
119                    pixel = float(toks[1])
120                elif toks[0]=="SIZE_X":
121                    size_x = int(toks[1])
122                elif toks[0]=="SIZE_Y":
123                    size_y = int(toks[1])
124           
125            # Read the data
126            data = []
127            error = []
128            if fversion==1.0:
129                data_str = datafile.readline()
130                data = data_str.split(' ')
131            else:
132                read_on = True
133                while read_on:
134                    data_str = datafile.readline()
135                    if len(data_str)==0:
136                        read_on = False
137                    else:
138                        toks = data_str.split()
139                        try:
140                            val = float(toks[0])
141                            err = float(toks[1])
142                            if data_conv_i is not None:
143                                val = data_conv_i(val, units=output.y_unit)
144                                err = data_conv_i(err, units=output.y_unit)
145                            data.append(val)
146                            error.append(err)
147                        except:
148                            logging.info("Skipping line:%s,%s" %( data_str,sys.exc_value))
149           
150            # Initialize
151            x_vals = []
152            y_vals = [] 
153            ymin = None
154            ymax = None
155            xmin = None
156            xmax = None
157           
158            # Qx and Qy vectors
159            theta = pixel / distance / 100.0
160            stepq = 4.0*math.pi/wavelength * math.sin(theta/2.0) 
161            for i_x in range(size_x):
162                theta = (i_x-center_x+1)*pixel / distance / 100.0
163                qx = 4.0*math.pi/wavelength * math.sin(theta/2.0)
164               
165                if has_converter == True and output.Q_unit != '1/A':
166                    qx = data_conv_q(qx, units=output.Q_unit)
167               
168                x_vals.append(qx)
169                if xmin==None or qx<xmin:
170                    xmin = qx
171                if xmax==None or qx>xmax:
172                    xmax = qx
173           
174            ymin = None
175            ymax = None
176            for i_y in range(size_y):
177                theta = (i_y-center_y+1)*pixel / distance / 100.0
178                qy = 4.0*math.pi/wavelength * math.sin(theta/2.0)
179               
180                if has_converter == True and output.Q_unit != '1/A':
181                    qy = data_conv_q(qy, units=output.Q_unit)
182               
183                y_vals.append(qy)
184                if ymin==None or qy<ymin:
185                    ymin = qy
186                if ymax==None or qy>ymax:
187                    ymax = qy
188           
189            # Store the data in the 2D array
190            itot = 0
191            i_x  = 0
192            i_y  = -1
193           
194            for i_pt in range(len(data)):
195                try:
196                    value = float(data[i_pt])
197                except:
198                    # For version 1.0, the data were still
199                    # stored as strings at this point.
200                    logging.info("Skipping entry (v1.0):%s,%s" %(str(data[i_pt]), sys.exc_value))
201               
202                # Get bin number
203                if math.fmod(i_pt, size_x)==0:
204                    i_x = 0
205                    i_y += 1
206                else:
207                    i_x += 1
208                   
209                output.data[i_y][i_x] = value       
210                #output.data[size_y-1-i_y][i_x] = value
211                if fversion>1.0:
212                    output.err_data[i_y][i_x] = error[i_pt]
213                    #output.err_data[size_y-1-i_y][i_x] = error[i_pt]
214               
215               
216            # Store all data ######################################
217            # Store wavelength
218            if has_converter==True and output.source.wavelength_unit != 'A':
219                conv = Converter('A')
220                wavelength = conv(wavelength, units=output.source.wavelength_unit)
221            output.source.wavelength = wavelength
222               
223            # Store distance
224            if has_converter==True and detector.distance_unit != 'm':
225                conv = Converter('m')
226                distance = conv(distance, units=detector.distance_unit)
227            detector.distance = distance
228           
229            # Store pixel size
230            if has_converter==True and detector.pixel_size_unit != 'mm':
231                conv = Converter('mm')
232                pixel = conv(pixel, units=detector.pixel_size_unit)
233            detector.pixel_size.x = pixel
234            detector.pixel_size.y = pixel
235
236            # Store beam center in distance units
237            detector.beam_center.x = center_x*pixel
238            detector.beam_center.y = center_y*pixel
239           
240            # Store limits of the image (2D array)
241            xmin    =xmin-stepq/2.0
242            xmax    =xmax+stepq/2.0
243            ymin    =ymin-stepq/2.0
244            ymax    =ymax+stepq/2.0
245           
246            if has_converter == True and output.Q_unit != '1/A':
247                xmin = data_conv_q(xmin, units=output.Q_unit)
248                xmax = data_conv_q(xmax, units=output.Q_unit)
249                ymin = data_conv_q(ymin, units=output.Q_unit)
250                ymax = data_conv_q(ymax, units=output.Q_unit)
251            output.xmin = xmin
252            output.xmax = xmax
253            output.ymin = ymin
254            output.ymax = ymax
255           
256            # Store x and y axis bin centers
257            output.x_bins     = x_vals
258            output.y_bins     = y_vals
259           
260            # Units
261            if data_conv_q is not None:
262                output.xaxis("\\rm{Q_{x}}", output.Q_unit)
263                output.yaxis("\\rm{Q_{y}}", output.Q_unit)
264            else:
265                output.xaxis("\\rm{Q_{x}}", 'A^{-1}')
266                output.yaxis("\\rm{Q_{y}}", 'A^{-1}')
267               
268            if data_conv_i is not None:
269                output.zaxis("\\rm{Intensity}", output.I_unit)
270            else:
271                output.zaxis("\\rm{Intensity}","cm^{-1}")
272           
273            if not fversion>=1.0:
274                raise ValueError,"Danse_reader can't read this file %s"%filename
275            else:
276                logging.info("Danse_reader Reading %s \n"%filename)
277           
278            # Store loading process information
279            output.meta_data['loader'] = self.type_name   
280            return output
281       
282        return None
283
284if __name__ == "__main__": 
285    reader = Reader()
286    print reader.read("../test/MP_New.sans")
287   
Note: See TracBrowser for help on using the repository browser.