Repository navigation
amici_sens: judge each sensitivity parameter on its own scale (#1261) - #1303
Merged
Merged
Conversation
) sens_verdict on the whole (time, species, parameter) tensor hands differ one array, whose significance gate counts a (species, parameter) column only past 1e-3 of the array's peak. A parameter column is in that parameter's units, so on the nightly's 82 compared amici_sens cases 2,702 of 4,272 parameter columns, in 56 cases, could be zeroed, negated or multiplied by 1000 and still read PASS. _compare now judges each column with column_verdicts, the rule fd_sens adopted in lanl#1167, moved into _amici_sens with judged_columns and JUDGE_FACTOR so the two suites share it: each column scaled to its own peak, judged where that peak clears its atol/|p| floor by 20x, and named on the row (columns_not_judged) where it does not. A row with no column to judge is BAD_TEST rather than a vacuous PASS. fd_sens calls the shared functions with its own floor and forgive mask; its behaviour is unchanged. Replayed on reference-data-v1: 3,448 columns judged, 824 not judged, every zeroed, negated or x1000 judged column reads DIFF, and no case's outcome moves (82 PASS, as the committed baseline), so the baseline stands as is.
…anl#1261) Judged per column only, a column under JUDGE_FACTOR x its atol/|p| floor was left out of the verdict entirely. Zeroed or negated at 5-15x its floor it read PASS where main's tensor-wide verdict read DIFF, and a model whose every column is that small read BAD_TEST (non-scoring) on a silent zero. The row now needs both verdicts: each judged column alone, and the tensor as a whole as before. A whole-tensor DIFF names the columns left out that disagree past their floor. n_below_noise_floor counts the whole tensor again (lanl#316). The compare-level BAD_TEST gets exception_class columns:none-judged (lanl#324), and the verdict tables name it.
From a blind review of the branch: - columns_diff named every column left out that was past its floor once the tensor failed, failing or not. A left-out column is named now only if the tensor's verdict fails it with every other column forgiven. - The comment's tallies mixed the judged columns with the whole tensor's (noise-rescued was a max over both). The tallies are the judged columns', labelled so, with the whole tensor's beside them where it fails or the floor decided it. - fd_sens judged a NaN-valued parameter on its atol/|p| floor (Python's max ignores a NaN); np.maximum did not. np.fmax does. - With no parameter values, columns_not_judged and columns_diff are None (not assessed), as n_columns_judged is, not []. - The matrix leads a commented BAD_TEST row with its exception_class. - Tests for each claim the old ones left unpinned: either side's peak counts, the factor from above, the atol scaling both ways, value, both halves of noise_decisive, column_peaks on a non-finite cell; the fd_sens test checks its own floor instead of comparing a wrapper with itself.
…d count (lanl#1261) From the blind review's re-check: - A left-out column was named when the tensor failed with every other column forgiven; differ never forgives a one-sided NaN or inf, so one in another column named every left-out column past its floor. Each is now judged with every other column of bngsim's set to AMICI's. - noise_decisive counts a floor decisive in the tensor's verdict, but n_noise_rescued is the judged columns', so a row could read decisive with 0 rescued. The tensor's count is its own field, n_noise_rescued_whole. 986 parity tests collected (27 in the new file); the floor follows.
This was referenced Oct 29, 2026
Open
This was referenced Oct 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1261.
The defect, measured on amici_sens
The issue asked for amici_sens to be measured first. I replayed the nightly's 48 models × 2 methods from
reference-data-v1(replay mode, no AMICI needed). The outcomes match the committed baseline on all 96 cases. For the 82 compared cases I saved both tensors, then zeroed, negated, or multiplied by 1000 each bngsim parameter column, one at a time.So the gap fd_sens had before #1167 is larger here: about 63% of amici_sens's columns could go wrong unseen.
The fix
_comparenow judges each parameter column on its own, by the rule fd_sens adopted in #1167. The code moves into_amici_sens.pyso both suites share it (issue step 2):column_verdicts:sens_verdictper column, each column scaled to its own peak, withatolscaled alike so theatol/|p|floor is unchanged.judged_columns: a column is judged where its peak, the larger of the two sides', clears itsatol/|p|floor byJUDGE_FACTOR= 20 (issue step 4). Otherwise it is listed incolumns_not_judged, as fd_sens does.n_columns_judged,columns_not_judged,columns_diff. The comment adds "k/n columns judged" and names the failing columns.After, on the same replay
On the issue's remaining steps:
max_relvalue. Soparity_checks/nightly/baselines/amici_sens.jsonstands as committed, with no new DIFF to triage.verdicts.py diffagainst it gives the same single alert as main's replay does on this machine (BIOMD0000000498n_jac_evals463 → 588). That alert is my Mac against the Linux baseline runner. A verdict change cannot alter solver work.:sensdispositions (MODEL0910846879, MODEL2105110001) are not among the nightly's 48 models, so the change invalue's meaning (now the worst column'smax_rel) reaches none of them.Changes
Plus
parity_checks/tests/test_amici_sens_per_column.py.Tests (
test_amici_sens_per_column.py, 10)'pass' == 'diff'columns_diff == ["k2"])columns_not_judgedand not judgedJUDGE_FACTORandcolumn_verdictsare the shared onesThe first two rows fail on main for the reason the issue names. The rest fail on main only because the fields and functions are new.
Mutations, each caught:
JUDGE_FACTOR = 0)Suites:
parity_checks/testsgives 916 passed. The merge of this branch with #1291, which also touchesfd_sens_run.py, is clean, and 932 pass on the merged tree. The one failure there checks that the build's commit is in the repository, and the merged tree is an extracted copy, not a git checkout. ruff 0.14.0 (the pinned version) is clean.No changelog fragment: this is a
parity_checks/change only, whichci/changelog.pydoes not ask for, as with #1167.Likely objections
atol/|p|floor are columns whose disagreement the floor would forgive anyway.valuechanges meaning." It is now the worst judged column'smax_rel, each column relative to its own peak, as in fd_sens. No disposition in the nightly's set reads it.pull_requestis the check: it should show the outcome table unchanged.