Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f2cc887
refactor(easydiffraction): move the easydiff package into gateways/ea…
AdamCorrao Oct 9, 2026
45bc833
feat(easydiffraction): native easydiffraction.rietveld schema (re/06)
AdamCorrao Oct 9, 2026
d8db8c5
feat(easydiffraction): native builder and run for easydiffraction.rie…
AdamCorrao Oct 9, 2026
508f39f
chore(easydiffraction): bump easydiffraction to 0.21.1 and solve env
AdamCorrao Oct 10, 2026
e2408f3
chore(easydiffraction): supported version ==0.21.1 (A116)
AdamCorrao Oct 10, 2026
b9af5c8
fix(easydiffraction): anisotropic ADPs reach the engine (EB-23, A169)
AdamCorrao Oct 10, 2026
4ff6e36
docs(easydiffraction): the not-converged warning names its likely cau…
AdamCorrao Oct 10, 2026
8c3b598
fix(easydiffraction): verify each calculator's settings on its own (A…
AdamCorrao Oct 10, 2026
b4fe715
test(easydiffraction): two-phase native fixture, test and golden (re/06)
AdamCorrao Oct 10, 2026
e5219b2
feat(easydiffraction): negative peak widths are refused, and reported…
AdamCorrao Oct 10, 2026
4cccf85
docs(easydiffraction): SCHEMA_HISTORY entry for engine schema 1.0.0 (…
AdamCorrao Oct 10, 2026
a0119d7
fix(easydiffraction): write the data loop without exponents (EB-89)
AdamCorrao Oct 10, 2026
f1c9bce
test(easydiffraction): the CrysPy LaB6 golden carries the negative-wi…
AdamCorrao Oct 10, 2026
3b1feec
feat(gsasii): report whether a Rietveld refinement converged (A172)
AdamCorrao Oct 10, 2026
585ba69
fix(easydiffraction): read the reflection list strictly; tests for si…
AdamCorrao Oct 10, 2026
1c9e499
fix(easydiffraction): verify settings on every special site; CrysPy r…
AdamCorrao Oct 10, 2026
8dfa9bb
fix(easydiffraction): refuse negative intensities; check peak widths …
AdamCorrao Oct 10, 2026
0000d5f
feat(easydiffraction): accept positions held as a lattice translation…
AdamCorrao Oct 10, 2026
d1d7a08
docs(easydiffraction): SCHEMA_HISTORY for the PR-review decisions (A1…
AdamCorrao Oct 10, 2026
799938f
fix(easydiffraction): at a zero limit, judge "ended at the limit" rel…
AdamCorrao Oct 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 85 additions & 4 deletions docs/SCHEMA_HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,11 @@ core `==1.0.0`. A 0.26.0 `GSASII_*` recipe is converted with
statistics over the stated fit window (`None` where undefined, e.g. no
degrees of freedom); `simulation_mode` (a simulation gets the same
statistics; against placeholder data they mean nothing); GSAS-II's own
values, `parameters_requested` and `parameters_varied` under
values, `parameters_requested`, `parameters_varied` and `converged`
(Rietveld; GSAS-II keeps no such flag for a peak fit) under
`engine_details`; structured `warnings` (defaults applied, GSAS-II's
refinement messages, fewer parameters varied than requested). A refinement
refinement messages, fewer parameters varied than requested, a Rietveld
refinement that stopped before converging, values kept). A refinement
that diverges (a non-finite calculated pattern) is a failure with a clear
message; GSAS-II itself does not flag it.

Expand Down Expand Up @@ -332,9 +334,88 @@ unchanged).

## easydiffraction engine schema

### 1.0.0 — introduced in PowderLine 0.2.0
### 1.0.0 — introduced in PowderLine 0.2.0 (in development)

Defined in `src/powderline/gateways/easydiffraction/schema.py` (engine-free),
on core 1.0.0. Accepted versions are declared: engine schema `==1.0.0`,
requiring core `==1.0.0`. Native recipes use easydiffraction's own names and
units (`setup_wavelength`, `calib_twotheta_offset`, `broad_gauss_u` in deg², …).
There is no converter from 0.26.0 recipes (the 0.26.0 `GSASII_*` →
easydiffraction path is unchanged until re/07).

Entries added by re/06 (`easydiffraction.rietveld`).
- **Workflow**: `easydiffraction.rietveld` (`phases`); no single peak fitting.
- **easydiffraction version**: pinned (`==0.21.1`) and read at run time; a
recipe states none.
- **No defaults**: a block left out means the feature is not modelled; every
value PowderLine would otherwise choose is a required field.
- **Parameters**: `[value, refine_flag, min, max]`. A stated bound replaces
easydiffraction's physical limit on that side; `null` keeps it (cell lengths
0–30 Å, angles 0–180°, occupancy 0–1, Uiso and U11/U22/U33 0–10 Ų, scale,
wavelength and μR ≥ 0). A value outside a physical limit is an error, even
when fixed (easydiffraction refuses it); a cell length over 30 Å cannot be
modelled.
- **Instrument**: `radiation` (`setup_wavelength` > 0; a Kα2 line
`setup_wavelength_2` + `setup_wavelength_2_to_1_ratio` stated together);
`polarization` (`setup_polarization_coefficient` p, `setup_monochromator_twotheta`;
GSAS-II's P is 1 − p); `corrections` (`calib_twotheta_offset`, and optionally
`calib_sample_displacement`, `calib_sample_transparency`); `absorption`
(`cylinder-hewat`, `mu_r`); `broadening` `{peak_type, parameters}` with
`cwl-pseudo-voigt` (both calculators), `cwl-pseudo-voigt-berar-baldinozzi-asymmetry`
(CrysPy) or `cwl-thompson-cox-hastings` (CrysFML, FCJ `asym_fcj_1/2`), and
`cutoff_fwhm` (CrysPy only). Gaussian FWHM² = U tan²θ + V tanθ + W (deg²),
Lorentzian FWHM = X tanθ + Y/cosθ (deg; GSAS-II's X and Y swap roles). A stated
profile that makes either width negative within 1° of the fit window (widened
by the size of the stated zero, displacement and transparency corrections) is
an error: easydiffraction computes reflections just outside the window too,
and would compute a wrong pattern without a message.
- **Background**: `chebyshev`, over the fit window's first and last points.
- **Phase block**: core's `space_group`, `unit_cell`, `atoms` (`Uiso` and
`Uaniso` in Ų, used as given), plus `scale` (≥ 0: a phase may contribute
nothing). Symmetry ties become one easydiffraction parameter per tie group,
the one easydiffraction leaves free.
- **Space groups**: the canonical name maps to one of easydiffraction's 230
short names plus a setting code (531 settings); each calculator accepts only
the settings it was verified to compute, for a general position and for every
special Wyckoff site (CrysPy 428, CrysFML 230; CrysPy computes
special positions wrongly in nine origin-choice-1 settings, which are refused
for it; the error names one it computes, or the other calculator).
- **Calculator-specific rules**: `Uaniso` needs CrysPy (CrysFML is handed only
B = 8π²·Ueq). With CrysPy, an atom on a special position with a free
coordinate must be written in the pattern of easydiffraction's Wyckoff
template for its site (CrysPy computes wrong intensities for other equivalent
writings); the run refuses it before calculating and names the position to
write. A position easydiffraction stores in another writing of the same site
(a lattice translation, e.g. (0.137, 0.863, z) on (x, −x, z) held as
(0.137, −0.137, z)) is accepted with the warning
`easydiffraction_position_translated`; bounds and reports stay in the recipe's
writing. CrysFML computes in single precision, below lmfit's finite-difference
step, so a CrysFML refinement can depend on its starting values: every CrysFML
refinement carries the warning `easydiffraction_crysfml_start_dependent`.
- **Refinement controls** (required): `calculator` (`cryspy` | `crysfml`),
`minimizer` (`lmfit (leastsq)`), `max_iterations` (lmfit's maximum number of
function evaluations), `chi_square_change_tolerance`,
`parameter_change_tolerance`, `gradient_tolerance`. No refine flag set = a
simulation (the pattern is calculated, lmfit is not run).
- **Fit window and data**: easydiffraction gets exactly the weighted points
with min ≤ 2θ ≤ max (open ends: the data's first or last weighted point), as
a CIF data loop at full precision; a weight above 1e8 (σ < 1e-4) on one of
them is an error (easydiffraction would replace σ by 1.0 without saying so),
and so is a negative intensity on one of them (easydiffraction refuses it).
- **Results**: `rwp`, `r_exp`, `gof`, `chi2_red` from PowderLine's uniform fit
statistics over the window (Rwp equal to easydiffraction's); its values,
calculator, peak type, `parameters_requested` and `parameters_varied`
(lmfit's count) under `engine_details`. The background column is
easydiffraction's own. CrysFML reports no reflection list, so no peak lists
are written with it. Warnings: `easydiffraction_parameters_not_varied`,
`easydiffraction_parameter_at_limit` (a value within 1e-6 relative of a stated bound
or physical limit; for a limit of 0, within 1e-6 of the parameter's starting
value), `easydiffraction_phase_contributes_nothing`
(informative), `easydiffraction_fit_not_converged` (the values are reported),
`easydiffraction_negative_width` (the refined profile makes a width negative
within the checked range), `easydiffraction_reflections_not_available`
(CrysFML), `easydiffraction_position_translated`,
`easydiffraction_crysfml_start_dependent`. Any non-finite calculated value,
refined value or reflection-list value is a divergence error.

---

Expand Down
Loading