source: sasview/DataLoader/readers/ascii_reader.py @ c9795f6

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 c9795f6 was 3617aa2, checked in by Mathieu Doucet <doucetm@…>, 16 years ago

DataLoader?: Added a new unit test

  • Property mode set to 100644
File size: 14.4 KB
Line 
1"""
2This software was developed by the University of Tennessee as part of the
3Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
4project funded by the US National Science Foundation.
5
6See the license text in license.txt
7
8copyright 2008, University of Tennessee
9"""
10
11import numpy
12import os
13from DataLoader.data_info import Data1D
14
15# Check whether we have a converter available
16has_converter = True
17try:
18    from data_util.nxsunit import Converter
19except:
20    has_converter = False
21
22class Reader:
23    """
24        Class to load ascii files (2 or 3 columns)
25    """
26    ## File type
27    type_name = "ASCII"
28   
29    ## Wildcards
30    type = ["ASCII files (*.txt)|*.txt",
31            "ASCII files (*.dat)|*.dat",
32            "ASCII files (*.abs)|*.abs"]
33    ## List of allowed extensions
34    ext=['.txt', '.TXT', '.dat', '.DAT', '.abs', '.ABS'] 
35   
36    def read(self, path):
37        """
38            Load data file
39           
40            @param path: file path
41            @return: Data1D object, or None
42            @raise RuntimeError: when the file can't be opened
43            @raise ValueError: when the length of the data vectors are inconsistent
44        """
45        if os.path.isfile(path):
46            basename  = os.path.basename(path)
47            root, extension = os.path.splitext(basename)
48            if extension.lower() in self.ext:
49                try:
50                    input_f =  open(path,'r')
51                except :
52                    raise  RuntimeError, "ascii_reader: cannot open %s" % path
53                buff = input_f.read()
54                lines = buff.split('\n')
55               
56                #Jae could not find python universal line spliter: keep the below for now
57                # some ascii data has \r line separator, try it when it has only one line
58                if len(lines) < 2 : 
59                    lines = buff.split('\r')
60                 
61                x  = numpy.zeros(0)
62                y  = numpy.zeros(0)
63                dy = numpy.zeros(0)
64                dx = numpy.zeros(0)
65               
66               #temp. space to sort data
67                tx  = numpy.zeros(0)
68                ty  = numpy.zeros(0)
69                tdy = numpy.zeros(0)
70                tdx = numpy.zeros(0)
71               
72                output = Data1D(x, y, dy=dy, dx=dx)
73                self.filename = output.filename = basename
74           
75                data_conv_q = None
76                data_conv_i = None
77               
78                if has_converter == True and output.x_unit != '1/A':
79                    data_conv_q = Converter('1/A')
80                    # Test it
81                    data_conv_q(1.0, output.x_unit)
82                   
83                if has_converter == True and output.y_unit != '1/cm':
84                    data_conv_i = Converter('1/cm')
85                    # Test it
86                    data_conv_i(1.0, output.y_unit)
87           
88               
89                # The first good line of data will define whether
90                # we have 2-column or 3-column ascii
91                has_error_dx = None
92                has_error_dy = None
93               
94                #Initialize counters for data lines and header lines.
95                is_data = False #Has more than 3 lines
96                mum_data_lines = 3 # More than "3" lines of data is considered as actual data unless that is the only data
97
98                i=-1            # To count # of current data candidate lines
99                i1=-1           # To count total # of previous data candidate lines
100                j=-1            # To count # of header lines
101                j1=-1           # Helps to count # of header lines
102                lentoks = 2     # minimum required number of columns of data; ( <= 4).
103               
104                for line in lines:
105                    toks = line.split()
106                   
107                    try:
108                       
109                        _x = float(toks[0])
110                        _y = float(toks[1])
111                       
112                        #To reject the line when reader meets less columns of data
113                        if lentoks == 3:
114                            _dy = float(toks[2])
115                        elif lentoks == 4:
116                            _dx = float(toks[3])
117                       
118                        #Reset the header line counters
119                        if j == j1:
120                            j = 0
121                            j1 = 0
122                           
123                        if i > 1:
124                            is_data = True
125                       
126                        if data_conv_q is not None:
127                            _x = data_conv_q(_x, units=output.x_unit)
128                           
129                        if data_conv_i is not None:
130                            _y = data_conv_i(_y, units=output.y_unit)                       
131                       
132                        # If we have an extra token, check
133                        # whether it can be interpreted as a
134                        # third column.
135                        _dy = None
136                        if len(toks)>2:
137                            try:
138                                _dy = float(toks[2])
139                               
140                                if data_conv_i is not None:
141                                    _dy = data_conv_i(_dy, units=output.y_unit)
142                               
143                            except:
144                                # The third column is not a float, skip it.
145                                pass
146                           
147                        # If we haven't set the 3rd column
148                        # flag, set it now.
149                        if has_error_dy == None:
150                            has_error_dy = False if _dy == None else True
151                           
152                        #Check for dx
153                        _dx = None
154                        if len(toks)>3:
155                            try:
156                                _dx = float(toks[3])
157                               
158                                if data_conv_i is not None:
159                                    _dx = data_conv_i(_dx, units=output.x_unit)
160                               
161                            except:
162                                # The 4th column is not a float, skip it.
163                                pass
164                           
165                        # If we haven't set the 3rd column
166                        # flag, set it now.
167                        if has_error_dx == None:
168                            has_error_dx = False if _dx == None else True
169                       
170                        #After talked with PB, we decided to take care of only 4 columns of data for now.
171                        #number of columns in the current line
172                        if len(toks)>= 4:
173                            new_lentoks = 4
174                        else:
175                            new_lentoks = len(toks)
176                       
177                        #If the previous columns are less than the current, mark the previous as non-data and reset the dependents. 
178                        if lentoks < new_lentoks :
179                            if is_data == False:
180                                i = -1
181                                i1 = 0
182                                j = -1
183                                j1 = -1
184                           
185                        #Delete the previously stored lines of data candidates if is not data.
186                        if i < 0 and -1< i1 < mum_data_lines and is_data == False:
187                            try:
188                                x= numpy.zeros(0)
189                                y= numpy.zeros(0)
190                               
191                            except:
192                                pass
193                           
194                        x  = numpy.append(x,   _x) 
195                        y  = numpy.append(y,   _y)
196                       
197                        if has_error_dy == True:
198                            #Delete the previously stored lines of data candidates if is not data.
199                            if i < 0 and -1< i1 < mum_data_lines and is_data== False:
200                                try:
201                                    dy = numpy.zeros(0) 
202                                except:
203                                    pass                                                               
204                            dy = numpy.append(dy, _dy)
205                           
206                        if has_error_dx == True:
207                            #Delete the previously stored lines of data candidates if is not data.
208                            if i < 0 and -1< i1 < mum_data_lines and is_data== False:
209                                try:
210                                    dx = numpy.zeros(0)                           
211                                except:
212                                    pass                                                               
213                            dx = numpy.append(dx, _dx)
214                           
215                        #Same for temp.
216                        #Delete the previously stored lines of data candidates if is not data.
217                        if i < 0 and -1< i1 < mum_data_lines and is_data== False:
218                            try:
219                                tx = numpy.zeros(0)
220                                ty = numpy.zeros(0)
221                            except:
222                                pass                                                               
223
224                        tx  = numpy.append(tx,   _x) 
225                        ty  = numpy.append(ty,   _y)
226                       
227                        if has_error_dy == True:
228                            #Delete the previously stored lines of data candidates if is not data.
229                            if i < 0 and -1<i1 < mum_data_lines and is_data== False:
230                                try:
231                                    tdy = numpy.zeros(0)
232                                except:
233                                    pass                                                                                                               
234                            tdy = numpy.append(tdy, _dy)
235                        if has_error_dx == True:
236                            #Delete the previously stored lines of data candidates if is not data.
237                            if i < 0 and -1< i1 < mum_data_lines and is_data== False:
238                                try:
239                                    tdx = numpy.zeros(0)
240                                except:
241                                    pass                                                                                                             
242                            tdx = numpy.append(tdx, _dx)
243
244                        #reset i1 and flag lentoks for the next
245                        if lentoks < new_lentoks :
246                            if is_data == False:
247                                i1 = -1                           
248                        if len(toks)>= 4:
249                            lentoks = 4
250                        else:
251                            lentoks = len(toks)
252                       
253                        #Reset # of header lines and counts # of data candidate lines   
254                        if j == 0 and j1 ==0:
255                            i1 = i + 1                           
256                        i+=1
257                       
258                    except:
259
260                        # It is data and meet non - number, then stop reading
261                        if is_data == True:
262                            break   
263                        lentoks = 2
264                        #Counting # of header lines                   
265                        j+=1
266                        if j == j1+1:
267                            j1 = j                           
268                        else:                           
269                            j = -1
270                        #Reset # of lines of data candidates
271                        i = -1
272                       
273                        # Couldn't parse this line, skip it
274                        pass
275                   
276   
277                     
278                # Sanity check
279                if has_error_dy == True and not len(y) == len(dy):
280                    raise RuntimeError, "ascii_reader: y and dy have different length"
281                if has_error_dx == True and not len(x) == len(dx):
282                    raise RuntimeError, "ascii_reader: y and dy have different length"
283
284                # If the data length is zero, consider this as
285                # though we were not able to read the file.
286                if len(x)==0:
287                    raise RuntimeError, "ascii_reader: could not load file"
288               
289                #Let's re-order the data to make cal. curve look better some cases
290                ind = numpy.lexsort((ty,tx))
291                for i in ind:
292                    x[i] = tx[ind[i]]
293                    y[i] = ty[ind[i]]
294                    if has_error_dy == True:
295                        dy[i] = tdy[ind[i]]
296                    if has_error_dx == True:
297                        dx[i] = tdx[ind[i]]
298               
299               
300                #Data   
301                output.x = x
302                output.y = y
303                output.dy = dy if has_error_dy == True else None
304                output.dx = dx if has_error_dx == True else None
305               
306                if data_conv_q is not None:
307                    output.xaxis("\\rm{Q}", output.x_unit)
308                else:
309                    output.xaxis("\\rm{Q}", 'A^{-1}')
310                if data_conv_i is not None:
311                    output.yaxis("\\rm{Intensity}", output.y_unit)
312                else:
313                    output.yaxis("\\rm{Intensity}","cm^{-1}")
314                return output
315           
316        else:
317            raise RuntimeError, "%s is not a file" % path
318        return None
319   
320if __name__ == "__main__": 
321    reader = Reader()
322    #print reader.read("../test/test_3_columns.txt")
323    print reader.read("../test/empty.txt")
324   
325   
326                       
Note: See TracBrowser for help on using the repository browser.