source: sasview/DataLoader/readers/ascii_reader.py @ 0b7bda7

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 0b7bda7 was 5f03524, checked in by Jae Cho <jhjcho@…>, 13 years ago

minor bug fix about dx length

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