From 14087b667c2cc7edc91e3c905d0ad1ab9b5cf34f Mon Sep 17 00:00:00 2001 From: Huimin Lyu Date: Wed, 1 Jul 2026 11:44:13 -0400 Subject: [PATCH 1/3] Added nf-core module presto/pairseq --- .../nf-core/presto/pairseq/environment.yml | 7 ++ modules/nf-core/presto/pairseq/main.nf | 68 +++++++++++++++++++ .../nf-core/presto/pairseq/tests/main.nf.test | 42 ++++++++++++ .../presto/pairseq/tests/main.nf.test.snap | 35 ++++++++++ 4 files changed, 152 insertions(+) create mode 100644 modules/nf-core/presto/pairseq/environment.yml create mode 100644 modules/nf-core/presto/pairseq/main.nf create mode 100644 modules/nf-core/presto/pairseq/tests/main.nf.test create mode 100644 modules/nf-core/presto/pairseq/tests/main.nf.test.snap diff --git a/modules/nf-core/presto/pairseq/environment.yml b/modules/nf-core/presto/pairseq/environment.yml new file mode 100644 index 000000000000..a574fd241ce0 --- /dev/null +++ b/modules/nf-core/presto/pairseq/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::presto=0.7.9" diff --git a/modules/nf-core/presto/pairseq/main.nf b/modules/nf-core/presto/pairseq/main.nf new file mode 100644 index 000000000000..08feb03d4cf1 --- /dev/null +++ b/modules/nf-core/presto/pairseq/main.nf @@ -0,0 +1,68 @@ +// TODO nf-core: If in doubt look at other nf-core/modules to see how we are doing things! :) +// https://github.com/nf-core/modules/tree/master/modules/nf-core/ +// You can also ask for help via your pull request or on the #modules channel on the nf-core Slack workspace: +// https://nf-co.re/join +// TODO nf-core: A module file SHOULD only define input and output files as command-line parameters. +// All other parameters MUST be provided using the "task.ext" directive, see here: +// https://www.nextflow.io/docs/latest/process.html#ext +// where "task.ext" is a string. +// Any parameters that need to be evaluated in the context of a particular sample +// e.g. single-end/paired-end data MUST also be defined and evaluated appropriately. +// TODO nf-core: Software that can be piped together SHOULD be added to separate module files +// unless there is a run-time, storage advantage in implementing in this way +// e.g. it's ok to have a single module for bwa to output BAM instead of SAM: +// bwa mem | samtools view -B -T ref.fasta +// TODO nf-core: Optional inputs are not currently supported by Nextflow. However, using an empty +// list (`[]`) instead of a file can be used to work around this issue. + +process PRESTO_PAIRSEQ { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/presto:0.7.9--pyhdfd78af_0': + 'quay.io/biocontainers/presto:0.7.9--pyhdfd78af_0' }" + + input: + tuple val(meta), path(R1_reads), path(R2_reads) + val(barcode_position) + + output: + tuple val(meta), path("*_pair-pass.fastq.gz"), path("*_pair-pass.fastq.gz") , emit: reads + path "*_command_log.txt", emit: logs + tuple val("${task.process}"), val('presto'), eval('PairSeq.py --version | grep -o "[0-9][0-9.]*" | head -n 1'), emit: versions_presto, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def copyfield = (barcode_position == 'R1')? '--1f BARCODE' : (barcode_position == 'R2')? '--2f BARCODE' : (barcode_position == 'R1R2')? '--1f BARCODE --2f BARCODE' : (barcode_position == 'clustersets')? '--1f CLUSTER --2f CLUSTER' : '' + def args = task.ext.args?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + PairSeq.py -1 ${R1_reads} \\ + -2 ${R2_reads} \\ + --outname ${prefix} \\ + $copyfield \\ + $args > ${prefix}_command_log.txt + + """ + + stub: + def copyfield = (barcode_position == 'R1')? '--1f BARCODE' : (barcode_position == 'R2')? '--2f BARCODE' : (barcode_position == 'R1R2')? '--1f BARCODE --2f BARCODE' : (barcode_position == 'clustersets')? '--1f CLUSTER --2f CLUSTER' : '' + def args = task.ext.args?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + // TODO nf-core: A stub section should mimic the execution of the original module as best as possible + // Have a look at the following examples: + // Simple example: https://github.com/nf-core/modules/blob/624977dfaf562211e68a8a868ca80acc8461f1ac/modules/nf-core/cutadapt/main.nf#L34-L46 + // Complex example: https://github.com/nf-core/modules/blob/88d43dad73a675e66bff49ebb57fe657a5909018/modules/nf-core/bedtools/split/main.nf#L32-L43 + // TODO nf-core: If the module doesn't use arguments ($args), you SHOULD remove: + // - The definition of args `def args = task.ext.args ?: ''` above. + // - The use of the variable in the script `echo $args ` below. + """ + touch ${prefix}-1_pair-pass.fastq.gz \\ + ${prefix}-2_pair-pass.fastq.gz \\ + ${prefix}_command_log.txt + """ +} diff --git a/modules/nf-core/presto/pairseq/tests/main.nf.test b/modules/nf-core/presto/pairseq/tests/main.nf.test new file mode 100644 index 000000000000..71eab938e251 --- /dev/null +++ b/modules/nf-core/presto/pairseq/tests/main.nf.test @@ -0,0 +1,42 @@ +nextflow_process { + + name "Test Process PRESTO_PAIRSEQ" + script "../main.nf" + process "PRESTO_PAIRSEQ" + + tag "modules" + tag "modules_nfcore" + tag "presto" + tag "presto/pairseq" + + test("homo_sapiens - fastq") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_airrseq_umi_R1.fastq.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_airrseq_R2.fastq.gz', checkIfExists: true), + ] + input[1]="" + """ + } + } + + then { + + assertAll( + { assert process.success}, + { assert snapshot( + process.out.reads.get(0).get(1), + process.out.reads.get(0).get(2) + ).match("test_snap_out")}, + { assert snapshot( + process.out.versions_presto).match("test_snap_versions") + }, + { assert path(process.out.logs.get(0)).getText().contains("PASS") } + ) + } + } +} diff --git a/modules/nf-core/presto/pairseq/tests/main.nf.test.snap b/modules/nf-core/presto/pairseq/tests/main.nf.test.snap new file mode 100644 index 000000000000..ff5138d3fee4 --- /dev/null +++ b/modules/nf-core/presto/pairseq/tests/main.nf.test.snap @@ -0,0 +1,35 @@ +{ + "test_snap_out": { + "content": [ + [ + "test-1_pair-pass.fastq.gz:md5,7f98eefe4c7111d4632685680b6b9a4b", + "test-2_pair-pass.fastq.gz:md5,51220f557d95ab70c0819e9a3e8e593a" + ], + [ + "test-1_pair-pass.fastq.gz:md5,7f98eefe4c7111d4632685680b6b9a4b", + "test-2_pair-pass.fastq.gz:md5,51220f557d95ab70c0819e9a3e8e593a" + ] + ], + "timestamp": "2026-07-01T11:37:32.233234794", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.4" + } + }, + "test_snap_versions": { + "content": [ + [ + [ + "PRESTO_PAIRSEQ", + "presto", + "0.7.9" + ] + ] + ], + "timestamp": "2026-07-01T11:37:32.31243821", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.4" + } + } +} \ No newline at end of file From bb4b4b5c5cc1ad03a4dc7befba2f093cfc94bf6e Mon Sep 17 00:00:00 2001 From: Huimin Lyu Date: Wed, 1 Jul 2026 13:48:18 -0400 Subject: [PATCH 2/3] Added meta.yml to presto/pairseq module --- modules/nf-core/presto/pairseq/meta.yml | 89 +++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 modules/nf-core/presto/pairseq/meta.yml diff --git a/modules/nf-core/presto/pairseq/meta.yml b/modules/nf-core/presto/pairseq/meta.yml new file mode 100644 index 000000000000..fe07a2b0c6e2 --- /dev/null +++ b/modules/nf-core/presto/pairseq/meta.yml @@ -0,0 +1,89 @@ +name: "presto_pairseq" +description: Sorts and matches sequence records with matching coordinates across + files +keywords: + - immcantation + - airrseq + - genomics + - immunoinformatics +tools: + - "presto": + description: "A bioinformatics toolkit for processing high-throughput lymphocyte + receptor sequencing data." + homepage: "https://immcantation.readthedocs.io" + documentation: "https://presto.readthedocs.io" + tool_dev_url: "https://bitbucket.org/kleinstein/presto" + doi: "10.1093/bioinformatics/btu138" + licence: + - "AGPL v3" + identifier: biotools:presto-measure +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test']` + - R1_reads: + type: file + description: compressed fastq file + pattern: "*.{fastq.gz}" + ontologies: + - edam: http://edamontology.org/format_1930 + - R2_reads: + type: file + description: compressed fastq file + pattern: "*.{fastq.gz}" + ontologies: + - edam: http://edamontology.org/format_1930 + - barcode_position: + type: string + description: Barcode position. One of "R1, R2, R1R2 or clustersets". Default + is "" +output: + reads: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test']` + - "*_pair-pass.fastq.gz": + type: file + description: paired fastq.gz file of R1 reads + pattern: "*.{fastq.gz}" + ontologies: + - edam: http://edamontology.org/format_1930 + - "*_pair-pass.fastq.gz": + type: file + description: paired fastq.gz file of R2 reads + pattern: "*.{fastq.gz}" + ontologies: + - edam: http://edamontology.org/format_1930 + logs: + - "*_command_log.txt": + type: file + description: command_logs + pattern: "*.txt" + ontologies: [] + versions_presto: + - - ${task.process}: + type: string + description: The name of the process + - presto: + type: string + description: the name of the tool + - PairSeq.py --version | grep -o "[0-9][0-9.]*" | head -n 1: + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - presto: + type: string + description: the name of the tool + - PairSeq.py --version | grep -o "[0-9][0-9.]*" | head -n 1: + type: eval + description: The expression to obtain the version of the tool +authors: + - "@Vivian0105" From f395f0b19e8abfef0bafd914499ff1343d6d2e27 Mon Sep 17 00:00:00 2001 From: Huimin Lyu Date: Wed, 1 Jul 2026 14:05:22 -0400 Subject: [PATCH 3/3] Update main.nf main.nf.tst --- modules/nf-core/presto/pairseq/main.nf | 24 ------------------- .../nf-core/presto/pairseq/tests/main.nf.test | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/modules/nf-core/presto/pairseq/main.nf b/modules/nf-core/presto/pairseq/main.nf index 08feb03d4cf1..57675d1d422b 100644 --- a/modules/nf-core/presto/pairseq/main.nf +++ b/modules/nf-core/presto/pairseq/main.nf @@ -1,20 +1,3 @@ -// TODO nf-core: If in doubt look at other nf-core/modules to see how we are doing things! :) -// https://github.com/nf-core/modules/tree/master/modules/nf-core/ -// You can also ask for help via your pull request or on the #modules channel on the nf-core Slack workspace: -// https://nf-co.re/join -// TODO nf-core: A module file SHOULD only define input and output files as command-line parameters. -// All other parameters MUST be provided using the "task.ext" directive, see here: -// https://www.nextflow.io/docs/latest/process.html#ext -// where "task.ext" is a string. -// Any parameters that need to be evaluated in the context of a particular sample -// e.g. single-end/paired-end data MUST also be defined and evaluated appropriately. -// TODO nf-core: Software that can be piped together SHOULD be added to separate module files -// unless there is a run-time, storage advantage in implementing in this way -// e.g. it's ok to have a single module for bwa to output BAM instead of SAM: -// bwa mem | samtools view -B -T ref.fasta -// TODO nf-core: Optional inputs are not currently supported by Nextflow. However, using an empty -// list (`[]`) instead of a file can be used to work around this issue. - process PRESTO_PAIRSEQ { tag "$meta.id" label 'process_low' @@ -53,13 +36,6 @@ process PRESTO_PAIRSEQ { def copyfield = (barcode_position == 'R1')? '--1f BARCODE' : (barcode_position == 'R2')? '--2f BARCODE' : (barcode_position == 'R1R2')? '--1f BARCODE --2f BARCODE' : (barcode_position == 'clustersets')? '--1f CLUSTER --2f CLUSTER' : '' def args = task.ext.args?: '' def prefix = task.ext.prefix ?: "${meta.id}" - // TODO nf-core: A stub section should mimic the execution of the original module as best as possible - // Have a look at the following examples: - // Simple example: https://github.com/nf-core/modules/blob/624977dfaf562211e68a8a868ca80acc8461f1ac/modules/nf-core/cutadapt/main.nf#L34-L46 - // Complex example: https://github.com/nf-core/modules/blob/88d43dad73a675e66bff49ebb57fe657a5909018/modules/nf-core/bedtools/split/main.nf#L32-L43 - // TODO nf-core: If the module doesn't use arguments ($args), you SHOULD remove: - // - The definition of args `def args = task.ext.args ?: ''` above. - // - The use of the variable in the script `echo $args ` below. """ touch ${prefix}-1_pair-pass.fastq.gz \\ ${prefix}-2_pair-pass.fastq.gz \\ diff --git a/modules/nf-core/presto/pairseq/tests/main.nf.test b/modules/nf-core/presto/pairseq/tests/main.nf.test index 71eab938e251..9dacd6062720 100644 --- a/modules/nf-core/presto/pairseq/tests/main.nf.test +++ b/modules/nf-core/presto/pairseq/tests/main.nf.test @@ -19,7 +19,7 @@ nextflow_process { file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_airrseq_umi_R1.fastq.gz', checkIfExists: true), file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_airrseq_R2.fastq.gz', checkIfExists: true), ] - input[1]="" + input[1] = "" """ } }