Pass the genome fasta to ngs-samples; run it and the analysis workflow as one throttled step - #101
Pass the genome fasta to ngs-samples; run it and the analysis workflow as one throttled step#101jbrestel wants to merge 4 commits into
Conversation
MakeNgsSamplesNextflowConfig now takes a genomeFile param, digests it to its cluster path, and writes it into the generated config as genomeFastaFile (same name dnaseq-nextflow uses). All six callers pass $$genomeSymLink$$ and now depend on symLinkGenome. The fasta already reached the cluster -- copyToCluster mirrors all of dataDir, which is where symLinkGenome puts it -- but the config step only depended on makeResultDir, so it could run before the symlink existed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Matches the param changes in ngs-samples-nextflow: retired genomeSize measured from referenceFasta now added referenceFasta required; pipeline fails fast without it added targetCoverage 60, was hardcoded in calculateMaxReads() added minOnTargetFraction 0.05 fraction floor / 20x inflation cap added minPlausibleFraction 0.01 wrong-genome flag threshold added pilotSize 100000 pilot draw Retiring genomeSize drops the getGenomeSize DB lookup, so this step no longer touches the database. gusConfigFile and organismAbbrev fed only that lookup and are removed from the six callers. The gate thresholds are constants here rather than XML params: the design treats them as one gate with explicit thresholds, not per-graph knobs, and six duplicated paramValues is how they become tribal knowledge. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
runNextflowOnCluster.xml ran ngs-samples-nextflow and the analysis workflow as two steps sharing the runNextflowOnCluster load type. Each released its throttle slot on completion, so after ngs-samples fetched an experiment's reads the analysis had to re-queue behind other experiments' fetches. Running both from one step makes the pair hold a single slot, which gives the throttle its back-pressure, and drops a step for the 24 callers that pass no ngs-samples config (there RunAndMonitorNextflowNGSSamples did nothing at all). Each run keeps its own job info, log, trace and stdout file names, unchanged from before, so a re-entered step still detects an already finished run from its own log and in-flight cluster state stays resumable. Replaces RunAndMonitorNextflowNGSSamples, whose only job was to rename those files and no-op on an empty config. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Added 44d1a07 — run ngs-samples and the analysis nextflow from a single workflow step, so it can be tested together with the genome-fasta change on this branch. Why
Running both from one step makes the fetch/analyse pair hold a single slot, which is what gives the throttle back-pressure. What
The 24 callers that pass no Depends onVEuPathDB/ReFlow#14. Verified
Two things left open
🤖 Generated with Claude Code |
runNextflowOnCluster.xml is shared by 30 callers, so the runClusterTask step it declares can only name one bucket for all of them. stepLoadTypes takes no variables -- neither substituteValues nor substituteMacros touches the attribute -- so tag the step from each call site instead, which is what the path form of stepLoadTypes on a <subgraph> is for. Load types AND together in okToRun, so these run alongside the shared runNextflowOnCluster cap rather than replacing it. The 24 callers with no samples to fetch add nothing and are unaffected. REQUIRES loadThrottle.prop in each workflow config to define these keys, since checkLoadTypes fails the graph build on an unknown stepLoadType: dnaseqNextflow, rnaseqNextflow, longReadRnaSeqNextflow, chipseqNextflow, originsNextflow, splicedLeaderNextflow Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Added 35f1119 — per-assay throttle buckets, plus how to set them.
|
Part of VEuPathDB/VEuPathDatasets#34 (epic VEuPathDB/VEuPathDatasets#13).
Two changes to the ngs-samples path, kept on one branch so they can be tested together. They are independent and separable at 44d1a07:
Both touch the same six callers:
snpAndCnvDNASeq,bulkrnaseq,longReadRnaSeq,processChipSeqExperiment,processOriginsExperiment,rnaSeqSplicedLeaderAndPolyASitesExperiment.1. Contamination-aware subsampling
Config params
MakeNgsSamplesNextflowConfignow emits the param set from the contamination-aware subsampling design:genomeSizereferenceFastanowreferenceFastatargetCoverage60calculateMaxReads()minOnTargetFraction0.05minPlausibleFraction0.01pilotSize100000assayTypeis unchanged but is now validated against three values pipeline-side instead of silently defaulting.The four gate thresholds are constants in the step class, not XML params. The design treats this as one gate with explicit thresholds rather than per-graph knobs, and six duplicated
paramValues is precisely how a threshold becomes tribal knowledge. Easy to promote to params later if a graph genuinely needs to differ.Getting the reference to the cluster
genomeFileis passed as$$genomeSymLink$$by all six callers, digested throughrelativePathToNextflowClusterPath, and emitted asreferenceFasta.No new mirroring machinery was needed — every graph already had a
symLinkGenomestep placing the fasta at$$dataDir$$/$$organismAbbrev$$.fasta, andcopyToClustermirrors all of$$dataDir$$, the same ride the samplesheet takes via thefinalsymlink.The real gap was a missing dependency edge:
ngsSamplesNextflowConfigdepended only onmakeResultDir, so the config could be written before the symlink existed. Five graphs got away with it on incidental ordering. Fixed here — all six nowdependsonsymLinkGenome.Side effect worth noting
Retiring
genomeSizeremoves thegetGenomeSizecall, so this step no longer touches the database at all.gusConfigFileandorganismAbbrevfed only that lookup and are dropped from the six callers. Nothing else in the step read them.2. One step for ngs-samples and the analysis workflow
Why
runNextflowOnCluster.xmlranrunNgsSamplesClusterTaskandrunClusterTaskas two steps sharing therunNextflowOnClusterload type. Each released its throttle slot on completion, so once ngs-samples had fetched an experiment's reads, the analysis run had to re-queue behind other experiments' fetches. There was no way to express "N experiments in flight": the throttle counts running steps, and between the two steps an experiment held nothing.Running both from one step makes the pair hold a single slot, which is what gives the throttle its back-pressure.
What
RunNgsSamplesAndNextflow—nextflowRuns()returns[ngs-samples, analysis];runloops them calling the inheritedrunAndMonitorRunAndMonitorNextflowNGSSamples, whose only job was renaming log files and no-opping on an empty configrunNextflowOnCluster.xml: two steps collapsed into one, still namedrunClusterTask, so downstreamdependsand existing DB step names are preservedMain/t/run_ngs_samples_and_nextflow.tThe 24 callers that pass no
ngsSamplesNextflowConfigFile(interpro, busco, tmhmm, signalp, maskGenome, …) drop that run entirely and lose a step that did nothing at all.Resumability
Each run keeps its own job info, log, trace and stdout file names, unchanged from before. That is load-bearing rather than cosmetic: a re-entered step detects an already-finished run from its own log via
_checkClusterTaskLogForDoneand proceeds to the next one. A single shared log would produce a step that could never resume past its first run.Because the names and the cluster paths are both unchanged, in-flight cluster state stays resumable across this deploy.
3. Per-assay throttle buckets
runNextflowOnCluster.xmlis shared by 30 callers, so the step it declares can only name one bucket for all of them.stepLoadTypestakes no variables — neitherWorkflowStep.substituteValues():777norsubstituteMacros():815touches the attribute, so$$foo$$would survive parsing and then die incheckLoadTypesas an unknown type. So each call site tags the step with the path form instead, which is the mechanism intended for this;LoadTypeTest.testConditionalLoadTypesalready covers the shape.snpAndCnvDNASeq.xmldnaseqNextflowbulkrnaseq.xmlrnaseqNextflowlongReadRnaSeq.xmllongReadRnaSeqNextflowprocessChipSeqExperiment.xmlchipseqNextflowprocessOriginsExperiment.xmloriginsNextflowrnaSeqSplicedLeaderAndPolyASitesExperiment.xmlsplicedLeaderNextflowloadThrottle.proplives in each workflow's config, not in version control, andWorkflowStep.checkLoadTypes()fails the graph build on a load type it can't find there. A missing key is not "unlimited" — it isUnknown stepLoadType: dnaseqNextflowand the workflow will not start. All six keys must be added to everyloadThrottle.prop, whether or not you want to throttle that assay:Those values are a starting point, not a recommendation. No
failThrottle.propchange is needed: these arestepLoadTypesonly, and the step's existingstepFailTypes="runNextflowOnCluster"key is already in use today.How to set the number
Each bucket counts concurrently running
runClusterTasksteps for that assay. Since the fetch and the analysis now share that step, one slot ≈ one experiment's full cluster footprint — SRA download, fastqs, BAMs — held from fetch through analysis. So the number answers "how many experiments of this assay do I want on the cluster at once?"The sizing driver is scratch disk and transfer bandwidth, not CPU: nextflow's own
maxForksalready governs parallelism within a run. Pick fromavailable scratch ÷ per-experiment footprint, start low, and raise it after watching a real load.Load types AND together in
RunnableWorkflow.okToRun(), sorunClusterTaskis bound by both its ownrunNextflowOnClusterbucket (shared by all 30 callers) and its per-assay bucket. Consequences:runNextflowOnClusteris a no-op; the tighter cap always wins.runNextflowOnCluster, or you have just renamed the shared cap.runNextflowOnClusterremains the ceiling on total concurrent cluster nextflow runs, including the 24 annotation callers that add no per-assay tag.totalinloadThrottle.propis unrelated and still required —Workflow.java:423already enforces it.runNextflowOnClusterrather than deleting the key.Merge order
ngs-samples-nextflow'scontamination-aware-subsamplingbranch first.referenceFastahas not landed onmain— the modules consume these params butnextflow.configstill declaresgenomeSize. Merging this PR first would break ngs-samples runs rather than being inert, sincereferenceFastais required and the pipeline fails fast without it.runAndMonitorderived the<workflow>.branchshared-config key from the step'snextflowWorkflowparam, which is only correct while a step runs one workflow. Without that PR, the ngs-samples run picks up the analysis workflow's branch.loadThrottle.propkeys before this reaches their workflow.Testing
perl -c.MakeNgsSamplesNextflowConfigexecuted against stub params to confirm the rendered config; output verified by inspection.Main/t/run_ngs_samples_and_nextflow.t: 21/21 pass. Pins the on-cluster file names to today's exact values, that each run gets its own log and job-info file, and that an empty ngs-samples config yields exactly one run.relativePathToNextflowClusterPathhelper rather than the base class's inline digest math; both were compared against five real dnaseq/interpro path shapes and agree.ReFlow/StepClasses/t/run_and_monitor_nextflow.t: 2 pass, 1 fails —tailLooksOk"Retried but failed" expects''and getsundef. Pre-existing; it fails identically with these changes stashed.Open items, not addressed here
copyLogFromClusterpulls onlynextflow.txt, andCopyNextflowResultFromClustercopies a singlefileparse'd name (outputFilesis split on commas only in$testmode). Needs a second copy step or a change to that class.runNgsSamplesClusterTaskrows will be orphaned inworkflowstepfor any workflow already past that step. Worth confirming how the controller treats a step present in the DB but absent from the graph before this runs against a live instance — it is the one failure mode nothing here tests.copyToCluster→deletFromClusterstill sits outside the throttled step, so staged working dirs remain on disk beyond the cap. Much narrower than before the merge, but not zero: a stalled or offline experiment holds disk while releasing its slot.