source: sasview/DataLoader/readers/ascii_reader.py @ 7d8094b

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 7d8094b was 3aed0eb, checked in by Jae Cho <jhjcho@…>, 15 years ago

cleaned up mess

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