p[0] = offset p[1] = ea p[2] = 1 p[3] = 1 p[4] = 0 #retrieve function for Appearance Energy - the alpha is None if not specified, hence returning a function with alpha fit-able #ae_func = fl.get_AE_func(sigma, alpha, linearbackground) sigma = fwhm / (2*sqrt(2*np.log(2))) ae_func = fl.AE_func(alpha, offsetfixed, linearbackground) ae_func = eval(ae_func) #actually fit p1 = fl.fit_function_to_data(data, ae_func, p) #log success if p1 is not None: log.write('============================') log.write('Fitted file %s with success.' % file[0]) log.AE_fit_p(p1, alpha, minfit, maxfit, linearbackground, fwhm, offsetfixed) else: log.write('Failed with fitting of file %s.' % file[0]) #we need to create a more speaking filename additions = '' additions += '_fwhm=%s' % str(fwhm) if alpha is not None:
def do_SF6_calibration(filelist, showplots = True, quadratic = True, outputfile = 'SF6_cal.pdf'): #this is tricky. we don't need to set the backed to PDF here before importing, because fitlib does that import matplotlib import matplotlib.pyplot as plt import fitlib as fl #instanciate a log object log = loglib.Log(tovariable = True) #define empty list of peaks used for calibration calpeaks = [] #pattern to match something like nES_SF6_bla.ee fn_pattern = re.compile('/nES_([A-Z]{1}[a-z]?)+[1-9]*_.*\.ee$') #set information for typical calibration peaks #dictionary with index fragmentname #data-structure: [[listofpeaksvalues], [actualpeakvalues], [fit parameters], [peak search offset], [peak search end]] #actualpeakvalues are set to 0 in the beginning frag_info = {'SF6': [[0.0], [0], [], None, [7.0]], 'SF5': [[0.1], [0], [], None, [7.0]], 'F': [[5.5, 9.0, 11.5], [0, 0, 0], [], [5.0], [16.0]], 'F2': [[4.625, 11.49], [0,0], [], None, [15.0]]} #for plot numbering i = 1 fitdata = [] fig1 = plt.figure() for file in filelist: if fn_pattern.search(file): badfile = False log.write(file) #read the file try: data = hl.readfile(file) except IOError: badfile = True log.write('Could not read the file: ' + file) #get rid of path (basename), then split by underscores. #we only want the second part of the filename (e.g. SF6) -> [1] fragment = os.path.basename(file).split('_')[1] # is that a proper fragment? if fragment not in frag_info: badfile = True log.write('Unknown fragment: ' + fragment) #fit the file if we can read it and if we know the fragment if badfile is False: log.write('Now dealing with fragment: ' + fragment) #guess peaks peaks = fl.guess_ES_peaks(data, len(frag_info[fragment][0]), offset = frag_info[fragment][3], limit = frag_info[fragment][4]) log.write('Result of peak guessing: ' + str(peaks)) #use guessed values to fit; return peak list to frag_info and add fit function parameters to frag_info if fragment is 'F': frag_info[fragment][1], frag_info[fragment][2] = fl.fitES(data, peaks, True) else: frag_info[fragment][1], frag_info[fragment][2] = fl.fitES(data, peaks) n = 0 for peakpos in frag_info[fragment][1]: fitdata.append([peakpos, frag_info[fragment][0][n]]) n += 1 #only plot if we actually had the file (fit parameter is still of type 'list' if this is the case) if type(frag_info[fragment][2]) is not list: plt.subplot(3,2,i) fl.plotES(data, fragment) # the /3 stems from the fact that the function takes the number of peaks, not parameters if fragment is 'F': fl.plot_fit(data, fl.gaussfunctions(3, True), frag_info[fragment][2]) else: fl.plot_fit(data, fl.gaussfunctions(len(frag_info[fragment][2])/3), frag_info[fragment][2]) i = i + 1 #now we fitted all the calibration scans and have an array with peaks in frag_info log.emptyline() log.write('Raw data of the fits: ' + str(frag_info)) log.emptyline() #convert to numpy array fitdata = array(fitdata, dtype = float) #quadratic or linear? if quadratic is True: fitfunc = lambda p, x: p[0] + p[1]*x + p[2]*x**2 p = [1]*3 else: fitfunc = lambda p, x: p[0] + p[1]*x p = [0]*2 p[0] = 2 p[1] = 1 #we fit the peak positions as they are with where they should be print fitdata parameters = fl.fit_function_to_data(fitdata, fitfunc, p) log.emptyline() log.write('Fitted and received the following parameters: ' + str(parameters)) if quadratic is True: log.write('Fit function is therefore y = %f + %f*x + %f*x^2' % (parameters[0], parameters[1], parameters[2])) else: log.write('Fit function is therefore y = %f + %f*x' % (parameters[0], parameters[1])) plt.subplot(3, 2, 5) plt.plot(fitdata[:,0], fitdata[:,1], 'bo') plt.xlabel('Measured') plt.ylabel('Corrected') plt.grid(True) plt.title('Calibration function') fl.plot_fit(fitdata, fitfunc, parameters) # plt.tight_layout() if showplots is True: plt.show() plt.savefig(outputfile) return parameters, log.logcontent