Structure Refinement: Si, SEPD¶
This example demonstrates a Rietveld refinement of Si crystal structure using time-of-flight neutron powder diffraction data from SEPD at Argonne.
Import Library¶
In [2]:
Copied!
from easydiffraction import Experiment
from easydiffraction import Project
from easydiffraction import SampleModel
from easydiffraction import download_from_repository
from easydiffraction import Experiment
from easydiffraction import Project
from easydiffraction import SampleModel
from easydiffraction import download_from_repository
⚠️ 'pycrysfml' module not found. This calculation engine will not be available. ✅ 'cryspy' calculation engine is successfully imported. ✅ 'pdffit' calculation engine is successfully imported.
In [3]:
Copied!
model = SampleModel('si')
model = SampleModel('si')
Set Space Group¶
In [4]:
Copied!
model.space_group.name_h_m = 'F d -3 m'
model.space_group.it_coordinate_system_code = '2'
model.space_group.name_h_m = 'F d -3 m'
model.space_group.it_coordinate_system_code = '2'
Set Unit Cell¶
In [5]:
Copied!
model.cell.length_a = 5.431
model.cell.length_a = 5.431
Set Atom Sites¶
In [6]:
Copied!
model.atom_sites.add('Si', 'Si', 0.125, 0.125, 0.125, b_iso=0.5)
model.atom_sites.add('Si', 'Si', 0.125, 0.125, 0.125, b_iso=0.5)
In [7]:
Copied!
download_from_repository('sepd_si.xye', destination='data')
download_from_repository('sepd_si.xye', destination='data')
⚠️ Warning
File 'data/sepd_si.xye' already exists and will not be overwritten.
Create Experiment¶
In [8]:
Copied!
expt = Experiment('sepd', beam_mode='time-of-flight', data_path='data/sepd_si.xye')
expt = Experiment('sepd', beam_mode='time-of-flight', data_path='data/sepd_si.xye')
Data loaded successfully
Experiment 🔬 'sepd'. Number of data points: 5600
Set Instrument¶
In [9]:
Copied!
expt.instrument.setup_twotheta_bank = 144.845
expt.instrument.calib_d_to_tof_offset = 0.0
expt.instrument.calib_d_to_tof_linear = 7476.91
expt.instrument.calib_d_to_tof_quad = -1.54
expt.instrument.setup_twotheta_bank = 144.845
expt.instrument.calib_d_to_tof_offset = 0.0
expt.instrument.calib_d_to_tof_linear = 7476.91
expt.instrument.calib_d_to_tof_quad = -1.54
Set Peak Profile¶
In [10]:
Copied!
expt.peak_profile_type = 'pseudo-voigt * ikeda-carpenter'
expt.peak.broad_gauss_sigma_0 = 3.0
expt.peak.broad_gauss_sigma_1 = 40.0
expt.peak.broad_gauss_sigma_2 = 2.0
expt.peak.broad_mix_beta_0 = 0.04221
expt.peak.broad_mix_beta_1 = 0.00946
expt.peak_profile_type = 'pseudo-voigt * ikeda-carpenter'
expt.peak.broad_gauss_sigma_0 = 3.0
expt.peak.broad_gauss_sigma_1 = 40.0
expt.peak.broad_gauss_sigma_2 = 2.0
expt.peak.broad_mix_beta_0 = 0.04221
expt.peak.broad_mix_beta_1 = 0.00946
Peak profile type for experiment 'sepd' changed to pseudo-voigt * ikeda-carpenter
Set Peak Asymmetry¶
In [11]:
Copied!
expt.peak.asym_alpha_0 = 0.0
expt.peak.asym_alpha_1 = 0.5971
expt.peak.asym_alpha_0 = 0.0
expt.peak.asym_alpha_1 = 0.5971
Set Background¶
In [12]:
Copied!
expt.background_type = 'line-segment'
for x in range(0, 35000, 5000):
expt.background.add(x=x, y=200)
expt.background_type = 'line-segment'
for x in range(0, 35000, 5000):
expt.background.add(x=x, y=200)
Background type for experiment 'sepd' changed to line-segment
Set Linked Phases¶
In [13]:
Copied!
expt.linked_phases.add('si', scale=10.0)
expt.linked_phases.add('si', scale=10.0)
In [14]:
Copied!
project = Project()
project = Project()
Set Plotting Engine¶
In [15]:
Copied!
project.plotter.engine = 'plotly'
project.plotter.engine = 'plotly'
Current plotter changed to
plotly
Add Sample Model¶
In [16]:
Copied!
project.sample_models.add(model)
project.sample_models.add(model)
Add Experiment¶
In [17]:
Copied!
project.experiments.add(expt)
project.experiments.add(expt)
In [18]:
Copied!
project.analysis.current_calculator = 'cryspy'
project.analysis.current_calculator = 'cryspy'
Current calculator changed to
cryspy
Set Minimizer¶
In [19]:
Copied!
project.analysis.current_minimizer = 'lmfit (leastsq)'
project.analysis.current_minimizer = 'lmfit (leastsq)'
Current minimizer changed to
lmfit (leastsq)
Plot Measured vs Calculated¶
In [20]:
Copied!
project.plot_meas_vs_calc(expt_name='sepd', show_residual=True)
project.plot_meas_vs_calc(expt_name='sepd', x_min=23200, x_max=23700, show_residual=True)
project.plot_meas_vs_calc(expt_name='sepd', show_residual=True)
project.plot_meas_vs_calc(expt_name='sepd', x_min=23200, x_max=23700, show_residual=True)
Perform Fit 1/5¶
Set parameters to be refined.
In [21]:
Copied!
model.cell.length_a.free = True
expt.linked_phases['si'].scale.free = True
expt.instrument.calib_d_to_tof_offset.free = True
model.cell.length_a.free = True
expt.linked_phases['si'].scale.free = True
expt.instrument.calib_d_to_tof_offset.free = True
Show free parameters after selection.
In [22]:
Copied!
project.analysis.show_free_params()
project.analysis.show_free_params()
Free parameters for both sample models (🧩 data blocks) and experiments (🔬 data blocks)
datablock | category | entry | parameter | value | uncertainty | min | max | units | |
---|---|---|---|---|---|---|---|---|---|
1 | si |
cell |
length_a |
5.4310 |
Å |
||||
2 | sepd |
instrument |
d_to_tof_offset |
0.0000 |
µs |
||||
3 | sepd |
linked_phases |
si |
scale |
10.0000 |
Run Fitting¶
In [23]:
Copied!
project.analysis.fit()
project.analysis.fit()
Using experiment 🔬 'sepd' for 'single' fitting 🚀 Starting fit process with 'lmfit (leastsq)'... 📈 Goodness-of-fit (reduced χ²) change:
iteration | χ² | improvement [%] |
---|---|---|
1 |
113.06 |
|
7 |
72.20 |
36.1% ↓ |
11 |
66.76 |
7.5% ↓ |
30 |
66.72 |
🏆 Best goodness-of-fit (reduced χ²) is 66.72 at iteration 25 ✅ Fitting complete.
Fit results
✅ Success: True
⏱️ Fitting time: 6.07 seconds
📏 Goodness-of-fit (reduced χ²): 66.72
📏 R-factor (Rf): 23.08%
📏 R-factor squared (Rf²): 12.55%
📏 Weighted R-factor (wR): 12.51%
📈 Fitted parameters:
datablock | category | entry | parameter | start | fitted | uncertainty | units | change | |
---|---|---|---|---|---|---|---|---|---|
1 | si |
cell |
length_a |
5.4310 |
5.4314 |
0.0002 |
Å |
0.01 % ↑ |
|
2 | sepd |
instrument |
d_to_tof_offset |
0.0000 |
-9.2543 |
0.2503 |
µs |
N/A |
|
3 | sepd |
linked_phases |
si |
scale |
10.0000 |
13.3619 |
0.1153 |
33.62 % ↑ |
Plot Measured vs Calculated¶
In [24]:
Copied!
project.plot_meas_vs_calc(expt_name='sepd', show_residual=True)
project.plot_meas_vs_calc(expt_name='sepd', show_residual=True)
In [25]:
Copied!
project.plot_meas_vs_calc(expt_name='sepd', x_min=23200, x_max=23700, show_residual=True)
project.plot_meas_vs_calc(expt_name='sepd', x_min=23200, x_max=23700, show_residual=True)
Perform Fit 2/5¶
Set more parameters to be refined.
In [26]:
Copied!
for point in expt.background:
point.y.free = True
for point in expt.background:
point.y.free = True
Show free parameters after selection.
In [27]:
Copied!
project.analysis.show_free_params()
project.analysis.show_free_params()
Free parameters for both sample models (🧩 data blocks) and experiments (🔬 data blocks)
datablock | category | entry | parameter | value | uncertainty | min | max | units | |
---|---|---|---|---|---|---|---|---|---|
1 | si |
cell |
length_a |
5.4314 |
0.0002 |
Å |
|||
2 | sepd |
background |
0 |
y |
200.0000 |
||||
3 | sepd |
background |
5000 |
y |
200.0000 |
||||
4 | sepd |
background |
10000 |
y |
200.0000 |
||||
5 | sepd |
background |
15000 |
y |
200.0000 |
||||
6 | sepd |
background |
20000 |
y |
200.0000 |
||||
7 | sepd |
background |
25000 |
y |
200.0000 |
||||
8 | sepd |
background |
30000 |
y |
200.0000 |
||||
9 | sepd |
instrument |
d_to_tof_offset |
-9.2543 |
0.2503 |
µs |
|||
10 | sepd |
linked_phases |
si |
scale |
13.3619 |
0.1153 |
Run Fitting¶
In [28]:
Copied!
project.analysis.fit()
project.analysis.fit()
Using experiment 🔬 'sepd' for 'single' fitting 🚀 Starting fit process with 'lmfit (leastsq)'... 📈 Goodness-of-fit (reduced χ²) change:
iteration | χ² | improvement [%] |
---|---|---|
1 |
66.80 |
|
14 |
3.38 |
94.9% ↓ |
48 |
3.38 |
🏆 Best goodness-of-fit (reduced χ²) is 3.38 at iteration 47 ✅ Fitting complete.
Fit results
✅ Success: True
⏱️ Fitting time: 9.60 seconds
📏 Goodness-of-fit (reduced χ²): 3.38
📏 R-factor (Rf): 9.29%
📏 R-factor squared (Rf²): 6.33%
📏 Weighted R-factor (wR): 5.95%
📈 Fitted parameters:
datablock | category | entry | parameter | start | fitted | uncertainty | units | change | |
---|---|---|---|---|---|---|---|---|---|
1 | si |
cell |
length_a |
5.4314 |
5.4314 |
0.0000 |
Å |
0.00 % ↑ |
|
2 | sepd |
background |
0 |
y |
200.0000 |
268.6002 |
0.9745 |
34.30 % ↑ |
|
3 | sepd |
background |
5000 |
y |
200.0000 |
144.7589 |
0.4071 |
27.62 % ↓ |
|
4 | sepd |
background |
10000 |
y |
200.0000 |
120.0247 |
0.4282 |
39.99 % ↓ |
|
5 | sepd |
background |
15000 |
y |
200.0000 |
135.8494 |
0.8169 |
32.08 % ↓ |
|
6 | sepd |
background |
20000 |
y |
200.0000 |
132.6887 |
1.4317 |
33.66 % ↓ |
|
7 | sepd |
background |
25000 |
y |
200.0000 |
175.1775 |
2.8755 |
12.41 % ↓ |
|
8 | sepd |
background |
30000 |
y |
200.0000 |
180.4556 |
5.8525 |
9.77 % ↓ |
|
9 | sepd |
instrument |
d_to_tof_offset |
-9.2543 |
-9.2534 |
0.0515 |
µs |
0.01 % ↓ |
|
10 | sepd |
linked_phases |
si |
scale |
13.3619 |
14.6317 |
0.0265 |
9.50 % ↑ |
Plot Measured vs Calculated¶
In [29]:
Copied!
project.plot_meas_vs_calc(expt_name='sepd', show_residual=True)
project.plot_meas_vs_calc(expt_name='sepd', show_residual=True)
In [30]:
Copied!
project.plot_meas_vs_calc(expt_name='sepd', x_min=23200, x_max=23700, show_residual=True)
project.plot_meas_vs_calc(expt_name='sepd', x_min=23200, x_max=23700, show_residual=True)
Perform Fit 3/5¶
Fix background points.
In [31]:
Copied!
for point in expt.background:
point.y.free = False
for point in expt.background:
point.y.free = False
Set more parameters to be refined.
In [32]:
Copied!
expt.peak.broad_gauss_sigma_0.free = True
expt.peak.broad_gauss_sigma_1.free = True
expt.peak.broad_gauss_sigma_2.free = True
expt.peak.broad_gauss_sigma_0.free = True
expt.peak.broad_gauss_sigma_1.free = True
expt.peak.broad_gauss_sigma_2.free = True
Show free parameters after selection.
In [33]:
Copied!
project.analysis.show_free_params()
project.analysis.show_free_params()
Free parameters for both sample models (🧩 data blocks) and experiments (🔬 data blocks)
datablock | category | entry | parameter | value | uncertainty | min | max | units | |
---|---|---|---|---|---|---|---|---|---|
1 | si |
cell |
length_a |
5.4314 |
0.0000 |
Å |
|||
2 | sepd |
instrument |
d_to_tof_offset |
-9.2534 |
0.0515 |
µs |
|||
3 | sepd |
linked_phases |
si |
scale |
14.6317 |
0.0265 |
|||
4 | sepd |
peak |
gauss_sigma_0 |
3.0000 |
µs² |
||||
5 | sepd |
peak |
gauss_sigma_1 |
40.0000 |
µs/Å |
||||
6 | sepd |
peak |
gauss_sigma_2 |
2.0000 |
µs²/Ų |
Run Fitting¶
In [34]:
Copied!
project.analysis.fit()
project.analysis.fit()
Using experiment 🔬 'sepd' for 'single' fitting 🚀 Starting fit process with 'lmfit (leastsq)'... 📈 Goodness-of-fit (reduced χ²) change:
iteration | χ² | improvement [%] |
---|---|---|
1 |
3.38 |
|
10 |
3.21 |
5.0% ↓ |
39 |
3.21 |
🏆 Best goodness-of-fit (reduced χ²) is 3.21 at iteration 38 ✅ Fitting complete.
Fit results
✅ Success: True
⏱️ Fitting time: 8.03 seconds
📏 Goodness-of-fit (reduced χ²): 3.21
📏 R-factor (Rf): 8.99%
📏 R-factor squared (Rf²): 5.52%
📏 Weighted R-factor (wR): 4.88%
📈 Fitted parameters:
datablock | category | entry | parameter | start | fitted | uncertainty | units | change | |
---|---|---|---|---|---|---|---|---|---|
1 | si |
cell |
length_a |
5.4314 |
5.4314 |
0.0000 |
Å |
0.00 % ↑ |
|
2 | sepd |
instrument |
d_to_tof_offset |
-9.2534 |
-9.2506 |
0.0546 |
µs |
0.03 % ↓ |
|
3 | sepd |
linked_phases |
si |
scale |
14.6317 |
14.7057 |
0.0257 |
0.51 % ↑ |
|
4 | sepd |
peak |
gauss_sigma_0 |
3.0000 |
5.7727 |
0.4206 |
µs² |
92.42 % ↑ |
|
5 | sepd |
peak |
gauss_sigma_1 |
40.0000 |
44.2827 |
0.7966 |
µs/Å |
10.71 % ↑ |
|
6 | sepd |
peak |
gauss_sigma_2 |
2.0000 |
1.2962 |
0.1680 |
µs²/Ų |
35.19 % ↓ |
Plot Measured vs Calculated¶
In [35]:
Copied!
project.plot_meas_vs_calc(expt_name='sepd', show_residual=True)
project.plot_meas_vs_calc(expt_name='sepd', show_residual=True)
In [36]:
Copied!
project.plot_meas_vs_calc(expt_name='sepd', x_min=23200, x_max=23700, show_residual=True)
project.plot_meas_vs_calc(expt_name='sepd', x_min=23200, x_max=23700, show_residual=True)
Perform Fit 4/5¶
Set more parameters to be refined.
In [37]:
Copied!
model.atom_sites['Si'].b_iso.free = True
model.atom_sites['Si'].b_iso.free = True
Show free parameters after selection.
In [38]:
Copied!
project.analysis.show_free_params()
project.analysis.show_free_params()
Free parameters for both sample models (🧩 data blocks) and experiments (🔬 data blocks)
datablock | category | entry | parameter | value | uncertainty | min | max | units | |
---|---|---|---|---|---|---|---|---|---|
1 | si |
atom_sites |
Si |
b_iso |
0.5000 |
Ų |
|||
2 | si |
cell |
length_a |
5.4314 |
0.0000 |
Å |
|||
3 | sepd |
instrument |
d_to_tof_offset |
-9.2506 |
0.0546 |
µs |
|||
4 | sepd |
linked_phases |
si |
scale |
14.7057 |
0.0257 |
|||
5 | sepd |
peak |
gauss_sigma_0 |
5.7727 |
0.4206 |
µs² |
|||
6 | sepd |
peak |
gauss_sigma_1 |
44.2827 |
0.7966 |
µs/Å |
|||
7 | sepd |
peak |
gauss_sigma_2 |
1.2962 |
0.1680 |
µs²/Ų |
Run Fitting¶
In [39]:
Copied!
project.analysis.fit()
project.analysis.fit()
Using experiment 🔬 'sepd' for 'single' fitting 🚀 Starting fit process with 'lmfit (leastsq)'... 📈 Goodness-of-fit (reduced χ²) change:
iteration | χ² | improvement [%] |
---|---|---|
1 |
3.21 |
|
44 |
3.19 |
🏆 Best goodness-of-fit (reduced χ²) is 3.19 at iteration 43 ✅ Fitting complete.
Fit results
✅ Success: True
⏱️ Fitting time: 9.01 seconds
📏 Goodness-of-fit (reduced χ²): 3.19
📏 R-factor (Rf): 9.01%
📏 R-factor squared (Rf²): 5.35%
📏 Weighted R-factor (wR): 4.47%
📈 Fitted parameters:
datablock | category | entry | parameter | start | fitted | uncertainty | units | change | |
---|---|---|---|---|---|---|---|---|---|
1 | si |
atom_sites |
Si |
b_iso |
0.5000 |
0.5201 |
0.0034 |
Ų |
4.02 % ↑ |
2 | si |
cell |
length_a |
5.4314 |
5.4314 |
0.0000 |
Å |
0.00 % ↑ |
|
3 | sepd |
instrument |
d_to_tof_offset |
-9.2506 |
-9.2823 |
0.0548 |
µs |
0.34 % ↑ |
|
4 | sepd |
linked_phases |
si |
scale |
14.7057 |
14.8594 |
0.0366 |
1.05 % ↑ |
|
5 | sepd |
peak |
gauss_sigma_0 |
5.7727 |
4.8233 |
0.4394 |
µs² |
16.45 % ↓ |
|
6 | sepd |
peak |
gauss_sigma_1 |
44.2827 |
45.2122 |
0.8016 |
µs/Å |
2.10 % ↑ |
|
7 | sepd |
peak |
gauss_sigma_2 |
1.2962 |
1.1931 |
0.1667 |
µs²/Ų |
7.95 % ↓ |
Plot Measured vs Calculated¶
In [40]:
Copied!
project.plot_meas_vs_calc(expt_name='sepd', show_residual=True)
project.plot_meas_vs_calc(expt_name='sepd', show_residual=True)
In [41]:
Copied!
project.plot_meas_vs_calc(expt_name='sepd', x_min=23200, x_max=23700, show_residual=True)
project.plot_meas_vs_calc(expt_name='sepd', x_min=23200, x_max=23700, show_residual=True)