Skip to content

Add orthogroup-level (cross-species) meta-analysis (WP6) - #58

Merged
sr320 merged 1 commit into
mainfrom
species/wp6-orthogroup-meta
Oct 15, 2026
Merged

sr320 merged 1 commit into
mainfrom
species/wp6-orthogroup-meta

Conversation

@sr320

@sr320 sr320 commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Second part of WP6 of the mussel and clam integration plan: orthogroup-level, cross-species meta-analysis. It builds on the orthogroup run from #51.

How it pools

Gene-level pooling never crosses species, because species_taxid is in its group key. aree meta-analyze --level orthogroup pools in two stages:

  1. Within species. Each species' estimate for an orthogroup is its existing gene-level pooled estimate, unchanged. Every gene-level rule still holds: prespecified primary comparisons, real standard errors only, and duplicate-mapping exclusion.
  2. Across species. Those estimates are pooled with the same DerSimonian–Laird model. Its Q, I² and τ² now measure heterogeneity between species.

It writes <label>_orthogroup_meta_analysis.tsv and <label>_orthogroup_species_estimates.tsv, the per-species rows behind each result.

What may pool

  • Single-copy orthogroups only, by default. In a multi-copy orthogroup, one species' gene would be compared with another species' different paralog, so those are counted and set aside. --include-multi-copy admits them only when each species has evidence for exactly one gene, and the row keeps its multi_copy label. Infer orthogroups across all seven species and attach them at harmonization (WP6, part 1) #51 found that most stress-response genes are multi-copy, which is why the default matters.
  • Orthogroups from the active run only. Evidence harmonized under an older run is set aside until it is re-harmonized.
  • Simulated and real evidence never pool together. Demo orthogroups are classed demo_crosswalk.

Each row carries k_studies_by_species, species_with_k2 and meets_replication_gate, which is true only when at least two species each have k ≥ 2 studies. It also carries direction_consistency_species, matching the gene-level definition, and a BH-adjusted p within each phenotype, feature-type and origin family.

Bug found while building it

The demo's illustrative orthogroup IDs (OG0000001, …) collide with real OrthoFinder IDs. The first run looked them up in the real run and set eight demo groups aside as multi-copy. Simulated evidence now never consults the run, and a regression test covers it. This is the same hazard as the demo's colliding LOC numbers.

Results

  • Demo: 8 orthogroups pool the oyster and mussel larval studies. hsp70 (OG0000001) pools to log2FC 1.76 with I² = 62% between species. None clears the gate, because the mussel has one study.
  • All committed real evidence: 465,531 records, 18 comparisons, all oyster. Nothing pools across species, which is correct: 63,725 orthogroup groups are single-species. 83.7% of resolved real records carry an orthogroup.

Real cross-species rows need a second species' evidence on main. #41, the Manila clam study, would supply it.

Tests

tests/test_orthogroup_meta.py has 11 tests:

  • the cross-species estimate equals a direct DerSimonian–Laird pool of the species estimates;
  • the replication gate;
  • opposite signs, which are reported rather than hidden;
  • single-species groups;
  • multi-copy groups, set aside by default and admitted with the flag;
  • paralogs within one species, which never pool;
  • orthogroups from a stale run;
  • the demo-ID collision;
  • conflicting orthogroups in the evidence;
  • per-family adjustment;
  • the demo end to end through the CLI.

534 tests pass and ruff is clean.

Docs

  • docs/interpreting_meta_analysis.md gains a "Cross-species results" section on reading these rows.
  • The README, the plan's WP6 status and the implementation status are updated.

Not in this PR

The cross-species candidate category, evidence cards that show both species, and the dashboard gate.

🤖 Generated with Claude Code

… --level orthogroup (WP6)

Gene-level pooling never crosses species. The orthogroup level pools in
two stages: each species' estimate is its gene-level pooled estimate,
unchanged (so primary comparisons, real standard errors and duplicate
mappings are still enforced), then those estimates are pooled across
species with the same DerSimonian-Laird model, reporting between-species
Q, I-squared and tau-squared.

- Single-copy orthogroups only by default; multi-copy ones are counted and
  set aside (--include-multi-copy admits them only when each species has
  evidence for one gene, and keeps the label). Orthogroups absent from the
  active run are set aside. Simulated and real evidence never pool.
- Each row carries per-species study counts and meets_replication_gate
  (two or more species with k >= 2 each); a per-species estimates table is
  written beside the results; BH within phenotype/feature-type/origin.
- The demo's illustrative orthogroup IDs collide with real OrthoFinder IDs
  and first took real multi_copy classes; simulated evidence now never
  consults the run (regression test).
- Demo: 8 orthogroups pool oyster with mussel, none past the gate. All
  committed real evidence (465,531 oyster records): nothing pools across
  species, correctly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sr320
sr320 merged commit 779a130 into main Oct 15, 2026
6 checks passed
@sr320
sr320 deleted the species/wp6-orthogroup-meta branch October 15, 2026 02:40
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