source: sasview/sansdataloader/src/sans/dataloader/readers/ascii_reader.py @ 9cd0baa

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 9cd0baa was 9cd0baa, checked in by Jae Cho <jhjcho@…>, 12 years ago

fixed problem with non-asciis in the file

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