Instrument calibration: BEER at ESS¶
This example demonstrates a Rietveld refinement of a duplex steel structure using time-of-flight neutron powder diffraction data simulated with McStas.
Two datasets from two symmetrically positioned banks (S2 and N2) of the BEER instrument are analyzed in this tutorial.
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 extract_data_paths_from_zip
from easydiffraction import extract_metadata
from easydiffraction import ExperimentFactory
from easydiffraction import Project
from easydiffraction import StructureFactory
from easydiffraction import download_data
from easydiffraction import extract_data_paths_from_zip
from easydiffraction import extract_metadata
In [3]:
Copied!
ferrite = StructureFactory.from_scratch(name='ferrite')
ferrite.space_group.name_h_m = 'I m -3 m'
ferrite.space_group.it_coordinate_system_code = '1'
ferrite.cell.length_a = 2.886
ferrite.atom_sites.create(
label='Fe',
type_symbol='Fe',
fract_x=0.0,
fract_y=0.0,
fract_z=0.0,
wyckoff_letter='a',
adp_type='Biso',
adp_iso=1.0,
)
ferrite = StructureFactory.from_scratch(name='ferrite')
ferrite.space_group.name_h_m = 'I m -3 m'
ferrite.space_group.it_coordinate_system_code = '1'
ferrite.cell.length_a = 2.886
ferrite.atom_sites.create(
label='Fe',
type_symbol='Fe',
fract_x=0.0,
fract_y=0.0,
fract_z=0.0,
wyckoff_letter='a',
adp_type='Biso',
adp_iso=1.0,
)
Create Austenite Structure¶
In [4]:
Copied!
austenite = StructureFactory.from_scratch(name='austenite')
austenite.space_group.name_h_m = 'F m -3 m'
austenite.space_group.it_coordinate_system_code = '1'
austenite.cell.length_a = 3.6468
austenite.atom_sites.create(
label='Fe',
type_symbol='Fe',
fract_x=0.0,
fract_y=0.0,
fract_z=0.0,
wyckoff_letter='a',
adp_type='Biso',
adp_iso=1.0,
)
austenite = StructureFactory.from_scratch(name='austenite')
austenite.space_group.name_h_m = 'F m -3 m'
austenite.space_group.it_coordinate_system_code = '1'
austenite.cell.length_a = 3.6468
austenite.atom_sites.create(
label='Fe',
type_symbol='Fe',
fract_x=0.0,
fract_y=0.0,
fract_z=0.0,
wyckoff_letter='a',
adp_type='Biso',
adp_iso=1.0,
)
In [5]:
Copied!
zip_path = download_data(id=33, destination='data')
data_paths = extract_data_paths_from_zip(zip_path, destination='data/ed-20')
data_path_s2 = data_paths[1] # 'Duplex_in_HR_for_IRF_S2.dat'
data_path_n2 = data_paths[0] # 'Duplex_in_HR_for_IRF_N2.dat'
zip_path = download_data(id=33, destination='data')
data_paths = extract_data_paths_from_zip(zip_path, destination='data/ed-20')
data_path_s2 = data_paths[1] # 'Duplex_in_HR_for_IRF_S2.dat'
data_path_n2 = data_paths[0] # 'Duplex_in_HR_for_IRF_N2.dat'
Getting data...
Data #33: ferrite + austenite, BEER (ESS), S2 and N2 detector bank datasets
✅ Data #33 downloaded to 'data/ed-33.zip'
Create Experiment¶
In [6]:
Copied!
expt_s2 = ExperimentFactory.from_data_path(
name='expt_s2',
data_path=data_path_s2,
beam_mode='time-of-flight',
)
expt_s2 = ExperimentFactory.from_data_path(
name='expt_s2',
data_path=data_path_s2,
beam_mode='time-of-flight',
)
In [7]:
Copied!
expt_n2 = ExperimentFactory.from_data_path(
name='expt_n2',
data_path=data_path_n2,
beam_mode='time-of-flight',
)
expt_n2 = ExperimentFactory.from_data_path(
name='expt_n2',
data_path=data_path_n2,
beam_mode='time-of-flight',
)
Set Instrument¶
In [8]:
Copied!
expt_s2.instrument.setup_twotheta_bank = extract_metadata(
data_path_s2, r'two_theta\s*=\s*(\d*\.?\d+)'
)
expt_s2.instrument.calib_d_to_tof_linear = extract_metadata(
data_path_s2, r'DIFC\s*=\s*(\d*\.?\d+)'
)
expt_s2.instrument.setup_twotheta_bank = extract_metadata(
data_path_s2, r'two_theta\s*=\s*(\d*\.?\d+)'
)
expt_s2.instrument.calib_d_to_tof_linear = extract_metadata(
data_path_s2, r'DIFC\s*=\s*(\d*\.?\d+)'
)
In [9]:
Copied!
expt_n2.instrument.setup_twotheta_bank = extract_metadata(
data_path_n2, r'two_theta\s*=\s*(\d*\.?\d+)'
)
expt_n2.instrument.calib_d_to_tof_linear = extract_metadata(
data_path_n2, r'DIFC\s*=\s*(\d*\.?\d+)'
)
expt_n2.instrument.setup_twotheta_bank = extract_metadata(
data_path_n2, r'two_theta\s*=\s*(\d*\.?\d+)'
)
expt_n2.instrument.calib_d_to_tof_linear = extract_metadata(
data_path_n2, r'DIFC\s*=\s*(\d*\.?\d+)'
)
Set Peak Profile¶
In [10]:
Copied!
expt_s2.show_peak_profile_types()
expt_s2.show_peak_profile_types()
Peak profile types
| Type | Description | ||
|---|---|---|---|
| 1 | pseudo-voigt | TOF non-convoluted pseudo-Voigt profile | |
| 2 | * | jorgensen | TOF Jorgensen profile: back-to-back exponentials ⊗ Gaussian |
| 3 | jorgensen-von-dreele | TOF Jorgensen-Von Dreele profile: back-to-back exponentials ⊗ pseudo-Voigt | |
| 4 | double-jorgensen-von-dreele | TOF Double-Jorgensen-Von Dreele profile: double back-to-back exponentials ⊗ pseudo-Voigt (Z-Rietveld type0m) |
In [11]:
Copied!
expt_s2.peak_profile_type = 'pseudo-voigt'
expt_s2.peak_profile_type = 'pseudo-voigt'
⚠️ Switching peak profile type discards existing peak parameters.
Peak profile type for experiment 'expt_s2' changed to
pseudo-voigt
In [12]:
Copied!
expt_s2.peak.broad_gauss_sigma_0 = 300
expt_s2.peak.broad_gauss_sigma_1 = 1200
expt_s2.peak.broad_gauss_sigma_2 = 900
expt_s2.peak.broad_gauss_sigma_0 = 300
expt_s2.peak.broad_gauss_sigma_1 = 1200
expt_s2.peak.broad_gauss_sigma_2 = 900
In [13]:
Copied!
expt_n2.peak_profile_type = 'pseudo-voigt'
expt_n2.peak_profile_type = 'pseudo-voigt'
⚠️ Switching peak profile type discards existing peak parameters.
Peak profile type for experiment 'expt_n2' changed to
pseudo-voigt
In [14]:
Copied!
expt_n2.peak.broad_gauss_sigma_0 = 300
expt_n2.peak.broad_gauss_sigma_1 = 1200
expt_n2.peak.broad_gauss_sigma_2 = 900
expt_n2.peak.broad_gauss_sigma_0 = 300
expt_n2.peak.broad_gauss_sigma_1 = 1200
expt_n2.peak.broad_gauss_sigma_2 = 900
Set Background¶
In [15]:
Copied!
expt_s2.show_background_types()
expt_s2.show_background_types()
Background types
| Type | Description | ||
|---|---|---|---|
| 1 | chebyshev | Chebyshev polynomial background | |
| 2 | * | line-segment | Linear interpolation between points |
In [16]:
Copied!
# expt_s2.background_type = 'line-segment'
# expt_s2.background_type = 'line-segment'
In [17]:
Copied!
for idx, (x, y) in enumerate(
[
(40111.8789, 0.0170),
(41193.5664, 0.1484),
(42041.3750, 0.1848),
(42713.7734, 0.1975),
(44409.3945, 0.1891),
(45198.7344, 0.2147),
(46251.1875, 0.1887),
(49350.0742, 0.2194),
(51289.6836, 0.1991),
(55245.1992, 0.1981),
(55679.7070, 0.2276),
(56383.9102, 0.2439),
(58956.1797, 0.2907),
(61536.4570, 0.3067),
(63768.0469, 0.3242),
(65581.2109, 0.2973),
(70183.8516, 0.2575),
(71787.8203, 0.2321),
(78343.1094, 0.2158),
(80016.8047, 0.1694),
(98141.8516, 0.2400),
(99262.2344, 0.4335),
(100985.8516, 0.4375),
(101933.8516, 0.3427),
(108656.0312, 0.5339),
(110896.7500, 0.9537),
(113137.4844, 1.1668),
(114430.2031, 1.1164),
(116929.4844, 0.9161),
(119428.7422, 0.6885),
(134506.3438, 0.0692),
],
start=1,
):
expt_s2.background.create(id=str(idx), x=x, y=y)
for idx, (x, y) in enumerate(
[
(40111.8789, 0.0170),
(41193.5664, 0.1484),
(42041.3750, 0.1848),
(42713.7734, 0.1975),
(44409.3945, 0.1891),
(45198.7344, 0.2147),
(46251.1875, 0.1887),
(49350.0742, 0.2194),
(51289.6836, 0.1991),
(55245.1992, 0.1981),
(55679.7070, 0.2276),
(56383.9102, 0.2439),
(58956.1797, 0.2907),
(61536.4570, 0.3067),
(63768.0469, 0.3242),
(65581.2109, 0.2973),
(70183.8516, 0.2575),
(71787.8203, 0.2321),
(78343.1094, 0.2158),
(80016.8047, 0.1694),
(98141.8516, 0.2400),
(99262.2344, 0.4335),
(100985.8516, 0.4375),
(101933.8516, 0.3427),
(108656.0312, 0.5339),
(110896.7500, 0.9537),
(113137.4844, 1.1668),
(114430.2031, 1.1164),
(116929.4844, 0.9161),
(119428.7422, 0.6885),
(134506.3438, 0.0692),
],
start=1,
):
expt_s2.background.create(id=str(idx), x=x, y=y)
In [18]:
Copied!
for point in expt_s2.background:
expt_n2.background.create(id=point.id.value, x=point.x.value, y=point.y.value)
for point in expt_s2.background:
expt_n2.background.create(id=point.id.value, x=point.x.value, y=point.y.value)
Set Linked Phases¶
In [19]:
Copied!
expt_s2.linked_phases.create(id='ferrite', scale=10)
expt_s2.linked_phases.create(id='austenite', scale=10)
expt_s2.linked_phases.create(id='ferrite', scale=10)
expt_s2.linked_phases.create(id='austenite', scale=10)
In [20]:
Copied!
expt_n2.linked_phases.create(id='ferrite', scale=10)
expt_n2.linked_phases.create(id='austenite', scale=10)
expt_n2.linked_phases.create(id='ferrite', scale=10)
expt_n2.linked_phases.create(id='austenite', scale=10)
Set Excluded Regions¶
In [21]:
Copied!
expt_s2.excluded_regions.create(id='1', start=0, end=40500)
expt_s2.excluded_regions.create(id='2', start=130000, end=180000)
expt_s2.excluded_regions.create(id='1', start=0, end=40500)
expt_s2.excluded_regions.create(id='2', start=130000, end=180000)
In [22]:
Copied!
expt_n2.excluded_regions.create(id='1', start=0, end=40500)
expt_n2.excluded_regions.create(id='2', start=130000, end=180000)
expt_n2.excluded_regions.create(id='1', start=0, end=40500)
expt_n2.excluded_regions.create(id='2', start=130000, end=180000)
In [23]:
Copied!
project = Project(name='beer')
project.save_as(dir_path='beer_mcstas')
project = Project(name='beer')
project.save_as(dir_path='beer_mcstas')
Saving project 📦 'beer' to
/home/runner/work/diffraction-lib/diffraction-lib/docs/docs/tutorials/beer_mcstas
├── 📄 project.cif
├── 📁 structures/
├── 📁 experiments/
├── 📁 analysis/
│ └── 📄 analysis.cif
└── 📄 summary.cif
Add Structures¶
In [24]:
Copied!
project.structures.add(ferrite)
project.structures.add(austenite)
project.structures.add(ferrite)
project.structures.add(austenite)
Add Experiments¶
In [25]:
Copied!
project.experiments.add(expt_s2)
project.experiments.add(expt_n2)
project.experiments.add(expt_s2)
project.experiments.add(expt_n2)
Plot Measured vs Calculated¶
In [26]:
Copied!
project.display.plotter.plot_meas_vs_calc(expt_name='expt_s2')
project.display.plotter.plot_meas_vs_calc(expt_name='expt_s2')
In [27]:
Copied!
project.display.plotter.plot_meas_vs_calc(expt_name='expt_n2')
project.display.plotter.plot_meas_vs_calc(expt_name='expt_n2')
In [28]:
Copied!
project.analysis.fit.show_modes()
project.analysis.fit.show_modes()
Fit modes
| Type | Description | ||
|---|---|---|---|
| 1 | * | single | Independent fitting of each experiment |
| 2 | joint | Simultaneous fitting of all experiments with weights | |
| 3 | sequential | Sequential fitting over data files in a directory |
In [29]:
Copied!
project.analysis.fit.mode = 'joint'
project.analysis.fit.mode = 'joint'
Set Free Parameters¶
In [30]:
Copied!
project.analysis.display.fittable_params()
project.analysis.display.fittable_params()
Fittable parameters for all structures (🧩 data blocks)
| datablock | category | entry | parameter | value | uncertainty | units | free | |
|---|---|---|---|---|---|---|---|---|
| 1 | ferrite | cell | length_a | 2.88600 | Å | False | ||
| 2 | ferrite | cell | length_b | 2.88600 | Å | False | ||
| 3 | ferrite | cell | length_c | 2.88600 | Å | False | ||
| 4 | ferrite | cell | angle_alpha | 90.00000 | deg | False | ||
| 5 | ferrite | cell | angle_beta | 90.00000 | deg | False | ||
| 6 | ferrite | cell | angle_gamma | 90.00000 | deg | False | ||
| 7 | ferrite | atom_site | Fe | fract_x | 0.00000 | False | ||
| 8 | ferrite | atom_site | Fe | fract_y | 0.00000 | False | ||
| 9 | ferrite | atom_site | Fe | fract_z | 0.00000 | False | ||
| 10 | ferrite | atom_site | Fe | occupancy | 1.00000 | False | ||
| 11 | ferrite | atom_site | Fe | adp_iso | 1.00000 | Ų | False | |
| 12 | austenite | cell | length_a | 3.64680 | Å | False | ||
| 13 | austenite | cell | length_b | 3.64680 | Å | False | ||
| 14 | austenite | cell | length_c | 3.64680 | Å | False | ||
| 15 | austenite | cell | angle_alpha | 90.00000 | deg | False | ||
| 16 | austenite | cell | angle_beta | 90.00000 | deg | False | ||
| 17 | austenite | cell | angle_gamma | 90.00000 | deg | False | ||
| 18 | austenite | atom_site | Fe | fract_x | 0.00000 | False | ||
| 19 | austenite | atom_site | Fe | fract_y | 0.00000 | False | ||
| 20 | austenite | atom_site | Fe | fract_z | 0.00000 | False | ||
| 21 | austenite | atom_site | Fe | occupancy | 1.00000 | False | ||
| 22 | austenite | atom_site | Fe | adp_iso | 1.00000 | Ų | False |
Fittable parameters for all experiments (🔬 data blocks)
| datablock | category | entry | parameter | value | uncertainty | units | free | |
|---|---|---|---|---|---|---|---|---|
| 1 | expt_s2 | linked_phases | ferrite | scale | 10.00000 | False | ||
| 2 | expt_s2 | linked_phases | austenite | scale | 10.00000 | False | ||
| 3 | expt_s2 | peak | lorentz_gamma_0 | 0.00000 | μs | False | ||
| 4 | expt_s2 | peak | lorentz_gamma_1 | 0.00000 | μs/Å | False | ||
| 5 | expt_s2 | peak | lorentz_gamma_2 | 0.00000 | μs²/Ų | False | ||
| 6 | expt_s2 | peak | gauss_sigma_0 | 300.00000 | μs² | False | ||
| 7 | expt_s2 | peak | gauss_sigma_1 | 1200.00000 | μs/Å | False | ||
| 8 | expt_s2 | peak | gauss_sigma_2 | 900.00000 | μs²/Ų | False | ||
| 9 | expt_s2 | instrument | twotheta_bank | 90.00000 | deg | False | ||
| 10 | expt_s2 | instrument | d_to_tof_offset | 0.00000 | μs | False | ||
| 11 | expt_s2 | instrument | d_to_tof_linear | 54902.18695 | μs/Å | False | ||
| 12 | expt_s2 | instrument | d_to_tof_quad | 0.00000 | μs/Ų | False | ||
| 13 | expt_s2 | instrument | d_to_tof_recip | 0.00000 | μs·Å | False | ||
| 14 | expt_s2 | background | 1 | y | 0.01700 | False | ||
| 15 | expt_s2 | background | 2 | y | 0.14840 | False | ||
| 16 | expt_s2 | background | 3 | y | 0.18480 | False | ||
| 17 | expt_s2 | background | 4 | y | 0.19750 | False | ||
| 18 | expt_s2 | background | 5 | y | 0.18910 | False | ||
| 19 | expt_s2 | background | 6 | y | 0.21470 | False | ||
| 20 | expt_s2 | background | 7 | y | 0.18870 | False | ||
| 21 | expt_s2 | background | 8 | y | 0.21940 | False | ||
| 22 | expt_s2 | background | 9 | y | 0.19910 | False | ||
| 23 | expt_s2 | background | 10 | y | 0.19810 | False | ||
| 24 | expt_s2 | background | 11 | y | 0.22760 | False | ||
| 25 | expt_s2 | background | 12 | y | 0.24390 | False | ||
| 26 | expt_s2 | background | 13 | y | 0.29070 | False | ||
| 27 | expt_s2 | background | 14 | y | 0.30670 | False | ||
| 28 | expt_s2 | background | 15 | y | 0.32420 | False | ||
| 29 | expt_s2 | background | 16 | y | 0.29730 | False | ||
| 30 | expt_s2 | background | 17 | y | 0.25750 | False | ||
| 31 | expt_s2 | background | 18 | y | 0.23210 | False | ||
| 32 | expt_s2 | background | 19 | y | 0.21580 | False | ||
| 33 | expt_s2 | background | 20 | y | 0.16940 | False | ||
| 34 | expt_s2 | background | 21 | y | 0.24000 | False | ||
| 35 | expt_s2 | background | 22 | y | 0.43350 | False | ||
| 36 | expt_s2 | background | 23 | y | 0.43750 | False | ||
| 37 | expt_s2 | background | 24 | y | 0.34270 | False | ||
| 38 | expt_s2 | background | 25 | y | 0.53390 | False | ||
| 39 | expt_s2 | background | 26 | y | 0.95370 | False | ||
| 40 | expt_s2 | background | 27 | y | 1.16680 | False | ||
| 41 | expt_s2 | background | 28 | y | 1.11640 | False | ||
| 42 | expt_s2 | background | 29 | y | 0.91610 | False | ||
| 43 | expt_s2 | background | 30 | y | 0.68850 | False | ||
| 44 | expt_s2 | background | 31 | y | 0.06920 | False | ||
| 45 | expt_n2 | linked_phases | ferrite | scale | 10.00000 | False | ||
| 46 | expt_n2 | linked_phases | austenite | scale | 10.00000 | False | ||
| 47 | expt_n2 | peak | lorentz_gamma_0 | 0.00000 | μs | False | ||
| 48 | expt_n2 | peak | lorentz_gamma_1 | 0.00000 | μs/Å | False | ||
| 49 | expt_n2 | peak | lorentz_gamma_2 | 0.00000 | μs²/Ų | False | ||
| 50 | expt_n2 | peak | gauss_sigma_0 | 300.00000 | μs² | False | ||
| 51 | expt_n2 | peak | gauss_sigma_1 | 1200.00000 | μs/Å | False | ||
| 52 | expt_n2 | peak | gauss_sigma_2 | 900.00000 | μs²/Ų | False | ||
| 53 | expt_n2 | instrument | twotheta_bank | 90.00000 | deg | False | ||
| 54 | expt_n2 | instrument | d_to_tof_offset | 0.00000 | μs | False | ||
| 55 | expt_n2 | instrument | d_to_tof_linear | 54902.18695 | μs/Å | False | ||
| 56 | expt_n2 | instrument | d_to_tof_quad | 0.00000 | μs/Ų | False | ||
| 57 | expt_n2 | instrument | d_to_tof_recip | 0.00000 | μs·Å | False | ||
| 58 | expt_n2 | background | 1 | y | 0.01700 | False | ||
| 59 | expt_n2 | background | 2 | y | 0.14840 | False | ||
| 60 | expt_n2 | background | 3 | y | 0.18480 | False | ||
| 61 | expt_n2 | background | 4 | y | 0.19750 | False | ||
| 62 | expt_n2 | background | 5 | y | 0.18910 | False | ||
| 63 | expt_n2 | background | 6 | y | 0.21470 | False | ||
| 64 | expt_n2 | background | 7 | y | 0.18870 | False | ||
| 65 | expt_n2 | background | 8 | y | 0.21940 | False | ||
| 66 | expt_n2 | background | 9 | y | 0.19910 | False | ||
| 67 | expt_n2 | background | 10 | y | 0.19810 | False | ||
| 68 | expt_n2 | background | 11 | y | 0.22760 | False | ||
| 69 | expt_n2 | background | 12 | y | 0.24390 | False | ||
| 70 | expt_n2 | background | 13 | y | 0.29070 | False | ||
| 71 | expt_n2 | background | 14 | y | 0.30670 | False | ||
| 72 | expt_n2 | background | 15 | y | 0.32420 | False | ||
| 73 | expt_n2 | background | 16 | y | 0.29730 | False | ||
| 74 | expt_n2 | background | 17 | y | 0.25750 | False | ||
| 75 | expt_n2 | background | 18 | y | 0.23210 | False | ||
| 76 | expt_n2 | background | 19 | y | 0.21580 | False | ||
| 77 | expt_n2 | background | 20 | y | 0.16940 | False | ||
| 78 | expt_n2 | background | 21 | y | 0.24000 | False | ||
| 79 | expt_n2 | background | 22 | y | 0.43350 | False | ||
| 80 | expt_n2 | background | 23 | y | 0.43750 | False | ||
| 81 | expt_n2 | background | 24 | y | 0.34270 | False | ||
| 82 | expt_n2 | background | 25 | y | 0.53390 | False | ||
| 83 | expt_n2 | background | 26 | y | 0.95370 | False | ||
| 84 | expt_n2 | background | 27 | y | 1.16680 | False | ||
| 85 | expt_n2 | background | 28 | y | 1.11640 | False | ||
| 86 | expt_n2 | background | 29 | y | 0.91610 | False | ||
| 87 | expt_n2 | background | 30 | y | 0.68850 | False | ||
| 88 | expt_n2 | background | 31 | y | 0.06920 | False |
In [31]:
Copied!
ferrite.atom_sites['Fe'].adp_iso.free = True
austenite.atom_sites['Fe'].adp_iso.free = True
ferrite.atom_sites['Fe'].adp_iso.free = True
austenite.atom_sites['Fe'].adp_iso.free = True
In [32]:
Copied!
expt_s2.linked_phases['ferrite'].scale.free = True
expt_s2.linked_phases['austenite'].scale.free = True
expt_s2.peak.broad_gauss_sigma_0.free = True
expt_s2.peak.broad_gauss_sigma_1.free = True
expt_s2.peak.broad_gauss_sigma_2.free = True
expt_s2.peak.broad_lorentz_gamma_0.free = True
expt_s2.instrument.calib_d_to_tof_offset.free = True
for segment in expt_s2.background:
segment.y.free = True
expt_s2.linked_phases['ferrite'].scale.free = True
expt_s2.linked_phases['austenite'].scale.free = True
expt_s2.peak.broad_gauss_sigma_0.free = True
expt_s2.peak.broad_gauss_sigma_1.free = True
expt_s2.peak.broad_gauss_sigma_2.free = True
expt_s2.peak.broad_lorentz_gamma_0.free = True
expt_s2.instrument.calib_d_to_tof_offset.free = True
for segment in expt_s2.background:
segment.y.free = True
In [33]:
Copied!
expt_n2.linked_phases['ferrite'].scale.free = True
expt_n2.linked_phases['austenite'].scale.free = True
expt_n2.peak.broad_gauss_sigma_0.free = True
expt_n2.peak.broad_gauss_sigma_1.free = True
expt_n2.peak.broad_gauss_sigma_2.free = True
expt_n2.peak.broad_lorentz_gamma_0.free = True
expt_n2.instrument.calib_d_to_tof_offset.free = True
for segment in expt_n2.background:
segment.y.free = True
expt_n2.linked_phases['ferrite'].scale.free = True
expt_n2.linked_phases['austenite'].scale.free = True
expt_n2.peak.broad_gauss_sigma_0.free = True
expt_n2.peak.broad_gauss_sigma_1.free = True
expt_n2.peak.broad_gauss_sigma_2.free = True
expt_n2.peak.broad_lorentz_gamma_0.free = True
expt_n2.instrument.calib_d_to_tof_offset.free = True
for segment in expt_n2.background:
segment.y.free = True
Add Constraints¶
In [34]:
Copied!
project.analysis.aliases.create(
label='s2_ferrite_scale', param=expt_s2.linked_phases['ferrite'].scale
)
project.analysis.aliases.create(
label='s2_austenite_scale', param=expt_s2.linked_phases['austenite'].scale
)
project.analysis.aliases.create(
label='n2_ferrite_scale', param=expt_n2.linked_phases['ferrite'].scale
)
project.analysis.aliases.create(
label='n2_austenite_scale', param=expt_n2.linked_phases['austenite'].scale
)
project.analysis.constraints.create(expression='n2_ferrite_scale = s2_ferrite_scale')
project.analysis.constraints.create(expression='n2_austenite_scale = s2_austenite_scale')
project.analysis.aliases.create(
label='s2_ferrite_scale', param=expt_s2.linked_phases['ferrite'].scale
)
project.analysis.aliases.create(
label='s2_austenite_scale', param=expt_s2.linked_phases['austenite'].scale
)
project.analysis.aliases.create(
label='n2_ferrite_scale', param=expt_n2.linked_phases['ferrite'].scale
)
project.analysis.aliases.create(
label='n2_austenite_scale', param=expt_n2.linked_phases['austenite'].scale
)
project.analysis.constraints.create(expression='n2_ferrite_scale = s2_ferrite_scale')
project.analysis.constraints.create(expression='n2_austenite_scale = s2_austenite_scale')
Run Fitting¶
Run full fitting with all free parameters.
In [35]:
Copied!
project.analysis.fit()
project.analysis.fit()
Using all experiments 🔬 ['expt_s2', 'expt_n2'] for 'joint' fitting
🚀 Starting fit process with 'lmfit (leastsq)'...
📈 Goodness-of-fit (reduced χ²) change:
| iteration | χ² | improvement [%] | |
|---|---|---|---|
| 1 | 1 | 843.64 | |
| 2 | 80 | 89.69 | 89.4% ↓ |
| 3 | 157 | 15.07 | 83.2% ↓ |
| 4 | 234 | 13.82 | 8.3% ↓ |
| 5 | 543 | 13.81 |
🏆 Best goodness-of-fit (reduced χ²) is 13.81 at iteration 542
✅ Fitting complete.
Saving project 📦 'beer' to
/home/runner/work/diffraction-lib/diffraction-lib/docs/docs/tutorials/beer_mcstas
├── 📄 project.cif
├── 📁 structures/
│ └── 📄 ferrite.cif
│ └── 📄 austenite.cif
├── 📁 experiments/
│ └── 📄 expt_s2.cif
│ └── 📄 expt_n2.cif
├── 📁 analysis/
│ └── 📄 analysis.cif
└── 📄 summary.cif
Fix background and run fitting again.
In [36]:
Copied!
for segment in expt_s2.background:
segment.y.free = False
for segment in expt_n2.background:
segment.y.free = False
for segment in expt_s2.background:
segment.y.free = False
for segment in expt_n2.background:
segment.y.free = False
In [37]:
Copied!
project.analysis.fit()
project.analysis.fit()
Using all experiments 🔬 ['expt_s2', 'expt_n2'] for 'joint' fitting
🚀 Starting fit process with 'lmfit (leastsq)'...
📈 Goodness-of-fit (reduced χ²) change:
| iteration | χ² | improvement [%] | |
|---|---|---|---|
| 1 | 1 | 13.66 | |
| 2 | 19 | 13.66 |
🏆 Best goodness-of-fit (reduced χ²) is 13.66 at iteration 18
✅ Fitting complete.
Saving project 📦 'beer' to
/home/runner/work/diffraction-lib/diffraction-lib/docs/docs/tutorials/beer_mcstas
├── 📄 project.cif
├── 📁 structures/
│ └── 📄 ferrite.cif
│ └── 📄 austenite.cif
├── 📁 experiments/
│ └── 📄 expt_s2.cif
│ └── 📄 expt_n2.cif
├── 📁 analysis/
│ └── 📄 analysis.cif
└── 📄 summary.cif
Show fit results and parameter correlations.
In [38]:
Copied!
project.analysis.display.fit_results()
project.display.plotter.plot_param_correlations()
project.analysis.display.fit_results()
project.display.plotter.plot_param_correlations()
Fit results
✅ Success: True
⏱️ Fitting time: 1.39 seconds
📏 Goodness-of-fit (reduced χ²): 13.66
📏 R-factor (Rf): 4.96%
📏 R-factor squared (Rf²): 3.86%
📏 Weighted R-factor (wR): 3.36%
📈 Fitted parameters:
| datablock | category | entry | parameter | start | fitted | uncertainty | units | change | |
|---|---|---|---|---|---|---|---|---|---|
| 1 | ferrite | atom_site | Fe | adp_iso | 1.7213 | 1.7213 | 0.0131 | Ų | 0.00 % ↑ |
| 2 | austenite | atom_site | Fe | adp_iso | 1.7092 | 1.7092 | 0.0122 | Ų | 0.00 % ↑ |
| 3 | expt_s2 | linked_phases | ferrite | scale | 50.3587 | 50.3587 | 0.1529 | 0.00 % ↑ | |
| 4 | expt_s2 | linked_phases | austenite | scale | 11.9852 | 11.9852 | 0.0308 | 0.00 % ↑ | |
| 5 | expt_s2 | peak | lorentz_gamma_0 | 5.0196 | 5.0196 | 0.1521 | μs | 0.00 % ↑ | |
| 6 | expt_s2 | peak | gauss_sigma_0 | 881.0993 | 881.1030 | 58.2232 | μs² | 0.00 % ↑ | |
| 7 | expt_s2 | peak | gauss_sigma_1 | 1298.8025 | 1298.7991 | 58.1755 | μs/Å | 0.00 % ↓ | |
| 8 | expt_s2 | peak | gauss_sigma_2 | 308.1175 | 308.1181 | 11.5800 | μs²/Ų | 0.00 % ↑ | |
| 9 | expt_s2 | instrument | d_to_tof_offset | -10.4444 | -10.4444 | 0.1217 | μs | 0.00 % ↑ | |
| 10 | expt_n2 | peak | lorentz_gamma_0 | 5.0134 | 5.0134 | 0.1527 | μs | 0.00 % ↑ | |
| 11 | expt_n2 | peak | gauss_sigma_0 | 915.4872 | 915.4909 | 58.7904 | μs² | 0.00 % ↑ | |
| 12 | expt_n2 | peak | gauss_sigma_1 | 1243.9300 | 1243.9265 | 58.7590 | μs/Å | 0.00 % ↓ | |
| 13 | expt_n2 | peak | gauss_sigma_2 | 325.5845 | 325.5851 | 11.6997 | μs²/Ų | 0.00 % ↑ | |
| 14 | expt_n2 | instrument | d_to_tof_offset | -2.2502 | -2.2502 | 0.1219 | μs | 0.00 % ↑ |
Plot Measured vs Calculated¶
Show full range in TOF.
In [39]:
Copied!
project.display.plotter.plot_meas_vs_calc(expt_name='expt_s2')
project.display.plotter.plot_meas_vs_calc(expt_name='expt_s2')
In [40]:
Copied!
project.display.plotter.plot_meas_vs_calc(expt_name='expt_n2')
project.display.plotter.plot_meas_vs_calc(expt_name='expt_n2')
Show selected peaks in d-spacing.
In [41]:
Copied!
project.display.plotter.plot_meas_vs_calc(
expt_name='expt_s2',
x='d_spacing',
x_min=2.08,
x_max=2.13,
)
project.display.plotter.plot_meas_vs_calc(
expt_name='expt_s2',
x='d_spacing',
x_min=2.08,
x_max=2.13,
)
In [42]:
Copied!
project.display.plotter.plot_meas_vs_calc(
expt_name='expt_n2',
x='d_spacing',
x_min=2.08,
x_max=2.13,
)
project.display.plotter.plot_meas_vs_calc(
expt_name='expt_n2',
x='d_spacing',
x_min=2.08,
x_max=2.13,
)