Source code for apav.analysis.models
"""
This file is part of APAV.
APAV is a python package for performing analysis and visualization on
atom probe tomography data sets.
Copyright (C) 2018 Jesse Smith
APAV is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
APAV is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with APAV. If not, see <http://www.gnu.org/licenses/>.
"""
import numpy as n
from numpy.polynomial import Polynomial
from lmfit.models import Model, update_param_vals
from lmfit.models import ExponentialGaussianModel as _EXPGauss
from numpy import ndarray
[docs]class ExponentialGaussianModel(_EXPGauss):
"""
Exponential gaussian model
"""
def __init__(self, *args, **kwargs):
"""
This model defines an exponentially modified gaussian with refined parameter min/max/initial values
for APAV
"""
super().__init__(*args, **kwargs)
[docs] def guess(self, *args, **kwargs):
vals = super().guess(*args, **kwargs)
x = kwargs["x"]
vals["center"].set(max=x.min(), min=0)
vals["amplitude"].set(min=0)
return vals
[docs]class PowerLawShiftModel(Model):
"""
Shifted power law model
"""
def __init__(self, *args, **kwargs):
"""
This model defines a shifted power law with refined parameter min/max/initial values
for APAV
"""
def power_law(x, amplitude, center, exponent):
# Cannot take fractional power of negative numbers
xx = x - center
xx[xx < 0] = 1
return amplitude * xx**exponent
super().__init__(power_law, *args, **kwargs)
[docs] def guess(self, data, x: ndarray = None, **kwargs):
"""
Estimate initial model parameter values from data.
"""
try:
cen = x.min() - x.min() * 0.1
idx = n.argwhere(data > 0).ravel()
xx, yy = n.log((x[idx] - cen) + 1.0e-14), n.log(data[idx] + 1.0e-14)
amp, expon = Polynomial.fit(xx, yy, 1)
except TypeError:
cen = 0
expon, amp = 1, n.log(abs(max(data) + 1.0e-9))
pars = self.make_params(amplitude=n.exp(amp), exponent=expon, center=cen)
update_param_vals(pars, self.prefix, **kwargs)
pars["amplitude"].set(min=1)
pars["exponent"].set(min=-1e3, max=-1)
pars["center"].set(min=0, max=x.min())
return pars