Structure Refinement: LBCO+Si, McStas¶
This example demonstrates a Rietveld refinement of La0.5Ba0.5CoO3 crystal structure with a small amount of Si phase using time-of-flight neutron powder diffraction data simulated with McStas.
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_1 = SampleModel('lbco')
model_1 = SampleModel('lbco')
Set Space Group¶
In [4]:
Copied!
model_1.space_group.name_h_m = 'P m -3 m'
model_1.space_group.it_coordinate_system_code = '1'
model_1.space_group.name_h_m = 'P m -3 m'
model_1.space_group.it_coordinate_system_code = '1'
Set Unit Cell¶
In [5]:
Copied!
model_1.cell.length_a = 3.8909
model_1.cell.length_a = 3.8909
Set Atom Sites¶
In [6]:
Copied!
model_1.atom_sites.add(
'La',
'La',
0,
0,
0,
wyckoff_letter='a',
b_iso=0.2,
occupancy=0.5,
)
model_1.atom_sites.add(
'Ba',
'Ba',
0,
0,
0,
wyckoff_letter='a',
b_iso=0.2,
occupancy=0.5,
)
model_1.atom_sites.add(
'Co',
'Co',
0.5,
0.5,
0.5,
wyckoff_letter='b',
b_iso=0.2567,
)
model_1.atom_sites.add(
'O',
'O',
0,
0.5,
0.5,
wyckoff_letter='c',
b_iso=1.4041,
)
model_1.atom_sites.add(
'La',
'La',
0,
0,
0,
wyckoff_letter='a',
b_iso=0.2,
occupancy=0.5,
)
model_1.atom_sites.add(
'Ba',
'Ba',
0,
0,
0,
wyckoff_letter='a',
b_iso=0.2,
occupancy=0.5,
)
model_1.atom_sites.add(
'Co',
'Co',
0.5,
0.5,
0.5,
wyckoff_letter='b',
b_iso=0.2567,
)
model_1.atom_sites.add(
'O',
'O',
0,
0.5,
0.5,
wyckoff_letter='c',
b_iso=1.4041,
)
Create Sample Model 2: Si¶
In [7]:
Copied!
model_2 = SampleModel('si')
model_2 = SampleModel('si')
Set Space Group¶
In [8]:
Copied!
model_2.space_group.name_h_m = 'F d -3 m'
model_2.space_group.it_coordinate_system_code = '2'
model_2.space_group.name_h_m = 'F d -3 m'
model_2.space_group.it_coordinate_system_code = '2'
Set Unit Cell¶
In [9]:
Copied!
model_2.cell.length_a = 5.43146
model_2.cell.length_a = 5.43146
Set Atom Sites¶
In [10]:
Copied!
model_2.atom_sites.add(
'Si',
'Si',
0.0,
0.0,
0.0,
wyckoff_letter='a',
b_iso=0.0,
)
model_2.atom_sites.add(
'Si',
'Si',
0.0,
0.0,
0.0,
wyckoff_letter='a',
b_iso=0.0,
)
In [11]:
Copied!
download_from_repository('mcstas_lbco-si.xye', destination='data')
download_from_repository('mcstas_lbco-si.xye', destination='data')
⚠️ Warning
File 'data/mcstas_lbco-si.xye' already exists and will not be overwritten.
Create Experiment¶
In [12]:
Copied!
experiment = Experiment(
'mcstas',
sample_form='powder',
beam_mode='time-of-flight',
radiation_probe='neutron',
scattering_type='bragg',
data_path='data/mcstas_lbco-si.xye',
)
experiment = Experiment(
'mcstas',
sample_form='powder',
beam_mode='time-of-flight',
radiation_probe='neutron',
scattering_type='bragg',
data_path='data/mcstas_lbco-si.xye',
)
Data loaded successfully
Experiment 🔬 'mcstas'. Number of data points: 1000
Set Instrument¶
In [13]:
Copied!
experiment.instrument.setup_twotheta_bank = 94.90931761529106
experiment.instrument.calib_d_to_tof_offset = 0.0
experiment.instrument.calib_d_to_tof_linear = 58724.76869981215
experiment.instrument.calib_d_to_tof_quad = -0.00001
experiment.instrument.setup_twotheta_bank = 94.90931761529106
experiment.instrument.calib_d_to_tof_offset = 0.0
experiment.instrument.calib_d_to_tof_linear = 58724.76869981215
experiment.instrument.calib_d_to_tof_quad = -0.00001
Set Peak Profile¶
In [14]:
Copied!
# experiment.peak_profile_type = 'pseudo-voigt * ikeda-carpenter'
experiment.peak.broad_gauss_sigma_0 = 45137
experiment.peak.broad_gauss_sigma_1 = -52394
experiment.peak.broad_gauss_sigma_2 = 22998
experiment.peak.broad_mix_beta_0 = 0.0055
experiment.peak.broad_mix_beta_1 = 0.0041
experiment.peak.asym_alpha_0 = 0
experiment.peak.asym_alpha_1 = 0.0097
# experiment.peak_profile_type = 'pseudo-voigt * ikeda-carpenter'
experiment.peak.broad_gauss_sigma_0 = 45137
experiment.peak.broad_gauss_sigma_1 = -52394
experiment.peak.broad_gauss_sigma_2 = 22998
experiment.peak.broad_mix_beta_0 = 0.0055
experiment.peak.broad_mix_beta_1 = 0.0041
experiment.peak.asym_alpha_0 = 0
experiment.peak.asym_alpha_1 = 0.0097
Set Background¶
Select the background type.
In [15]:
Copied!
experiment.background_type = 'line-segment'
experiment.background_type = 'line-segment'
Background type for experiment 'mcstas' changed to line-segment
Add background points.
In [16]:
Copied!
experiment.background.add(x=45000, y=0.2)
experiment.background.add(x=50000, y=0.2)
experiment.background.add(x=55000, y=0.2)
experiment.background.add(x=65000, y=0.2)
experiment.background.add(x=70000, y=0.2)
experiment.background.add(x=75000, y=0.2)
experiment.background.add(x=80000, y=0.2)
experiment.background.add(x=85000, y=0.2)
experiment.background.add(x=90000, y=0.2)
experiment.background.add(x=95000, y=0.2)
experiment.background.add(x=100000, y=0.2)
experiment.background.add(x=105000, y=0.2)
experiment.background.add(x=110000, y=0.2)
experiment.background.add(x=45000, y=0.2)
experiment.background.add(x=50000, y=0.2)
experiment.background.add(x=55000, y=0.2)
experiment.background.add(x=65000, y=0.2)
experiment.background.add(x=70000, y=0.2)
experiment.background.add(x=75000, y=0.2)
experiment.background.add(x=80000, y=0.2)
experiment.background.add(x=85000, y=0.2)
experiment.background.add(x=90000, y=0.2)
experiment.background.add(x=95000, y=0.2)
experiment.background.add(x=100000, y=0.2)
experiment.background.add(x=105000, y=0.2)
experiment.background.add(x=110000, y=0.2)
Set Linked Phases¶
In [17]:
Copied!
experiment.linked_phases.add('lbco', scale=4.0)
experiment.linked_phases.add('si', scale=0.2)
experiment.linked_phases.add('lbco', scale=4.0)
experiment.linked_phases.add('si', scale=0.2)
In [18]:
Copied!
project = Project()
project = Project()
Set Plotting Engine¶
In [19]:
Copied!
project.plotter.engine = 'plotly'
project.plotter.engine = 'plotly'
Current plotter changed to
plotly
Add Sample Models¶
In [20]:
Copied!
project.sample_models.add(model_1)
project.sample_models.add(model_2)
project.sample_models.add(model_1)
project.sample_models.add(model_2)
Show Sample Models¶
In [21]:
Copied!
project.sample_models.show_names()
project.sample_models.show_names()
Defined sample models 🧩
['lbco', 'si']
Add Experiments¶
In [22]:
Copied!
project.experiments.add(experiment)
project.experiments.add(experiment)
Set Excluded Regions¶
Show measured data as loaded from the file.
In [23]:
Copied!
project.plot_meas(expt_name='mcstas')
project.plot_meas(expt_name='mcstas')
Add excluded regions.
In [24]:
Copied!
experiment.excluded_regions.add(minimum=0, maximum=40000)
experiment.excluded_regions.add(minimum=108000, maximum=200000)
experiment.excluded_regions.add(minimum=0, maximum=40000)
experiment.excluded_regions.add(minimum=108000, maximum=200000)
Show excluded regions.
In [25]:
Copied!
experiment.excluded_regions.show()
experiment.excluded_regions.show()
Excluded regions
minimum | maximum |
---|---|
0 |
40000 |
108000 |
200000 |
Show measured data after adding excluded regions.
In [26]:
Copied!
project.plot_meas(expt_name='mcstas')
project.plot_meas(expt_name='mcstas')
Show experiment as CIF.
In [27]:
Copied!
project.experiments['mcstas'].show_as_cif()
project.experiments['mcstas'].show_as_cif()
Experiment 🔬 'mcstas' as cif
data_mcstas |
_expt_type.beam_mode time-of-flight |
_expt_type.radiation_probe neutron |
_expt_type.sample_form powder |
_expt_type.scattering_type bragg |
_instr.d_to_tof_linear 58724.76869981215 |
_instr.d_to_tof_offset 0.0 |
_instr.d_to_tof_quad -1e-05 |
_instr.d_to_tof_recip 0.0 |
_instr.2theta_bank 94.90931761529106 |
_peak.asym_alpha_0 0 |
_peak.asym_alpha_1 0.0097 |
_peak.gauss_sigma_0 45137 |
_peak.gauss_sigma_1 -52394 |
_peak.gauss_sigma_2 22998 |
_peak.lorentz_gamma_0 0.0 |
_peak.lorentz_gamma_1 0.0 |
_peak.lorentz_gamma_2 0.0 |
_peak.mix_beta_0 0.0055 |
_peak.mix_beta_1 0.0041 |
loop_ |
_pd_phase_block.id |
_pd_phase_block.scale |
lbco 4.0 |
si 0.2 |
loop_ |
_pd_background.line_segment_X |
_pd_background.line_segment_intensity |
45000 0.2 |
50000 0.2 |
55000 0.2 |
65000 0.2 |
70000 0.2 |
75000 0.2 |
80000 0.2 |
85000 0.2 |
90000 0.2 |
95000 0.2 |
100000 0.2 |
105000 0.2 |
110000 0.2 |
loop_ |
_excluded_region.maximum |
_excluded_region.minimum |
40000 0 |
200000 108000 |
loop_ |
_pd_meas.2theta_scan |
_pd_meas.intensity_total |
_pd_meas.intensity_total_su |
41168.1286 0.21537107469310052 0.024851140698641586 |
41273.8536 0.2608731253560513 0.03329888041963864 |
41379.5785 0.3043368615904641 0.0354708759178845 |
41485.3035 0.473667080481105 0.04206283617542718 |
41591.0285 0.6002651986502522 0.04196647994561225 |
... |
107563.4097 0.2230171962356684 0.007062820875646159 |
107669.1347 0.2196314236755727 0.007156715455880738 |
107774.8597 0.22676234246085125 0.00713080922521723 |
107880.5847 0.21245260466359916 0.006812625277766074 |
107986.3096 0.21452950815000962 0.006898412477966333 |
In [28]:
Copied!
project.analysis.current_calculator = 'cryspy'
project.analysis.current_calculator = 'cryspy'
Current calculator changed to
cryspy
Set Minimizer¶
In [29]:
Copied!
project.analysis.current_minimizer = 'lmfit (leastsq)'
project.analysis.current_minimizer = 'lmfit (leastsq)'
Current minimizer changed to
lmfit (leastsq)
Set Fitting Parameters¶
Set sample model parameters to be optimized.
In [30]:
Copied!
model_1.cell.length_a.free = True
model_1.atom_sites['Co'].b_iso.free = True
model_1.atom_sites['O'].b_iso.free = True
model_2.cell.length_a.free = True
model_1.cell.length_a.free = True
model_1.atom_sites['Co'].b_iso.free = True
model_1.atom_sites['O'].b_iso.free = True
model_2.cell.length_a.free = True
Set experiment parameters to be optimized.
In [31]:
Copied!
experiment.linked_phases['lbco'].scale.free = True
experiment.linked_phases['si'].scale.free = True
experiment.peak.broad_gauss_sigma_0.free = True
experiment.peak.broad_gauss_sigma_1.free = True
experiment.peak.broad_gauss_sigma_2.free = True
experiment.peak.asym_alpha_1.free = True
experiment.peak.broad_mix_beta_0.free = True
experiment.peak.broad_mix_beta_1.free = True
for point in experiment.background:
point.y.free = True
experiment.linked_phases['lbco'].scale.free = True
experiment.linked_phases['si'].scale.free = True
experiment.peak.broad_gauss_sigma_0.free = True
experiment.peak.broad_gauss_sigma_1.free = True
experiment.peak.broad_gauss_sigma_2.free = True
experiment.peak.asym_alpha_1.free = True
experiment.peak.broad_mix_beta_0.free = True
experiment.peak.broad_mix_beta_1.free = True
for point in experiment.background:
point.y.free = True
Perform Fit¶
In [32]:
Copied!
project.analysis.fit()
project.analysis.fit()
Using experiment 🔬 'mcstas' for 'single' fitting 🚀 Starting fit process with 'lmfit (leastsq)'... 📈 Goodness-of-fit (reduced χ²) change:
iteration | χ² | improvement [%] |
---|---|---|
1 |
301.41 |
|
29 |
3.36 |
98.9% ↓ |
55 |
3.24 |
3.7% ↓ |
134 |
3.24 |
🏆 Best goodness-of-fit (reduced χ²) is 3.24 at iteration 133
✅ Fitting complete.
Fit results
✅ Success: True
⏱️ Fitting time: 2.14 seconds
📏 Goodness-of-fit (reduced χ²): 3.24
📏 R-factor (Rf): 4.76%
📏 R-factor squared (Rf²): 5.16%
📏 Weighted R-factor (wR): 5.22%
📈 Fitted parameters:
datablock | category | entry | parameter | start | fitted | uncertainty | units | change | |
---|---|---|---|---|---|---|---|---|---|
1 | lbco |
atom_sites |
Co |
b_iso |
0.2567 |
0.3233 |
0.0853 |
Ų |
25.94 % ↑ |
2 | lbco |
atom_sites |
O |
b_iso |
1.4041 |
2.1686 |
0.0282 |
Ų |
54.45 % ↑ |
3 | lbco |
cell |
length_a |
3.8909 |
3.8904 |
0.0001 |
Å |
0.01 % ↓ |
|
4 | si |
cell |
length_a |
5.4315 |
5.4327 |
0.0006 |
Å |
0.02 % ↑ |
|
5 | mcstas |
background |
45000 |
y |
0.2000 |
0.2502 |
0.0082 |
25.09 % ↑ |
|
6 | mcstas |
background |
50000 |
y |
0.2000 |
0.2498 |
0.0080 |
24.91 % ↑ |
|
7 | mcstas |
background |
55000 |
y |
0.2000 |
0.2674 |
0.0047 |
33.68 % ↑ |
|
8 | mcstas |
background |
65000 |
y |
0.2000 |
0.2551 |
0.0036 |
27.53 % ↑ |
|
9 | mcstas |
background |
70000 |
y |
0.2000 |
0.2463 |
0.0035 |
23.17 % ↑ |
|
10 | mcstas |
background |
75000 |
y |
0.2000 |
0.2417 |
0.0027 |
20.86 % ↑ |
|
11 | mcstas |
background |
80000 |
y |
0.2000 |
0.2421 |
0.0033 |
21.07 % ↑ |
|
12 | mcstas |
background |
85000 |
y |
0.2000 |
0.2374 |
0.0021 |
18.71 % ↑ |
|
13 | mcstas |
background |
90000 |
y |
0.2000 |
0.2381 |
0.0020 |
19.07 % ↑ |
|
14 | mcstas |
background |
95000 |
y |
0.2000 |
0.2423 |
0.0025 |
21.14 % ↑ |
|
15 | mcstas |
background |
100000 |
y |
0.2000 |
0.2258 |
0.0022 |
12.88 % ↑ |
|
16 | mcstas |
background |
105000 |
y |
0.2000 |
0.2228 |
0.0026 |
11.40 % ↑ |
|
17 | mcstas |
background |
110000 |
y |
0.2000 |
0.2225 |
0.0078 |
11.23 % ↑ |
|
18 | mcstas |
linked_phases |
lbco |
scale |
4.0000 |
4.5577 |
0.0318 |
13.94 % ↑ |
|
19 | mcstas |
linked_phases |
si |
scale |
0.2000 |
0.0314 |
0.0008 |
84.28 % ↓ |
|
20 | mcstas |
peak |
asym_alpha_1 |
0.0097 |
0.0097 |
0.0002 |
0.40 % ↓ |
||
21 | mcstas |
peak |
gauss_sigma_0 |
45137.0000 |
45210.8969 |
2868.4651 |
µs² |
0.16 % ↑ |
|
22 | mcstas |
peak |
gauss_sigma_1 |
-52394.0000 |
-52476.8991 |
3797.9256 |
µs/Å |
0.16 % ↑ |
|
23 | mcstas |
peak |
gauss_sigma_2 |
22998.0000 |
23014.3392 |
1193.4306 |
µs²/Ų |
0.07 % ↑ |
|
24 | mcstas |
peak |
mix_beta_0 |
0.0055 |
0.0055 |
0.0001 |
deg |
0.64 % ↑ |
|
25 | mcstas |
peak |
mix_beta_1 |
0.0041 |
0.0041 |
0.0003 |
deg |
0.32 % ↓ |
Plot Measured vs Calculated¶
In [33]:
Copied!
project.plot_meas_vs_calc(expt_name='mcstas')
project.plot_meas_vs_calc(expt_name='mcstas')