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

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

dataloader: allow all file extensions to be read by the ascii reader.

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