Make species and assembly reference data real, validated, and load-bearing - #3
Merged
Merged
Conversation
…aring
Three cleanups from the codebase review, which turned out to be one coherent
problem: AREE's reference context was decorative. Nothing read it, nothing
validated it, and the one fact that most needed surfacing was invisible.
Species identity. `species` was free text compared by exact string. The Pacific
oyster was reassigned from Crassostrea to Magallana; both names are in current
use; every study registered here says Crassostrea while the identifier
crosswalk is built under Magallana. Adds
registry/controlled_vocabularies/species.yaml mapping accepted names and
synonyms onto NCBI taxids, and a `species_taxid` evidence column carrying the
canonical identity alongside the reported name, which is preserved.
`aree validate-study` now rejects an unknown species and warns on a synonym.
Meta-analysis groups on `species_taxid`, not the reported name. Previously
species was absent from the grouping key entirely — harmless while everything
is one species, but it meant a second species would have pooled into the same
estimate, and a curator writing "Magallana gigas" would have silently split the
oyster in two. Neither failure mode would have raised anything.
Genome assemblies. data/reference/genome_assemblies.yaml was read by no code
and shipped `PLACEHOLDER_CONFIRM_BEFORE_REAL_USE` as an accession. It now
carries both oyster assemblies with accessions verified against the NCBI
Datasets API (recorded in the file), and `aree validate-study` rejects a
`genome_assembly` that does not resolve to an entry, cross-checking its taxid
against the species. Resolution accepts the assembly_id, either accession, or
the combined form publications use ("GCA_902806645.1 (cgigas_uk_roslin_v1)").
The annotation crossing, which is the substantive find. HESSER2024_VCOR
declares the Roslin assembly, but AREE standardizes its identifiers against the
current NCBI reference — xbMagGiga1.1, release GCF_963853765.1-RS_2024_06, a
different assembly from a different centre. That is correct behaviour, since
NCBI Gene IDs persist across assemblies, but nothing recorded that it happened.
Every evidence record now carries `identifier_annotation_release` next to
`genome_assembly`. It is empty, not invented, for the synthetic demo crosswalk.
Stale status. HESSER2024_VCOR sat at `analysis_status: not_started` through
several harmonization runs, so `aree harmonize` now warns when it harmonizes a
study still registered as not_started rather than only fixing the one value.
(Its `annotation_version: null` is not stale — the source states no annotation,
and that is documented honest curation.)
Also folds the four assay harmonizers' duplicated reference-field blocks into
one `study_reference_fields()` helper, so they cannot drift apart on this again.
Tests: 96 -> 132. scripts/check_real_study_evidence.py additionally asserts the
annotation crossing and taxid, so CI guards them. Docs updated:
handling_genome_versions.md rewritten around the real assemblies and the
crossing, adding_a_species.md gains the synonym guidance and corrects its claim
that meta-analysis ignores species, roadmap.md drops the resolved placeholder
item.
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.
Three cleanups flagged in the codebase review. They turned out to be one coherent problem: AREE's reference context was decorative — nothing read it, nothing validated it, and the fact that most needed surfacing was invisible.
The substantive find: an invisible annotation crossing
HESSER2024_VCORdeclares the Roslin assembly (GCA_902806645.1). AREE standardizes its identifiers against a different one: the current NCBI referencexbMagGiga1.1/GCF_963853765.1, annotation releaseRS_2024_06— a different assembly from a different sequencing centre, because that is what the crosswalk is built from.This is correct behaviour. NCBI Gene IDs persist across assemblies and re-annotations, which is precisely why the identifier hierarchy prefers them. But nothing recorded that the crossing happened — a reader of the evidence table saw only the study's own assembly and would reasonably assume the identifiers came from it.
Every evidence record now carries
identifier_annotation_releasealongsidegenome_assembly:genome_assemblyGCA_902806645.1 (cgigas_uk_roslin_v1)— what the study usedidentifier_annotation_releaseGCF_963853765.1 (xbMagGiga1.1), annotation release GCF_963853765.1-RS_2024_06— what the identifiers refer toFor demo studies it is empty, not invented: the demo crosswalk is synthetic and has no annotation provenance to report.
Both accessions were verified against the NCBI Datasets API rather than trusted from the strings already in the repo. The verification date is recorded in the file.
A latent bug: species was not in the meta-analysis grouping key
Not merely unvalidated — absent from
GROUP_KEYSentirely. Harmless while everything is one species, but it meant two failure modes, neither of which would have raised anything:That second case is live, not hypothetical: the Pacific oyster was reassigned from Crassostrea to Magallana, both names are in current use, and AREE's own crosswalk is built under Magallana while every registered study says Crassostrea.
Adds
registry/controlled_vocabularies/species.yamlmapping accepted names and synonyms onto NCBI taxids, and aspecies_taxidevidence column. Grouping is now on the canonical taxid. The reported name is preserved inspecies— validation warns on a synonym rather than rewriting it, consistent with how the repo treats identifiers.Genome assemblies: dead code made load-bearing
data/reference/genome_assemblies.yamlwas read by no code and shippedPLACEHOLDER_CONFIRM_BEFORE_REAL_USEas an accession. It now carries both oyster assemblies with verified accessions, andaree validate-studyrejects agenome_assemblythat does not resolve to an entry, cross-checking its taxid against the species. Resolution accepts theassembly_id, either accession, or the combined form publications actually use.A test asserts no placeholder accession can return.
Stale status field
HESSER2024_VCORsat atanalysis_status: not_startedthrough several harmonization runs. Rather than only fixing the value,aree harmonizenow warns when it harmonizes a study still registered asnot_started— the field is curator-maintained, so it will drift again otherwise. It does not rewrite the curator's YAML.Correction to the review: I had also flagged
annotation_version: nullas stale. That was wrong — the source states no annotation version, and the null is documented honest curation. Left as is.Also
The four assay harmonizers each duplicated the species/assembly/annotation block. Folded into one
study_reference_fields()helper so they cannot drift apart on this again.Verification
Lint clean · 132 tests pass (was 96) · demo pipeline · real-study path · Streamlit serves HTTP 200 · full CI sequence run locally against a fresh venv.
scripts/check_real_study_evidence.pynow also guards the annotation crossing and the taxid, so CI catches a regression:Meta-analysis output is unchanged at 34 pooled rows, all simulated — the real study still contributes none, as expected.
Docs
handling_genome_versions.mdrewritten around the two real assemblies and the crossing.adding_a_species.mdgains the synonym guidance and corrects a claim that is now false — it said meta-analysis "does not reference species directly, so nothing there needs to change."roadmap.mddrops the resolved placeholder item.Still open
The real study continues to contribute no pooled estimate, and random-effects pooling remains exercised only on simulated inputs. That needs a second real study with full statistics, not more reference-data work.
🤖 Generated with Claude Code