From d994009de657275a7b43b0c8588870a57289caeb Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 14:05:53 +0200 Subject: [PATCH 01/18] Add verification-software-version-labels ADR suggestion --- docs/dev/adrs/index.md | 1 + .../verification-software-version-labels.md | 256 ++++++++++++++++++ 2 files changed, 257 insertions(+) create mode 100644 docs/dev/adrs/suggestions/verification-software-version-labels.md diff --git a/docs/dev/adrs/index.md b/docs/dev/adrs/index.md index 98c589831..6102a74d3 100644 --- a/docs/dev/adrs/index.md +++ b/docs/dev/adrs/index.md @@ -56,6 +56,7 @@ folders. | Quality | Accepted | Test Strategy | Defines layered unit, functional, integration, script, and notebook testing. | [`test-strategy.md`](accepted/test-strategy.md) | | Quality | Accepted | Test Suite and Validation Strategy | Strict test layers, cost tiers, coverage/codecov policy, cross-engine verification docs, and a nightly validation harness. | [`test-suite-and-validation.md`](accepted/test-suite-and-validation.md) | | Quality | Suggestion | Notebook-Owned Verification Regression Gating | Replaces the external `ci_skip.txt` list with a single in-notebook `regression=False` flag (plus a cell tag for pre-flag crashes). | [`verification-regression-flag.md`](suggestions/verification-regression-flag.md) | +| Quality | Suggestion | Software Version Labels on Verification Pages | Shows FullProf, EasyDiffraction, and engine versions on every verification page (e.g. `edi X.Y.Z (cryspy X.Y.Z)`) via a `verify` helper. | [`verification-software-version-labels.md`](suggestions/verification-software-version-labels.md) | | Structure model | Accepted | Type-Neutral ADP Parameters | Keeps ADP parameter object identities stable across B/U and iso/ani switches. | [`type-neutral-adp-parameters.md`](accepted/type-neutral-adp-parameters.md) | | Structure model | Accepted | Automatic Wyckoff Position Detection | Detects Wyckoff letter, multiplicity, and site symmetry from space group and coordinates; calculators consume them. | [`wyckoff-letter-detection.md`](accepted/wyckoff-letter-detection.md) | | Structure model | Accepted | Complete Space-Group Reference Database | One-time build of a complete space_groups.json.gz (all 230 groups) from cctbx, verified against multiple sources. | [`space-group-database.md`](accepted/space-group-database.md) | diff --git a/docs/dev/adrs/suggestions/verification-software-version-labels.md b/docs/dev/adrs/suggestions/verification-software-version-labels.md new file mode 100644 index 000000000..39faba6c3 --- /dev/null +++ b/docs/dev/adrs/suggestions/verification-software-version-labels.md @@ -0,0 +1,256 @@ +# ADR: Software Version Labels on Verification Pages + +## Status + +Proposed. + +## Date + +2026-06-17 + +## Group + +Quality. + +## Context + +The cross-engine **Verification** pages (established by +[`test-suite-and-validation`](../accepted/test-suite-and-validation.md) +§6) overlay an EasyDiffraction calculator on a frozen FullProf reference +and score the agreement. A scientist reading such a page — or revisiting +it after an engine update — needs to know **which versions of software +produced the curves**, because cross-engine agreement is version +dependent. The Bérar–Baldinozzi case (issue 166) is the clearest +example: whether cryspy and FullProf agree depends on the exact cryspy +build, so a page that does not state its versions cannot be reproduced +or trusted over time. + +Today this **provenance is incomplete and inconsistent**: + +- The **reference** is labelled with the FullProf version on **some** + pages via + `FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE)` + (the version is parsed from the FullProf `.sum`), but **not all** + pages use it. +- The **candidate** is a bare string — `candidate_label='edi-cryspy'` or + `'edi-crysfml'` — carrying **no version** for either EasyDiffraction + or the calculator engine. + +So a reader cannot tell which EasyDiffraction release, which cryspy / +crysfml build, or (on some pages) which FullProf version a comparison +reflects. + +## Decision + +### 1. Every comparison shows the versions of all three components + +Each verification comparison renders the versions of (a) FullProf, (b) +EasyDiffraction, and (c) the engine that produced each curve, so +provenance is **visible in the published HTML** and travels with the +page. The versions appear in **both** label surfaces a page already has, +not just one: + +- the **plot legend** — the `reference_label` / `candidate_label` + arguments of `display.pattern_comparison` (and the single-crystal + reflection equivalent); and +- the **agreement table** — the single `label` element of each + `(label, reference, candidate)` triple passed to + `verify.assert_patterns_agree`, which is rendered verbatim in the + table's `Comparison` column and echoed in the `AssertionError` failure + message (`src/easydiffraction/analysis/verification.py`). + +`assert_patterns_agree` takes **one** comparison label per row, not +separate reference and candidate labels. So its label must be a +**combined** string that names **both** sides — the versioned candidate +and the versioned reference — e.g. +`edi X.Y.Z (cryspy X.Y.Z) vs FullProf X.YZ`. Using the candidate label +alone there would show the EasyDiffraction and engine versions but +**omit FullProf**, defeating the "all three components" goal on that +surface. The page composes the row label as +`f'{candidate_label} vs {reference_label}'` from the same component +labels it uses in the legend (`candidate_label` from +`verify.engine_label`, `reference_label` from `verify.fullprof_label`), +so the legend and the table draw from identical strings and cannot +drift. + +### 2. Canonical label formats + +Version numbers are rendered **bare** (`X.Y.Z`), with **no `v` prefix**, +across all three components so the labels read uniformly: + +- **Reference** → `FullProf X.YZ`, produced by `verify.fullprof_label` + (the FullProf version parsed from the `.sum`), applied **consistently + on every page** — not just where it is used today. `fullprof_label` + currently emits `FullProf vX.YZ`; it is changed to drop the `v` so the + reference matches the bare candidate style (see Compatibility). +- **Candidate** → `edi X.Y.Z (cryspy X.Y.Z)`, and likewise + `edi X.Y.Z (crysfml X.Y.Z)`, replacing the bare `edi-cryspy` / + `edi-crysfml`. The EasyDiffraction version comes first because it is + the package under test; the engine version is the one it drove the + calculation with. + +### 2a. Pre-release / dev builds + +A dev or pre-release install is shown as **release plus the short dev +marker**, dropping the local `+g` segment: a `0.11.0.dev3+g1a2b3c` +install renders as `edi 0.11.0.dev3`. This keeps the "this is a +pre-release build" signal visible (so a dev-build comparison is not +mistaken for a released one) while keeping the label free of the noisy +commit hash. The same rule applies to any engine package reporting a PEP +440 dev/pre-release version. + +### 3. A `verify` helper builds the candidate label from an explicit engine tag + +A single helper — `verify.engine_label(engine, refined=False)` — returns +the **candidate** string only (the reference side stays the existing +`verify.fullprof_label`, so the two single-purpose helpers mirror each +other). It builds the candidate string from: + +- the **EasyDiffraction** package version + (`importlib.metadata.version('easydiffraction')`), and +- the **named calculator engine's** version (see Decision 3a). + +The engine is passed **explicitly as a tag** (`'cryspy'`, `'crysfml'`), +**not** read from `experiment.calculator.type` at render time. This is a +deliberate contract choice: a verification page computes one engine's +curve, stores it, **switches the calculator**, computes the next, then +compares the **stored** arrays together (e.g. +`docs/docs/verification/pd-neut-cwl_pv_lbco.py` calculates with +`cryspy`, switches to `crysfml`, then renders both stored results). A +helper that read the _active_ engine at render time would label a stored +`cryspy` result with whichever engine happened to be active later — +silently wrong provenance. Binding the label to an explicit tag keeps it +aligned with the engine that actually produced the curve. + +In practice the page captures the label **once, immediately after each +calculation**, alongside the engine tag it already passes to +`verify.calculate_pattern(project, experiment, engine)` / +`verify.calculate_reflections(...)`, and reuses that stored candidate +label both as the legend `candidate_label` and as the candidate half of +the combined agreement-table row label +(`f'{candidate_label} vs {reference_label}'`, Decision 1). The same tag +drives the calculation and the label, so they cannot diverge. + +### 3a. Engine version source: the existing engine→package map + +Each engine's version is resolved through the project's **existing** +engine-to-package mapping and metadata lookup +(`_SOFTWARE_PACKAGE_BY_ENGINE` and `_software_version` in +`src/easydiffraction/analysis/analysis.py`), which already maps +`'cryspy' → 'cryspy'` and `'crysfml' → 'crysfml'` and reads the +installed version via `importlib.metadata.version`. The `verify` helper +reuses this single resolution path rather than calling +`cryspy.__version__` or an engine-specific banner parse, so all engine +provenance comes from one place and a new engine is covered by adding +one map entry. + +**Unknown-version behaviour.** If an engine's package version cannot be +resolved (no installed metadata), the helper renders an **explicit, +visible marker** — e.g. `edi X.Y.Z (crysfml ?)` — and never silently +drops the engine version. A missing version is a provenance gap and must +be obvious on the page, consistent with the project's no-silent-failures +principle. This is a render path (it produces a published doc), so it +must not hard-fail the page; the visible marker is the deliberate +fallback. + +### 4. Refined-candidate labels keep the version + +Where a page shows both a raw and a refined candidate (e.g. +`edi-cryspy (refined)`), the version is preserved: +`edi X.Y.Z (cryspy X.Y.Z, refined)`. + +## Consequences + +### Positive + +- **Reproducible provenance.** Every page states the exact FullProf, + EasyDiffraction, and engine versions behind its curves; a future + reader (or a re-run after an engine bump) can tell what was compared. +- **Cross-engine discrepancies become interpretable.** Issue-166-style + "cryspy disagrees with FullProf" notes are anchored to concrete + versions instead of "some build". +- **Consistency.** The FullProf label stops being optional; one helper + drives the candidate label so every page is uniform. +- Labels are **live**: bumping EasyDiffraction or an engine updates the + rendered versions automatically on regeneration, with no per-page + edit. + +### Trade-offs + +- Regenerated notebooks (`notebook-prepare --overwrite`) will show + **version churn** in their committed outputs whenever a version bumps + — expected and desirable (it is the provenance), but it does mean the + `.ipynb` diffs include version strings. +- The helper must resolve each engine's version robustly; an engine + without a discoverable version renders the visible fallback marker + defined in Decision 3a. + +### Compatibility + +- Beta, no shims: the bare `candidate_label='edi-cryspy'` / + `'edi-crysfml'` literals are replaced by the helper on every + verification page; `fullprof_label` is added where missing. +- `verify.fullprof_label` changes its output from `FullProf vX.YZ` to + `FullProf X.YZ` (drop the `v`, Decision 2). Beta, no shims: every page + already calling it re-renders with the bare label on regeneration; its + docstring example is updated to match. (The underlying + `fullprof_version` parser is unchanged — only the label formatting.) +- `notebook-generation` is unaffected: the label is computed in the + `.py` source and regenerated into the notebook. + +## Alternatives Considered + +### Keep bare `edi-cryspy` / `edi-crysfml` + +No versions at all. Rejected: defeats the provenance purpose and makes +version-dependent agreement (issue 166) unreproducible. + +### Record versions in notebook metadata only + +Stash versions in `.ipynb` metadata rather than the visible label. +Rejected: invisible to a reader of the rendered page, and splits the +provenance away from the comparison it describes. + +### Hard-code version strings in each page + +Write the versions as literals next to each label. Rejected: drifts +silently the moment any component is upgraded; the helper keeps them +live. + +## Open Questions + +All questions are now **resolved** (owner decision); recorded here so +the rationale is not lost: + +- **Engine version source — resolved (Decision 3a).** Versions come from + the existing `_SOFTWARE_PACKAGE_BY_ENGINE` / `_software_version` path + in `analysis.py` (`importlib.metadata.version`), with a visible + `crysfml ?`-style marker when a version is unresolvable — no + engine-specific API, no silent omission, no page hard-fail. +- **Label binding — resolved (Decision 3).** The helper takes an + explicit engine tag, not `experiment.calculator.type`, so a stored + result keeps the version of the engine that produced it. +- **Helper name — resolved: + `verify.engine_label(engine, refined=False)`, candidate only (Decision + 3).** The reference side stays `verify.fullprof_label`; the two small + single-purpose helpers mirror each other and the page composes the + combined table label from both. No single dual-return call (it would + couple engine-version logic to `.sum` parsing). +- **Render location — resolved: legend + agreement-table label only + (Decision 1).** No separate provenance caption/row; the versions live + on the two label surfaces a page already has, reusing existing label + plumbing. +- **Format — resolved: bare `X.Y.Z`, no `v` prefix (Decision 2), applied + to all three components.** `fullprof_label` drops its `v` to match + (Compatibility). Pre-release/dev builds render as release plus the + short dev marker (`0.11.0.dev3`), dropping the `+g` local segment + (Decision 2a). + +## Deferred Work + +- Applying the helper across every verification `.py` and regenerating + notebooks belongs to the implementation plan, not this ADR. +- Relationship to the verification regression-gating change is only + adjacent: see + [`verification-regression-flag`](../accepted/verification-regression-flag.md), + which flagged this provenance gap; the two can ship independently. From 3c3186f3a8dae4e5de28b24c11972a13ec1cedd2 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 14:06:02 +0200 Subject: [PATCH 02/18] Add verification-software-version-labels implementation plan --- .../verification-software-version-labels.md | 284 ++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 docs/dev/plans/verification-software-version-labels.md diff --git a/docs/dev/plans/verification-software-version-labels.md b/docs/dev/plans/verification-software-version-labels.md new file mode 100644 index 000000000..c8622c187 --- /dev/null +++ b/docs/dev/plans/verification-software-version-labels.md @@ -0,0 +1,284 @@ +# Plan: Software Version Labels on Verification Pages + +Follows [`AGENTS.md`](../../../AGENTS.md). No deliberate exceptions to +the two-phase workflow: Phase 1 is library + page edits only (no test +authoring), Phase 2 does all test work and runs the verification suite. + +## ADR + +Implements +[`verification-software-version-labels`](../adrs/suggestions/verification-software-version-labels.md) +(Proposed). Per §Change Discipline it is **promoted to `accepted/`** as +part of this PR (P1.4). No new dependency is required — every version is +read through `easydiffraction.utils.utils.package_version` and formatted +for display by a small `verify` helper (`_label_version`, see +Decisions); `stripped_package_version` is **not** used, since it would +drop this repo's `+dev*`/`+dirty*`/`+devdirty*` markers. + +The sibling +[`verification-regression-flag`](../adrs/suggestions/verification-regression-flag.md) +ADR is **separate work**. Both touch the same 15 verification `.py` +pages and their regenerated notebooks, so see Open Question 1 on +ordering. + +## Branch + PR + +- Branch: `verification-software-version-labels` (flat slug off + `develop`). **Not yet created** — `/draft-impl-1` creates and checks + it out off `develop` before its first commit. The current working + branch is `verification-regression-flag`; the uncommitted ADR/plan + edits travel onto the new branch when it is created. +- PR targets `develop`, not `master`. Do not push unless asked. + +## Decisions (from the ADR) + +- **All three versions, both surfaces (Decision 1).** Each comparison + renders FullProf, EasyDiffraction, and the producing engine version in + **both** the plot legend (`reference_label` / `candidate_label`) + **and** the agreement table. The `assert_patterns_agree` row label is + a **combined** string `f'{candidate_label} vs {reference_label}'` so + all three appear there too (it takes one label per row, not a pair). +- **Bare `X.Y.Z` format (Decision 2).** No `v` prefix on any component. + `verify.fullprof_label` changes `FullProf vX.YZ` → `FullProf X.YZ`. + Candidate is `edi X.Y.Z (cryspy X.Y.Z)` / `edi X.Y.Z (crysfml X.Y.Z)`. +- **Dev/pre-release marker (Decision 2a).** Release plus short dev + marker, dropping the `+g` local segment: `edi 0.11.0.dev3`. +- **Helper takes an explicit engine tag (Decision 3).** + `verify.engine_label('cryspy', …)`, **not** + `experiment.calculator.type` read at render time, so a stored result + keeps the version of the engine that produced it. Candidate-only; the + reference side stays `verify.fullprof_label`. +- **Engine version source (Decision 3a).** Resolved through the existing + engine→package map + `importlib.metadata` path; a visible + `crysfml ?`-style marker when a version is unresolvable (never silent, + never a page hard-fail). +- **Refined / annotated candidates keep the version (Decision 4).** e.g. + `edi X.Y.Z (cryspy X.Y.Z, refined)`. + +## Decisions already made for this plan + +- **Dev-marker formatter keeps this repo's local markers; drops only a + git-hash tail.** This repo's versioningit config + (`pyproject.toml [tool.versioningit.format]`) carries the dev signal + in the **local** segment — `{base}+dev{N}`, `{base}+dirty{N}`, + `{base}+devdirty{N}` — which `stripped_package_version` would strip, + rendering `1.2.3+dev3` as `1.2.3` and hiding a dev build (caught in + review 1). So `engine_label` must **not** use + `stripped_package_version` for the EasyDiffraction version. Instead a + small `verify` formatter (e.g. `_label_version(pkg)`) takes the + **raw** `package_version` and **keeps** any + `+dev*`/`+dirty*`/`+devdirty*` marker, trimming **only** a pure + VCS-hash local part (`+g`) to honour Decision 2a's "drop the + noisy commit hash". Net effect on this repo: `1.2.3+dev3` → + `edi 1.2.3+dev3`; a clean release `1.2.3` → `edi 1.2.3`. The same + formatter is applied to engine versions. `_is_dev_version` in + `utils.utils` already encodes the `+dev`/`+dirty`/`+devdirty` marker + detection and can back the formatter. +- **Engine→package map moves to `utils.utils` (P1.1).** Today the map + lives as the private `_SOFTWARE_PACKAGE_BY_ENGINE` in `analysis.py` + (with `_software_version` reading the **raw** version for CIF + provenance stamping). To satisfy Decision 3a's "single resolution + path" without `verification.py` importing heavy `analysis.py`, the + **map** is extracted to `utils.utils` (which both modules already + import and which already owns `package_version`). `analysis.py` + imports it and keeps its existing raw-version stamping behavior + **unchanged**; `verification.py` reads the same map but formats the + result through the `_label_version` display helper (see the dev-marker + decision above). The format (raw for CIF vs display for labels) is a + per-caller choice on top of one shared map. +- **`refined: bool` is generalized to `note: str | None = None`.** Real + pages carry more than "refined": `(scale only)`, + `(scale + ext radius)`, `(refined)`. A boolean cannot express those, + so the helper signature is `engine_label(engine, note=None)` → + `edi X (cryspy X)` or `edi X (cryspy X, )`. `note='refined'` + covers Decision 4. This **refines** the ADR's `refined=False` wording; + the ADR's Decision 3/4 text is updated to `note=` during the promotion + step (P1.4) so ADR and code agree. +- **SC pages always get a versioned FullProf label — no bare fallback.** + Single-crystal pages currently pass the literal + `reference_label='FullProf'` and load + `verify.load_fullprof_sc_f2calc(dir, '.out')`. `fullprof_label` + accepts `.sum`/`.out`, and review 1 confirmed every SC `.out` in use + (`tbti.out`, `prnio.out`) carries the `FullProf.2k (Version 8.40 …)` + banner (sibling `.sum` files exist too). So all SC pages call + `verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE)` like + the powder pages. Keeping the bare `'FullProf'` is **not** an allowed + outcome (it would reintroduce the versionless state this work + removes); if a banner source is ever genuinely absent, the fallback is + a visible `FullProf ?`, never the bare label. + +## Open questions + +1. **Ordering vs `verification-regression-flag`.** Both edit all 15 + `docs/docs/verification/*.py` pages and regenerate the same + notebooks, and both are in flight. Recommendation: land this + **after** `verification-regression-flag` merges to `develop`, then + branch this off the updated `develop`, so the label edits layer + cleanly on the migrated pages instead of colliding. Confirm with the + owner before `/draft-impl-1`. +2. **ADR Decision 4 wording.** The `refined`→`note` generalization above + edits the ADR at promotion (P1.4). Flagged so the owner can veto the + signature if a strict boolean is preferred. + +_(Resolved in review 1: the SC `.out` banner question — every +single-crystal `.out` in use carries the 8.40 banner, so SC pages use +`fullprof_label` with no versionless fallback; see the SC decision +above.)_ + +## Concrete files likely to change + +- `src/easydiffraction/utils/utils.py` — extract the engine→package map + (e.g. `SOFTWARE_PACKAGE_BY_ENGINE`) here; it already hosts + `package_version` / `stripped_package_version`. +- `src/easydiffraction/analysis/analysis.py` — import the shared map; + drop the local `_SOFTWARE_PACKAGE_BY_ENGINE`; `_software_version` + unchanged in behavior (still raw version for CIF stamping). +- `src/easydiffraction/analysis/verification.py` — add + `engine_label(engine, note=None)`; change `fullprof_label` to emit + `FullProf {version}` (drop `v`); update its docstring example. +- The **15** `docs/docs/verification/*.py` pages (+ regenerated `.ipynb` + via `pixi run notebook-prepare`): replace bare + `candidate_label='edi-cryspy'` / `'edi-crysfml'` / `'ed-cryspy'` / + `'ed-crysfml'` (and `(refined)` / `(scale only)` / + `(scale + ext radius)` variants) with `verify.engine_label(...)`; + switch literal `reference_label='FullProf'` to a page + `FULLPROF_LABEL = verify.fullprof_label(...)` where missing; build + combined `assert_patterns_agree` row labels. +- `tests/unit/easydiffraction/analysis/test_verification.py` — Phase 2 + only: update `test_fullprof_label_formats_version` (now + `FullProf 8.40`) and add `engine_label` cases. +- `docs/dev/adrs/suggestions/verification-software-version-labels.md` → + `git mv` to `accepted/`; `docs/dev/adrs/index.md` row flipped to + Accepted; links fixed. + +Find every label call site first with +`git grep -nE "candidate_label|reference_label|assert_patterns_agree|fullprof_label" -- 'docs/docs/verification/*.py'` +and every map user with `git grep -n "_SOFTWARE_PACKAGE_BY_ENGINE"`. + +## Implementation steps (Phase 1) + +Each `- [ ]` is one atomic commit; stage only the listed paths; commit +each before the next. No `test_verification.py` changes in Phase 1 — the +existing `fullprof_label` test may be left temporarily stale (it is not +run until Phase 2). + +- [ ] **P1.1 — Share the engine→package map in `utils.utils`.** Move + `_SOFTWARE_PACKAGE_BY_ENGINE` from `analysis.py` into + `src/easydiffraction/utils/utils.py` (public + `SOFTWARE_PACKAGE_BY_ENGINE`); import it in `analysis.py` so + `_software_version` keeps its current raw-version behavior + unchanged. Pure refactor, no behavior change. Commit: + `Share engine-to-package map from utils` + +- [ ] **P1.2 — Add `engine_label`; make `fullprof_label` bare.** In + `verification.py`: add a `_label_version(pkg)` formatter (raw + `package_version`, keep `+dev*`/`+dirty*`/`+devdirty*`, trim only + a `+g` VCS-hash tail — see the dev-marker decision above) and + `engine_label(engine, note=None)` that builds + `edi {edi_ver} ({engine} {engine_ver}[, {note}])` via that + formatter and `SOFTWARE_PACKAGE_BY_ENGINE`, rendering a visible + `{engine} ?` marker when the engine version is `None` (Decision + 3a). Change `fullprof_label` to return `f'FullProf {version}'` and + update its docstring example. Docstrings only; no test edits. + Commit: `Add engine_label helper and drop v from fullprof_label` + +- [ ] **P1.3 — Migrate the 15 verification pages.** For each + `docs/docs/verification/*.py`: define page-level label variables + right after each calculation + (`LABEL_CRYSPY = verify.engine_label('cryspy')`, refined/annotated + via `note=`), set + `FULLPROF_LABEL = verify.fullprof_label(, )` + where the reference label is still the literal `'FullProf'`, pass + these to `pattern_comparison` / `reflection_comparison`, and build + each `assert_patterns_agree` row label as + `f'{LABEL_xxx} vs {FULLPROF_LABEL}'`. SC pages use + `fullprof_label` with their `.out` (banners confirmed in review 1) + — no bare `'FullProf'` left anywhere. Run + `pixi run notebook-prepare`; stage the `.py` + regenerated + `.ipynb`. Commit: `Show software versions on verification pages` + +- [ ] **P1.4 — Promote the ADR.** First reconcile the ADR text with what + was implemented: (a) update Decision 3/4 wording from + `refined=False` to `note=None` (Open Question 3); (b) update + **Decision 3a** and its matching resolved Open Question so they + name the new shared map location (`SOFTWARE_PACKAGE_BY_ENGINE` in + `utils.utils`, P1.1) instead of the old private `analysis.py` + `_SOFTWARE_PACKAGE_BY_ENGINE`/`_software_version`, and record the + per-caller raw-vs-display formatting split (analysis stamps the + raw version into CIF; `verify` renders the dev-marker display form + via `_label_version`); (c) revise **Decision 2a** and its matching + resolved format Open Question so they describe the implemented + display formatter — preserve this repo's configured + `+dev*`/`+dirty*`/ `+devdirty*` local markers and trim **only** a + pure `+g` VCS-hash suffix (the `.devN+g…` example may stay as + the hash-trim illustration). Then `git mv` + `docs/dev/adrs/suggestions/verification-software-version-labels.md` + → `accepted/`; set `**Status:** Accepted`; flip its + `docs/dev/adrs/index.md` row to Accepted with the `accepted/...` + link; fix any links that pointed at `suggestions/...` + (`git grep -n verification-software-version-labels`). Commit: + `Promote verification-software-version-labels ADR to accepted` + +- [ ] **P1.5 — Phase 1 review gate.** No-code; mark `[x]` and commit the + checklist update alone. Commit: `Reach Phase 1 review gate` + +## Status checklist + +- [ ] P1.1 share engine→package map +- [ ] P1.2 engine_label + bare fullprof_label +- [ ] P1.3 migrate 15 verification pages +- [ ] P1.4 promote ADR +- [ ] P1.5 Phase 1 review gate +- [ ] Phase 2 verification green + +## Phase 2 — Verification + +Per the two-phase workflow, Phase 2 **starts with the test work**, then +runs the verification commands. + +**Step 1 — update and extend `test_verification.py` first.** Before any +`pixi run` command: + +- **Update existing case.** `test_fullprof_label_formats_version` must + now expect `'FullProf 8.40'` (no `v`). +- **Add `engine_label` cases:** + - basic candidate string for a known engine (assert the + `edi X.Y.Z (cryspy X.Y.Z)` shape using the installed versions); + - `note='refined'` appends `, refined`; + - an unresolvable engine version renders the visible `?` marker, not a + silent omission and not a raise (monkeypatch the version lookup to + return `None`); + - the dev-marker behavior for this repo's configured forms + (monkeypatch the lookup): `1.2.3+dev3`, `0.5.8+dirty3`, and + `0.5.8+devdirty3` are **preserved** verbatim in the label (a dev + build never collapses to its release number), while a pure VCS-hash + tail such as `1.2.3+g1a2b3c` is trimmed to `1.2.3`. + +**Step 2 — run the verification commands.** From the repo root; use the +zsh-safe log-capture when output is needed. + +- `pixi run fix` (commit auto-fixes incl. regenerated + `docs/dev/package-structure/{full,short}.md`). +- `pixi run check > /tmp/edi-check.log 2>&1; check_exit_code=$?; tail -n 200 /tmp/edi-check.log; exit $check_exit_code` +- `pixi run unit-tests > /tmp/edi-unit.log 2>&1; unit_tests_exit_code=$?; tail -n 120 /tmp/edi-unit.log; exit $unit_tests_exit_code` +- `pixi run integration-tests > /tmp/edi-int.log 2>&1; integration_tests_exit_code=$?; tail -n 120 /tmp/edi-int.log; exit $integration_tests_exit_code` +- `pixi run script-tests > /tmp/edi-script.log 2>&1; script_tests_exit_code=$?; tail -n 120 /tmp/edi-script.log; exit $script_tests_exit_code` + (every verification page now reads live versions; confirm none fail on + a missing FullProf banner — Open Question 2). +- `pixi run test-structure-check` (confirms no new test-layout drift + from the added `engine_label` cases). + +## Suggested Pull Request + +**Title:** Every verification page now shows the exact software versions +behind its curves + +**Description:** Each cross-engine verification page now states which +software produced the compared curves — the FullProf version, the +EasyDiffraction version, and the calculation engine (cryspy or crysfml) +version — right in the plot legend and the agreement table (for example +`edi 0.11.0 (cryspy 2.4.1) vs FullProf 8.40`). Because cross-engine +agreement can depend on the exact build, this makes every comparison +reproducible and lets a reader tell at a glance what was compared, even +after a later software update. The versions are read live, so they stay +correct automatically whenever a component is upgraded. From e609fc52bf800995c8d75b5d55e5d11c2975045a Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 14:08:10 +0200 Subject: [PATCH 03/18] Share engine-to-package map from utils --- .../plans/verification-software-version-labels.md | 4 ++-- src/easydiffraction/analysis/analysis.py | 12 ++---------- src/easydiffraction/utils/utils.py | 11 +++++++++++ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/docs/dev/plans/verification-software-version-labels.md b/docs/dev/plans/verification-software-version-labels.md index c8622c187..2b5318796 100644 --- a/docs/dev/plans/verification-software-version-labels.md +++ b/docs/dev/plans/verification-software-version-labels.md @@ -162,7 +162,7 @@ each before the next. No `test_verification.py` changes in Phase 1 — the existing `fullprof_label` test may be left temporarily stale (it is not run until Phase 2). -- [ ] **P1.1 — Share the engine→package map in `utils.utils`.** Move +- [x] **P1.1 — Share the engine→package map in `utils.utils`.** Move `_SOFTWARE_PACKAGE_BY_ENGINE` from `analysis.py` into `src/easydiffraction/utils/utils.py` (public `SOFTWARE_PACKAGE_BY_ENGINE`); import it in `analysis.py` so @@ -224,7 +224,7 @@ run until Phase 2). ## Status checklist -- [ ] P1.1 share engine→package map +- [x] P1.1 share engine→package map - [ ] P1.2 engine_label + bare fullprof_label - [ ] P1.3 migrate 15 verification pages - [ ] P1.4 promote ADR diff --git a/src/easydiffraction/analysis/analysis.py b/src/easydiffraction/analysis/analysis.py index e48d5420d..f6c551259 100644 --- a/src/easydiffraction/analysis/analysis.py +++ b/src/easydiffraction/analysis/analysis.py @@ -72,6 +72,7 @@ from easydiffraction.utils.utils import render_cif from easydiffraction.utils.utils import render_object_help from easydiffraction.utils.utils import render_table +from easydiffraction.utils.utils import SOFTWARE_PACKAGE_BY_ENGINE if TYPE_CHECKING: from collections.abc import Callable @@ -109,15 +110,6 @@ def _parameter_display_units(param: object) -> str: _GT_REFLECTION_THRESHOLD_SIGMA = 3.0 _GT_REFLECTION_THRESHOLD_EXPRESSION = r'I>3\s(I)' _EASYDIFFRACTION_URL = 'https://github.com/easyscience/diffraction-lib' -_SOFTWARE_PACKAGE_BY_ENGINE = { - 'cryspy': 'cryspy', - 'crysfml': 'crysfml', - 'pdffit': 'diffpy.pdffit2', - 'lmfit': 'lmfit', - 'dfols': 'dfols', - 'bumps': 'bumps', - 'emcee': 'emcee', -} @dataclass(frozen=True) @@ -642,7 +634,7 @@ def _type_info_tag(obj: object) -> str: @staticmethod def _software_version(name: str) -> str | None: """Return the installed package version for one engine name.""" - package_name = _SOFTWARE_PACKAGE_BY_ENGINE.get(name) + package_name = SOFTWARE_PACKAGE_BY_ENGINE.get(name) if package_name is None: return None return package_version(package_name) diff --git a/src/easydiffraction/utils/utils.py b/src/easydiffraction/utils/utils.py index 9e62ea631..d126af118 100644 --- a/src/easydiffraction/utils/utils.py +++ b/src/easydiffraction/utils/utils.py @@ -686,6 +686,17 @@ def list_data() -> None: ) +SOFTWARE_PACKAGE_BY_ENGINE = { + 'cryspy': 'cryspy', + 'crysfml': 'crysfml', + 'pdffit': 'diffpy.pdffit2', + 'lmfit': 'lmfit', + 'dfols': 'dfols', + 'bumps': 'bumps', + 'emcee': 'emcee', +} + + def package_version(package_name: str) -> str | None: """ Get the installed version string of the specified package. From f184e06e95caf8f0e2dd6dbad00becdeb2089291 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 14:10:10 +0200 Subject: [PATCH 04/18] Add engine_label helper and drop v from fullprof_label --- .../verification-software-version-labels.md | 4 +- src/easydiffraction/analysis/verification.py | 78 +++++++++++++++++-- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/docs/dev/plans/verification-software-version-labels.md b/docs/dev/plans/verification-software-version-labels.md index 2b5318796..61f124e98 100644 --- a/docs/dev/plans/verification-software-version-labels.md +++ b/docs/dev/plans/verification-software-version-labels.md @@ -170,7 +170,7 @@ run until Phase 2). unchanged. Pure refactor, no behavior change. Commit: `Share engine-to-package map from utils` -- [ ] **P1.2 — Add `engine_label`; make `fullprof_label` bare.** In +- [x] **P1.2 — Add `engine_label`; make `fullprof_label` bare.** In `verification.py`: add a `_label_version(pkg)` formatter (raw `package_version`, keep `+dev*`/`+dirty*`/`+devdirty*`, trim only a `+g` VCS-hash tail — see the dev-marker decision above) and @@ -225,7 +225,7 @@ run until Phase 2). ## Status checklist - [x] P1.1 share engine→package map -- [ ] P1.2 engine_label + bare fullprof_label +- [x] P1.2 engine_label + bare fullprof_label - [ ] P1.3 migrate 15 verification pages - [ ] P1.4 promote ADR - [ ] P1.5 Phase 1 review gate diff --git a/src/easydiffraction/analysis/verification.py b/src/easydiffraction/analysis/verification.py index 76754c8ee..d7d4c30fe 100644 --- a/src/easydiffraction/analysis/verification.py +++ b/src/easydiffraction/analysis/verification.py @@ -22,7 +22,9 @@ import numpy as np from easydiffraction.datablocks.experiment.item.base import intensity_category_for +from easydiffraction.utils.utils import package_version from easydiffraction.utils.utils import render_table +from easydiffraction.utils.utils import SOFTWARE_PACKAGE_BY_ENGINE # Closeness metrics are computed on absolute intensities: each page # seeds the FullProf scale (from its .pcr) so the calculated patterns @@ -385,7 +387,7 @@ def fullprof_version(project_dir: str, summary_file: str) -> str: of its ``.sum`` (or ``.out``) output — the line ``** PROGRAM FullProf.2k (Version 8.40 - Feb2026-ILL JRC) **`` — and returns just the version number (for example ``'8.40'``), suited to a plot legend - such as ``f'FullProf v{version}'``. + such as ``f'FullProf {version}'``. Resolved inside the bundled reference directory, so the caller passes the project sub-folder and the summary file name. @@ -419,11 +421,11 @@ def fullprof_version(project_dir: str, summary_file: str) -> str: def fullprof_label(project_dir: str, summary_file: str) -> str: """ - Return a FullProf plot-legend label, e.g. ``'FullProf v8.40'``. + Return a FullProf plot-legend label, e.g. ``'FullProf 8.40'``. Convenience wrapper over :func:`fullprof_version` so verification pages set ``reference_label`` in one line rather than repeating the - ``f'FullProf v{...}'`` formatting. + ``f'FullProf {...}'`` formatting. Parameters ---------- @@ -436,9 +438,75 @@ def fullprof_label(project_dir: str, summary_file: str) -> str: Returns ------- str - The legend label ``f'FullProf v{version}'``. + The legend label ``f'FullProf {version}'``. """ - return f'FullProf v{fullprof_version(project_dir, summary_file)}' + return f'FullProf {fullprof_version(project_dir, summary_file)}' + + +_VCS_HASH_LOCAL_RE = re.compile(r'^g?[0-9a-f]{6,40}$') + + +def _label_version(package_name: str) -> str | None: + """ + Return an installed package version formatted for a page label. + + Keeps this project's versioningit dev markers + (``+dev{N}`` / ``+dirty{N}`` / ``+devdirty{N}``) and any PEP 440 + public dev/pre-release segment, but trims a pure VCS-hash local part + (for example ``+g1a2b3c``) so the label stays readable. + + Parameters + ---------- + package_name : str + Distribution name to query (for example ``'easydiffraction'``). + + Returns + ------- + str | None + The display version string, or ``None`` if the package is not + installed. + """ + raw = package_version(package_name) + if raw is None: + return None + base, separator, local = raw.partition('+') + if separator and _VCS_HASH_LOCAL_RE.match(local): + return base + return raw + + +def engine_label(engine: str, note: str | None = None) -> str: + """ + Return the candidate label for a verification comparison. + + Builds the EasyDiffraction-plus-engine candidate string with live + versions, for example ``'edi 1.2.3 (cryspy 2.4.1)'`` or, with a + ``note``, ``'edi 1.2.3 (cryspy 2.4.1, refined)'``. The engine is + named explicitly (not read from the active calculator) so a stored + result keeps the version of the engine that produced it. An + unresolvable version renders a visible ``?`` marker rather than being + omitted. + + Parameters + ---------- + engine : str + Calculation engine tag, for example ``'cryspy'`` or + ``'crysfml'``. + note : str | None, default=None + Optional annotation appended inside the parentheses, for example + ``'refined'`` or ``'scale only'``. + + Returns + ------- + str + The candidate label string. + """ + edi_version = _label_version('easydiffraction') + engine_version = _label_version(SOFTWARE_PACKAGE_BY_ENGINE.get(engine, engine)) + edi_text = f'edi {edi_version}' if edi_version is not None else 'edi ?' + engine_text = f'{engine} {engine_version}' if engine_version is not None else f'{engine} ?' + inner = engine_text if note is None else f'{engine_text}, {note}' + return f'{edi_text} ({inner})' def load_fullprof_sc_f2calc(project_dir: str, out_file: str) -> dict[tuple[int, int, int], float]: From 0ee5ddd0e40993fb0c2161e286c5933d7eca4822 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 14:17:35 +0200 Subject: [PATCH 05/18] Show software versions on verification pages --- .../verification-software-version-labels.md | 4 +- .../pd-neut-cwl_pv-beba_pbso4.ipynb | 94 +++---------------- .../verification/pd-neut-cwl_pv-beba_pbso4.py | 12 ++- .../pd-neut-cwl_pv-beta_y2o3.ipynb | 6 +- .../verification/pd-neut-cwl_pv-beta_y2o3.py | 6 +- .../pd-neut-cwl_pv-march_lbco.ipynb | 12 ++- .../verification/pd-neut-cwl_pv-march_lbco.py | 12 ++- .../verification/pd-neut-cwl_pv_lbco.ipynb | 14 +-- docs/docs/verification/pd-neut-cwl_pv_lbco.py | 14 +-- .../verification/pd-neut-cwl_pv_pbso4.ipynb | 14 +-- .../docs/verification/pd-neut-cwl_pv_pbso4.py | 14 +-- ...d-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb | 18 ++-- .../pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py | 18 ++-- .../pd-neut-cwl_tch-fcj-noabs_lab6.ipynb | 22 +++-- .../pd-neut-cwl_tch-fcj-noabs_lab6.py | 22 +++-- .../pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb | 14 +-- .../pd-neut-cwl_tch-fcj-nosldl_lab6.py | 12 ++- .../pd-neut-cwl_tch-fcj_lab6.ipynb | 22 +++-- .../verification/pd-neut-cwl_tch-fcj_lab6.py | 22 +++-- docs/docs/verification/pd-neut-tof_j_si.ipynb | 12 +-- docs/docs/verification/pd-neut-tof_j_si.py | 12 +-- .../verification/pd-neut-tof_jvd_ncaf.ipynb | 12 +-- .../docs/verification/pd-neut-tof_jvd_ncaf.py | 12 +-- .../verification/pd-neut-tof_jvd_si.ipynb | 12 +-- docs/docs/verification/pd-neut-tof_jvd_si.py | 12 +-- .../sc-neut-cwl_ext-iso_tbti.ipynb | 13 +-- .../verification/sc-neut-cwl_ext-iso_tbti.py | 11 ++- .../verification/sc-neut-cwl_noext_tbti.ipynb | 13 +-- .../verification/sc-neut-cwl_noext_tbti.py | 11 ++- .../verification/sc-neut-cwl_pr2nio4.ipynb | 13 +-- docs/docs/verification/sc-neut-cwl_pr2nio4.py | 11 ++- 31 files changed, 232 insertions(+), 264 deletions(-) diff --git a/docs/dev/plans/verification-software-version-labels.md b/docs/dev/plans/verification-software-version-labels.md index 61f124e98..611565638 100644 --- a/docs/dev/plans/verification-software-version-labels.md +++ b/docs/dev/plans/verification-software-version-labels.md @@ -182,7 +182,7 @@ run until Phase 2). update its docstring example. Docstrings only; no test edits. Commit: `Add engine_label helper and drop v from fullprof_label` -- [ ] **P1.3 — Migrate the 15 verification pages.** For each +- [x] **P1.3 — Migrate the 15 verification pages.** For each `docs/docs/verification/*.py`: define page-level label variables right after each calculation (`LABEL_CRYSPY = verify.engine_label('cryspy')`, refined/annotated @@ -226,7 +226,7 @@ run until Phase 2). - [x] P1.1 share engine→package map - [x] P1.2 engine_label + bare fullprof_label -- [ ] P1.3 migrate 15 verification pages +- [x] P1.3 migrate 15 verification pages - [ ] P1.4 promote ADR - [ ] P1.5 Phase 1 review gate - [ ] Phase 2 verification green diff --git a/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.ipynb b/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.ipynb index 697bf539f..a44fd2923 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.ipynb +++ b/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.ipynb @@ -26,14 +26,16 @@ "source": [ "# PbSO₄ — neutron powder, constant wavelength, Bérar–Baldinozzi asymmetry\n", "\n", - "**Note — cryspy vs FullProf.** cryspy and FullProf implement the\n", + "**Note — cryspy vs FullProf.**\n", + "\n", + "cryspy and FullProf implement the\n", "Bérar–Baldinozzi empirical asymmetry with different conventions: an\n", "overall sign and a coefficient inside the `F_b` term differ between the\n", - "two programs. As a result the four `asym_beba_*` parameters do **not**\n", + "two software. As a result the four `asym_beba_*` parameters do **not**\n", "transfer one-to-one between cryspy and FullProf — the same numbers give\n", "different profiles. The refinement below frees the asymmetry so it can\n", "absorb this convention difference; the structural results are\n", - "unaffected. See development issue 166 for the detailed comparison." + "unaffected." ] }, { @@ -156,6 +158,8 @@ "source": [ "FULLPROF_PROJECT_DIR = 'pd-neut-cwl_pv-beba_pbso4'\n", "FULLPROF_PRF_FILE = 'pbso4.prf'\n", + "FULLPROF_SUM_FILE = 'pbso4.sum'\n", + "FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE)\n", "FULLPROF_BAC_FILE = 'pbso4.bac'\n", "FULLPROF_ZERO = -0.08424 # FullProf Zero\n", "FULLPROF_SCALE = 1.463815 # FullProf Scale\n", @@ -254,8 +258,8 @@ " 'pbso4',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -297,8 +301,8 @@ " 'pbso4',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy (refined)',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy', note='refined'),\n", ")" ] }, @@ -306,77 +310,6 @@ "cell_type": "markdown", "id": "15", "metadata": {}, - "source": [ - "## edi-crysfml VS FullProf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "16", - "metadata": {}, - "outputs": [], - "source": [ - "experiment.calculator.type = 'crysfml'\n", - "\n", - "experiment.linked_structures['pbso4'].scale = FULLPROF_SCALE\n", - "\n", - "experiment.peak.type = 'pseudo-voigt'\n", - "experiment.peak.broad_gauss_u = FULLPROF_U\n", - "experiment.peak.broad_gauss_v = FULLPROF_V\n", - "experiment.peak.broad_gauss_w = FULLPROF_W\n", - "experiment.peak.broad_lorentz_x = FULLPROF_X\n", - "experiment.peak.broad_lorentz_y = FULLPROF_Y\n", - "\n", - "project.analysis.calculate()\n", - "calc_ed_crysfml = experiment.data.intensity_calc\n", - "\n", - "project.display.pattern_comparison(\n", - " 'pbso4',\n", - " reference=calc_fullprof,\n", - " candidate=calc_ed_crysfml,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-crysfml',\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "17", - "metadata": {}, - "source": [ - "## Fit edi-crysfml to FullProf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "18", - "metadata": {}, - "outputs": [], - "source": [ - "experiment.linked_structures['pbso4'].scale.free = True\n", - "experiment.instrument.calib_twotheta_offset.free = True\n", - "\n", - "project.analysis.fit()\n", - "project.display.fit.results()\n", - "\n", - "project.analysis.calculate()\n", - "calc_ed_crysfml_refined = experiment.data.intensity_calc\n", - "\n", - "project.display.pattern_comparison(\n", - " 'pbso4',\n", - " reference=calc_fullprof,\n", - " candidate=calc_ed_crysfml_refined,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-crysfml (refined)',\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "19", - "metadata": {}, "source": [ "## Agreement check" ] @@ -384,14 +317,13 @@ { "cell_type": "code", "execution_count": null, - "id": "20", + "id": "16", "metadata": {}, "outputs": [], "source": [ "verify.assert_patterns_agree(\n", " [\n", - " ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy_refined),\n", - " ('crysfml vs FullProf', calc_fullprof, calc_ed_crysfml_refined),\n", + " (f'{verify.engine_label(\"cryspy\", note=\"refined\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.py b/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.py index 52088c518..75235dbe8 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.py +++ b/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.py @@ -90,6 +90,8 @@ # %% FULLPROF_PROJECT_DIR = 'pd-neut-cwl_pv-beba_pbso4' FULLPROF_PRF_FILE = 'pbso4.prf' +FULLPROF_SUM_FILE = 'pbso4.sum' +FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE) FULLPROF_BAC_FILE = 'pbso4.bac' FULLPROF_ZERO = -0.08424 # FullProf Zero FULLPROF_SCALE = 1.463815 # FullProf Scale @@ -164,8 +166,8 @@ 'pbso4', reference=calc_fullprof, candidate=calc_ed_cryspy, - reference_label='FullProf', - candidate_label='edi-cryspy', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -195,8 +197,8 @@ 'pbso4', reference=calc_fullprof, candidate=calc_ed_cryspy_refined, - reference_label='FullProf', - candidate_label='edi-cryspy (refined)', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy', note='refined'), ) # %% [markdown] @@ -205,7 +207,7 @@ # %% verify.assert_patterns_agree( [ - ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy_refined), + (f'{verify.engine_label("cryspy", note="refined")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined), ], raise_on_failure=False, ) diff --git a/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.ipynb b/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.ipynb index a1307e3a5..8c623ad27 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.ipynb +++ b/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.ipynb @@ -252,7 +252,7 @@ " reference=verify.restrict_to_included(experiment, calc_fullprof),\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-cryspy',\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -285,7 +285,7 @@ " reference=verify.restrict_to_included(experiment, calc_fullprof),\n", " candidate=calc_ed_cryspy_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-cryspy (refined)',\n", + " candidate_label=verify.engine_label('cryspy', note='refined'),\n", ")" ] }, @@ -307,7 +307,7 @@ "verify.assert_patterns_agree(\n", " [\n", " (\n", - " 'cryspy vs FullProf',\n", + " f'{verify.engine_label(\"cryspy\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_cryspy_refined,\n", " ),\n", diff --git a/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.py b/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.py index cac979fbf..11c5d3f1e 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.py +++ b/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.py @@ -160,7 +160,7 @@ reference=verify.restrict_to_included(experiment, calc_fullprof), candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label='edi-cryspy', + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -181,7 +181,7 @@ reference=verify.restrict_to_included(experiment, calc_fullprof), candidate=calc_ed_cryspy_refined, reference_label=FULLPROF_LABEL, - candidate_label='edi-cryspy (refined)', + candidate_label=verify.engine_label('cryspy', note='refined'), ) # %% [markdown] @@ -191,7 +191,7 @@ verify.assert_patterns_agree( [ ( - 'cryspy vs FullProf', + f'{verify.engine_label("cryspy", note="refined")} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_cryspy_refined, ), diff --git a/docs/docs/verification/pd-neut-cwl_pv-march_lbco.ipynb b/docs/docs/verification/pd-neut-cwl_pv-march_lbco.ipynb index b3ff4f9e1..e609e12e7 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-march_lbco.ipynb +++ b/docs/docs/verification/pd-neut-cwl_pv-march_lbco.ipynb @@ -155,6 +155,8 @@ "source": [ "FULLPROF_PROJECT_DIR = 'pd-neut-cwl_pv-march_lbco'\n", "FULLPROF_PRF_FILE = 'lbco.prf'\n", + "FULLPROF_SUM_FILE = 'lbco.sum'\n", + "FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE)\n", "FULLPROF_BAC_FILE = 'lbco.bac'\n", "FULLPROF_ZERO = 0.62040 # FullProf Zero\n", "FULLPROF_SCALE = 9.405870 # FullProf Scale\n", @@ -250,8 +252,8 @@ " 'lbco',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -289,8 +291,8 @@ " 'lbco',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy (refined)',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy', note='refined'),\n", ")" ] }, @@ -311,7 +313,7 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " ('cryspy refined vs FullProf', calc_fullprof, calc_ed_cryspy_refined),\n", + " (f'{verify.engine_label(\"cryspy\", note=\"refined\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined),\n", " ],\n", ")" ] diff --git a/docs/docs/verification/pd-neut-cwl_pv-march_lbco.py b/docs/docs/verification/pd-neut-cwl_pv-march_lbco.py index 5e3fa9064..df7ca3378 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-march_lbco.py +++ b/docs/docs/verification/pd-neut-cwl_pv-march_lbco.py @@ -87,6 +87,8 @@ # %% FULLPROF_PROJECT_DIR = 'pd-neut-cwl_pv-march_lbco' FULLPROF_PRF_FILE = 'lbco.prf' +FULLPROF_SUM_FILE = 'lbco.sum' +FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE) FULLPROF_BAC_FILE = 'lbco.bac' FULLPROF_ZERO = 0.62040 # FullProf Zero FULLPROF_SCALE = 9.405870 # FullProf Scale @@ -158,8 +160,8 @@ 'lbco', reference=calc_fullprof, candidate=calc_ed_cryspy, - reference_label='FullProf', - candidate_label='edi-cryspy', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -185,8 +187,8 @@ 'lbco', reference=calc_fullprof, candidate=calc_ed_cryspy_refined, - reference_label='FullProf', - candidate_label='edi-cryspy (refined)', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy', note='refined'), ) # %% [markdown] @@ -195,7 +197,7 @@ # %% verify.assert_patterns_agree( [ - ('cryspy refined vs FullProf', calc_fullprof, calc_ed_cryspy_refined), + (f'{verify.engine_label("cryspy", note="refined")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined), ], ) diff --git a/docs/docs/verification/pd-neut-cwl_pv_lbco.ipynb b/docs/docs/verification/pd-neut-cwl_pv_lbco.ipynb index 90878eb35..757eb1ee3 100644 --- a/docs/docs/verification/pd-neut-cwl_pv_lbco.ipynb +++ b/docs/docs/verification/pd-neut-cwl_pv_lbco.ipynb @@ -140,6 +140,8 @@ "source": [ "FULLPROF_PROJECT_DIR = 'pd-neut-cwl_pv_lbco'\n", "FULLPROF_PRF_FILE = 'lbco.prf'\n", + "FULLPROF_SUM_FILE = 'lbco.sum'\n", + "FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE)\n", "FULLPROF_BAC_FILE = 'lbco.bac'\n", "FULLPROF_ZERO = 0.62040 # FullProf Zero\n", "FULLPROF_SCALE = 9.405870 # FullProf Scale\n", @@ -221,8 +223,8 @@ " 'lbco',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -250,8 +252,8 @@ " 'lbco',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-crysfml',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('crysfml'),\n", ")" ] }, @@ -272,8 +274,8 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy),\n", - " ('crysfml vs FullProf', calc_fullprof, calc_ed_crysfml),\n", + " (f'{verify.engine_label(\"cryspy\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", + " (f'{verify.engine_label(\"crysfml\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", ")" ] diff --git a/docs/docs/verification/pd-neut-cwl_pv_lbco.py b/docs/docs/verification/pd-neut-cwl_pv_lbco.py index 3274b1245..8ced4b13e 100644 --- a/docs/docs/verification/pd-neut-cwl_pv_lbco.py +++ b/docs/docs/verification/pd-neut-cwl_pv_lbco.py @@ -72,6 +72,8 @@ # %% FULLPROF_PROJECT_DIR = 'pd-neut-cwl_pv_lbco' FULLPROF_PRF_FILE = 'lbco.prf' +FULLPROF_SUM_FILE = 'lbco.sum' +FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE) FULLPROF_BAC_FILE = 'lbco.bac' FULLPROF_ZERO = 0.62040 # FullProf Zero FULLPROF_SCALE = 9.405870 # FullProf Scale @@ -129,8 +131,8 @@ 'lbco', reference=calc_fullprof, candidate=calc_ed_cryspy, - reference_label='FullProf', - candidate_label='edi-cryspy', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -146,8 +148,8 @@ 'lbco', reference=calc_fullprof, candidate=calc_ed_crysfml, - reference_label='FullProf', - candidate_label='edi-crysfml', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('crysfml'), ) # %% [markdown] @@ -156,7 +158,7 @@ # %% verify.assert_patterns_agree( [ - ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy), - ('crysfml vs FullProf', calc_fullprof, calc_ed_crysfml), + (f'{verify.engine_label("cryspy")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), + (f'{verify.engine_label("crysfml")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], ) diff --git a/docs/docs/verification/pd-neut-cwl_pv_pbso4.ipynb b/docs/docs/verification/pd-neut-cwl_pv_pbso4.ipynb index d52d62417..9d8a219b9 100644 --- a/docs/docs/verification/pd-neut-cwl_pv_pbso4.ipynb +++ b/docs/docs/verification/pd-neut-cwl_pv_pbso4.ipynb @@ -147,6 +147,8 @@ "source": [ "FULLPROF_PROJECT_DIR = 'pd-neut-cwl_pv_pbso4'\n", "FULLPROF_PRF_FILE = 'pbso4.prf'\n", + "FULLPROF_SUM_FILE = 'pbso4.sum'\n", + "FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE)\n", "FULLPROF_BAC_FILE = 'pbso4.bac'\n", "FULLPROF_ZERO = -0.14357 # FullProf Zero\n", "FULLPROF_SCALE = 1.467900 # FullProf Scale\n", @@ -228,8 +230,8 @@ " 'pbso4',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -257,8 +259,8 @@ " 'pbso4',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-crysfml',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('crysfml'),\n", ")" ] }, @@ -279,8 +281,8 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy),\n", - " ('crysfml vs FullProf', calc_fullprof, calc_ed_crysfml),\n", + " (f'{verify.engine_label(\"cryspy\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", + " (f'{verify.engine_label(\"crysfml\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", ")" ] diff --git a/docs/docs/verification/pd-neut-cwl_pv_pbso4.py b/docs/docs/verification/pd-neut-cwl_pv_pbso4.py index 1a22263cb..683e583aa 100644 --- a/docs/docs/verification/pd-neut-cwl_pv_pbso4.py +++ b/docs/docs/verification/pd-neut-cwl_pv_pbso4.py @@ -79,6 +79,8 @@ # %% FULLPROF_PROJECT_DIR = 'pd-neut-cwl_pv_pbso4' FULLPROF_PRF_FILE = 'pbso4.prf' +FULLPROF_SUM_FILE = 'pbso4.sum' +FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE) FULLPROF_BAC_FILE = 'pbso4.bac' FULLPROF_ZERO = -0.14357 # FullProf Zero FULLPROF_SCALE = 1.467900 # FullProf Scale @@ -136,8 +138,8 @@ 'pbso4', reference=calc_fullprof, candidate=calc_ed_cryspy, - reference_label='FullProf', - candidate_label='edi-cryspy', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -153,8 +155,8 @@ 'pbso4', reference=calc_fullprof, candidate=calc_ed_crysfml, - reference_label='FullProf', - candidate_label='edi-crysfml', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('crysfml'), ) # %% [markdown] @@ -163,7 +165,7 @@ # %% verify.assert_patterns_agree( [ - ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy), - ('crysfml vs FullProf', calc_fullprof, calc_ed_crysfml), + (f'{verify.engine_label("cryspy")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), + (f'{verify.engine_label("crysfml")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], ) diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb index 728dc1126..402d6e79a 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb @@ -115,6 +115,8 @@ "source": [ "FULLPROF_PROJECT_DIR = 'pd-neut-cwl_tch-fcj_lab6'\n", "FULLPROF_PRF_FILE = 'ECH0030684_LaB6_1p622A_noAbs_noSLDL.prf'\n", + "FULLPROF_SUM_FILE = 'ECH0030684_LaB6_1p622A_noAbs_noSLDL.sum'\n", + "FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE)\n", "FULLPROF_BAC_FILE = 'ECH0030684_LaB6_1p622A_noAbs_noSLDL.bac'\n", "FULLPROF_ZERO = -0.45778 # FullProf Zero\n", "FULLPROF_SCALE = 42.98374 # FullProf Scale\n", @@ -201,8 +203,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -230,8 +232,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-crysfml',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('crysfml'),\n", ")" ] }, @@ -263,8 +265,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml_refined,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-crysfml (refined)',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('crysfml', note='refined'),\n", ")" ] }, @@ -285,8 +287,8 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy),\n", - " ('crysfml vs FullProf', calc_fullprof, calc_ed_crysfml),\n", + " (f'{verify.engine_label(\"cryspy\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", + " (f'{verify.engine_label(\"crysfml\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py index cf56c3dd5..e38f3cce3 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py @@ -47,6 +47,8 @@ # %% FULLPROF_PROJECT_DIR = 'pd-neut-cwl_tch-fcj_lab6' FULLPROF_PRF_FILE = 'ECH0030684_LaB6_1p622A_noAbs_noSLDL.prf' +FULLPROF_SUM_FILE = 'ECH0030684_LaB6_1p622A_noAbs_noSLDL.sum' +FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE) FULLPROF_BAC_FILE = 'ECH0030684_LaB6_1p622A_noAbs_noSLDL.bac' FULLPROF_ZERO = -0.45778 # FullProf Zero FULLPROF_SCALE = 42.98374 # FullProf Scale @@ -109,8 +111,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_cryspy, - reference_label='FullProf', - candidate_label='edi-cryspy', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -126,8 +128,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml, - reference_label='FullProf', - candidate_label='edi-crysfml', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('crysfml'), ) # %% [markdown] @@ -147,8 +149,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml_refined, - reference_label='FullProf', - candidate_label='edi-crysfml (refined)', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('crysfml', note='refined'), ) # %% [markdown] @@ -157,8 +159,8 @@ # %% verify.assert_patterns_agree( [ - ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy), - ('crysfml vs FullProf', calc_fullprof, calc_ed_crysfml), + (f'{verify.engine_label("cryspy")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), + (f'{verify.engine_label("crysfml")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], raise_on_failure=False, ) diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.ipynb b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.ipynb index 3e2f6999a..bb7d2025a 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.ipynb +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.ipynb @@ -115,6 +115,8 @@ "source": [ "FULLPROF_PROJECT_DIR = 'pd-neut-cwl_tch-fcj_lab6'\n", "FULLPROF_PRF_FILE = 'ECH0030684_LaB6_1p622A_noAbs.prf'\n", + "FULLPROF_SUM_FILE = 'ECH0030684_LaB6_1p622A_noAbs.sum'\n", + "FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE)\n", "FULLPROF_BAC_FILE = 'ECH0030684_LaB6_1p622A_noAbs.bac'\n", "FULLPROF_ZERO = -0.21148 # FullProf Zero\n", "FULLPROF_SCALE = 44.51785 # FullProf Scale\n", @@ -204,8 +206,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -239,8 +241,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy (refined)',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy', note='refined'),\n", ")" ] }, @@ -280,8 +282,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-crysfml',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('crysfml'),\n", ")" ] }, @@ -316,8 +318,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml_refined,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-crysfml (refined)',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('crysfml', note='refined'),\n", ")" ] }, @@ -338,8 +340,8 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy),\n", - " ('crysfml vs FullProf', calc_fullprof, calc_ed_crysfml),\n", + " (f'{verify.engine_label(\"cryspy\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", + " (f'{verify.engine_label(\"crysfml\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.py b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.py index e5aac1edf..1a77802f1 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.py +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.py @@ -47,6 +47,8 @@ # %% FULLPROF_PROJECT_DIR = 'pd-neut-cwl_tch-fcj_lab6' FULLPROF_PRF_FILE = 'ECH0030684_LaB6_1p622A_noAbs.prf' +FULLPROF_SUM_FILE = 'ECH0030684_LaB6_1p622A_noAbs.sum' +FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE) FULLPROF_BAC_FILE = 'ECH0030684_LaB6_1p622A_noAbs.bac' FULLPROF_ZERO = -0.21148 # FullProf Zero FULLPROF_SCALE = 44.51785 # FullProf Scale @@ -112,8 +114,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_cryspy, - reference_label='FullProf', - candidate_label='edi-cryspy', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -135,8 +137,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_cryspy_refined, - reference_label='FullProf', - candidate_label='edi-cryspy (refined)', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy', note='refined'), ) # %% [markdown] @@ -164,8 +166,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml, - reference_label='FullProf', - candidate_label='edi-crysfml', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('crysfml'), ) # %% [markdown] @@ -188,8 +190,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml_refined, - reference_label='FullProf', - candidate_label='edi-crysfml (refined)', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('crysfml', note='refined'), ) # %% [markdown] @@ -198,8 +200,8 @@ # %% verify.assert_patterns_agree( [ - ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy), - ('crysfml vs FullProf', calc_fullprof, calc_ed_crysfml), + (f'{verify.engine_label("cryspy")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), + (f'{verify.engine_label("crysfml")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], raise_on_failure=False, ) diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb b/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb index f5f393545..1ab897b4f 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb @@ -135,6 +135,8 @@ "source": [ "FULLPROF_PROJECT_DIR = 'pd-neut-cwl_tch-fcj_lab6'\n", "FULLPROF_PRF_FILE = 'ECH0030684_LaB6_1p622A_noSLDL.prf'\n", + "FULLPROF_SUM_FILE = 'ECH0030684_LaB6_1p622A_noSLDL.sum'\n", + "FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE)\n", "FULLPROF_BAC_FILE = 'ECH0030684_LaB6_1p622A_noSLDL.bac'\n", "FULLPROF_ZERO = -0.21110 # FullProf Zero\n", "FULLPROF_SCALE = 141.1285 # FullProf Scale\n", @@ -180,7 +182,7 @@ ")\n", "verify.set_reference_as_measured(experiment, x, calc_fullprof)\n", "\n", - "experiment.linked_phases.create(id='lab6', scale=FULLPROF_SCALE)\n", + "experiment.linked_structures.create(structure_id='lab6', scale=FULLPROF_SCALE)\n", "\n", "experiment.instrument.setup_wavelength = FULLPROF_WAVELENGTH\n", "experiment.instrument.calib_twotheta_offset = FULLPROF_ZERO\n", @@ -227,8 +229,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", - " reference_label='FullProf',\n", - " candidate_label='ed-cryspy',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -264,8 +266,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", - " reference_label='FullProf',\n", - " candidate_label='ed-crysfml',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('crysfml'),\n", ")" ] }, @@ -290,7 +292,7 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy),\n", + " (f'{verify.engine_label(\"cryspy\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", " ],\n", " raise_on_failure=True,\n", ")" diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.py b/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.py index f2ec6e84e..c2dc00c92 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.py +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.py @@ -62,6 +62,8 @@ # %% FULLPROF_PROJECT_DIR = 'pd-neut-cwl_tch-fcj_lab6' FULLPROF_PRF_FILE = 'ECH0030684_LaB6_1p622A_noSLDL.prf' +FULLPROF_SUM_FILE = 'ECH0030684_LaB6_1p622A_noSLDL.sum' +FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE) FULLPROF_BAC_FILE = 'ECH0030684_LaB6_1p622A_noSLDL.bac' FULLPROF_ZERO = -0.21110 # FullProf Zero FULLPROF_SCALE = 141.1285 # FullProf Scale @@ -130,8 +132,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_cryspy, - reference_label='FullProf', - candidate_label='ed-cryspy', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -155,8 +157,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml, - reference_label='FullProf', - candidate_label='ed-crysfml', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('crysfml'), ) # %% [markdown] @@ -169,7 +171,7 @@ # %% verify.assert_patterns_agree( [ - ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy), + (f'{verify.engine_label("cryspy")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), ], raise_on_failure=True, ) diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.ipynb b/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.ipynb index 9d8104788..81aa54324 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.ipynb +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.ipynb @@ -115,6 +115,8 @@ "source": [ "FULLPROF_PROJECT_DIR = 'pd-neut-cwl_tch-fcj_lab6'\n", "FULLPROF_PRF_FILE = 'ECH0030684_LaB6_1p622A.prf'\n", + "FULLPROF_SUM_FILE = 'ECH0030684_LaB6_1p622A.sum'\n", + "FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE)\n", "FULLPROF_BAC_FILE = 'ECH0030684_LaB6_1p622A.bac'\n", "FULLPROF_ZERO = -0.21110 # FullProf Zero\n", "FULLPROF_SCALE = 141.1285 # FullProf Scale\n", @@ -211,8 +213,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -246,8 +248,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy (refined)',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy', note='refined'),\n", ")" ] }, @@ -287,8 +289,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-crysfml',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('crysfml'),\n", ")" ] }, @@ -323,8 +325,8 @@ " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml_refined,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-crysfml (refined)',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('crysfml', note='refined'),\n", ")" ] }, @@ -345,8 +347,8 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy),\n", - " ('crysfml vs FullProf', calc_fullprof, calc_ed_crysfml),\n", + " (f'{verify.engine_label(\"cryspy\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", + " (f'{verify.engine_label(\"crysfml\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py b/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py index 8bdbd9e3f..ccc7b42a9 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py @@ -47,6 +47,8 @@ # %% FULLPROF_PROJECT_DIR = 'pd-neut-cwl_tch-fcj_lab6' FULLPROF_PRF_FILE = 'ECH0030684_LaB6_1p622A.prf' +FULLPROF_SUM_FILE = 'ECH0030684_LaB6_1p622A.sum' +FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE) FULLPROF_BAC_FILE = 'ECH0030684_LaB6_1p622A.bac' FULLPROF_ZERO = -0.21110 # FullProf Zero FULLPROF_SCALE = 141.1285 # FullProf Scale @@ -119,8 +121,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_cryspy, - reference_label='FullProf', - candidate_label='edi-cryspy', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -142,8 +144,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_cryspy_refined, - reference_label='FullProf', - candidate_label='edi-cryspy (refined)', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy', note='refined'), ) # %% [markdown] @@ -171,8 +173,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml, - reference_label='FullProf', - candidate_label='edi-crysfml', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('crysfml'), ) # %% [markdown] @@ -195,8 +197,8 @@ 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml_refined, - reference_label='FullProf', - candidate_label='edi-crysfml (refined)', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('crysfml', note='refined'), ) # %% [markdown] @@ -205,8 +207,8 @@ # %% verify.assert_patterns_agree( [ - ('cryspy vs FullProf', calc_fullprof, calc_ed_cryspy), - ('crysfml vs FullProf', calc_fullprof, calc_ed_crysfml), + (f'{verify.engine_label("cryspy")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), + (f'{verify.engine_label("crysfml")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], raise_on_failure=False, ) diff --git a/docs/docs/verification/pd-neut-tof_j_si.ipynb b/docs/docs/verification/pd-neut-tof_j_si.ipynb index 2a03b97a9..19a7437f5 100644 --- a/docs/docs/verification/pd-neut-tof_j_si.ipynb +++ b/docs/docs/verification/pd-neut-tof_j_si.ipynb @@ -207,7 +207,7 @@ " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-cryspy',\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -240,7 +240,7 @@ " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-cryspy (refined)',\n", + " candidate_label=verify.engine_label('cryspy', note='refined'),\n", ")" ] }, @@ -281,7 +281,7 @@ " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-crysfml',\n", + " candidate_label=verify.engine_label('crysfml'),\n", ")" ] }, @@ -314,7 +314,7 @@ " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-crysfml (refined)',\n", + " candidate_label=verify.engine_label('crysfml', note='refined'),\n", ")" ] }, @@ -346,12 +346,12 @@ "verify.assert_patterns_agree(\n", " [\n", " (\n", - " 'cryspy vs FullProf',\n", + " f'{verify.engine_label(\"cryspy\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_cryspy_refined,\n", " ),\n", " (\n", - " 'crysfml vs FullProf',\n", + " f'{verify.engine_label(\"crysfml\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_crysfml_refined,\n", " ),\n", diff --git a/docs/docs/verification/pd-neut-tof_j_si.py b/docs/docs/verification/pd-neut-tof_j_si.py index 1656bd5e9..8ec82ac13 100644 --- a/docs/docs/verification/pd-neut-tof_j_si.py +++ b/docs/docs/verification/pd-neut-tof_j_si.py @@ -115,7 +115,7 @@ reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label='edi-cryspy', + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -136,7 +136,7 @@ reference=calc_fullprof, candidate=calc_ed_cryspy_refined, reference_label=FULLPROF_LABEL, - candidate_label='edi-cryspy (refined)', + candidate_label=verify.engine_label('cryspy', note='refined'), ) # %% @@ -158,7 +158,7 @@ reference=calc_fullprof, candidate=calc_ed_crysfml, reference_label=FULLPROF_LABEL, - candidate_label='edi-crysfml', + candidate_label=verify.engine_label('crysfml'), ) # %% [markdown] @@ -179,7 +179,7 @@ reference=calc_fullprof, candidate=calc_ed_crysfml_refined, reference_label=FULLPROF_LABEL, - candidate_label='edi-crysfml (refined)', + candidate_label=verify.engine_label('crysfml', note='refined'), ) # %% @@ -192,12 +192,12 @@ verify.assert_patterns_agree( [ ( - 'cryspy vs FullProf', + f'{verify.engine_label("cryspy", note="refined")} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_cryspy_refined, ), ( - 'crysfml vs FullProf', + f'{verify.engine_label("crysfml", note="refined")} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_crysfml_refined, ), diff --git a/docs/docs/verification/pd-neut-tof_jvd_ncaf.ipynb b/docs/docs/verification/pd-neut-tof_jvd_ncaf.ipynb index b0c171add..b3ed5ed95 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_ncaf.ipynb +++ b/docs/docs/verification/pd-neut-tof_jvd_ncaf.ipynb @@ -254,7 +254,7 @@ " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-cryspy',\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -287,7 +287,7 @@ " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-cryspy (refined)',\n", + " candidate_label=verify.engine_label('cryspy', note='refined'),\n", ")" ] }, @@ -328,7 +328,7 @@ " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-crysfml',\n", + " candidate_label=verify.engine_label('crysfml'),\n", ")" ] }, @@ -361,7 +361,7 @@ " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-crysfml (refined)',\n", + " candidate_label=verify.engine_label('crysfml', note='refined'),\n", ")" ] }, @@ -393,12 +393,12 @@ "verify.assert_patterns_agree(\n", " [\n", " (\n", - " 'cryspy vs FullProf',\n", + " f'{verify.engine_label(\"cryspy\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_cryspy_refined,\n", " ),\n", " (\n", - " 'crysfml vs FullProf',\n", + " f'{verify.engine_label(\"crysfml\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_crysfml_refined,\n", " ),\n", diff --git a/docs/docs/verification/pd-neut-tof_jvd_ncaf.py b/docs/docs/verification/pd-neut-tof_jvd_ncaf.py index 0563ef3ae..86368f54c 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_ncaf.py +++ b/docs/docs/verification/pd-neut-tof_jvd_ncaf.py @@ -162,7 +162,7 @@ reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label='edi-cryspy', + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -183,7 +183,7 @@ reference=calc_fullprof, candidate=calc_ed_cryspy_refined, reference_label=FULLPROF_LABEL, - candidate_label='edi-cryspy (refined)', + candidate_label=verify.engine_label('cryspy', note='refined'), ) # %% @@ -205,7 +205,7 @@ reference=calc_fullprof, candidate=calc_ed_crysfml, reference_label=FULLPROF_LABEL, - candidate_label='edi-crysfml', + candidate_label=verify.engine_label('crysfml'), ) # %% [markdown] @@ -226,7 +226,7 @@ reference=calc_fullprof, candidate=calc_ed_crysfml_refined, reference_label=FULLPROF_LABEL, - candidate_label='edi-crysfml (refined)', + candidate_label=verify.engine_label('crysfml', note='refined'), ) # %% @@ -239,12 +239,12 @@ verify.assert_patterns_agree( [ ( - 'cryspy vs FullProf', + f'{verify.engine_label("cryspy", note="refined")} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_cryspy_refined, ), ( - 'crysfml vs FullProf', + f'{verify.engine_label("crysfml", note="refined")} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_crysfml_refined, ), diff --git a/docs/docs/verification/pd-neut-tof_jvd_si.ipynb b/docs/docs/verification/pd-neut-tof_jvd_si.ipynb index 0aad56566..200bb9de7 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_si.ipynb +++ b/docs/docs/verification/pd-neut-tof_jvd_si.ipynb @@ -213,7 +213,7 @@ " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-cryspy',\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -248,7 +248,7 @@ " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-cryspy (refined)',\n", + " candidate_label=verify.engine_label('cryspy', note='refined'),\n", ")" ] }, @@ -300,7 +300,7 @@ " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-crysfml',\n", + " candidate_label=verify.engine_label('crysfml'),\n", ")" ] }, @@ -334,7 +334,7 @@ " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label='edi-crysfml (refined)',\n", + " candidate_label=verify.engine_label('crysfml', note='refined'),\n", ")" ] }, @@ -376,12 +376,12 @@ "verify.assert_patterns_agree(\n", " [\n", " (\n", - " 'cryspy vs FullProf',\n", + " f'{verify.engine_label(\"cryspy\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_cryspy_refined,\n", " ),\n", " (\n", - " 'crysfml vs FullProf',\n", + " f'{verify.engine_label(\"crysfml\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_crysfml_refined,\n", " ),\n", diff --git a/docs/docs/verification/pd-neut-tof_jvd_si.py b/docs/docs/verification/pd-neut-tof_jvd_si.py index 23c8876b0..cc6911cac 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_si.py +++ b/docs/docs/verification/pd-neut-tof_jvd_si.py @@ -121,7 +121,7 @@ reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label='edi-cryspy', + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -144,7 +144,7 @@ reference=calc_fullprof, candidate=calc_ed_cryspy_refined, reference_label=FULLPROF_LABEL, - candidate_label='edi-cryspy (refined)', + candidate_label=verify.engine_label('cryspy', note='refined'), ) # %% @@ -170,7 +170,7 @@ reference=calc_fullprof, candidate=calc_ed_crysfml, reference_label=FULLPROF_LABEL, - candidate_label='edi-crysfml', + candidate_label=verify.engine_label('crysfml'), ) # %% [markdown] @@ -192,7 +192,7 @@ reference=calc_fullprof, candidate=calc_ed_crysfml_refined, reference_label=FULLPROF_LABEL, - candidate_label='edi-crysfml (refined)', + candidate_label=verify.engine_label('crysfml', note='refined'), ) # %% @@ -208,12 +208,12 @@ verify.assert_patterns_agree( [ ( - 'cryspy vs FullProf', + f'{verify.engine_label("cryspy", note="refined")} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_cryspy_refined, ), ( - 'crysfml vs FullProf', + f'{verify.engine_label("crysfml", note="refined")} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_crysfml_refined, ), diff --git a/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.ipynb b/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.ipynb index f139ce0fb..87a27d832 100644 --- a/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.ipynb +++ b/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.ipynb @@ -170,7 +170,8 @@ "EXTINCTION_RADIUS = 10.0\n", "EXTINCTION_MOSAICITY = 35000.0\n", "\n", - "f2calc = verify.load_fullprof_sc_f2calc(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE)" + "f2calc = verify.load_fullprof_sc_f2calc(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE)\n", + "FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE)" ] }, { @@ -230,8 +231,8 @@ " 'tbti',\n", " reference=reference,\n", " candidate=candidate,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -265,8 +266,8 @@ " 'tbti',\n", " reference=reference_refined,\n", " candidate=candidate_refined,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy (scale + ext radius)',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy', note='scale + ext radius'),\n", ")\n", "\n", "verify.report_refinement_closeness(\n", @@ -293,7 +294,7 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " ('cryspy vs FullProf', reference_refined, candidate_refined),\n", + " (f'{verify.engine_label(\"cryspy\", note=\"scale + ext radius\")} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.py b/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.py index acab703f5..d3fffa5aa 100644 --- a/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.py +++ b/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.py @@ -96,6 +96,7 @@ EXTINCTION_MOSAICITY = 35000.0 f2calc = verify.load_fullprof_sc_f2calc(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE) +FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE) # %% [markdown] # ## Create the experiment @@ -131,8 +132,8 @@ 'tbti', reference=reference, candidate=candidate, - reference_label='FullProf', - candidate_label='edi-cryspy', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -154,8 +155,8 @@ 'tbti', reference=reference_refined, candidate=candidate_refined, - reference_label='FullProf', - candidate_label='edi-cryspy (scale + ext radius)', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy', note='scale + ext radius'), ) verify.report_refinement_closeness( @@ -170,7 +171,7 @@ # %% verify.assert_patterns_agree( [ - ('cryspy vs FullProf', reference_refined, candidate_refined), + (f'{verify.engine_label("cryspy", note="scale + ext radius")} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), ], raise_on_failure=False, ) diff --git a/docs/docs/verification/sc-neut-cwl_noext_tbti.ipynb b/docs/docs/verification/sc-neut-cwl_noext_tbti.ipynb index 43269d09c..f8386c1ce 100644 --- a/docs/docs/verification/sc-neut-cwl_noext_tbti.ipynb +++ b/docs/docs/verification/sc-neut-cwl_noext_tbti.ipynb @@ -166,7 +166,8 @@ "FULLPROF_SCALE = 0.28749475 # FullProf Scale\n", "FULLPROF_WAVELENGTH = 0.7930 # FullProf Lambda\n", "\n", - "f2calc = verify.load_fullprof_sc_f2calc(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE)" + "f2calc = verify.load_fullprof_sc_f2calc(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE)\n", + "FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE)" ] }, { @@ -223,8 +224,8 @@ " 'tbti',\n", " reference=reference,\n", " candidate=candidate,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -257,8 +258,8 @@ " 'tbti',\n", " reference=reference_refined,\n", " candidate=candidate_refined,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy (scale only)',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy', note='scale only'),\n", ")\n", "\n", "verify.report_refinement_closeness(\n", @@ -285,7 +286,7 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " ('cryspy vs FullProf', reference_refined, candidate_refined),\n", + " (f'{verify.engine_label(\"cryspy\", note=\"scale only\")} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/sc-neut-cwl_noext_tbti.py b/docs/docs/verification/sc-neut-cwl_noext_tbti.py index 6ede69a2d..e2e4bde72 100644 --- a/docs/docs/verification/sc-neut-cwl_noext_tbti.py +++ b/docs/docs/verification/sc-neut-cwl_noext_tbti.py @@ -92,6 +92,7 @@ FULLPROF_WAVELENGTH = 0.7930 # FullProf Lambda f2calc = verify.load_fullprof_sc_f2calc(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE) +FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE) # %% [markdown] # ## Create the experiment @@ -124,8 +125,8 @@ 'tbti', reference=reference, candidate=candidate, - reference_label='FullProf', - candidate_label='edi-cryspy', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -146,8 +147,8 @@ 'tbti', reference=reference_refined, candidate=candidate_refined, - reference_label='FullProf', - candidate_label='edi-cryspy (scale only)', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy', note='scale only'), ) verify.report_refinement_closeness( @@ -162,7 +163,7 @@ # %% verify.assert_patterns_agree( [ - ('cryspy vs FullProf', reference_refined, candidate_refined), + (f'{verify.engine_label("cryspy", note="scale only")} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), ], raise_on_failure=False, ) diff --git a/docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb b/docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb index dd981cce9..3c7c6201f 100644 --- a/docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb +++ b/docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb @@ -201,7 +201,8 @@ "FULLPROF_SCALE = 0.06298 # FullProf Scale\n", "FULLPROF_WAVELENGTH = 0.8302 # FullProf Lambda\n", "\n", - "f2calc = verify.load_fullprof_sc_f2calc(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE)" + "f2calc = verify.load_fullprof_sc_f2calc(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE)\n", + "FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE)" ] }, { @@ -258,8 +259,8 @@ " 'pr2nio4',\n", " reference=reference,\n", " candidate=candidate,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy'),\n", ")" ] }, @@ -292,8 +293,8 @@ " 'pr2nio4',\n", " reference=reference_refined,\n", " candidate=candidate_refined,\n", - " reference_label='FullProf',\n", - " candidate_label='edi-cryspy (scale only)',\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=verify.engine_label('cryspy', note='scale only'),\n", ")\n", "\n", "verify.report_refinement_closeness(\n", @@ -320,7 +321,7 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " ('cryspy vs FullProf', reference_refined, candidate_refined),\n", + " (f'{verify.engine_label(\"cryspy\", note=\"scale only\")} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/sc-neut-cwl_pr2nio4.py b/docs/docs/verification/sc-neut-cwl_pr2nio4.py index c4ec4ea29..6e09d31a6 100644 --- a/docs/docs/verification/sc-neut-cwl_pr2nio4.py +++ b/docs/docs/verification/sc-neut-cwl_pr2nio4.py @@ -127,6 +127,7 @@ FULLPROF_WAVELENGTH = 0.8302 # FullProf Lambda f2calc = verify.load_fullprof_sc_f2calc(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE) +FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_OUT_FILE) # %% [markdown] # ## Create the experiment @@ -159,8 +160,8 @@ 'pr2nio4', reference=reference, candidate=candidate, - reference_label='FullProf', - candidate_label='edi-cryspy', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy'), ) # %% [markdown] @@ -181,8 +182,8 @@ 'pr2nio4', reference=reference_refined, candidate=candidate_refined, - reference_label='FullProf', - candidate_label='edi-cryspy (scale only)', + reference_label=FULLPROF_LABEL, + candidate_label=verify.engine_label('cryspy', note='scale only'), ) verify.report_refinement_closeness( @@ -197,7 +198,7 @@ # %% verify.assert_patterns_agree( [ - ('cryspy vs FullProf', reference_refined, candidate_refined), + (f'{verify.engine_label("cryspy", note="scale only")} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), ], raise_on_failure=False, ) From 85570b43207c4f85dd394fe99879f9fbac027a71 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 14:21:20 +0200 Subject: [PATCH 06/18] Promote verification-software-version-labels ADR to accepted --- .../verification-software-version-labels.md | 77 +++++++++++-------- docs/dev/adrs/index.md | 2 +- .../verification-software-version-labels.md | 8 +- 3 files changed, 52 insertions(+), 35 deletions(-) rename docs/dev/adrs/{suggestions => accepted}/verification-software-version-labels.md (77%) diff --git a/docs/dev/adrs/suggestions/verification-software-version-labels.md b/docs/dev/adrs/accepted/verification-software-version-labels.md similarity index 77% rename from docs/dev/adrs/suggestions/verification-software-version-labels.md rename to docs/dev/adrs/accepted/verification-software-version-labels.md index 39faba6c3..dd3b4144f 100644 --- a/docs/dev/adrs/suggestions/verification-software-version-labels.md +++ b/docs/dev/adrs/accepted/verification-software-version-labels.md @@ -2,7 +2,7 @@ ## Status -Proposed. +Accepted. ## Date @@ -15,7 +15,7 @@ Quality. ## Context The cross-engine **Verification** pages (established by -[`test-suite-and-validation`](../accepted/test-suite-and-validation.md) +[`test-suite-and-validation`](test-suite-and-validation.md) §6) overlay an EasyDiffraction calculator on a frozen FullProf reference and score the agreement. A scientist reading such a page — or revisiting it after an engine update — needs to know **which versions of software @@ -91,20 +91,30 @@ across all three components so the labels read uniformly: ### 2a. Pre-release / dev builds -A dev or pre-release install is shown as **release plus the short dev -marker**, dropping the local `+g` segment: a `0.11.0.dev3+g1a2b3c` -install renders as `edi 0.11.0.dev3`. This keeps the "this is a -pre-release build" signal visible (so a dev-build comparison is not -mistaken for a released one) while keeping the label free of the noisy -commit hash. The same rule applies to any engine package reporting a PEP -440 dev/pre-release version. +A dev or pre-release install keeps its **dev marker** visible (so a +dev-build comparison is not mistaken for a released one) while dropping +only a **pure VCS-hash local segment** (`+g`) to keep the label +readable. Concretely, this project's versioningit emits the dev signal +in the *local* segment — `{base}+dev{N}`, `{base}+dirty{N}`, +`{base}+devdirty{N}` (see `pyproject.toml` +`[tool.versioningit.format]`) — so those markers are **preserved +verbatim**: an `edi` install of `1.2.3+dev3` renders `edi 1.2.3+dev3`. +A pure git-hash local part such as `0.11.0.dev3+g1a2b3c` is trimmed to +`edi 0.11.0.dev3`. The same rule applies to any engine package. (A +public-segment-only formatter such as `stripped_package_version` is +deliberately **not** used here: it would discard the `+dev*`/`+dirty*` +local markers and make a dev build look released.) ### 3. A `verify` helper builds the candidate label from an explicit engine tag -A single helper — `verify.engine_label(engine, refined=False)` — returns +A single helper — `verify.engine_label(engine, note=None)` — returns the **candidate** string only (the reference side stays the existing `verify.fullprof_label`, so the two single-purpose helpers mirror each -other). It builds the candidate string from: +other). The optional free-text `note` annotates the candidate inside the +parentheses (for example `note='refined'`, `note='scale only'`, +`note='scale + ext radius'`), generalising what would otherwise be a +boolean `refined` flag so the real pages' varied annotations are all +expressible. It builds the candidate string from: - the **EasyDiffraction** package version (`importlib.metadata.version('easydiffraction')`), and @@ -133,16 +143,18 @@ drives the calculation and the label, so they cannot diverge. ### 3a. Engine version source: the existing engine→package map -Each engine's version is resolved through the project's **existing** -engine-to-package mapping and metadata lookup -(`_SOFTWARE_PACKAGE_BY_ENGINE` and `_software_version` in -`src/easydiffraction/analysis/analysis.py`), which already maps -`'cryspy' → 'cryspy'` and `'crysfml' → 'crysfml'` and reads the -installed version via `importlib.metadata.version`. The `verify` helper -reuses this single resolution path rather than calling -`cryspy.__version__` or an engine-specific banner parse, so all engine -provenance comes from one place and a new engine is covered by adding -one map entry. +Each engine's version is resolved through the project's shared +engine-to-package map `SOFTWARE_PACKAGE_BY_ENGINE` in +`src/easydiffraction/utils/utils.py`, which maps `'cryspy' → 'cryspy'` +and `'crysfml' → 'crysfml'` and is read with `importlib.metadata` +(`package_version`). The map lives in `utils.utils` so both the fit +provenance path (`analysis.py`, which stamps the **raw** version into +CIF) and the `verify` label helper draw from one place without `verify` +importing heavy `analysis.py`; a new engine is covered by adding one map +entry. The per-caller difference is purely formatting: `analysis.py` +records the raw version, while `verify.engine_label` renders the display +form (Decision 2a — keep dev markers, trim a `+g` tail) via a small +`_label_version` helper. **Unknown-version behaviour.** If an engine's package version cannot be resolved (no installed metadata), the helper renders an **explicit, @@ -223,28 +235,33 @@ All questions are now **resolved** (owner decision); recorded here so the rationale is not lost: - **Engine version source — resolved (Decision 3a).** Versions come from - the existing `_SOFTWARE_PACKAGE_BY_ENGINE` / `_software_version` path - in `analysis.py` (`importlib.metadata.version`), with a visible + the shared `SOFTWARE_PACKAGE_BY_ENGINE` map in `utils.utils` + (`importlib.metadata` via `package_version`), with a visible `crysfml ?`-style marker when a version is unresolvable — no - engine-specific API, no silent omission, no page hard-fail. + engine-specific API, no silent omission, no page hard-fail. The fit + provenance path in `analysis.py` reads the same map (raw version for + CIF); `verify` renders the display form. - **Label binding — resolved (Decision 3).** The helper takes an explicit engine tag, not `experiment.calculator.type`, so a stored result keeps the version of the engine that produced it. - **Helper name — resolved: - `verify.engine_label(engine, refined=False)`, candidate only (Decision + `verify.engine_label(engine, note=None)`, candidate only (Decision 3).** The reference side stays `verify.fullprof_label`; the two small single-purpose helpers mirror each other and the page composes the combined table label from both. No single dual-return call (it would - couple engine-version logic to `.sum` parsing). + couple engine-version logic to `.sum` parsing). The free-text `note` + generalises a boolean `refined` so annotations like `scale only` are + expressible. - **Render location — resolved: legend + agreement-table label only (Decision 1).** No separate provenance caption/row; the versions live on the two label surfaces a page already has, reusing existing label plumbing. - **Format — resolved: bare `X.Y.Z`, no `v` prefix (Decision 2), applied to all three components.** `fullprof_label` drops its `v` to match - (Compatibility). Pre-release/dev builds render as release plus the - short dev marker (`0.11.0.dev3`), dropping the `+g` local segment - (Decision 2a). + (Compatibility). Pre-release/dev builds **keep** this repo's local dev + markers (`+dev*`/`+dirty*`/`+devdirty*`) and trim only a pure `+g` + VCS-hash tail (Decision 2a); `stripped_package_version` is not used + because it would drop those markers. ## Deferred Work @@ -252,5 +269,5 @@ the rationale is not lost: notebooks belongs to the implementation plan, not this ADR. - Relationship to the verification regression-gating change is only adjacent: see - [`verification-regression-flag`](../accepted/verification-regression-flag.md), + [`verification-regression-flag`](verification-regression-flag.md), which flagged this provenance gap; the two can ship independently. diff --git a/docs/dev/adrs/index.md b/docs/dev/adrs/index.md index 6102a74d3..b3c75ff60 100644 --- a/docs/dev/adrs/index.md +++ b/docs/dev/adrs/index.md @@ -56,7 +56,7 @@ folders. | Quality | Accepted | Test Strategy | Defines layered unit, functional, integration, script, and notebook testing. | [`test-strategy.md`](accepted/test-strategy.md) | | Quality | Accepted | Test Suite and Validation Strategy | Strict test layers, cost tiers, coverage/codecov policy, cross-engine verification docs, and a nightly validation harness. | [`test-suite-and-validation.md`](accepted/test-suite-and-validation.md) | | Quality | Suggestion | Notebook-Owned Verification Regression Gating | Replaces the external `ci_skip.txt` list with a single in-notebook `regression=False` flag (plus a cell tag for pre-flag crashes). | [`verification-regression-flag.md`](suggestions/verification-regression-flag.md) | -| Quality | Suggestion | Software Version Labels on Verification Pages | Shows FullProf, EasyDiffraction, and engine versions on every verification page (e.g. `edi X.Y.Z (cryspy X.Y.Z)`) via a `verify` helper. | [`verification-software-version-labels.md`](suggestions/verification-software-version-labels.md) | +| Quality | Accepted | Software Version Labels on Verification Pages | Shows FullProf, EasyDiffraction, and engine versions on every verification page (e.g. `edi X.Y.Z (cryspy X.Y.Z)`) via a `verify` helper. | [`verification-software-version-labels.md`](accepted/verification-software-version-labels.md) | | Structure model | Accepted | Type-Neutral ADP Parameters | Keeps ADP parameter object identities stable across B/U and iso/ani switches. | [`type-neutral-adp-parameters.md`](accepted/type-neutral-adp-parameters.md) | | Structure model | Accepted | Automatic Wyckoff Position Detection | Detects Wyckoff letter, multiplicity, and site symmetry from space group and coordinates; calculators consume them. | [`wyckoff-letter-detection.md`](accepted/wyckoff-letter-detection.md) | | Structure model | Accepted | Complete Space-Group Reference Database | One-time build of a complete space_groups.json.gz (all 230 groups) from cctbx, verified against multiple sources. | [`space-group-database.md`](accepted/space-group-database.md) | diff --git a/docs/dev/plans/verification-software-version-labels.md b/docs/dev/plans/verification-software-version-labels.md index 611565638..bdb59af58 100644 --- a/docs/dev/plans/verification-software-version-labels.md +++ b/docs/dev/plans/verification-software-version-labels.md @@ -7,8 +7,8 @@ authoring), Phase 2 does all test work and runs the verification suite. ## ADR Implements -[`verification-software-version-labels`](../adrs/suggestions/verification-software-version-labels.md) -(Proposed). Per §Change Discipline it is **promoted to `accepted/`** as +[`verification-software-version-labels`](../adrs/accepted/verification-software-version-labels.md) +(Accepted). Per §Change Discipline it is **promoted to `accepted/`** as part of this PR (P1.4). No new dependency is required — every version is read through `easydiffraction.utils.utils.package_version` and formatted for display by a small `verify` helper (`_label_version`, see @@ -197,7 +197,7 @@ run until Phase 2). `pixi run notebook-prepare`; stage the `.py` + regenerated `.ipynb`. Commit: `Show software versions on verification pages` -- [ ] **P1.4 — Promote the ADR.** First reconcile the ADR text with what +- [x] **P1.4 — Promote the ADR.** First reconcile the ADR text with what was implemented: (a) update Decision 3/4 wording from `refined=False` to `note=None` (Open Question 3); (b) update **Decision 3a** and its matching resolved Open Question so they @@ -227,7 +227,7 @@ run until Phase 2). - [x] P1.1 share engine→package map - [x] P1.2 engine_label + bare fullprof_label - [x] P1.3 migrate 15 verification pages -- [ ] P1.4 promote ADR +- [x] P1.4 promote ADR - [ ] P1.5 Phase 1 review gate - [ ] Phase 2 verification green From 39d4f89ed5bffd9221c8ade05cb374027a8b4117 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 14:21:47 +0200 Subject: [PATCH 07/18] Reach Phase 1 review gate --- docs/dev/plans/verification-software-version-labels.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dev/plans/verification-software-version-labels.md b/docs/dev/plans/verification-software-version-labels.md index bdb59af58..de1e32629 100644 --- a/docs/dev/plans/verification-software-version-labels.md +++ b/docs/dev/plans/verification-software-version-labels.md @@ -219,7 +219,7 @@ run until Phase 2). (`git grep -n verification-software-version-labels`). Commit: `Promote verification-software-version-labels ADR to accepted` -- [ ] **P1.5 — Phase 1 review gate.** No-code; mark `[x]` and commit the +- [x] **P1.5 — Phase 1 review gate.** No-code; mark `[x]` and commit the checklist update alone. Commit: `Reach Phase 1 review gate` ## Status checklist @@ -228,7 +228,7 @@ run until Phase 2). - [x] P1.2 engine_label + bare fullprof_label - [x] P1.3 migrate 15 verification pages - [x] P1.4 promote ADR -- [ ] P1.5 Phase 1 review gate +- [x] P1.5 Phase 1 review gate - [ ] Phase 2 verification green ## Phase 2 — Verification From 9bd1374b09f83af6cb52a4769b94235a593de061 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 14:51:43 +0200 Subject: [PATCH 08/18] Update software-labels branch status --- .../verification-software-version-labels.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/dev/plans/verification-software-version-labels.md b/docs/dev/plans/verification-software-version-labels.md index de1e32629..096bc7ffc 100644 --- a/docs/dev/plans/verification-software-version-labels.md +++ b/docs/dev/plans/verification-software-version-labels.md @@ -24,10 +24,8 @@ ordering. ## Branch + PR - Branch: `verification-software-version-labels` (flat slug off - `develop`). **Not yet created** — `/draft-impl-1` creates and checks - it out off `develop` before its first commit. The current working - branch is `verification-regression-flag`; the uncommitted ADR/plan - edits travel onto the new branch when it is created. + `develop`). Created and checked out during the Phase 1 review-fix + cycle; the software-version-labels commits now live on this branch. - PR targets `develop`, not `master`. Do not push unless asked. ## Decisions (from the ADR) @@ -111,11 +109,11 @@ ordering. 1. **Ordering vs `verification-regression-flag`.** Both edit all 15 `docs/docs/verification/*.py` pages and regenerate the same - notebooks, and both are in flight. Recommendation: land this - **after** `verification-regression-flag` merges to `develop`, then - branch this off the updated `develop`, so the label edits layer - cleanly on the migrated pages instead of colliding. Confirm with the - owner before `/draft-impl-1`. + notebooks, and both are in flight. The Phase 1 review-fix cycle moved + this work onto its own `verification-software-version-labels` branch + from `develop`, so the PR can be reviewed independently. If the + regression-flag branch lands first, rebase this branch onto updated + `develop` and resolve the expected verification-page conflicts there. 2. **ADR Decision 4 wording.** The `refined`→`note` generalization above edits the ADR at promotion (P1.4). Flagged so the owner can veto the signature if a strict boolean is preferred. From 04f47371119e3202c2d11e5afe68234c34b03fda Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 14:52:23 +0200 Subject: [PATCH 09/18] Require g prefix for version hash labels --- src/easydiffraction/analysis/verification.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/easydiffraction/analysis/verification.py b/src/easydiffraction/analysis/verification.py index d7d4c30fe..dbe2f72de 100644 --- a/src/easydiffraction/analysis/verification.py +++ b/src/easydiffraction/analysis/verification.py @@ -443,7 +443,7 @@ def fullprof_label(project_dir: str, summary_file: str) -> str: return f'FullProf {fullprof_version(project_dir, summary_file)}' -_VCS_HASH_LOCAL_RE = re.compile(r'^g?[0-9a-f]{6,40}$') +_VCS_HASH_LOCAL_RE = re.compile(r'^g[0-9a-f]{6,40}$') def _label_version(package_name: str) -> str | None: @@ -452,7 +452,7 @@ def _label_version(package_name: str) -> str | None: Keeps this project's versioningit dev markers (``+dev{N}`` / ``+dirty{N}`` / ``+devdirty{N}``) and any PEP 440 - public dev/pre-release segment, but trims a pure VCS-hash local part + public dev/pre-release segment, but trims a g-prefixed VCS-hash local part (for example ``+g1a2b3c``) so the label stays readable. Parameters From 52737fa05b09f5658be1a1c4598a0fdd05a26486 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 14:53:04 +0200 Subject: [PATCH 10/18] Validate verification engine label tags --- src/easydiffraction/analysis/verification.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/easydiffraction/analysis/verification.py b/src/easydiffraction/analysis/verification.py index dbe2f72de..08d614774 100644 --- a/src/easydiffraction/analysis/verification.py +++ b/src/easydiffraction/analysis/verification.py @@ -500,11 +500,24 @@ def engine_label(engine: str, note: str | None = None) -> str: ------- str The candidate label string. + + Raises + ------ + ValueError + If ``engine`` is not in the shared engine-to-package map. """ + if engine not in SOFTWARE_PACKAGE_BY_ENGINE: + supported = ', '.join(sorted(SOFTWARE_PACKAGE_BY_ENGINE)) + msg = f"Unknown engine {engine!r}; expected one of: {supported}." + raise ValueError(msg) + edi_version = _label_version('easydiffraction') - engine_version = _label_version(SOFTWARE_PACKAGE_BY_ENGINE.get(engine, engine)) + engine_version = _label_version(SOFTWARE_PACKAGE_BY_ENGINE[engine]) edi_text = f'edi {edi_version}' if edi_version is not None else 'edi ?' - engine_text = f'{engine} {engine_version}' if engine_version is not None else f'{engine} ?' + if engine_version is None: + engine_text = f'{engine} ?' + else: + engine_text = f'{engine} {engine_version}' inner = engine_text if note is None else f'{engine_text}, {note}' return f'{edi_text} ({inner})' From 512a403eb7aea93033c525efe457ab92f94ea37c Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 14:56:23 +0200 Subject: [PATCH 11/18] Reuse captured verification labels --- .../verification/pd-neut-cwl_pv-beba_pbso4.ipynb | 8 +++++--- .../verification/pd-neut-cwl_pv-beba_pbso4.py | 8 +++++--- .../verification/pd-neut-cwl_pv-beta_y2o3.ipynb | 8 +++++--- .../verification/pd-neut-cwl_pv-beta_y2o3.py | 8 +++++--- .../verification/pd-neut-cwl_pv-march_lbco.ipynb | 8 +++++--- .../verification/pd-neut-cwl_pv-march_lbco.py | 8 +++++--- docs/docs/verification/pd-neut-cwl_pv_lbco.ipynb | 10 ++++++---- docs/docs/verification/pd-neut-cwl_pv_lbco.py | 10 ++++++---- .../docs/verification/pd-neut-cwl_pv_pbso4.ipynb | 10 ++++++---- docs/docs/verification/pd-neut-cwl_pv_pbso4.py | 10 ++++++---- .../pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb | 13 ++++++++----- .../pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py | 13 ++++++++----- .../pd-neut-cwl_tch-fcj-noabs_lab6.ipynb | 16 ++++++++++------ .../pd-neut-cwl_tch-fcj-noabs_lab6.py | 16 ++++++++++------ .../pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb | 8 +++++--- .../pd-neut-cwl_tch-fcj-nosldl_lab6.py | 8 +++++--- .../verification/pd-neut-cwl_tch-fcj_lab6.ipynb | 16 ++++++++++------ .../verification/pd-neut-cwl_tch-fcj_lab6.py | 16 ++++++++++------ docs/docs/verification/pd-neut-tof_j_si.ipynb | 16 ++++++++++------ docs/docs/verification/pd-neut-tof_j_si.py | 16 ++++++++++------ .../docs/verification/pd-neut-tof_jvd_ncaf.ipynb | 16 ++++++++++------ docs/docs/verification/pd-neut-tof_jvd_ncaf.py | 16 ++++++++++------ docs/docs/verification/pd-neut-tof_jvd_si.ipynb | 16 ++++++++++------ docs/docs/verification/pd-neut-tof_jvd_si.py | 16 ++++++++++------ .../verification/sc-neut-cwl_ext-iso_tbti.ipynb | 8 +++++--- .../verification/sc-neut-cwl_ext-iso_tbti.py | 8 +++++--- .../verification/sc-neut-cwl_noext_tbti.ipynb | 8 +++++--- docs/docs/verification/sc-neut-cwl_noext_tbti.py | 8 +++++--- docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb | 8 +++++--- docs/docs/verification/sc-neut-cwl_pr2nio4.py | 8 +++++--- 30 files changed, 210 insertions(+), 128 deletions(-) diff --git a/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.ipynb b/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.ipynb index a44fd2923..ce345c441 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.ipynb +++ b/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.ipynb @@ -253,13 +253,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "\n", "project.display.pattern_comparison(\n", " 'pbso4',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -296,13 +297,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'pbso4',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSPY_REFINED,\n", ")" ] }, @@ -323,7 +325,7 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " (f'{verify.engine_label(\"cryspy\", note=\"refined\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined),\n", + " (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.py b/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.py index 75235dbe8..9d2a7fb0a 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.py +++ b/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.py @@ -161,13 +161,14 @@ project.analysis.calculate() calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') project.display.pattern_comparison( 'pbso4', reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -192,13 +193,14 @@ project.analysis.calculate() calc_ed_cryspy_refined = experiment.data.intensity_calc +LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined') project.display.pattern_comparison( 'pbso4', reference=calc_fullprof, candidate=calc_ed_cryspy_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy', note='refined'), + candidate_label=LABEL_ED_CRYSPY_REFINED, ) # %% [markdown] @@ -207,7 +209,7 @@ # %% verify.assert_patterns_agree( [ - (f'{verify.engine_label("cryspy", note="refined")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined), + (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined), ], raise_on_failure=False, ) diff --git a/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.ipynb b/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.ipynb index 8c623ad27..9c881086e 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.ipynb +++ b/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.ipynb @@ -246,13 +246,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "\n", "project.display.pattern_comparison(\n", " 'y2o3',\n", " reference=verify.restrict_to_included(experiment, calc_fullprof),\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -279,13 +280,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'y2o3',\n", " reference=verify.restrict_to_included(experiment, calc_fullprof),\n", " candidate=calc_ed_cryspy_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSPY_REFINED,\n", ")" ] }, @@ -307,7 +309,7 @@ "verify.assert_patterns_agree(\n", " [\n", " (\n", - " f'{verify.engine_label(\"cryspy\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", + " f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_cryspy_refined,\n", " ),\n", diff --git a/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.py b/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.py index 11c5d3f1e..efb6f22ab 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.py +++ b/docs/docs/verification/pd-neut-cwl_pv-beta_y2o3.py @@ -154,13 +154,14 @@ project.analysis.calculate() calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') project.display.pattern_comparison( 'y2o3', reference=verify.restrict_to_included(experiment, calc_fullprof), candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -175,13 +176,14 @@ project.analysis.calculate() calc_ed_cryspy_refined = experiment.data.intensity_calc +LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined') project.display.pattern_comparison( 'y2o3', reference=verify.restrict_to_included(experiment, calc_fullprof), candidate=calc_ed_cryspy_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy', note='refined'), + candidate_label=LABEL_ED_CRYSPY_REFINED, ) # %% [markdown] @@ -191,7 +193,7 @@ verify.assert_patterns_agree( [ ( - f'{verify.engine_label("cryspy", note="refined")} vs {FULLPROF_LABEL}', + f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_cryspy_refined, ), diff --git a/docs/docs/verification/pd-neut-cwl_pv-march_lbco.ipynb b/docs/docs/verification/pd-neut-cwl_pv-march_lbco.ipynb index e609e12e7..b4217bacf 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-march_lbco.ipynb +++ b/docs/docs/verification/pd-neut-cwl_pv-march_lbco.ipynb @@ -247,13 +247,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "\n", "project.display.pattern_comparison(\n", " 'lbco',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -286,13 +287,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'lbco',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSPY_REFINED,\n", ")" ] }, @@ -313,7 +315,7 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " (f'{verify.engine_label(\"cryspy\", note=\"refined\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined),\n", + " (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined),\n", " ],\n", ")" ] diff --git a/docs/docs/verification/pd-neut-cwl_pv-march_lbco.py b/docs/docs/verification/pd-neut-cwl_pv-march_lbco.py index df7ca3378..63e69affa 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-march_lbco.py +++ b/docs/docs/verification/pd-neut-cwl_pv-march_lbco.py @@ -155,13 +155,14 @@ project.analysis.calculate() calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') project.display.pattern_comparison( 'lbco', reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -182,13 +183,14 @@ project.analysis.calculate() calc_ed_cryspy_refined = experiment.data.intensity_calc +LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined') project.display.pattern_comparison( 'lbco', reference=calc_fullprof, candidate=calc_ed_cryspy_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy', note='refined'), + candidate_label=LABEL_ED_CRYSPY_REFINED, ) # %% [markdown] @@ -197,7 +199,7 @@ # %% verify.assert_patterns_agree( [ - (f'{verify.engine_label("cryspy", note="refined")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined), + (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined), ], ) diff --git a/docs/docs/verification/pd-neut-cwl_pv_lbco.ipynb b/docs/docs/verification/pd-neut-cwl_pv_lbco.ipynb index 757eb1ee3..646e68584 100644 --- a/docs/docs/verification/pd-neut-cwl_pv_lbco.ipynb +++ b/docs/docs/verification/pd-neut-cwl_pv_lbco.ipynb @@ -218,13 +218,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "\n", "project.display.pattern_comparison(\n", " 'lbco',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -247,13 +248,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML = verify.engine_label('crysfml')\n", "\n", "project.display.pattern_comparison(\n", " 'lbco',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml'),\n", + " candidate_label=LABEL_ED_CRYSFML,\n", ")" ] }, @@ -274,8 +276,8 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " (f'{verify.engine_label(\"cryspy\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", - " (f'{verify.engine_label(\"crysfml\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", + " (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", + " (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", ")" ] diff --git a/docs/docs/verification/pd-neut-cwl_pv_lbco.py b/docs/docs/verification/pd-neut-cwl_pv_lbco.py index 8ced4b13e..965a210f5 100644 --- a/docs/docs/verification/pd-neut-cwl_pv_lbco.py +++ b/docs/docs/verification/pd-neut-cwl_pv_lbco.py @@ -126,13 +126,14 @@ project.analysis.calculate() calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') project.display.pattern_comparison( 'lbco', reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -143,13 +144,14 @@ project.analysis.calculate() calc_ed_crysfml = experiment.data.intensity_calc +LABEL_ED_CRYSFML = verify.engine_label('crysfml') project.display.pattern_comparison( 'lbco', reference=calc_fullprof, candidate=calc_ed_crysfml, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml'), + candidate_label=LABEL_ED_CRYSFML, ) # %% [markdown] @@ -158,7 +160,7 @@ # %% verify.assert_patterns_agree( [ - (f'{verify.engine_label("cryspy")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), - (f'{verify.engine_label("crysfml")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), + (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), + (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], ) diff --git a/docs/docs/verification/pd-neut-cwl_pv_pbso4.ipynb b/docs/docs/verification/pd-neut-cwl_pv_pbso4.ipynb index 9d8a219b9..8e1856be9 100644 --- a/docs/docs/verification/pd-neut-cwl_pv_pbso4.ipynb +++ b/docs/docs/verification/pd-neut-cwl_pv_pbso4.ipynb @@ -225,13 +225,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "\n", "project.display.pattern_comparison(\n", " 'pbso4',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -254,13 +255,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML = verify.engine_label('crysfml')\n", "\n", "project.display.pattern_comparison(\n", " 'pbso4',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml'),\n", + " candidate_label=LABEL_ED_CRYSFML,\n", ")" ] }, @@ -281,8 +283,8 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " (f'{verify.engine_label(\"cryspy\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", - " (f'{verify.engine_label(\"crysfml\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", + " (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", + " (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", ")" ] diff --git a/docs/docs/verification/pd-neut-cwl_pv_pbso4.py b/docs/docs/verification/pd-neut-cwl_pv_pbso4.py index 683e583aa..34c90ca68 100644 --- a/docs/docs/verification/pd-neut-cwl_pv_pbso4.py +++ b/docs/docs/verification/pd-neut-cwl_pv_pbso4.py @@ -133,13 +133,14 @@ project.analysis.calculate() calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') project.display.pattern_comparison( 'pbso4', reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -150,13 +151,14 @@ project.analysis.calculate() calc_ed_crysfml = experiment.data.intensity_calc +LABEL_ED_CRYSFML = verify.engine_label('crysfml') project.display.pattern_comparison( 'pbso4', reference=calc_fullprof, candidate=calc_ed_crysfml, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml'), + candidate_label=LABEL_ED_CRYSFML, ) # %% [markdown] @@ -165,7 +167,7 @@ # %% verify.assert_patterns_agree( [ - (f'{verify.engine_label("cryspy")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), - (f'{verify.engine_label("crysfml")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), + (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), + (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], ) diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb index 402d6e79a..b53079d7c 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb @@ -198,13 +198,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -227,13 +228,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML = verify.engine_label('crysfml')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml'),\n", + " candidate_label=LABEL_ED_CRYSFML,\n", ")" ] }, @@ -260,13 +262,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML_REFINED = verify.engine_label('crysfml', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSFML_REFINED,\n", ")" ] }, @@ -287,8 +290,8 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " (f'{verify.engine_label(\"cryspy\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", - " (f'{verify.engine_label(\"crysfml\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", + " (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", + " (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py index e38f3cce3..bdec96c9a 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py @@ -106,13 +106,14 @@ project.analysis.calculate() calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -123,13 +124,14 @@ project.analysis.calculate() calc_ed_crysfml = experiment.data.intensity_calc +LABEL_ED_CRYSFML = verify.engine_label('crysfml') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml'), + candidate_label=LABEL_ED_CRYSFML, ) # %% [markdown] @@ -144,13 +146,14 @@ project.analysis.calculate() calc_ed_crysfml_refined = experiment.data.intensity_calc +LABEL_ED_CRYSFML_REFINED = verify.engine_label('crysfml', note='refined') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml', note='refined'), + candidate_label=LABEL_ED_CRYSFML_REFINED, ) # %% [markdown] @@ -159,8 +162,8 @@ # %% verify.assert_patterns_agree( [ - (f'{verify.engine_label("cryspy")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), - (f'{verify.engine_label("crysfml")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), + (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), + (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], raise_on_failure=False, ) diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.ipynb b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.ipynb index bb7d2025a..ecab7af92 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.ipynb +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.ipynb @@ -201,13 +201,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -236,13 +237,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSPY_REFINED,\n", ")" ] }, @@ -277,13 +279,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML = verify.engine_label('crysfml')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml'),\n", + " candidate_label=LABEL_ED_CRYSFML,\n", ")" ] }, @@ -313,13 +316,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML_REFINED = verify.engine_label('crysfml', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSFML_REFINED,\n", ")" ] }, @@ -340,8 +344,8 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " (f'{verify.engine_label(\"cryspy\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", - " (f'{verify.engine_label(\"crysfml\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", + " (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", + " (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.py b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.py index 1a77802f1..47fd9052c 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.py +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.py @@ -109,13 +109,14 @@ project.analysis.calculate() calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -132,13 +133,14 @@ project.analysis.calculate() calc_ed_cryspy_refined = experiment.data.intensity_calc +LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_cryspy_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy', note='refined'), + candidate_label=LABEL_ED_CRYSPY_REFINED, ) # %% [markdown] @@ -161,13 +163,14 @@ project.analysis.calculate() calc_ed_crysfml = experiment.data.intensity_calc +LABEL_ED_CRYSFML = verify.engine_label('crysfml') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml'), + candidate_label=LABEL_ED_CRYSFML, ) # %% [markdown] @@ -185,13 +188,14 @@ project.analysis.calculate() calc_ed_crysfml_refined = experiment.data.intensity_calc +LABEL_ED_CRYSFML_REFINED = verify.engine_label('crysfml', note='refined') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml', note='refined'), + candidate_label=LABEL_ED_CRYSFML_REFINED, ) # %% [markdown] @@ -200,8 +204,8 @@ # %% verify.assert_patterns_agree( [ - (f'{verify.engine_label("cryspy")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), - (f'{verify.engine_label("crysfml")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), + (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), + (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], raise_on_failure=False, ) diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb b/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb index 1ab897b4f..69f42e6a8 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb @@ -224,13 +224,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -261,13 +262,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML = verify.engine_label('crysfml')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml'),\n", + " candidate_label=LABEL_ED_CRYSFML,\n", ")" ] }, @@ -292,7 +294,7 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " (f'{verify.engine_label(\"cryspy\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", + " (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", " ],\n", " raise_on_failure=True,\n", ")" diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.py b/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.py index c2dc00c92..964f249f2 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.py +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.py @@ -127,13 +127,14 @@ project.analysis.calculate() calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -152,13 +153,14 @@ project.analysis.calculate() calc_ed_crysfml = experiment.data.intensity_calc +LABEL_ED_CRYSFML = verify.engine_label('crysfml') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml'), + candidate_label=LABEL_ED_CRYSFML, ) # %% [markdown] @@ -171,7 +173,7 @@ # %% verify.assert_patterns_agree( [ - (f'{verify.engine_label("cryspy")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), + (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), ], raise_on_failure=True, ) diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.ipynb b/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.ipynb index 81aa54324..4982e4ef3 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.ipynb +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.ipynb @@ -208,13 +208,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -243,13 +244,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSPY_REFINED,\n", ")" ] }, @@ -284,13 +286,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML = verify.engine_label('crysfml')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml'),\n", + " candidate_label=LABEL_ED_CRYSFML,\n", ")" ] }, @@ -320,13 +323,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML_REFINED = verify.engine_label('crysfml', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'lab6',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSFML_REFINED,\n", ")" ] }, @@ -347,8 +351,8 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " (f'{verify.engine_label(\"cryspy\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", - " (f'{verify.engine_label(\"crysfml\")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", + " (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", + " (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py b/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py index ccc7b42a9..545813a3a 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py @@ -116,13 +116,14 @@ project.analysis.calculate() calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -139,13 +140,14 @@ project.analysis.calculate() calc_ed_cryspy_refined = experiment.data.intensity_calc +LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_cryspy_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy', note='refined'), + candidate_label=LABEL_ED_CRYSPY_REFINED, ) # %% [markdown] @@ -168,13 +170,14 @@ project.analysis.calculate() calc_ed_crysfml = experiment.data.intensity_calc +LABEL_ED_CRYSFML = verify.engine_label('crysfml') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml'), + candidate_label=LABEL_ED_CRYSFML, ) # %% [markdown] @@ -192,13 +195,14 @@ project.analysis.calculate() calc_ed_crysfml_refined = experiment.data.intensity_calc +LABEL_ED_CRYSFML_REFINED = verify.engine_label('crysfml', note='refined') project.display.pattern_comparison( 'lab6', reference=calc_fullprof, candidate=calc_ed_crysfml_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml', note='refined'), + candidate_label=LABEL_ED_CRYSFML_REFINED, ) # %% [markdown] @@ -207,8 +211,8 @@ # %% verify.assert_patterns_agree( [ - (f'{verify.engine_label("cryspy")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), - (f'{verify.engine_label("crysfml")} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), + (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), + (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], raise_on_failure=False, ) diff --git a/docs/docs/verification/pd-neut-tof_j_si.ipynb b/docs/docs/verification/pd-neut-tof_j_si.ipynb index 19a7437f5..ddacfa626 100644 --- a/docs/docs/verification/pd-neut-tof_j_si.ipynb +++ b/docs/docs/verification/pd-neut-tof_j_si.ipynb @@ -201,13 +201,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "\n", "project.display.pattern_comparison(\n", " 'si',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -234,13 +235,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'si',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSPY_REFINED,\n", ")" ] }, @@ -275,13 +277,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML = verify.engine_label('crysfml')\n", "\n", "project.display.pattern_comparison(\n", " 'si',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml'),\n", + " candidate_label=LABEL_ED_CRYSFML,\n", ")" ] }, @@ -308,13 +311,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML_REFINED = verify.engine_label('crysfml', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'si',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSFML_REFINED,\n", ")" ] }, @@ -346,12 +350,12 @@ "verify.assert_patterns_agree(\n", " [\n", " (\n", - " f'{verify.engine_label(\"cryspy\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", + " f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_cryspy_refined,\n", " ),\n", " (\n", - " f'{verify.engine_label(\"crysfml\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", + " f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_crysfml_refined,\n", " ),\n", diff --git a/docs/docs/verification/pd-neut-tof_j_si.py b/docs/docs/verification/pd-neut-tof_j_si.py index 8ec82ac13..3a7b2c483 100644 --- a/docs/docs/verification/pd-neut-tof_j_si.py +++ b/docs/docs/verification/pd-neut-tof_j_si.py @@ -109,13 +109,14 @@ project.analysis.calculate() calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') project.display.pattern_comparison( 'si', reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -130,13 +131,14 @@ project.analysis.calculate() calc_ed_cryspy_refined = experiment.data.intensity_calc +LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined') project.display.pattern_comparison( 'si', reference=calc_fullprof, candidate=calc_ed_cryspy_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy', note='refined'), + candidate_label=LABEL_ED_CRYSPY_REFINED, ) # %% @@ -152,13 +154,14 @@ project.analysis.calculate() calc_ed_crysfml = experiment.data.intensity_calc +LABEL_ED_CRYSFML = verify.engine_label('crysfml') project.display.pattern_comparison( 'si', reference=calc_fullprof, candidate=calc_ed_crysfml, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml'), + candidate_label=LABEL_ED_CRYSFML, ) # %% [markdown] @@ -173,13 +176,14 @@ project.analysis.calculate() calc_ed_crysfml_refined = experiment.data.intensity_calc +LABEL_ED_CRYSFML_REFINED = verify.engine_label('crysfml', note='refined') project.display.pattern_comparison( 'si', reference=calc_fullprof, candidate=calc_ed_crysfml_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml', note='refined'), + candidate_label=LABEL_ED_CRYSFML_REFINED, ) # %% @@ -192,12 +196,12 @@ verify.assert_patterns_agree( [ ( - f'{verify.engine_label("cryspy", note="refined")} vs {FULLPROF_LABEL}', + f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_cryspy_refined, ), ( - f'{verify.engine_label("crysfml", note="refined")} vs {FULLPROF_LABEL}', + f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_crysfml_refined, ), diff --git a/docs/docs/verification/pd-neut-tof_jvd_ncaf.ipynb b/docs/docs/verification/pd-neut-tof_jvd_ncaf.ipynb index b3ed5ed95..c398b4f00 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_ncaf.ipynb +++ b/docs/docs/verification/pd-neut-tof_jvd_ncaf.ipynb @@ -248,13 +248,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "\n", "project.display.pattern_comparison(\n", " 'ncaf',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -281,13 +282,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'ncaf',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSPY_REFINED,\n", ")" ] }, @@ -322,13 +324,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML = verify.engine_label('crysfml')\n", "\n", "project.display.pattern_comparison(\n", " 'ncaf',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml'),\n", + " candidate_label=LABEL_ED_CRYSFML,\n", ")" ] }, @@ -355,13 +358,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML_REFINED = verify.engine_label('crysfml', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'ncaf',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSFML_REFINED,\n", ")" ] }, @@ -393,12 +397,12 @@ "verify.assert_patterns_agree(\n", " [\n", " (\n", - " f'{verify.engine_label(\"cryspy\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", + " f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_cryspy_refined,\n", " ),\n", " (\n", - " f'{verify.engine_label(\"crysfml\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", + " f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_crysfml_refined,\n", " ),\n", diff --git a/docs/docs/verification/pd-neut-tof_jvd_ncaf.py b/docs/docs/verification/pd-neut-tof_jvd_ncaf.py index 86368f54c..7ece521b0 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_ncaf.py +++ b/docs/docs/verification/pd-neut-tof_jvd_ncaf.py @@ -156,13 +156,14 @@ project.analysis.calculate() calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') project.display.pattern_comparison( 'ncaf', reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -177,13 +178,14 @@ project.analysis.calculate() calc_ed_cryspy_refined = experiment.data.intensity_calc +LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined') project.display.pattern_comparison( 'ncaf', reference=calc_fullprof, candidate=calc_ed_cryspy_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy', note='refined'), + candidate_label=LABEL_ED_CRYSPY_REFINED, ) # %% @@ -199,13 +201,14 @@ project.analysis.calculate() calc_ed_crysfml = experiment.data.intensity_calc +LABEL_ED_CRYSFML = verify.engine_label('crysfml') project.display.pattern_comparison( 'ncaf', reference=calc_fullprof, candidate=calc_ed_crysfml, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml'), + candidate_label=LABEL_ED_CRYSFML, ) # %% [markdown] @@ -220,13 +223,14 @@ project.analysis.calculate() calc_ed_crysfml_refined = experiment.data.intensity_calc +LABEL_ED_CRYSFML_REFINED = verify.engine_label('crysfml', note='refined') project.display.pattern_comparison( 'ncaf', reference=calc_fullprof, candidate=calc_ed_crysfml_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml', note='refined'), + candidate_label=LABEL_ED_CRYSFML_REFINED, ) # %% @@ -239,12 +243,12 @@ verify.assert_patterns_agree( [ ( - f'{verify.engine_label("cryspy", note="refined")} vs {FULLPROF_LABEL}', + f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_cryspy_refined, ), ( - f'{verify.engine_label("crysfml", note="refined")} vs {FULLPROF_LABEL}', + f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_crysfml_refined, ), diff --git a/docs/docs/verification/pd-neut-tof_jvd_si.ipynb b/docs/docs/verification/pd-neut-tof_jvd_si.ipynb index 200bb9de7..06a1598a3 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_si.ipynb +++ b/docs/docs/verification/pd-neut-tof_jvd_si.ipynb @@ -207,13 +207,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "\n", "project.display.pattern_comparison(\n", " 'si',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -242,13 +243,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_cryspy_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'si',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_cryspy_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSPY_REFINED,\n", ")" ] }, @@ -294,13 +296,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML = verify.engine_label('crysfml')\n", "\n", "project.display.pattern_comparison(\n", " 'si',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml'),\n", + " candidate_label=LABEL_ED_CRYSFML,\n", ")" ] }, @@ -328,13 +331,14 @@ "\n", "project.analysis.calculate()\n", "calc_ed_crysfml_refined = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML_REFINED = verify.engine_label('crysfml', note='refined')\n", "\n", "project.display.pattern_comparison(\n", " 'si',\n", " reference=calc_fullprof,\n", " candidate=calc_ed_crysfml_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('crysfml', note='refined'),\n", + " candidate_label=LABEL_ED_CRYSFML_REFINED,\n", ")" ] }, @@ -376,12 +380,12 @@ "verify.assert_patterns_agree(\n", " [\n", " (\n", - " f'{verify.engine_label(\"cryspy\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", + " f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_cryspy_refined,\n", " ),\n", " (\n", - " f'{verify.engine_label(\"crysfml\", note=\"refined\")} vs {FULLPROF_LABEL}',\n", + " f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_crysfml_refined,\n", " ),\n", diff --git a/docs/docs/verification/pd-neut-tof_jvd_si.py b/docs/docs/verification/pd-neut-tof_jvd_si.py index cc6911cac..bb989e275 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_si.py +++ b/docs/docs/verification/pd-neut-tof_jvd_si.py @@ -115,13 +115,14 @@ project.analysis.calculate() calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') project.display.pattern_comparison( 'si', reference=calc_fullprof, candidate=calc_ed_cryspy, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -138,13 +139,14 @@ project.analysis.calculate() calc_ed_cryspy_refined = experiment.data.intensity_calc +LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='refined') project.display.pattern_comparison( 'si', reference=calc_fullprof, candidate=calc_ed_cryspy_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy', note='refined'), + candidate_label=LABEL_ED_CRYSPY_REFINED, ) # %% @@ -164,13 +166,14 @@ project.analysis.calculate() calc_ed_crysfml = experiment.data.intensity_calc +LABEL_ED_CRYSFML = verify.engine_label('crysfml') project.display.pattern_comparison( 'si', reference=calc_fullprof, candidate=calc_ed_crysfml, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml'), + candidate_label=LABEL_ED_CRYSFML, ) # %% [markdown] @@ -186,13 +189,14 @@ project.analysis.calculate() calc_ed_crysfml_refined = experiment.data.intensity_calc +LABEL_ED_CRYSFML_REFINED = verify.engine_label('crysfml', note='refined') project.display.pattern_comparison( 'si', reference=calc_fullprof, candidate=calc_ed_crysfml_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('crysfml', note='refined'), + candidate_label=LABEL_ED_CRYSFML_REFINED, ) # %% @@ -208,12 +212,12 @@ verify.assert_patterns_agree( [ ( - f'{verify.engine_label("cryspy", note="refined")} vs {FULLPROF_LABEL}', + f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_cryspy_refined, ), ( - f'{verify.engine_label("crysfml", note="refined")} vs {FULLPROF_LABEL}', + f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), calc_ed_crysfml_refined, ), diff --git a/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.ipynb b/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.ipynb index 87a27d832..b3a3737db 100644 --- a/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.ipynb +++ b/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.ipynb @@ -225,6 +225,7 @@ "outputs": [], "source": [ "calc_ed_cryspy = verify.calculate_reflections(project, experiment, 'cryspy')\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "reference, candidate = verify.align_reflections(f2calc, calc_ed_cryspy)\n", "\n", "project.display.reflection_comparison(\n", @@ -232,7 +233,7 @@ " reference=reference,\n", " candidate=candidate,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -260,6 +261,7 @@ "project.display.fit.results()\n", "\n", "calc_ed_cryspy_refined = verify.calculate_reflections(project, experiment, 'cryspy')\n", + "LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='scale + ext radius')\n", "reference_refined, candidate_refined = verify.align_reflections(f2calc, calc_ed_cryspy_refined)\n", "\n", "project.display.reflection_comparison(\n", @@ -267,7 +269,7 @@ " reference=reference_refined,\n", " candidate=candidate_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy', note='scale + ext radius'),\n", + " candidate_label=LABEL_ED_CRYSPY_REFINED,\n", ")\n", "\n", "verify.report_refinement_closeness(\n", @@ -294,7 +296,7 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " (f'{verify.engine_label(\"cryspy\", note=\"scale + ext radius\")} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", + " (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.py b/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.py index d3fffa5aa..79c239f21 100644 --- a/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.py +++ b/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.py @@ -126,6 +126,7 @@ # %% calc_ed_cryspy = verify.calculate_reflections(project, experiment, 'cryspy') +LABEL_ED_CRYSPY = verify.engine_label('cryspy') reference, candidate = verify.align_reflections(f2calc, calc_ed_cryspy) project.display.reflection_comparison( @@ -133,7 +134,7 @@ reference=reference, candidate=candidate, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -149,6 +150,7 @@ project.display.fit.results() calc_ed_cryspy_refined = verify.calculate_reflections(project, experiment, 'cryspy') +LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='scale + ext radius') reference_refined, candidate_refined = verify.align_reflections(f2calc, calc_ed_cryspy_refined) project.display.reflection_comparison( @@ -156,7 +158,7 @@ reference=reference_refined, candidate=candidate_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy', note='scale + ext radius'), + candidate_label=LABEL_ED_CRYSPY_REFINED, ) verify.report_refinement_closeness( @@ -171,7 +173,7 @@ # %% verify.assert_patterns_agree( [ - (f'{verify.engine_label("cryspy", note="scale + ext radius")} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), + (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), ], raise_on_failure=False, ) diff --git a/docs/docs/verification/sc-neut-cwl_noext_tbti.ipynb b/docs/docs/verification/sc-neut-cwl_noext_tbti.ipynb index f8386c1ce..cafe5b6a7 100644 --- a/docs/docs/verification/sc-neut-cwl_noext_tbti.ipynb +++ b/docs/docs/verification/sc-neut-cwl_noext_tbti.ipynb @@ -218,6 +218,7 @@ "outputs": [], "source": [ "calc_ed_cryspy = verify.calculate_reflections(project, experiment, 'cryspy')\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "reference, candidate = verify.align_reflections(f2calc, calc_ed_cryspy)\n", "\n", "project.display.reflection_comparison(\n", @@ -225,7 +226,7 @@ " reference=reference,\n", " candidate=candidate,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -252,6 +253,7 @@ "project.display.fit.results()\n", "\n", "calc_ed_cryspy_refined = verify.calculate_reflections(project, experiment, 'cryspy')\n", + "LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='scale only')\n", "reference_refined, candidate_refined = verify.align_reflections(f2calc, calc_ed_cryspy_refined)\n", "\n", "project.display.reflection_comparison(\n", @@ -259,7 +261,7 @@ " reference=reference_refined,\n", " candidate=candidate_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy', note='scale only'),\n", + " candidate_label=LABEL_ED_CRYSPY_REFINED,\n", ")\n", "\n", "verify.report_refinement_closeness(\n", @@ -286,7 +288,7 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " (f'{verify.engine_label(\"cryspy\", note=\"scale only\")} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", + " (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/sc-neut-cwl_noext_tbti.py b/docs/docs/verification/sc-neut-cwl_noext_tbti.py index e2e4bde72..76b09f263 100644 --- a/docs/docs/verification/sc-neut-cwl_noext_tbti.py +++ b/docs/docs/verification/sc-neut-cwl_noext_tbti.py @@ -119,6 +119,7 @@ # %% calc_ed_cryspy = verify.calculate_reflections(project, experiment, 'cryspy') +LABEL_ED_CRYSPY = verify.engine_label('cryspy') reference, candidate = verify.align_reflections(f2calc, calc_ed_cryspy) project.display.reflection_comparison( @@ -126,7 +127,7 @@ reference=reference, candidate=candidate, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -141,6 +142,7 @@ project.display.fit.results() calc_ed_cryspy_refined = verify.calculate_reflections(project, experiment, 'cryspy') +LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='scale only') reference_refined, candidate_refined = verify.align_reflections(f2calc, calc_ed_cryspy_refined) project.display.reflection_comparison( @@ -148,7 +150,7 @@ reference=reference_refined, candidate=candidate_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy', note='scale only'), + candidate_label=LABEL_ED_CRYSPY_REFINED, ) verify.report_refinement_closeness( @@ -163,7 +165,7 @@ # %% verify.assert_patterns_agree( [ - (f'{verify.engine_label("cryspy", note="scale only")} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), + (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), ], raise_on_failure=False, ) diff --git a/docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb b/docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb index 3c7c6201f..8faf62f8b 100644 --- a/docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb +++ b/docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb @@ -253,6 +253,7 @@ "outputs": [], "source": [ "calc_ed_cryspy = verify.calculate_reflections(project, experiment, 'cryspy')\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", "reference, candidate = verify.align_reflections(f2calc, calc_ed_cryspy)\n", "\n", "project.display.reflection_comparison(\n", @@ -260,7 +261,7 @@ " reference=reference,\n", " candidate=candidate,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy'),\n", + " candidate_label=LABEL_ED_CRYSPY,\n", ")" ] }, @@ -287,6 +288,7 @@ "project.display.fit.results()\n", "\n", "calc_ed_cryspy_refined = verify.calculate_reflections(project, experiment, 'cryspy')\n", + "LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='scale only')\n", "reference_refined, candidate_refined = verify.align_reflections(f2calc, calc_ed_cryspy_refined)\n", "\n", "project.display.reflection_comparison(\n", @@ -294,7 +296,7 @@ " reference=reference_refined,\n", " candidate=candidate_refined,\n", " reference_label=FULLPROF_LABEL,\n", - " candidate_label=verify.engine_label('cryspy', note='scale only'),\n", + " candidate_label=LABEL_ED_CRYSPY_REFINED,\n", ")\n", "\n", "verify.report_refinement_closeness(\n", @@ -321,7 +323,7 @@ "source": [ "verify.assert_patterns_agree(\n", " [\n", - " (f'{verify.engine_label(\"cryspy\", note=\"scale only\")} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", + " (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", " ],\n", " raise_on_failure=False,\n", ")" diff --git a/docs/docs/verification/sc-neut-cwl_pr2nio4.py b/docs/docs/verification/sc-neut-cwl_pr2nio4.py index 6e09d31a6..d0f3d29c9 100644 --- a/docs/docs/verification/sc-neut-cwl_pr2nio4.py +++ b/docs/docs/verification/sc-neut-cwl_pr2nio4.py @@ -154,6 +154,7 @@ # %% calc_ed_cryspy = verify.calculate_reflections(project, experiment, 'cryspy') +LABEL_ED_CRYSPY = verify.engine_label('cryspy') reference, candidate = verify.align_reflections(f2calc, calc_ed_cryspy) project.display.reflection_comparison( @@ -161,7 +162,7 @@ reference=reference, candidate=candidate, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy'), + candidate_label=LABEL_ED_CRYSPY, ) # %% [markdown] @@ -176,6 +177,7 @@ project.display.fit.results() calc_ed_cryspy_refined = verify.calculate_reflections(project, experiment, 'cryspy') +LABEL_ED_CRYSPY_REFINED = verify.engine_label('cryspy', note='scale only') reference_refined, candidate_refined = verify.align_reflections(f2calc, calc_ed_cryspy_refined) project.display.reflection_comparison( @@ -183,7 +185,7 @@ reference=reference_refined, candidate=candidate_refined, reference_label=FULLPROF_LABEL, - candidate_label=verify.engine_label('cryspy', note='scale only'), + candidate_label=LABEL_ED_CRYSPY_REFINED, ) verify.report_refinement_closeness( @@ -198,7 +200,7 @@ # %% verify.assert_patterns_agree( [ - (f'{verify.engine_label("cryspy", note="scale only")} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), + (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), ], raise_on_failure=False, ) From 122a054bc4e3dbf8b3cdafecb343f4a1e58651d7 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 15:02:12 +0200 Subject: [PATCH 12/18] Test verification software labels --- .../analysis/test_verification.py | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/tests/unit/easydiffraction/analysis/test_verification.py b/tests/unit/easydiffraction/analysis/test_verification.py index fa32aa669..2d82bfb04 100644 --- a/tests/unit/easydiffraction/analysis/test_verification.py +++ b/tests/unit/easydiffraction/analysis/test_verification.py @@ -66,7 +66,56 @@ def test_fullprof_label_formats_version(ref_dir): ' ** PROGRAM FullProf.2k (Version 8.40 - Feb2026-ILL JRC) **\n', encoding='utf-8', ) - assert verify.fullprof_label('', 'ref.sum') == 'FullProf v8.40' + assert verify.fullprof_label('', 'ref.sum') == 'FullProf 8.40' + + +def test_engine_label_formats_candidate_versions(monkeypatch): + versions = { + 'easydiffraction': '1.2.3', + 'cryspy': '2.4.6', + } + monkeypatch.setattr(verify, 'package_version', lambda name: versions[name]) + assert verify.engine_label('cryspy') == 'edi 1.2.3 (cryspy 2.4.6)' + + +def test_engine_label_appends_note(monkeypatch): + versions = { + 'easydiffraction': '1.2.3', + 'cryspy': '2.4.6', + } + monkeypatch.setattr(verify, 'package_version', lambda name: versions[name]) + assert verify.engine_label('cryspy', note='refined') == 'edi 1.2.3 (cryspy 2.4.6, refined)' + + +def test_engine_label_marks_unresolvable_engine_version(monkeypatch): + def fake_package_version(name): + if name == 'easydiffraction': + return '1.2.3' + return None + + monkeypatch.setattr(verify, 'package_version', fake_package_version) + assert verify.engine_label('cryspy') == 'edi 1.2.3 (cryspy ?)' + + +@pytest.mark.parametrize( + ('raw_version', 'expected_version'), + [ + ('1.2.3+dev3', '1.2.3+dev3'), + ('0.5.8+dirty3', '0.5.8+dirty3'), + ('0.5.8+devdirty3', '0.5.8+devdirty3'), + ('1.2.3+g1a2b3c', '1.2.3'), + ('1.2.3+abcdef', '1.2.3+abcdef'), + ], +) +def test_engine_label_preserves_dev_markers(monkeypatch, raw_version, expected_version): + monkeypatch.setattr(verify, 'package_version', lambda _name: raw_version) + expected = f'edi {expected_version} (cryspy {expected_version})' + assert verify.engine_label('cryspy') == expected + + +def test_engine_label_rejects_unknown_engine(): + with pytest.raises(ValueError, match="Unknown engine 'crysfmi'"): + verify.engine_label('crysfmi') class _FakeCategory: From 1bbf2ab3e4566e6dd63cc6f4512dd61cc3b76ae3 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 15:03:07 +0200 Subject: [PATCH 13/18] Apply pixi run fix auto-fixes --- src/easydiffraction/analysis/verification.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/easydiffraction/analysis/verification.py b/src/easydiffraction/analysis/verification.py index 08d614774..6682210b6 100644 --- a/src/easydiffraction/analysis/verification.py +++ b/src/easydiffraction/analysis/verification.py @@ -450,9 +450,9 @@ def _label_version(package_name: str) -> str | None: """ Return an installed package version formatted for a page label. - Keeps this project's versioningit dev markers - (``+dev{N}`` / ``+dirty{N}`` / ``+devdirty{N}``) and any PEP 440 - public dev/pre-release segment, but trims a g-prefixed VCS-hash local part + Keeps this project's versioningit dev markers (``+dev{N}`` / + ``+dirty{N}`` / ``+devdirty{N}``) and any PEP 440 public + dev/pre-release segment, but trims a g-prefixed VCS-hash local part (for example ``+g1a2b3c``) so the label stays readable. Parameters @@ -484,8 +484,8 @@ def engine_label(engine: str, note: str | None = None) -> str: ``note``, ``'edi 1.2.3 (cryspy 2.4.1, refined)'``. The engine is named explicitly (not read from the active calculator) so a stored result keeps the version of the engine that produced it. An - unresolvable version renders a visible ``?`` marker rather than being - omitted. + unresolvable version renders a visible ``?`` marker rather than + being omitted. Parameters ---------- From dc638fb1630bfe5163782e9972cc9b02dc33eda9 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 15:04:05 +0200 Subject: [PATCH 14/18] Apply pixi run fix auto-fixes --- src/easydiffraction/analysis/analysis.py | 2 +- src/easydiffraction/analysis/verification.py | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/easydiffraction/analysis/analysis.py b/src/easydiffraction/analysis/analysis.py index f6c551259..a366c6477 100644 --- a/src/easydiffraction/analysis/analysis.py +++ b/src/easydiffraction/analysis/analysis.py @@ -65,6 +65,7 @@ from easydiffraction.utils.enums import VerbosityEnum from easydiffraction.utils.logging import console from easydiffraction.utils.logging import log +from easydiffraction.utils.utils import SOFTWARE_PACKAGE_BY_ENGINE from easydiffraction.utils.utils import _help_method_rows from easydiffraction.utils.utils import _help_property_rows from easydiffraction.utils.utils import format_bulleted_warning @@ -72,7 +73,6 @@ from easydiffraction.utils.utils import render_cif from easydiffraction.utils.utils import render_object_help from easydiffraction.utils.utils import render_table -from easydiffraction.utils.utils import SOFTWARE_PACKAGE_BY_ENGINE if TYPE_CHECKING: from collections.abc import Callable diff --git a/src/easydiffraction/analysis/verification.py b/src/easydiffraction/analysis/verification.py index 6682210b6..fb14a2666 100644 --- a/src/easydiffraction/analysis/verification.py +++ b/src/easydiffraction/analysis/verification.py @@ -22,9 +22,9 @@ import numpy as np from easydiffraction.datablocks.experiment.item.base import intensity_category_for +from easydiffraction.utils.utils import SOFTWARE_PACKAGE_BY_ENGINE from easydiffraction.utils.utils import package_version from easydiffraction.utils.utils import render_table -from easydiffraction.utils.utils import SOFTWARE_PACKAGE_BY_ENGINE # Closeness metrics are computed on absolute intensities: each page # seeds the FullProf scale (from its .pcr) so the calculated patterns @@ -508,16 +508,13 @@ def engine_label(engine: str, note: str | None = None) -> str: """ if engine not in SOFTWARE_PACKAGE_BY_ENGINE: supported = ', '.join(sorted(SOFTWARE_PACKAGE_BY_ENGINE)) - msg = f"Unknown engine {engine!r}; expected one of: {supported}." + msg = f'Unknown engine {engine!r}; expected one of: {supported}.' raise ValueError(msg) edi_version = _label_version('easydiffraction') engine_version = _label_version(SOFTWARE_PACKAGE_BY_ENGINE[engine]) edi_text = f'edi {edi_version}' if edi_version is not None else 'edi ?' - if engine_version is None: - engine_text = f'{engine} ?' - else: - engine_text = f'{engine} {engine_version}' + engine_text = f'{engine} ?' if engine_version is None else f'{engine} {engine_version}' inner = engine_text if note is None else f'{engine_text}, {note}' return f'{edi_text} ({inner})' From d7959c9533943842ffede3e69f019366f5335d16 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 15:05:15 +0200 Subject: [PATCH 15/18] Apply pixi run fix auto-fixes --- .../verification-software-version-labels.md | 61 +++++----- docs/dev/adrs/index.md | 112 +++++++++--------- 2 files changed, 86 insertions(+), 87 deletions(-) diff --git a/docs/dev/adrs/accepted/verification-software-version-labels.md b/docs/dev/adrs/accepted/verification-software-version-labels.md index dd3b4144f..f9718df66 100644 --- a/docs/dev/adrs/accepted/verification-software-version-labels.md +++ b/docs/dev/adrs/accepted/verification-software-version-labels.md @@ -15,15 +15,15 @@ Quality. ## Context The cross-engine **Verification** pages (established by -[`test-suite-and-validation`](test-suite-and-validation.md) -§6) overlay an EasyDiffraction calculator on a frozen FullProf reference -and score the agreement. A scientist reading such a page — or revisiting -it after an engine update — needs to know **which versions of software -produced the curves**, because cross-engine agreement is version -dependent. The Bérar–Baldinozzi case (issue 166) is the clearest -example: whether cryspy and FullProf agree depends on the exact cryspy -build, so a page that does not state its versions cannot be reproduced -or trusted over time. +[`test-suite-and-validation`](test-suite-and-validation.md) §6) overlay +an EasyDiffraction calculator on a frozen FullProf reference and score +the agreement. A scientist reading such a page — or revisiting it after +an engine update — needs to know **which versions of software produced +the curves**, because cross-engine agreement is version dependent. The +Bérar–Baldinozzi case (issue 166) is the clearest example: whether +cryspy and FullProf agree depends on the exact cryspy build, so a page +that does not state its versions cannot be reproduced or trusted over +time. Today this **provenance is incomplete and inconsistent**: @@ -95,20 +95,20 @@ A dev or pre-release install keeps its **dev marker** visible (so a dev-build comparison is not mistaken for a released one) while dropping only a **pure VCS-hash local segment** (`+g`) to keep the label readable. Concretely, this project's versioningit emits the dev signal -in the *local* segment — `{base}+dev{N}`, `{base}+dirty{N}`, -`{base}+devdirty{N}` (see `pyproject.toml` -`[tool.versioningit.format]`) — so those markers are **preserved -verbatim**: an `edi` install of `1.2.3+dev3` renders `edi 1.2.3+dev3`. -A pure git-hash local part such as `0.11.0.dev3+g1a2b3c` is trimmed to -`edi 0.11.0.dev3`. The same rule applies to any engine package. (A -public-segment-only formatter such as `stripped_package_version` is -deliberately **not** used here: it would discard the `+dev*`/`+dirty*` -local markers and make a dev build look released.) +in the _local_ segment — `{base}+dev{N}`, `{base}+dirty{N}`, +`{base}+devdirty{N}` (see `pyproject.toml` `[tool.versioningit.format]`) +— so those markers are **preserved verbatim**: an `edi` install of +`1.2.3+dev3` renders `edi 1.2.3+dev3`. A pure git-hash local part such +as `0.11.0.dev3+g1a2b3c` is trimmed to `edi 0.11.0.dev3`. The same rule +applies to any engine package. (A public-segment-only formatter such as +`stripped_package_version` is deliberately **not** used here: it would +discard the `+dev*`/`+dirty*` local markers and make a dev build look +released.) ### 3. A `verify` helper builds the candidate label from an explicit engine tag -A single helper — `verify.engine_label(engine, note=None)` — returns -the **candidate** string only (the reference side stays the existing +A single helper — `verify.engine_label(engine, note=None)` — returns the +**candidate** string only (the reference side stays the existing `verify.fullprof_label`, so the two single-purpose helpers mirror each other). The optional free-text `note` annotates the candidate inside the parentheses (for example `note='refined'`, `note='scale only'`, @@ -244,14 +244,13 @@ the rationale is not lost: - **Label binding — resolved (Decision 3).** The helper takes an explicit engine tag, not `experiment.calculator.type`, so a stored result keeps the version of the engine that produced it. -- **Helper name — resolved: - `verify.engine_label(engine, note=None)`, candidate only (Decision - 3).** The reference side stays `verify.fullprof_label`; the two small - single-purpose helpers mirror each other and the page composes the - combined table label from both. No single dual-return call (it would - couple engine-version logic to `.sum` parsing). The free-text `note` - generalises a boolean `refined` so annotations like `scale only` are - expressible. +- **Helper name — resolved: `verify.engine_label(engine, note=None)`, + candidate only (Decision 3).** The reference side stays + `verify.fullprof_label`; the two small single-purpose helpers mirror + each other and the page composes the combined table label from both. + No single dual-return call (it would couple engine-version logic to + `.sum` parsing). The free-text `note` generalises a boolean `refined` + so annotations like `scale only` are expressible. - **Render location — resolved: legend + agreement-table label only (Decision 1).** No separate provenance caption/row; the versions live on the two label surfaces a page already has, reusing existing label @@ -259,9 +258,9 @@ the rationale is not lost: - **Format — resolved: bare `X.Y.Z`, no `v` prefix (Decision 2), applied to all three components.** `fullprof_label` drops its `v` to match (Compatibility). Pre-release/dev builds **keep** this repo's local dev - markers (`+dev*`/`+dirty*`/`+devdirty*`) and trim only a pure `+g` - VCS-hash tail (Decision 2a); `stripped_package_version` is not used - because it would drop those markers. + markers (`+dev*`/`+dirty*`/`+devdirty*`) and trim only a pure + `+g` VCS-hash tail (Decision 2a); `stripped_package_version` is + not used because it would drop those markers. ## Deferred Work diff --git a/docs/dev/adrs/index.md b/docs/dev/adrs/index.md index b3c75ff60..1eebee081 100644 --- a/docs/dev/adrs/index.md +++ b/docs/dev/adrs/index.md @@ -13,60 +13,60 @@ folders. ## ADR Index -| Group | Status | Title | Short description | Link | -| -------------------- | ---------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -| Analysis and fitting | Accepted | Fit Mode Categories and Fit Execution API | Splits fitting configuration from execution and defines active sibling fit-mode categories. | [`fit-mode-categories.md`](accepted/fit-mode-categories.md) | -| Analysis and fitting | Accepted | Runtime Fit Results | Keeps full fit outputs runtime-only in the current design unless a narrower persistence ADR is accepted. | [`runtime-fit-results.md`](accepted/runtime-fit-results.md) | -| Analysis and fitting | Accepted | Analysis CIF Fit State | Defines the persisted fit-state projection in `analysis/analysis.cif` and `analysis/mcmc.h5`. | [`analysis-cif-fit-state.md`](accepted/analysis-cif-fit-state.md) | -| Analysis and fitting | Accepted | Parameter Correlation Persistence | Persists deterministic and posterior correlation summaries in `_fit_parameter_correlation` | [`parameter-correlation-persistence.md`](accepted/parameter-correlation-persistence.md) | -| Analysis and fitting | Suggestion | Fit Output Files and Data Exports | Narrows remaining archive/export questions after adopting `results.csv` and `mcmc.h5`. | [`fit-output-files-and-data-exports.md`](suggestions/fit-output-files-and-data-exports.md) | -| Analysis and fitting | Accepted | Dataset-Driven Fit Mode Availability | Offers fit modes by per-mode preconditions, restricts `single` to one dataset (closing issue 85), and keeps `sequential` as the folder sweep. | [`dataset-driven-fit-modes.md`](accepted/dataset-driven-fit-modes.md) | -| Analysis and fitting | Accepted | Minimizer Category Consolidation | Collapses the seven Bayesian categories into one owner-level switchable `minimizer` category with HDF5 sidecar. | [`minimizer-category-consolidation.md`](accepted/minimizer-category-consolidation.md) | -| Analysis and fitting | Accepted | Minimizer Input/Output Split | Keeps `analysis.minimizer` input-only and moves scalar fit outputs to paired `analysis.fit_result` classes. | [`minimizer-input-output-split.md`](accepted/minimizer-input-output-split.md) | -| Analysis and fitting | Superseded | Parameter-Level Posterior Projection | Superseded by minimizer-category consolidation; kept as historical context for `parameter.posterior`. | [`parameter-posterior-summary.md`](suggestions/parameter-posterior-summary.md) | -| Analysis and fitting | Accepted | Undo Fit | Builds rollback semantics and CLI behavior on already-persisted pre-fit scalar snapshots. | [`undo-fit.md`](accepted/undo-fit.md) | -| Analysis and fitting | Accepted | Bayesian Resume and MCMC Sidecar Naming | Extends bumps-DREAM with resume/extend like emcee and renames the MCMC sidecar to `mcmc.h5` with per-engine state groups. | [`bayesian-resume-and-mcmc-sidecar.md`](accepted/bayesian-resume-and-mcmc-sidecar.md) | -| Core model | Accepted | Category Owners and Real Datablocks | Introduces `CategoryOwner` so singleton sections do not pretend to be real CIF datablocks. | [`category-owner-sections.md`](accepted/category-owner-sections.md) | -| Core model | Accepted | Enum-Backed Closed Value Sets | Requires finite option sets to use `(str, Enum)` classes for validation and dispatch. | [`enum-backed-closed-values.md`](accepted/enum-backed-closed-values.md) | -| Core model | Accepted | Guarded Public Properties | Uses property setters as the public writability contract for guarded objects. | [`guarded-public-properties.md`](accepted/guarded-public-properties.md) | -| Core model | Accepted | Two-Level Category Parameter Access | Keeps parameter access to `datablock.category.parameter` or `datablock.collection[id].parameter`. | [`category-parameter-access.md`](accepted/category-parameter-access.md) | -| Documentation | Accepted | Descriptor Property Docstring Template | Makes descriptor metadata the source of truth for public property docstrings and annotations. | [`property-docstring-template.md`](accepted/property-docstring-template.md) | -| Documentation | Accepted | Development Documentation Structure | Defines the `docs/dev` layout for ADRs, issues, plans, package structure, and roadmap. | [`development-docs-structure.md`](accepted/development-docs-structure.md) | -| Documentation | Accepted | Help Method Discoverability | Requires primary public objects and facades to expose consistent `help()` output. | [`help-discoverability.md`](accepted/help-discoverability.md) | -| Documentation | Accepted | Notebook Generation Source of Truth | Treats tutorial `.py` files as editable sources and notebooks as generated artifacts. | [`notebook-generation.md`](accepted/notebook-generation.md) | -| Documentation | Accepted | Plotting & Docs Performance for Interactive Figures | Self-hosts a lazy, shared figure runtime so docs pages load fast and progressively while staying interactive. | [`plotting-docs-performance.md`](accepted/plotting-docs-performance.md) | -| Documentation | Accepted | Documentation CI and Build Verification | Strict MkDocs builds, API-derived docs, snippet smoke tests, link checks, and prose/spelling checks. | [`documentation-ci-build.md`](accepted/documentation-ci-build.md) | -| Documentation | Accepted | Data Download Source Pinning | Pins downloadable data to one git commit kept in a packaged file, drops the redundant index checksum, cache-busting by commit-named index. | [`data-source-pinning.md`](accepted/data-source-pinning.md) | -| Experiment model | Accepted | Immutable Experiment Type | Makes experiment type axes creation-time state rather than mutable runtime state. | [`immutable-experiment-type.md`](accepted/immutable-experiment-type.md) | -| Experiment model | Accepted | Automatic Line-Segment Background Estimation | Detects line-segment background control points from the measured pattern, peak-insensitive and editable. | [`background-auto-estimate.md`](accepted/background-auto-estimate.md) | -| Experiment model | Accepted | Calculation Without Measured Data | Adds a writable `data_range` category so a structure-only experiment is calculable and plottable without loaded data. | [`calculation-without-measured-data.md`](accepted/calculation-without-measured-data.md) | -| Experiment model | Accepted | Preferred-Orientation Category | Adds a per-phase March–Dollase preferred-orientation category for textured powder refinement on the CrysPy backend. | [`preferred-orientation-category.md`](accepted/preferred-orientation-category.md) | -| Experiment model | Accepted | Model Sample Absorption (Debye–Scherrer, μR) | Switchable `absorption` category applying a calculator-independent cylindrical Hewat A(θ) envelope for powder samples. | [`model-sample-absorption.md`](accepted/model-sample-absorption.md) | -| Factories | Accepted | Factory Contracts and Metadata | Standardizes factory construction, metadata, compatibility, and registration behavior. | [`factory-contracts.md`](accepted/factory-contracts.md) | -| Naming | Accepted | Factory Tag Naming | Defines canonical factory tag style and standard abbreviations. | [`factory-tag-naming.md`](accepted/factory-tag-naming.md) | -| Naming | Accepted | Downloadable Resource Naming | Replaces integer dataset/tutorial ids with stable descriptive slugs and moves presentation order into separate metadata. | [`resource-naming.md`](accepted/resource-naming.md) | -| Persistence | Accepted | Free-Flag CIF Encoding | Encodes fit free/fixed state through CIF uncertainty syntax instead of a separate free list. | [`free-flag-cif-encoding.md`](accepted/free-flag-cif-encoding.md) | -| Persistence | Accepted | Loop Category Keys and Identity Naming | Documents loop collection keys and naming rules aligned with CIF category keys. | [`loop-category-key-identity.md`](accepted/loop-category-key-identity.md) | -| Persistence | Accepted | Project Facade and Persistence Layout | Documents the current `Project` facade and saved directory layout. | [`project-facade-and-persistence.md`](accepted/project-facade-and-persistence.md) | -| Persistence | Accepted | IUCr CIF Tag Alignment | Aligns default CIF tags with IUCr dictionaries and adds a clean IUCr-aligned report export. | [`iucr-cif-tag-alignment.md`](accepted/iucr-cif-tag-alignment.md) | -| Persistence | Accepted | Python and CIF Category Correspondence | Compares current Python paths and CIF tags, then records scoped one-to-one mapping for project-level categories. | [`python-cif-category-correspondence.md`](accepted/python-cif-category-correspondence.md) | -| Persistence | Accepted | Edi Project Persistence | Defines STAR-based EasyDiffraction project files with UX-oriented names and strict CIF reserved for report export. | [`edstar-project-persistence.md`](accepted/edstar-project-persistence.md) | -| Quality | Accepted | Lint Complexity Thresholds | Treats ruff PLR complexity limits as design guardrails that should not be bypassed. | [`lint-complexity-thresholds.md`](accepted/lint-complexity-thresholds.md) | -| Quality | Accepted | Lint Rule Scope and Test-File Exceptions | Records the standing tests/\*\* PLR/N812 ignores and CIF-aligned `id`/`type` builtin exception from the lint audit. | [`lint-rule-exceptions.md`](accepted/lint-rule-exceptions.md) | -| Quality | Accepted | Test Strategy | Defines layered unit, functional, integration, script, and notebook testing. | [`test-strategy.md`](accepted/test-strategy.md) | -| Quality | Accepted | Test Suite and Validation Strategy | Strict test layers, cost tiers, coverage/codecov policy, cross-engine verification docs, and a nightly validation harness. | [`test-suite-and-validation.md`](accepted/test-suite-and-validation.md) | -| Quality | Suggestion | Notebook-Owned Verification Regression Gating | Replaces the external `ci_skip.txt` list with a single in-notebook `regression=False` flag (plus a cell tag for pre-flag crashes). | [`verification-regression-flag.md`](suggestions/verification-regression-flag.md) | +| Group | Status | Title | Short description | Link | +| -------------------- | ---------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| Analysis and fitting | Accepted | Fit Mode Categories and Fit Execution API | Splits fitting configuration from execution and defines active sibling fit-mode categories. | [`fit-mode-categories.md`](accepted/fit-mode-categories.md) | +| Analysis and fitting | Accepted | Runtime Fit Results | Keeps full fit outputs runtime-only in the current design unless a narrower persistence ADR is accepted. | [`runtime-fit-results.md`](accepted/runtime-fit-results.md) | +| Analysis and fitting | Accepted | Analysis CIF Fit State | Defines the persisted fit-state projection in `analysis/analysis.cif` and `analysis/mcmc.h5`. | [`analysis-cif-fit-state.md`](accepted/analysis-cif-fit-state.md) | +| Analysis and fitting | Accepted | Parameter Correlation Persistence | Persists deterministic and posterior correlation summaries in `_fit_parameter_correlation` | [`parameter-correlation-persistence.md`](accepted/parameter-correlation-persistence.md) | +| Analysis and fitting | Suggestion | Fit Output Files and Data Exports | Narrows remaining archive/export questions after adopting `results.csv` and `mcmc.h5`. | [`fit-output-files-and-data-exports.md`](suggestions/fit-output-files-and-data-exports.md) | +| Analysis and fitting | Accepted | Dataset-Driven Fit Mode Availability | Offers fit modes by per-mode preconditions, restricts `single` to one dataset (closing issue 85), and keeps `sequential` as the folder sweep. | [`dataset-driven-fit-modes.md`](accepted/dataset-driven-fit-modes.md) | +| Analysis and fitting | Accepted | Minimizer Category Consolidation | Collapses the seven Bayesian categories into one owner-level switchable `minimizer` category with HDF5 sidecar. | [`minimizer-category-consolidation.md`](accepted/minimizer-category-consolidation.md) | +| Analysis and fitting | Accepted | Minimizer Input/Output Split | Keeps `analysis.minimizer` input-only and moves scalar fit outputs to paired `analysis.fit_result` classes. | [`minimizer-input-output-split.md`](accepted/minimizer-input-output-split.md) | +| Analysis and fitting | Superseded | Parameter-Level Posterior Projection | Superseded by minimizer-category consolidation; kept as historical context for `parameter.posterior`. | [`parameter-posterior-summary.md`](suggestions/parameter-posterior-summary.md) | +| Analysis and fitting | Accepted | Undo Fit | Builds rollback semantics and CLI behavior on already-persisted pre-fit scalar snapshots. | [`undo-fit.md`](accepted/undo-fit.md) | +| Analysis and fitting | Accepted | Bayesian Resume and MCMC Sidecar Naming | Extends bumps-DREAM with resume/extend like emcee and renames the MCMC sidecar to `mcmc.h5` with per-engine state groups. | [`bayesian-resume-and-mcmc-sidecar.md`](accepted/bayesian-resume-and-mcmc-sidecar.md) | +| Core model | Accepted | Category Owners and Real Datablocks | Introduces `CategoryOwner` so singleton sections do not pretend to be real CIF datablocks. | [`category-owner-sections.md`](accepted/category-owner-sections.md) | +| Core model | Accepted | Enum-Backed Closed Value Sets | Requires finite option sets to use `(str, Enum)` classes for validation and dispatch. | [`enum-backed-closed-values.md`](accepted/enum-backed-closed-values.md) | +| Core model | Accepted | Guarded Public Properties | Uses property setters as the public writability contract for guarded objects. | [`guarded-public-properties.md`](accepted/guarded-public-properties.md) | +| Core model | Accepted | Two-Level Category Parameter Access | Keeps parameter access to `datablock.category.parameter` or `datablock.collection[id].parameter`. | [`category-parameter-access.md`](accepted/category-parameter-access.md) | +| Documentation | Accepted | Descriptor Property Docstring Template | Makes descriptor metadata the source of truth for public property docstrings and annotations. | [`property-docstring-template.md`](accepted/property-docstring-template.md) | +| Documentation | Accepted | Development Documentation Structure | Defines the `docs/dev` layout for ADRs, issues, plans, package structure, and roadmap. | [`development-docs-structure.md`](accepted/development-docs-structure.md) | +| Documentation | Accepted | Help Method Discoverability | Requires primary public objects and facades to expose consistent `help()` output. | [`help-discoverability.md`](accepted/help-discoverability.md) | +| Documentation | Accepted | Notebook Generation Source of Truth | Treats tutorial `.py` files as editable sources and notebooks as generated artifacts. | [`notebook-generation.md`](accepted/notebook-generation.md) | +| Documentation | Accepted | Plotting & Docs Performance for Interactive Figures | Self-hosts a lazy, shared figure runtime so docs pages load fast and progressively while staying interactive. | [`plotting-docs-performance.md`](accepted/plotting-docs-performance.md) | +| Documentation | Accepted | Documentation CI and Build Verification | Strict MkDocs builds, API-derived docs, snippet smoke tests, link checks, and prose/spelling checks. | [`documentation-ci-build.md`](accepted/documentation-ci-build.md) | +| Documentation | Accepted | Data Download Source Pinning | Pins downloadable data to one git commit kept in a packaged file, drops the redundant index checksum, cache-busting by commit-named index. | [`data-source-pinning.md`](accepted/data-source-pinning.md) | +| Experiment model | Accepted | Immutable Experiment Type | Makes experiment type axes creation-time state rather than mutable runtime state. | [`immutable-experiment-type.md`](accepted/immutable-experiment-type.md) | +| Experiment model | Accepted | Automatic Line-Segment Background Estimation | Detects line-segment background control points from the measured pattern, peak-insensitive and editable. | [`background-auto-estimate.md`](accepted/background-auto-estimate.md) | +| Experiment model | Accepted | Calculation Without Measured Data | Adds a writable `data_range` category so a structure-only experiment is calculable and plottable without loaded data. | [`calculation-without-measured-data.md`](accepted/calculation-without-measured-data.md) | +| Experiment model | Accepted | Preferred-Orientation Category | Adds a per-phase March–Dollase preferred-orientation category for textured powder refinement on the CrysPy backend. | [`preferred-orientation-category.md`](accepted/preferred-orientation-category.md) | +| Experiment model | Accepted | Model Sample Absorption (Debye–Scherrer, μR) | Switchable `absorption` category applying a calculator-independent cylindrical Hewat A(θ) envelope for powder samples. | [`model-sample-absorption.md`](accepted/model-sample-absorption.md) | +| Factories | Accepted | Factory Contracts and Metadata | Standardizes factory construction, metadata, compatibility, and registration behavior. | [`factory-contracts.md`](accepted/factory-contracts.md) | +| Naming | Accepted | Factory Tag Naming | Defines canonical factory tag style and standard abbreviations. | [`factory-tag-naming.md`](accepted/factory-tag-naming.md) | +| Naming | Accepted | Downloadable Resource Naming | Replaces integer dataset/tutorial ids with stable descriptive slugs and moves presentation order into separate metadata. | [`resource-naming.md`](accepted/resource-naming.md) | +| Persistence | Accepted | Free-Flag CIF Encoding | Encodes fit free/fixed state through CIF uncertainty syntax instead of a separate free list. | [`free-flag-cif-encoding.md`](accepted/free-flag-cif-encoding.md) | +| Persistence | Accepted | Loop Category Keys and Identity Naming | Documents loop collection keys and naming rules aligned with CIF category keys. | [`loop-category-key-identity.md`](accepted/loop-category-key-identity.md) | +| Persistence | Accepted | Project Facade and Persistence Layout | Documents the current `Project` facade and saved directory layout. | [`project-facade-and-persistence.md`](accepted/project-facade-and-persistence.md) | +| Persistence | Accepted | IUCr CIF Tag Alignment | Aligns default CIF tags with IUCr dictionaries and adds a clean IUCr-aligned report export. | [`iucr-cif-tag-alignment.md`](accepted/iucr-cif-tag-alignment.md) | +| Persistence | Accepted | Python and CIF Category Correspondence | Compares current Python paths and CIF tags, then records scoped one-to-one mapping for project-level categories. | [`python-cif-category-correspondence.md`](accepted/python-cif-category-correspondence.md) | +| Persistence | Accepted | Edi Project Persistence | Defines STAR-based EasyDiffraction project files with UX-oriented names and strict CIF reserved for report export. | [`edstar-project-persistence.md`](accepted/edstar-project-persistence.md) | +| Quality | Accepted | Lint Complexity Thresholds | Treats ruff PLR complexity limits as design guardrails that should not be bypassed. | [`lint-complexity-thresholds.md`](accepted/lint-complexity-thresholds.md) | +| Quality | Accepted | Lint Rule Scope and Test-File Exceptions | Records the standing tests/\*\* PLR/N812 ignores and CIF-aligned `id`/`type` builtin exception from the lint audit. | [`lint-rule-exceptions.md`](accepted/lint-rule-exceptions.md) | +| Quality | Accepted | Test Strategy | Defines layered unit, functional, integration, script, and notebook testing. | [`test-strategy.md`](accepted/test-strategy.md) | +| Quality | Accepted | Test Suite and Validation Strategy | Strict test layers, cost tiers, coverage/codecov policy, cross-engine verification docs, and a nightly validation harness. | [`test-suite-and-validation.md`](accepted/test-suite-and-validation.md) | +| Quality | Suggestion | Notebook-Owned Verification Regression Gating | Replaces the external `ci_skip.txt` list with a single in-notebook `regression=False` flag (plus a cell tag for pre-flag crashes). | [`verification-regression-flag.md`](suggestions/verification-regression-flag.md) | | Quality | Accepted | Software Version Labels on Verification Pages | Shows FullProf, EasyDiffraction, and engine versions on every verification page (e.g. `edi X.Y.Z (cryspy X.Y.Z)`) via a `verify` helper. | [`verification-software-version-labels.md`](accepted/verification-software-version-labels.md) | -| Structure model | Accepted | Type-Neutral ADP Parameters | Keeps ADP parameter object identities stable across B/U and iso/ani switches. | [`type-neutral-adp-parameters.md`](accepted/type-neutral-adp-parameters.md) | -| Structure model | Accepted | Automatic Wyckoff Position Detection | Detects Wyckoff letter, multiplicity, and site symmetry from space group and coordinates; calculators consume them. | [`wyckoff-letter-detection.md`](accepted/wyckoff-letter-detection.md) | -| Structure model | Accepted | Complete Space-Group Reference Database | One-time build of a complete space_groups.json.gz (all 230 groups) from cctbx, verified against multiple sources. | [`space-group-database.md`](accepted/space-group-database.md) | -| User-facing API | Accepted | Crystal Structure 3D Visualization | Adds a renderer-neutral scene model drawn by ASCII and interactive Three.js engines for viewing crystal structures. | [`crysview-structure-visualization.md`](accepted/crysview-structure-visualization.md) | -| User-facing API | Accepted | Display UX Facade | Defines `project.display` and `project.rendering` responsibilities and display method names. | [`display-ux.md`](accepted/display-ux.md) | -| User-facing API | Accepted | Fit Results Display Naming | Short, IUCr/GUM-aligned column headers (`s.u.`, `value`, `95% CI`) with a footnote glossary on every fit table. | [`fit-results-display-naming.md`](accepted/fit-results-display-naming.md) | -| User-facing API | Accepted | Project Summary Rendering | Defines project report configuration plus terminal, HTML, TeX, PDF, and clean report-CIF metadata policy. | [`project-summary-rendering.md`](accepted/project-summary-rendering.md) | -| User-facing API | Accepted | Selector Families | Distinguishes backend selectors, switchable-category selectors, and active-sibling selectors. | [`selector-families.md`](accepted/selector-families.md) | -| User-facing API | Accepted | String Paths and Live Descriptors | Separates persisted field selectors from references to live model parameters. | [`string-paths-and-live-descriptors.md`](accepted/string-paths-and-live-descriptors.md) | -| User-facing API | Accepted | Switchable Category API | Places multi-type category selectors on the owner and omits public selectors for fixed or single-type categories. | [`switchable-category-api.md`](accepted/switchable-category-api.md) | -| User-facing API | Accepted | Switchable Category Owned Selectors | Moves the writable `type` selector and `show_supported()` onto the category itself; collapses the CIF duplication. | [`switchable-category-owned-selectors.md`](accepted/switchable-category-owned-selectors.md) | -| User-facing API | Accepted | Unified Pattern View | `pattern()` always renders available data, drops `include`, and unifies single- and three-panel figure sizing. | [`pattern-display-unification.md`](accepted/pattern-display-unification.md) | -| User-facing API | Accepted | Value-Selector Discovery | Gives enumerated value fields a per-descriptor `show_supported()`, beside the three category-level selector families. | [`value-selector-discovery.md`](accepted/value-selector-discovery.md) | +| Structure model | Accepted | Type-Neutral ADP Parameters | Keeps ADP parameter object identities stable across B/U and iso/ani switches. | [`type-neutral-adp-parameters.md`](accepted/type-neutral-adp-parameters.md) | +| Structure model | Accepted | Automatic Wyckoff Position Detection | Detects Wyckoff letter, multiplicity, and site symmetry from space group and coordinates; calculators consume them. | [`wyckoff-letter-detection.md`](accepted/wyckoff-letter-detection.md) | +| Structure model | Accepted | Complete Space-Group Reference Database | One-time build of a complete space_groups.json.gz (all 230 groups) from cctbx, verified against multiple sources. | [`space-group-database.md`](accepted/space-group-database.md) | +| User-facing API | Accepted | Crystal Structure 3D Visualization | Adds a renderer-neutral scene model drawn by ASCII and interactive Three.js engines for viewing crystal structures. | [`crysview-structure-visualization.md`](accepted/crysview-structure-visualization.md) | +| User-facing API | Accepted | Display UX Facade | Defines `project.display` and `project.rendering` responsibilities and display method names. | [`display-ux.md`](accepted/display-ux.md) | +| User-facing API | Accepted | Fit Results Display Naming | Short, IUCr/GUM-aligned column headers (`s.u.`, `value`, `95% CI`) with a footnote glossary on every fit table. | [`fit-results-display-naming.md`](accepted/fit-results-display-naming.md) | +| User-facing API | Accepted | Project Summary Rendering | Defines project report configuration plus terminal, HTML, TeX, PDF, and clean report-CIF metadata policy. | [`project-summary-rendering.md`](accepted/project-summary-rendering.md) | +| User-facing API | Accepted | Selector Families | Distinguishes backend selectors, switchable-category selectors, and active-sibling selectors. | [`selector-families.md`](accepted/selector-families.md) | +| User-facing API | Accepted | String Paths and Live Descriptors | Separates persisted field selectors from references to live model parameters. | [`string-paths-and-live-descriptors.md`](accepted/string-paths-and-live-descriptors.md) | +| User-facing API | Accepted | Switchable Category API | Places multi-type category selectors on the owner and omits public selectors for fixed or single-type categories. | [`switchable-category-api.md`](accepted/switchable-category-api.md) | +| User-facing API | Accepted | Switchable Category Owned Selectors | Moves the writable `type` selector and `show_supported()` onto the category itself; collapses the CIF duplication. | [`switchable-category-owned-selectors.md`](accepted/switchable-category-owned-selectors.md) | +| User-facing API | Accepted | Unified Pattern View | `pattern()` always renders available data, drops `include`, and unifies single- and three-panel figure sizing. | [`pattern-display-unification.md`](accepted/pattern-display-unification.md) | +| User-facing API | Accepted | Value-Selector Discovery | Gives enumerated value fields a per-descriptor `show_supported()`, beside the three category-level selector families. | [`value-selector-discovery.md`](accepted/value-selector-discovery.md) | From a110c4ea5ada12d0928df9707b7fdb250e50443a Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 16:58:40 +0200 Subject: [PATCH 16/18] Integrate known_discrepancy verification gating --- .../accepted/test-suite-and-validation.md | 10 + .../accepted/verification-regression-flag.md | 218 ++++++++++++ docs/dev/adrs/index.md | 2 +- .../in-house-calculation-engine.md | 2 +- .../verification-regression-flag.md | 262 --------------- ...nd-add-the-physical-fcj-asymmetry-model.md | 4 +- ...-on-tof-jorgensen-von-dreele-lorentzian.md | 6 +- ...ysfml-tof-jorgensen-profile-discrepancy.md | 10 +- ...in-systematic-peak-position-corrections.md | 9 +- .../dev/plans/verification-regression-flag.md | 310 ++++++++++++++++++ docs/dev/testing-guide.md | 27 +- docs/docs/conftest.py | 53 --- docs/docs/verification/ci_skip.txt | 23 -- docs/docs/verification/index.md | 53 +-- .../pd-neut-cwl_pv-beba_pbso4.ipynb | 9 +- .../verification/pd-neut-cwl_pv-beba_pbso4.py | 9 +- ...d-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb | 3 +- .../pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py | 3 +- .../pd-neut-cwl_tch-fcj-noabs_lab6.ipynb | 3 +- .../pd-neut-cwl_tch-fcj-noabs_lab6.py | 3 +- .../pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb | 28 +- .../pd-neut-cwl_tch-fcj-nosldl_lab6.py | 28 +- .../pd-neut-cwl_tch-fcj_lab6.ipynb | 6 +- .../verification/pd-neut-cwl_tch-fcj_lab6.py | 6 +- docs/docs/verification/pd-neut-tof_j_si.ipynb | 6 +- docs/docs/verification/pd-neut-tof_j_si.py | 6 +- .../verification/pd-neut-tof_jvd_ncaf.ipynb | 27 +- .../docs/verification/pd-neut-tof_jvd_ncaf.py | 27 +- .../verification/pd-neut-tof_jvd_si.ipynb | 3 +- docs/docs/verification/pd-neut-tof_jvd_si.py | 3 +- .../sc-neut-cwl_ext-iso_tbti.ipynb | 3 +- .../verification/sc-neut-cwl_ext-iso_tbti.py | 3 +- .../verification/sc-neut-cwl_noext_tbti.ipynb | 9 +- .../verification/sc-neut-cwl_noext_tbti.py | 9 +- .../verification/sc-neut-cwl_pr2nio4.ipynb | 9 +- docs/docs/verification/sc-neut-cwl_pr2nio4.py | 9 +- pixi.toml | 3 +- src/easydiffraction/analysis/analysis.py | 2 +- src/easydiffraction/analysis/verification.py | 59 +++- .../analysis/test_verification.py | 60 +++- tests/unit/tools/test_script_runner_skip.py | 97 ++++++ tools/test_scripts.py | 86 ++++- 42 files changed, 998 insertions(+), 510 deletions(-) create mode 100644 docs/dev/adrs/accepted/verification-regression-flag.md delete mode 100644 docs/dev/adrs/suggestions/verification-regression-flag.md create mode 100644 docs/dev/plans/verification-regression-flag.md delete mode 100644 docs/docs/conftest.py delete mode 100644 docs/docs/verification/ci_skip.txt create mode 100644 tests/unit/tools/test_script_runner_skip.py diff --git a/docs/dev/adrs/accepted/test-suite-and-validation.md b/docs/dev/adrs/accepted/test-suite-and-validation.md index 6d0744057..f35965e96 100644 --- a/docs/dev/adrs/accepted/test-suite-and-validation.md +++ b/docs/dev/adrs/accepted/test-suite-and-validation.md @@ -241,6 +241,16 @@ source → notebook via `pixi run notebook-prepare`, built with compare them pairwise (`ed-cryspy`, `ed-crysfml`, … and later `fullprof`). This is far faster than fitting, so the same pages double as **fast regression scripts** under `script-tests`. +- **Known-discrepancy gating (in-source, no external list).** A page + whose engine cannot yet reproduce a modelled effect marks the + difference **in the notebook itself** by calling the agreement check + with `known_discrepancy=True` and a `reason` (rendered on the page). + This is a two-sided assertion: the page passes while it stays + discrepant and **hard-fails** if it later starts agreeing, forcing a + manual re-gate. `script-tests` statically detects the flag (or a + `raises-exception` cell tag for pages that error before the check) and + **skips** those pages, while `nbmake` still executes and renders every + page. There is no external skip list. - **Metrics.** Report clear, documented closeness metrics per pair — a profile-difference metric (Rwp-style), maximum point-wise deviation, and an integrated-intensity ratio — with explicit tolerances. diff --git a/docs/dev/adrs/accepted/verification-regression-flag.md b/docs/dev/adrs/accepted/verification-regression-flag.md new file mode 100644 index 000000000..0fc9c9ed1 --- /dev/null +++ b/docs/dev/adrs/accepted/verification-regression-flag.md @@ -0,0 +1,218 @@ +# ADR: Notebook-Owned Verification Regression Gating + +## Status + +Accepted. + +## Date + +2026-06-17 + +## Group + +Quality. + +## Context + +The cross-engine **Verification** pages (established by +[`test-suite-and-validation`](test-suite-and-validation.md) §6, and +built as `.py` sources per +[`notebook-generation`](notebook-generation.md)) serve two roles at +once: each page is a **regression test** (its calculated pattern is +checked against a frozen FullProf reference) and a **published HTML +doc** (it renders a comparison and an agreement table for scientists). + +Historically that dual role was controlled by two separate mechanisms: + +1. **`verify.assert_patterns_agree(..., raise_on_failure=...)`** — the + per-page agreement check. With the default `raise_on_failure=True` it + raised `AssertionError` when any metric was out of tolerance. With + `raise_on_failure=False` it rendered the table but did not raise. +2. **`docs/docs/verification/ci_skip.txt`** — an external list of + notebook stems consumed by `notebook-tests`/nbmake and + `script-tests`. + +That split was confusing. Deciding "this page is known-bad, do not gate +regression on it, but still publish it" required editing a flag inside +the notebook and adding the stem (with a reason) to a separate file. The +reason a page was exempt was invisible on the rendered page. + +The project owner wants a **single source of truth, set at the end of +the notebook**, with this intent: + +> If a verification page is good, it is a regression test and a doc +> page. If I know its regression is bad because a feature is not +> implemented yet, I mark that page as a known discrepancy but still +> keep it as an HTML doc. + +This ADR makes the notebook source own that decision and removes the +external skip list. + +## Decision + +### 1. One in-notebook flag is the single source of truth + +The agreement check gains an intention-revealing parameter that replaces +`raise_on_failure`: + +```python +verify.assert_patterns_agree( + [('cryspy vs FullProf', reference, candidate)], + known_discrepancy=True, + reason='FCJ S_L/D_L not implemented in cryspy yet (issue 166)', +) +``` + +- `known_discrepancy=False` (**default**) asserts the patterns **agree** + within tolerance. Out-of-tolerance metrics raise `AssertionError`. The + page is a regression test and a doc page. +- `known_discrepancy=True` asserts the patterns **still disagree** (the + documented known-bad state). Out-of-tolerance metrics render and pass. + If the page unexpectedly agrees within tolerance, the check raises a + re-gate `AssertionError`. + +`reason` is required when `known_discrepancy=True`, so every exemption +is explained on the published page. + +`raise_on_failure` is replaced by `known_discrepancy` (default `False`). +Beta, no shims: existing pages are migrated, not aliased. + +### 1a. A re-gated discrepancy fails CI + +`known_discrepancy=True` is a **two-sided** assertion. It does not +merely silence a failure; it asserts the discrepancy is **still there**. +The moment a known-bad page starts matching within tolerance, the page +**hard-fails** with a re-gate message. A developer clears it by deleting +`known_discrepancy` / `reason` (re-gating the page) or, if the match is +spurious, by tightening the tolerance. + +### 1b. Return value means "expectation met" + +`assert_patterns_agree` returns `True` when the assertion holds: +patterns agree for a default page, or patterns still disagree for a +`known_discrepancy=True` page. Otherwise it raises `AssertionError`. + +The return value is no longer the raw agreement boolean. Callers that +need raw metrics continue to use `verify.pattern_closeness(...)`. + +### 2. Delete `ci_skip.txt` and derive runner behavior from source + +A page that runs to completion is handled entirely from its in-notebook +flag: + +- `notebook-tests`/nbmake executes every page. A + `known_discrepancy=True` page renders and runs its two-sided + assertion: still-discrepant pages pass; pages that start agreeing + hard-fail and force manual re-gating. +- `script-tests` statically detects `known_discrepancy=True` in the page + source and skips that page, so the fast runner does not spend time on + known-bad refinement fits that it cannot use as regression gates. + +No external list is needed. `docs/docs/verification/ci_skip.txt` and the +nbmake `xfail` hook are removed. The script-test runner skips pages only +from an in-source `known_discrepancy=True` literal or an in-source +`raises-exception` cell tag (Decision 3). + +### 3. Pages that error before the flag use a cell tag + +An end-of-notebook flag can only govern a notebook that reaches the end. +A page that raises mid-execution (for example because it needs an +unreleased calculator API) never reaches `assert_patterns_agree`. + +Those temporary pages tag the failing cell `raises-exception` in the +Jupytext source (`# %% tags=["raises-exception"]`) and include a short +markdown note explaining why. nbmake executes the notebook and allows +only the tagged cell to raise; `script-tests` statically detects the tag +and skips the page because subprocess execution cannot enforce +cell-level precision. + +### 4. `reason` is on-page provenance + +The old `ci_skip.txt` comments move into `reason=` (or the +`raises-exception` companion note), so the explanation is visible in the +published page and travels with the code that sets it. + +### 5. No fit section on pages that already agree + +A verification page includes a refinement (`fit`) section only when the +raw calculation does **not** match the reference within tolerance and a +fit is needed to reach agreement, or when a `known_discrepancy=True` +page needs to show how the engine can match with its own parameters. A +page whose calculated pattern already agrees within tolerance just +calculates and asserts. + +## Consequences + +### Positive + +- **One place, in the notebook.** Whether a page gates regression is + decided where the page is authored, next to the data it checks. +- **Provenance is public.** The exemption reason renders on the page + instead of hiding in a list file. +- **Approved pages are unchanged and still regression-checked** in both + runners. +- **Fixed pages cannot stay silently exempt.** A known-bad page that + starts agreeing hard-fails in nbmake, forcing manual re-gating. +- **The fast runner stays fast.** `script-tests` skips known-bad and + crash pages from in-source declarations, while nbmake still executes + and renders every page. + +### Trade-offs + +- Known-bad pages are exercised by nbmake rather than `script-tests`, so + setup errors unique to those pages surface in the slower pass. +- The `raises-exception` boundary must be applied per failing cell. +- Static detection of `known_discrepancy=True` and `raises-exception` + must inspect the actual call/marker, not a loose substring. + +## Compatibility + +- Beta, no shims. Every verification page that used + `raise_on_failure=False` is migrated with an explicit per-page + decision: either re-gate by removing the flag, or keep + `known_discrepancy=True, reason=...`. +- `notebook-generation` is unaffected: sources remain `.py` files; any + `raises-exception` tag is expressed in the `.py` and regenerated into + the notebook via `notebook-prepare`. +- Revises [`test-suite-and-validation`](test-suite-and-validation.md) §6 + and removes the old `ci_skip.txt`/conftest wiring described by the + documentation test workflow. + +## Alternatives Considered + +### Keep both mechanisms + +Rejected. Two places to edit and the reason stays invisible on the page. + +### Keep an external list as the source of truth + +Rejected. The decision then lives outside the notebook, opposite to the +desired authoring model. + +### Notebook-level metadata + +Rejected as the primary mechanism. It is not near the agreement check, +is not visible in the rendered page, and still needs a separate rendered +reason. The narrower per-cell `raises-exception` tag is retained only +for pre-flag crashes. + +### A separate render-only function + +Rejected. Two functions double the surface and still need a way to make +fixed known-bad pages fail CI. + +## Resolved Questions + +- **Naming:** `known_discrepancy=True` was chosen because it is longer + but self-descriptive at the call site. +- **Fast-runner speed:** `script-tests` skips known-discrepancy pages by + statically reading the in-source flag; nbmake still executes them. +- **Re-enable signal:** a known-discrepancy page that starts agreeing + hard-fails CI instead of warning. + +## Deferred Work + +- Any future speed optimization must stay derived from the in-source + flag/tag, not reintroduce an external semantic list. +- Software and engine version provenance is covered by + [`verification-software-version-labels`](verification-software-version-labels.md). diff --git a/docs/dev/adrs/index.md b/docs/dev/adrs/index.md index 1eebee081..8bd8a098a 100644 --- a/docs/dev/adrs/index.md +++ b/docs/dev/adrs/index.md @@ -55,7 +55,7 @@ folders. | Quality | Accepted | Lint Rule Scope and Test-File Exceptions | Records the standing tests/\*\* PLR/N812 ignores and CIF-aligned `id`/`type` builtin exception from the lint audit. | [`lint-rule-exceptions.md`](accepted/lint-rule-exceptions.md) | | Quality | Accepted | Test Strategy | Defines layered unit, functional, integration, script, and notebook testing. | [`test-strategy.md`](accepted/test-strategy.md) | | Quality | Accepted | Test Suite and Validation Strategy | Strict test layers, cost tiers, coverage/codecov policy, cross-engine verification docs, and a nightly validation harness. | [`test-suite-and-validation.md`](accepted/test-suite-and-validation.md) | -| Quality | Suggestion | Notebook-Owned Verification Regression Gating | Replaces the external `ci_skip.txt` list with a single in-notebook `regression=False` flag (plus a cell tag for pre-flag crashes). | [`verification-regression-flag.md`](suggestions/verification-regression-flag.md) | +| Quality | Accepted | Notebook-Owned Verification Regression Gating | Replaces the external `ci_skip.txt` list with a single in-notebook `known_discrepancy` flag (plus a cell tag for pre-flag crashes). | [`verification-regression-flag.md`](accepted/verification-regression-flag.md) | | Quality | Accepted | Software Version Labels on Verification Pages | Shows FullProf, EasyDiffraction, and engine versions on every verification page (e.g. `edi X.Y.Z (cryspy X.Y.Z)`) via a `verify` helper. | [`verification-software-version-labels.md`](accepted/verification-software-version-labels.md) | | Structure model | Accepted | Type-Neutral ADP Parameters | Keeps ADP parameter object identities stable across B/U and iso/ani switches. | [`type-neutral-adp-parameters.md`](accepted/type-neutral-adp-parameters.md) | | Structure model | Accepted | Automatic Wyckoff Position Detection | Detects Wyckoff letter, multiplicity, and site symmetry from space group and coordinates; calculators consume them. | [`wyckoff-letter-detection.md`](accepted/wyckoff-letter-detection.md) | diff --git a/docs/dev/adrs/suggestions/in-house-calculation-engine.md b/docs/dev/adrs/suggestions/in-house-calculation-engine.md index e12589f58..831cba228 100644 --- a/docs/dev/adrs/suggestions/in-house-calculation-engine.md +++ b/docs/dev/adrs/suggestions/in-house-calculation-engine.md @@ -37,7 +37,7 @@ keeps paying: transparency (FullProf `SyCos`/`SySin`) corrections are wired on the EasyDiffraction side but cannot be verified or shipped because they depend on the unreleased `cryspy` PR #46 (open issue 131; the - verification page is in `ci_skip.txt`). + verification page is gated as known-bad in-notebook). 2. **Corrections with no clean home.** Sample absorption (Debye–Scherrer `μR`, open issue 119) is a small, well-specified, angle-dependent intensity factor. Investigation shows **both** `cryspy` and `crysfml` diff --git a/docs/dev/adrs/suggestions/verification-regression-flag.md b/docs/dev/adrs/suggestions/verification-regression-flag.md deleted file mode 100644 index b20ea1ab8..000000000 --- a/docs/dev/adrs/suggestions/verification-regression-flag.md +++ /dev/null @@ -1,262 +0,0 @@ -# ADR: Notebook-Owned Verification Regression Gating - -## Status - -Proposed. - -## Date - -2026-06-17 - -## Group - -Quality. - -## Context - -The cross-engine **Verification** pages (established by -[`test-suite-and-validation`](accepted/test-suite-and-validation.md) §6, -and built as `.py` sources per -[`notebook-generation`](accepted/notebook-generation.md)) serve two -roles at once: each page is a **regression test** (its calculated -pattern is checked against a frozen FullProf reference) and a -**published HTML doc** (it renders a comparison and an agreement table -for scientists). - -Today that dual role is controlled by **two separate mechanisms**, and a -single page can need both: - -1. **`verify.assert_patterns_agree(..., raise_on_failure=…)`** — the - per-page agreement check. With the default `raise_on_failure=True` it - raises `AssertionError` when any metric is out of tolerance, which is - what makes the page a regression test. With `raise_on_failure=False` - it renders the table but does not raise. -2. **`docs/docs/verification/ci_skip.txt`** — an external list of - notebook stems, consumed by two runners: - - `docs/docs/conftest.py` marks listed notebooks **`xfail` - (`strict=False`)** for `notebook-tests`/nbmake — they still execute - and render, but a failure is tolerated; - - `tools/test_scripts.py` **`pytest.skip`s** them in `script-tests` - (the fast runner that executes each page's `.py` as a subprocess - and fails if it raises). - -This split is confusing: deciding "this page is known-bad, do not gate -regression on it, but still publish it" requires editing a flag inside -the notebook **and** adding the stem (with a `# reason`) to a separate -file. The reason a page is exempt lives in `ci_skip.txt`, invisible to -readers of the published page. The PbSO₄ Bérar–Baldinozzi page -(issue 166) is the current live example: it carries both -`raise_on_failure=False` **and** a `ci_skip.txt` entry. - -The project owner wants a **single source of truth, set at the end of -the notebook**, with this intent: - -> If a verification page is good, it is a regression test and a doc -> page. If I know its regression is bad because a feature is not -> implemented yet, I mark that page as "not regression-gated" but still -> keep it as an HTML doc. - -This ADR makes the notebook itself own that decision and removes -`ci_skip.txt`, within one boundary that is intrinsic to "decide from -inside the notebook". - -## Decision - -### 1. One in-notebook flag is the single source of truth - -The agreement check gains an intention-revealing, **self-documenting** -parameter that subsumes `raise_on_failure`: - -```python -verify.assert_patterns_agree( - [('cryspy vs FullProf', reference, candidate)], - regression=False, # known-bad: render, don't gate - reason='FCJ S_L/D_L not implemented in cryspy yet (issue 166)', -) -``` - -- `regression=True` (**default**) → assert on out-of-tolerance; the page - is a **regression test and a doc page**. -- `regression=False` → render the comparison table, **do not raise**, - and surface `reason` in the rendered output. `reason` is **required** - when `regression=False` so every exemption is explained on the page - itself. - -`raise_on_failure` is renamed to `regression` (its inverse). Beta, no -shims: existing pages are migrated, not aliased (see Compatibility). - -### 2. Delete `ci_skip.txt` and its two consumers - -For every page that **runs to completion** (the normal case — an -unimplemented feature means the engine ignores the unsupported parameter -and produces a different curve, it does not crash), the in-notebook flag -fully determines behaviour: - -- `notebook-tests`/nbmake: the page executes, the `regression=False` - check does not raise, the notebook **passes and renders** to HTML. -- `script-tests`: the `.py` subprocess completes without raising, so the - page **passes**. - -No external list is needed. `docs/docs/verification/ci_skip.txt`, the -`xfail` logic in `docs/docs/conftest.py`, and the `pytest.skip` block in -`tools/test_scripts.py` are **removed**. - -### 3. Boundary: pages that error _before_ the flag use a cell tag - -An end-of-notebook flag can only govern a notebook that **reaches the -end**. A page that raises mid-execution — e.g. one needing an -**unreleased** calculator API that errors rather than no-ops — never -reaches `assert_patterns_agree`, and `script-tests` fails on a raising -subprocess regardless of any flag. - -For those (temporary, "waiting on a dependency release") cases the -**failing cell is tagged `raises-exception`** in the source `.py` -(jupytext cell metadata, honoured by nbmake and reproduced into the -generated notebook). This keeps control **inside the notebook** — still -one place, still no external list — and is paired with a short markdown -note stating why. A page in this state is, by definition, not currently -runnable as a regression test; tagging documents that explicitly. - -### 4. `reason` replaces the `ci_skip.txt` comment as on-page provenance - -The `# reason` strings currently buried in `ci_skip.txt` move into the -`reason=` argument (and the `raises-exception` companion note), so the -explanation is **visible in the published page** and travels with the -code that sets it. - -## Consequences - -### Positive - -- **One place, in the notebook.** Whether a page gates regression is - decided where the page is authored, at the end, next to the data it - checks — matching the owner's mental model. -- **Provenance is public.** The exemption reason renders on the page - instead of hiding in a list file. -- **Approved pages are unchanged and still regression-checked** in both - runners (default `regression=True`); the dual "test + doc" role is - preserved. -- **All pages are still generated and rendered to HTML**, exactly as - today (this never depended on `ci_skip.txt`). -- Three coupled artifacts (`ci_skip.txt`, the conftest filter, the - script-test skip) collapse into one library parameter. - -### Trade-offs - -- **Known-bad pages now run in `script-tests`** instead of being - skipped, so the fast runner does the refinement fit for those pages - too and gets somewhat slower. Acceptable for the current page count; - if it ever matters, speed is a _separate_ concern from regression - intent and must not reintroduce a second semantic list (see Open - Questions). -- **Loss of the `xfail`/`xpass` signal.** Today a known-bad page is an - `xfail`; if it unexpectedly starts agreeing it shows as `xpass`. Under - this ADR a `regression=False` page simply passes, so "this known-bad - page now actually matches — time to re-enable the gate" is no longer - surfaced automatically. Mitigation in Open Questions (optional - `xpass`-style warning when a `regression=False` page is within - tolerance). -- The `raises-exception` boundary (Decision 3) is less automatic than a - list entry and must be applied per failing cell. - -### Compatibility - -- Beta, no shims. Every verification `.py` is migrated: - `raise_on_failure=False` → `regression=False, reason=…`; the implicit - default stays "regression-gated". `ci_skip.txt` entries become - `regression=False` flags (runnable pages) or `raises-exception` tags - (pre-flag crashes). -- `notebook-generation` is unaffected: sources remain the `.py` files; - the `raises-exception` tag is expressed in the `.py` and regenerated - into the notebook via `notebook-prepare`. -- Revises - [`test-suite-and-validation`](accepted/test-suite-and-validation.md) - §6 (the `script-tests` "skip via `ci_skip.txt`" detail) and the - `ci_skip.txt`/conftest wiring under - [`documentation-ci-build`](accepted/documentation-ci-build.md). Those - ADRs are updated when this is implemented. - -## Alternatives Considered - -### Keep both mechanisms (status quo) - -Two places to edit, reason invisible on the page. Rejected per the -owner's explicit request for a single in-notebook control. - -### Make `regression=False` (or `ci_skip`) auto-derived, keep the list - -Drive `xfail`/skip from the list only and drop the per-page flag. -Rejected: the decision then lives outside the notebook, the opposite of -what is wanted, and the reason stays hidden. - -### Notebook-level metadata instead of an end-of-notebook call - -Encode "not regression-gated" in notebook-level metadata read at pytest -**collection** time (so even a crashing page could be `xfail`ed without -a separate file). Rejected as the primary mechanism: it is not "at the -end of the notebook like `raise_on_failure`", it is invisible in the -rendered page, and it splits the control surface between a metadata key -and the agreement call. The narrower per-cell `raises-exception` tag -(Decision 3) is preferred for the rare crash case. - -### A `verify.show_patterns(...)` function distinct from - -`assert_patterns_agree(...)` - -Two functions — one that asserts, one that only renders — instead of one -function with a flag. Rejected: it still needs the `raises-exception` -boundary for crashes, doubles the surface, and a boolean on the existing -call is closer to the requested "like `raise_on_failure=False`" shape. - -## Open Questions - -- **Naming.** `regression=False` vs keeping `raise_on_failure` vs - `gate_regression=`/`expected=`. Proposed: `regression` with a required - `reason`. -- **Fast-runner speed.** Should `script-tests` still avoid the - refinement fit for `regression=False` pages? Any "skip for speed" must - be derivable from the in-notebook flag (e.g. the runner statically - detects `regression=False` in the `.py`) so it does **not** become a - second semantic list. Needs the page audit below. -- **Re-enable signal.** Should a `regression=False` page that is - actually within tolerance emit a visible warning (an `xpass` analogue) - so a fixed page gets re-gated? Proposed: yes, a non-failing warning. -- **Audit dependency.** How many current `ci_skip.txt` pages merely - disagree (Decision 2) versus crash before the flag (Decision 3)? The - implementation plan must classify each of the eight pages first. - -## Deferred Work - -- The page-by-page audit (disagree-cleanly vs crash) and the migration - of all verification `.py` files belong to the implementation plan, not - this ADR. -- Any static "skip slow `regression=False` pages in `script-tests`" - optimisation is deferred until the audit shows it is needed. - -### Adjacent ADR needed — show software/engine versions on verification pages - -Separate from regression gating, the verification pages should record -the **provenance** of every comparison: which versions of -EasyDiffraction, the calculator engine, and FullProf produced the -curves. This is only partly done today — some pages label the reference -via -`FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE)` -(the FullProf version parsed from the `.sum`), but **not all pages do**, -and the candidate is still a bare `edi-cryspy` / `edi-crysfml` with no -version. - -The intended labelling is, for example: - -- reference → `FullProf vX.YZ` (already via `fullprof_label`, applied - consistently); -- candidate → `edi vX.Y.Z (cryspy vX.Y.Z)`, and likewise - `edi vX.Y.Z (crysfml vX.Y.Z)`, instead of the current `edi-cryspy` / - `edi-crysfml`. - -This needs its **own ADR** (or an extension of the -verification-framework decision in -[`test-suite-and-validation`](accepted/test-suite-and-validation.md) -§6): a `verify` helper that builds the candidate label from the -EasyDiffraction package version and the **active calculator engine's** -version, applied on every page next to `fullprof_label`. Recorded here -only as a pointer; it is out of scope for this regression-gating ADR. diff --git a/docs/dev/issues/open/high_rename-asym-empir-and-add-the-physical-fcj-asymmetry-model.md b/docs/dev/issues/open/high_rename-asym-empir-and-add-the-physical-fcj-asymmetry-model.md index 988612bba..375b4a818 100644 --- a/docs/dev/issues/open/high_rename-asym-empir-and-add-the-physical-fcj-asymmetry-model.md +++ b/docs/dev/issues/open/high_rename-asym-empir-and-add-the-physical-fcj-asymmetry-model.md @@ -42,8 +42,8 @@ instrument-meaningful. known and fall back to the empirical correction otherwise. **Relates to:** the asymmetry discrepancy tracked in issue 166 and on -the `pd-neut-cwl_pv-beba_pbso4` Verification page (currently in -`docs/docs/verification/ci_skip.txt`), and the TCH/FCJ work noted on the +the `pd-neut-cwl_pv-beba_pbso4` Verification page (currently marked +`known_discrepancy=True`), and the TCH/FCJ work noted on the `pd-neut-cwl_tch-fcj_lab6` page. **Depends on:** calculator-backend support for the FCJ asymmetry diff --git a/docs/dev/issues/open/highest_cryspy-diverges-on-tof-jorgensen-von-dreele-lorentzian.md b/docs/dev/issues/open/highest_cryspy-diverges-on-tof-jorgensen-von-dreele-lorentzian.md index 6b53095af..f194d1cd8 100644 --- a/docs/dev/issues/open/highest_cryspy-diverges-on-tof-jorgensen-von-dreele-lorentzian.md +++ b/docs/dev/issues/open/highest_cryspy-diverges-on-tof-jorgensen-von-dreele-lorentzian.md @@ -19,10 +19,8 @@ crysfml/FullProf. **Visible on:** the Si TOF Verification page (`pd-neut-tof_jvd_si`), whose closeness table flags the `cryspy` rows in red — reported via a -non-raising agreement check, not enforced, so CI stays green. -Re-introduce a strict check, or skip the page via -`docs/docs/verification/ci_skip.txt`, once work on the cryspy backend -begins. +`known_discrepancy=True` agreement check, so CI fails once the page +starts agreeing and must be re-gated manually. **Depends on:** nothing. diff --git a/docs/dev/issues/open/highest_investigate-ed-crysfml-tof-jorgensen-profile-discrepancy.md b/docs/dev/issues/open/highest_investigate-ed-crysfml-tof-jorgensen-profile-discrepancy.md index 460762fde..5d18ce57a 100644 --- a/docs/dev/issues/open/highest_investigate-ed-crysfml-tof-jorgensen-profile-discrepancy.md +++ b/docs/dev/issues/open/highest_investigate-ed-crysfml-tof-jorgensen-profile-discrepancy.md @@ -14,12 +14,12 @@ complementary to the `cryspy` Jorgensen–Von Dreele Lorentzian divergence tracked in issue 130. **Visible on:** the Si TOF Jorgensen Verification page -(`pd-neut-tof_j_si`), currently skipped via -`docs/docs/verification/ci_skip.txt`. Re-enable the page (or tighten its -agreement check) once the crysfml profile is reconciled. +(`pd-neut-tof_j_si`), currently marked with `known_discrepancy=True`. +Re-gate the page (or tighten its agreement check) once the crysfml +profile is reconciled. **Depends on:** nothing. **Recommended-priority note:** crysfml TOF Jorgensen is ~8.5% off and -has a CI-skipped verification page (paired with #130). **Tier 1 (do -first).** +has a known-discrepancy verification page (paired with #130). **Tier 1 +(do first).** diff --git a/docs/dev/issues/open/medium_add-sycos-sysin-systematic-peak-position-corrections.md b/docs/dev/issues/open/medium_add-sycos-sysin-systematic-peak-position-corrections.md index 63715b615..8b9a855e2 100644 --- a/docs/dev/issues/open/medium_add-sycos-sysin-systematic-peak-position-corrections.md +++ b/docs/dev/issues/open/medium_add-sycos-sysin-systematic-peak-position-corrections.md @@ -16,11 +16,12 @@ calculator wiring — is still to do. A prepared verification page, `docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py`, uses the issue #38 -LaB6 dataset and is skipped via `ci_skip.txt`. Finishing it also needs a -custom ¹¹B scattering length, the Thompson–Cox–Hastings profile, and a -FullProf-style polynomial background, which that dataset relies on. +LaB6 dataset and is marked `known_discrepancy=True`. Finishing it also +needs a custom ¹¹B scattering length, the Thompson–Cox–Hastings profile, +and a FullProf-style polynomial background, which that dataset relies +on. **Fix:** add `SyCos`/`SySin` to the CWL instrument category, pass them -to the calculators, then un-skip the LaB6 page. +to the calculators, then re-gate the LaB6 page. **Depends on:** nothing. diff --git a/docs/dev/plans/verification-regression-flag.md b/docs/dev/plans/verification-regression-flag.md new file mode 100644 index 000000000..ee697163f --- /dev/null +++ b/docs/dev/plans/verification-regression-flag.md @@ -0,0 +1,310 @@ +# Plan: Notebook-Owned Verification Regression Gating (`known_discrepancy`) + +Follows [`AGENTS.md`](../../../AGENTS.md). Two explicitly-scoped +exceptions to the usual two-phase rules: + +1. A small, unrelated **Windows CI fix** is bundled at the owner's + request (P1.7). +2. **P1.3 runs each verification page once to classify it** + (disagree-cleanly / crash / re-gate) — a deliberate, **read-only** + Phase-1 audit needed to decide each page's migration. It is not test + authoring and runs no test suite; the exact command is in P1.3. All + real test work stays in Phase 2. + +## ADR + +Implements +[`verification-regression-flag`](../adrs/accepted/verification-regression-flag.md) +(Accepted). Per §Change Discipline it is **promoted to `accepted/`** as +part of this PR (P1.6). The sibling +[`verification-software-version-labels`](../adrs/suggestions/verification-software-version-labels.md) +ADR is **not** implemented here — separate work. + +Revises two accepted ADRs (P1.5): +[`test-suite-and-validation`](../adrs/accepted/test-suite-and-validation.md) +§6 (the `script-tests` "skip via `ci_skip.txt`" detail) and +[`documentation-ci-build`](../adrs/accepted/documentation-ci-build.md) +(the `ci_skip.txt`/conftest wiring). + +## Branch + PR + +- Branch: `verification-regression-flag` (flat slug off `develop`, + **already created and checked out**; carries one prior housekeeping + commit, `Remove completed dataset-driven-fit-modes plan`). +- PR targets `develop`, not `master`. Do not push unless asked. + +## Decisions (from the ADR) + +- **Flag.** `assert_patterns_agree` gains + `known_discrepancy: bool = False` (replacing `raise_on_failure`) and a + `reason: str | None = None` (**required** when + `known_discrepancy=True`). +- **Two-sided assertion (Decision 1a).** `known_discrepancy=True` + asserts the patterns **still disagree**: out of tolerance → render, do + not raise; **within** tolerance → **raise** a re-gate + `AssertionError`. +- **Return contract (Decision 1b).** Returns `True` when the page met + its expectation (agree for default; still-disagree for known-bad) or + **raises**. No longer the raw agreement boolean; raw metrics stay on + `verify.pattern_closeness`. +- **One source of truth, two runners (Decision 2).** Delete + `ci_skip.txt`; `script-tests` statically detects + `known_discrepancy=True` **or** a `raises-exception` tag in the `.py` + and **skips** those pages; `conftest.py`'s xfail logic is removed; + **nbmake runs every page** (render + the re-gate hard-fail). +- **Crash boundary (Decision 3).** Pre-flag-crash pages tag the failing + cell `raises-exception` (+ a markdown note); `script-tests` skips them + via the same scan. +- **On-page provenance (Decision 4).** `reason` renders on the page, + replacing the `ci_skip.txt` comment. +- **Fit hygiene (Decision 5).** A page already agreeing within tolerance + carries no fit section. +- **Audit (ADR Open Questions).** Every page using the old + `raise_on_failure=False` is migrated with an explicit per-page + decision; this is a larger set than `ci_skip.txt` (P1.3). + +## Decisions already made for this plan + +- The audit covers **11 pages** — the 10 `.py` files using + `raise_on_failure=False` plus `pd-neut-cwl_tch-fcj-nosldl_lab6` (in + `ci_skip.txt` but not using the flag, so likely a crash page): + - **In `ci_skip.txt` + `raise_on_failure=False`** (7): `beba_pbso4`, + `tch-fcj-noabs-nosldl_lab6`, `tch-fcj-noabs_lab6`, `tch-fcj_lab6`, + `tof_j_si`, `tof_jvd_si`, `sc-neut-cwl_ext-iso_tbti`. + - **`ci_skip.txt` only** (1): `tch-fcj-nosldl_lab6` (no flag → audit + as crash vs gated). + - **`raise_on_failure=False` only, not skip-listed** (3): + `pd-neut-tof_jvd_ncaf`, `sc-neut-cwl_noext_tbti`, + `sc-neut-cwl_pr2nio4` — these currently pass both runners ungated, + so the audit decides re-gate (`known_discrepancy=False`) vs keep + `known_discrepancy=True, reason=…`. +- **Migration is mechanical except the per-page verdict**, which + requires running each page once (disagree-cleanly vs crash; re-gate vs + keep). +- The non-asserting `verify.patterns_agree(...) -> bool` wrapper is + added **only if** a page or test needs a plain boolean (decide during + P1.1). + +## Open questions + +1. Per-page audit verdicts (P1.3) — **resolved**, recorded below. Each + page was run once with + `pixi run python docs/docs/verification/.py` against installed + cryspy 0.11.0 (the unpinned version CI also resolves), classifying by + exit code and the rendered agreement table: + + | Page | Result | Migration | + | --------------------------------------- | ------------------------------ | --------------------------------- | + | `pd-neut-cwl_pv-beba_pbso4` | agrees (fit recovers FullProf) | **re-gate** (drop flag) | + | `pd-neut-tof_jvd_ncaf` | agrees | **re-gate** (was not skip-listed) | + | `sc-neut-cwl_noext_tbti` | agrees | **re-gate** (was not skip-listed) | + | `sc-neut-cwl_pr2nio4` | agrees | **re-gate** (was not skip-listed) | + | `pd-neut-cwl_tch-fcj-noabs-nosldl_lab6` | disagrees, runs | `known_discrepancy=True` | + | `pd-neut-cwl_tch-fcj-noabs_lab6` | disagrees, runs | `known_discrepancy=True` | + | `pd-neut-cwl_tch-fcj_lab6` | disagrees, runs | `known_discrepancy=True` | + | `pd-neut-cwl_tch-fcj-nosldl_lab6` | disagrees, runs (note updated) | `known_discrepancy=True` | + | `pd-neut-tof_j_si` | crysfml disagrees | `known_discrepancy=True` | + | `pd-neut-tof_jvd_si` | cryspy disagrees | `known_discrepancy=True` | + | `sc-neut-cwl_ext-iso_tbti` | disagrees | `known_discrepancy=True` | + + No page crashed before its agreement check, so **no + `raises-exception` cell tags were needed**. The three not-skip-listed + pages (`jvd_ncaf`, `sc-noext`, `sc-pr2nio4`) all agree, so all are + re-gated. `pv-beba_pbso4` was previously skip-listed but now agrees + after its own-asymmetry fit, so it is re-gated too. + `tch-fcj-nosldl_lab6` previously asserted agreement + (`raise_on_failure=True`) but disagrees on released cryspy 0.11.0 + (its develop-cryspy demo agrees), so its note was updated and it is + marked `known_discrepancy=True`. + +2. `conftest.py`: **resolved at P1.2** — the file hosted only the + ci_skip xfail logic, so it was deleted entirely. + +## Concrete files likely to change + +- `src/easydiffraction/analysis/verification.py` — + `assert_patterns_agree` (flag, reason, two-sided assertion, return + contract). +- `tests/unit/easydiffraction/analysis/test_verification.py` — all + changes happen in **Phase 2**: migrate existing + `raise_on_failure`/return-contract cases and add the new + `known_discrepancy` cases. Phase 1 does not touch this file. +- `tools/test_scripts.py` — replace the `ci_skip.txt` skip with the + in-source static scan. +- `docs/docs/conftest.py` — remove the ci_skip xfail logic. +- `docs/docs/verification/ci_skip.txt` — **deleted**. +- The 11 audited `docs/docs/verification/*.py` pages (+ regenerated + `.ipynb` via `pixi run notebook-prepare`); also any other page + carrying a now-removable fit section (Decision 5). +- `docs/docs/verification/index.md` — wording that referenced CI-skip. +- `docs/dev/testing-guide.md` (~line 82) and the `verification-exec` + task comment in `pixi.toml` (~line 233) — `ci_skip` references that go + stale once the file is deleted; plus anything else the `git grep` + surfaces. +- `docs/dev/adrs/suggestions/verification-regression-flag.md` → `git mv` + to `accepted/`; `docs/dev/adrs/index.md` row flipped to Accepted; + links fixed. +- `docs/dev/adrs/accepted/test-suite-and-validation.md`, + `docs/dev/adrs/accepted/documentation-ci-build.md` — revise the + `ci_skip.txt` wiring text. +- `src/easydiffraction/analysis/analysis.py` line ~2819 — **Windows + fix** (see P1.7). + +Find every occurrence first with +`git grep -n "raise_on_failure\|ci_skip"`. + +## Implementation steps (Phase 1) + +Each `- [ ]` is one atomic commit; stage only the listed paths; commit +each before the next. + +- [x] **P1.1 — `known_discrepancy` in `assert_patterns_agree`.** In + `verification.py`: replace `raise_on_failure` with + `known_discrepancy: bool = False` and add + `reason: str | None = None` (required when + `known_discrepancy=True`); implement the two-sided assertion + (Decision 1a) and the "expectation met" return (Decision 1b); + raise a clear re-gate `AssertionError` on unexpected agreement. + Update the docstring only. **No `test_verification.py` changes in + Phase 1** — all test work (updating the existing + `raise_on_failure`/return-contract cases and adding the new + `known_discrepancy` cases) is the first task of Phase 2; the tests + may be left temporarily stale until then since they are not run + during Phase 1. Commit: + `Add known_discrepancy flag to assert_patterns_agree` + +- [x] **P1.2 — Remove `ci_skip.txt`; make both runners in-source.** + Delete `docs/docs/verification/ci_skip.txt`; remove the xfail + logic from `docs/docs/conftest.py` (delete the file if nothing + else lives there, per Open Question 2); replace the skip block in + `tools/test_scripts.py` with a static scan that skips a + verification `.py` declaring `known_discrepancy=True` or a + `raises-exception` tag. Also update the `ci_skip`-mechanism + references in `docs/dev/testing-guide.md` (~line 82) and the + `verification-exec` task comment in `pixi.toml` (~line 233), and + any other reference the grep surfaces, so no obsolete guidance is + left behind. Commit: + `Drive verification skips from in-source flag, drop ci_skip.txt` + +- [x] **P1.3 — Audit and migrate the 11 pages.** _(Named Phase-1 audit + exception — read-only classification, see intro.)_ Classify each + page by running its source once: + `pixi run python docs/docs/verification/.py` — a clean exit + means it runs to completion (then its agreement table says + disagree-cleanly vs already-agrees); an exception before the final + agreement call means a crash page. Record the per-page verdict in + this plan's Open Questions. Then for each: migrate + `raise_on_failure=False` → `known_discrepancy=True, reason=…` + (carrying the old `ci_skip.txt` reason onto the page) **or** + re-gate by dropping the flag where it actually agrees; add + `raises-exception` cell tags + notes for crash pages; remove fit + sections from pages that already agree (Decision 5). Run + `pixi run notebook-prepare`; stage the `.py` + regenerated + `.ipynb`. Commit: + `Migrate verification pages to known_discrepancy flag` + +- [x] **P1.4 — Update verification docs prose.** Fix + `docs/docs/verification/index.md` (and any page text) that + described the `ci_skip.txt` mechanism. Commit: + `Update verification docs for known_discrepancy gating` + +- [x] **P1.5 — Revise the two accepted ADRs.** Update + `test-suite-and-validation.md` §6 and `documentation-ci-build.md` + to the in-source mechanism (no `ci_skip.txt`). **Done:** §6 of + `test-suite-and-validation.md` gained a "Known-discrepancy gating" + bullet describing the in-source flag/tag and the two runners. A + `git grep` confirmed `documentation-ci-build.md` never referenced + `ci_skip.txt`/`conftest`, so it had no stale wiring to revise and + was left unchanged. Commit: + `Revise accepted ADRs for in-source verification gating` + +- [x] **P1.6 — Promote the ADR.** `git mv` + `docs/dev/adrs/suggestions/verification-regression-flag.md` → + `accepted/`; set `**Status:** Accepted`; flip its + `docs/dev/adrs/index.md` row to Accepted with the `accepted/...` + link; fix any links that pointed at `suggestions/...` + (`git grep -n verification-regression-flag`). Commit: + `Promote verification-regression-flag ADR to accepted` + +- [x] **P1.7 — Windows CI fix (bundled, unrelated).** In + `src/easydiffraction/analysis/analysis.py` (~line 2819) the + rewritten `data_dir` is built with + `str(Path('data') / 'sequential')`, which is `data\sequential` on + Windows and fails `test_copy_data_archives_and_rewrites_data_dir` + (expects `data/sequential`). Store a POSIX path: + `Path('data', 'sequential').as_posix()` (or the literal + `'data/sequential'`). The existing test is the spec — no test + change. Commit: + `Store sequential data_dir as POSIX path for Windows` + +- [x] **P1.8 — Phase 1 review gate.** No-code; mark `[x]` and commit the + checklist update alone. Commit: `Reach Phase 1 review gate` + +## Status checklist + +- [x] P1.1 known_discrepancy flag +- [x] P1.2 remove ci_skip.txt + runners +- [x] P1.3 audit + migrate pages +- [x] P1.4 verification docs prose +- [x] P1.5 revise accepted ADRs +- [x] P1.6 promote ADR +- [x] P1.7 Windows CI fix +- [x] P1.8 Phase 1 review gate +- [x] Phase 2 verification green + +## Phase 2 — Verification + +Per the `AGENTS.md` two-phase workflow, Phase 2 **starts with the test +work**, then runs the verification commands. No `test_verification.py` +edits happen in Phase 1 — Phase 1 may leave the existing tests +temporarily stale (they are not run until here). + +**Step 1 — update and extend `test_verification.py` first.** Before any +`pixi run` command: + +- **Update existing cases** to the changed contract: every test that + passed `raise_on_failure=` migrates to `known_discrepancy=`, and every + test asserting the old "returns the raw agreement boolean" return + value migrates to the Decision 1b "expectation met" contract (`True` + when the page met its expectation, `AssertionError` otherwise). +- **Add new cases** for the new behavior: + - the two-sided assertion — a `known_discrepancy=True` page that is + out of tolerance passes, and one that is within tolerance raises the + re-gate `AssertionError`; + - the required-`reason` validation — `known_discrepancy=True` without + a non-empty `reason` raises; + - the "expectation met" return value for both a default page and a + passing `known_discrepancy=True` page. + +**Step 2 — run the verification commands.** From the repo root; use the +zsh-safe log-capture when output is needed. + +- `pixi run fix` (commit auto-fixes incl. regenerated + `docs/dev/package-structure/{full,short}.md`). +- `pixi run check > /tmp/edi-check.log 2>&1; check_exit_code=$?; tail -n 200 /tmp/edi-check.log; exit $check_exit_code` +- `pixi run unit-tests > /tmp/edi-unit.log 2>&1; unit_tests_exit_code=$?; tail -n 120 /tmp/edi-unit.log; exit $unit_tests_exit_code` + (Linux cannot reproduce the Windows path failure — the + `test_copy_data_archives_and_rewrites_data_dir` test already passes + here; the P1.7 fix makes it pass on Windows too.) +- `pixi run integration-tests > /tmp/edi-int.log 2>&1; integration_tests_exit_code=$?; tail -n 120 /tmp/edi-int.log; exit $integration_tests_exit_code` +- `pixi run script-tests > /tmp/edi-script.log 2>&1; script_tests_exit_code=$?; tail -n 120 /tmp/edi-script.log; exit $script_tests_exit_code` + (must skip the `known_discrepancy=True` / `raises-exception` pages via + the new in-source scan — confirm none of them run here). +- `pixi run notebook-tests > /tmp/edi-nb.log 2>&1; notebook_tests_exit_code=$?; tail -n 120 /tmp/edi-nb.log; exit $notebook_tests_exit_code` + (every page executes; a still-discrepant `known_discrepancy=True` page + passes, and a `raises-exception` page xfails cell-precisely). + +## Suggested Pull Request + +**Title:** Simpler, self-documenting handling of known-bad verification +pages + +**Description:** A verification page that can't yet match its reference +(because an engine feature isn't implemented) is now marked **in the +notebook itself** with `known_discrepancy=True` and a short reason that +shows on the published page — replacing the separate hidden skip list. +Good pages stay regression tests as before; a known-bad page that later +starts matching now fails CI on purpose, so its "known-bad" mark gets +removed deliberately rather than lingering forever. Also fixes a +Windows-only path issue in sequential fitting so the saved data folder +is recorded consistently across operating systems. diff --git a/docs/dev/testing-guide.md b/docs/dev/testing-guide.md index e2464ed2a..f81ef67c6 100644 --- a/docs/dev/testing-guide.md +++ b/docs/dev/testing-guide.md @@ -73,13 +73,24 @@ fall back on) invalid values. Use `hypothesis` (deterministic profile) for generative coverage and explicit parametrised tables for the known-critical boundaries. -## Skipping a verification page in CI +## Marking a known-bad verification page A known-failing verification page (for example one waiting on an engine -fix) can be excluded from the two runners that execute it — -`pixi run script-tests` and `pixi run notebook-tests` — without removing -it from the documentation. Add its notebook stem to -`docs/docs/verification/ci_skip.txt`, one per line with a `# reason`. -Both runners read that single file (`tools/test_scripts.py` and the -nbmake `conftest.py` at `docs/docs/`). The page is still committed and -rendered in the docs; remove the entry once the issue is fixed. +fix) is marked **in the notebook itself**, not in an external list. At +the end of the page, call the agreement check with +`known_discrepancy=True` and a `reason` explaining the known-bad state: + +```python +verify.assert_patterns_agree( + [('cryspy vs FullProf', reference, candidate)], + known_discrepancy=True, + reason='FCJ S_L/D_L not implemented in cryspy yet (issue 166)', +) +``` + +This asserts the documented disagreement **still holds**: the page +passes while it stays out of tolerance, and **fails CI** the moment it +starts agreeing, so its mark must be removed and the page re-gated by +hand. `pixi run script-tests` (the fast regression runner) statically +detects the flag and skips the page, while `pixi run notebook-tests` +executes the page for rendering and the re-gate check. diff --git a/docs/docs/conftest.py b/docs/docs/conftest.py deleted file mode 100644 index 941da895f..000000000 --- a/docs/docs/conftest.py +++ /dev/null @@ -1,53 +0,0 @@ -# SPDX-FileCopyrightText: 2026 EasyScience contributors -# SPDX-License-Identifier: BSD-3-Clause -"""xfail verification notebooks listed in ``verification/ci_skip.txt``. - -``pixi run notebook-tests`` (and the docs-build execution step) collect -every ``*.ipynb`` under ``docs/docs/`` with nbmake. Verification notebook -stems listed in ``verification/ci_skip.txt`` are marked ``xfail`` (not -``skip``): nbmake still **executes** them — so they render in the -documentation and ``--overwrite`` writes their outputs — but a known -discrepancy or pending-feature page is an expected failure rather than a -suite failure. ``strict=False`` keeps a page that happens to pass (for -example one whose agreement check runs with ``raise_on_failure=False``) -from turning into a failure. The script-test runner reads the same file -but skips those stems outright (see ``tools/test_scripts.py``), since the -refinement fits are slow and that runner is the fast regression check. - -This lives at ``docs/docs/`` rather than beside the notebooks so it is not -swept into the notebook-generation globs, which target the ``tutorials`` -and ``verification`` directories directly. -""" - -from __future__ import annotations - -from pathlib import Path - -import pytest - -_VERIFICATION_DIR = Path(__file__).parent / 'verification' -_SKIP_FILE = _VERIFICATION_DIR / 'ci_skip.txt' - - -def ci_skipped_stems() -> set[str]: - """Return verification notebook stems allowed to fail in CI.""" - if not _SKIP_FILE.is_file(): - return set() - stems: set[str] = set() - for line in _SKIP_FILE.read_text(encoding='utf-8').splitlines(): - entry = line.split('#', 1)[0].strip() - if entry: - stems.add(entry) - return stems - - -def pytest_collection_modifyitems(items: list[pytest.Item]) -> None: - """xfail listed verification notebooks so they run but cannot fail.""" - allowed = ci_skipped_stems() - if not allowed: - return - for item in items: - path = Path(str(getattr(item, 'fspath', ''))) - if path.parent.name == 'verification' and path.suffix == '.ipynb' and path.stem in allowed: - reason = f"Verification page '{path.stem}' is allowed to fail in CI (ci_skip.txt)" - item.add_marker(pytest.mark.xfail(reason=reason, strict=False)) diff --git a/docs/docs/verification/ci_skip.txt b/docs/docs/verification/ci_skip.txt deleted file mode 100644 index ef49c84a5..000000000 --- a/docs/docs/verification/ci_skip.txt +++ /dev/null @@ -1,23 +0,0 @@ -# Verification notebooks to skip in CI. -# -# List one notebook stem per line (the file name without extension), -# followed by an optional "# reason". Both CI runners that execute the -# verification pages consult this file: -# -# * pixi run script-tests (tools/test_scripts.py) -# * pixi run notebook-tests (nbmake, via docs/docs/conftest.py) -# -# A skipped page is still committed and still shown in the documentation; -# it is only excluded from those two runners so a known-failing page does -# not block CI while it is being fixed. Remove the entry once the -# underlying issue is resolved. -# -# Example (do not leave commented examples as active entries): -pd-neut-cwl_pv-beba_pbso4 # Berar-Baldinozzi asymmetry differs between cryspy/FullProf (issue 166); not in ed-crysfml -pd-neut-cwl_tch-fcj-noabs-nosldl_lab6 # needs unreleased cryspy PR #46 (SyCos/SySin, cos2theta convention) -pd-neut-cwl_tch-fcj-noabs_lab6 # FCJ asymmetry (S_L/D_L) not implemented in cryspy; see docs/dev/issues/index.md -pd-neut-cwl_tch-fcj_lab6 # FCJ asymmetry (S_L/D_L) not implemented in cryspy; absorption (muR=0.7, HEWAT) now modelled; see docs/dev/issues/index.md -pd-neut-cwl_tch-fcj-nosldl_lab6 # absorption demo passes on develop cryspy; released cryspy needs PR #46 (SyCos/SySin); see docs/dev/issues/index.md -pd-neut-tof_j_si # ed-crysfml TOF Jorgensen profile ~8.5% off after fitting scale (area ratio 1.09, corr 0.997); cryspy matches FullProf -pd-neut-tof_jvd_si # cryspy TOF Lorentzian discrepancy; see docs/dev/issues/index.md -sc-neut-cwl_ext-iso_tbti # Different asymmetry types in cryspy vs FullProf \ No newline at end of file diff --git a/docs/docs/verification/index.md b/docs/docs/verification/index.md index dd7bb370b..24589e3b9 100644 --- a/docs/docs/verification/index.md +++ b/docs/docs/verification/index.md @@ -24,9 +24,13 @@ y=x scatter instead of a profile overlay, and use `cryspy` only — the sole engine with single-crystal Bragg support. Most pages also run as a fast regression check (`pixi run script-tests` -and `pixi run notebook-tests`), so agreement is monitored over time. A -few are excluded from CI where an engine cannot yet reproduce a modelled -effect; each such page states the reason below. +and `pixi run notebook-tests`), so agreement is monitored over time. +Where an engine cannot yet reproduce a modelled effect, the page marks +the difference **in the notebook itself** with `known_discrepancy=True` +and a short reason: it still renders in the docs and is verified to +**stay** discrepant — failing CI if it unexpectedly starts agreeing, so +the mark must then be removed — while the fast regression run skips it. +Such pages are flagged **Known discrepancy** below. Pages are grouped by **experiment type** (sample form, radiation probe, and beam mode). Coverage grows to span every supported combination — @@ -46,26 +50,32 @@ and so on. The list below notes only what is specific to each page. Anglesite (PbSO₄, _Pnma_); pseudo-Voigt, no asymmetry. - [PbSO₄ `pd-neut-cwl` (Bérar–Baldinozzi asymmetry)](pd-neut-cwl_pv-beba_pbso4.ipynb) – Anglesite (PbSO₄, _Pnma_); pseudo-Voigt with Bérar–Baldinozzi - (FullProf-style) axial-divergence asymmetry (`asym_beba_*`). Skipped - in CI: cryspy and FullProf implement this asymmetry with different - conventions (issue 166), and crysfml has no empirical-asymmetry model. + (FullProf-style) axial-divergence asymmetry (`asym_beba_*`). cryspy + and FullProf implement this asymmetry with different conventions + (issue 166), so the FullProf coefficients do not transfer one-to-one; + freeing cryspy's own coefficients recovers the FullProf profile, so + the page agrees. crysfml has no empirical-asymmetry model. - [LaB₆ `pd-neut-cwl` (SyCos/SySin)](pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb) – Lanthanum hexaboride (LaB₆, _Pm-3m_); pseudo-Voigt with SyCos/SySin - sample-displacement and transparency corrections. Skipped in CI: - pending the unreleased cryspy build that adds these corrections. + sample-displacement and transparency corrections. Known discrepancy: + pending the unreleased cryspy build (PR #46) that adds these + corrections. - [LaB₆ `pd-neut-cwl` (FCJ asymmetry)](pd-neut-cwl_tch-fcj-noabs_lab6.ipynb) – Lanthanum hexaboride (LaB₆, _Pm-3m_); Thompson–Cox–Hastings with - Finger–Cox– Jephcoat axial-divergence asymmetry. Skipped in CI: FCJ - asymmetry is crysfml-only. + Finger–Cox– Jephcoat axial-divergence asymmetry. Known discrepancy: + FCJ asymmetry is not implemented in cryspy (crysfml-only). - [LaB₆ `pd-neut-cwl` (absorption)](pd-neut-cwl_tch-fcj_lab6.ipynb) – Lanthanum hexaboride (LaB₆, _Pm-3m_); adds Debye–Scherrer sample absorption (μR = 0.7), now modelled by both engines, on top of FCJ - asymmetry. Skipped in CI: FCJ asymmetry is crysfml-only. + asymmetry. Known discrepancy: FCJ asymmetry is not implemented in + cryspy (crysfml-only). - [LaB₆ `pd-neut-cwl` (absorption, no FCJ)](pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb) – Lanthanum hexaboride (LaB₆, _Pm-3m_); Debye–Scherrer sample absorption (μR = 0.7) with FCJ asymmetry switched off, isolating the - absorption correction. ed-cryspy matches FullProf (enabling the - correction removes a ≈ 2.9× intensity mismatch). + absorption correction. Enabling the correction removes a ≈ 2.9× + intensity mismatch. Known discrepancy: a residual peak-position + difference remains on the released cryspy (needs PR #46); it agrees on + a develop cryspy build. - [Y₂O₃ `pd-neut-cwl` (anisotropic β-tensor ADPs)](pd-neut-cwl_pv-beta_y2o3.ipynb) – Yttria (Y₂O₃, bixbyite, _Ia-3_); dimensionless β-tensor anisotropic ADPs (`adp_type='beta'`) on the three sites, with cylindrical @@ -79,16 +89,16 @@ and so on. The list below notes only what is specific to each page. ## Powder, neutron, time-of-flight - [Si `pd-neut-tof` (Jorgensen)](pd-neut-tof_j_si.ipynb) – Silicon (Si, - _Fd-3m_); Jorgensen (back-to-back exponentials with a Gaussian). + _Fd-3m_); Jorgensen (back-to-back exponentials with a Gaussian). Known + discrepancy: the ed-crysfml profile is ~8.5% off after fitting the + scale; cryspy matches FullProf (issue 130). - [Si `pd-neut-tof` (Jorgensen–Von Dreele)](pd-neut-tof_jvd_si.ipynb) – Silicon (Si, _Fd-3m_); Jorgensen–Von Dreele (back-to-back exponentials - with a pseudo-Voigt). Skipped in CI: residual cryspy TOF Lorentzian - discrepancy. + with a pseudo-Voigt). Known discrepancy: residual cryspy TOF + Lorentzian discrepancy. - [NaCaAlF `pd-neut-tof`](pd-neut-tof_jvd_ncaf.ipynb) – Sodium calcium - aluminium fluoride (Na₂Ca₃Al₂F₁₄, _I2₁3_); Jorgensen–Von Dreele. - Skipped in CI: the FullProf reference uses a tabulated - instrument-resolution file that the polynomial profile cannot - reproduce. + aluminium fluoride (Na₂Ca₃Al₂F₁₄, _I2₁3_); Jorgensen–Von Dreele. Both + engines agree with the FullProf reference within tolerance. ## Single crystal, neutron, constant wavelength @@ -105,4 +115,5 @@ and so on. The list below notes only what is specific to each page. FullProf reference with anisotropic ADPs and empirical extinction. Cryspy extinction (`becker-coppens`, `gauss`) uses two parameters, `radius` and `mosaicity`. Only `scale` and `radius` are refined - against FullProf. + against FullProf. Known discrepancy: cryspy and FullProf use different + asymmetry conventions. diff --git a/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.ipynb b/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.ipynb index ce345c441..9bba4956d 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.ipynb +++ b/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.ipynb @@ -323,12 +323,9 @@ "metadata": {}, "outputs": [], "source": [ - "verify.assert_patterns_agree(\n", - " [\n", - " (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined),\n", - " ],\n", - " raise_on_failure=False,\n", - ")" + "verify.assert_patterns_agree([\n", + " (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined),\n", + "])" ] } ], diff --git a/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.py b/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.py index 9d2a7fb0a..94f325928 100644 --- a/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.py +++ b/docs/docs/verification/pd-neut-cwl_pv-beba_pbso4.py @@ -207,9 +207,6 @@ # ## Agreement check # %% -verify.assert_patterns_agree( - [ - (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined), - ], - raise_on_failure=False, -) +verify.assert_patterns_agree([ + (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy_refined), +]) diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb index b53079d7c..3032354ce 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.ipynb @@ -293,7 +293,8 @@ " (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", " (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", - " raise_on_failure=False,\n", + " known_discrepancy=True,\n", + " reason=('needs unreleased cryspy PR #46 (SyCos/SySin, cos2theta convention)'),\n", ")" ] } diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py index bdec96c9a..3053c0509 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs-nosldl_lab6.py @@ -165,5 +165,6 @@ (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], - raise_on_failure=False, + known_discrepancy=True, + reason=('needs unreleased cryspy PR #46 (SyCos/SySin, cos2theta convention)'), ) diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.ipynb b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.ipynb index ecab7af92..dfe1f8107 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.ipynb +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.ipynb @@ -347,7 +347,8 @@ " (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", " (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", - " raise_on_failure=False,\n", + " known_discrepancy=True,\n", + " reason='FCJ asymmetry (S_L/D_L) is not implemented in cryspy.',\n", ")" ] } diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.py b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.py index 47fd9052c..adb790607 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.py +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-noabs_lab6.py @@ -207,5 +207,6 @@ (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], - raise_on_failure=False, + known_discrepancy=True, + reason='FCJ asymmetry (S_L/D_L) is not implemented in cryspy.', ) diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb b/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb index 69f42e6a8..5ccbe5cc9 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.ipynb @@ -38,13 +38,17 @@ "(S_L = D_L = 0), so the absorption correction is the only remaining\n", "angle-dependent intensity effect.\n", "\n", - "The agreement is asserted against **ed-cryspy**, whose base intensities\n", - "match FullProf for this sample. Without the correction the calculated\n", - "pattern is ≈ 2.9× too intense (the FullProf reference is attenuated by\n", - "absorption); enabling `cylinder-hewat` with μR = 0.7 brings ed-cryspy\n", - "into agreement with FullProf. ed-crysfml is shown for completeness but\n", - "not asserted: it has a separate, pre-existing intensity-convention\n", - "difference with FullProf for LaB₆ that is independent of absorption." + "The absorption correction is demonstrated against **ed-cryspy**, whose\n", + "base intensities match FullProf for this sample. Without the correction\n", + "the calculated pattern is ≈ 2.9× too intense (the FullProf reference is\n", + "attenuated by absorption); enabling `cylinder-hewat` with μR = 0.7\n", + "restores the intensity scale. A residual peak-position discrepancy\n", + "remains on the released cryspy because the SyCos/SySin systematic shift\n", + "needs the unreleased cryspy PR #46, so this page is marked as a **known\n", + "discrepancy** (it agrees on a develop cryspy build). ed-crysfml is shown\n", + "for completeness but not asserted: it has a separate, pre-existing\n", + "intensity-convention difference with FullProf for LaB₆ that is\n", + "independent of absorption." ] }, { @@ -281,8 +285,9 @@ "## Agreement check\n", "\n", "Only ed-cryspy is asserted (see the note at the top): enabling the\n", - "`cylinder-hewat` absorption brings it into agreement with the\n", - "absorption-corrected FullProf reference." + "`cylinder-hewat` absorption restores the intensity scale, but a residual\n", + "peak-position discrepancy persists on the released cryspy (needs PR #46),\n", + "so the page is marked `known_discrepancy=True`." ] }, { @@ -296,7 +301,10 @@ " [\n", " (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", " ],\n", - " raise_on_failure=True,\n", + " known_discrepancy=True,\n", + " reason=(\n", + " 'absorption demo passes on develop cryspy; released cryspy needs PR #46 (SyCos/SySin)'\n", + " ),\n", ")" ] } diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.py b/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.py index 964f249f2..a298e0c3c 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.py +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj-nosldl_lab6.py @@ -8,13 +8,17 @@ # (S_L = D_L = 0), so the absorption correction is the only remaining # angle-dependent intensity effect. # -# The agreement is asserted against **ed-cryspy**, whose base intensities -# match FullProf for this sample. Without the correction the calculated -# pattern is ≈ 2.9× too intense (the FullProf reference is attenuated by -# absorption); enabling `cylinder-hewat` with μR = 0.7 brings ed-cryspy -# into agreement with FullProf. ed-crysfml is shown for completeness but -# not asserted: it has a separate, pre-existing intensity-convention -# difference with FullProf for LaB₆ that is independent of absorption. +# The absorption correction is demonstrated against **ed-cryspy**, whose +# base intensities match FullProf for this sample. Without the correction +# the calculated pattern is ≈ 2.9× too intense (the FullProf reference is +# attenuated by absorption); enabling `cylinder-hewat` with μR = 0.7 +# restores the intensity scale. A residual peak-position discrepancy +# remains on the released cryspy because the SyCos/SySin systematic shift +# needs the unreleased cryspy PR #46, so this page is marked as a **known +# discrepancy** (it agrees on a develop cryspy build). ed-crysfml is shown +# for completeness but not asserted: it has a separate, pre-existing +# intensity-convention difference with FullProf for LaB₆ that is +# independent of absorption. # %% import easydiffraction as ed @@ -167,13 +171,17 @@ # ## Agreement check # # Only ed-cryspy is asserted (see the note at the top): enabling the -# `cylinder-hewat` absorption brings it into agreement with the -# absorption-corrected FullProf reference. +# `cylinder-hewat` absorption restores the intensity scale, but a residual +# peak-position discrepancy persists on the released cryspy (needs PR #46), +# so the page is marked `known_discrepancy=True`. # %% verify.assert_patterns_agree( [ (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), ], - raise_on_failure=True, + known_discrepancy=True, + reason=( + 'absorption demo passes on develop cryspy; released cryspy needs PR #46 (SyCos/SySin)' + ), ) diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.ipynb b/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.ipynb index 4982e4ef3..6d8f76c77 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.ipynb +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.ipynb @@ -354,7 +354,11 @@ " (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", " (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", " ],\n", - " raise_on_failure=False,\n", + " known_discrepancy=True,\n", + " reason=(\n", + " 'FCJ asymmetry (S_L/D_L) is not implemented in cryspy; '\n", + " 'absorption is modelled by both engines.'\n", + " ),\n", ")" ] } diff --git a/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py b/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py index 545813a3a..ed1cf489d 100644 --- a/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py +++ b/docs/docs/verification/pd-neut-cwl_tch-fcj_lab6.py @@ -214,5 +214,9 @@ (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), ], - raise_on_failure=False, + known_discrepancy=True, + reason=( + 'FCJ asymmetry (S_L/D_L) is not implemented in cryspy; ' + 'absorption is modelled by both engines.' + ), ) diff --git a/docs/docs/verification/pd-neut-tof_j_si.ipynb b/docs/docs/verification/pd-neut-tof_j_si.ipynb index ddacfa626..2d3121579 100644 --- a/docs/docs/verification/pd-neut-tof_j_si.ipynb +++ b/docs/docs/verification/pd-neut-tof_j_si.ipynb @@ -360,7 +360,11 @@ " calc_ed_crysfml_refined,\n", " ),\n", " ],\n", - " raise_on_failure=False,\n", + " known_discrepancy=True,\n", + " reason=(\n", + " 'ed-crysfml TOF Jorgensen profile is about 8.5% off after '\n", + " 'fitting scale; cryspy matches FullProf.'\n", + " ),\n", ")" ] } diff --git a/docs/docs/verification/pd-neut-tof_j_si.py b/docs/docs/verification/pd-neut-tof_j_si.py index 3a7b2c483..c900bfb3c 100644 --- a/docs/docs/verification/pd-neut-tof_j_si.py +++ b/docs/docs/verification/pd-neut-tof_j_si.py @@ -206,5 +206,9 @@ calc_ed_crysfml_refined, ), ], - raise_on_failure=False, + known_discrepancy=True, + reason=( + 'ed-crysfml TOF Jorgensen profile is about 8.5% off after ' + 'fitting scale; cryspy matches FullProf.' + ), ) diff --git a/docs/docs/verification/pd-neut-tof_jvd_ncaf.ipynb b/docs/docs/verification/pd-neut-tof_jvd_ncaf.ipynb index c398b4f00..fcc29b51e 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_ncaf.ipynb +++ b/docs/docs/verification/pd-neut-tof_jvd_ncaf.ipynb @@ -394,21 +394,18 @@ "metadata": {}, "outputs": [], "source": [ - "verify.assert_patterns_agree(\n", - " [\n", - " (\n", - " f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}',\n", - " verify.restrict_to_included(experiment, calc_fullprof),\n", - " calc_ed_cryspy_refined,\n", - " ),\n", - " (\n", - " f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}',\n", - " verify.restrict_to_included(experiment, calc_fullprof),\n", - " calc_ed_crysfml_refined,\n", - " ),\n", - " ],\n", - " raise_on_failure=False,\n", - ")" + "verify.assert_patterns_agree([\n", + " (\n", + " f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}',\n", + " verify.restrict_to_included(experiment, calc_fullprof),\n", + " calc_ed_cryspy_refined,\n", + " ),\n", + " (\n", + " f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}',\n", + " verify.restrict_to_included(experiment, calc_fullprof),\n", + " calc_ed_crysfml_refined,\n", + " ),\n", + "])" ] } ], diff --git a/docs/docs/verification/pd-neut-tof_jvd_ncaf.py b/docs/docs/verification/pd-neut-tof_jvd_ncaf.py index 7ece521b0..ce99c50e1 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_ncaf.py +++ b/docs/docs/verification/pd-neut-tof_jvd_ncaf.py @@ -240,18 +240,15 @@ # ## Agreement check # %% -verify.assert_patterns_agree( - [ - ( - f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', - verify.restrict_to_included(experiment, calc_fullprof), - calc_ed_cryspy_refined, - ), - ( - f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}', - verify.restrict_to_included(experiment, calc_fullprof), - calc_ed_crysfml_refined, - ), - ], - raise_on_failure=False, -) +verify.assert_patterns_agree([ + ( + f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', + verify.restrict_to_included(experiment, calc_fullprof), + calc_ed_cryspy_refined, + ), + ( + f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}', + verify.restrict_to_included(experiment, calc_fullprof), + calc_ed_crysfml_refined, + ), +]) diff --git a/docs/docs/verification/pd-neut-tof_jvd_si.ipynb b/docs/docs/verification/pd-neut-tof_jvd_si.ipynb index 06a1598a3..0acf391f9 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_si.ipynb +++ b/docs/docs/verification/pd-neut-tof_jvd_si.ipynb @@ -390,7 +390,8 @@ " calc_ed_crysfml_refined,\n", " ),\n", " ],\n", - " raise_on_failure=False,\n", + " known_discrepancy=True,\n", + " reason='cryspy TOF Lorentzian discrepancy.',\n", ")" ] } diff --git a/docs/docs/verification/pd-neut-tof_jvd_si.py b/docs/docs/verification/pd-neut-tof_jvd_si.py index bb989e275..1f901984e 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_si.py +++ b/docs/docs/verification/pd-neut-tof_jvd_si.py @@ -222,5 +222,6 @@ calc_ed_crysfml_refined, ), ], - raise_on_failure=False, + known_discrepancy=True, + reason='cryspy TOF Lorentzian discrepancy.', ) diff --git a/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.ipynb b/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.ipynb index b3a3737db..73a3ff096 100644 --- a/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.ipynb +++ b/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.ipynb @@ -298,7 +298,8 @@ " [\n", " (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", " ],\n", - " raise_on_failure=False,\n", + " known_discrepancy=True,\n", + " reason='cryspy and FullProf use different extinction conventions.',\n", ")" ] } diff --git a/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.py b/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.py index 79c239f21..8bf7bf284 100644 --- a/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.py +++ b/docs/docs/verification/sc-neut-cwl_ext-iso_tbti.py @@ -175,5 +175,6 @@ [ (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), ], - raise_on_failure=False, + known_discrepancy=True, + reason='cryspy and FullProf use different extinction conventions.', ) diff --git a/docs/docs/verification/sc-neut-cwl_noext_tbti.ipynb b/docs/docs/verification/sc-neut-cwl_noext_tbti.ipynb index cafe5b6a7..de202717d 100644 --- a/docs/docs/verification/sc-neut-cwl_noext_tbti.ipynb +++ b/docs/docs/verification/sc-neut-cwl_noext_tbti.ipynb @@ -286,12 +286,9 @@ "metadata": {}, "outputs": [], "source": [ - "verify.assert_patterns_agree(\n", - " [\n", - " (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", - " ],\n", - " raise_on_failure=False,\n", - ")" + "verify.assert_patterns_agree([\n", + " (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", + "])" ] } ], diff --git a/docs/docs/verification/sc-neut-cwl_noext_tbti.py b/docs/docs/verification/sc-neut-cwl_noext_tbti.py index 76b09f263..a5d7f1152 100644 --- a/docs/docs/verification/sc-neut-cwl_noext_tbti.py +++ b/docs/docs/verification/sc-neut-cwl_noext_tbti.py @@ -163,9 +163,6 @@ # ## Agreement check # %% -verify.assert_patterns_agree( - [ - (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), - ], - raise_on_failure=False, -) +verify.assert_patterns_agree([ + (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), +]) diff --git a/docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb b/docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb index 8faf62f8b..daa0b7a40 100644 --- a/docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb +++ b/docs/docs/verification/sc-neut-cwl_pr2nio4.ipynb @@ -321,12 +321,9 @@ "metadata": {}, "outputs": [], "source": [ - "verify.assert_patterns_agree(\n", - " [\n", - " (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", - " ],\n", - " raise_on_failure=False,\n", - ")" + "verify.assert_patterns_agree([\n", + " (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined),\n", + "])" ] } ], diff --git a/docs/docs/verification/sc-neut-cwl_pr2nio4.py b/docs/docs/verification/sc-neut-cwl_pr2nio4.py index d0f3d29c9..8029e8523 100644 --- a/docs/docs/verification/sc-neut-cwl_pr2nio4.py +++ b/docs/docs/verification/sc-neut-cwl_pr2nio4.py @@ -198,9 +198,6 @@ # ## Agreement check # %% -verify.assert_patterns_agree( - [ - (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), - ], - raise_on_failure=False, -) +verify.assert_patterns_agree([ + (f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', reference_refined, candidate_refined), +]) diff --git a/pixi.toml b/pixi.toml index 18becaef3..fbdbe0fa2 100644 --- a/pixi.toml +++ b/pixi.toml @@ -230,7 +230,8 @@ notebook-tweak = 'python tools/tweak_notebooks.py docs/docs/tutorials/ docs/docs notebook-exec = { cmd = 'python -m pytest --nbmake docs/docs/tutorials/ docs/docs/verification/ --overwrite --color=yes -n auto -v', env = { EASYDIFFRACTION_ARTIFACT_ROOT = 'tmp/tutorials', EASYDIFFRACTION_FIGURE_EMBED_MODE = 'shared' } } notebook-exec-ci = { cmd = 'python -m pytest --nbmake docs/docs/tutorials/ docs/docs/verification/ --nbmake-timeout=1200 --overwrite --color=yes -n auto -v', env = { EASYDIFFRACTION_ARTIFACT_ROOT = '.', EASYDIFFRACTION_FIGURE_EMBED_MODE = 'shared' } } # Execute and overwrite outputs for the verification notebooks only (the -# verification-page subset of notebook-exec); honours ci_skip.txt. +# verification-page subset of notebook-exec); nbmake runs every page, and +# a known-bad page is gated by its in-notebook known_discrepancy flag. verification-exec = { cmd = 'python -m pytest --nbmake docs/docs/verification/ --overwrite --color=yes -n auto -v', env = { EASYDIFFRACTION_ARTIFACT_ROOT = 'tmp/tutorials', EASYDIFFRACTION_FIGURE_EMBED_MODE = 'shared' } } notebook-prepare = { depends-on = [ diff --git a/src/easydiffraction/analysis/analysis.py b/src/easydiffraction/analysis/analysis.py index a366c6477..f27405bdf 100644 --- a/src/easydiffraction/analysis/analysis.py +++ b/src/easydiffraction/analysis/analysis.py @@ -2808,7 +2808,7 @@ def _resolve_sequential_source(self) -> str: for path in matched: shutil.copy2(path, destination / Path(path).name) - self._sequential_fit.data_dir = str(Path('data') / 'sequential') + self._sequential_fit.data_dir = Path('data', 'sequential').as_posix() return str(destination) def _prepare_fit_run( diff --git a/src/easydiffraction/analysis/verification.py b/src/easydiffraction/analysis/verification.py index fb14a2666..e674d8778 100644 --- a/src/easydiffraction/analysis/verification.py +++ b/src/easydiffraction/analysis/verification.py @@ -24,6 +24,7 @@ from easydiffraction.datablocks.experiment.item.base import intensity_category_for from easydiffraction.utils.utils import SOFTWARE_PACKAGE_BY_ENGINE from easydiffraction.utils.utils import package_version +from easydiffraction.utils.utils import print_table_footnote from easydiffraction.utils.utils import render_table # Closeness metrics are computed on absolute intensities: each page @@ -973,35 +974,63 @@ def assert_patterns_agree( comparisons: list[tuple[str, np.ndarray, np.ndarray]], *, tolerances: AgreementTolerances | None = None, - raise_on_failure: bool = True, + known_discrepancy: bool = False, + reason: str | None = None, ) -> bool: """ - Render a pass/fail agreement table for one or more pattern pairs. + Assert one or more pattern pairs meet their documented expectation. Each comparison is scored with :func:`pattern_closeness` and checked against ``tolerances``. A single table summarises every metric with a check/cross icon; an out-of-bounds actual value is shown in red. + The assertion is two-sided and driven by ``known_discrepancy``: + + * ``known_discrepancy=False`` (default) asserts the patterns + **agree** — the page is a regression test, and any + out-of-tolerance metric raises ``AssertionError``. + * ``known_discrepancy=True`` asserts the patterns **still disagree** + — the documented known-bad state. The expected out-of-tolerance + result passes (the discrepancy stays visible); if the page has + started agreeing within tolerance it raises ``AssertionError`` so + the now-fixed page fails CI and must be re-gated by hand. + Parameters ---------- comparisons : list[tuple[str, np.ndarray, np.ndarray]] ``(label, reference, candidate)`` triples to compare. tolerances : AgreementTolerances | None, default=None Tolerance bounds; the documented defaults are used when omitted. - raise_on_failure : bool, default=True - Whether to raise ``AssertionError`` when any metric is out of - bounds, so the verification notebooks stay regression-checked. + known_discrepancy : bool, default=False + When True, assert the documented disagreement persists instead + of asserting agreement (see above). + reason : str | None, default=None + Required when ``known_discrepancy=True``: a short explanation of + the known-bad state, shown on the published page. Returns ------- bool - ``True`` when every metric is within tolerance. + ``True`` when the page met its expectation (a default page that + agrees, or a ``known_discrepancy`` page that still disagrees). Raises ------ + ValueError + If ``known_discrepancy=True`` is given without a non-empty + ``reason``. AssertionError - If any metric is out of bounds and ``raise_on_failure`` is True. + If the expectation is not met: a default page whose patterns + disagree, or a ``known_discrepancy`` page that now agrees within + tolerance. """ + if known_discrepancy and not (reason and reason.strip()): + msg = ( + '`known_discrepancy=True` requires a non-empty `reason` ' + 'explaining the known-bad state (shown on the page).' + ) + raise ValueError(msg) + tolerances = tolerances or AgreementTolerances() rows: list[list[str]] = [] failures: list[str] = [] @@ -1025,11 +1054,23 @@ def assert_patterns_agree( columns_data=rows, ) - if failures and raise_on_failure: + if known_discrepancy: + print_table_footnote([('Known discrepancy', reason)]) + if not failures: + msg = ( + 'This page now agrees within tolerance — remove ' + '`known_discrepancy` (and `reason`) to re-gate it as a ' + 'regression test, or tighten the tolerance if the match ' + 'is spurious.' + ) + raise AssertionError(msg) + return True + + if failures: joined = '; '.join(failures) msg = f'Pattern agreement check failed: {joined}.' raise AssertionError(msg) - return not failures + return True # ---------------------------------------------------------------------- diff --git a/tests/unit/easydiffraction/analysis/test_verification.py b/tests/unit/easydiffraction/analysis/test_verification.py index 2d82bfb04..739a37728 100644 --- a/tests/unit/easydiffraction/analysis/test_verification.py +++ b/tests/unit/easydiffraction/analysis/test_verification.py @@ -285,15 +285,69 @@ def test_assert_patterns_agree_raises_for_divergent_patterns(): verify.assert_patterns_agree([('a vs b', reference, candidate)]) -def test_assert_patterns_agree_can_report_without_raising(): +def test_assert_patterns_agree_known_discrepancy_passes_while_divergent(): x = np.linspace(0.0, 10.0, 200) reference = _gaussian(x, 5.0, 0.4) * 100.0 candidate = _gaussian(x, 6.5, 0.4) * 100.0 result = verify.assert_patterns_agree( [('a vs b', reference, candidate)], - raise_on_failure=False, + known_discrepancy=True, + reason='documented engine gap', ) - assert result is False + assert result is True + + +def test_assert_patterns_agree_known_discrepancy_regates_when_agreeing(): + x = np.linspace(0.0, 10.0, 200) + reference = _gaussian(x, 5.0, 0.4) * 100.0 + candidate = reference * 1.0001 + with pytest.raises(AssertionError, match='now agrees within tolerance'): + verify.assert_patterns_agree( + [('a vs b', reference, candidate)], + known_discrepancy=True, + reason='documented engine gap', + ) + + +def test_assert_patterns_agree_known_discrepancy_requires_reason(): + x = np.linspace(0.0, 10.0, 200) + reference = _gaussian(x, 5.0, 0.4) * 100.0 + candidate = _gaussian(x, 6.5, 0.4) * 100.0 + with pytest.raises(ValueError, match='requires a non-empty `reason`'): + verify.assert_patterns_agree( + [('a vs b', reference, candidate)], + known_discrepancy=True, + ) + with pytest.raises(ValueError, match='requires a non-empty `reason`'): + verify.assert_patterns_agree( + [('a vs b', reference, candidate)], + known_discrepancy=True, + reason=' ', + ) + + +def test_assert_patterns_agree_renders_known_discrepancy_reason(monkeypatch): + captured = [] + monkeypatch.setattr(verify, 'print_table_footnote', captured.append) + x = np.linspace(0.0, 10.0, 200) + reference = _gaussian(x, 5.0, 0.4) * 100.0 + candidate = _gaussian(x, 6.5, 0.4) * 100.0 + verify.assert_patterns_agree( + [('a vs b', reference, candidate)], + known_discrepancy=True, + reason='engine gap X', + ) + assert [('Known discrepancy', 'engine gap X')] in captured + + +def test_assert_patterns_agree_does_not_render_reason_for_default_page(monkeypatch): + captured = [] + monkeypatch.setattr(verify, 'print_table_footnote', captured.append) + x = np.linspace(0.0, 10.0, 200) + reference = _gaussian(x, 5.0, 0.4) * 100.0 + candidate = reference * 1.0001 + verify.assert_patterns_agree([('a vs b', reference, candidate)]) + assert captured == [] def test_agreement_tolerances_defaults(): diff --git a/tests/unit/tools/test_script_runner_skip.py b/tests/unit/tools/test_script_runner_skip.py new file mode 100644 index 000000000..b333fbd46 --- /dev/null +++ b/tests/unit/tools/test_script_runner_skip.py @@ -0,0 +1,97 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause +"""Tests for the verification-page skip scan in tools/test_scripts.py.""" + +from __future__ import annotations + +import importlib.util +import sys +from pathlib import Path + + +def _load_runner(): + repo_root = Path(__file__).resolve().parents[3] + module_path = repo_root / 'tools' / 'test_scripts.py' + spec = importlib.util.spec_from_file_location('script_runner_under_test', module_path) + module = importlib.util.module_from_spec(spec) + sys.modules[spec.name] = module + spec.loader.exec_module(module) + return module + + +_runner = _load_runner() + +_REAL_CALL = ( + 'verify.assert_patterns_agree(\n' + " [('a vs b', ref, cand)],\n" + ' known_discrepancy=True,\n' + " reason='x',\n" + ')\n' +) + + +def test_calls_known_discrepancy_detects_literal_keyword(): + assert _runner._calls_known_discrepancy(_REAL_CALL) is True + + +def test_calls_known_discrepancy_ignores_comment_mention(): + source = '# known_discrepancy=True in a comment\nverify.assert_patterns_agree([])\n' + assert _runner._calls_known_discrepancy(source) is False + + +def test_calls_known_discrepancy_ignores_string_mention(): + source = "note = 'known_discrepancy=True'\nverify.assert_patterns_agree([])\n" + assert _runner._calls_known_discrepancy(source) is False + + +def test_calls_known_discrepancy_ignores_false_value(): + source = 'verify.assert_patterns_agree([], known_discrepancy=False)\n' + assert _runner._calls_known_discrepancy(source) is False + + +def test_calls_known_discrepancy_syntax_error_not_detected(): + # A page that fails to parse must not be silently skipped, so the + # script runner executes it and surfaces the error. + assert _runner._calls_known_discrepancy('def (:\n') is False + + +def test_tags_raises_exception_on_cell_marker(): + source = '# %% tags=["raises-exception"]\nraise RuntimeError\n' + assert _runner._tags_raises_exception(source) is True + + +def test_tags_raises_exception_ignores_plain_comment(): + source = '# mentions raises-exception in prose\nx = 1\n' + assert _runner._tags_raises_exception(source) is False + + +def test_verification_skip_reason_skips_known_discrepancy(tmp_path): + page = tmp_path / 'verification' / 'pd.py' + page.parent.mkdir() + page.write_text(_REAL_CALL, encoding='utf-8') + reason = _runner._verification_skip_reason(page) + assert reason is not None + assert 'known_discrepancy' in reason + + +def test_verification_skip_reason_skips_raises_exception(tmp_path): + page = tmp_path / 'verification' / 'pd.py' + page.parent.mkdir() + page.write_text('# %% tags=["raises-exception"]\nraise RuntimeError\n', encoding='utf-8') + reason = _runner._verification_skip_reason(page) + assert reason is not None + assert 'raises-exception' in reason + + +def test_verification_skip_reason_runs_regated_page(tmp_path): + page = tmp_path / 'verification' / 'pd.py' + page.parent.mkdir() + page.write_text("verify.assert_patterns_agree([('a', ref, cand)])\n", encoding='utf-8') + assert _runner._verification_skip_reason(page) is None + + +def test_verification_skip_reason_never_skips_tutorials(tmp_path): + page = tmp_path / 'tutorials' / 'pd.py' + page.parent.mkdir() + page.write_text(_REAL_CALL, encoding='utf-8') + assert _runner._verification_skip_reason(page) is None diff --git a/tools/test_scripts.py b/tools/test_scripts.py index f5d96c689..f146c26c6 100644 --- a/tools/test_scripts.py +++ b/tools/test_scripts.py @@ -11,7 +11,11 @@ model/experiment names), which can cause false failures. """ +from __future__ import annotations + +import ast import os +import re import subprocess # noqa: S404 import sys from pathlib import Path @@ -20,22 +24,75 @@ _repo_root = Path(__file__).resolve().parents[1] _src_root = _repo_root / 'src' -_CI_SKIP_FILE = _repo_root / 'docs' / 'docs' / 'verification' / 'ci_skip.txt' +_VERIFICATION_DIR_NAME = 'verification' + +# The fast script runner skips a verification page that statically +# declares a known discrepancy (its agreement assertion is two-sided and +# the refinement fit is slow) or tags a cell as raising before the +# assertion is reached. nbmake still executes both kinds, so no coverage +# is lost here. The in-source flag/tag is the single source of truth; +# there is no external skip list. Detection is narrow on purpose: the +# flag is read from the actual ``assert_patterns_agree`` call via the AST +# (not a loose substring a comment could trip), and the tag only from a +# jupytext ``# %%`` cell marker. +_RAISES_EXCEPTION_TAG_RE = re.compile(r'tags\s*=\s*\[[^\]]*["\']raises-exception["\']') + + +def _calls_known_discrepancy(source: str) -> bool: + """True if a real ``assert_patterns_agree(..., known_discrepancy=True)``. + + Parses the source and inspects each ``assert_patterns_agree`` call for + a literal ``known_discrepancy=True`` keyword, so a comment, string, or + markdown cell that merely mentions the flag does not trip the skip. A + page that fails to parse is treated as not-skipped, so script-tests + runs it and surfaces the error rather than silently skipping. + """ + try: + tree = ast.parse(source) + except SyntaxError: + return False + for node in ast.walk(tree): + if not isinstance(node, ast.Call): + continue + func = node.func + name = func.attr if isinstance(func, ast.Attribute) else getattr(func, 'id', None) + if name != 'assert_patterns_agree': + continue + for keyword in node.keywords: + if ( + keyword.arg == 'known_discrepancy' + and isinstance(keyword.value, ast.Constant) + and keyword.value.value is True + ): + return True + return False -def _ci_skipped_stems(): - """Verification notebook stems to skip (shared with the nbmake conftest).""" - if not _CI_SKIP_FILE.is_file(): - return set() - stems = set() - for line in _CI_SKIP_FILE.read_text(encoding='utf-8').splitlines(): - entry = line.split('#', 1)[0].strip() - if entry: - stems.add(entry) - return stems +def _tags_raises_exception(source: str) -> bool: + """True if a jupytext ``# %%`` cell marker tags a cell raises-exception.""" + for line in source.splitlines(): + stripped = line.lstrip() + if stripped.startswith('# %%') and _RAISES_EXCEPTION_TAG_RE.search(stripped): + return True + return False -_CI_SKIP = _ci_skipped_stems() +def _verification_skip_reason(script_path: Path) -> str | None: + """Return why a verification page is skipped by script-tests, or None. + + Skips a page under ``docs/docs/verification`` that statically + declares ``known_discrepancy=True`` in its agreement call or tags a + cell ``raises-exception``; nbmake covers both instead. Tutorial + scripts are never skipped. + """ + if script_path.parent.name != _VERIFICATION_DIR_NAME: + return None + source = script_path.read_text(encoding='utf-8') + if _calls_known_discrepancy(source): + return f'{script_path.stem}: known_discrepancy=True (covered by nbmake)' + if _tags_raises_exception(source): + return f'{script_path.stem}: raises-exception cell tag (covered by nbmake)' + return None # Discover tutorial and verification scripts, excluding checkpoint files # and pytest conftest modules. @@ -55,8 +112,9 @@ def test_script_runs(script_path: Path): Each script is run in the context of __main__ to mimic standalone execution. """ - if script_path.stem in _CI_SKIP: - pytest.skip(f'{script_path.stem} is skipped in CI (ci_skip.txt)') + skip_reason = _verification_skip_reason(script_path) + if skip_reason is not None: + pytest.skip(skip_reason) env = os.environ.copy() if _src_root.exists(): From 4e9126f6338194baa19187b1251a0eaff74850a1 Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 16:59:12 +0200 Subject: [PATCH 17/18] Add X-ray PbSO4 verification page --- .../fullprof/pd-xray-pbso4/pbsox.bac | 602 ++ .../fullprof/pd-xray-pbso4/pbsox.dat | 602 ++ .../fullprof/pd-xray-pbso4/pbsox.pcr | 63 + .../fullprof/pd-xray-pbso4/pbsox.prf | 6813 +++++++++++++++++ .../fullprof/pd-xray-pbso4/pbsox.sum | 147 + docs/docs/verification/index.md | 10 + docs/docs/verification/pd-xray-pbso4.ipynb | 330 + docs/docs/verification/pd-xray-pbso4.py | 195 + 8 files changed, 8762 insertions(+) create mode 100644 docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.bac create mode 100644 docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.dat create mode 100644 docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.pcr create mode 100644 docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.prf create mode 100644 docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.sum create mode 100644 docs/docs/verification/pd-xray-pbso4.ipynb create mode 100644 docs/docs/verification/pd-xray-pbso4.py diff --git a/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.bac b/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.bac new file mode 100644 index 000000000..c71c3c563 --- /dev/null +++ b/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.bac @@ -0,0 +1,602 @@ + 10.048160 0.025000 160.048157 Background of: pbsox + 126 126 126 126 126 126 126 126 125 125 + 125 125 125 125 125 125 124 124 124 124 + 124 124 124 124 123 123 123 123 123 123 + 123 123 123 122 122 122 122 122 122 122 + 122 121 121 121 121 121 121 121 121 121 + 120 120 120 120 120 120 120 120 120 119 + 119 119 119 119 119 119 119 119 119 118 + 118 118 118 118 118 118 118 118 117 117 + 117 117 117 117 117 117 117 117 116 116 + 116 116 116 116 116 116 116 116 116 115 + 115 115 115 115 115 115 115 115 115 115 + 114 114 114 114 114 114 114 114 114 114 + 114 113 113 113 113 113 113 113 113 113 + 113 113 113 112 112 112 112 112 112 112 + 112 112 112 112 112 111 111 111 111 111 + 111 111 111 111 111 111 111 111 110 110 + 110 110 110 110 110 110 110 110 110 110 + 110 110 109 109 109 109 109 109 109 109 + 109 109 109 109 109 109 109 108 108 108 + 108 108 108 108 108 108 108 108 108 108 + 108 108 108 107 107 107 107 107 107 107 + 107 107 107 107 107 107 107 107 107 107 + 106 106 106 106 106 106 106 106 106 106 + 106 106 106 106 106 106 106 106 105 105 + 105 105 105 105 105 105 105 105 105 105 + 105 105 105 105 105 105 105 105 105 104 + 104 104 104 104 104 104 104 104 104 104 + 104 104 104 104 104 104 104 104 104 104 + 104 104 104 103 103 103 103 103 103 103 + 103 103 103 103 103 103 103 103 103 103 + 103 103 103 103 103 103 103 103 103 103 + 103 103 102 102 102 102 102 102 102 102 + 102 102 102 102 102 102 102 102 102 102 + 102 102 102 102 102 102 102 102 102 102 + 102 102 102 102 102 102 102 102 101 101 + 101 101 101 101 101 101 101 101 101 101 + 101 101 101 101 101 101 101 101 101 101 + 101 101 101 101 101 101 101 101 101 101 + 101 101 101 101 101 101 101 101 101 101 + 101 101 101 101 101 101 101 101 101 101 + 101 101 101 101 101 101 101 101 101 101 + 101 101 100 100 100 100 100 100 100 100 + 100 100 100 100 100 100 100 100 100 100 + 100 100 100 100 100 100 100 100 100 100 + 100 100 100 100 100 100 100 100 100 100 + 100 100 100 100 100 100 100 100 100 100 + 100 100 100 100 100 100 100 100 100 100 + 100 100 100 100 100 100 100 100 100 100 + 100 100 100 100 100 100 100 100 100 100 + 100 100 100 100 100 100 100 100 100 100 + 100 100 101 101 101 101 101 101 101 101 + 101 101 101 101 101 101 101 101 101 101 + 101 101 101 101 101 101 101 101 101 101 + 101 101 101 101 101 101 101 101 101 101 + 101 101 101 101 101 101 101 101 101 101 + 101 101 101 101 101 101 101 101 101 101 + 101 101 101 101 101 101 101 101 101 101 + 101 101 101 102 102 102 102 102 102 102 + 102 102 102 102 102 102 102 102 102 102 + 102 102 102 102 102 102 102 102 102 102 + 102 102 102 102 102 102 102 102 102 102 + 102 102 102 102 102 102 102 103 103 103 + 103 103 103 103 103 103 103 103 103 103 + 103 103 103 103 103 103 103 103 103 103 + 103 103 103 103 103 103 103 103 103 103 + 103 103 104 104 104 104 104 104 104 104 + 104 104 104 104 104 104 104 104 104 104 + 104 104 104 104 104 104 104 104 104 104 + 104 104 104 105 105 105 105 105 105 105 + 105 105 105 105 105 105 105 105 105 105 + 105 105 105 105 105 105 105 105 105 105 + 105 106 106 106 106 106 106 106 106 106 + 106 106 106 106 106 106 106 106 106 106 + 106 106 106 106 106 106 106 107 107 107 + 107 107 107 107 107 107 107 107 107 107 + 107 107 107 107 107 107 107 107 107 107 + 107 108 108 108 108 108 108 108 108 108 + 108 108 108 108 108 108 108 108 108 108 + 108 108 108 108 109 109 109 109 109 109 + 109 109 109 109 109 109 109 109 109 109 + 109 109 109 109 109 109 110 110 110 110 + 110 110 110 110 110 110 110 110 110 110 + 110 110 110 110 110 110 110 110 111 111 + 111 111 111 111 111 111 111 111 111 111 + 111 111 111 111 111 111 111 111 112 112 + 112 112 112 112 112 112 112 112 112 112 + 112 112 112 112 112 112 112 112 113 113 + 113 113 113 113 113 113 113 113 113 113 + 113 113 113 113 113 113 113 113 114 114 + 114 114 114 114 114 114 114 114 114 114 + 114 114 114 114 114 114 114 115 115 115 + 115 115 115 115 115 115 115 115 115 115 + 115 115 115 115 115 116 116 116 116 116 + 116 116 116 116 116 116 116 116 116 116 + 116 116 116 116 117 117 117 117 117 117 + 117 117 117 117 117 117 117 117 117 117 + 117 117 118 118 118 118 118 118 118 118 + 118 118 118 118 118 118 118 118 118 118 + 119 119 119 119 119 119 119 119 119 119 + 119 119 119 119 119 119 119 120 120 120 + 120 120 120 120 120 120 120 120 120 120 + 120 120 120 120 120 121 121 121 121 121 + 121 121 121 121 121 121 121 121 121 121 + 121 121 122 122 122 122 122 122 122 122 + 122 122 122 122 122 122 122 122 122 123 + 123 123 123 123 123 123 123 123 123 123 + 123 123 123 123 123 123 124 124 124 124 + 124 124 124 124 124 124 124 124 124 124 + 124 124 124 125 125 125 125 125 125 125 + 125 125 125 125 125 125 125 125 125 126 + 126 126 126 126 126 126 126 126 126 126 + 126 126 126 126 126 126 127 127 127 127 + 127 127 127 127 127 127 127 127 127 127 + 127 127 127 128 128 128 128 128 128 128 + 128 128 128 128 128 128 128 128 128 129 + 129 129 129 129 129 129 129 129 129 129 + 129 129 129 129 129 129 130 130 130 130 + 130 130 130 130 130 130 130 130 130 130 + 130 130 131 131 131 131 131 131 131 131 + 131 131 131 131 131 131 131 131 131 132 + 132 132 132 132 132 132 132 132 132 132 + 132 132 132 132 132 133 133 133 133 133 + 133 133 133 133 133 133 133 133 133 133 + 133 133 134 134 134 134 134 134 134 134 + 134 134 134 134 134 134 134 134 135 135 + 135 135 135 135 135 135 135 135 135 135 + 135 135 135 135 135 136 136 136 136 136 + 136 136 136 136 136 136 136 136 136 136 + 136 136 137 137 137 137 137 137 137 137 + 137 137 137 137 137 137 137 137 138 138 + 138 138 138 138 138 138 138 138 138 138 + 138 138 138 138 138 139 139 139 139 139 + 139 139 139 139 139 139 139 139 139 139 + 139 139 140 140 140 140 140 140 140 140 + 140 140 140 140 140 140 140 140 140 141 + 141 141 141 141 141 141 141 141 141 141 + 141 141 141 141 141 141 142 142 142 142 + 142 142 142 142 142 142 142 142 142 142 + 142 142 142 143 143 143 143 143 143 143 + 143 143 143 143 143 143 143 143 143 143 + 144 144 144 144 144 144 144 144 144 144 + 144 144 144 144 144 144 144 144 145 145 + 145 145 145 145 145 145 145 145 145 145 + 145 145 145 145 145 145 146 146 146 146 + 146 146 146 146 146 146 146 146 146 146 + 146 146 146 147 147 147 147 147 147 147 + 147 147 147 147 147 147 147 147 147 147 + 147 148 148 148 148 148 148 148 148 148 + 148 148 148 148 148 148 148 148 148 149 + 149 149 149 149 149 149 149 149 149 149 + 149 149 149 149 149 149 149 149 150 150 + 150 150 150 150 150 150 150 150 150 150 + 150 150 150 150 150 150 150 151 151 151 + 151 151 151 151 151 151 151 151 151 151 + 151 151 151 151 151 152 152 152 152 152 + 152 152 152 152 152 152 152 152 152 152 + 152 152 152 152 152 153 153 153 153 153 + 153 153 153 153 153 153 153 153 153 153 + 153 153 153 153 154 154 154 154 154 154 + 154 154 154 154 154 154 154 154 154 154 + 154 154 154 154 155 155 155 155 155 155 + 155 155 155 155 155 155 155 155 155 155 + 155 155 155 155 156 156 156 156 156 156 + 156 156 156 156 156 156 156 156 156 156 + 156 156 156 156 156 157 157 157 157 157 + 157 157 157 157 157 157 157 157 157 157 + 157 157 157 157 157 157 158 158 158 158 + 158 158 158 158 158 158 158 158 158 158 + 158 158 158 158 158 158 158 158 159 159 + 159 159 159 159 159 159 159 159 159 159 + 159 159 159 159 159 159 159 159 159 159 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 162 162 162 162 + 162 162 162 162 162 162 162 162 162 162 + 162 162 162 162 162 162 162 162 162 162 + 163 163 163 163 163 163 163 163 163 163 + 163 163 163 163 163 163 163 163 163 163 + 163 163 163 163 163 164 164 164 164 164 + 164 164 164 164 164 164 164 164 164 164 + 164 164 164 164 164 164 164 164 164 164 + 164 165 165 165 165 165 165 165 165 165 + 165 165 165 165 165 165 165 165 165 165 + 165 165 165 165 165 165 165 165 166 166 + 166 166 166 166 166 166 166 166 166 166 + 166 166 166 166 166 166 166 166 166 166 + 166 166 166 166 166 166 167 167 167 167 + 167 167 167 167 167 167 167 167 167 167 + 167 167 167 167 167 167 167 167 167 167 + 167 167 167 167 167 167 168 168 168 168 + 168 168 168 168 168 168 168 168 168 168 + 168 168 168 168 168 168 168 168 168 168 + 168 168 168 168 168 168 168 168 169 169 + 169 169 169 169 169 169 169 169 169 169 + 169 169 169 169 169 169 169 169 169 169 + 169 169 169 169 169 169 169 169 169 169 + 169 170 170 170 170 170 170 170 170 170 + 170 170 170 170 170 170 170 170 170 170 + 170 170 170 170 170 170 170 170 170 170 + 170 170 170 170 170 170 170 171 171 171 + 171 171 171 171 171 171 171 171 171 171 + 171 171 171 171 171 171 171 171 171 171 + 171 171 171 171 171 171 171 171 171 171 + 171 171 171 171 171 171 172 172 172 172 + 172 172 172 172 172 172 172 172 172 172 + 172 172 172 172 172 172 172 172 172 172 + 172 172 172 172 172 172 172 172 172 172 + 172 172 172 172 172 172 172 172 172 172 + 173 173 173 173 173 173 173 173 173 173 + 173 173 173 173 173 173 173 173 173 173 + 173 173 173 173 173 173 173 173 173 173 + 173 173 173 173 173 173 173 173 173 173 + 173 173 173 173 173 173 173 173 173 174 + 174 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 174 174 174 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 177 177 177 177 177 177 177 + 177 177 177 177 177 177 177 177 177 177 + 177 177 177 177 177 177 177 177 177 177 + 177 177 177 177 177 177 177 177 177 177 + 177 177 177 177 177 177 177 177 177 177 + 177 177 177 177 177 177 177 177 177 177 + 177 177 177 177 177 177 177 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 173 173 173 173 173 + 173 173 173 173 173 173 173 173 173 173 + 173 173 173 173 173 173 173 173 173 173 + 173 173 173 173 173 173 173 173 173 173 + 173 173 173 173 173 173 173 173 173 173 + 173 173 173 173 173 173 173 173 173 173 + 173 173 173 173 173 173 173 173 173 173 + 173 172 172 172 172 172 172 172 172 172 + 172 172 172 172 172 172 172 172 172 172 + 172 172 172 172 172 172 172 172 172 172 + 172 172 172 172 172 172 172 172 172 172 + 172 172 172 172 172 172 172 172 172 172 + 172 172 172 172 172 172 172 172 172 172 + 172 172 171 171 171 171 171 171 171 171 + 171 171 171 171 171 171 171 171 171 171 + 171 171 171 171 171 171 171 171 171 171 + 171 171 171 171 171 171 171 171 171 171 + 171 171 171 171 171 171 171 171 171 171 + 171 171 171 171 171 171 171 171 171 171 + 170 170 170 170 170 170 170 170 170 170 + 170 170 170 170 170 170 170 170 170 170 + 170 170 170 170 170 170 170 170 170 170 + 170 170 170 170 170 170 170 170 170 170 + 170 170 170 170 170 170 170 170 170 170 + 170 170 170 170 170 169 169 169 169 169 + 169 169 169 169 169 169 169 169 169 169 + 169 169 169 169 169 169 169 169 169 169 + 169 169 169 169 169 169 169 169 169 169 + 169 169 169 169 169 169 169 169 169 169 + 169 169 169 169 169 169 169 169 169 169 + 168 168 168 168 168 168 168 168 168 168 + 168 168 168 168 168 168 168 168 168 168 + 168 168 168 168 168 168 168 168 168 168 + 168 168 168 168 168 168 168 168 168 168 + 168 168 168 168 168 168 168 168 168 168 + 168 168 168 168 167 167 167 167 167 167 + 167 167 167 167 167 167 167 167 167 167 + 167 167 167 167 167 167 167 167 167 167 + 167 167 167 167 167 167 167 167 167 167 + 167 167 167 167 167 167 167 167 167 167 + 167 167 167 167 167 167 167 167 166 166 + 166 166 166 166 166 166 166 166 166 166 + 166 166 166 166 166 166 166 166 166 166 + 166 166 166 166 166 166 166 166 166 166 + 166 166 166 166 166 166 166 166 166 166 + 166 166 166 166 166 166 166 166 166 166 + 166 166 166 166 165 165 165 165 165 165 + 165 165 165 165 165 165 165 165 165 165 + 165 165 165 165 165 165 165 165 165 165 + 165 165 165 165 165 165 165 165 165 165 + 165 165 165 165 165 165 165 165 165 165 + 165 165 165 165 165 165 165 165 165 165 + 165 164 164 164 164 164 164 164 164 164 + 164 164 164 164 164 164 164 164 164 164 + 164 164 164 164 164 164 164 164 164 164 + 164 164 164 164 164 164 164 164 164 164 + 164 164 164 164 164 164 164 164 164 164 + 164 164 164 164 164 164 164 164 164 164 + 164 164 163 163 163 163 163 163 163 163 + 163 163 163 163 163 163 163 163 163 163 + 163 163 163 163 163 163 163 163 163 163 + 163 163 163 163 163 163 163 163 163 163 + 163 163 163 163 163 163 163 163 163 163 + 163 163 163 163 163 163 163 163 163 163 + 163 163 163 163 163 163 163 163 162 162 + 162 162 162 162 162 162 162 162 162 162 + 162 162 162 162 162 162 162 162 162 162 + 162 162 162 162 162 162 162 162 162 162 + 162 162 162 162 162 162 162 162 162 162 + 162 162 162 162 162 162 162 162 162 162 + 162 162 162 162 162 162 162 162 162 162 + 162 162 162 162 162 162 162 162 162 162 + 162 162 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 159 159 159 159 159 159 159 159 + 159 159 159 159 159 159 159 159 159 159 + 159 159 159 159 159 159 159 159 159 159 + 159 159 159 159 159 159 159 159 159 159 + 159 159 159 159 159 159 159 159 159 159 + 159 159 159 159 159 159 159 159 159 159 + 159 159 159 159 159 159 159 159 159 159 + 159 159 159 159 159 159 159 159 159 159 + 159 159 159 159 159 159 159 159 159 159 + 159 159 159 159 159 159 159 159 159 159 + 159 159 159 159 159 159 159 159 159 159 + 159 159 159 159 159 159 159 159 159 159 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 160 160 160 160 160 + 160 160 160 160 160 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 161 161 161 161 161 161 161 161 161 + 161 162 162 162 162 162 162 162 162 162 + 162 162 162 162 162 162 162 162 162 162 + 162 162 162 162 162 162 162 162 162 162 + 162 162 162 162 162 162 162 162 162 162 + 162 162 162 162 162 162 162 162 162 162 + 162 162 162 162 162 162 162 162 162 163 + 163 163 163 163 163 163 163 163 163 163 + 163 163 163 163 163 163 163 163 163 163 + 163 163 163 163 163 163 163 163 163 163 + 163 163 163 163 163 163 163 163 163 163 + 163 163 163 163 163 163 163 163 164 164 + 164 164 164 164 164 164 164 164 164 164 + 164 164 164 164 164 164 164 164 164 164 + 164 164 164 164 164 164 164 164 164 164 + 164 164 164 164 164 164 164 164 164 164 + 164 165 165 165 165 165 165 165 165 165 + 165 165 165 165 165 165 165 165 165 165 + 165 165 165 165 165 165 165 165 165 165 + 165 165 165 165 165 165 165 165 165 165 + 166 166 166 166 166 166 166 166 166 166 + 166 166 166 166 166 166 166 166 166 166 + 166 166 166 166 166 166 166 166 166 166 + 166 166 166 166 166 166 167 167 167 167 + 167 167 167 167 167 167 167 167 167 167 + 167 167 167 167 167 167 167 167 167 167 + 167 167 167 167 167 167 167 167 167 168 + 168 168 168 168 168 168 168 168 168 168 + 168 168 168 168 168 168 168 168 168 168 + 168 168 168 168 168 168 168 168 168 168 + 169 169 169 169 169 169 169 169 169 169 + 169 169 169 169 169 169 169 169 169 169 + 169 169 169 169 169 169 169 169 169 169 + 170 170 170 170 170 170 170 170 170 170 + 170 170 170 170 170 170 170 170 170 170 + 170 170 170 170 170 170 170 170 171 171 + 171 171 171 171 171 171 171 171 171 171 + 171 171 171 171 171 171 171 171 171 171 + 171 171 171 171 172 172 172 172 172 172 + 172 172 172 172 172 172 172 172 172 172 + 172 172 172 172 172 172 172 172 172 172 + 173 173 173 173 173 173 173 173 173 173 + 173 173 173 173 173 173 173 173 173 173 + 173 173 173 173 173 174 174 174 174 174 + 174 174 174 174 174 174 174 174 174 174 + 174 174 174 174 174 174 174 174 174 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 175 175 175 175 175 175 175 175 + 175 175 176 176 176 176 176 176 176 176 + 176 176 176 176 176 176 176 176 176 176 + 176 176 176 176 177 177 177 177 177 177 + 177 177 177 177 177 177 177 177 177 177 + 177 177 177 177 177 177 178 178 178 178 + 178 178 178 178 178 178 178 178 178 178 + 178 178 178 178 178 178 178 178 179 179 + 179 179 179 179 179 179 179 179 179 179 + 179 179 179 179 179 179 179 179 179 180 + 180 180 180 180 180 180 180 180 180 180 + 180 180 180 180 180 180 180 180 180 181 + 181 181 181 181 181 181 181 181 181 181 + 181 181 181 181 181 181 181 181 181 182 + 182 182 182 182 182 182 182 182 182 182 + 182 182 182 182 182 182 182 182 182 183 + 183 183 183 183 183 183 183 183 183 183 + 183 183 183 183 183 183 183 183 184 184 + 184 184 184 184 184 184 184 184 184 184 + 184 184 184 184 184 184 184 185 185 185 + 185 185 185 185 185 185 185 185 185 185 + 185 185 185 185 185 185 186 186 186 186 + 186 186 186 186 186 186 186 186 186 186 + 186 186 186 186 187 187 187 187 187 187 + 187 187 187 187 187 187 187 187 187 187 + 187 187 188 188 188 188 188 188 188 188 + 188 188 188 188 188 188 188 188 188 188 + 189 189 189 189 189 189 189 189 189 189 + 189 189 189 189 189 189 189 189 190 190 + 190 190 190 190 190 190 190 190 190 190 + 190 190 190 190 190 190 191 191 191 191 + 191 191 191 191 191 191 191 191 191 191 + 191 191 191 192 192 192 192 192 192 192 + 192 192 192 192 192 192 192 192 192 192 + 193 193 193 193 193 193 193 193 193 193 + 193 193 193 193 193 193 193 194 194 194 + 194 194 194 194 194 194 194 194 194 194 + 194 194 194 194 195 195 195 195 195 195 + 195 195 195 195 195 195 195 195 195 195 + 195 196 196 196 196 196 196 196 196 196 + 196 196 196 196 196 196 196 196 197 197 + 197 197 197 197 197 197 197 197 197 197 + 197 197 197 197 198 198 198 198 198 198 + 198 198 198 198 198 198 198 198 198 198 + 198 199 199 199 199 199 199 199 199 199 + 199 199 199 199 199 199 199 200 200 200 + 200 200 200 200 200 200 200 200 200 200 + 200 200 200 201 201 201 201 201 201 201 + 201 201 201 201 201 201 201 201 201 201 + 202 202 202 202 202 202 202 202 202 202 + 202 202 202 202 202 202 203 203 203 203 + 203 203 203 203 203 203 203 203 203 203 + 203 203 204 204 204 204 204 204 204 204 + 204 204 204 204 204 204 204 204 205 205 + 205 205 205 205 205 205 205 205 205 205 + 205 205 205 205 206 206 206 206 206 206 + 206 206 206 206 206 206 206 206 206 206 + 207 207 207 207 207 207 207 207 207 207 + 207 207 207 207 207 207 208 208 208 208 + 208 208 208 208 208 208 208 208 208 208 + 208 208 208 209 209 209 209 209 209 209 + 209 209 209 209 209 209 209 209 209 210 + 210 210 210 210 210 210 210 210 210 210 + 210 210 210 210 210 211 211 211 211 211 + 211 211 211 211 211 211 211 211 211 211 + 211 212 212 212 212 212 212 212 212 212 + 212 212 212 212 212 212 212 213 213 213 + 213 213 213 213 213 213 213 213 213 213 + 213 213 213 213 214 214 214 214 214 214 + 214 214 214 214 214 214 214 214 214 214 + 215 215 215 215 215 215 215 215 215 215 + 215 215 215 215 215 215 215 216 216 216 + 216 216 216 216 216 216 216 216 216 216 + 216 216 216 217 217 217 217 217 217 217 + 217 217 217 217 217 217 217 217 217 217 + 218 218 218 218 218 218 218 218 218 218 + 218 218 218 218 218 218 218 219 219 219 + 219 219 219 219 219 219 219 219 219 219 + 219 219 219 219 220 220 220 220 220 220 + 220 220 220 220 220 220 220 220 220 220 + 220 220 221 221 221 221 221 221 221 221 + 221 221 221 221 221 221 221 221 221 222 + 222 222 222 222 222 222 222 222 222 222 + 222 222 222 222 222 222 222 223 223 223 + 223 223 223 223 223 223 223 223 223 223 + 223 223 223 223 223 224 224 224 224 224 + 224 224 224 224 224 224 224 224 224 224 + 224 224 224 224 225 225 225 225 225 225 + 225 225 225 225 225 225 225 225 225 225 + 225 225 225 226 226 226 226 226 226 226 + 226 226 226 226 226 226 226 226 226 226 + 226 226 227 227 227 227 227 227 227 227 + 227 227 227 227 227 227 227 227 227 227 + 227 227 228 228 228 228 228 228 228 228 + 228 228 228 228 228 228 228 228 228 228 + 228 228 229 229 229 229 229 229 229 229 + 229 229 229 229 229 229 229 229 229 229 + 229 229 229 229 230 230 230 230 230 230 + 230 230 230 230 230 230 230 230 230 230 + 230 230 230 230 230 230 231 231 231 231 + 231 231 231 231 231 231 231 231 231 231 + 231 231 231 231 231 231 231 231 231 232 + 232 232 232 232 232 232 232 232 232 232 + 232 232 232 232 232 232 232 232 232 232 + 232 232 232 233 233 233 233 233 233 233 + 233 233 233 233 233 233 233 233 233 233 + 233 233 233 233 233 233 233 233 233 233 + 234 234 234 234 234 234 234 234 234 234 + 234 234 234 234 234 234 234 234 234 234 + 234 234 234 234 234 234 234 234 235 235 + 235 235 235 235 235 235 235 235 235 235 + 235 235 235 235 235 235 235 235 235 235 + 235 235 235 235 235 235 235 235 235 235 + 236 236 236 236 236 236 236 236 236 236 + 236 236 236 236 236 236 236 236 236 236 + 236 236 236 236 236 236 236 236 236 236 + 236 236 236 236 236 236 236 236 237 237 + 237 237 237 237 237 237 237 237 237 237 + 237 237 237 237 237 237 237 237 237 237 + 237 237 237 237 237 237 237 237 237 237 + 237 237 237 237 237 237 237 237 237 237 + 237 237 237 237 237 237 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 238 238 238 238 238 238 238 238 238 + 238 diff --git a/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.dat b/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.dat new file mode 100644 index 000000000..cc2d2b0d4 --- /dev/null +++ b/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.dat @@ -0,0 +1,602 @@ +10.000 0.025 160.000 PbSO4 XrayDif (Rietveld Round Robin, R.J. Hill, JApC 2 + 179 147 165 172 150 165 150 158 134 146 + 167 159 139 145 165 150 149 156 143 166 + 154 131 144 131 140 147 155 148 140 138 + 127 146 147 114 129 129 128 136 148 132 + 141 135 141 145 131 142 148 151 127 133 + 131 125 129 128 134 142 115 138 125 120 + 130 118 118 116 119 101 117 142 112 114 + 111 122 131 107 121 123 120 126 125 120 + 103 121 109 115 122 123 107 126 133 120 + 100 130 130 109 116 121 99 107 110 136 + 113 102 117 111 105 92 110 116 124 111 + 91 106 122 121 119 114 129 95 117 102 + 102 117 99 124 107 108 99 113 104 92 + 98 107 88 96 104 81 111 78 104 119 + 106 105 96 81 95 96 103 91 112 107 + 87 112 92 79 92 103 97 102 86 97 + 103 93 111 95 96 93 85 104 98 108 + 76 92 95 89 105 95 92 105 89 99 + 101 97 93 99 100 83 93 96 69 101 + 97 85 95 85 111 85 86 100 88 98 + 92 93 94 93 81 98 78 79 93 81 + 88 73 85 106 88 94 96 91 101 89 + 87 95 87 97 81 87 93 90 73 98 + 86 80 82 97 80 81 80 81 73 106 + 92 101 98 104 106 98 114 97 129 112 + 141 167 157 200 215 321 397 434 445 313 + 197 155 110 118 86 110 95 93 98 80 + 85 106 86 103 92 88 94 79 92 106 + 82 104 94 88 97 93 90 120 93 106 + 89 92 100 91 99 81 89 79 91 84 + 92 107 99 92 87 88 67 81 86 85 + 103 85 77 105 93 96 93 85 75 105 + 85 89 86 76 86 71 101 100 89 74 + 101 103 95 100 87 94 84 102 92 80 + 82 105 84 83 93 92 105 94 88 97 + 88 110 110 84 89 98 92 86 110 98 + 93 94 104 96 105 99 117 111 100 125 + 99 107 107 98 84 112 99 93 108 100 + 91 98 124 98 121 114 93 87 95 95 + 121 102 127 119 118 107 100 95 116 136 + 92 127 127 115 124 130 123 137 136 165 + 150 173 190 211 212 255 264 305 353 415 + 507 623 833 1076 1417 1958 2624 3927 5466 7996 + 11062 12925 12506 10327 8178 6771 5910 4886 3432 2110 + 1182 802 623 527 435 393 356 333 295 316 + 280 248 264 216 202 211 187 168 208 160 + 171 149 166 138 168 129 147 134 125 137 + 112 128 134 121 138 103 124 115 119 109 + 119 116 127 133 121 109 114 113 120 118 + 102 110 118 123 116 112 107 121 104 124 + 105 128 115 128 99 130 109 125 138 141 + 135 125 140 152 177 177 191 195 225 258 + 301 337 468 618 837 1082 1507 2283 3235 4791 + 6588 8176 8122 6687 5078 3206 1822 1101 712 566 + 470 381 302 277 259 259 212 198 189 153 + 182 178 175 164 139 176 159 147 172 167 + 159 180 168 162 166 147 149 161 173 145 + 210 201 257 262 342 451 598 796 1089 1648 + 2386 3203 3155 2711 1970 1292 729 450 289 285 + 218 211 202 168 165 177 176 197 164 141 + 160 160 157 145 165 158 158 197 179 203 + 194 216 282 282 364 456 632 854 1213 1815 + 2863 4063 4649 4165 3168 2329 1423 738 438 367 + 295 246 246 191 179 178 170 182 158 182 + 179 184 181 169 171 191 175 216 195 224 + 209 251 257 298 297 378 406 499 590 746 + 983 1402 2108 3097 4641 7229 10690 13494 13106 10401 + 7908 5365 2857 1575 947 697 595 529 450 423 + 344 319 309 252 257 252 266 275 257 285 + 285 270 280 347 282 362 426 461 637 693 + 1051 1425 2158 3198 5190 8004 10350 9724 7797 6126 + 4329 2276 1177 756 591 486 352 340 314 270 + 256 253 245 206 212 183 205 185 164 197 + 167 175 159 152 162 168 151 153 128 167 + 147 140 139 153 153 154 145 147 134 160 + 137 134 131 157 137 145 151 164 171 172 + 165 168 162 193 169 199 186 208 196 182 + 246 245 284 340 364 382 519 665 837 1080 + 1566 2321 3438 5181 8141 12608 15702 14432 12071 9687 + 7137 4123 2094 1334 1013 780 668 467 438 379 + 355 263 287 299 247 253 236 223 193 198 + 184 204 185 174 201 168 185 175 171 153 + 162 135 159 139 147 127 143 140 115 142 + 123 156 133 135 128 130 127 120 121 106 + 134 114 107 123 111 92 134 87 130 97 + 101 113 119 122 114 117 84 105 111 104 + 119 119 101 117 122 105 128 116 126 115 + 121 116 144 141 128 148 165 172 182 174 + 193 230 247 312 325 423 589 755 1130 1670 + 2522 3976 5312 5540 4806 3984 3579 2684 1672 977 + 645 451 390 317 305 278 234 264 246 263 + 239 271 260 299 300 332 411 497 630 918 + 1214 1839 2852 4745 6636 7831 7010 5926 5069 4251 + 2900 1743 1167 841 646 517 412 354 301 282 + 234 204 235 226 207 200 180 180 179 172 + 180 157 154 173 198 147 168 157 199 209 + 242 257 328 467 631 994 1449 1522 1193 977 + 947 796 548 358 251 190 164 159 137 134 + 136 126 122 128 108 100 120 106 123 117 + 113 108 121 104 104 100 105 107 108 103 + 108 123 92 122 97 101 92 114 89 81 + 113 76 89 99 89 98 98 104 120 100 + 99 89 111 98 96 95 84 115 106 100 + 86 110 86 98 97 109 112 105 86 102 + 91 98 111 89 95 95 84 114 108 96 + 94 94 102 91 106 103 82 121 101 109 + 112 104 103 105 112 119 116 119 115 106 + 122 116 120 130 107 137 132 131 140 150 + 149 161 190 210 234 297 378 583 909 1431 + 2164 2620 2390 1970 1772 1685 1327 891 543 352 + 292 230 177 182 207 158 143 129 161 133 + 119 120 128 118 121 132 135 134 132 135 + 156 182 207 266 351 368 312 269 260 249 + 219 174 157 146 135 137 136 103 107 99 + 133 129 147 130 115 123 109 106 115 136 + 119 126 131 135 116 112 123 116 121 136 + 147 130 156 138 133 144 163 171 198 191 + 196 226 243 294 352 472 630 984 1383 2157 + 2946 2947 2469 1988 2056 1767 1317 793 524 362 + 282 264 227 186 194 168 177 199 174 169 + 183 194 204 189 213 296 350 476 746 894 + 816 615 549 596 524 395 306 223 164 206 + 198 162 173 163 144 169 160 156 143 187 + 146 146 157 177 173 171 197 214 254 333 + 505 760 1047 1074 910 689 698 717 570 382 + 273 291 231 278 239 272 257 316 315 377 + 419 593 709 1116 1749 2604 3739 4133 3642 2835 + 2622 2580 2147 1381 844 578 447 351 339 309 + 260 268 240 250 233 275 281 285 381 450 + 601 801 895 881 726 644 608 589 498 386 + 283 277 254 276 249 224 213 196 234 186 + 215 191 211 189 204 193 227 221 225 199 + 187 193 214 235 241 232 239 254 252 264 + 251 260 320 375 379 442 425 492 574 693 + 816 1046 1286 1773 2593 4047 6544 9907 12440 12196 + 9815 8006 7742 7431 5975 3773 2148 1465 1080 849 + 683 579 560 480 481 470 468 450 469 498 + 468 528 615 632 765 985 1263 1833 2821 4290 + 5647 5682 5372 5802 7664 7744 5866 4103 3552 3442 + 2855 1843 1102 771 578 517 456 381 379 335 + 326 303 286 287 274 272 282 267 236 255 + 238 218 224 209 228 244 234 221 237 224 + 217 187 261 216 246 244 282 276 314 333 + 385 413 609 855 1397 2190 3180 3151 2427 1819 + 1843 2058 1720 1115 716 480 364 297 300 267 + 227 215 189 213 174 175 193 183 178 166 + 171 171 172 161 151 143 141 139 172 153 + 169 141 125 135 142 134 142 138 152 159 + 140 143 136 147 144 148 153 112 148 138 + 119 121 160 136 164 137 166 142 158 176 + 175 183 249 309 389 541 720 682 600 452 + 443 453 437 329 289 226 201 182 160 178 + 146 181 142 201 182 174 168 174 233 275 + 331 464 712 969 1093 984 752 624 651 695 + 597 460 284 261 211 196 175 167 165 143 + 153 155 137 161 131 138 125 114 154 114 + 118 120 130 117 126 132 122 133 122 113 + 128 139 126 140 120 122 122 136 116 113 + 103 120 129 112 118 140 135 101 128 115 + 126 120 119 107 122 124 123 159 132 136 + 115 142 132 144 140 131 112 147 129 129 + 106 129 127 122 155 130 121 131 173 157 + 146 153 168 199 204 212 232 255 319 410 + 629 1090 1814 2668 2463 1752 1187 1257 1542 1549 + 1066 624 387 314 267 208 211 210 181 170 + 154 155 143 171 156 134 142 142 136 139 + 139 132 152 123 137 125 132 133 137 148 + 121 150 139 127 127 146 147 155 131 144 + 148 138 149 154 142 141 181 185 169 181 + 203 236 232 335 428 600 826 1143 1282 1262 + 1070 962 964 871 886 728 557 468 370 267 + 235 203 187 181 188 189 166 167 175 191 + 184 181 226 228 258 216 233 250 287 332 + 441 506 459 447 383 372 397 408 434 419 + 346 392 441 622 912 1096 1359 1605 1949 1937 + 1843 2020 1980 1741 1467 1209 1080 998 719 548 + 393 314 277 248 204 179 180 168 160 170 + 160 184 179 164 149 156 140 161 149 134 + 126 143 138 142 163 131 161 131 147 150 + 160 128 126 128 152 134 158 135 162 157 + 173 156 162 158 164 155 194 195 196 253 + 262 350 464 665 937 1141 1055 834 657 648 + 638 752 672 543 404 370 386 469 560 465 + 360 285 276 355 364 291 228 190 194 195 + 180 163 154 156 184 181 152 176 177 160 + 178 185 175 206 214 244 255 254 373 514 + 623 827 875 884 951 1181 1887 2582 2875 2303 + 1613 1270 1312 1510 1599 1288 890 794 643 683 + 884 1207 1571 1762 1506 1186 969 975 1015 1048 + 938 733 494 392 292 276 254 229 216 203 + 194 189 192 181 191 163 175 186 149 175 + 142 180 136 151 177 156 159 174 148 147 + 141 145 156 144 149 145 127 143 159 129 + 161 138 145 165 172 184 217 266 272 313 + 288 275 321 323 439 573 743 906 960 812 + 566 541 535 554 567 599 473 359 290 254 + 189 184 196 210 190 179 148 160 147 122 + 148 141 140 142 114 150 151 132 153 140 + 118 128 140 136 122 130 135 133 165 160 + 163 166 190 264 331 334 297 215 205 212 + 268 226 256 199 165 148 159 132 154 139 + 121 144 131 136 139 120 129 130 143 127 + 150 156 154 153 162 208 247 207 192 179 + 148 154 204 186 208 175 141 111 124 132 + 127 125 124 147 143 135 136 143 145 143 + 148 151 139 142 135 161 143 139 136 158 + 164 167 165 181 147 160 195 209 190 226 + 195 241 278 302 344 427 563 789 990 1317 + 1792 2342 2479 2083 1541 1233 1186 1301 1408 1348 + 1086 761 509 405 349 309 273 269 244 252 + 286 309 289 316 317 259 228 223 259 237 + 212 212 201 184 201 170 165 182 182 183 + 199 200 208 190 185 230 275 352 448 647 + 956 1241 1280 1063 730 559 576 678 833 919 + 838 736 578 449 352 332 306 308 321 300 + 245 216 201 182 162 147 163 193 149 171 + 166 202 155 141 162 155 166 190 174 189 + 211 169 195 197 235 250 286 344 394 561 + 722 930 1317 1481 1358 1037 813 746 717 877 + 916 896 663 502 396 302 255 280 238 238 + 233 267 258 267 346 468 667 897 976 870 + 617 478 483 485 541 636 625 465 354 276 + 231 232 190 216 192 191 172 178 212 172 + 174 183 142 176 174 159 196 194 202 246 + 258 272 227 206 220 234 235 252 241 246 + 280 326 391 456 640 670 639 521 515 493 + 632 854 1153 1468 1384 1196 879 770 660 705 + 773 815 766 626 469 409 338 280 267 303 + 290 315 308 375 471 637 830 1073 1024 833 + 639 528 502 569 667 732 600 516 444 417 + 430 431 409 399 319 289 333 368 368 375 + 332 257 253 244 250 251 239 260 202 234 + 236 222 268 246 261 301 352 434 507 687 + 891 929 869 744 766 883 1213 1390 1383 1276 + 1228 1172 1129 970 905 839 745 632 628 600 + 552 393 307 265 275 215 233 208 186 180 + 200 182 178 170 180 177 190 173 203 200 + 185 218 207 244 220 243 266 280 324 394 + 567 690 853 934 815 877 894 888 744 665 + 674 693 634 583 589 572 455 501 497 637 + 833 1120 968 776 526 397 372 472 548 682 + 632 479 341 304 211 213 199 185 190 194 + 183 193 204 201 264 298 373 364 306 270 + 271 259 298 371 433 565 625 581 460 365 + 291 270 311 317 411 435 426 481 415 358 + 268 245 239 204 246 236 272 241 203 182 + 189 163 165 161 145 149 163 166 138 141 + 158 145 131 135 147 133 140 144 155 157 + 196 193 175 172 174 148 164 177 183 250 + 310 439 401 356 276 178 216 209 222 263 + 281 270 217 181 183 174 171 151 142 130 + 147 146 148 124 129 128 135 143 135 145 + 134 131 154 135 139 155 143 151 154 160 + 141 160 155 171 166 159 187 205 212 230 + 313 346 402 511 535 696 717 624 520 421 + 399 344 380 468 482 453 373 267 229 209 + 176 193 210 179 173 207 225 265 315 289 + 229 197 204 221 249 258 290 401 434 421 + 368 358 396 462 547 580 497 442 397 313 + 316 296 341 355 373 333 274 262 290 329 + 333 356 280 237 214 238 243 204 239 255 + 249 226 191 222 193 236 264 308 340 330 + 282 229 235 204 203 252 249 232 222 217 + 226 222 238 265 341 339 338 302 275 242 + 218 232 297 360 399 423 365 273 254 262 + 216 316 339 402 509 598 700 742 619 470 + 398 379 352 351 379 443 466 438 357 289 + 258 233 216 241 235 277 309 358 356 323 + 273 243 224 243 250 220 267 291 282 252 + 255 328 357 411 375 323 267 240 208 209 + 236 248 261 256 244 203 173 170 174 168 + 167 181 159 195 168 180 186 175 191 213 + 274 266 323 421 552 799 1129 1277 1123 820 + 610 504 408 478 543 708 817 736 641 568 + 413 433 373 314 321 244 262 251 232 241 + 216 240 212 196 173 187 175 173 152 163 + 143 135 122 139 128 134 140 117 150 134 + 152 127 170 158 155 173 161 136 128 177 + 165 140 154 143 168 189 130 160 151 182 + 221 238 260 315 327 311 246 211 204 196 + 211 191 234 225 255 200 186 186 162 140 + 153 147 143 153 154 133 145 148 165 155 + 155 147 176 149 165 136 163 163 198 215 + 249 304 377 414 339 322 284 301 311 380 + 550 624 660 617 461 363 284 266 268 289 + 340 375 363 327 259 216 172 180 208 177 + 157 189 192 222 222 188 184 164 173 182 + 153 158 158 183 190 178 169 145 170 138 + 169 133 134 122 126 153 112 125 127 147 + 125 125 142 143 138 145 166 165 156 154 + 169 130 173 155 178 211 247 289 310 276 + 303 376 468 665 803 829 683 570 507 383 + 335 352 412 522 575 652 681 634 466 368 + 301 214 226 205 239 226 271 279 280 247 + 223 201 199 198 206 191 154 174 144 155 + 161 172 178 192 155 171 155 160 138 156 + 178 163 191 200 208 186 167 183 157 148 + 163 174 187 182 189 190 190 199 240 247 + 334 391 512 618 663 593 456 395 343 288 + 292 310 392 389 437 361 351 262 250 233 + 197 195 171 174 171 159 158 120 128 140 + 148 156 133 156 144 163 158 158 154 165 + 196 206 256 278 255 253 223 190 196 176 + 171 212 204 252 224 192 180 172 166 159 + 155 148 167 137 178 161 180 156 169 178 + 174 181 172 238 209 240 343 384 500 673 + 704 763 656 551 406 354 352 301 357 414 + 440 502 459 425 378 418 427 467 441 400 + 327 278 259 240 213 206 241 263 287 291 + 245 243 198 195 195 164 178 161 161 183 + 177 177 177 192 219 260 310 337 312 290 + 275 243 192 200 212 205 180 219 274 271 + 200 205 195 179 171 171 147 147 167 159 + 157 145 164 142 143 164 157 153 145 168 + 159 169 137 182 196 218 216 223 269 295 + 288 280 281 187 264 216 220 242 264 272 + 326 362 407 468 432 443 383 393 367 415 + 471 595 626 583 491 456 411 322 328 289 + 271 302 377 369 373 347 296 292 257 269 + 241 218 212 239 254 295 314 356 301 277 + 252 251 186 197 162 192 231 223 207 238 + 196 196 176 171 178 146 169 161 149 173 + 156 143 154 152 139 184 185 161 159 152 + 159 176 164 168 193 195 187 237 228 265 + 291 347 409 454 552 524 552 502 483 433 + 382 363 322 328 389 469 485 438 491 415 + 377 375 322 288 280 263 275 245 243 239 + 247 216 204 210 196 220 209 212 226 201 + 225 228 210 244 298 405 445 534 579 538 + 495 466 410 389 387 429 460 573 607 740 + 853 781 733 593 499 398 368 334 370 358 + 391 376 394 414 383 300 294 275 246 259 + 235 239 243 277 363 383 434 436 378 373 + 386 438 464 491 539 539 523 499 478 472 + 383 345 354 352 383 370 410 453 416 396 + 392 319 335 407 461 587 741 875 863 754 + 619 485 429 336 321 296 316 385 474 539 + 571 493 420 345 272 242 219 229 203 220 + 211 190 171 195 176 218 208 212 230 265 + 314 278 306 262 281 209 235 222 223 246 + 268 316 307 316 273 247 229 201 198 173 + 202 173 212 185 197 193 193 194 169 169 + 157 167 175 140 174 146 171 142 152 171 + 150 142 161 150 163 154 149 157 192 185 + 184 205 231 238 263 324 365 388 380 421 + 418 408 385 374 346 329 297 319 322 328 + 298 290 304 311 312 319 292 241 239 202 + 206 202 227 236 307 309 385 341 324 290 + 208 241 201 202 181 217 264 229 326 303 + 345 304 296 241 242 210 187 206 194 221 + 216 245 242 251 258 232 215 189 192 163 + 158 162 174 182 169 151 187 179 167 169 + 146 149 146 158 142 164 142 153 147 163 + 160 163 127 150 159 140 136 159 171 178 + 159 162 193 156 176 161 155 146 179 208 + 186 194 252 230 219 182 179 174 147 189 + 166 142 144 177 178 215 182 160 196 200 + 159 163 150 175 144 132 160 169 138 171 + 129 167 172 135 170 172 169 199 221 233 + 283 291 299 257 239 226 185 195 194 175 + 192 182 189 210 252 217 230 223 192 205 + 179 185 155 193 190 214 215 230 223 212 + 233 221 242 216 261 265 370 406 501 447 + 488 473 365 279 283 285 282 239 267 263 + 309 349 345 322 338 308 238 221 215 197 + 205 208 222 206 204 230 240 284 313 331 + 344 297 275 267 216 230 194 195 234 196 + 198 240 255 287 314 318 255 232 213 186 + 193 156 168 155 154 187 181 194 183 206 + 191 179 174 158 176 183 184 188 222 211 + 242 267 330 363 390 397 332 288 273 199 + 218 198 206 228 206 216 256 259 301 265 + 240 206 224 183 160 190 158 161 161 143 + 144 177 175 142 129 140 166 156 126 156 + 144 146 136 145 160 147 142 150 168 164 + 168 195 207 229 260 263 294 291 279 245 + 211 240 218 197 226 253 249 289 329 377 + 412 419 371 310 258 236 243 235 224 241 + 236 239 302 286 295 329 390 376 405 380 + 376 363 361 296 313 279 295 248 253 273 + 273 275 305 282 295 295 304 318 331 336 + 336 371 349 315 280 286 238 265 226 238 + 222 224 254 303 311 297 319 302 295 299 + 325 347 294 264 265 239 227 226 250 203 + 229 202 234 220 206 230 228 259 221 276 + 276 271 278 298 341 366 384 388 410 433 + 388 382 298 327 266 250 252 252 262 270 + 257 249 251 336 305 284 293 236 224 207 + 200 174 177 180 163 150 181 174 141 156 + 143 166 148 174 153 160 159 160 155 141 + 148 157 157 161 171 164 169 170 167 189 + 220 252 328 298 286 290 266 220 171 193 + 194 170 235 195 207 227 261 320 343 339 + 411 416 350 350 288 343 300 286 283 249 + 258 232 229 233 215 250 258 250 251 245 + 233 220 257 219 207 208 191 187 198 176 + 184 190 192 159 176 166 196 172 180 208 + 219 202 177 175 170 167 175 153 145 178 + 168 153 159 179 196 175 174 168 180 139 + 157 143 156 157 151 155 158 155 141 152 + 145 158 153 149 153 150 144 150 143 172 + 141 166 170 162 206 182 172 183 175 178 + 179 157 163 182 184 177 163 172 185 159 + 185 176 169 161 173 190 193 150 175 151 + 176 166 171 187 180 216 212 269 301 313 + 319 328 299 252 252 228 200 209 202 225 + 199 251 236 263 299 302 338 248 259 262 + 213 211 206 210 168 191 159 183 202 211 + 205 206 205 223 200 184 189 186 185 205 + 197 210 206 202 174 175 190 165 173 179 + 192 168 168 181 170 200 198 219 211 238 + 222 205 221 204 219 196 210 196 234 212 + 191 250 230 226 277 263 296 319 338 385 + 408 381 356 290 284 268 222 245 214 211 + 204 227 254 236 290 305 290 337 276 281 + 238 243 231 205 205 193 180 171 185 191 + 191 190 179 169 175 199 179 189 210 191 + 206 212 210 235 205 182 185 177 171 153 + 154 152 170 155 156 153 171 188 181 180 + 201 183 191 184 187 163 161 165 160 185 + 198 164 176 182 172 172 186 189 181 231 + 209 211 227 226 193 216 211 211 193 175 + 192 209 196 195 230 231 239 311 285 263 + 289 262 214 212 218 186 191 199 183 190 + 168 194 191 195 207 218 222 241 242 219 + 189 202 202 190 225 204 223 262 258 317 + 312 304 299 278 265 221 205 225 211 203 + 192 201 197 227 184 205 216 256 253 288 + 249 280 219 217 249 229 198 193 178 205 + 210 185 179 213 233 225 232 264 271 285 + 273 342 326 401 358 432 331 361 330 283 + 282 263 245 232 219 251 241 241 265 237 + 251 266 291 301 300 280 332 285 276 261 + 262 264 280 291 292 284 266 240 219 232 + 218 192 181 184 219 187 174 184 204 197 + 217 215 213 212 218 210 224 183 178 205 + 184 185 180 197 154 171 181 155 145 184 + 180 173 168 190 169 161 174 158 167 182 + 165 183 168 159 161 155 189 186 150 168 + 186 194 155 171 151 165 175 156 163 164 + 166 185 163 202 186 183 183 155 199 176 + 188 177 165 198 170 186 188 193 190 207 + 234 205 212 216 213 266 257 269 300 330 + 339 357 382 326 325 282 284 305 353 293 + 354 327 397 378 367 341 307 311 274 313 + 351 347 326 307 293 260 283 272 272 302 + 307 313 332 337 327 331 343 329 371 392 + 418 493 471 481 485 486 422 425 387 379 + 330 338 327 321 327 386 375 412 398 371 + 398 377 382 419 397 373 325 333 311 301 + 293 291 268 279 289 278 266 268 284 258 + 251 258 247 251 211 209 220 218 191 186 + 214 213 216 227 196 202 213 186 198 224 + 177 197 160 191 209 217 216 215 200 207 + 202 234 218 252 249 281 270 287 318 319 + 370 397 434 494 424 485 464 454 461 371 + 326 309 280 332 297 277 293 303 342 293 + 322 350 360 343 387 437 442 460 486 451 + 433 459 369 415 340 328 323 291 265 305 + 279 298 320 299 306 340 314 329 324 367 + 378 335 338 293 299 293 263 285 277 283 + 326 291 311 315 351 367 353 387 404 365 + 354 382 318 310 342 355 334 382 359 322 + 317 322 315 322 260 275 282 290 318 296 + 276 281 309 281 305 298 276 252 303 282 + 308 302 293 288 268 300 319 297 302 304 + 346 392 454 519 565 590 593 601 563 482 + 500 403 417 386 328 293 321 300 313 294 + 318 294 329 329 364 360 385 412 426 405 + 418 417 358 384 387 312 316 304 295 296 + 294 273 325 330 345 300 370 350 381 297 + 316 300 270 271 292 249 263 269 273 252 + 250 225 241 245 268 276 264 282 294 314 + 303 269 295 283 293 286 264 255 259 252 + 270 255 304 293 311 285 332 321 350 358 + 431 433 427 380 413 422 348 388 355 370 + 353 322 348 325 320 369 351 400 379 399 + 406 396 397 415 439 438 437 478 495 511 + 450 497 498 433 477 484 430 431 454 399 + 382 384 351 334 347 336 330 306 330 311 + 298 301 344 335 334 303 326 359 397 356 + 347 310 347 332 312 335 334 316 309 294 + 334 342 332 279 267 257 292 288 273 245 + 269 248 228 250 249 230 238 217 238 212 + 246 246 239 262 265 264 240 250 246 226 + 227 235 226 256 190 215 236 223 227 203 + 206 190 232 230 201 219 203 216 213 208 + 224 210 202 212 205 236 220 194 199 201 + 216 237 212 225 203 241 232 260 253 257 + 282 291 283 325 333 335 293 315 297 310 + 285 285 276 258 251 269 228 215 259 235 + 257 241 289 229 267 270 284 265 274 275 + 279 277 269 267 263 299 262 263 268 235 + 232 261 236 224 251 249 247 217 238 231 + 251 261 251 308 300 333 311 283 279 289 + 281 273 244 299 263 257 209 284 256 270 + 280 276 282 293 282 285 309 299 295 307 + 253 258 255 297 296 248 286 288 259 276 + 256 257 268 246 273 271 306 287 286 303 + 283 335 330 366 380 334 362 408 432 479 + 440 484 478 479 513 472 445 466 437 414 + 396 374 314 326 326 323 316 354 315 351 + 329 370 366 415 444 423 414 412 463 464 + 424 427 411 394 383 394 330 360 359 303 + 294 289 271 288 264 284 262 274 278 293 + 289 309 292 313 286 291 303 279 298 301 + 278 261 314 299 316 353 319 339 335 341 + 306 303 298 290 317 318 296 336 295 284 + 241 276 245 247 263 270 261 239 247 250 + 209 238 247 257 255 273 272 319 274 307 + 253 284 254 274 278 237 257 249 261 242 + 256 255 236 234 250 233 250 231 252 244 + 256 226 267 246 257 255 278 292 308 274 + 375 361 344 361 347 352 322 337 267 268 + 286 279 276 252 242 277 271 275 272 295 + 281 338 320 350 381 404 451 441 452 417 + 450 436 437 440 474 453 457 438 387 386 + 366 341 337 308 329 283 296 289 297 240 + 268 282 297 291 281 305 336 324 307 332 + 328 309 315 330 291 290 344 314 324 327 + 259 268 305 304 300 285 292 289 294 278 + 261 297 252 280 245 266 283 238 266 262 + 249 255 240 239 221 251 212 233 238 249 + 256 216 262 249 248 263 281 234 290 269 + 284 233 286 275 263 245 259 276 229 261 + 273 272 231 212 233 256 241 228 234 238 + 216 207 221 233 238 217 238 251 268 259 + 230 276 257 260 255 244 258 279 291 290 + 295 289 273 306 307 264 289 270 234 252 + 243 244 251 235 234 246 239 257 218 234 + 230 253 248 257 248 255 261 275 288 301 + 283 308 268 300 305 254 251 256 280 290 + 267 278 302 264 263 289 231 271 289 268 + 310 278 280 262 234 278 288 265 302 278 + 273 279 303 318 317 312 303 312 311 308 + 304 284 281 287 262 273 284 261 241 238 + 276 276 274 262 279 274 238 278 273 274 + 260 245 293 307 304 266 287 292 295 295 + 305 300 281 287 299 268 292 267 236 248 + 272 274 237 251 245 285 252 272 258 269 + 268 299 240 263 260 315 315 295 279 295 + 333 322 338 383 339 311 323 295 275 295 + 289 294 287 275 249 232 269 258 268 290 + 253 266 234 233 223 231 252 275 267 251 + 284 281 254 265 309 269 296 290 301 297 + 300 345 298 347 345 374 366 387 392 438 + 465 470 443 511 473 474 455 473 452 460 + 440 386 385 402 418 382 348 344 360 366 + 351 322 327 318 352 341 308 357 325 367 + 383 381 376 381 434 410 412 411 393 427 + 429 441 407 412 456 389 386 382 368 352 + 367 366 364 366 352 312 345 336 284 310 + 289 318 287 303 306 320 330 334 345 367 + 407 379 410 396 429 425 449 416 394 390 + 394 404 356 350 378 369 362 311 297 307 + 293 291 338 300 290 317 312 270 313 278 + 321 327 332 337 328 301 322 334 330 315 + 311 302 338 321 317 331 335 345 317 306 + 309 336 309 299 319 310 287 281 268 260 + 279 279 289 265 261 264 260 271 265 270 + 280 304 283 289 294 325 269 282 293 275 + 283 281 283 277 284 275 277 278 273 284 + 267 270 287 316 261 283 294 275 324 306 + 302 276 392 339 309 315 322 359 308 335 + 315 318 319 328 315 303 296 300 304 283 + 292 266 279 295 258 289 272 251 305 263 + 261 299 291 276 294 259 254 297 287 257 + 284 255 260 259 300 264 300 287 298 283 + 279 271 291 304 299 272 316 298 322 306 + 268 257 279 262 269 291 258 269 295 293 + 268 264 272 272 288 270 267 277 310 292 + 276 290 319 322 316 343 345 379 383 389 + 437 371 405 427 442 424 438 396 384 381 + 329 322 319 274 318 304 316 324 275 319 + 259 272 262 270 263 266 242 265 251 276 + 277 260 256 240 278 252 286 295 268 301 + 296 268 299 298 305 293 327 343 362 367 + 358 324 322 330 356 353 351 324 359 339 + 289 330 295 293 293 300 296 319 302 276 + 293 271 283 256 258 269 272 213 257 274 + 242 245 252 212 261 281 259 253 280 255 + 229 241 242 248 259 257 256 253 281 292 + 254 273 278 277 264 219 271 279 246 268 + 282 272 270 221 262 286 267 254 267 259 + 267 276 269 251 256 228 248 243 254 254 + 245 242 250 264 274 255 281 229 263 250 + 241 259 268 285 241 255 268 257 263 266 + 298 281 271 261 280 296 283 341 280 304 + 282 258 262 279 285 319 293 322 316 348 + 341 339 321 373 376 366 402 391 405 407 + 422 395 434 419 426 385 390 375 357 343 + 359 344 285 324 317 345 303 315 288 301 + 281 327 316 260 299 302 249 293 271 296 + 258 283 268 271 305 268 234 286 278 274 + 274 253 238 291 274 300 282 303 285 323 + 340 283 355 288 335 350 313 303 338 326 + 359 372 325 325 352 345 348 330 336 310 + 343 321 329 325 329 330 311 316 327 320 + 306 348 345 330 325 371 381 421 388 403 + 413 417 391 385 376 382 420 374 352 328 + 368 diff --git a/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.pcr b/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.pcr new file mode 100644 index 000000000..68d8a47f9 --- /dev/null +++ b/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.pcr @@ -0,0 +1,63 @@ +COMM PbSO4 XrayDif (Rietveld Refinement Round Robin, R.J. Hill, JApC 2 +! Current global Chi2 (Bragg contrib.) = 11.30 +! Files => DAT-file: pbsox.dat, PCR-file: pbsox +!Job Npr Nph Nba Nex Nsc Nor Dum Iwg Ilo Ias Res Ste Nre Cry Uni Cor Opt Aut + 0 7 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +! +!Ipr Ppl Ioc Mat Pcr Ls1 Ls2 Ls3 NLI Prf Ins Rpa Sym Hkl Fou Sho Ana + 0 2 1 0 1 0 4 0 0 2 0 1 1 0 4 1 1 +! +! Lambda1 Lambda2 Ratio Bkpos Wdt Cthm muR AsyLim Rpolarz 2nd-muR -> Patt# 1 + 1.540560 1.544400 0.50000 50.000 6.000 0.8000 0.0000 160.00 0.0000 0.0000 +! +!NCY Eps R_at R_an R_pr R_gl Thmin Step Thmax PSD Sent0 + 30 0.10 0.10 0.10 0.10 0.10 10.0000 0.025000 160.0000 0.000 0.000 +! +! Excluded regions (LowT HighT) for Pattern# 1 + 0.00 10.00 + 154.00 180.00 +! +! + 0 !Number of refined parameters +! +! Zero Code SyCos Code SySin Code Lambda Code MORE ->Patt# 1 + -0.04816 0.0 0.00000 0.0 0.00000 0.0 0.000000 0.00 0 +! Background coefficients/codes for Pattern# 1 (Polynomial of 6th degree) + 154.318 100.004 -92.329 -95.599 126.679 -31.804 + 0.00 0.00 0.00 0.00 0.00 0.00 +!------------------------------------------------------------------------------- +! Data for PHASE number: 1 ==> Current R_Bragg for Pattern# 1: 9.4433 +!------------------------------------------------------------------------------- +PbSO4 +! +!Nat Dis Ang Pr1 Pr2 Pr3 Jbt Irf Isy Str Furth ATZ Nvk Npr More + 5 0 0 0.0 0.0 1.0 0 0 0 0 0 1213.030 0 7 0 +! +! +P n m a <--Space group symbol +!Atom Typ X Y Z Biso Occ In Fin N_t Spc /Codes +Pb PB 0.18788 0.25000 0.16749 1.78522 0.50000 0 0 0 0 #conn S O 0 2 + 0.00 0.00 0.00 0.00 0.00 +S S 0.06302 0.25000 0.68446 0.85413 0.50000 0 0 0 0 + 0.00 0.00 0.00 0.00 0.00 +O1 O 0.91235 0.25000 0.59346 1.33362 0.50000 0 0 0 0 + 0.00 0.00 0.00 0.00 0.00 +O2 O 0.18443 0.25000 0.53434 1.57511 0.50000 0 0 0 0 + 0.00 0.00 0.00 0.00 0.00 +O3 O 0.07573 0.01951 0.81594 1.32792 1.00000 0 0 0 0 + 0.00 0.00 0.00 0.00 0.00 +!-------> Profile Parameters for Pattern # 1 ----> Phase # 1 +! Scale Shape1 Bov Str1 Str2 Str3 Strain-Model + 0.4693346E-03 0.00000 0.00000 0.00000 0.00000 0.00000 0 + 0.00000 0.000 0.000 0.000 0.000 0.000 +! U V W X Y GauSiz LorSiz Size-Model + 0.048457 -0.083053 0.035188 0.000000 0.049268 0.000000 0.000000 0 + 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +! a b c alpha beta gamma # Cell Info + 8.479832 5.397758 6.959325 90.000000 90.000000 90.000000 # box -0.25 1.25 -0.15 1.15 -0.15 1.15 + 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 +! Pref1 Pref2 Asy1 Asy2 Asy3 Asy4 S_L D_L + 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 + 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +! 2Th1/TOF1 2Th2/TOF2 Pattern to plot + 10.000 154.000 1 diff --git a/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.prf b/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.prf new file mode 100644 index 000000000..38e65b1fd --- /dev/null +++ b/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.prf @@ -0,0 +1,6813 @@ +IGOR +WAVES TwoTheta, Iobs, Icalc, Diff +BEGIN + 10.000 179.00 126.48 52.52 + 10.025 147.00 126.35 20.65 + 10.050 165.00 126.22 38.78 + 10.075 172.00 126.09 45.91 + 10.100 150.00 125.96 24.04 + 10.125 165.00 125.83 39.17 + 10.150 150.00 125.71 24.29 + 10.175 158.00 125.58 32.42 + 10.200 134.00 125.45 8.55 + 10.225 146.00 125.32 20.68 + 10.250 167.00 125.20 41.80 + 10.275 159.00 125.07 33.93 + 10.300 139.00 124.95 14.05 + 10.325 145.00 124.82 20.18 + 10.350 165.00 124.70 40.30 + 10.375 150.00 124.57 25.43 + 10.400 149.00 124.45 24.55 + 10.425 156.00 124.32 31.68 + 10.450 143.00 124.20 18.80 + 10.475 166.00 124.08 41.92 + 10.500 154.00 123.95 30.05 + 10.525 131.00 123.83 7.17 + 10.550 144.00 123.71 20.29 + 10.575 131.00 123.59 7.41 + 10.600 140.00 123.47 16.53 + 10.625 147.00 123.35 23.65 + 10.650 155.00 123.23 31.77 + 10.675 148.00 123.11 24.89 + 10.700 140.00 122.99 17.01 + 10.725 138.00 122.87 15.13 + 10.750 127.00 122.75 4.25 + 10.775 146.00 122.63 23.37 + 10.800 147.00 122.51 24.49 + 10.825 114.00 122.39 -8.39 + 10.850 129.00 122.28 6.72 + 10.875 129.00 122.16 6.84 + 10.900 128.00 122.04 5.96 + 10.925 136.00 121.93 14.07 + 10.950 148.00 121.81 26.19 + 10.975 132.00 121.70 10.30 + 11.000 141.00 121.58 19.42 + 11.025 135.00 121.47 13.53 + 11.050 141.00 121.35 19.65 + 11.075 145.00 121.24 23.76 + 11.100 131.00 121.12 9.88 + 11.125 142.00 121.01 20.99 + 11.150 148.00 120.90 27.10 + 11.175 151.00 120.79 30.21 + 11.200 127.00 120.67 6.33 + 11.225 133.00 120.56 12.44 + 11.250 131.00 120.45 10.55 + 11.275 125.00 120.34 4.66 + 11.300 129.00 120.23 8.77 + 11.325 128.00 120.12 7.88 + 11.350 134.00 120.01 13.99 + 11.375 142.00 119.90 22.10 + 11.400 115.00 119.79 -4.79 + 11.425 138.00 119.68 18.32 + 11.450 125.00 119.57 5.43 + 11.475 120.00 119.47 0.53 + 11.500 130.00 119.36 10.64 + 11.525 118.00 119.25 -1.25 + 11.550 118.00 119.14 -1.14 + 11.575 116.00 119.04 -3.04 + 11.600 119.00 118.93 0.07 + 11.625 101.00 118.82 -17.82 + 11.650 117.00 118.72 -1.72 + 11.675 142.00 118.61 23.39 + 11.700 112.00 118.51 -6.51 + 11.725 114.00 118.40 -4.40 + 11.750 111.00 118.30 -7.30 + 11.775 122.00 118.20 3.80 + 11.800 131.00 118.09 12.91 + 11.825 107.00 117.99 -10.99 + 11.850 121.00 117.89 3.11 + 11.875 123.00 117.78 5.22 + 11.900 120.00 117.68 2.32 + 11.925 126.00 117.58 8.42 + 11.950 125.00 117.48 7.52 + 11.975 120.00 117.38 2.62 + 12.000 103.00 117.28 -14.28 + 12.025 121.00 117.18 3.82 + 12.050 109.00 117.08 -8.08 + 12.075 115.00 116.98 -1.98 + 12.100 122.00 116.88 5.12 + 12.125 123.00 116.78 6.22 + 12.150 107.00 116.68 -9.68 + 12.175 126.00 116.58 9.42 + 12.200 133.00 116.49 16.51 + 12.225 120.00 116.39 3.61 + 12.250 100.00 116.29 -16.29 + 12.275 130.00 116.20 13.80 + 12.300 130.00 116.10 13.90 + 12.325 109.00 116.00 -7.00 + 12.350 116.00 115.91 0.09 + 12.375 121.00 115.81 5.19 + 12.400 99.00 115.72 -16.72 + 12.425 107.00 115.62 -8.62 + 12.450 110.00 115.53 -5.53 + 12.475 136.00 115.43 20.57 + 12.500 113.00 115.34 -2.34 + 12.525 102.00 115.25 -13.25 + 12.550 117.00 115.15 1.85 + 12.575 111.00 115.06 -4.06 + 12.600 105.00 114.97 -9.97 + 12.625 92.00 114.88 -22.88 + 12.650 110.00 114.79 -4.79 + 12.675 116.00 114.69 1.31 + 12.700 124.00 114.60 9.40 + 12.725 111.00 114.51 -3.51 + 12.750 91.00 114.42 -23.42 + 12.775 106.00 114.33 -8.33 + 12.800 122.00 114.24 7.76 + 12.825 121.00 114.15 6.85 + 12.850 119.00 114.06 4.94 + 12.875 114.00 113.98 0.02 + 12.900 129.00 113.89 15.11 + 12.925 95.00 113.80 -18.80 + 12.950 117.00 113.71 3.29 + 12.975 102.00 113.63 -11.63 + 13.000 102.00 113.54 -11.54 + 13.025 117.00 113.45 3.55 + 13.050 99.00 113.37 -14.37 + 13.075 124.00 113.28 10.72 + 13.100 107.00 113.19 -6.19 + 13.125 108.00 113.11 -5.11 + 13.150 99.00 113.02 -14.02 + 13.175 113.00 112.94 0.06 + 13.200 104.00 112.86 -8.86 + 13.225 92.00 112.77 -20.77 + 13.250 98.00 112.69 -14.69 + 13.275 107.00 112.60 -5.60 + 13.300 88.00 112.52 -24.52 + 13.325 96.00 112.44 -16.44 + 13.350 104.00 112.36 -8.36 + 13.375 81.00 112.28 -31.28 + 13.400 111.00 112.19 -1.19 + 13.425 78.00 112.11 -34.11 + 13.450 104.00 112.03 -8.03 + 13.475 119.00 111.95 7.05 + 13.500 106.00 111.87 -5.87 + 13.525 105.00 111.79 -6.79 + 13.550 96.00 111.71 -15.71 + 13.575 81.00 111.63 -30.63 + 13.600 95.00 111.55 -16.55 + 13.625 96.00 111.47 -15.47 + 13.650 103.00 111.40 -8.40 + 13.675 91.00 111.32 -20.32 + 13.700 112.00 111.24 0.76 + 13.725 107.00 111.16 -4.16 + 13.750 87.00 111.08 -24.08 + 13.775 112.00 111.01 0.99 + 13.800 92.00 110.93 -18.93 + 13.825 79.00 110.86 -31.86 + 13.850 92.00 110.78 -18.78 + 13.875 103.00 110.70 -7.70 + 13.900 97.00 110.63 -13.63 + 13.925 102.00 110.55 -8.55 + 13.950 86.00 110.48 -24.48 + 13.975 97.00 110.41 -13.41 + 14.000 103.00 110.33 -7.33 + 14.025 93.00 110.26 -17.26 + 14.050 111.00 110.18 0.82 + 14.075 95.00 110.11 -15.11 + 14.100 96.00 110.04 -14.04 + 14.125 93.00 109.97 -16.97 + 14.150 85.00 109.89 -24.89 + 14.175 104.00 109.82 -5.82 + 14.200 98.00 109.75 -11.75 + 14.225 108.00 109.68 -1.68 + 14.250 76.00 109.61 -33.61 + 14.275 92.00 109.54 -17.54 + 14.300 95.00 109.47 -14.47 + 14.325 89.00 109.40 -20.40 + 14.350 105.00 109.33 -4.33 + 14.375 95.00 109.26 -14.26 + 14.400 92.00 109.19 -17.19 + 14.425 105.00 109.12 -4.12 + 14.450 89.00 109.05 -20.05 + 14.475 99.00 108.99 -9.99 + 14.500 101.00 108.92 -7.92 + 14.525 97.00 108.85 -11.85 + 14.550 93.00 108.78 -15.78 + 14.575 99.00 108.72 -9.72 + 14.600 100.00 108.65 -8.65 + 14.625 83.00 108.58 -25.58 + 14.650 93.00 108.52 -15.52 + 14.675 96.00 108.45 -12.45 + 14.700 69.00 108.39 -39.39 + 14.725 101.00 108.32 -7.32 + 14.750 97.00 108.26 -11.26 + 14.775 85.00 108.19 -23.19 + 14.800 95.00 108.13 -13.13 + 14.825 85.00 108.06 -23.06 + 14.850 111.00 108.00 3.00 + 14.875 85.00 107.94 -22.94 + 14.900 86.00 107.87 -21.87 + 14.925 100.00 107.81 -7.81 + 14.950 88.00 107.75 -19.75 + 14.975 98.00 107.69 -9.69 + 15.000 92.00 107.63 -15.63 + 15.025 93.00 107.56 -14.56 + 15.050 94.00 107.50 -13.50 + 15.075 93.00 107.44 -14.44 + 15.100 81.00 107.38 -26.38 + 15.125 98.00 107.32 -9.32 + 15.150 78.00 107.26 -29.26 + 15.175 79.00 107.20 -28.20 + 15.200 93.00 107.14 -14.14 + 15.225 81.00 107.08 -26.08 + 15.250 88.00 107.02 -19.02 + 15.275 73.00 106.97 -33.97 + 15.300 85.00 106.91 -21.91 + 15.325 106.00 107.18 -1.18 + 15.350 88.00 107.14 -19.14 + 15.375 94.00 107.26 -13.26 + 15.400 96.00 107.23 -11.23 + 15.425 91.00 107.20 -16.20 + 15.450 101.00 107.18 -6.18 + 15.475 89.00 107.15 -18.15 + 15.500 87.00 107.13 -20.13 + 15.525 95.00 107.11 -12.11 + 15.550 87.00 107.10 -20.10 + 15.575 97.00 107.09 -10.09 + 15.600 81.00 107.08 -26.08 + 15.625 87.00 107.08 -20.08 + 15.650 93.00 107.08 -14.08 + 15.675 90.00 107.09 -17.09 + 15.700 73.00 107.11 -34.11 + 15.725 98.00 107.14 -9.14 + 15.750 86.00 107.17 -21.17 + 15.775 80.00 107.21 -27.21 + 15.800 82.00 107.27 -25.27 + 15.825 97.00 107.34 -10.34 + 15.850 80.00 107.42 -27.42 + 15.875 81.00 107.53 -26.53 + 15.900 80.00 107.65 -27.65 + 15.925 81.00 107.80 -26.80 + 15.950 73.00 107.99 -34.99 + 15.975 106.00 108.21 -2.21 + 16.000 92.00 108.48 -16.48 + 16.025 101.00 108.80 -7.80 + 16.050 98.00 109.20 -11.20 + 16.075 104.00 109.70 -5.70 + 16.100 106.00 110.33 -4.33 + 16.125 98.00 111.18 -13.18 + 16.150 114.00 112.42 1.58 + 16.175 97.00 114.42 -17.42 + 16.200 129.00 117.94 11.06 + 16.225 112.00 124.29 -12.29 + 16.250 141.00 135.49 5.51 + 16.275 167.00 154.01 12.99 + 16.300 157.00 182.06 -25.06 + 16.325 200.00 220.32 -20.32 + 16.350 215.00 266.41 -51.41 + 16.375 321.00 313.87 7.13 + 16.400 397.00 352.18 44.82 + 16.425 434.00 369.85 64.15 + 16.450 445.00 361.07 83.93 + 16.475 313.00 329.29 -16.29 + 16.500 197.00 284.32 -87.32 + 16.525 155.00 237.09 -82.09 + 16.550 110.00 195.59 -85.59 + 16.575 118.00 163.63 -45.63 + 16.600 86.00 141.55 -55.55 + 16.625 110.00 127.63 -17.63 + 16.650 95.00 119.45 -24.45 + 16.675 93.00 114.83 -21.83 + 16.700 98.00 112.18 -14.18 + 16.725 80.00 110.57 -30.57 + 16.750 85.00 109.48 -24.48 + 16.775 106.00 108.68 -2.68 + 16.800 86.00 108.04 -22.04 + 16.825 103.00 107.52 -4.52 + 16.850 92.00 107.07 -15.07 + 16.875 88.00 106.69 -18.69 + 16.900 94.00 106.36 -12.36 + 16.925 79.00 106.07 -27.07 + 16.950 92.00 105.82 -13.82 + 16.975 106.00 105.59 0.41 + 17.000 82.00 105.39 -23.39 + 17.025 104.00 105.20 -1.20 + 17.050 94.00 105.04 -11.04 + 17.075 88.00 104.88 -16.88 + 17.100 97.00 104.75 -7.75 + 17.125 93.00 104.62 -11.62 + 17.150 90.00 104.50 -14.50 + 17.175 120.00 104.39 15.61 + 17.200 93.00 104.28 -11.28 + 17.225 106.00 104.18 1.82 + 17.250 89.00 104.09 -15.09 + 17.275 92.00 104.00 -12.00 + 17.300 100.00 103.92 -3.92 + 17.325 91.00 103.84 -12.84 + 17.350 99.00 103.77 -4.77 + 17.375 81.00 103.70 -22.70 + 17.400 89.00 103.63 -14.63 + 17.425 79.00 103.56 -24.56 + 17.450 91.00 103.50 -12.50 + 17.475 84.00 103.44 -19.44 + 17.500 92.00 103.38 -11.38 + 17.525 107.00 103.00 4.00 + 17.550 99.00 102.96 -3.96 + 17.575 92.00 102.76 -10.76 + 17.600 87.00 102.73 -15.73 + 17.625 88.00 102.69 -14.69 + 17.650 67.00 102.66 -35.66 + 17.675 81.00 102.63 -21.63 + 17.700 86.00 102.60 -16.60 + 17.725 85.00 102.56 -17.56 + 17.750 103.00 102.53 0.47 + 17.775 85.00 102.50 -17.50 + 17.800 77.00 102.47 -25.47 + 17.825 105.00 102.44 2.56 + 17.850 93.00 102.41 -9.41 + 17.875 96.00 102.38 -6.38 + 17.900 93.00 102.35 -9.35 + 17.925 85.00 102.32 -17.32 + 17.950 75.00 102.29 -27.29 + 17.975 105.00 102.26 2.74 + 18.000 85.00 102.23 -17.23 + 18.025 89.00 102.20 -13.20 + 18.050 86.00 102.17 -16.17 + 18.075 76.00 102.14 -26.14 + 18.100 86.00 102.11 -16.11 + 18.125 71.00 102.08 -31.08 + 18.150 101.00 102.05 -1.05 + 18.175 100.00 102.03 -2.03 + 18.200 89.00 102.00 -13.00 + 18.225 74.00 101.97 -27.97 + 18.250 101.00 101.94 -0.94 + 18.275 103.00 101.92 1.08 + 18.300 95.00 101.89 -6.89 + 18.325 100.00 101.86 -1.86 + 18.350 87.00 101.84 -14.84 + 18.375 94.00 101.81 -7.81 + 18.400 84.00 101.79 -17.79 + 18.425 102.00 101.76 0.24 + 18.450 92.00 101.74 -9.74 + 18.475 80.00 101.71 -21.71 + 18.500 82.00 101.69 -19.69 + 18.525 105.00 101.66 3.34 + 18.550 84.00 101.64 -17.64 + 18.575 83.00 101.61 -18.61 + 18.600 93.00 101.59 -8.59 + 18.625 92.00 101.57 -9.57 + 18.650 105.00 101.54 3.46 + 18.675 94.00 101.52 -7.52 + 18.700 88.00 101.50 -13.50 + 18.725 97.00 101.47 -4.47 + 18.750 88.00 101.45 -13.45 + 18.775 110.00 101.43 8.57 + 18.800 110.00 101.41 8.59 + 18.825 84.00 101.39 -17.39 + 18.850 89.00 101.36 -12.36 + 18.875 98.00 101.34 -3.34 + 18.900 92.00 101.32 -9.32 + 18.925 86.00 101.30 -15.30 + 18.950 110.00 101.28 8.72 + 18.975 98.00 101.26 -3.26 + 19.000 93.00 101.24 -8.24 + 19.025 94.00 101.22 -7.22 + 19.050 104.00 101.20 2.80 + 19.075 96.00 101.18 -5.18 + 19.100 105.00 101.16 3.84 + 19.125 99.00 101.14 -2.14 + 19.150 117.00 101.12 15.88 + 19.175 111.00 101.11 9.89 + 19.200 100.00 101.09 -1.09 + 19.225 125.00 101.07 23.93 + 19.250 99.00 101.05 -2.05 + 19.275 107.00 101.03 5.97 + 19.300 107.00 101.02 5.98 + 19.325 98.00 101.00 -3.00 + 19.350 84.00 100.98 -16.98 + 19.375 112.00 100.97 11.03 + 19.400 99.00 100.95 -1.95 + 19.425 93.00 100.93 -7.93 + 19.450 108.00 100.92 7.08 + 19.475 100.00 100.90 -0.90 + 19.500 91.00 100.89 -9.89 + 19.525 98.00 100.87 -2.87 + 19.550 124.00 100.85 23.15 + 19.575 98.00 100.84 -2.84 + 19.600 121.00 100.82 20.18 + 19.625 114.00 100.81 13.19 + 19.650 93.00 100.80 -7.80 + 19.675 87.00 100.78 -13.78 + 19.700 95.00 100.77 -5.77 + 19.725 95.00 113.36 -18.36 + 19.750 121.00 113.98 7.02 + 19.775 102.00 120.88 -18.88 + 19.800 127.00 121.90 5.10 + 19.825 119.00 123.01 -4.01 + 19.850 118.00 128.31 -10.31 + 19.875 107.00 129.81 -22.81 + 19.900 100.00 133.47 -33.47 + 19.925 95.00 135.35 -40.35 + 19.950 116.00 137.39 -21.39 + 19.975 136.00 139.62 -3.62 + 20.000 92.00 142.06 -50.06 + 20.025 127.00 144.74 -17.74 + 20.050 127.00 147.69 -20.69 + 20.075 115.00 150.95 -35.95 + 20.100 124.00 154.56 -30.56 + 20.125 130.00 158.57 -28.57 + 20.150 123.00 163.06 -40.06 + 20.175 137.00 168.09 -31.09 + 20.200 136.00 173.75 -37.75 + 20.225 165.00 180.15 -15.15 + 20.250 150.00 187.44 -37.44 + 20.275 173.00 195.78 -22.78 + 20.300 190.00 205.37 -15.37 + 20.325 211.00 216.49 -5.49 + 20.350 212.00 229.47 -17.47 + 20.375 255.00 244.75 10.25 + 20.400 264.00 262.92 1.08 + 20.425 305.00 284.82 20.18 + 20.450 353.00 311.80 41.20 + 20.475 415.00 346.42 68.58 + 20.500 507.00 394.12 112.88 + 20.525 623.00 466.88 156.12 + 20.550 833.00 589.61 243.39 + 20.575 1076.00 808.71 267.29 + 20.600 1417.00 1197.90 219.10 + 20.625 1958.00 1852.95 105.05 + 20.650 2624.00 2865.16 -241.16 + 20.675 3927.00 4272.45 -345.45 + 20.700 5466.00 6003.21 -537.21 + 20.725 7996.00 7829.07 166.93 + 20.750 11062.00 9367.11 1694.89 + 20.775 12925.00 10225.68 2699.32 + 20.800 12506.00 10263.90 2242.10 + 20.825 10327.00 9620.80 706.20 + 20.850 8178.00 8561.99 -383.99 + 20.875 6771.00 7341.40 -570.40 + 20.900 5910.00 6100.43 -190.43 + 20.925 4886.00 4906.71 -20.71 + 20.950 3432.00 3806.54 -374.54 + 20.975 2110.00 2839.48 -729.48 + 21.000 1182.00 2043.13 -861.13 + 21.025 802.00 1434.55 -632.55 + 21.050 623.00 1002.41 -379.41 + 21.075 527.00 715.55 -188.55 + 21.100 435.00 535.40 -100.40 + 21.125 393.00 425.67 -32.67 + 21.150 356.00 358.29 -2.29 + 21.175 333.00 314.74 18.26 + 21.200 295.00 284.25 10.75 + 21.225 316.00 261.18 54.82 + 21.250 280.00 242.72 37.28 + 21.275 248.00 227.45 20.55 + 21.300 264.00 214.57 49.43 + 21.325 216.00 203.58 12.42 + 21.350 202.00 194.11 7.89 + 21.375 211.00 185.89 25.11 + 21.400 187.00 178.71 8.29 + 21.425 168.00 172.40 -4.40 + 21.450 208.00 166.82 41.18 + 21.475 160.00 161.87 -1.87 + 21.500 171.00 157.46 13.54 + 21.525 149.00 153.50 -4.50 + 21.550 166.00 149.95 16.05 + 21.575 138.00 146.74 -8.74 + 21.600 168.00 143.83 24.17 + 21.625 129.00 141.19 -12.19 + 21.650 147.00 138.78 8.22 + 21.675 134.00 136.58 -2.58 + 21.700 125.00 134.57 -9.57 + 21.725 137.00 132.72 4.28 + 21.750 112.00 131.01 -19.01 + 21.775 128.00 129.44 -1.44 + 21.800 134.00 127.99 6.01 + 21.825 121.00 114.69 6.31 + 21.850 138.00 113.98 24.02 + 21.875 103.00 107.35 -4.35 + 21.900 124.00 107.01 16.99 + 21.925 115.00 106.69 8.31 + 21.950 119.00 102.50 16.50 + 21.975 109.00 102.40 6.60 + 22.000 119.00 100.36 18.64 + 22.025 116.00 100.36 15.64 + 22.050 127.00 100.37 26.63 + 22.075 133.00 100.37 32.63 + 22.100 121.00 100.38 20.62 + 22.125 109.00 100.38 8.62 + 22.150 114.00 100.39 13.61 + 22.175 113.00 100.40 12.60 + 22.200 120.00 100.40 19.60 + 22.225 118.00 100.41 17.59 + 22.250 102.00 100.41 1.59 + 22.275 110.00 109.19 0.81 + 22.300 118.00 109.64 8.36 + 22.325 123.00 114.42 8.58 + 22.350 116.00 115.17 0.83 + 22.375 112.00 115.98 -3.98 + 22.400 107.00 116.86 -9.86 + 22.425 121.00 117.82 3.18 + 22.450 104.00 118.86 -14.86 + 22.475 124.00 119.99 4.01 + 22.500 105.00 121.23 -16.23 + 22.525 128.00 122.59 5.41 + 22.550 115.00 124.09 -9.09 + 22.575 128.00 125.74 2.26 + 22.600 99.00 127.58 -28.58 + 22.625 130.00 129.61 0.39 + 22.650 109.00 131.88 -22.88 + 22.675 125.00 134.43 -9.43 + 22.700 138.00 137.29 0.71 + 22.725 141.00 140.53 0.47 + 22.750 135.00 144.21 -9.21 + 22.775 125.00 148.41 -23.41 + 22.800 140.00 153.25 -13.25 + 22.825 152.00 158.85 -6.85 + 22.850 177.00 165.38 11.62 + 22.875 177.00 173.06 3.94 + 22.900 191.00 182.17 8.83 + 22.925 195.00 193.08 1.92 + 22.950 225.00 206.37 18.63 + 22.975 258.00 222.91 35.09 + 23.000 301.00 244.45 56.55 + 23.025 337.00 274.79 62.21 + 23.050 468.00 322.46 145.54 + 23.075 618.00 405.54 212.46 + 23.100 837.00 557.69 279.31 + 23.125 1082.00 831.83 250.17 + 23.150 1507.00 1294.17 212.83 + 23.175 2283.00 2001.33 281.67 + 23.200 3235.00 2962.54 272.46 + 23.225 4791.00 4096.12 694.88 + 23.250 6588.00 5198.96 1389.04 + 23.275 8176.00 5966.82 2209.18 + 23.300 8122.00 6151.44 1970.56 + 23.325 6687.00 5733.57 953.43 + 23.350 5078.00 4864.67 213.33 + 23.375 3206.00 3776.25 -570.25 + 23.400 1822.00 2713.15 -891.15 + 23.425 1101.00 1836.86 -735.86 + 23.450 712.00 1201.07 -489.07 + 23.475 566.00 785.70 -219.70 + 23.500 470.00 536.42 -66.42 + 23.525 381.00 398.85 -17.85 + 23.550 302.00 320.15 -18.15 + 23.575 277.00 274.34 2.66 + 23.600 259.00 247.01 11.99 + 23.625 259.00 226.50 32.50 + 23.650 212.00 210.90 1.10 + 23.675 198.00 198.50 -0.50 + 23.700 189.00 188.42 0.58 + 23.725 153.00 180.11 -27.11 + 23.750 182.00 173.23 8.77 + 23.775 178.00 167.50 10.50 + 23.800 175.00 162.73 12.27 + 23.825 164.00 158.76 5.24 + 23.850 139.00 155.47 -16.47 + 23.875 176.00 152.78 23.22 + 23.900 159.00 150.63 8.37 + 23.925 147.00 148.95 -1.95 + 23.950 172.00 147.73 24.27 + 23.975 167.00 146.93 20.07 + 24.000 159.00 146.56 12.44 + 24.025 180.00 146.62 33.38 + 24.050 168.00 147.13 20.87 + 24.075 162.00 148.14 13.86 + 24.100 166.00 149.70 16.30 + 24.125 147.00 151.89 -4.89 + 24.150 149.00 154.83 -5.83 + 24.175 161.00 158.69 2.31 + 24.200 173.00 163.73 9.27 + 24.225 145.00 170.38 -25.38 + 24.250 210.00 179.56 30.44 + 24.275 201.00 193.29 7.71 + 24.300 257.00 207.72 49.28 + 24.325 262.00 249.57 12.43 + 24.350 342.00 326.89 15.11 + 24.375 451.00 460.55 -9.55 + 24.400 598.00 687.12 -89.12 + 24.425 796.00 1021.22 -225.22 + 24.450 1089.00 1454.69 -365.69 + 24.475 1648.00 1934.37 -286.37 + 24.500 2386.00 2353.68 32.32 + 24.525 3203.00 2581.93 621.07 + 24.550 3155.00 2557.94 597.06 + 24.575 2711.00 2303.40 407.60 + 24.600 1970.00 1899.20 70.80 + 24.625 1292.00 1447.20 -155.20 + 24.650 729.00 1034.08 -305.08 + 24.675 450.00 711.56 -261.56 + 24.700 289.00 487.84 -198.84 + 24.725 285.00 347.25 -62.25 + 24.750 218.00 265.53 -47.53 + 24.775 211.00 220.18 -9.18 + 24.800 202.00 195.00 7.00 + 24.825 168.00 180.21 -12.21 + 24.850 165.00 170.70 -5.70 + 24.875 177.00 164.08 12.92 + 24.900 176.00 159.26 16.74 + 24.925 197.00 155.72 41.28 + 24.950 164.00 153.20 10.80 + 24.975 141.00 151.54 -10.54 + 25.000 160.00 150.64 9.36 + 25.025 160.00 150.44 9.56 + 25.050 157.00 150.92 6.08 + 25.075 145.00 152.09 -7.09 + 25.100 165.00 153.99 11.01 + 25.125 158.00 156.69 1.31 + 25.150 158.00 160.31 -2.31 + 25.175 197.00 165.03 31.97 + 25.200 179.00 171.11 7.89 + 25.225 203.00 178.94 24.06 + 25.250 194.00 189.30 4.70 + 25.275 216.00 203.80 12.20 + 25.300 282.00 226.15 55.85 + 25.325 282.00 264.60 17.40 + 25.350 364.00 335.46 28.54 + 25.375 456.00 466.13 -10.13 + 25.400 632.00 693.62 -61.62 + 25.425 854.00 1053.61 -199.61 + 25.450 1213.00 1559.61 -346.61 + 25.475 1815.00 2176.96 -361.96 + 25.500 2863.00 2801.86 61.14 + 25.525 4063.00 3260.89 802.11 + 25.550 4649.00 3409.71 1239.29 + 25.575 4165.00 3226.27 938.73 + 25.600 3168.00 2787.53 380.47 + 25.625 2329.00 2208.44 120.56 + 25.650 1423.00 1619.26 -196.26 + 25.675 738.00 1120.39 -382.39 + 25.700 438.00 767.09 -329.09 + 25.725 367.00 523.14 -156.14 + 25.750 295.00 375.54 -80.54 + 25.775 246.00 299.93 -53.93 + 25.800 246.00 254.37 -8.37 + 25.825 191.00 228.83 -37.83 + 25.850 179.00 213.44 -34.44 + 25.875 178.00 203.34 -25.34 + 25.900 170.00 196.31 -26.31 + 25.925 182.00 191.35 -9.35 + 25.950 158.00 187.95 -29.95 + 25.975 182.00 185.83 -3.83 + 26.000 179.00 184.81 -5.81 + 26.025 184.00 184.79 -0.79 + 26.050 181.00 185.70 -4.70 + 26.075 169.00 187.51 -18.51 + 26.100 171.00 190.24 -19.24 + 26.125 191.00 193.92 -2.92 + 26.150 175.00 198.64 -23.64 + 26.175 216.00 204.50 11.50 + 26.200 195.00 211.69 -16.69 + 26.225 224.00 220.40 3.60 + 26.250 209.00 230.93 -21.93 + 26.275 251.00 243.68 7.32 + 26.300 257.00 259.16 -2.16 + 26.325 298.00 278.09 19.91 + 26.350 297.00 301.50 -4.50 + 26.375 378.00 331.09 46.91 + 26.400 406.00 370.20 35.80 + 26.425 499.00 426.26 72.74 + 26.450 590.00 516.37 73.63 + 26.475 746.00 677.03 68.97 + 26.500 983.00 975.87 7.13 + 26.525 1402.00 1511.47 -109.47 + 26.550 2108.00 2414.73 -306.73 + 26.575 3097.00 3766.04 -669.04 + 26.600 4641.00 5534.97 -893.97 + 26.625 7229.00 7506.00 -277.00 + 26.650 10690.00 9222.23 1467.77 + 26.675 13494.00 10142.98 3351.02 + 26.700 13106.00 10001.29 3104.71 + 26.725 10401.00 8980.42 1420.58 + 26.750 7908.00 7380.02 527.98 + 26.775 5365.00 5556.01 -191.01 + 26.800 2857.00 3884.32 -1027.32 + 26.825 1575.00 2573.69 -998.69 + 26.850 947.00 1662.21 -715.21 + 26.875 697.00 1088.34 -391.34 + 26.900 595.00 754.55 -159.55 + 26.925 529.00 569.24 -40.24 + 26.950 450.00 465.92 -15.92 + 26.975 423.00 404.56 18.44 + 27.000 344.00 364.41 -20.41 + 27.025 319.00 335.82 -16.82 + 27.050 309.00 314.41 -5.41 + 27.075 252.00 298.15 -46.15 + 27.100 257.00 285.90 -28.90 + 27.125 252.00 276.99 -24.99 + 27.150 266.00 270.97 -4.97 + 27.175 275.00 267.57 7.43 + 27.200 257.00 266.66 -9.66 + 27.225 285.00 268.24 16.76 + 27.250 285.00 272.43 12.57 + 27.275 270.00 279.48 -9.48 + 27.300 280.00 289.84 -9.84 + 27.325 347.00 304.21 42.79 + 27.350 282.00 323.83 -41.83 + 27.375 362.00 351.14 10.86 + 27.400 426.00 391.70 34.30 + 27.425 461.00 458.47 2.53 + 27.450 637.00 579.51 57.49 + 27.475 693.00 807.61 -114.61 + 27.500 1051.00 1224.39 -173.39 + 27.525 1425.00 1925.99 -500.99 + 27.550 2158.00 2980.79 -822.79 + 27.575 3198.00 4365.56 -1167.56 + 27.600 5190.00 5902.65 -712.65 + 27.625 8004.00 7226.46 777.54 + 27.650 10350.00 7886.14 2463.86 + 27.675 9724.00 7744.84 1979.16 + 27.700 7797.00 6943.31 853.69 + 27.725 6126.00 5696.93 429.07 + 27.750 4329.00 4291.28 37.72 + 27.775 2276.00 3001.65 -725.65 + 27.800 1177.00 1989.97 -812.97 + 27.825 756.00 1286.19 -530.19 + 27.850 591.00 842.87 -251.87 + 27.875 486.00 584.74 -98.74 + 27.900 352.00 440.89 -88.89 + 27.925 340.00 359.84 -19.84 + 27.950 314.00 310.71 3.29 + 27.975 270.00 277.57 -7.57 + 28.000 256.00 253.02 2.98 + 28.025 253.00 233.73 19.27 + 28.050 245.00 218.09 26.91 + 28.075 206.00 205.17 0.83 + 28.100 212.00 194.36 17.64 + 28.125 183.00 185.23 -2.23 + 28.150 205.00 177.45 27.55 + 28.175 185.00 170.77 14.23 + 28.200 164.00 164.99 -0.99 + 28.225 197.00 159.96 37.04 + 28.250 167.00 155.56 11.44 + 28.275 175.00 151.69 23.31 + 28.300 159.00 148.26 10.74 + 28.325 152.00 145.21 6.79 + 28.350 162.00 142.49 19.51 + 28.375 168.00 140.06 27.94 + 28.400 151.00 137.87 13.13 + 28.425 153.00 135.89 17.11 + 28.450 128.00 134.10 -6.10 + 28.475 167.00 132.48 34.52 + 28.500 147.00 131.01 15.99 + 28.525 140.00 129.66 10.34 + 28.550 139.00 128.43 10.57 + 28.575 153.00 127.30 25.70 + 28.600 153.00 126.26 26.74 + 28.625 154.00 113.60 40.40 + 28.650 145.00 113.29 31.71 + 28.675 147.00 113.00 34.00 + 28.700 134.00 127.54 6.46 + 28.725 160.00 128.72 31.28 + 28.750 137.00 129.99 7.01 + 28.775 134.00 141.58 -7.58 + 28.800 131.00 143.65 -12.65 + 28.825 157.00 145.89 11.11 + 28.850 137.00 148.35 -11.35 + 28.875 145.00 151.03 -6.03 + 28.900 151.00 153.98 -2.98 + 28.925 164.00 157.22 6.78 + 28.950 171.00 160.81 10.19 + 28.975 172.00 164.78 7.22 + 29.000 165.00 169.21 -4.21 + 29.025 168.00 174.16 -6.16 + 29.050 162.00 179.71 -17.71 + 29.075 193.00 185.98 7.02 + 29.100 169.00 193.08 -24.08 + 29.125 199.00 201.18 -2.18 + 29.150 186.00 210.47 -24.47 + 29.175 208.00 221.19 -13.19 + 29.200 196.00 233.66 -37.66 + 29.225 182.00 248.28 -66.28 + 29.250 246.00 265.55 -19.55 + 29.275 245.00 286.18 -41.18 + 29.300 284.00 311.08 -27.08 + 29.325 340.00 341.56 -1.56 + 29.350 364.00 379.70 -15.70 + 29.375 382.00 429.35 -47.35 + 29.400 519.00 499.07 19.93 + 29.425 665.00 608.98 56.02 + 29.450 837.00 803.70 33.30 + 29.475 1080.00 1169.33 -89.33 + 29.500 1566.00 1841.74 -275.74 + 29.525 2321.00 2982.68 -661.68 + 29.550 3438.00 4705.89 -1267.89 + 29.575 5181.00 6965.37 -1784.37 + 29.600 8141.00 9446.57 -1305.57 + 29.625 12608.00 11513.79 1094.21 + 29.650 15702.00 12456.81 3245.19 + 29.675 14432.00 12103.46 2328.54 + 29.700 12071.00 10792.38 1278.62 + 29.725 9687.00 8855.54 831.46 + 29.750 7137.00 6662.88 474.12 + 29.775 4123.00 4645.16 -522.16 + 29.800 2094.00 3060.09 -966.09 + 29.825 1334.00 1957.05 -623.05 + 29.850 1013.00 1263.29 -250.29 + 29.875 780.00 860.83 -80.83 + 29.900 668.00 637.43 30.57 + 29.925 467.00 511.55 -44.55 + 29.950 438.00 434.75 3.25 + 29.975 379.00 382.44 -3.44 + 30.000 355.00 343.43 11.57 + 30.025 263.00 312.67 -49.67 + 30.050 287.00 287.70 -0.70 + 30.075 299.00 267.08 31.92 + 30.100 247.00 249.84 -2.84 + 30.125 253.00 235.28 17.72 + 30.150 236.00 222.89 13.11 + 30.175 223.00 212.24 10.76 + 30.200 193.00 203.03 -10.03 + 30.225 198.00 195.02 2.98 + 30.250 184.00 188.01 -4.01 + 30.275 204.00 181.83 22.17 + 30.300 185.00 176.37 8.63 + 30.325 174.00 171.51 2.49 + 30.350 201.00 167.18 33.82 + 30.375 168.00 163.29 4.71 + 30.400 185.00 159.80 25.20 + 30.425 175.00 156.65 18.35 + 30.450 171.00 153.79 17.21 + 30.475 153.00 151.20 1.80 + 30.500 162.00 148.84 13.16 + 30.525 135.00 146.68 -11.68 + 30.550 159.00 144.71 14.29 + 30.575 139.00 142.90 -3.90 + 30.600 147.00 121.75 25.25 + 30.625 127.00 121.19 5.81 + 30.650 143.00 120.67 22.33 + 30.675 140.00 110.49 29.51 + 30.700 115.00 110.54 4.46 + 30.725 142.00 110.59 31.41 + 30.750 123.00 110.64 12.36 + 30.775 156.00 110.69 45.31 + 30.800 133.00 110.74 22.26 + 30.825 135.00 110.78 24.22 + 30.850 128.00 110.83 17.17 + 30.875 130.00 110.88 19.12 + 30.900 127.00 110.93 16.07 + 30.925 120.00 110.98 9.02 + 30.950 121.00 111.03 9.97 + 30.975 106.00 111.07 -5.07 + 31.000 134.00 111.12 22.88 + 31.025 114.00 111.17 2.83 + 31.050 107.00 111.22 -4.22 + 31.075 123.00 111.27 11.73 + 31.100 111.00 111.32 -0.32 + 31.125 92.00 111.37 -19.37 + 31.150 134.00 111.42 22.58 + 31.175 87.00 111.47 -24.47 + 31.200 130.00 111.52 18.48 + 31.225 97.00 111.57 -14.57 + 31.250 101.00 111.62 -10.62 + 31.275 113.00 111.66 1.34 + 31.300 119.00 111.71 7.29 + 31.325 122.00 111.76 10.24 + 31.350 114.00 111.81 2.19 + 31.375 117.00 111.86 5.14 + 31.400 84.00 120.23 -36.23 + 31.425 105.00 120.75 -15.75 + 31.450 111.00 121.32 -10.32 + 31.475 104.00 121.94 -17.94 + 31.500 119.00 126.90 -7.90 + 31.525 119.00 127.87 -8.87 + 31.550 101.00 128.94 -27.94 + 31.575 117.00 130.11 -13.11 + 31.600 122.00 131.40 -9.40 + 31.625 105.00 132.81 -27.81 + 31.650 128.00 134.38 -6.38 + 31.675 116.00 136.13 -20.13 + 31.700 126.00 138.08 -12.08 + 31.725 115.00 140.26 -25.26 + 31.750 121.00 142.73 -21.73 + 31.775 116.00 145.52 -29.52 + 31.800 144.00 148.71 -4.71 + 31.825 141.00 152.36 -11.36 + 31.850 128.00 156.58 -28.58 + 31.875 148.00 161.49 -13.49 + 31.900 165.00 167.26 -2.26 + 31.925 172.00 174.09 -2.09 + 31.950 182.00 182.26 -0.26 + 31.975 174.00 192.15 -18.15 + 32.000 193.00 204.30 -11.30 + 32.025 230.00 219.52 10.48 + 32.050 247.00 239.36 7.64 + 32.075 312.00 267.19 44.81 + 32.100 325.00 311.12 13.88 + 32.125 423.00 389.60 33.40 + 32.150 589.00 538.80 50.20 + 32.175 755.00 815.84 -60.84 + 32.200 1130.00 1286.60 -156.60 + 32.225 1670.00 2001.30 -331.30 + 32.250 2522.00 2904.78 -382.78 + 32.275 3976.00 3850.18 125.82 + 32.300 5312.00 4551.80 760.20 + 32.325 5540.00 4764.04 775.96 + 32.350 4806.00 4513.49 292.51 + 32.375 3984.00 3981.50 2.50 + 32.400 3579.00 3266.13 312.87 + 32.425 2684.00 2472.32 211.68 + 32.450 1672.00 1747.79 -75.79 + 32.475 977.00 1183.10 -206.10 + 32.500 645.00 794.07 -149.07 + 32.525 451.00 553.37 -102.37 + 32.550 390.00 417.04 -27.04 + 32.575 317.00 343.67 -26.67 + 32.600 305.00 303.88 1.12 + 32.625 278.00 280.95 -2.95 + 32.650 234.00 266.82 -32.82 + 32.675 264.00 258.02 5.98 + 32.700 246.00 253.10 -7.10 + 32.725 263.00 251.45 11.55 + 32.750 239.00 252.85 -13.85 + 32.775 271.00 257.33 13.67 + 32.800 260.00 265.18 -5.18 + 32.825 299.00 276.97 22.03 + 32.850 300.00 293.83 6.17 + 32.875 332.00 318.16 13.84 + 32.900 411.00 355.75 55.25 + 32.925 497.00 420.57 76.43 + 32.950 630.00 543.13 86.87 + 32.975 918.00 779.03 138.97 + 33.000 1214.00 1206.91 7.09 + 33.025 1839.00 1901.04 -62.04 + 33.050 2852.00 2877.23 -25.23 + 33.075 4745.00 4030.26 714.74 + 33.100 6636.00 5088.62 1547.38 + 33.125 7831.00 5678.97 2152.03 + 33.150 7010.00 5654.16 1355.84 + 33.175 5926.00 5208.17 717.83 + 33.200 5069.00 4516.34 552.66 + 33.225 4251.00 3638.25 612.75 + 33.250 2900.00 2723.92 176.08 + 33.275 1743.00 1926.05 -183.05 + 33.300 1167.00 1318.49 -151.49 + 33.325 841.00 898.30 -57.30 + 33.350 646.00 632.87 13.13 + 33.375 517.00 471.96 45.04 + 33.400 412.00 374.22 37.78 + 33.425 354.00 313.61 40.39 + 33.450 301.00 274.34 26.66 + 33.475 282.00 247.67 34.33 + 33.500 234.00 228.65 5.35 + 33.525 204.00 214.42 -10.42 + 33.550 235.00 203.33 31.67 + 33.575 226.00 194.44 31.56 + 33.600 207.00 187.19 19.81 + 33.625 200.00 181.25 18.75 + 33.650 180.00 176.38 3.62 + 33.675 180.00 172.40 7.60 + 33.700 179.00 169.19 9.81 + 33.725 172.00 166.68 5.32 + 33.750 180.00 164.80 15.20 + 33.775 157.00 163.53 -6.53 + 33.800 154.00 162.87 -8.87 + 33.825 173.00 162.85 10.15 + 33.850 198.00 163.55 34.45 + 33.875 147.00 165.09 -18.09 + 33.900 168.00 167.73 0.27 + 33.925 157.00 171.97 -14.97 + 33.950 199.00 179.08 19.92 + 33.975 209.00 192.17 16.83 + 34.000 242.00 217.90 24.10 + 34.025 257.00 258.25 -1.25 + 34.050 328.00 349.76 -21.76 + 34.075 467.00 495.61 -28.61 + 34.100 631.00 695.21 -64.21 + 34.125 994.00 916.17 77.83 + 34.150 1449.00 1105.62 343.38 + 34.175 1522.00 1186.72 335.28 + 34.200 1193.00 1149.79 43.21 + 34.225 977.00 1043.81 -66.81 + 34.250 947.00 898.96 48.04 + 34.275 796.00 725.73 70.27 + 34.300 548.00 551.79 -3.79 + 34.325 358.00 406.02 -48.02 + 34.350 251.00 299.75 -48.75 + 34.375 190.00 230.88 -40.88 + 34.400 164.00 190.49 -26.49 + 34.425 159.00 168.25 -9.25 + 34.450 137.00 155.98 -18.98 + 34.475 134.00 148.65 -14.65 + 34.500 136.00 143.72 -7.72 + 34.525 126.00 140.08 -14.08 + 34.550 122.00 137.24 -15.24 + 34.575 128.00 134.95 -6.95 + 34.600 108.00 133.09 -25.09 + 34.625 100.00 131.54 -31.54 + 34.650 120.00 130.25 -10.25 + 34.675 106.00 129.16 -23.16 + 34.700 123.00 128.24 -5.24 + 34.725 117.00 127.45 -10.45 + 34.750 113.00 126.78 -13.78 + 34.775 108.00 126.19 -18.19 + 34.800 121.00 125.68 -4.68 + 34.825 104.00 125.24 -21.24 + 34.850 104.00 124.85 -20.85 + 34.875 100.00 124.52 -24.52 + 34.900 105.00 124.22 -19.22 + 34.925 107.00 123.96 -16.96 + 34.950 108.00 123.73 -15.73 + 34.975 103.00 123.52 -20.52 + 35.000 108.00 123.34 -15.34 + 35.025 123.00 123.19 -0.19 + 35.050 92.00 123.05 -31.05 + 35.075 122.00 121.02 0.98 + 35.100 97.00 121.01 -24.01 + 35.125 101.00 121.01 -20.01 + 35.150 92.00 120.04 -28.04 + 35.175 114.00 120.09 -6.09 + 35.200 89.00 120.15 -31.15 + 35.225 81.00 120.21 -39.21 + 35.250 113.00 120.27 -7.27 + 35.275 76.00 120.32 -44.32 + 35.300 89.00 120.38 -31.38 + 35.325 99.00 120.44 -21.44 + 35.350 89.00 120.50 -31.50 + 35.375 98.00 120.56 -22.56 + 35.400 98.00 120.61 -22.61 + 35.425 104.00 120.67 -16.67 + 35.450 120.00 120.73 -0.73 + 35.475 100.00 120.79 -20.79 + 35.500 99.00 120.84 -21.84 + 35.525 89.00 120.90 -31.90 + 35.550 111.00 120.96 -9.96 + 35.575 98.00 121.02 -23.02 + 35.600 96.00 121.08 -25.08 + 35.625 95.00 121.14 -26.14 + 35.650 84.00 121.19 -37.19 + 35.675 115.00 121.25 -6.25 + 35.700 106.00 121.31 -15.31 + 35.725 100.00 121.37 -21.37 + 35.750 86.00 121.43 -35.43 + 35.775 110.00 121.48 -11.48 + 35.800 86.00 121.54 -35.54 + 35.825 98.00 121.60 -23.60 + 35.850 97.00 121.66 -24.66 + 35.875 109.00 121.72 -12.72 + 35.900 112.00 121.78 -9.78 + 35.925 105.00 121.83 -16.83 + 35.950 86.00 121.89 -35.89 + 35.975 102.00 121.95 -19.95 + 36.000 91.00 122.01 -31.01 + 36.025 98.00 122.07 -24.07 + 36.050 111.00 122.13 -11.13 + 36.075 89.00 122.19 -33.19 + 36.100 95.00 122.24 -27.24 + 36.125 95.00 122.30 -27.30 + 36.150 84.00 122.36 -38.36 + 36.175 114.00 122.42 -8.42 + 36.200 108.00 122.48 -14.48 + 36.225 96.00 122.54 -26.54 + 36.250 94.00 122.60 -28.60 + 36.275 94.00 122.66 -28.66 + 36.300 102.00 122.71 -20.71 + 36.325 91.00 122.77 -31.77 + 36.350 106.00 122.87 -16.87 + 36.375 103.00 122.94 -19.94 + 36.400 82.00 123.00 -41.00 + 36.425 121.00 127.31 -6.31 + 36.450 101.00 127.66 -26.66 + 36.475 109.00 128.01 -19.01 + 36.500 112.00 128.38 -16.38 + 36.525 104.00 130.93 -26.93 + 36.550 103.00 131.51 -28.51 + 36.575 105.00 132.14 -27.14 + 36.600 112.00 132.83 -20.83 + 36.625 119.00 133.60 -14.60 + 36.650 116.00 134.45 -18.45 + 36.675 119.00 135.39 -16.39 + 36.700 115.00 136.45 -21.45 + 36.725 106.00 137.64 -31.64 + 36.750 122.00 138.98 -16.98 + 36.775 116.00 140.52 -24.52 + 36.800 120.00 142.28 -22.28 + 36.825 130.00 144.31 -14.31 + 36.850 107.00 146.67 -39.67 + 36.875 137.00 149.45 -12.45 + 36.900 132.00 152.75 -20.75 + 36.925 131.00 156.71 -25.71 + 36.950 140.00 161.53 -21.53 + 36.975 150.00 167.47 -17.47 + 37.000 149.00 174.97 -25.97 + 37.025 161.00 184.79 -23.79 + 37.050 190.00 198.53 -8.53 + 37.075 210.00 219.95 -9.95 + 37.100 234.00 257.86 -23.86 + 37.125 297.00 330.30 -33.30 + 37.150 378.00 466.91 -88.91 + 37.175 583.00 702.02 -119.02 + 37.200 909.00 1053.20 -144.20 + 37.225 1431.00 1491.99 -60.99 + 37.250 2164.00 1917.28 246.72 + 37.275 2620.00 2163.38 456.62 + 37.300 2390.00 2143.57 246.43 + 37.325 1970.00 1962.08 7.92 + 37.350 1772.00 1731.94 40.06 + 37.375 1685.00 1462.16 222.84 + 37.400 1327.00 1146.60 180.40 + 37.425 891.00 838.53 52.47 + 37.450 543.00 588.56 -45.56 + 37.475 352.00 413.29 -61.29 + 37.500 292.00 305.07 -13.07 + 37.525 230.00 244.51 -14.51 + 37.550 177.00 211.93 -34.93 + 37.575 182.00 193.55 -11.55 + 37.600 207.00 181.92 25.08 + 37.625 158.00 173.69 -15.69 + 37.650 143.00 167.46 -24.46 + 37.675 129.00 162.58 -33.58 + 37.700 161.00 158.70 2.30 + 37.725 133.00 155.62 -22.62 + 37.750 119.00 153.17 -34.17 + 37.775 120.00 151.25 -31.25 + 37.800 128.00 149.81 -21.81 + 37.825 118.00 148.80 -30.80 + 37.850 121.00 148.22 -27.22 + 37.875 132.00 148.13 -16.13 + 37.900 135.00 148.68 -13.68 + 37.925 134.00 150.36 -16.36 + 37.950 132.00 154.34 -22.34 + 37.975 135.00 163.07 -28.07 + 38.000 156.00 180.47 -24.47 + 38.025 182.00 210.72 -28.72 + 38.050 207.00 255.15 -48.15 + 38.075 266.00 308.41 -42.41 + 38.100 351.00 355.26 -4.26 + 38.125 368.00 375.21 -7.21 + 38.150 312.00 360.68 -48.68 + 38.175 269.00 336.62 -67.62 + 38.200 260.00 309.76 -49.76 + 38.225 249.00 276.10 -27.10 + 38.250 219.00 239.43 -20.43 + 38.275 174.00 204.48 -30.48 + 38.300 157.00 176.81 -19.81 + 38.325 146.00 157.94 -11.94 + 38.350 135.00 146.61 -11.61 + 38.375 137.00 140.42 -3.42 + 38.400 136.00 137.12 -1.12 + 38.425 103.00 135.22 -32.22 + 38.450 107.00 134.00 -27.00 + 38.475 99.00 133.12 -34.12 + 38.500 133.00 132.45 0.55 + 38.525 129.00 131.93 -2.93 + 38.550 147.00 131.52 15.48 + 38.575 130.00 131.18 -1.18 + 38.600 115.00 130.91 -15.91 + 38.625 123.00 130.70 -7.70 + 38.650 109.00 130.52 -21.52 + 38.675 106.00 135.36 -29.36 + 38.700 115.00 135.56 -20.56 + 38.725 136.00 135.81 0.19 + 38.750 119.00 136.12 -17.12 + 38.775 126.00 136.48 -10.48 + 38.800 131.00 139.52 -8.52 + 38.825 135.00 140.17 -5.17 + 38.850 116.00 140.90 -24.90 + 38.875 112.00 141.74 -29.74 + 38.900 123.00 142.68 -19.68 + 38.925 116.00 143.75 -27.75 + 38.950 121.00 144.97 -23.97 + 38.975 136.00 145.87 -9.87 + 39.000 147.00 147.49 -0.49 + 39.025 130.00 149.34 -19.34 + 39.050 156.00 151.49 4.51 + 39.075 138.00 153.75 -15.75 + 39.100 133.00 156.71 -23.71 + 39.125 144.00 160.21 -16.21 + 39.150 163.00 164.40 -1.40 + 39.175 171.00 169.48 1.52 + 39.200 198.00 175.73 22.27 + 39.225 191.00 183.54 7.46 + 39.250 196.00 193.55 2.45 + 39.275 226.00 206.96 19.04 + 39.300 243.00 226.65 16.35 + 39.325 294.00 259.90 34.10 + 39.350 352.00 323.59 28.41 + 39.375 472.00 449.40 22.60 + 39.400 630.00 680.53 -50.53 + 39.425 984.00 1051.16 -67.16 + 39.450 1383.00 1541.40 -158.40 + 39.475 2157.00 2046.73 110.27 + 39.500 2946.00 2365.29 580.71 + 39.525 2947.00 2360.00 587.00 + 39.550 2469.00 2150.42 318.58 + 39.575 1988.00 1911.27 76.73 + 39.600 2056.00 1667.76 388.24 + 39.625 1767.00 1364.50 402.50 + 39.650 1317.00 1026.04 290.96 + 39.675 793.00 725.82 67.18 + 39.700 524.00 503.48 20.52 + 39.725 362.00 361.71 0.29 + 39.750 282.00 281.67 0.33 + 39.775 264.00 239.32 24.68 + 39.800 227.00 216.36 10.64 + 39.825 186.00 202.58 -16.58 + 39.850 194.00 193.34 0.66 + 39.875 168.00 186.78 -18.78 + 39.900 177.00 182.11 -5.11 + 39.925 199.00 178.95 20.05 + 39.950 174.00 177.13 -3.13 + 39.975 169.00 176.64 -7.64 + 40.000 183.00 177.68 5.32 + 40.025 194.00 180.97 13.03 + 40.050 204.00 188.57 15.43 + 40.075 189.00 205.37 -16.37 + 40.100 213.00 240.62 -27.62 + 40.125 296.00 306.83 -10.83 + 40.150 350.00 412.92 -62.92 + 40.175 476.00 552.54 -76.54 + 40.200 746.00 692.40 53.60 + 40.225 894.00 772.33 121.67 + 40.250 816.00 758.61 57.39 + 40.275 615.00 695.70 -80.70 + 40.300 549.00 629.33 -80.33 + 40.325 596.00 564.33 31.67 + 40.350 524.00 476.88 47.12 + 40.375 395.00 384.14 10.86 + 40.400 306.00 300.87 5.13 + 40.425 223.00 239.47 -16.47 + 40.450 164.00 198.34 -34.34 + 40.475 206.00 176.88 29.12 + 40.500 198.00 165.72 32.28 + 40.525 162.00 159.79 2.21 + 40.550 173.00 156.33 16.67 + 40.575 163.00 154.13 8.87 + 40.600 144.00 152.68 -8.68 + 40.625 169.00 151.79 17.21 + 40.650 160.00 151.37 8.63 + 40.675 156.00 151.35 4.65 + 40.700 143.00 151.74 -8.74 + 40.725 187.00 152.55 34.45 + 40.750 146.00 153.82 -7.82 + 40.775 146.00 155.66 -9.66 + 40.800 157.00 158.20 -1.20 + 40.825 177.00 161.74 15.26 + 40.850 173.00 166.88 6.12 + 40.875 171.00 183.22 -12.22 + 40.900 197.00 199.14 -2.14 + 40.925 214.00 230.65 -16.65 + 40.950 254.00 291.56 -37.56 + 40.975 333.00 400.43 -67.43 + 41.000 505.00 552.97 -47.97 + 41.025 760.00 729.11 30.89 + 41.050 1047.00 865.73 181.27 + 41.075 1074.00 896.29 177.71 + 41.100 910.00 834.51 75.49 + 41.125 689.00 754.11 -65.11 + 41.150 698.00 685.95 12.05 + 41.175 717.00 609.89 107.11 + 41.200 570.00 509.37 60.63 + 41.225 382.00 406.45 -24.45 + 41.250 273.00 323.95 -50.95 + 41.275 291.00 269.77 21.23 + 41.300 231.00 240.75 -9.75 + 41.325 278.00 229.07 48.93 + 41.350 239.00 227.67 11.33 + 41.375 272.00 232.47 39.53 + 41.400 257.00 242.07 14.93 + 41.425 316.00 256.89 59.11 + 41.450 315.00 279.42 35.58 + 41.475 377.00 316.74 60.26 + 41.500 419.00 387.07 31.93 + 41.525 593.00 531.19 61.81 + 41.550 709.00 809.41 -100.41 + 41.575 1116.00 1287.95 -171.95 + 41.600 1749.00 1975.30 -226.30 + 41.625 2604.00 2751.93 -147.93 + 41.650 3739.00 3320.76 418.24 + 41.675 4133.00 3385.23 747.77 + 41.700 3642.00 3065.92 576.08 + 41.725 2835.00 2702.57 132.43 + 41.750 2622.00 2413.83 208.17 + 41.775 2580.00 2081.71 498.29 + 41.800 2147.00 1631.66 515.34 + 41.825 1381.00 1167.49 213.51 + 41.850 844.00 792.10 51.90 + 41.875 578.00 537.34 40.66 + 41.900 447.00 390.43 56.57 + 41.925 351.00 312.87 38.13 + 41.950 339.00 272.16 66.84 + 41.975 309.00 247.98 61.02 + 42.000 260.00 233.07 26.93 + 42.025 268.00 222.93 45.07 + 42.050 240.00 216.19 23.81 + 42.075 250.00 212.39 37.61 + 42.100 233.00 211.78 21.22 + 42.125 275.00 215.96 59.04 + 42.150 281.00 229.49 51.51 + 42.175 285.00 261.83 23.17 + 42.200 381.00 327.07 53.93 + 42.225 450.00 436.90 13.10 + 42.250 601.00 586.66 14.34 + 42.275 801.00 740.04 60.96 + 42.300 895.00 826.29 68.71 + 42.325 881.00 804.10 76.90 + 42.350 726.00 726.14 -0.14 + 42.375 644.00 655.82 -11.82 + 42.400 608.00 600.39 7.61 + 42.425 589.00 528.74 60.26 + 42.450 498.00 435.06 62.94 + 42.475 386.00 337.39 48.61 + 42.500 283.00 269.69 13.31 + 42.525 277.00 227.93 49.07 + 42.550 254.00 205.59 48.41 + 42.575 276.00 189.02 86.98 + 42.600 249.00 179.87 69.13 + 42.625 224.00 172.98 51.02 + 42.650 213.00 168.11 44.89 + 42.675 196.00 164.13 31.87 + 42.700 234.00 159.90 74.10 + 42.725 186.00 155.60 30.40 + 42.750 215.00 151.92 63.08 + 42.775 191.00 149.18 41.82 + 42.800 211.00 147.30 63.70 + 42.825 189.00 146.04 42.96 + 42.850 204.00 145.17 58.83 + 42.875 193.00 144.52 48.48 + 42.900 227.00 143.99 83.01 + 42.925 221.00 157.71 63.29 + 42.950 225.00 173.82 51.18 + 42.975 199.00 175.65 23.35 + 43.000 187.00 177.75 9.25 + 43.025 193.00 180.16 12.84 + 43.050 214.00 190.14 23.86 + 43.075 235.00 201.70 33.30 + 43.100 241.00 204.86 36.14 + 43.125 232.00 210.20 21.80 + 43.150 239.00 216.34 22.66 + 43.175 254.00 223.34 30.66 + 43.200 252.00 231.37 20.63 + 43.225 264.00 239.89 24.11 + 43.250 251.00 250.66 0.34 + 43.275 260.00 263.28 -3.28 + 43.300 320.00 278.17 41.83 + 43.325 375.00 295.90 79.10 + 43.350 379.00 317.26 61.74 + 43.375 442.00 343.25 98.75 + 43.400 425.00 375.45 49.55 + 43.425 492.00 415.93 76.07 + 43.450 574.00 468.02 105.98 + 43.475 693.00 537.71 155.29 + 43.500 816.00 638.81 177.19 + 43.525 1046.00 806.76 239.24 + 43.550 1286.00 1126.95 159.05 + 43.575 1773.00 1767.36 5.64 + 43.600 2593.00 2966.22 -373.22 + 43.625 4047.00 4906.53 -859.53 + 43.650 6544.00 7469.92 -925.92 + 43.675 9907.00 9962.45 -55.45 + 43.700 12440.00 11244.43 1195.57 + 43.725 12196.00 10820.24 1375.76 + 43.750 9815.00 9517.86 297.14 + 43.775 8006.00 8363.25 -357.25 + 43.800 7742.00 7509.51 232.49 + 43.825 7431.00 6459.16 971.84 + 43.850 5975.00 5014.84 960.16 + 43.875 3773.00 3486.43 286.57 + 43.900 2148.00 2257.55 -109.55 + 43.925 1465.00 1444.03 20.97 + 43.950 1080.00 979.34 100.66 + 43.975 849.00 741.08 107.92 + 44.000 683.00 612.13 70.87 + 44.025 579.00 536.50 42.50 + 44.050 560.00 486.74 73.26 + 44.075 480.00 451.84 28.16 + 44.100 481.00 427.17 53.83 + 44.125 470.00 410.47 59.53 + 44.150 468.00 400.47 67.53 + 44.175 450.00 396.57 53.43 + 44.200 469.00 398.64 70.36 + 44.225 498.00 407.09 90.91 + 44.250 468.00 422.97 45.03 + 44.275 528.00 448.60 79.40 + 44.300 615.00 489.33 125.67 + 44.325 632.00 558.88 73.12 + 44.350 765.00 690.49 74.51 + 44.375 985.00 950.90 34.10 + 44.400 1263.00 1437.37 -174.37 + 44.425 1833.00 2228.01 -395.01 + 44.450 2821.00 3291.46 -470.46 + 44.475 4290.00 4382.53 -92.53 + 44.500 5647.00 5108.31 538.69 + 44.525 5682.00 5439.54 242.46 + 44.550 5372.00 5833.49 -461.49 + 44.575 5802.00 6424.41 -622.41 + 44.600 7664.00 6689.05 974.95 + 44.625 7744.00 6087.90 1656.10 + 44.650 5866.00 4981.13 884.87 + 44.675 4103.00 4018.63 84.37 + 44.700 3552.00 3377.39 174.61 + 44.725 3442.00 2812.41 629.59 + 44.750 2855.00 2150.37 704.63 + 44.775 1843.00 1511.06 331.94 + 44.800 1102.00 1017.35 84.65 + 44.825 771.00 696.89 74.11 + 44.850 578.00 514.46 63.54 + 44.875 517.00 415.86 101.14 + 44.900 456.00 359.35 96.65 + 44.925 381.00 322.51 58.49 + 44.950 379.00 295.65 83.35 + 44.975 335.00 274.81 60.19 + 45.000 326.00 258.13 67.87 + 45.025 303.00 244.53 58.47 + 45.050 286.00 233.28 52.72 + 45.075 287.00 223.86 63.14 + 45.100 274.00 215.89 58.11 + 45.125 272.00 209.09 62.91 + 45.150 282.00 203.23 78.77 + 45.175 267.00 205.54 61.46 + 45.200 236.00 201.54 34.46 + 45.225 255.00 198.24 56.76 + 45.250 238.00 195.47 42.53 + 45.275 218.00 183.39 34.61 + 45.300 224.00 185.81 38.19 + 45.325 209.00 185.08 23.92 + 45.350 228.00 184.75 43.25 + 45.375 244.00 169.73 74.27 + 45.400 234.00 171.06 62.94 + 45.425 221.00 172.70 48.30 + 45.450 237.00 174.70 62.30 + 45.475 224.00 177.12 46.88 + 45.500 217.00 175.20 41.80 + 45.525 187.00 179.07 7.93 + 45.550 261.00 183.69 77.31 + 45.575 216.00 189.30 26.70 + 45.600 246.00 196.19 49.81 + 45.625 244.00 204.77 39.23 + 45.650 282.00 215.69 66.31 + 45.675 276.00 229.90 46.10 + 45.700 314.00 249.27 64.73 + 45.725 333.00 278.24 54.76 + 45.750 385.00 328.77 56.23 + 45.775 413.00 430.13 -17.13 + 45.800 609.00 637.52 -28.52 + 45.825 855.00 1019.14 -164.14 + 45.850 1397.00 1600.71 -203.71 + 45.875 2190.00 2280.03 -90.03 + 45.900 3180.00 2756.25 423.75 + 45.925 3151.00 2714.83 436.17 + 45.950 2427.00 2326.52 100.48 + 45.975 1819.00 1984.96 -165.96 + 46.000 1843.00 1831.95 11.05 + 46.025 2058.00 1725.99 332.01 + 46.050 1720.00 1463.56 256.44 + 46.075 1115.00 1087.62 27.38 + 46.100 716.00 744.55 -28.55 + 46.125 480.00 503.54 -23.54 + 46.150 364.00 363.13 0.87 + 46.175 297.00 290.34 6.66 + 46.200 300.00 252.68 47.32 + 46.225 267.00 230.81 36.19 + 46.250 227.00 216.10 10.90 + 46.275 215.00 205.23 9.77 + 46.300 189.00 196.81 -7.81 + 46.325 213.00 190.12 22.88 + 46.350 174.00 184.72 -10.72 + 46.375 175.00 180.29 -5.29 + 46.400 193.00 176.61 16.39 + 46.425 183.00 173.53 9.47 + 46.450 178.00 170.92 7.08 + 46.475 166.00 168.69 -2.69 + 46.500 171.00 166.77 4.23 + 46.525 171.00 165.11 5.89 + 46.550 172.00 163.67 8.33 + 46.575 161.00 162.40 -1.40 + 46.600 151.00 161.29 -10.29 + 46.625 143.00 160.30 -17.30 + 46.650 141.00 159.43 -18.43 + 46.675 139.00 151.96 -12.96 + 46.700 172.00 151.68 20.32 + 46.725 153.00 151.43 1.57 + 46.750 169.00 151.22 17.78 + 46.775 141.00 147.51 -6.51 + 46.800 125.00 147.57 -22.57 + 46.825 135.00 147.62 -12.62 + 46.850 142.00 147.68 -5.68 + 46.875 134.00 147.73 -13.73 + 46.900 142.00 147.79 -5.79 + 46.925 138.00 149.22 -11.22 + 46.950 152.00 149.41 2.59 + 46.975 159.00 149.58 9.42 + 47.000 140.00 149.76 -9.76 + 47.025 143.00 149.96 -6.96 + 47.050 136.00 150.86 -14.86 + 47.075 147.00 151.14 -4.14 + 47.100 144.00 151.48 -7.48 + 47.125 148.00 151.87 -3.87 + 47.150 153.00 152.27 0.73 + 47.175 112.00 152.72 -40.72 + 47.200 148.00 153.23 -5.23 + 47.225 138.00 153.83 -15.83 + 47.250 119.00 154.53 -35.53 + 47.275 121.00 155.35 -34.35 + 47.300 160.00 156.32 3.68 + 47.325 136.00 157.48 -21.48 + 47.350 164.00 158.92 5.08 + 47.375 137.00 160.70 -23.70 + 47.400 166.00 162.98 3.02 + 47.425 142.00 165.95 -23.95 + 47.450 158.00 170.04 -12.04 + 47.475 176.00 176.26 -0.26 + 47.500 175.00 187.38 -12.38 + 47.525 183.00 210.13 -27.13 + 47.550 249.00 256.65 -7.65 + 47.575 309.00 340.27 -31.27 + 47.600 389.00 461.79 -72.79 + 47.625 541.00 592.37 -51.37 + 47.650 720.00 654.24 65.76 + 47.675 682.00 608.87 73.13 + 47.700 600.00 523.27 76.73 + 47.725 452.00 468.72 -16.72 + 47.750 443.00 456.82 -13.82 + 47.775 453.00 448.36 4.64 + 47.800 437.00 400.94 36.06 + 47.825 329.00 331.44 -2.44 + 47.850 289.00 268.79 20.21 + 47.875 226.00 225.74 0.26 + 47.900 201.00 201.86 -0.86 + 47.925 182.00 190.62 -8.62 + 47.950 160.00 185.47 -25.47 + 47.975 178.00 182.33 -4.33 + 48.000 146.00 180.03 -34.03 + 48.025 181.00 178.82 2.18 + 48.050 142.00 178.94 -36.94 + 48.075 201.00 180.42 20.58 + 48.100 182.00 183.32 -1.32 + 48.125 174.00 187.86 -13.86 + 48.150 168.00 194.79 -26.79 + 48.175 174.00 206.18 -32.18 + 48.200 233.00 227.94 5.06 + 48.225 275.00 273.92 1.08 + 48.250 331.00 367.59 -36.59 + 48.275 464.00 531.09 -67.09 + 48.300 712.00 756.43 -44.43 + 48.325 969.00 968.25 0.75 + 48.350 1093.00 1024.87 68.13 + 48.375 984.00 899.77 84.23 + 48.400 752.00 746.92 5.08 + 48.425 624.00 670.50 -46.50 + 48.450 651.00 664.36 -13.36 + 48.475 695.00 640.55 54.45 + 48.500 597.00 541.02 55.98 + 48.525 460.00 414.22 45.78 + 48.550 284.00 310.61 -26.61 + 48.575 261.00 244.89 16.11 + 48.600 211.00 209.82 1.18 + 48.625 196.00 192.31 3.69 + 48.650 175.00 182.91 -7.91 + 48.675 167.00 177.01 -10.01 + 48.700 165.00 172.81 -7.81 + 48.725 143.00 169.64 -26.64 + 48.750 153.00 167.17 -14.17 + 48.775 155.00 165.20 -10.20 + 48.800 137.00 163.61 -26.61 + 48.825 161.00 162.31 -1.31 + 48.850 131.00 161.23 -30.23 + 48.875 138.00 160.33 -22.33 + 48.900 125.00 159.57 -34.57 + 48.925 114.00 158.93 -44.93 + 48.950 154.00 158.37 -4.37 + 48.975 114.00 157.90 -43.90 + 49.000 118.00 157.49 -39.49 + 49.025 120.00 157.14 -37.14 + 49.050 130.00 156.83 -26.83 + 49.075 117.00 154.17 -37.17 + 49.100 126.00 154.09 -28.09 + 49.125 132.00 154.02 -22.02 + 49.150 122.00 153.97 -31.97 + 49.175 133.00 153.93 -20.93 + 49.200 122.00 152.69 -30.69 + 49.225 113.00 152.75 -39.75 + 49.250 128.00 152.80 -24.80 + 49.275 139.00 152.85 -13.85 + 49.300 126.00 152.90 -26.90 + 49.325 140.00 152.95 -12.95 + 49.350 120.00 153.00 -33.00 + 49.375 122.00 153.05 -31.05 + 49.400 122.00 153.10 -31.10 + 49.425 136.00 153.16 -17.16 + 49.450 116.00 153.21 -37.21 + 49.475 113.00 153.26 -40.26 + 49.500 103.00 153.31 -50.31 + 49.525 120.00 153.36 -33.36 + 49.550 129.00 153.41 -24.41 + 49.575 112.00 153.46 -41.46 + 49.600 118.00 153.51 -35.51 + 49.625 140.00 153.56 -13.56 + 49.650 135.00 153.61 -18.61 + 49.675 101.00 153.66 -52.66 + 49.700 128.00 153.72 -25.72 + 49.725 115.00 153.77 -38.77 + 49.750 126.00 153.82 -27.82 + 49.775 120.00 153.87 -33.87 + 49.800 119.00 153.92 -34.92 + 49.825 107.00 153.97 -46.97 + 49.850 122.00 154.02 -32.02 + 49.875 124.00 154.07 -30.07 + 49.900 123.00 154.12 -31.12 + 49.925 159.00 154.17 4.83 + 49.950 132.00 154.22 -22.22 + 49.975 136.00 154.27 -18.27 + 50.000 115.00 154.32 -39.32 + 50.025 142.00 154.37 -12.37 + 50.050 132.00 154.42 -22.42 + 50.075 144.00 154.47 -10.47 + 50.100 140.00 154.52 -14.52 + 50.125 131.00 154.57 -23.57 + 50.150 112.00 161.69 -49.69 + 50.175 147.00 162.28 -15.28 + 50.200 129.00 162.95 -33.95 + 50.225 129.00 163.70 -34.70 + 50.250 106.00 164.56 -58.56 + 50.275 129.00 165.53 -36.53 + 50.300 127.00 170.28 -43.28 + 50.325 122.00 171.77 -49.77 + 50.350 155.00 173.46 -18.46 + 50.375 130.00 175.41 -45.41 + 50.400 121.00 177.69 -56.69 + 50.425 131.00 180.39 -49.39 + 50.450 173.00 183.59 -10.59 + 50.475 157.00 187.40 -30.40 + 50.500 146.00 192.02 -46.02 + 50.525 153.00 197.71 -44.71 + 50.550 168.00 204.84 -36.84 + 50.575 199.00 213.93 -14.93 + 50.600 204.00 225.77 -21.77 + 50.625 212.00 241.67 -29.67 + 50.650 232.00 264.35 -32.35 + 50.675 255.00 300.92 -45.92 + 50.700 319.00 371.31 -52.31 + 50.725 410.00 521.60 -111.60 + 50.750 629.00 824.46 -195.46 + 50.775 1090.00 1331.96 -241.96 + 50.800 1814.00 1970.77 -156.77 + 50.825 2668.00 2419.07 248.93 + 50.850 2463.00 2292.39 170.61 + 50.875 1752.00 1809.42 -57.42 + 50.900 1187.00 1435.15 -248.15 + 50.925 1257.00 1344.73 -87.73 + 50.950 1542.00 1425.75 116.25 + 50.975 1549.00 1384.11 164.89 + 51.000 1066.00 1103.34 -37.34 + 51.025 624.00 767.78 -143.78 + 51.050 387.00 514.34 -127.34 + 51.075 314.00 365.65 -51.65 + 51.100 267.00 290.79 -23.79 + 51.125 208.00 253.66 -45.66 + 51.150 211.00 232.68 -21.68 + 51.175 210.00 218.76 -8.76 + 51.200 181.00 208.60 -27.60 + 51.225 170.00 200.83 -30.83 + 51.250 154.00 194.73 -40.73 + 51.275 155.00 189.86 -34.86 + 51.300 143.00 185.89 -42.89 + 51.325 171.00 182.63 -11.63 + 51.350 156.00 179.91 -23.91 + 51.375 134.00 177.62 -43.62 + 51.400 142.00 175.67 -33.67 + 51.425 142.00 174.00 -32.00 + 51.450 136.00 172.56 -36.56 + 51.475 139.00 171.31 -32.31 + 51.500 139.00 170.22 -31.22 + 51.525 132.00 162.48 -30.48 + 51.550 152.00 162.09 -10.09 + 51.575 123.00 161.76 -38.76 + 51.600 137.00 161.47 -24.47 + 51.625 125.00 161.22 -36.22 + 51.650 132.00 157.51 -25.51 + 51.675 133.00 157.56 -24.56 + 51.700 137.00 157.61 -20.61 + 51.725 148.00 157.65 -9.65 + 51.750 121.00 157.70 -36.70 + 51.775 150.00 160.90 -10.90 + 51.800 139.00 161.20 -22.20 + 51.825 127.00 161.53 -34.53 + 51.850 127.00 162.75 -35.75 + 51.875 146.00 163.23 -17.23 + 51.900 147.00 163.76 -16.76 + 51.925 155.00 165.98 -10.98 + 51.950 131.00 166.79 -35.79 + 51.975 144.00 167.73 -23.73 + 52.000 148.00 169.25 -21.25 + 52.025 138.00 170.55 -32.55 + 52.050 149.00 172.07 -23.07 + 52.075 154.00 173.87 -19.87 + 52.100 142.00 176.04 -34.04 + 52.125 141.00 178.67 -37.67 + 52.150 181.00 181.93 -0.93 + 52.175 185.00 186.03 -1.03 + 52.200 169.00 191.29 -22.29 + 52.225 181.00 198.21 -17.21 + 52.250 203.00 207.68 -4.68 + 52.275 236.00 221.70 14.30 + 52.300 232.00 245.85 -13.85 + 52.325 335.00 294.93 40.07 + 52.350 428.00 398.50 29.50 + 52.375 600.00 591.78 8.22 + 52.400 826.00 877.85 -51.85 + 52.425 1143.00 1164.11 -21.11 + 52.450 1282.00 1250.54 31.46 + 52.475 1262.00 1122.89 139.11 + 52.500 1070.00 973.21 96.79 + 52.525 962.00 878.88 83.12 + 52.550 964.00 852.46 111.54 + 52.575 871.00 846.51 24.49 + 52.600 886.00 762.62 123.38 + 52.625 728.00 628.27 99.73 + 52.650 557.00 504.64 52.36 + 52.675 468.00 394.93 73.07 + 52.700 370.00 310.57 59.43 + 52.725 267.00 256.30 10.70 + 52.750 235.00 225.18 9.82 + 52.775 203.00 208.78 -5.78 + 52.800 187.00 199.26 -12.26 + 52.825 181.00 193.30 -12.30 + 52.850 188.00 189.25 -1.25 + 52.875 189.00 186.45 2.55 + 52.900 166.00 184.64 -18.64 + 52.925 167.00 183.80 -16.80 + 52.950 175.00 184.29 -9.29 + 52.975 191.00 189.12 1.88 + 53.000 184.00 196.54 -12.54 + 53.025 181.00 209.81 -28.81 + 53.050 226.00 230.81 -4.81 + 53.075 228.00 242.60 -14.60 + 53.100 258.00 239.55 18.45 + 53.125 216.00 229.43 -13.43 + 53.150 233.00 233.50 -0.50 + 53.175 250.00 251.47 -1.47 + 53.200 287.00 298.38 -11.38 + 53.225 332.00 371.64 -39.64 + 53.250 441.00 459.70 -18.70 + 53.275 506.00 522.03 -16.03 + 53.300 459.00 497.82 -38.82 + 53.325 447.00 419.70 27.30 + 53.350 383.00 363.64 19.36 + 53.375 372.00 355.84 16.16 + 53.400 397.00 383.46 13.54 + 53.425 408.00 404.36 3.64 + 53.450 434.00 386.55 47.45 + 53.475 419.00 357.04 61.96 + 53.500 346.00 350.66 -4.66 + 53.525 392.00 389.79 2.21 + 53.550 441.00 497.17 -56.17 + 53.575 622.00 694.67 -72.67 + 53.600 912.00 978.65 -66.65 + 53.625 1096.00 1278.06 -182.06 + 53.650 1359.00 1540.33 -181.33 + 53.675 1605.00 1800.19 -195.19 + 53.700 1949.00 1942.31 6.69 + 53.725 1937.00 1976.95 -39.95 + 53.750 1843.00 2092.80 -249.80 + 53.775 2020.00 2168.92 -148.92 + 53.800 1980.00 1993.01 -13.01 + 53.825 1741.00 1695.76 45.24 + 53.850 1467.00 1394.42 72.58 + 53.875 1209.00 1167.57 41.43 + 53.900 1080.00 1065.17 14.83 + 53.925 998.00 970.93 27.07 + 53.950 719.00 777.45 -58.45 + 53.975 548.00 564.33 -16.33 + 54.000 393.00 408.10 -15.10 + 54.025 314.00 317.13 -3.13 + 54.050 277.00 270.10 6.90 + 54.075 248.00 244.98 3.02 + 54.100 204.00 228.96 -24.96 + 54.125 179.00 218.03 -39.03 + 54.150 180.00 209.76 -29.76 + 54.175 168.00 203.30 -35.30 + 54.200 160.00 198.12 -38.12 + 54.225 170.00 193.91 -23.91 + 54.250 160.00 190.44 -30.44 + 54.275 184.00 185.67 -1.67 + 54.300 179.00 183.34 -4.34 + 54.325 164.00 181.36 -17.36 + 54.350 149.00 175.93 -26.93 + 54.375 156.00 174.73 -18.73 + 54.400 140.00 173.70 -33.70 + 54.425 161.00 167.94 -6.94 + 54.450 149.00 167.50 -18.50 + 54.475 134.00 167.12 -33.12 + 54.500 126.00 164.97 -38.97 + 54.525 143.00 164.81 -21.81 + 54.550 138.00 164.46 -26.46 + 54.575 142.00 162.63 -20.63 + 54.600 163.00 162.67 0.33 + 54.625 131.00 162.71 -31.71 + 54.650 161.00 162.75 -1.75 + 54.675 131.00 162.79 -31.79 + 54.700 147.00 162.83 -15.83 + 54.725 150.00 162.87 -12.87 + 54.750 160.00 162.91 -2.91 + 54.775 128.00 166.80 -38.80 + 54.800 126.00 167.18 -41.18 + 54.825 128.00 167.60 -39.60 + 54.850 152.00 168.08 -16.08 + 54.875 134.00 168.62 -34.62 + 54.900 158.00 169.25 -11.25 + 54.925 135.00 171.88 -36.88 + 54.950 162.00 172.90 -10.90 + 54.975 157.00 174.09 -17.09 + 55.000 173.00 175.48 -2.48 + 55.025 156.00 177.13 -21.13 + 55.050 162.00 179.13 -17.13 + 55.075 158.00 182.78 -24.78 + 55.100 164.00 185.98 -21.98 + 55.125 155.00 190.05 -35.05 + 55.150 194.00 195.33 -1.33 + 55.175 195.00 202.37 -7.37 + 55.200 196.00 212.17 -16.17 + 55.225 253.00 227.51 25.49 + 55.250 262.00 253.66 8.34 + 55.275 350.00 308.84 41.16 + 55.300 464.00 428.96 35.04 + 55.325 665.00 653.44 11.56 + 55.350 937.00 967.00 -30.00 + 55.375 1141.00 1202.59 -61.59 + 55.400 1055.00 1115.87 -60.87 + 55.425 834.00 837.11 -3.11 + 55.450 657.00 628.40 28.60 + 55.475 648.00 580.11 67.89 + 55.500 638.00 660.49 -22.49 + 55.525 752.00 745.02 6.98 + 55.550 672.00 684.61 -12.61 + 55.575 543.00 532.89 10.11 + 55.600 404.00 417.72 -13.72 + 55.625 370.00 386.45 -16.45 + 55.650 386.00 433.33 -47.33 + 55.675 469.00 512.35 -43.35 + 55.700 560.00 529.71 30.29 + 55.725 465.00 450.18 14.82 + 55.750 360.00 359.18 0.82 + 55.775 285.00 312.77 -27.77 + 55.800 276.00 317.34 -41.34 + 55.825 355.00 348.25 6.75 + 55.850 364.00 354.23 9.77 + 55.875 291.00 311.10 -20.10 + 55.900 228.00 257.91 -29.91 + 55.925 190.00 222.40 -32.40 + 55.950 194.00 202.20 -8.20 + 55.975 195.00 192.46 2.54 + 56.000 180.00 187.46 -7.46 + 56.025 163.00 181.01 -18.01 + 56.050 154.00 179.18 -25.18 + 56.075 156.00 177.94 -21.94 + 56.100 184.00 187.63 -3.63 + 56.125 181.00 188.10 -7.10 + 56.150 152.00 188.99 -36.99 + 56.175 176.00 188.62 -12.62 + 56.200 177.00 190.53 -13.53 + 56.225 160.00 192.97 -32.97 + 56.250 178.00 200.67 -22.67 + 56.275 185.00 204.97 -19.97 + 56.300 175.00 210.40 -35.40 + 56.325 206.00 216.24 -10.24 + 56.350 214.00 225.44 -11.44 + 56.375 244.00 238.00 6.00 + 56.400 255.00 256.98 -1.98 + 56.425 254.00 290.78 -36.78 + 56.450 373.00 358.28 14.72 + 56.475 514.00 490.40 23.60 + 56.500 623.00 680.35 -57.35 + 56.525 827.00 859.08 -32.08 + 56.550 875.00 885.49 -10.49 + 56.575 884.00 833.98 50.02 + 56.600 951.00 937.77 13.23 + 56.625 1181.00 1364.45 -183.45 + 56.650 1887.00 2117.38 -230.38 + 56.675 2582.00 2830.21 -248.21 + 56.700 2875.00 2747.91 127.09 + 56.725 2303.00 2002.64 300.36 + 56.750 1613.00 1356.92 256.08 + 56.775 1270.00 1112.05 157.95 + 56.800 1312.00 1235.62 76.38 + 56.825 1510.00 1494.10 15.90 + 56.850 1599.00 1483.19 115.81 + 56.875 1288.00 1137.94 150.06 + 56.900 890.00 787.48 102.52 + 56.925 794.00 579.69 214.31 + 56.950 643.00 513.64 129.36 + 56.975 683.00 574.50 108.50 + 57.000 884.00 794.68 89.32 + 57.025 1207.00 1210.00 -3.00 + 57.050 1571.00 1711.03 -140.03 + 57.075 1762.00 1880.96 -118.96 + 57.100 1506.00 1536.01 -30.01 + 57.125 1186.00 1118.11 67.89 + 57.150 969.00 879.89 89.11 + 57.175 975.00 868.18 106.82 + 57.200 1015.00 1016.47 -1.47 + 57.225 1048.00 1103.26 -55.26 + 57.250 938.00 936.08 1.92 + 57.275 733.00 682.70 50.30 + 57.300 494.00 477.95 16.05 + 57.325 392.00 355.70 36.30 + 57.350 292.00 288.36 3.64 + 57.375 276.00 252.32 23.68 + 57.400 254.00 231.90 22.10 + 57.425 229.00 219.13 9.87 + 57.450 216.00 206.00 10.00 + 57.475 203.00 199.77 3.23 + 57.500 194.00 194.99 -0.99 + 57.525 189.00 191.23 -2.23 + 57.550 192.00 188.21 3.79 + 57.575 181.00 185.75 -4.75 + 57.600 191.00 183.72 7.28 + 57.625 163.00 182.02 -19.02 + 57.650 175.00 180.58 -5.58 + 57.675 186.00 173.50 12.50 + 57.700 149.00 172.90 -23.90 + 57.725 175.00 172.39 2.61 + 57.750 142.00 171.54 -29.54 + 57.775 180.00 171.20 8.80 + 57.800 136.00 170.90 -34.90 + 57.825 151.00 170.65 -19.65 + 57.850 177.00 167.69 9.31 + 57.875 156.00 167.71 -11.71 + 57.900 159.00 167.94 -8.94 + 57.925 174.00 168.01 5.99 + 57.950 148.00 168.09 -20.09 + 57.975 147.00 168.18 -21.18 + 58.000 141.00 168.27 -27.27 + 58.025 145.00 168.38 -23.38 + 58.050 156.00 168.70 -12.70 + 58.075 144.00 168.85 -24.85 + 58.100 149.00 169.02 -20.02 + 58.125 145.00 172.87 -27.87 + 58.150 127.00 173.46 -46.46 + 58.175 143.00 174.14 -31.14 + 58.200 159.00 174.96 -15.96 + 58.225 129.00 175.94 -46.94 + 58.250 161.00 177.16 -16.16 + 58.275 138.00 180.43 -42.43 + 58.300 145.00 182.58 -37.58 + 58.325 165.00 185.51 -20.51 + 58.350 172.00 190.29 -18.29 + 58.375 184.00 198.63 -14.63 + 58.400 217.00 215.36 1.64 + 58.425 266.00 245.17 20.83 + 58.450 272.00 284.03 -12.03 + 58.475 313.00 305.00 8.00 + 58.500 288.00 288.62 -0.62 + 58.525 275.00 267.00 8.00 + 58.550 321.00 264.67 56.33 + 58.575 323.00 292.69 30.31 + 58.600 439.00 368.18 70.82 + 58.625 573.00 519.63 53.37 + 58.650 743.00 760.59 -17.59 + 58.675 906.00 1029.36 -123.36 + 58.700 960.00 1074.04 -114.04 + 58.725 812.00 826.51 -14.51 + 58.750 566.00 574.34 -8.34 + 58.775 541.00 455.28 85.72 + 58.800 535.00 474.96 60.04 + 58.825 554.00 586.74 -32.74 + 58.850 567.00 673.39 -106.39 + 58.875 599.00 605.17 -6.17 + 58.900 473.00 475.60 -2.60 + 58.925 359.00 376.95 -17.95 + 58.950 290.00 304.57 -14.57 + 58.975 254.00 255.97 -1.97 + 59.000 189.00 229.44 -40.44 + 59.025 184.00 219.40 -35.40 + 59.050 196.00 220.59 -24.59 + 59.075 210.00 224.91 -14.91 + 59.100 190.00 220.25 -30.25 + 59.125 179.00 206.54 -27.54 + 59.150 148.00 194.45 -46.45 + 59.175 160.00 187.03 -27.03 + 59.200 147.00 183.03 -36.03 + 59.225 122.00 180.52 -58.52 + 59.250 148.00 178.97 -30.97 + 59.275 141.00 174.37 -33.37 + 59.300 140.00 173.71 -33.71 + 59.325 142.00 174.09 -32.09 + 59.350 114.00 173.76 -59.76 + 59.375 150.00 173.52 -23.52 + 59.400 151.00 173.36 -22.36 + 59.425 132.00 173.26 -41.26 + 59.450 153.00 171.60 -18.60 + 59.475 140.00 172.18 -32.18 + 59.500 118.00 172.42 -54.42 + 59.525 128.00 172.48 -44.48 + 59.550 140.00 172.89 -32.89 + 59.575 136.00 173.40 -37.40 + 59.600 122.00 174.05 -52.05 + 59.625 130.00 174.89 -44.89 + 59.650 135.00 176.01 -41.01 + 59.675 133.00 177.39 -44.39 + 59.700 165.00 179.54 -14.54 + 59.725 160.00 182.80 -22.80 + 59.750 163.00 188.53 -25.53 + 59.775 166.00 200.83 -34.83 + 59.800 190.00 228.67 -38.67 + 59.825 264.00 281.92 -17.92 + 59.850 331.00 352.08 -21.08 + 59.875 334.00 379.69 -45.69 + 59.900 297.00 327.75 -30.75 + 59.925 215.00 265.13 -50.13 + 59.950 205.00 231.66 -26.66 + 59.975 212.00 230.21 -18.21 + 60.000 268.00 252.98 15.02 + 60.025 226.00 279.84 -53.84 + 60.050 256.00 272.22 -16.22 + 60.075 199.00 236.70 -37.70 + 60.100 165.00 207.43 -42.43 + 60.125 148.00 190.99 -42.99 + 60.150 159.00 183.50 -24.50 + 60.175 132.00 180.00 -48.00 + 60.200 154.00 178.05 -24.05 + 60.225 139.00 176.79 -37.79 + 60.250 121.00 175.95 -54.95 + 60.275 144.00 175.66 -31.66 + 60.300 131.00 175.32 -44.32 + 60.325 136.00 175.14 -39.14 + 60.350 139.00 175.11 -36.11 + 60.375 120.00 175.22 -55.22 + 60.400 129.00 175.50 -46.50 + 60.425 130.00 175.97 -45.97 + 60.450 143.00 175.92 -32.92 + 60.475 127.00 177.11 -50.11 + 60.500 150.00 178.93 -28.93 + 60.525 156.00 182.04 -26.04 + 60.550 154.00 188.52 -34.52 + 60.575 153.00 203.47 -50.47 + 60.600 162.00 233.48 -71.48 + 60.625 208.00 277.94 -69.94 + 60.650 247.00 303.56 -56.56 + 60.675 207.00 275.43 -68.43 + 60.700 192.00 233.88 -41.88 + 60.725 179.00 209.51 -30.51 + 60.750 148.00 205.23 -57.23 + 60.775 154.00 217.07 -63.07 + 60.800 204.00 236.13 -32.13 + 60.825 186.00 238.76 -52.76 + 60.850 208.00 217.99 -9.99 + 60.875 175.00 197.30 -22.30 + 60.900 141.00 185.23 -44.23 + 60.925 111.00 179.64 -68.64 + 60.950 124.00 177.07 -53.07 + 60.975 132.00 175.66 -43.66 + 61.000 127.00 174.75 -47.75 + 61.025 125.00 174.11 -49.11 + 61.050 124.00 173.68 -49.68 + 61.075 147.00 173.35 -26.35 + 61.100 143.00 173.09 -30.09 + 61.125 135.00 172.89 -37.89 + 61.150 136.00 172.73 -36.73 + 61.175 143.00 172.60 -29.60 + 61.200 145.00 172.51 -27.51 + 61.225 143.00 171.95 -28.95 + 61.250 148.00 171.95 -23.95 + 61.275 151.00 171.95 -20.95 + 61.300 139.00 171.97 -32.97 + 61.325 142.00 172.00 -30.00 + 61.350 135.00 172.04 -37.04 + 61.375 161.00 171.83 -10.83 + 61.400 143.00 171.94 -28.94 + 61.425 139.00 173.86 -34.86 + 61.450 136.00 174.24 -38.24 + 61.475 158.00 174.78 -16.78 + 61.500 164.00 175.68 -11.68 + 61.525 167.00 190.46 -23.46 + 61.550 165.00 195.06 -30.06 + 61.575 181.00 201.08 -20.08 + 61.600 147.00 206.21 -59.21 + 61.625 160.00 206.57 -46.57 + 61.650 195.00 206.31 -11.31 + 61.675 209.00 208.30 0.70 + 61.700 190.00 219.61 -29.61 + 61.725 226.00 227.85 -1.85 + 61.750 195.00 238.72 -43.72 + 61.775 241.00 251.01 -10.01 + 61.800 278.00 265.37 12.63 + 61.825 302.00 286.10 15.90 + 61.850 344.00 320.33 23.67 + 61.875 427.00 383.38 43.62 + 61.900 563.00 503.66 59.34 + 61.925 789.00 708.02 80.98 + 61.950 990.00 974.18 15.82 + 61.975 1317.00 1273.14 43.86 + 62.000 1792.00 1854.98 -62.98 + 62.025 2342.00 2766.20 -424.20 + 62.050 2479.00 3109.41 -630.41 + 62.075 2083.00 2328.69 -245.69 + 62.100 1541.00 1514.73 26.27 + 62.125 1233.00 1112.47 120.53 + 62.150 1186.00 1024.45 161.55 + 62.175 1301.00 1228.52 72.48 + 62.200 1408.00 1622.00 -214.00 + 62.225 1348.00 1668.64 -320.64 + 62.250 1086.00 1188.44 -102.44 + 62.275 761.00 733.97 27.03 + 62.300 509.00 480.42 28.58 + 62.325 405.00 365.53 39.47 + 62.350 349.00 312.09 36.91 + 62.375 309.00 282.38 26.62 + 62.400 273.00 263.85 9.15 + 62.425 269.00 252.76 16.24 + 62.450 244.00 249.30 -5.30 + 62.475 252.00 257.55 -5.55 + 62.500 286.00 281.35 4.65 + 62.525 309.00 318.46 -9.46 + 62.550 289.00 332.01 -43.01 + 62.575 316.00 321.90 -5.90 + 62.600 317.00 297.98 19.02 + 62.625 259.00 267.98 -8.98 + 62.650 228.00 242.45 -14.45 + 62.675 223.00 237.44 -14.44 + 62.700 259.00 248.23 10.77 + 62.725 237.00 250.68 -13.68 + 62.750 212.00 243.73 -31.73 + 62.775 212.00 236.00 -24.00 + 62.800 201.00 219.19 -18.19 + 62.825 184.00 203.11 -19.11 + 62.850 201.00 194.08 6.92 + 62.875 170.00 190.27 -20.27 + 62.900 165.00 189.07 -24.07 + 62.925 182.00 189.09 -7.09 + 62.950 182.00 189.87 -7.87 + 62.975 183.00 194.45 -11.45 + 63.000 199.00 196.95 2.05 + 63.025 200.00 201.77 -1.77 + 63.050 208.00 206.57 1.43 + 63.075 190.00 212.68 -22.68 + 63.100 185.00 221.80 -36.80 + 63.125 230.00 234.88 -4.88 + 63.150 275.00 254.39 20.61 + 63.175 352.00 288.09 63.91 + 63.200 448.00 358.69 89.31 + 63.225 647.00 522.23 124.77 + 63.250 956.00 857.22 98.78 + 63.275 1241.00 1317.56 -76.56 + 63.300 1280.00 1430.17 -150.17 + 63.325 1063.00 1025.73 37.27 + 63.350 730.00 652.65 77.35 + 63.375 559.00 479.98 79.02 + 63.400 576.00 472.80 103.20 + 63.425 678.00 604.87 73.13 + 63.450 833.00 839.30 -6.30 + 63.475 919.00 956.50 -37.50 + 63.500 838.00 846.57 -8.57 + 63.525 736.00 708.06 27.94 + 63.550 578.00 527.50 50.50 + 63.575 449.00 380.54 68.46 + 63.600 352.00 302.88 49.12 + 63.625 332.00 275.46 56.54 + 63.650 306.00 283.81 22.19 + 63.675 308.00 320.88 -12.88 + 63.700 321.00 350.43 -29.43 + 63.725 300.00 314.11 -14.11 + 63.750 245.00 258.83 -13.83 + 63.775 216.00 224.04 -8.04 + 63.800 201.00 207.22 -6.22 + 63.825 182.00 193.66 -11.66 + 63.850 162.00 189.34 -27.34 + 63.875 147.00 186.45 -39.45 + 63.900 163.00 184.37 -21.37 + 63.925 193.00 182.81 10.19 + 63.950 149.00 181.60 -32.60 + 63.975 171.00 180.63 -9.63 + 64.000 166.00 177.15 -11.15 + 64.025 202.00 176.74 25.26 + 64.050 155.00 175.15 -20.15 + 64.075 141.00 184.22 -43.22 + 64.100 162.00 185.08 -23.08 + 64.125 155.00 186.13 -31.13 + 64.150 166.00 187.40 -21.40 + 64.175 190.00 188.95 1.05 + 64.200 174.00 190.84 -16.84 + 64.225 189.00 192.54 -3.54 + 64.250 211.00 195.49 15.51 + 64.275 169.00 204.13 -35.13 + 64.300 195.00 209.39 -14.39 + 64.325 197.00 216.15 -19.15 + 64.350 235.00 225.09 9.91 + 64.375 250.00 237.24 12.76 + 64.400 286.00 254.37 31.63 + 64.425 344.00 279.66 64.34 + 64.450 394.00 320.00 74.00 + 64.475 561.00 395.56 165.44 + 64.500 722.00 567.58 154.42 + 64.525 930.00 960.97 -30.97 + 64.550 1317.00 1648.60 -331.60 + 64.575 1481.00 2163.86 -682.86 + 64.600 1358.00 1711.06 -353.06 + 64.625 1037.00 1033.88 3.12 + 64.650 813.00 657.88 155.12 + 64.675 746.00 547.96 198.04 + 64.700 717.00 632.95 84.05 + 64.725 877.00 910.10 -33.10 + 64.750 916.00 1208.39 -292.39 + 64.775 896.00 1064.18 -168.18 + 64.800 663.00 691.36 -28.36 + 64.825 502.00 447.46 54.54 + 64.850 396.00 334.83 61.17 + 64.875 302.00 286.32 15.68 + 64.900 255.00 264.81 -9.81 + 64.925 280.00 251.30 28.70 + 64.950 238.00 243.83 -5.83 + 64.975 238.00 240.76 -2.76 + 65.000 233.00 241.59 -8.59 + 65.025 267.00 246.70 20.30 + 65.050 258.00 257.54 0.46 + 65.075 267.00 278.00 -11.00 + 65.100 346.00 311.43 34.57 + 65.125 468.00 411.82 56.18 + 65.150 667.00 642.60 24.40 + 65.175 897.00 1036.39 -139.39 + 65.200 976.00 1276.37 -300.37 + 65.225 870.00 970.95 -100.95 + 65.250 617.00 609.63 7.37 + 65.275 478.00 420.47 57.53 + 65.300 483.00 372.13 110.87 + 65.325 485.00 423.44 61.56 + 65.350 541.00 576.98 -35.98 + 65.375 636.00 742.79 -106.79 + 65.400 625.00 652.58 -27.58 + 65.425 465.00 445.06 19.94 + 65.450 354.00 314.77 39.23 + 65.475 276.00 255.80 20.20 + 65.500 231.00 230.46 0.54 + 65.525 232.00 218.91 13.09 + 65.550 190.00 212.83 -22.83 + 65.575 216.00 206.93 9.07 + 65.600 192.00 200.01 -8.01 + 65.625 191.00 194.92 -3.92 + 65.650 172.00 191.72 -19.72 + 65.675 178.00 189.82 -11.82 + 65.700 212.00 183.99 28.01 + 65.725 172.00 184.84 -12.84 + 65.750 174.00 185.18 -11.18 + 65.775 183.00 183.92 -0.92 + 65.800 142.00 182.80 -40.80 + 65.825 176.00 182.56 -6.56 + 65.850 174.00 183.13 -9.13 + 65.875 159.00 182.00 -23.00 + 65.900 196.00 188.23 7.77 + 65.925 194.00 195.67 -1.67 + 65.950 202.00 212.97 -10.97 + 65.975 246.00 246.32 -0.32 + 66.000 258.00 278.62 -20.62 + 66.025 272.00 260.77 11.23 + 66.050 227.00 225.84 1.16 + 66.075 206.00 206.71 -0.71 + 66.100 220.00 202.87 17.13 + 66.125 234.00 215.42 18.58 + 66.150 235.00 229.77 5.23 + 66.175 252.00 252.22 -0.22 + 66.200 241.00 260.67 -19.67 + 66.225 246.00 251.33 -5.33 + 66.250 280.00 251.34 28.66 + 66.275 326.00 270.23 55.77 + 66.300 391.00 323.34 67.66 + 66.325 456.00 453.99 2.01 + 66.350 640.00 678.83 -38.83 + 66.375 670.00 822.20 -152.20 + 66.400 639.00 653.42 -14.42 + 66.425 521.00 470.61 50.39 + 66.450 515.00 396.78 118.22 + 66.475 493.00 406.49 86.51 + 66.500 632.00 494.88 137.12 + 66.525 854.00 725.19 128.81 + 66.550 1153.00 1190.28 -37.28 + 66.575 1468.00 1805.83 -337.83 + 66.600 1384.00 2066.39 -682.39 + 66.625 1196.00 1452.60 -256.60 + 66.650 879.00 851.74 27.26 + 66.675 770.00 565.43 204.57 + 66.700 660.00 483.06 176.94 + 66.725 705.00 544.42 160.58 + 66.750 773.00 759.93 13.07 + 66.775 815.00 1063.24 -248.24 + 66.800 766.00 992.23 -226.23 + 66.825 626.00 649.18 -23.18 + 66.850 469.00 426.40 42.60 + 66.875 409.00 324.26 84.74 + 66.900 338.00 282.14 55.86 + 66.925 280.00 264.94 15.06 + 66.950 267.00 254.65 12.35 + 66.975 303.00 250.69 52.31 + 67.000 290.00 251.99 38.01 + 67.025 315.00 258.95 56.05 + 67.050 308.00 272.20 35.80 + 67.075 375.00 292.79 82.21 + 67.100 471.00 351.89 119.11 + 67.125 637.00 493.04 143.96 + 67.150 830.00 814.49 15.51 + 67.175 1073.00 1308.58 -235.58 + 67.200 1024.00 1371.35 -347.35 + 67.225 833.00 895.33 -62.33 + 67.250 639.00 553.07 85.93 + 67.275 528.00 408.78 119.22 + 67.300 502.00 383.92 118.08 + 67.325 569.00 451.31 117.69 + 67.350 667.00 638.37 28.63 + 67.375 732.00 843.04 -111.04 + 67.400 600.00 714.72 -114.72 + 67.425 516.00 479.62 36.38 + 67.450 444.00 358.11 85.89 + 67.475 417.00 333.21 83.79 + 67.500 430.00 377.32 52.68 + 67.525 431.00 444.94 -13.94 + 67.550 409.00 404.34 4.66 + 67.575 399.00 319.81 79.19 + 67.600 319.00 280.88 38.12 + 67.625 289.00 290.48 -1.48 + 67.650 333.00 347.90 -14.90 + 67.675 368.00 412.42 -44.42 + 67.700 368.00 406.19 -38.19 + 67.725 375.00 366.90 8.10 + 67.750 332.00 297.28 34.72 + 67.775 257.00 248.15 8.85 + 67.800 253.00 230.65 22.35 + 67.825 244.00 243.31 0.69 + 67.850 250.00 268.33 -18.33 + 67.875 251.00 279.33 -28.33 + 67.900 239.00 245.81 -6.81 + 67.925 260.00 218.36 41.64 + 67.950 202.00 206.09 -4.09 + 67.975 234.00 201.92 32.08 + 68.000 236.00 205.78 30.22 + 68.025 222.00 210.74 11.26 + 68.050 268.00 215.34 52.66 + 68.075 246.00 222.66 23.34 + 68.100 261.00 239.15 21.85 + 68.125 301.00 260.05 40.95 + 68.150 352.00 295.31 56.69 + 68.175 434.00 349.96 84.04 + 68.200 507.00 421.23 85.77 + 68.225 687.00 599.08 87.92 + 68.250 891.00 964.89 -73.89 + 68.275 929.00 1237.23 -308.23 + 68.300 869.00 946.74 -77.74 + 68.325 744.00 653.80 90.20 + 68.350 766.00 580.37 185.63 + 68.375 883.00 706.47 176.53 + 68.400 1213.00 1057.31 155.69 + 68.425 1390.00 1463.78 -73.78 + 68.450 1383.00 1431.88 -48.88 + 68.475 1276.00 1257.31 18.69 + 68.500 1228.00 1140.18 87.82 + 68.525 1172.00 1260.64 -88.64 + 68.550 1129.00 1110.67 18.33 + 68.575 970.00 835.83 134.17 + 68.600 905.00 809.10 95.90 + 68.625 839.00 823.55 15.45 + 68.650 745.00 633.42 111.58 + 68.675 632.00 519.23 112.77 + 68.700 628.00 567.96 60.04 + 68.725 600.00 670.24 -70.24 + 68.750 552.00 546.23 5.77 + 68.775 393.00 378.62 14.38 + 68.800 307.00 290.38 16.62 + 68.825 265.00 250.98 14.02 + 68.850 275.00 231.13 43.87 + 68.875 215.00 219.25 -4.25 + 68.900 233.00 206.57 26.43 + 68.925 208.00 198.64 9.36 + 68.950 186.00 194.94 -8.94 + 68.975 180.00 192.15 -12.15 + 69.000 200.00 185.92 14.08 + 69.025 182.00 184.63 -2.63 + 69.050 178.00 183.64 -5.64 + 69.075 170.00 180.51 -10.51 + 69.100 180.00 180.21 -0.21 + 69.125 177.00 180.06 -3.06 + 69.150 190.00 186.23 3.77 + 69.175 173.00 185.07 -12.07 + 69.200 203.00 186.91 16.09 + 69.225 200.00 189.79 10.21 + 69.250 185.00 199.31 -14.31 + 69.275 218.00 210.78 7.22 + 69.300 207.00 227.19 -20.19 + 69.325 244.00 228.72 15.28 + 69.350 220.00 223.99 -3.99 + 69.375 243.00 224.38 18.62 + 69.400 266.00 232.57 33.43 + 69.425 280.00 248.31 31.69 + 69.450 324.00 277.57 46.43 + 69.475 394.00 328.65 65.35 + 69.500 567.00 436.20 130.80 + 69.525 690.00 671.79 18.21 + 69.550 853.00 1092.83 -239.83 + 69.575 934.00 1222.07 -288.07 + 69.600 815.00 882.71 -67.71 + 69.625 877.00 777.46 99.54 + 69.650 894.00 949.70 -55.70 + 69.675 888.00 955.57 -67.57 + 69.700 744.00 702.70 41.30 + 69.725 665.00 632.46 32.54 + 69.750 674.00 764.33 -90.33 + 69.775 693.00 774.87 -81.87 + 69.800 634.00 583.64 50.36 + 69.825 583.00 527.32 55.68 + 69.850 589.00 609.88 -20.88 + 69.875 572.00 597.50 -25.50 + 69.900 455.00 457.36 -2.36 + 69.925 501.00 390.27 110.73 + 69.950 497.00 404.71 92.29 + 69.975 637.00 519.18 117.82 + 70.000 833.00 824.39 8.61 + 70.025 1120.00 1282.34 -162.34 + 70.050 968.00 1157.44 -189.44 + 70.075 776.00 695.10 80.90 + 70.100 526.00 447.47 78.53 + 70.125 397.00 357.63 39.37 + 70.150 372.00 338.38 33.62 + 70.175 472.00 377.77 94.23 + 70.200 548.00 513.80 34.20 + 70.225 682.00 739.75 -57.75 + 70.250 632.00 678.88 -46.88 + 70.275 479.00 440.68 38.32 + 70.300 341.00 309.92 31.08 + 70.325 304.00 256.10 47.90 + 70.350 211.00 231.39 -20.39 + 70.375 213.00 217.80 -4.80 + 70.400 199.00 209.53 -10.53 + 70.425 185.00 204.31 -19.31 + 70.450 190.00 201.08 -11.08 + 70.475 194.00 194.08 -0.08 + 70.500 183.00 198.13 -15.13 + 70.525 193.00 200.57 -7.57 + 70.550 204.00 205.43 -1.43 + 70.575 201.00 214.85 -13.85 + 70.600 264.00 235.52 28.48 + 70.625 298.00 285.84 12.16 + 70.650 373.00 387.94 -14.94 + 70.675 364.00 436.28 -72.28 + 70.700 306.00 337.19 -31.19 + 70.725 270.00 268.48 1.52 + 70.750 271.00 244.43 26.57 + 70.775 259.00 243.94 15.06 + 70.800 298.00 262.33 35.67 + 70.825 371.00 308.16 62.84 + 70.850 433.00 415.44 17.56 + 70.875 565.00 594.75 -29.75 + 70.900 625.00 789.19 -164.19 + 70.925 581.00 754.27 -173.27 + 70.950 460.00 489.60 -29.60 + 70.975 365.00 341.25 23.75 + 71.000 291.00 285.80 5.20 + 71.025 270.00 270.88 -0.88 + 71.050 311.00 284.68 26.32 + 71.075 317.00 343.81 -26.81 + 71.100 411.00 462.56 -51.56 + 71.125 435.00 508.18 -73.18 + 71.150 426.00 418.79 7.21 + 71.175 481.00 420.03 60.97 + 71.200 415.00 473.60 -58.60 + 71.225 358.00 379.95 -21.95 + 71.250 268.00 283.56 -15.56 + 71.275 245.00 240.47 4.53 + 71.300 239.00 223.15 15.85 + 71.325 204.00 219.00 -15.00 + 71.350 246.00 225.01 20.99 + 71.375 236.00 257.64 -21.64 + 71.400 272.00 306.66 -34.66 + 71.425 241.00 279.70 -38.70 + 71.450 203.00 229.01 -26.01 + 71.475 182.00 204.56 -22.56 + 71.500 189.00 194.19 -5.19 + 71.525 163.00 188.90 -25.90 + 71.550 165.00 184.40 -19.40 + 71.575 161.00 182.61 -21.61 + 71.600 145.00 181.39 -36.39 + 71.625 149.00 179.26 -30.26 + 71.650 163.00 178.88 -15.88 + 71.675 166.00 178.56 -12.56 + 71.700 138.00 178.33 -40.33 + 71.725 141.00 178.17 -37.17 + 71.750 158.00 178.08 -20.08 + 71.775 145.00 178.04 -33.04 + 71.800 131.00 178.06 -47.06 + 71.825 135.00 177.43 -42.43 + 71.850 147.00 177.78 -30.78 + 71.875 133.00 178.24 -45.24 + 71.900 140.00 178.89 -38.89 + 71.925 144.00 182.73 -38.73 + 71.950 155.00 185.37 -30.37 + 71.975 157.00 191.11 -34.11 + 72.000 196.00 203.22 -7.22 + 72.025 193.00 213.88 -20.88 + 72.050 175.00 210.99 -35.99 + 72.075 172.00 201.32 -29.32 + 72.100 174.00 194.97 -20.97 + 72.125 148.00 195.69 -47.69 + 72.150 164.00 199.15 -35.15 + 72.175 177.00 206.98 -29.98 + 72.200 183.00 222.65 -39.65 + 72.225 250.00 251.59 -1.59 + 72.250 310.00 304.47 5.53 + 72.275 439.00 426.50 12.50 + 72.300 401.00 569.10 -168.10 + 72.325 356.00 444.05 -88.05 + 72.350 276.00 306.30 -30.30 + 72.375 178.00 248.79 -70.79 + 72.400 216.00 228.10 -12.10 + 72.425 209.00 224.02 -15.02 + 72.450 222.00 235.89 -13.89 + 72.475 263.00 278.17 -15.17 + 72.500 281.00 360.63 -79.63 + 72.525 270.00 346.34 -76.34 + 72.550 217.00 261.98 -44.98 + 72.575 181.00 220.03 -39.03 + 72.600 183.00 202.67 -19.67 + 72.625 174.00 194.54 -20.54 + 72.650 171.00 190.32 -19.32 + 72.675 151.00 188.68 -37.68 + 72.700 142.00 188.38 -46.38 + 72.725 130.00 183.51 -53.51 + 72.750 147.00 181.21 -34.21 + 72.775 146.00 180.00 -34.00 + 72.800 148.00 179.33 -31.33 + 72.825 124.00 178.93 -54.93 + 72.850 129.00 178.78 -49.78 + 72.875 128.00 178.98 -50.98 + 72.900 135.00 179.70 -44.70 + 72.925 143.00 178.42 -35.42 + 72.950 135.00 177.47 -42.47 + 72.975 145.00 176.99 -31.99 + 73.000 134.00 176.78 -42.78 + 73.025 131.00 176.69 -45.69 + 73.050 154.00 176.63 -22.63 + 73.075 135.00 176.60 -41.60 + 73.100 139.00 176.55 -37.55 + 73.125 155.00 176.53 -21.53 + 73.150 143.00 176.52 -33.52 + 73.175 151.00 178.16 -27.16 + 73.200 154.00 178.39 -24.39 + 73.225 160.00 178.68 -18.68 + 73.250 141.00 179.05 -38.05 + 73.275 160.00 185.47 -25.47 + 73.300 155.00 186.96 -31.96 + 73.325 171.00 188.86 -17.86 + 73.350 166.00 191.36 -25.36 + 73.375 159.00 194.75 -35.75 + 73.400 187.00 200.38 -13.38 + 73.425 205.00 207.54 -2.54 + 73.450 212.00 218.80 -6.80 + 73.475 230.00 238.49 -8.49 + 73.500 313.00 281.68 31.32 + 73.525 346.00 372.45 -26.45 + 73.550 402.00 499.64 -97.64 + 73.575 511.00 477.10 33.90 + 73.600 535.00 515.78 19.22 + 73.625 696.00 781.40 -85.40 + 73.650 717.00 1062.58 -345.58 + 73.675 624.00 720.63 -96.63 + 73.700 520.00 456.95 63.05 + 73.725 421.00 371.56 49.44 + 73.750 399.00 381.62 17.38 + 73.775 344.00 389.61 -45.61 + 73.800 380.00 356.85 23.15 + 73.825 468.00 408.63 59.37 + 73.850 482.00 581.66 -99.66 + 73.875 453.00 574.59 -121.59 + 73.900 373.00 377.87 -4.87 + 73.925 267.00 281.54 -14.54 + 73.950 229.00 239.84 -10.84 + 73.975 209.00 220.72 -11.72 + 74.000 176.00 210.46 -34.46 + 74.025 193.00 204.75 -11.75 + 74.050 210.00 197.49 12.51 + 74.075 179.00 197.87 -18.87 + 74.100 173.00 203.40 -30.40 + 74.125 207.00 212.32 -5.32 + 74.150 225.00 233.84 -8.84 + 74.175 265.00 287.70 -22.70 + 74.200 315.00 373.69 -58.69 + 74.225 289.00 322.54 -33.54 + 74.250 229.00 252.27 -23.27 + 74.275 197.00 225.20 -28.20 + 74.300 204.00 218.52 -14.52 + 74.325 221.00 220.77 0.23 + 74.350 249.00 232.49 16.51 + 74.375 258.00 261.37 -3.37 + 74.400 290.00 329.99 -39.99 + 74.425 401.00 439.00 -38.00 + 74.450 434.00 533.74 -99.74 + 74.475 421.00 446.44 -25.44 + 74.500 368.00 332.94 35.06 + 74.525 358.00 301.65 56.35 + 74.550 396.00 322.02 73.98 + 74.575 462.00 410.21 51.79 + 74.600 547.00 641.26 -94.26 + 74.625 580.00 822.74 -242.74 + 74.650 497.00 603.44 -106.44 + 74.675 442.00 487.48 -45.48 + 74.700 397.00 361.99 35.01 + 74.725 313.00 292.53 20.47 + 74.750 316.00 270.43 45.57 + 74.775 296.00 278.54 17.46 + 74.800 341.00 329.45 11.55 + 74.825 355.00 458.82 -103.82 + 74.850 373.00 464.12 -91.12 + 74.875 333.00 329.34 3.66 + 74.900 274.00 269.96 4.04 + 74.925 262.00 255.12 6.88 + 74.950 290.00 269.22 20.78 + 74.975 329.00 329.31 -0.31 + 75.000 333.00 460.39 -127.39 + 75.025 356.00 435.99 -79.99 + 75.050 280.00 301.93 -21.93 + 75.075 237.00 243.72 -6.72 + 75.100 214.00 223.23 -9.23 + 75.125 238.00 215.15 22.85 + 75.150 243.00 216.22 26.78 + 75.175 204.00 229.07 -25.07 + 75.200 239.00 268.07 -29.07 + 75.225 255.00 333.57 -78.57 + 75.250 249.00 294.44 -45.44 + 75.275 226.00 238.06 -12.06 + 75.300 191.00 216.75 -25.75 + 75.325 222.00 212.26 9.74 + 75.350 193.00 215.56 -22.56 + 75.375 236.00 229.08 6.92 + 75.400 264.00 261.62 2.38 + 75.425 308.00 350.61 -42.61 + 75.450 340.00 494.82 -154.82 + 75.475 330.00 405.12 -75.12 + 75.500 282.00 284.85 -2.85 + 75.525 229.00 238.98 -9.98 + 75.550 235.00 220.33 14.67 + 75.575 204.00 214.58 -10.58 + 75.600 203.00 218.12 -15.12 + 75.625 252.00 234.62 17.38 + 75.650 249.00 283.96 -34.96 + 75.675 232.00 348.13 -116.13 + 75.700 222.00 289.56 -67.56 + 75.725 217.00 238.02 -21.02 + 75.750 226.00 221.51 4.49 + 75.775 222.00 220.78 1.22 + 75.800 238.00 229.97 8.03 + 75.825 265.00 256.57 8.43 + 75.850 341.00 323.25 17.75 + 75.875 339.00 477.80 -138.80 + 75.900 338.00 494.31 -156.31 + 75.925 302.00 335.94 -33.94 + 75.950 275.00 261.97 13.03 + 75.975 242.00 234.56 7.44 + 76.000 218.00 227.32 -9.32 + 76.025 232.00 232.05 -0.05 + 76.050 297.00 253.34 43.66 + 76.075 360.00 317.99 42.01 + 76.100 399.00 454.73 -55.73 + 76.125 423.00 535.83 -112.83 + 76.150 365.00 396.23 -31.23 + 76.175 273.00 292.11 -19.11 + 76.200 254.00 252.02 1.98 + 76.225 262.00 238.00 24.00 + 76.250 216.00 236.77 -20.77 + 76.275 316.00 243.59 72.41 + 76.300 339.00 271.56 67.44 + 76.325 402.00 326.84 75.16 + 76.350 509.00 418.89 90.11 + 76.375 598.00 498.77 99.23 + 76.400 700.00 746.53 -46.53 + 76.425 742.00 1171.38 -429.38 + 76.450 619.00 879.23 -260.23 + 76.475 470.00 511.67 -41.67 + 76.500 398.00 361.56 36.44 + 76.525 379.00 301.07 77.93 + 76.550 352.00 280.79 71.21 + 76.575 351.00 287.38 63.62 + 76.600 379.00 334.68 44.32 + 76.625 443.00 466.21 -23.21 + 76.650 466.00 679.72 -213.72 + 76.675 438.00 537.42 -99.42 + 76.700 357.00 351.62 5.38 + 76.725 289.00 274.47 14.53 + 76.750 258.00 240.80 17.20 + 76.775 233.00 225.38 7.62 + 76.800 216.00 218.63 -2.63 + 76.825 241.00 213.02 27.98 + 76.850 235.00 219.33 15.67 + 76.875 277.00 235.85 41.15 + 76.900 309.00 275.73 33.27 + 76.925 358.00 376.79 -18.79 + 76.950 356.00 533.34 -177.34 + 76.975 323.00 432.49 -109.49 + 77.000 273.00 301.32 -28.32 + 77.025 243.00 248.35 -5.35 + 77.050 224.00 224.54 -0.54 + 77.075 243.00 218.22 24.78 + 77.100 250.00 221.59 28.41 + 77.125 220.00 238.26 -18.26 + 77.150 267.00 284.71 -17.71 + 77.175 291.00 367.40 -76.40 + 77.200 282.00 334.84 -52.84 + 77.225 252.00 274.39 -22.39 + 77.250 255.00 263.87 -8.87 + 77.275 328.00 293.41 34.59 + 77.300 357.00 391.29 -34.29 + 77.325 411.00 569.57 -158.57 + 77.350 375.00 480.72 -105.72 + 77.375 323.00 322.27 0.73 + 77.400 267.00 255.83 11.17 + 77.425 240.00 229.09 10.91 + 77.450 208.00 219.03 -11.03 + 77.475 209.00 219.46 -10.46 + 77.500 236.00 232.88 3.12 + 77.525 248.00 274.40 -26.40 + 77.550 261.00 362.28 -101.28 + 77.575 256.00 344.33 -88.33 + 77.600 244.00 257.54 -13.54 + 77.625 203.00 218.02 -15.02 + 77.650 173.00 201.08 -28.08 + 77.675 170.00 192.66 -22.66 + 77.700 174.00 187.90 -13.90 + 77.725 168.00 182.41 -14.41 + 77.750 167.00 180.73 -13.73 + 77.775 181.00 179.59 1.41 + 77.800 159.00 191.22 -32.22 + 77.825 195.00 192.43 2.57 + 77.850 168.00 194.22 -26.22 + 77.875 180.00 196.70 -16.70 + 77.900 186.00 200.10 -14.10 + 77.925 175.00 204.85 -29.85 + 77.950 191.00 209.73 -18.73 + 77.975 213.00 217.74 -4.74 + 78.000 274.00 229.53 44.47 + 78.025 266.00 247.42 18.58 + 78.050 323.00 282.73 40.27 + 78.075 421.00 332.61 88.39 + 78.100 552.00 426.65 125.35 + 78.125 799.00 629.71 169.29 + 78.150 1129.00 1125.54 3.46 + 78.175 1277.00 1940.08 -663.08 + 78.200 1123.00 1503.96 -380.96 + 78.225 820.00 809.95 10.05 + 78.250 610.00 522.27 87.73 + 78.275 504.00 407.02 96.98 + 78.300 408.00 364.59 43.41 + 78.325 478.00 368.02 109.98 + 78.350 543.00 426.43 116.57 + 78.375 708.00 602.85 105.15 + 78.400 817.00 995.88 -178.88 + 78.425 736.00 1011.57 -275.57 + 78.450 641.00 619.93 21.07 + 78.475 568.00 459.33 108.67 + 78.500 413.00 461.02 -48.02 + 78.525 433.00 475.44 -42.44 + 78.550 373.00 360.45 12.55 + 78.575 314.00 285.43 28.57 + 78.600 321.00 275.89 45.11 + 78.625 244.00 290.67 -46.67 + 78.650 262.00 268.75 -6.75 + 78.675 251.00 258.61 -7.61 + 78.700 232.00 253.88 -21.88 + 78.725 241.00 267.30 -26.30 + 78.750 216.00 304.90 -88.90 + 78.775 240.00 268.84 -28.84 + 78.800 212.00 223.69 -11.69 + 78.825 196.00 213.52 -17.52 + 78.850 173.00 220.94 -47.94 + 78.875 187.00 217.30 -30.30 + 78.900 175.00 206.14 -31.14 + 78.925 173.00 199.12 -26.12 + 78.950 152.00 189.46 -37.46 + 78.975 163.00 183.93 -20.93 + 79.000 143.00 181.27 -38.27 + 79.025 135.00 179.42 -44.42 + 79.050 122.00 178.61 -56.61 + 79.075 139.00 177.95 -38.95 + 79.100 128.00 177.71 -49.71 + 79.125 134.00 177.65 -43.65 + 79.150 140.00 177.09 -37.09 + 79.175 117.00 177.53 -60.53 + 79.200 150.00 178.52 -28.52 + 79.225 134.00 179.99 -45.99 + 79.250 152.00 182.64 -30.64 + 79.275 127.00 188.87 -61.87 + 79.300 170.00 203.90 -33.90 + 79.325 158.00 227.85 -69.85 + 79.350 155.00 214.22 -59.22 + 79.375 173.00 193.62 -20.62 + 79.400 161.00 185.01 -24.01 + 79.425 136.00 181.51 -45.51 + 79.450 128.00 180.17 -52.17 + 79.475 177.00 182.48 -5.48 + 79.500 165.00 184.34 -19.34 + 79.525 140.00 189.23 -49.23 + 79.550 154.00 200.28 -46.28 + 79.575 143.00 205.23 -62.23 + 79.600 168.00 193.68 -25.68 + 79.625 189.00 187.87 1.13 + 79.650 130.00 186.54 -56.54 + 79.675 160.00 187.43 -27.43 + 79.700 151.00 190.12 -39.12 + 79.725 182.00 196.06 -14.06 + 79.750 221.00 205.54 15.46 + 79.775 238.00 223.81 14.19 + 79.800 260.00 263.91 -3.91 + 79.825 315.00 360.83 -45.83 + 79.850 327.00 496.56 -169.56 + 79.875 311.00 400.00 -89.00 + 79.900 246.00 283.03 -37.03 + 79.925 211.00 234.48 -23.48 + 79.950 204.00 214.57 -10.57 + 79.975 196.00 206.78 -10.78 + 80.000 211.00 206.65 4.35 + 80.025 191.00 215.22 -24.22 + 80.050 234.00 241.53 -7.53 + 80.075 225.00 304.90 -79.90 + 80.100 255.00 332.17 -77.17 + 80.125 200.00 259.21 -59.21 + 80.150 186.00 216.93 -30.93 + 80.175 186.00 199.16 -13.16 + 80.200 162.00 190.78 -28.78 + 80.225 140.00 186.31 -46.31 + 80.250 153.00 181.70 -28.70 + 80.275 147.00 180.74 -33.74 + 80.300 143.00 181.14 -38.14 + 80.325 153.00 183.85 -30.85 + 80.350 154.00 185.91 -31.91 + 80.375 133.00 181.48 -48.48 + 80.400 145.00 178.49 -33.49 + 80.425 148.00 177.16 -29.16 + 80.450 165.00 179.79 -14.79 + 80.475 155.00 179.93 -24.93 + 80.500 155.00 179.41 -24.41 + 80.525 147.00 180.46 -33.46 + 80.550 176.00 182.31 -6.31 + 80.575 149.00 185.52 -36.52 + 80.600 165.00 187.10 -22.10 + 80.625 136.00 187.25 -51.25 + 80.650 163.00 189.43 -26.43 + 80.675 163.00 198.71 -35.71 + 80.700 198.00 208.49 -10.49 + 80.725 215.00 222.49 -7.49 + 80.750 249.00 248.45 0.55 + 80.775 304.00 303.64 0.36 + 80.800 377.00 434.64 -57.64 + 80.825 414.00 637.42 -223.42 + 80.850 339.00 524.35 -185.35 + 80.875 322.00 356.46 -34.46 + 80.900 284.00 290.70 -6.70 + 80.925 301.00 274.76 26.24 + 80.950 311.00 283.01 27.99 + 80.975 380.00 320.02 59.98 + 81.000 550.00 413.12 136.88 + 81.025 624.00 643.96 -19.96 + 81.050 660.00 1009.31 -349.31 + 81.075 617.00 886.72 -269.72 + 81.100 461.00 547.31 -86.31 + 81.125 363.00 370.95 -7.95 + 81.150 284.00 297.35 -13.35 + 81.175 266.00 265.90 0.10 + 81.200 268.00 256.30 11.70 + 81.225 289.00 263.65 25.35 + 81.250 340.00 305.87 34.13 + 81.275 375.00 419.04 -44.04 + 81.300 363.00 527.83 -164.83 + 81.325 327.00 389.24 -62.24 + 81.350 259.00 282.54 -23.54 + 81.375 216.00 238.26 -22.26 + 81.400 172.00 217.63 -45.63 + 81.425 180.00 205.92 -25.92 + 81.450 208.00 195.10 12.90 + 81.475 177.00 191.55 -14.55 + 81.500 157.00 191.78 -34.78 + 81.525 189.00 195.07 -6.07 + 81.550 192.00 204.08 -12.08 + 81.575 222.00 227.01 -5.01 + 81.600 222.00 278.10 -56.10 + 81.625 188.00 291.22 -103.22 + 81.650 184.00 236.33 -52.33 + 81.675 164.00 206.41 -42.41 + 81.700 173.00 191.85 -18.85 + 81.725 182.00 186.74 -4.74 + 81.750 153.00 184.98 -31.98 + 81.775 158.00 185.75 -27.75 + 81.800 158.00 190.07 -32.07 + 81.825 183.00 202.33 -19.33 + 81.850 190.00 228.40 -38.40 + 81.875 178.00 228.15 -50.15 + 81.900 169.00 201.18 -32.18 + 81.925 145.00 187.71 -42.71 + 81.950 170.00 181.89 -11.89 + 81.975 138.00 179.01 -41.01 + 82.000 169.00 177.39 -8.39 + 82.025 133.00 175.63 -42.63 + 82.050 134.00 175.03 -41.03 + 82.075 122.00 174.63 -52.63 + 82.100 126.00 174.34 -48.34 + 82.125 153.00 174.13 -21.13 + 82.150 112.00 173.96 -61.96 + 82.175 125.00 173.83 -48.83 + 82.200 127.00 173.72 -46.72 + 82.225 147.00 173.63 -26.63 + 82.250 125.00 173.56 -48.56 + 82.275 125.00 173.12 -48.12 + 82.300 142.00 173.10 -31.10 + 82.325 143.00 174.02 -31.02 + 82.350 138.00 174.14 -36.14 + 82.375 145.00 174.29 -29.29 + 82.400 166.00 174.49 -8.49 + 82.425 165.00 174.74 -9.74 + 82.450 156.00 175.07 -19.07 + 82.475 154.00 179.98 -25.98 + 82.500 169.00 184.86 -15.86 + 82.525 130.00 187.03 -57.03 + 82.550 173.00 189.96 -16.96 + 82.575 155.00 194.54 -39.54 + 82.600 178.00 200.81 -22.81 + 82.625 211.00 211.16 -0.16 + 82.650 247.00 230.67 16.33 + 82.675 289.00 272.56 16.44 + 82.700 310.00 336.58 -26.58 + 82.725 276.00 321.86 -45.86 + 82.750 303.00 296.24 6.76 + 82.775 376.00 317.27 58.73 + 82.800 468.00 390.69 77.31 + 82.825 665.00 565.15 99.85 + 82.850 803.00 931.33 -128.33 + 82.875 829.00 1136.18 -307.18 + 82.900 683.00 986.92 -303.92 + 82.925 570.00 641.91 -71.91 + 82.950 507.00 473.81 33.19 + 82.975 383.00 381.90 1.10 + 83.000 335.00 326.39 8.61 + 83.025 352.00 313.58 38.42 + 83.050 412.00 338.44 73.56 + 83.075 522.00 419.19 102.81 + 83.100 575.00 606.61 -31.61 + 83.125 652.00 772.20 -120.20 + 83.150 681.00 825.82 -144.82 + 83.175 634.00 807.33 -173.33 + 83.200 466.00 580.13 -114.13 + 83.225 368.00 386.45 -18.45 + 83.250 301.00 300.46 0.54 + 83.275 214.00 256.87 -42.87 + 83.300 226.00 234.51 -8.51 + 83.325 205.00 227.25 -22.25 + 83.350 239.00 229.62 9.38 + 83.375 226.00 246.07 -20.07 + 83.400 271.00 294.85 -23.85 + 83.425 279.00 381.29 -102.29 + 83.450 280.00 346.62 -66.62 + 83.475 247.00 270.54 -23.54 + 83.500 223.00 243.93 -20.93 + 83.525 201.00 250.24 -49.24 + 83.550 199.00 286.99 -87.99 + 83.575 198.00 271.04 -73.04 + 83.600 206.00 223.84 -17.84 + 83.625 191.00 201.18 -10.18 + 83.650 154.00 191.27 -37.27 + 83.675 174.00 186.64 -12.64 + 83.700 144.00 184.72 -40.72 + 83.725 155.00 185.86 -30.86 + 83.750 161.00 189.11 -28.11 + 83.775 172.00 198.53 -26.53 + 83.800 178.00 219.89 -41.89 + 83.825 192.00 225.61 -33.61 + 83.850 155.00 201.00 -46.00 + 83.875 171.00 188.37 -17.37 + 83.900 155.00 183.36 -28.36 + 83.925 160.00 181.52 -21.52 + 83.950 138.00 181.35 -43.35 + 83.975 156.00 182.32 -26.32 + 84.000 178.00 185.43 -7.43 + 84.025 163.00 191.78 -28.78 + 84.050 191.00 205.57 -14.57 + 84.075 200.00 238.27 -38.27 + 84.100 208.00 296.04 -88.04 + 84.125 186.00 280.64 -94.64 + 84.150 167.00 227.32 -60.32 + 84.175 183.00 201.44 -18.44 + 84.200 157.00 193.58 -36.58 + 84.225 148.00 192.23 -44.23 + 84.250 163.00 191.58 -28.58 + 84.275 174.00 193.56 -19.56 + 84.300 187.00 199.22 -12.22 + 84.325 182.00 212.60 -30.60 + 84.350 189.00 241.02 -52.02 + 84.375 190.00 253.72 -63.72 + 84.400 190.00 230.11 -40.11 + 84.425 199.00 219.23 -20.23 + 84.450 240.00 221.36 18.64 + 84.475 247.00 234.77 12.23 + 84.500 334.00 261.24 72.76 + 84.525 391.00 310.05 80.95 + 84.550 512.00 418.40 93.60 + 84.575 618.00 661.39 -43.39 + 84.600 663.00 935.84 -272.84 + 84.625 593.00 889.58 -296.58 + 84.650 456.00 575.13 -119.13 + 84.675 395.00 383.05 11.95 + 84.700 343.00 301.95 41.05 + 84.725 288.00 267.18 20.82 + 84.750 292.00 255.19 36.81 + 84.775 310.00 260.26 49.74 + 84.800 392.00 290.28 101.72 + 84.825 389.00 372.27 16.73 + 84.850 437.00 521.85 -84.85 + 84.875 361.00 570.28 -209.28 + 84.900 351.00 444.42 -93.42 + 84.925 262.00 311.16 -49.16 + 84.950 250.00 250.08 -0.08 + 84.975 233.00 221.66 11.34 + 85.000 197.00 203.71 -6.71 + 85.025 195.00 191.93 3.07 + 85.050 171.00 187.00 -16.00 + 85.075 174.00 184.05 -10.05 + 85.100 171.00 182.67 -11.67 + 85.125 159.00 181.23 -22.23 + 85.150 158.00 178.85 -20.85 + 85.175 120.00 177.23 -57.23 + 85.200 128.00 178.26 -50.26 + 85.225 140.00 177.80 -37.80 + 85.250 148.00 177.59 -29.59 + 85.275 156.00 176.25 -20.25 + 85.300 133.00 175.13 -42.13 + 85.325 156.00 175.97 -19.97 + 85.350 144.00 177.25 -33.25 + 85.375 163.00 179.01 -16.01 + 85.400 158.00 180.45 -22.45 + 85.425 158.00 182.59 -24.59 + 85.450 154.00 186.39 -32.39 + 85.475 165.00 193.97 -28.97 + 85.500 196.00 205.91 -9.91 + 85.525 206.00 229.83 -23.83 + 85.550 256.00 284.19 -28.19 + 85.575 278.00 400.28 -122.28 + 85.600 255.00 441.42 -186.42 + 85.625 253.00 317.49 -64.49 + 85.650 223.00 245.52 -22.52 + 85.675 190.00 215.38 -25.38 + 85.700 196.00 202.07 -6.07 + 85.725 176.00 196.50 -20.50 + 85.750 171.00 195.87 -24.87 + 85.775 212.00 200.54 11.46 + 85.800 204.00 214.76 -10.76 + 85.825 252.00 251.29 0.71 + 85.850 224.00 311.27 -87.27 + 85.875 192.00 283.87 -91.87 + 85.900 180.00 227.36 -47.36 + 85.925 172.00 201.21 -29.21 + 85.950 166.00 189.46 -23.46 + 85.975 159.00 183.44 -24.44 + 86.000 155.00 178.06 -23.06 + 86.025 148.00 176.14 -28.14 + 86.050 167.00 174.86 -7.86 + 86.075 137.00 174.07 -37.07 + 86.100 178.00 173.45 4.55 + 86.125 161.00 181.15 -20.15 + 86.150 180.00 181.94 -1.94 + 86.175 156.00 183.06 -27.06 + 86.200 169.00 184.59 -15.59 + 86.225 178.00 186.61 -8.61 + 86.250 174.00 189.31 -15.31 + 86.275 181.00 192.07 -11.07 + 86.300 172.00 197.17 -25.17 + 86.325 238.00 204.38 33.62 + 86.350 209.00 215.14 -6.14 + 86.375 240.00 232.15 7.85 + 86.400 343.00 263.99 79.01 + 86.425 384.00 306.08 77.92 + 86.450 500.00 387.15 112.85 + 86.475 673.00 562.86 110.14 + 86.500 704.00 951.63 -247.63 + 86.525 763.00 1320.20 -557.20 + 86.550 656.00 894.13 -238.13 + 86.575 551.00 533.62 17.38 + 86.600 406.00 379.90 26.10 + 86.625 354.00 313.41 40.59 + 86.650 352.00 285.52 66.48 + 86.675 301.00 279.49 21.51 + 86.700 357.00 290.24 66.76 + 86.725 414.00 330.46 83.54 + 86.750 440.00 430.82 9.18 + 86.775 502.00 651.17 -149.17 + 86.800 459.00 752.81 -293.81 + 86.825 425.00 514.62 -89.62 + 86.850 378.00 377.25 0.75 + 86.875 418.00 341.82 76.18 + 86.900 427.00 380.17 46.83 + 86.925 467.00 491.64 -24.64 + 86.950 441.00 502.83 -61.83 + 86.975 400.00 450.40 -50.40 + 87.000 327.00 342.73 -15.73 + 87.025 278.00 267.41 10.59 + 87.050 259.00 233.58 25.42 + 87.075 240.00 218.39 21.61 + 87.100 213.00 212.79 0.21 + 87.125 206.00 214.91 -8.91 + 87.150 241.00 228.18 12.82 + 87.175 263.00 264.79 -1.79 + 87.200 287.00 321.85 -34.85 + 87.225 291.00 323.95 -32.95 + 87.250 245.00 296.85 -51.85 + 87.275 243.00 243.60 -0.60 + 87.300 198.00 212.63 -14.63 + 87.325 195.00 197.45 -2.45 + 87.350 195.00 188.39 6.61 + 87.375 164.00 184.58 -20.58 + 87.400 178.00 181.56 -3.56 + 87.425 161.00 180.74 -19.74 + 87.450 161.00 180.71 -19.71 + 87.475 183.00 181.40 1.60 + 87.500 177.00 182.90 -5.90 + 87.525 177.00 185.51 -8.51 + 87.550 177.00 190.97 -13.97 + 87.575 192.00 198.37 -6.37 + 87.600 219.00 211.58 7.42 + 87.625 260.00 236.97 23.03 + 87.650 310.00 295.52 14.48 + 87.675 337.00 421.04 -84.04 + 87.700 312.00 513.92 -201.92 + 87.725 290.00 382.68 -92.68 + 87.750 275.00 277.15 -2.15 + 87.775 243.00 231.06 11.94 + 87.800 192.00 210.86 -18.86 + 87.825 200.00 201.81 -1.81 + 87.850 212.00 198.93 13.07 + 87.875 205.00 201.38 3.62 + 87.900 180.00 211.72 -31.72 + 87.925 219.00 239.12 -20.12 + 87.950 274.00 300.02 -26.02 + 87.975 271.00 343.55 -72.55 + 88.000 200.00 278.48 -78.48 + 88.025 205.00 225.28 -20.28 + 88.050 195.00 201.58 -6.58 + 88.075 179.00 191.13 -12.13 + 88.100 171.00 185.23 -14.23 + 88.125 171.00 178.53 -7.53 + 88.150 147.00 175.91 -28.91 + 88.175 147.00 174.27 -27.27 + 88.200 167.00 173.18 -6.18 + 88.225 159.00 172.40 -13.40 + 88.250 157.00 171.84 -14.84 + 88.275 145.00 171.44 -26.44 + 88.300 164.00 171.18 -7.18 + 88.325 142.00 173.09 -31.09 + 88.350 143.00 173.51 -30.51 + 88.375 164.00 173.74 -9.74 + 88.400 157.00 172.41 -15.41 + 88.425 153.00 172.57 -19.57 + 88.450 145.00 173.00 -28.00 + 88.475 168.00 173.64 -5.64 + 88.500 159.00 174.53 -15.53 + 88.525 169.00 175.74 -6.74 + 88.550 137.00 177.44 -40.44 + 88.575 182.00 179.87 2.13 + 88.600 196.00 184.49 11.51 + 88.625 218.00 190.38 27.62 + 88.650 216.00 200.40 15.60 + 88.675 223.00 222.43 0.57 + 88.700 269.00 264.39 4.61 + 88.725 295.00 355.23 -60.23 + 88.750 288.00 464.25 -176.25 + 88.775 280.00 398.12 -118.12 + 88.800 281.00 291.13 -10.13 + 88.825 187.00 239.08 -52.08 + 88.850 264.00 217.52 46.48 + 88.875 216.00 213.32 2.68 + 88.900 220.00 212.31 7.69 + 88.925 242.00 216.91 25.09 + 88.950 264.00 230.22 33.78 + 88.975 272.00 256.06 15.94 + 89.000 326.00 310.58 15.42 + 89.025 362.00 399.35 -37.35 + 89.050 407.00 453.67 -46.67 + 89.075 468.00 538.35 -70.35 + 89.100 432.00 648.38 -216.38 + 89.125 443.00 528.14 -85.14 + 89.150 383.00 394.60 -11.60 + 89.175 393.00 327.95 65.05 + 89.200 367.00 303.01 63.99 + 89.225 415.00 318.48 96.52 + 89.250 471.00 386.29 84.71 + 89.275 595.00 550.81 44.19 + 89.300 626.00 804.16 -178.16 + 89.325 583.00 781.46 -198.46 + 89.350 491.00 594.01 -103.01 + 89.375 456.00 534.57 -78.57 + 89.400 411.00 449.65 -38.65 + 89.425 322.00 346.50 -24.50 + 89.450 328.00 290.25 37.75 + 89.475 289.00 264.81 24.19 + 89.500 271.00 259.19 11.81 + 89.525 302.00 278.49 23.51 + 89.550 377.00 335.42 41.58 + 89.575 369.00 450.59 -81.59 + 89.600 373.00 492.16 -119.16 + 89.625 347.00 380.85 -33.85 + 89.650 296.00 307.96 -11.96 + 89.675 292.00 298.03 -6.03 + 89.700 257.00 305.69 -48.69 + 89.725 269.00 269.67 -0.67 + 89.750 241.00 235.09 5.91 + 89.775 218.00 214.97 3.03 + 89.800 212.00 210.79 1.21 + 89.825 239.00 214.81 24.19 + 89.850 254.00 228.29 25.71 + 89.875 295.00 265.14 29.86 + 89.900 314.00 344.88 -30.88 + 89.925 356.00 445.36 -89.36 + 89.950 301.00 413.83 -112.83 + 89.975 277.00 331.99 -54.99 + 90.000 252.00 273.80 -21.80 + 90.025 251.00 231.96 19.04 + 90.050 186.00 210.38 -24.38 + 90.075 197.00 198.93 -1.93 + 90.100 162.00 195.87 -33.87 + 90.125 192.00 198.17 -6.17 + 90.150 231.00 208.80 22.20 + 90.175 223.00 235.47 -12.47 + 90.200 207.00 283.62 -76.62 + 90.225 238.00 297.27 -59.27 + 90.250 196.00 248.20 -52.20 + 90.275 196.00 210.48 -14.48 + 90.300 176.00 192.26 -16.26 + 90.325 171.00 183.68 -12.68 + 90.350 178.00 179.09 -1.09 + 90.375 146.00 176.28 -30.28 + 90.400 169.00 172.83 -3.83 + 90.425 161.00 171.68 -10.68 + 90.450 149.00 170.85 -21.85 + 90.475 173.00 169.99 3.01 + 90.500 156.00 169.54 -13.54 + 90.525 143.00 169.19 -26.19 + 90.550 154.00 168.91 -14.91 + 90.575 152.00 168.68 -16.68 + 90.600 139.00 168.50 -29.50 + 90.625 184.00 168.34 15.66 + 90.650 185.00 172.53 12.47 + 90.675 161.00 172.89 -11.89 + 90.700 159.00 172.60 -13.60 + 90.725 152.00 173.25 -21.25 + 90.750 159.00 174.02 -15.02 + 90.775 176.00 175.93 0.07 + 90.800 164.00 177.20 -13.20 + 90.825 168.00 178.77 -10.77 + 90.850 193.00 180.76 12.24 + 90.875 195.00 183.32 11.68 + 90.900 187.00 187.01 -0.01 + 90.925 237.00 191.58 45.42 + 90.950 228.00 200.19 27.81 + 90.975 265.00 209.67 55.33 + 91.000 291.00 224.51 66.49 + 91.025 347.00 248.15 98.85 + 91.050 409.00 292.81 116.19 + 91.075 454.00 386.40 67.60 + 91.100 552.00 578.73 -26.73 + 91.125 524.00 854.59 -330.59 + 91.150 552.00 866.71 -314.71 + 91.175 502.00 612.30 -110.30 + 91.200 483.00 453.53 29.47 + 91.225 433.00 417.56 15.44 + 91.250 382.00 414.79 -32.79 + 91.275 363.00 355.66 7.34 + 91.300 322.00 304.02 17.98 + 91.325 328.00 289.97 38.03 + 91.350 389.00 314.51 74.49 + 91.375 469.00 386.84 82.16 + 91.400 485.00 502.41 -17.41 + 91.425 438.00 605.11 -167.11 + 91.450 491.00 547.84 -56.84 + 91.475 415.00 447.18 -32.18 + 91.500 377.00 389.17 -12.17 + 91.525 375.00 351.08 23.92 + 91.550 322.00 319.27 2.73 + 91.575 288.00 279.64 8.36 + 91.600 280.00 261.83 18.17 + 91.625 263.00 255.82 7.18 + 91.650 275.00 239.01 35.99 + 91.675 245.00 231.70 13.30 + 91.700 243.00 224.89 18.11 + 91.725 239.00 215.15 23.85 + 91.750 247.00 215.83 31.17 + 91.775 216.00 224.59 -8.59 + 91.800 204.00 219.36 -15.36 + 91.825 210.00 204.67 5.33 + 91.850 196.00 196.66 -0.66 + 91.875 220.00 196.50 23.50 + 91.900 209.00 201.94 7.06 + 91.925 212.00 203.32 8.68 + 91.950 226.00 196.20 29.80 + 91.975 201.00 192.74 8.26 + 92.000 225.00 194.35 30.65 + 92.025 228.00 201.68 26.32 + 92.050 210.00 208.24 1.76 + 92.075 244.00 219.57 24.43 + 92.100 298.00 238.59 59.41 + 92.125 405.00 274.41 130.59 + 92.150 445.00 350.25 94.75 + 92.175 534.00 501.87 32.13 + 92.200 579.00 717.37 -138.37 + 92.225 538.00 757.54 -219.54 + 92.250 495.00 559.13 -64.13 + 92.275 466.00 397.18 68.82 + 92.300 410.00 321.13 88.87 + 92.325 389.00 299.97 89.03 + 92.350 387.00 313.79 73.21 + 92.375 429.00 359.64 69.36 + 92.400 460.00 416.44 43.56 + 92.425 573.00 454.75 118.25 + 92.450 607.00 529.20 77.80 + 92.475 740.00 673.81 66.19 + 92.500 853.00 923.85 -70.85 + 92.525 781.00 1105.30 -324.30 + 92.550 733.00 933.23 -200.23 + 92.575 593.00 626.21 -33.21 + 92.600 499.00 429.98 69.02 + 92.625 398.00 338.14 59.86 + 92.650 368.00 306.75 61.25 + 92.675 334.00 306.33 27.67 + 92.700 370.00 315.85 54.15 + 92.725 358.00 316.68 41.32 + 92.750 391.00 325.17 65.83 + 92.775 376.00 355.66 20.34 + 92.800 394.00 426.99 -32.99 + 92.825 414.00 510.09 -96.09 + 92.850 383.00 469.29 -86.29 + 92.875 300.00 358.52 -58.52 + 92.900 294.00 280.51 13.49 + 92.925 275.00 240.75 34.25 + 92.950 246.00 223.87 22.13 + 92.975 259.00 215.97 43.03 + 93.000 235.00 212.86 22.14 + 93.025 239.00 214.27 24.73 + 93.050 243.00 218.86 24.14 + 93.075 277.00 230.41 46.59 + 93.100 363.00 263.27 99.73 + 93.125 383.00 328.96 54.04 + 93.150 434.00 430.37 3.63 + 93.175 436.00 487.62 -51.62 + 93.200 378.00 418.42 -40.42 + 93.225 373.00 341.36 31.64 + 93.250 386.00 314.61 71.39 + 93.275 438.00 339.33 98.67 + 93.300 464.00 406.37 57.63 + 93.325 491.00 481.37 9.63 + 93.350 539.00 545.64 -6.64 + 93.375 539.00 624.05 -85.05 + 93.400 523.00 698.86 -175.86 + 93.425 499.00 627.83 -128.83 + 93.450 478.00 530.78 -52.78 + 93.475 472.00 471.73 0.27 + 93.500 383.00 390.80 -7.80 + 93.525 345.00 321.93 23.07 + 93.550 354.00 289.85 64.15 + 93.575 352.00 290.48 61.52 + 93.600 383.00 317.35 65.65 + 93.625 370.00 354.61 15.39 + 93.650 410.00 391.36 18.64 + 93.675 453.00 441.00 12.00 + 93.700 416.00 501.92 -85.92 + 93.725 396.00 483.73 -87.73 + 93.750 392.00 401.41 -9.41 + 93.775 319.00 335.86 -16.86 + 93.800 335.00 306.23 28.77 + 93.825 407.00 307.63 99.37 + 93.850 461.00 344.38 116.62 + 93.875 587.00 439.68 147.32 + 93.900 741.00 633.36 107.64 + 93.925 875.00 918.79 -43.79 + 93.950 863.00 1076.74 -213.74 + 93.975 754.00 904.28 -150.28 + 94.000 619.00 632.25 -13.25 + 94.025 485.00 453.83 31.17 + 94.050 429.00 354.80 74.20 + 94.075 336.00 298.69 37.31 + 94.100 321.00 270.53 50.47 + 94.125 296.00 261.09 34.91 + 94.150 316.00 269.03 46.97 + 94.175 385.00 302.83 82.17 + 94.200 474.00 381.01 92.99 + 94.225 539.00 511.23 27.77 + 94.250 571.00 617.64 -46.64 + 94.275 493.00 568.03 -75.03 + 94.300 420.00 425.79 -5.79 + 94.325 345.00 315.25 29.75 + 94.350 272.00 254.44 17.56 + 94.375 242.00 224.34 17.66 + 94.400 219.00 208.67 10.33 + 94.425 229.00 199.42 29.58 + 94.450 203.00 193.44 9.56 + 94.475 220.00 190.05 29.95 + 94.500 211.00 185.02 25.98 + 94.525 190.00 181.88 8.12 + 94.550 171.00 181.59 -10.59 + 94.575 195.00 182.09 12.91 + 94.600 176.00 183.28 -7.28 + 94.625 218.00 185.93 32.07 + 94.650 208.00 190.75 17.25 + 94.675 212.00 200.05 11.95 + 94.700 230.00 219.43 10.57 + 94.725 265.00 258.43 6.57 + 94.750 314.00 323.32 -9.32 + 94.775 278.00 387.27 -109.27 + 94.800 306.00 372.24 -66.24 + 94.825 262.00 301.04 -39.04 + 94.850 281.00 244.81 36.19 + 94.875 209.00 215.57 -6.57 + 94.900 235.00 203.52 31.48 + 94.925 222.00 201.24 20.76 + 94.950 223.00 206.99 16.01 + 94.975 246.00 224.22 21.78 + 95.000 268.00 258.77 9.23 + 95.025 316.00 308.77 7.23 + 95.050 307.00 343.43 -36.43 + 95.075 316.00 345.75 -29.75 + 95.100 273.00 324.44 -51.44 + 95.125 247.00 275.52 -28.52 + 95.150 229.00 231.86 -2.86 + 95.175 201.00 205.88 -4.88 + 95.200 198.00 192.86 5.14 + 95.225 173.00 187.07 -14.07 + 95.250 202.00 185.66 16.34 + 95.275 173.00 188.71 -15.71 + 95.300 212.00 197.96 14.04 + 95.325 185.00 213.78 -28.78 + 95.350 197.00 226.67 -29.67 + 95.375 193.00 217.61 -24.61 + 95.400 193.00 198.91 -5.91 + 95.425 194.00 184.68 9.32 + 95.450 169.00 176.69 -7.69 + 95.475 169.00 172.68 -3.68 + 95.500 157.00 170.57 -13.57 + 95.525 167.00 169.21 -2.21 + 95.550 175.00 168.19 6.81 + 95.575 140.00 167.42 -27.42 + 95.600 174.00 168.52 5.48 + 95.625 146.00 168.23 -22.23 + 95.650 171.00 167.72 3.28 + 95.675 142.00 167.70 -25.70 + 95.700 152.00 167.23 -15.23 + 95.725 171.00 168.63 2.37 + 95.750 150.00 168.98 -18.98 + 95.775 142.00 169.44 -27.44 + 95.800 161.00 170.01 -9.01 + 95.825 150.00 170.70 -20.70 + 95.850 163.00 171.49 -8.49 + 95.875 154.00 172.45 -18.45 + 95.900 149.00 174.47 -25.47 + 95.925 157.00 176.13 -19.13 + 95.950 192.00 178.10 13.90 + 95.975 185.00 180.97 4.03 + 96.000 184.00 184.83 -0.83 + 96.025 205.00 190.82 14.18 + 96.050 231.00 198.98 32.02 + 96.075 238.00 212.72 25.28 + 96.100 263.00 238.77 24.23 + 96.125 324.00 289.02 34.98 + 96.150 365.00 374.64 -9.64 + 96.175 388.00 482.27 -94.27 + 96.200 380.00 531.28 -151.28 + 96.225 421.00 482.43 -61.43 + 96.250 418.00 427.26 -9.26 + 96.275 408.00 412.90 -4.90 + 96.300 385.00 442.47 -57.47 + 96.325 374.00 457.51 -83.51 + 96.350 346.00 400.22 -54.22 + 96.375 329.00 324.33 4.67 + 96.400 297.00 275.28 21.72 + 96.425 319.00 258.50 60.50 + 96.450 322.00 270.72 51.28 + 96.475 328.00 307.83 20.17 + 96.500 298.00 352.42 -54.42 + 96.525 290.00 359.48 -69.48 + 96.550 304.00 328.24 -24.24 + 96.575 311.00 302.70 8.30 + 96.600 312.00 298.96 13.04 + 96.625 319.00 313.62 5.38 + 96.650 292.00 313.01 -21.01 + 96.675 241.00 278.82 -37.82 + 96.700 239.00 241.58 -2.58 + 96.725 202.00 217.32 -15.32 + 96.750 206.00 205.34 0.66 + 96.775 202.00 201.67 0.33 + 96.800 227.00 204.37 22.63 + 96.825 236.00 213.96 22.04 + 96.850 307.00 239.47 67.53 + 96.875 309.00 285.38 23.62 + 96.900 385.00 346.66 38.34 + 96.925 341.00 380.56 -39.56 + 96.950 324.00 343.46 -19.46 + 96.975 290.00 281.90 8.10 + 97.000 208.00 235.72 -27.72 + 97.025 241.00 209.82 31.18 + 97.050 201.00 197.59 3.41 + 97.075 202.00 192.65 9.35 + 97.100 181.00 191.78 -10.78 + 97.125 217.00 194.64 22.36 + 97.150 264.00 202.28 61.72 + 97.175 229.00 220.73 8.27 + 97.200 326.00 254.54 71.46 + 97.225 303.00 303.44 -0.44 + 97.250 345.00 345.92 -0.92 + 97.275 304.00 350.42 -46.42 + 97.300 296.00 315.31 -19.31 + 97.325 241.00 265.04 -24.04 + 97.350 242.00 226.81 15.19 + 97.375 210.00 204.87 5.13 + 97.400 187.00 194.37 -7.37 + 97.425 206.00 190.50 15.50 + 97.450 194.00 191.12 2.88 + 97.475 221.00 196.81 24.19 + 97.500 216.00 210.94 5.06 + 97.525 245.00 237.85 7.15 + 97.550 242.00 277.47 -35.47 + 97.575 251.00 311.43 -60.43 + 97.600 258.00 310.93 -52.93 + 97.625 232.00 277.76 -45.76 + 97.650 215.00 238.54 -23.54 + 97.675 189.00 210.86 -21.86 + 97.700 192.00 196.57 -4.57 + 97.725 163.00 192.02 -29.02 + 97.750 158.00 193.31 -35.31 + 97.775 162.00 195.95 -33.95 + 97.800 174.00 195.63 -21.63 + 97.825 182.00 195.48 -13.48 + 97.850 169.00 201.08 -32.08 + 97.875 151.00 212.53 -61.53 + 97.900 187.00 221.35 -34.35 + 97.925 179.00 215.61 -36.61 + 97.950 167.00 199.64 -32.64 + 97.975 169.00 186.15 -17.15 + 98.000 146.00 177.89 -31.89 + 98.025 149.00 174.10 -25.10 + 98.050 146.00 173.31 -27.31 + 98.075 158.00 174.32 -16.32 + 98.100 142.00 175.44 -33.44 + 98.125 164.00 174.36 -10.36 + 98.150 142.00 171.93 -29.93 + 98.175 153.00 169.39 -16.39 + 98.200 147.00 167.68 -20.68 + 98.225 163.00 166.74 -3.74 + 98.250 160.00 165.82 -5.82 + 98.275 163.00 165.45 -2.45 + 98.300 127.00 165.49 -38.49 + 98.325 150.00 165.70 -15.70 + 98.350 159.00 166.09 -7.09 + 98.375 140.00 166.79 -26.79 + 98.400 136.00 168.12 -32.12 + 98.425 159.00 170.72 -11.72 + 98.450 171.00 175.46 -4.46 + 98.475 178.00 183.32 -5.32 + 98.500 159.00 192.36 -33.36 + 98.525 162.00 196.65 -34.65 + 98.550 193.00 191.64 1.36 + 98.575 156.00 183.11 -27.11 + 98.600 176.00 177.05 -1.05 + 98.625 161.00 173.89 -12.89 + 98.650 155.00 173.23 -18.23 + 98.675 146.00 174.60 -28.60 + 98.700 179.00 178.50 0.50 + 98.725 208.00 186.85 21.15 + 98.750 186.00 202.56 -16.56 + 98.775 194.00 227.33 -33.33 + 98.800 252.00 256.12 -4.12 + 98.825 230.00 269.83 -39.83 + 98.850 219.00 255.33 -36.33 + 98.875 182.00 228.02 -46.02 + 98.900 179.00 203.77 -24.77 + 98.925 174.00 188.03 -14.03 + 98.950 147.00 179.46 -32.46 + 98.975 189.00 175.35 13.65 + 99.000 166.00 173.75 -7.75 + 99.025 142.00 173.94 -31.94 + 99.050 144.00 176.26 -32.26 + 99.075 177.00 181.78 -4.78 + 99.100 178.00 192.38 -14.38 + 99.125 215.00 205.23 9.77 + 99.150 182.00 214.58 -32.58 + 99.175 160.00 211.90 -51.90 + 99.200 196.00 202.69 -6.69 + 99.225 200.00 196.75 3.25 + 99.250 159.00 197.15 -38.15 + 99.275 163.00 200.27 -37.27 + 99.300 150.00 198.42 -48.42 + 99.325 175.00 190.29 -15.29 + 99.350 144.00 181.70 -37.70 + 99.375 132.00 175.64 -43.64 + 99.400 160.00 172.20 -12.20 + 99.425 169.00 171.01 -2.01 + 99.450 138.00 170.48 -32.48 + 99.475 171.00 170.63 0.37 + 99.500 129.00 171.44 -42.44 + 99.525 167.00 172.75 -5.75 + 99.550 172.00 175.75 -3.75 + 99.575 135.00 180.45 -45.45 + 99.600 170.00 186.28 -16.28 + 99.625 172.00 191.06 -19.06 + 99.650 169.00 193.30 -24.30 + 99.675 199.00 196.96 2.04 + 99.700 221.00 208.22 12.78 + 99.725 233.00 233.47 -0.47 + 99.750 283.00 275.81 7.19 + 99.775 291.00 330.41 -39.41 + 99.800 299.00 369.60 -70.60 + 99.825 257.00 355.31 -98.31 + 99.850 239.00 303.23 -64.23 + 99.875 226.00 252.32 -26.32 + 99.900 185.00 217.59 -32.59 + 99.925 195.00 198.03 -3.03 + 99.950 194.00 188.43 5.57 + 99.975 175.00 184.36 -9.36 + 100.000 192.00 184.72 7.28 + 100.025 182.00 187.66 -5.66 + 100.050 189.00 196.51 -7.51 + 100.075 210.00 212.24 -2.24 + 100.100 252.00 236.06 15.94 + 100.125 217.00 261.89 -44.89 + 100.150 230.00 271.84 -41.84 + 100.175 223.00 255.33 -32.33 + 100.200 192.00 228.75 -36.75 + 100.225 205.00 206.95 -1.95 + 100.250 179.00 193.53 -14.53 + 100.275 185.00 187.05 -2.05 + 100.300 155.00 185.43 -30.43 + 100.325 193.00 188.17 4.83 + 100.350 190.00 195.05 -5.05 + 100.375 214.00 208.62 5.38 + 100.400 215.00 229.85 -14.85 + 100.425 230.00 254.48 -24.48 + 100.450 223.00 268.98 -45.98 + 100.475 212.00 260.31 -48.31 + 100.500 233.00 239.25 -6.25 + 100.525 221.00 220.38 0.62 + 100.550 242.00 211.15 30.85 + 100.575 216.00 211.69 4.31 + 100.600 261.00 223.34 37.66 + 100.625 265.00 250.32 14.68 + 100.650 370.00 298.34 71.66 + 100.675 406.00 369.38 36.62 + 100.700 501.00 449.58 51.42 + 100.725 447.00 498.85 -51.85 + 100.750 488.00 496.65 -8.65 + 100.775 473.00 470.22 2.78 + 100.800 365.00 422.59 -57.59 + 100.825 279.00 356.21 -77.21 + 100.850 283.00 295.84 -12.84 + 100.875 285.00 254.34 30.66 + 100.900 282.00 232.55 49.45 + 100.925 239.00 226.30 12.70 + 100.950 267.00 232.59 34.41 + 100.975 263.00 249.81 13.19 + 101.000 309.00 277.11 31.89 + 101.025 349.00 312.42 36.58 + 101.050 345.00 344.93 0.07 + 101.075 322.00 355.47 -33.47 + 101.100 338.00 341.79 -3.79 + 101.125 308.00 316.49 -8.49 + 101.150 238.00 284.13 -46.13 + 101.175 221.00 250.37 -29.37 + 101.200 215.00 223.48 -8.48 + 101.225 197.00 206.52 -9.52 + 101.250 205.00 197.61 7.39 + 101.275 208.00 194.61 13.39 + 101.300 222.00 195.63 26.37 + 101.325 206.00 199.12 6.88 + 101.350 204.00 204.39 -0.39 + 101.375 230.00 212.31 17.69 + 101.400 240.00 224.72 15.28 + 101.425 284.00 244.94 39.06 + 101.450 313.00 273.74 39.26 + 101.475 331.00 303.04 27.96 + 101.500 344.00 325.99 18.01 + 101.525 297.00 330.34 -33.34 + 101.550 275.00 305.00 -30.00 + 101.575 267.00 265.75 1.25 + 101.600 216.00 231.17 -15.17 + 101.625 230.00 207.68 22.32 + 101.650 194.00 194.37 -0.37 + 101.675 195.00 188.27 6.73 + 101.700 234.00 187.08 46.92 + 101.725 196.00 190.08 5.92 + 101.750 198.00 198.26 -0.26 + 101.775 240.00 213.62 26.38 + 101.800 255.00 236.94 18.06 + 101.825 287.00 266.01 20.99 + 101.850 314.00 292.47 21.53 + 101.875 318.00 303.17 14.83 + 101.900 255.00 285.85 -30.85 + 101.925 232.00 252.96 -20.96 + 101.950 213.00 222.19 -9.19 + 101.975 186.00 200.34 -14.34 + 102.000 193.00 187.17 5.83 + 102.025 156.00 180.09 -24.09 + 102.050 168.00 176.56 -8.56 + 102.075 155.00 175.02 -20.02 + 102.100 154.00 174.96 -20.96 + 102.125 187.00 176.60 10.40 + 102.150 181.00 180.30 0.70 + 102.175 194.00 186.73 7.27 + 102.200 183.00 193.69 -10.69 + 102.225 206.00 198.10 7.90 + 102.250 191.00 196.15 -5.15 + 102.275 179.00 190.12 -11.12 + 102.300 174.00 183.59 -9.59 + 102.325 158.00 179.69 -21.69 + 102.350 176.00 178.22 -2.22 + 102.375 183.00 178.99 4.01 + 102.400 184.00 181.87 2.13 + 102.425 188.00 187.16 0.84 + 102.450 222.00 195.86 26.14 + 102.475 211.00 209.83 1.17 + 102.500 242.00 232.14 9.86 + 102.525 267.00 267.55 -0.55 + 102.550 330.00 318.90 11.10 + 102.575 363.00 378.39 -15.39 + 102.600 390.00 417.91 -27.91 + 102.625 397.00 404.58 -7.58 + 102.650 332.00 349.92 -17.92 + 102.675 288.00 289.72 -1.72 + 102.700 273.00 243.78 29.22 + 102.725 199.00 214.77 -15.77 + 102.750 218.00 199.20 18.80 + 102.775 198.00 192.37 5.63 + 102.800 206.00 191.00 15.00 + 102.825 228.00 193.87 34.13 + 102.850 206.00 201.37 4.63 + 102.875 216.00 215.18 0.82 + 102.900 256.00 236.97 19.03 + 102.925 259.00 264.69 -5.69 + 102.950 301.00 287.84 13.16 + 102.975 265.00 288.98 -23.98 + 103.000 240.00 265.94 -25.94 + 103.025 206.00 235.20 -29.20 + 103.050 224.00 209.23 14.77 + 103.075 183.00 191.62 -8.62 + 103.100 160.00 181.19 -21.19 + 103.125 190.00 175.17 14.83 + 103.150 158.00 171.77 -13.77 + 103.175 161.00 169.67 -8.67 + 103.200 161.00 168.24 -7.24 + 103.225 143.00 167.21 -24.21 + 103.250 144.00 166.42 -22.42 + 103.275 177.00 165.80 11.20 + 103.300 175.00 165.28 9.72 + 103.325 142.00 164.91 -22.91 + 103.350 129.00 164.75 -35.75 + 103.375 140.00 164.55 -24.55 + 103.400 166.00 164.41 1.59 + 103.425 156.00 163.99 -7.99 + 103.450 126.00 164.36 -38.36 + 103.475 156.00 164.51 -8.51 + 103.500 144.00 164.72 -20.72 + 103.525 146.00 165.00 -19.00 + 103.550 136.00 165.36 -29.36 + 103.575 145.00 165.83 -20.83 + 103.600 160.00 166.42 -6.42 + 103.625 147.00 167.16 -20.16 + 103.650 142.00 168.10 -26.10 + 103.675 150.00 169.32 -19.32 + 103.700 168.00 171.05 -3.05 + 103.725 164.00 173.49 -9.49 + 103.750 168.00 177.39 -9.39 + 103.775 195.00 184.48 10.52 + 103.800 207.00 196.01 10.99 + 103.825 229.00 215.89 13.11 + 103.850 260.00 245.03 14.97 + 103.875 263.00 281.76 -18.76 + 103.900 294.00 312.95 -18.95 + 103.925 291.00 320.70 -29.70 + 103.950 279.00 299.63 -20.63 + 103.975 245.00 266.75 -21.75 + 104.000 211.00 237.63 -26.63 + 104.025 240.00 218.28 21.72 + 104.050 218.00 208.31 9.69 + 104.075 197.00 206.17 -9.17 + 104.100 226.00 210.90 15.10 + 104.125 253.00 222.85 30.15 + 104.150 249.00 242.88 6.12 + 104.175 289.00 271.14 17.86 + 104.200 329.00 307.37 21.63 + 104.225 377.00 351.57 25.43 + 104.250 412.00 396.01 15.99 + 104.275 419.00 415.78 3.22 + 104.300 371.00 392.74 -21.74 + 104.325 310.00 342.10 -32.10 + 104.350 258.00 290.14 -32.14 + 104.375 236.00 250.13 -14.13 + 104.400 243.00 224.71 18.29 + 104.425 235.00 211.80 23.20 + 104.450 224.00 206.63 17.37 + 104.475 241.00 207.40 33.60 + 104.500 236.00 213.08 22.92 + 104.525 239.00 223.35 15.65 + 104.550 302.00 237.85 64.15 + 104.575 286.00 257.60 28.40 + 104.600 295.00 285.02 9.98 + 104.625 329.00 320.00 9.00 + 104.650 390.00 358.24 31.76 + 104.675 376.00 398.74 -22.74 + 104.700 405.00 442.56 -37.56 + 104.725 380.00 475.44 -95.44 + 104.750 376.00 470.06 -94.06 + 104.775 363.00 423.20 -60.20 + 104.800 361.00 365.94 -4.94 + 104.825 296.00 320.06 -24.06 + 104.850 313.00 292.45 20.55 + 104.875 279.00 278.14 0.86 + 104.900 295.00 266.49 28.51 + 104.925 248.00 252.34 -4.34 + 104.950 253.00 238.73 14.27 + 104.975 273.00 231.34 41.66 + 105.000 273.00 233.64 39.36 + 105.025 275.00 247.26 27.74 + 105.050 305.00 271.17 33.83 + 105.075 282.00 300.41 -18.41 + 105.100 295.00 323.14 -28.14 + 105.125 295.00 325.78 -30.78 + 105.150 304.00 310.60 -6.60 + 105.175 318.00 296.66 21.34 + 105.200 331.00 296.60 34.40 + 105.225 336.00 315.30 20.70 + 105.250 336.00 348.87 -12.87 + 105.275 371.00 384.02 -13.02 + 105.300 349.00 399.79 -50.79 + 105.325 315.00 382.22 -67.22 + 105.350 280.00 341.55 -61.55 + 105.375 286.00 298.08 -12.08 + 105.400 238.00 262.76 -24.76 + 105.425 265.00 237.66 27.34 + 105.450 226.00 220.89 5.11 + 105.475 238.00 211.71 26.29 + 105.500 222.00 209.59 12.41 + 105.525 224.00 214.48 9.52 + 105.550 254.00 227.81 26.19 + 105.575 303.00 250.73 52.27 + 105.600 311.00 279.27 31.73 + 105.625 297.00 307.11 -10.11 + 105.650 319.00 327.36 -8.36 + 105.675 302.00 333.48 -31.48 + 105.700 295.00 325.84 -30.84 + 105.725 299.00 313.31 -14.31 + 105.750 325.00 305.88 19.12 + 105.775 347.00 304.60 42.40 + 105.800 294.00 301.73 -7.73 + 105.825 264.00 287.35 -23.35 + 105.850 265.00 263.90 1.10 + 105.875 239.00 240.48 -1.48 + 105.900 227.00 223.08 3.92 + 105.925 226.00 213.57 12.43 + 105.950 250.00 211.65 38.35 + 105.975 203.00 213.71 -10.71 + 106.000 229.00 215.74 13.26 + 106.025 202.00 215.23 -13.23 + 106.050 234.00 212.22 21.78 + 106.075 220.00 210.34 9.66 + 106.100 206.00 212.33 -6.33 + 106.125 230.00 218.98 11.02 + 106.150 228.00 228.93 -0.93 + 106.175 259.00 238.43 20.57 + 106.200 221.00 243.26 -22.26 + 106.225 276.00 246.10 29.90 + 106.250 276.00 251.59 24.41 + 106.275 271.00 263.33 7.67 + 106.300 278.00 281.82 -3.82 + 106.325 298.00 303.35 -5.35 + 106.350 341.00 320.95 20.05 + 106.375 366.00 333.20 32.80 + 106.400 384.00 350.04 33.96 + 106.425 388.00 380.84 7.16 + 106.450 410.00 424.08 -14.08 + 106.475 433.00 463.36 -30.36 + 106.500 388.00 471.06 -83.06 + 106.525 382.00 435.64 -53.64 + 106.550 298.00 376.88 -78.88 + 106.575 327.00 319.66 7.34 + 106.600 266.00 275.98 -9.98 + 106.625 250.00 249.62 0.38 + 106.650 252.00 238.31 13.69 + 106.675 252.00 237.90 14.10 + 106.700 262.00 243.56 18.44 + 106.725 270.00 249.76 20.24 + 106.750 257.00 254.17 2.83 + 106.775 249.00 259.46 -10.46 + 106.800 251.00 270.71 -19.71 + 106.825 336.00 289.00 47.00 + 106.850 305.00 308.81 -3.81 + 106.875 284.00 318.38 -34.38 + 106.900 293.00 306.72 -13.72 + 106.925 236.00 279.10 -43.10 + 106.950 224.00 248.01 -24.01 + 106.975 207.00 221.27 -14.27 + 107.000 200.00 201.59 -1.59 + 107.025 174.00 188.67 -14.67 + 107.050 177.00 180.81 -3.81 + 107.075 180.00 176.14 3.86 + 107.100 163.00 173.24 -10.24 + 107.125 150.00 171.11 -21.11 + 107.150 181.00 169.66 11.34 + 107.175 174.00 168.53 5.47 + 107.200 141.00 167.66 -26.66 + 107.225 156.00 166.98 -10.98 + 107.250 143.00 166.43 -23.43 + 107.275 166.00 165.90 0.10 + 107.300 148.00 166.29 -18.29 + 107.325 174.00 166.11 7.89 + 107.350 153.00 166.03 -13.03 + 107.375 160.00 166.02 -6.02 + 107.400 159.00 166.09 -7.09 + 107.425 160.00 165.22 -5.22 + 107.450 155.00 165.78 -10.78 + 107.475 141.00 166.16 -25.16 + 107.500 148.00 166.63 -18.63 + 107.525 157.00 167.23 -10.23 + 107.550 157.00 168.02 -11.02 + 107.575 161.00 169.07 -8.07 + 107.600 171.00 170.53 0.47 + 107.625 164.00 172.61 -8.61 + 107.650 169.00 175.73 -6.73 + 107.675 170.00 180.49 -10.49 + 107.700 167.00 188.87 -21.87 + 107.725 189.00 201.67 -12.67 + 107.750 220.00 220.79 -0.79 + 107.775 252.00 246.43 5.57 + 107.800 328.00 275.90 52.10 + 107.825 298.00 301.46 -3.46 + 107.850 286.00 312.27 -26.27 + 107.875 290.00 301.57 -11.57 + 107.900 266.00 276.50 -10.50 + 107.925 220.00 248.60 -28.60 + 107.950 171.00 224.84 -53.84 + 107.975 193.00 207.76 -14.76 + 108.000 194.00 197.30 -3.30 + 108.025 170.00 192.31 -22.31 + 108.050 235.00 191.61 43.39 + 108.075 195.00 194.81 0.19 + 108.100 207.00 202.59 4.41 + 108.125 227.00 216.81 10.19 + 108.150 261.00 239.92 21.08 + 108.175 320.00 273.83 46.17 + 108.200 343.00 317.96 25.04 + 108.225 339.00 367.19 -28.19 + 108.250 411.00 410.08 0.92 + 108.275 416.00 433.60 -17.60 + 108.300 350.00 428.41 -78.41 + 108.325 350.00 398.65 -48.65 + 108.350 288.00 361.03 -73.03 + 108.375 343.00 329.42 13.58 + 108.400 300.00 308.21 -8.21 + 108.425 286.00 293.75 -7.75 + 108.450 283.00 278.80 4.20 + 108.475 249.00 260.52 -11.52 + 108.500 258.00 242.20 15.80 + 108.525 232.00 228.05 3.95 + 108.550 229.00 220.74 8.26 + 108.575 233.00 221.50 11.50 + 108.600 215.00 230.29 -15.29 + 108.625 250.00 245.05 4.95 + 108.650 258.00 261.86 -3.86 + 108.675 250.00 273.96 -23.96 + 108.700 251.00 274.83 -23.83 + 108.725 245.00 265.02 -20.02 + 108.750 233.00 251.38 -18.38 + 108.775 220.00 239.62 -19.62 + 108.800 257.00 231.47 25.53 + 108.825 219.00 225.21 -6.21 + 108.850 207.00 217.30 -10.30 + 108.875 208.00 207.83 0.17 + 108.900 191.00 197.91 -6.91 + 108.925 187.00 189.19 -2.19 + 108.950 198.00 182.46 15.54 + 108.975 176.00 177.87 -1.87 + 109.000 184.00 175.23 8.77 + 109.025 190.00 174.22 15.78 + 109.050 192.00 174.82 17.18 + 109.075 159.00 177.27 -18.27 + 109.100 176.00 182.10 -6.10 + 109.125 166.00 189.83 -23.83 + 109.150 196.00 200.54 -4.54 + 109.175 172.00 213.31 -41.31 + 109.200 180.00 225.53 -45.53 + 109.225 208.00 232.71 -24.71 + 109.250 219.00 230.65 -11.65 + 109.275 202.00 220.81 -18.81 + 109.300 177.00 206.96 -29.96 + 109.325 175.00 194.43 -19.43 + 109.350 170.00 184.32 -14.32 + 109.375 167.00 177.21 -10.21 + 109.400 175.00 172.81 2.19 + 109.425 153.00 170.50 -17.50 + 109.450 145.00 169.53 -24.53 + 109.475 178.00 170.18 7.82 + 109.500 168.00 172.21 -4.21 + 109.525 153.00 175.82 -22.82 + 109.550 159.00 180.80 -21.80 + 109.575 179.00 186.78 -7.78 + 109.600 196.00 192.66 3.34 + 109.625 175.00 196.41 -21.41 + 109.650 174.00 196.00 -22.00 + 109.675 168.00 191.52 -23.52 + 109.700 180.00 184.75 -4.75 + 109.725 139.00 178.38 -39.38 + 109.750 157.00 173.07 -16.07 + 109.775 143.00 169.19 -26.19 + 109.800 156.00 166.64 -10.64 + 109.825 157.00 165.13 -8.13 + 109.850 151.00 164.21 -13.21 + 109.875 155.00 163.91 -8.91 + 109.900 158.00 164.00 -6.00 + 109.925 155.00 164.47 -9.47 + 109.950 141.00 165.24 -24.24 + 109.975 152.00 166.30 -14.30 + 110.000 145.00 167.56 -22.56 + 110.025 158.00 168.76 -10.76 + 110.050 153.00 169.46 -16.46 + 110.075 149.00 169.31 -20.31 + 110.100 153.00 168.41 -15.41 + 110.125 150.00 167.23 -17.23 + 110.150 144.00 166.19 -22.19 + 110.175 150.00 166.05 -16.05 + 110.200 143.00 166.05 -23.05 + 110.225 172.00 166.80 5.20 + 110.250 141.00 168.46 -27.46 + 110.275 166.00 170.89 -4.89 + 110.300 170.00 174.55 -4.55 + 110.325 162.00 178.91 -16.91 + 110.350 206.00 183.26 22.74 + 110.375 182.00 186.42 -4.42 + 110.400 172.00 187.38 -15.38 + 110.425 183.00 186.45 -3.45 + 110.450 175.00 184.92 -9.92 + 110.475 178.00 183.97 -5.97 + 110.500 179.00 184.33 -5.33 + 110.525 157.00 186.53 -29.53 + 110.550 163.00 189.72 -26.72 + 110.575 182.00 193.20 -11.20 + 110.600 184.00 194.70 -10.70 + 110.625 177.00 193.27 -16.27 + 110.650 163.00 189.60 -26.60 + 110.675 172.00 185.40 -13.40 + 110.700 185.00 181.87 3.13 + 110.725 159.00 179.80 -20.80 + 110.750 185.00 179.00 6.00 + 110.775 176.00 178.86 -2.86 + 110.800 169.00 178.57 -9.57 + 110.825 161.00 177.71 -16.71 + 110.850 173.00 176.61 -3.61 + 110.875 190.00 175.89 14.11 + 110.900 193.00 176.03 16.97 + 110.925 150.00 177.23 -27.23 + 110.950 175.00 179.55 -4.55 + 110.975 151.00 182.34 -31.34 + 111.000 176.00 185.05 -9.05 + 111.025 166.00 187.04 -21.04 + 111.050 171.00 188.49 -17.49 + 111.075 187.00 190.67 -3.67 + 111.100 180.00 195.35 -15.35 + 111.125 216.00 204.21 11.79 + 111.150 212.00 218.68 -6.68 + 111.175 269.00 239.11 29.89 + 111.200 301.00 264.31 36.69 + 111.225 313.00 290.62 22.38 + 111.250 319.00 311.17 7.83 + 111.275 328.00 317.56 10.44 + 111.300 299.00 306.55 -7.55 + 111.325 252.00 283.66 -31.66 + 111.350 252.00 257.30 -5.30 + 111.375 228.00 233.39 -5.39 + 111.400 200.00 214.92 -14.92 + 111.425 209.00 202.84 6.16 + 111.450 202.00 197.01 4.99 + 111.475 225.00 196.97 28.03 + 111.500 199.00 202.68 -3.68 + 111.525 251.00 214.14 36.86 + 111.550 236.00 231.31 4.69 + 111.575 263.00 253.52 9.48 + 111.600 299.00 277.82 21.18 + 111.625 302.00 299.52 2.48 + 111.650 338.00 312.46 25.54 + 111.675 248.00 312.63 -64.63 + 111.700 259.00 299.91 -40.91 + 111.725 262.00 278.15 -16.15 + 111.750 213.00 253.14 -40.14 + 111.775 211.00 229.89 -18.89 + 111.800 206.00 211.06 -5.06 + 111.825 210.00 197.40 12.60 + 111.850 168.00 188.68 -20.68 + 111.875 191.00 183.86 7.14 + 111.900 159.00 182.27 -23.27 + 111.925 183.00 183.41 -0.41 + 111.950 202.00 186.84 15.16 + 111.975 211.00 192.14 18.86 + 112.000 205.00 198.64 6.36 + 112.025 206.00 204.84 1.16 + 112.050 205.00 208.84 -3.84 + 112.075 223.00 208.95 14.05 + 112.100 200.00 205.96 -5.96 + 112.125 184.00 200.80 -16.80 + 112.150 189.00 196.29 -7.29 + 112.175 186.00 193.75 -7.75 + 112.200 185.00 193.67 -8.67 + 112.225 205.00 195.76 9.24 + 112.250 197.00 198.91 -1.91 + 112.275 210.00 201.41 8.59 + 112.300 206.00 201.36 4.64 + 112.325 202.00 198.25 3.75 + 112.350 174.00 193.09 -19.09 + 112.375 175.00 187.40 -12.40 + 112.400 190.00 181.82 8.18 + 112.425 165.00 177.86 -12.86 + 112.450 173.00 175.35 -2.35 + 112.475 179.00 174.04 4.96 + 112.500 192.00 174.27 17.73 + 112.525 168.00 175.59 -7.59 + 112.550 168.00 178.52 -10.52 + 112.575 181.00 183.49 -2.49 + 112.600 170.00 190.95 -20.95 + 112.625 200.00 201.08 -1.08 + 112.650 198.00 213.50 -15.50 + 112.675 219.00 226.92 -7.92 + 112.700 211.00 238.84 -27.84 + 112.725 238.00 245.80 -7.80 + 112.750 222.00 245.29 -23.29 + 112.775 205.00 237.93 -32.93 + 112.800 221.00 227.71 -6.71 + 112.825 204.00 217.59 -13.59 + 112.850 219.00 210.19 8.81 + 112.875 196.00 206.24 -10.24 + 112.900 210.00 205.60 4.40 + 112.925 196.00 207.81 -11.81 + 112.950 234.00 212.10 21.90 + 112.975 212.00 217.39 -5.39 + 113.000 191.00 222.28 -31.28 + 113.025 250.00 225.93 24.07 + 113.050 230.00 229.24 0.76 + 113.075 226.00 234.59 -8.59 + 113.100 277.00 244.48 32.52 + 113.125 263.00 259.91 3.09 + 113.150 296.00 280.76 15.24 + 113.175 319.00 305.21 13.79 + 113.200 338.00 330.23 7.77 + 113.225 385.00 351.75 33.25 + 113.250 408.00 363.25 44.75 + 113.275 381.00 359.06 21.94 + 113.300 356.00 339.90 16.10 + 113.325 290.00 312.58 -22.58 + 113.350 284.00 284.37 -0.37 + 113.375 268.00 259.85 8.15 + 113.400 222.00 240.98 -18.98 + 113.425 245.00 227.74 17.26 + 113.450 214.00 218.96 -4.96 + 113.475 211.00 214.00 -3.00 + 113.500 204.00 212.79 -8.79 + 113.525 227.00 215.96 11.04 + 113.550 254.00 223.82 30.18 + 113.575 236.00 236.38 -0.38 + 113.600 290.00 252.56 37.44 + 113.625 305.00 269.91 35.09 + 113.650 290.00 284.50 5.50 + 113.675 337.00 291.96 45.04 + 113.700 276.00 289.33 -13.33 + 113.725 281.00 276.89 4.11 + 113.750 238.00 258.30 -20.30 + 113.775 243.00 238.13 4.87 + 113.800 231.00 219.69 11.31 + 113.825 205.00 204.67 0.33 + 113.850 205.00 193.56 11.44 + 113.875 193.00 186.08 6.92 + 113.900 180.00 181.41 -1.41 + 113.925 171.00 179.35 -8.35 + 113.950 185.00 179.24 5.76 + 113.975 191.00 180.44 10.56 + 114.000 191.00 182.70 8.30 + 114.025 190.00 185.61 4.39 + 114.050 179.00 188.58 -9.58 + 114.075 169.00 190.87 -21.87 + 114.100 175.00 191.91 -16.91 + 114.125 199.00 191.99 7.01 + 114.150 179.00 191.84 -12.84 + 114.175 189.00 192.76 -3.76 + 114.200 210.00 195.50 14.50 + 114.225 191.00 200.59 -9.59 + 114.250 206.00 207.54 -1.54 + 114.275 212.00 215.19 -3.19 + 114.300 210.00 221.55 -11.55 + 114.325 235.00 224.17 10.83 + 114.350 205.00 221.53 -16.53 + 114.375 182.00 214.61 -32.61 + 114.400 185.00 205.56 -20.56 + 114.425 177.00 196.30 -19.30 + 114.450 171.00 187.80 -16.80 + 114.475 153.00 181.38 -28.38 + 114.500 154.00 176.81 -22.81 + 114.525 152.00 173.90 -21.90 + 114.550 170.00 172.51 -2.51 + 114.575 155.00 172.28 -17.28 + 114.600 156.00 173.16 -17.16 + 114.625 153.00 175.12 -22.12 + 114.650 171.00 178.07 -7.07 + 114.675 188.00 182.02 5.98 + 114.700 181.00 186.59 -5.59 + 114.725 180.00 191.13 -11.13 + 114.750 201.00 194.66 6.34 + 114.775 183.00 196.12 -13.12 + 114.800 191.00 195.04 -4.04 + 114.825 184.00 191.99 -7.99 + 114.850 187.00 187.94 -0.94 + 114.875 163.00 183.70 -20.70 + 114.900 161.00 179.91 -18.91 + 114.925 165.00 176.63 -11.63 + 114.950 160.00 174.54 -14.54 + 114.975 185.00 173.45 11.55 + 115.000 198.00 173.38 24.62 + 115.025 164.00 174.39 -10.39 + 115.050 176.00 176.61 -0.61 + 115.075 182.00 180.13 1.87 + 115.100 172.00 184.97 -12.97 + 115.125 172.00 190.98 -18.98 + 115.150 186.00 197.75 -11.75 + 115.175 189.00 204.51 -15.51 + 115.200 181.00 210.43 -29.43 + 115.225 231.00 214.18 16.82 + 115.250 209.00 216.22 -7.22 + 115.275 211.00 217.52 -6.52 + 115.300 227.00 219.13 7.87 + 115.325 226.00 221.25 4.75 + 115.350 193.00 223.36 -30.36 + 115.375 216.00 224.00 -8.00 + 115.400 211.00 221.85 -10.85 + 115.425 211.00 216.90 -5.90 + 115.450 193.00 210.46 -17.46 + 115.475 175.00 204.30 -29.30 + 115.500 192.00 199.81 -7.81 + 115.525 209.00 197.98 11.02 + 115.550 196.00 199.38 -3.38 + 115.575 195.00 203.97 -8.97 + 115.600 230.00 211.78 18.22 + 115.625 231.00 221.76 9.24 + 115.650 239.00 232.57 6.43 + 115.675 311.00 242.03 68.97 + 115.700 285.00 248.32 36.68 + 115.725 263.00 249.91 13.09 + 115.750 289.00 246.80 42.20 + 115.775 262.00 240.42 21.58 + 115.800 214.00 232.52 -18.52 + 115.825 212.00 224.09 -12.09 + 115.850 218.00 215.44 2.56 + 115.875 186.00 206.89 -20.89 + 115.900 191.00 199.02 -8.02 + 115.925 199.00 192.41 6.59 + 115.950 183.00 187.40 -4.40 + 115.975 190.00 184.13 5.87 + 116.000 168.00 182.61 -14.61 + 116.025 194.00 182.70 11.30 + 116.050 191.00 184.39 6.61 + 116.075 195.00 187.34 7.66 + 116.100 207.00 191.19 15.81 + 116.125 218.00 195.09 22.91 + 116.150 222.00 198.25 23.75 + 116.175 241.00 199.68 41.32 + 116.200 242.00 198.97 43.03 + 116.225 219.00 196.62 22.38 + 116.250 189.00 193.70 -4.70 + 116.275 202.00 191.72 10.28 + 116.300 202.00 190.91 11.09 + 116.325 190.00 192.43 -2.43 + 116.350 225.00 196.91 28.09 + 116.375 204.00 204.94 -0.94 + 116.400 223.00 216.16 6.84 + 116.425 262.00 230.23 31.77 + 116.450 258.00 245.93 12.07 + 116.475 317.00 261.06 55.94 + 116.500 312.00 272.46 39.54 + 116.525 304.00 277.33 26.67 + 116.550 299.00 274.41 24.59 + 116.575 278.00 264.79 13.21 + 116.600 265.00 250.98 14.02 + 116.625 221.00 235.59 -14.59 + 116.650 205.00 220.83 -15.83 + 116.675 225.00 208.01 16.99 + 116.700 211.00 198.12 12.88 + 116.725 203.00 191.35 11.65 + 116.750 192.00 187.19 4.81 + 116.775 201.00 185.56 15.44 + 116.800 197.00 186.27 10.73 + 116.825 227.00 189.27 37.73 + 116.850 184.00 194.26 -10.26 + 116.875 205.00 201.15 3.85 + 116.900 216.00 209.51 6.49 + 116.925 256.00 218.53 37.47 + 116.950 253.00 227.03 25.97 + 116.975 288.00 233.20 54.80 + 117.000 249.00 235.83 13.17 + 117.025 280.00 234.37 45.63 + 117.050 219.00 229.84 -10.84 + 117.075 217.00 223.17 -6.17 + 117.100 249.00 215.57 33.43 + 117.125 229.00 208.08 20.92 + 117.150 198.00 201.36 -3.36 + 117.175 193.00 195.90 -2.90 + 117.200 178.00 191.81 -13.81 + 117.225 205.00 189.14 15.86 + 117.250 210.00 187.97 22.03 + 117.275 185.00 188.38 -3.38 + 117.300 179.00 190.46 -11.46 + 117.325 213.00 194.27 18.73 + 117.350 233.00 199.88 33.12 + 117.375 225.00 207.27 17.73 + 117.400 232.00 216.38 15.62 + 117.425 264.00 226.87 37.13 + 117.450 271.00 238.49 32.51 + 117.475 285.00 250.97 34.03 + 117.500 273.00 264.68 8.32 + 117.525 342.00 280.51 61.49 + 117.550 326.00 298.65 27.35 + 117.575 401.00 318.30 82.70 + 117.600 358.00 337.15 20.85 + 117.625 432.00 351.71 80.29 + 117.650 331.00 358.79 -27.79 + 117.675 361.00 357.52 3.48 + 117.700 330.00 349.24 -19.24 + 117.725 283.00 335.69 -52.69 + 117.750 282.00 318.12 -36.12 + 117.775 263.00 298.12 -35.12 + 117.800 245.00 277.99 -32.99 + 117.825 232.00 259.98 -27.98 + 117.850 219.00 245.26 -26.26 + 117.875 251.00 234.88 16.12 + 117.900 241.00 228.45 12.55 + 117.925 241.00 225.43 15.57 + 117.950 265.00 225.40 39.60 + 117.975 237.00 228.03 8.97 + 118.000 251.00 233.18 17.82 + 118.025 266.00 240.59 25.41 + 118.050 291.00 249.56 41.44 + 118.075 301.00 258.82 42.18 + 118.100 300.00 266.71 33.29 + 118.125 280.00 271.90 8.10 + 118.150 332.00 274.21 57.79 + 118.175 285.00 274.52 10.48 + 118.200 276.00 273.82 2.18 + 118.225 261.00 272.73 -11.73 + 118.250 262.00 271.77 -9.77 + 118.275 264.00 271.40 -7.40 + 118.300 280.00 271.57 8.43 + 118.325 291.00 271.36 19.64 + 118.350 292.00 269.21 22.79 + 118.375 284.00 264.13 19.87 + 118.400 266.00 255.58 10.42 + 118.425 240.00 244.39 -4.39 + 118.450 219.00 231.90 -12.90 + 118.475 232.00 219.58 12.42 + 118.500 218.00 208.53 9.47 + 118.525 192.00 199.33 -7.33 + 118.550 181.00 192.23 -11.23 + 118.575 184.00 187.23 -3.23 + 118.600 219.00 184.17 34.83 + 118.625 187.00 182.85 4.15 + 118.650 174.00 183.09 -9.09 + 118.675 184.00 184.76 -0.76 + 118.700 204.00 187.70 16.30 + 118.725 197.00 191.70 5.30 + 118.750 217.00 196.44 20.56 + 118.775 215.00 201.39 13.61 + 118.800 213.00 205.79 7.21 + 118.825 212.00 208.79 3.21 + 118.850 218.00 209.62 8.38 + 118.875 210.00 208.20 1.80 + 118.900 224.00 204.72 19.28 + 118.925 183.00 199.89 -16.89 + 118.950 178.00 194.47 -16.47 + 118.975 205.00 189.13 15.87 + 119.000 184.00 184.29 -0.29 + 119.025 185.00 179.84 5.16 + 119.050 180.00 176.59 3.41 + 119.075 197.00 174.14 22.86 + 119.100 154.00 172.35 -18.35 + 119.125 171.00 171.10 -0.10 + 119.150 181.00 170.04 10.96 + 119.175 155.00 169.45 -14.45 + 119.200 145.00 169.06 -24.06 + 119.225 184.00 168.86 15.14 + 119.250 180.00 168.68 11.32 + 119.275 173.00 168.87 4.13 + 119.300 168.00 168.83 -0.83 + 119.325 190.00 168.83 21.17 + 119.350 169.00 168.82 0.18 + 119.375 161.00 168.87 -7.87 + 119.400 174.00 168.91 5.09 + 119.425 158.00 168.92 -10.92 + 119.450 167.00 168.87 -1.87 + 119.475 182.00 168.77 13.23 + 119.500 165.00 168.64 -3.64 + 119.525 183.00 168.31 14.69 + 119.550 168.00 168.49 -0.49 + 119.575 159.00 168.38 -9.38 + 119.600 161.00 168.30 -7.30 + 119.625 155.00 168.14 -13.14 + 119.650 189.00 168.12 20.88 + 119.675 186.00 168.12 17.88 + 119.700 150.00 168.17 -18.17 + 119.725 168.00 168.20 -0.20 + 119.750 186.00 168.39 17.61 + 119.775 194.00 168.35 25.65 + 119.800 155.00 168.41 -13.41 + 119.825 171.00 168.37 2.63 + 119.850 151.00 168.46 -17.46 + 119.875 165.00 168.55 -3.55 + 119.900 175.00 168.66 6.34 + 119.925 156.00 168.77 -12.77 + 119.950 163.00 168.90 -5.90 + 119.975 164.00 169.04 -5.04 + 120.000 166.00 169.20 -3.20 + 120.025 185.00 169.52 15.48 + 120.050 163.00 169.71 -6.71 + 120.075 202.00 169.91 32.09 + 120.100 186.00 170.13 15.87 + 120.125 183.00 170.36 12.64 + 120.150 183.00 170.60 12.40 + 120.175 155.00 170.86 -15.86 + 120.200 199.00 171.14 27.86 + 120.225 176.00 171.46 4.54 + 120.250 188.00 172.27 15.73 + 120.275 177.00 172.64 4.36 + 120.300 165.00 173.34 -8.34 + 120.325 198.00 173.83 24.17 + 120.350 170.00 174.47 -4.47 + 120.375 186.00 175.23 10.77 + 120.400 188.00 176.14 11.86 + 120.425 193.00 177.29 15.71 + 120.450 190.00 178.81 11.19 + 120.475 207.00 180.90 26.10 + 120.500 234.00 183.85 50.15 + 120.525 205.00 188.11 16.89 + 120.550 212.00 193.99 18.01 + 120.575 216.00 202.07 13.93 + 120.600 213.00 213.04 -0.04 + 120.625 266.00 226.55 39.45 + 120.650 257.00 242.78 14.22 + 120.675 269.00 261.13 7.87 + 120.700 300.00 280.38 19.62 + 120.725 330.00 298.68 31.32 + 120.750 339.00 313.86 25.14 + 120.775 357.00 323.16 33.84 + 120.800 382.00 325.16 56.84 + 120.825 326.00 320.43 5.57 + 120.850 325.00 311.35 13.65 + 120.875 282.00 301.08 -19.08 + 120.900 284.00 292.46 -8.46 + 120.925 305.00 287.42 17.58 + 120.950 353.00 286.86 66.14 + 120.975 293.00 290.70 2.30 + 121.000 354.00 297.91 56.09 + 121.025 327.00 306.51 20.49 + 121.050 397.00 314.00 83.00 + 121.075 378.00 317.99 60.01 + 121.100 367.00 317.51 49.49 + 121.125 341.00 312.93 28.07 + 121.150 307.00 306.24 0.76 + 121.175 311.00 299.31 11.69 + 121.200 274.00 293.31 -19.31 + 121.225 313.00 288.56 24.44 + 121.250 351.00 284.58 66.42 + 121.275 347.00 280.44 66.56 + 121.300 326.00 275.23 50.77 + 121.325 307.00 268.70 38.30 + 121.350 293.00 261.40 31.60 + 121.375 260.00 254.42 5.58 + 121.400 283.00 248.84 34.16 + 121.425 272.00 245.46 26.54 + 121.450 272.00 244.70 27.30 + 121.475 302.00 246.60 55.40 + 121.500 307.00 250.85 56.15 + 121.525 313.00 256.82 56.18 + 121.550 332.00 263.72 68.28 + 121.575 337.00 270.82 66.18 + 121.600 327.00 278.00 49.00 + 121.625 331.00 286.06 44.94 + 121.650 343.00 296.52 46.48 + 121.675 329.00 310.90 18.10 + 121.700 371.00 330.13 40.87 + 121.725 392.00 354.18 37.82 + 121.750 418.00 381.85 36.15 + 121.775 493.00 410.59 82.41 + 121.800 471.00 436.55 34.45 + 121.825 481.00 455.10 25.90 + 121.850 485.00 462.22 22.78 + 121.875 486.00 456.38 29.62 + 121.900 422.00 439.31 -17.31 + 121.925 425.00 415.10 9.90 + 121.950 387.00 388.57 -1.57 + 121.975 379.00 363.93 15.07 + 122.000 330.00 344.21 -14.21 + 122.025 338.00 331.20 6.80 + 122.050 327.00 325.50 1.50 + 122.075 321.00 326.63 -5.63 + 122.100 327.00 333.44 -6.44 + 122.125 386.00 344.00 42.00 + 122.150 375.00 356.49 18.51 + 122.175 412.00 368.91 43.09 + 122.200 398.00 379.61 18.39 + 122.225 371.00 386.80 -15.80 + 122.250 398.00 390.20 7.80 + 122.275 377.00 390.62 -13.62 + 122.300 382.00 388.57 -6.57 + 122.325 419.00 383.99 35.01 + 122.350 397.00 375.69 21.31 + 122.375 373.00 363.56 9.44 + 122.400 325.00 347.51 -22.51 + 122.425 333.00 328.89 4.11 + 122.450 311.00 309.62 1.38 + 122.475 301.00 291.59 9.41 + 122.500 293.00 276.23 16.77 + 122.525 291.00 264.42 26.58 + 122.550 268.00 256.47 11.53 + 122.575 279.00 252.25 26.75 + 122.600 289.00 251.11 37.89 + 122.625 278.00 251.72 26.28 + 122.650 266.00 253.66 12.34 + 122.675 268.00 255.47 12.53 + 122.700 284.00 256.19 27.81 + 122.725 258.00 254.62 3.38 + 122.750 251.00 250.28 0.72 + 122.775 258.00 243.74 14.26 + 122.800 247.00 235.39 11.61 + 122.825 251.00 226.38 24.62 + 122.850 211.00 217.67 -6.67 + 122.875 209.00 209.50 -0.50 + 122.900 220.00 202.57 17.43 + 122.925 218.00 196.87 21.13 + 122.950 191.00 192.38 -1.38 + 122.975 186.00 188.99 -2.99 + 123.000 214.00 186.52 27.48 + 123.025 213.00 184.77 28.23 + 123.050 216.00 183.58 32.42 + 123.075 227.00 182.81 44.19 + 123.100 196.00 182.35 13.65 + 123.125 202.00 182.10 19.90 + 123.150 213.00 182.02 30.98 + 123.175 186.00 182.11 3.89 + 123.200 198.00 182.30 15.70 + 123.225 224.00 182.58 41.42 + 123.250 177.00 182.95 -5.95 + 123.275 197.00 183.36 13.64 + 123.300 160.00 183.91 -23.91 + 123.325 191.00 184.36 6.64 + 123.350 209.00 184.85 24.15 + 123.375 217.00 185.34 31.66 + 123.400 216.00 185.93 30.07 + 123.425 215.00 186.70 28.30 + 123.450 200.00 187.32 12.68 + 123.475 207.00 188.64 18.36 + 123.500 202.00 190.86 11.14 + 123.525 234.00 194.00 40.00 + 123.550 218.00 198.40 19.60 + 123.575 252.00 204.45 47.55 + 123.600 249.00 212.59 36.41 + 123.625 281.00 223.26 57.74 + 123.650 270.00 236.87 33.13 + 123.675 287.00 253.93 33.07 + 123.700 318.00 273.97 44.03 + 123.725 319.00 296.61 22.39 + 123.750 370.00 321.19 48.81 + 123.775 397.00 346.25 50.75 + 123.800 434.00 370.13 63.87 + 123.825 494.00 390.67 103.33 + 123.850 424.00 406.48 17.52 + 123.875 485.00 415.22 69.78 + 123.900 464.00 415.05 48.95 + 123.925 454.00 405.73 48.27 + 123.950 461.00 388.34 72.66 + 123.975 371.00 365.39 5.61 + 124.000 326.00 340.37 -14.37 + 124.025 309.00 315.62 -6.62 + 124.050 280.00 293.41 -13.41 + 124.075 332.00 275.03 56.97 + 124.100 297.00 261.31 35.69 + 124.125 277.00 252.62 24.38 + 124.150 293.00 248.99 44.01 + 124.175 303.00 250.22 52.78 + 124.200 342.00 256.10 85.90 + 124.225 293.00 265.88 27.12 + 124.250 322.00 279.08 42.92 + 124.275 350.00 294.90 55.10 + 124.300 360.00 312.55 47.45 + 124.325 343.00 331.06 11.94 + 124.350 387.00 349.56 37.44 + 124.375 437.00 366.97 70.03 + 124.400 442.00 382.45 59.55 + 124.425 460.00 394.31 65.69 + 124.450 486.00 401.17 84.83 + 124.475 451.00 401.86 49.14 + 124.500 433.00 396.06 36.94 + 124.525 459.00 384.25 74.75 + 124.550 369.00 367.65 1.35 + 124.575 415.00 347.98 67.02 + 124.600 340.00 327.18 12.82 + 124.625 328.00 307.05 20.95 + 124.650 323.00 289.10 33.90 + 124.675 291.00 274.46 16.54 + 124.700 265.00 263.76 1.24 + 124.725 305.00 257.28 47.72 + 124.750 279.00 254.91 24.09 + 124.775 298.00 256.26 41.74 + 124.800 320.00 260.96 59.04 + 124.825 299.00 267.90 31.10 + 124.850 306.00 275.81 30.19 + 124.875 340.00 283.86 56.14 + 124.900 314.00 290.93 23.07 + 124.925 329.00 296.19 32.81 + 124.950 324.00 298.88 25.12 + 124.975 367.00 299.07 67.93 + 125.000 378.00 297.05 80.95 + 125.025 335.00 293.11 41.89 + 125.050 338.00 287.54 50.46 + 125.075 293.00 280.63 12.37 + 125.100 299.00 272.92 26.08 + 125.125 293.00 265.12 27.88 + 125.150 263.00 258.07 4.93 + 125.175 285.00 252.60 32.40 + 125.200 277.00 249.48 27.52 + 125.225 283.00 249.28 33.72 + 125.250 326.00 252.42 73.58 + 125.275 291.00 259.01 31.99 + 125.300 311.00 268.92 42.08 + 125.325 315.00 281.82 33.18 + 125.350 351.00 296.76 54.24 + 125.375 367.00 312.42 54.58 + 125.400 353.00 327.42 25.58 + 125.425 387.00 339.96 47.04 + 125.450 404.00 348.40 55.60 + 125.475 365.00 351.86 13.14 + 125.500 354.00 350.28 3.72 + 125.525 382.00 345.13 36.87 + 125.550 318.00 337.93 -19.93 + 125.575 310.00 330.12 -20.12 + 125.600 342.00 322.35 19.65 + 125.625 355.00 315.65 39.35 + 125.650 334.00 309.46 24.54 + 125.675 382.00 303.75 78.25 + 125.700 359.00 297.94 61.06 + 125.725 322.00 291.55 30.45 + 125.750 317.00 284.60 32.40 + 125.775 322.00 277.55 44.45 + 125.800 315.00 270.71 44.29 + 125.825 322.00 264.85 57.15 + 125.850 260.00 260.45 -0.45 + 125.875 275.00 257.69 17.31 + 125.900 282.00 256.60 25.40 + 125.925 290.00 256.90 33.10 + 125.950 318.00 258.09 59.91 + 125.975 296.00 259.50 36.50 + 126.000 276.00 260.41 15.59 + 126.025 281.00 260.32 20.68 + 126.050 309.00 259.01 49.99 + 126.075 281.00 256.98 24.02 + 126.100 305.00 254.60 50.40 + 126.125 298.00 252.31 45.69 + 126.150 276.00 250.39 25.61 + 126.175 252.00 248.80 3.20 + 126.200 303.00 247.69 55.31 + 126.225 282.00 246.89 35.11 + 126.250 308.00 245.96 62.04 + 126.275 302.00 245.16 56.84 + 126.300 293.00 244.42 48.58 + 126.325 288.00 244.11 43.89 + 126.350 268.00 244.83 23.17 + 126.375 300.00 247.34 52.66 + 126.400 319.00 252.39 66.61 + 126.425 297.00 260.67 36.33 + 126.450 302.00 272.68 29.32 + 126.475 304.00 288.64 15.36 + 126.500 346.00 308.46 37.54 + 126.525 392.00 331.56 60.44 + 126.550 454.00 356.88 97.12 + 126.575 519.00 382.81 136.19 + 126.600 565.00 407.18 157.82 + 126.625 590.00 427.42 162.58 + 126.650 593.00 441.03 151.97 + 126.675 601.00 446.24 154.76 + 126.700 563.00 442.45 120.55 + 126.725 482.00 431.07 50.93 + 126.750 500.00 413.78 86.22 + 126.775 403.00 392.60 10.40 + 126.800 417.00 369.31 47.69 + 126.825 386.00 345.68 40.32 + 126.850 328.00 322.56 5.44 + 126.875 293.00 301.49 -8.49 + 126.900 321.00 283.31 37.69 + 126.925 300.00 268.72 31.28 + 126.950 313.00 258.02 54.98 + 126.975 294.00 251.31 42.69 + 127.000 318.00 248.53 69.47 + 127.025 294.00 249.45 44.55 + 127.050 329.00 253.83 75.17 + 127.075 329.00 261.05 67.95 + 127.100 364.00 270.57 93.43 + 127.125 360.00 281.62 78.38 + 127.150 385.00 293.22 91.78 + 127.175 412.00 304.19 107.81 + 127.200 426.00 313.38 112.62 + 127.225 405.00 319.35 85.65 + 127.250 418.00 321.46 96.54 + 127.275 417.00 319.32 97.68 + 127.300 358.00 314.21 43.79 + 127.325 384.00 306.76 77.24 + 127.350 387.00 298.02 88.98 + 127.375 312.00 289.07 22.93 + 127.400 316.00 280.47 35.53 + 127.425 304.00 273.09 30.91 + 127.450 295.00 267.73 27.27 + 127.475 296.00 264.34 31.66 + 127.500 294.00 263.39 30.61 + 127.525 273.00 264.70 8.30 + 127.550 325.00 267.74 57.26 + 127.575 330.00 272.19 57.81 + 127.600 345.00 277.16 67.84 + 127.625 300.00 281.94 18.06 + 127.650 370.00 285.35 84.65 + 127.675 350.00 286.90 63.10 + 127.700 381.00 286.10 94.90 + 127.725 297.00 282.74 14.26 + 127.750 316.00 277.00 39.00 + 127.775 300.00 269.42 30.58 + 127.800 270.00 260.55 9.45 + 127.825 271.00 251.21 19.79 + 127.850 292.00 241.90 50.10 + 127.875 249.00 233.43 15.57 + 127.900 263.00 226.04 36.96 + 127.925 269.00 219.98 49.02 + 127.950 273.00 215.40 57.60 + 127.975 252.00 212.32 39.68 + 128.000 250.00 210.72 39.28 + 128.025 225.00 210.62 14.38 + 128.050 241.00 211.69 29.31 + 128.075 245.00 213.83 31.17 + 128.100 268.00 216.92 51.08 + 128.125 276.00 220.66 55.34 + 128.150 264.00 224.71 39.29 + 128.175 282.00 228.97 53.03 + 128.200 294.00 232.83 61.17 + 128.225 314.00 236.02 77.98 + 128.250 303.00 238.26 64.74 + 128.275 269.00 239.37 29.63 + 128.300 295.00 239.27 55.73 + 128.325 283.00 238.03 44.97 + 128.350 293.00 235.91 57.09 + 128.375 286.00 233.29 52.71 + 128.400 264.00 230.65 33.35 + 128.425 255.00 228.38 26.62 + 128.450 259.00 226.92 32.08 + 128.475 252.00 226.72 25.28 + 128.500 270.00 227.92 42.08 + 128.525 255.00 230.55 24.45 + 128.550 304.00 235.07 68.93 + 128.575 293.00 241.80 51.20 + 128.600 311.00 250.40 60.60 + 128.625 285.00 260.70 24.30 + 128.650 332.00 272.42 59.58 + 128.675 321.00 285.13 35.87 + 128.700 350.00 298.22 51.78 + 128.725 358.00 311.27 46.73 + 128.750 431.00 323.39 107.61 + 128.775 433.00 333.64 99.36 + 128.800 427.00 341.11 85.89 + 128.825 380.00 345.17 34.83 + 128.850 413.00 345.71 67.29 + 128.875 422.00 343.29 78.71 + 128.900 348.00 338.88 9.12 + 128.925 388.00 333.56 54.44 + 128.950 355.00 328.26 26.74 + 128.975 370.00 323.67 46.33 + 129.000 353.00 320.14 32.86 + 129.025 322.00 317.81 4.19 + 129.050 348.00 316.73 31.27 + 129.075 325.00 316.77 8.23 + 129.100 320.00 317.99 2.01 + 129.125 369.00 320.42 48.58 + 129.150 351.00 323.89 27.11 + 129.175 400.00 328.42 71.58 + 129.200 379.00 333.88 45.12 + 129.225 399.00 339.84 59.16 + 129.250 406.00 346.11 59.89 + 129.275 396.00 352.71 43.29 + 129.300 397.00 359.78 37.22 + 129.325 415.00 367.60 47.40 + 129.350 439.00 376.19 62.81 + 129.375 438.00 385.35 52.65 + 129.400 437.00 394.65 42.35 + 129.425 478.00 403.49 74.51 + 129.450 495.00 411.29 83.71 + 129.475 511.00 417.53 93.47 + 129.500 450.00 421.83 28.17 + 129.525 497.00 424.04 72.96 + 129.550 498.00 424.18 73.82 + 129.575 433.00 422.35 10.65 + 129.600 477.00 418.83 58.17 + 129.625 484.00 413.53 70.47 + 129.650 430.00 406.16 23.84 + 129.675 431.00 396.86 34.14 + 129.700 454.00 385.58 68.42 + 129.725 399.00 372.71 26.29 + 129.750 382.00 358.94 23.06 + 129.775 384.00 344.95 39.05 + 129.800 351.00 331.31 19.69 + 129.825 334.00 318.46 15.54 + 129.850 347.00 306.75 40.25 + 129.875 336.00 296.45 39.55 + 129.900 330.00 287.84 42.16 + 129.925 306.00 281.16 24.84 + 129.950 330.00 276.55 53.45 + 129.975 311.00 274.03 36.97 + 130.000 298.00 273.50 24.50 + 130.025 301.00 274.69 26.31 + 130.050 344.00 277.25 66.75 + 130.075 335.00 280.70 54.30 + 130.100 334.00 284.58 49.42 + 130.125 303.00 288.43 14.57 + 130.150 326.00 291.75 34.25 + 130.175 359.00 294.42 64.58 + 130.200 397.00 296.29 100.71 + 130.225 356.00 297.28 58.72 + 130.250 347.00 297.22 49.78 + 130.275 310.00 295.95 14.05 + 130.300 347.00 293.47 53.53 + 130.325 332.00 289.92 42.08 + 130.350 312.00 285.64 26.36 + 130.375 335.00 281.09 53.91 + 130.400 334.00 276.66 57.34 + 130.425 316.00 272.63 43.37 + 130.450 309.00 269.15 39.85 + 130.475 294.00 266.19 27.81 + 130.500 334.00 263.61 70.39 + 130.525 342.00 261.18 80.82 + 130.550 332.00 258.65 73.35 + 130.575 279.00 255.74 23.26 + 130.600 267.00 252.33 14.67 + 130.625 257.00 248.39 8.61 + 130.650 292.00 244.04 47.96 + 130.675 288.00 239.45 48.55 + 130.700 273.00 234.93 38.07 + 130.725 245.00 230.65 14.35 + 130.750 269.00 226.70 42.30 + 130.775 248.00 223.23 24.77 + 130.800 228.00 220.28 7.72 + 130.825 250.00 217.87 32.13 + 130.850 249.00 215.70 33.30 + 130.875 230.00 214.32 15.68 + 130.900 238.00 213.33 24.67 + 130.925 217.00 212.69 4.31 + 130.950 238.00 212.37 25.63 + 130.975 212.00 212.36 -0.36 + 131.000 246.00 212.64 33.36 + 131.025 246.00 213.18 32.82 + 131.050 239.00 213.92 25.08 + 131.075 262.00 214.81 47.19 + 131.100 265.00 215.64 49.36 + 131.125 264.00 216.46 47.54 + 131.150 240.00 217.04 22.96 + 131.175 250.00 217.25 32.75 + 131.200 246.00 216.98 29.02 + 131.225 226.00 216.18 9.82 + 131.250 227.00 214.87 12.13 + 131.275 235.00 213.14 21.86 + 131.300 226.00 211.03 14.97 + 131.325 256.00 208.82 47.18 + 131.350 190.00 206.56 -16.56 + 131.375 215.00 204.35 10.65 + 131.400 236.00 202.27 33.73 + 131.425 223.00 200.37 22.63 + 131.450 227.00 198.67 28.33 + 131.475 203.00 197.06 5.94 + 131.500 206.00 195.82 10.18 + 131.525 190.00 194.81 -4.81 + 131.550 232.00 193.99 38.01 + 131.575 230.00 193.16 36.84 + 131.600 201.00 192.68 8.32 + 131.625 219.00 192.34 26.66 + 131.650 203.00 192.09 10.91 + 131.675 216.00 191.95 24.05 + 131.700 213.00 191.88 21.12 + 131.725 208.00 192.01 15.99 + 131.750 224.00 191.89 32.11 + 131.775 210.00 191.96 18.04 + 131.800 202.00 192.14 9.86 + 131.825 212.00 192.39 19.61 + 131.850 205.00 192.72 12.28 + 131.875 236.00 193.14 42.86 + 131.900 220.00 193.69 26.31 + 131.925 194.00 194.37 -0.37 + 131.950 199.00 195.30 3.70 + 131.975 201.00 196.51 4.49 + 132.000 216.00 198.06 17.94 + 132.025 237.00 200.05 36.95 + 132.050 212.00 202.56 9.44 + 132.075 225.00 205.67 19.33 + 132.100 203.00 209.45 -6.45 + 132.125 241.00 213.95 27.05 + 132.150 232.00 219.18 12.82 + 132.175 260.00 225.12 34.88 + 132.200 253.00 231.67 21.33 + 132.225 257.00 238.59 18.41 + 132.250 282.00 245.84 36.16 + 132.275 291.00 253.05 37.95 + 132.300 283.00 259.82 23.18 + 132.325 325.00 265.78 59.22 + 132.350 333.00 270.57 62.43 + 132.375 335.00 273.74 61.26 + 132.400 293.00 275.18 17.82 + 132.425 315.00 274.75 40.25 + 132.450 297.00 272.92 24.08 + 132.475 310.00 269.80 40.20 + 132.500 285.00 265.69 19.31 + 132.525 285.00 261.10 23.90 + 132.550 276.00 255.87 20.13 + 132.575 258.00 250.47 7.53 + 132.600 251.00 245.20 5.80 + 132.625 269.00 240.30 28.70 + 132.650 228.00 236.12 -8.12 + 132.675 215.00 232.58 -17.58 + 132.700 259.00 229.92 29.08 + 132.725 235.00 228.23 6.77 + 132.750 257.00 227.32 29.68 + 132.775 241.00 227.34 13.66 + 132.800 289.00 228.11 60.89 + 132.825 229.00 229.49 -0.49 + 132.850 267.00 231.33 35.67 + 132.875 270.00 233.45 36.55 + 132.900 284.00 235.72 48.28 + 132.925 265.00 237.94 27.06 + 132.950 274.00 239.96 34.04 + 132.975 275.00 241.62 33.38 + 133.000 279.00 242.75 36.25 + 133.025 277.00 243.21 33.79 + 133.050 269.00 242.95 26.05 + 133.075 267.00 241.97 25.03 + 133.100 263.00 240.51 22.49 + 133.125 299.00 238.46 60.54 + 133.150 262.00 236.06 25.94 + 133.175 263.00 233.59 29.41 + 133.200 268.00 230.96 37.04 + 133.225 235.00 228.41 6.59 + 133.250 232.00 226.10 5.90 + 133.275 261.00 224.24 36.76 + 133.300 236.00 222.80 13.20 + 133.325 224.00 221.95 2.05 + 133.350 251.00 221.82 29.18 + 133.375 249.00 222.38 26.62 + 133.400 247.00 223.64 23.36 + 133.425 217.00 225.55 -8.55 + 133.450 238.00 228.08 9.92 + 133.475 231.00 231.08 -0.08 + 133.500 251.00 234.41 16.59 + 133.525 261.00 237.87 23.13 + 133.550 251.00 241.28 9.72 + 133.575 308.00 244.40 63.60 + 133.600 300.00 247.01 52.99 + 133.625 333.00 248.92 84.08 + 133.650 311.00 249.96 61.04 + 133.675 283.00 250.08 32.92 + 133.700 279.00 249.36 29.64 + 133.725 289.00 247.98 41.02 + 133.750 281.00 246.28 34.72 + 133.775 273.00 244.46 28.54 + 133.800 244.00 242.86 1.14 + 133.825 299.00 241.76 57.24 + 133.850 263.00 241.34 21.66 + 133.875 257.00 241.75 15.25 + 133.900 209.00 243.06 -34.06 + 133.925 284.00 245.26 38.74 + 133.950 256.00 248.29 7.71 + 133.975 270.00 252.00 18.00 + 134.000 280.00 256.17 23.83 + 134.025 276.00 260.57 15.43 + 134.050 282.00 264.78 17.22 + 134.075 293.00 268.50 24.50 + 134.100 282.00 271.46 10.54 + 134.125 285.00 273.28 11.72 + 134.150 309.00 273.91 35.09 + 134.175 299.00 273.39 25.61 + 134.200 295.00 271.85 23.15 + 134.225 307.00 269.49 37.51 + 134.250 253.00 266.52 -13.52 + 134.275 258.00 263.16 -5.16 + 134.300 255.00 259.45 -4.45 + 134.325 297.00 255.58 41.42 + 134.350 296.00 251.65 44.35 + 134.375 248.00 247.82 0.18 + 134.400 286.00 244.23 41.77 + 134.425 288.00 241.06 46.94 + 134.450 259.00 238.45 20.55 + 134.475 276.00 236.54 39.46 + 134.500 256.00 235.44 20.56 + 134.525 257.00 235.23 21.77 + 134.550 268.00 235.99 32.01 + 134.575 246.00 237.78 8.22 + 134.600 273.00 240.64 32.36 + 134.625 271.00 244.55 26.45 + 134.650 306.00 249.63 56.37 + 134.675 287.00 255.76 31.24 + 134.700 286.00 263.07 22.93 + 134.725 303.00 271.42 31.58 + 134.750 283.00 280.78 2.22 + 134.775 335.00 290.94 44.06 + 134.800 330.00 301.82 28.18 + 134.825 366.00 313.27 52.73 + 134.850 380.00 325.08 54.92 + 134.875 334.00 337.14 -3.14 + 134.900 362.00 349.14 12.86 + 134.925 408.00 360.77 47.23 + 134.950 432.00 371.51 60.49 + 134.975 479.00 380.87 98.13 + 135.000 440.00 388.36 51.64 + 135.025 484.00 393.57 90.43 + 135.050 478.00 396.28 81.72 + 135.075 479.00 396.40 82.60 + 135.100 513.00 394.01 118.99 + 135.125 472.00 389.26 82.74 + 135.150 445.00 382.41 62.59 + 135.175 466.00 373.79 92.21 + 135.200 437.00 363.90 73.10 + 135.225 414.00 353.28 60.72 + 135.250 396.00 342.51 53.49 + 135.275 374.00 332.18 41.82 + 135.300 314.00 322.79 -8.79 + 135.325 326.00 314.82 11.18 + 135.350 326.00 308.58 17.42 + 135.375 323.00 304.30 18.70 + 135.400 316.00 302.19 13.81 + 135.425 354.00 302.21 51.79 + 135.450 315.00 304.27 10.73 + 135.475 351.00 308.20 42.80 + 135.500 329.00 313.70 15.30 + 135.525 370.00 320.56 49.44 + 135.550 366.00 327.99 38.01 + 135.575 415.00 335.64 79.36 + 135.600 444.00 342.92 101.08 + 135.625 423.00 349.26 73.74 + 135.650 414.00 354.16 59.84 + 135.675 412.00 357.26 54.74 + 135.700 463.00 358.34 104.66 + 135.725 464.00 357.35 106.65 + 135.750 424.00 354.41 69.59 + 135.775 427.00 349.71 77.29 + 135.800 411.00 343.51 67.49 + 135.825 394.00 336.08 57.92 + 135.850 383.00 327.73 55.27 + 135.875 394.00 318.77 75.23 + 135.900 330.00 309.47 20.53 + 135.925 360.00 300.18 59.82 + 135.950 359.00 291.17 67.83 + 135.975 303.00 282.71 20.29 + 136.000 294.00 275.00 19.00 + 136.025 289.00 268.19 20.81 + 136.050 271.00 262.28 8.72 + 136.075 288.00 257.51 30.49 + 136.100 264.00 253.98 10.02 + 136.125 284.00 251.28 32.72 + 136.150 262.00 249.52 12.48 + 136.175 274.00 248.61 25.39 + 136.200 278.00 248.43 29.57 + 136.225 293.00 248.93 44.07 + 136.250 289.00 249.80 39.20 + 136.275 309.00 250.97 58.03 + 136.300 292.00 252.42 39.58 + 136.325 313.00 253.76 59.24 + 136.350 286.00 255.03 30.97 + 136.375 291.00 256.22 34.78 + 136.400 303.00 257.35 45.65 + 136.425 279.00 258.48 20.52 + 136.450 298.00 259.70 38.30 + 136.475 301.00 261.10 39.90 + 136.500 278.00 262.72 15.28 + 136.525 261.00 264.60 -3.60 + 136.550 314.00 266.59 47.41 + 136.575 299.00 268.87 30.13 + 136.600 316.00 271.22 44.78 + 136.625 353.00 273.49 79.51 + 136.650 319.00 275.51 43.49 + 136.675 339.00 277.14 61.86 + 136.700 335.00 278.23 56.77 + 136.725 341.00 278.66 62.34 + 136.750 306.00 278.39 27.61 + 136.775 303.00 277.39 25.61 + 136.800 298.00 275.88 22.12 + 136.825 290.00 273.71 16.29 + 136.850 317.00 271.05 45.95 + 136.875 318.00 267.99 50.01 + 136.900 296.00 264.59 31.41 + 136.925 336.00 260.93 75.07 + 136.950 295.00 257.09 37.91 + 136.975 284.00 253.19 30.81 + 137.000 241.00 249.41 -8.41 + 137.025 276.00 245.74 30.26 + 137.050 245.00 242.36 2.64 + 137.075 247.00 239.38 7.62 + 137.100 263.00 236.87 26.13 + 137.125 270.00 234.87 35.13 + 137.150 261.00 233.43 27.57 + 137.175 239.00 232.53 6.47 + 137.200 247.00 232.16 14.84 + 137.225 250.00 232.28 17.72 + 137.250 209.00 232.88 -23.88 + 137.275 238.00 233.72 4.28 + 137.300 247.00 234.89 12.11 + 137.325 257.00 236.23 20.77 + 137.350 255.00 237.61 17.39 + 137.375 273.00 238.92 34.08 + 137.400 272.00 240.08 31.92 + 137.425 319.00 240.98 78.02 + 137.450 274.00 241.56 32.44 + 137.475 307.00 241.80 65.20 + 137.500 253.00 241.69 11.31 + 137.525 284.00 241.03 42.97 + 137.550 254.00 240.29 13.71 + 137.575 274.00 239.30 34.70 + 137.600 278.00 238.08 39.92 + 137.625 237.00 236.69 0.31 + 137.650 257.00 235.01 21.99 + 137.675 249.00 233.38 15.62 + 137.700 261.00 231.71 29.29 + 137.725 242.00 230.03 11.97 + 137.750 256.00 228.49 27.51 + 137.775 255.00 227.14 27.86 + 137.800 236.00 226.07 9.93 + 137.825 234.00 225.30 8.70 + 137.850 250.00 224.93 25.07 + 137.875 233.00 225.02 7.98 + 137.900 250.00 225.63 24.37 + 137.925 231.00 226.82 4.18 + 137.950 252.00 228.61 23.39 + 137.975 244.00 231.09 12.91 + 138.000 256.00 234.21 21.79 + 138.025 226.00 238.00 -12.00 + 138.050 267.00 242.45 24.55 + 138.075 246.00 247.46 -1.46 + 138.100 257.00 252.97 4.03 + 138.125 255.00 258.86 -3.86 + 138.150 278.00 265.00 13.00 + 138.175 292.00 271.18 20.82 + 138.200 308.00 277.07 30.93 + 138.225 274.00 282.69 -8.69 + 138.250 375.00 287.64 87.36 + 138.275 361.00 291.55 69.45 + 138.300 344.00 294.41 49.59 + 138.325 361.00 295.96 65.04 + 138.350 347.00 296.15 50.85 + 138.375 352.00 295.04 56.96 + 138.400 322.00 292.82 29.18 + 138.425 337.00 289.68 47.32 + 138.450 267.00 286.09 -19.09 + 138.475 268.00 282.30 -14.30 + 138.500 286.00 278.62 7.38 + 138.525 279.00 275.38 3.62 + 138.550 276.00 272.84 3.16 + 138.575 252.00 271.24 -19.24 + 138.600 242.00 270.77 -28.77 + 138.625 277.00 271.59 5.41 + 138.650 271.00 273.81 -2.81 + 138.675 275.00 277.48 -2.48 + 138.700 272.00 282.61 -10.61 + 138.725 295.00 289.19 5.81 + 138.750 281.00 297.05 -16.05 + 138.775 338.00 306.08 31.92 + 138.800 320.00 316.03 3.97 + 138.825 350.00 326.64 23.36 + 138.850 381.00 337.63 43.37 + 138.875 404.00 348.54 55.46 + 138.900 451.00 359.01 91.99 + 138.925 441.00 368.62 72.38 + 138.950 452.00 377.00 75.00 + 138.975 417.00 383.77 33.23 + 139.000 450.00 388.85 61.15 + 139.025 436.00 392.04 43.96 + 139.050 437.00 393.31 43.69 + 139.075 440.00 392.64 47.36 + 139.100 474.00 390.12 83.88 + 139.125 453.00 385.82 67.18 + 139.150 457.00 379.87 77.13 + 139.175 438.00 372.47 65.53 + 139.200 387.00 363.85 23.15 + 139.225 386.00 354.32 31.68 + 139.250 366.00 344.23 21.77 + 139.275 341.00 333.92 7.08 + 139.300 337.00 323.72 13.28 + 139.325 308.00 314.00 -6.00 + 139.350 329.00 304.99 24.01 + 139.375 283.00 296.91 -13.91 + 139.400 296.00 289.84 6.16 + 139.425 289.00 284.02 4.98 + 139.450 297.00 279.43 17.57 + 139.475 240.00 276.08 -36.08 + 139.500 268.00 273.92 -5.92 + 139.525 282.00 272.84 9.16 + 139.550 297.00 272.75 24.25 + 139.575 291.00 273.51 17.49 + 139.600 281.00 274.89 6.11 + 139.625 305.00 276.79 28.21 + 139.650 336.00 278.97 57.03 + 139.675 324.00 281.22 42.78 + 139.700 307.00 283.35 23.65 + 139.725 332.00 285.21 46.79 + 139.750 328.00 286.68 41.32 + 139.775 309.00 287.69 21.31 + 139.800 315.00 288.23 26.77 + 139.825 330.00 288.32 41.68 + 139.850 291.00 288.03 2.97 + 139.875 290.00 287.31 2.69 + 139.900 344.00 286.24 57.76 + 139.925 314.00 284.83 29.17 + 139.950 324.00 283.13 40.87 + 139.975 327.00 281.16 45.84 + 140.000 259.00 278.97 -19.97 + 140.025 268.00 276.64 -8.64 + 140.050 305.00 274.23 30.77 + 140.075 304.00 271.79 32.21 + 140.100 300.00 269.36 30.64 + 140.125 285.00 267.00 18.00 + 140.150 292.00 264.70 27.30 + 140.175 289.00 262.44 26.56 + 140.200 294.00 260.16 33.84 + 140.225 278.00 257.96 20.04 + 140.250 261.00 255.65 5.35 + 140.275 297.00 253.26 43.74 + 140.300 252.00 250.80 1.20 + 140.325 280.00 248.30 31.70 + 140.350 245.00 245.80 -0.80 + 140.375 266.00 243.35 22.65 + 140.400 283.00 240.97 42.03 + 140.425 238.00 238.77 -0.77 + 140.450 266.00 236.76 29.24 + 140.475 262.00 234.99 27.01 + 140.500 249.00 233.49 15.51 + 140.525 255.00 232.29 22.71 + 140.550 240.00 231.40 8.60 + 140.575 239.00 230.83 8.17 + 140.600 221.00 230.60 -9.60 + 140.625 251.00 230.68 20.32 + 140.650 212.00 231.07 -19.07 + 140.675 233.00 231.74 1.26 + 140.700 238.00 232.66 5.34 + 140.725 249.00 233.81 15.19 + 140.750 256.00 235.14 20.86 + 140.775 216.00 236.60 -20.60 + 140.800 262.00 238.14 23.86 + 140.825 249.00 239.71 9.29 + 140.850 248.00 241.28 6.72 + 140.875 263.00 242.76 20.24 + 140.900 281.00 244.13 36.87 + 140.925 234.00 245.36 -11.36 + 140.950 290.00 246.42 43.58 + 140.975 269.00 247.29 21.71 + 141.000 284.00 247.97 36.03 + 141.025 233.00 248.36 -15.36 + 141.050 286.00 248.47 37.53 + 141.075 275.00 248.29 26.71 + 141.100 263.00 247.80 15.20 + 141.125 245.00 247.02 -2.02 + 141.150 259.00 245.80 13.20 + 141.175 276.00 244.51 31.49 + 141.200 229.00 243.04 -14.04 + 141.225 261.00 241.44 19.56 + 141.250 273.00 239.78 33.22 + 141.275 272.00 238.12 33.88 + 141.300 231.00 236.53 -5.53 + 141.325 212.00 235.05 -23.05 + 141.350 233.00 233.74 -0.74 + 141.375 256.00 232.63 23.37 + 141.400 241.00 231.76 9.24 + 141.425 228.00 231.15 -3.15 + 141.450 234.00 230.83 3.17 + 141.475 238.00 230.79 7.21 + 141.500 216.00 231.06 -15.06 + 141.525 207.00 231.63 -24.63 + 141.550 221.00 232.49 -11.49 + 141.575 233.00 233.62 -0.62 + 141.600 238.00 235.01 2.99 + 141.625 217.00 236.65 -19.65 + 141.650 238.00 238.48 -0.48 + 141.675 251.00 240.59 10.41 + 141.700 268.00 242.73 25.27 + 141.725 259.00 244.99 14.01 + 141.750 230.00 247.30 -17.30 + 141.775 276.00 249.64 26.36 + 141.800 257.00 251.94 5.06 + 141.825 260.00 254.14 5.86 + 141.850 255.00 255.99 -0.99 + 141.875 244.00 257.79 -13.79 + 141.900 258.00 259.28 -1.28 + 141.925 279.00 260.40 18.60 + 141.950 291.00 261.11 29.89 + 141.975 290.00 261.27 28.73 + 142.000 295.00 261.06 33.94 + 142.025 289.00 260.38 28.62 + 142.050 273.00 259.28 13.72 + 142.075 306.00 257.82 48.18 + 142.100 307.00 255.92 51.08 + 142.125 264.00 253.94 10.06 + 142.150 289.00 251.83 37.17 + 142.175 270.00 249.67 20.33 + 142.200 234.00 247.54 -13.54 + 142.225 252.00 245.52 6.48 + 142.250 243.00 243.67 -0.67 + 142.275 244.00 242.04 1.96 + 142.300 251.00 240.67 10.33 + 142.325 235.00 239.60 -4.60 + 142.350 234.00 238.84 -4.84 + 142.375 246.00 238.39 7.61 + 142.400 239.00 238.27 0.73 + 142.425 257.00 238.44 18.56 + 142.450 218.00 238.90 -20.90 + 142.475 234.00 239.66 -5.66 + 142.500 230.00 240.59 -10.59 + 142.525 253.00 241.69 11.31 + 142.550 248.00 242.93 5.07 + 142.575 257.00 244.26 12.74 + 142.600 248.00 245.65 2.35 + 142.625 255.00 247.05 7.95 + 142.650 261.00 248.43 12.57 + 142.675 275.00 249.77 25.23 + 142.700 288.00 250.93 37.07 + 142.725 301.00 252.07 48.93 + 142.750 283.00 253.09 29.91 + 142.775 308.00 254.20 53.80 + 142.800 268.00 254.91 13.09 + 142.825 300.00 255.46 44.54 + 142.850 305.00 255.86 49.14 + 142.875 254.00 256.14 -2.14 + 142.900 251.00 256.31 -5.31 + 142.925 256.00 256.40 -0.40 + 142.950 280.00 256.41 23.59 + 142.975 290.00 256.52 33.48 + 143.000 267.00 256.62 10.38 + 143.025 278.00 256.77 21.23 + 143.050 302.00 256.99 45.01 + 143.075 264.00 257.30 6.70 + 143.100 263.00 257.69 5.31 + 143.125 289.00 258.16 30.84 + 143.150 231.00 258.71 -27.71 + 143.175 271.00 259.32 11.68 + 143.200 289.00 259.98 29.02 + 143.225 268.00 260.69 7.31 + 143.250 310.00 261.47 48.53 + 143.275 278.00 262.25 15.75 + 143.300 280.00 263.17 16.83 + 143.325 262.00 264.17 -2.17 + 143.350 234.00 265.26 -31.26 + 143.375 278.00 266.44 11.56 + 143.400 288.00 267.70 20.30 + 143.425 265.00 269.12 -4.12 + 143.450 302.00 270.45 31.55 + 143.475 278.00 271.76 6.24 + 143.500 273.00 273.01 -0.01 + 143.525 279.00 274.13 4.87 + 143.550 303.00 275.07 27.93 + 143.575 318.00 275.88 42.12 + 143.600 317.00 276.28 40.72 + 143.625 312.00 276.32 35.68 + 143.650 303.00 275.99 27.01 + 143.675 312.00 275.29 36.71 + 143.700 311.00 274.24 36.76 + 143.725 308.00 272.88 35.12 + 143.750 304.00 271.29 32.71 + 143.775 284.00 269.53 14.47 + 143.800 281.00 267.70 13.30 + 143.825 287.00 265.84 21.16 + 143.850 262.00 264.02 -2.02 + 143.875 273.00 262.32 10.68 + 143.900 284.00 260.77 23.23 + 143.925 261.00 259.41 1.59 + 143.950 241.00 258.26 -17.26 + 143.975 238.00 257.36 -19.36 + 144.000 276.00 256.72 19.28 + 144.025 276.00 256.32 19.68 + 144.050 274.00 256.15 17.85 + 144.075 262.00 256.21 5.79 + 144.100 279.00 256.46 22.54 + 144.125 274.00 256.90 17.10 + 144.150 238.00 257.50 -19.50 + 144.175 278.00 258.21 19.79 + 144.200 273.00 259.06 13.94 + 144.225 274.00 259.97 14.03 + 144.250 260.00 260.95 -0.95 + 144.275 245.00 261.94 -16.94 + 144.300 293.00 262.79 30.21 + 144.325 307.00 263.54 43.46 + 144.350 304.00 264.13 39.87 + 144.375 266.00 264.54 1.46 + 144.400 287.00 264.73 22.27 + 144.425 292.00 264.69 27.31 + 144.450 295.00 264.40 30.60 + 144.475 295.00 263.87 31.13 + 144.500 305.00 263.09 41.91 + 144.525 300.00 262.09 37.91 + 144.550 281.00 260.90 20.10 + 144.575 287.00 259.55 27.45 + 144.600 299.00 258.10 40.90 + 144.625 268.00 256.59 11.41 + 144.650 292.00 255.09 36.91 + 144.675 267.00 253.65 13.35 + 144.700 236.00 252.33 -16.33 + 144.725 248.00 251.19 -3.19 + 144.750 272.00 250.27 21.73 + 144.775 274.00 249.62 24.38 + 144.800 237.00 249.29 -12.29 + 144.825 251.00 249.35 1.65 + 144.850 245.00 249.70 -4.70 + 144.875 285.00 250.43 34.57 + 144.900 252.00 251.55 0.45 + 144.925 272.00 253.05 18.95 + 144.950 258.00 254.91 3.09 + 144.975 269.00 257.11 11.89 + 145.000 268.00 259.62 8.38 + 145.025 299.00 262.40 36.60 + 145.050 240.00 265.40 -25.40 + 145.075 263.00 268.54 -5.54 + 145.100 260.00 271.76 -11.76 + 145.125 315.00 275.02 39.98 + 145.150 315.00 278.11 36.89 + 145.175 295.00 281.03 13.97 + 145.200 279.00 283.68 -4.68 + 145.225 295.00 285.95 9.05 + 145.250 333.00 287.76 45.24 + 145.275 322.00 289.00 33.00 + 145.300 338.00 289.67 48.33 + 145.325 383.00 289.73 93.27 + 145.350 339.00 289.16 49.84 + 145.375 311.00 288.00 23.00 + 145.400 323.00 286.30 36.70 + 145.425 295.00 284.13 10.87 + 145.450 275.00 281.60 -6.60 + 145.475 295.00 278.78 16.22 + 145.500 289.00 275.77 13.23 + 145.525 294.00 272.66 21.34 + 145.550 287.00 269.54 17.46 + 145.575 275.00 266.48 8.52 + 145.600 249.00 263.56 -14.56 + 145.625 232.00 260.83 -28.83 + 145.650 269.00 258.35 10.65 + 145.675 258.00 256.20 1.80 + 145.700 268.00 254.35 13.65 + 145.725 290.00 252.86 37.14 + 145.750 253.00 251.77 1.23 + 145.775 266.00 251.09 14.91 + 145.800 234.00 250.84 -16.84 + 145.825 233.00 251.02 -18.02 + 145.850 223.00 251.64 -28.64 + 145.875 231.00 252.71 -21.71 + 145.900 252.00 254.24 -2.24 + 145.925 275.00 256.24 18.76 + 145.950 267.00 258.70 8.30 + 145.975 251.00 261.63 -10.63 + 146.000 284.00 265.02 18.98 + 146.025 281.00 268.88 12.12 + 146.050 254.00 273.20 -19.20 + 146.075 265.00 277.96 -12.96 + 146.100 309.00 283.18 25.82 + 146.125 269.00 288.81 -19.81 + 146.150 296.00 294.86 1.14 + 146.175 290.00 301.29 -11.29 + 146.200 301.00 308.04 -7.04 + 146.225 297.00 315.06 -18.06 + 146.250 300.00 322.35 -22.35 + 146.275 345.00 329.83 15.17 + 146.300 298.00 337.44 -39.44 + 146.325 347.00 345.12 1.88 + 146.350 345.00 352.93 -7.93 + 146.375 374.00 360.53 13.47 + 146.400 366.00 367.96 -1.96 + 146.425 387.00 375.09 11.91 + 146.450 392.00 381.80 10.20 + 146.475 438.00 387.95 50.05 + 146.500 465.00 393.38 71.62 + 146.525 470.00 397.96 72.04 + 146.550 443.00 401.55 41.45 + 146.575 511.00 404.00 107.00 + 146.600 473.00 405.33 67.67 + 146.625 474.00 405.46 68.54 + 146.650 455.00 404.42 50.58 + 146.675 473.00 402.30 70.70 + 146.700 452.00 399.18 52.82 + 146.725 460.00 395.22 64.78 + 146.750 440.00 390.57 49.43 + 146.775 386.00 385.40 0.60 + 146.800 385.00 379.87 5.13 + 146.825 402.00 374.13 27.87 + 146.850 418.00 368.35 49.65 + 146.875 382.00 362.67 19.33 + 146.900 348.00 357.23 -9.23 + 146.925 344.00 352.17 -8.17 + 146.950 360.00 347.60 12.40 + 146.975 366.00 343.62 22.38 + 147.000 351.00 340.31 10.69 + 147.025 322.00 337.75 -15.75 + 147.050 327.00 335.97 -8.97 + 147.075 318.00 334.90 -16.90 + 147.100 352.00 334.70 17.30 + 147.125 341.00 335.26 5.74 + 147.150 308.00 336.54 -28.54 + 147.175 357.00 338.46 18.54 + 147.200 325.00 340.94 -15.94 + 147.225 367.00 343.88 23.12 + 147.250 383.00 347.20 35.80 + 147.275 381.00 350.67 30.33 + 147.300 376.00 354.21 21.79 + 147.325 381.00 357.67 23.33 + 147.350 434.00 360.94 73.06 + 147.375 410.00 363.87 46.13 + 147.400 412.00 366.38 45.62 + 147.425 411.00 368.35 42.65 + 147.450 393.00 369.73 23.27 + 147.475 427.00 370.45 56.55 + 147.500 429.00 370.50 58.50 + 147.525 441.00 369.84 71.16 + 147.550 407.00 368.50 38.50 + 147.575 412.00 366.48 45.52 + 147.600 456.00 363.87 92.13 + 147.625 389.00 360.74 28.26 + 147.650 386.00 357.15 28.85 + 147.675 382.00 353.23 28.77 + 147.700 368.00 349.07 18.93 + 147.725 352.00 344.79 7.21 + 147.750 367.00 340.50 26.50 + 147.775 366.00 336.30 29.70 + 147.800 364.00 332.28 31.72 + 147.825 366.00 328.55 37.45 + 147.850 352.00 325.16 26.84 + 147.875 312.00 322.20 -10.20 + 147.900 345.00 319.69 25.31 + 147.925 336.00 317.73 18.27 + 147.950 284.00 316.46 -32.46 + 147.975 310.00 315.64 -5.64 + 148.000 289.00 315.39 -26.39 + 148.025 318.00 315.71 2.29 + 148.050 287.00 316.56 -29.56 + 148.075 303.00 317.88 -14.88 + 148.100 306.00 319.68 -13.68 + 148.125 320.00 321.85 -1.85 + 148.150 330.00 324.32 5.68 + 148.175 334.00 326.99 7.01 + 148.200 345.00 329.78 15.22 + 148.225 367.00 332.57 34.43 + 148.250 407.00 335.25 71.75 + 148.275 379.00 337.71 41.29 + 148.300 410.00 339.85 70.15 + 148.325 396.00 341.57 54.43 + 148.350 429.00 342.79 86.21 + 148.375 425.00 343.45 81.55 + 148.400 449.00 343.49 105.51 + 148.425 416.00 342.92 73.08 + 148.450 394.00 341.74 52.26 + 148.475 390.00 340.00 50.00 + 148.500 394.00 337.75 56.25 + 148.525 404.00 335.08 68.92 + 148.550 356.00 332.08 23.92 + 148.575 350.00 328.84 21.16 + 148.600 378.00 325.45 52.55 + 148.625 369.00 322.00 47.00 + 148.650 362.00 318.59 43.41 + 148.675 311.00 315.28 -4.28 + 148.700 297.00 312.15 -15.15 + 148.725 307.00 309.24 -2.24 + 148.750 293.00 306.61 -13.61 + 148.775 291.00 304.28 -13.28 + 148.800 338.00 302.28 35.72 + 148.825 300.00 300.63 -0.63 + 148.850 290.00 299.31 -9.31 + 148.875 317.00 298.38 18.62 + 148.900 312.00 297.69 14.31 + 148.925 270.00 297.26 -27.26 + 148.950 313.00 297.09 15.91 + 148.975 278.00 297.00 -19.00 + 149.000 321.00 297.16 23.84 + 149.025 327.00 297.42 29.58 + 149.050 332.00 297.73 34.27 + 149.075 337.00 298.04 38.96 + 149.100 328.00 298.35 29.65 + 149.125 301.00 298.57 2.43 + 149.150 322.00 298.71 23.29 + 149.175 334.00 298.74 35.26 + 149.200 330.00 298.65 31.35 + 149.225 315.00 298.44 16.56 + 149.250 311.00 298.10 12.90 + 149.275 302.00 297.62 4.38 + 149.300 338.00 297.00 41.00 + 149.325 321.00 296.23 24.77 + 149.350 317.00 295.30 21.70 + 149.375 331.00 294.23 36.77 + 149.400 335.00 293.00 42.00 + 149.425 345.00 291.62 53.38 + 149.450 317.00 290.10 26.90 + 149.475 306.00 288.47 17.53 + 149.500 309.00 286.74 22.26 + 149.525 336.00 284.93 51.07 + 149.550 309.00 283.07 25.93 + 149.575 299.00 281.21 17.79 + 149.600 319.00 279.35 39.65 + 149.625 310.00 277.54 32.46 + 149.650 287.00 275.80 11.20 + 149.675 281.00 274.16 6.84 + 149.700 268.00 272.64 -4.64 + 149.725 260.00 271.24 -11.24 + 149.750 279.00 269.99 9.01 + 149.775 279.00 268.89 10.11 + 149.800 289.00 267.95 21.05 + 149.825 265.00 267.18 -2.18 + 149.850 261.00 266.55 -5.55 + 149.875 264.00 266.09 -2.09 + 149.900 260.00 265.76 -5.76 + 149.925 271.00 265.57 5.43 + 149.950 265.00 265.49 -0.49 + 149.975 270.00 265.52 4.48 + 150.000 280.00 265.64 14.36 + 150.025 304.00 265.85 38.15 + 150.050 283.00 266.05 16.95 + 150.075 289.00 266.34 22.66 + 150.100 294.00 266.66 27.34 + 150.125 325.00 267.01 57.99 + 150.150 269.00 267.37 1.63 + 150.175 282.00 267.76 14.24 + 150.200 293.00 268.17 24.83 + 150.225 275.00 268.61 6.39 + 150.250 283.00 269.10 13.90 + 150.275 281.00 269.66 11.34 + 150.300 283.00 270.29 12.71 + 150.325 277.00 271.02 5.98 + 150.350 284.00 271.87 12.13 + 150.375 275.00 272.85 2.15 + 150.400 277.00 273.97 3.03 + 150.425 278.00 275.26 2.74 + 150.450 273.00 276.54 -3.54 + 150.475 284.00 278.10 5.90 + 150.500 267.00 279.91 -12.91 + 150.525 270.00 281.89 -11.89 + 150.550 287.00 284.04 2.96 + 150.575 316.00 286.35 29.65 + 150.600 261.00 288.78 -27.78 + 150.625 283.00 291.32 -8.32 + 150.650 294.00 293.94 0.06 + 150.675 275.00 296.61 -21.61 + 150.700 324.00 299.29 24.71 + 150.725 306.00 301.93 4.07 + 150.750 302.00 304.45 -2.45 + 150.775 276.00 306.90 -30.90 + 150.800 392.00 309.18 82.82 + 150.825 339.00 311.24 27.76 + 150.850 309.00 313.03 -4.03 + 150.875 315.00 314.51 0.49 + 150.900 322.00 315.65 6.35 + 150.925 359.00 316.40 42.60 + 150.950 308.00 316.75 -8.75 + 150.975 335.00 316.68 18.32 + 151.000 315.00 316.19 -1.19 + 151.025 318.00 315.30 2.70 + 151.050 319.00 314.02 4.98 + 151.075 328.00 312.41 15.59 + 151.100 315.00 310.48 4.52 + 151.125 303.00 308.39 -5.39 + 151.150 296.00 306.00 -10.00 + 151.175 300.00 303.47 -3.47 + 151.200 304.00 300.82 3.18 + 151.225 283.00 298.15 -15.15 + 151.250 292.00 295.42 -3.42 + 151.275 266.00 292.73 -26.73 + 151.300 279.00 290.10 -11.10 + 151.325 295.00 287.57 7.43 + 151.350 258.00 285.05 -27.05 + 151.375 289.00 282.80 6.20 + 151.400 272.00 280.73 -8.73 + 151.425 251.00 278.84 -27.84 + 151.450 305.00 277.16 27.84 + 151.475 263.00 275.69 -12.69 + 151.500 261.00 274.44 -13.44 + 151.525 299.00 273.42 25.58 + 151.550 291.00 272.61 18.39 + 151.575 276.00 271.93 4.07 + 151.600 294.00 271.52 22.48 + 151.625 259.00 271.33 -12.33 + 151.650 254.00 271.34 -17.34 + 151.675 297.00 271.53 25.47 + 151.700 287.00 271.87 15.13 + 151.725 257.00 272.36 -15.36 + 151.750 284.00 272.97 11.03 + 151.775 255.00 273.68 -18.68 + 151.800 260.00 274.48 -14.48 + 151.825 259.00 275.33 -16.33 + 151.850 300.00 276.23 23.77 + 151.875 264.00 277.11 -13.11 + 151.900 300.00 278.01 21.99 + 151.925 287.00 278.88 8.12 + 151.950 298.00 279.71 18.29 + 151.975 283.00 280.46 2.54 + 152.000 279.00 281.13 -2.13 + 152.025 271.00 281.70 -10.70 + 152.050 291.00 282.16 8.84 + 152.075 304.00 282.55 21.45 + 152.100 299.00 282.79 16.21 + 152.125 272.00 282.92 -10.92 + 152.150 316.00 282.95 33.05 + 152.175 298.00 282.92 15.08 + 152.200 322.00 282.81 39.19 + 152.225 306.00 282.67 23.33 + 152.250 268.00 282.52 -14.52 + 152.275 257.00 282.39 -25.39 + 152.300 279.00 282.31 -3.31 + 152.325 262.00 282.31 -20.31 + 152.350 269.00 282.41 -13.41 + 152.375 291.00 282.64 8.36 + 152.400 258.00 283.02 -25.02 + 152.425 269.00 283.57 -14.57 + 152.450 295.00 284.29 10.71 + 152.475 293.00 285.21 7.79 + 152.500 268.00 286.34 -18.34 + 152.525 264.00 287.71 -23.71 + 152.550 272.00 289.24 -17.24 + 152.575 272.00 290.87 -18.87 + 152.600 288.00 292.79 -4.79 + 152.625 270.00 294.89 -24.89 + 152.650 267.00 297.13 -30.13 + 152.675 277.00 299.50 -22.50 + 152.700 310.00 301.98 8.02 + 152.725 292.00 304.52 -12.52 + 152.750 276.00 307.09 -31.09 + 152.775 290.00 309.66 -19.66 + 152.800 319.00 312.18 6.82 + 152.825 322.00 314.62 7.38 + 152.850 316.00 316.91 -0.91 + 152.875 343.00 319.02 23.98 + 152.900 345.00 320.90 24.10 + 152.925 379.00 322.51 56.49 + 152.950 383.00 323.80 59.20 + 152.975 389.00 324.75 64.25 + 153.000 437.00 325.31 111.69 + 153.025 371.00 325.48 45.52 + 153.050 405.00 325.23 79.77 + 153.075 427.00 324.58 102.42 + 153.100 442.00 323.53 118.47 + 153.125 424.00 322.11 101.89 + 153.150 438.00 320.34 117.66 + 153.175 396.00 318.25 77.75 + 153.200 384.00 315.90 68.10 + 153.225 381.00 313.32 67.68 + 153.250 329.00 310.57 18.43 + 153.275 322.00 307.67 14.33 + 153.300 319.00 304.69 14.31 + 153.325 274.00 301.66 -27.66 + 153.350 318.00 298.57 19.43 + 153.375 304.00 295.57 8.43 + 153.400 316.00 292.65 23.35 + 153.425 324.00 289.83 34.17 + 153.450 275.00 287.15 -12.15 + 153.475 319.00 284.63 34.37 + 153.500 259.00 282.30 -23.30 + 153.525 272.00 280.18 -8.18 + 153.550 262.00 278.28 -16.28 + 153.575 270.00 276.62 -6.62 + 153.600 263.00 275.21 -12.21 + 153.625 266.00 274.05 -8.05 + 153.650 242.00 273.15 -31.15 + 153.675 265.00 272.51 -7.51 + 153.700 251.00 272.14 -21.14 + 153.725 276.00 272.01 3.99 + 153.750 277.00 272.13 4.87 + 153.775 260.00 272.44 -12.44 + 153.800 256.00 273.02 -17.02 + 153.825 240.00 273.80 -33.80 + 153.850 278.00 274.78 3.22 + 153.875 252.00 275.93 -23.93 + 153.900 286.00 277.24 8.76 + 153.925 295.00 278.67 16.33 + 153.950 268.00 280.21 -12.21 + 153.975 301.00 281.83 19.17 + 154.000 296.00 235.51 60.49 + 154.025 268.00 235.54 32.46 + 154.050 299.00 235.57 63.43 + 154.075 298.00 235.60 62.40 + 154.100 305.00 235.63 69.37 + 154.125 293.00 235.65 57.35 + 154.150 327.00 235.68 91.32 + 154.175 343.00 235.71 107.29 + 154.200 362.00 235.74 126.26 + 154.225 367.00 235.77 131.23 + 154.250 358.00 235.80 122.20 + 154.275 324.00 235.82 88.18 + 154.300 322.00 235.85 86.15 + 154.325 330.00 235.88 94.12 + 154.350 356.00 235.91 120.09 + 154.375 353.00 235.93 117.07 + 154.400 351.00 235.96 115.04 + 154.425 324.00 235.99 88.01 + 154.450 359.00 236.01 122.99 + 154.475 339.00 236.04 102.96 + 154.500 289.00 236.07 52.93 + 154.525 330.00 236.09 93.91 + 154.550 295.00 236.12 58.88 + 154.575 293.00 236.15 56.85 + 154.600 293.00 236.17 56.83 + 154.625 300.00 236.20 63.80 + 154.650 296.00 236.22 59.78 + 154.675 319.00 236.25 82.75 + 154.700 302.00 236.28 65.72 + 154.725 276.00 236.30 39.70 + 154.750 293.00 236.33 56.67 + 154.775 271.00 236.35 34.65 + 154.800 283.00 236.38 46.62 + 154.825 256.00 236.40 19.60 + 154.850 258.00 236.43 21.57 + 154.875 269.00 236.45 32.55 + 154.900 272.00 236.48 35.52 + 154.925 213.00 236.50 -23.50 + 154.950 257.00 236.52 20.48 + 154.975 274.00 236.55 37.45 + 155.000 242.00 236.57 5.43 + 155.025 245.00 236.60 8.40 + 155.050 252.00 236.62 15.38 + 155.075 212.00 236.64 -24.64 + 155.100 261.00 236.67 24.33 + 155.125 281.00 236.69 44.31 + 155.150 259.00 236.71 22.29 + 155.175 253.00 236.73 16.27 + 155.200 280.00 236.76 43.24 + 155.225 255.00 236.78 18.22 + 155.250 229.00 236.80 -7.80 + 155.275 241.00 236.82 4.18 + 155.300 242.00 236.85 5.15 + 155.325 248.00 236.87 11.13 + 155.350 259.00 236.89 22.11 + 155.375 257.00 236.91 20.09 + 155.400 256.00 236.93 19.07 + 155.425 253.00 236.95 16.05 + 155.450 281.00 236.98 44.02 + 155.475 292.00 237.00 55.00 + 155.500 254.00 237.02 16.98 + 155.525 273.00 237.04 35.96 + 155.550 278.00 237.06 40.94 + 155.575 277.00 237.08 39.92 + 155.600 264.00 237.10 26.90 + 155.625 219.00 237.12 -18.12 + 155.650 271.00 237.14 33.86 + 155.675 279.00 237.16 41.84 + 155.700 246.00 237.18 8.82 + 155.725 268.00 237.20 30.80 + 155.750 282.00 237.22 44.78 + 155.775 272.00 237.24 34.76 + 155.800 270.00 237.26 32.74 + 155.825 221.00 237.28 -16.28 + 155.850 262.00 237.29 24.71 + 155.875 286.00 237.31 48.69 + 155.900 267.00 237.33 29.67 + 155.925 254.00 237.35 16.65 + 155.950 267.00 237.37 29.63 + 155.975 259.00 237.39 21.61 + 156.000 267.00 237.40 29.60 + 156.025 276.00 237.42 38.58 + 156.050 269.00 237.44 31.56 + 156.075 251.00 237.46 13.54 + 156.100 256.00 237.47 18.53 + 156.125 228.00 237.49 -9.49 + 156.150 248.00 237.51 10.49 + 156.175 243.00 237.52 5.48 + 156.200 254.00 237.54 16.46 + 156.225 254.00 237.56 16.44 + 156.250 245.00 237.57 7.43 + 156.275 242.00 237.59 4.41 + 156.300 250.00 237.60 12.40 + 156.325 264.00 237.62 26.38 + 156.350 274.00 237.64 36.36 + 156.375 255.00 237.65 17.35 + 156.400 281.00 237.67 43.33 + 156.425 229.00 237.68 -8.68 + 156.450 263.00 237.70 25.30 + 156.475 250.00 237.71 12.29 + 156.500 241.00 237.73 3.27 + 156.525 259.00 237.74 21.26 + 156.550 268.00 237.75 30.25 + 156.575 285.00 237.77 47.23 + 156.600 241.00 237.78 3.22 + 156.625 255.00 237.80 17.20 + 156.650 268.00 237.81 30.19 + 156.675 257.00 237.82 19.18 + 156.700 263.00 237.84 25.16 + 156.725 266.00 237.85 28.15 + 156.750 298.00 237.86 60.14 + 156.775 281.00 237.88 43.12 + 156.800 271.00 237.89 33.11 + 156.825 261.00 237.90 23.10 + 156.850 280.00 237.91 42.09 + 156.875 296.00 237.92 58.08 + 156.900 283.00 237.94 45.06 + 156.925 341.00 237.95 103.05 + 156.950 280.00 237.96 42.04 + 156.975 304.00 237.97 66.03 + 157.000 282.00 237.98 44.02 + 157.025 258.00 237.99 20.01 + 157.050 262.00 238.00 24.00 + 157.075 279.00 238.02 40.98 + 157.100 285.00 238.03 46.97 + 157.125 319.00 238.04 80.96 + 157.150 293.00 238.05 54.95 + 157.175 322.00 238.06 83.94 + 157.200 316.00 238.07 77.93 + 157.225 348.00 238.08 109.92 + 157.250 341.00 238.09 102.91 + 157.275 339.00 238.09 100.91 + 157.300 321.00 238.10 82.90 + 157.325 373.00 238.11 134.89 + 157.350 376.00 238.12 137.88 + 157.375 366.00 238.13 127.87 + 157.400 402.00 238.14 163.86 + 157.425 391.00 238.15 152.85 + 157.450 405.00 238.16 166.84 + 157.475 407.00 238.16 168.84 + 157.500 422.00 238.17 183.83 + 157.525 395.00 238.18 156.82 + 157.550 434.00 238.19 195.81 + 157.575 419.00 238.19 180.81 + 157.600 426.00 238.20 187.80 + 157.625 385.00 238.21 146.79 + 157.650 390.00 238.21 151.79 + 157.675 375.00 238.22 136.78 + 157.700 357.00 238.23 118.77 + 157.725 343.00 238.23 104.77 + 157.750 359.00 238.24 120.76 + 157.775 344.00 238.24 105.76 + 157.800 285.00 238.25 46.75 + 157.825 324.00 238.26 85.74 + 157.850 317.00 238.26 78.74 + 157.875 345.00 238.27 106.73 + 157.900 303.00 238.27 64.73 + 157.925 315.00 238.28 76.72 + 157.950 288.00 238.28 49.72 + 157.975 301.00 238.28 62.72 + 158.000 281.00 238.29 42.71 + 158.025 327.00 238.29 88.71 + 158.050 316.00 238.30 77.70 + 158.075 260.00 238.30 21.70 + 158.100 299.00 238.30 60.70 + 158.125 302.00 238.31 63.69 + 158.150 249.00 238.31 10.69 + 158.175 293.00 238.31 54.69 + 158.200 271.00 238.32 32.68 + 158.225 296.00 238.32 57.68 + 158.250 258.00 238.32 19.68 + 158.275 283.00 238.32 44.68 + 158.300 268.00 238.32 29.68 + 158.325 271.00 238.33 32.67 + 158.350 305.00 238.33 66.67 + 158.375 268.00 238.33 29.67 + 158.400 234.00 238.33 -4.33 + 158.425 286.00 238.33 47.67 + 158.450 278.00 238.33 39.67 + 158.475 274.00 238.33 35.67 + 158.500 274.00 238.33 35.67 + 158.525 253.00 238.33 14.67 + 158.550 238.00 238.33 -0.33 + 158.575 291.00 238.33 52.67 + 158.600 274.00 238.33 35.67 + 158.625 300.00 238.33 61.67 + 158.650 282.00 238.33 43.67 + 158.675 303.00 238.33 64.67 + 158.700 285.00 238.33 46.67 + 158.725 323.00 238.33 84.67 + 158.750 340.00 238.32 101.68 + 158.775 283.00 238.32 44.68 + 158.800 355.00 238.32 116.68 + 158.825 288.00 238.32 49.68 + 158.850 335.00 238.32 96.68 + 158.875 350.00 238.31 111.69 + 158.900 313.00 238.31 74.69 + 158.925 303.00 238.31 64.69 + 158.950 338.00 238.30 99.70 + 158.975 326.00 238.30 87.70 + 159.000 359.00 238.30 120.70 + 159.025 372.00 238.29 133.71 + 159.050 325.00 238.29 86.71 + 159.075 325.00 238.29 86.71 + 159.100 352.00 238.28 113.72 + 159.125 345.00 238.28 106.72 + 159.150 348.00 238.27 109.73 + 159.175 330.00 238.27 91.73 + 159.200 336.00 238.26 97.74 + 159.225 310.00 238.26 71.74 + 159.250 343.00 238.25 104.75 + 159.275 321.00 238.25 82.75 + 159.300 329.00 238.24 90.76 + 159.325 325.00 238.23 86.77 + 159.350 329.00 238.23 90.77 + 159.375 330.00 238.22 91.78 + 159.400 311.00 238.21 72.79 + 159.425 316.00 238.21 77.79 + 159.450 327.00 238.20 88.80 + 159.475 320.00 238.19 81.81 + 159.500 306.00 238.18 67.82 + 159.525 348.00 238.18 109.82 + 159.550 345.00 238.17 106.83 + 159.575 330.00 238.16 91.84 + 159.600 325.00 238.15 86.85 + 159.625 371.00 238.14 132.86 + 159.650 381.00 238.13 142.87 + 159.675 421.00 238.12 182.88 + 159.700 388.00 238.12 149.88 + 159.725 403.00 238.11 164.89 + 159.750 413.00 238.10 174.90 + 159.775 417.00 238.09 178.91 + 159.800 391.00 238.08 152.92 + 159.825 385.00 238.07 146.93 + 159.850 376.00 238.05 137.95 + 159.875 382.00 238.04 143.96 + 159.900 420.00 238.03 181.97 + 159.925 374.00 238.02 135.98 + 159.950 352.00 238.01 113.99 + 159.975 328.00 238.00 90.00 + 160.000 368.00 237.99 130.01 +END +WAVES Phase1, tik1 +BEGIN + 16.416 -523 + 16.458 -523 + 20.761 -523 + 20.813 -523 + 20.886 -523 + 20.939 -523 + 23.278 -523 + 23.337 -523 + 24.517 -523 + 24.579 -523 + 25.530 -523 + 25.595 -523 + 26.666 -523 + 26.734 -523 + 27.640 -523 + 27.710 -523 + 29.637 -523 + 29.713 -523 + 32.305 -523 + 32.388 -523 + 33.118 -523 + 33.203 -523 + 33.233 -523 + 33.319 -523 + 34.163 -523 + 34.251 -523 + 37.194 -523 + 37.273 -523 + 37.291 -523 + 37.369 -523 + 38.116 -523 + 38.215 -523 + 39.501 -523 + 39.604 -523 + 40.224 -523 + 40.329 -523 + 41.060 -523 + 41.167 -523 + 41.657 -523 + 41.766 -523 + 42.299 -523 + 42.326 -523 + 42.409 -523 + 42.437 -523 + 42.564 -523 + 42.675 -523 + 43.684 -523 + 43.711 -523 + 43.799 -523 + 43.826 -523 + 44.433 -523 + 44.493 -523 + 44.550 -523 + 44.598 -523 + 44.610 -523 + 44.716 -523 + 45.906 -523 + 46.027 -523 + 47.647 -523 + 47.672 -523 + 47.774 -523 + 47.799 -523 + 47.829 -523 + 47.955 -523 + 48.342 -523 + 48.470 -523 + 50.313 -523 + 50.447 -523 + 50.831 -523 + 50.967 -523 + 52.439 -523 + 52.509 -523 + 52.580 -523 + 52.650 -523 + 53.077 -523 + 53.220 -523 + 53.281 -523 + 53.424 -523 + 53.622 -523 + 53.690 -523 + 53.755 -523 + 53.766 -523 + 53.778 -523 + 53.835 -523 + 53.900 -523 + 53.923 -523 + 54.989 -523 + 55.138 -523 + 55.381 -523 + 55.531 -523 + 55.693 -523 + 55.844 -523 + 56.534 -523 + 56.546 -523 + 56.685 -523 + 56.688 -523 + 56.700 -523 + 56.839 -523 + 57.069 -523 + 57.134 -523 + 57.224 -523 + 57.290 -523 + 58.472 -523 + 58.632 -523 + 58.691 -523 + 58.852 -523 + 58.925 -523 + 59.086 -523 + 59.870 -523 + 60.035 -523 + 60.649 -523 + 60.816 -523 + 61.590 -523 + 61.611 -523 + 61.761 -523 + 61.782 -523 + 61.955 -523 + 62.044 -523 + 62.127 -523 + 62.216 -523 + 62.538 -523 + 62.600 -523 + 62.712 -523 + 62.774 -523 + 63.292 -523 + 63.468 -523 + 63.525 -523 + 63.702 -523 + 64.576 -523 + 64.756 -523 + 65.198 -523 + 65.381 -523 + 65.563 -523 + 65.747 -523 + 66.004 -523 + 66.190 -523 + 66.373 -523 + 66.560 -523 + 66.597 -523 + 66.785 -523 + 67.189 -523 + 67.379 -523 + 67.531 -523 + 67.677 -523 + 67.722 -523 + 67.869 -523 + 68.177 -523 + 68.273 -523 + 68.371 -523 + 68.426 -523 + 68.467 -523 + 68.533 -523 + 68.620 -523 + 68.728 -523 + 69.310 -523 + 69.507 -523 + 69.566 -523 + 69.653 -523 + 69.664 -523 + 69.765 -523 + 69.776 -523 + 69.835 -523 + 69.852 -523 + 69.863 -523 + 69.976 -523 + 70.034 -523 + 70.035 -523 + 70.234 -523 + 70.669 -523 + 70.872 -523 + 70.895 -523 + 70.914 -523 + 71.098 -523 + 71.118 -523 + 71.201 -523 + 71.406 -523 + 72.019 -523 + 72.053 -523 + 72.227 -523 + 72.261 -523 + 72.302 -523 + 72.511 -523 + 72.702 -523 + 72.913 -523 + 73.552 -523 + 73.648 -523 + 73.766 -523 + 73.863 -523 + 74.205 -523 + 74.421 -523 + 74.456 -523 + 74.620 -523 + 74.673 -523 + 74.838 -523 + 75.011 -523 + 75.230 -523 + 75.455 -523 + 75.676 -523 + 75.889 -523 + 76.112 -523 + 76.128 -523 + 76.352 -523 + 76.429 -523 + 76.654 -523 + 76.954 -523 + 77.181 -523 + 77.332 -523 + 77.560 -523 + 77.944 -523 + 78.175 -523 + 78.181 -523 + 78.413 -523 + 78.520 -523 + 78.627 -523 + 78.683 -523 + 78.753 -523 + 78.861 -523 + 78.918 -523 + 79.268 -523 + 79.330 -523 + 79.505 -523 + 79.523 -523 + 79.567 -523 + 79.761 -523 + 79.849 -523 + 79.855 -523 + 80.089 -523 + 80.094 -523 + 80.346 -523 + 80.588 -523 + 80.830 -523 + 81.054 -523 + 81.074 -523 + 81.298 -523 + 81.389 -523 + 81.615 -523 + 81.634 -523 + 81.636 -523 + 81.862 -523 + 81.881 -523 + 82.705 -523 + 82.862 -523 + 82.894 -523 + 82.957 -523 + 83.115 -523 + 83.147 -523 + 83.178 -523 + 83.432 -523 + 83.560 -523 + 83.816 -523 + 84.108 -523 + 84.130 -523 + 84.367 -523 + 84.388 -523 + 84.595 -523 + 84.622 -523 + 84.855 -523 + 84.882 -523 + 85.116 -523 + 85.209 -523 + 85.379 -523 + 85.472 -523 + 85.592 -523 + 85.857 -523 + 86.408 -523 + 86.471 -523 + 86.524 -523 + 86.677 -523 + 86.740 -523 + 86.793 -523 + 86.935 -523 + 86.975 -523 + 87.206 -523 + 87.246 -523 + 87.697 -523 + 87.972 -523 + 88.090 -523 + 88.366 -523 + 88.664 -523 + 88.754 -523 + 88.943 -523 + 89.034 -523 + 89.101 -523 + 89.156 -523 + 89.310 -523 + 89.383 -523 + 89.438 -523 + 89.593 -523 + 89.700 -523 + 89.725 -523 + 89.931 -523 + 89.984 -523 + 90.010 -523 + 90.217 -523 + 90.737 -523 + 91.027 -523 + 91.138 -523 + 91.248 -523 + 91.390 -523 + 91.430 -523 + 91.490 -523 + 91.541 -523 + 91.622 -523 + 91.684 -523 + 91.704 -523 + 91.784 -523 + 91.916 -523 + 91.999 -523 + 92.215 -523 + 92.400 -523 + 92.455 -523 + 92.513 -523 + 92.529 -523 + 92.537 -523 + 92.699 -523 + 92.754 -523 + 92.828 -523 + 92.836 -523 + 93.172 -523 + 93.315 -523 + 93.347 -523 + 93.402 -523 + 93.474 -523 + 93.476 -523 + 93.618 -523 + 93.650 -523 + 93.706 -523 + 93.726 -523 + 93.780 -523 + 93.940 -523 + 93.958 -523 + 94.032 -523 + 94.041 -523 + 94.247 -523 + 94.265 -523 + 94.348 -523 + 94.579 -523 + 94.783 -523 + 94.889 -523 + 95.042 -523 + 95.095 -523 + 95.355 -523 + 95.512 -523 + 95.828 -523 + 96.194 -523 + 96.250 -523 + 96.324 -523 + 96.513 -523 + 96.569 -523 + 96.643 -523 + 96.925 -523 + 97.248 -523 + 97.284 -523 + 97.579 -523 + 97.609 -523 + 97.781 -523 + 97.906 -523 + 98.109 -523 + 98.353 -523 + 98.523 -523 + 98.684 -523 + 98.821 -523 + 98.855 -523 + 99.155 -523 + 99.288 -523 + 99.625 -523 + 99.806 -523 + 100.147 -523 + 100.390 -523 + 100.452 -523 + 100.719 -523 + 100.733 -523 + 100.789 -523 + 100.796 -523 + 100.977 -523 + 101.025 -523 + 101.033 -523 + 101.065 -523 + 101.109 -523 + 101.135 -523 + 101.191 -523 + 101.324 -523 + 101.372 -523 + 101.381 -523 + 101.457 -523 + 101.471 -523 + 101.527 -523 + 101.539 -523 + 101.821 -523 + 101.877 -523 + 101.878 -523 + 102.230 -523 + 102.489 -523 + 102.607 -523 + 102.846 -523 + 102.965 -523 + 103.763 -523 + 103.915 -523 + 103.920 -523 + 104.024 -523 + 104.050 -523 + 104.129 -523 + 104.178 -523 + 104.273 -523 + 104.281 -523 + 104.286 -523 + 104.390 -523 + 104.417 -523 + 104.546 -523 + 104.642 -523 + 104.739 -523 + 104.892 -523 + 105.111 -523 + 105.264 -523 + 105.304 -523 + 105.326 -523 + 105.413 -523 + 105.631 -523 + 105.679 -523 + 105.701 -523 + 105.789 -523 + 105.806 -523 + 106.009 -523 + 106.014 -523 + 106.185 -523 + 106.254 -523 + 106.347 -523 + 106.394 -523 + 106.495 -523 + 106.636 -523 + 106.730 -523 + 106.879 -523 + 107.087 -523 + 107.474 -523 + 107.694 -523 + 107.816 -523 + 107.849 -523 + 107.874 -523 + 107.951 -523 + 108.087 -523 + 108.209 -523 + 108.243 -523 + 108.268 -523 + 108.290 -523 + 108.346 -523 + 108.439 -523 + 108.458 -523 + 108.686 -523 + 108.836 -523 + 108.856 -523 + 109.233 -523 + 109.546 -523 + 109.637 -523 + 109.951 -523 + 110.058 -523 + 110.384 -523 + 110.468 -523 + 110.603 -523 + 110.796 -523 + 111.017 -523 + 111.127 -523 + 111.271 -523 + 111.545 -523 + 111.640 -523 + 111.690 -523 + 112.062 -523 + 112.285 -523 + 112.302 -523 + 112.712 -523 + 112.729 -523 + 112.736 -523 + 112.896 -523 + 113.010 -523 + 113.167 -523 + 113.261 -523 + 113.328 -523 + 113.351 -523 + 113.443 -523 + 113.651 -523 + 113.697 -523 + 113.787 -523 + 114.090 -523 + 114.328 -523 + 114.772 -523 + 114.860 -523 + 114.959 -523 + 115.213 -523 + 115.309 -523 + 115.388 -523 + 115.408 -523 + 115.665 -523 + 115.719 -523 + 115.841 -523 + 116.030 -523 + 116.176 -523 + 116.489 -523 + 116.518 -523 + 116.580 -523 + 116.981 -523 + 117.035 -523 + 117.044 -523 + 117.097 -523 + 117.180 -523 + 117.461 -523 + 117.503 -523 + 117.566 -523 + 117.637 -523 + 117.650 -523 + 117.742 -523 + 117.744 -523 + 117.934 -523 + 118.111 -523 + 118.217 -523 + 118.219 -523 + 118.340 -523 + 118.386 -523 + 118.393 -523 + 118.821 -523 + 118.867 -523 + 118.874 -523 + 118.950 -523 + 119.221 -523 + 119.437 -523 + 119.711 -523 + 120.135 -523 + 120.306 -523 + 120.432 -523 + 120.634 -523 + 120.750 -523 + 120.793 -523 + 120.806 -523 + 120.933 -523 + 121.075 -523 + 121.255 -523 + 121.298 -523 + 121.333 -523 + 121.561 -523 + 121.583 -523 + 121.838 -523 + 121.844 -523 + 121.875 -523 + 122.075 -523 + 122.109 -523 + 122.209 -523 + 122.355 -523 + 122.392 -523 + 122.628 -523 + 122.729 -523 + 123.334 -523 + 123.783 -523 + 123.816 -523 + 123.866 -523 + 123.890 -523 + 123.922 -523 + 124.301 -523 + 124.320 -523 + 124.354 -523 + 124.429 -523 + 124.462 -523 + 124.502 -523 + 124.508 -523 + 124.569 -523 + 124.845 -523 + 124.925 -523 + 125.048 -523 + 125.054 -523 + 125.116 -523 + 125.455 -523 + 125.476 -523 + 125.658 -523 + 125.690 -523 + 125.727 -523 + 126.012 -523 + 126.218 -523 + 126.250 -523 + 126.287 -523 + 126.652 -523 + 126.675 -523 + 126.802 -523 + 127.224 -523 + 127.248 -523 + 127.376 -523 + 127.621 -523 + 127.709 -523 + 127.769 -523 + 128.206 -523 + 128.294 -523 + 128.355 -523 + 128.658 -523 + 128.820 -523 + 129.020 -523 + 129.058 -523 + 129.234 -523 + 129.256 -523 + 129.306 -523 + 129.420 -523 + 129.506 -523 + 129.578 -523 + 129.623 -523 + 129.661 -523 + 129.674 -523 + 129.688 -523 + 129.840 -523 + 129.913 -523 + 129.986 -523 + 130.116 -523 + 130.189 -523 + 130.286 -523 + 130.287 -523 + 130.301 -523 + 130.513 -523 + 130.591 -523 + 130.602 -523 + 130.786 -523 + 130.908 -523 + 131.137 -523 + 131.217 -523 + 131.342 -523 + 131.414 -523 + 131.919 -523 + 131.978 -523 + 132.350 -523 + 132.388 -523 + 132.393 -523 + 132.543 -523 + 132.564 -523 + 132.858 -523 + 132.971 -523 + 133.002 -523 + 133.040 -523 + 133.046 -523 + 133.198 -523 + 133.518 -523 + 133.632 -523 + 133.636 -523 + 133.660 -523 + 134.120 -523 + 134.308 -523 + 134.333 -523 + 134.640 -523 + 134.800 -523 + 135.010 -523 + 135.141 -523 + 135.213 -523 + 135.329 -523 + 135.412 -523 + 135.635 -523 + 135.649 -523 + 135.706 -523 + 135.728 -523 + 135.839 -523 + 135.912 -523 + 136.018 -523 + 136.115 -523 + 136.342 -523 + 136.356 -523 + 136.436 -523 + 136.652 -523 + 136.732 -523 + 136.732 -523 + 136.861 -523 + 136.923 -523 + 136.957 -523 + 137.034 -523 + 137.377 -523 + 137.459 -523 + 137.591 -523 + 137.654 -523 + 137.688 -523 + 137.766 -523 + 138.327 -523 + 138.392 -523 + 138.782 -523 + 138.958 -523 + 139.085 -523 + 139.152 -523 + 139.183 -523 + 139.549 -523 + 139.729 -523 + 139.959 -523 + 140.258 -523 + 140.853 -523 + 141.057 -523 + 141.146 -523 + 141.665 -523 + 141.925 -523 + 141.966 -523 + 142.044 -523 + 142.576 -523 + 142.763 -523 + 142.799 -523 + 142.868 -523 + 142.884 -523 + 143.204 -523 + 143.430 -523 + 143.643 -523 + 143.658 -523 + 143.729 -523 + 144.074 -523 + 144.359 -523 + 144.514 -523 + 144.524 -523 + 145.260 -523 + 145.319 -523 + 145.420 -523 + 145.874 -523 + 146.171 -523 + 146.217 -523 + 146.247 -523 + 146.271 -523 + 146.342 -523 + 146.596 -523 + 146.609 -523 + 146.819 -523 + 146.848 -523 + 147.125 -523 + 147.173 -523 + 147.228 -523 + 147.301 -523 + 147.379 -523 + 147.563 -523 + 147.576 -523 + 147.823 -523 + 148.310 -523 + 148.371 -523 + 148.416 -523 + 148.557 -523 + 149.073 -523 + 149.077 -523 + 149.334 -523 + 149.444 -523 + 149.590 -523 + 150.125 -523 + 150.129 -523 + 150.264 -523 + 150.501 -523 + 150.745 -523 + 150.968 -523 + 151.361 -523 + 151.538 -523 + 151.608 -523 + 151.863 -523 + 152.095 -523 + 152.689 -523 + 153.033 -523 + 153.434 -523 + 154.254 -523 + 154.547 -523 + 154.675 -523 + 155.621 -523 + 155.666 -523 + 155.847 -523 + 156.411 -523 + 156.623 -523 + 156.984 -523 + 157.031 -523 + 157.438 -523 + 157.510 -523 + 157.598 -523 + 157.823 -523 + 158.049 -523 + 158.129 -523 + 158.921 -523 + 158.999 -523 + 159.093 -523 + 159.664 -523 + 159.707 -523 + 161.086 -523 +END +WAVES Excrg1, excl1 +BEGIN + 10.00 -523 + 10.00 -523 +END +WAVES Excrg2, excl2 +BEGIN + 154.00 -523 + 160.00 -523 +END +X Silent 1 +X DefaultFont Times +X Display Iobs, Icalc, Diff vs TwoTheta +X Modify mode(Iobs)=2, rgb(Iobs)=(0,0,0), rgb(Diff)=(3800,44400,4000) +X SetAxis bottom 10.00, 160.00 +X Modify lsize(Iobs)=2 +X Modify offset(Diff)={0, -4004} +X Modify wbRGB=(48483,64909,65535), gbRGB=(64612,65535,49415) +X Modify mirror(left)=2, mirror(bottom)=2 +X Modify gfSize=12 +X Append excl1 vs Excrg1 +X Modify mode(excl1)=7, hbFill(excl1)=4 +X Modify rgb(excl1)=(6421,62320,64794) +X Append excl2 vs Excrg2 +X Modify mode(excl2)=7, hbFill(excl2)=4 +X Modify rgb(excl2)=(6421,62320,64794) +X Append tik1 vs Phase1 +X Modify mode(tik1)=1 +X TextBox /F=2/S=3/A=RT "Files: pbsox\rDate of fit: \Z09 17/06/2026/ 16:20:24.0\Z12\rPbSO4\rChi2 = 10.49" +X Label left "\Z14Intensity" +X Label bottom "\Z142-Theta (in degrees)" +X TileWindows/O=1/C +X ShowInfo +X | Title of data set: PbSO4 XrayDif (Rietveld Refinement Round Robin, R.J. Hill, JApC 2 +X | Date of run: 17/06/2026 / 16:20:24.0 +X Beep +X Beep diff --git a/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.sum b/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.sum new file mode 100644 index 000000000..ffa751224 --- /dev/null +++ b/docs/docs/verification/fullprof/pd-xray-pbso4/pbsox.sum @@ -0,0 +1,147 @@ + + + ********************************************************** + ** PROGRAM FullProf.2k (Version 8.40 - Feb2026-ILL JRC) ** + ********************************************************** + M U L T I -- P A T T E R N + Rietveld, Profile Matching & Integrated Intensity + Refinement of X-ray and/or Neutron Data + + + Date: 17/06/2026 Time: 16:20:22.899 + + => PCR file code: pbsox + => DAT file code: pbsox -> Relative contribution: 1.0000 + => Title: PbSO4 XrayDif (Rietveld Refinement Round Robin, R.J. Hill, JApC 2 + + ==> CONDITIONS OF THIS RUN FOR PATTERN No.: 1 + + => Global Refinement of X-ray powder diffraction data + => Global Refinement of X-ray powder diffraction data + Bragg-Brentano(X-rays) or Debye-Scherrer geometry(Neutrons) + => The 7th default profile function was selected + + => Data supplied in free format for pattern: 1 + => Analysis of refinement at the end + => Wavelengths: 1.54056 1.54440 + => Cos(Monochromator angle)= 0.8000 + => Absorption correction (AC), muR-eff = 0.0000 0.0000 + => Base of peaks: 2.0*HW* 6.00 + ==> Angular range, step and number of points: + 2Thmin: 10.000000 2Thmax: 160.000000 Step: 0.025000 No. of points: 6001 + =>-------> Pattern# 1 + => Crystal Structure Refinement for phase: 1 + => The density (volumic mass) of phase 1 is: 6.324 g/cm3 + => Scor: 2.9604 + + ==> RESULTS OF REFINEMENT: + + + => No. of fitted parameters: 0 + + +------------------------------------------------------------------------------ + => Phase No. 1 PbSO4 P n m a +------------------------------------------------------------------------------ + + => No. of reflections for pattern#: 1: 768/2 + + + ==> ATOM PARAMETERS: + + Name x sx y sy z sz B sB occ. socc. Mult + Pb 0.18788( 0) 0.25000( 0) 0.16749( 0) 1.785( 0) 0.500( 0) 4 + S 0.06302( 0) 0.25000( 0) 0.68446( 0) 0.854( 0) 0.500( 0) 4 + O1 0.91235( 0) 0.25000( 0) 0.59346( 0) 1.334( 0) 0.500( 0) 4 + O2 0.18443( 0) 0.25000( 0) 0.53434( 0) 1.575( 0) 0.500( 0) 4 + O3 0.07573( 0) 0.01951( 0) 0.81594( 0) 1.328( 0) 1.000( 0) 8 + + ==> PROFILE PARAMETERS FOR PATTERN# 1 + + => Cell parameters : + 8.47983 0.00000 + 5.39776 0.00000 + 6.95932 0.00000 + 90.00000 0.00000 + 90.00000 0.00000 + 90.00000 0.00000 + + => overall scale factor : 0.4693346E-03 0.000000 + => Eta(p-v) or m(p-vii) : 0.00000 0.00000 + => Overall tem. factor : 0.00000 0.00000 + => Halfwidth parameters : 0.04846 0.00000 + -0.08305 0.00000 + 0.03519 0.00000 + => Preferred orientation: 0.00000 0.00000 + 0.00000 0.00000 + => Asymmetry parameters : 0.00000 0.00000 + 0.00000 0.00000 + 0.00000 0.00000 + 0.00000 0.00000 + => X and y parameters : 0.00000 0.00000 + 0.04927 0.00000 + => Strain parameters : 0.00000 0.00000 + 0.00000 0.00000 + 0.00000 0.00000 + => Size parameters (G,L): 0.00000 0.00000 + 0.00000 0.00000 + + => Add. shape parameters: + 0.00000 0.00000 + 0.00000 0.00000 + + + + ==> GLOBAL PARAMETERS FOR PATTERN# 1 + + + => Zero-point: -0.0482 0.0000 + => Background Polynomial Parameters ==> + 154.32 0.0000 + 100.00 0.0000 + -92.329 0.0000 + -95.599 0.0000 + 126.68 0.0000 + -31.804 0.0000 + + => Cos( theta)-shift parameter : 0.0000 0.0000 + => Sin(2theta)-shift parameter : 0.0000 0.0000 + + ==> RELIABILITY FACTORS WITH ALL NON-EXCLUDED POINTS FOR PATTERN: 1 + + => Cycle: 1 => MaxCycle: 30 + => N-P+C: 5760 + => R-factors (not corrected for background) for Pattern: 1 + => Rp: 12.5 Rwp: 15.9 Rexp: 4.92 Chi2: 10.5 L.S. refinement + => Conventional Rietveld R-factors for Pattern: 1 + => Rp: 20.5 Rwp: 22.6 Rexp: 6.98 Chi2: 10.5 + => Deviance: 0.580E+05 Dev* : 10.06 + => DW-Stat.: 0.5516 DW-exp: 1.9182 + => N-sigma of the GoF: 509.374 + + ==> RELIABILITY FACTORS FOR POINTS WITH BRAGG CONTRIBUTIONS FOR PATTERN: 1 + + => N-P+C: 5350 + => R-factors (not corrected for background) for Pattern: 1 + => Rp: 12.4 Rwp: 15.9 Rexp: 4.79 Chi2: 11.0 L.S. refinement + => Conventional Rietveld R-factors for Pattern: 1 + => Rp: 20.0 Rwp: 22.4 Rexp: 6.73 Chi2: 11.0 + => Deviance: 0.567E+05 Dev* : 10.60 + => DW-Stat.: 0.5644 DW-exp: 1.9151 + => N-sigma of the GoF: 519.150 + + => Global user-weigthed Chi2 (Bragg contrib.): 11.3 + + ----------------------------------------------------- + BRAGG R-Factors and weight fractions for Pattern # 1 + ----------------------------------------------------- + + => Phase: 1 PbSO4 + => Bragg R-factor: 9.45 Vol: 318.543( 0.000) Fract(%): 100.00( 0.00) + => Rf-factor= 10.4 ATZ: 1213.030 Brindley: 1.0000 + + + CPU Time: 1.203 seconds + 0.020 minutes + + => Run finished at: Date: 17/06/2026 Time: 16:20:24.111 diff --git a/docs/docs/verification/index.md b/docs/docs/verification/index.md index 24589e3b9..783fb09d6 100644 --- a/docs/docs/verification/index.md +++ b/docs/docs/verification/index.md @@ -100,6 +100,16 @@ and so on. The list below notes only what is specific to each page. aluminium fluoride (Na₂Ca₃Al₂F₁₄, _I2₁3_); Jorgensen–Von Dreele. Both engines agree with the FullProf reference within tolerance. +## Powder, X-ray, constant wavelength + +- [PbSO₄ `pd-xray`](pd-xray-pbso4.ipynb) – Anglesite (PbSO₄, _Pnma_); + laboratory Cu-source X-ray Rietveld Round Robin data; pseudo-Voigt. + Known discrepancy: FullProf models the full Cu Kα₁/Kα₂ doublet and its + X-ray Lorentz–polarization correction, whereas cryspy and crysfml + calculate from a single wavelength and a different polarization + convention, so neither engine yet reproduces the FullProf X-ray + profile. + ## Single crystal, neutron, constant wavelength - [Pr₂NiO₄ `sc-neut-cwl` (no extinction)](sc-neut-cwl_pr2nio4.ipynb) – diff --git a/docs/docs/verification/pd-xray-pbso4.ipynb b/docs/docs/verification/pd-xray-pbso4.ipynb new file mode 100644 index 000000000..c0bcf2024 --- /dev/null +++ b/docs/docs/verification/pd-xray-pbso4.ipynb @@ -0,0 +1,330 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "0", + "metadata": { + "tags": [ + "hide-in-docs" + ] + }, + "outputs": [], + "source": [ + "# Check whether easydiffraction is installed; install it if needed.\n", + "# Required for remote environments such as Google Colab.\n", + "import importlib.util\n", + "\n", + "if importlib.util.find_spec('easydiffraction') is None:\n", + " %pip install easydiffraction" + ] + }, + { + "cell_type": "markdown", + "id": "1", + "metadata": {}, + "source": [ + "# PbSO₄ — X-ray powder, constant wavelength, pseudo-Voigt\n", + "\n", + "**Note — known discrepancy.**\n", + "\n", + "This is the X-ray Rietveld Round Robin anglesite (PbSO₄) measured with\n", + "a laboratory Cu source. FullProf models the full Cu Kα₁/Kα₂ doublet\n", + "(two wavelengths with a fixed intensity ratio) and applies its X-ray\n", + "Lorentz–polarization and monochromator-polarization corrections.\n", + "`cryspy` and `crysfml` currently calculate this pattern from a single\n", + "wavelength and a different polarization convention, so neither engine\n", + "reproduces the FullProf X-ray profile. The page is kept as a published\n", + "comparison and gated as a *known discrepancy* so it is verified to stay\n", + "discrepant; the X-ray doublet/polarization handling is left for later." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "import easydiffraction as edi\n", + "from easydiffraction import ExperimentFactory\n", + "from easydiffraction import StructureFactory\n", + "from easydiffraction.analysis import verification as verify" + ] + }, + { + "cell_type": "markdown", + "id": "3", + "metadata": {}, + "source": [ + "## Build the project" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "project = edi.Project()" + ] + }, + { + "cell_type": "markdown", + "id": "5", + "metadata": {}, + "source": [ + "## Define the structure" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [ + "structure = StructureFactory.from_scratch(name='pbso4')\n", + "\n", + "structure.space_group.name_h_m = 'P n m a' # FullProf Space group symbol\n", + "\n", + "structure.cell.length_a = 8.479832 # FullProf a\n", + "structure.cell.length_b = 5.397758 # FullProf b\n", + "structure.cell.length_c = 6.959325 # FullProf c\n", + "\n", + "structure.atom_sites.create(\n", + " id='Pb', # FullProf Atom\n", + " type_symbol='Pb', # FullProf Typ\n", + " fract_x=0.18788, # FullProf X\n", + " fract_y=0.25, # FullProf Y\n", + " fract_z=0.16749, # FullProf Z\n", + " adp_type='Biso', # FullProf Biso\n", + " adp_iso=1.78522, # FullProf Biso\n", + ")\n", + "structure.atom_sites.create(\n", + " id='S', # FullProf Atom\n", + " type_symbol='S', # FullProf Typ\n", + " fract_x=0.06302, # FullProf X\n", + " fract_y=0.25, # FullProf Y\n", + " fract_z=0.68446, # FullProf Z\n", + " adp_type='Biso', # FullProf Biso\n", + " adp_iso=0.85413, # FullProf Biso\n", + ")\n", + "structure.atom_sites.create(\n", + " id='O1', # FullProf Atom\n", + " type_symbol='O', # FullProf Typ\n", + " fract_x=0.91235, # FullProf X\n", + " fract_y=0.25, # FullProf Y\n", + " fract_z=0.59346, # FullProf Z\n", + " adp_type='Biso', # FullProf Biso\n", + " adp_iso=1.33362, # FullProf Biso\n", + ")\n", + "structure.atom_sites.create(\n", + " id='O2', # FullProf Atom\n", + " type_symbol='O', # FullProf Typ\n", + " fract_x=0.18443, # FullProf X\n", + " fract_y=0.25, # FullProf Y\n", + " fract_z=0.53434, # FullProf Z\n", + " adp_type='Biso', # FullProf Biso\n", + " adp_iso=1.57511, # FullProf Biso\n", + ")\n", + "structure.atom_sites.create(\n", + " id='O3', # FullProf Atom\n", + " type_symbol='O', # FullProf Typ\n", + " fract_x=0.07573, # FullProf X\n", + " fract_y=0.01951, # FullProf Y\n", + " fract_z=0.81594, # FullProf Z\n", + " adp_type='Biso', # FullProf Biso\n", + " adp_iso=1.32792, # FullProf Biso\n", + ")\n", + "\n", + "project.structures.add(structure)" + ] + }, + { + "cell_type": "markdown", + "id": "7", + "metadata": {}, + "source": [ + "## Load the FullProf reference" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", + "metadata": {}, + "outputs": [], + "source": [ + "FULLPROF_PROJECT_DIR = 'pd-xray-pbso4'\n", + "FULLPROF_PRF_FILE = 'pbsox.prf'\n", + "FULLPROF_SUM_FILE = 'pbsox.sum'\n", + "FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE)\n", + "FULLPROF_BAC_FILE = 'pbsox.bac'\n", + "FULLPROF_ZERO = -0.04816 # FullProf Zero\n", + "FULLPROF_SCALE = 0.0004693346 # FullProf Scale\n", + "FULLPROF_WAVELENGTH = 1.540560 # FullProf Lambda1\n", + "FULLPROF_U = 0.048457 # FullProf U\n", + "FULLPROF_V = -0.083053 # FullProf V\n", + "FULLPROF_W = 0.035188 # FullProf W\n", + "FULLPROF_X = 0.0 # FullProf X\n", + "FULLPROF_Y = 0.049268 # FullProf Y\n", + "\n", + "x, calc_fullprof = verify.load_fullprof_calc_profile(\n", + " FULLPROF_PROJECT_DIR,\n", + " FULLPROF_PRF_FILE,\n", + " FULLPROF_BAC_FILE,\n", + " FULLPROF_ZERO,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "9", + "metadata": {}, + "source": [ + "## Create the experiment" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": {}, + "outputs": [], + "source": [ + "experiment = ExperimentFactory.from_scratch(\n", + " name='pbso4',\n", + " sample_form='powder',\n", + " beam_mode='constant wavelength',\n", + " radiation_probe='xray',\n", + " scattering_type='bragg',\n", + ")\n", + "verify.set_reference_as_measured(experiment, x, calc_fullprof)\n", + "\n", + "experiment.linked_structures.create(structure_id='pbso4', scale=FULLPROF_SCALE)\n", + "\n", + "experiment.instrument.setup_wavelength = FULLPROF_WAVELENGTH\n", + "experiment.instrument.calib_twotheta_offset = FULLPROF_ZERO\n", + "\n", + "experiment.peak.type = 'pseudo-voigt'\n", + "experiment.peak.broad_gauss_u = FULLPROF_U\n", + "experiment.peak.broad_gauss_v = FULLPROF_V\n", + "experiment.peak.broad_gauss_w = FULLPROF_W\n", + "experiment.peak.broad_lorentz_x = FULLPROF_X\n", + "experiment.peak.broad_lorentz_y = FULLPROF_Y\n", + "\n", + "project.experiments.add(experiment)" + ] + }, + { + "cell_type": "markdown", + "id": "11", + "metadata": {}, + "source": [ + "## edi-cryspy VS FullProf" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": {}, + "outputs": [], + "source": [ + "experiment.calculator.type = 'cryspy'\n", + "\n", + "project.analysis.calculate()\n", + "calc_ed_cryspy = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSPY = verify.engine_label('cryspy')\n", + "\n", + "project.display.pattern_comparison(\n", + " 'pbso4',\n", + " reference=calc_fullprof,\n", + " candidate=calc_ed_cryspy,\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=LABEL_ED_CRYSPY,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "13", + "metadata": {}, + "source": [ + "## edi-crysfml VS FullProf" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14", + "metadata": {}, + "outputs": [], + "source": [ + "experiment.calculator.type = 'crysfml'\n", + "\n", + "project.analysis.calculate()\n", + "calc_ed_crysfml = experiment.data.intensity_calc\n", + "LABEL_ED_CRYSFML = verify.engine_label('crysfml')\n", + "\n", + "project.display.pattern_comparison(\n", + " 'pbso4',\n", + " reference=calc_fullprof,\n", + " candidate=calc_ed_crysfml,\n", + " reference_label=FULLPROF_LABEL,\n", + " candidate_label=LABEL_ED_CRYSFML,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "15", + "metadata": {}, + "source": [ + "## Agreement check" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16", + "metadata": {}, + "outputs": [], + "source": [ + "verify.assert_patterns_agree(\n", + " [\n", + " (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy),\n", + " (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml),\n", + " ],\n", + " known_discrepancy=True,\n", + " reason=(\n", + " 'Laboratory X-ray PbSO4: FullProf models the full Cu Ka1/Ka2 '\n", + " 'doublet and its X-ray Lorentz-polarization correction, while '\n", + " 'cryspy and crysfml calculate from a single wavelength and a '\n", + " 'different polarization convention, so neither engine yet '\n", + " 'reproduces the FullProf X-ray profile.'\n", + " ),\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "jupytext": { + "cell_metadata_filter": "-all", + "main_language": "python", + "notebook_metadata_filter": "-all" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/docs/verification/pd-xray-pbso4.py b/docs/docs/verification/pd-xray-pbso4.py new file mode 100644 index 000000000..566cc5eff --- /dev/null +++ b/docs/docs/verification/pd-xray-pbso4.py @@ -0,0 +1,195 @@ +# %% [markdown] +# # PbSO₄ — X-ray powder, constant wavelength, pseudo-Voigt +# +# **Note — known discrepancy.** +# +# This is the X-ray Rietveld Round Robin anglesite (PbSO₄) measured with +# a laboratory Cu source. FullProf models the full Cu Kα₁/Kα₂ doublet +# (two wavelengths with a fixed intensity ratio) and applies its X-ray +# Lorentz–polarization and monochromator-polarization corrections. +# `cryspy` and `crysfml` currently calculate this pattern from a single +# wavelength and a different polarization convention, so neither engine +# reproduces the FullProf X-ray profile. The page is kept as a published +# comparison and gated as a *known discrepancy* so it is verified to stay +# discrepant; the X-ray doublet/polarization handling is left for later. + +# %% +import easydiffraction as edi +from easydiffraction import ExperimentFactory +from easydiffraction import StructureFactory +from easydiffraction.analysis import verification as verify + +# %% [markdown] +# ## Build the project + +# %% +project = edi.Project() + +# %% [markdown] +# ## Define the structure + +# %% +structure = StructureFactory.from_scratch(name='pbso4') + +structure.space_group.name_h_m = 'P n m a' # FullProf Space group symbol + +structure.cell.length_a = 8.479832 # FullProf a +structure.cell.length_b = 5.397758 # FullProf b +structure.cell.length_c = 6.959325 # FullProf c + +structure.atom_sites.create( + id='Pb', # FullProf Atom + type_symbol='Pb', # FullProf Typ + fract_x=0.18788, # FullProf X + fract_y=0.25, # FullProf Y + fract_z=0.16749, # FullProf Z + adp_type='Biso', # FullProf Biso + adp_iso=1.78522, # FullProf Biso +) +structure.atom_sites.create( + id='S', # FullProf Atom + type_symbol='S', # FullProf Typ + fract_x=0.06302, # FullProf X + fract_y=0.25, # FullProf Y + fract_z=0.68446, # FullProf Z + adp_type='Biso', # FullProf Biso + adp_iso=0.85413, # FullProf Biso +) +structure.atom_sites.create( + id='O1', # FullProf Atom + type_symbol='O', # FullProf Typ + fract_x=0.91235, # FullProf X + fract_y=0.25, # FullProf Y + fract_z=0.59346, # FullProf Z + adp_type='Biso', # FullProf Biso + adp_iso=1.33362, # FullProf Biso +) +structure.atom_sites.create( + id='O2', # FullProf Atom + type_symbol='O', # FullProf Typ + fract_x=0.18443, # FullProf X + fract_y=0.25, # FullProf Y + fract_z=0.53434, # FullProf Z + adp_type='Biso', # FullProf Biso + adp_iso=1.57511, # FullProf Biso +) +structure.atom_sites.create( + id='O3', # FullProf Atom + type_symbol='O', # FullProf Typ + fract_x=0.07573, # FullProf X + fract_y=0.01951, # FullProf Y + fract_z=0.81594, # FullProf Z + adp_type='Biso', # FullProf Biso + adp_iso=1.32792, # FullProf Biso +) + +project.structures.add(structure) + +# %% [markdown] +# ## Load the FullProf reference + +# %% +FULLPROF_PROJECT_DIR = 'pd-xray-pbso4' +FULLPROF_PRF_FILE = 'pbsox.prf' +FULLPROF_SUM_FILE = 'pbsox.sum' +FULLPROF_LABEL = verify.fullprof_label(FULLPROF_PROJECT_DIR, FULLPROF_SUM_FILE) +FULLPROF_BAC_FILE = 'pbsox.bac' +FULLPROF_ZERO = -0.04816 # FullProf Zero +FULLPROF_SCALE = 0.0004693346 # FullProf Scale +FULLPROF_WAVELENGTH = 1.540560 # FullProf Lambda1 +FULLPROF_U = 0.048457 # FullProf U +FULLPROF_V = -0.083053 # FullProf V +FULLPROF_W = 0.035188 # FullProf W +FULLPROF_X = 0.0 # FullProf X +FULLPROF_Y = 0.049268 # FullProf Y + +x, calc_fullprof = verify.load_fullprof_calc_profile( + FULLPROF_PROJECT_DIR, + FULLPROF_PRF_FILE, + FULLPROF_BAC_FILE, + FULLPROF_ZERO, +) + +# %% [markdown] +# ## Create the experiment + +# %% +experiment = ExperimentFactory.from_scratch( + name='pbso4', + sample_form='powder', + beam_mode='constant wavelength', + radiation_probe='xray', + scattering_type='bragg', +) +verify.set_reference_as_measured(experiment, x, calc_fullprof) + +experiment.linked_structures.create(structure_id='pbso4', scale=FULLPROF_SCALE) + +experiment.instrument.setup_wavelength = FULLPROF_WAVELENGTH +experiment.instrument.calib_twotheta_offset = FULLPROF_ZERO + +experiment.peak.type = 'pseudo-voigt' +experiment.peak.broad_gauss_u = FULLPROF_U +experiment.peak.broad_gauss_v = FULLPROF_V +experiment.peak.broad_gauss_w = FULLPROF_W +experiment.peak.broad_lorentz_x = FULLPROF_X +experiment.peak.broad_lorentz_y = FULLPROF_Y + +project.experiments.add(experiment) + +# %% [markdown] +# ## edi-cryspy VS FullProf + +# %% +experiment.calculator.type = 'cryspy' + +project.analysis.calculate() +calc_ed_cryspy = experiment.data.intensity_calc +LABEL_ED_CRYSPY = verify.engine_label('cryspy') + +project.display.pattern_comparison( + 'pbso4', + reference=calc_fullprof, + candidate=calc_ed_cryspy, + reference_label=FULLPROF_LABEL, + candidate_label=LABEL_ED_CRYSPY, +) + +# %% [markdown] +# ## edi-crysfml VS FullProf + +# %% +experiment.calculator.type = 'crysfml' + +project.analysis.calculate() +calc_ed_crysfml = experiment.data.intensity_calc +LABEL_ED_CRYSFML = verify.engine_label('crysfml') + +project.display.pattern_comparison( + 'pbso4', + reference=calc_fullprof, + candidate=calc_ed_crysfml, + reference_label=FULLPROF_LABEL, + candidate_label=LABEL_ED_CRYSFML, +) + +# %% [markdown] +# ## Agreement check + +# %% +verify.assert_patterns_agree( + [ + (f'{LABEL_ED_CRYSPY} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_cryspy), + (f'{LABEL_ED_CRYSFML} vs {FULLPROF_LABEL}', calc_fullprof, calc_ed_crysfml), + ], + known_discrepancy=True, + reason=( + 'Laboratory X-ray PbSO4: FullProf models the full Cu Ka1/Ka2 ' + 'doublet and its X-ray Lorentz-polarization correction, while ' + 'cryspy and crysfml calculate from a single wavelength and a ' + 'different polarization convention, so neither engine yet ' + 'reproduces the FullProf X-ray profile.' + ), +) + +# %% From 1f7c3099e99a69c6570dab2d79e37f73eb35ab9b Mon Sep 17 00:00:00 2001 From: Andrew Sazonov Date: Wed, 17 Jun 2026 17:34:24 +0200 Subject: [PATCH 18/18] Assert known_discrepancy per comparison, not per call --- .../accepted/verification-regression-flag.md | 12 +++++- docs/docs/verification/pd-neut-tof_j_si.ipynb | 13 ++++-- docs/docs/verification/pd-neut-tof_j_si.py | 13 ++++-- .../verification/pd-neut-tof_jvd_si.ipynb | 16 ++++++-- docs/docs/verification/pd-neut-tof_jvd_si.py | 16 ++++++-- src/easydiffraction/analysis/verification.py | 40 +++++++++++++------ .../analysis/test_verification.py | 30 +++++++++++++- 7 files changed, 110 insertions(+), 30 deletions(-) diff --git a/docs/dev/adrs/accepted/verification-regression-flag.md b/docs/dev/adrs/accepted/verification-regression-flag.md index 0fc9c9ed1..1003fbcde 100644 --- a/docs/dev/adrs/accepted/verification-regression-flag.md +++ b/docs/dev/adrs/accepted/verification-regression-flag.md @@ -77,7 +77,7 @@ is explained on the published page. `raise_on_failure` is replaced by `known_discrepancy` (default `False`). Beta, no shims: existing pages are migrated, not aliased. -### 1a. A re-gated discrepancy fails CI +### 1a. A re-gated discrepancy fails CI, per comparison `known_discrepancy=True` is a **two-sided** assertion. It does not merely silence a failure; it asserts the discrepancy is **still there**. @@ -86,6 +86,16 @@ The moment a known-bad page starts matching within tolerance, the page `known_discrepancy` / `reason` (re-gating the page) or, if the match is spurious, by tightening the tolerance. +The assertion is evaluated **per comparison**: a +`known_discrepancy=True` call asserts that _every_ listed +`(label, reference, candidate)` comparison still disagrees, and re-gates +if **any** of them now agrees. This stops a known-bad comparison from +masking a regression in an expected-good one that shares the same call — +for example a page that overlays both engines where one matches the +reference and the other does not. Expected-good comparisons therefore +stay in their own default (gated) `assert_patterns_agree(...)` call, and +only the genuinely known-bad comparisons carry `known_discrepancy=True`. + ### 1b. Return value means "expectation met" `assert_patterns_agree` returns `True` when the assertion holds: diff --git a/docs/docs/verification/pd-neut-tof_j_si.ipynb b/docs/docs/verification/pd-neut-tof_j_si.ipynb index 2d3121579..77c06f7c6 100644 --- a/docs/docs/verification/pd-neut-tof_j_si.ipynb +++ b/docs/docs/verification/pd-neut-tof_j_si.ipynb @@ -347,6 +347,7 @@ "metadata": {}, "outputs": [], "source": [ + "# cryspy matches FullProf, so it is gated as a regression test.\n", "verify.assert_patterns_agree(\n", " [\n", " (\n", @@ -354,6 +355,13 @@ " verify.restrict_to_included(experiment, calc_fullprof),\n", " calc_ed_cryspy_refined,\n", " ),\n", + " ],\n", + ")\n", + "\n", + "# ed-crysfml is the known-bad comparison, asserted separately so it\n", + "# cannot mask a cryspy regression in the gated call above.\n", + "verify.assert_patterns_agree(\n", + " [\n", " (\n", " f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", @@ -361,10 +369,7 @@ " ),\n", " ],\n", " known_discrepancy=True,\n", - " reason=(\n", - " 'ed-crysfml TOF Jorgensen profile is about 8.5% off after '\n", - " 'fitting scale; cryspy matches FullProf.'\n", - " ),\n", + " reason='ed-crysfml TOF Jorgensen profile is about 8.5% off after fitting scale.',\n", ")" ] } diff --git a/docs/docs/verification/pd-neut-tof_j_si.py b/docs/docs/verification/pd-neut-tof_j_si.py index c900bfb3c..527af99c7 100644 --- a/docs/docs/verification/pd-neut-tof_j_si.py +++ b/docs/docs/verification/pd-neut-tof_j_si.py @@ -193,6 +193,7 @@ # ## Agreement check # %% +# cryspy matches FullProf, so it is gated as a regression test. verify.assert_patterns_agree( [ ( @@ -200,6 +201,13 @@ verify.restrict_to_included(experiment, calc_fullprof), calc_ed_cryspy_refined, ), + ], +) + +# ed-crysfml is the known-bad comparison, asserted separately so it +# cannot mask a cryspy regression in the gated call above. +verify.assert_patterns_agree( + [ ( f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), @@ -207,8 +215,5 @@ ), ], known_discrepancy=True, - reason=( - 'ed-crysfml TOF Jorgensen profile is about 8.5% off after ' - 'fitting scale; cryspy matches FullProf.' - ), + reason='ed-crysfml TOF Jorgensen profile is about 8.5% off after fitting scale.', ) diff --git a/docs/docs/verification/pd-neut-tof_jvd_si.ipynb b/docs/docs/verification/pd-neut-tof_jvd_si.ipynb index 0acf391f9..8e9925652 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_si.ipynb +++ b/docs/docs/verification/pd-neut-tof_jvd_si.ipynb @@ -377,17 +377,25 @@ "metadata": {}, "outputs": [], "source": [ + "# crysfml matches FullProf, so it is gated as a regression test.\n", "verify.assert_patterns_agree(\n", " [\n", " (\n", - " f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}',\n", + " f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", - " calc_ed_cryspy_refined,\n", + " calc_ed_crysfml_refined,\n", " ),\n", + " ],\n", + ")\n", + "\n", + "# cryspy is the known-bad comparison, asserted separately so it cannot\n", + "# mask a crysfml regression in the gated call above.\n", + "verify.assert_patterns_agree(\n", + " [\n", " (\n", - " f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}',\n", + " f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}',\n", " verify.restrict_to_included(experiment, calc_fullprof),\n", - " calc_ed_crysfml_refined,\n", + " calc_ed_cryspy_refined,\n", " ),\n", " ],\n", " known_discrepancy=True,\n", diff --git a/docs/docs/verification/pd-neut-tof_jvd_si.py b/docs/docs/verification/pd-neut-tof_jvd_si.py index 1f901984e..41cda5ada 100644 --- a/docs/docs/verification/pd-neut-tof_jvd_si.py +++ b/docs/docs/verification/pd-neut-tof_jvd_si.py @@ -209,17 +209,25 @@ # ## Agreement check # %% +# crysfml matches FullProf, so it is gated as a regression test. verify.assert_patterns_agree( [ ( - f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', + f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), - calc_ed_cryspy_refined, + calc_ed_crysfml_refined, ), + ], +) + +# cryspy is the known-bad comparison, asserted separately so it cannot +# mask a crysfml regression in the gated call above. +verify.assert_patterns_agree( + [ ( - f'{LABEL_ED_CRYSFML_REFINED} vs {FULLPROF_LABEL}', + f'{LABEL_ED_CRYSPY_REFINED} vs {FULLPROF_LABEL}', verify.restrict_to_included(experiment, calc_fullprof), - calc_ed_crysfml_refined, + calc_ed_cryspy_refined, ), ], known_discrepancy=True, diff --git a/src/easydiffraction/analysis/verification.py b/src/easydiffraction/analysis/verification.py index e674d8778..e5fa6b8c9 100644 --- a/src/easydiffraction/analysis/verification.py +++ b/src/easydiffraction/analysis/verification.py @@ -989,11 +989,15 @@ def assert_patterns_agree( * ``known_discrepancy=False`` (default) asserts the patterns **agree** — the page is a regression test, and any out-of-tolerance metric raises ``AssertionError``. - * ``known_discrepancy=True`` asserts the patterns **still disagree** - — the documented known-bad state. The expected out-of-tolerance - result passes (the discrepancy stays visible); if the page has - started agreeing within tolerance it raises ``AssertionError`` so - the now-fixed page fails CI and must be re-gated by hand. + * ``known_discrepancy=True`` asserts that **every** listed + comparison **still disagrees** — the documented known-bad state. + The expected out-of-tolerance result passes (the discrepancy + stays visible); if **any** comparison has started agreeing + within tolerance it raises ``AssertionError`` so the now-fixed + comparison fails CI and must be re-gated by hand. A known-bad + comparison cannot mask a regression in an expected-good one: + keep expected-good comparisons in their own default (gated) + call. Parameters ---------- @@ -1021,8 +1025,8 @@ def assert_patterns_agree( ``reason``. AssertionError If the expectation is not met: a default page whose patterns - disagree, or a ``known_discrepancy`` page that now agrees within - tolerance. + disagree, or a ``known_discrepancy`` call in which any + comparison now agrees within tolerance. """ if known_discrepancy and not (reason and reason.strip()): msg = ( @@ -1034,8 +1038,10 @@ def assert_patterns_agree( tolerances = tolerances or AgreementTolerances() rows: list[list[str]] = [] failures: list[str] = [] + agreeing: list[str] = [] for label, reference, candidate in comparisons: checks = _agreement_checks(pattern_closeness(reference, candidate), tolerances) + comparison_failed = False for index, check in enumerate(checks): actual = check.actual if check.passed else f'[red]{check.actual}[/red]' rows.append([ @@ -1047,6 +1053,9 @@ def assert_patterns_agree( ]) if not check.passed: failures.append(f'{label} · {check.metric} = {check.actual}') + comparison_failed = True + if not comparison_failed: + agreeing.append(label) render_table( columns_headers=['Comparison', 'Metric', 'Expected', 'Actual', 'OK'], @@ -1056,12 +1065,19 @@ def assert_patterns_agree( if known_discrepancy: print_table_footnote([('Known discrepancy', reason)]) - if not failures: + # A known_discrepancy call asserts that *every* listed + # comparison still disagrees, so a known-bad comparison cannot + # mask a regression in an expected-good one. Any comparison that + # now agrees within tolerance must be re-gated on its own. + if agreeing: + joined = ', '.join(agreeing) msg = ( - 'This page now agrees within tolerance — remove ' - '`known_discrepancy` (and `reason`) to re-gate it as a ' - 'regression test, or tighten the tolerance if the match ' - 'is spurious.' + f'These comparisons now agree within tolerance: {joined}. ' + 'A `known_discrepancy=True` call asserts that every listed ' + 'comparison still disagrees; move each agreeing comparison ' + 'into its own gated `assert_patterns_agree(...)` call ' + '(without `known_discrepancy`), or tighten the tolerance if ' + 'the match is spurious.' ) raise AssertionError(msg) return True diff --git a/tests/unit/easydiffraction/analysis/test_verification.py b/tests/unit/easydiffraction/analysis/test_verification.py index 739a37728..6f1c65372 100644 --- a/tests/unit/easydiffraction/analysis/test_verification.py +++ b/tests/unit/easydiffraction/analysis/test_verification.py @@ -297,11 +297,39 @@ def test_assert_patterns_agree_known_discrepancy_passes_while_divergent(): assert result is True +def test_assert_patterns_agree_known_discrepancy_passes_when_all_disagree(): + x = np.linspace(0.0, 10.0, 200) + reference = _gaussian(x, 5.0, 0.4) * 100.0 + bad_one = _gaussian(x, 6.5, 0.4) * 100.0 + bad_two = _gaussian(x, 3.5, 0.4) * 100.0 + result = verify.assert_patterns_agree( + [('one', reference, bad_one), ('two', reference, bad_two)], + known_discrepancy=True, + reason='both engines known-bad', + ) + assert result is True + + +def test_assert_patterns_agree_known_discrepancy_regates_when_one_comparison_agrees(): + # A known-bad comparison must not mask a regression in an + # expected-good comparison sharing the same call. + x = np.linspace(0.0, 10.0, 200) + reference = _gaussian(x, 5.0, 0.4) * 100.0 + agreeing = reference * 1.0001 + divergent = _gaussian(x, 6.5, 0.4) * 100.0 + with pytest.raises(AssertionError, match='now agree within tolerance'): + verify.assert_patterns_agree( + [('good', reference, agreeing), ('bad', reference, divergent)], + known_discrepancy=True, + reason='only one engine is known-bad', + ) + + def test_assert_patterns_agree_known_discrepancy_regates_when_agreeing(): x = np.linspace(0.0, 10.0, 200) reference = _gaussian(x, 5.0, 0.4) * 100.0 candidate = reference * 1.0001 - with pytest.raises(AssertionError, match='now agrees within tolerance'): + with pytest.raises(AssertionError, match='now agree within tolerance'): verify.assert_patterns_agree( [('a vs b', reference, candidate)], known_discrepancy=True,