Fitting CHESS temperature dependent linecuts#
Import functions#
from nxs_analysis_tools.datareduction import load_data, Scissors
from nxs_analysis_tools.chess import *
from lmfit.models import GaussianModel, LinearModel
Create TempDependece object and load data#
sample = TempDependence()
sample.load_datasets(folder='example_data/sample_name')
Found temperature folders:
[0] 15
[1] 100
[2] 300
-----------------------------------------------
Loading 15 K indexed .nxs files...
Found example_data/sample_name/15/example_hkli.nxs
data:NXdata
@axes = ['H', 'K', 'L']
@signal = 'counts'
H = float64(100)
K = float64(150)
L = float64(200)
counts = float64(100x150x200)
-----------------------------------------------
Loading 100 K indexed .nxs files...
Found example_data/sample_name/100/example_hkli.nxs
data:NXdata
@axes = ['H', 'K', 'L']
@signal = 'counts'
H = float64(100)
K = float64(150)
L = float64(200)
counts = float64(100x150x200)
-----------------------------------------------
Loading 300 K indexed .nxs files...
Found example_data/sample_name/300/example_hkli.nxs
data:NXdata
@axes = ['H', 'K', 'L']
@signal = 'counts'
H = float64(100)
K = float64(150)
L = float64(200)
counts = float64(100x150x200)
Perform linecuts#
sample.cut_data(center=(0,0,0), window=(0.1,0.5,0.1))
-------------------------------
Cutting T = 15 K data...
Linecut axis: K
Integrated axes: ['H', 'L']
-------------------------------
Cutting T = 100 K data...
Linecut axis: K
Integrated axes: ['H', 'L']
-------------------------------
Cutting T = 300 K data...
Linecut axis: K
Integrated axes: ['H', 'L']
{'15': NXdata('data'), '100': NXdata('data'), '300': NXdata('data')}
The LinecutModel
class#
Each TempDependence
object has a LinecutModel
for each temperature, stored in the .linecutmodels
attribute.
sample.linecutmodels
{'15': <nxs_analysis_tools.fitting.LinecutModel at 0x7f90be581300>,
'100': <nxs_analysis_tools.fitting.LinecutModel at 0x7f90866fa260>,
'300': <nxs_analysis_tools.fitting.LinecutModel at 0x7f90866fa230>}
Create lmfit
model#
Use the .set_model_components()
method to set the model to be used for fitting the linecut. The model_components
parameter must be a Model
or list
of Model
objects.
sample.set_model_components([GaussianModel(prefix='peak'), LinearModel(prefix='background')])
Set model constraints#
Set constraints on the model using .set_param_hint()
.
sample.set_param_hint('peakcenter', min=-0.1, max=0.1)
After the model and the hints have been specified, use the .make_params()
method to initialize the parameters.
The constraints can be different for each temperature - for example, here we set the constraints of the Gaussian sigma at 300 K only.
sample.linecutmodels['300'].set_param_hint('peaksigma', min=-1, max=1)
Initialize parameters#
sample.make_params()
Perform initial guess#
Use the .guess()
method to perform an initial guess.
sample.guess()
The initial values of the parameters that result can be viewed using the .print_initial_params()
method.
sample.print_initial_params()
peaksigma
min: -1
max: 1
peakfwhm
expr: 2.3548200*peaksigma
peakheight
expr: 0.3989423*peakamplitude/max(1e-15, peaksigma)
peakcenter
min: -0.1
max: 0.1
peaksigma
min: -1
max: 1
peakfwhm
expr: 2.3548200*peaksigma
peakheight
expr: 0.3989423*peakamplitude/max(1e-15, peaksigma)
peakcenter
min: -0.1
max: 0.1
peaksigma
min: -1
max: 1
peakfwhm
expr: 2.3548200*peaksigma
peakheight
expr: 0.3989423*peakamplitude/max(1e-15, peaksigma)
peakcenter
min: -0.1
max: 0.1
These can also be accessed through the individual LinecutModel
objects.
sample.linecutmodels['15'].params
name | value | initial value | min | max | vary | expression |
---|---|---|---|---|---|---|
peakamplitude | 219.885366 | 219.88536567293792 | -inf | inf | True | |
peakcenter | 0.00000000 | 0.0 | -inf | inf | True | |
peaksigma | 0.06040268 | 0.06040268456375841 | 0.00000000 | 1.00000000 | True | |
backgroundslope | 2.3853e-14 | 2.3853065274578794e-14 | -inf | inf | True | |
backgroundintercept | 180.019533 | 180.0195329458017 | -inf | inf | True | |
peakfwhm | 0.14223745 | None | -inf | inf | False | 2.3548200*peaksigma |
peakheight | 1452.27938 | None | -inf | inf | False | 0.3989423*peakamplitude/max(1e-15, peaksigma) |
peakcorrlength | 44.1739171 | None | -inf | inf | False | (2 * 3.141592653589793) / peakfwhm |
Visualize the initial guesses#
sample.plot_initial_guess()
Perform the fit#
sample.fit()
Fitting 15 K data...
Done.
Fitting 100 K data...
Done.
Fitting 300 K data...
Done.
Fits completed.
Visualize all fits#
The .plot_fit
function prints fit results for all temperatures. The parameter fit_report
(default True
) determines whether the fit report is also printed.
Additionally, an optional Markdown heading can be displayed using the mdheadings
parameter (default False
).
sample.plot_fit(mdheadings=True)
15 K Fit Results
[[Model]]
(Model(gaussian, prefix='peak') + Model(linear, prefix='background'))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 25
# data points = 76
# variables = 5
chi-square = 1.3162e-16
reduced chi-square = 1.8539e-18
Akaike info crit = -3098.19567
Bayesian info crit = -3086.54200
R-squared = 1.00000000
## Warning: uncertainties could not be estimated:
backgroundslope: at initial value
[[Variables]]
peakamplitude: 183.644087 (init = 219.8854)
peakcenter: -9.7004e-15 (init = 0)
peaksigma: 0.06000000 (init = 0.06040268)
backgroundslope: -5.2966e-11 (init = 2.385307e-14)
backgroundintercept: -5.6044e-10 (init = 180.0195)
peakfwhm: 0.14128920 == '2.3548200*peaksigma'
peakheight: 1221.05658 == '0.3989423*peakamplitude/max(1e-15, peaksigma)'
peakcorrlength: 44.4703863 == '(2 * 3.141592653589793) / peakfwhm'
[[Model]]
(Model(gaussian, prefix='peak') + Model(linear, prefix='background'))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 34
# data points = 76
# variables = 5
chi-square = 5.9182e-05
reduced chi-square = 8.3356e-07
Akaike info crit = -1058.98702
Bayesian info crit = -1047.33335
R-squared = 1.00000000
[[Variables]]
peakamplitude: 291.982900 +/- 1.1230e-04 (0.00%) (init = 397.8052)
peakcenter: -3.6249e-12 +/- 3.0297e-08 (835795.34%) (init = -6.167906e-18)
peaksigma: 0.09999993 +/- 3.5765e-08 (0.00%) (init = 0.114094)
backgroundslope: 3.5175e-14 +/- 3.7545e-04 (1067379877973.20%) (init = 3.517481e-14)
backgroundintercept: 5.6407e-04 +/- 1.5350e-04 (27.21%) (init = 286.2205)
peakfwhm: 0.23548184 +/- 8.4221e-08 (0.00%) == '2.3548200*peaksigma'
peakheight: 1164.84410 +/- 3.2639e-04 (0.00%) == '0.3989423*peakamplitude/max(1e-15, peaksigma)'
peakcorrlength: 26.6822500 +/- 9.5430e-06 (0.00%) == '(2 * 3.141592653589793) / peakfwhm'
[[Correlations]] (unreported correlations are < 0.100)
C(peakamplitude, backgroundintercept) = -0.7268
C(peakamplitude, peaksigma) = +0.7173
C(peaksigma, backgroundintercept) = -0.5215
C(backgroundslope, backgroundintercept) = -0.1658
C(peakamplitude, backgroundslope) = +0.1205
[[Model]]
(Model(gaussian, prefix='peak') + Model(linear, prefix='background'))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 31
# data points = 76
# variables = 5
chi-square = 85.5499422
reduced chi-square = 1.20492876
Akaike info crit = 18.9958908
Bayesian info crit = 30.6495575
R-squared = 0.99998814
## Warning: uncertainties could not be estimated:
peakcenter: at initial value
backgroundslope: at initial value
[[Variables]]
peakamplitude: 349.382304 (init = 469.3782)
peakcenter: -4.2492e-10 (init = -1.982541e-17)
peaksigma: 0.15931867 (init = 0.1812081)
backgroundslope: 1.1764e-14 (init = 1.176368e-14)
backgroundintercept: 3.23456528 (init = 345.2546)
peakfwhm: 0.37516679 == '2.3548200*peaksigma'
peakheight: 874.871598 == '0.3989423*peakamplitude/max(1e-15, peaksigma)'
peakcorrlength: 16.7477118 == '(2 * 3.141592653589793) / peakfwhm'
100 K Fit Results
300 K Fit Results
Access the fit values#
The x and y values of the fit are stored in the .x
(identical to the raw x values) and the .y_fit
attributes.
sample.linecutmodels['15'].x
array([-0.503356, -0.489933, -0.47651 , ..., 0.47651 , 0.489933,
0.503356])
sample.linecutmodels['15'].y_fit
array([-5.331438e-10, -5.304346e-10, -5.106177e-10, ..., -5.610952e-10,
-5.823341e-10, -5.864651e-10])
The residuals are stored within the ModelResult
class of the lmfit package, which is stored in the .modelresult
attribute of the LinecutModel
class.
sample.linecutmodels['15'].modelresult.residual
array([-5.353978e-10, -5.347390e-10, -5.352385e-10, ..., -5.857160e-10,
-5.866385e-10, -5.887192e-10])
Viewing the fit report#
Use the .print_fit_report()
method to print out the fit report for all temperatures.
sample.print_fit_report()
[[[15 K Fit Report]]]
[[Model]]
(Model(gaussian, prefix='peak') + Model(linear, prefix='background'))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 25
# data points = 76
# variables = 5
chi-square = 1.3162e-16
reduced chi-square = 1.8539e-18
Akaike info crit = -3098.19567
Bayesian info crit = -3086.54200
R-squared = 1.00000000
## Warning: uncertainties could not be estimated:
backgroundslope: at initial value
[[Variables]]
peakamplitude: 183.644087 (init = 219.8854)
peakcenter: -9.7004e-15 (init = 0)
peaksigma: 0.06000000 (init = 0.06040268)
backgroundslope: -5.2966e-11 (init = 2.385307e-14)
backgroundintercept: -5.6044e-10 (init = 180.0195)
peakfwhm: 0.14128920 == '2.3548200*peaksigma'
peakheight: 1221.05658 == '0.3989423*peakamplitude/max(1e-15, peaksigma)'
peakcorrlength: 44.4703863 == '(2 * 3.141592653589793) / peakfwhm'
[[[100 K Fit Report]]]
[[Model]]
(Model(gaussian, prefix='peak') + Model(linear, prefix='background'))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 34
# data points = 76
# variables = 5
chi-square = 5.9182e-05
reduced chi-square = 8.3356e-07
Akaike info crit = -1058.98702
Bayesian info crit = -1047.33335
R-squared = 1.00000000
[[Variables]]
peakamplitude: 291.982900 +/- 1.1230e-04 (0.00%) (init = 397.8052)
peakcenter: -3.6249e-12 +/- 3.0297e-08 (835795.34%) (init = -6.167906e-18)
peaksigma: 0.09999993 +/- 3.5765e-08 (0.00%) (init = 0.114094)
backgroundslope: 3.5175e-14 +/- 3.7545e-04 (1067379877973.20%) (init = 3.517481e-14)
backgroundintercept: 5.6407e-04 +/- 1.5350e-04 (27.21%) (init = 286.2205)
peakfwhm: 0.23548184 +/- 8.4221e-08 (0.00%) == '2.3548200*peaksigma'
peakheight: 1164.84410 +/- 3.2639e-04 (0.00%) == '0.3989423*peakamplitude/max(1e-15, peaksigma)'
peakcorrlength: 26.6822500 +/- 9.5430e-06 (0.00%) == '(2 * 3.141592653589793) / peakfwhm'
[[Correlations]] (unreported correlations are < 0.100)
C(peakamplitude, backgroundintercept) = -0.7268
C(peakamplitude, peaksigma) = +0.7173
C(peaksigma, backgroundintercept) = -0.5215
C(backgroundslope, backgroundintercept) = -0.1658
C(peakamplitude, backgroundslope) = +0.1205
[[[300 K Fit Report]]]
[[Model]]
(Model(gaussian, prefix='peak') + Model(linear, prefix='background'))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 31
# data points = 76
# variables = 5
chi-square = 85.5499422
reduced chi-square = 1.20492876
Akaike info crit = 18.9958908
Bayesian info crit = 30.6495575
R-squared = 0.99998814
## Warning: uncertainties could not be estimated:
peakcenter: at initial value
backgroundslope: at initial value
[[Variables]]
peakamplitude: 349.382304 (init = 469.3782)
peakcenter: -4.2492e-10 (init = -1.982541e-17)
peaksigma: 0.15931867 (init = 0.1812081)
backgroundslope: 1.1764e-14 (init = 1.176368e-14)
backgroundintercept: 3.23456528 (init = 345.2546)
peakfwhm: 0.37516679 == '2.3548200*peaksigma'
peakheight: 874.871598 == '0.3989423*peakamplitude/max(1e-15, peaksigma)'
peakcorrlength: 16.7477118 == '(2 * 3.141592653589793) / peakfwhm'
To obtain a fit report for just one temperature, use the .fit_report()
method of the ModelResult
object stored in the .linecutmodels
attr
Or, to access a single temperature fit report:
sample.linecutmodels['15'].print_fit_report()
[[Model]]
(Model(gaussian, prefix='peak') + Model(linear, prefix='background'))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 25
# data points = 76
# variables = 5
chi-square = 1.3162e-16
reduced chi-square = 1.8539e-18
Akaike info crit = -3098.19567
Bayesian info crit = -3086.54200
R-squared = 1.00000000
## Warning: uncertainties could not be estimated:
backgroundslope: at initial value
[[Variables]]
peakamplitude: 183.644087 (init = 219.8854)
peakcenter: -9.7004e-15 (init = 0)
peaksigma: 0.06000000 (init = 0.06040268)
backgroundslope: -5.2966e-11 (init = 2.385307e-14)
backgroundintercept: -5.6044e-10 (init = 180.0195)
peakfwhm: 0.14128920 == '2.3548200*peaksigma'
peakheight: 1221.05658 == '0.3989423*peakamplitude/max(1e-15, peaksigma)'
peakcorrlength: 44.4703863 == '(2 * 3.141592653589793) / peakfwhm'