Automatic phase-2 hand-off: create super cohort and self-submit via analysis-runner - #46
Open
joshuamschmidt wants to merge 55 commits into
Open
Automatic phase-2 hand-off: create super cohort and self-submit via analysis-runner#46joshuamschmidt wants to merge 55 commits into
joshuamschmidt wants to merge 55 commits into
Conversation
Co-authored-by: joshua m schmidt <joshua.schmidt@populationgenomics.org.au>
Co-authored-by: joshua m schmidt <joshua.schmidt@populationgenomics.org.au>
… 2 from a batch job
…nalysis-runner 3.3.0
joshuamschmidt
temporarily deployed
to
development
August 10, 2026 13:48 — with
GitHub Actions
Inactive
joshuamschmidt
temporarily deployed
to
development
August 10, 2026 13:52 — with
GitHub Actions
Inactive
joshuamschmidt
temporarily deployed
to
development
August 10, 2026 13:53 — with
GitHub Actions
Inactive
joshuamschmidt
temporarily deployed
to
development
August 10, 2026 13:56 — with
GitHub Actions
Inactive
…s, record before submit
joshuamschmidt
temporarily deployed
to
development
August 10, 2026 14:12 — with
GitHub Actions
Inactive
joshuamschmidt
temporarily deployed
to
development
August 10, 2026 14:13 — with
GitHub Actions
Inactive
joshuamschmidt
temporarily deployed
to
development
August 10, 2026 14:16 — with
GitHub Actions
Inactive
… change that broke CI tag derivation
…regates cannot collide
…phase-1 and phase-2 stages
… plan keys directly
joshuamschmidt
force-pushed
the
pr3b-two-phase
branch
from
August 12, 2026 23:59
55fdc23 to
531a19a
Compare
…analysis-runner example
…es into the phase check
…-submit # Conflicts: # README.md # pipeline_dag.png # src/popgen_genotyping/config_phase2.toml # src/popgen_genotyping/jobs/merge_cohort_plink_job.py # src/popgen_genotyping/second_workflow.py # src/popgen_genotyping/stages.py # test/test_king_ibdseg.py # test/test_merge_cohort_plink.py # test/test_metamist_utils.py
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.
Purpose
Stacked on #44. Removes the manual break between the two pipeline phases so a single launch runs end to end.
Previously the analyst ran phase 1, created the super cohort between phases, then launched phase 2 as a new run. cpg-flow can't create or validate a cohort mid-run, but the cohort only needs to exist before the phase-2 driver builds its DAG. A batch job at the end of phase 1 can therefore create the cohort and submit phase 2 itself. Self-submission is possible since analysis-runner 3.3.0 (populationgenomics/analysis-runner#764), which skips the full-access confirmation prompt when stdin is not a TTY. Same approach as populationgenomics/cpg-flow-seqr-loader#62, plus cohort creation via
CohortApi.create_cohort_from_criteria.Changes
jobs/submit_phase2_job.py: PythonJob in the driver image, run off spot so a preemption cannot repeat a completed submission. In order, the job:check_expected_outputs = false) or a rescheduled attempt cannot submit phase 2 twice.array_cohort_bedandarray_bafregressanalyses are registered in Metamist: cpg-flow's registration jobs are not stage dependencies, and phase 2 resolves these analyses at driver startup.input_cohorts = [super], stripsar-guidand any stage selection), writes the submission record, then POSTs the phase-2 submission to the analysis-runner server. An HTTP failure fails the job (therun_analysis_runnerhelper would log and swallow it). The POST carries no repo or commit, so the pinned driver image alone supplies the code.The record is written before the POST, so the worst crash leaves a record without a submission; the recovery is in the error message (delete the sentinel, re-run phase 1).
stages.py: newSubmitPhase2MultiCohortStage withrequired_stages=[BafRegress, CohortBcfToPlink], so it runs once, after the plate compute jobs. Reads the sameprevious_aggregate_cohort_idkey asMergeCohortPlink, so the two phases cannot drift.metamist_utils.py:resolve_super_cohort_membership,find_cohort_by_membership,create_custom_cohort,wait_for_cohort_analyses, and a sharedmetamist_projecthelper replacing three copies of the-testsuffix logic. Membership resolution raises when every plate SG is already in the previous aggregate (nothing new to aggregate). A re-run reuses an existing cohort with identical membership (latest by numeric ID if several match) instead of creating a duplicate; a name collision with different membership raises. Creation passessg_ids_internalas the sole criterion, then verifies the created cohort's membership against the request and raises on any shortfall (e.g. SGs Metamist excluded as ineligible), rather than shipping a silently smaller cohort.previous_aggregate_cohort_idis now required in both phases: a cohort ID, or the literal'bootstrap'for a from-scratch build. Previously the key was optional and absence meant bootstrap, so a forgotten entry would silently build a new-plates-only aggregate and register it as the latest. This is a config-breaking change for existing configs.Entry points:
run_workflowreplaced byfirst_workflow(per-plate stages plus hand-off) andsecond_workflow(merge, export, QC). The split replaces Two phase pipeline #44's submission-time phase check: each entry point pins its own stage list and rejects anonly_stagesselection naming stages outside its phase, andsecond_workflowstill requires exactly one input cohort. Accumulating plates over several phase-1 runs before one aggregation still works viaworkflow.last_stages.Configs:
config_phase1.tomlno longer pinsonly_stages(it would skipSubmitPhase2) and gains the requiredsuper_cohort_namekey. In both phasesdriver_imagemust be this repo's own image pinned to an exact tag, never:latest: the submit job imports the package and re-submits with that image string, which phase 2 resolves at its own start, so a floating tag can run the two phases on different code.pyproject.toml: requireanalysis-runner>=3.3.0; declarerequestsandtomlas direct dependencies of the submit job.README and DAG diagram updated.
For reviewers: this changes when an aggregate goes live
Under the agreed design (Harper/Josh/Silk meeting, 13 Jul 2026), running phase 2 was a deliberate act with a manual cohort-creation step in between. With this PR, launching phase 1 produces a new registered
array_aggregate_pgenhours later, unattended, and downstream consumers (single_sample_qc, the atlas) pick up the latest aggregate. The merge-plan printout becomes a post-hoc audit rather than a gate; the hard check is the merge job's--keepcount assert, which fails the run if the merged fileset disagrees with the super cohort. If we want a human gate back, the cheap option is a config flag that creates the cohort but prints the phase-2 command instead of submitting it. Please confirm we are happy with unattended release before this merges.Tests
27 new unit tests (11 of #44's
run_workflowphase-check tests are replaced by entry-point equivalents); 89 total pass.