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 ExperimentFactory
from easydiffraction import Project
from easydiffraction import StructureFactory
from easydiffraction import download_data
from easydiffraction import ExperimentFactory
from easydiffraction import Project
from easydiffraction import StructureFactory
from easydiffraction import download_data
In [3]:
Copied!
structure_1 = StructureFactory.from_scratch(name='lbco')
structure_1 = StructureFactory.from_scratch(name='lbco')
Set Space Group¶
In [4]:
Copied!
structure_1.space_group.name_h_m = 'P m -3 m'
structure_1.space_group.it_coordinate_system_code = '1'
structure_1.space_group.name_h_m = 'P m -3 m'
structure_1.space_group.it_coordinate_system_code = '1'
Set Unit Cell¶
In [5]:
Copied!
structure_1.cell.length_a = 3.8909
structure_1.cell.length_a = 3.8909
Set Atom Sites¶
In [6]:
Copied!
structure_1.atom_sites.create(
label='La',
type_symbol='La',
fract_x=0,
fract_y=0,
fract_z=0,
wyckoff_letter='a',
b_iso=0.2,
occupancy=0.5,
)
structure_1.atom_sites.create(
label='Ba',
type_symbol='Ba',
fract_x=0,
fract_y=0,
fract_z=0,
wyckoff_letter='a',
b_iso=0.2,
occupancy=0.5,
)
structure_1.atom_sites.create(
label='Co',
type_symbol='Co',
fract_x=0.5,
fract_y=0.5,
fract_z=0.5,
wyckoff_letter='b',
b_iso=0.2567,
)
structure_1.atom_sites.create(
label='O',
type_symbol='O',
fract_x=0,
fract_y=0.5,
fract_z=0.5,
wyckoff_letter='c',
b_iso=1.4041,
)
structure_1.atom_sites.create(
label='La',
type_symbol='La',
fract_x=0,
fract_y=0,
fract_z=0,
wyckoff_letter='a',
b_iso=0.2,
occupancy=0.5,
)
structure_1.atom_sites.create(
label='Ba',
type_symbol='Ba',
fract_x=0,
fract_y=0,
fract_z=0,
wyckoff_letter='a',
b_iso=0.2,
occupancy=0.5,
)
structure_1.atom_sites.create(
label='Co',
type_symbol='Co',
fract_x=0.5,
fract_y=0.5,
fract_z=0.5,
wyckoff_letter='b',
b_iso=0.2567,
)
structure_1.atom_sites.create(
label='O',
type_symbol='O',
fract_x=0,
fract_y=0.5,
fract_z=0.5,
wyckoff_letter='c',
b_iso=1.4041,
)
Create Structure 2: Si¶
In [7]:
Copied!
structure_2 = StructureFactory.from_scratch(name='si')
structure_2 = StructureFactory.from_scratch(name='si')
Set Space Group¶
In [8]:
Copied!
structure_2.space_group.name_h_m = 'F d -3 m'
structure_2.space_group.it_coordinate_system_code = '2'
structure_2.space_group.name_h_m = 'F d -3 m'
structure_2.space_group.it_coordinate_system_code = '2'
Set Unit Cell¶
In [9]:
Copied!
structure_2.cell.length_a = 5.43146
structure_2.cell.length_a = 5.43146
Set Atom Sites¶
In [10]:
Copied!
structure_2.atom_sites.create(
label='Si',
type_symbol='Si',
fract_x=0.0,
fract_y=0.0,
fract_z=0.0,
wyckoff_letter='a',
b_iso=0.0,
)
structure_2.atom_sites.create(
label='Si',
type_symbol='Si',
fract_x=0.0,
fract_y=0.0,
fract_z=0.0,
wyckoff_letter='a',
b_iso=0.0,
)
In [11]:
Copied!
data_path = download_data(id=8, destination='data')
data_path = download_data(id=8, destination='data')
Getting data...
Data #8: La0.5Ba0.5CoO3 + Si, McStas simulation
✅ Data #8 downloaded to 'data/ed-8.xye'
Create Experiment¶
In [12]:
Copied!
experiment = ExperimentFactory.from_data_path(
name='mcstas',
data_path=data_path,
sample_form='powder',
beam_mode='time-of-flight',
radiation_probe='neutron',
scattering_type='bragg',
)
experiment = ExperimentFactory.from_data_path(
name='mcstas',
data_path=data_path,
sample_form='powder',
beam_mode='time-of-flight',
radiation_probe='neutron',
scattering_type='bragg',
)
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' already set to
line-segment
Add background points.
In [16]:
Copied!
experiment.background.create(id='1', x=45000, y=0.2)
experiment.background.create(id='2', x=50000, y=0.2)
experiment.background.create(id='3', x=55000, y=0.2)
experiment.background.create(id='4', x=65000, y=0.2)
experiment.background.create(id='5', x=70000, y=0.2)
experiment.background.create(id='6', x=75000, y=0.2)
experiment.background.create(id='7', x=80000, y=0.2)
experiment.background.create(id='8', x=85000, y=0.2)
experiment.background.create(id='9', x=90000, y=0.2)
experiment.background.create(id='10', x=95000, y=0.2)
experiment.background.create(id='11', x=100000, y=0.2)
experiment.background.create(id='12', x=105000, y=0.2)
experiment.background.create(id='13', x=110000, y=0.2)
experiment.background.create(id='1', x=45000, y=0.2)
experiment.background.create(id='2', x=50000, y=0.2)
experiment.background.create(id='3', x=55000, y=0.2)
experiment.background.create(id='4', x=65000, y=0.2)
experiment.background.create(id='5', x=70000, y=0.2)
experiment.background.create(id='6', x=75000, y=0.2)
experiment.background.create(id='7', x=80000, y=0.2)
experiment.background.create(id='8', x=85000, y=0.2)
experiment.background.create(id='9', x=90000, y=0.2)
experiment.background.create(id='10', x=95000, y=0.2)
experiment.background.create(id='11', x=100000, y=0.2)
experiment.background.create(id='12', x=105000, y=0.2)
experiment.background.create(id='13', x=110000, y=0.2)
Set Linked Phases¶
In [17]:
Copied!
experiment.linked_phases.create(id='lbco', scale=4.0)
experiment.linked_phases.create(id='si', scale=0.2)
experiment.linked_phases.create(id='lbco', scale=4.0)
experiment.linked_phases.create(id='si', scale=0.2)
In [18]:
Copied!
project = Project()
project = Project()
Add Structures¶
In [19]:
Copied!
project.structures.add(structure_1)
project.structures.add(structure_2)
project.structures.add(structure_1)
project.structures.add(structure_2)
Show Structures¶
In [20]:
Copied!
project.structures.show_names()
project.structures.show_names()
Defined structures 🧩
['lbco', 'si']
Add Experiments¶
In [21]:
Copied!
project.experiments.add(experiment)
project.experiments.add(experiment)
Set Excluded Regions¶
Show measured data as loaded from the file.
In [22]:
Copied!
project.plot_meas(expt_name='mcstas')
project.plot_meas(expt_name='mcstas')
Add excluded regions.
In [23]:
Copied!
experiment.excluded_regions.create(id='1', start=0, end=40000)
experiment.excluded_regions.create(id='2', start=108000, end=200000)
experiment.excluded_regions.create(id='1', start=0, end=40000)
experiment.excluded_regions.create(id='2', start=108000, end=200000)
Show excluded regions.
In [24]:
Copied!
experiment.excluded_regions.show()
experiment.excluded_regions.show()
Excluded regions
| start | end | |
|---|---|---|
| 1 | 0.00000 | 40000 |
| 2 | 108000.00000 | 200000 |
Show measured data after adding excluded regions.
In [25]:
Copied!
project.plot_meas(expt_name='mcstas')
project.plot_meas(expt_name='mcstas')
Show experiment as CIF.
In [26]:
Copied!
project.experiments['mcstas'].show_as_cif()
project.experiments['mcstas'].show_as_cif()
Experiment 🔬 'mcstas' as cif
| CIF | |
|---|---|
| 1 | data_mcstas |
| 2 | |
| 3 | _expt_type.sample_form powder |
| 4 | _expt_type.beam_mode time-of-flight |
| 5 | _expt_type.radiation_probe neutron |
| 6 | _expt_type.scattering_type bragg |
| 7 | |
| 8 | _diffrn.ambient_temperature None |
| 9 | _diffrn.ambient_pressure None |
| 10 | _diffrn.ambient_magnetic_field None |
| 11 | _diffrn.ambient_electric_field None |
| 12 | |
| 13 | _peak.asym_alpha_0 0.00000000 |
| 14 | _peak.asym_alpha_1 0.00970000 |
| 15 | _peak.gauss_sigma_0 45137.00000000 |
| 16 | _peak.gauss_sigma_1 -52394.00000000 |
| 17 | _peak.gauss_sigma_2 22998.00000000 |
| 18 | _peak.lorentz_gamma_0 0.00000000 |
| 19 | _peak.lorentz_gamma_1 0.00000000 |
| 20 | _peak.lorentz_gamma_2 0.00000000 |
| 21 | _peak.mix_beta_0 0.00550000 |
| 22 | _peak.mix_beta_1 0.00410000 |
| 23 | |
| 24 | _instr.2theta_bank 94.90931762 |
| 25 | _instr.d_to_tof_offset 0.00000000 |
| 26 | _instr.d_to_tof_linear 58724.76869981 |
| 27 | _instr.d_to_tof_quad -0.00001000 |
| 28 | _instr.d_to_tof_recip 0.00000000 |
| 29 | |
| 30 | loop_ |
| 31 | _pd_phase_block.id |
| 32 | _pd_phase_block.scale |
| 33 | lbco 4.00000000 |
| 34 | si 0.20000000 |
| 35 | |
| 36 | loop_ |
| 37 | _excluded_region.id |
| 38 | _excluded_region.start |
| 39 | _excluded_region.end |
| 40 | 1 0.00000000 40000.00000000 |
| 41 | 2 108000.00000000 200000.00000000 |
| 42 | |
| 43 | loop_ |
| 44 | _pd_meas.time_of_flight |
| 45 | _pd_data.point_id |
| 46 | _pd_proc.d_spacing |
| 47 | _pd_meas.intensity_total |
| 48 | _pd_meas.intensity_total_su |
| 49 | _pd_calc.intensity_total |
| 50 | _pd_calc.intensity_bkg |
| 51 | _pd_data.refinement_status |
| 52 | 41168.12860000 1 0.70103524 0.21537107 0.02485114 0.25454340 0.20000000 incl |
| 53 | 41273.85360000 2 0.70283531 0.26087313 0.03329888 0.33827395 0.20000000 incl |
| 54 | 41379.57850000 3 0.70463575 0.30433686 0.03547088 0.46671493 0.20000000 incl |
| 55 | 41485.30350000 4 0.70643619 0.47366708 0.04206284 0.58607008 0.20000000 incl |
| 56 | 41591.02850000 5 0.70823626 0.60026520 0.04196648 0.62332828 0.20000000 incl |
| 57 | 41696.75340000 6 0.71003669 0.60174483 0.03965186 0.55740167 0.20000000 incl |
| 58 | 41802.47840000 7 0.71183713 0.50118258 0.03810349 0.43268835 0.20000000 incl |
| 59 | 41908.20340000 8 0.71363756 0.37702264 0.03458906 0.31517712 0.20000000 incl |
| 60 | 42013.92840000 9 0.71543800 0.27533183 0.03190951 0.24565766 0.20000000 incl |
| 61 | 42119.65330000 10 0.71723844 0.26182311 0.02830043 0.22739950 0.20000000 incl |
| 62 | ... |
| 63 | 145835.84890000 991 2.48337892 0.22406860 0.01131008 0.20000000 0.20000000 excl |
| 64 | 145941.57390000 992 2.48517936 0.21377274 0.01070627 0.20000000 0.20000000 excl |
| 65 | 146047.29880000 993 2.48697943 0.20927726 0.01085520 0.20000000 0.20000000 excl |
| 66 | 146153.02380000 994 2.48877986 0.21839779 0.01091455 0.20000000 0.20000000 excl |
| 67 | 146258.74880000 995 2.49058030 0.21613293 0.01104795 0.20000000 0.20000000 excl |
| 68 | 146364.47370000 996 2.49238037 0.20571926 0.01109275 0.20000000 0.20000000 excl |
| 69 | 146470.19870000 997 2.49418081 0.22615941 0.01142946 0.20000000 0.20000000 excl |
| 70 | 146575.92370000 998 2.49598124 0.22113311 0.01151463 0.20000000 0.20000000 excl |
| 71 | 146681.64860000 999 2.49778168 0.20862390 0.01097638 0.20000000 0.20000000 excl |
| 72 | 146787.37360000 1000 2.49958175 0.20883912 0.01092893 0.20000000 0.20000000 excl |
| 73 | |
| 74 | loop_ |
| 75 | _pd_background.id |
| 76 | _pd_background.line_segment_X |
| 77 | _pd_background.line_segment_intensity |
| 78 | 1 45000.00000000 0.20000000 |
| 79 | 2 50000.00000000 0.20000000 |
| 80 | 3 55000.00000000 0.20000000 |
| 81 | 4 65000.00000000 0.20000000 |
| 82 | 5 70000.00000000 0.20000000 |
| 83 | 6 75000.00000000 0.20000000 |
| 84 | 7 80000.00000000 0.20000000 |
| 85 | 8 85000.00000000 0.20000000 |
| 86 | 9 90000.00000000 0.20000000 |
| 87 | 10 95000.00000000 0.20000000 |
| 88 | 11 100000.00000000 0.20000000 |
| 89 | 12 105000.00000000 0.20000000 |
| 90 | 13 110000.00000000 0.20000000 |
In [27]:
Copied!
project.analysis.current_minimizer = 'lmfit'
project.analysis.current_minimizer = 'lmfit'
Current minimizer changed to
lmfit
Set Fitting Parameters¶
Set structure parameters to be optimized.
In [28]:
Copied!
structure_1.cell.length_a.free = True
structure_1.atom_sites['Co'].b_iso.free = True
structure_1.atom_sites['O'].b_iso.free = True
structure_2.cell.length_a.free = True
structure_1.cell.length_a.free = True
structure_1.atom_sites['Co'].b_iso.free = True
structure_1.atom_sites['O'].b_iso.free = True
structure_2.cell.length_a.free = True
Set experiment parameters to be optimized.
In [29]:
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 [30]:
Copied!
project.analysis.fit()
project.analysis.show_fit_results()
project.analysis.fit()
project.analysis.show_fit_results()
Using experiment 🔬 'mcstas' for 'single' fitting
🚀 Starting fit process with 'lmfit (leastsq)'...
📈 Goodness-of-fit (reduced χ²) change:
| iteration | χ² | improvement [%] | |
|---|---|---|---|
| 1 | 1 | 301.41 | |
| 2 | 29 | 3.36 | 98.9% ↓ |
| 3 | 55 | 3.24 | 3.7% ↓ |
| 4 | 134 | 3.24 |
🏆 Best goodness-of-fit (reduced χ²) is 3.24 at iteration 133
✅ Fitting complete.
Fit results
✅ Success: True
⏱️ Fitting time: 4.40 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 | cell | length_a | 3.8909 | 3.8904 | 0.0001 | Å | 0.01 % ↓ | |
| 2 | lbco | atom_site | Co | b_iso | 0.2567 | 0.3233 | 0.0853 | Ų | 25.94 % ↑ |
| 3 | lbco | atom_site | O | b_iso | 1.4041 | 2.1686 | 0.0282 | Ų | 54.45 % ↑ |
| 4 | si | cell | length_a | 5.4315 | 5.4327 | 0.0006 | Å | 0.02 % ↑ | |
| 5 | mcstas | linked_phases | lbco | scale | 4.0000 | 4.5577 | 0.0318 | 13.94 % ↑ | |
| 6 | mcstas | linked_phases | si | scale | 0.2000 | 0.0314 | 0.0008 | 84.28 % ↓ | |
| 7 | mcstas | peak | asym_alpha_1 | 0.0097 | 0.0097 | 0.0002 | 0.40 % ↓ | ||
| 8 | mcstas | peak | gauss_sigma_0 | 45137.0000 | 45210.8969 | 2868.4651 | µs² | 0.16 % ↑ | |
| 9 | mcstas | peak | gauss_sigma_1 | -52394.0000 | -52476.8991 | 3797.9256 | µs/Å | 0.16 % ↑ | |
| 10 | mcstas | peak | gauss_sigma_2 | 22998.0000 | 23014.3392 | 1193.4306 | µs²/Ų | 0.07 % ↑ | |
| 11 | mcstas | peak | mix_beta_0 | 0.0055 | 0.0055 | 0.0001 | deg | 0.64 % ↑ | |
| 12 | mcstas | peak | mix_beta_1 | 0.0041 | 0.0041 | 0.0003 | deg | 0.32 % ↓ | |
| 13 | mcstas | background | 1 | y | 0.2000 | 0.2502 | 0.0082 | 25.09 % ↑ | |
| 14 | mcstas | background | 2 | y | 0.2000 | 0.2498 | 0.0080 | 24.91 % ↑ | |
| 15 | mcstas | background | 3 | y | 0.2000 | 0.2674 | 0.0047 | 33.68 % ↑ | |
| 16 | mcstas | background | 4 | y | 0.2000 | 0.2551 | 0.0036 | 27.53 % ↑ | |
| 17 | mcstas | background | 5 | y | 0.2000 | 0.2463 | 0.0035 | 23.17 % ↑ | |
| 18 | mcstas | background | 6 | y | 0.2000 | 0.2417 | 0.0027 | 20.86 % ↑ | |
| 19 | mcstas | background | 7 | y | 0.2000 | 0.2421 | 0.0033 | 21.07 % ↑ | |
| 20 | mcstas | background | 8 | y | 0.2000 | 0.2374 | 0.0021 | 18.71 % ↑ | |
| 21 | mcstas | background | 9 | y | 0.2000 | 0.2381 | 0.0020 | 19.07 % ↑ | |
| 22 | mcstas | background | 10 | y | 0.2000 | 0.2423 | 0.0025 | 21.14 % ↑ | |
| 23 | mcstas | background | 11 | y | 0.2000 | 0.2258 | 0.0022 | 12.88 % ↑ | |
| 24 | mcstas | background | 12 | y | 0.2000 | 0.2228 | 0.0026 | 11.40 % ↑ | |
| 25 | mcstas | background | 13 | y | 0.2000 | 0.2225 | 0.0078 | 11.23 % ↑ |
Plot Measured vs Calculated¶
In [31]:
Copied!
project.plot_meas_vs_calc(expt_name='mcstas')
project.plot_meas_vs_calc(expt_name='mcstas')
In [ ]:
Copied!