def get_model(model_name, model_prefix=''): if model_name == 'voigt': mdl = models.VoigtModel(prefix=model_prefix) elif model_name == 'gauss': mdl = models.GaussianModel(prefix=model_prefix) elif model_name == 'constant': mdl = models.ConstantModel(prefix=model_prefix) elif model_name == 'linear': mdl = models.LinearModel(prefix=model_prefix) elif model_name == 'exp': mdl = models.ExponentialModel(prefix=model_prefix) elif model_name == 'logistic': mdl = models.StepModel(prefix=model_prefix, form='logistic') elif model_name == 'sine': mdl = models.SineModel(prefix=model_prefix) else: raise ValueError('Model name not recognized.') return mdl
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()
def fit_peak(self, roi=None, xpeak=None, sigma_guess=None, model_name='gauss-erf-const', **kwargs): """ Main routine """ # Exit if no roi if roi is None: self.fit = None self.model_name = None else: self.model_name = model_name # Start timer tic = time.time() # --------- # Setup ROI # --------- self.set_roi(roi) x = self.get_x_roi() y = self.get_y_roi() y_sig = self.get_y_sig_roi() x_widths = self.get_x_widths_roi() # --------------------------- # Guesses based on input data # --------------------------- # Set peak center to center of ROI if not given if xpeak is None: xpeak = (x[0] + x[-1]) / 2. # Guess sigma if not provided if sigma_guess is None: fwhm_guess = self.guess_fwhm(xpeak) sigma_guess = fwhm_guess / FWHM_SIG_RATIO # Heights at the sides of the ROI left_shelf_height = y[0] right_shelf_height = y[-1] # Line guess lin_slope = (y[-1] - y[0]) / (x[-1] - x[0]) lin_intercept = y[0] - lin_slope * x[0] # Two peaks guess (33 and 66 percent through ROI) xpeak0 = x[0] + (x[-1] - x[0]) * 0.33 xpeak1 = x[0] + (x[-1] - x[0]) * 0.66 # Index of at the ROI center ix_half = int(round(float(len(x)) / 2.)) # ------------------- # Setup fitting model # ------------------- if model_name == 'gauss-erf-const': # Models erf_mod = models.StepModel(form='erf', prefix='erf_') gauss_mod = models.GaussianModel(prefix='gauss_') bk_mod = models.ConstantModel(prefix='bk_') # Initialize parameters pars = erf_mod.make_params() pars.update(gauss_mod.make_params()) pars.update(bk_mod.make_params()) # Erfc (sigma and center are locked to gauss below) pars['erf_amplitude'].set(right_shelf_height - left_shelf_height, max=0.) # Gauss pars['gauss_center'].set( xpeak ) # , min=xpeak - 2 * fwhm_guess, max=xpeak + 2 * fwhm_guess) pars['gauss_sigma'].set(sigma_guess) pars['gauss_amplitude'].set(np.sum(y * x_widths), min=0) # Background pars['bk_c'].set(left_shelf_height, min=0.) # Same center and sigma pars.add('erf_center', expr='gauss_center') pars.add('erf_sigma', expr='gauss_sigma * {}'.format(FWHM_SIG_RATIO)) self.model = gauss_mod + erf_mod + bk_mod elif model_name == 'double-gauss-line': # Models lin_mod = models.LinearModel(prefix='lin_') g0_mod = models.GaussianModel(prefix='gauss0_') g1_mod = models.GaussianModel(prefix='gauss1_') # Initialize parameters pars = lin_mod.make_params() pars.update(g0_mod.make_params()) pars.update(g1_mod.make_params()) # Line (background) pars['lin_slope'].set(lin_slope, max=0.) pars['lin_intercept'].set(lin_intercept) # Gauss 0 (left) pars['gauss0_center'].set( xpeak0 ) # , min=xpeak - 2 * fwhm_guess, max=xpeak + 2 * fwhm_guess) pars['gauss0_sigma'].set(sigma_guess) pars['gauss0_amplitude'].set(np.sum(y[:ix_half] * x_widths[:ix_half]), min=0) # Gauss 1 (right) pars['gauss1_center'].set( xpeak1 ) # , min=xpeak - 2 * fwhm_guess, max=xpeak + 2 * fwhm_guess) pars['gauss1_sigma'].set(sigma_guess) pars['gauss1_amplitude'].set(np.sum(y[ix_half:] * x_widths[ix_half:]), min=0) self.model = lin_mod + g0_mod + g1_mod else: raise NotImplementedError( 'Model ({}) not recognized'.format(model_name)) # ----------- # Perform fit # ----------- try: self.fit = self.model.fit(y, pars, x=x, weights=1. / y_sig) except: print("[ERROR] Couldn't fit peak") self.fit = None if self.verbosity > 0: print('Fit time: {:.3f} seconds'.format(time.time() - tic))