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

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 ecc58e72 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
RevLine 
[8bd8ea4]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
[daa56d0]15# Check whether we have a converter available
[99d1af6]16has_converter = True
17try:
18    from data_util.nxsunit import Converter
19except:
20    has_converter = False
21
[8bd8ea4]22class Reader:
23    """
[730c9eb]24        Class to load ascii files (2, 3 or 4 columns)
[8bd8ea4]25    """
[8780e9a]26    ## File type
[28caa03]27    type_name = "ASCII"
28   
29    ## Wildcards
[8780e9a]30    type = ["ASCII files (*.txt)|*.txt",
[470bf7e]31            "ASCII files (*.dat)|*.dat",
32            "ASCII files (*.abs)|*.abs"]
[8bd8ea4]33    ## List of allowed extensions
[470bf7e]34    ext=['.txt', '.TXT', '.dat', '.DAT', '.abs', '.ABS'] 
[8bd8ea4]35   
[e082e2c]36    ## Flag to bypass extension check
37    allow_all = True
38   
[8bd8ea4]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)
[e082e2c]51            if self.allow_all or extension.lower() in self.ext:
[8bd8ea4]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')
[470bf7e]58               
[892f246]59                #Jae could not find python universal line spliter: keep the below for now
[730c9eb]60                # some ascii data has \r line separator, try it when the data is on only one long line
[470bf7e]61                if len(lines) < 2 : 
62                    lines = buff.split('\r')
63                 
[8bd8ea4]64                x  = numpy.zeros(0)
65                y  = numpy.zeros(0)
66                dy = numpy.zeros(0)
[de1da34]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)
[8bd8ea4]76                self.filename = output.filename = basename
[99d1af6]77           
78                data_conv_q = None
79                data_conv_i = None
80               
[ca10d8e]81                if has_converter == True and output.x_unit != '1/A':
82                    data_conv_q = Converter('1/A')
[99d1af6]83                    # Test it
84                    data_conv_q(1.0, output.x_unit)
85                   
[ca10d8e]86                if has_converter == True and output.y_unit != '1/cm':
87                    data_conv_i = Converter('1/cm')
[99d1af6]88                    # Test it
89                    data_conv_i(1.0, output.y_unit)
90           
[8bd8ea4]91               
92                # The first good line of data will define whether
93                # we have 2-column or 3-column ascii
[de1da34]94                has_error_dx = None
95                has_error_dy = None
[8bd8ea4]96               
[892f246]97                #Initialize counters for data lines and header lines.
[0e5e586]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
[892f246]100
[d508be9]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).
[892f246]106               
[8bd8ea4]107                for line in lines:
108                    toks = line.split()
[892f246]109                   
[8bd8ea4]110                    try:
[892f246]111                       
[8bd8ea4]112                        _x = float(toks[0])
113                        _y = float(toks[1])
114                       
[892f246]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
[d508be9]122                       
[99d1af6]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                       
[8bd8ea4]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])
[99d1af6]136                               
137                                if data_conv_i is not None:
138                                    _dy = data_conv_i(_dy, units=output.y_unit)
139                               
[8bd8ea4]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.
[de1da34]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
[892f246]166                       
[d508be9]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
[0e5e586]169                        #To remember the # of columns in the current line of data
170                        new_lentoks = len(toks)
[d508be9]171                       
[3aed0eb]172                        #If the previous columns not equal to the current, mark the previous as non-data and reset the dependents. 
[272b107]173                        if lentoks != new_lentoks :
174                            if is_data == True:
175                                break
176                            else:
[d508be9]177                                i = -1
178                                i1 = 0
179                                j = -1
180                                j1 = -1
181                           
[272b107]182                           
[892f246]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                           
[8bd8ea4]192                        x  = numpy.append(x,   _x) 
193                        y  = numpy.append(y,   _y)
[892f246]194                       
[de1da34]195                        if has_error_dy == True:
[892f246]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                                                               
[8bd8ea4]202                            dy = numpy.append(dy, _dy)
[892f246]203                           
[de1da34]204                        if has_error_dx == True:
[892f246]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                                                               
[de1da34]211                            dx = numpy.append(dx, _dx)
212                           
213                        #Same for temp.
[892f246]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
[de1da34]222                        tx  = numpy.append(tx,   _x) 
223                        ty  = numpy.append(ty,   _y)
[892f246]224                       
[de1da34]225                        if has_error_dy == True:
[892f246]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                                                                                                               
[de1da34]232                            tdy = numpy.append(tdy, _dy)
233                        if has_error_dx == True:
[892f246]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                                                                                                             
[de1da34]240                            tdx = numpy.append(tdx, _dx)
[d508be9]241
242                        #reset i1 and flag lentoks for the next
243                        if lentoks < new_lentoks :
244                            if is_data == False:
245                                i1 = -1                           
[0e5e586]246                        #To remember the # of columns on the current line for the next line of data
247                        lentoks = len(toks)
[8bd8ea4]248                       
[892f246]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                       
[8bd8ea4]254                    except:
[892f246]255
256                        # It is data and meet non - number, then stop reading
257                        if is_data == True:
258                            break   
[d508be9]259                        lentoks = 2
[892f246]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                       
[8bd8ea4]269                        # Couldn't parse this line, skip it
270                        pass
[892f246]271                   
272   
[8bd8ea4]273                     
274                # Sanity check
[de1da34]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):
[daa56d0]278                    raise RuntimeError, "ascii_reader: y and dy have different length"
[8bd8ea4]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:
[daa56d0]283                    raise RuntimeError, "ascii_reader: could not load file"
[de1da34]284               
[470bf7e]285                #Let's re-order the data to make cal. curve look better some cases
[de1da34]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]]
[892f246]294               
[d508be9]295               
[892f246]296                #Data   
[8bd8ea4]297                output.x = x
298                output.y = y
[de1da34]299                output.dy = dy if has_error_dy == True else None
300                output.dx = dx if has_error_dx == True else None
301               
[99d1af6]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:
[0e2aa40]307                    output.yaxis("\\rm{Intensity}", output.y_unit)
[99d1af6]308                else:
[0e2aa40]309                    output.yaxis("\\rm{Intensity}","cm^{-1}")
[8bd8ea4]310                return output
[892f246]311           
[8bd8ea4]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.