hexsample.modeling
— Fitting models#
Module documentation#
Fit models.
- class hexsample.modeling.FitStatus(par_names: Tuple[str], par_values: ndarray, par_bounds: Tuple = None)#
Small container class holding the fit status.
- Parameters:
par_names (tuple of strings) – The names of the fit parameters.
par_values (array_like) – The initial values of the fit parameters. This must an iterable of the same length of the parameter names, and is converted to a numpy array in the constructor.
par_bounds (tuple, optional) – The initial bounds for the fit parameters. This is either None (in which ] case the bounds are assumed to be -np.inf–np.inf for all the fit parameters) or a 2-element tuple of iterables of the the same length of the parameter names expressing the minimum and maximum bound for each parameter.
- _process_bounds(par_bounds: Tuple = None) Tuple[ndarray, ndarray] #
Small utility functions to process the parameter bounds for later use.
Verbatim from the scipy documentation, there are two ways to specify the bounds:
Instance of Bounds class.
2-tuple of array_like: Each element of the tuple must be either an array with the length equal to the number of parameters, or a scalar (in which case the bound is taken to be the same for all parameters). Use np.inf with an appropriate sign to disable bounds on all or some parameters.
Since we want to keep track of the bounds and, possibly, change them, we turn all allowed possibilities, here, into a 2-tuple of numpy arrays.
- _index(par_name: str) int #
Convenience method returning the index within the parameter vector for a given parameter name.
- parameter_value(par_name: str) float #
Return the parameter value for a given parameter indexed by name.
- Parameters:
par_name (str) – The parameter name.
- parameter_errors() ndarray #
Return the vector of parameter errors, that is, the square root of the diagonal elements of the covariance matrix.
- parameter_error(par_name: str) float #
Return the parameter error by name.
- Parameters:
par_name (str) – The parameter name.
- reduced_chisquare() float #
Return the reduced chisquare.
- set_parameter_bounds(par_name: str, min_: float, max_: float) None #
Set the baounds for a given parameter.
- Parameters:
par_name (str) – The parameter name.
min (float) – The minimum bound.
max (float) – The maximum bound.
- set_parameter(par_name: str, value: float) None #
Set the value for a given parameter (indexed by name).
- Parameters:
par_name (str) – The parameter name.
value (float) – The parameter value.
- update(popt: ndarray, pcov: ndarray, chisq: float, ndof: int) None #
Update the data structure after a fit.
- Parameters:
popt (array_like) – The array of best-fit parameters from scipy.optimize.curve_fit().
pcov (array_like) – The covariance matrix of the paremeters from scipy.optimize.curve_fit().
chisq (float) – The value of the chisquare.
ndof (int) – The number of degrees of freedom from the fit.
- class hexsample.modeling.FitModelBase#
Base class for a fittable model.
The class features a number of static members that derived class should redefine as needed:
PAR_NAMES
is a list containing the names of the model parameters;PAR_DEFAULT_VALUES
is a list containing the default values of the model parameters;PAR_DEFAULT_BOUNDS
is a tuple containing the default values of the parameter bounds to be used for the fitting;DEFAULT_RANGE
is a two-element list with the default support (x-axis range) for the model. (This is automatically updated at runtime depending on the input data when the model is used in a fit.)
In addition, each derived class should override the following methods:
the
eval(x, *args)
should return the value of the model at a given x for a given set of values of the underlying parameters;the
jacobian(x, *args)
method, if defined, is passed to the underlying fit engine allowing to reduce the number of function calls in the fit.
Finally, if there is a sensible way to initialize the model parameters based on a set of input data, derived classes should overload the
init_parameters(xdata, ydata)
method of the base class, as the latter is called by fitting routines if no explicit array of initial values are passed as an argument. The default behavior of the class method defined in the base class is to do nothing.See
hexsample.modeling.Gaussian
for a working example.- PAR_NAMES = None#
- PAR_DEFAULT_VALUES = None#
- PAR_DEFAULT_BOUNDS = None#
- DEFAULT_RANGE = (0.0, 1.0)#
- name() str #
Return the model name.
- set_parameter(par_name: str, value: float) None #
Convenience function to set the value for a given parameter in the underlying FitStatus object.
- set_range(xmin: float, xmax: float) None #
Set the function range.
- Parameters:
xmin (float) – The minimum x-range value.
xmax (float) – The maximum x-range value.
- plot(num_points: int = 250, **kwargs) None #
Plot the model.
- stat_box(x: float = 0.95, y: float = 0.95) None #
Plot a stat box for the model.
- static eval(x: ndarray, *parameters) ndarray #
Eval the model at a given x and a given set of parameter values.
This needs to be overloaded by any derived classes.
- init_parameters(xdata: ndarray, ydata: ndarray) None #
Assign a sensible set of values to the model parameters, based on a data set to be fitted.
In the base class the method is not doing anything, but it can be reimplemented in derived classes to help make sure the fit converges without too much manual intervention.
- Parameters:
xdata (array_like) – The x data.
ydata (array_like) – The y data.
- fit(xdata: ndarray, ydata: ndarray, p0: ndarray = None, sigma: ndarray = None, xmin: float = -inf, xmax: float = inf, absolute_sigma: bool = True, check_finite: bool = True, method: str = None, verbose: bool = True, **kwargs)#
Lightweight wrapper over the
scipy.optimize.curve_fit()
function to take advantage of the modeling facilities. More specifically, in addition to performing the actual fit, we update all the model parameters so that, after the fact, we do have a complete picture of the fit outcome.- Parameters:
model (
modeling.FitModelBase
instance callable) – The model function, f(x, …). It must take the independent variable as the first argument and the parameters to fit as separate remaining arguments.xdata (array_like) – The independent variable where the data is measured.
ydata (array_like) – The dependent data — nominally f(xdata, …)
p0 (None, scalar, or sequence, optional) – Initial guess for the parameters. If None, then the initial values will all be 1.
sigma (None or array_like, optional) – Uncertainties in ydata. If None, all the uncertainties are set to 1 and the fit becomes effectively unweighted.
xmin (float) – The minimum value for the input x-values.
xmax (float) – The maximum value for the input x-values.
absolute_sigma (bool, optional) – If True, sigma is used in an absolute sense and the estimated parameter covariance pcov reflects these absolute values. If False, only the relative magnitudes of the sigma values matter. The returned parameter covariance matrix pcov is based on scaling sigma by a constant factor. This constant is set by demanding that the reduced chisq for the optimal parameters popt when using the scaled sigma equals unity.
method ({'lm', 'trf', 'dogbox'}, optional) – Method to use for optimization. See least_squares for more details. Default is ‘lm’ for unconstrained problems and ‘trf’ if bounds are provided. The method ‘lm’ won’t work when the number of observations is less than the number of variables, use ‘trf’ or ‘dogbox’ in this case.
verbose (bool) – Print the model if True.
kwargs – Keyword arguments passed to leastsq for
method='lm'
or least_squares otherwise.
- fit_histogram(histogram: Histogram1d, p0: ndarray = None, xmin: float = -inf, xmax: float = inf, absolute_sigma: bool = True, check_finite: bool = True, method: str = None, verbose: bool = True, **kwargs)#
Fit a histogram to a given model.
This is basically calling
ixpeobssim.core.fitting.fit()
with some pre-processing to turn the histogram bin edges and content into x-y data. Particularly, the bin centers are taken as the independent data series, the bin contents are taken as the dependent data saries, and the square root of the counts as the Poisson error.For additional parameters look at the documentation of the
ixpeobssim.core.fitting.fit()
- Parameters:
model (
modeling.FitModelBase
instance or) – callable The fit model.histogram (ixpeHistogram1d instance) – The histogram to be fitted.
- static _merge_class_attributes(func, *components: type) Tuple #
Basic function to merge class attributes while summing models.
This is heavily used in the model sum factory below, as it turns out that this is the besic signature that is needed to merge the class attributes when summing models.
Note that we are not using the native Python
sum(*args, start=[])
, here, as it is not supported in Python 3.7.
- static model_sum_factory(*components: type) type #
Class factory to sum class models.
Here we have worked out the math to sum up an arbitrary number of model classes.
- class hexsample.modeling.Constant#
Constant model.
\[f(x; C) = C\]- PAR_NAMES = ('constant',)#
- PAR_DEFAULT_VALUES = (1.0,)#
- static eval(x: ndarray, constant: float) ndarray #
Overloaded method.
- static jacobian(x: ndarray, constant: float) ndarray #
Overloaded method.
- init_parameters(xdata: ndarray, ydata: ndarray) None #
Overloaded method.
- class hexsample.modeling.Line#
Straight-line model.
\[f(x; m, q) = mx + q\]- PAR_NAMES = ('intercept', 'slope')#
- PAR_DEFAULT_VALUES = (1.0, 1.0)#
- static eval(x: ndarray, intercept: float, slope: float) ndarray #
Overloaded method.
- static jacobian(x: ndarray, intercept: float, slope: float) ndarray #
Overloaded method.
- class hexsample.modeling.Gaussian#
One-dimensional Gaussian model.
\[f(x; N, \mu, \sigma) = N e^{-\frac{(x - \mu)^2}{2\sigma^2}}\]- PAR_NAMES = ('normalization', 'mean', 'sigma')#
- PAR_DEFAULT_VALUES = (1.0, 0.0, 1.0)#
- PAR_DEFAULT_BOUNDS = ((0.0, -inf, 0.0), (inf, inf, inf))#
- DEFAULT_RANGE = (-5.0, 5.0)#
- SIGMA_TO_FWHM = 2.3548200450309493#
- static eval(x: ndarray, normalization: float, mean: float, sigma: float) ndarray #
Overloaded method.
- static jacobian(x: ndarray, normalization: float, mean: float, sigma: float) ndarray #
Overloaded method.
- init_parameters(xdata: ndarray, ydata: ndarray) None #
Overloaded method.
- fwhm() float #
Return the absolute FWHM of the model.
- hexsample.modeling._DoubleGaussian#
alias of
_model
- class hexsample.modeling.DoubleGaussian#
Implementation of a double gaussian.
- init_parameters(xdata: ndarray, ydata: ndarray) None #
Overloaded method.
- fit(*args, **kwargs)#
Overloaded fit method.
This is to ensure that, at the end of the fit, the order of the two gaussians is fixed, i.e., the one with the smallest mean come first.
- class hexsample.modeling.PowerLaw#
Power law model.
\[f(x; N, \Gamma) = N x^\Gamma\]- PAR_NAMES = ('normalization', 'index')#
- PAR_DEFAULT_VALUES = (1.0, -1.0)#
- PAR_DEFAULT_BOUNDS = ((0.0, -inf), (inf, inf))#
- DEFAULT_RANGE = (0.01, 1.0)#
- static eval(x: ndarray, normalization: float, index: float) ndarray #
Overloaded method.
- static jacobian(x: ndarray, normalization: float, index: float) ndarray #
Overloaded method.
- class hexsample.modeling.Exponential#
Exponential model.
\[f(x; N, \lambda) = N e^{\frac{x}{\lambda}}\]- PAR_NAMES = ('normalization', 'scale')#
- PAR_DEFAULT_VALUES = (1.0, -1.0)#
- PAR_DEFAULT_BOUNDS = ((0.0, -inf), (inf, inf))#
- static eval(x: ndarray, normalization: float, scale: float) ndarray #
Overloaded method.
- static jacobian(x: ndarray, normalization: float, scale: float) ndarray #
Overloaded method.
- init_parameters(xdata: ndarray, ydata: ndarray) None #
Overloaded method.