Beispiel #1
0
def create_xrf_line(x, params, linedict, linefunc):
    funcmodel = Model(linefunc)
    # start with the function parameters...
    funcparams = funcmodel.make_params()
    #
    # copy the function based parameters from params to funcparams
    #
    for key in params:
        if key in funcparams:
            funcparams[key].value = params[key].value
            funcparams[key].min = params[key].min
            funcparams[key].max = params[key].max
            funcparams[key].vary = params[key].vary
    result = np.zeros_like(x)
    sigma_keys = [s for s in funcparams.keys() if 'sigma' in s]

    for key, linegroup in linedict.iteritems():
        if key in params:
            for line in linegroup:
                # update funcparams
                funcparams["area"].value   = params[key].value*\
                                             line.intensity
                funcparams["center"].value = line.line_energy
                for ii in sigma_keys:
                    funcparams[ii].value = np.sqrt(params[ii].value**2 + \
                             (line.line_energy*0.001))
                result = result + funcmodel.eval(funcparams, x=x)

    return result
Beispiel #2
0
def lmDDOPhaseFit(xdata, ydata, params, f0_range = 1.2, Q_range = 3):    
    f0= params[0]
    Q=1/(2*params[2])
    
    x = xdata
    y = ydata
#Define a linear model and a Damped Oscillator Model    
#    ddophase_mod = ExpressionModel('off + m*x- arctan(1/Q * 1/(f0/x - x/f0))-')
    ddophase_mod = Model(phase)
#Initial Pars for Linear Model
    pars =  ddophase_mod.make_params(off=0, m=0, f0=f0, Q=Q)

#Add fit parameters, Center, Amplitude, and Sigma
    pars['f0'].set(min=f0/f0_range, max=f0*f0_range)
    pars['Q'].set(min=Q/Q_range, max=Q*Q_range)
#Create full model. Add linear model and all peaks
#Initialize fit
    init = ddophase_mod.eval(pars, x=x)
#Do the fit. The weight exponential can weight the points porportional to the
#amplitude of y point. In this way, points on peak can be given more weight.     
    out=ddophase_mod.fit(y, pars,x=x)
#Get the fit parameters
    fittedf0= out.params['f0'].value
    fittedQ = out.params['Q'].value
#Returns the output fit as well as an array of the fit parameters
    """Returns output fit as will as list of important fitting parameters"""
    return out, [fittedf0, np.nan, np.nan, fittedQ]
Beispiel #3
0
def lmDDOPhaseFit(xdata, ydata, params, f0_range=1.2, Q_range=3):
    f0 = params[0]
    Q = 1 / (2 * params[2])

    x = xdata
    y = ydata
    #Define a linear model and a Damped Oscillator Model
    #    ddophase_mod = ExpressionModel('off + m*x- arctan(1/Q * 1/(f0/x - x/f0))-')
    ddophase_mod = Model(phase)
    #Initial Pars for Linear Model
    pars = ddophase_mod.make_params(off=0, m=0, f0=f0, Q=Q)

    #Add fit parameters, Center, Amplitude, and Sigma
    pars['f0'].set(min=f0 / f0_range, max=f0 * f0_range)
    pars['Q'].set(min=Q / Q_range, max=Q * Q_range)
    #Create full model. Add linear model and all peaks
    #Initialize fit
    init = ddophase_mod.eval(pars, x=x)
    #Do the fit. The weight exponential can weight the points porportional to the
    #amplitude of y point. In this way, points on peak can be given more weight.
    out = ddophase_mod.fit(y, pars, x=x)
    #Get the fit parameters
    fittedf0 = out.params['f0'].value
    fittedQ = out.params['Q'].value
    #Returns the output fit as well as an array of the fit parameters
    """Returns output fit as will as list of important fitting parameters"""
    return out, [fittedf0, np.nan, np.nan, fittedQ]
Beispiel #4
0
def FitCurve(func, xdata, ydata):
    ''' Fit data to a function form '''
    fmodel = Model(func)
    params = fmodel.make_params(Psi_1=1, Psi_2=0, N=640, AAAvgVol=10648)
    params['N'].vary = False
    params['AAAvgVol'].vary = False
    results = fmodel.fit(ydata, params, x=xdata)
    y = fmodel.eval(x=xdata, params=results.params)
    #parameters_opt, parameter_covariance = curve_fit(func,xdata,ydata)
    return results, ydata
Beispiel #5
0
def simple_echo_fits():
    """
    Takes the highest point of each echo and fits the echo_as_T2 function to those points.
    """
    xrs, yrs, xr, yr, filename, dat1 = range_to_list()
    length = len(yrs)
    max_y = [np.max(yrs[i]) for i in range(length)]
    max_y_loc = [np.where(yrs[i] == max_y[i])[0][0] for i in range(length)]
    cents = [xrs[i][max_y_loc[i]] for i in range(length)]
    heights = max_y
    # TODO: Find a better value for the uncertainty on y-values.
    heights = np.array(heights)
    cents = np.array(cents)
    maxy = np.max(heights)
    miny = np.min(heights)
    decay_pos = np.where(heights == find_nearest(heights, maxy / e))[0][0]
    decay_pos_time = cents[decay_pos]
    avg_y_sep = abs(np.mean(np.diff(heights)))
    efit = Model(echo_as_T2)
    print(efit, echo_as_T2)
    param = efit.make_params()
    param.add('M0', value=maxy, min=maxy * 0.5, max=maxy + (avg_y_sep * 5))
    param.add('T2', value=decay_pos_time, min=decay_pos_time * 0.1, max=decay_pos_time * 2.5)
    if miny != 0:
        param.add('c', value=miny * 0.3, min=miny * 0.1, max=miny * 2.2)
    param.add('ph', value=cents[0] * 0.5, min=0, max=cents[0] * 2)
    param.add('m1', value=0.1)
    param.add('m', value=1)
    result_2 = efit.fit(heights, param, t=cents, method='leastsq', weights=np.mean(np.diff(dat1['T'])) / heights)
    print(result_2.fit_report())
    print('\n', result_2.params.pretty_print())
    ax = plt.gca()
    ax.set_xlabel('Time (us)', fontsize=14)
    ax.set_ylabel('Voltage (V)', fontsize=14)
    xes = np.linspace(np.min(cents), np.max(cents), 100)
    y = efit.eval(t=xes, params=result_2.params)
    plt.plot(xes, y, antialiased=True)
    plt.plot(cents, heights, 'x', ms=8, color='k')
    plt.plot(dat1['V'], dat1['T'], lw=2, antialiased=True,
             color='#4a4a4a', zorder=1)
    plt.title(filename)
    plt.xlim(left=0, right=np.max(cents) * 1.1)
    # plt.ylim(bottom=0, top=result_2.params['M0'].value * 1.1)
    plt.axhline(result_2.params['M0'].value, color='k', ls='--', alpha=0.7, lw=1, zorder=2)
    plt.axhline(result_2.params['M0'].value / e, color='k', ls='--', alpha=0.7, lw=1, zorder=2)
    plt.text(0.9, 0.9, "T_1: {:.4f} us".format(result_2.params['T2'].value), horizontalalignment='center',
             verticalalignment="center",
             transform=ax.transAxes,
             bbox={'pad': 8, 'fc': 'w'}, fontsize=14)
    plt.tight_layout()
    plt.tick_params(axis='both', which='major', labelsize=13)
    fig_manager = plt.get_current_fig_manager()
    fig_manager.window.showMaximized()
    plt.show()
Beispiel #6
0
    def draw_model_fit(self, path, wavelength, flux):
        """ Generate the gauss model, draw the model results based on x value range
        and update the table that shows the results parameters"""
        self.__quadraticDeque.append(1)

        for i, key in enumerate(self.__quadraticDict.keys()):
            self.__quadraticDict[key] = self.__quadraticDeque[i]

        #Obtain the wavelength values on given range
        wavelengthValues = wavelength[
            (wavelength >= self.__quadraticDict['left'][0])
            & (wavelength <= self.__quadraticDict['right'][0])]
        #Obtain de indexes from the initial wavelength array
        #based on the min a max values of the slice made previously
        index1 = np.where(wavelength == np.amin(wavelengthValues))
        index2 = np.where(wavelength == np.amax(wavelengthValues))
        #Obtain the flux values between the indexes obtained previously
        fluxValues = flux[index1[0][0]:(index2[0][0] + 1)]
        quadratic_model = Model(quadratic_fitting_function, name='model1')

        slope = calculate_slope(self.__quadraticDict['left'][0],
                                self.__quadraticDict['left'][1],
                                self.__quadraticDict['right'][0],
                                self.__quadraticDict['right'][1])

        inital_y_values = self._generate_initial_quadratic_model(
            wavelengthValues,
            calculate_intercept(slope, self.__quadraticDict['left'][0],
                                self.__quadraticDict['left'][1]), slope)

        params = quadratic_model.make_params(a=calculate_intercept(
            slope, self.__quadraticDict['left'][0],
            self.__quadraticDict['left'][1]),
                                             b=slope)

        init = quadratic_model.eval(params, x=wavelengthValues)
        result = quadratic_model.fit(fluxValues, params, x=wavelengthValues)

        #Update table of results parameters
        resultText = "Path: {}".format(path)
        resultText = resultText + "\n" + \
            "Quadratic model: {} + {} * x + {} * x**2".format(str(result.params['a'].value), str(result.params['b'].value), str(result.params['c2'].value))

        quadraticFitResultList = [
            key + " = " + str(result.params[key].value)
            for key in result.params
        ]

        for resultParams in quadraticFitResultList:
            resultText = resultText + "\n" + resultParams
        resultText = resultText + "\n" + "Chi-square" + " = " + str(
            result.chisqr)

        return result, resultText, wavelengthValues, fluxValues, inital_y_values, None
Beispiel #7
0
class erf_model():
    def __init__(self, params0=[1, 1, 1], fixedParams0=[False, False, False]):
        assert (len(params0) == 3)
        assert (len(fixedParams0) == 3)

        self.model = Model(self.erf_curve)
        self.modelResult = None

        self.param_names = self.model.param_names
        self.params = self.model.make_params()
        for i in range(len(self.param_names)):
            param_name = self.param_names[i]
            self.params[param_name].value = params0[i]
            self.params[param_name].vary = not fixedParams0[i]

    # t is an array of time points []
    def predict(self, t_eval):
        return self.model.eval(self.params, t=t_eval)

    # return a matrix with 9 quantiles
    def predict_with_quantiles(self, t_eval):
        quantiles = [10, 20, 30, 40, 50, 60, 70, 80,
                     90]  # 9 different quantiles
        y_pred_lst = self.predict(t_eval)

        y_pred_quantiles_lst = []
        for y_pred in y_pred_lst:
            y_pred_quantiles = [y_pred for i in range(len(quantiles))]
            y_pred_quantiles_lst.append(y_pred_quantiles)
        return y_pred_quantiles_lst

    # params must have logp, a, b
    def erf_curve(self, t, logp, a, b):
        p = 10**logp
        pred_y = p / 2 * (1 + erf(a * (t - b)))
        return pred_y

    # predicts a time window, inclusive
    def predict_timewindow(self, start, end):
        t = np.arange(start, end)
        pred_y = self.predict(t)
        return pred_y

    # fits to array of time and deaths
    def fit(self, T, y):
        self.modelResult = self.model.fit(y, self.params, t=T)
        self.params = self.modelResult.params

        # get cov matrix and errors
        # errors = np.sqrt(np.diag(pcov))
        return self
Beispiel #8
0
def prueba():
    y2 = [49.0, 49.0, 101.0, 67.0, 65.0, 52.0, 49.0, 49.0, 54.0, 49.0, 48.0, 49.0]
    y = [i-50 for i in y2]
    x = linspace(0.0, 11.0, num=12) #variable ind para evento
    x2 = linspace(0.0, 11.0, num=400)   #variable ind para fit
    gmod = Model(gaussian)  #Generar un Modelo Gaussiano
    
    peak = max(y)
    result = gmod.fit(y, x=x, amp=peak, cen=5, wid=1)
    final = gmod.eval(x=x2, amp=result.best_values['amp'], cen=result.best_values['cen'], wid=result.best_values['wid'])
    
    plt.plot(x, y,         'bo')
    plt.plot(x, result.init_fit, 'k--')
    #plt.plot(x, result.best_fit, 'r-')
    plt.plot(x2, final, 'r-')
    plt.show()
Beispiel #9
0
    def test_wrapped_model_func(self):
        x = np.linspace(-1, 1, 51)
        y = 2.0*x + 3 + 0.0003 * x*x
        y += np.random.normal(size=len(x), scale=0.025)
        mod = Model(linear_func)
        pars = mod.make_params(a=1.5, b=2.5)

        tmp = mod.eval(pars, x=x)

        self.assertTrue(tmp.max() > 3)
        self.assertTrue(tmp.min() > -20)

        result = mod.fit(y, pars, x=x)
        self.assertTrue(result.chisqr < 0.05)
        self.assertTrue(result.aic < -350)
        self.assertTrue(result.errorbars)

        self.assertTrue(abs(result.params['a'].value - 2.0) < 0.05)
        self.assertTrue(abs(result.params['b'].value - 3.0) < 0.41)
Beispiel #10
0
 def fit_planck(self):
     T_wien, em_wien = fit_wien(self.lamda, self.I2)
     bmmodel = Model(planck, independent_vars=['lamda'])
     params = Parameters()
     params.add('T', value=T_wien)
     params.add('em', value=em_wien)
     self.result = bmmodel.fit(self.I2, params, lamda=self.lamda)
     # write error report
     report_fit(self.result)
     self.result.params.pretty_print()
     Ifit = bmmodel.eval(self.result.params, lamda=self.lamda)
     plt.figure()
     plt.plot(self.lamda * 1e9, self.I2, label='T gradient + absorption')
     plt.plot(self.lamda * 1e9,
              Ifit,
              label='Fitted ' + str(self.result.params.valuesdict()['T']) +
              ' K')
     plt.xlabel("wavelegnth (nm)")
     plt.ylabel("radiance (W/m^3)")
     plt.legend()
Beispiel #11
0
def gauss_fwhm2(x, y):
    cont_bi = np.sqrt(2 * np.log(2))
    xsize = np.size(x)
    amp = np.amax(y)
    cen = x[np.argmax(y)]

    #mean = sum(x * y) / sum(y)
    wid = fwhm(x, y)  #np.sqrt(sum(y * (x - mean) ** 2) / sum(y))

    gmodel = Model(Gauss)
    print('parameter names: {}'.format(gmodel.param_names))
    print('independent variables: {}'.format(gmodel.independent_vars))
    params = gmodel.make_params(amp=amp, cen=cen, wid=wid, bis=np.amin(y))
    results = gmodel.fit(y, params, x=x)
    print(results.fit_report())

    fitx = np.linspace(np.amin(x) * 1.1, np.amax(x) * 1.1, num=np.size(x) * 2)
    fity = gmodel.eval(params=results.params, x=fitx)
    dely = results.eval_uncertainty(sigma=3, x=fitx)  #3sigma uncertainity

    fwhm0 = results.params["wid"] * cont_bi
    return fwhm0, fitx, fity, results, dely
Beispiel #12
0
def fit_model_double(function,
                     energy_fit,
                     eqe_fit,
                     bound_dict,
                     p0=None,
                     include_disorder=False,
                     print_report=False
                     ):
    """
    Function to perform curve fit using lmfit
    This function is used for simultaneous double peak fitting
    :param function: function to fit against (i.e. gaussian, gaussian_disorder etc.)
    :param energy_fit: energy values to fit against [list or array]
    :param eqe_fit: EQE values to fit against [list or array]
    :param bound_dict: dictionary of boundary values [dict]
                       dict keys:
                       start_ECT, stop_ECT
                       start_lCT, stop_lCT
                       start_fCT, stop_fCT
                       start_Eopt, stop_Eopt
                       start_lopt, stop_lopt
                       start_fopt, stop_fopt
                       start_sig, stop_sig
    :param p0: list of initial guesses for curve_fit function [list]
    :param include_disorder: boolean value to specify whether to include disorder [bool]
    :param print_report: boolean value to specify whether to print fit report [bool]
    :return: best_vals: list of best fit parameters [list]
             covar: covariance matrix of fit
             y_fit: calculated EQE values of the fit [list]
             r_squared: R^2 of the fit [float]
    """
    if p0 is None: # if no guess is given, initialize with all ones. This is consistent with curve_fit.
        if include_disorder:
            p0 = [1, 1, 1, 1, 1, 1, 1]
        else:
            p0 = [1, 1, 1, 1, 1, 1]

    gmodel = Model(function)

    gmodel.set_param_hint('ECT', min=bound_dict['start_ECT'], max=bound_dict['stop_ECT'])
    gmodel.set_param_hint('lCT', min=bound_dict['start_lCT'], max=bound_dict['stop_lCT'])
    gmodel.set_param_hint('fCT', min=bound_dict['start_fCT'], max=bound_dict['stop_fCT'])
    gmodel.set_param_hint('Eopt', min=bound_dict['start_Eopt'], max=bound_dict['stop_Eopt'])
    gmodel.set_param_hint('lopt', min=bound_dict['start_lopt'], max=bound_dict['stop_lopt'])
    gmodel.set_param_hint('fopt', min=bound_dict['start_fopt'], max=bound_dict['stop_fopt'])

    if include_disorder:
        gmodel.set_param_hint('sig', min=bound_dict['start_sig'], max=bound_dict['stop_sig'])

        result = gmodel.fit(eqe_fit,
                            E=energy_fit,
                            fCT=p0[0],
                            lCT=p0[1],
                            ECT=p0[2],
                            fopt=p0[3],
                            lopt=p0[4],
                            Eopt=p0[5],
                            sig=p0[6]
                            )

        if print_report:
            print(result.fit_report())

        fCT = float(result.params['fCT'].value)
        lCT = float(result.params['lCT'].value)
        ECT = float(result.params['ECT'].value)
        fopt = float(result.params['fopt'].value)
        lopt = float(result.params['lopt'].value)
        Eopt = float(result.params['Eopt'].value)
        sig = float(result.params['sig'].value)

        best_vals = [fCT, lCT, ECT, fopt, lopt, Eopt, sig]

        covar = result.covar
        if covar is None:
            covar = np.zeros((7, 7))

        y_fit = gmodel.eval(E=np.array(energy_fit),
                            fCT=fCT,
                            lCT=lCT,
                            ECT=ECT,
                            fopt=fopt,
                            lopt=lopt,
                            Eopt=Eopt,
                            sig=sig
                            )
    else:
        result = gmodel.fit(eqe_fit,
                            E=energy_fit,
                            fCT=p0[0],
                            lCT=p0[1],
                            ECT=p0[2],
                            fopt=p0[3],
                            lopt=p0[4],
                            Eopt=p0[5]
                            )

        if print_report:
            print(result.fit_report())

        fCT = float(result.params['fCT'].value)
        lCT = float(result.params['lCT'].value)
        ECT = float(result.params['ECT'].value)
        fopt = float(result.params['fopt'].value)
        lopt = float(result.params['lopt'].value)
        Eopt = float(result.params['Eopt'].value)

        best_vals = [fCT, lCT, ECT, fopt, lopt, Eopt]

        covar = result.covar
        if covar is None:
            covar = np.zeros((6, 6))

        y_fit = gmodel.eval(E=np.array(energy_fit),
                            fCT=fCT,
                            lCT=lCT,
                            ECT=ECT,
                            fopt=fopt,
                            lopt=lopt,
                            Eopt=Eopt
                            )

    r_squared = R_squared(eqe_fit, y_fit)

    return best_vals, covar, y_fit, r_squared
Beispiel #13
0
    DA_params = Parameters()
    with open("dual_annealing_params.json", mode='r') as fname:
        params = json.load(fname)
        DA_params.loads(params)

    path_to_covid_data = "RJ_data.csv"
    path_to_pop_data = "RJ_populations.csv"
    DATA = get_data(path_to_pop_data, path_to_covid_data)
    X0 = DATA[0]
    time_frame = np.arange(0, 365, 1)

    kinetic_seasonal_model = Model(SIRD_kinetic_seasonal, independent_vars=['t', 'x0'])
    no_social_distancing_model = Model(SIRD_kinetic_seasonal_no_SD, independent_vars=['t', 'x0'])

    DE_pred = kinetic_seasonal_model.eval(DE_params, t=time_frame, x0=X0)
    BH_pred = kinetic_seasonal_model.eval(BH_params, t=time_frame, x0=X0)
    DA_pred = kinetic_seasonal_model.eval(DA_params, t=time_frame, x0=X0)

    print "Differential Evolution:"
    DE_params.pretty_print()
    print "gamma0 : %f" % (DE_params["gamma_sum"] * DE_params["gamma_partition"])
    print "gamma1 : %f" % (DE_params["gamma_sum"] * (1 - DE_params["gamma_partition"]))
    print "mu0 : %f" % (DE_params["mu_sum"] * DE_params["mu_partition"])
    print "mu1 : %f" % (DE_params["mu_sum"] * (1 - DE_params["mu_partition"]))

    print "Total  Number of Infected DE:\t\t%.1f" % (DE_pred[-1,2] + DE_pred[-1,3])
    print "Total Number of Dead DE:\t\t\t%.1f\n" % DE_pred[-1,3]

    print "Basin Hopping:"
    BH_params.pretty_print()
Beispiel #14
0
x2 = linspace(0.0, 11.0, num=300)   #variable ind para fit, 300 asi el eje x esta en 1ns
gmod = Model(gaussian)  #Generar un Modelo Gaussiano

#Iterar el Corpus de datos para realizar un archivo con los features en tuplas
#sampled_data = []

with open("C:\Users\Anai\Desktop\Miguel\LAGO\LAGO-AI\src\cosmicfilter\CosmicTrain.txt", "r") as f:
    with open("OutputClusterReduced.txt", "w") as output:
        for l in f:
            data = l.split("-")
            raw_data = data[0].strip().split(" ")
            #print(raw_data)
            y = [int(i)-47 for i in raw_data]
            peak = max(y)
            result = gmod.fit(y, x=x, amp=peak, cen=3, wid=1)
            final = gmod.eval(x=x2, amp=result.best_values['amp'], cen=result.best_values['cen'], wid=result.best_values['wid'])
            rtime = argmax(final)
            dummy = str(rtime)+"-"+str(peak)
            #if dummy not in sampled_data:
            output.write("["+str(rtime)+","+str(float(peak))+"]\n")
            #sampled_data.append(str(rtime)+"-"+str(peak))
            
print("Finished...")       
#amp_result = result.best_values['amp']
#cen_result = result.best_values['cen']
#wid_result = result.best_values['wid']



#print(result.fit_report())
#print(final)
Beispiel #15
0
class XRFAllElementModel(Model):

    def __init__(self, exptdesc,linedict,xrffunc,comptonfunc, elasticfunc,
                 linetype='element',*args,**kwargs):
        """

        An XRF spectrum model
        LMFIT offers a range of options for coupling parameters and models but in order to be able to do 
        this it needs to manipulate parameters - in particular string expressions and this leads 
        big slowdowns if you've a large number of models or coupled parameters.     
        To speed up the calculation rather than create the XRF spectrum from a sum of Gaussian Models
        we create a single model with many parameters.
        The basic lmfit model works as follows:
        parse the arguments of the input function.
        Build a list of param names from these arguments
        Apply paramhints to these param_names or make parameters from the param names
  
        This class will pass a basic line

        """
        # Pass an empty function to model
        super(XRFAllElementModel, self).__init__(None,*args, **kwargs)
        # Arguments need to be converted to  
        # a list of elements (the peaks -> translating to peak areas) + the line type arguments 
        # The basic model just assigns  
        # self.func = function
        # parses the function parameters to
        #
        # line model
        self.funcmodel = Model(xrffunc)
        self.funcparams_all = self.funcmodel.make_params()
        self.funcparams_sub = self.funcmodel.make_params()   
        # remove the area and center parameter 
        self.funcparams_all.pop("area",None)
        self.funcparams_all.pop("center",None)
        # pileup model
        self.pileupmodel = Model(linefunc)
        self.pileupmodel = self.pileupmodel.make_params()
        # remove the area and center parameter 
        self.funcparams_all.pop("area",None)
        self.funcparams_all.pop("center",None)


        # get the function name
        self.linedict = linedict
        self.exptdesc = exptdesc
        self.funcname   = linefunc.__name__
        self._name = "xrf_model"
        self.func = self.funcover
        #self.create_full_parameters(self)
        
        
    def create_full_parameters(self):
        
        # remove the area and center parameter 
        # For each element in the linedict add a parameter
        # which will control the area
        self.funcparams_all = deepcopy(self.funcparams_sub)
        self.funcparams_all.pop("area",None)
        self.funcparams_all.pop("center",None)
        
        for key in self.exptdesc["lineshape"]["element"][self.funcname].keys():
            if key in self.funcparams_all:
                self.funcparams_all[key].value = \
                    self.exptdesc["lineshape"]["element"]\
                    [self.funcname][key]["value"]
                self.funcparams_all[key].min   = \
                    self.exptdesc["lineshape"]["element"]\
                    [self.funcname][key]["min"]
                self.funcparams_all[key].max   = \
                    self.exptdesc["lineshape"]["element"]\
                    [self.funcname][key]["max"]
                self.funcparams_all[key].vary  = \
                    self.exptdesc["lineshape"]["element"]\
                    [self.funcname][key]["vary"]
        for key in self.linedict:
#            if not '+' in key:            
            self.funcparams_all.add(key,
                **self.exptdesc["lineshape"]["element"][self.funcname]["area"])

         
        

    def make_params(self):
        self.create_full_parameters()
        return self.funcparams_all

    def funcover(self, params,**kwargs):
        #
        # copy the function based parameters from params to funcparams
        # 
        for key in params:
            if key in self.funcparams_sub:
                self.funcparams_sub[key].value = params[key].value
                self.funcparams_sub[key].min   = params[key].min
                self.funcparams_sub[key].max   = params[key].max
                self.funcparams_sub[key].vary  = params[key].vary
        xrf_sigma_keys = [s for s in self.funcparams_sub if 'sigma' in s]
        elastic_sigma_keys = [s for s in self.elasticparams if 'sigma' in s]
        xrf_sigma_keys = [s for s in self.funcparams_sub if 'sigma' in s]
        
        first=True
        #
        # Do the basic lines XRF and Escape first...
        #
        for key,linegroup in self.linedict.iteritems():
            if key in params:
                for line in linegroup:
                    # update funcparams
                    self.funcparams_sub["area"].value   = params[key].value*\
                                                 line.intensity
                    self.funcparams_sub["center"].value = line.line_energy
                    if isinstance(line,(XrayLine,EscapeLine)):
                        for ii in sigma_keys:
                            self.funcparams_sub[ii].value = np.sqrt(params[ii].value**2 + \
                                     (line.line_energy*0.001))
                        lineresult =\
                            self.funcmodel.eval(self.funcparams_sub,**kwargs)
                    if isinstance(line,(ElasticLine)):
                        for ii in elastic_sigma_keys:
                            self.funcparams_sub[ii].value = np.sqrt(params[ii].value**2 + \
                                     (line.line_energy*0.001))
                        lineresult=\
                            self.elasticmodel.eval(self.funcparams_sub,**kwargs)
                    if isinstance(line,(ComptonLine)):
                        for ii in elastic_sigma_keys:
                            self.funcparams_sub[ii].value = np.sqrt(params[ii].value**2 + \
                                     (line.line_energy*0.001))
                        lineresult=\
                            self.comptonmodel.eval(self.funcparams_sub,**kwargs)
                    if isinstance(line,PileupLine):
                            # full method is to convolute the lines 
                            # split the label to determine the individual lines
                            # generate each line...
                            # roll them both to zero
                            # convolve the lineshapes
                            # roll them back to the energy 
                            pass
               
                
                
                    if first:
                        result = lineresult
                        first = False
                    else:
                        result += lineresult
        
        return result
        
        
    def eval(self, params=None, **kwargs):
        result= self.funcover(params=params, **kwargs)
        return result
Beispiel #16
0
  def process_cam_image(self, data, title_string, draw_plots = False):
    """process a matrix of camera data"""
    ret = {}
    # values in pixels and counts
    ret['fit_fail'] = True
    ret['saturated'] = True
    ret['sigmaX'] = 0
    ret['sigmaY'] = 0
    ret['peakPosX'] = 0
    ret['peakPosY'] = 0
    ret['amplitude'] = 0
    ret['theta'] = 0
    ret['blur_volume'] = 0
    ret['blur_peak'] = 0
    ret['background'] = 0

    if draw_plots:
      # plot the image
      fig = plt.figure()
      ax = plt.matshow(data, fignum=fig.number)
      ax.axes.xaxis.tick_bottom()
      plt.title('RAW Camera|' + title_string)
      plt.colorbar(label='Counts')

    cameraBits = 12  # bit depth of the camera
    nCameraValues = 2**cameraBits  # and so there are this many unique values a pixel can take on
    maxCamValue = nCameraValues - 1  # and so the maximum value a pixel can take on is this
    xRes = data.shape[0]  # image x resolution
    yRes =  data.shape[1]  # image y resolution
    nPix = xRes * yRes # number of pixels in camera image

    # corner method of finding background
    #cornerDim = 50
    #corner = camData[:cornerDim,-cornerDim:] # take corner of the image
    #background = corner.mean()

    # histogram method of finding background (better probs)
    # take a histogram of counts in image and call the bin with the most counts the background
    bins = np.bincount(data.ravel(),minlength=nCameraValues) # maybe gaussian blur the image first?
    background = bins.argmax().astype(np.int16)
    ret['background'] = background

    #print("Camera background found to be {:} counts.".format(background))

    # camData with background offset subtracted away
    bg0 = data.copy() - background  

    #camMax = camData.max()
    #camAvg = camData.mean()
    #print("Camera Maximum:",camMax * photons_per_count,"[photons]")
    #self.sd['camMax'] = float(camMax * photons_per_count)

    # global auto-threshold the image (for finding the substrate)
    blur = data.copy() # copy camera data so we don't mess up the origional
    blur = cv2.medianBlur(src=blur, ksize=5) # median filter here
    bg0_blur = blur - background  # camData with background offset subtracted away

    # detect camera saturation
    saturation_percent_of_max = 5  # any pixel within this percent of max is considered saturated
    saturation_percent_of_pixels = 1  # if any more than this percent of total pixels in ROI are saturated, then we set the saturated flag for the image
    sat_thresh = np.int16(round((1-(saturation_percent_of_max / 100)) * maxCamValue))  # any pixel over this value is saturated
    nSatPix = np.count_nonzero(blur.ravel() >= sat_thresh)  # number of saturated pixels
    cameraSaturated = True
    if nSatPix < nPix*saturation_percent_of_pixels / 100:
      cameraSaturated = False
      ret['saturated'] = False
    else:
      print("WARNING: Image saturation detected. >{:}% of pixels are within {:}% of their max value".format(saturation_percent_of_pixels, saturation_percent_of_max))

    cantFindSubstrate = True
    if (not cameraSaturated):
      ret['blur_peak'] = bg0_blur.max()
      ret['blur_volume'] = bg0_blur.sum()
      
      if self.verbose:
        print("Median filtered image peak: {:.0f} [counts]".format(ret['blur_peak']))
        print("Median filtered image volume: {:.3g} [counts]".format(ret['blur_volume']))

      # global auto-threshold the image (for finding the substrate)
      thresh_copy = data.copy() # copy camera data so we don't mess up the origional
      thresh_copy = (thresh_copy/nCameraValues*(2**8-1)).round()  # re-normalize to be 8 bit
      thresh_copy = thresh_copy.astype(np.uint8) # information loss here, though only for thresh finding just because the big (k=15 filter makes) cv2 puke for 16bit numbers :-P
      thresh_blur = cv2.medianBlur(src=thresh_copy, ksize=15) # big filter here    
      tret,thresh = cv2.threshold(thresh_blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) # global auto-threshold
      nz = cv2.findNonZero(thresh) # thresh --> bool
      if nz is not None:
        mar = cv2.minAreaRect(nz) # find our substrate, minimum area rectangle = ((center_x,center_y),(width,height), angle)
      else: # this gets hit when the camera data is dark
        mar = ((0,0),(0,0), 0)
        
      # caculate the ROI
      boxScaleFactor = 0.70 # reduce ROI by this factor to prevent substrate edge effects
      smaller = (mar[0],tuple([x*boxScaleFactor for x in mar[1]]), mar[2]) # scale box width and height
      box = cv2.boxPoints(smaller).astype(np.int0) # find new ROI corners
      
      # show user the new ROI
      whereIsROI = cv2.drawContours(thresh_blur, [box], 0, 127, 3)
      if draw_plots:
        # for the ROI image
        fig = plt.figure()        
        ax = plt.matshow(whereIsROI, fignum=fig.number, cmap='gray', vmin = 0, vmax = 255)
        ax.axes.xaxis.tick_bottom()
        plt.title('Camera ROI|' + title_string)
      
      # did we find the substrate?
      approxSubstrateArea = mar[1][0] * mar[1][1]  # compute substrate area
      substrateAreaFactor = 0.8    
      if nPix * substrateAreaFactor > approxSubstrateArea: # test if the ROI is huge
        cantFindSubstrate = False
        # now we'll crop the blurred camera data
        ROI = np.full(data.shape, np.NaN)  # ROI starts as NaNs TODO: check shape, maybe bg0_blur
        mask = np.zeros_like(data)  # now we'll build up a mask for the ROI TODO: check shape, maybe bg0_blur
        cv2.drawContours(mask, [box], 0, 255, -1)  # fill the ROI box with white in the mask array
        ROI[mask == 255] = bg0_blur[mask == 255]  # now copy the blurred image data from the ROI region into the ROI array 
      else:
        print("WARNING: Can't find the substrate")  # and quit if it's too big    

    if self.fitSpot and (not cantFindSubstrate) and (not cameraSaturated):
      # let's make some initial guesses for the 2d gaussian fit
      twoDG_model = Model(analyzer.twoD_Gaussian, independent_vars=['x','y', 'offset'])
      guesses = twoDG_model.make_params()      
      # the raw image moment calculation forms the basis of our guesses
      m = cv2.moments(bg0_blur)
      
      data_sum = m['m00']
      
      # "center of mass"
      guesses['yo'].value = m['m10']/data_sum
      guesses['xo'].value = m['m01']/data_sum
      
      #angle = 0.5 * np.arctan(2 * m['mu11'] / (m['mu20'] - m['mu02']))
      #guesses['theta'].value = abs(angle - constants.pi/4) - constants.pi/4# lol, wtf, check this against more examples
      guesses['theta'].value = 0  # can't really get angle guess right
      
      guesses['sigma_y'].value = np.sqrt(m['mu20']/m['m00'])
      guesses['sigma_x'].value = np.sqrt(m['mu02']/m['m00'])
      
      # take an average of the points around the peak to find amplitude
      xc = round(guesses['xo'].value)
      yc = round(guesses['yo'].value)
      guesses['amplitude'].value = bg0_blur[xc,yc]
      
      # Create x and y grid
      xv = np.linspace(0, xRes-1, xRes) #TODO: check if yRes needs to be used here
      yv = np.linspace(0, yRes-1, yRes) #TODO: check if xRes needs to be used here
      x, y = np.meshgrid(xv, yv, indexing='ij')
      #x, y = np.meshgrid(xv, yv)
      
      # here we fit the camera data to a 2D gaussian model
      fitFail = True
      try:
        fitResult = twoDG_model.fit(ROI, x=x, y=y, offset=0, params=guesses, nan_policy='omit', fit_kws={'maxfev': 500})
        if fitResult.success:
          fitFail = False
      except:
        pass
          
      if fitFail:
        print('Camera spot 2D gaussian fit failure \a')
      else:  # do these things when the fit does not fail
        # the fit parameters in counts and pixels
        ret['sigmaX'] = fitResult.params['sigma_x'].value
        ret['sigmaY'] = fitResult.params['sigma_y'].value
        ret['peakPosX'] = fitResult.params['xo'].value
        ret['peakPosY'] = fitResult.params['yo'].value
        ret['amplitude'] = fitResult.params['amplitude'].value
        ret['theta'] = fitResult.params['theta'].value

        if self.verbose:
          totalVolume = 2 * constants.pi * ret['amplitude'] * ret['sigmaX'] * ret['sigmaY']
          print("Gaussian spot amplitude seen by camera: {:.0f} [counts]".format(ret['amplitude']))
          print("Gaussian spot volume seen by camera: {:.3g} [counts]".format(totalVolume))
          print("Gaussian spot sigma X : {:.2f} [pixels]".format(ret['sigmaX']))
          print("Gaussian spot sigma Y : {:.2f} [pixels]".format(ret['sigmaY']))
          print("Gaussian spot position X : {:.2f} [pixels]".format(ret['peakPosX']))
          print("Gaussian spot position Y : {:.2f} [pixels]".format(ret['peakPosY']))
          print("Gaussian spot rotation : {:.4f} [radians]".format(ret['theta']))

        if draw_plots:
          theta = fitResult.params['theta'].value
          amplitude = fitResult.params['amplitude'].value
          peakPos = (fitResult.params['xo'].value, fitResult.params['yo'].value)
          sigma = (fitResult.params['sigma_x'].value, fitResult.params['sigma_y'].value)
          fitSurface2D = twoDG_model.eval(x=x, y=y, offset=0, params=fitResult.params)
          
          # let's make some evaluation lines
          nPoints = 100
          nSigmas = 4 # line length, number of sigmas to plot in each direction
          rA = np.linspace(-nSigmas*sigma[0], nSigmas*sigma[0], nPoints) # radii (in polar coords for line A)
          AX = rA*np.cos(theta+np.pi/2) + peakPos[0] # x values for line A
          AY = rA*np.sin(theta+np.pi/2) + peakPos[1] # y values for line A
        
          rB = np.linspace(-nSigmas*sigma[1],nSigmas*sigma[1],nPoints) # radii (in polar coords for line B)
          BX = rB*np.cos(theta) + peakPos[0] # x values for line B
          BY = rB*np.sin(theta) + peakPos[1] # y values for line B
                
          f = interpolate.RectBivariateSpline(xv, yv, data) # linear interpolation for data surface
        
          lineAData = f.ev(AX,AY)
          lineAFit = twoDG_model.eval(x=AX, y=AY, offset=background, params=fitResult.params)
        
          lineBData = f.ev(BX,BY)
          lineBFit = twoDG_model.eval(x=BX, y=BY, offset=background, params=fitResult.params)
        
          residuals = lineBData - lineBFit
          ss_res = np.sum(residuals**2)
          ss_tot = np.sum((lineBData - np.mean(lineBData)) ** 2)
          r2 = 1 - (ss_res / ss_tot)
          
          fig, axes = plt.subplots(2, 2,figsize=(8, 6), facecolor='w', edgecolor='k')
          fig.suptitle('Camera|' + self.titleString, fontsize=10)
          axes[0,0].matshow(data, cmap=plt.cm.copper)
          axes[0,0].contour(y, x, mask, 3, colors='yellow', alpha=0.2)
          #thresh
          #whereIsROI2 = cv2.drawContours(camData, [box], 0, 50, 3)
          #axes[0,0].matshow(whereIsROI2, cmap=plt.cm.copper)  # 
          ax.axes.xaxis.tick_bottom()

          if len(np.unique(fitSurface2D)) is not 1: # this works around a bug in contour()
            axes[0,0].contour(y, x, fitSurface2D, 3, colors='gray', alpha=0.5)
          else:
            print('Warning: contour() bug avoided')
          
          axes[0,0].plot(AY,AX,'r', alpha=0.5) # plot line A
          axes[0,0].plot(BY,BX,'g', alpha=0.5) # plot line B
          axes[0,0].set_title("Image Data")
          axes[0,0].set_ylim([xv.max(), xv.min()])
          axes[0,0].set_xlim([yv.min(), yv.max()])
          axes[0,0].xaxis.tick_bottom()
        
          axes[1,0].plot(rA, lineAData, 'r', label='Data')
          axes[1,0].plot(rA, lineAFit, 'k', label='Fit')
          axes[1,0].set_title('Red Line Cut')
          axes[1,0].set_xlabel('Distance from center of spot [pixels]')
          axes[1,0].set_ylabel('Magnitude [counts]')
          axes[1,0].grid(linestyle = '--')
          handles, labels = axes[1,0].get_legend_handles_labels()
          axes[1,0].legend(handles, labels)        
        
          axes[1,1].plot(rB,lineBData,'g',label='Data')
          axes[1,1].plot(rB,lineBFit,'k',label='Fit')
          axes[1,1].set_title('Green Line Cut')
          axes[1,1].set_xlabel('Distance from center of spot [pixels]')
          axes[1,1].set_ylabel('Magnitude [counts]')
          axes[1,1].yaxis.set_label_position("right")
          axes[1,1].grid(linestyle='--')
          handles, labels = axes[1,1].get_legend_handles_labels()
          axes[1,1].legend(handles, labels)
          
        
          axes[0,1].axis('off')
          axes[0,1].set_title('Fit Details')
          
          logMessages = io.StringIO()
          print("Green Line Cut R^2 = {:0.8f}".format(r2), file=logMessages)
          print("Peak = {:+011.5f} [counts]\n".format(amplitude+background), file=logMessages)
          print("     ====Fit Parameters====", file=logMessages)
          print("Amplitude = {:+011.5f} [counts]".format(amplitude), file=logMessages)
          print("Center X  = {:+011.5f} [pixels]".format(peakPos[1]), file=logMessages)
          print("Center Y  = {:+011.5f} [pixels]".format(peakPos[0]), file=logMessages)
          print("Sigma X   = {:+011.5f} [pixels]".format(sigma[1]), file=logMessages)
          print("Sigma Y   = {:+011.5f} [pixels]".format(sigma[0]), file=logMessages)
          print("Rotation  = {:+011.5f} [radians]".format(theta), file=logMessages)
          print("Baseline  = {:+011.5f} [counts]".format(background), file=logMessages)
          logMessages.seek(0)
          messages = logMessages.read()      
          
          axes[0,1].text(0,0,messages, family='monospace')
      ret['fit_fail'] = fitFail
      return(ret)
Beispiel #17
0
class XRFModel(Model):
    def __init__(self, exptdesc, linedict, linefunc, *args, **kwargs):
        """

        An XRF spectrum model
        LMFIT offers a range of options for coupling parameters and models but in order to be able to do 
        this it needs to manipulate parameters - in particular string expressions and this leads 
        big slowdowns if you've a large number of models or coupled parameters.     
        To speed up the calculation rather than create the XRF spectrum from a sum of Gaussian Models
        we create a single model with many parameters.
        The basic lmfit model works as follows:
        parse the arguments of the input function.
        Build a list of param names from these arguments
        Apply paramhints to these param_names or make parameters from the param names
  
        This class will pass a basic line

        """
        # Pass an empty function to model
        super(XRFModel,
              self).__init__(linefunc,
                             prefix="xrf_",
                             independent_vars=['x', 'area', 'center'])

        self.linedict = linedict
        self.exptdesc = exptdesc
        self.func = self.xrffunc
        self.linefunc = linefunc
        self.xrfmodel = Model(linefunc)
        self.set_param_hints_from_dict("element", linefunc.__name__)

        name = None
        if name is None and hasattr(self.xrffunc, '__name__'):
            name = self.func.__name__
        self._name = name

    def set_param_hints_from_dict(self, linetype, linefuncname):
        """

        This sets the default paramter hints for the model on setup
        
        """
        avail_hints = self.exptdesc["lineshape"][linetype][linefuncname].keys()
        for key in avail_hints:
            if key in self._param_root_names:
                self.set_param_hint(key,expr=None,**self.exptdesc["lineshape"]\
                                      [linetype][linefuncname][key])
        # exclude pileups from the parameters
        for key in self.linedict:
            if not any(word in key for word in ['+', 'Elastic', 'Compton']):
                self.set_param_hint(key,expr=None,**self.exptdesc["lineshape"]["element"]\
                    [self.linefunc.__name__]["area"])

        self.set_param_hint("fano",expr=None,**self.exptdesc["xrf_fitting"]["params"]\
                    ["fano"])

    def make_params(self):

        params = super(XRFModel, self).make_params()
        #
        # If the element list is empty return no parameters...
        #
        elementlist = []
        for key in self.linedict:
            if any(keyv not in key for keyv in ['+', 'Elastic', 'Compton']):
                elementlist.append(key)
        if elementlist:
            return params
        else:
            return Parameters()

    def xrffunc(self, params, **kwargs):

        xrf_sigma_keys = [s for s in params if 'sigma' in s]
        #
        # common parameters
        # pileup_factor , fano
        #
        first = True
        x = kwargs.get('x', None)
        result = np.zeros(len(x))
        fano = params["fano"]
        #
        # Do the basic lines XRF and Escape first...
        #
        for key, linegroup in self.linedict.iteritems():
            if key in params:
                for line in linegroup:
                    area = params[key].value * line.intensity
                    center = line.line_energy
                    # update funcparams
                    #if type(line) == XrayLine or type(line) == EscapeLine:
                    if isinstance(line, (XrayLine, EscapeLine)):
                        for ii in xrf_sigma_keys:
                            params[ii].value = sqrt(params[ii].value**2 + \
                                     (center*fano))
                        lineresult =\
                            self.xrfmodel.eval(params=params,area = area,
                                               center = center,**kwargs)
                    if first:
                        result = lineresult
                        first = False
                    else:
                        result += lineresult
        #
        # generate the pileup lines...
        # you can convolute the whole line with itself to get the pileup
        # (basic code is a variation on what's done in pymca..)
        #
        #
        # The problem is largely in the intensity scaling. For a simple
        # 2-event summation you can just scale it by some factor
        # but for 3 event pileup the magnitude over the curve
        # grows rather than diminishes.
        #

#        result = result + pileup_factor*self.selfconvolute(result,**kwargs)

        return result

    def eval(self, params=None, **kwargs):
        pardict = self.make_funcargs(params)
        return self.xrffunc(params, pardict, **kwargs)
Beispiel #18
0
def simple_echo_fits2():
    """
    Takes the highest point of each echo and fits the echo_as_T2 function to those points.
    """
    datafolder = filedialog.askopenfilenames(initialdir="C:\\Users\Josh\IdeaProjects\OpticalPumping",
                                             title="Select data for bulk plotting")
    for filename in datafolder:
        name_ext = filename.split('/')[-1]
        name_no_ending = name_ext.split('.csv')[0]
        dat1 = read_csv("C:\\Users\\Josh\\IdeaProjects\\OpticalPumping\\Rabi_RDAT\\{}".format(name_ext),
                        names=['T', 'V'])
        backup_datV = np.array(dat1['V'])
        backup_datT = np.array(dat1['T'])
        try:
            dat3 = read_csv("C:\\Users\\Josh\\IdeaProjects\\OpticalPumping\\Sweep_ranges\\{}".format(name_ext),
                            names=['Lower Bound', 'LowerIndex', 'Upper Bound', 'UpperIndex'])
        except FileNotFoundError:
            fig1, ax1 = plt.subplots()
            plt.title('Pick Ranges for Exponential decay fit')
            Figure1, = ax1.plot(dat1['T'], dat1['V'])
            Sel3 = RangeTool(dat1['T'], dat1['V'], Figure1, ax1, name_no_ending)
            fullscreen()
            plt.show()
            dat3 = Sel3.return_range()
        plt.close()
        xrange = []
        yrange = []
        xranges = {}
        yranges = {}
        x_append = xrange.append
        y_append = yrange.append
        for o in range(0, len(dat3)):
            x_append((dat1['T'][dat3['LowerIndex'][o]:dat3['UpperIndex'][o] + 1]).values)
            y_append((dat1['V'][dat3['LowerIndex'][o]:dat3['UpperIndex'][o] + 1]).values)
        for o in range(0, len(xrange)):
            xranges[o] = xrange[o]
            yranges[o] = yrange[o]
        xrs = xranges
        yrs = yranges
        length = len(yrs)
        try:
            max_y = [np.max(yrs[i]) for i in range(length)]
            max_y_loc = [np.where(yrs[i] == max_y[i])[0][0] for i in range(length)]
            cents = [xrs[i][max_y_loc[i]] for i in range(length)]
            min_y = [np.min(yrs[i]) for i in range(length)]
            min_y_loc = [np.where(yrs[i] == min_y[i])[0][0] for i in range(length)]
            min_cents = [xrs[i][min_y_loc[i]] for i in range(length)]
            heights = max_y
            heights2 = min_y
            # TODO: Find a better value for the uncertainty on y-values.
            heights = np.array(heights)
            cents = np.array(cents)
            min_cents = np.array(min_cents)
            maxy = np.max(heights)
            miny = np.min(heights)
            heights2 = np.array(heights2)
            maxy2 = np.max(heights2)
            avg_y_sep = abs(np.mean(np.diff(heights)))
            ys = [((heights2[x] + heights2[x + 1]) / 2 if x < len(heights2) - 1 else heights2[x]) for x in range(len(
                    heights2 - 1))]
            background_interp = interp1d(x=cents, y=ys, bounds_error=False)
            dat1['V'] = dat1['V'] - background_interp(dat1['T'])
            heights = heights - ys
            maxy = maxy - background_interp(cents[0])
            efit = Model(echo_as_T2)
            param = efit.make_params()
            decay_pos = np.where(heights == find_nearest(heights, maxy / e))[0][0]
            decay_pos_time = cents[decay_pos]
            param.add('M0', value=maxy, min=maxy * 0.9, max=maxy + (avg_y_sep * 1.5))
            param.add('T2', value=decay_pos_time, min=decay_pos_time * 0.1, max=decay_pos_time * 6.5)

            param.add('ph', value=cents[0] * 0.6, min=0, max=cents[0] * 1.3)
            param.add('c', value=0, min=-5, max=5)

            result_2 = efit.fit(heights, param, t=cents, method='brute', weights=np.mean(np.diff(dat1['T'])) / heights2)
            print('\n', name_no_ending)
            print(result_2.fit_report())

            fig3, ax3 = plt.subplots(figsize=(8, 5.5))
            ax3.set_xlabel('Time (µs)', fontsize=14)
            ax3.set_ylabel('Voltage (a.u.)', fontsize=14)
            xes = np.linspace(np.min(cents), np.max(cents), 100)
            y = efit.eval(t=xes, params=result_2.params)
            plt.plot(xes, y, antialiased=True)
            plt.plot(min_cents, ys - background_interp(min_cents))
            # plt.plot(xes, quadratic(xes, result_2.params['m1'].value, result_2.params['m'].value, result_2.params[
            #     'c'].value))
            plt.plot(cents, heights, 'x', ms=8, color='k')
            plt.plot(dat1['T'], dat1['V'], lw=2, antialiased=True,
                     color='#4a4a4a', zorder=1)
            plt.title(filename)
            plt.xlim(left=0, right=np.max(cents) * 1.1)
            # plt.ylim(bottom=0, top=result_2.params['M0'].value * 1.1)
            plt.axhline(result_2.params['M0'].value, color='k', ls='--', alpha=0.7, lw=1, zorder=2)
            plt.axhline(result_2.params['M0'].value / e, color='k', ls='--', alpha=0.7, lw=1, zorder=2)
            plt.text(0.9, 0.9, "T_1: {:.4f} us".format(result_2.params['T2'].value), horizontalalignment='center',
                     verticalalignment="center",
                     transform=ax3.transAxes,
                     bbox={'pad': 8, 'fc': 'w'}, fontsize=14)
            # plt.tight_layout()
            plt.tick_params(axis='both', which='major', labelsize=13)
            fullscreen()
            plt.savefig("C:\\Users\\Josh\\IdeaProjects\\OpticalPumping\\MatplotlibFigures\\ExpDecay_{}.png".format(
                    name_no_ending), dpi=600)
            plt.show()

            plt.close()
            dat1.dropna(axis=0, how='any', inplace=True)
            sample_rate = round(1 / np.mean(np.diff(dat1['T'])), 11)
            length = len(dat1['T'])
            fo = fftpack.fft(dat1['V'])
            freq4 = [x * 10e6 * sample_rate / length for x in np.array(range(0, length))]

            fig5, ax5 = plt.subplots(figsize=(8, 5.5))
            plt.title('Select region containing peak')
            figure5, = ax5.plot(freq4[2:100], abs(fo[2:100]))
            # Sel1 = RangeTool(freq4[2:100], abs(fo[2:100]), figure5, ax5, 'thing')
            fullscreen()
            ax5.set_xlabel('Frequency (Hz)', fontsize=14)
            ax5.set_ylabel('Intensity (a.u.)', fontsize=14)
            plt.savefig("C:\\Users\\Josh\\IdeaProjects\\OpticalPumping\\MatplotlibFigures\\FourierDecay_{}.png".format(
                    name_no_ending), dpi=600)
            plt.show()
            # range2 = Sel1.return_range()
            bing = np.where(abs(fo[2:100]) == np.max(abs(fo[2:100])))[0][0]
            print('Maximum frequency: {:.2f}Hz'.format(freq4[2:100][bing]))
            print('\n \n    ')
            plt.close()

        except ValueError:
            print('ValueError in simpleechofits2 at end')
            continue
Beispiel #19
0
#result = gmodel.fit(y, x=x, amp=5, cen=5, wid=1)

#print(result.fit_report())

JH = CRDW(i)
pos, neg = correlation(i)
beta = cointegration(JH)
country = Y_growth[i]
model = Model(model,independent_vars=['JH','pos', 'neg', 'beta', 'country'])

from lmfit import Model
model_us = Model(model)
model_us.independent_vars
model.independent_vars

model_us.eval(params, i=7)

model_us.fit(7, params)

pars = model.make_params(a=3, b=0.5)
mod = Model(myfunc)
mod.set_param_hint('a', value=1.0)
mod.set_param_hint('b', value=0.3, min=0, max=1.0)
pars = mod.make_params()

range_N=[50]
range_T=[50]
range_alpha=[2, 5, 10]
range_a=[1, 2, 5, 10]
range_var_eps=[0.5, 1]
Beispiel #20
0
    def param(self):
        RF_mcvine = []
        RFE_mcvine = []

        RF_intp = []
        RFE_intp = []
        RF_Fit = []

        peak_positionE = []
        error = []
        R_fit = []
        a_fit = []
        b_fit = []
        s_fit = []
        t0_fit = []
        A_fit = []
        p_fit = []

        a0 = 1.6
        a1 = 1.5
        b0 = 31.9
        k = 46.

        # b_cal = 1 / b0

        Ei_array = np.array([15, 60, 100, 200, 600])
        a_array = np.array([0.21850, 0.35601, 0.46473, 0.71558, 1.33170])
        b_array = np.array([0.03737, 0.03931, 0.04370, 0.09717, 0.19422])
        R_array = np.array([0.76500, 0.73662, 0.62021, 0.31510, 0.26689])
        t0_array = np.array([0.42578, 0.22595, 0.17405, 0.12609, 0.07622])

        A_fixed = 1
        s_fixed = 2

        a = QApplication([])

        mcvine = QFileDialog.getOpenFileNames()[0]

        # a_cal = interp1d(Ei_array, a_array, fill_value='interpolate', kind='cubic')(self.Ei)
        # b_cal = interp1d(Ei_array, b_array, fill_value='interpolate', kind='cubic')(self.Ei)
        # R_cal = interp1d(Ei_array, R_array, fill_value='interpolate', kind='cubic')(self.Ei)
        # t0_cal = interp1d(Ei_array, t0_array, fill_value='interpolate', kind='cubic')(self.Ei)
        if self.Ei == 30:
            a_cal = 0.28175
            b_cal = 0.03827
            R_cal = 0.78498
            t0_cal = 0.30687

        if self.Ei == 130:
            a_cal = 0.528
            b_cal = 0.04910
            R_cal = 0.51
            t0_cal = 0.155

        if self.Ei == 300:
            a_cal = 0.89
            b_cal = 0.15
            R_cal = 0.28
            t0_cal = 0.10
            # R_cal = 0.5  # 0.5 for Ei=30,

        # a_cal = 1. / (a0 + (self.lamda(self.Ei) * a1))

        no_Et_Files = len(mcvine)
        for i in range(no_Et_Files):
            mcvineSol = mcvine[i]

            print(mcvineSol)
            iqe = hh.load(mcvineSol)

            iqe.I[iqe.I != iqe.I] = 0

            ie = iqe.sum('Q')  # histogram of DOS

            ie.I[np.isnan(ie.I)] = 0

            ie.I = ie.I / np.sum(ie.I)

            RF_mcvine.append(ie.I)

            RFE_mcvine.append(ie.E)

            peak_position = ie.E[np.where(ie.I == max(ie.I))[0][
                0]]  # finding the position of the peak of Eenergy transfer thar are given from mcvine

            # if self.Ei==30:
            #     if peak_position>20:
            #         s_fixed=8

            peak_positionE.append(peak_position)

            #### interpolation

            EnerInt = np.arange(min(ie.E), max(ie.E),
                                self.Et_interpolation_space)

            RF_inpl = interp1d(ie.E,
                               ie.I,
                               fill_value='interpolate',
                               kind='cubic')(EnerInt)

            RF_inpl[RF_inpl < 0] = 0

            RF_intp.append(RF_inpl)
            RFE_intp.append(EnerInt)

            ##model fitting
            taxis = self.t(self.l3, self.Ei, peak_position, EnerInt)

            mod = Model(self.Count)

            # RF_inpl = RF_inpl / np.sum(RF_inpl)

            p_val = np.sum(RF_inpl)
            #         RF_inter.append( RF_inpl(EnerInt ))

            # t0_cal =1
            #
            # print (t_fixed)

            # if self.Ei==30:
            #     t_fixed = peak_position

            # R_cal=np.exp(-81.799/(k*(self.lamda(self.Ei)**2)))

            # if self.Ei == 130:
            # R_cal=0.5

            print(a_cal, b_cal, R_cal)

            # if self.Ei == 130:
            #         mod.set_param_hint('R', value=R_cal, min=0.0, max=1.0 )
            #         mod.set_param_hint('a', value=a_cal,  min=0.0)
            #         mod.set_param_hint('b', value=b_cal, min=0.0)
            #         mod.set_param_hint('s', value=s_fixed, min=0.0)
            #         mod.set_param_hint('t0', value=t_fixed, min=0.0)

            # if self.Ei == 30:
            #     mod.set_param_hint('R', value=R_cal, min=0.0, max=1.0)
            #     mod.set_param_hint('a', value=a_cal, min=0.0)
            #     mod.set_param_hint('b', value=b_cal, min=0.0)
            #     mod.set_param_hint('s', value=s_fixed, min=0.0)
            #     mod.set_param_hint('t0', value=t_fixed, min=0.0, vary=False)

            # if self.Ei == 30:
            #     mod.set_param_hint('R', value=R_cal, vary=False)
            #     mod.set_param_hint('a', value=a_cal, vary=False)
            #     mod.set_param_hint('b', value=b_cal, vary=False)
            #     mod.set_param_hint('s', value=s_fixed, min=0.0)
            #     mod.set_param_hint('t0', value=t_fixed, min=0.0)

            # if self.Ei == 300:
            if i == 0:
                mod.set_param_hint('R', value=R_cal, min=0.0, max=1.0)
                mod.set_param_hint('a', value=a_cal)
                mod.set_param_hint('b', value=b_cal)
                mod.set_param_hint('s', value=s_fixed, min=0.0)
                mod.set_param_hint('t0', value=t0_cal, min=0.0)

            if i > 0:
                mod.set_param_hint('R', value=R_cal, vary=False)
                mod.set_param_hint('a', value=a_cal, vary=False)
                mod.set_param_hint('b', value=b_cal, vary=False)
                mod.set_param_hint('s', value=s_fixed, min=0.0)
                mod.set_param_hint('t0', value=t0_cal, min=0.0, vary=False)

            mod.set_param_hint('p', value=p_val, min=0.0, vary=False)
            # a.exec_()
            pars = mod.make_params()

            result = mod.fit(RF_inpl,
                             pars,
                             tm=taxis,
                             fit_kws={'nan_policy': 'omit'})

            RF_Fit.append(result.best_fit)

            residual = np.sqrt((np.sum(
                (RF_inpl - result.best_fit)**2)) / len(EnerInt))

            error.append(residual)

            dely = mod.eval(pars, tm=taxis)

            R_cal0 = R_cal
            a_cal0 = a_cal
            b_cal0 = b_cal
            t0_cal0 = t0_cal

            R_cal = result.params['R'].value
            a_cal = result.params['a'].value
            b_cal = result.params['b'].value
            t0_cal = result.params['t0'].value

            R_fit.append(result.params['R'].value)  # saving the parameters
            a_fit.append(result.params['a'].value)  # saving the parameters
            b_fit.append(result.params['b'].value)  # saving the parameters
            s_fit.append(result.params['s'].value)  # saving the parameters
            t0_fit.append(result.params['t0'].value)  # saving the parameters
            p_fit.append(result.params['p'].value)  # saving the parameters

        # print R_fit
        RF_mcvine = np.reshape(RF_mcvine, (no_Et_Files, -1))
        RFE_mcvine = np.reshape(RFE_mcvine, (no_Et_Files, -1))
        RF_intp = np.reshape(RF_intp, (no_Et_Files, -1))
        RFE_intp = np.reshape(RFE_intp, (no_Et_Files, -1))
        RF_Fit = np.reshape(RF_Fit, (no_Et_Files, -1))

        np.savetxt(
            'Ikeda_Carpenter Parameters for Ei= {}.xlsx'.format(self.Ei),
            np.c_[peak_positionE, R_fit, a_fit, b_fit, s_fit, t0_fit])

        return (RF_mcvine, RFE_mcvine, RF_intp, RFE_intp, RF_Fit, R_fit, a_fit,
                b_fit, s_fit, t0_fit, p_fit, peak_positionE, error)
Beispiel #21
0
def fit_model(function,
              energy_fit,
              eqe_fit,
              p0=None,
              include_disorder=False
              ):
    """
    Function to perform curve fit using lmfit
    This function is used for standard / disorder single peak fits.
    :param function: function to fit against (i.e. gaussian, gaussian_disorder etc.)
    :param energy_fit: energy values to fit against [list or array]
    :param eqe_fit: EQE values to fit against [list or array]
    :param p0: list of initial guesses for curve_fit function [list]
    :param include_disorder: boolean value
    :return: best_vals: list of best fit parameters [list]
             covar: covariance matrix of fit
             y_fit: calculated EQE values of the fit [list]
             r_squared: R^2 of the fit [float]
    """

    if p0 is None: # if no guess is given, initialize with all ones. This is consistent with curve_fit.
        if include_disorder:
            p0 = [1, 1, 1, 1]
        else:
            p0 = [1, 1, 1]

    gmodel = Model(function)

    gmodel.set_param_hint('Ect', min=0, max=1.6)
    gmodel.set_param_hint('l', min=0, max=0.6) # changed from 0.4
    gmodel.set_param_hint('f', min=0, max=0.1) # changed from 0.4

    if include_disorder:
        gmodel.set_param_hint('sig', min=0, max=0.2)

        result = gmodel.fit(eqe_fit,
                            f=p0[0],
                            l=p0[1],
                            Ect=p0[2],
                            sig=p0[3],
                            E=energy_fit
                            )

        f = float(result.params['f'].value)
        l = float(result.params['l'].value)
        Ect = float(result.params['Ect'].value)
        sig = float(result.params['sig'].value)

        best_vals = [f, l, Ect, sig]

        covar = result.covar
        if covar is None:
            covar = np.zeros((4, 4))

        y_fit = gmodel.eval(E=np.array(energy_fit),
                            f=f,
                            l=l,
                            Ect=Ect,
                            sig=sig
                            )
    else:
        result = gmodel.fit(eqe_fit,
                            f=p0[0],
                            l=p0[1],
                            Ect=p0[2],
                            E=energy_fit
                            )

        f = float(result.params['f'].value)
        l = float(result.params['l'].value)
        Ect = float(result.params['Ect'].value)

        best_vals = [f, l, Ect]

        covar = result.covar
        if covar is None:
            covar = np.zeros((4, 4))

        y_fit = gmodel.eval(E=np.array(energy_fit),
                            f=f,
                            l=l,
                            Ect=Ect
                            )

    r_squared = R_squared(eqe_fit, y_fit)

    return best_vals, covar, y_fit, r_squared
Beispiel #22
0
def slit_fit(nu,
             spec,
             init_params=None,
             lineshape='sGaussian',
             power_factor=1.,
             eval_only=False,
             save_fit=False,
             dir_save=None,
             file_name=None,
             **kwargs):
    r"""fitting the experimental slit function with a chosen lineshape

    .. attention::
        It is recommended to always look for initial parameters by using the
        `eval_only` option to roughly match the shape of the experimental slit
        function. The built-in initial parameters may not work for all the
        cases.

    Parameters
    ----------
    nu : 1d array of floats
        Spectral positions in [:math:`\mathrm{cm}^{-1}`].
    spec : 1d array of floats
        Experimentally obtained slit function, usually an isolated atomic line
        from a calibration lamp.
    init_params : dict, optional
        Initial fitting parameters for the lineshape. Refer to
        :mod:`carspy.convol_fcn.asym_Voigt` and
        :mod:`carspy.convol_fcn.asym_Gaussian` for the required arguments.
    lineshape : str, optional
        Type of the lineshape, by default 'sGaussian'. Choose between
        'sGaussian' and 'sVoigt'.
    eval_only : bool, optional
        If true, returns the evaluation with given initial parameters.
    save_fit : bool, optional
        If true, fit results will be saved in a pickle file.
    dir_save : str, optional
        If `save_fit` is true, a string to the desired directory for saving.
    file_name : str, optional
        If `save_fit` is true, specify the file name without file extension.

    Other Parameters
    ----------------
    **kwargs:
        Keyword arguments of the `Model.fit()` method from the module `lmfit`.

    Returns
    -------
    1d array
        If `eval_only` is true, the evaluation result is returned.

    """
    if lineshape == 'sGaussian':
        slit_func = partial(asym_Gaussian, power_factor=power_factor)
    elif lineshape == 'sVoigt':
        slit_func = partial(asym_Voigt, power_factor=power_factor)
    else:
        raise ValueError("Please choose between 'sGaussian' and 'sVoigt'")
    slit_func.__name__ = 'slit_func'

    fit_model = Model(
        slit_func,
        independent_vars='w',
    )

    if init_params is None:
        init_params = (('w0', 0, True), ('sigma', 2, True, 0.01, 10),
                       ('k', 2, True, 0, 10), ('a_sigma', -0.8, True, -5, 5),
                       ('a_k', 1, True, -5, 5), ('sigma_L_l', 0.1, True, 0.01,
                                                 5), ('sigma_L_h', 0.1, True,
                                                      0.01, 5), ('offset', 0,
                                                                 True, 0, 1))

    params = fit_model.make_params()
    params.add_many(*init_params)
    if eval_only:
        return fit_model.eval(params, w=nu)
    else:
        fit_result = fit_model.fit((spec / spec.max())**power_factor,
                                   params,
                                   w=nu,
                                   **kwargs)
        report_fit(fit_result, show_correl=True, modelpars=params)
        fit_result.plot()

        if save_fit and dir_save and file_name:
            path_write = Path(dir_save) / (file_name + '.pkl')
            pkl_dump(path_write, fit_result)
def use_lmfit(x_values, y_values,  functionlist, title,i, max_y_values):
    """
    Use lmfit.
    IN : x- and y-values.
         functionlist (which functions to use)

          adapted from https://stackoverflow.com/a/49843706/4173718

    TODO: Make all graphs in one graph
    """
    a_start, b_start, c_start = 0,0,0
    for function in functionlist:
        #placeholder0.subheader(f"LMFIT - {title} - {function}")

        # create a Model from the model function
        if function == "exponential":
            bmodel = Model(exponential)
            formula = "a * np.exp(-b * np.exp(-c * x))"
        elif function == "derivate":
            bmodel = Model(derivate)
            formula = "a * b * c * np.exp(b * (-1 * np.exp(-c * x)) - c * x)"
        elif function == "gaussian":
            bmodel = Model(gaussian_2)
            formula =  "a * np.exp(-((x - b) ** 2) / c)"
        else:
            st.write("Please choose a function")
            st.stop()

        # create Parameters, giving initial values
        #params = bmodel.make_params(a=4711, b=12, c=0.06)
        params = bmodel.make_params(a=a_start, b=b_start, c=c_start)  # IC BEDDEN MAART APRIL
        # params = bmodel.make_params()
        params["a"].min = a_start
        params["b"].min = b_start
        params["c"].min = c_start


        # do fit, st.write result
        result = bmodel.fit(y_values, params, x=x_values)
        a = round(result.params['a'].value,5)
        b= round(result.params['b'].value,5)
        c =round(result.params['c'].value,5)

        placeholder1.text(result.fit_report())
        with _lock:
            #fig1y = plt.figure()
            fig1y, ax1 = plt.subplots()
            ax2 = ax1.twinx()
            # plot results -- note that `best_fit` is already available
            ax1.scatter(x_values, y_values, color="#00b3b3", s=2)
            #ax1.plot(x_values, result.best_fit, "g")
            res = (f"a: {a} / b: {b} / c: {c}")
            plt.title(f"{title} / lmfit - {function}\n{formula}\n{res}")
            t = np.linspace(0.0, TOTAL_DAYS_IN_GRAPH, 10000)
            # use `result.eval()` to evaluate model given params and x
            ax1.plot(t, bmodel.eval(result.params, x=t), "r-")
            ax2.plot (t, derivate_of_derivate(t,a,b,c), color = 'purple')
            ax2.axhline(linewidth=1, color='purple', alpha=0.5, linestyle="--")
            #ax1.plot (t, derivate(t,26660.1, 9.01298, 0.032198), color = 'purple')
            #ax2.plot (t, derivate_of_derivate(t,26660.1, 9.01298, 0.032198), color = 'yellow')
            #plt.ylim(bottom=0)
            #ax1.ylim(0, max_y_values*1.1)
            #ax1.set_ylim(510,1200)
            #ax2.set_ylim(0,12)
            ax1.set_xlabel(f"Days from {from_}")

            ax1.set_ylabel(f"{title} - red")
            ax2.set_ylabel("delta - purple")
            #plt.show()
            filename= (f"{OUTPUT_DIR}lmfit_{title}_{function}_{i}")

            plt.savefig(filename, dpi=100, bbox_inches="tight")
            placeholder.pyplot(fig1y)

        if prepare_for_animation == False:
            with _lock:
                fig1z = plt.figure()
                # plot results -- note that `best_fit` is already available


                if function == "exponential":
                    plt.plot(t, derivate(t,a,b,c))
                    function_x = "derivate"
                    formula_x = "a * b * c * np.exp(b * (-1 * np.exp(-c * x)) - c * x)"

                elif function == "derivate":
                    plt.plot(t, exponential(t, a,b,c))
                    function_x = "exponential"
                    formula_x = "a * np.exp(-b * np.exp(-c * x))"

                else:
                    st.error("ERROR")
                    st.stop()
                plt.title(f"{title} / {function_x}\n{formula_x}\n{res}")
                t = np.linspace(0.0, TOTAL_DAYS_IN_GRAPH, 10000)

                # use `result.eval()` to evaluate model given params and x
                #plt.plot(t, bmodel.eval(result.params, x=t), "r-")
                plt.ylim(bottom=0)
                plt.xlabel(f"Days from {from_}")

                plt.ylabel(title)
                #plt.show()
                #filename= (f"{OUTPUT_DIR}lmfit_{title}_{function}_{i}")
                #plt.savefig(filename, dpi=100, bbox_inches="tight")
                st.pyplot(fig1z)

    return filename
Beispiel #24
0
def fine_s21_model(freqs_fine, fit_params):
    #use this after fitting the data to get a prettier model
    totalmodel = Model(resonator_cable)
    params = totalmodel.make_params(**fit_params)
    fine_model = totalmodel.eval(params, f=freqs_fine)
    return fine_model
Beispiel #25
0
class XRFAllElementModel():
    def __init__(self, exptdesc, linedict, xrffunc, comptonfunc, elasticfunc,
                 *args, **kwargs):
        """

        An XRF spectrum model
        LMFIT offers a range of options for coupling parameters and models but in order to be able to do 
        this it needs to manipulate parameters - in particular string expressions and this leads 
        big slowdowns if you've a large number of models or coupled parameters.     
        To speed up the calculation rather than create the XRF spectrum from a sum of Gaussian Models
        we create a single model with many parameters.
        The basic lmfit model works as follows:
        parse the arguments of the input function.
        Build a list of param names from these arguments
        Apply paramhints to these param_names or make parameters from the param names
  
        This class will pass a basic line

        """
        self.linedict = linedict
        self.exptdesc = exptdesc

        #
        # xrf line model
        self.xrfmodel = Model(xrffunc,
                              prefix="xrf_",
                              independent_vars=['x', 'area', 'center'])
        self.set_param_hints_from_dict(self.xrfmodel, "element",
                                       xrffunc.__name__)
        self.xrfparams = self.xrfmodel.make_params()
        #self.xrfparams.pretty_print()
        # elastic model
        self.elasticmodel = Model(elasticfunc,
                                  prefix="elastic_",
                                  independent_vars=['x', 'area', 'center'])
        self.set_param_hints_from_dict(self.elasticmodel, "elastic",
                                       elasticfunc.__name__)
        self.elasticparams = self.elasticmodel.make_params()
        # compton model
        self.comptonmodel = Model(comptonfunc,
                                  prefix="compton_",
                                  independent_vars=['x', 'area', 'center'])
        self.set_param_hints_from_dict(self.comptonmodel, "compton",
                                       comptonfunc.__name__)
        self.comptonparams = self.comptonmodel.make_params()

    def set_param_hints_from_dict(self, model, linetype, linefuncname):

        avail_hints = self.exptdesc["lineshape"][linetype][linefuncname].keys()
        for key in avail_hints:
            if key in model._param_root_names:
                model.set_param_hint(key,expr=None,**self.exptdesc["lineshape"]\
                                      [linetype][linefuncname][key])

    def make_params(self):
        # A composite of the parameters..
        self.funcparams_all = Parameters()
        self.funcparams_all.update(self.xrfparams)
        self.funcparams_all.update(self.comptonparams)
        self.funcparams_all.update(self.elasticparams)

        # exclude pileups from the parameters
        for key in self.linedict:
            if not '+' in key:
                if "Elastic" in key:
                    self.funcparams_all.add(key,
                        **self.exptdesc["lineshape"]["elastic"]\
                        [self.elasticmodel.func.__name__]["area"])
                elif "Compton" in key:
                    self.funcparams_all.add(key,
                        **self.exptdesc["lineshape"]["compton"]\
                        [self.comptonmodel.func.__name__]["area"])
                else:
                    self.funcparams_all.add(key,
                        **self.exptdesc["lineshape"]["element"]\
                        [self.xrfmodel.func.__name__]["area"])

    #    self.funcparams_all.add("pileup_factor",value=0.05,min=1.0e-5,
    #                           max=2.,vary=True)

        return self.funcparams_all

    def compositefunc(self, params, **kwargs):

        xrf_sigma_keys = [s for s in self.xrfparams if 'sigma' in s]
        elastic_sigma_keys = [s for s in self.elasticparams if 'sigma' in s]
        compton_sigma_keys = [s for s in self.comptonparams if 'sigma' in s]
        #
        # common parameters
        # pileup_factor , fano
        #
        #      pileup_factor = params["pileup_factor"].value

        first = True
        x = kwargs.get('x', None)
        result = np.zeros(len(x))
        #
        # Do the basic lines XRF and Escape first...
        #
        for key, linegroup in self.linedict.iteritems():
            if key in params:
                for line in linegroup:
                    area = params[key].value * line.intensity
                    center = line.line_energy
                    # update funcparams
                    if isinstance(line, (XrayLine, EscapeLine)):
                        #             for ii in xrf_sigma_keys:
                        #                 params[ii].value = np.sqrt(params[ii].value**2 + \
                        #                          (line.line_energy*0.0001))
                        lineresult =\
                            self.xrfmodel.eval(params=params,area = area,
                                               center = center,**kwargs)
                    if isinstance(line, (ElasticLine)):
                        #            for ii in elastic_sigma_keys:
                        #                params[ii].value = np.sqrt(params[ii].value**2 + \
                        #                         (line.line_energy*0.0001))
                        lineresult=\
                            self.elasticmodel.eval(params=params,area = area,
                                                   center = center,**kwargs)

                    if isinstance(line, (ComptonLine)):
                        #           for ii in compton_sigma_keys:
                        #               params[ii].value = np.sqrt(params[ii].value**2 + \
                        #                        (line.line_energy*0.0001))
                        lineresult=\
                            self.comptonmodel.eval(params=params,area = area,
                                                   center = center,**kwargs)
                    if first:
                        result = lineresult
                        first = False
                    else:
                        result += lineresult
        #
        # generate the pileup lines...
        # you can convolute the whole line with itself to get the pileup
        # (basic code is a variation on what's done in pymca..)
        #
        #
        # The problem is largely in the intensity scaling. For a simple
        # 2-event summation you can just scale it by some factor
        # but for 3 event pileup the magnitude over the curve
        # grows rather than diminishes.
        #

#     result = result + pileup_factor*self.selfconvolute(result,**kwargs)

        return result

    def eval(self, params=None, **kwargs):
        result = self.compositefunc(params=params, **kwargs)
        return result

    def selfconvolute(self, spectra, **kwargs):
        x = kwargs.get('x', None)
        start_index = int(x[0] / 0.01)
        pileup_window = np.zeros(3 * len(spectra))
        result = np.zeros(len(spectra))
        window = spectra
        spectrum = copy(spectra)
        for i in range(2):
            pileup = np.convolve(spectrum, window)
            pileup = pileup / (window.sum())
            pileup_window[start_index:len(pileup) + start_index] += pileup[:]
            spectrum = copy(pileup_window[0:len(spectra)])
            result = result + spectrum
        return result

    def residuals(self, params, *args, **kwargs):
        # Do this to include errors as weights.
        weights = kwargs.get('weights', None)
        data = kwargs.get('data', None)
        x = kwargs.get('x', None)
        model = self.compositefunc(params, x=x)
        resids = model - data
        return resids / weights

    def fit(self, params, *args, **kwargs):
        return minimize(self.residuals, params, *args, **kwargs)
Beispiel #26
0
    cellModelV.set_param_hint('I0', min=0)

    #fitResult = cellModel.fit(ii, V=vv)
    #resultParams = fitResult.params
    #print(fitResult.fit_report())
    #print(fitResult.message)

    fitResult = cellModelV.fit(vv, I=ii, method='nelder')
    resultParams = fitResult.params
    print(fitResult.fit_report())
    print(fitResult.message)
    exit(code=0)

    #resultParams['Rsh'].value = resultParams['Rsh'].value + 1000
    #resultParams['Iph'].value = resultParams['Iph'].value - 0.09e-3
    #resultParams['n'].value = resultParams['n'].value + 0.2

    fig, ax = plt.subplots()
    fitVals = cellModel.eval(params=resultParams, V=vv)
    ax.plot(vv, fitVals, label='Fit')
    ax.plot(vv, ii, '.', label='Data')
    ax.legend()
    fig.tight_layout()

    print("SSE={:}".format(SSE(fitVals, ii)))

    plt.show()

    #cellModelInv = Model(cellEqnV)
    #print(f.name)
 
 #fitResult = cellModel.fit(ii, V=vv)
 #resultParams = fitResult.params
 #print(fitResult.fit_report())
 #print(fitResult.message)
 
 fitResult = cellModelV.fit(vv, I=ii,method='nelder')
 resultParams = fitResult.params
 print(fitResult.fit_report())
 print(fitResult.message)
 exit(code=0)
 
 #resultParams['Rsh'].value = resultParams['Rsh'].value + 1000
 #resultParams['Iph'].value = resultParams['Iph'].value - 0.09e-3
 #resultParams['n'].value = resultParams['n'].value + 0.2
 
 fig, ax = plt.subplots()
 fitVals = cellModel.eval(params=resultParams,V=vv)
 ax.plot(vv,fitVals,label='Fit')
 ax.plot(vv,ii,'.',label='Data')
 ax.legend()
 fig.tight_layout()
 
 
 print("SSE={:}".format(SSE(fitVals,ii)))
 
 plt.show()
 
 #cellModelInv = Model(cellEqnV)
 #print(f.name)
 
def AdvancedBraggEdgeFitting(
    myspectrum, myrange, myTOF, est_pos, est_sigma, est_alpha, bool_print,
    bool_average, bool_linear, bool_transmission
):  ## my range should be now the index position of the spectra that I want to study, est_pos is also the index position where the expected peak is

    #get the part of the spectrum that I want to fit
    mybragg = myspectrum[myrange[0]:myrange[1]]

    if (bool_average):
        mybragg = running_mean(mybragg, 3)

    t = myTOF[myrange[0]:myrange[1]]
    est_pos = est_pos - myrange[
        0]  # I move the estimated position relative to the studied range, this is an index
    t0_f = myTOF[
        est_pos +
        myrange[0]]  # this is the actual estimated first position in TOF [s]

    plt.figure()
    plt.plot(t, mybragg)
    plt.plot(t0_f, mybragg[est_pos], 'x', markeredgewidth=3, c='orange')
    plt.title('Bragg edge')
    plt.xlabel('Wavelenght [Å]')
    plt.ylabel('Tranmission I/I$_{0}$')
    #     plt.savefig('step1_fitting.pdf')

    t_before = t[0:est_pos]
    bragg_before = mybragg[0:est_pos]
    #     t_after= t[est_pos+int(est_pos*0.2):-1]
    #     bragg_after=mybragg[est_pos+int(est_pos*0.2):-1]
    t_after = t[est_pos + int(est_pos * 0.2):-1]
    bragg_after = mybragg[est_pos + int(est_pos * 0.2):-1]

    #first step: estimate the linear or exponential function before and after the Bragg Edge

    if (bool_linear):
        [slope_before,
         interception_before] = np.polyfit(t_before, bragg_before, 1)
        [slope_after, interception_after] = np.polyfit(t_after, bragg_after, 1)
        #first guess of paramters
        a2_f = slope_after
        a5_f = interception_before
        a6_f = slope_before
        a1_f = interception_after
        plt.figure()
        plt.plot(t_before, bragg_before, '.g')
        plt.plot(t_after, bragg_after, '.r')
        plt.plot(t, mybragg)
        plt.plot(t, interception_before + slope_before * t, 'g')
        plt.plot(t, interception_after + slope_after * t, 'r')
        plt.title('linear fitting before and after the given edge position')
        gmodel = Model(BraggEdgeLinear)
    else:
        [slope_before,
         interception_before] = np.polyfit(t_before, bragg_before, 1)
        [slope_after, interception_after] = np.polyfit(t_after, bragg_after, 1)
        #first guess of paramters
        a2_f = slope_after
        a5_f = interception_before
        a6_f = slope_before
        a1_f = interception_after

        exp_model_after = Model(exp_after)
        params = exp_model_after.make_params(a1=a1_f, a2=a2_f)
        result_exp_model_after = exp_model_after.fit(bragg_after,
                                                     params,
                                                     t=t_after)
        a1_f = result_exp_model_after.best_values.get('a1')
        a2_f = result_exp_model_after.best_values.get('a2')

        exp_model_before = Model(exp_combined)
        params = exp_model_before.make_params(a1=a1_f,
                                              a2=a2_f,
                                              a5=a5_f,
                                              a6=a6_f)
        params['a1'].vary = False
        params['a2'].vary = False
        result_exp_model_before = exp_model_before.fit(bragg_before,
                                                       params,
                                                       t=t_before)
        a5_f = result_exp_model_before.best_values.get('a5')
        a6_f = result_exp_model_before.best_values.get('a6')
        gmodel = Model(BraggEdgeExponential)
        plt.figure()
        plt.plot(t_before, bragg_before, '.r', label='int point')
        plt.plot(t_after, bragg_after, '.g', label='int point')
        plt.plot(t, mybragg)

        plt.plot(t,
                 interception_before + slope_before * t,
                 '--r',
                 label='firred line before')
        plt.plot(t,
                 interception_after + slope_after * t,
                 '--g',
                 label='fitted line after')
        plt.plot(t, exp_after(t, a1_f, a2_f), 'g', label='fitted exp before')
        plt.plot(t,
                 exp_combined(t, a1_f, a2_f, a5_f, a6_f),
                 'r',
                 label='fitted exp after')
        plt.xlabel('Wavelenght [Å]')
        plt.ylabel('Transmission I/I$_{0}$')
        plt.title('fitting before and after the given edge position')
        plt.legend()
#         plt.savefig('step2_fitting_legend.pdf')
#         plt.plot(t, BraggEdgeExponential(t,t0_f,est_alpha,est_sigma,a1_f,a2_f,a5_f,a6_f))

    sigma_f = est_sigma
    alpha_f = est_alpha
    # method='trust_exact'
    # method='nelder' #not bad
    # method='differential_evolution' # needs bounds
    # method='basinhopping' # not bad
    # method='lmsquare' # this should implement the Levemberq-Marquardt but it says Nelder-Mead method (which should be Amoeba)
    method = 'least_squares'  # default and it implements the Levenberg-Marquardt

    params = gmodel.make_params(t0=t0_f,
                                sigma=sigma_f,
                                alpha=alpha_f,
                                a1=a1_f,
                                a2=a2_f,
                                a5=a5_f,
                                a6=a6_f,
                                bool_trasmission=bool_transmission)
    print(bool_transmission)

    first_guess = gmodel.eval(params, t=t)
    plt.figure()
    plt.plot(t, mybragg, label='data')
    plt.plot(t, first_guess, '--b', label='initial model')
    plt.title('initial BE with given parameters')
    plt.xlabel('Wavelenght [Å]')
    plt.ylabel('Transmission I/I$_{0}$')
    plt.legend()
    #     plt.savefig('step3_fitting_legend.pdf')

    params['alpha'].vary = False
    params['sigma'].vary = False
    params['t0'].vary = False
    params['a2'].vary = False
    params['a5'].vary = False
    params['bool_transmission'].vary = False

    result1 = gmodel.fit(mybragg,
                         params,
                         t=t,
                         method=method,
                         nan_policy='propagate')
    #    print(result1.fit_report())

    a1_f = result1.best_values.get('a1')
    a6_f = result1.best_values.get('a6')

    params = gmodel.make_params(t0=t0_f,
                                sigma=sigma_f,
                                alpha=alpha_f,
                                a1=a1_f,
                                a2=a2_f,
                                a5=a5_f,
                                a6=a6_f,
                                bool_trasmission=bool_transmission)
    params['alpha'].vary = False
    params['sigma'].vary = False
    params['t0'].vary = False
    params['a1'].vary = False
    params['a6'].vary = False
    params['bool_transmission'].vary = False

    result2 = gmodel.fit(mybragg,
                         params,
                         t=t,
                         method=method,
                         nan_policy='propagate')

    a2_f = result2.best_values.get('a2')
    a5_f = result2.best_values.get('a5')

    params = gmodel.make_params(t0=t0_f,
                                sigma=sigma_f,
                                alpha=alpha_f,
                                a1=a1_f,
                                a2=a2_f,
                                a5=a5_f,
                                a6=a6_f,
                                bool_trasmission=bool_transmission)
    params['a2'].vary = False
    params['a5'].vary = False
    params['a1'].vary = False
    params['a6'].vary = False
    params['sigma'].vary = False
    params['alpha'].vary = False
    params['bool_transmission'].vary = False
    params['t0'].min = myTOF[myrange[0]]
    params['t0'].max = myTOF[myrange[1]]

    result3 = gmodel.fit(mybragg,
                         params,
                         t=t,
                         method=method,
                         nan_policy='propagate')

    t0_f = result3.best_values.get('t0')

    params = gmodel.make_params(t0=t0_f,
                                sigma=sigma_f,
                                alpha=alpha_f,
                                a1=a1_f,
                                a2=a2_f,
                                a5=a5_f,
                                a6=a6_f,
                                bool_trasmission=bool_transmission)
    params['a2'].vary = False
    params['a5'].vary = False
    params['a1'].vary = False
    params['a6'].vary = False
    params['bool_transmission'].vary = False
    params['t0'].min = myTOF[myrange[0]]
    params['t0'].max = myTOF[myrange[1]]
    params['alpha'].min = 0.0
    params['alpha'].max = 1.5
    params['sigma'].min = 0.0
    params['sigma'].max = 1.5

    result4 = gmodel.fit(mybragg,
                         params,
                         t=t,
                         nan_policy='propagate',
                         method=method)

    sigma_f = result4.best_values.get('sigma')
    alpha_f = result4.best_values.get('alpha')
    t0_f = result4.best_values.get('t0')

    params = gmodel.make_params(t0=t0_f,
                                sigma=sigma_f,
                                alpha=alpha_f,
                                a1=a1_f,
                                a2=a2_f,
                                a5=a5_f,
                                a6=a6_f,
                                bool_trasmission=bool_transmission)
    params['t0'].vary = False
    params['sigma'].vary = False
    params['alpha'].vary = False
    params['bool_transmission'].vary = False

    result5 = gmodel.fit(mybragg,
                         params,
                         t=t,
                         nan_policy='propagate',
                         method=method)

    a1_f = result5.best_values.get('a1')
    a2_f = result5.best_values.get('a2')
    a5_f = result5.best_values.get('a5')
    a6_f = result5.best_values.get('a6')

    params = gmodel.make_params(t0=t0_f,
                                sigma=sigma_f,
                                alpha=alpha_f,
                                a1=a1_f,
                                a2=a2_f,
                                a5=a5_f,
                                a6=a6_f,
                                bool_trasmission=bool_transmission)
    params['a2'].vary = False
    params['a5'].vary = False
    params['a1'].vary = False
    params['a6'].vary = False
    params['bool_transmission'].vary = False
    params['t0'].min = myTOF[myrange[0]]
    params['t0'].max = myTOF[myrange[1]]
    params['alpha'].min = 0.0
    params['alpha'].max = 1.5
    params['sigma'].min = 0.0
    params['sigma'].max = 1.5

    result6 = gmodel.fit(mybragg,
                         params,
                         t=t,
                         nan_policy='propagate',
                         method=method)

    t0_f = result6.best_values.get('t0')
    sigma_f = result6.best_values.get('sigma')
    alpha_f = result6.best_values.get('alpha')

    params = gmodel.make_params(t0=t0_f,
                                sigma=sigma_f,
                                alpha=alpha_f,
                                a1=a1_f,
                                a2=a2_f,
                                a5=a5_f,
                                a6=a6_f)
    params['bool_transmission'].vary = False
    params['t0'].min = myTOF[myrange[0]]
    params['t0'].max = myTOF[myrange[1]]
    params['alpha'].min = 0.0
    params['alpha'].max = 1.5
    params['sigma'].min = 0.0
    params['sigma'].max = 1.5

    result7 = gmodel.fit(mybragg,
                         params,
                         t=t,
                         nan_policy='propagate',
                         method=method)

    #     print(params)
    print(result7.fit_report())
    print(result7.covar)
    print('bool value, Boolean for whether error bars were estimated by fit.',
          result7.errorbars)
    print(result7.ci_out)  # print out the interval confidence
    #     print(result7.conf_interval())
    #     print(result7.ci_report()) # this crashes sometimes when the MinimizerException: Cannot determine Confidence Intervals without sensible uncertainty estimates

    t0_f = result7.best_values.get('t0')
    sigma_f = result7.best_values.get('sigma')
    alpha_f = result7.best_values.get('alpha')
    a1_f = result7.best_values.get('a1')
    a2_f = result7.best_values.get('a2')
    a5_f = result7.best_values.get('a5')
    a6_f = result7.best_values.get('a6')

    #    Get the extrema for edge height fitting
    fitted_data = result7.best_fit
    pos_extrema = []

    ## Attempt n.1 -------- Here I was searching the last 0 value and the first value with 1.0 in the step function, however is it not a robust solution
    #     step_function = B(t,t0_f,alpha_f,sigma_f)
    #     min_pos = find_last(step_function,0.0)
    #     pos_extrema.append(min_pos)
    #     max_pos = find_first(step_function,0.99)
    #     pos_extrema.append(max_pos)

    if (bool_linear):
        fit_before = line_before(t, a5_f, a6_f)
        fit_after = line_after(t, a1_f, a2_f)
    else:
        fit_before = exp_combined(t, a1_f, a2_f, a5_f, a6_f)
        fit_after = exp_after(t, a1_f, a2_f)

    fit_edge = B(t, t0_f, alpha_f, sigma_f, bool_transmission)

    plt.figure()
    plt.plot(t, fit_before, 'o-')
    plt.plot(t, fit_after, 'o-')
    plt.plot(t, fitted_data, '.-')

    index_t0 = find_nearest(t, t0_f)

    # Attempt n.2 ------This is Florencia's approach: this gives an overestimation in most cases of the edge height
    #     pos_extrema.append(fit_before[index_t0])
    #     pos_extrema.append(fit_after[index_t0])

    # Attempt n.3 ------ This approach is based on the difference between the fit before and after the edge and the fitted data itself. so far, it gives the nicest results on the calibration sample, however the value used as threshold is not general and should probably be adjusted from case to case. So again it is not yet the final solution

    for i in range(0, len(fitted_data)):
        #         print(i,(fitted_data[i]-fit_before[i]))
        if (np.abs(fitted_data[i] - fit_before[i]) > 1e-4):
            pos_extrema.append(i - 1)
            break

    for i in range(len(fitted_data) - 1, 0, -1):  # here I am moving backwards
        #         print(i,(fitted_data[i]-fit_after[i]))
        if (np.abs(fitted_data[i] - fit_after[i]) > 1e-3):
            pos_extrema.append(i)
            break

#     # Attempt n.4 -- max and min before and after the estimated edge position, for the calibration sample works fine
#     range_min = t[0:index_t0]
#     range_max= t[index_t0:-1]
#     min_fit = np.min(fitted_data[0:index_t0])
#     max_fit = np.max(fitted_data[index_t0:-1])
#     pos_min = find_nearest(fitted_data[0:index_t0], min_fit)
#     pos_max = index_t0+find_nearest(fitted_data[index_t0:-1], max_fit)

## For other attempts have a look in the SENJU branch

    height = np.abs(mybragg[pos_extrema[0]] - mybragg[pos_extrema[1]])

    plt.figure()
    plt.plot(t, mybragg)
    #     plt.plot(t, result7.init_fit, 'k--')

    plt.plot(t,
             result1.best_fit,
             '--',
             color='gray',
             label='intermediate steps')
    plt.plot(t, result1.init_fit, '--', color='gray')
    plt.plot(t, result2.best_fit, '--', color='gray')
    plt.plot(t, result3.best_fit, '--', color='gray')
    plt.plot(t, result4.best_fit, '--', color='gray')
    plt.plot(t, result5.best_fit, '--', color='gray')
    plt.plot(t, result6.best_fit, '--', color='gray')
    plt.plot(t, result7.best_fit, 'r', linewidth='1.5', label='final fit')
    plt.legend()
    plt.xlabel('Wavelenght [Å]')
    plt.ylabel('Transmission I/I$_{0}$')

    plt.plot(t0_f, result7.best_fit[index_t0], 'ok')
    plt.plot(t[pos_extrema[0]], result7.best_fit[pos_extrema[0]], 'ok')
    plt.plot(t[pos_extrema[1]], result7.best_fit[pos_extrema[1]], 'ok')
    plt.title('edge fitting and estimated edge position')
    plt.show()

    if (bool_print):
        print('first iteration: ', result1.fit_report())
        print('second iteration: ', result2.fit_report())
        print('third iteration: ', result3.fit_report())
        print('fourth iteration: ', result4.fit_report())
        print('fifth iteration: ', result5.fit_report())
        print('sixth iteration: ', result6.fit_report())

    return {
        't0': t0_f,
        'sigma': sigma_f,
        'alpha': alpha_f,
        'a1': a1_f,
        'a2': a2_f,
        'a5': a5_f,
        'a6': a6_f,
        'final_result': result7,
        'fitted_data': fitted_data,
        'pos_extrema': pos_extrema,
        'height': height
    }
Beispiel #29
0
def echo_fits():
    """
    Fits a Gaussian with a linear background to each of the echo peaks, finds the centroid and top of
    the Gaussian, then fits the echo_as_T2 function to the points given by x=centroid, y=top.
    """
    xrs, yrs, xr, yr, filename, dat1 = range_to_list()
    cents: List[float] = []
    cents_uncert: List[float] = []
    heights: List[float] = []
    heights_uncert: List[float] = []
    for i in range(0, len(xrs)):
        mdl = GaussianModel(prefix='G_')
        lne = LinearModel(prefix='L_')
        params = mdl.guess(yrs[i], x=xrs[i])
        params += lne.guess(yrs[i], x=xrs[i])
        max_y = np.max(yrs[i])
        min_y = np.min(yrs[i])
        max_x = np.max(yrs[i])
        min_x = np.min(yrs[i])
        predicted_slope = (max_y - min_y) / (max_x - min_x)
        params.add('L_slope',
                   value=predicted_slope,
                   min=predicted_slope * 1.1,
                   max=predicted_slope * 0.9)
        params.add('L_intercept',
                   value=min_y,
                   min=min_y * 0.9,
                   max=min_y * 1.1)
        params.add('G_height',
                   value=max_y - min_y,
                   min=(max_y - min_y) * 0.99,
                   max=(max_y - min_y) * 1.05)
        model = mdl + lne
        result = model.fit(yrs[i], params, x=xrs[i], method='leastsq')
        cent: float = result.params['G_center'].value
        amp: float = result.params['G_height'].value
        inter: float = result.params['L_intercept'].value
        grad: float = result.params['L_slope'].value
        height: float = amp + ((cent * grad) + inter)
        heights.append(height)
        cents.append(cent)
        cents_uncert.append(result.params['G_center'].stderr)
        partial_amp = 1
        partial_grad = cent
        partial_x = grad
        partial_inter = 1
        amp_term = partial_amp * result.params['G_height'].stderr
        grad_term = partial_grad * result.params['L_slope'].stderr
        x_term = partial_x * np.mean(np.diff(xrs[i]))
        inter_term = partial_inter * result.params['L_intercept'].stderr
        height_uncert = np.sqrt(amp_term**2 + grad_term**2 + x_term**2 +
                                inter_term**2)
        heights_uncert.append(height_uncert)
    heights = np.array(heights)
    cents = np.array(cents)
    maxy = np.max(heights)
    miny = np.min(heights)
    decay_pos = np.where(heights == find_nearest(heights, maxy / e))[0][0]
    decay_pos_time = cents[decay_pos]
    avg_y_sep = abs(np.mean(np.diff(heights)))
    efit = Model(echo_as_T2)
    param = efit.make_params()
    param.add('M0', value=maxy, min=maxy * 0.8, max=maxy + (avg_y_sep * 2))
    param.add('T2',
              value=decay_pos_time,
              min=decay_pos_time * 0.1,
              max=decay_pos_time * 1.5)
    param.add('c', value=miny * 0.3, min=miny * 0.1, max=miny * 1)
    param.add('ph', value=cents[0] * 0.1, min=0, max=cents[0] * 1)
    result_2 = efit.fit(
        heights,
        param,
        t=cents,
        method='leastsq',
        weights=np.sqrt(
            np.mean(np.diff(dat1['m']))**2 + np.array(heights_uncert)**2) /
        heights)
    print(result_2.fit_report())
    print('\n', result_2.params.pretty_print(fmt='e', precision=2))
    ax = plt.gca()
    ax.set_xlabel('Time (s)', fontsize=14)
    ax.set_ylabel('Magnetization (A/m)', fontsize=14)
    xes = np.linspace(np.min(cents), np.max(cents), 100)
    y = efit.eval(t=xes, params=result_2.params)
    plt.plot(xes, y, antialiased=True)
    plt.plot(cents, heights, 'x', ms=8, color='k')
    plt.plot(dat1['t'],
             dat1['m'],
             lw=2,
             antialiased=True,
             color='#4a4a4a',
             zorder=1)
    plt.title(filename)
    plt.xlim(left=0, right=np.max(cents) * 1.1)
    plt.ylim(bottom=0, top=result_2.params['M0'].value * 1.3)
    plt.axhline(result_2.params['M0'].value,
                color='k',
                ls='--',
                alpha=0.7,
                lw=1,
                zorder=2)
    plt.axhline(result_2.params['M0'].value / e,
                color='k',
                ls='--',
                alpha=0.7,
                lw=1,
                zorder=2)
    plt.text(0.9,
             0.9,
             "T_1: {:.4f} s".format(result_2.params['T2'].value),
             horizontalalignment='center',
             verticalalignment="center",
             transform=ax.transAxes,
             bbox={
                 'pad': 8,
                 'fc': 'w'
             },
             fontsize=14)
    plt.tight_layout()
    plt.tick_params(axis='both', which='major', labelsize=13)
    fig_manager = plt.get_current_fig_manager()
    fig_manager.window.showMaximized()
    plt.show()
Beispiel #30
0

def galstep(r, mass, a):
    return (mass / (2 * np.pi)) * (a / (r * (r + a)**3))


gmodel = Model(gaussian)
galmodel = Model(galstep)

gauss_params = gmodel.make_params(cen=5, amp=200, wid=1)
galstep_params = galmodel.make_params(mass=2.3e+10, a=1.5)

x = np.linspace(0.1, 10, 201)
#y_gauss = gmodel.eval(gauss_params, x=x)
#y_galstep = galmodel.eval(galstep_params, r=x)
y_gauss = gmodel.eval(x=x, cen=6.5, amp=100, wid=2.0)
y_galstep = galmodel.eval(r=x, mass=3.0e+10, a=3.0)

result_gauss = gmodel.fit(y_gauss, gauss_params, x=x)
result_galstep = galmodel.fit(y_galstep, galstep_params, r=x)

print(result_gauss.fit_report())
print(result_galstep.fit_report())

fig, axs = plt.subplots(1, 2)
axs[0].plot(x, y_gauss, 'o')
axs[0].plot(x, result_gauss.init_fit, 'k--', label='init fit')
axs[0].plot(x, result_gauss.best_fit, 'r-', label='best fit')
axs[0].legend()

axs[1].plot(x, y_galstep, 'o')
Beispiel #31
0
def main():

    '''
    parser = argparse.ArgumentParser(prog='enamelsample',
             description='Resample image of enamel to standard grid',
             add_help=True)
    parser.add_argument('images', type=str, nargs='+', help='Images of enamel 1.')
    #parser.add_argument('images2', type=str, nargs='+', help='Images of enamel 2.')
    parser.add_argument('-sp', '--spacing', type=float, default=x_resampling, help='Marker spacing (in pixels).')
    parser.add_argument('-ex', '--exact', type=float, default=10., help='Exactness of baseline spline.')
    parser.add_argument('-l', '--order-by-length', action='store_true',
                              help='Order teeth according to length.')
    parser.add_argument('-s', '--show', action='store_true', help='Show plot.')
    parser.add_argument('-o', '--output-dir', type=str, default='likelihood min model ',
                              help='Directory in which to store output.')
    parser.add_argument('-f', '--output', type=str, default='likelihood_min_model.h5',
                        help='Name of mineralization model file to be created.')
    parser.add_argument('-p', '--partitions', type=int, nargs=2, default=(1,1),
                              help='Number of partitions, and partition to operate on.')
    if 'python' in sys.argv[0]:
        offset = 2
    else:
        offset = 1
    args = parser.parse_args(sys.argv[offset:])

    warnings.simplefilter('ignore')
    
    # Load and standardize each tooth image
    alignedimg = []
    Nx, Ny = [], []
    age = []
    
    for i,fname in enumerate(args.images):
        print 'Processing %s ...' % fname
        
        img = load_image(fname)
        
        # Extract age from filename
        age.append(float(fname[1:4]))

        # Generate a spline for each tooth edge
        
        x, spl = get_baseline(img, exactness=args.exact)
        
        # Place makers along the bottom edge
        
        markerPos, markerDeriv = place_markers(x, spl[1], spacing=args.spacing)
        
        # Calculate y values of edges
        
        y = []
        for i in xrange(2):
            y.append(spl[i](x))
        
        # Calculate perpendicular lines to edges
        # Height of line is # in markerPos + #
    
        DeltaMarker = -np.ones((len(markerDeriv), 2), dtype='f8')
        DeltaMarker[:,0] = markerDeriv[:]
        markerPos2 = markerPos + 80. * DeltaMarker
        
        # Goal: take our x positions, step along the y positions, and get the
        # values from the image.
        # Plot everything
      
        # Resample image to standard grid
        alignedimg.append(get_image_values_2(img, markerPos, DeltaMarker, fname))
    '''

    # My sheep model data from images, video
    model_days = np.array([30., 40., 50., 60., 70., 80., 90., 100., 110., 120., 130., 140., 150., 160., 170., 180., 190., 200., 210., 220., 230., 240., 250., 260., 270., 280., 290., 300.])
    model_completion = np.array([2.3, 2.3, 2.76, 2.76, 4.6, 9.2, 11.96, 11.96, 13.8, 13.8, 15.64, 16.56, 16.56, 20.7, 20.7, 22.08, 23.46, 23.46, 23.46, 23.46, 23.46, 24.38, 24.84, 24.84, 27.6, 27.6, np.nan, 30.36])
    model_initiation = np.array([14.72, 15.64, 16.56, 17.48, 18.4, 24.84, 26.68, 26.68, 28.52, 28.52, 29.44, 30.36, 30.36, 31.28, 31.28, 31.74, 33.12, 33.12, 33.12, 33.12, 33.12, 33.58, 34.04, 34.04, 34.96, 34.96, np.nan, 34.96])
    model_min_length = model_initiation - model_completion
    model_length_percent = model_min_length / 39.
    model_increase_per_day = np.array([1.104, 0.552, 1.564, 1.932, 0.092, 0., 0.16866667, 0.16866667, 0.16866667, 0.16866667, 0.16866667, 0.16866667, 0.092, 0.092, 0.092, 0.092, 0.092, 0.092, 0.092, 0.10514286, 0.10514286, 0.10514286, 0.10514286, 0.10514286, 0.10514286, 0.10514286, 0.10514286, 0.10514286, 0.10514286, 0.10514286, 0.10514286, 0.10514286, 0.10514286, 0.092, 0.15333333, 0.15333333, 0.15333333, 0.138, 0.138, 0.184, 0.276, 0.21466667, 0.21466667, 0.21466667, 0., 0.552, 0.70533333, 0.70533333, 0.70533333, 1.104, 0.598, 0.598, 0., 0.299, 0.299, 0.299, 0.299, 0.1472, 0.1472, 0.1472, 0.1472, 0.1472, 0.092, 0.092, 0.092, 0.092, 0.092, 0.092, 0.092, 0.092, 0.092, 0.092, 0.092, 0.092, 0.092, 0.092, 0.092, 0.0736, 0.0736, 0.0736, 0.0736, 0.0736, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0.05952941, 0., 0.092, 0.05366667, 0.05366667, 0.05366667, 0.05366667, 0.05366667, 0.05366667, 0.05366667, 0.05366667, 0.05366667, 0.05366667, 0.05366667, 0.05366667, 0.04293333, 0.04293333, 0.04293333, 0.04293333, 0.04293333, 0.04293333, 0.04293333, 0.04293333, 0.04293333, 0.04293333, 0.04293333, 0.04293333, 0.04293333, 0.04293333, 0.04293333, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.03942857, 0.0368, 0.0368, 0.0368, 0.0368, 0.0368, 0.0368, 0.0368, 0.0368, 0.0368, 0.0368, 0.0368, 0.0368, 0.0368, 0.0368, 0.0368, 0., 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.03504762, 0.046, 0.046, 0.0345, 0.0345, 0.0345, 0.0345, 0.0345, 0.0345, 0.0345, 0.0345, 0., 0.046, 0.046, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.036, 0.04025, 0.04025, 0.04025, 0.04025, 0.04025, 0.04025, 0.04025, 0.04025, 0.04025, 0.04025, 0.04025, 0.04025, 0.04025, 0.04025, 0.04025, 0.04025, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.0644, 0.0644, 0.0644, 0.0644, 0.0644, 0.0644, 0.0644, 0.0644, 0.0644, 0.0644]) 
    for i in xrange(np.size(model_increase_per_day)):
        if model_increase_per_day[i] > 0.4:
            model_increase_per_day[i] = 0.40
    model_pct_increase_per_day = model_increase_per_day / np.max(model_increase_per_day)

    # Kierdorf 2013 data
    kday = np.array([7.5, 21.5, 49.5, 63.3, 73., 154., 168., 185.5, 199., 212.5, 230., 247.5])
    kext = np.array([177.6, 168.4, 180., 131.7, 109.9, 40.4, 35.5, 35.0, 33.2, 27.1, 28.0, 29.3])

    tooth_days = np.array([1., 9., 11., 19., 21., 30., 31., 31., 38., 42., 54., 56., 56., 58., 61., 66., 68., 73., 78., 84., 88., 92., 97., 100., 101., 101., 104., 105., 124., 127., 140., 140., 157., 167., 173., 174., 179., 202., 222., 235., 238., 251., 259., 274.])
    tooth_extension = np.array([9.38, 8.05, 11.32, 9.43, 13.34, 16.19, 13.85, 15.96, 15.32, 14.21, 17.99, 19.32, 19.32, 18.31, 17.53, 18.68, 18.49, 22.08, 23.14, 19.92, 27.97, 24.38, 25.53, 29.07, 27.65, 26.27, 27.55, 24.33, 29.03, 29.07, 30.36, 31.79, 31.37, 31.28, 35.79, 29.81, 31.79, 34.04, 33.21, 34.50, 33.76, 33.40, 36.34, 33.63])
    tooth_35p = np.array([2.07, 1.52, 2.39, 2.67, 4.60, 7.04, 4.55, 5.47, 5.47, 4.83, 8.19, 9.98, 9.75, 9.89, 9.29, 10.40, 8.88, 12.88, 14.49, 11.96, 19.04, 17.48, 16.74, 20.61, 18.86, 17.34, 19.92, 14.67, 22.03, 22.91, 24.47, 26.08, 26.13, 25.94, 34.45, 25.35, 26.91, 30.08, 30.68, 33.49, 28.29, 28.34, 35.83, 33.63])
    tooth_70p = np.array([np.nan, np.nan, np.nan, np.nan, np.nan, 2.76, np.nan, np.nan, np.nan, np.nan, 3.68, 4.60, 4.69, 5.11, 4.88, 5.75, 4.74, 7.36, 8.97, 5.15, 13.62, 12.33, 11.13, 14.54, 13.25, 10.81, 13.25, 8.69, 15.78, 17.16, 19.27, 20.56, 19.87, 21.48, 30.27, 20.01, 22.17, 24.56, 26.27, 28.11, 23.55, 23.83, 36.34, 29.49])
    tooth_mat_length = tooth_extension - tooth_70p / np.percentile(tooth_extension, 95)

    tooth_70p_days = np.array([30., 54., 56., 56., 58., 61., 66., 68., 73., 78., 84., 88., 92., 97., 100., 101., 101., 104., 105., 124., 127., 140., 140., 157., 167., 173., 174., 179., 202., 222., 235., 238., 251., 259., 274.])
    tooth_70p_b = np.array([2.76, 3.68, 4.60, 4.69, 5.11, 4.88, 5.75, 4.74, 7.36, 8.97, 5.15, 13.62, 12.33, 11.13, 14.54, 13.25, 10.81, 13.25, 8.69, 15.78, 17.16, 19.27, 20.56, 19.87, 21.48, 30.27, 20.01, 22.17, 24.56, 26.27, 28.11, 23.55, 23.83, 36.34, 29.49])

    p0_var_ext = np.array([30.34, .006102, -10.54])
    p0_var_p35 = np.array([23., .008, 13.])
    p0_var_p70 = np.array([25., .006, 110.])

    days = np.linspace(-50, 350, 401)
    ext_variables, ext_pcov = curve_fit(est_tooth_extension, tooth_days, tooth_extension, p0_var_ext)
    p35_variables, p35_pcov = curve_fit(est_tooth_extension, tooth_days, tooth_35p, p0_var_p35)
    p70_variables, p70_pcov = curve_fit(est_tooth_extension, tooth_70p_days, tooth_70p_b, p0_var_p70)
    p70_variables2, p70_pcov2 = leastsq(func=curve_residuals, x0=p70_variables, args=(p0_var_p70, tooth_70p_days, tooth_70p_b))
    print ext_variables
    print p35_variables
    print p70_variables
    print p70_variables2
    
    extension_erf = est_tooth_extension(days, ext_variables[0], ext_variables[1], ext_variables[2])
    p35_erf = est_tooth_extension(days, p35_variables[0], p35_variables[1], p35_variables[2])
    p70_erf = est_tooth_extension(days, p70_variables2[0], p70_variables2[1], p70_variables2[2])

    diff_extension_erf = np.diff(extension_erf) * 1000
    diff_p35_erf = np.diff(p35_erf) * 1000
    diff_p70_erf = np.diff(p70_erf) * 1000

    ext_zero = ext_variables[1] - ext_variables[2]*spec.erfinv((36. - ext_variables[0])/ext_variables[0])
    p35_zero = p35_variables[1] - p35_variables[2]*spec.erfinv((36. - p35_variables[0])/p35_variables[0])
    p70_zero = p70_variables2[1] - p70_variables2[2]*spec.erfinv((36. - p70_variables2[0])/p70_variables2[0])
    print ext_zero, p35_zero, p70_zero 

    gmod = Model(est_tooth_extension)
    print gmod.eval(x=tooth_70p_b, amplitude=25., slope=.006, offset=110.)


    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax2 = ax.twinx()
    ax2.plot(days[1::4], diff_extension_erf[::4], 'b.', label=r'$ \mathrm{extension} \ \Delta $')
    ax2.plot(days[1::4], diff_p35_erf[::4], 'm.', label=r'$ \mathrm{maturation} \ \Delta $')
    ax2.plot(days[1::4], diff_p70_erf[::4], 'r.', label=r'$ \mathrm{completion} \ \Delta $')
    ax2.set_ylim([0,300])
    ax2.set_xlim([-60,350])
    ax.plot(tooth_days, tooth_extension, marker='o', linestyle='none', color='b', label=r'$ \mathrm{extension}$')
    ax.plot(tooth_days, tooth_35p, marker='o', linestyle='none', color='m', label=r'$ \mathrm{maturation}$')
    ax.plot(tooth_days, tooth_70p, marker='o', linestyle='none', color='r', label=r'$ \mathrm{completion}$')
    ax.plot(days, extension_erf, linestyle='-', color='b', label=r'$ \mathrm{extension,} \ \mathrm{optimized} $')
    ax.plot(days, p35_erf, linestyle='-', color='m', label=r'$ \mathrm{maturation,} \ \mathrm{optimized} $')
    ax.plot(days, p70_erf, linestyle='-', color='r', label=r'$ \mathrm{completion,} \ \mathrm{optimized} $')
    ax.set_ylim([0,40])
    ax.set_xlim([-60,350])
    plt.title('Enamel secretion and maturation progress over time')
    ax.set_xlabel('Days after birth')
    ax.set_ylabel('Progress from cusp tip in mm')
    ax2.set_ylabel('Secretion or maturation speed in um/day')
    ax2.legend(loc='lower right', fancybox=True, framealpha=0.8)
    ax.legend(loc='upper left', fancybox=True, framealpha=0.8)

    plt.show()
    '''
    ax2 = ax.twinx()
    ax2.plot(xs, ys, color='g', label='radiograph extension, smooth')
    ax2.plot(days, increase_per_day, color='y', label='radiograph extension, raw')
    ax2.plot(kday, kext, color='k', mfc='none', marker='o', linestyle='none', label='histology extension')
    plt.show()
    '''



    return 0
Beispiel #32
0
    def ls_fit(self, add_params=None, path_fit=None, show_fit=False,
               eval_only=False, **kwargs):
        """
        Fitting the experimental CARS spectrum.

        .. attention::
            The least-quare fit module ``lmfit`` is necessary for this method.
            Please be aware that certain Python versions may not be supported
            by ``lmfit``. For displaying the fit results ``matplotlib`` will be
            needed as well.

        Parameters
        ----------
        add_params : nested tuple, optional
            List of parameters controlling the fitting process. This option can
            be used to modify these initial parameters:

            .. code-block:: python

                (('temperature', 2000, True, 250, 3000),
                 ('del_Tv', 0, False),
                 ('x_mol', 0.6, x_mol_var, 0.2, 1.5),
                 ('nu_shift', fit_params['nu_shift'], False),
                 ('nu_stretch', fit_params['nu_stretch'], False),
                 ('pump_lw', fit_params['pump_lw'], False),
                 ('param1', fit_params['param1'], False),
                 ('param2', fit_params['param2'], False),
                 ('param3', fit_params['param3'], False),
                 ('param4', fit_params['param4'], False),
                 ('param5', fit_params['param5'], False),
                 ('param6', fit_params['param6'], False))
            Each element of the nested tuple has the following element in
            order:
                variable_name : str
                    All the arguments of
                    :mod:`carspy.cars_fit.CarsFit.cars_expt_synth`
                    are admissible variables except for the independent
                    variable `nu_expt`.
                initial_guess : float
                    Initial guess or fixed value set for this variable.
                variable : bool
                    Determine if the variable is fixed (False) or not (True)
                    during the fit.
                lower_bound : float
                    Lower boundary for the fitting variable. If not provided,
                    negative infinity will be assumed.
                upper_bound : float
                    Upper boundary for the fitting variable. If not provide,
                    positive infinity will be assumed.
            For more details refer to the documentation of ``lmfit.Model``.
        path_fit : str
            Path to the `.pkl` file of fitting result created by
            :mod:`carspy.cars_fit.CarsFit.save_fit`. This allows importing
            the fitting result of an existing spectrum, such that the inferred
            values of certain parameters (such as those related to the
            spectrometer) could be re-used in the next fit. A standard use case
            for this would be the fitting result of a room-temperature
            spectrum. This is needed if the `fit` in `fit_mode` of
            :mod:`carspy.cars_fit.CarsFit` is set to `T_x`.
        show_fit : bool, optional
            If True, the fitting results will be reported and plotted. This is
            done via built-in functions in ``lmfit``.
        """
        # general setup
        fit_model = Model(self.cars_expt_synth, independent_vars=['nu_expt'])
        initi_params = []
        # different fitting modes
        if self.fit_mode['fit'] == 'T_x':
            if path_fit is None:
                raise ValueError("Please provide path to a .pkl file "
                                 "containing the fitting result of a spectrum")
            if self.fit_mode['chem_eq']:
                x_mol_var = False
            else:
                x_mol_var = True
            fit_params = pkl_load(path_fit).params
            initi_params = (('temperature', 2000, True, 250, 3000),
                            ('del_Tv', 0, False),
                            ('x_mol', 0.6, x_mol_var, 0.2, 1.5),
                            ('nu_shift', fit_params['nu_shift'], False),
                            ('nu_stretch', fit_params['nu_stretch'], False),
                            ('pump_lw', fit_params['pump_lw'], False),
                            ('param1', fit_params['param1'], False),
                            ('param2', fit_params['param2'], False),
                            ('param3', fit_params['param3'], False),
                            ('param4', fit_params['param4'], False),
                            ('param5', fit_params['param5'], False),
                            ('param6', fit_params['param6'], False))

        if self.fit_mode['fit'] == 'custom':
            if add_params is None:
                raise ValueError("Please specify fitting parameters first "
                                 "using add_params")
        params = fit_model.make_params()
        params.add_many(*initi_params)
        if add_params is not None:
            params.add_many(*add_params)

        if eval_only:
            return fit_model.eval(params, nu_expt=self.nu)
        else:
            self.fit_result = fit_model.fit(np.nan_to_num(self.spec_cars),
                                            params,
                                            nu_expt=self.nu, **kwargs)

            if show_fit:
                report_fit(self.fit_result, show_correl=True, modelpars=params)
                self.fit_result.plot()
Beispiel #33
0
phase = (bfield - popt["bfield_offset"]) * popt["radians_per_tesla"]
if config.getboolean("BOTH_BRANCHES"):
    fig, (ax_p, ax_n) = plt.subplots(2, 1, sharex=True)
    plot(
        phase / (2 * np.pi),
        ic_n / 1e-6,
        ax=ax_n,
        xlabel="phase [2π]",
        ylabel="switching current [μA]",
        label="data",
        marker=".",
    )
    if not args.dry_run:
        best_p, best_n = np.split(result.best_fit, 2)
        plot(phase / (2 * np.pi), best_n / 1e-6, ax=ax_n, label="fit")
    init_p, init_n = np.split(model.eval(bfield=bfield, params=params), 2)
    if args.plot_guess:
        plot(phase / (2 * np.pi), init_n / 1e-6, ax=ax_n, label="guess")
else:
    fig, ax_p = plt.subplots()
    if not args.dry_run:
        best_p = result.best_fit
    init_p = model.eval(bfield=bfield, params=params)
plot(
    phase / (2 * np.pi),
    ic_p / 1e-6,
    ax=ax_p,
    xlabel="phase [2π]",
    ylabel="switching current [μA]",
    label="data",
    marker=".",