source: sasview/DataLoader/readers/ascii_reader.py @ 330c63b

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 330c63b was fca90f82, checked in by Jae Cho <jhjcho@…>, 14 years ago

put zeros for dx,dy when no errs are given: asked by Mathieu

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