#!/usr/bin/python2 """ AUTHOR: Michal Odstrcil 2012 Provide simple web interface for pygolem for data downloading """ from numpy import * import os, re, sys, time from scipy.signal import medfilt def fix_str(string, remove_latex = False): """ FIx the string to avoid any problems during plotting """ if isnone(string): return "" #print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" #print string, len(string) string = str(string) if remove_latex: string = re.sub('[\$\{\}]', "", string) return string if not re.match(".*\$.*", string): # hot fix of "latex font" if you can use $ solve it yourself for s in [r'\_', r'\^', r'\{', r'\}', r'\#', r'\%', r'<', r'>']: string = re.sub('([^\\\])'+s, r'\1'+s, string) return string def get_units(label): """ Exctract only the units from the ylabel full name """ if re.match(".*\[.+\]", label): label = re.sub("(.+)(\[.+\])", r"\2", label ) label = re.sub("[\[\]]", "", label ) label = fix_str(label, True) else: label = "" #label = re.sub("(.+)", r"[\1]", label ) return label ###################### SIMPLE DATA LOADING ############################## def saveconst(fname, const, fmt = "%g"): """ Save number `const` as text file `fname` param str fname: Name of saved file param scalar const: saved constant (or string) """ with open(fname, 'w') as fhandle: if not type(const) is str: fhandle.write( "%g\n" % const ) else: fhandle.write( "%s\n" % const ) def loadconst(fname, isfloat = True): """ Read number (or string) from file param str fname: Name of saved file """ with open(fname, 'r') as fhandle: const = fhandle.readline() try: assert isfloat return float(const) #return the raw string except: return re.sub('\n', '', const) # return as string !!! def cat(path, lines = [0], return_array = False): """ read file from `path` and return string. If there is several lines, it can return array if `return_array == True` """ try: with open(path, 'r') as f: content_tmp = f.readlines() if return_array: return content_tmp if len(lines) == 0: lines = range(len(content_tmp)) content = "" for i in lines: content += content_tmp[i] except: content = 'N/A' return content #return the raw string def loadSpectra(shot = None): """ Special function to load data stored in the spectrometry file """ from pygolem_lite import Shot DataFile = Shot(shot).exist('spectrometr:data') #DataFile = path+name+'.txt' if not os.path.isfile(DataFile): raise Exception('Data file '+DataFile+' does not exists.') Data = {} f = open(DataFile, 'r') line_header = 0 for i,line in enumerate(f): line_header +=1 ind = line.find('Serial Number') if ind != -1: SN = line[ind+15:-1] ind = line.find('Date and time (GMT)') #if ind != -1: #Data['time'] = mktime(strptime(line[ind+21:-1])) ind = line.find('Number of spectra') if ind != -1: Data['n_spectra'] = int(line[ind+19:-1]) ind = line.find('Resolution') if ind != -1: Data['n_pixels'] = int( line[ind+16:-1]) ind = line.find('Integration time [ms]') if ind != -1: Data['integ_time'] = float(line[ind+22:-1]) ind = line.find('Board temperature [C]') if ind != -1: Data['temperature'] = float(line[ind+22:-1]) ind = line.find('Time stamps [ms]') if ind != -1: s = line[ind+18:-1] Data['time_stamps'] = float_(s.strip('[]').split()) ind = line.find('Noise RMS') if ind != -1: Data['readoutNoiseRMS'] = float(line[ind+20:-1]) if line.find('***************') != -1: break f.close() if Data['readoutNoiseRMS'] > 10:#probably failura in the calculation Data['readoutNoiseRMS'] = 10 #t0 = time.time() f = open(DataFile, 'r') data = genfromtxt(f,skip_header=line_header) f.close() #print "time", time.time() - t0 Data['wavelength'] = data[:,0] Data['spectrum'] = data[:,1:] return Data ####################### OTHER USEFUL ROUTINES #################################x def nanmedian(data): return median(data[~isnan(data)]) def list2array(L): """ convert list output from pygolem to array / scalar """ if type(L) is not list and type(L) is not tuple : return L if ndim(L[1]) == 1: dim = 1 else: dim = size(L[1],1) out = empty([len(L[0]), dim+1]) out[:,0] = L[0] out[:,1:] = reshape(L[1], (-1, dim)) return out def isnone(data): """ Simple function to check if input is None """ if data is None: return True if type(data) is ndarray: if ndim(data) == 0: return data.item() is None else: return data == array([None]) if type(data) is list or type(str) is tuple: return [ data[i] is None for i in range(len(data)) ] else: return False def find_data(fname): """ Test if file fname exists and return path, otherwise False """ end_list = [ '', '.npz', '.npy', '.gz', '.csv', '.lvm', '.txt', '_dp.csv' ] for end in end_list: if os.path.exists(fname + end): return fname + end return False def read_config(path, file = ""): """Read data configuration from the fileobject and return it as a dictionary""" try: data_types = load(path+file+'.npy').item() # speed-up except: import ConfigParser from collections import OrderedDict config = ConfigParser.RawConfigParser() data_types = OrderedDict() config.readfp(open(path+file, 'r')) for data_type in config.sections(): data_types[data_type.lower()] = dict(config.items(data_type)) # data_type is not case sensitive try: save(path+file, data_types ) # save for faster loading next time.. except: pass return data_types def check_data_config(config): """ Check that all items in config contains obligatory items """ items = sort( array(['identifier', 'datadir', 'name', 'type','ylabel'])) for key in config.keys(): items_tmp = sorted(array( config[key].keys() )) if any(~in1d(items, items_tmp)): print "Error" , key, 'missing item', items[~in1d(items, items_tmp)] print "Item " + key + " is removed from config !!! " config.pop(key) # remove key from data set !!! return config def unique_ind(ind_new, ind_orig): """ Return intersection of sets as sorted indices """ #return where(in1d(ind_1,ind_2))[0] ind = zeros(len(ind_orig)) for i in range(len(ind_orig)): ind[i] = where(ind_new == ind_orig[i])[0][0] return int_(ind) #### mathematical ================ def smooth(data, ker_size): """ Use gausian kernel for smoothing """ data = copy(data) from scipy.signal import fftconvolve kernel = linspace(-3, 3, 2*ceil(ker_size/2)+1) kernel = exp(-kernel**2) kernel /= sum(kernel) if ndim(data) ==1: data = data[:,None] for i in range(size(data,1)): ind = ~isnan(data[:,i]) data[ind,i] = medfilt(data[ind,i], max(3,2*ceil(ker_size/4)+1) ) # remove outliers p = polyfit(where(ind)[0], data[ind,i], 1) data[ind,i] -= polyval(p, where(ind)[0]) data[ind,i] = fftconvolve(data[ind,i], kernel, mode="same") data[ind,i] += polyval(p, where(ind)[0]) return squeeze(data)