Co₂SiO₄ on D20, cooling scan¶
Fit the olivine Co₂SiO₄ with its magnetic structure to the whole D20 cooling scan, 213 patterns from 497.4 K down to 2.3 K, one after another and from the lowest temperature up. First the fit is staged on the 2.3 K pattern, the scan's template; then each later pattern starts from the previous result. The cobalt moments stay free at every temperature and fall towards zero near the Néel temperature, about 50 K.
The project is the catalogue case pd-neut-cwl_cosio-d20_scan-213f, the one the command line
and the app's Examples open. Its two Co sites share one displacement from the start.
Fitting
Sequential pd neut cwl Bragg
Crystal structure
Magnetic structure
import csv
from pathlib import Path
import easydiffraction as edi
Load the project¶
A sequential fit writes one row per pattern into the project's analysis/results.csv, so work
on a copy of the project, saved to a folder of its own.
project_path = edi.download_data('pd-neut-cwl_cosio-d20_scan-213f', destination='data')
project = edi.Project.load(project_path)
project.save_as('pd-neut-cwl_cosio-d20_scan-213f')
structure = project.structures['cosio']
experiment = project.experiments['d20']
Data 'pd-neut-cwl_cosio-d20_scan-213f' is at data/pd-neut-cwl_cosio-d20_scan-213f-a86d87ed4b81/pd-neut-cwl_cosio-d20_scan-213f
Saving project to 'pd-neut-cwl_cosio-d20_scan-213f'
Stage the template fit¶
The template is the 2.3 K pattern. Fit it alone first, in stages, so the scan starts from a good model: switch the fitting mode to a single fit, and start with nothing free.
project.analysis.fitting_mode = 'single'
for parameter in project.free_parameters:
parameter.free = False
project.display.pattern('d20')
Perform the analysis¶
Scale, 2θ zero and cell¶
experiment.linked_structures['cosio'].scale.free = True
experiment.instrument.calib_twotheta_offset.free = True
structure.cell.length_a.free = True
structure.cell.length_b.free = True
structure.cell.length_c.free = True
project.display.parameters.free()
project.analysis.fit()
project.display.fit.results()
edi fit: project pd-neut-cwl_cosio-d20_scan-213f, 1438 pts fitted / 1506 loaded, 5 free
iter time (s) Rwp (%) reduced χ² change
15.23 64.02
1 0.006 14.24 55.94 12.6% ↓
2 0.012 14.22 55.83 0.2% ↓
3 0.017 14.22 55.83
4 0.025 14.22 55.83
done · converged · 4 iters · reduced χ² 55.83 · Rwp 14.22 % · 0.03 s
project.display.pattern('d20')
Background¶
The sixteen background points follow the level between the peaks.
for point in experiment.background:
point.intensity.free = True
project.analysis.fit()
project.display.fit.results()
edi fit: project pd-neut-cwl_cosio-d20_scan-213f, 1438 pts fitted / 1506 loaded, 21 free
iter time (s) Rwp (%) reduced χ² change
14.22 56.46
1 0.008 13.46 50.59 10.4% ↓
2 0.017 13.46 50.59
done · converged · 2 iters · reduced χ² 50.59 · Rwp 13.46 % · 0.02 s
project.display.pattern('d20')
Peak widths¶
U, V and W only: across a temperature scan the Lorentzian term and the asymmetry stay at their 2.3 K values, as do the form factor's j2 term.
experiment.peak.broad_gauss_u.free = True
experiment.peak.broad_gauss_v.free = True
experiment.peak.broad_gauss_w.free = True
project.analysis.fit()
project.display.fit.results()
edi fit: project pd-neut-cwl_cosio-d20_scan-213f, 1438 pts fitted / 1506 loaded, 24 free
iter time (s) Rwp (%) reduced χ² change
13.46 50.70
1 0.008 13.29 49.39 2.6% ↓
2 0.015 13.29 49.35 0.1% ↓
3 0.023 13.28 49.35
done · converged · 3 iters · reduced χ² 49.35 · Rwp 13.28 % · 0.03 s
project.display.pattern('d20')
Atom positions¶
for site in structure.atom_sites:
for coordinate in (site.fract_x, site.fract_y, site.fract_z):
coordinate.free = not coordinate.symmetry_constrained
project.analysis.fit()
project.display.fit.results()
edi fit: project pd-neut-cwl_cosio-d20_scan-213f, 1438 pts fitted / 1506 loaded, 35 free
iter time (s) Rwp (%) reduced χ² change
13.28 49.74
1 0.008 13.22 49.28 0.9% ↓
2 0.015 13.22 49.27
3 0.024 13.22 49.27
done · converged · 3 iters · reduced χ² 49.27 · Rwp 13.22 % · 0.03 s
project.display.pattern('d20')
Displacements¶
Co2's displacement follows Co1's by the project's constraint.
for site in structure.atom_sites:
site.adp_iso.free = not site.adp_iso.user_constrained
project.analysis.fit()
project.display.fit.results()
edi fit: project pd-neut-cwl_cosio-d20_scan-213f, 1438 pts fitted / 1506 loaded, 40 free
iter time (s) Rwp (%) reduced χ² change
13.22 49.45
1 0.009 13.01 47.86 3.2% ↓
2 0.016 13.00 47.83 0.1% ↓
3 0.026 13.00 47.83
done · converged · 3 iters · reduced χ² 47.83 · Rwp 13.00 % · 0.03 s
project.display.pattern('d20')
Magnetic moments¶
Last, the moments: Co1 in any direction, Co2 along b.
structure.atom_site_moment['Co1'].crystalaxis_x.free = True
structure.atom_site_moment['Co1'].crystalaxis_y.free = True
structure.atom_site_moment['Co1'].crystalaxis_z.free = True
structure.atom_site_moment['Co2'].crystalaxis_y.free = True
project.analysis.fit()
project.display.fit.results()
edi fit: project pd-neut-cwl_cosio-d20_scan-213f, 1438 pts fitted / 1506 loaded, 44 free
iter time (s) Rwp (%) reduced χ² change
13.00 47.97
1 0.011 10.87 33.54 30.1% ↓
2 0.018 4.94 6.91 79.4% ↓
3 0.024 4.71 6.30 8.8% ↓
4 0.031 4.69 6.25 0.8% ↓
5 0.041 4.69 6.24 0.2% ↓
6 0.048 4.69 6.24
7 0.056 4.69 6.24
8 0.063 4.69 6.24
9 0.071 4.69 6.24
10 0.078 4.69 6.24
11 0.086 4.69 6.24
12 0.096 4.69 6.24
13 0.103 4.69 6.24
14 0.110 4.69 6.24
15 0.119 4.69 6.24
16 0.127 4.69 6.24
17 0.134 4.69 6.24
18 0.142 4.69 6.24
19 0.149 4.69 6.24
20 0.159 4.69 6.24
21 0.166 4.69 6.24
22 0.177 4.69 6.24
done · converged · 22 iters · reduced χ² 6.24 · Rwp 4.69 % · 0.19 s
project.display.pattern('d20')
Fit the scan¶
Back to the sequential mode, with the template's free parameters. The fit can stop between patterns: here it stops after five, all below 3 K, and the rows it wrote stay.
project.analysis.fitting_mode = 'sequential'
fitted = []
result = project.fit_sequential(
on_file_complete=lambda *args: fitted.append(args),
should_cancel=lambda: len(fitted) >= 5,
)
print(result.status.name.lower(), 'after', len(fitted), 'patterns')
cancelled after 5 patterns
Resume¶
Starting again continues with the first pattern that has no row yet, from the last fitted values. The whole scan takes a while.
result = project.fit_sequential(on_file_complete=lambda *args: fitted.append(args))
print(result.status.name.lower(), 'with', len(fitted), 'patterns fitted in all')
done with 213 patterns fitted in all
The moments against temperature¶
One row per pattern, in the order they were fitted. The moment columns name their site and component.
results = Path('pd-neut-cwl_cosio-d20_scan-213f/analysis/results.csv')
with results.open(newline='', encoding='utf-8') as file:
rows = list(csv.DictReader(file))
moments = [name for name in rows[0] if 'crystalaxis' in name and not name.endswith('_su')]
print(len(rows), 'rows; moment columns:', ', '.join(moments))
213 rows; moment columns: cosio.atom_site_moment.Co1.crystalaxis_x, cosio.atom_site_moment.Co1.crystalaxis_x.uncertainty, cosio.atom_site_moment.Co1.crystalaxis_y, cosio.atom_site_moment.Co1.crystalaxis_y.uncertainty, cosio.atom_site_moment.Co1.crystalaxis_z, cosio.atom_site_moment.Co1.crystalaxis_z.uncertainty, cosio.atom_site_moment.Co2.crystalaxis_y, cosio.atom_site_moment.Co2.crystalaxis_y.uncertainty
Save the report¶
The HTML report draws the measured, calculated and difference patterns with the nuclear and the magnetic reflection positions, and lists the structure and the fit. Open it in a browser.
project.report.save_html('pd-neut-cwl_cosio-d20_scan-213f.html')
Saving report to 'pd-neut-cwl_cosio-d20_scan-213f.html'