Structure Refinement: NCAF, WISH¶
This example demonstrates a Rietveld refinement of Na2Ca3Al2F14 crystal structure using time-of-flight neutron powder diffraction data from WISH at ISIS.
Two datasets from detector banks 5+6 and 4+7 are used for joint fitting.
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('ncaf')
model = SampleModel('ncaf')
Set Space Group¶
In [4]:
Copied!
model.space_group.name_h_m = 'I 21 3'
model.space_group.it_coordinate_system_code = '1'
model.space_group.name_h_m = 'I 21 3'
model.space_group.it_coordinate_system_code = '1'
Set Unit Cell¶
In [5]:
Copied!
model.cell.length_a = 10.250256
model.cell.length_a = 10.250256
Set Atom Sites¶
In [6]:
Copied!
model.atom_sites.add('Ca', 'Ca', 0.4663, 0.0, 0.25, wyckoff_letter='b', b_iso=0.92)
model.atom_sites.add('Al', 'Al', 0.2521, 0.2521, 0.2521, wyckoff_letter='a', b_iso=0.73)
model.atom_sites.add('Na', 'Na', 0.0851, 0.0851, 0.0851, wyckoff_letter='a', b_iso=2.08)
model.atom_sites.add('F1', 'F', 0.1377, 0.3054, 0.1195, wyckoff_letter='c', b_iso=0.90)
model.atom_sites.add('F2', 'F', 0.3625, 0.3633, 0.1867, wyckoff_letter='c', b_iso=1.37)
model.atom_sites.add('F3', 'F', 0.4612, 0.4612, 0.4612, wyckoff_letter='a', b_iso=0.88)
model.atom_sites.add('Ca', 'Ca', 0.4663, 0.0, 0.25, wyckoff_letter='b', b_iso=0.92)
model.atom_sites.add('Al', 'Al', 0.2521, 0.2521, 0.2521, wyckoff_letter='a', b_iso=0.73)
model.atom_sites.add('Na', 'Na', 0.0851, 0.0851, 0.0851, wyckoff_letter='a', b_iso=2.08)
model.atom_sites.add('F1', 'F', 0.1377, 0.3054, 0.1195, wyckoff_letter='c', b_iso=0.90)
model.atom_sites.add('F2', 'F', 0.3625, 0.3633, 0.1867, wyckoff_letter='c', b_iso=1.37)
model.atom_sites.add('F3', 'F', 0.4612, 0.4612, 0.4612, wyckoff_letter='a', b_iso=0.88)
In [7]:
Copied!
download_from_repository(
'wish_ncaf_5_6.xys',
destination='data',
)
download_from_repository(
'wish_ncaf_5_6.xys',
destination='data',
)
⚠️ Warning
File 'data/wish_ncaf_5_6.xys' already exists and will not be overwritten.
In [8]:
Copied!
download_from_repository(
'wish_ncaf_4_7.xys',
destination='data',
)
download_from_repository(
'wish_ncaf_4_7.xys',
destination='data',
)
⚠️ Warning
File 'data/wish_ncaf_4_7.xys' already exists and will not be overwritten.
Create Experiment¶
In [9]:
Copied!
expt56 = Experiment(
'wish_5_6',
beam_mode='time-of-flight',
data_path='data/wish_ncaf_5_6.xys',
)
expt56 = Experiment(
'wish_5_6',
beam_mode='time-of-flight',
data_path='data/wish_ncaf_5_6.xys',
)
Data loaded successfully
Experiment 🔬 'wish_5_6'. Number of data points: 4121
In [10]:
Copied!
expt47 = Experiment(
'wish_4_7',
beam_mode='time-of-flight',
data_path='data/wish_ncaf_4_7.xys',
)
expt47 = Experiment(
'wish_4_7',
beam_mode='time-of-flight',
data_path='data/wish_ncaf_4_7.xys',
)
Data loaded successfully
Experiment 🔬 'wish_4_7'. Number of data points: 4043
Set Instrument¶
In [11]:
Copied!
expt56.instrument.setup_twotheta_bank = 152.827
expt56.instrument.calib_d_to_tof_offset = -13.5
expt56.instrument.calib_d_to_tof_linear = 20773.0
expt56.instrument.calib_d_to_tof_quad = -1.08308
expt56.instrument.setup_twotheta_bank = 152.827
expt56.instrument.calib_d_to_tof_offset = -13.5
expt56.instrument.calib_d_to_tof_linear = 20773.0
expt56.instrument.calib_d_to_tof_quad = -1.08308
In [12]:
Copied!
expt47.instrument.setup_twotheta_bank = 121.660
expt47.instrument.calib_d_to_tof_offset = -15.0
expt47.instrument.calib_d_to_tof_linear = 18660.0
expt47.instrument.calib_d_to_tof_quad = -0.47488
expt47.instrument.setup_twotheta_bank = 121.660
expt47.instrument.calib_d_to_tof_offset = -15.0
expt47.instrument.calib_d_to_tof_linear = 18660.0
expt47.instrument.calib_d_to_tof_quad = -0.47488
Set Peak Profile¶
In [13]:
Copied!
expt56.peak.broad_gauss_sigma_0 = 0.0
expt56.peak.broad_gauss_sigma_1 = 0.0
expt56.peak.broad_gauss_sigma_2 = 15.5
expt56.peak.broad_mix_beta_0 = 0.007
expt56.peak.broad_mix_beta_1 = 0.01
expt56.peak.asym_alpha_0 = -0.0094
expt56.peak.asym_alpha_1 = 0.1
expt56.peak.broad_gauss_sigma_0 = 0.0
expt56.peak.broad_gauss_sigma_1 = 0.0
expt56.peak.broad_gauss_sigma_2 = 15.5
expt56.peak.broad_mix_beta_0 = 0.007
expt56.peak.broad_mix_beta_1 = 0.01
expt56.peak.asym_alpha_0 = -0.0094
expt56.peak.asym_alpha_1 = 0.1
In [14]:
Copied!
expt47.peak.broad_gauss_sigma_0 = 0.0
expt47.peak.broad_gauss_sigma_1 = 29.8
expt47.peak.broad_gauss_sigma_2 = 18.0
expt47.peak.broad_mix_beta_0 = 0.006
expt47.peak.broad_mix_beta_1 = 0.015
expt47.peak.asym_alpha_0 = -0.0115
expt47.peak.asym_alpha_1 = 0.1
expt47.peak.broad_gauss_sigma_0 = 0.0
expt47.peak.broad_gauss_sigma_1 = 29.8
expt47.peak.broad_gauss_sigma_2 = 18.0
expt47.peak.broad_mix_beta_0 = 0.006
expt47.peak.broad_mix_beta_1 = 0.015
expt47.peak.asym_alpha_0 = -0.0115
expt47.peak.asym_alpha_1 = 0.1
Set Background¶
In [15]:
Copied!
expt56.background_type = 'line-segment'
for x, y in [
(9162, 465),
(11136, 593),
(13313, 497),
(14906, 546),
(16454, 533),
(17352, 496),
(18743, 428),
(20179, 452),
(21368, 397),
(22176, 468),
(22827, 477),
(24644, 380),
(26439, 381),
(28257, 378),
(31196, 343),
(34034, 328),
(37265, 310),
(41214, 323),
(44827, 283),
(49830, 273),
(52905, 257),
(58204, 260),
(62916, 261),
(70186, 262),
(74204, 262),
(82103, 268),
(91958, 268),
(102712, 262),
]:
expt56.background.add(x, y)
expt56.background_type = 'line-segment'
for x, y in [
(9162, 465),
(11136, 593),
(13313, 497),
(14906, 546),
(16454, 533),
(17352, 496),
(18743, 428),
(20179, 452),
(21368, 397),
(22176, 468),
(22827, 477),
(24644, 380),
(26439, 381),
(28257, 378),
(31196, 343),
(34034, 328),
(37265, 310),
(41214, 323),
(44827, 283),
(49830, 273),
(52905, 257),
(58204, 260),
(62916, 261),
(70186, 262),
(74204, 262),
(82103, 268),
(91958, 268),
(102712, 262),
]:
expt56.background.add(x, y)
Background type for experiment 'wish_5_6' changed to line-segment
In [16]:
Copied!
expt47.background_type = 'line-segment'
for x, y in [
(9090, 488),
(10672, 566),
(12287, 494),
(14037, 559),
(15451, 529),
(16764, 445),
(18076, 460),
(19456, 413),
(20466, 511),
(21880, 396),
(23798, 391),
(25447, 385),
(28073, 349),
(30058, 332),
(32583, 309),
(34804, 355),
(37160, 318),
(40324, 290),
(46895, 260),
(50631, 256),
(54602, 246),
(58439, 264),
(66520, 250),
(75002, 258),
(83649, 257),
(92770, 255),
(101524, 260),
]:
expt47.background.add(x, y)
expt47.background_type = 'line-segment'
for x, y in [
(9090, 488),
(10672, 566),
(12287, 494),
(14037, 559),
(15451, 529),
(16764, 445),
(18076, 460),
(19456, 413),
(20466, 511),
(21880, 396),
(23798, 391),
(25447, 385),
(28073, 349),
(30058, 332),
(32583, 309),
(34804, 355),
(37160, 318),
(40324, 290),
(46895, 260),
(50631, 256),
(54602, 246),
(58439, 264),
(66520, 250),
(75002, 258),
(83649, 257),
(92770, 255),
(101524, 260),
]:
expt47.background.add(x, y)
Background type for experiment 'wish_4_7' changed to line-segment
Set Linked Phases¶
In [17]:
Copied!
expt56.linked_phases.add('ncaf', scale=1.0)
expt56.linked_phases.add('ncaf', scale=1.0)
In [18]:
Copied!
expt47.linked_phases.add('ncaf', scale=2.0)
expt47.linked_phases.add('ncaf', scale=2.0)
Set Excluded Regions¶
In [19]:
Copied!
expt56.excluded_regions.add(minimum=0, maximum=10010)
expt56.excluded_regions.add(minimum=100010, maximum=200000)
expt56.excluded_regions.add(minimum=0, maximum=10010)
expt56.excluded_regions.add(minimum=100010, maximum=200000)
In [20]:
Copied!
expt47.excluded_regions.add(minimum=0, maximum=10006)
expt47.excluded_regions.add(minimum=100004, maximum=200000)
expt47.excluded_regions.add(minimum=0, maximum=10006)
expt47.excluded_regions.add(minimum=100004, maximum=200000)
In [21]:
Copied!
project = Project()
project = Project()
Set Plotting Engine¶
In [22]:
Copied!
project.plotter.engine = 'plotly'
project.plotter.engine = 'plotly'
Current plotter changed to
plotly
Add Sample Model¶
In [23]:
Copied!
project.sample_models.add(model)
project.sample_models.add(model)
Add Experiment¶
In [24]:
Copied!
project.experiments.add(expt56)
project.experiments.add(expt47)
project.experiments.add(expt56)
project.experiments.add(expt47)
In [25]:
Copied!
project.analysis.current_calculator = 'cryspy'
project.analysis.current_calculator = 'cryspy'
Current calculator changed to
cryspy
Set Minimizer¶
In [26]:
Copied!
project.analysis.current_minimizer = 'lmfit (leastsq)'
project.analysis.current_minimizer = 'lmfit (leastsq)'
Current minimizer changed to
lmfit (leastsq)
Set Fit Mode¶
In [27]:
Copied!
project.analysis.fit_mode = 'joint'
project.analysis.fit_mode = 'joint'
Current fit mode changed to
joint
Set Free Parameters¶
In [28]:
Copied!
model.atom_sites['Ca'].b_iso.free = True
model.atom_sites['Al'].b_iso.free = True
model.atom_sites['Na'].b_iso.free = True
model.atom_sites['F1'].b_iso.free = True
model.atom_sites['F2'].b_iso.free = True
model.atom_sites['F3'].b_iso.free = True
model.atom_sites['Ca'].b_iso.free = True
model.atom_sites['Al'].b_iso.free = True
model.atom_sites['Na'].b_iso.free = True
model.atom_sites['F1'].b_iso.free = True
model.atom_sites['F2'].b_iso.free = True
model.atom_sites['F3'].b_iso.free = True
In [29]:
Copied!
expt56.linked_phases['ncaf'].scale.free = True
expt56.instrument.calib_d_to_tof_offset.free = True
expt56.instrument.calib_d_to_tof_linear.free = True
expt56.peak.broad_gauss_sigma_2.free = True
expt56.peak.broad_mix_beta_0.free = True
expt56.peak.broad_mix_beta_1.free = True
expt56.peak.asym_alpha_1.free = True
expt47.linked_phases['ncaf'].scale.free = True
expt47.instrument.calib_d_to_tof_linear.free = True
expt47.instrument.calib_d_to_tof_offset.free = True
expt47.peak.broad_gauss_sigma_2.free = True
expt47.peak.broad_mix_beta_0.free = True
expt47.peak.broad_mix_beta_1.free = True
expt47.peak.asym_alpha_1.free = True
expt56.linked_phases['ncaf'].scale.free = True
expt56.instrument.calib_d_to_tof_offset.free = True
expt56.instrument.calib_d_to_tof_linear.free = True
expt56.peak.broad_gauss_sigma_2.free = True
expt56.peak.broad_mix_beta_0.free = True
expt56.peak.broad_mix_beta_1.free = True
expt56.peak.asym_alpha_1.free = True
expt47.linked_phases['ncaf'].scale.free = True
expt47.instrument.calib_d_to_tof_linear.free = True
expt47.instrument.calib_d_to_tof_offset.free = True
expt47.peak.broad_gauss_sigma_2.free = True
expt47.peak.broad_mix_beta_0.free = True
expt47.peak.broad_mix_beta_1.free = True
expt47.peak.asym_alpha_1.free = True
Plot Measured vs Calculated¶
In [30]:
Copied!
project.plot_meas_vs_calc(expt_name='wish_5_6', show_residual=True)
project.plot_meas_vs_calc(expt_name='wish_5_6', show_residual=True)
In [31]:
Copied!
project.plot_meas_vs_calc(expt_name='wish_4_7', show_residual=True)
project.plot_meas_vs_calc(expt_name='wish_4_7', show_residual=True)
Run Fitting¶
In [32]:
Copied!
project.analysis.fit()
project.analysis.fit()
Using all experiments 🔬 ['wish_5_6', 'wish_4_7'] for 'joint' fitting 🚀 Starting fit process with 'lmfit (leastsq)'... 📈 Goodness-of-fit (reduced χ²) change:
iteration | χ² | improvement [%] |
---|---|---|
1 |
47.53 |
|
24 |
15.57 |
67.2% ↓ |
109 |
15.49 |
🏆 Best goodness-of-fit (reduced χ²) is 15.49 at iteration 98 ✅ Fitting complete.
Fit results
✅ Success: True
⏱️ Fitting time: 64.44 seconds
📏 Goodness-of-fit (reduced χ²): 15.49
📏 R-factor (Rf): 6.98%
📏 R-factor squared (Rf²): 8.05%
📏 Weighted R-factor (wR): 9.15%
📈 Fitted parameters:
datablock | category | entry | parameter | start | fitted | uncertainty | units | change | |
---|---|---|---|---|---|---|---|---|---|
1 | ncaf |
atom_sites |
Ca |
b_iso |
0.9200 |
0.9340 |
0.0448 |
Ų |
1.52 % ↑ |
2 | ncaf |
atom_sites |
Al |
b_iso |
0.7300 |
0.7330 |
0.0569 |
Ų |
0.41 % ↑ |
3 | ncaf |
atom_sites |
Na |
b_iso |
2.0800 |
2.0474 |
0.1082 |
Ų |
1.57 % ↓ |
4 | ncaf |
atom_sites |
F1 |
b_iso |
0.9000 |
0.9389 |
0.0373 |
Ų |
4.32 % ↑ |
5 | ncaf |
atom_sites |
F2 |
b_iso |
1.3700 |
1.3442 |
0.0408 |
Ų |
1.88 % ↓ |
6 | ncaf |
atom_sites |
F3 |
b_iso |
0.8800 |
0.8481 |
0.0551 |
Ų |
3.62 % ↓ |
7 | wish_5_6 |
instrument |
d_to_tof_linear |
20773.0000 |
20773.0394 |
0.3051 |
µs/Å |
0.00 % ↑ |
|
8 | wish_5_6 |
instrument |
d_to_tof_offset |
-13.5000 |
-13.6260 |
0.4257 |
µs |
0.93 % ↑ |
|
9 | wish_5_6 |
linked_phases |
ncaf |
scale |
1.0000 |
1.1029 |
0.0035 |
10.29 % ↑ |
|
10 | wish_5_6 |
peak |
asym_alpha_1 |
0.1000 |
0.1094 |
0.0012 |
9.43 % ↑ |
||
11 | wish_5_6 |
peak |
gauss_sigma_2 |
15.5000 |
15.6543 |
0.7398 |
µs²/Ų |
1.00 % ↑ |
|
12 | wish_5_6 |
peak |
mix_beta_0 |
0.0070 |
0.0067 |
0.0000 |
deg |
4.54 % ↓ |
|
13 | wish_5_6 |
peak |
mix_beta_1 |
0.0100 |
0.0101 |
0.0002 |
deg |
1.46 % ↑ |
|
14 | wish_4_7 |
instrument |
d_to_tof_linear |
18660.0000 |
18660.1028 |
0.3625 |
µs/Å |
0.00 % ↑ |
|
15 | wish_4_7 |
instrument |
d_to_tof_offset |
-15.0000 |
-14.9768 |
0.5084 |
µs |
0.15 % ↓ |
|
16 | wish_4_7 |
linked_phases |
ncaf |
scale |
2.0000 |
2.5216 |
0.0077 |
26.08 % ↑ |
|
17 | wish_4_7 |
peak |
asym_alpha_1 |
0.1000 |
0.1222 |
0.0018 |
22.15 % ↑ |
||
18 | wish_4_7 |
peak |
gauss_sigma_2 |
18.0000 |
18.2604 |
0.8685 |
µs²/Ų |
1.45 % ↑ |
|
19 | wish_4_7 |
peak |
mix_beta_0 |
0.0060 |
0.0065 |
0.0000 |
deg |
7.52 % ↑ |
|
20 | wish_4_7 |
peak |
mix_beta_1 |
0.0150 |
0.0148 |
0.0003 |
deg |
1.38 % ↓ |
Plot Measured vs Calculated¶
In [33]:
Copied!
project.plot_meas_vs_calc(expt_name='wish_5_6', show_residual=True)
project.plot_meas_vs_calc(expt_name='wish_5_6', show_residual=True)
In [34]:
Copied!
project.plot_meas_vs_calc(expt_name='wish_4_7', show_residual=True)
project.plot_meas_vs_calc(expt_name='wish_4_7', show_residual=True)
Summary¶
This final section shows how to review the results of the analysis.
Show Project Summary¶
In [35]:
Copied!
project.summary.show_report()
project.summary.show_report()
*** PROJECT INFO *** Title Untitled Project *** CRYSTALLOGRAPHIC DATA *** Phase datablock 🧩 ncaf Space group I 21 3 Cell parameters
alpha |
90.00000 |
beta |
90.00000 |
gamma |
90.00000 |
a |
10.25026 |
b |
10.25026 |
c |
10.25026 |
Atom sites
Label | Type | fract_x | fract_y | fract_z | Occupancy | B_iso |
---|---|---|---|---|---|---|
Ca |
Ca |
0.46630 |
0.00000 |
0.25000 |
1.00000 |
0.93400 |
Al |
Al |
0.25210 |
0.25210 |
0.25210 |
1.00000 |
0.73301 |
Na |
Na |
0.08510 |
0.08510 |
0.08510 |
1.00000 |
2.04740 |
F1 |
F |
0.13770 |
0.30540 |
0.11950 |
1.00000 |
0.93890 |
F2 |
F |
0.36250 |
0.36330 |
0.18670 |
1.00000 |
1.34424 |
F3 |
F |
0.46120 |
0.46120 |
0.46120 |
1.00000 |
0.84814 |
*** EXPERIMENTS *** Experiment datablock 🔬 wish_5_6 Experiment type powder, neutron, time-of-flight Profile type pseudo-voigt * ikeda-carpenter Experiment datablock 🔬 wish_4_7 Experiment type powder, neutron, time-of-flight Profile type pseudo-voigt * ikeda-carpenter *** FITTING *** Calculation engine cryspy Minimization engine lmfit (leastsq) Fit quality
Goodness-of-fit (reduced χ²) |
15.49 |