PR: Backbone subsampling — stable sequence set across reruns - #9
Merged
Conversation
Adds WorkdirPaths.backbone_strains property (config/backbone_strains.txt) and SubsamplingConfig.backbone_strains field (None by default). The field propagates automatically to the resolved Snakemake config via model_dump(). No behaviour change — feature is completely off when the field is None. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…onfig When backbone_strains (a path to a one-strain-per-line include-list) is provided, a synthetic samples.__backbone__ entry is added to the resolved subsample config so augur subsample force-keeps the listed strains regardless of group caps. Defaults to None — no-op for existing callers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds _materialize_backbone() helper that extracts the previous run's subsampled strain list, writes it to config/backbone_strains.txt, and sets cfg.subsampling.backbone_strains before write_snakemake_config_overrides so the resolved config already carries the path. Guards: self-reference (exit 2), missing previous run (warning + no-op), empty backbone (warning + no-op). Manifest records backbone_from path and strain count for provenance. CLI gains --backbone-from PREV_WORKDIR flag. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
resolve_subsample_config rule now reads _sub.get("backbone_strains") from
the resolved config and passes it to resolve_subsample_config() so the
__backbone__ synthetic sample set is injected before augur subsample runs.
Adds integration test confirming the DAG plans cleanly when
backbone_strains is set in the resolved config.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rnals Adds --backbone-from usage example to CLAUDE.md Running the Full Pipeline section (with RSV 2-year-gap example), documents key limitations (best-effort QC, runtime-only, self-reference guard), and documents the implementation path (backbone_strains.txt → SubsamplingConfig → resolve_subsample_config → __backbone__ sample set). Co-Authored-By: Claude Sonnet 4.6 <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.
Summary
Adds opt-in
--backbone-from <prev_workdir>flag toflexpipe-runso a surveillance rerun can anchor itself to a previous build's subsampled strain list. The new subsample becomes the union of (stable backbone strains) + (freshly-selected new sequences), making results comparable across months-apart runs without re-subsampling from scratch.Motivation
Without this, each run independently re-subsamples from the full available pool. Even older, previously-selected sequences can drop in or out of the tree between runs — conflating biological signal with sampling noise. For a lab running scheduled surveillance (e.g. RSV every 6 months), this makes "what's new since last time?" hard to answer reliably.
Mechanism
augur subsampleis driven entirely by a YAML config. A sample set with only aninclude:path force-keeps every listed strain regardless ofgroup_by/sequences_per_groupcaps. We exploit this:_materialize_backbone()inrun.pyreads thestraincolumn from<prev_workdir>/results/subsampled/metadata.tsvand writes it to<workdir>/config/backbone_strains.txtcfg.subsampling.backbone_strainsis set to that path beforewrite_snakemake_config_overridesis called, so it propagates into the single resolved Snakemake configfileresolve_subsample_configrule passes it toflexpipe.config.resolve_subsample_config(), which injectssamples.__backbone__: {include: <path>}into the resolved subsample YAMLaugur subsampleforce-keeps the backbone strains on top of the normal subsampleUsage
Edge cases
--backbone-fromomitted--backbone-from== current workdiraugur subsample(acceptable)clade_filterKey design decisions
includeapplies withinaugur subsample, which runs afteraugur filterandclade_filter. Strains that newly fail QC are correctly excluded even if they were in the previous backbone.SubsamplingConfig.backbone_strainsis never authored inbuilds/*/config.yaml(would bake a machine-specific absolute path into version control).backbone_frompath andbackbone_strain_countare recorded inmanifest.json.Files changed
flexpipe/paths.py—WorkdirPaths.backbone_strainsproperty (config/backbone_strains.txt)flexpipe/config.py—SubsamplingConfig.backbone_strains: str | None;resolve_subsample_config()extended withbackbone_strainsparamflexpipe/run.py—_materialize_backbone()helper;--backbone-fromCLI arg; threading throughrun_pipeline→_run_pipeline_locked; manifest provenanceingest/Snakefile—resolve_subsample_configrule reads_sub.get("backbone_strains")and passes it throughCLAUDE.md— usage example, semantics, and limitations documentedTests
_materialize_backbone(happy path, missing dir, empty metadata, self-reference, end-to-endrun_pipelinepropagation),resolve_subsample_configbackbone injection, and config schema propagation to resolved YAMLbackbone_strainsis set