|
|
@ -61,13 +61,22 @@ def expansion(x, amplitude=1.0, offset=0.0): |
|
|
|
def dampingOscillation(x, center=0, amplitude=1.0, frequency=1.0, decay=1.0, offset=0.0): |
|
|
|
return amplitude * np.exp(-decay*x)*np.sin(2*np.pi*frequency*(x-center)) + offset |
|
|
|
|
|
|
|
|
|
|
|
def double_structure(x, x1=0.25, x2=0.75, amplitude=1.0, center=0.0, sigma=1.0, a=-1.0, b=0, c=0): |
|
|
|
|
|
|
|
y = np.zeros(x.shape) |
|
|
|
|
|
|
|
return ((amplitude/(max(tiny, s2pi*sigma))) |
|
|
|
* exp(-(1.0*x-center)**2 / max(tiny, (2*sigma**2)))) |
|
|
|
def two_gaussian2d(x, y=0.0, A_amplitude=1.0, A_centerx=0.0, A_centery=0.0, A_sigmax=1.0, |
|
|
|
A_sigmay=1.0, B_amplitude=1.0, B_centerx=0.0, B_centery=0.0, B_sigmax=1.0, |
|
|
|
B_sigmay=1.0): |
|
|
|
"""Return a 2-dimensional Gaussian function. |
|
|
|
|
|
|
|
gaussian2d(x, y, amplitude, centerx, centery, sigmax, sigmay) = |
|
|
|
amplitude/(2*pi*sigmax*sigmay) * exp(-(x-centerx)**2/(2*sigmax**2) |
|
|
|
-(y-centery)**2/(2*sigmay**2)) |
|
|
|
|
|
|
|
""" |
|
|
|
z = A_amplitude*(gaussian(x, amplitude=1, center=A_centerx, sigma=A_sigmax) * |
|
|
|
gaussian(y, amplitude=1, center=A_centery, sigma=A_sigmay)) |
|
|
|
z += B_amplitude*(gaussian(x, amplitude=1, center=B_centerx, sigma=B_sigmax) * |
|
|
|
gaussian(y, amplitude=1, center=B_centery, sigma=B_sigmay)) |
|
|
|
return z |
|
|
|
|
|
|
|
|
|
|
|
class GaussianWithOffsetModel(Model): |
|
|
@ -178,6 +187,36 @@ class DampingOscillationModel(Model): |
|
|
|
return update_param_vals(pars, self.prefix, **kwargs) |
|
|
|
|
|
|
|
|
|
|
|
class TwoGaussian2dModel(Model): |
|
|
|
|
|
|
|
fwhm_factor = 2*np.sqrt(2*np.log(2)) |
|
|
|
height_factor = 1./2*np.pi |
|
|
|
|
|
|
|
def __init__(self, independent_vars=['x', 'y'], prefix='', nan_policy='raise', |
|
|
|
**kwargs): |
|
|
|
kwargs.update({'prefix': prefix, 'nan_policy': nan_policy, |
|
|
|
'independent_vars': independent_vars}) |
|
|
|
|
|
|
|
self.helperModel = Gaussian2dModel() |
|
|
|
|
|
|
|
super().__init__(two_gaussian2d, **kwargs) |
|
|
|
|
|
|
|
def guess(self, data, x, y, negative=False, **kwargs): |
|
|
|
pars_guess = guess_from_peak2d(self.helperModel, data, x, y, negative) |
|
|
|
pars = self.make_params(A_amplitude=pars_guess['amplitude'], A_centerx=pars_guess['centerx'], A_centery=pars_guess['centery'], |
|
|
|
A_sigmax=pars_guess['sigmax'], A_sigmay=pars_guess['sigmay'], |
|
|
|
B_amplitude=pars_guess['amplitude'], B_centerx=pars_guess['centerx'], B_centery=pars_guess['centery'], |
|
|
|
B_sigmax=pars_guess['sigmax'], B_sigmay=pars_guess['sigmay']) |
|
|
|
|
|
|
|
pars.add(f'{self.prefix}delta', value=-1, max=0, vary=True) |
|
|
|
pars[f'{self.prefix}A_sigmax'].set(expr=f'delta + {self.prefix}B_sigmax') |
|
|
|
pars[f'{self.prefix}A_sigmay'].set(min=0.0) |
|
|
|
pars[f'{self.prefix}B_sigmax'].set(min=0.0) |
|
|
|
pars[f'{self.prefix}B_sigmay'].set(min=0.0) |
|
|
|
|
|
|
|
return pars |
|
|
|
|
|
|
|
|
|
|
|
lmfit_models = {'Constant': ConstantModel, |
|
|
|
'Complex Constant': ComplexConstantModel, |
|
|
|
'Linear': LinearModel, |
|
|
@ -209,7 +248,8 @@ lmfit_models = {'Constant': ConstantModel, |
|
|
|
'Gaussian With Offset':GaussianWithOffsetModel, |
|
|
|
'Lorentzian With Offset':LorentzianWithOffsetModel, |
|
|
|
'Expansion':ExpansionModel, |
|
|
|
'Damping Oscillation Model':DampingOscillationModel |
|
|
|
'Damping Oscillation Model':DampingOscillationModel, |
|
|
|
'Two Gaussian-2D':TwoGaussian2dModel, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -224,19 +264,20 @@ class FitAnalyser(): |
|
|
|
|
|
|
|
self.fitDim = fitDim |
|
|
|
|
|
|
|
def _guess_1D(self, data, x): |
|
|
|
return self.fitModel.guess(data=data, x=x) |
|
|
|
def _guess_1D(self, data, x, **kwargs): |
|
|
|
return self.fitModel.guess(data=data, x=x, **kwargs) |
|
|
|
|
|
|
|
def _guess_2D(self, data, x, y): |
|
|
|
return self.fitModel.guess(data=data, x=x, y=y) |
|
|
|
def _guess_2D(self, data, x, y, **kwargs): |
|
|
|
return self.fitModel.guess(data=data, x=x, y=y, **kwargs) |
|
|
|
|
|
|
|
def guess(self, dataArray, x=None, y=None, input_core_dims=None, dask='parallelized', vectorize=True, **kwargs): |
|
|
|
def guess(self, dataArray, x=None, y=None, guess_kwargs={}, input_core_dims=None, dask='parallelized', vectorize=True, keep_attrs=True, **kwargs): |
|
|
|
|
|
|
|
kwargs.update( |
|
|
|
{ |
|
|
|
"dask": dask, |
|
|
|
"vectorize": vectorize, |
|
|
|
"input_core_dims": input_core_dims |
|
|
|
"input_core_dims": input_core_dims, |
|
|
|
'keep_attrs': keep_attrs, |
|
|
|
} |
|
|
|
) |
|
|
|
|
|
|
@ -262,7 +303,13 @@ class FitAnalyser(): |
|
|
|
|
|
|
|
if self.fitDim == 1: |
|
|
|
|
|
|
|
return xr.apply_ufunc(self._guess_1D, dataArray, kwargs={'x':x}, |
|
|
|
guess_kwargs.update( |
|
|
|
{ |
|
|
|
'x':x, |
|
|
|
} |
|
|
|
) |
|
|
|
|
|
|
|
return xr.apply_ufunc(self._guess_1D, dataArray, kwargs=guess_kwargs, |
|
|
|
output_dtypes=[type(self.fitModel.make_params())], |
|
|
|
**kwargs |
|
|
|
) |
|
|
@ -297,7 +344,14 @@ class FitAnalyser(): |
|
|
|
|
|
|
|
kwargs["input_core_dims"][0] = ['_z'] |
|
|
|
|
|
|
|
return xr.apply_ufunc(self._guess_2D, dataArray, kwargs={'x':_x, 'y':_y}, |
|
|
|
guess_kwargs.update( |
|
|
|
{ |
|
|
|
'x':_x, |
|
|
|
'y':_y, |
|
|
|
} |
|
|
|
) |
|
|
|
|
|
|
|
return xr.apply_ufunc(self._guess_2D, dataArray, kwargs=guess_kwargs, |
|
|
|
output_dtypes=[type(self.fitModel.make_params())], |
|
|
|
**kwargs |
|
|
|
) |
|
|
@ -309,13 +363,14 @@ class FitAnalyser(): |
|
|
|
def _fit_2D(self, data, params, x, y): |
|
|
|
return self.fitModel.fit(data=data, x=x, y=y, params=params) |
|
|
|
|
|
|
|
def fit(self, dataArray, paramsArray, x=None, y=None, input_core_dims=None, dask='parallelized', vectorize=True, **kwargs): |
|
|
|
def fit(self, dataArray, paramsArray, x=None, y=None, input_core_dims=None, dask='parallelized', vectorize=True, keep_attrs=True, **kwargs): |
|
|
|
|
|
|
|
kwargs.update( |
|
|
|
{ |
|
|
|
"dask": dask, |
|
|
|
"vectorize": vectorize, |
|
|
|
"input_core_dims": input_core_dims, |
|
|
|
'keep_attrs': keep_attrs, |
|
|
|
} |
|
|
|
) |
|
|
|
|
|
|
@ -415,7 +470,6 @@ class FitAnalyser(): |
|
|
|
output_dtypes=[type(lmfit.model.ModelResult(self.fitModel, self.fitModel.make_params()))], |
|
|
|
**kwargs) |
|
|
|
|
|
|
|
|
|
|
|
def _eval_1D(self, fitResult, x): |
|
|
|
return self.fitModel.eval(x=x, **fitResult.best_values) |
|
|
|
|
|
|
|