############################################################################ #This software was developed by the University of Tennessee as part of the #Distributed Data Analysis of Neutron Scattering Experiments (DANSE) #project funded by the US National Science Foundation. #If you use DANSE applications to do scientific research that leads to #publication, we ask that you acknowledge the use of the software with the #following sentence: #This work benefited from DANSE software developed under NSF award DMR-0520547. #copyright 2008, University of Tennessee ############################################################################# import numpy import os from DataLoader.data_info import Data1D # Check whether we have a converter available has_converter = True try: from data_util.nxsunit import Converter except: has_converter = False class Reader: """ Class to load ascii files (2, 3 or 4 columns). """ ## File type type_name = "ASCII" ## Wildcards type = ["ASCII files (*.txt)|*.txt", "ASCII files (*.dat)|*.dat", "ASCII files (*.abs)|*.abs"] ## List of allowed extensions ext=['.txt', '.TXT', '.dat', '.DAT', '.abs', '.ABS'] ## Flag to bypass extension check allow_all = True def read(self, path): """ Load data file :param path: file path :return: Data1D object, or None :raise RuntimeError: when the file can't be opened :raise ValueError: when the length of the data vectors are inconsistent """ if os.path.isfile(path): basename = os.path.basename(path) root, extension = os.path.splitext(basename) if self.allow_all or extension.lower() in self.ext: try: input_f = open(path,'r') except : raise RuntimeError, "ascii_reader: cannot open %s" % path buff = input_f.read() lines = buff.split('\n') #Jae could not find python universal line spliter: keep the below for now # some ascii data has \r line separator, try it when the data is on only one long line if len(lines) < 2 : lines = buff.split('\r') x = numpy.zeros(0) y = numpy.zeros(0) dy = numpy.zeros(0) dx = numpy.zeros(0) #temp. space to sort data tx = numpy.zeros(0) ty = numpy.zeros(0) tdy = numpy.zeros(0) tdx = numpy.zeros(0) output = Data1D(x, y, dy=dy, dx=dx) self.filename = output.filename = basename data_conv_q = None data_conv_i = None if has_converter == True and output.x_unit != '1/A': data_conv_q = Converter('1/A') # Test it data_conv_q(1.0, output.x_unit) if has_converter == True and output.y_unit != '1/cm': data_conv_i = Converter('1/cm') # Test it data_conv_i(1.0, output.y_unit) # The first good line of data will define whether # we have 2-column or 3-column ascii has_error_dx = None has_error_dy = None #Initialize counters for data lines and header lines. is_data = False #Has more than 5 lines mum_data_lines = 5 # More than "5" lines of data is considered as actual data unless that is the only data i=-1 # To count # of current data candidate lines i1=-1 # To count total # of previous data candidate lines j=-1 # To count # of header lines j1=-1 # Helps to count # of header lines lentoks = 2 # minimum required number of columns of data; ( <= 4). for line in lines: toks = line.split() try: #Make sure that all columns are numbers. for colnum in range(len(toks)): float(toks[colnum]) _x = float(toks[0]) _y = float(toks[1]) #Reset the header line counters if j == j1: j = 0 j1 = 0 if i > 1: is_data = True if data_conv_q is not None: _x = data_conv_q(_x, units=output.x_unit) if data_conv_i is not None: _y = data_conv_i(_y, units=output.y_unit) # If we have an extra token, check # whether it can be interpreted as a # third column. _dy = None if len(toks)>2: try: _dy = float(toks[2]) if data_conv_i is not None: _dy = data_conv_i(_dy, units=output.y_unit) except: # The third column is not a float, skip it. pass # If we haven't set the 3rd column # flag, set it now. if has_error_dy == None: has_error_dy = False if _dy == None else True #Check for dx _dx = None if len(toks)>3: try: _dx = float(toks[3]) if data_conv_i is not None: _dx = data_conv_i(_dx, units=output.x_unit) except: # The 4th column is not a float, skip it. pass # If we haven't set the 3rd column # flag, set it now. if has_error_dx == None: has_error_dx = False if _dx == None else True #After talked with PB, we decided to take care of only 4 columns of data for now. #number of columns in the current line #To remember the # of columns in the current line of data new_lentoks = len(toks) #If the previous columns not equal to the current, mark the previous as non-data and reset the dependents. if lentoks != new_lentoks : if is_data == True: break else: i = -1 i1 = 0 j = -1 j1 = -1 #Delete the previously stored lines of data candidates if is not data. if i < 0 and -1< i1 < mum_data_lines and is_data == False: try: x= numpy.zeros(0) y= numpy.zeros(0) except: pass x = numpy.append(x, _x) y = numpy.append(y, _y) if has_error_dy == True: #Delete the previously stored lines of data candidates if is not data. if i < 0 and -1< i1 < mum_data_lines and is_data== False: try: dy = numpy.zeros(0) except: pass dy = numpy.append(dy, _dy) if has_error_dx == True: #Delete the previously stored lines of data candidates if is not data. if i < 0 and -1< i1 < mum_data_lines and is_data== False: try: dx = numpy.zeros(0) except: pass dx = numpy.append(dx, _dx) #Same for temp. #Delete the previously stored lines of data candidates if is not data. if i < 0 and -1< i1 < mum_data_lines and is_data== False: try: tx = numpy.zeros(0) ty = numpy.zeros(0) except: pass tx = numpy.append(tx, _x) ty = numpy.append(ty, _y) if has_error_dy == True: #Delete the previously stored lines of data candidates if is not data. if i < 0 and -1