fix(chrombpnet): drop the 33 mouse (mm10) models — chorus is hg38-only - #121
Merged
Merged
Conversation
ENCODE publishes a mouse developmental atlas of ChromBPNet models
(embryonic forebrain/midbrain/hindbrain/limb/liver/heart/neural tube/
facial prominence, E11.5-E14.5). 33 of the registry's 42 ATAC/DNASE
entries were those mouse models, and every code path around them
assumes hg38:
- scripts/build_backgrounds_chrombpnet.py opens genomes/hg38.fa and
draws its DHS-anchored positions from the hg38 DHS vocabulary, so
the per-track CDFs shipped for those rows were built by pushing
*human* sequence through *mouse* models.
- The registry recorded no organism, so there was no field to filter
or assert on. That is what let the mismatch ship.
The 9 surviving human models are exactly the set that
scripts/generate_catv1_defaults.py already listed as
CHROMBPNET_HUMAN_ANNOTATIONS ("CATv1 is GRCh38-only, so those have no
counterpart and are omitted") — so the filter already existed in one
place and had simply never propagated to the registry or the builder.
chrombpnet_pertrack.npz goes 786 -> 753 rows (9 human ATAC/DNASE + 744
human CHIP) by pure row subsetting; no model was run and no CDF value
recomputed. Validated: the 9 surviving accessibility rows are
bit-identical, sample counts unchanged (18,672/34,004/1,088,128), all
744 CHIP rows preserved, every CDF finite/monotone/non-zero.
Re-adding mouse needs an mm10 FASTA *and* an mm10 region set for
background construction (the cCRE Registry has an mm10 build; the DHS
vocabulary does not), so it is tracked separately rather than as a
registry edit. The mouse heads of Enformer (1,643 tracks) and Borzoi
(2,608) stay unexposed; both are human-only today only because a
*_human_targets.txt was chosen, with nothing asserting that against the
FASTA the builders open.
CAUTION for any future species filter: the mouse tissue names collided
with *human* ENCODE CHIP biosamples — "liver", "heart", "brain" and
"forebrain" are all human CHIP contexts in
chrombpnet_JASPAR_metadata.tsv. The removal keys on (assay, cell_type),
never on the bare tissue name; the validator asserts no CHIP row is
dropped, and 16 human CHIP rows with colliding names were correctly
kept.
No consumer breaks: chrombpnet.py, discovery.py, mcp/server.py,
_setup_prefetch.py and the builder all read the registry dynamically,
and no test pins its contents. Setup now prefetches 9 model tars
instead of 42.
507 passed, 4 skipped, 0 failed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The registry goes 42 -> 9 ATAC/DNASE models and the shipped NPZ goes
786 -> 753 rows, so every doc stating the old numbers now contradicts
the code.
audits/AUDIT_CHECKLIST.md:205 is the one that matters most: it is the
canonical-numbers list, and it ends "No doc may disagree. P1". Merging
the removal without this change would make the checklist contradict the
thing it exists to check. Its entry now also records *why* the number
moved, so the next reader does not have to reconstruct it.
Nine locations, all live docs:
audits/AUDIT_CHECKLIST.md:93,205
docs/NORMALIZATION_GUIDE.md:135,174,466,551,789,1094
README.md:374,1228
Two judgement calls:
- README.md:361 keeps "786 h5's". That column is "Mirror size" and
describes what is hosted on chorus-chrombpnet-slim, which is a
different 786 from the CDF row count — the 33 mm10 h5s are still on
the mirror. Added the fetch behaviour instead, matching how the
Cherimoya row already distinguishes hosted from fetched.
- CHANGELOG.md is untouched. Its 786 references (:17,:198,:208,:210,
:343) are historical release records and correctly describe what
shipped at the time; rewriting them would falsify the history.
docs/plans/chrombpnet-hf-slim-mirror.md:91 also keeps its "42 ChromBPNet
ATAC/DNase x 25.6 MB" — that is mirror sizing arithmetic in a planning
doc, not a live count.
507 passed, 4 skipped, 0 failed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
The defect
ENCODE publishes a mouse developmental atlas of ChromBPNet models (embryonic forebrain / midbrain / hindbrain / limb / liver / heart / neural tube / facial prominence, stages E11.5–E14.5). 33 of the registry's 42 ATAC/DNASE entries were those mouse models, and every code path around them assumes hg38:
scripts/build_backgrounds_chrombpnet.pyopensgenomes/hg38.faand draws its DHS-anchored positions from the hg38 DHS vocabulary. So the per-track CDFs shipped for those 33 rows were built by pushing human sequence through mouse models.Why 9 is the right surviving set
The 9 human models kept here are exactly the set
scripts/generate_catv1_defaults.pyalready listed asCHROMBPNET_HUMAN_ANNOTATIONS, with the comment "CATv1 is GRCh38-only, so those have no counterpart and are omitted." The filter already existed in one place and had simply never propagated to the registry or the builder — so this is an independent corroboration, not a fresh judgement call.The background
chrombpnet_pertrack.npzgoes 786 → 753 rows (9 human ATAC/DNASE + 744 human CHIP) by pure row subsetting — no model was run and no CDF value recomputed.Validated (
validate_753.py, all checks passed):The name-collision trap
The mouse tissue names collide with human ENCODE CHIP biosamples —
liver,heart,brainandforebrainare all human CHIP contexts inchrombpnet_JASPAR_metadata.tsv. A name-only filter would silently delete human CHIP rows.So the removal keys on
(assay, cell_type), never on the bare tissue name; the validator asserts no CHIP row is dropped, and 16 human CHIP rows with colliding names were correctly kept. The registry header now carries this warning for the next person.Scope: what is not changed
Enformer (1,643 mouse tracks) and Borzoi (2,608) stay unexposed. Both are human-only today only because a
*_human_targets.txtwas chosen — nothing asserts that choice against the FASTA the builders open, and nothing would catch a future*_mouse_targets.txt. Also unfixed here:AlphaGenomeOracle(organism="mouse")is accepted, stored, and never read. Those get a per-rowgenomefield and a hard assert in follow-up work.Re-adding mouse properly needs an mm10 FASTA and an mm10 region set for background construction (the cCRE Registry has an mm10 build; the DHS vocabulary does not), so it is tracked separately rather than as a registry edit.
Blast radius
No consumer breaks —
chrombpnet.py,discovery.py,mcp/server.py,_setup_prefetch.pyand the builder all read the registry dynamically, and no test pins its contents. Setup now prefetches 9 model tars instead of 42.Two stale comments updated (
discovery.py's alias-dedup note,generate_catv1_defaults.py's "also ships mouse models") and one misleading test docstring.507 passed, 4 skipped, 0 failed🤖 Generated with Claude Code