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

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 c8570c3 was 5f2d3c78, checked in by Jae Cho <jhjcho@…>, 15 years ago

data line should be composed only with numbers in any of the columns.
Added unittest and testdata

  • Property mode set to 100644
File size: 14.6 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                        #Make sure that all columns are numbers.
112                        for colnum in range(len(toks)):
113                            float(toks[colnum])
114                           
115                        _x = float(toks[0])
116                        _y = float(toks[1])
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                        #To remember the # of columns in the current line of data
173                        new_lentoks = len(toks)
174                       
175                        #If the previous columns not equal to the current, mark the previous as non-data and reset the dependents. 
176                        if lentoks != new_lentoks :
177                            if is_data == True:
178                                break
179                            else:
180                                i = -1
181                                i1 = 0
182                                j = -1
183                                j1 = -1
184                           
185                           
186                        #Delete the previously stored lines of data candidates if is not data.
187                        if i < 0 and -1< i1 < mum_data_lines and is_data == False:
188                            try:
189                                x= numpy.zeros(0)
190                                y= numpy.zeros(0)
191                               
192                            except:
193                                pass
194                           
195                        x  = numpy.append(x,   _x) 
196                        y  = numpy.append(y,   _y)
197                       
198                        if has_error_dy == True:
199                            #Delete the previously stored lines of data candidates if is not data.
200                            if i < 0 and -1< i1 < mum_data_lines and is_data== False:
201                                try:
202                                    dy = numpy.zeros(0) 
203                                except:
204                                    pass                                                               
205                            dy = numpy.append(dy, _dy)
206                           
207                        if has_error_dx == True:
208                            #Delete the previously stored lines of data candidates if is not data.
209                            if i < 0 and -1< i1 < mum_data_lines and is_data== False:
210                                try:
211                                    dx = numpy.zeros(0)                           
212                                except:
213                                    pass                                                               
214                            dx = numpy.append(dx, _dx)
215                           
216                        #Same for temp.
217                        #Delete the previously stored lines of data candidates if is not data.
218                        if i < 0 and -1< i1 < mum_data_lines and is_data== False:
219                            try:
220                                tx = numpy.zeros(0)
221                                ty = numpy.zeros(0)
222                            except:
223                                pass                                                               
224
225                        tx  = numpy.append(tx,   _x) 
226                        ty  = numpy.append(ty,   _y)
227                       
228                        if has_error_dy == True:
229                            #Delete the previously stored lines of data candidates if is not data.
230                            if i < 0 and -1<i1 < mum_data_lines and is_data== False:
231                                try:
232                                    tdy = numpy.zeros(0)
233                                except:
234                                    pass                                                                                                               
235                            tdy = numpy.append(tdy, _dy)
236                        if has_error_dx == True:
237                            #Delete the previously stored lines of data candidates if is not data.
238                            if i < 0 and -1< i1 < mum_data_lines and is_data== False:
239                                try:
240                                    tdx = numpy.zeros(0)
241                                except:
242                                    pass                                                                                                             
243                            tdx = numpy.append(tdx, _dx)
244
245                        #reset i1 and flag lentoks for the next
246                        if lentoks < new_lentoks :
247                            if is_data == False:
248                                i1 = -1                           
249                        #To remember the # of columns on the current line for the next line of data
250                        lentoks = len(toks)
251                       
252                        #Reset # of header lines and counts # of data candidate lines   
253                        if j == 0 and j1 ==0:
254                            i1 = i + 1                           
255                        i+=1
256                       
257                    except:
258
259                        # It is data and meet non - number, then stop reading
260                        if is_data == True:
261                            break   
262                        lentoks = 2
263                        #Counting # of header lines                   
264                        j+=1
265                        if j == j1+1:
266                            j1 = j                           
267                        else:                           
268                            j = -1
269                        #Reset # of lines of data candidates
270                        i = -1
271                       
272                        # Couldn't parse this line, skip it
273                        pass
274                   
275   
276                     
277                # Sanity check
278                if has_error_dy == True and not len(y) == len(dy):
279                    raise RuntimeError, "ascii_reader: y and dy have different length"
280                if has_error_dx == True and not len(x) == len(dx):
281                    raise RuntimeError, "ascii_reader: y and dy have different length"
282
283                # If the data length is zero, consider this as
284                # though we were not able to read the file.
285                if len(x)==0:
286                    raise RuntimeError, "ascii_reader: could not load file"
287               
288                #Let's re-order the data to make cal. curve look better some cases
289                ind = numpy.lexsort((ty,tx))
290                for i in ind:
291                    x[i] = tx[ind[i]]
292                    y[i] = ty[ind[i]]
293                    if has_error_dy == True:
294                        dy[i] = tdy[ind[i]]
295                    if has_error_dx == True:
296                        dx[i] = tdx[ind[i]]
297               
298               
299                #Data   
300                output.x = x
301                output.y = y
302                output.dy = dy if has_error_dy == True else None
303                output.dx = dx if has_error_dx == True else None
304               
305                if data_conv_q is not None:
306                    output.xaxis("\\rm{Q}", output.x_unit)
307                else:
308                    output.xaxis("\\rm{Q}", 'A^{-1}')
309                if data_conv_i is not None:
310                    output.yaxis("\\rm{Intensity}", output.y_unit)
311                else:
312                    output.yaxis("\\rm{Intensity}","cm^{-1}")
313                   
314                # Store loading process information
315                output.meta_data['loader'] = self.type_name   
316                   
317                return output
318           
319        else:
320            raise RuntimeError, "%s is not a file" % path
321        return None
322   
323if __name__ == "__main__": 
324    reader = Reader()
325    #print reader.read("../test/test_3_columns.txt")
326    print reader.read("../test/empty.txt")
327   
328   
329                       
Note: See TracBrowser for help on using the repository browser.