예제 #1
0
def test_height_fwhm_calculation(peakdata):
    """Test for correctness of height and FWHM calculation."""
    # mu = 0
    # variance = 1.0
    # sigma = np.sqrt(variance)
    # x = np.linspace(mu - 20*sigma, mu + 20*sigma, 100.0)
    # y = norm.pdf(x, mu, 1)
    x = peakdata[0]
    y = peakdata[1]
    check_height_fwhm(x, y, lineshapes.voigt, models.VoigtModel())
    check_height_fwhm(x, y, lineshapes.pvoigt, models.PseudoVoigtModel())
    check_height_fwhm(x, y, lineshapes.pearson7, models.Pearson7Model())
    check_height_fwhm(x, y, lineshapes.moffat, models.MoffatModel())
    check_height_fwhm(x, y, lineshapes.students_t, models.StudentsTModel())
    check_height_fwhm(x, y, lineshapes.breit_wigner, models.BreitWignerModel())
    check_height_fwhm(x, y, lineshapes.damped_oscillator,
                      models.DampedOscillatorModel())
    check_height_fwhm(x, y, lineshapes.dho,
                      models.DampedHarmonicOscillatorModel())
    check_height_fwhm(x, y, lineshapes.expgaussian,
                      models.ExponentialGaussianModel())
    check_height_fwhm(x, y, lineshapes.skewed_gaussian,
                      models.SkewedGaussianModel())
    check_height_fwhm(x, y, lineshapes.doniach, models.DoniachModel())
    x = x-9  # Lognormal will only fit peaks with centers < 1
    check_height_fwhm(x, y, lineshapes.lognormal, models.LognormalModel())
예제 #2
0
def test_peak_like():
    # mu = 0
    # variance = 1.0
    # sigma = np.sqrt(variance)
    # x = np.linspace(mu - 20*sigma, mu + 20*sigma, 100.0)
    # y = norm.pdf(x, mu, 1)
    data = np.loadtxt('../examples/test_peak.dat')
    x = data[:, 0]
    y = data[:, 1]
    check_height_fwhm(x, y, lineshapes.voigt, models.VoigtModel())
    check_height_fwhm(x, y, lineshapes.pvoigt, models.PseudoVoigtModel())
    check_height_fwhm(x, y, lineshapes.pearson7, models.Pearson7Model())
    check_height_fwhm(x, y, lineshapes.moffat, models.MoffatModel())
    check_height_fwhm(x, y, lineshapes.students_t, models.StudentsTModel())
    check_height_fwhm(x, y, lineshapes.breit_wigner, models.BreitWignerModel())
    check_height_fwhm(x, y, lineshapes.damped_oscillator,
                      models.DampedOscillatorModel())
    check_height_fwhm(x, y, lineshapes.dho,
                      models.DampedHarmonicOscillatorModel())
    check_height_fwhm(x, y, lineshapes.expgaussian,
                      models.ExponentialGaussianModel())
    check_height_fwhm(x, y, lineshapes.skewed_gaussian,
                      models.SkewedGaussianModel())
    check_height_fwhm(x, y, lineshapes.donaich, models.DonaichModel())
    x = x - 9  # Lognormal will only fit peaks with centers < 1
    check_height_fwhm(x, y, lineshapes.lognormal, models.LognormalModel())
예제 #3
0
def make_peak_model(settings):
    
    if settings.peak_model == "GaussDerivative":
        return lmfit_custom_models.GaussDerivativeModel()
    elif settings.peak_model == "Voigt": 
        return lmfit_models.PseudoVoigtModel()
    else:
        return lmfit_models.GaussianModel()
예제 #4
0
    def model_gen(V_series, dQdV_series, cd, i, cyc, battery):
        """Develops initial model and parameters for battery data fitting.

        V_series = Pandas series of voltage data
        dQdV_series = Pandas series of differential capacity data
        cd = either 'c' for charge and 'd' for discharge.

        Output:
        par = lmfit parameters object
        mod = lmfit model object"""

        # generates numpy arrays for use in fitting
        sigx_bot, sigy_bot = fitters.cd_dataframe(V_series, dQdV_series, cd)

        # creates a polynomial fitting object
        mod = models.PolynomialModel(4)

        # sets polynomial parameters based on a
        # guess of a polynomial fit to the data with no peaks
        par = mod.guess(sigy_bot, x=sigx_bot)

        # prints a notice if no peaks are found
        if all(i) is False:
            notice = 'Cycle ' + str(cyc) + cd + \
                ' in battery ' + battery + ' has no peaks.'
            print(notice)

        # iterates over all peak indices
        else:
            for index in i:

                # generates unique parameter strings based on index of peak
                center, sigma, amplitude, fraction, comb = fitters.label_gen(
                    index)

                # generates a pseudo voigt fitting model
                gaus_loop = models.PseudoVoigtModel(prefix=comb)
                par.update(gaus_loop.make_params())

                # uses unique parameter strings to generate parameters
                # with initial guesses
                # in this model, the center of the peak is locked at the
                # peak location determined from PeakUtils

                par[center].set(sigx_bot[index], vary=False)
                par[sigma].set(0.01)
                par[amplitude].set(.05, min=0)
                par[fraction].set(.5, min=0, max=1)

                mod = mod + gaus_loop

        return par, mod
예제 #5
0
파일: MSPeakCalc.py 프로젝트: hechth/CoreMS
    def pseudovoigt(self,
                    oversample_multiplier=1,
                    delta_rp=0,
                    mz_overlay=1,
                    fraction=0.5):
        '''
        Legacy pseudovoigt lineshape function
        '''
        if self.resolving_power:

            # full width half maximum distance
            self.fwhm = (self.mz_exp / (self.resolving_power + delta_rp)
                         )  #self.resolving_power)

            # stardart deviation
            sigma = self.fwhm / 2

            # half width baseline distance

            #mz_domain = linspace(self.mz_exp - hw_base_distance,
            #                     self.mz_exp + hw_base_distance, datapoint)
            mz_domain = self.get_mz_domain(oversample_multiplier, mz_overlay)

            # gaussian_pdf = lambda x0, x, s: (1/ math.sqrt(2*math.pi*math.pow(s,2))) * math.exp(-1 * math.pow(x-x0,2) / 2*math.pow(s,2) )
            model = models.PseudoVoigtModel()

            # TODO derive amplitude
            gamma = sigma

            amplitude = (sqrt(2 * pi) * sigma) * self.abundance
            amplitude = (sqrt(pi / log(2)) * (pi * sigma * self.abundance)) / (
                (pi * (1 - gamma)) + (sqrt(pi * log(2)) * gamma))

            params = model.make_params(center=self.mz_exp, sigma=sigma)

            calc_abundance = model.eval(params=params, x=mz_domain)

            return mz_domain, calc_abundance

        else:

            raise LookupError(
                'resolving power is not defined, try to use set_max_resolving_power()'
            )
예제 #6
0
def test_height_and_fwhm_expression_evalution_in_builtin_models():
    """Assert models do not throw an ZeroDivisionError."""
    mod = models.GaussianModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9)
    params.update_constraints()

    mod = models.LorentzianModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9)
    params.update_constraints()

    mod = models.SplitLorentzianModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9, sigma_r=1.0)
    params.update_constraints()

    mod = models.VoigtModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9, gamma=1.0)
    params.update_constraints()

    mod = models.PseudoVoigtModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9, fraction=0.5)
    params.update_constraints()

    mod = models.MoffatModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9, beta=0.0)
    params.update_constraints()

    mod = models.Pearson7Model()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9, expon=1.0)
    params.update_constraints()

    mod = models.StudentsTModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9)
    params.update_constraints()

    mod = models.BreitWignerModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9, q=0.0)
    params.update_constraints()

    mod = models.LognormalModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9)
    params.update_constraints()

    mod = models.DampedOscillatorModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9)
    params.update_constraints()

    mod = models.DampedHarmonicOscillatorModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9, gamma=0.0)
    params.update_constraints()

    mod = models.ExponentialGaussianModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9, gamma=0.0)
    params.update_constraints()

    mod = models.SkewedGaussianModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9, gamma=0.0)
    params.update_constraints()

    mod = models.SkewedVoigtModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9, gamma=0.0,
                             skew=0.0)
    params.update_constraints()

    mod = models.DoniachModel()
    params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9, gamma=0.0)
    params.update_constraints()

    mod = models.StepModel()
    for f in ('linear', 'arctan', 'erf', 'logistic'):
        params = mod.make_params(amplitude=1.0, center=0.0, sigma=0.9, form=f)
        params.update_constraints()

    mod = models.RectangleModel()
    for f in ('linear', 'arctan', 'erf', 'logistic'):
        params = mod.make_params(amplitude=1.0, center1=0.0, sigma1=0.0,
                                 center2=0.0, sigma2=0.0, form=f)
        params.update_constraints()
예제 #7
0
    def model_gen(V_series, dQdV_series, cd, i, cyc, v_toappend, thresh):
        """Develops initial model and parameters for battery data fitting.
        V_series = Pandas series of voltage data
        dQdV_series = Pandas series of differential capacity data
        cd = either 'c' for charge and 'd' for discharge.
        v_toappend is the list of voltages to append to the peak indices 
        Output:
        par = lmfit parameters object
        mod = lmfit model object"""

        
        # generates numpy arrays for use in fitting
        sigx_bot, sigy_bot = fitters.cd_dataframe(V_series, dQdV_series, cd)
        if len(sigx_bot)>5 and sigx_bot[5]>sigx_bot[1]:
            # check if the voltage values are increasing - the right order for gaussian
            sigx_bot_new = sigx_bot
            sigy_bot_new = sigy_bot
            newi = i
        else:
            sigx_bot_new = sigx_bot[::-1] # reverses the order of elements in the array
            sigy_bot_new = sigy_bot[::-1]
            newi = np.array([], dtype = int)
            for elem in i:
                # append a new index, because now everything is backwards
                newi = np.append(newi, int(len(sigx_bot_new) - elem - 1))

        # creates a polynomial fitting object
        # prints a notice if no peaks are found
        if all(newi) is False or len(newi) < 1:
            notice = 'Cycle ' + str(cyc) + cd + \
                ' in battery ' + ' has no peaks.'
            print(notice)
            base_mod = models.GaussianModel(prefix = 'base_')
            mod = base_mod
            # changed from PolynomialModel to Gaussian on 10-10-18
            # Gaussian params are A, mew, and sigma
            # sets polynomial parameters based on a
            # guess of a polynomial fit to the data with no peaks
            #mod.set_param_hint('base_amplitude', min = 0)
            #mod.set_param_hint('base_sigma', min = 0.001)
            par = mod.make_params()
        # iterates over all peak indices
        else:
            # have to convert from inputted voltages to indices of peaks within sigx_bot
            user_appended_ind = []
            rev_user_append = []
            if len(v_toappend) > 0: 
                for vapp in v_toappend:
                    if sigx_bot.min()<=vapp<=sigx_bot.max():
                        #check if voltage given is valid
                        ind_app= np.where(np.isclose(sigx_bot, float(vapp), atol = 0.1))[0][0]
                        user_appended_ind.append(ind_app)
                        rev_user_app = np.where(np.isclose(sigx_bot_new, float(vapp), atol = 0.1))[0][0]
                        rev_user_append.append(rev_user_app)
                    # this gives a final list of user appended indices 
                i = i.tolist() + user_appended_ind
                newi = newi.tolist() + rev_user_append # combine the two lists of indices to get the final set of peak locations
            else:
                i = i.tolist()
                newi = newi.tolist()
            count = 0
            for index in newi:

                # generates unique parameter strings based on index of peak
                center, sigma, amplitude, fraction, comb = fitters.label_gen(
                    index)
                # generates a pseudo voigt fitting model
                gaus_loop = models.PseudoVoigtModel(prefix=comb)
                if count == 0:
                    mod = gaus_loop 
                    #mod.set_param_hint(amplitude, min = 0.001)
                    par = mod.make_params()
                    #par = mod.guess(sigy_bot_new, x=sigx_bot_new)
                    count = count + 1
                else: 
                    mod = mod + gaus_loop
                    #gaus_loop.set_param_hint(amplitude, min = 0.001)
                    par.update(gaus_loop.make_params())
                    count = count + 1 

                # uses unique parameter strings to generate parameters
                # with initial guesses
                # in this model, the center of the peak is locked at the
                # peak location determined from PeakUtils
                par[center].set(sigx_bot_new[index], vary=False)
                    # don't allow the centers of the peaks found by peakutsils to vary 
                par[sigma].set((np.max(sigx_bot_new)-np.min(sigx_bot_new))/100)
                par[amplitude].set((np.mean(sigy_bot_new))/50, min=0)
                par[fraction].set(.5, min=0, max=1)

        # then add the gaussian after the peaks
            base_mod = models.GaussianModel(prefix = 'base_')
            mod = mod + base_mod
            base_par = base_mod.make_params()
            base_par['base_amplitude'].set(np.mean(sigy_bot_new))
            # these are initial guesses for the base
            base_par['base_center'].set(np.mean(sigx_bot_new))
            base_par['base_sigma'].set((np.max(sigx_bot_new)-np.min(sigx_bot_new))/2)
            # changed from PolynomialModel to Gaussian on 10-10-18
            # Gaussian params are A, mew, and sigma
            # sets polynomial parameters based on a
            # guess of a polynomial fit to the data with no peaks
            #base_mod.set_param_hint('base_amplitude', min = 0)
            #base_mod.set_param_hint('base_sigma', min = 0.001)
            par.update(base_par)
        #mod.set_param_hint('base_height', min = 0, max = 0.01) 

        #par = mod.guess(sigy_bot_new, x=sigx_bot_new)
        #print(cyc)
        return par, mod, i
예제 #8
0
def model_gen(V_series, dQdV_series, cd, i, cyc, thresh):
    """Develops initial model and parameters for battery data fitting.
    V_series = Pandas series of voltage data
    dQdV_series = Pandas series of differential capacity data
    cd = either 'c' for charge and 'd' for discharge.
    i = list of peak indices found by peak finder
    Output:
    par = lmfit parameters object
    mod = lmfit model object"""

    # generates numpy arrays for use in fitting
    sigx_bot, sigy_bot = cd_dataframe(V_series, dQdV_series, cd)
    if len(sigx_bot) > 5 and sigx_bot[5] > sigx_bot[1]:
        # check if the voltage values are increasing - the right order for
        # gaussian
        sigx_bot_new = sigx_bot
        sigy_bot_new = sigy_bot
        newi = i
    else:
        sigx_bot_new = sigx_bot[::-1]
        # reverses the order of elements in the array
        sigy_bot_new = sigy_bot[::-1]
        newi = np.array([], dtype=int)
        for elem in i:
            # append a new index, because now everything is backwards
            newi = np.append(newi, int(len(sigx_bot_new) - elem - 1))
    if all(newi) is False or len(newi) < 1:
        base_mod = models.GaussianModel(prefix='base_')
        mod = base_mod
        par = mod.make_params()
    else:
        # have to convert from inputted voltages to indices of peaks within
        # sigx_bot
        user_appended_ind = []
        rev_user_append = []
        if not isinstance(i, list):
            i = i.tolist()
        if not isinstance(newi, list):
            newi = newi.tolist()
        count = 0
        for index in newi:

            # generates unique parameter strings based on index of peak
            center, sigma, amplitude, fraction, comb = label_gen(index)
            # generates a pseudo voigt fitting model
            gaus_loop = models.PseudoVoigtModel(prefix=comb)
            if count == 0:
                mod = gaus_loop
                par = mod.make_params()
                count = count + 1
            else:
                mod = mod + gaus_loop
                par.update(gaus_loop.make_params())
                count = count + 1
            par[center].set(sigx_bot_new[index], vary=False)
            par[sigma].set((np.max(sigx_bot_new) - np.min(sigx_bot_new)) / 100)
            par[amplitude].set((np.mean(sigy_bot_new)) / 50, min=0)
            par[fraction].set(.5, min=0, max=1)

    # then add the gaussian after the peaks
        base_mod = models.GaussianModel(prefix='base_')
        mod = mod + base_mod
        base_par = base_mod.make_params()
        base_par['base_amplitude'].set(np.mean(sigy_bot_new))
        # these are initial guesses for the base
        base_par['base_center'].set(np.mean(sigx_bot_new))
        base_par['base_sigma'].set(
            (np.max(sigx_bot_new) - np.min(sigx_bot_new)) / 2)
        par.update(base_par)
    return par, mod, i