Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
super(ExponentialModel, self).__init__(exponential, **kwargs)
def guess(self, data, x=None, **kwargs):
"""Estimate initial model parameter values from data."""
try:
sval, oval = np.polyfit(x, np.log(abs(data)+1.e-15), 1)
except TypeError:
sval, oval = 1., np.log(abs(max(data)+1.e-9))
pars = self.make_params(amplitude=np.exp(oval), decay=-1.0/sval)
return update_param_vals(pars, self.prefix, **kwargs)
__init__.__doc__ = COMMON_INIT_DOC
guess.__doc__ = COMMON_GUESS_DOC
class StepModel(Model):
r"""A model based on a Step function, with three Parameters:
``amplitude`` (:math:`A`), ``center`` (:math:`\mu`) and ``sigma`` (:math:`\sigma`).
There are four choices for ``form``:
- ``linear`` (the default)
- ``atan`` or ``arctan`` for an arc-tangent function
- ``erf`` for an error function
- ``logistic`` for a logistic function (see https://en.wikipedia.org/wiki/Logistic_function)
The step function starts with a value 0, and ends with a value of
:math:`A` rising to :math:`A/2` at :math:`\mu`, with :math:`\sigma`
setting the characteristic width. The functional forms are defined as:
.. math::
:nowrap:
An `lmfit.Model` object with all the parameters already initialized.
"""
peak1 = lmfit.models.GaussianModel(prefix='p1_')
peak2 = lmfit.models.GaussianModel(prefix='p2_')
model = peak1 + peak2
model.set_param_hint('p1_center', value=p1_center, min=-1, max=2)
model.set_param_hint('p2_center', value=p2_center, min=-1, max=2)
model.set_param_hint('p1_sigma', value=p1_sigma, min=0.01, max=0.2)
model.set_param_hint('p2_sigma', value=p2_sigma, min=0.01, max=0.2)
model.set_param_hint('p1_amplitude', value=1, min=0.01)
model.set_param_hint('p2_amplitude', value=1, min=0.01)
name = '2-gaussians'
if add_bridge:
bridge = lmfit.model.Model(bridge_function, prefix='br_')
model += bridge
model.set_param_hint('br_amplitude', value=0.0001, min=0)
model.set_param_hint('br_center1', min=0, expr='p1_center')
model.set_param_hint('br_center2', min=0, expr='p2_center')
model.set_param_hint('br_sigma1', min=0, expr='p1_sigma')
model.set_param_hint('br_sigma2', min=0, expr='p2_sigma')
name += '-bridge'
model.name = name
return model
def load_model(fname, funcdefs=None):
"""Load a saved Model from a file.
Parameters
----------
fname : str
Name of file containing saved Model.
funcdefs : dict, optional
Dictionary of custom function names and definitions.
Returns
-------
Model
"""
m = Model(lambda x: x)
with open(fname) as fh:
model = m.load(fh, funcdefs=funcdefs)
return model
"max({0}, (4*{prefix:s}center**2+{prefix:s}sigma**2)))")
self.set_param_hint('height', expr=fmt.format(tiny, prefix=self.prefix))
self.set_param_hint('fwhm', expr=fwhm_expr(self))
def guess(self, data, x=None, negative=False, **kwargs):
"""Estimate initial model parameter values from data."""
pars = guess_from_peak(self, data, x, negative,
ampscale=0.1, sigscale=0.1)
pars['%sgamma' % self.prefix].set(value=1.0, min=0.0)
return update_param_vals(pars, self.prefix, **kwargs)
__init__.__doc__ = COMMON_INIT_DOC
guess.__doc__ = COMMON_GUESS_DOC
class ExponentialGaussianModel(Model):
r"""A model of an Exponentially modified Gaussian distribution
(see https://en.wikipedia.org/wiki/Exponentially_modified_Gaussian_distribution) with
four Parameters ``amplitude`` (:math:`A`), ``center`` (:math:`\mu`),
``sigma`` (:math:`\sigma`), and ``gamma`` (:math:`\gamma`).
In addition, parameters ``fwhm`` and ``height`` are included as constraints
to report full width at half maximum and maximum peak height, respectively.
.. math::
f(x; A, \mu, \sigma, \gamma) = \frac{A\gamma}{2}
\exp\bigl[\gamma({\mu - x + \gamma\sigma^2/2})\bigr]
{\operatorname{erfc}}\Bigl(\frac{\mu + \gamma\sigma^2 - x}{\sqrt{2}\sigma}\Bigr)
where :func:`erfc` is the complementary error function.
def _set_paramhints_prefix(self):
self.set_param_hint('sigma', min=0)
self.set_param_hint('fwhm', expr=fwhm_expr(self))
self.set_param_hint('height', expr=height_expr(self))
def guess(self, data, x=None, negative=False, **kwargs):
"""Estimate initial model parameter values from data."""
pars = guess_from_peak(self, data, x, negative, ampscale=1.25)
return update_param_vals(pars, self.prefix, **kwargs)
__init__.__doc__ = COMMON_INIT_DOC
guess.__doc__ = COMMON_GUESS_DOC
class SplitLorentzianModel(Model):
r"""A model based on a Lorentzian or Cauchy-Lorentz distribution function
(see https://en.wikipedia.org/wiki/Cauchy_distribution), with four
parameters: ``amplitude``, ``center``, ``sigma``, and ``sigma_r``.
In addition, parameters ``fwhm`` and ``height`` are included as constraints
to report full width at half maximum and maximum peak height, respectively.
'Split' means that the width of the distribution is different between
left and right slopes.
.. math::
f(x; A, \mu, \sigma, \sigma_r) = \frac{2 A}{\pi (\sigma+\sigma_r)} \big[\frac{\sigma^2}{(x - \mu)^2 + \sigma^2} * H(\mu-x) + \frac{\sigma_r^2}{(x - \mu)^2 + \sigma_r^2} * H(x-\mu)\big]
where the parameter ``amplitude`` corresponds to :math:`A`, ``center`` to
:math:`\mu`, ``sigma`` to :math:`\sigma`, ``sigma_l`` to
def factory_two_asym_gaussians(add_bridge=False, p1_center=0.1, p2_center=0.9,
p1_sigma=0.03, p2_sigma=0.03):
"""Return a 2-Asym-Gaussians + (optional) bridge model that can fit data.
The Asym-Gaussian function is :func:`asym_gaussian`.
Arguments:
add_bridge (bool): if True adds a bridge function between the two
gaussian peaks. If False the model has only two Asym-Gaussians.
The other arguments are initial values for the model parameters.
Returns
An `lmfit.Model` object with all the parameters already initialized.
"""
peak1 = lmfit.model.Model(asym_gaussian, prefix='p1_')
peak2 = lmfit.model.Model(asym_gaussian, prefix='p2_')
model = peak1 + peak2
model.set_param_hint('p1_center', value=p1_center, min=-1, max=2)
#model.set_param_hint('p2_center', value=p2_center, min=-1, max=2)
model.set_param_hint('p1_sigma1', value=p1_sigma, min=0.01, max=0.2)
model.set_param_hint('p1_sigma2', value=p1_sigma, min=0.01, max=0.2)
model.set_param_hint('p2_sigma1', value=p2_sigma, min=0.01, max=0.2)
model.set_param_hint('p2_sigma2', value=p2_sigma, min=0.01, max=0.2)
model.set_param_hint('p1_amplitude', value=1, min=0.01)
model.set_param_hint('p2_amplitude', value=1, min=0.01)
model.set_param_hint('pos_delta', value=0.3, min=0)
model.set_param_hint('p2_center', min=-1, expr='p1_center + pos_delta')
name = '2-asym-gaussians'
self.set_param_hint('sigma_r', min=0)
self.set_param_hint('fwhm', expr=fwhm_expr.format(pre=self.prefix))
self.set_param_hint('height', expr=height_expr.format(np.pi, tiny, pre=self.prefix))
def guess(self, data, x=None, negative=False, **kwargs):
"""Estimate initial model parameter values from data."""
pars = guess_from_peak(self, data, x, negative, ampscale=1.25)
sigma = pars['%ssigma' % self.prefix]
pars['%ssigma_r' % self.prefix].set(value=sigma.value, min=sigma.min, max=sigma.max)
return update_param_vals(pars, self.prefix, **kwargs)
__init__.__doc__ = COMMON_INIT_DOC
guess.__doc__ = COMMON_GUESS_DOC
class VoigtModel(Model):
r"""A model based on a Voigt distribution function (see
https://en.wikipedia.org/wiki/Voigt_profile), with four Parameters:
``amplitude``, ``center``, ``sigma``, and ``gamma``. By default,
``gamma`` is constrained to have a value equal to ``sigma``, though it
can be varied independently. In addition, parameters ``fwhm`` and
``height`` are included as constraints to report full width at half
maximum and maximum peak height, respectively. The definition for the
Voigt function used here is
.. math::
f(x; A, \mu, \sigma, \gamma) = \frac{A \textrm{Re}[w(z)]}{\sigma\sqrt{2 \pi}}
where
.. math::
def __init__(self, data, model=None, all_models=None, axes_style={},
data_style={}, init_style={}, best_style={}, **kwargs):
# Dropdown menu of all subclasses of Model, incl. user-defined.
self.models_menu = Dropdown()
# Dropbox API is very different between IPy 2.x and 3.x.
if IPY2:
if all_models is None:
all_models = {m.__name__: m for m in Model.__subclasses__()}
self.models_menu.values = all_models
else:
if all_models is None:
all_models = [(m.__name__, m) for m in Model.__subclasses__()]
self.models_menu.options = all_models
self.models_menu.on_trait_change(self._on_model_value_change, 'value')
# Button to trigger fitting.
self.fit_button = Button(description='Fit')
self.fit_button.on_click(self._on_fit_button_click)
# Button to trigger guessing.
self.guess_button = Button(description='Auto-Guess')
self.guess_button.on_click(self._on_guess_button_click)
# Parameter widgets are not built here. They are (re-)built when
# the model is (re-)set.
"wofz((1j*{pre:s}gamma)/(max({0}, {pre:s}sigma*sqrt(2)))).real")
self.set_param_hint('fwhm', expr=fexpr.format(pre=self.prefix))
self.set_param_hint('height', expr=hexpr.format(tiny, pre=self.prefix))
def guess(self, data, x=None, negative=False, **kwargs):
"""Estimate initial model parameter values from data."""
pars = guess_from_peak(self, data, x, negative,
ampscale=1.5, sigscale=0.65)
return update_param_vals(pars, self.prefix, **kwargs)
__init__.__doc__ = COMMON_INIT_DOC
guess.__doc__ = COMMON_GUESS_DOC
class PseudoVoigtModel(Model):
r"""A model based on a pseudo-Voigt distribution function
(see https://en.wikipedia.org/wiki/Voigt_profile#Pseudo-Voigt_Approximation),
which is a weighted sum of a Gaussian and Lorentzian distribution function
that share values for ``amplitude`` (:math:`A`), ``center`` (:math:`\mu`)
and full width at half maximum ``fwhm`` (and so have constrained values of
``sigma`` (:math:`\sigma`) and ``height`` (maximum peak height).
A parameter ``fraction`` (:math:`\alpha`) controls the relative weight of
the Gaussian and Lorentzian components, giving the full definition of
.. math::
f(x; A, \mu, \sigma, \alpha) = \frac{(1-\alpha)A}{\sigma_g\sqrt{2\pi}}
e^{[{-{(x-\mu)^2}/{{2\sigma_g}^2}}]}
+ \frac{\alpha A}{\pi} \big[\frac{\sigma}{(x - \mu)^2 + \sigma^2}\big]
where :math:`\sigma_g = {\sigma}/{\sqrt{2\ln{2}}}` so that the full width
def constant(x, c=0.0):
return c
super(ConstantModel, self).__init__(constant, **kwargs)
def guess(self, data, **kwargs):
"""Estimate initial model parameter values from data."""
pars = self.make_params()
pars['%sc' % self.prefix].set(value=data.mean())
return update_param_vals(pars, self.prefix, **kwargs)
__init__.__doc__ = COMMON_INIT_DOC
guess.__doc__ = COMMON_GUESS_DOC
class ComplexConstantModel(Model):
"""Complex constant model, with wo Parameters: ``re``, and ``im``.
Note that ``re`` and ``im`` are 'constant' in the sense of having no
dependence on the independent variable ``x``, not in the sense of
being non-varying. To be clear, ``re`` and ``im`` will be Parameters
that will be varied in the fit (by default, of course).
"""
def __init__(self, independent_vars=['x'], prefix='', nan_policy='raise',
name=None, **kwargs):
kwargs.update({'prefix': prefix, 'nan_policy': nan_policy,
'independent_vars': independent_vars})
def constant(x, re=0., im=0.):
return re + 1j*im