Ejemplo n.º 1
0
def fit_Voigt_and_step(x_lst,y_lst,x_min_flt,x_max_flt, pre, width_1, width_2, print_all_fits_bool,place_to_save_str):
    '''
    x_lst = x axis
    y_lst = spectra to fit
    first = beginning of fitting regions
    last = end of fitting region
    print_all_fits = Bool, do you want to save all plots
    place_to_save = string that is the filename where we're saving the data
    
    returns result object
    
    '''

    # Restrict the fit
    x_bkp = x_lst
    y_bkp = y_lst
    
    x_lst, y_lst, y_p, ypp = smooth_and_remove_step(x_lst, y_lst, x_min_flt, x_max_flt,True)
    
    '''
    *******************************************************
    Section of bad code that it'd take too long to do right
    *******************************************************
    '''
    step_at = 95
    step_width = 10
    prefp = pre
    prefs = "stp"
    prefc = 'c'    
    w_guess = 3 # sigma
    '''
    *******************************************************
    Section of bad code that it'd take too long to do right
    *******************************************************
    '''
    
    # this is the money
    # defines the model that'll be fit
    peak = VoigtModel(prefix = prefp, independent_vars=['x'],nan_policy='raise')
    step = StepModel(prefix = prefs, independent_vars=['x'],form='logistic')
    const = ConstantModel(prefix = prefc,independent_vars=['x'], nan_policy='raise', form ='logistic')
    
    mod = peak + step + const
    #mod = peak + const
    
    # guess parameters
    x_max = x_lst[np.argmax(y_lst)]
    y_max = y_lst[np.argmax(y_lst)]
    
    # Peak
    # here we set up the peak fitting guess. Then the peak fitter will make a parameter object out of them
    mod.set_param_hint(prefp+'amplitude', value = value_max*y_max, min = .6*value_max_min*y_max,max = 4*value_max_max*y_max, vary=True)
    # mod.set_param_hint(prefp+'center', value = x_max, min = x_max*(1-wiggle_room), max = x_max*(1+wiggle_room),vary=True)
    mod.set_param_hint(prefp+'center', value = x_max,min = x_max*.97, max = x_max*1.03, vary=True)
    
     # Basically FWHM/3.6
    if pre =='one':     # fitting with only one peak
        mod.set_param_hint(prefp+'sigma', value = width_1, min = .25*width_2, max = 2*width_1,vary=True)
    else:               # fitting with two peaks
        mod.set_param_hint(prefp+'sigma', value = width_2, min = 0, max = width_1,vary=True)
    
    # Constant
    top = []
    bottom = []
    for a,b in zip(x_lst,y_lst):
        if a > 135:
            top.append(b)
        elif a < 93:
            bottom.append(b)
    top = np.mean(np.asarray(top))
    bottom = np.mean(np.asarray(bottom))
            
    mod.set_param_hint(prefc+'c', value = bottom, min = -3*bottom, max = 3*bottom,vary=True)
    
    # restrict the fit again
    x_fit = []
    y_fit = []
    for a,b in zip(x_lst,y_lst):
        if 80 < a < 135:
            x_fit.append(a)
            y_fit.append(b)
    top = y_fit[0]
    bottom = y_fit[-1]
    
    # Step
    # Step height
    delta = 2*abs(top - bottom)
    if delta == 0:
        delta = 1
    mod.set_param_hint(prefs+'amplitude', value = delta, min = -3*delta, max = 3*delta, vary=True)
    # Charastic width
    mod.set_param_hint(prefs+'sigma', value = 3,min = 1, max = 3, vary=False)
    # The half way point... 
    mod.set_param_hint(prefs+'center', value = step_at, min = step_at-step_width, max = step_at+step_width, vary = False)
    
    result = mod.fit(y_fit, x=x_fit, params = mod.make_params())
    
    # If print all fits ... 
    if print_all_fits_bool:
        x_dense = np.arange(x_min_flt,x_max_flt,(x_max_flt-x_min_flt)/300.0).tolist()
        
        # each component
        for x in result.best_values:
            if prefp in x:      # Get peak
                peak.set_param_hint(x, value = result.best_values[str(x)])
            elif prefs in x:    # Get step
                step.set_param_hint(x, value = result.best_values[str(x)])
        
        # Data - 'background' 
        y_m_background = []
        for a,b in zip(x_lst,y_lst):
            y_m_background.append(b - result.eval(x=a) + peak.eval(x=a,  params=peak.make_params()))
        
        peak_only = [peak.eval(x=yy, params=peak.make_params()) for yy in x_dense]
        #stp_only = [result.best_values['stpamplitude'] + result.best_values['cc']]*len(x_dense)
        # sum of them
        #y_fit = [a+b for a,b in zip(peak_only,stp_only)]
        y_fit = [a+b for a in peak_only]
        
        plt.plot(x_dense,peak_only, 'g', label = 'Peak Only')
        #plt.plot(x_dense,stp_only, 'g--', label = None)
        #plt.plot(x_dense, y_fit, 'g', label = "Fit Result")        
        
        plt.plot(x_lst,y_lst,'bx', label= "Data")
        plt.plot(x_lst,y_m_background,'ko', label= "Data-Background")
        
        plt.title("Fit vs Data")
        plt.xlabel("Inv Cm")
        plt.ylabel("counts")
        plt.legend()
        plt.savefig(place_to_save_str+"Voigt&Step")
        plt.clf()    
    
    return result
Ejemplo n.º 2
0
def fit_Voigt_and_step(x_lst,y_lst,x_min_flt,x_max_flt,print_all_fits_bool,place_to_save_str):
    '''
    x_lst = x axis
    y_lst = spectra to fit
    first = beginning of fitting regions
    last = end of fitting region
    print_all_fits = Bool, do you want to save all plots
    place_to_save = string that is the filename where we're saving the data
    
    '''
    import numpy as np
    # for smoothing the curves
    import scipy.interpolate as interp #import splev 
    
    from lmfit.models import VoigtModel, StepModel, ConstantModel
    from lmfit import CompositeModel
    
    # Restrict the fit
    x_fit = []
    y_fit = []
    
    for x,y in zip(x_lst, y_lst):
        if x_min_flt < x < x_max_flt:
            x_fit.append(float(x))
            y_fit.append(float(y))
    
    x_fit = np.asarray(x_fit)
    y_fit = np.asarray(y_fit)   
    
    # now we find the parameters using the - d^2/dx^2
    ysmooth = interp.interp1d(x_fit, y_fit, kind='cubic')
    # differentiate x 2
    yp = np.gradient(ysmooth(x_fit))
    ypp = np.gradient(yp)
    # we want the peaks of -d2/dx2 
    ypp = np.asarray([-x for x in ypp])
    
    '''
    *******************************************************
    Section of bad code that it'd take too long to do right
    *******************************************************
    '''
    step_at = 100
    step_width = 3
    prefp = "one"
    prefs = "stp"
    prefc = 'c'    
    w_guess = 3 # sigma
    '''
    *******************************************************
    Section of bad code that it'd take too long to do right
    *******************************************************
    '''
    
    # this is the money
    # defines the model that'll be fit
    peak = VoigtModel(prefix = prefp, independent_vars=['x'],nan_policy='raise')
    step = StepModel(prefix = prefs, independent_vars=['x'], nan_policy='raise')
    const = ConstantModel(prefix = prefc,independent_vars=['x'], nan_policy='raise', form ='logistic')
    
    mod = peak + step + const
    
    # guess parameters
    x_max = x_fit[np.argmax(y_fit)]
    y_max = y_fit[np.argmax(y_fit)]
    
    # Peak
    # here we set up the peak fitting guess. Then the peak fitter will make a parameter object out of them
    mod.set_param_hint(prefp+'amplitude', value = 4*y_max, min = y_max,max = 30*y_max, vary=True)
    # mod.set_param_hint(prefp+'center', value = x_max, min = x_max*(1-wiggle_room), max = x_max*(1+wiggle_room),vary=True)
    mod.set_param_hint(prefp+'center', value = x_max, vary=True)
    # Basically FWHM/3.6
    mod.set_param_hint(prefp+'sigma', value = w_guess, min = 0, max = 5*w_guess,vary=True)
    
    # Step
    # Step height
    delta = abs(y_fit[-1]-y_fit[0])
    mod.set_param_hint(prefs+'amplitude', value = delta, min = delta*.9, max = delta*1.1, vary=True)
    # Charastic width
    mod.set_param_hint(prefs+'sigma', value = 2,min = 1, max = 3, vary=True)
    # The half way point... 
    mod.set_param_hint(prefs+'center', value = step_at, min = step_at-step_width, max = step_at+step_width, vary = True)
    
    # Constant
    mod.set_param_hint(prefc+'c', value = y_fit[-1], min = 0, max = 2*y_fit[0],vary=True)    
    
    result = mod.fit(y_fit, x=x_fit, params = mod.make_params())
    
    # If print all fits ... 
    if print_all_fits_bool:
        x_dense = np.arange(x_min_flt,x_max_flt,(x_max_flt-x_min_flt)/300.0).tolist()
        
        result.plot_fit(xlabel='Inv Cm', ylabel='counts',datafmt = 'xb', numpoints=len(x_fit)*10)
        
        for x in result.best_values:
            if prefp in x:      # Get peak
                peak.set_param_hint(x, value = result.best_values[str(x)])
            elif prefs in x:    # Get step
                step.set_param_hint(x, value = result.best_values[str(x)])
        
        comp = [result.best_values['cc'] + peak.eval(x=yy, params=peak.make_params()) for yy in x_dense]
        plt.plot(x_dense,comp, 'green', label = None)
        
        comp = [result.best_values['stpamplitude'] + result.best_values['cc']]*len(x_dense)
        plt.plot(x_dense, comp, 'green', label= None)
        
        # comp = [result.best_values['cc'] + step.eval(x=yy, params=step.make_params()) for yy in x_dense]
        # plt.plot(x_dense, comp, 'green', label= None)
        
        plt.title("Fit vs Data")
        plt.legend()
        plt.savefig(place_to_save_str)
        plt.clf()    
    
    return result.best_values