Skip to content

Throw on malformed outcome rates row - #27

Merged
mtcorread merged 5 commits into
IDAS-Durham:mainfrom
gavdoubleu:fix/outcome-rates-row-sum-throws
Sep 13, 2026
Merged

Throw on malformed outcome rates row#27
mtcorread merged 5 commits into
IDAS-Durham:mainfrom
gavdoubleu:fix/outcome-rates-row-sum-throws

Conversation

@gavdoubleu

Copy link
Copy Markdown
Contributor

Summary

  • Throw instead of warn when an outcome rates row doesn't sum correctly
  • Regenerate infection_outcome_rates_covid19.csv to pass the new check

Review

Code-reviewed at medium effort: no correctness bugs, no dropped invariants.

@gavdoubleu
gavdoubleu requested a review from mtcorread as a code owner August 27, 2026 15:59
gavdoubleu added 2 commits September 8, 2026 14:56
validateOutcomeRowSums already detected rows that do not sum to 1, and only
printed to stderr. It fired on 5 of the 40 rows of the covid19 table, worst sum
1.326, for the life of that file, and the warning was read and ignored. The
outcome columns are a probability distribution over trajectories, so a row that
does not sum to 1 is not a table computeTrajectoryRates can sample from: the
weights are renormalised only above 1.0001 and negatives are never clamped, so
the overshoot silently redistributes probability along the trajectory walk.

Also rejects negative rates, as a second net rather than the first one - a
negative can hide inside a row that still sums to 1.

Replaces data/infection_outcome_rates_covid19.csv with the rebuilt table this
now requires. It was the file tripping the check, and configs/config_2021 reads
it, so test_simulator and the two MPI reproducibility tests failed against the
old copy the moment the warning became an error. The rebuild itself belongs to
my_june, which generates this file from a sourced evidence databank and keeps
this copy as its mirror; see its plans/rebuild-covid-outcome-rates.md. It is 42
rows against 40, keyed on residence venue type and XLGU as well as age and sex,
every row summing to 1 with nothing negative.

All 52 tests pass.
@gavdoubleu
gavdoubleu force-pushed the fix/outcome-rates-row-sum-throws branch from 0ae7dfb to 3c169a3 Compare September 8, 2026 14:15
@mtcorread

Copy link
Copy Markdown
Collaborator

Thanks Gavin. The loader change is right, it's small, and it's what the title says, so I'd like to merge it on its own. Could you split this PR in two?

1. Throw on a malformed row (this PR). Keep the disease_loader.cpp change here. It can't land by itself yet, though: against the COVID table currently on main, config_2021 no longer loads. I built main plus only this loader change and ran it:

Outcome rates row 20 sums to 1.011326, expected 1.0.

18 of the 40 rows fail the new check (row sums up to 1.326), and 7 of them carry a negative severe. So this half needs those rows in the existing table made valid, however you think is right for the data, without bringing in the whole replacement.

2. The replacement COVID table (a separate PR). It should come with what it's built from: scripts/build_outcome_rates.py and data/infection_outcome_rates_evidence/. The CSV header cites both, plus plans/rebuild-covid-outcome-rates.md and CONTEXT.md, and none of them exist on any branch. As it stands the table can't be regenerated or checked. Please drop the plans/CONTEXT references from the header either way.

That second PR also uses filter.geo_unit.XLGU, which only exists once #25 is in, so it has to land after #25.

@gavdoubleu

gavdoubleu commented Sep 13, 2026 via email

Copy link
Copy Markdown
Contributor Author

@mtcorread

Copy link
Copy Markdown
Collaborator

Definitely Claude went rogue there... I was like 'check PR 27', left to the bathroom and come back to him commenting on my behalf 💀. No, I think we don't need to add those back or split the PR. Do not worry, also I didn't expect you to be checking this at this time! Go to bed 😝

@gavdoubleu

gavdoubleu commented Sep 13, 2026 via email

Copy link
Copy Markdown
Contributor Author

@mtcorread

Copy link
Copy Markdown
Collaborator

I didn't work on Friday so I was gonna make up for it today :P

The header named a generator script, a plans document, a glossary and an evidence directory. None of them are in JUNE2; the table's provenance lives with the data, not here, so the references only pointed nowhere.
mtcorread added a commit that referenced this pull request Sep 13, 2026
test_simulator built small worlds by hand and then loaded
configs/config_2021/disease.yaml and infection_seeds.yaml, so it broke
whenever the production configs grew something those worlds couldn't
answer. #27's outcome table filters on XLGU, which neither test world
declares, and the load-time check throws.

The test now loads tests/configs/simulator_disease.yaml, which picks
trajectories by fixed probability and has no outcome table, and
tests/configs/simulator_infection_seeds.yaml, which seeds on the test's own
start date. The old seed file was dated a month after the run, so the smoke
test never infected anyone. With its own seed file it infects 5 of its 20
people.
@mtcorread
mtcorread merged commit 6634db9 into IDAS-Durham:main Sep 13, 2026
5 checks passed
mtcorread added a commit to gavdoubleu/JUNE2 that referenced this pull request Sep 13, 2026
This brings in IDAS-Durham#30 and IDAS-Durham#27 from main without conflicts. IDAS-Durham#30 only changes
test_simulator and adds its own test configs, and IDAS-Durham#27 only changes the
outcome-rates loader and the COVID table, and this branch touches none of
those files.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants