Repository navigation
New module: spoligotyper - #13085
New module: spoligotyper#13085duceppemo wants to merge 3 commits into
Conversation
In silico spoligotyping of the M. tuberculosis complex from reads or assemblies, with species (regions of difference) and lineages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vagkaratzas
left a comment
There was a problem hiding this comment.
- Blocking: the module still uses legacy biocontainers/depot containers; it needs a Seqera Wave build (
nf-core modules containers create). - Blocking: the tests should snapshot
sanitizeOutput(process.out)(withunstableKeysplus a stable check for unstable channels) instead of picking channels and file names; the paired-end test only snapshots versions. - Smaller points: use
${prefix}in the output paths, quote interpolated paths, and fix themeta.ymldetails (args_id, FASTQ/FASTA ontologies, "Optional" on the PDF).
Not run: G1 and G2. The PR's nf-core CI workflows (Run Linting, Run nf-test) have not run on the head commit and are waiting for maintainer approval (action_required), so there is no CI result to read. Please run nf-core modules lint spoligotyper and the tests with --profile +singularity; the PR description says the Singularity test was not run. G3 (nextflow lint) passes.
Diff 7.41/10 · Overall 7.41/10
nf-core-reviewer 0.3.0 / vagkaratzas-review (rubric v2) · claude-sonnet-5-5
| container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? | ||
| 'https://depot.galaxyproject.org/singularity/spoligotyper:0.9.0--pyhdfd78af_0' : | ||
| 'quay.io/biocontainers/spoligotyper:0.9.0--pyhdfd78af_0' }" |
There was a problem hiding this comment.
The container still points to legacy biocontainers / depot.galaxyproject.org. Please build a Seqera Wave container with nf-core modules containers create spoligotyper, which also adds the containers: block to meta.yml and the .conda-lock/ files.
| tuple val(meta), path("*_spoligotyping.txt") , emit: tsv | ||
| tuple val(meta), path("*_spoligotyping.json") , emit: json | ||
| tuple val(meta), path("*_spoligotyping.pdf") , emit: pdf, optional: true | ||
| tuple val(meta), path("*_spoligotyping_mqc.json"), emit: multiqc |
There was a problem hiding this comment.
The output names are predictable (--sample ${prefix} gives ${prefix}_spoligotyping.*), so use ${prefix} instead of globs.
| tuple val(meta), path("*_spoligotyping.txt") , emit: tsv | |
| tuple val(meta), path("*_spoligotyping.json") , emit: json | |
| tuple val(meta), path("*_spoligotyping.pdf") , emit: pdf, optional: true | |
| tuple val(meta), path("*_spoligotyping_mqc.json"), emit: multiqc | |
| tuple val(meta), path("${prefix}_spoligotyping.txt") , emit: tsv | |
| tuple val(meta), path("${prefix}_spoligotyping.json") , emit: json | |
| tuple val(meta), path("${prefix}_spoligotyping.pdf") , emit: pdf, optional: true | |
| tuple val(meta), path("${prefix}_spoligotyping_mqc.json"), emit: multiqc |
| def args = task.ext.args ?: '' | ||
| def prefix = task.ext.prefix ?: "${meta.id}" | ||
| // Reads (single-end or paired-end) or an assembly: spoligotyper detects the file type | ||
| def input = reads instanceof List && reads.size() == 2 ? "-r1 ${reads[0]} -r2 ${reads[1]}" : "-r1 ${reads}" |
There was a problem hiding this comment.
Quote the staged file names in case they contain spaces.
| def input = reads instanceof List && reads.size() == 2 ? "-r1 ${reads[0]} -r2 ${reads[1]}" : "-r1 ${reads}" | |
| def input = reads instanceof List && reads.size() == 2 ? "-r1 '${reads[0]}' -r2 '${reads[1]}'" : "-r1 '${reads}'" |
| spoligotyper \\ | ||
| $args \\ | ||
| $input \\ | ||
| --sample ${prefix} \\ |
There was a problem hiding this comment.
Same here: quote the prefix.
| --sample ${prefix} \\ | |
| --sample "${prefix}" \\ |
| - genotyping | ||
| - lineage | ||
| tools: | ||
| - spoligotyper: |
There was a problem hiding this comment.
The tool is missing args_id: "$args".
| e.g. [ id:'test', single_end:false ] | ||
| - "*_spoligotyping.pdf": | ||
| type: file | ||
| description: PDF report for quality assurance (not written with --no-pdf) |
There was a problem hiding this comment.
The PDF output is optional (optional: true in main.nf), so the description should say "Optional".
| description: PDF report for quality assurance (not written with --no-pdf) | |
| description: Optional PDF report for quality assurance (not written with --no-pdf) |
|
|
||
| // nf-core test data has no M. tuberculosis complex genome: these tests check that the module runs and | ||
| // writes its outputs ("MTBC not detected" is the expected result). | ||
| test("sarscov2 - fasta") { |
There was a problem hiding this comment.
Put a bare assert process.success before assertAll(...), as in the nf-core template (same for the other two tests).
| { assert snapshot( | ||
| file(process.out.pdf[0][1]).name, | ||
| file(process.out.json[0][1]).name, | ||
| process.out.multiqc, | ||
| process.out.findAll { key, val -> key.startsWith('versions') } | ||
| ).match() } |
There was a problem hiding this comment.
Do not hand-pick channels and file names. Snapshot sanitizeOutput(process.out) and list only the truly unstable channels (the PDF and the JSON with run information, if they change between runs) in unstableKeys. Give each exempted channel back a stable check in the same snapshot(...), e.g. .contains() on a line the tool always writes.
| assertAll( | ||
| { assert process.success }, | ||
| { assert path(process.out.tsv[0][1]).text.contains('fastq') }, | ||
| { assert snapshot(process.out.findAll { key, val -> key.startsWith('versions') }).match() } |
There was a problem hiding this comment.
This test only snapshots the versions, so the paired-end branch is not checked against its outputs. Use snapshot(sanitizeOutput(process.out, unstableKeys: [...])) with the same stable checks as above.
| then { | ||
| assertAll( | ||
| { assert process.success }, | ||
| { assert snapshot(process.out).match() } |
There was a problem hiding this comment.
Wrap the output with sanitizeOutput.
| { assert snapshot(process.out).match() } | |
| { assert snapshot(sanitizeOutput(process.out)).match() } |
|
CI only runs automatically for nf-core members. Please ask for a GitHub invitation in the nf-core Slack #github-invitations channel; once you've joined, CI will run on your next push. Comment added by Claude |
- Seqera Wave containers (nf-core modules containers create) instead of
the legacy biocontainers/depot images, with the conda lock files
- Tests snapshot sanitizeOutput(process.out) with unstableKeys for the
json and pdf channels (they embed run timestamps), plus stable content
checks on those channels; snapshot regenerated
- ${prefix} in the output paths, quoted interpolated paths
- meta.yml: args_id, FASTQ/FASTA ontologies on the input, 'Optional.' on
the pdf output, ${prefix} output names
nf-core modules lint: 79 passed, 0 warnings, 0 failed.
nf-test passes with --profile docker and --profile singularity.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
This PR exceeds the recommended size of 1000 lines. Please make sure you are NOT addressing multiple issues with one PR. Note this PR might be rejected due to its size. |
|
Thanks for the review @vagkaratzas — all points addressed in 009a860:
Verified locally: The CI workflows may still need maintainer approval to run on this PR. |
@duceppemo can you do the above so you become a member of the nf-core organization, in order to have the tests on the ci run? |
PR checklist
New module for spoligotyper (bioconda, docs): in silico spoligotyping of the Mycobacterium tuberculosis complex from reads (single or paired-end) or assemblies. Besides the spoligotype (binary, octal, hexadecimal, SB number), it reports the species from regions of difference, the lineage (Coll et al. 2014 barcode), the livestock lineages (Zwyer et al. 2021) and the lineage 1 sublineages (Netikul et al. 2022). Outputs: a table, JSON, a PDF report and a MultiQC custom content file.
nf-core test data has no M. tuberculosis complex genome, so the tests check that the module runs on the SARS-CoV-2 genome and reads and writes its outputs ("MTBC not detected" is the expected result for these data).
topic: versions- See version_topicslabelnf-core modules test spoligotyper --profile dockernf-core modules test spoligotyper --profile singularity(no Singularity on my machine, and the depot image is not mirrored yet)nf-core modules test spoligotyper --profile condanf-core modules lint spoligotyper: 61 tests passed, 0 warnings, 0 failed.🤖 Generated with Claude Code