diff --git a/modules/nf-core/autocycler/cluster/environment.yml b/modules/nf-core/autocycler/cluster/environment.yml new file mode 100644 index 00000000000..4acd4e2ab28 --- /dev/null +++ b/modules/nf-core/autocycler/cluster/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::autocycler=0.5.2" diff --git a/modules/nf-core/autocycler/cluster/main.nf b/modules/nf-core/autocycler/cluster/main.nf new file mode 100644 index 00000000000..7ed022d770b --- /dev/null +++ b/modules/nf-core/autocycler/cluster/main.nf @@ -0,0 +1,51 @@ +process AUTOCYCLER_CLUSTER { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/autocycler:0.5.2--h3ab6199_0': + 'biocontainers/autocycler:0.5.2--h3ab6199_0' }" + + input: + tuple val(meta), path(gfa) + + output: + tuple val(meta), path("clustering/qc_pass/*/*.gfa"), emit: clusters + tuple val(meta), path("clustering/qc_pass/*/*.yaml"), emit: clusterstats + tuple val(meta), path("clustering/*.newick"), emit: newick + tuple val(meta), path("clustering/*.tsv"), emit: tsv + tuple val(meta), path("clustering/*.phylip"), emit: pairwisedistances + tuple val(meta), path("clustering/*.yaml"), emit: stats + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + """ + autocycler cluster \\ + $args \\ + -a . + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + autocycler: \$(autocycler --version | sed 's/^[^ ]* //') + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + """ + mkdir clustering/qc_pass/cluster_000 -p + touch clustering/clustering.{newick,yaml,tsv} + touch clustering/pairwise_distances.phylip + touch clustering/qc_pass/cluster_000/0_untrimmed.{gfa,yaml} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + autocycler: \$(autocycler --version | sed 's/^[^ ]* //') + END_VERSIONS + """ +} diff --git a/modules/nf-core/autocycler/cluster/meta.yml b/modules/nf-core/autocycler/cluster/meta.yml new file mode 100644 index 00000000000..83b5de55829 --- /dev/null +++ b/modules/nf-core/autocycler/cluster/meta.yml @@ -0,0 +1,109 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "autocycler_cluster" +description: Cluster replicons in compressed assemblies with Autocycler. +keywords: + - autocycler + - genome-assembly + - clustering + - long-read +tools: + - autocycler: + description: "A tools for generating consensus long-read assemblies for bacterial genomes." + homepage: "https://github.com/rrwick/Autocycler/wiki" + documentation: "https://github.com/rrwick/Autocycler/wiki" + tool_dev_url: "https://github.com/rrwick/Autocycler" + doi: "10.1093/bioinformatics/btaf474" + licence: ["GPL-3.0"] + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - gfa: + type: file + description: | + Assembly graph files produced by the compression step. + pattern: "*/*.gfa" + +output: + clusters: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "clustering/qc_pass/*/*.gfa": + type: file + description: Aassembly graphs of clustered contigs. + pattern: "clustering/qc_pass/*/*.gfa" + ontologies: + - edam: "http://edamontology.org/format_3975" #GFA1 + clusterstats: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "clustering/qc_pass/*/*.yaml": + type: file + description: Per-cluster metrics reported by Autocycler. + pattern: "clustering/qc_pass/*/*.yaml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + newick: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "clustering/*.newick": + type: file + description: Newick tree relating contigs. + pattern: "clustering/*.newick" + tsv: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "clustering/*.tsv": + type: file + description: Tabular summary of cluster relationships. + pattern: "clustering/*.tsv" + pairwisedistances: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "clustering/*.phylip": + type: file + description: Pairwise distance matrix in PHYLIP format. + pattern: "clustering/*.phylip" + stats: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "clustering/*.yaml": + type: file + description: Run-level statistics for the clustering step. + pattern: "clustering/*.yaml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + versions: + - "versions.yml": + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + +authors: + - "@dwells-eit" +maintainers: + - "@dwells-eit" diff --git a/modules/nf-core/autocycler/cluster/tests/main.nf.test b/modules/nf-core/autocycler/cluster/tests/main.nf.test new file mode 100644 index 00000000000..792b02691f3 --- /dev/null +++ b/modules/nf-core/autocycler/cluster/tests/main.nf.test @@ -0,0 +1,73 @@ +nextflow_process { + + name "Test Process AUTOCYCLER_CLUSTER" + script "../main.nf" + process "AUTOCYCLER_CLUSTER" + + tag "modules" + tag "modules_nfcore" + tag "autocycler" + tag "autocycler/compress" + tag "autocycler/cluster" + + test("sarscov2 - assembly - fasta") { + + setup { + run("AUTOCYCLER_COMPRESS") { + script "../../compress/main.nf" + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/contigs.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/scaffolds.fasta', checkIfExists: true), + ] // assemblies + ] + """ + } + } + } + + when { + process { + """ + input[0] = AUTOCYCLER_COMPRESS.out.gfa + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - assembly - fasta - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/autocycler/cluster/tests/main.nf.test.snap b/modules/nf-core/autocycler/cluster/tests/main.nf.test.snap new file mode 100644 index 00000000000..a9fbc342d4e --- /dev/null +++ b/modules/nf-core/autocycler/cluster/tests/main.nf.test.snap @@ -0,0 +1,276 @@ +{ + "sarscov2 - assembly - fasta - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "0_untrimmed.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "0_untrimmed.yaml:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "clustering.newick:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "clustering.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "pairwise_distances.phylip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "clustering.yaml:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "6": [ + "versions.yml:md5,6c0bd1b1b590f56dd7fa72cc206acfe3" + ], + "clusters": [ + [ + { + "id": "test", + "single_end": false + }, + "0_untrimmed.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "clusterstats": [ + [ + { + "id": "test", + "single_end": false + }, + "0_untrimmed.yaml:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "newick": [ + [ + { + "id": "test", + "single_end": false + }, + "clustering.newick:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "pairwisedistances": [ + [ + { + "id": "test", + "single_end": false + }, + "pairwise_distances.phylip:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "clustering.yaml:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tsv": [ + [ + { + "id": "test", + "single_end": false + }, + "clustering.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,6c0bd1b1b590f56dd7fa72cc206acfe3" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-10-28T10:44:36.312554184" + }, + "sarscov2 - assembly - fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "1_untrimmed.gfa:md5,73912628f3a2c2d066bc36d14c7229b9", + "1_untrimmed.gfa:md5,719a197598d0f1499dccbbfe77ece24f", + "1_untrimmed.gfa:md5,8313fd7f1ab97e957ed1ee4bb20b655d", + "1_untrimmed.gfa:md5,6296117f3fca264d84ada14f778a23a6", + "1_untrimmed.gfa:md5,224d8fe4f6350f9e3c5b69c5078e3059" + ] + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "1_untrimmed.yaml:md5,6ac8ce32b804e839499e95279f3945db", + "1_untrimmed.yaml:md5,44c31adc6f2f2bae83bb3f90d5fe4ab1", + "1_untrimmed.yaml:md5,1b7a0a5583d9ba65a87546d11019213b", + "1_untrimmed.yaml:md5,2a1657662c94f7fa22f8c3eac7cd0e42", + "1_untrimmed.yaml:md5,2ee32f3c9b1bd21d702665f50c86a005" + ] + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "clustering.newick:md5,c0a4ebfeba0c1bb289be9267933a0f37" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "clustering.tsv:md5,30f7a64acefcc55a1863ff306a2901ac" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "pairwise_distances.phylip:md5,7e266e6d2b0834c802de7909521e197e" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "clustering.yaml:md5,1e48271631555f4f7a989620d0d4db8c" + ] + ], + "6": [ + "versions.yml:md5,6c0bd1b1b590f56dd7fa72cc206acfe3" + ], + "clusters": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "1_untrimmed.gfa:md5,73912628f3a2c2d066bc36d14c7229b9", + "1_untrimmed.gfa:md5,719a197598d0f1499dccbbfe77ece24f", + "1_untrimmed.gfa:md5,8313fd7f1ab97e957ed1ee4bb20b655d", + "1_untrimmed.gfa:md5,6296117f3fca264d84ada14f778a23a6", + "1_untrimmed.gfa:md5,224d8fe4f6350f9e3c5b69c5078e3059" + ] + ] + ], + "clusterstats": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "1_untrimmed.yaml:md5,6ac8ce32b804e839499e95279f3945db", + "1_untrimmed.yaml:md5,44c31adc6f2f2bae83bb3f90d5fe4ab1", + "1_untrimmed.yaml:md5,1b7a0a5583d9ba65a87546d11019213b", + "1_untrimmed.yaml:md5,2a1657662c94f7fa22f8c3eac7cd0e42", + "1_untrimmed.yaml:md5,2ee32f3c9b1bd21d702665f50c86a005" + ] + ] + ], + "newick": [ + [ + { + "id": "test", + "single_end": false + }, + "clustering.newick:md5,c0a4ebfeba0c1bb289be9267933a0f37" + ] + ], + "pairwisedistances": [ + [ + { + "id": "test", + "single_end": false + }, + "pairwise_distances.phylip:md5,7e266e6d2b0834c802de7909521e197e" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "clustering.yaml:md5,1e48271631555f4f7a989620d0d4db8c" + ] + ], + "tsv": [ + [ + { + "id": "test", + "single_end": false + }, + "clustering.tsv:md5,30f7a64acefcc55a1863ff306a2901ac" + ] + ], + "versions": [ + "versions.yml:md5,6c0bd1b1b590f56dd7fa72cc206acfe3" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-10-28T10:43:46.382913621" + } +} \ No newline at end of file diff --git a/modules/nf-core/autocycler/combine/environment.yml b/modules/nf-core/autocycler/combine/environment.yml new file mode 100644 index 00000000000..4acd4e2ab28 --- /dev/null +++ b/modules/nf-core/autocycler/combine/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::autocycler=0.5.2" diff --git a/modules/nf-core/autocycler/combine/main.nf b/modules/nf-core/autocycler/combine/main.nf new file mode 100644 index 00000000000..80db2762112 --- /dev/null +++ b/modules/nf-core/autocycler/combine/main.nf @@ -0,0 +1,49 @@ +process AUTOCYCLER_COMBINE { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/autocycler:0.5.2--h3ab6199_0': + 'biocontainers/autocycler:0.5.2--h3ab6199_0' }" + + input: + tuple val(meta), path(clusters) + + output: + tuple val(meta), path("$prefix/consensus_assembly.fasta"), emit: fasta + tuple val(meta), path("$prefix/consensus_assembly.gfa"), emit: gfa + tuple val(meta), path("$prefix/consensus_assembly.yaml"), emit: stats + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + autocycler combine \\ + $args \\ + -i $clusters \\ + -a $prefix + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + autocycler: \$(autocycler --version | sed 's/^[^ ]* //') + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + mkdir $prefix + touch $prefix/consensus_assembly.{fasta,gfa,yaml} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + autocycler: \$(autocycler --version | sed 's/^[^ ]* //') + END_VERSIONS + """ +} diff --git a/modules/nf-core/autocycler/combine/meta.yml b/modules/nf-core/autocycler/combine/meta.yml new file mode 100644 index 00000000000..a79282a733c --- /dev/null +++ b/modules/nf-core/autocycler/combine/meta.yml @@ -0,0 +1,79 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "autocycler_combine" +description: Merge resolved cluster assemblies into final consensus outputs with Autocycler. +keywords: + - autocycler + - genome-assembly + - consensus + - long-read +tools: + - autocycler: + description: "A tools for generating consensus long-read assemblies for bacterial genomes." + homepage: "https://github.com/rrwick/Autocycler/wiki" + documentation: "https://github.com/rrwick/Autocycler/wiki" + tool_dev_url: "https://github.com/rrwick/Autocycler" + doi: "10.1093/bioinformatics/btaf474" + licence: ["GPL-3.0"] + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - clusters: + type: file + description: | + Final cluster assembly graphs (GFA) to be combined into consensus sequences. + pattern: "*.gfa" + +output: + fasta: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "$prefix/consensus_assembly.fasta": + type: file + description: Consensus genome sequence generated by Autocycler. + pattern: "*/consensus_assembly.fasta" + ontologies: + - edam: "http://edamontology.org/format_1929" # FASTA + gfa: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "$prefix/consensus_assembly.gfa": + type: file + description: Consensus assembly graph generated by Autocycler. + pattern: "$prefix/consensus_assembly.gfa" + ontologies: + - edam: "http://edamontology.org/format_3975" #GFA1 + stats: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "$prefix/consensus_assembly.yaml": + type: file + description: Run statistics for the combine step. + pattern: "$prefix/consensus_assembly.yaml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + versions: + - "versions.yml": + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + +authors: + - "@dwells-eit" +maintainers: + - "@dwells-eit" diff --git a/modules/nf-core/autocycler/combine/tests/main.nf.test b/modules/nf-core/autocycler/combine/tests/main.nf.test new file mode 100644 index 00000000000..86049595c46 --- /dev/null +++ b/modules/nf-core/autocycler/combine/tests/main.nf.test @@ -0,0 +1,110 @@ +nextflow_process { + + name "Test Process AUTOCYCLER_COMBINE" + script "../main.nf" + process "AUTOCYCLER_COMBINE" + + tag "modules" + tag "modules_nfcore" + tag "autocycler" + tag "autocycler/compress" + tag "autocycler/cluster" + tag "autocycler/trim" + tag "autocycler/resolve" + tag "autocycler/combine" + + test("sarscov2 - assemblies -fasta") { + + setup { + run("AUTOCYCLER_COMPRESS") { + script "../../compress/main.nf" + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/contigs.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/scaffolds.fasta', checkIfExists: true), + ] // assemblies + ] + """ + } + } + run("AUTOCYCLER_CLUSTER") { + script "../../cluster/main.nf" + process { + """ + input[0] = AUTOCYCLER_COMPRESS.out.gfa + """ + } + } + run("AUTOCYCLER_TRIM") { + script "../../trim/main.nf" + process { + """ + AUTOCYCLER_CLUSTER.out.clusters + .flatMap { meta, gfa_list -> + gfa_list.collect { gfa -> [meta, gfa] } // Separate gfas, each with a meta + } + .map { meta, file -> + def cluster_id = (file.parent.name) // Add cluster id to meta + tuple( meta + [cluster: cluster_id], file ) + } + .set{ ch_clusters } // channel: [ val(meta), gfa] + + input[0] = ch_clusters + """ + } + } + run("AUTOCYCLER_RESOLVE"){ + script "../../resolve/main.nf" + process { + """ + input[0] = AUTOCYCLER_TRIM.out.gfa + """ + } + + } + } + + when { + process { + """ + input[0] = AUTOCYCLER_RESOLVE.out.resolved + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - assemblies -fasta - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } +} diff --git a/modules/nf-core/autocycler/combine/tests/main.nf.test.snap b/modules/nf-core/autocycler/combine/tests/main.nf.test.snap new file mode 100644 index 00000000000..df12371f028 --- /dev/null +++ b/modules/nf-core/autocycler/combine/tests/main.nf.test.snap @@ -0,0 +1,350 @@ +{ + "sarscov2 - assemblies -fasta - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "consensus_assembly.fasta:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "consensus_assembly.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "consensus_assembly.yaml:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,cd4c6e07ce524c5c2296afff8a45fecb" + ], + "fasta": [ + [ + { + "id": "test", + "single_end": false + }, + "consensus_assembly.fasta:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "gfa": [ + [ + { + "id": "test", + "single_end": false + }, + "consensus_assembly.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "consensus_assembly.yaml:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,cd4c6e07ce524c5c2296afff8a45fecb" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-10-28T11:15:12.388399773" + }, + "sarscov2 - assemblies -fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "consensus_assembly.fasta:md5,942e9dd63658ae5ee987c3865f64ef97" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "consensus_assembly.fasta:md5,3b5f0c0e1e480de5682e5956b40013ee" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "consensus_assembly.fasta:md5,6f06846e831457b1763b0e457b8c101e" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "consensus_assembly.fasta:md5,a161425fe8e139d75ae54fdd04e56545" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "consensus_assembly.fasta:md5,8b8d300eb4be010bd97e4a1aebbd61d4" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "consensus_assembly.gfa:md5,c69dd262070f9c81a87034f3aaf9888f" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "consensus_assembly.gfa:md5,6428e5cb960883dcdc4898fa0e972591" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "consensus_assembly.gfa:md5,30aaa1f58f19ccbf959ac8fa55a78f99" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "consensus_assembly.gfa:md5,4b946f7cc4d7055fb61bee1925be2bb0" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "consensus_assembly.gfa:md5,7b2b22be5424893816a4c12f6bc9e1f2" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "consensus_assembly.yaml:md5,20dfc59b6e81c68d1b74073032cc0d4d" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "consensus_assembly.yaml:md5,9c2e31d0d42dc7fe715482a19a5768c2" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "consensus_assembly.yaml:md5,d19724fae1e2b9d0695ec93d25f080bb" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "consensus_assembly.yaml:md5,d9fcba2ec57942a133c527ae13fc72e6" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "consensus_assembly.yaml:md5,a935e95b6c41fcee0858902d797e5613" + ] + ], + "3": [ + "versions.yml:md5,cd4c6e07ce524c5c2296afff8a45fecb", + "versions.yml:md5,cd4c6e07ce524c5c2296afff8a45fecb", + "versions.yml:md5,cd4c6e07ce524c5c2296afff8a45fecb", + "versions.yml:md5,cd4c6e07ce524c5c2296afff8a45fecb", + "versions.yml:md5,cd4c6e07ce524c5c2296afff8a45fecb" + ], + "fasta": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "consensus_assembly.fasta:md5,942e9dd63658ae5ee987c3865f64ef97" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "consensus_assembly.fasta:md5,3b5f0c0e1e480de5682e5956b40013ee" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "consensus_assembly.fasta:md5,6f06846e831457b1763b0e457b8c101e" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "consensus_assembly.fasta:md5,a161425fe8e139d75ae54fdd04e56545" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "consensus_assembly.fasta:md5,8b8d300eb4be010bd97e4a1aebbd61d4" + ] + ], + "gfa": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "consensus_assembly.gfa:md5,c69dd262070f9c81a87034f3aaf9888f" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "consensus_assembly.gfa:md5,6428e5cb960883dcdc4898fa0e972591" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "consensus_assembly.gfa:md5,30aaa1f58f19ccbf959ac8fa55a78f99" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "consensus_assembly.gfa:md5,4b946f7cc4d7055fb61bee1925be2bb0" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "consensus_assembly.gfa:md5,7b2b22be5424893816a4c12f6bc9e1f2" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "consensus_assembly.yaml:md5,20dfc59b6e81c68d1b74073032cc0d4d" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "consensus_assembly.yaml:md5,9c2e31d0d42dc7fe715482a19a5768c2" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "consensus_assembly.yaml:md5,d19724fae1e2b9d0695ec93d25f080bb" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "consensus_assembly.yaml:md5,d9fcba2ec57942a133c527ae13fc72e6" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "consensus_assembly.yaml:md5,a935e95b6c41fcee0858902d797e5613" + ] + ], + "versions": [ + "versions.yml:md5,cd4c6e07ce524c5c2296afff8a45fecb", + "versions.yml:md5,cd4c6e07ce524c5c2296afff8a45fecb", + "versions.yml:md5,cd4c6e07ce524c5c2296afff8a45fecb", + "versions.yml:md5,cd4c6e07ce524c5c2296afff8a45fecb", + "versions.yml:md5,cd4c6e07ce524c5c2296afff8a45fecb" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-10-28T11:15:36.324875025" + } +} \ No newline at end of file diff --git a/modules/nf-core/autocycler/compress/environment.yml b/modules/nf-core/autocycler/compress/environment.yml new file mode 100644 index 00000000000..4acd4e2ab28 --- /dev/null +++ b/modules/nf-core/autocycler/compress/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::autocycler=0.5.2" diff --git a/modules/nf-core/autocycler/compress/main.nf b/modules/nf-core/autocycler/compress/main.nf new file mode 100644 index 00000000000..29ee404f453 --- /dev/null +++ b/modules/nf-core/autocycler/compress/main.nf @@ -0,0 +1,51 @@ + +process AUTOCYCLER_COMPRESS { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/autocycler:0.5.2--h3ab6199_0': + 'biocontainers/autocycler:0.5.2--h3ab6199_0' }" + + input: + tuple val(meta), path(assemblies) + + output: + tuple val(meta), path("$prefix/*.gfa"), emit: gfa + tuple val(meta), path("$prefix/*.yaml"), emit: stats + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + autocycler compress \\ + $args \\ + -t $task.cpus \\ + -i . \\ + -a ${prefix} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + autocycler: \$(autocycler --version | sed 's/^[^ ]* //') + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + mkdir $prefix + touch ${prefix}/input_assemblies.gfa + touch ${prefix}/input_assemblies.yaml + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + autocycler: \$(autocycler --version | sed 's/^[^ ]* //') + END_VERSIONS + """ +} diff --git a/modules/nf-core/autocycler/compress/meta.yml b/modules/nf-core/autocycler/compress/meta.yml new file mode 100644 index 00000000000..95d74317358 --- /dev/null +++ b/modules/nf-core/autocycler/compress/meta.yml @@ -0,0 +1,71 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "autocycler_compress" +description: Package candidate assemblies for clustering by Autocycler. +keywords: + - autocycler + - genome-assembly + - compression + - long-read +tools: + - autocycler: + description: "A tools for generating consensus long-read assemblies for bacterial genomes." + homepage: "https://github.com/rrwick/Autocycler/wiki" + documentation: "https://github.com/rrwick/Autocycler/wiki" + tool_dev_url: "https://github.com/rrwick/Autocycler" + doi: "10.1093/bioinformatics/btaf474" + licence: ["GPL-3.0"] + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - assemblies: + type: file + description: | + Candidate assembly files (typically FASTA) generated for the sample. + pattern: "*.{fasta,fa,fasta.gz,fa.gz}" + ontologies: + - edam: "http://edamontology.org/format_1929" # FASTA + - edam: "http://edamontology.org/format_3989" # GZIP + +output: + gfa: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "$prefix/*.gfa": + type: file + description: Assembly graph files ready for clustering. + pattern: "$prefix/*.gfa" + ontologies: + - edam: "http://edamontology.org/format_3975" #GFA1 + + stats: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "$prefix/*.yaml": + type: file + description: Summary statistics generated during compression. + pattern: "*/*.yaml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + versions: + - "versions.yml": + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + +authors: + - "@dwells-eit" +maintainers: + - "@dwells-eit" diff --git a/modules/nf-core/autocycler/compress/tests/main.nf.test b/modules/nf-core/autocycler/compress/tests/main.nf.test new file mode 100644 index 00000000000..a11e1d0b7f1 --- /dev/null +++ b/modules/nf-core/autocycler/compress/tests/main.nf.test @@ -0,0 +1,64 @@ +nextflow_process { + + name "Test Process AUTOCYCLER_COMPRESS" + script "../main.nf" + process "AUTOCYCLER_COMPRESS" + + tag "modules" + tag "modules_nfcore" + tag "autocycler" + tag "autocycler/compress" + + test("sarscov2 - fasta") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/contigs.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/scaffolds.fasta', checkIfExists: true), + ] // assemblies + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - fasta - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/contigs.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/scaffolds.fasta', checkIfExists: true), + ] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/autocycler/compress/tests/main.nf.test.snap b/modules/nf-core/autocycler/compress/tests/main.nf.test.snap new file mode 100644 index 00000000000..1a5181e41cd --- /dev/null +++ b/modules/nf-core/autocycler/compress/tests/main.nf.test.snap @@ -0,0 +1,108 @@ +{ + "sarscov2 - fasta - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "input_assemblies.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "input_assemblies.yaml:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,842cd4fed38c11bfb1130da4de2ade14" + ], + "gfa": [ + [ + { + "id": "test", + "single_end": false + }, + "input_assemblies.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "input_assemblies.yaml:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,842cd4fed38c11bfb1130da4de2ade14" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-10-28T09:03:44.162388971" + }, + "sarscov2 - fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "input_assemblies.gfa:md5,e4918bf93dc58755971bec2baf0897e6" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "input_assemblies.yaml:md5,2d4d10d343d16ef57c9dceb12d8c6e1c" + ] + ], + "2": [ + "versions.yml:md5,842cd4fed38c11bfb1130da4de2ade14" + ], + "gfa": [ + [ + { + "id": "test", + "single_end": false + }, + "input_assemblies.gfa:md5,e4918bf93dc58755971bec2baf0897e6" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "input_assemblies.yaml:md5,2d4d10d343d16ef57c9dceb12d8c6e1c" + ] + ], + "versions": [ + "versions.yml:md5,842cd4fed38c11bfb1130da4de2ade14" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-10-28T09:02:09.484596514" + } +} \ No newline at end of file diff --git a/modules/nf-core/autocycler/resolve/environment.yml b/modules/nf-core/autocycler/resolve/environment.yml new file mode 100644 index 00000000000..4acd4e2ab28 --- /dev/null +++ b/modules/nf-core/autocycler/resolve/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::autocycler=0.5.2" diff --git a/modules/nf-core/autocycler/resolve/main.nf b/modules/nf-core/autocycler/resolve/main.nf new file mode 100644 index 00000000000..409aa9f0d4c --- /dev/null +++ b/modules/nf-core/autocycler/resolve/main.nf @@ -0,0 +1,47 @@ +process AUTOCYCLER_RESOLVE { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/autocycler:0.5.2--h3ab6199_0': + 'biocontainers/autocycler:0.5.2--h3ab6199_0' }" + + input: + tuple val(meta), path(gfa) + + output: + tuple val(meta), path("3_bridged.gfa"), emit: bridged + tuple val(meta), path("4_merged.gfa"), emit: merged + tuple val(meta), path("5_final.gfa"), emit: resolved + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + """ + autocycler resolve \\ + $args \\ + -c . + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + autocycler: \$(autocycler --version | sed 's/^[^ ]* //') + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + """ + touch 3_bridged.gfa + touch 4_merged.gfa + touch 5_final.gfa + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + autocycler: \$(autocycler --version | sed 's/^[^ ]* //') + END_VERSIONS + """ +} diff --git a/modules/nf-core/autocycler/resolve/meta.yml b/modules/nf-core/autocycler/resolve/meta.yml new file mode 100644 index 00000000000..5dd628b1e16 --- /dev/null +++ b/modules/nf-core/autocycler/resolve/meta.yml @@ -0,0 +1,79 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "autocycler_resolve" +description: Resolve trimmed assembly graphs into final contigs within Autocycler. +keywords: + - autocycler + - genome-assembly + - graph-resolution + - long-read +tools: + - autocycler: + description: "A tools for generating consensus long-read assemblies for bacterial genomes." + homepage: "https://github.com/rrwick/Autocycler/wiki" + documentation: "https://github.com/rrwick/Autocycler/wiki" + tool_dev_url: "https://github.com/rrwick/Autocycler" + doi: "10.1093/bioinformatics/btaf474" + licence: ["GPL-3.0"] + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - gfa: + type: file + description: | + Trimmed assembly graph in GFA format from the previous step. + pattern: "*.gfa" + +output: + bridged: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "3_bridged.gfa": + type: file + description: Assembly graph with bridges resolved. + pattern: "3_bridged.gfa" + ontologies: + - edam: "http://edamontology.org/format_3975" #GFA1 + merged: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "4_merged.gfa": + type: file + description: Merged assembly graph after bridging. + pattern: "4_merged.gfa" + ontologies: + - edam: "http://edamontology.org/format_3975" #GFA1 + resolved: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "5_final.gfa": + type: file + description: Final resolved assembly graph. + pattern: "5_final.gfa" + ontologies: + - edam: "http://edamontology.org/format_3975" #GFA1 + versions: + - "versions.yml": + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + +authors: + - "@dwells-eit" +maintainers: + - "@dwells-eit" diff --git a/modules/nf-core/autocycler/resolve/tests/main.nf.test b/modules/nf-core/autocycler/resolve/tests/main.nf.test new file mode 100644 index 00000000000..130f4f2912b --- /dev/null +++ b/modules/nf-core/autocycler/resolve/tests/main.nf.test @@ -0,0 +1,101 @@ +nextflow_process { + + name "Test Process AUTOCYCLER_RESOLVE" + script "../main.nf" + process "AUTOCYCLER_RESOLVE" + + tag "modules" + tag "modules_nfcore" + tag "autocycler" + tag "autocycler/compress" + tag "autocycler/cluster" + tag "autocycler/trim" + tag "autocycler/resolve" + + test("sarscov2 - assemblies - fasta") { + + setup { + run("AUTOCYCLER_COMPRESS") { + script "../../compress/main.nf" + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/contigs.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/scaffolds.fasta', checkIfExists: true), + ] // assemblies + ] + """ + } + } + run("AUTOCYCLER_CLUSTER") { + script "../../cluster/main.nf" + process { + """ + input[0] = AUTOCYCLER_COMPRESS.out.gfa + """ + } + } + run("AUTOCYCLER_TRIM") { + script "../../trim/main.nf" + process { + """ + AUTOCYCLER_CLUSTER.out.clusters + .flatMap { meta, gfa_list -> + gfa_list.collect { gfa -> [meta, gfa] } // Separate gfas, each with a meta + } + .map { meta, file -> + def cluster_id = (file.parent.name) // Add cluster id to meta + tuple( meta + [cluster: cluster_id], file ) + } + .set{ ch_clusters } // channel: [ val(meta), gfa] + + input[0] = ch_clusters + """ + } + } + } + + when { + process { + """ + input[0] = AUTOCYCLER_TRIM.out.gfa + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - assemblies -fasta - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/autocycler/resolve/tests/main.nf.test.snap b/modules/nf-core/autocycler/resolve/tests/main.nf.test.snap new file mode 100644 index 00000000000..c58dc4c13c6 --- /dev/null +++ b/modules/nf-core/autocycler/resolve/tests/main.nf.test.snap @@ -0,0 +1,350 @@ +{ + "sarscov2 - assemblies - fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "3_bridged.gfa:md5,32ab6dfb62c3e0a89e87827d3b216b11" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "3_bridged.gfa:md5,f8ddaec9123e475eab872cfe35767571" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "3_bridged.gfa:md5,f1d19e1dc4d76283358c880d44714bc2" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "3_bridged.gfa:md5,0886b8a7eb8e86875c43f116cd756d7c" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "3_bridged.gfa:md5,f919ba084f3e6e05481843b7acc7470b" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "4_merged.gfa:md5,32ab6dfb62c3e0a89e87827d3b216b11" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "4_merged.gfa:md5,f8ddaec9123e475eab872cfe35767571" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "4_merged.gfa:md5,f1d19e1dc4d76283358c880d44714bc2" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "4_merged.gfa:md5,0886b8a7eb8e86875c43f116cd756d7c" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "4_merged.gfa:md5,f919ba084f3e6e05481843b7acc7470b" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "5_final.gfa:md5,32ab6dfb62c3e0a89e87827d3b216b11" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "5_final.gfa:md5,f8ddaec9123e475eab872cfe35767571" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "5_final.gfa:md5,f1d19e1dc4d76283358c880d44714bc2" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "5_final.gfa:md5,0886b8a7eb8e86875c43f116cd756d7c" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "5_final.gfa:md5,f919ba084f3e6e05481843b7acc7470b" + ] + ], + "3": [ + "versions.yml:md5,79bc18dd056bcbf7f1d6315822b6394e", + "versions.yml:md5,79bc18dd056bcbf7f1d6315822b6394e", + "versions.yml:md5,79bc18dd056bcbf7f1d6315822b6394e", + "versions.yml:md5,79bc18dd056bcbf7f1d6315822b6394e", + "versions.yml:md5,79bc18dd056bcbf7f1d6315822b6394e" + ], + "bridged": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "3_bridged.gfa:md5,32ab6dfb62c3e0a89e87827d3b216b11" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "3_bridged.gfa:md5,f8ddaec9123e475eab872cfe35767571" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "3_bridged.gfa:md5,f1d19e1dc4d76283358c880d44714bc2" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "3_bridged.gfa:md5,0886b8a7eb8e86875c43f116cd756d7c" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "3_bridged.gfa:md5,f919ba084f3e6e05481843b7acc7470b" + ] + ], + "merged": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "4_merged.gfa:md5,32ab6dfb62c3e0a89e87827d3b216b11" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "4_merged.gfa:md5,f8ddaec9123e475eab872cfe35767571" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "4_merged.gfa:md5,f1d19e1dc4d76283358c880d44714bc2" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "4_merged.gfa:md5,0886b8a7eb8e86875c43f116cd756d7c" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "4_merged.gfa:md5,f919ba084f3e6e05481843b7acc7470b" + ] + ], + "resolved": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "5_final.gfa:md5,32ab6dfb62c3e0a89e87827d3b216b11" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "5_final.gfa:md5,f8ddaec9123e475eab872cfe35767571" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "5_final.gfa:md5,f1d19e1dc4d76283358c880d44714bc2" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "5_final.gfa:md5,0886b8a7eb8e86875c43f116cd756d7c" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "5_final.gfa:md5,f919ba084f3e6e05481843b7acc7470b" + ] + ], + "versions": [ + "versions.yml:md5,79bc18dd056bcbf7f1d6315822b6394e", + "versions.yml:md5,79bc18dd056bcbf7f1d6315822b6394e", + "versions.yml:md5,79bc18dd056bcbf7f1d6315822b6394e", + "versions.yml:md5,79bc18dd056bcbf7f1d6315822b6394e", + "versions.yml:md5,79bc18dd056bcbf7f1d6315822b6394e" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-10-28T11:05:51.541318237" + }, + "sarscov2 - assemblies -fasta - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "3_bridged.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "4_merged.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "5_final.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,79bc18dd056bcbf7f1d6315822b6394e" + ], + "bridged": [ + [ + { + "id": "test", + "single_end": false + }, + "3_bridged.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "merged": [ + [ + { + "id": "test", + "single_end": false + }, + "4_merged.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "resolved": [ + [ + { + "id": "test", + "single_end": false + }, + "5_final.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,79bc18dd056bcbf7f1d6315822b6394e" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-10-28T11:05:27.313463504" + } +} \ No newline at end of file diff --git a/modules/nf-core/autocycler/subsample/environment.yml b/modules/nf-core/autocycler/subsample/environment.yml new file mode 100644 index 00000000000..4acd4e2ab28 --- /dev/null +++ b/modules/nf-core/autocycler/subsample/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::autocycler=0.5.2" diff --git a/modules/nf-core/autocycler/subsample/main.nf b/modules/nf-core/autocycler/subsample/main.nf new file mode 100644 index 00000000000..65a4d1f2196 --- /dev/null +++ b/modules/nf-core/autocycler/subsample/main.nf @@ -0,0 +1,55 @@ + +process AUTOCYCLER_SUBSAMPLE { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/autocycler:0.5.2--h3ab6199_0': + 'biocontainers/autocycler:0.5.2--h3ab6199_0' }" + + input: + tuple val(meta), path(reads) + val genome_size + + output: + tuple val(meta), path("$prefix/*.fastq.gz"), emit: subsampled_reads + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + // fix random seed for reproducibility if not specified in command line + if (!(args ==~ /.*--seed.*/)) {args += " --seed 42"} + """ + autocycler subsample \\ + $args \\ + --reads $reads \\ + --out_dir ${prefix} \\ + --genome_size $genome_size + + gzip $prefix/*.fastq + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + autocycler: \$(autocycler --version | sed 's/^[^ ]* //') + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + + mkdir $prefix + echo | gzip > ${prefix}/sample_00.fastq.gz + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + autocycler: \$(autocycler --version | sed 's/^[^ ]* //') + END_VERSIONS + """ +} diff --git a/modules/nf-core/autocycler/subsample/meta.yml b/modules/nf-core/autocycler/subsample/meta.yml new file mode 100644 index 00000000000..17e972ff4e5 --- /dev/null +++ b/modules/nf-core/autocycler/subsample/meta.yml @@ -0,0 +1,60 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "autocycler_subsample" +description: Downsample long-read sequencing data to the requested coverage using Autocycler. +keywords: + - autocycler + - subsampling + - long-read +tools: + - autocycler: + description: "A tools for generating consensus long-read assemblies for bacterial genomes." + homepage: "https://github.com/rrwick/Autocycler/wiki" + documentation: "https://github.com/rrwick/Autocycler/wiki" + tool_dev_url: "https://github.com/rrwick/Autocycler" + doi: "10.1093/bioinformatics/btaf474" + licence: ["GPL-3.0"] + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - reads: + type: file + description: | + Long-read sequencing reads for the sample in FASTQ format (compressed or uncompressed). + pattern: "*.{fastq,fastq.gz,fq,fq.gz}" + ontologies: + - edam: "http://edamontology.org/format_1930" # FASTQ + - genome_size: + type: integer + description: Expected genome size in bases used to calculate the target sequencing depth. + +output: + subsampled_reads: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "$prefix/*.fastq.gz": + type: file + description: Subsampled reads produced by Autocycler. + pattern: "*/*.fastq.gz" + ontologies: + - edam: "http://edamontology.org/format_1930" # FASTQ + - edam: "http://edamontology.org/format_3989" # GZIP + versions: + - "versions.yml": + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + +authors: + - "@dwells" +maintainers: + - "@dwells" diff --git a/modules/nf-core/autocycler/subsample/tests/main.nf.test b/modules/nf-core/autocycler/subsample/tests/main.nf.test new file mode 100644 index 00000000000..c49afba8285 --- /dev/null +++ b/modules/nf-core/autocycler/subsample/tests/main.nf.test @@ -0,0 +1,60 @@ +nextflow_process { + + name "Test Process AUTOCYCLER_SUBSAMPLE" + script "../main.nf" + process "AUTOCYCLER_SUBSAMPLE" + + tag "modules" + tag "modules_nfcore" + tag "autocycler" + tag "autocycler/subsample" + + test("Pseudomonas_fluorescens - fastq_gz") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists: true), // reads + ] + input[1] = 300 // set genome size very small to get sufficient depth + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("Pseudomonas_fluorescens - fastq_gz - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + 'genomics/sarscov2/nanopore/fastq/test.fastq.gz', checkIfExists: true), // reads + ] + input[1] = 30000 // genome size + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/autocycler/subsample/tests/main.nf.test.snap b/modules/nf-core/autocycler/subsample/tests/main.nf.test.snap new file mode 100644 index 00000000000..c0d75d98e41 --- /dev/null +++ b/modules/nf-core/autocycler/subsample/tests/main.nf.test.snap @@ -0,0 +1,82 @@ +{ + "Pseudomonas_fluorescens - fastq_gz": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "sample_01.fastq.gz:md5,7a9ac52d5071893300808fc11091bdbb", + "sample_02.fastq.gz:md5,e1e73dc1f31aa8b30834286d13ab500a", + "sample_03.fastq.gz:md5,e5cead9b5bbdf541062423065a5b6f51", + "sample_04.fastq.gz:md5,312cb2589411da99ecfd50392e999cdc" + ] + ] + ], + "1": [ + "versions.yml:md5,0abfe90f7bd1d54716b236993073b514" + ], + "subsampled_reads": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "sample_01.fastq.gz:md5,7a9ac52d5071893300808fc11091bdbb", + "sample_02.fastq.gz:md5,e1e73dc1f31aa8b30834286d13ab500a", + "sample_03.fastq.gz:md5,e5cead9b5bbdf541062423065a5b6f51", + "sample_04.fastq.gz:md5,312cb2589411da99ecfd50392e999cdc" + ] + ] + ], + "versions": [ + "versions.yml:md5,0abfe90f7bd1d54716b236993073b514" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-10-29T08:36:17.505206711" + }, + "Pseudomonas_fluorescens - fastq_gz - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "sample_00.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + "versions.yml:md5,0abfe90f7bd1d54716b236993073b514" + ], + "subsampled_reads": [ + [ + { + "id": "test", + "single_end": false + }, + "sample_00.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,0abfe90f7bd1d54716b236993073b514" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-10-29T08:07:36.406154106" + } +} \ No newline at end of file diff --git a/modules/nf-core/autocycler/subsample/tests/nextflow.config b/modules/nf-core/autocycler/subsample/tests/nextflow.config new file mode 100644 index 00000000000..a7aa8f2f803 --- /dev/null +++ b/modules/nf-core/autocycler/subsample/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'AUTOCYCLER_SUBSAMPLE' { + ext.args = params.module_args + } +} diff --git a/modules/nf-core/autocycler/trim/environment.yml b/modules/nf-core/autocycler/trim/environment.yml new file mode 100644 index 00000000000..4acd4e2ab28 --- /dev/null +++ b/modules/nf-core/autocycler/trim/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - "bioconda::autocycler=0.5.2" diff --git a/modules/nf-core/autocycler/trim/main.nf b/modules/nf-core/autocycler/trim/main.nf new file mode 100644 index 00000000000..4cca2a8dcc2 --- /dev/null +++ b/modules/nf-core/autocycler/trim/main.nf @@ -0,0 +1,47 @@ +process AUTOCYCLER_TRIM { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/autocycler:0.5.2--h3ab6199_0': + 'biocontainers/autocycler:0.5.2--h3ab6199_0' }" + + input: + tuple val(meta), path(gfa) + + output: + tuple val(meta), path("*.gfa"), emit: gfa + tuple val(meta), path("*.yaml"), emit: stats + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + """ + autocycler trim \\ + $args \\ + --threads $task.cpus \\ + -c . + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + autocycler: \$(autocycler --version | sed 's/^[^ ]* //') + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + """ + + touch 2_trimmed.gfa + touch 2_trimmed.yaml + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + autocycler: \$(autocycler --version | sed 's/^[^ ]* //') + END_VERSIONS + """ +} diff --git a/modules/nf-core/autocycler/trim/meta.yml b/modules/nf-core/autocycler/trim/meta.yml new file mode 100644 index 00000000000..e69f8b1efa5 --- /dev/null +++ b/modules/nf-core/autocycler/trim/meta.yml @@ -0,0 +1,67 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "autocycler_trim" +description: Trim cluster assembly graphs to remove unsupported segments prior to resolution. +keywords: + - autocycler + - genome-assembly + - graph-trimming + - long-read +tools: + - autocycler: + description: "A tools for generating consensus long-read assemblies for bacterial genomes." + homepage: "https://github.com/rrwick/Autocycler/wiki" + documentation: "https://github.com/rrwick/Autocycler/wiki" + tool_dev_url: "https://github.com/rrwick/Autocycler" + doi: "10.1093/bioinformatics/btaf474" + licence: ["GPL-3.0"] + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - gfa: + type: file + description: | + Cluster-specific assembly graph in GFA format. + pattern: "*.gfa" + +output: + gfa: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.gfa": + type: file + description: Trimmed assembly graphs emitted by Autocycler. + pattern: "*.gfa" + ontologies: + - edam: "http://edamontology.org/format_3975" #GFA1 + stats: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1' ]` + - "*.yaml": + type: file + description: Trimming statistics for each cluster. + pattern: "*.yaml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + versions: + - "versions.yml": + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: "http://edamontology.org/format_3750" # YAML + +authors: + - "@dwells-eit" +maintainers: + - "@dwells-eit" diff --git a/modules/nf-core/autocycler/trim/tests/main.nf.test b/modules/nf-core/autocycler/trim/tests/main.nf.test new file mode 100644 index 00000000000..693f04cf21f --- /dev/null +++ b/modules/nf-core/autocycler/trim/tests/main.nf.test @@ -0,0 +1,92 @@ +nextflow_process { + + name "Test Process AUTOCYCLER_TRIM" + script "../main.nf" + process "AUTOCYCLER_TRIM" + + tag "modules" + tag "modules_nfcore" + tag "autocycler" + tag "autocycler/compress" + tag "autocycler/cluster" + tag "autocycler/trim" + + test("sarscov2 - assemblies - fasta") { + + setup { + run("AUTOCYCLER_COMPRESS") { + script "../../compress/main.nf" + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [ + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/contigs.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fasta/scaffolds.fasta', checkIfExists: true), + ] // assemblies + ] + """ + } + } + run("AUTOCYCLER_CLUSTER") { + script "../../cluster/main.nf" + process { + """ + input[0] = AUTOCYCLER_COMPRESS.out.gfa + """ + } + } + } + + when { + process { + """ + AUTOCYCLER_CLUSTER.out.clusters + .flatMap { meta, gfa_list -> + gfa_list.collect { gfa -> [meta, gfa] } // Separate gfas, each with a meta + } + .map { meta, file -> + def cluster_id = (file.parent.name) // Add cluster id to meta + tuple( meta + [cluster: cluster_id], file ) + } + .set{ ch_clusters } // channel: [ val(meta), gfa] + + input[0] = ch_clusters + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + + test("sarscov2 - assemblies -fasta - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + + } + +} diff --git a/modules/nf-core/autocycler/trim/tests/main.nf.test.snap b/modules/nf-core/autocycler/trim/tests/main.nf.test.snap new file mode 100644 index 00000000000..9762d4262d1 --- /dev/null +++ b/modules/nf-core/autocycler/trim/tests/main.nf.test.snap @@ -0,0 +1,248 @@ +{ + "sarscov2 - assemblies - fasta": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "2_trimmed.gfa:md5,e4339397d2a188c90fc16a10aebba086" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "2_trimmed.gfa:md5,b754228734964e5c1a3f006da2de3c37" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "2_trimmed.gfa:md5,1bff9016ffb75edc4c73cdeedbc2b7c4" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "2_trimmed.gfa:md5,dbbb6784efded7f8cb436fb254c426fd" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "2_trimmed.gfa:md5,e08589f6402186b099efeb367add5a09" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "2_trimmed.yaml:md5,236a2cbde4b5c7a3423b65cab2d9204a" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "2_trimmed.yaml:md5,a3ce7e8c652fc91da69088cd776c94e6" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "2_trimmed.yaml:md5,bf72f5ecfed4757e2114665b3e2ff4e5" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "2_trimmed.yaml:md5,b8ca2603d9b0fbec9e0dd53c2d1003dd" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "2_trimmed.yaml:md5,de8ad13f8a9b4b911a08a53b9b88e4bd" + ] + ], + "2": [ + "versions.yml:md5,9d6f2f1409574f288a085c66ba884cb7", + "versions.yml:md5,9d6f2f1409574f288a085c66ba884cb7", + "versions.yml:md5,9d6f2f1409574f288a085c66ba884cb7", + "versions.yml:md5,9d6f2f1409574f288a085c66ba884cb7", + "versions.yml:md5,9d6f2f1409574f288a085c66ba884cb7" + ], + "gfa": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "2_trimmed.gfa:md5,e4339397d2a188c90fc16a10aebba086" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "2_trimmed.gfa:md5,b754228734964e5c1a3f006da2de3c37" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "2_trimmed.gfa:md5,1bff9016ffb75edc4c73cdeedbc2b7c4" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "2_trimmed.gfa:md5,dbbb6784efded7f8cb436fb254c426fd" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "2_trimmed.gfa:md5,e08589f6402186b099efeb367add5a09" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_001" + }, + "2_trimmed.yaml:md5,236a2cbde4b5c7a3423b65cab2d9204a" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_002" + }, + "2_trimmed.yaml:md5,a3ce7e8c652fc91da69088cd776c94e6" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_003" + }, + "2_trimmed.yaml:md5,bf72f5ecfed4757e2114665b3e2ff4e5" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_004" + }, + "2_trimmed.yaml:md5,b8ca2603d9b0fbec9e0dd53c2d1003dd" + ], + [ + { + "id": "test", + "single_end": false, + "cluster": "cluster_005" + }, + "2_trimmed.yaml:md5,de8ad13f8a9b4b911a08a53b9b88e4bd" + ] + ], + "versions": [ + "versions.yml:md5,9d6f2f1409574f288a085c66ba884cb7", + "versions.yml:md5,9d6f2f1409574f288a085c66ba884cb7", + "versions.yml:md5,9d6f2f1409574f288a085c66ba884cb7", + "versions.yml:md5,9d6f2f1409574f288a085c66ba884cb7", + "versions.yml:md5,9d6f2f1409574f288a085c66ba884cb7" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-10-28T10:57:59.014535177" + }, + "sarscov2 - assemblies -fasta - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "2_trimmed.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "2_trimmed.yaml:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + "versions.yml:md5,9d6f2f1409574f288a085c66ba884cb7" + ], + "gfa": [ + [ + { + "id": "test", + "single_end": false + }, + "2_trimmed.gfa:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "stats": [ + [ + { + "id": "test", + "single_end": false + }, + "2_trimmed.yaml:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,9d6f2f1409574f288a085c66ba884cb7" + ] + } + ], + "meta": { + "nf-test": "0.9.2", + "nextflow": "25.04.4" + }, + "timestamp": "2025-10-28T10:58:04.464338286" + } +} \ No newline at end of file