Repository navigation
Re/04 gsasii schema - #5
Merged
Merged
Conversation
…ema 1.0.0) - gateways/gsasii/schema.py (engine-free): recipes on CoreRecipe, the phase GsasiiPhase(Phase[RefinableParameter]) with scale and peak_broadening flat (A93), the single-source instrument blocks (A99, A103), background and Peak List peaks; RefinableParameter only, no bounds (A84). - GSAS-II rules: space-group settings GSAS-II reads as themselves (canonical name -> GSAS-II symbol; :1 and 9 unreadable settings refused, EB-03, EB-41); GSAS-II cell refinement groups (A95); SH/L >= 0.002 (A91); background-peak and Peak List floors (A86, A90); simulation refines nothing (A88); scale >= 0; phase names unique ignoring case (A112). - Documented defaults (A119): size/strain left out = 10 um / 0 with a structured warning (A87, A107); background left out = one fixed 0.0 term. - Version declarations ==1.0.0 in capabilities() (A65, A81). - schema_core.collect_warnings: a validated model's structured warnings with full field paths (A115). - gsasii_iparm1: GSAS-II's Iparm1 built from the instrument block. - validate() / the gateway route gsasii.* recipes to the native schema; GSASII_* recipes keep the legacy validation until re/07. - Tests: schema rules (77); the space-group translation and cell groups proven against GSAS-II for all 564 canonical names (1054); canary registration (A122); import-block test validates a native recipe. Assisted-by: claude-code:claude-opus-5-5 Assisted-by: claude-code:claude-sonnet-5-5
…er re/04) gateways/gsasii/_legacy_executor.py holds byte-identical copies, taken at 2810c82, of every function the re/04 frozen-edits ledger touches (R1-R10), and of every function on the 0.26.0 path from run_refinement that calls one of them (18 functions + SCHEMA_EXECUTORS). The functions it imports are unedited and shared. So a GSASII_* recipe runs only unedited code and the before/after-refactor comparison stays exact (maintainer, ledger sign-off 2026-10-08). Generated, not edited; deleted with the 0.26.0 schema in re/07. Not yet called: routing to it lands with the ledger edits. Added to the code-hash manifest (script, tripwire test, _code_hash.json). Assisted-by: claude-code:claude-opus-5-5
Input-side edits to the frozen gateway, signed by the maintainer 2026-10-08 (devkit tasks/re04-frozen-edits.md). Only recipe reads change; nothing GSAS-II does to the project changes: - R1 run_refinement takes the native model: Iparm1 built from the instrument blocks (gsasii_iparm1), fit_range from the core model, getattr for the workflow-specific single_peaks/phases, the instrument dumped whole, 'gsasii.spf' check, SCHEMA_EXECUTORS gains the native names; - R2 instrument setter reads radiation.wavelength and corrections.polarization (the corrections loop skips polarization); - R3/R5 the phase block itself (A93), name = dict key (A100); - R4 [value, flag] values; canonical name -> GSAS-II symbol (A105, EB-41); - R6-R8 unpack_refinement_parameter reads [value, flag] too, the 6 bare unpacks + background peaks use it, has_active_refinement_parameter counts 2-element lists (else atom refinement was silently skipped); - R9 background peaks read pv_gaussian_sigma_sq (A89); - R10 extractor reads use getattr. Routing (gateways/gsasii/routing.py): kicker.run_refinement sends a native model to executors.run_refinement and a 0.26.0 RecipeModel to the verbatim legacy copy; the server and the client's in-process fallback validate a received dict with the matching schema. Tests: test_run_refinement_missing_keys runs every case on both executors. Default suite 2673 passed, 4 skipped; every 2810c82 baseline test passes (the 21 retargeted ones in both modes); regression references untouched. Assisted-by: claude-code:claude-opus-5-5 Assisted-by: claude-code:claude-sonnet-5-5
scripts/convert_recipe_026.py states explicitly what v0.1.1 refined and reports every change: structure + parameterization merged into one phase block (the parameterization value won), refine flags expanded to the symmetry and GSAS-II cell groups v0.1.1 refined together (A95), symmetry-fixed flags false, ADP type/flags as GSAS-II used them, v0.1.1's silent defaults written out, Multiplicity dropped where it disagrees (A101), space group to the canonical name as GSAS-II read it (A105), instrument blocks from Iparm1 + parameterization (A103), SH/L to GSAS-II's 0.002 floor (A91), pv_gaussian_sigma -> pv_gaussian_sigma_sq (A89), bounds dropped (A84). Anything the gsasii schema rejects stops the conversion with every problem listed; nothing is fixed silently. The symmetry rewriting stays private to the converter (A124). Engine-free. Tests (43): one per rule, both ADP-switch directions, GSAS-II's reading of every example's symbol, and every committed example (LaB6 and LaB6_simulation stop on the background-peak gamma floor, example_template on its placeholder instrument). Equivalence (devkit probe re04_equivalence_probe.py): for 8 examples the legacy path on the edited 0.26.0 recipe and the native path on its conversion give identical Rwp, ycalc and refined values. Assisted-by: claude-code:claude-opus-5-5 Assisted-by: claude-code:claude-sonnet-5-5
Regenerated from 2810c82 by the same call-graph closure: adds verbatim execute_spf_refinement (R12), export_refined_parameters_csv, _extract_fit_profile (R14) and their caller _extract_refined_parameters, so a 0.26.0 recipe still runs only unedited code (21 functions + SCHEMA_EXECUTORS; the 22 names it imports are byte-identical to 2810c82). Code-hash manifest updated. Assisted-by: claude-code:claude-opus-5-5
GSAS-II misreads some orientations of the 2-fold sites in R32, R-3m and R-3c
(:H): it calls them general with double the multiplicity, which gives 4x the
Bragg intensity with nothing refined (EB-40; devkit probe
re04_eb40_orientation_probe.py). Some sites it cannot name ('sp'), and then
refining a coordinate or Uaniso crashes its constraint setup (EB-05).
- core symmetry.orbit(space_group, xyz): the equivalent positions in gemmi's
operation order, reduced to [0, 1), one per position (engine-free);
- gateways/gsasii/sites.py: after add_phases_from_dict, each atom's GSAS-II
(site_sym, mult) is compared with core's multiplicity; a mismatch, or 'sp'
with a refined coordinate/Uaniso, is an EngineExecutionError naming the
first orbit member GSAS-II reads correctly (never a silent substitution);
- executors.run_refinement calls it (native path only; one line, signed).
Tests land with the batch-2 run tests (tests/test_gsasii_native_run.py).
Assisted-by: claude-code:claude-opus-5-5
… writers (ledger R11, R12, R14) Signed by the maintainer 2026-10-08 (devkit tasks/re04-frozen-edits.md, batch 2); native path only, the 0.26.0 path runs the verbatim legacy copy. - R11 gateways/gsasii/fit_report.py, merged into run_refinement's result: rwp, r_exp, gof, chi2_red from core fitstats over the fit window (A23, A125); engine_details with GSAS-II's own Rwp, GOF (sqrt of reduced chi^2 in a Rietveld refinement, EB-52), chi2, Nobs, parameters_requested (one per refined symmetry tie group) and parameters_varied (Rvals Nvars, which counts parameters GSAS-II then drops, EB-33; Peak List sigDict for SPF); GSAS-II's refinement message (EB-32) as a structured warning. - R12 execute_spf_refinement: refine_peaks' bare TypeError when DoPeakFit fails becomes a clear EngineExecutionError (EB-38). - R14 (A83, native only): the refined-parameters, fit-profile, unit-cell and peak-list tails write through core reports writers, cells formatted as to_csv did (gateways/gsasii/report_rows.py); files byte-identical to the legacy path's on 8 examples (devkit tasks/re04-equivalence-batch2.json). - kicker.run: a native recipe's validation warnings are collected once and carried to the result ahead of the run's; the validate_only summary reports core/engine schema versions and warnings. - server: the response model carries the new keys (they were dropped in server mode); a 0.26.0 result still has none of them. - docs/SCHEMA_HISTORY.md: the gsasii 1.0.0 section. - Tests: tests/test_gsasii_native_run.py (statistics, engine details, warnings, validate_only, refined zero/polarization/SH-L are varied, EB-40 and EB-05 site errors naming a working position, orbit, EB-38, SPF); server response model; mock tests patch the new readers. Assisted-by: claude-code:claude-opus-5-5
- wavelength > 0 and crystallite size > 0 are validation errors (GSAS-II fails on both); LG_eta and polarization stay unlimited (A126) - Peak List peak positions must lie inside the fit window, like background peaks (A126) - single peak fitting: a refine flag on the width source not in use is an error (U..Z with use_instrument_profile false; a peak's sigma^2/gamma with true), since GSAS-II ignores it silently (A127, EB-53) - the JSON Schema shows no null for blocks validation never accepts as null; core absent_not_null_schema made public for the engine schemas - peak_broadening and its parts: the "leave it out" message for null - any gsasii.* schema_name routes to the native schema, so a typo is reported at schema_name with the valid names Assisted-by: claude-code:claude-opus-5-5
- a refinement that diverged (non-finite calculated pattern in the fit window) is an EngineExecutionError saying so; GSAS-II does not flag it (A130, EB-52) - every native result has simulation_mode; a simulation gets the standard statistics; an undefined statistic is None, never NaN (A129) - gsasii_parameters_not_varied warning when GSAS-II varied fewer parameters than the recipe requests (A128, EB-53) - fit_report accepts the peak fit's own Rvals (SPF GOF, used by ledger R16) - GSASClient adds a native recipe's validation warnings on its own paths; kicker.run only in-process (A115); server response carries simulation_mode - site-check messages: payload.-rooted paths, exact decimals where one exists, and a Uaniso must be transformed with the position (A117, A120) - pandas_csv_rows matches to_csv for float32 and non-float missing values Assisted-by: claude-code:claude-opus-5-5
- R15: execute_spf_refinement's EB-38 handler (R12) converts only
DoPeakFit's None result ("'NoneType' object is not subscriptable"); any
other TypeError keeps its own traceback
- R16: execute_spf_refinement returns the peak fit's Rvals and
run_refinement passes them to fit_report, so SPF engine_details has
GSAS-II's own GOF (for a peak fit, the reduced chi^2, EB-52)
Reads only; GSAS-II side unchanged. The legacy copy keeps both functions
verbatim from 2810c82. Code hash updated. Signed by the maintainer
2026-10-08 (devkit tasks/re04-frozen-edits.md, batch 3).
Assisted-by: claude-code:claude-opus-5-5
- ":R" / ":H" suffixes read as GSAS-II read them ("R -3 m:R" was turned
into ":H"); a test checks every gemmi spelling v0.1.1's GSAS-II read
converts to the same setting
- an explicit origin choice ":1" stops: v0.1.1 ran origin-1 coordinates as
origin 2, so neither structure is known
- a partial parameterization Uaniso and an unknown correction key stop
(v0.1.1 raised on both)
- every 0.26.0 key the conversion does not carry is reported (keys v0.1.1
ignored, unused size/strain fields holding a value, parameterization atoms
with no structure atom); the old Uij key is read as Uaniso, as v0.1.1 did
Assisted-by: claude-code:claude-opus-5-5
…R review Wavelength and crystallite size > 0, Peak List peaks inside the fit window, the single-peak-fitting width source, simulation_mode, None for undefined statistics, divergence as a failure, the not-varied warning (A126-A131). Assisted-by: claude-code:claude-opus-5-5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
re/04: native GSAS-II schemas (
gsasii.rietveld,gsasii.spf) and gateway adoptionMerges
re/04-gsasii-schema(7 commits on2810c82, tip65b95ca) intorefactor/multi-engine. Not a gate branch. Plan: devkitdossiers/multi-engine/subplans/re-04-gsasii-schema.md; decisions A81–A92,A93–A123 as they apply to gsasii, A124, A125 (master plan §3).
What this does
gateways/gsasii/schema.py, engine-free), built on core 1.0.0:Phase[RefinableParameter]plusscaleandpeak_broadening);radiation,geometry,corrections,broadening);[value, refine_flag], with no bounds (A84).run_refinementconsumes the validated model (A39). The input-side edits to frozen code are ledger rows R1–R14, all signed in devkittasks/re04-frozen-edits.md.GSASII_*0.26.0 recipes still run, through a verbatim legacy copy of every touched function (_legacy_executor.py, generated from2810c82). The 0.26.0 path runs only unedited code until re/07.scripts/convert_recipe_026.py(0.26.0 → gsasii 1.0.0). It states explicitly what v0.1.1 refined and reports every change. Anything the new schema rejects stops the conversion with every problem listed; nothing is fixed silently.rwp,r_exp,gof,chi2_redfrom corefitstats(A125);engine_details, withparameters_requestedandparameters_varied;warnings: the documented defaults applied, and GSAS-II's refinement messages.A recipe, before and after (LaB6, abridged)
0.26.0 (
GSASII_Rietveld): the structure and parameterization are separate blocks, and the instrument has two sources:gsasii 1.0.0 (
gsasii.rietveld, produced by the converter): one phase block, one instrument, every value explicit:The converter's report for it:
(The committed LaB6 example itself stops in the converter: its background peak
has γ = 1e-5, below GSAS-II's silent floor of 0.1 (A86, EB-35). The example
above raises it to 0.1 first. The example is fixed at re/07.)
Commits
e2481dbschema_core.collect_warnings;validate()routesgsasii.*recipes; schema tests (77) + GSAS-II proof tests (1054)809c329ba068d2run_refinement, setters,project; routing (gateways/gsasii/routing.py)c93615338d6007SCHEMA_EXECUTORS)b8923ddsymmetry.orbit65b95cakicker.runwarnings andvalidate_onlysummary; server response fields; SCHEMA_HISTORY gsasii 1.0.0Rules the gsasii schema enforces
P 21 n m,A b a m) it reads as another setting (EB-41).:R: all six). Matches GSAS-II's owncellVarydispatch for all 522 settings (A95).scale≥ 0 and required; phase names and atom labels unique ignoring case (A112).'sp', EB-05), but only when a coordinate or Uaniso is refined.Evidence
2810c82: 1518 passed, 4 skipped). Every baseline test passes; the 21test_run_refinement_missing_keystests now run as[legacy]and[native].probes/re04_equivalence_probe.py): 8 examples run on both paths, each 0.26.0 recipe edited only to state the new defaults. Results:tests/test_gsasii_native_run.py):zero_shift,polarizationandaxial_divergenceare actually varied (A103);examples/untouched; code hash updated (manifest now includes the legacy copy).Behaviour changes vs v0.1.1
Rows 6–17 in devkit
tasks/deliberate-changes.md, reviewed at G2. Notably:rwpis the uniform Rwp. For the two simulation examples, GSAS-II reports wR 100 %, while the uniform Rwp against their placeholder observations is 1787 % / 6820 % (EB-52; to be documented in re/10).Left for later branches
collect_warnings, the fit-report pattern, the A125 keys and the canary registration.Assisted-by: claude-code:claude-opus-5-5
Assisted-by: claude-code:claude-sonnet-5-5