Skip to content

Add cross-species candidates and evidence cards: aree build-cross-species-cards (WP6) - #68

Merged
sr320 merged 3 commits into
mainfrom
species/wp6-cross-species-candidates
Oct 16, 2026
Merged

sr320 merged 3 commits into
mainfrom
species/wp6-cross-species-candidates

Conversation

@sr320

@sr320 sr320 commented Oct 16, 2026

Copy link
Copy Markdown
Owner

WP6 of docs/mussel_clam_integration_plan.md: cross-species candidates and evidence cards that show every species side by side. The dashboard gate is the remaining WP6 item.

What it adds

aree build-cross-species-cards [--phenotype] [--feature-type] [--max-adjusted-p] [--all-cards] [--include-multi-copy] runs the orthogroup-level meta-analysis (#58), then tiers and scores every row. Hard gates come first and the score second, as for single-species candidates.

Gate Passes when
replication at least two species each have k ≥ 2 studies of their own
direction every species' estimate has the same sign
significance pooled cross-species BH-adjusted p ≤ 0.05
phenotype_relevance the weakest evidence class across all species' records is more than exposure-only
quality each species' own gene-level quality flags are within the gene-level limit
Tier Meaning
cross_species_convergence every gate passes
cross_species_emerging concordant and significant, but another gate fails (named in gates_failed)
cross_species_discordant species each significant at gene level disagree in sign; surfaced, never dropped
cross_species_unsupported not significant, or a sign disagreement involving a non-significant species

The score is a transparent weighted sum that adds to 100, with a between-species I² penalty of up to 15 points. The weakest species' study count carries the most weight.

Outputs go to reports/evidence_cards/cross_species/: candidates.tsv with every row and its components, index.json, and a card per row with a significant pooled or per-species signal. A card shows, for each species, the gene, original IDs, studies, tissue, life stage, stressor, n, effect with 95% CI and gene-level adjusted p. It then shows the pooled estimate, the between-species heterogeneity, the orthogroup run (or "demo crosswalk, illustrative"), the failed gates, design-confounding warnings, limitations and a next step.

Also in this PR:

  • Per-species estimates: the orthogroup per-species table now carries each species' contributing evidence IDs, sample size, contexts, mapping confidences and quality flags.
  • Single-species cards: they now name their orthogroup and point to the cross-species card. They still state that other species are never pooled into them.
  • Bug fix: the dashboard's pool summary read *_orthogroup_meta_analysis.tsv as a gene-level pool, which lacks k_studies, so the dashboard build would crash after any orthogroup run. A regression test covers it.

Results

  • Demo: 5 emerging and 3 unsupported rows, none convergent, because the demo mussel has one study per gene.
  • Real data (first real cross-species rows): with TUCCI2025_HEAT_PRIMING on main, the three oyster thermal-tolerance studies and the clam pool through 5,681 single-copy orthogroups. 4,890 multi-copy orthogroups were set aside.
Tier Rows
convergence 0
emerging 64
discordant 6
unsupported 5,611

603 cards are rendered. Every emerging row fails three gates. Replication fails because there is one clam study. Phenotype relevance fails because the clam comparison is exposure-only. Quality fails because each species' own flags exceed the limit, just as they do for its single-species candidates. PERUZZA2023_HEATWAVE (#64) is the second clam study, which can bring the clam to k = 2.

Two rules changed after seeing real data

  • Discordant. The first version called any sign disagreement discordant. On real data, 2,880 of 2,886 such rows involved a species that was not significant on its own, which is noise around zero. Discordant now requires significant species of opposite sign; the other 2,880 rows are unsupported, with direction still listed in gates_failed.
  • Quality. The first version took the union of flags across all species, which reached five or six flags on every real row. That would fail the gate however good each species' evidence was. Quality is now the weakest species' own gene-level quality.

Checks

  • ruff check src tests: clean.
  • pytest: 606 passed, 2 skipped, on the branch merged with current main.
  • New tests in tests/test_cross_species_candidates.py cover each tier, the named gates, per-species quality, the noise-versus-reversal rule, score reproducibility and the heterogeneity penalty, the card contents, the demo CLI end to end, orthogroup names on single-species cards, and the dashboard regression.

Docs updated: interpreting_candidate_scores.md (new "Cross-species candidates" section), interpreting_meta_analysis.md, mussel_clam_integration_plan.md (WP6 status), implementation_status.md, and README.md (command table).

🤖 Generated with Claude Code

sr320 and others added 3 commits October 16, 2026 04:34
…cies-cards (WP6)

Tiers orthogroup-level results behind five named gates (replication, direction, significance, phenotype relevance, quality) into cross_species_convergence / emerging / discordant / unsupported, with a transparent weighted score and a between-species I-squared penalty. Cards show every species side by side. Single-species cards now name their orthogroup. Fixes the dashboard pool summary reading orthogroup results as gene-level pools.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ity per species

On the first real oyster-clam pool (5,681 single-copy orthogroups), 2,880 of 2,886 sign disagreements involved a non-significant species, and the union of quality flags across species failed the quality gate for every row. Discordant now requires species each significant at gene level with opposite signs; other sign disagreements are unsupported. Quality is the weakest species' own gene-level quality. Docs record the first real cross-species results.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sr320
sr320 merged commit d4100e9 into main Oct 16, 2026
6 checks passed
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.

1 participant