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 ExperimentFactory
from easydiffraction import Project
from easydiffraction import SampleModelFactory
from easydiffraction import download_from_repository
from easydiffraction import ExperimentFactory
from easydiffraction import Project
from easydiffraction import SampleModelFactory
from easydiffraction import download_from_repository
In [3]:
Copied!
model = SampleModelFactory.create(name='si')
model = SampleModelFactory.create(name='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_from_args(
    label='Si',
    type_symbol='Si',
    fract_x=0.125,
    fract_y=0.125,
    fract_z=0.125,
    b_iso=0.5,
)
model.atom_sites.add_from_args(
    label='Si',
    type_symbol='Si',
    fract_x=0.125,
    fract_y=0.125,
    fract_z=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')
Downloading...
File 'sepd_si.xye' from 'easyscience/diffraction-lib'
Create Experiment¶
In [8]:
Copied!
expt = ExperimentFactory.create(
    name='sepd', data_path='data/sepd_si.xye', beam_mode='time-of-flight'
)
expt = ExperimentFactory.create(
    name='sepd', data_path='data/sepd_si.xye', beam_mode='time-of-flight'
)
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_from_args(x=x, y=200)
expt.background_type = 'line-segment'
for x in range(0, 35000, 5000):
    expt.background.add_from_args(x=x, y=200)
Background type for experiment 'sepd' changed to
line-segment
Set Linked Phases¶
In [13]:
Copied!
expt.linked_phases.add_from_args(id='si', scale=10.0)
expt.linked_phases.add_from_args(id='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'
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.43100 | -inf | inf | Å | ||
| 2 | sepd | linked_phases | si | scale | 10.00000 | -inf | inf | ||
| 3 | sepd | instrument | d_to_tof_offset | 0.00000 | -inf | inf | µs | 
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 | 1 | 113.06 | |
| 2 | 7 | 72.20 | 36.1% ↓ | 
| 3 | 11 | 66.76 | 7.5% ↓ | 
| 4 | 30 | 66.72 | 
🏆 Best goodness-of-fit (reduced χ²) is 66.72 at iteration 26
✅ Fitting complete.
Fit results
✅ Success: True
⏱️ Fitting time: 8.53 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 | None | length_a | 5.4310 | 5.4314 | 0.0002 | Å | 0.01 % ↑ | 
| 2 | sepd | linked_phases | si | scale | 10.0000 | 13.3619 | 0.1153 | 33.62 % ↑ | |
| 3 | sepd | instrument | None | d_to_tof_offset | 0.0000 | -9.2543 | 0.2503 | µs | N/A | 
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.43135 | 0.00018 | -inf | inf | Å | |
| 2 | sepd | linked_phases | si | scale | 13.36187 | 0.11531 | -inf | inf | |
| 3 | sepd | instrument | d_to_tof_offset | -9.25432 | 0.25033 | -inf | inf | µs | |
| 4 | sepd | background | 0 | y | 200.00000 | -inf | inf | ||
| 5 | sepd | background | 5000 | y | 200.00000 | -inf | inf | ||
| 6 | sepd | background | 10000 | y | 200.00000 | -inf | inf | ||
| 7 | sepd | background | 15000 | y | 200.00000 | -inf | inf | ||
| 8 | sepd | background | 20000 | y | 200.00000 | -inf | inf | ||
| 9 | sepd | background | 25000 | y | 200.00000 | -inf | inf | ||
| 10 | sepd | background | 30000 | y | 200.00000 | -inf | inf | 
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 | 1 | 66.80 | |
| 2 | 14 | 3.38 | 94.9% ↓ | 
| 3 | 48 | 3.38 | 
🏆 Best goodness-of-fit (reduced χ²) is 3.38 at iteration 47
✅ Fitting complete.
Fit results
✅ Success: True
⏱️ Fitting time: 11.87 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 | None | length_a | 5.4314 | 5.4314 | 0.0000 | Å | 0.00 % ↑ | 
| 2 | sepd | linked_phases | si | scale | 13.3619 | 14.6317 | 0.0265 | 9.50 % ↑ | |
| 3 | sepd | instrument | None | d_to_tof_offset | -9.2543 | -9.2534 | 0.0515 | µs | 0.01 % ↓ | 
| 4 | sepd | background | 0 | y | 200.0000 | 268.6002 | 0.9745 | 34.30 % ↑ | |
| 5 | sepd | background | 5000 | y | 200.0000 | 144.7589 | 0.4071 | 27.62 % ↓ | |
| 6 | sepd | background | 10000 | y | 200.0000 | 120.0247 | 0.4282 | 39.99 % ↓ | |
| 7 | sepd | background | 15000 | y | 200.0000 | 135.8494 | 0.8169 | 32.08 % ↓ | |
| 8 | sepd | background | 20000 | y | 200.0000 | 132.6887 | 1.4317 | 33.66 % ↓ | |
| 9 | sepd | background | 25000 | y | 200.0000 | 175.1775 | 2.8755 | 12.41 % ↓ | |
| 10 | sepd | background | 30000 | y | 200.0000 | 180.4556 | 5.8525 | 9.77 % ↓ | 
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.43137 | 0.00004 | -inf | inf | Å | |
| 2 | sepd | peak | gauss_sigma_0 | 3.00000 | -inf | inf | µs² | ||
| 3 | sepd | peak | gauss_sigma_1 | 40.00000 | -inf | inf | µs/Å | ||
| 4 | sepd | peak | gauss_sigma_2 | 2.00000 | -inf | inf | µs²/Ų | ||
| 5 | sepd | linked_phases | si | scale | 14.63167 | 0.02651 | -inf | inf | |
| 6 | sepd | instrument | d_to_tof_offset | -9.25336 | 0.05153 | -inf | inf | µ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 | 1 | 3.38 | |
| 2 | 10 | 3.21 | 5.0% ↓ | 
| 3 | 39 | 3.21 | 
🏆 Best goodness-of-fit (reduced χ²) is 3.21 at iteration 38
✅ Fitting complete.
Fit results
✅ Success: True
⏱️ Fitting time: 8.44 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 | None | length_a | 5.4314 | 5.4314 | 0.0000 | Å | 0.00 % ↑ | 
| 2 | sepd | peak | None | gauss_sigma_0 | 3.0000 | 5.7727 | 0.4206 | µs² | 92.42 % ↑ | 
| 3 | sepd | peak | None | gauss_sigma_1 | 40.0000 | 44.2827 | 0.7966 | µs/Å | 10.71 % ↑ | 
| 4 | sepd | peak | None | gauss_sigma_2 | 2.0000 | 1.2962 | 0.1680 | µs²/Ų | 35.19 % ↓ | 
| 5 | sepd | linked_phases | si | scale | 14.6317 | 14.7057 | 0.0257 | 0.51 % ↑ | |
| 6 | sepd | instrument | None | d_to_tof_offset | -9.2534 | -9.2506 | 0.0546 | µs | 0.03 % ↓ | 
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 | cell | length_a | 5.43143 | 0.00004 | -inf | inf | Å | |
| 2 | si | atom_site | Si | b_iso | 0.50000 | -inf | inf | Ų | |
| 3 | sepd | peak | gauss_sigma_0 | 5.77274 | 0.42055 | -inf | inf | µs² | |
| 4 | sepd | peak | gauss_sigma_1 | 44.28265 | 0.79664 | -inf | inf | µs/Å | |
| 5 | sepd | peak | gauss_sigma_2 | 1.29621 | 0.16795 | -inf | inf | µs²/Ų | |
| 6 | sepd | linked_phases | si | scale | 14.70568 | 0.02567 | -inf | inf | |
| 7 | sepd | instrument | d_to_tof_offset | -9.25065 | 0.05458 | -inf | inf | µ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 | 1 | 3.21 | |
| 2 | 44 | 3.19 | 
🏆 Best goodness-of-fit (reduced χ²) is 3.19 at iteration 43
✅ Fitting complete.
Fit results
✅ Success: True
⏱️ Fitting time: 10.04 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 | cell | None | length_a | 5.4314 | 5.4314 | 0.0000 | Å | 0.00 % ↑ | 
| 2 | si | atom_site | Si | b_iso | 0.5000 | 0.5201 | 0.0034 | Ų | 4.02 % ↑ | 
| 3 | sepd | peak | None | gauss_sigma_0 | 5.7727 | 4.8233 | 0.4394 | µs² | 16.45 % ↓ | 
| 4 | sepd | peak | None | gauss_sigma_1 | 44.2827 | 45.2122 | 0.8016 | µs/Å | 2.10 % ↑ | 
| 5 | sepd | peak | None | gauss_sigma_2 | 1.2962 | 1.1931 | 0.1667 | µs²/Ų | 7.95 % ↓ | 
| 6 | sepd | linked_phases | si | scale | 14.7057 | 14.8594 | 0.0366 | 1.05 % ↑ | |
| 7 | sepd | instrument | None | d_to_tof_offset | -9.2506 | -9.2823 | 0.0548 | µs | 0.34 % ↑ | 
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)