") },
+ { assert path(process.out.log.get(0).get(1)).getText().contains("total bases: 13683") },
+ { assert snapshot(
+ process.out.json,
+ process.out.reads,
+ process.out.reads_fail,
+ process.out.reads_merged,
+ process.out.versions).match() }
+ )
+ }
+ }
+
+ test("test_fastp_single_end_qc_only") {
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:true ],
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ]
+ ])
+ input[1] = []
+ input[2] = true
+ input[3] = false
+ input[4] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert path(process.out.html.get(0).get(1)).getText().contains("single end (151 cycles)") },
+ { assert path(process.out.log.get(0).get(1)).getText().contains("reads passed filter: 99") },
+ { assert snapshot(
+ process.out.json,
+ process.out.reads,
+ process.out.reads,
+ process.out.reads_fail,
+ process.out.reads_fail,
+ process.out.reads_merged,
+ process.out.reads_merged,
+ process.out.versions).match() }
+ )
+ }
+ }
+
+ test("test_fastp_paired_end_qc_only") {
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ]
+ ])
+ input[1] = []
+ input[2] = true
+ input[3] = false
+ input[4] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert path(process.out.html.get(0).get(1)).getText().contains("The input has little adapter percentage (~0.000000%), probably it's trimmed before.") },
+ { assert path(process.out.log.get(0).get(1)).getText().contains("Q30 bases: 12281(88.3716%)") },
+ { assert snapshot(
+ process.out.json,
+ process.out.reads,
+ process.out.reads,
+ process.out.reads_fail,
+ process.out.reads_fail,
+ process.out.reads_merged,
+ process.out.reads_merged,
+ process.out.versions).match() }
+ )
+ }
+ }
+
+ test("test_fastp_single_end - stub") {
+
+ options "-stub"
+
+ when {
+
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:true ],
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ]
+ ])
+ input[1] = []
+ input[2] = false
+ input[3] = false
+ input[4] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+ test("test_fastp_paired_end - stub") {
+
+ options "-stub"
+
+ when {
+
+ process {
+ """
+ adapter_fasta = []
+ save_trimmed_pass = true
+ save_trimmed_fail = false
+ save_merged = false
+
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ]
+ ])
+ input[1] = []
+ input[2] = false
+ input[3] = false
+ input[4] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+ test("fastp - stub test_fastp_interleaved") {
+
+ options "-stub"
+
+ config './nextflow.interleaved.config'
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:true ], // meta map
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true) ]
+ ])
+ input[1] = []
+ input[2] = false
+ input[3] = false
+ input[4] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+ test("test_fastp_single_end_trim_fail - stub") {
+
+ options "-stub"
+
+ when {
+
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:true ], // meta map
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ]
+ ])
+ input[1] = []
+ input[2] = false
+ input[3] = true
+ input[4] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+ test("test_fastp_paired_end_trim_fail - stub") {
+
+ options "-stub"
+
+ config './nextflow.save_failed.config'
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)]
+ ])
+ input[1] = []
+ input[2] = false
+ input[3] = true
+ input[4] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+ test("test_fastp_paired_end_merged - stub") {
+
+ options "-stub"
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ]
+ ])
+ input[1] = []
+ input[2] = false
+ input[3] = false
+ input[4] = true
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+ test("test_fastp_paired_end_merged_adapterlist - stub") {
+
+ options "-stub"
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ]
+ ])
+ input[1] = Channel.of([ file(params.modules_testdata_base_path + 'delete_me/fastp/adapters.fasta', checkIfExists: true) ])
+ input[2] = false
+ input[3] = false
+ input[4] = true
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+ test("test_fastp_single_end_qc_only - stub") {
+
+ options "-stub"
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:true ],
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ]
+ ])
+ input[1] = []
+ input[2] = true
+ input[3] = false
+ input[4] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+ test("test_fastp_paired_end_qc_only - stub") {
+
+ options "-stub"
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ]
+ ])
+ input[1] = []
+ input[2] = true
+ input[3] = false
+ input[4] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/fastp/tests/main.nf.test.snap b/modules/nf-core/fastp/tests/main.nf.test.snap
new file mode 100644
index 0000000..54be7e4
--- /dev/null
+++ b/modules/nf-core/fastp/tests/main.nf.test.snap
@@ -0,0 +1,1331 @@
+{
+ "test_fastp_single_end_qc_only - stub": {
+ "content": [
+ {
+ "0": [
+
+ ],
+ "1": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "2": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "3": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "4": [
+
+ ],
+ "5": [
+
+ ],
+ "6": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ],
+ "html": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "json": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "log": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "reads": [
+
+ ],
+ "reads_fail": [
+
+ ],
+ "reads_merged": [
+
+ ],
+ "versions": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T14:31:10.841098"
+ },
+ "test_fastp_paired_end": {
+ "content": [
+ [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,1e0f8e27e71728e2b63fc64086be95cd"
+ ]
+ ],
+ [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test_1.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7",
+ "test_2.fastp.fastq.gz:md5,25cbdca08e2083dbd4f0502de6b62f39"
+ ]
+ ]
+ ],
+ [
+
+ ],
+ [
+
+ ],
+ [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:43:28.665779"
+ },
+ "test_fastp_paired_end_merged_adapterlist": {
+ "content": [
+ [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,5914ca3f21ce162123a824e33e8564f6"
+ ]
+ ],
+ [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test_1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672",
+ "test_2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba"
+ ]
+ ]
+ ],
+ [
+
+ ],
+ [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.merged.fastq.gz:md5,c873bb1ab3fa859dcc47306465e749d5"
+ ]
+ ],
+ [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:44:18.210375"
+ },
+ "test_fastp_single_end_qc_only": {
+ "content": [
+ [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.json:md5,5cc5f01e449309e0e689ed6f51a2294a"
+ ]
+ ],
+ [
+
+ ],
+ [
+
+ ],
+ [
+
+ ],
+ [
+
+ ],
+ [
+
+ ],
+ [
+
+ ],
+ [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:44:27.380974"
+ },
+ "test_fastp_paired_end_trim_fail": {
+ "content": [
+ [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test_1.fastp.fastq.gz:md5,6ff32a64c5188b9a9192be1398c262c7",
+ "test_2.fastp.fastq.gz:md5,db0cb7c9977e94ac2b4b446ebd017a8a"
+ ]
+ ]
+ ],
+ [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test.paired.fail.fastq.gz:md5,409b687c734cedd7a1fec14d316e1366",
+ "test_1.fail.fastq.gz:md5,4f273cf3159c13f79e8ffae12f5661f6",
+ "test_2.fail.fastq.gz:md5,f97b9edefb5649aab661fbc9e71fc995"
+ ]
+ ]
+ ],
+ [
+
+ ],
+ [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,4c3268ddb50ea5b33125984776aa3519"
+ ]
+ ],
+ [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:43:58.749589"
+ },
+ "fastp - stub test_fastp_interleaved": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "1": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "2": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "3": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "4": [
+
+ ],
+ "5": [
+
+ ],
+ "6": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ],
+ "html": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "json": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "log": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "reads": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "reads_fail": [
+
+ ],
+ "reads_merged": [
+
+ ],
+ "versions": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:50:00.270029"
+ },
+ "test_fastp_single_end - stub": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "1": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "2": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "3": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "4": [
+
+ ],
+ "5": [
+
+ ],
+ "6": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ],
+ "html": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "json": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "log": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "reads": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "reads_fail": [
+
+ ],
+ "reads_merged": [
+
+ ],
+ "versions": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:49:42.502789"
+ },
+ "test_fastp_paired_end_merged_adapterlist - stub": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940",
+ "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ]
+ ],
+ "1": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "2": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "3": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "4": [
+
+ ],
+ "5": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "6": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ],
+ "html": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "json": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "log": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "reads": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940",
+ "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ]
+ ],
+ "reads_fail": [
+
+ ],
+ "reads_merged": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:54:53.458252"
+ },
+ "test_fastp_paired_end_merged - stub": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940",
+ "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ]
+ ],
+ "1": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "2": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "3": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "4": [
+
+ ],
+ "5": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "6": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ],
+ "html": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "json": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "log": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "reads": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940",
+ "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ]
+ ],
+ "reads_fail": [
+
+ ],
+ "reads_merged": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.merged.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:50:27.689379"
+ },
+ "test_fastp_paired_end_merged": {
+ "content": [
+ [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,b712fd68ed0322f4bec49ff2a5237fcc"
+ ]
+ ],
+ [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test_1.fastp.fastq.gz:md5,54b726a55e992a869fd3fa778afe1672",
+ "test_2.fastp.fastq.gz:md5,29d3b33b869f7b63417b8ff07bb128ba"
+ ]
+ ]
+ ],
+ [
+
+ ],
+ [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.merged.fastq.gz:md5,c873bb1ab3fa859dcc47306465e749d5"
+ ]
+ ],
+ [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:44:08.68476"
+ },
+ "test_fastp_paired_end - stub": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940",
+ "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ]
+ ],
+ "1": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "2": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "3": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "4": [
+
+ ],
+ "5": [
+
+ ],
+ "6": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ],
+ "html": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "json": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "log": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "reads": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940",
+ "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ]
+ ],
+ "reads_fail": [
+
+ ],
+ "reads_merged": [
+
+ ],
+ "versions": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:49:51.679221"
+ },
+ "test_fastp_single_end": {
+ "content": [
+ [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.json:md5,c852d7a6dba5819e4ac8d9673bedcacc"
+ ]
+ ],
+ [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7"
+ ]
+ ],
+ [
+
+ ],
+ [
+
+ ],
+ [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:43:18.834322"
+ },
+ "test_fastp_single_end_trim_fail - stub": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "1": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "2": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "3": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "4": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "5": [
+
+ ],
+ "6": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ],
+ "html": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "json": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "log": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "reads": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "reads_fail": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "reads_merged": [
+
+ ],
+ "versions": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T14:05:36.898142"
+ },
+ "test_fastp_paired_end_trim_fail - stub": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940",
+ "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ]
+ ],
+ "1": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "2": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "3": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "4": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test.paired.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940",
+ "test_1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940",
+ "test_2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ]
+ ],
+ "5": [
+
+ ],
+ "6": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ],
+ "html": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "json": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "log": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "reads": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test_1.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940",
+ "test_2.fastp.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ]
+ ],
+ "reads_fail": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ [
+ "test.paired.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940",
+ "test_1.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940",
+ "test_2.fail.fastq.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ]
+ ],
+ "reads_merged": [
+
+ ],
+ "versions": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T14:05:49.212847"
+ },
+ "fastp test_fastp_interleaved": {
+ "content": [
+ [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.fastq.gz:md5,217d62dc13a23e92513a1bd8e1bcea39"
+ ]
+ ],
+ [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.json:md5,b24e0624df5cc0b11cd5ba21b726fb22"
+ ]
+ ],
+ [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:43:38.910832"
+ },
+ "test_fastp_single_end_trim_fail": {
+ "content": [
+ [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.json:md5,9a7ee180f000e8d00c7fb67f06293eb5"
+ ]
+ ],
+ [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fastp.fastq.gz:md5,67b2bbae47f073e05a97a9c2edce23c7"
+ ]
+ ],
+ [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.fail.fastq.gz:md5,3e4aaadb66a5b8fc9b881bf39c227abd"
+ ]
+ ],
+ [
+
+ ],
+ [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:43:48.22378"
+ },
+ "test_fastp_paired_end_qc_only": {
+ "content": [
+ [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,623064a45912dac6f2b64e3f2e9901df"
+ ]
+ ],
+ [
+
+ ],
+ [
+
+ ],
+ [
+
+ ],
+ [
+
+ ],
+ [
+
+ ],
+ [
+
+ ],
+ [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T13:44:36.334938"
+ },
+ "test_fastp_paired_end_qc_only - stub": {
+ "content": [
+ {
+ "0": [
+
+ ],
+ "1": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "2": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "3": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "4": [
+
+ ],
+ "5": [
+
+ ],
+ "6": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ],
+ "html": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.html:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "json": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.json:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "log": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.fastp.log:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "reads": [
+
+ ],
+ "reads_fail": [
+
+ ],
+ "reads_merged": [
+
+ ],
+ "versions": [
+ "versions.yml:md5,48ffc994212fb1fc9f83a74fa69c9f02"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "24.04.2"
+ },
+ "timestamp": "2024-07-05T14:31:27.096468"
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/fastp/tests/nextflow.interleaved.config b/modules/nf-core/fastp/tests/nextflow.interleaved.config
new file mode 100644
index 0000000..4be8dbd
--- /dev/null
+++ b/modules/nf-core/fastp/tests/nextflow.interleaved.config
@@ -0,0 +1,5 @@
+process {
+ withName: FASTP {
+ ext.args = "--interleaved_in -e 30"
+ }
+}
diff --git a/modules/nf-core/fastp/tests/nextflow.save_failed.config b/modules/nf-core/fastp/tests/nextflow.save_failed.config
new file mode 100644
index 0000000..53b61b0
--- /dev/null
+++ b/modules/nf-core/fastp/tests/nextflow.save_failed.config
@@ -0,0 +1,5 @@
+process {
+ withName: FASTP {
+ ext.args = "-e 30"
+ }
+}
diff --git a/modules/nf-core/fastp/tests/tags.yml b/modules/nf-core/fastp/tests/tags.yml
new file mode 100644
index 0000000..c1afcce
--- /dev/null
+++ b/modules/nf-core/fastp/tests/tags.yml
@@ -0,0 +1,2 @@
+fastp:
+ - modules/nf-core/fastp/**
diff --git a/modules/nf-core/fgbio/callmolecularconsensusreads/environment.yml b/modules/nf-core/fgbio/callmolecularconsensusreads/environment.yml
new file mode 100644
index 0000000..e2c4b14
--- /dev/null
+++ b/modules/nf-core/fgbio/callmolecularconsensusreads/environment.yml
@@ -0,0 +1,5 @@
+channels:
+ - conda-forge
+ - bioconda
+dependencies:
+ - bioconda::fgbio=2.4.0
diff --git a/modules/nf-core/fgbio/callmolecularconsensusreads/main.nf b/modules/nf-core/fgbio/callmolecularconsensusreads/main.nf
new file mode 100644
index 0000000..7d2e660
--- /dev/null
+++ b/modules/nf-core/fgbio/callmolecularconsensusreads/main.nf
@@ -0,0 +1,64 @@
+process FGBIO_CALLMOLECULARCONSENSUSREADS {
+ tag "$meta.id"
+ label 'process_medium'
+
+ conda "${moduleDir}/environment.yml"
+ container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
+ 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/87/87626ef674e2f19366ae6214575a114fe80ce598e796894820550731706a84be/data' :
+ 'community.wave.seqera.io/library/fgbio:2.4.0--913bad9d47ff8ddc' }"
+
+ input:
+ tuple val(meta), path(grouped_bam)
+ val min_reads
+ val min_baseq
+
+ output:
+ tuple val(meta), path("*.bam"), emit: bam
+ path "versions.yml" , emit: versions
+
+ when:
+ task.ext.when == null || task.ext.when
+
+ script:
+ def args = task.ext.args ?: ''
+ def prefix = task.ext.prefix ?: "${meta.id}_consensus_unmapped"
+ def mem_gb = 8
+ if (!task.memory) {
+ log.info '[fgbio CallMolecularConsensusReads] Available memory not known - defaulting to 8GB. Specify process memory requirements to change this.'
+ } else {
+ mem_gb = task.memory.giga
+ }
+ if ("$grouped_bam" == "${prefix}.bam") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!"
+ """
+ fgbio \\
+ -Xmx${mem_gb}g \\
+ --tmp-dir=. \\
+ --async-io=true \\
+ --compression=1 \\
+ CallMolecularConsensusReads \\
+ --input $grouped_bam \\
+ --output ${prefix}.bam \\
+ --min-reads ${min_reads} \\
+ --min-input-base-quality ${min_baseq} \\
+ --threads ${task.cpus} \\
+ $args;
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ fgbio: \$( echo \$(fgbio --version 2>&1 | tr -d '[:cntrl:]' ) | sed -e 's/^.*Version: //;s/\\[.*\$//')
+ END_VERSIONS
+ """
+
+ stub:
+ prefix = task.ext.prefix ?: "${meta.id}_consensus_unmapped"
+ if ("$grouped_bam" == "${prefix}.bam") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!"
+ """
+ touch ${prefix}.bam
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ fgbio: \$( echo \$(fgbio --version 2>&1 | tr -d '[:cntrl:]' ) | sed -e 's/^.*Version: //;s/\\[.*\$//')
+ END_VERSIONS
+ """
+
+}
diff --git a/modules/nf-core/fgbio/callmolecularconsensusreads/meta.yml b/modules/nf-core/fgbio/callmolecularconsensusreads/meta.yml
new file mode 100644
index 0000000..846c297
--- /dev/null
+++ b/modules/nf-core/fgbio/callmolecularconsensusreads/meta.yml
@@ -0,0 +1,51 @@
+name: fgbio_callmolecularconsensusreads
+description: Calls consensus sequences from reads with the same unique molecular tag.
+keywords:
+ - UMIs
+ - consensus sequence
+ - bam
+tools:
+ - fgbio:
+ description: Tools for working with genomic and high throughput sequencing data.
+ homepage: https://github.com/fulcrumgenomics/fgbio
+ documentation: http://fulcrumgenomics.github.io/fgbio/
+ licence: ["MIT"]
+ identifier: biotools:fgbio
+input:
+ - - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false, collapse:false ]
+ - grouped_bam:
+ type: file
+ description: |
+ The input SAM or BAM file, grouped by UMIs
+ pattern: "*.{bam,sam}"
+ - - min_reads:
+ type: integer
+ description: Minimum number of original reads to build each consensus read.
+ - - min_baseq:
+ type: integer
+ description: Ignore bases in raw reads that have Q below this value.
+output:
+ - bam:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - "*.bam":
+ type: file
+ description: |
+ Output SAM or BAM file to write consensus reads.
+ pattern: "*.{bam,sam}"
+ - versions:
+ - versions.yml:
+ type: file
+ description: File containing software versions
+ pattern: "versions.yml"
+authors:
+ - "@sruthipsuresh"
+maintainers:
+ - "@sruthipsuresh"
diff --git a/modules/nf-core/fgbio/callmolecularconsensusreads/tests/main.nf.test b/modules/nf-core/fgbio/callmolecularconsensusreads/tests/main.nf.test
new file mode 100644
index 0000000..8a90634
--- /dev/null
+++ b/modules/nf-core/fgbio/callmolecularconsensusreads/tests/main.nf.test
@@ -0,0 +1,72 @@
+nextflow_process {
+
+ name "Test Process FGBIO_CALLMOLECULARCONSENSUSREADS"
+ script "../main.nf"
+ process "FGBIO_CALLMOLECULARCONSENSUSREADS"
+
+ tag "modules"
+ tag "modules_nfcore"
+ tag "fgbio"
+ tag "fgbio/callmolecularconsensusreads"
+ tag "fgbio/sortbam"
+
+ setup {
+
+ run("FGBIO_SORTBAM") {
+ script "../../sortbam/main.nf"
+ config "./sort.config"
+ process {
+ """
+ input[0] = [[ id:'homo_sapiens_genome' ],
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true)
+ ]
+ """
+ }
+ }
+ }
+
+ test("homo_sapiens - bam") {
+
+ when {
+ process {
+ """
+ input[0] = FGBIO_SORTBAM.out.bam
+ input[1] = 1
+ input[2] = 20
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+
+ }
+
+ test("homo_sapiens - stub") {
+
+ options "-stub"
+
+ when {
+ process {
+ """
+ input[0] = FGBIO_SORTBAM.out.bam
+ input[1] = 1
+ input[2] = 20
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+
+ }
+
+}
diff --git a/modules/nf-core/fgbio/callmolecularconsensusreads/tests/main.nf.test.snap b/modules/nf-core/fgbio/callmolecularconsensusreads/tests/main.nf.test.snap
new file mode 100644
index 0000000..e7e4507
--- /dev/null
+++ b/modules/nf-core/fgbio/callmolecularconsensusreads/tests/main.nf.test.snap
@@ -0,0 +1,68 @@
+{
+ "homo_sapiens - stub": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "homo_sapiens_genome"
+ },
+ "homo_sapiens_genome_consensus_unmapped.bam:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "1": [
+ "versions.yml:md5,b5ef59a06877dec12426c4c2c02e887c"
+ ],
+ "bam": [
+ [
+ {
+ "id": "homo_sapiens_genome"
+ },
+ "homo_sapiens_genome_consensus_unmapped.bam:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,b5ef59a06877dec12426c4c2c02e887c"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-11-11T12:22:07.722755"
+ },
+ "homo_sapiens - bam": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "homo_sapiens_genome"
+ },
+ "homo_sapiens_genome_consensus_unmapped.bam:md5,f56c861f1f604ecc9894dc9182b170f8"
+ ]
+ ],
+ "1": [
+ "versions.yml:md5,b5ef59a06877dec12426c4c2c02e887c"
+ ],
+ "bam": [
+ [
+ {
+ "id": "homo_sapiens_genome"
+ },
+ "homo_sapiens_genome_consensus_unmapped.bam:md5,f56c861f1f604ecc9894dc9182b170f8"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,b5ef59a06877dec12426c4c2c02e887c"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-11-11T12:21:46.241305"
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/fgbio/callmolecularconsensusreads/tests/sort.config b/modules/nf-core/fgbio/callmolecularconsensusreads/tests/sort.config
new file mode 100644
index 0000000..b205c8f
--- /dev/null
+++ b/modules/nf-core/fgbio/callmolecularconsensusreads/tests/sort.config
@@ -0,0 +1,6 @@
+process {
+ withName: FGBIO_SORTBAM {
+ ext.args = '-s TemplateCoordinate'
+ ext.prefix = { "${meta.id}_out" }
+ }
+}
diff --git a/modules/nf-core/fgbio/callmolecularconsensusreads/tests/tags.yml b/modules/nf-core/fgbio/callmolecularconsensusreads/tests/tags.yml
new file mode 100644
index 0000000..4f9fcba
--- /dev/null
+++ b/modules/nf-core/fgbio/callmolecularconsensusreads/tests/tags.yml
@@ -0,0 +1,2 @@
+fgbio/callmolecularconsensusreads:
+ - "modules/nf-core/fgbio/callmolecularconsensusreads/**"
diff --git a/modules/nf-core/fgbio/groupreadsbyumi/environment.yml b/modules/nf-core/fgbio/groupreadsbyumi/environment.yml
new file mode 100644
index 0000000..e2c4b14
--- /dev/null
+++ b/modules/nf-core/fgbio/groupreadsbyumi/environment.yml
@@ -0,0 +1,5 @@
+channels:
+ - conda-forge
+ - bioconda
+dependencies:
+ - bioconda::fgbio=2.4.0
diff --git a/modules/nf-core/fgbio/groupreadsbyumi/main.nf b/modules/nf-core/fgbio/groupreadsbyumi/main.nf
new file mode 100644
index 0000000..c0506c9
--- /dev/null
+++ b/modules/nf-core/fgbio/groupreadsbyumi/main.nf
@@ -0,0 +1,67 @@
+process FGBIO_GROUPREADSBYUMI {
+ tag "$meta.id"
+ label 'process_low'
+
+ conda "${moduleDir}/environment.yml"
+ container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
+ 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/87/87626ef674e2f19366ae6214575a114fe80ce598e796894820550731706a84be/data' :
+ 'community.wave.seqera.io/library/fgbio:2.4.0--913bad9d47ff8ddc' }"
+
+ input:
+ tuple val(meta), path(bam)
+ val(strategy)
+
+ output:
+ tuple val(meta), path("*.bam") , emit: bam
+ tuple val(meta), path("*histogram.txt"), emit: histogram
+ path "versions.yml" , emit: versions
+
+ when:
+ task.ext.when == null || task.ext.when
+
+ script:
+ def args = task.ext.args ?: ''
+ def prefix = task.ext.prefix ?: "${meta.id}_umi-grouped"
+ def mem_gb = 8
+ if (!task.memory) {
+ log.info '[fgbio FilterConsensusReads] Available memory not known - defaulting to 8GB. Specify process memory requirements to change this.'
+ } else if (mem_gb > task.memory.giga) {
+ if (task.memory.giga < 2) {
+ mem_gb = 1
+ } else {
+ mem_gb = task.memory.giga - 1
+ }
+ }
+
+ if ("$bam" == "${prefix}.bam") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!"
+
+ """
+ fgbio \\
+ -Xmx${mem_gb}g \\
+ --tmp-dir=. \\
+ GroupReadsByUmi \\
+ -s $strategy \\
+ $args \\
+ -i $bam \\
+ -o ${prefix}.bam \\
+ -f ${prefix}_histogram.txt
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ fgbio: \$( echo \$(fgbio --version 2>&1 | tr -d '[:cntrl:]' ) | sed -e 's/^.*Version: //;s/\\[.*\$//')
+ END_VERSIONS
+ """
+
+ stub:
+ def prefix = task.ext.prefix ?: "${meta.id}_umi-grouped"
+ if ("$bam" == "${prefix}.bam") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!"
+ """
+ touch ${prefix}.bam
+ touch ${prefix}_histogram.txt
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ fgbio: \$( echo \$(fgbio --version 2>&1 | tr -d '[:cntrl:]' ) | sed -e 's/^.*Version: //;s/\\[.*\$//')
+ END_VERSIONS
+ """
+}
diff --git a/modules/nf-core/fgbio/groupreadsbyumi/meta.yml b/modules/nf-core/fgbio/groupreadsbyumi/meta.yml
new file mode 100644
index 0000000..3e525fd
--- /dev/null
+++ b/modules/nf-core/fgbio/groupreadsbyumi/meta.yml
@@ -0,0 +1,68 @@
+name: fgbio_groupreadsbyumi
+description: |
+ Groups reads together that appear to have come from the same original molecule.
+ Reads are grouped by template, and then templates are sorted by the 5’ mapping positions
+ of the reads from the template, used from earliest mapping position to latest.
+ Reads that have the same end positions are then sub-grouped by UMI sequence.
+ (!) Note: the MQ tag is required on reads with mapped mates (!)
+ This can be added using samblaster with the optional argument --addMateTags.
+keywords:
+ - UMI
+ - groupreads
+ - fgbio
+tools:
+ - fgbio:
+ description: A set of tools for working with genomic and high throughput sequencing
+ data, including UMIs
+ homepage: http://fulcrumgenomics.github.io/fgbio/
+ documentation: http://fulcrumgenomics.github.io/fgbio/tools/latest/
+ tool_dev_url: https://github.com/fulcrumgenomics/fgbio
+ licence: ["MIT"]
+ identifier: biotools:fgbio
+input:
+ - - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - bam:
+ type: file
+ description: |
+ BAM file. Note: the MQ tag is required on reads with mapped mates (!)
+ pattern: "*.bam"
+ - - strategy:
+ type: string
+ enum: ["Identity", "Edit", "Adjacency", "Paired"]
+ description: |
+ Reguired argument: defines the UMI assignment strategy.
+ Must be chosen among: Identity, Edit, Adjacency, Paired.
+output:
+ - bam:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - "*.bam":
+ type: file
+ description: UMI-grouped BAM
+ pattern: "*.bam"
+ - histogram:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - "*histogram.txt":
+ type: file
+ description: A text file containing the tag family size counts
+ pattern: "*.txt"
+ - versions:
+ - versions.yml:
+ type: file
+ description: File containing software versions
+ pattern: "versions.yml"
+authors:
+ - "@lescai"
+maintainers:
+ - "@lescai"
diff --git a/modules/nf-core/fgbio/groupreadsbyumi/tests/main.nf.test b/modules/nf-core/fgbio/groupreadsbyumi/tests/main.nf.test
new file mode 100644
index 0000000..a9e8bd2
--- /dev/null
+++ b/modules/nf-core/fgbio/groupreadsbyumi/tests/main.nf.test
@@ -0,0 +1,60 @@
+nextflow_process {
+
+ name "Test Process FGBIO_GROUPREADSBYUMI"
+ script "../main.nf"
+ process "FGBIO_GROUPREADSBYUMI"
+
+ tag "modules"
+ tag "modules_nfcore"
+ tag "fgbio"
+ tag "fgbio/groupreadsbyumi"
+
+ test("sarscov2 - bam") {
+
+ when {
+ process {
+ """
+ input[0] = [
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/umi/test.paired_end.unsorted_tagged.bam', checkIfExists: true)
+ ]
+ input[1] = "Adjacency"
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+
+ }
+
+ test("sarscov2 - bam - stub") {
+
+ options "-stub"
+
+ when {
+ process {
+ """
+ input[0] = [
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/umi/test.paired_end.unsorted_tagged.bam', checkIfExists: true)
+ ]
+ input[1] = "Adjacency"
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+
+ }
+
+}
diff --git a/modules/nf-core/fgbio/groupreadsbyumi/tests/main.nf.test.snap b/modules/nf-core/fgbio/groupreadsbyumi/tests/main.nf.test.snap
new file mode 100644
index 0000000..67956c5
--- /dev/null
+++ b/modules/nf-core/fgbio/groupreadsbyumi/tests/main.nf.test.snap
@@ -0,0 +1,108 @@
+{
+ "sarscov2 - bam - stub": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test_umi-grouped.bam:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "1": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test_umi-grouped_histogram.txt:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "2": [
+ "versions.yml:md5,3951d85671eb08c5731449a16bd9a229"
+ ],
+ "bam": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test_umi-grouped.bam:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "histogram": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test_umi-grouped_histogram.txt:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,3951d85671eb08c5731449a16bd9a229"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-11-11T12:25:36.897639"
+ },
+ "sarscov2 - bam": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test_umi-grouped.bam:md5,35bfc992c30d8e3e50816159fa58cb11"
+ ]
+ ],
+ "1": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test_umi-grouped_histogram.txt:md5,9a0c622b65209afbce0840e2affff983"
+ ]
+ ],
+ "2": [
+ "versions.yml:md5,3951d85671eb08c5731449a16bd9a229"
+ ],
+ "bam": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test_umi-grouped.bam:md5,35bfc992c30d8e3e50816159fa58cb11"
+ ]
+ ],
+ "histogram": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test_umi-grouped_histogram.txt:md5,9a0c622b65209afbce0840e2affff983"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,3951d85671eb08c5731449a16bd9a229"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-11-11T12:25:25.077144"
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/fgbio/groupreadsbyumi/tests/tags.yml b/modules/nf-core/fgbio/groupreadsbyumi/tests/tags.yml
new file mode 100644
index 0000000..83146c4
--- /dev/null
+++ b/modules/nf-core/fgbio/groupreadsbyumi/tests/tags.yml
@@ -0,0 +1,2 @@
+fgbio/groupreadsbyumi:
+ - "modules/nf-core/fgbio/groupreadsbyumi/**"
diff --git a/modules/nf-core/gatk4/fastqtosam/environment.yml b/modules/nf-core/gatk4/fastqtosam/environment.yml
new file mode 100644
index 0000000..1f7d082
--- /dev/null
+++ b/modules/nf-core/gatk4/fastqtosam/environment.yml
@@ -0,0 +1,10 @@
+---
+# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json
+channels:
+ - conda-forge
+ - bioconda
+dependencies:
+ # renovate: datasource=conda depName=bioconda/gatk4
+ - bioconda::gatk4=4.6.1.0
+ # renovate: datasource=conda depName=bioconda/gcnvkernel
+ - bioconda::gcnvkernel=0.9
diff --git a/modules/nf-core/gatk4/fastqtosam/main.nf b/modules/nf-core/gatk4/fastqtosam/main.nf
new file mode 100644
index 0000000..e79f847
--- /dev/null
+++ b/modules/nf-core/gatk4/fastqtosam/main.nf
@@ -0,0 +1,56 @@
+process GATK4_FASTQTOSAM {
+ tag "$meta.id"
+ label 'process_low'
+
+ conda "${moduleDir}/environment.yml"
+ container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
+ 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/b2/b28daf5d9bb2f0d129dcad1b7410e0dd8a9b087aaf3ec7ced929b1f57624ad98/data':
+ 'community.wave.seqera.io/library/gatk4_gcnvkernel:e48d414933d188cd' }"
+
+ input:
+ tuple val(meta), path(reads)
+
+ output:
+ tuple val(meta), path("*.bam"), emit: bam
+ path "versions.yml" , emit: versions
+
+ when:
+ task.ext.when == null || task.ext.when
+
+ script:
+ def args = task.ext.args ?: ''
+ def prefix = task.ext.prefix ?: "${meta.id}"
+ def reads_command = meta.single_end ? "--FASTQ $reads" : "--FASTQ ${reads[0]} --FASTQ2 ${reads[1]}"
+
+ def avail_mem = 3072
+ if (!task.memory) {
+ log.info '[GATK FastqToSam] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.'
+ } else {
+ avail_mem = (task.memory.mega*0.8).intValue()
+ }
+ """
+ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\
+ FastqToSam \\
+ $reads_command \\
+ --OUTPUT ${prefix}.bam \\
+ --SAMPLE_NAME $prefix \\
+ --TMP_DIR . \\
+ $args
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//')
+ END_VERSIONS
+ """
+
+ stub:
+ def prefix = task.ext.prefix ?: "${meta.id}"
+ """
+ touch ${prefix}.bam
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//')
+ END_VERSIONS
+ """
+}
diff --git a/modules/nf-core/gatk4/fastqtosam/meta.yml b/modules/nf-core/gatk4/fastqtosam/meta.yml
new file mode 100644
index 0000000..6d3e907
--- /dev/null
+++ b/modules/nf-core/gatk4/fastqtosam/meta.yml
@@ -0,0 +1,51 @@
+name: gatk4_fastqtosam
+description: Converts FastQ file to SAM/BAM format
+keywords:
+ - bam
+ - convert
+ - fastq
+ - gatk4
+tools:
+ - gatk4:
+ description: Genome Analysis Toolkit (GATK4) Developed in the Data Sciences Platform
+ at the Broad Institute, the toolkit offers a wide variety of tools with a primary
+ focus on variant discovery and genotyping. Its powerful processing engine and
+ high-performance computing features make it capable of taking on projects of
+ any size.
+ homepage: https://gatk.broadinstitute.org/hc/en-us
+ documentation: https://gatk.broadinstitute.org/hc/en-us/categories/360002369672s
+ tool_dev_url: https://github.com/broadinstitute/gatk
+ doi: "10.1158/1538-7445.AM2017-3590"
+ licence: ["MIT"]
+ identifier: ""
+input:
+ - - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - reads:
+ type: file
+ description: List of input FastQ files of size 1 and 2 for single-end and paired-end
+ data, respectively.
+ pattern: "*.fastq.gz"
+output:
+ - bam:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - "*.bam":
+ type: file
+ description: Converted BAM file
+ pattern: "*.bam"
+ - versions:
+ - versions.yml:
+ type: file
+ description: File containing software versions
+ pattern: "versions.yml"
+authors:
+ - "@ntoda03"
+maintainers:
+ - "@ntoda03"
diff --git a/modules/nf-core/gatk4/fastqtosam/tests/main.nf.test b/modules/nf-core/gatk4/fastqtosam/tests/main.nf.test
new file mode 100644
index 0000000..8ba0ff0
--- /dev/null
+++ b/modules/nf-core/gatk4/fastqtosam/tests/main.nf.test
@@ -0,0 +1,85 @@
+
+nextflow_process {
+
+ name "Test Process GATK4_FASTQTOSAM"
+ script "../main.nf"
+ process "GATK4_FASTQTOSAM"
+
+ tag "modules"
+ tag "modules_nfcore"
+ tag "gatk4"
+ tag "gatk4/fastqtosam"
+
+ test("test-gatk4-fastqtosam-single-end") {
+
+ when {
+ process {
+ """
+ input[0] = [ [ id:'test', single_end:true ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)
+ ]
+
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(
+ bam(process.out.bam[0][1]).getReadsMD5(),
+ process.out.versions
+ ).match()
+ }
+ )
+ }
+ }
+
+ test("test-gatk4-fastqtosam-paired-end") {
+
+ when {
+ process {
+ """
+ input[0] = [ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)
+ ]
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(
+ bam(process.out.bam[0][1]).getReadsMD5(),
+ process.out.versions
+ ).match()
+ }
+ )
+ }
+ }
+
+ test("test-gatk4-fastqtosam-single-end - stub") {
+
+ options "-stub"
+
+ when {
+ process {
+ """
+ input[0] = [ [ id:'test', single_end:true ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)
+ ]
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+}
diff --git a/modules/nf-core/gatk4/fastqtosam/tests/main.nf.test.snap b/modules/nf-core/gatk4/fastqtosam/tests/main.nf.test.snap
new file mode 100644
index 0000000..5c57586
--- /dev/null
+++ b/modules/nf-core/gatk4/fastqtosam/tests/main.nf.test.snap
@@ -0,0 +1,63 @@
+{
+ "test-gatk4-fastqtosam-single-end - stub": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "1": [
+ "versions.yml:md5,1d5e403a0c261ca92954dd22455adf47"
+ ],
+ "bam": [
+ [
+ {
+ "id": "test",
+ "single_end": true
+ },
+ "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,1d5e403a0c261ca92954dd22455adf47"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.1",
+ "nextflow": "24.10.0"
+ },
+ "timestamp": "2024-10-31T11:02:58.024964061"
+ },
+ "test-gatk4-fastqtosam-single-end": {
+ "content": [
+ "e6a4aa204d980e177a0458596f0a70ac",
+ [
+ "versions.yml:md5,1d5e403a0c261ca92954dd22455adf47"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.1",
+ "nextflow": "24.10.0"
+ },
+ "timestamp": "2024-10-31T11:02:34.422399439"
+ },
+ "test-gatk4-fastqtosam-paired-end": {
+ "content": [
+ "e6a4aa204d980e177a0458596f0a70ac",
+ [
+ "versions.yml:md5,1d5e403a0c261ca92954dd22455adf47"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.1",
+ "nextflow": "24.10.0"
+ },
+ "timestamp": "2024-10-31T11:02:47.309600742"
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/gatk4/mergebamalignment/environment.yml b/modules/nf-core/gatk4/mergebamalignment/environment.yml
new file mode 100644
index 0000000..1f7d082
--- /dev/null
+++ b/modules/nf-core/gatk4/mergebamalignment/environment.yml
@@ -0,0 +1,10 @@
+---
+# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json
+channels:
+ - conda-forge
+ - bioconda
+dependencies:
+ # renovate: datasource=conda depName=bioconda/gatk4
+ - bioconda::gatk4=4.6.1.0
+ # renovate: datasource=conda depName=bioconda/gcnvkernel
+ - bioconda::gcnvkernel=0.9
diff --git a/modules/nf-core/gatk4/mergebamalignment/main.nf b/modules/nf-core/gatk4/mergebamalignment/main.nf
new file mode 100644
index 0000000..69027e0
--- /dev/null
+++ b/modules/nf-core/gatk4/mergebamalignment/main.nf
@@ -0,0 +1,58 @@
+process GATK4_MERGEBAMALIGNMENT {
+ tag "$meta.id"
+ label 'process_low'
+
+ conda "${moduleDir}/environment.yml"
+ container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
+ 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/b2/b28daf5d9bb2f0d129dcad1b7410e0dd8a9b087aaf3ec7ced929b1f57624ad98/data':
+ 'community.wave.seqera.io/library/gatk4_gcnvkernel:e48d414933d188cd' }"
+
+ input:
+ tuple val(meta), path(aligned), path(unmapped)
+ tuple val(meta2), path(fasta)
+ tuple val(meta3), path(dict)
+
+ output:
+ tuple val(meta), path('*.bam'), emit: bam
+ path "versions.yml" , emit: versions
+
+ when:
+ task.ext.when == null || task.ext.when
+
+ script:
+ def args = task.ext.args ?: ''
+ def prefix = task.ext.prefix ?: "${meta.id}"
+
+ def avail_mem = 3072
+ if (!task.memory) {
+ log.info '[GATK MergeBamAlignment] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.'
+ } else {
+ avail_mem = (task.memory.mega*0.8).intValue()
+ }
+ """
+ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\
+ MergeBamAlignment \\
+ --UNMAPPED_BAM $unmapped \\
+ --ALIGNED_BAM $aligned \\
+ --OUTPUT ${prefix}.bam \\
+ --REFERENCE_SEQUENCE $fasta \\
+ --TMP_DIR . \\
+ $args
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//')
+ END_VERSIONS
+ """
+
+ stub:
+ def prefix = task.ext.prefix ?: "${meta.id}"
+ """
+ touch ${prefix}.bam
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//')
+ END_VERSIONS
+ """
+}
diff --git a/modules/nf-core/gatk4/mergebamalignment/meta.yml b/modules/nf-core/gatk4/mergebamalignment/meta.yml
new file mode 100644
index 0000000..7bde934
--- /dev/null
+++ b/modules/nf-core/gatk4/mergebamalignment/meta.yml
@@ -0,0 +1,70 @@
+name: gatk4_mergebamalignment
+description: Merge unmapped with mapped BAM files
+keywords:
+ - alignment
+ - bam
+ - gatk4
+ - merge
+ - mergebamalignment
+tools:
+ - gatk4:
+ description: |
+ Developed in the Data Sciences Platform at the Broad Institute, the toolkit offers a wide variety of tools
+ with a primary focus on variant discovery and genotyping. Its powerful processing engine
+ and high-performance computing features make it capable of taking on projects of any size.
+ homepage: https://gatk.broadinstitute.org/hc/en-us
+ documentation: https://gatk.broadinstitute.org/hc/en-us/categories/360002369672s
+ doi: 10.1158/1538-7445.AM2017-3590
+ licence: ["Apache-2.0"]
+ identifier: ""
+input:
+ - - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test']
+ - aligned:
+ type: file
+ description: The aligned bam file
+ pattern: "*.{bam}"
+ - unmapped:
+ type: file
+ description: The unmapped bam file
+ pattern: "*.{bam}"
+ - - meta2:
+ type: map
+ description: |
+ Groovy Map containing reference information
+ e.g. [ id:'genome' ]
+ - fasta:
+ type: file
+ description: The reference fasta file
+ - - meta3:
+ type: map
+ description: |
+ Groovy Map containing reference information
+ e.g. [ id:'genome' ]
+ - dict:
+ type: file
+ description: GATK sequence dictionary
+output:
+ - bam:
+ - meta:
+ type: file
+ description: The merged bam file
+ pattern: "*.bam"
+ - "*.bam":
+ type: file
+ description: The merged bam file
+ pattern: "*.bam"
+ - versions:
+ - versions.yml:
+ type: file
+ description: File containing software versions
+ pattern: "versions.yml"
+authors:
+ - "@kevinmenden"
+ - "@ramprasadn"
+maintainers:
+ - "@kevinmenden"
+ - "@ramprasadn"
diff --git a/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test b/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test
new file mode 100644
index 0000000..96e93bb
--- /dev/null
+++ b/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test
@@ -0,0 +1,73 @@
+
+nextflow_process {
+
+ name "Test Process GATK4_MERGEBAMALIGNMENT"
+ script "../main.nf"
+ process "GATK4_MERGEBAMALIGNMENT"
+
+ tag "modules"
+ tag "modules_nfcore"
+ tag "gatk4"
+ tag "gatk4/mergebamalignment"
+
+ test("test-gatk4-mergebamalignment") {
+
+ when {
+ process {
+ """
+ input[0] = [ [ id:'test' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.unaligned.bam', checkIfExists: true)
+ ]
+ input[1] = [ [ id:'genome' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)
+ ]
+ input[2] = [ [ id:'genome' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)
+ ]
+
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(
+ bam(process.out.bam[0][1]).getReadsMD5(),
+ process.out.versions
+ ).match()
+ }
+ )
+ }
+ }
+
+ test("test-gatk4-mergebamalignment-stubs") {
+ options '-stub'
+ when {
+ process {
+ """
+ input[0] = [ [ id:'test' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.unaligned.bam', checkIfExists: true)
+ ]
+ input[1] = [ [ id:'genome' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)
+ ]
+ input[2] = [ [ id:'genome' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)
+ ]
+
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+}
diff --git a/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test.snap b/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test.snap
new file mode 100644
index 0000000..476eecd
--- /dev/null
+++ b/modules/nf-core/gatk4/mergebamalignment/tests/main.nf.test.snap
@@ -0,0 +1,48 @@
+{
+ "test-gatk4-mergebamalignment-stubs": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test"
+ },
+ "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "1": [
+ "versions.yml:md5,19f0b1268d925943a61f6f686061d519"
+ ],
+ "bam": [
+ [
+ {
+ "id": "test"
+ },
+ "test.bam:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,19f0b1268d925943a61f6f686061d519"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.1",
+ "nextflow": "24.10.0"
+ },
+ "timestamp": "2024-10-31T11:29:07.319519362"
+ },
+ "test-gatk4-mergebamalignment": {
+ "content": [
+ "30c325e1e032eb1782a280d34c0fb1c7",
+ [
+ "versions.yml:md5,19f0b1268d925943a61f6f686061d519"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.1",
+ "nextflow": "24.10.0"
+ },
+ "timestamp": "2024-10-31T11:28:55.287907787"
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/gatk4/samtofastq/environment.yml b/modules/nf-core/gatk4/samtofastq/environment.yml
new file mode 100644
index 0000000..1f7d082
--- /dev/null
+++ b/modules/nf-core/gatk4/samtofastq/environment.yml
@@ -0,0 +1,10 @@
+---
+# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json
+channels:
+ - conda-forge
+ - bioconda
+dependencies:
+ # renovate: datasource=conda depName=bioconda/gatk4
+ - bioconda::gatk4=4.6.1.0
+ # renovate: datasource=conda depName=bioconda/gcnvkernel
+ - bioconda::gcnvkernel=0.9
diff --git a/modules/nf-core/gatk4/samtofastq/main.nf b/modules/nf-core/gatk4/samtofastq/main.nf
new file mode 100644
index 0000000..7760d45
--- /dev/null
+++ b/modules/nf-core/gatk4/samtofastq/main.nf
@@ -0,0 +1,57 @@
+process GATK4_SAMTOFASTQ {
+ tag "$meta.id"
+ label 'process_low'
+
+ conda "${moduleDir}/environment.yml"
+ container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
+ 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/b2/b28daf5d9bb2f0d129dcad1b7410e0dd8a9b087aaf3ec7ced929b1f57624ad98/data':
+ 'community.wave.seqera.io/library/gatk4_gcnvkernel:e48d414933d188cd' }"
+
+ input:
+ tuple val(meta), path(bam)
+
+ output:
+ tuple val(meta), path('*.fastq.gz'), emit: fastq
+ path "versions.yml" , emit: versions
+
+ when:
+ task.ext.when == null || task.ext.when
+
+ script:
+ def args = task.ext.args ?: ''
+ def prefix = task.ext.prefix ?: "${meta.id}"
+ def output = meta.single_end ? "--FASTQ ${prefix}.fastq.gz" : "--FASTQ ${prefix}_1.fastq.gz --SECOND_END_FASTQ ${prefix}_2.fastq.gz"
+
+ def avail_mem = 3072
+ if (!task.memory) {
+ log.info '[GATK SamToFastq] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.'
+ } else {
+ avail_mem = (task.memory.mega*0.8).intValue()
+ }
+ """
+ gatk --java-options "-Xmx${avail_mem}M -XX:-UsePerfData" \\
+ SamToFastq \\
+ --INPUT $bam \\
+ $output \\
+ --TMP_DIR . \\
+ $args
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//')
+ END_VERSIONS
+ """
+
+ stub:
+ def prefix = task.ext.prefix ?: "${meta.id}"
+ """
+ touch ${prefix}.fastq.gz
+ touch ${prefix}_1.fastq.gz
+ touch ${prefix}_2.fastq.gz
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ gatk4: \$(echo \$(gatk --version 2>&1) | sed 's/^.*(GATK) v//; s/ .*\$//')
+ END_VERSIONS
+ """
+}
diff --git a/modules/nf-core/gatk4/samtofastq/meta.yml b/modules/nf-core/gatk4/samtofastq/meta.yml
new file mode 100644
index 0000000..91a8e50
--- /dev/null
+++ b/modules/nf-core/gatk4/samtofastq/meta.yml
@@ -0,0 +1,46 @@
+name: gatk4_samtofastq
+description: Converts BAM/SAM file to FastQ format
+keywords:
+ - bed
+ - gatk4
+ - interval_list
+tools:
+ - gatk4:
+ description: |
+ Developed in the Data Sciences Platform at the Broad Institute, the toolkit offers a wide variety of tools
+ with a primary focus on variant discovery and genotyping. Its powerful processing engine
+ and high-performance computing features make it capable of taking on projects of any size.
+ homepage: https://gatk.broadinstitute.org/hc/en-us
+ documentation: https://gatk.broadinstitute.org/hc/en-us/categories/360002369672s
+ doi: 10.1158/1538-7445.AM2017-3590
+ licence: ["Apache-2.0"]
+ identifier: ""
+input:
+ - - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test']
+ - bam:
+ type: file
+ description: Input SAM/BAM file
+ pattern: "*.{bam,sam}"
+output:
+ - fastq:
+ - meta:
+ type: file
+ description: converted fastq file
+ pattern: "*.fastq"
+ - "*.fastq.gz":
+ type: file
+ description: converted fastq file
+ pattern: "*.fastq"
+ - versions:
+ - versions.yml:
+ type: file
+ description: File containing software versions
+ pattern: "versions.yml"
+authors:
+ - "@kevinmenden"
+maintainers:
+ - "@kevinmenden"
diff --git a/modules/nf-core/gatk4/samtofastq/tests/main.nf.test b/modules/nf-core/gatk4/samtofastq/tests/main.nf.test
new file mode 100644
index 0000000..30a41ad
--- /dev/null
+++ b/modules/nf-core/gatk4/samtofastq/tests/main.nf.test
@@ -0,0 +1,88 @@
+
+nextflow_process {
+
+ name "Test Process GATK4_SAMTOFASTQ"
+ script "../main.nf"
+ process "GATK4_SAMTOFASTQ"
+
+ tag "modules"
+ tag "modules_nfcore"
+ tag "gatk4"
+ tag "gatk4/samtofastq"
+
+ test("test-gatk4-samtofastq-single-end") {
+
+ when {
+ process {
+ """
+ input[0] = [ [ id:'test', single_end: true ], // meta map
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true) ]
+ ]
+
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(
+ path(process.out.fastq[0][1]).linesGzip[3..7],
+ process.out.versions
+ ).match()
+ }
+ )
+ }
+ }
+
+ test("test-gatk4-samtofastq-paired-end") {
+
+ when {
+ process {
+ """
+ input[0] = [ [ id:'test', single_end: false ], // meta map
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true) ]
+ ]
+
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(
+ process.out.fastq[0][1].collect { path(it).linesGzip[3..7] },
+ process.out.versions
+ ).match()
+ }
+ )
+ }
+ }
+
+ test("test-gatk4-samtofastq-paired-end-stubs") {
+ options '-stub'
+ when {
+ process {
+ """
+ input[0] = [ [ id:'test', single_end: true ], // meta map
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true) ]
+ ]
+
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(
+ process.out.fastq[0][1].collect { file(it).name },
+ process.out.versions
+ ).match()
+ }
+ )
+ }
+ }
+
+}
diff --git a/modules/nf-core/gatk4/samtofastq/tests/main.nf.test.snap b/modules/nf-core/gatk4/samtofastq/tests/main.nf.test.snap
new file mode 100644
index 0000000..38040db
--- /dev/null
+++ b/modules/nf-core/gatk4/samtofastq/tests/main.nf.test.snap
@@ -0,0 +1,66 @@
+{
+ "test-gatk4-samtofastq-single-end": {
+ "content": [
+ [
+ "AAAAAAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAEEEEE
versions.yml
+ "${task.process}":
+ multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" )
+ END_VERSIONS
+ """
+
+ stub:
+ """
+ mkdir multiqc_data
+ mkdir multiqc_plots
+ touch multiqc_report.html
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" )
+ END_VERSIONS
+ """
+}
diff --git a/modules/nf-core/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml
new file mode 100644
index 0000000..b16c187
--- /dev/null
+++ b/modules/nf-core/multiqc/meta.yml
@@ -0,0 +1,78 @@
+name: multiqc
+description: Aggregate results from bioinformatics analyses across many samples into
+ a single report
+keywords:
+ - QC
+ - bioinformatics tools
+ - Beautiful stand-alone HTML report
+tools:
+ - multiqc:
+ description: |
+ MultiQC searches a given directory for analysis logs and compiles a HTML report.
+ It's a general use tool, perfect for summarising the output from numerous bioinformatics tools.
+ homepage: https://multiqc.info/
+ documentation: https://multiqc.info/docs/
+ licence: ["GPL-3.0-or-later"]
+ identifier: biotools:multiqc
+input:
+ - - multiqc_files:
+ type: file
+ description: |
+ List of reports / files recognised by MultiQC, for example the html and zip output of FastQC
+ - - multiqc_config:
+ type: file
+ description: Optional config yml for MultiQC
+ pattern: "*.{yml,yaml}"
+ - - extra_multiqc_config:
+ type: file
+ description: Second optional config yml for MultiQC. Will override common sections
+ in multiqc_config.
+ pattern: "*.{yml,yaml}"
+ - - multiqc_logo:
+ type: file
+ description: Optional logo file for MultiQC
+ pattern: "*.{png}"
+ - - replace_names:
+ type: file
+ description: |
+ Optional two-column sample renaming file. First column a set of
+ patterns, second column a set of corresponding replacements. Passed via
+ MultiQC's `--replace-names` option.
+ pattern: "*.{tsv}"
+ - - sample_names:
+ type: file
+ description: |
+ Optional TSV file with headers, passed to the MultiQC --sample_names
+ argument.
+ pattern: "*.{tsv}"
+output:
+ - report:
+ - "*multiqc_report.html":
+ type: file
+ description: MultiQC report file
+ pattern: "multiqc_report.html"
+ - data:
+ - "*_data":
+ type: directory
+ description: MultiQC data dir
+ pattern: "multiqc_data"
+ - plots:
+ - "*_plots":
+ type: file
+ description: Plots created by MultiQC
+ pattern: "*_data"
+ - versions:
+ - versions.yml:
+ type: file
+ description: File containing software versions
+ pattern: "versions.yml"
+authors:
+ - "@abhi18av"
+ - "@bunop"
+ - "@drpatelh"
+ - "@jfy133"
+maintainers:
+ - "@abhi18av"
+ - "@bunop"
+ - "@drpatelh"
+ - "@jfy133"
diff --git a/modules/nf-core/multiqc/tests/main.nf.test b/modules/nf-core/multiqc/tests/main.nf.test
new file mode 100644
index 0000000..33316a7
--- /dev/null
+++ b/modules/nf-core/multiqc/tests/main.nf.test
@@ -0,0 +1,92 @@
+nextflow_process {
+
+ name "Test Process MULTIQC"
+ script "../main.nf"
+ process "MULTIQC"
+
+ tag "modules"
+ tag "modules_nfcore"
+ tag "multiqc"
+
+ config "./nextflow.config"
+
+ test("sarscov2 single-end [fastqc]") {
+
+ when {
+ process {
+ """
+ input[0] = Channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true))
+ input[1] = []
+ input[2] = []
+ input[3] = []
+ input[4] = []
+ input[5] = []
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert process.out.report[0] ==~ ".*/multiqc_report.html" },
+ { assert process.out.data[0] ==~ ".*/multiqc_data" },
+ { assert snapshot(process.out.versions).match("multiqc_versions_single") }
+ )
+ }
+
+ }
+
+ test("sarscov2 single-end [fastqc] [config]") {
+
+ when {
+ process {
+ """
+ input[0] = Channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true))
+ input[1] = Channel.of(file("https://github.com/nf-core/tools/raw/dev/nf_core/pipeline-template/assets/multiqc_config.yml", checkIfExists: true))
+ input[2] = []
+ input[3] = []
+ input[4] = []
+ input[5] = []
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert process.out.report[0] ==~ ".*/multiqc_report.html" },
+ { assert process.out.data[0] ==~ ".*/multiqc_data" },
+ { assert snapshot(process.out.versions).match("multiqc_versions_config") }
+ )
+ }
+ }
+
+ test("sarscov2 single-end [fastqc] - stub") {
+
+ options "-stub"
+
+ when {
+ process {
+ """
+ input[0] = Channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true))
+ input[1] = []
+ input[2] = []
+ input[3] = []
+ input[4] = []
+ input[5] = []
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out.report.collect { file(it).getName() } +
+ process.out.data.collect { file(it).getName() } +
+ process.out.plots.collect { file(it).getName() } +
+ process.out.versions ).match("multiqc_stub") }
+ )
+ }
+
+ }
+}
diff --git a/modules/nf-core/multiqc/tests/main.nf.test.snap b/modules/nf-core/multiqc/tests/main.nf.test.snap
new file mode 100644
index 0000000..2fcbb5f
--- /dev/null
+++ b/modules/nf-core/multiqc/tests/main.nf.test.snap
@@ -0,0 +1,41 @@
+{
+ "multiqc_versions_single": {
+ "content": [
+ [
+ "versions.yml:md5,41f391dcedce7f93ca188f3a3ffa0916"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-02T17:51:46.317523"
+ },
+ "multiqc_stub": {
+ "content": [
+ [
+ "multiqc_report.html",
+ "multiqc_data",
+ "multiqc_plots",
+ "versions.yml:md5,41f391dcedce7f93ca188f3a3ffa0916"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-02T17:52:20.680978"
+ },
+ "multiqc_versions_config": {
+ "content": [
+ [
+ "versions.yml:md5,41f391dcedce7f93ca188f3a3ffa0916"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-02T17:52:09.185842"
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/multiqc/tests/nextflow.config b/modules/nf-core/multiqc/tests/nextflow.config
new file mode 100644
index 0000000..c537a6a
--- /dev/null
+++ b/modules/nf-core/multiqc/tests/nextflow.config
@@ -0,0 +1,5 @@
+process {
+ withName: 'MULTIQC' {
+ ext.prefix = null
+ }
+}
diff --git a/modules/nf-core/multiqc/tests/tags.yml b/modules/nf-core/multiqc/tests/tags.yml
new file mode 100644
index 0000000..bea6c0d
--- /dev/null
+++ b/modules/nf-core/multiqc/tests/tags.yml
@@ -0,0 +1,2 @@
+multiqc:
+ - modules/nf-core/multiqc/**
diff --git a/modules/nf-core/picard/bedtointervallist/environment.yml b/modules/nf-core/picard/bedtointervallist/environment.yml
new file mode 100644
index 0000000..1d715d5
--- /dev/null
+++ b/modules/nf-core/picard/bedtointervallist/environment.yml
@@ -0,0 +1,5 @@
+channels:
+ - conda-forge
+ - bioconda
+dependencies:
+ - bioconda::picard=3.3.0
diff --git a/modules/nf-core/picard/bedtointervallist/main.nf b/modules/nf-core/picard/bedtointervallist/main.nf
new file mode 100644
index 0000000..c8eddb1
--- /dev/null
+++ b/modules/nf-core/picard/bedtointervallist/main.nf
@@ -0,0 +1,68 @@
+process PICARD_BEDTOINTERVALLIST {
+ 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/picard:3.3.0--hdfd78af_0' :
+ 'biocontainers/picard:3.3.0--hdfd78af_0' }"
+
+ input:
+ tuple val(meta) , path(bed)
+ tuple val(meta2), path(dict)
+ file arguments_file
+
+ output:
+ tuple val(meta), path('*.interval_list'), emit: interval_list
+ path "versions.yml" , emit: versions
+
+ when:
+ task.ext.when == null || task.ext.when
+
+ script:
+ def args = task.ext.args ?: ''
+ def prefix = task.ext.prefix ?: "${meta.id}"
+ def args_file = arguments_file ? "--arguments_file ${arguments_file}" : ""
+
+ def avail_mem = 3072
+ if (!task.memory) {
+ log.info '[Picard BedToIntervalList] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.'
+ } else {
+ avail_mem = (task.memory.mega*0.8).intValue()
+ }
+ """
+ picard \\
+ -Xmx${avail_mem}M \\
+ BedToIntervalList \\
+ --INPUT $bed \\
+ --OUTPUT ${prefix}.interval_list \\
+ --SEQUENCE_DICTIONARY $dict \\
+ --TMP_DIR . \\
+ $args_file $args
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ picard: \$(echo \$(picard BedToIntervalList --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:)
+ END_VERSIONS
+ """
+
+ stub:
+ def prefix = task.ext.prefix ?: "${meta.id}"
+ """
+ echo "picard \\
+ -Xmx${avail_mem}M \\
+ BedToIntervalList \\
+ --INPUT $bed \\
+ --OUTPUT ${prefix}.interval_list \\
+ --SEQUENCE_DICTIONARY $dict \\
+ --TMP_DIR . \\
+ $args_file $args"
+
+ touch ${prefix}.interval_list
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ picard: \$(echo \$(picard BedToIntervalList --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:)
+ END_VERSIONS
+ """
+}
diff --git a/modules/nf-core/picard/bedtointervallist/meta.yml b/modules/nf-core/picard/bedtointervallist/meta.yml
new file mode 100644
index 0000000..e9e35a2
--- /dev/null
+++ b/modules/nf-core/picard/bedtointervallist/meta.yml
@@ -0,0 +1,62 @@
+name: picard_bedtointervallist
+description: Creates an interval list from a bed file and a reference dict
+keywords:
+ - bed
+ - interval list
+ - picard
+ - convert
+tools:
+ - gatk4:
+ description: |
+ Developed in the Data Sciences Platform at the Broad Institute, the toolkit offers a wide variety of tools
+ with a primary focus on variant discovery and genotyping. Its powerful processing engine
+ and high-performance computing features make it capable of taking on projects of any size.
+ homepage: https://gatk.broadinstitute.org/hc/en-us
+ documentation: https://gatk.broadinstitute.org/hc/en-us/categories/360002369672s
+ doi: 10.1158/1538-7445.AM2017-3590
+ licence: ["Apache-2.0"]
+ identifier: biotools:picard_tools
+input:
+ - - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test']
+ - bed:
+ type: file
+ description: Input bed file
+ pattern: "*.bed"
+ - - meta2:
+ type: map
+ description: |
+ Groovy Map containing reference information
+ e.g. [ id:'genome']
+ - dict:
+ type: file
+ description: Sequence dictionary
+ pattern: "*.dict"
+output:
+ - interval_list:
+ - meta:
+ type: file
+ description: gatk interval list file
+ pattern: "*.interval_list"
+ - "*.interval_list":
+ type: file
+ description: gatk interval list file
+ pattern: "*.interval_list"
+ - _list:
+ type: file
+ description: gatk interval list file
+ pattern: "*.interval_list"
+ - versions:
+ - versions.yml:
+ type: file
+ description: File containing software versions
+ pattern: "versions.yml"
+authors:
+ - "@kevinmenden"
+ - "@matthdsm"
+maintainers:
+ - "@kevinmenden"
+ - "@matthdsm"
diff --git a/modules/nf-core/picard/bedtointervallist/tests/main.nf.test b/modules/nf-core/picard/bedtointervallist/tests/main.nf.test
new file mode 100644
index 0000000..fd13208
--- /dev/null
+++ b/modules/nf-core/picard/bedtointervallist/tests/main.nf.test
@@ -0,0 +1,40 @@
+
+nextflow_process {
+
+ name "Test Process PICARD_BEDTOINTERVALLIST"
+ script "../main.nf"
+ process "PICARD_BEDTOINTERVALLIST"
+
+ tag "modules"
+ tag "modules_nfcore"
+ tag "picard"
+ tag "picard/bedtointervallist"
+
+ test("test-picard-bedtointervallist") {
+
+ when {
+ process {
+ """
+ input[0] = [
+ [ id:'test' ], // meta map
+ [ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/test.bed', checkIfExists: true) ]
+ ]
+ input[1] = [
+ [ id:'test' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)
+ ]
+ input[2] = []
+
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+}
diff --git a/modules/nf-core/picard/bedtointervallist/tests/main.nf.test.snap b/modules/nf-core/picard/bedtointervallist/tests/main.nf.test.snap
new file mode 100644
index 0000000..7382eaf
--- /dev/null
+++ b/modules/nf-core/picard/bedtointervallist/tests/main.nf.test.snap
@@ -0,0 +1,35 @@
+{
+ "test-picard-bedtointervallist": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test"
+ },
+ "test.interval_list:md5,e51101c9357fb2d59fd30e370eefa39c"
+ ]
+ ],
+ "1": [
+ "versions.yml:md5,33540ea0c31ded2c1db95f82406034f8"
+ ],
+ "interval_list": [
+ [
+ {
+ "id": "test"
+ },
+ "test.interval_list:md5,e51101c9357fb2d59fd30e370eefa39c"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,33540ea0c31ded2c1db95f82406034f8"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-18T10:17:35.308452582"
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/picard/collecthsmetrics/environment.yml b/modules/nf-core/picard/collecthsmetrics/environment.yml
new file mode 100644
index 0000000..1d715d5
--- /dev/null
+++ b/modules/nf-core/picard/collecthsmetrics/environment.yml
@@ -0,0 +1,5 @@
+channels:
+ - conda-forge
+ - bioconda
+dependencies:
+ - bioconda::picard=3.3.0
diff --git a/modules/nf-core/picard/collecthsmetrics/main.nf b/modules/nf-core/picard/collecthsmetrics/main.nf
new file mode 100644
index 0000000..1d017ef
--- /dev/null
+++ b/modules/nf-core/picard/collecthsmetrics/main.nf
@@ -0,0 +1,82 @@
+process PICARD_COLLECTHSMETRICS {
+ 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/picard:3.3.0--hdfd78af_0' :
+ 'biocontainers/picard:3.3.0--hdfd78af_0' }"
+
+ input:
+ tuple val(meta), path(bam), path(bai), path(bait_intervals, stageAs: "baits/*"), path(target_intervals, stageAs: 'targets/*')
+ tuple val(meta2), path(fasta)
+ tuple val(meta3), path(fai)
+ tuple val(meta4), path(dict)
+
+ output:
+ tuple val(meta), path("*_metrics") , emit: metrics
+ path "versions.yml" , emit: versions
+
+ when:
+ task.ext.when == null || task.ext.when
+
+ script:
+ def args = task.ext.args ?: ''
+ def prefix = task.ext.prefix ?: "${meta.id}"
+ def reference = fasta ? "--REFERENCE_SEQUENCE ${fasta}" : ""
+
+ def avail_mem = 3072
+ if (!task.memory) {
+ log.info '[Picard CollectHsMetrics] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.'
+ } else {
+ avail_mem = (task.memory.mega*0.8).intValue()
+ }
+
+ def bait_interval_list = bait_intervals
+ def bait_intervallist_cmd = ""
+ if (bait_intervals =~ /.(bed|bed.gz)$/){
+ bait_interval_list = bait_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list")
+ bait_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${bait_intervals} --OUTPUT ${bait_interval_list} --SEQUENCE_DICTIONARY ${dict} --TMP_DIR ."
+ }
+
+ def target_interval_list = target_intervals
+ def target_intervallist_cmd = ""
+ if (target_intervals =~ /.(bed|bed.gz)$/){
+ target_interval_list = target_intervals.toString().replaceAll(/.(bed|bed.gz)$/, ".interval_list")
+ target_intervallist_cmd = "picard -Xmx${avail_mem}M BedToIntervalList --INPUT ${target_intervals} --OUTPUT ${target_interval_list} --SEQUENCE_DICTIONARY ${dict} --TMP_DIR ."
+ }
+
+
+ """
+
+ $bait_intervallist_cmd
+ $target_intervallist_cmd
+
+ picard \\
+ -Xmx${avail_mem}M \\
+ CollectHsMetrics \\
+ $args \\
+ $reference \\
+ --BAIT_INTERVALS $bait_interval_list \\
+ --TARGET_INTERVALS $target_interval_list \\
+ --INPUT $bam \\
+ --OUTPUT ${prefix}.CollectHsMetrics.coverage_metrics
+
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ picard: \$(echo \$(picard CollectHsMetrics --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:)
+ END_VERSIONS
+ """
+
+ stub:
+ def prefix = task.ext.prefix ?: "${meta.id}"
+ """
+ touch ${prefix}.CollectHsMetrics.coverage_metrics
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ picard: \$(echo \$(picard CollectHsMetrics --version 2>&1) | grep -o 'Version:.*' | cut -f2- -d:)
+ END_VERSIONS
+ """
+}
diff --git a/modules/nf-core/picard/collecthsmetrics/meta.yml b/modules/nf-core/picard/collecthsmetrics/meta.yml
new file mode 100644
index 0000000..ea6deda
--- /dev/null
+++ b/modules/nf-core/picard/collecthsmetrics/meta.yml
@@ -0,0 +1,94 @@
+name: picard_collecthsmetrics
+description: Collects hybrid-selection (HS) metrics for a SAM or BAM file.
+keywords:
+ - alignment
+ - metrics
+ - statistics
+ - insert
+ - hybrid-selection
+ - quality
+ - bam
+tools:
+ - picard:
+ description: |
+ A set of command line tools (in Java) for manipulating high-throughput sequencing (HTS)
+ data and formats such as SAM/BAM/CRAM and VCF.
+ homepage: https://broadinstitute.github.io/picard/
+ documentation: https://broadinstitute.github.io/picard/
+ tool_dev_url: https://github.com/broadinstitute/picard/
+ licence: ["MIT"]
+ identifier: biotools:picard_tools
+input:
+ - - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - bam:
+ type: file
+ description: An aligned BAM/CRAM/SAM file
+ pattern: "*.{bam,cram,sam}"
+ - bai:
+ type: file
+ description: Optional aligned BAM/CRAM/SAM file index
+ pattern: "*.{bai,crai,sai}"
+ - bait_intervals:
+ type: file
+ description: An interval file that contains the locations of the baits used.
+ pattern: "*.{interval_list,bed,bed.gz}"
+ - target_intervals:
+ type: file
+ description: An interval file that contains the locations of the targets.
+ pattern: "*.{interval_list,bed,bed.gz}"
+ - - meta2:
+ type: map
+ description: |
+ Groovy Map containing reference information
+ e.g. [ id:'genome' ]
+ - fasta:
+ type: file
+ description: |
+ A reference file to calculate dropout metrics measuring reduced representation of reads.
+ Optional input.
+ pattern: "*.{fa,fasta,fna}"
+ - - meta3:
+ type: map
+ description: |
+ Groovy Map containing reference information
+ e.g. [ id:'genome' ]
+ - fai:
+ type: file
+ description: Index of FASTA file. Only needed when fasta is supplied.
+ pattern: "*.fai"
+ - - meta4:
+ type: map
+ description: |
+ Groovy Map containing reference information
+ e.g. [ id:'genome' ]
+ - dict:
+ type: file
+ description: Sequence dictionary of FASTA file. Only needed when bed interval
+ lists are supplied.
+ pattern: "*.dict"
+output:
+ - metrics:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - "*_metrics":
+ type: file
+ description: Alignment metrics files generated by picard
+ pattern: "*_{metrics}"
+ - versions:
+ - versions.yml:
+ type: file
+ description: File containing software versions
+ pattern: "versions.yml"
+authors:
+ - "@projectoriented"
+ - "@matthdsm"
+maintainers:
+ - "@projectoriented"
+ - "@matthdsm"
diff --git a/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test b/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test
new file mode 100644
index 0000000..3bbbd8c
--- /dev/null
+++ b/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test
@@ -0,0 +1,191 @@
+nextflow_process {
+
+ name "Test Process PICARD_COLLECTHSMETRICS"
+ script "../main.nf"
+ process "PICARD_COLLECTHSMETRICS"
+
+ tag "modules"
+ tag "modules_nfcore"
+ tag "picard"
+ tag "picard/collecthsmetrics"
+
+ test("sarscov2 - bam") {
+
+ when {
+ process {
+ """
+ input[0] = [
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/baits.interval_list', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/targets.interval_list', checkIfExists: true)
+ ]
+ input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]
+ input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]
+ input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)]
+ """
+ }
+ }
+
+ then {
+ def size = path(process.out.metrics[0][1]).size()
+ def lines = path(process.out.metrics[0][1]).readLines()[0..100]
+ lines.remove(3) // remove timestamp
+ assertAll(
+ { assert process.success },
+ { assert snapshot(
+ file(process.out.metrics[0][1]).name,
+ size,
+ lines,
+ process.out.versions
+ ).match()
+ }
+ )
+ }
+
+ }
+
+ test("sarscov2 - bam - stub") {
+
+ options "-stub"
+
+ when {
+ process {
+ """
+ input[0] = [
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/baits.interval_list', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/targets.interval_list', checkIfExists: true)
+ ]
+ input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]
+ input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]
+ input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)]
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out.versions).match("versions") }
+ )
+ }
+
+ }
+
+ test("sarscov2 - bam - nofasta") {
+
+ when {
+ process {
+ """
+ input[0] = [
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/baits.interval_list', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/picard/targets.interval_list', checkIfExists: true)
+ ]
+ input[1] = [[:],[]]
+ input[2] = [[:],[]]
+ input[3] = [[:],[]]
+ """
+ }
+ }
+
+ then {
+ def size = path(process.out.metrics[0][1]).size()
+ def lines = path(process.out.metrics[0][1]).readLines()[0..100]
+ lines.remove(3) // remove timestamp
+ assertAll(
+ { assert process.success },
+ { assert snapshot(
+ file(process.out.metrics[0][1]).name,
+ size,
+ lines,
+ process.out.versions
+ ).match()
+ }
+ )
+ }
+
+ }
+
+ test("sarscov2 - bam - bed") {
+
+ when {
+ process {
+ """
+ input[0] = [
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/baits.bed', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/test.bed', checkIfExists: true)
+ ]
+
+ input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]
+ input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]
+ input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)]
+ """
+ }
+ }
+
+ then {
+ def size = path(process.out.metrics[0][1]).size()
+ def lines = path(process.out.metrics[0][1]).readLines()[0..100]
+ lines.remove(3) // remove timestamp
+ assertAll(
+ { assert process.success },
+ { assert snapshot(
+ file(process.out.metrics[0][1]).name,
+ size,
+ lines,
+ process.out.versions
+ ).match()
+ }
+ )
+ }
+
+ }
+
+ test("sarscov2 - bam - samebed") {
+
+ when {
+ process {
+ """
+ input[0] = [
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/baits.bed', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/bed/baits.bed', checkIfExists: true)
+ ]
+
+ input[1] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)]
+ input[2] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta.fai', checkIfExists: true)]
+ input[3] = [[id:'genome'], file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.dict', checkIfExists: true)]
+ """
+ }
+ }
+
+ then {
+ def size = path(process.out.metrics[0][1]).size()
+ def lines = path(process.out.metrics[0][1]).readLines()[0..100]
+ lines.remove(3) // remove timestamp
+ assertAll(
+ { assert process.success },
+ { assert snapshot(
+ file(process.out.metrics[0][1]).name,
+ size,
+ lines,
+ process.out.versions
+ ).match()
+ }
+ )
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test.snap b/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test.snap
new file mode 100644
index 0000000..4d21710
--- /dev/null
+++ b/modules/nf-core/picard/collecthsmetrics/tests/main.nf.test.snap
@@ -0,0 +1,478 @@
+{
+ "sarscov2 - bam - nofasta": {
+ "content": [
+ "test.CollectHsMetrics.coverage_metrics",
+ 3548,
+ [
+ "## htsjdk.samtools.metrics.StringHeader",
+ "# CollectHsMetrics --BAIT_INTERVALS baits/baits.interval_list --TARGET_INTERVALS targets/targets.interval_list --INPUT test.paired_end.sorted.bam --OUTPUT test.CollectHsMetrics.coverage_metrics --METRIC_ACCUMULATION_LEVEL ALL_READS --NEAR_DISTANCE 250 --MINIMUM_MAPPING_QUALITY 20 --MINIMUM_BASE_QUALITY 20 --CLIP_OVERLAPPING_READS true --INCLUDE_INDELS false --COVERAGE_CAP 200 --SAMPLE_SIZE 10000 --ALLELE_FRACTION 0.001 --ALLELE_FRACTION 0.005 --ALLELE_FRACTION 0.01 --ALLELE_FRACTION 0.02 --ALLELE_FRACTION 0.05 --ALLELE_FRACTION 0.1 --ALLELE_FRACTION 0.2 --ALLELE_FRACTION 0.3 --ALLELE_FRACTION 0.5 --VERBOSITY INFO --QUIET false --VALIDATION_STRINGENCY STRICT --COMPRESSION_LEVEL 5 --MAX_RECORDS_IN_RAM 500000 --CREATE_INDEX false --CREATE_MD5_FILE false --help false --version false --showHidden false --USE_JDK_DEFLATER false --USE_JDK_INFLATER false",
+ "## htsjdk.samtools.metrics.StringHeader",
+ "",
+ "## METRICS CLASS\tpicard.analysis.directed.HsMetrics",
+ "BAIT_SET\tBAIT_TERRITORY\tBAIT_DESIGN_EFFICIENCY\tON_BAIT_BASES\tNEAR_BAIT_BASES\tOFF_BAIT_BASES\tPCT_SELECTED_BASES\tPCT_OFF_BAIT\tON_BAIT_VS_SELECTED\tMEAN_BAIT_COVERAGE\tPCT_USABLE_BASES_ON_BAIT\tPCT_USABLE_BASES_ON_TARGET\tFOLD_ENRICHMENT\tHS_LIBRARY_SIZE\tHS_PENALTY_10X\tHS_PENALTY_20X\tHS_PENALTY_30X\tHS_PENALTY_40X\tHS_PENALTY_50X\tHS_PENALTY_100X\tTARGET_TERRITORY\tGENOME_SIZE\tTOTAL_READS\tPF_READS\tPF_BASES\tPF_UNIQUE_READS\tPF_UQ_READS_ALIGNED\tPF_BASES_ALIGNED\tPF_UQ_BASES_ALIGNED\tON_TARGET_BASES\tPCT_PF_READS\tPCT_PF_UQ_READS\tPCT_PF_UQ_READS_ALIGNED\tMEAN_TARGET_COVERAGE\tMEDIAN_TARGET_COVERAGE\tMAX_TARGET_COVERAGE\tMIN_TARGET_COVERAGE\tZERO_CVG_TARGETS_PCT\tPCT_EXC_DUPE\tPCT_EXC_ADAPTER\tPCT_EXC_MAPQ\tPCT_EXC_BASEQ\tPCT_EXC_OVERLAP\tPCT_EXC_OFF_TARGET\tFOLD_80_BASE_PENALTY\tPCT_TARGET_BASES_1X\tPCT_TARGET_BASES_2X\tPCT_TARGET_BASES_10X\tPCT_TARGET_BASES_20X\tPCT_TARGET_BASES_30X\tPCT_TARGET_BASES_40X\tPCT_TARGET_BASES_50X\tPCT_TARGET_BASES_100X\tPCT_TARGET_BASES_250X\tPCT_TARGET_BASES_500X\tPCT_TARGET_BASES_1000X\tPCT_TARGET_BASES_2500X\tPCT_TARGET_BASES_5000X\tPCT_TARGET_BASES_10000X\tPCT_TARGET_BASES_25000X\tPCT_TARGET_BASES_50000X\tPCT_TARGET_BASES_100000X\tAT_DROPOUT\tGC_DROPOUT\tHET_SNP_SENSITIVITY\tHET_SNP_Q\tSAMPLE\tLIBRARY\tREAD_GROUP",
+ "baits\t158\t0.594937\t725\t3985\t22691\t0.171892\t0.828108\t0.153928\t4.588608\t0.026225\t0.000181\t4.995204\t\t0\t0\t0\t0\t0\t0\t94\t29829\t200\t200\t27645\t200\t197\t27401\t27401\t5\t1\t1\t0.985\t0.053191\t0\t1\t0\t0.75\t0\t0\t0.005438\t0.054487\t0.259516\t0.680377\t?\t0.053191\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0.015734\t0\t\t\t",
+ "",
+ "## HISTOGRAM\tjava.lang.Integer",
+ "coverage_or_base_quality\thigh_quality_coverage_count\tunfiltered_baseq_count",
+ "0\t89\t0",
+ "1\t5\t0",
+ "2\t0\t0",
+ "3\t0\t0",
+ "4\t0\t0",
+ "5\t0\t0",
+ "6\t0\t0",
+ "7\t0\t0",
+ "8\t0\t0",
+ "9\t0\t0",
+ "10\t0\t0",
+ "11\t0\t0",
+ "12\t0\t0",
+ "13\t0\t0",
+ "14\t0\t5",
+ "15\t0\t0",
+ "16\t0\t0",
+ "17\t0\t0",
+ "18\t0\t0",
+ "19\t0\t0",
+ "20\t0\t0",
+ "21\t0\t1",
+ "22\t0\t0",
+ "23\t0\t0",
+ "24\t0\t0",
+ "25\t0\t0",
+ "26\t0\t0",
+ "27\t0\t0",
+ "28\t0\t0",
+ "29\t0\t0",
+ "30\t0\t0",
+ "31\t0\t0",
+ "32\t0\t1",
+ "33\t0\t0",
+ "34\t0\t0",
+ "35\t0\t0",
+ "36\t0\t3",
+ "37\t0\t0",
+ "38\t0\t0",
+ "39\t0\t0",
+ "40\t0\t0",
+ "41\t0\t0",
+ "42\t0\t0",
+ "43\t0\t0",
+ "44\t0\t0",
+ "45\t0\t0",
+ "46\t0\t0",
+ "47\t0\t0",
+ "48\t0\t0",
+ "49\t0\t0",
+ "50\t0\t0",
+ "51\t0\t0",
+ "52\t0\t0",
+ "53\t0\t0",
+ "54\t0\t0",
+ "55\t0\t0",
+ "56\t0\t0",
+ "57\t0\t0",
+ "58\t0\t0",
+ "59\t0\t0",
+ "60\t0\t0",
+ "61\t0\t0",
+ "62\t0\t0",
+ "63\t0\t0",
+ "64\t0\t0",
+ "65\t0\t0",
+ "66\t0\t0",
+ "67\t0\t0",
+ "68\t0\t0",
+ "69\t0\t0",
+ "70\t0\t0",
+ "71\t0\t0",
+ "72\t0\t0",
+ "73\t0\t0",
+ "74\t0\t0",
+ "75\t0\t0",
+ "76\t0\t0",
+ "77\t0\t0",
+ "78\t0\t0",
+ "79\t0\t0",
+ "80\t0\t0",
+ "81\t0\t0",
+ "82\t0\t0",
+ "83\t0\t0",
+ "84\t0\t0",
+ "85\t0\t0",
+ "86\t0\t0",
+ "87\t0\t0",
+ "88\t0\t0",
+ "89\t0\t0"
+ ],
+ [
+ "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-18T10:51:55.291163084"
+ },
+ "versions": {
+ "content": [
+ [
+ "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-18T10:51:30.748857589"
+ },
+ "sarscov2 - bam - samebed": {
+ "content": [
+ "test.CollectHsMetrics.coverage_metrics",
+ 3586,
+ [
+ "## htsjdk.samtools.metrics.StringHeader",
+ "# CollectHsMetrics --BAIT_INTERVALS baits/baits.interval_list --TARGET_INTERVALS targets/baits.interval_list --INPUT test.paired_end.sorted.bam --OUTPUT test.CollectHsMetrics.coverage_metrics --REFERENCE_SEQUENCE genome.fasta --METRIC_ACCUMULATION_LEVEL ALL_READS --NEAR_DISTANCE 250 --MINIMUM_MAPPING_QUALITY 20 --MINIMUM_BASE_QUALITY 20 --CLIP_OVERLAPPING_READS true --INCLUDE_INDELS false --COVERAGE_CAP 200 --SAMPLE_SIZE 10000 --ALLELE_FRACTION 0.001 --ALLELE_FRACTION 0.005 --ALLELE_FRACTION 0.01 --ALLELE_FRACTION 0.02 --ALLELE_FRACTION 0.05 --ALLELE_FRACTION 0.1 --ALLELE_FRACTION 0.2 --ALLELE_FRACTION 0.3 --ALLELE_FRACTION 0.5 --VERBOSITY INFO --QUIET false --VALIDATION_STRINGENCY STRICT --COMPRESSION_LEVEL 5 --MAX_RECORDS_IN_RAM 500000 --CREATE_INDEX false --CREATE_MD5_FILE false --help false --version false --showHidden false --USE_JDK_DEFLATER false --USE_JDK_INFLATER false",
+ "## htsjdk.samtools.metrics.StringHeader",
+ "",
+ "## METRICS CLASS\tpicard.analysis.directed.HsMetrics",
+ "BAIT_SET\tBAIT_TERRITORY\tBAIT_DESIGN_EFFICIENCY\tON_BAIT_BASES\tNEAR_BAIT_BASES\tOFF_BAIT_BASES\tPCT_SELECTED_BASES\tPCT_OFF_BAIT\tON_BAIT_VS_SELECTED\tMEAN_BAIT_COVERAGE\tPCT_USABLE_BASES_ON_BAIT\tPCT_USABLE_BASES_ON_TARGET\tFOLD_ENRICHMENT\tHS_LIBRARY_SIZE\tHS_PENALTY_10X\tHS_PENALTY_20X\tHS_PENALTY_30X\tHS_PENALTY_40X\tHS_PENALTY_50X\tHS_PENALTY_100X\tTARGET_TERRITORY\tGENOME_SIZE\tTOTAL_READS\tPF_READS\tPF_BASES\tPF_UNIQUE_READS\tPF_UQ_READS_ALIGNED\tPF_BASES_ALIGNED\tPF_UQ_BASES_ALIGNED\tON_TARGET_BASES\tPCT_PF_READS\tPCT_PF_UQ_READS\tPCT_PF_UQ_READS_ALIGNED\tMEAN_TARGET_COVERAGE\tMEDIAN_TARGET_COVERAGE\tMAX_TARGET_COVERAGE\tMIN_TARGET_COVERAGE\tZERO_CVG_TARGETS_PCT\tPCT_EXC_DUPE\tPCT_EXC_ADAPTER\tPCT_EXC_MAPQ\tPCT_EXC_BASEQ\tPCT_EXC_OVERLAP\tPCT_EXC_OFF_TARGET\tFOLD_80_BASE_PENALTY\tPCT_TARGET_BASES_1X\tPCT_TARGET_BASES_2X\tPCT_TARGET_BASES_10X\tPCT_TARGET_BASES_20X\tPCT_TARGET_BASES_30X\tPCT_TARGET_BASES_40X\tPCT_TARGET_BASES_50X\tPCT_TARGET_BASES_100X\tPCT_TARGET_BASES_250X\tPCT_TARGET_BASES_500X\tPCT_TARGET_BASES_1000X\tPCT_TARGET_BASES_2500X\tPCT_TARGET_BASES_5000X\tPCT_TARGET_BASES_10000X\tPCT_TARGET_BASES_25000X\tPCT_TARGET_BASES_50000X\tPCT_TARGET_BASES_100000X\tAT_DROPOUT\tGC_DROPOUT\tHET_SNP_SENSITIVITY\tHET_SNP_Q\tSAMPLE\tLIBRARY\tREAD_GROUP",
+ "baits\t158\t1\t725\t3985\t22691\t0.171892\t0.828108\t0.153928\t4.588608\t0.026225\t0.013782\t4.995204\t\t0\t0\t0\t0\t0\t0\t158\t29829\t200\t200\t27645\t200\t197\t27401\t27401\t381\t1\t1\t0.985\t2.411392\t2\t3\t2\t0\t0\t0\t0.005438\t0.054487\t0.259516\t0.666655\t1.205696\t1\t1\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t7.018506\t0\t0.394337\t2\t\t\t",
+ "",
+ "## HISTOGRAM\tjava.lang.Integer",
+ "coverage_or_base_quality\thigh_quality_coverage_count\tunfiltered_baseq_count",
+ "0\t0\t0",
+ "1\t0\t0",
+ "2\t93\t0",
+ "3\t65\t0",
+ "4\t0\t0",
+ "5\t0\t0",
+ "6\t0\t0",
+ "7\t0\t0",
+ "8\t0\t0",
+ "9\t0\t0",
+ "10\t0\t0",
+ "11\t0\t0",
+ "12\t0\t0",
+ "13\t0\t0",
+ "14\t0\t28",
+ "15\t0\t0",
+ "16\t0\t0",
+ "17\t0\t0",
+ "18\t0\t0",
+ "19\t0\t0",
+ "20\t0\t0",
+ "21\t0\t9",
+ "22\t0\t0",
+ "23\t0\t0",
+ "24\t0\t0",
+ "25\t0\t0",
+ "26\t0\t0",
+ "27\t0\t20",
+ "28\t0\t0",
+ "29\t0\t0",
+ "30\t0\t0",
+ "31\t0\t0",
+ "32\t0\t90",
+ "33\t0\t0",
+ "34\t0\t0",
+ "35\t0\t0",
+ "36\t0\t262",
+ "37\t0\t0",
+ "38\t0\t0",
+ "39\t0\t0",
+ "40\t0\t0",
+ "41\t0\t0",
+ "42\t0\t0",
+ "43\t0\t0",
+ "44\t0\t0",
+ "45\t0\t0",
+ "46\t0\t0",
+ "47\t0\t0",
+ "48\t0\t0",
+ "49\t0\t0",
+ "50\t0\t0",
+ "51\t0\t0",
+ "52\t0\t0",
+ "53\t0\t0",
+ "54\t0\t0",
+ "55\t0\t0",
+ "56\t0\t0",
+ "57\t0\t0",
+ "58\t0\t0",
+ "59\t0\t0",
+ "60\t0\t0",
+ "61\t0\t0",
+ "62\t0\t0",
+ "63\t0\t0",
+ "64\t0\t0",
+ "65\t0\t0",
+ "66\t0\t0",
+ "67\t0\t0",
+ "68\t0\t0",
+ "69\t0\t0",
+ "70\t0\t0",
+ "71\t0\t0",
+ "72\t0\t0",
+ "73\t0\t0",
+ "74\t0\t0",
+ "75\t0\t0",
+ "76\t0\t0",
+ "77\t0\t0",
+ "78\t0\t0",
+ "79\t0\t0",
+ "80\t0\t0",
+ "81\t0\t0",
+ "82\t0\t0",
+ "83\t0\t0",
+ "84\t0\t0",
+ "85\t0\t0",
+ "86\t0\t0",
+ "87\t0\t0",
+ "88\t0\t0",
+ "89\t0\t0"
+ ],
+ [
+ "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-18T10:52:43.803456585"
+ },
+ "sarscov2 - bam": {
+ "content": [
+ "test.CollectHsMetrics.coverage_metrics",
+ 3598,
+ [
+ "## htsjdk.samtools.metrics.StringHeader",
+ "# CollectHsMetrics --BAIT_INTERVALS baits/baits.interval_list --TARGET_INTERVALS targets/targets.interval_list --INPUT test.paired_end.sorted.bam --OUTPUT test.CollectHsMetrics.coverage_metrics --REFERENCE_SEQUENCE genome.fasta --METRIC_ACCUMULATION_LEVEL ALL_READS --NEAR_DISTANCE 250 --MINIMUM_MAPPING_QUALITY 20 --MINIMUM_BASE_QUALITY 20 --CLIP_OVERLAPPING_READS true --INCLUDE_INDELS false --COVERAGE_CAP 200 --SAMPLE_SIZE 10000 --ALLELE_FRACTION 0.001 --ALLELE_FRACTION 0.005 --ALLELE_FRACTION 0.01 --ALLELE_FRACTION 0.02 --ALLELE_FRACTION 0.05 --ALLELE_FRACTION 0.1 --ALLELE_FRACTION 0.2 --ALLELE_FRACTION 0.3 --ALLELE_FRACTION 0.5 --VERBOSITY INFO --QUIET false --VALIDATION_STRINGENCY STRICT --COMPRESSION_LEVEL 5 --MAX_RECORDS_IN_RAM 500000 --CREATE_INDEX false --CREATE_MD5_FILE false --help false --version false --showHidden false --USE_JDK_DEFLATER false --USE_JDK_INFLATER false",
+ "## htsjdk.samtools.metrics.StringHeader",
+ "",
+ "## METRICS CLASS\tpicard.analysis.directed.HsMetrics",
+ "BAIT_SET\tBAIT_TERRITORY\tBAIT_DESIGN_EFFICIENCY\tON_BAIT_BASES\tNEAR_BAIT_BASES\tOFF_BAIT_BASES\tPCT_SELECTED_BASES\tPCT_OFF_BAIT\tON_BAIT_VS_SELECTED\tMEAN_BAIT_COVERAGE\tPCT_USABLE_BASES_ON_BAIT\tPCT_USABLE_BASES_ON_TARGET\tFOLD_ENRICHMENT\tHS_LIBRARY_SIZE\tHS_PENALTY_10X\tHS_PENALTY_20X\tHS_PENALTY_30X\tHS_PENALTY_40X\tHS_PENALTY_50X\tHS_PENALTY_100X\tTARGET_TERRITORY\tGENOME_SIZE\tTOTAL_READS\tPF_READS\tPF_BASES\tPF_UNIQUE_READS\tPF_UQ_READS_ALIGNED\tPF_BASES_ALIGNED\tPF_UQ_BASES_ALIGNED\tON_TARGET_BASES\tPCT_PF_READS\tPCT_PF_UQ_READS\tPCT_PF_UQ_READS_ALIGNED\tMEAN_TARGET_COVERAGE\tMEDIAN_TARGET_COVERAGE\tMAX_TARGET_COVERAGE\tMIN_TARGET_COVERAGE\tZERO_CVG_TARGETS_PCT\tPCT_EXC_DUPE\tPCT_EXC_ADAPTER\tPCT_EXC_MAPQ\tPCT_EXC_BASEQ\tPCT_EXC_OVERLAP\tPCT_EXC_OFF_TARGET\tFOLD_80_BASE_PENALTY\tPCT_TARGET_BASES_1X\tPCT_TARGET_BASES_2X\tPCT_TARGET_BASES_10X\tPCT_TARGET_BASES_20X\tPCT_TARGET_BASES_30X\tPCT_TARGET_BASES_40X\tPCT_TARGET_BASES_50X\tPCT_TARGET_BASES_100X\tPCT_TARGET_BASES_250X\tPCT_TARGET_BASES_500X\tPCT_TARGET_BASES_1000X\tPCT_TARGET_BASES_2500X\tPCT_TARGET_BASES_5000X\tPCT_TARGET_BASES_10000X\tPCT_TARGET_BASES_25000X\tPCT_TARGET_BASES_50000X\tPCT_TARGET_BASES_100000X\tAT_DROPOUT\tGC_DROPOUT\tHET_SNP_SENSITIVITY\tHET_SNP_Q\tSAMPLE\tLIBRARY\tREAD_GROUP",
+ "baits\t158\t0.594937\t725\t3985\t22691\t0.171892\t0.828108\t0.153928\t4.588608\t0.026225\t0.000181\t4.995204\t\t0\t0\t0\t0\t0\t0\t94\t29829\t200\t200\t27645\t200\t197\t27401\t27401\t5\t1\t1\t0.985\t0.053191\t0\t1\t0\t0.75\t0\t0\t0.005438\t0.054487\t0.259516\t0.680377\t?\t0.053191\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t76.595745\t23.404255\t0.015734\t0\t\t\t",
+ "",
+ "## HISTOGRAM\tjava.lang.Integer",
+ "coverage_or_base_quality\thigh_quality_coverage_count\tunfiltered_baseq_count",
+ "0\t89\t0",
+ "1\t5\t0",
+ "2\t0\t0",
+ "3\t0\t0",
+ "4\t0\t0",
+ "5\t0\t0",
+ "6\t0\t0",
+ "7\t0\t0",
+ "8\t0\t0",
+ "9\t0\t0",
+ "10\t0\t0",
+ "11\t0\t0",
+ "12\t0\t0",
+ "13\t0\t0",
+ "14\t0\t5",
+ "15\t0\t0",
+ "16\t0\t0",
+ "17\t0\t0",
+ "18\t0\t0",
+ "19\t0\t0",
+ "20\t0\t0",
+ "21\t0\t1",
+ "22\t0\t0",
+ "23\t0\t0",
+ "24\t0\t0",
+ "25\t0\t0",
+ "26\t0\t0",
+ "27\t0\t0",
+ "28\t0\t0",
+ "29\t0\t0",
+ "30\t0\t0",
+ "31\t0\t0",
+ "32\t0\t1",
+ "33\t0\t0",
+ "34\t0\t0",
+ "35\t0\t0",
+ "36\t0\t3",
+ "37\t0\t0",
+ "38\t0\t0",
+ "39\t0\t0",
+ "40\t0\t0",
+ "41\t0\t0",
+ "42\t0\t0",
+ "43\t0\t0",
+ "44\t0\t0",
+ "45\t0\t0",
+ "46\t0\t0",
+ "47\t0\t0",
+ "48\t0\t0",
+ "49\t0\t0",
+ "50\t0\t0",
+ "51\t0\t0",
+ "52\t0\t0",
+ "53\t0\t0",
+ "54\t0\t0",
+ "55\t0\t0",
+ "56\t0\t0",
+ "57\t0\t0",
+ "58\t0\t0",
+ "59\t0\t0",
+ "60\t0\t0",
+ "61\t0\t0",
+ "62\t0\t0",
+ "63\t0\t0",
+ "64\t0\t0",
+ "65\t0\t0",
+ "66\t0\t0",
+ "67\t0\t0",
+ "68\t0\t0",
+ "69\t0\t0",
+ "70\t0\t0",
+ "71\t0\t0",
+ "72\t0\t0",
+ "73\t0\t0",
+ "74\t0\t0",
+ "75\t0\t0",
+ "76\t0\t0",
+ "77\t0\t0",
+ "78\t0\t0",
+ "79\t0\t0",
+ "80\t0\t0",
+ "81\t0\t0",
+ "82\t0\t0",
+ "83\t0\t0",
+ "84\t0\t0",
+ "85\t0\t0",
+ "86\t0\t0",
+ "87\t0\t0",
+ "88\t0\t0",
+ "89\t0\t0"
+ ],
+ [
+ "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-18T10:51:01.881343611"
+ },
+ "sarscov2 - bam - bed": {
+ "content": [
+ "test.CollectHsMetrics.coverage_metrics",
+ 3595,
+ [
+ "## htsjdk.samtools.metrics.StringHeader",
+ "# CollectHsMetrics --BAIT_INTERVALS baits/baits.interval_list --TARGET_INTERVALS targets/test.interval_list --INPUT test.paired_end.sorted.bam --OUTPUT test.CollectHsMetrics.coverage_metrics --REFERENCE_SEQUENCE genome.fasta --METRIC_ACCUMULATION_LEVEL ALL_READS --NEAR_DISTANCE 250 --MINIMUM_MAPPING_QUALITY 20 --MINIMUM_BASE_QUALITY 20 --CLIP_OVERLAPPING_READS true --INCLUDE_INDELS false --COVERAGE_CAP 200 --SAMPLE_SIZE 10000 --ALLELE_FRACTION 0.001 --ALLELE_FRACTION 0.005 --ALLELE_FRACTION 0.01 --ALLELE_FRACTION 0.02 --ALLELE_FRACTION 0.05 --ALLELE_FRACTION 0.1 --ALLELE_FRACTION 0.2 --ALLELE_FRACTION 0.3 --ALLELE_FRACTION 0.5 --VERBOSITY INFO --QUIET false --VALIDATION_STRINGENCY STRICT --COMPRESSION_LEVEL 5 --MAX_RECORDS_IN_RAM 500000 --CREATE_INDEX false --CREATE_MD5_FILE false --help false --version false --showHidden false --USE_JDK_DEFLATER false --USE_JDK_INFLATER false",
+ "## htsjdk.samtools.metrics.StringHeader",
+ "",
+ "## METRICS CLASS\tpicard.analysis.directed.HsMetrics",
+ "BAIT_SET\tBAIT_TERRITORY\tBAIT_DESIGN_EFFICIENCY\tON_BAIT_BASES\tNEAR_BAIT_BASES\tOFF_BAIT_BASES\tPCT_SELECTED_BASES\tPCT_OFF_BAIT\tON_BAIT_VS_SELECTED\tMEAN_BAIT_COVERAGE\tPCT_USABLE_BASES_ON_BAIT\tPCT_USABLE_BASES_ON_TARGET\tFOLD_ENRICHMENT\tHS_LIBRARY_SIZE\tHS_PENALTY_10X\tHS_PENALTY_20X\tHS_PENALTY_30X\tHS_PENALTY_40X\tHS_PENALTY_50X\tHS_PENALTY_100X\tTARGET_TERRITORY\tGENOME_SIZE\tTOTAL_READS\tPF_READS\tPF_BASES\tPF_UNIQUE_READS\tPF_UQ_READS_ALIGNED\tPF_BASES_ALIGNED\tPF_UQ_BASES_ALIGNED\tON_TARGET_BASES\tPCT_PF_READS\tPCT_PF_UQ_READS\tPCT_PF_UQ_READS_ALIGNED\tMEAN_TARGET_COVERAGE\tMEDIAN_TARGET_COVERAGE\tMAX_TARGET_COVERAGE\tMIN_TARGET_COVERAGE\tZERO_CVG_TARGETS_PCT\tPCT_EXC_DUPE\tPCT_EXC_ADAPTER\tPCT_EXC_MAPQ\tPCT_EXC_BASEQ\tPCT_EXC_OVERLAP\tPCT_EXC_OFF_TARGET\tFOLD_80_BASE_PENALTY\tPCT_TARGET_BASES_1X\tPCT_TARGET_BASES_2X\tPCT_TARGET_BASES_10X\tPCT_TARGET_BASES_20X\tPCT_TARGET_BASES_30X\tPCT_TARGET_BASES_40X\tPCT_TARGET_BASES_50X\tPCT_TARGET_BASES_100X\tPCT_TARGET_BASES_250X\tPCT_TARGET_BASES_500X\tPCT_TARGET_BASES_1000X\tPCT_TARGET_BASES_2500X\tPCT_TARGET_BASES_5000X\tPCT_TARGET_BASES_10000X\tPCT_TARGET_BASES_25000X\tPCT_TARGET_BASES_50000X\tPCT_TARGET_BASES_100000X\tAT_DROPOUT\tGC_DROPOUT\tHET_SNP_SENSITIVITY\tHET_SNP_Q\tSAMPLE\tLIBRARY\tREAD_GROUP",
+ "baits\t158\t0.594937\t725\t3985\t22691\t0.171892\t0.828108\t0.153928\t4.588608\t0.026225\t0.000181\t4.995204\t\t0\t0\t0\t0\t0\t0\t94\t29829\t200\t200\t27645\t200\t197\t27401\t27401\t5\t1\t1\t0.985\t0.053191\t0\t1\t0\t0.75\t0\t0\t0.005438\t0.054487\t0.259516\t0.680377\t?\t0.053191\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t76.595745\t23.404255\t0.015734\t0\t\t\t",
+ "",
+ "## HISTOGRAM\tjava.lang.Integer",
+ "coverage_or_base_quality\thigh_quality_coverage_count\tunfiltered_baseq_count",
+ "0\t89\t0",
+ "1\t5\t0",
+ "2\t0\t0",
+ "3\t0\t0",
+ "4\t0\t0",
+ "5\t0\t0",
+ "6\t0\t0",
+ "7\t0\t0",
+ "8\t0\t0",
+ "9\t0\t0",
+ "10\t0\t0",
+ "11\t0\t0",
+ "12\t0\t0",
+ "13\t0\t0",
+ "14\t0\t5",
+ "15\t0\t0",
+ "16\t0\t0",
+ "17\t0\t0",
+ "18\t0\t0",
+ "19\t0\t0",
+ "20\t0\t0",
+ "21\t0\t1",
+ "22\t0\t0",
+ "23\t0\t0",
+ "24\t0\t0",
+ "25\t0\t0",
+ "26\t0\t0",
+ "27\t0\t0",
+ "28\t0\t0",
+ "29\t0\t0",
+ "30\t0\t0",
+ "31\t0\t0",
+ "32\t0\t1",
+ "33\t0\t0",
+ "34\t0\t0",
+ "35\t0\t0",
+ "36\t0\t3",
+ "37\t0\t0",
+ "38\t0\t0",
+ "39\t0\t0",
+ "40\t0\t0",
+ "41\t0\t0",
+ "42\t0\t0",
+ "43\t0\t0",
+ "44\t0\t0",
+ "45\t0\t0",
+ "46\t0\t0",
+ "47\t0\t0",
+ "48\t0\t0",
+ "49\t0\t0",
+ "50\t0\t0",
+ "51\t0\t0",
+ "52\t0\t0",
+ "53\t0\t0",
+ "54\t0\t0",
+ "55\t0\t0",
+ "56\t0\t0",
+ "57\t0\t0",
+ "58\t0\t0",
+ "59\t0\t0",
+ "60\t0\t0",
+ "61\t0\t0",
+ "62\t0\t0",
+ "63\t0\t0",
+ "64\t0\t0",
+ "65\t0\t0",
+ "66\t0\t0",
+ "67\t0\t0",
+ "68\t0\t0",
+ "69\t0\t0",
+ "70\t0\t0",
+ "71\t0\t0",
+ "72\t0\t0",
+ "73\t0\t0",
+ "74\t0\t0",
+ "75\t0\t0",
+ "76\t0\t0",
+ "77\t0\t0",
+ "78\t0\t0",
+ "79\t0\t0",
+ "80\t0\t0",
+ "81\t0\t0",
+ "82\t0\t0",
+ "83\t0\t0",
+ "84\t0\t0",
+ "85\t0\t0",
+ "86\t0\t0",
+ "87\t0\t0",
+ "88\t0\t0",
+ "89\t0\t0"
+ ],
+ [
+ "versions.yml:md5,bdfc7b655683e7b66f68e894c999805e"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-18T10:52:22.830749735"
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/picard/collecthsmetrics/tests/tags.yml b/modules/nf-core/picard/collecthsmetrics/tests/tags.yml
new file mode 100644
index 0000000..b353f95
--- /dev/null
+++ b/modules/nf-core/picard/collecthsmetrics/tests/tags.yml
@@ -0,0 +1,2 @@
+picard/collecthsmetrics:
+ - "modules/nf-core/picard/collecthsmetrics/**"
diff --git a/modules/nf-core/picard/sortsam/environment.yml b/modules/nf-core/picard/sortsam/environment.yml
new file mode 100644
index 0000000..1d715d5
--- /dev/null
+++ b/modules/nf-core/picard/sortsam/environment.yml
@@ -0,0 +1,5 @@
+channels:
+ - conda-forge
+ - bioconda
+dependencies:
+ - bioconda::picard=3.3.0
diff --git a/modules/nf-core/picard/sortsam/main.nf b/modules/nf-core/picard/sortsam/main.nf
new file mode 100644
index 0000000..e3f4945
--- /dev/null
+++ b/modules/nf-core/picard/sortsam/main.nf
@@ -0,0 +1,46 @@
+process PICARD_SORTSAM {
+ 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/picard:3.3.0--hdfd78af_0' :
+ 'biocontainers/picard:3.3.0--hdfd78af_0' }"
+
+ input:
+ tuple val(meta), path(bam)
+ val sort_order
+
+ output:
+ tuple val(meta), path("*.bam"), emit: bam
+ path "versions.yml" , emit: versions
+
+ when:
+ task.ext.when == null || task.ext.when
+
+ script:
+ def args = task.ext.args ?: ''
+ def prefix = task.ext.prefix ?: "${meta.id}"
+ def avail_mem = 3072
+ if (!task.memory) {
+ log.info '[Picard SortSam] Available memory not known - defaulting to 3GB. Specify process memory requirements to change this.'
+ } else {
+ avail_mem = (task.memory.mega*0.8).intValue()
+ }
+
+ if ("$bam" == "${prefix}.bam") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!"
+
+ """
+ picard \\
+ SortSam \\
+ -Xmx${avail_mem}M \\
+ --INPUT $bam \\
+ --OUTPUT ${prefix}.bam \\
+ --SORT_ORDER $sort_order
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ picard: \$(picard SortSam --version 2>&1 | grep -o 'Version:.*' | cut -f2- -d:)
+ END_VERSIONS
+ """
+}
diff --git a/modules/nf-core/picard/sortsam/meta.yml b/modules/nf-core/picard/sortsam/meta.yml
new file mode 100644
index 0000000..24ea9d3
--- /dev/null
+++ b/modules/nf-core/picard/sortsam/meta.yml
@@ -0,0 +1,50 @@
+name: picard_sortsam
+description: Sorts BAM/SAM files based on a variety of picard specific criteria
+keywords:
+ - sort
+ - bam
+ - sam
+ - picard
+tools:
+ - picard:
+ description: |
+ A set of command line tools (in Java) for manipulating high-throughput sequencing (HTS)
+ data and formats such as SAM/BAM/CRAM and VCF.
+ homepage: https://broadinstitute.github.io/picard/
+ documentation: https://broadinstitute.github.io/picard/
+ licence: ["MIT"]
+ identifier: biotools:picard_tools
+input:
+ - - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - bam:
+ type: file
+ description: BAM/CRAM/SAM file
+ pattern: "*.{bam,sam}"
+ - - sort_order:
+ type: string
+ description: Picard sort order type
+ pattern: "unsorted|queryname|coordinate|duplicate|unknown"
+output:
+ - bam:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - "*.bam":
+ type: file
+ description: Sorted BAM/CRAM/SAM file
+ pattern: "*.{bam}"
+ - versions:
+ - versions.yml:
+ type: file
+ description: File containing software versions
+ pattern: "versions.yml"
+authors:
+ - "@jfy133"
+maintainers:
+ - "@jfy133"
diff --git a/modules/nf-core/picard/sortsam/tests/main.nf.test b/modules/nf-core/picard/sortsam/tests/main.nf.test
new file mode 100644
index 0000000..9d9af09
--- /dev/null
+++ b/modules/nf-core/picard/sortsam/tests/main.nf.test
@@ -0,0 +1,40 @@
+
+nextflow_process {
+
+ name "Test Process PICARD_SORTSAM"
+ script "../main.nf"
+ process "PICARD_SORTSAM"
+ config "./nextflow.config"
+
+ tag "modules"
+ tag "modules_nfcore"
+ tag "picard"
+ tag "picard/sortsam"
+
+ test("test-picard-sortsam") {
+
+ when {
+ process {
+ """
+ input[0] = [ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.single_end.bam', checkIfExists: true)
+ ]
+ input[1] = "queryname"
+
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(
+ bam(process.out.bam[0][1]).getReadsMD5(),
+ process.out.versions
+ ).match()
+ }
+ )
+ }
+ }
+
+}
diff --git a/modules/nf-core/picard/sortsam/tests/main.nf.test.snap b/modules/nf-core/picard/sortsam/tests/main.nf.test.snap
new file mode 100644
index 0000000..22728f4
--- /dev/null
+++ b/modules/nf-core/picard/sortsam/tests/main.nf.test.snap
@@ -0,0 +1,15 @@
+{
+ "test-picard-sortsam": {
+ "content": [
+ "b9847fed94d2b7286e18caaa099658ce",
+ [
+ "versions.yml:md5,b1d858b31471d4a0ce2407c491b6e299"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-18T10:09:43.110521445"
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/picard/sortsam/tests/nextflow.config b/modules/nf-core/picard/sortsam/tests/nextflow.config
new file mode 100644
index 0000000..8512101
--- /dev/null
+++ b/modules/nf-core/picard/sortsam/tests/nextflow.config
@@ -0,0 +1,5 @@
+process {
+ withName: PICARD_SORTSAM {
+ ext.prefix = { "${meta.id}.sorted" }
+ }
+}
diff --git a/modules/nf-core/samtools/index/environment.yml b/modules/nf-core/samtools/index/environment.yml
new file mode 100644
index 0000000..62054fc
--- /dev/null
+++ b/modules/nf-core/samtools/index/environment.yml
@@ -0,0 +1,8 @@
+---
+# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json
+channels:
+ - conda-forge
+ - bioconda
+dependencies:
+ - bioconda::htslib=1.21
+ - bioconda::samtools=1.21
diff --git a/modules/nf-core/samtools/index/main.nf b/modules/nf-core/samtools/index/main.nf
new file mode 100644
index 0000000..3117561
--- /dev/null
+++ b/modules/nf-core/samtools/index/main.nf
@@ -0,0 +1,49 @@
+process SAMTOOLS_INDEX {
+ 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/samtools:1.21--h50ea8bc_0' :
+ 'biocontainers/samtools:1.21--h50ea8bc_0' }"
+
+ input:
+ tuple val(meta), path(input)
+
+ output:
+ tuple val(meta), path("*.bai") , optional:true, emit: bai
+ tuple val(meta), path("*.csi") , optional:true, emit: csi
+ tuple val(meta), path("*.crai"), optional:true, emit: crai
+ path "versions.yml" , emit: versions
+
+ when:
+ task.ext.when == null || task.ext.when
+
+ script:
+ def args = task.ext.args ?: ''
+ """
+ samtools \\
+ index \\
+ -@ ${task.cpus-1} \\
+ $args \\
+ $input
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//')
+ END_VERSIONS
+ """
+
+ stub:
+ def args = task.ext.args ?: ''
+ def extension = file(input).getExtension() == 'cram' ?
+ "crai" : args.contains("-c") ? "csi" : "bai"
+ """
+ touch ${input}.${extension}
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//')
+ END_VERSIONS
+ """
+}
diff --git a/modules/nf-core/samtools/index/meta.yml b/modules/nf-core/samtools/index/meta.yml
new file mode 100644
index 0000000..db8df0d
--- /dev/null
+++ b/modules/nf-core/samtools/index/meta.yml
@@ -0,0 +1,71 @@
+name: samtools_index
+description: Index SAM/BAM/CRAM file
+keywords:
+ - index
+ - bam
+ - sam
+ - cram
+tools:
+ - samtools:
+ description: |
+ SAMtools is a set of utilities for interacting with and post-processing
+ short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li.
+ These files are generated as output by short read aligners like BWA.
+ homepage: http://www.htslib.org/
+ documentation: http://www.htslib.org/doc/samtools.html
+ doi: 10.1093/bioinformatics/btp352
+ licence: ["MIT"]
+ identifier: biotools:samtools
+input:
+ - - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - input:
+ type: file
+ description: input file
+output:
+ - bai:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - "*.bai":
+ type: file
+ description: BAM/CRAM/SAM index file
+ pattern: "*.{bai,crai,sai}"
+ - csi:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - "*.csi":
+ type: file
+ description: CSI index file
+ pattern: "*.{csi}"
+ - crai:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - "*.crai":
+ type: file
+ description: BAM/CRAM/SAM index file
+ pattern: "*.{bai,crai,sai}"
+ - versions:
+ - versions.yml:
+ type: file
+ description: File containing software versions
+ pattern: "versions.yml"
+authors:
+ - "@drpatelh"
+ - "@ewels"
+ - "@maxulysse"
+maintainers:
+ - "@drpatelh"
+ - "@ewels"
+ - "@maxulysse"
diff --git a/modules/nf-core/samtools/index/tests/csi.nextflow.config b/modules/nf-core/samtools/index/tests/csi.nextflow.config
new file mode 100644
index 0000000..0ed260e
--- /dev/null
+++ b/modules/nf-core/samtools/index/tests/csi.nextflow.config
@@ -0,0 +1,7 @@
+process {
+
+ withName: SAMTOOLS_INDEX {
+ ext.args = '-c'
+ }
+
+}
diff --git a/modules/nf-core/samtools/index/tests/main.nf.test b/modules/nf-core/samtools/index/tests/main.nf.test
new file mode 100644
index 0000000..ca34fb5
--- /dev/null
+++ b/modules/nf-core/samtools/index/tests/main.nf.test
@@ -0,0 +1,140 @@
+nextflow_process {
+
+ name "Test Process SAMTOOLS_INDEX"
+ script "../main.nf"
+ process "SAMTOOLS_INDEX"
+ tag "modules"
+ tag "modules_nfcore"
+ tag "samtools"
+ tag "samtools/index"
+
+ test("bai") {
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true)
+ ])
+ """
+ }
+ }
+
+ then {
+ assertAll (
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+ test("crai") {
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram', checkIfExists: true)
+ ])
+ """
+ }
+ }
+
+ then {
+ assertAll (
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+ test("csi") {
+ config "./csi.nextflow.config"
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true)
+ ])
+ """
+ }
+ }
+
+ then {
+ assertAll (
+ { assert process.success },
+ { assert snapshot(
+ file(process.out.csi[0][1]).name,
+ process.out.versions
+ ).match() }
+ )
+ }
+ }
+
+ test("bai - stub") {
+ options "-stub"
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true)
+ ])
+ """
+ }
+ }
+
+ then {
+ assertAll (
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+ test("crai - stub") {
+ options "-stub"
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.recalibrated.sorted.cram', checkIfExists: true)
+ ])
+ """
+ }
+ }
+
+ then {
+ assertAll (
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+
+ test("csi - stub") {
+ options "-stub"
+ config "./csi.nextflow.config"
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true)
+ ])
+ """
+ }
+ }
+
+ then {
+ assertAll (
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+ }
+ }
+}
diff --git a/modules/nf-core/samtools/index/tests/main.nf.test.snap b/modules/nf-core/samtools/index/tests/main.nf.test.snap
new file mode 100644
index 0000000..72d65e8
--- /dev/null
+++ b/modules/nf-core/samtools/index/tests/main.nf.test.snap
@@ -0,0 +1,250 @@
+{
+ "csi - stub": {
+ "content": [
+ {
+ "0": [
+
+ ],
+ "1": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.paired_end.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "2": [
+
+ ],
+ "3": [
+ "versions.yml:md5,5e09a6fdf76de396728f877193d72315"
+ ],
+ "bai": [
+
+ ],
+ "crai": [
+
+ ],
+ "csi": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.paired_end.sorted.bam.csi:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,5e09a6fdf76de396728f877193d72315"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-09-16T08:21:25.261127166"
+ },
+ "crai - stub": {
+ "content": [
+ {
+ "0": [
+
+ ],
+ "1": [
+
+ ],
+ "2": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.paired_end.recalibrated.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "3": [
+ "versions.yml:md5,5e09a6fdf76de396728f877193d72315"
+ ],
+ "bai": [
+
+ ],
+ "crai": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.paired_end.recalibrated.sorted.cram.crai:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "csi": [
+
+ ],
+ "versions": [
+ "versions.yml:md5,5e09a6fdf76de396728f877193d72315"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-09-16T08:21:12.653194876"
+ },
+ "bai - stub": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.paired_end.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "1": [
+
+ ],
+ "2": [
+
+ ],
+ "3": [
+ "versions.yml:md5,5e09a6fdf76de396728f877193d72315"
+ ],
+ "bai": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.paired_end.sorted.bam.bai:md5,d41d8cd98f00b204e9800998ecf8427e"
+ ]
+ ],
+ "crai": [
+
+ ],
+ "csi": [
+
+ ],
+ "versions": [
+ "versions.yml:md5,5e09a6fdf76de396728f877193d72315"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-09-16T08:21:01.854932651"
+ },
+ "csi": {
+ "content": [
+ "test.paired_end.sorted.bam.csi",
+ [
+ "versions.yml:md5,5e09a6fdf76de396728f877193d72315"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-09-16T08:20:51.485364222"
+ },
+ "crai": {
+ "content": [
+ {
+ "0": [
+
+ ],
+ "1": [
+
+ ],
+ "2": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.paired_end.recalibrated.sorted.cram.crai:md5,14bc3bd5c89cacc8f4541f9062429029"
+ ]
+ ],
+ "3": [
+ "versions.yml:md5,5e09a6fdf76de396728f877193d72315"
+ ],
+ "bai": [
+
+ ],
+ "crai": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.paired_end.recalibrated.sorted.cram.crai:md5,14bc3bd5c89cacc8f4541f9062429029"
+ ]
+ ],
+ "csi": [
+
+ ],
+ "versions": [
+ "versions.yml:md5,5e09a6fdf76de396728f877193d72315"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-09-16T08:20:40.518873972"
+ },
+ "bai": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.paired_end.sorted.bam.bai:md5,704c10dd1326482448ca3073fdebc2f4"
+ ]
+ ],
+ "1": [
+
+ ],
+ "2": [
+
+ ],
+ "3": [
+ "versions.yml:md5,5e09a6fdf76de396728f877193d72315"
+ ],
+ "bai": [
+ [
+ {
+ "id": "test",
+ "single_end": false
+ },
+ "test.paired_end.sorted.bam.bai:md5,704c10dd1326482448ca3073fdebc2f4"
+ ]
+ ],
+ "crai": [
+
+ ],
+ "csi": [
+
+ ],
+ "versions": [
+ "versions.yml:md5,5e09a6fdf76de396728f877193d72315"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-09-16T08:20:21.184050361"
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/samtools/index/tests/tags.yml b/modules/nf-core/samtools/index/tests/tags.yml
new file mode 100644
index 0000000..e0f58a7
--- /dev/null
+++ b/modules/nf-core/samtools/index/tests/tags.yml
@@ -0,0 +1,2 @@
+samtools/index:
+ - modules/nf-core/samtools/index/**
diff --git a/modules/nf-core/samtools/view/environment.yml b/modules/nf-core/samtools/view/environment.yml
new file mode 100644
index 0000000..02cda6e
--- /dev/null
+++ b/modules/nf-core/samtools/view/environment.yml
@@ -0,0 +1,10 @@
+---
+# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json
+channels:
+ - conda-forge
+ - bioconda
+dependencies:
+ # renovate: datasource=conda depName=bioconda/htslib
+ - bioconda::htslib=1.21
+ # renovate: datasource=conda depName=bioconda/samtools
+ - bioconda::samtools=1.21
diff --git a/modules/nf-core/samtools/view/main.nf b/modules/nf-core/samtools/view/main.nf
new file mode 100644
index 0000000..a6941e6
--- /dev/null
+++ b/modules/nf-core/samtools/view/main.nf
@@ -0,0 +1,77 @@
+process SAMTOOLS_VIEW {
+ tag "$meta.id"
+ label 'process_low'
+
+ conda "${moduleDir}/environment.yml"
+ container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
+ 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/9e/9edc2564215d5cd137a8b25ca8a311600987186d406b092022444adf3c4447f7/data' :
+ 'community.wave.seqera.io/library/htslib_samtools:1.21--6cb89bfd40cbaabf' }"
+
+ input:
+ tuple val(meta), path(input), path(index)
+ tuple val(meta2), path(fasta)
+ path qname
+
+ output:
+ tuple val(meta), path("${prefix}.bam"), emit: bam, optional: true
+ tuple val(meta), path("${prefix}.cram"), emit: cram, optional: true
+ tuple val(meta), path("${prefix}.sam"), emit: sam, optional: true
+ tuple val(meta), path("${prefix}.${file_type}.bai"), emit: bai, optional: true
+ tuple val(meta), path("${prefix}.${file_type}.csi"), emit: csi, optional: true
+ tuple val(meta), path("${prefix}.${file_type}.crai"), emit: crai, optional: true
+ tuple val(meta), path("${prefix}.unselected.${file_type}"), emit: unselected, optional: true
+ tuple val(meta), path("${prefix}.unselected.${file_type}.{bai,csi,crsi}"), emit: unselected_index, optional: true
+ path "versions.yml", emit: versions
+
+ when:
+ task.ext.when == null || task.ext.when
+
+ script:
+ def args = task.ext.args ?: ''
+ def args2 = task.ext.args2 ?: ''
+ prefix = task.ext.prefix ?: "${meta.id}"
+ def reference = fasta ? "--reference ${fasta}" : ""
+ file_type = args.contains("--output-fmt sam") ? "sam" :
+ args.contains("--output-fmt bam") ? "bam" :
+ args.contains("--output-fmt cram") ? "cram" :
+ input.getExtension()
+ readnames = qname ? "--qname-file ${qname} --output-unselected ${prefix}.unselected.${file_type}": ""
+ if ("$input" == "${prefix}.${file_type}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!"
+ """
+ samtools \\
+ view \\
+ --threads ${task.cpus-1} \\
+ ${reference} \\
+ ${readnames} \\
+ $args \\
+ -o ${prefix}.${file_type} \\
+ $input \\
+ $args2
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//')
+ END_VERSIONS
+ """
+
+ stub:
+ def args = task.ext.args ?: ''
+ prefix = task.ext.prefix ?: "${meta.id}"
+ file_type = args.contains("--output-fmt sam") ? "sam" :
+ args.contains("--output-fmt bam") ? "bam" :
+ args.contains("--output-fmt cram") ? "cram" :
+ input.getExtension()
+ if ("$input" == "${prefix}.${file_type}") error "Input and output names are the same, use \"task.ext.prefix\" to disambiguate!"
+
+ index = args.contains("--write-index") ? "touch ${prefix}.${file_type}.csi" : ""
+
+ """
+ touch ${prefix}.${file_type}
+ ${index}
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ samtools: \$(echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//')
+ END_VERSIONS
+ """
+}
diff --git a/modules/nf-core/samtools/view/meta.yml b/modules/nf-core/samtools/view/meta.yml
new file mode 100644
index 0000000..caa7b01
--- /dev/null
+++ b/modules/nf-core/samtools/view/meta.yml
@@ -0,0 +1,141 @@
+name: samtools_view
+description: filter/convert SAM/BAM/CRAM file
+keywords:
+ - view
+ - bam
+ - sam
+ - cram
+tools:
+ - samtools:
+ description: |
+ SAMtools is a set of utilities for interacting with and post-processing
+ short DNA sequence read alignments in the SAM, BAM and CRAM formats, written by Heng Li.
+ These files are generated as output by short read aligners like BWA.
+ homepage: http://www.htslib.org/
+ documentation: http://www.htslib.org/doc/samtools.html
+ doi: 10.1093/bioinformatics/btp352
+ licence: ["MIT"]
+ identifier: biotools:samtools
+input:
+ - - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - input:
+ type: file
+ description: BAM/CRAM/SAM file
+ pattern: "*.{bam,cram,sam}"
+ - index:
+ type: file
+ description: BAM.BAI/BAM.CSI/CRAM.CRAI file (optional)
+ pattern: "*.{.bai,.csi,.crai}"
+ - - meta2:
+ type: map
+ description: |
+ Groovy Map containing reference information
+ e.g. [ id:'test' ]
+ - fasta:
+ type: file
+ description: Reference file the CRAM was created with (optional)
+ pattern: "*.{fasta,fa}"
+ - - qname:
+ type: file
+ description: Optional file with read names to output only select alignments
+ pattern: "*.{txt,list}"
+output:
+ - bam:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - ${prefix}.bam:
+ type: file
+ description: optional filtered/converted BAM file
+ pattern: "*.{bam}"
+ - cram:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - ${prefix}.cram:
+ type: file
+ description: optional filtered/converted CRAM file
+ pattern: "*.{cram}"
+ - sam:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - ${prefix}.sam:
+ type: file
+ description: optional filtered/converted SAM file
+ pattern: "*.{sam}"
+ - bai:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - ${prefix}.${file_type}.bai:
+ type: file
+ description: optional BAM file index
+ pattern: "*.{bai}"
+ - csi:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - ${prefix}.${file_type}.csi:
+ type: file
+ description: optional tabix BAM file index
+ pattern: "*.{csi}"
+ - crai:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - ${prefix}.${file_type}.crai:
+ type: file
+ description: optional CRAM file index
+ pattern: "*.{crai}"
+ - unselected:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - ${prefix}.unselected.${file_type}:
+ type: file
+ description: optional file with unselected alignments
+ pattern: "*.unselected.{bam,cram,sam}"
+ - unselected_index:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - ${prefix}.unselected.${file_type}.{bai,csi,crsi}:
+ type: file
+ description: index for the "unselected" file
+ pattern: "*.unselected.{bai,csi,crai}"
+ - versions:
+ - versions.yml:
+ type: file
+ description: File containing software versions
+ pattern: "versions.yml"
+authors:
+ - "@drpatelh"
+ - "@joseespinosa"
+ - "@FriederikeHanssen"
+ - "@priyanka-surana"
+maintainers:
+ - "@drpatelh"
+ - "@joseespinosa"
+ - "@FriederikeHanssen"
+ - "@priyanka-surana"
diff --git a/modules/nf-core/samtools/view/tests/bam.config b/modules/nf-core/samtools/view/tests/bam.config
new file mode 100644
index 0000000..c10d108
--- /dev/null
+++ b/modules/nf-core/samtools/view/tests/bam.config
@@ -0,0 +1,3 @@
+process {
+ ext.args = "--output-fmt bam"
+}
\ No newline at end of file
diff --git a/modules/nf-core/samtools/view/tests/bam_index.config b/modules/nf-core/samtools/view/tests/bam_index.config
new file mode 100644
index 0000000..771ae03
--- /dev/null
+++ b/modules/nf-core/samtools/view/tests/bam_index.config
@@ -0,0 +1,3 @@
+process {
+ ext.args = "--output-fmt bam --write-index"
+}
\ No newline at end of file
diff --git a/modules/nf-core/samtools/view/tests/main.nf.test b/modules/nf-core/samtools/view/tests/main.nf.test
new file mode 100644
index 0000000..37b81a9
--- /dev/null
+++ b/modules/nf-core/samtools/view/tests/main.nf.test
@@ -0,0 +1,214 @@
+nextflow_process {
+
+ name "Test Process SAMTOOLS_VIEW"
+ script "../main.nf"
+ process "SAMTOOLS_VIEW"
+
+ tag "modules"
+ tag "modules_nfcore"
+ tag "samtools"
+ tag "samtools/view"
+
+ test("bam") {
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true),
+ []
+ ])
+ input[1] = [[],[]]
+ input[2] = []
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(file(process.out.bam[0][1]).name).match("bam_bam") },
+ { assert snapshot(process.out.bai).match("bam_bai") },
+ { assert snapshot(process.out.crai).match("bam_crai") },
+ { assert snapshot(process.out.cram).match("bam_cram") },
+ { assert snapshot(process.out.csi).match("bam_csi") },
+ { assert snapshot(process.out.sam).match("bam_sam") },
+ { assert snapshot(process.out.versions).match("bam_versions") }
+ )
+ }
+ }
+
+ test("cram") {
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true)
+ ])
+ input[1] = Channel.of([
+ [ id:'genome' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)
+ ])
+ input[2] = []
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(file(process.out.cram[0][1]).name).match("cram_cram") },
+ { assert snapshot(process.out.bai).match("cram_bai") },
+ { assert snapshot(process.out.bam).match("cram_bam") },
+ { assert snapshot(process.out.crai).match("cram_crai") },
+ { assert snapshot(process.out.csi).match("cram_csi") },
+ { assert snapshot(process.out.sam).match("cram_sam") },
+ { assert snapshot(process.out.versions).match("cram_versions") }
+ )
+ }
+ }
+
+ test("cram_to_bam") {
+
+ config "./bam.config"
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true),
+ []
+ ])
+ input[1] = Channel.of([
+ [ id:'genome' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)
+ ])
+ input[2] = []
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(file(process.out.bam[0][1]).name).match("cram_to_bam_bam") },
+ { assert snapshot(process.out.bai).match("cram_to_bam_bai") },
+ { assert snapshot(process.out.crai).match("cram_to_bam_crai") },
+ { assert snapshot(process.out.cram).match("cram_to_bam_cram") },
+ { assert snapshot(process.out.csi).match("cram_to_bam_csi") },
+ { assert snapshot(process.out.sam).match("cram_to_bam_sam") },
+ { assert snapshot(process.out.versions).match("cram_to_bam_versions") }
+ )
+ }
+ }
+
+ test("cram_to_bam_index") {
+
+ config "./bam_index.config"
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true),
+ []
+ ])
+ input[1] = Channel.of([
+ [ id:'genome' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)
+ ])
+ input[2] = []
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(file(process.out.bam[0][1]).name).match("cram_to_bam_index_bam") },
+ { assert snapshot(file(process.out.csi[0][1]).name).match("cram_to_bam_index_csi") },
+ { assert snapshot(process.out.bai).match("cram_to_bam_index_bai") },
+ { assert snapshot(process.out.crai).match("cram_to_bam_index_crai") },
+ { assert snapshot(process.out.cram).match("cram_to_bam_index_cram") },
+ { assert snapshot(process.out.sam).match("cram_to_bam_index_sam") },
+ { assert snapshot(process.out.versions).match("cram_to_bam_index_versions") }
+ )
+ }
+ }
+
+ test("cram_to_bam_index_qname") {
+
+ config "./bam_index.config"
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true),
+ []
+ ])
+ input[1] = Channel.of([
+ [ id:'genome' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)
+ ])
+ input[2] = Channel.of("testN:2817", "testN:2814").collectFile(name: "readnames.list", newLine: true)
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(file(process.out.bam[0][1]).name).match("cram_to_bam_index_qname_bam") },
+ { assert snapshot(file(process.out.csi[0][1]).name).match("cram_to_bam_index_qname_csi") },
+ { assert snapshot(process.out.bai).match("cram_to_bam_index_qname_bai") },
+ { assert snapshot(process.out.crai).match("cram_to_bam_index_qname_crai") },
+ { assert snapshot(process.out.cram).match("cram_to_bam_index_qname_cram") },
+ { assert snapshot(process.out.sam).match("cram_to_bam_index_qname_sam") },
+ { assert snapshot(file(process.out.unselected[0][1]).name).match("cram_to_bam_index_qname_unselected") },
+ { assert snapshot(file(process.out.unselected_index[0][1]).name).match("cram_to_bam_index_qname_unselected_csi") },
+ { assert snapshot(process.out.versions).match("cram_to_bam_index_qname_versions") }
+ )
+ }
+ }
+
+ test("bam_stub") {
+
+ options "-stub"
+ config "./bam_index.config"
+
+ when {
+ process {
+ """
+ input[0] = Channel.of([
+ [ id:'test', single_end:false ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.bam', checkIfExists: true),
+ []
+ ])
+ input[1] = [[],[]]
+ input[2] = []
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(file(process.out.bam[0][1]).name).match("bam_stub_bam") },
+ { assert snapshot(file(process.out.csi[0][1]).name).match("bam_stub_csi") },
+ { assert snapshot(process.out.bai).match("bam_stub_bai") },
+ { assert snapshot(process.out.crai).match("bam_stub_crai") },
+ { assert snapshot(process.out.cram).match("bam_stub_cram") },
+ { assert snapshot(process.out.sam).match("bam_stub_sam") },
+ { assert snapshot(process.out.versions).match("bam_stub_versions") }
+ )
+ }
+ }
+}
diff --git a/modules/nf-core/samtools/view/tests/main.nf.test.snap b/modules/nf-core/samtools/view/tests/main.nf.test.snap
new file mode 100644
index 0000000..63849b0
--- /dev/null
+++ b/modules/nf-core/samtools/view/tests/main.nf.test.snap
@@ -0,0 +1,528 @@
+{
+ "bam_bam": {
+ "content": [
+ "test.bam"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:37:51.256068"
+ },
+ "cram_to_bam_index_csi": {
+ "content": [
+ "test.bam.csi"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:12.958617"
+ },
+ "bam_stub_bam": {
+ "content": [
+ "test.bam"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:32.065301"
+ },
+ "bam_bai": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:37:51.258578"
+ },
+ "bam_stub_bai": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:32.071284"
+ },
+ "bam_stub_versions": {
+ "content": [
+ [
+ "versions.yml:md5,176db5ec46b965219604bcdbb3ef9e07"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-09-16T09:26:24.461775464"
+ },
+ "cram_to_bam_index_cram": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:12.972288"
+ },
+ "cram_to_bam_sam": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:04.999247"
+ },
+ "cram_to_bam_index_sam": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:12.976457"
+ },
+ "cram_crai": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:37:56.497581"
+ },
+ "cram_csi": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:37:56.50038"
+ },
+ "cram_to_bam_cram": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:04.992239"
+ },
+ "cram_to_bam_index_qname_csi": {
+ "content": [
+ "test.bam.csi"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:23.325496"
+ },
+ "bam_stub_sam": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:32.079529"
+ },
+ "cram_cram": {
+ "content": [
+ "test.cram"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:37:56.490286"
+ },
+ "cram_to_bam_index_qname_unselected_csi": {
+ "content": [
+ "test.unselected.bam.csi"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:23.328458"
+ },
+ "bam_csi": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:37:51.262882"
+ },
+ "cram_to_bam_crai": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:04.989247"
+ },
+ "cram_to_bam_index_crai": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:12.967681"
+ },
+ "cram_to_bam_index_qname_versions": {
+ "content": [
+ [
+ "versions.yml:md5,176db5ec46b965219604bcdbb3ef9e07"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-09-16T09:25:51.953436682"
+ },
+ "cram_to_bam_bam": {
+ "content": [
+ "test.bam"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:04.982361"
+ },
+ "cram_to_bam_index_bam": {
+ "content": [
+ "test.bam"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:12.95456"
+ },
+ "cram_to_bam_index_versions": {
+ "content": [
+ [
+ "versions.yml:md5,176db5ec46b965219604bcdbb3ef9e07"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-09-16T09:25:14.475388399"
+ },
+ "cram_to_bam_bai": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:04.98601"
+ },
+ "cram_to_bam_versions": {
+ "content": [
+ [
+ "versions.yml:md5,176db5ec46b965219604bcdbb3ef9e07"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-09-16T09:24:49.673441798"
+ },
+ "cram_bam": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:37:56.495512"
+ },
+ "bam_stub_cram": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:32.076908"
+ },
+ "cram_to_bam_index_qname_bai": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:23.328458"
+ },
+ "cram_to_bam_index_qname_crai": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:23.330789"
+ },
+ "cram_bai": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:37:56.493129"
+ },
+ "bam_stub_crai": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:32.074313"
+ },
+ "cram_to_bam_index_qname_bam": {
+ "content": [
+ "test.bam"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:23.322874"
+ },
+ "cram_to_bam_index_qname_unselected": {
+ "content": [
+ "test.unselected.bam"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:23.322874"
+ },
+ "cram_to_bam_index_qname_unselected_csi": {
+ "content": [
+ "test.unselected.bam.csi"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:23.328458"
+ },
+ "bam_versions": {
+ "content": [
+ [
+ "versions.yml:md5,176db5ec46b965219604bcdbb3ef9e07"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-09-16T09:23:27.151650338"
+ },
+ "cram_to_bam_index_qname_cram": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:23.333248"
+ },
+ "bam_crai": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:37:51.259774"
+ },
+ "bam_cram": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:37:51.261287"
+ },
+ "cram_to_bam_csi": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:04.995454"
+ },
+ "cram_sam": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:37:56.502625"
+ },
+ "cram_versions": {
+ "content": [
+ [
+ "versions.yml:md5,176db5ec46b965219604bcdbb3ef9e07"
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-09-16T09:24:12.95416913"
+ },
+ "cram_to_bam_index_qname_unselected": {
+ "content": [
+ "test.unselected.bam"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:23.322874"
+ },
+ "bam_sam": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:37:51.264651"
+ },
+ "cram_to_bam_index_bai": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:12.962863"
+ },
+ "cram_to_bam_index_qname_sam": {
+ "content": [
+ [
+
+ ]
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:23.337634"
+ },
+ "bam_stub_csi": {
+ "content": [
+ "test.bam.csi"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.04.3"
+ },
+ "timestamp": "2024-02-12T19:38:32.068596"
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/samtools/view/tests/tags.yml b/modules/nf-core/samtools/view/tests/tags.yml
new file mode 100644
index 0000000..4fdf1dd
--- /dev/null
+++ b/modules/nf-core/samtools/view/tests/tags.yml
@@ -0,0 +1,2 @@
+samtools/view:
+ - "modules/nf-core/samtools/view/**"
diff --git a/modules/nf-core/vardictjava/environment.yml b/modules/nf-core/vardictjava/environment.yml
new file mode 100644
index 0000000..a835c6d
--- /dev/null
+++ b/modules/nf-core/vardictjava/environment.yml
@@ -0,0 +1,6 @@
+channels:
+ - conda-forge
+ - bioconda
+dependencies:
+ - bioconda::htslib=1.20
+ - bioconda::vardict-java=1.8.3
diff --git a/modules/nf-core/vardictjava/main.nf b/modules/nf-core/vardictjava/main.nf
new file mode 100644
index 0000000..a2c7666
--- /dev/null
+++ b/modules/nf-core/vardictjava/main.nf
@@ -0,0 +1,67 @@
+process VARDICTJAVA {
+ tag "$meta.id"
+ label 'process_high'
+
+ conda "${moduleDir}/environment.yml"
+ container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
+ 'https://depot.galaxyproject.org/singularity/mulled-v2-731b8c4cf44d76e9aa181af565b9eee448d82a8c:edd70e76f3529411a748168f6eb1a61f29702123-0' :
+ 'biocontainers/mulled-v2-731b8c4cf44d76e9aa181af565b9eee448d82a8c:edd70e76f3529411a748168f6eb1a61f29702123-0' }"
+
+ input:
+ tuple val(meta), path(bams), path(bais), path(bed)
+ tuple val(meta2), path(fasta)
+ tuple val(meta3), path(fasta_fai)
+
+ output:
+ tuple val(meta), path("*.vcf.gz"), emit: vcf
+ path "versions.yml" , emit: versions
+
+ when:
+ task.ext.when == null || task.ext.when
+
+ script:
+ def args = task.ext.args ?: '-c 1 -S 2 -E 3'
+ def args2 = task.ext.args2 ?: ''
+ def args3 = task.ext.args3 ?: ''
+ def prefix = task.ext.prefix ?: "${meta.id}"
+
+ // Don't run test scripts when -fisher has been used by vardictjava
+ def run_test = !args.contains("-fisher")
+
+ def somatic = bams instanceof List && bams.size() == 2 ? true : false
+ def input = somatic ? "-b \"${bams[0]}|${bams[1]}\"" : "-b ${bams}"
+ def test = run_test ? somatic ? "| testsomatic.R" : "| teststrandbias.R" : ""
+ def convert_to_vcf = somatic ? "var2vcf_paired.pl" : "var2vcf_valid.pl"
+ """
+ export JAVA_OPTS='"-Xms${task.memory.toMega()/4}m" "-Xmx${task.memory.toGiga()}g" "-Dsamjdk.reference_fasta=${fasta}"'
+ vardict-java \\
+ ${args} \\
+ ${input} \\
+ -th ${task.cpus} \\
+ -G ${fasta} \\
+ ${bed} \\
+ ${test} \\
+ | ${convert_to_vcf} \\
+ ${args2} \\
+ | bgzip ${args3} --threads ${task.cpus} > ${prefix}.vcf.gz
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ vardict-java: \$( realpath \$( command -v vardict-java ) | sed 's/.*java-//;s/-.*//' )
+ var2vcf_valid.pl: \$( var2vcf_valid.pl -h | sed '2!d;s/.* //' )
+ END_VERSIONS
+ """
+
+ stub:
+ def prefix = task.ext.prefix ?: "${meta.id}"
+
+ """
+ echo '' | gzip > ${prefix}.vcf.gz
+
+ cat <<-END_VERSIONS > versions.yml
+ "${task.process}":
+ vardict-java: \$( realpath \$( command -v vardict-java ) | sed 's/.*java-//;s/-.*//' )
+ var2vcf_valid.pl: \$( var2vcf_valid.pl -h | sed '2!d;s/.* //' )
+ END_VERSIONS
+ """
+}
diff --git a/modules/nf-core/vardictjava/meta.yml b/modules/nf-core/vardictjava/meta.yml
new file mode 100644
index 0000000..801db6f
--- /dev/null
+++ b/modules/nf-core/vardictjava/meta.yml
@@ -0,0 +1,74 @@
+name: "vardictjava"
+description: The Java port of the VarDict variant caller
+keywords:
+ - variant calling
+ - vcf
+ - bam
+ - snv
+ - sv
+tools:
+ - "vardictjava":
+ description: "Java port of the VarDict variant discovery program"
+ homepage: "https://github.com/AstraZeneca-NGS/VarDictJava"
+ documentation: "https://github.com/AstraZeneca-NGS/VarDictJava"
+ tool_dev_url: "https://github.com/AstraZeneca-NGS/VarDictJava"
+ doi: "10.1093/nar/gkw227 "
+ licence: ["MIT"]
+ identifier: ""
+input:
+ - - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - bams:
+ type: file
+ description: One or two BAM files. Supply two BAM files to run Vardict in paired
+ mode.
+ pattern: "*.bam"
+ - bais:
+ type: file
+ description: Index/indices of the BAM file(s)
+ pattern: "*.bai"
+ - bed:
+ type: file
+ description: BED with the regions of interest
+ pattern: "*.bed"
+ - - meta2:
+ type: map
+ description: |
+ Groovy Map containing fasta information
+ e.g. [ id:'test', single_end:false ]
+ - fasta:
+ type: file
+ description: FASTA of the reference genome
+ pattern: "*.{fa,fasta}"
+ - - meta3:
+ type: map
+ description: |
+ Groovy Map containing fasta information
+ e.g. [ id:'test', single_end:false ]
+ - fasta_fai:
+ type: file
+ description: The index of the FASTA of the reference genome
+ pattern: "*.fai"
+output:
+ - vcf:
+ - meta:
+ type: map
+ description: |
+ Groovy Map containing sample information
+ e.g. [ id:'test', single_end:false ]
+ - "*.vcf.gz":
+ type: file
+ description: VCF file output
+ pattern: "*.vcf.gz"
+ - versions:
+ - versions.yml:
+ type: file
+ description: File containing software versions
+ pattern: "versions.yml"
+authors:
+ - "@nvnieuwk"
+maintainers:
+ - "@nvnieuwk"
diff --git a/modules/nf-core/vardictjava/tests/main.nf.test b/modules/nf-core/vardictjava/tests/main.nf.test
new file mode 100644
index 0000000..31e1058
--- /dev/null
+++ b/modules/nf-core/vardictjava/tests/main.nf.test
@@ -0,0 +1,155 @@
+nextflow_process {
+
+ name "Test Process VARDICTJAVA"
+ script "../main.nf"
+ process "VARDICTJAVA"
+ tag "modules"
+ tag "modules_nfcore"
+ tag "vardictjava"
+
+ test("homo_sapiens - [bam, bai, bed] - fasta - fai") {
+
+ when {
+ process {
+ """
+ input[0] = Channel.value([
+ [ id:'test' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true)
+ ])
+ input[1] = [
+ [id:"ref"],
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)
+ ]
+ input[2] = [
+ [id:"ref"],
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true)
+ ]
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+
+
+ }
+
+ }
+
+ test("homo_sapiens - [[bam, bam], [bai, bai], bed] - fasta - fai") {
+
+ when {
+ process {
+ """
+ input[0] = Channel.value([
+ [ id:'test' ], // meta map
+ [
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam', checkIfExists: true)
+ ],
+ [
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam.bai', checkIfExists: true)
+ ],
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true)
+ ])
+ input[1] = [
+ [id:"ref"],
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)
+ ]
+ input[2] = [
+ [id:"ref"],
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true)
+ ]
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+
+
+ }
+
+ }
+
+ test("homo_sapiens - [bam, bai, bed] - fasta - fai - fisher") {
+
+ config "./nextflow.config"
+ when {
+ process {
+ """
+ input[0] = Channel.value([
+ [ id:'test' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true)
+ ])
+ input[1] = [
+ [id:"ref"],
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)
+ ]
+ input[2] = [
+ [id:"ref"],
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true)
+ ]
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+
+
+ }
+
+ }
+
+ test("homo_sapiens - [bam, bai, bed] - fasta - fai - stub") {
+
+ options "-stub"
+
+ when {
+ process {
+ """
+ input[0] = Channel.value([
+ [ id:'test' ], // meta map
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true),
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.bed', checkIfExists: true)
+ ])
+ input[1] = [
+ [id:"ref"],
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true)
+ ]
+ input[2] = [
+ [id:"ref"],
+ file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true)
+ ]
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert process.success },
+ { assert snapshot(process.out).match() }
+ )
+
+
+ }
+
+ }
+
+}
diff --git a/modules/nf-core/vardictjava/tests/main.nf.test.snap b/modules/nf-core/vardictjava/tests/main.nf.test.snap
new file mode 100644
index 0000000..35674ed
--- /dev/null
+++ b/modules/nf-core/vardictjava/tests/main.nf.test.snap
@@ -0,0 +1,134 @@
+{
+ "homo_sapiens - [bam, bai, bed] - fasta - fai": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test"
+ },
+ "test.vcf.gz:md5,e8411ecae49b4f6afa6ea0b681ea506e"
+ ]
+ ],
+ "1": [
+ "versions.yml:md5,6bf7aa0cbaac4a6e2acab2c475ec2389"
+ ],
+ "vcf": [
+ [
+ {
+ "id": "test"
+ },
+ "test.vcf.gz:md5,e8411ecae49b4f6afa6ea0b681ea506e"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,6bf7aa0cbaac4a6e2acab2c475ec2389"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-07T16:05:15.117453312"
+ },
+ "homo_sapiens - [[bam, bam], [bai, bai], bed] - fasta - fai": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test"
+ },
+ "test.vcf.gz:md5,b52c874c18be636d876d1e0df4a449c3"
+ ]
+ ],
+ "1": [
+ "versions.yml:md5,6bf7aa0cbaac4a6e2acab2c475ec2389"
+ ],
+ "vcf": [
+ [
+ {
+ "id": "test"
+ },
+ "test.vcf.gz:md5,b52c874c18be636d876d1e0df4a449c3"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,6bf7aa0cbaac4a6e2acab2c475ec2389"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-07T16:05:26.932438089"
+ },
+ "homo_sapiens - [bam, bai, bed] - fasta - fai - fisher": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test"
+ },
+ "test.vcf.gz:md5,e8411ecae49b4f6afa6ea0b681ea506e"
+ ]
+ ],
+ "1": [
+ "versions.yml:md5,6bf7aa0cbaac4a6e2acab2c475ec2389"
+ ],
+ "vcf": [
+ [
+ {
+ "id": "test"
+ },
+ "test.vcf.gz:md5,e8411ecae49b4f6afa6ea0b681ea506e"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,6bf7aa0cbaac4a6e2acab2c475ec2389"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-07T16:05:38.456816851"
+ },
+ "homo_sapiens - [bam, bai, bed] - fasta - fai - stub": {
+ "content": [
+ {
+ "0": [
+ [
+ {
+ "id": "test"
+ },
+ "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "1": [
+ "versions.yml:md5,6bf7aa0cbaac4a6e2acab2c475ec2389"
+ ],
+ "vcf": [
+ [
+ {
+ "id": "test"
+ },
+ "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940"
+ ]
+ ],
+ "versions": [
+ "versions.yml:md5,6bf7aa0cbaac4a6e2acab2c475ec2389"
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.9.0",
+ "nextflow": "24.04.4"
+ },
+ "timestamp": "2024-10-07T16:05:48.440804849"
+ }
+}
\ No newline at end of file
diff --git a/modules/nf-core/vardictjava/tests/nextflow.config b/modules/nf-core/vardictjava/tests/nextflow.config
new file mode 100644
index 0000000..c6e8571
--- /dev/null
+++ b/modules/nf-core/vardictjava/tests/nextflow.config
@@ -0,0 +1,3 @@
+process {
+ ext.args = "-c 1 -S 2 -E 3 -fisher"
+}
\ No newline at end of file
diff --git a/modules/nf-core/vardictjava/tests/tags.yml b/modules/nf-core/vardictjava/tests/tags.yml
new file mode 100644
index 0000000..453c9b2
--- /dev/null
+++ b/modules/nf-core/vardictjava/tests/tags.yml
@@ -0,0 +1,2 @@
+vardictjava:
+ - modules/nf-core/vardictjava/**
diff --git a/nextflow.config b/nextflow.config
index 8d17a85..bb43c97 100644
--- a/nextflow.config
+++ b/nextflow.config
@@ -1,20 +1,243 @@
-docker.enabled = true
-conda.enabled = true
-dag.overwrite = true
-process.executor = 'slurm'
-workDir = "/path/to/workDir"
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ mobidic/mobict Nextflow config file
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ Default config options for all compute environments
+----------------------------------------------------------------------------------------
+*/
+// Global default params, used in configs
params {
- struct_r1 = "5M2S+T"
- struct_r2 = "5M2S+T"
- ref = "/path/to/referenceGenome.fasta"
- dict = "/path/to/referenceGenome.dict"
- fastq = "/path/to/fastq/files/*_{R1,R2}_001.fastq.gz"
- filter_fastq = /^((?!Undetermined).)*$/
- outdir = "/output/path"
- bed = "/path/to/bedFile"
- teststrandbias = "/path/to/teststrandbias.R/used/by/vardict"
- var2vcf = "/path/to/var2vcf_valid.pl/used/by/vardict"
- cache = "/path/to/cacheVEP"
- fasta = "/path/to/fastaVEP"
+
+ // TODO nf-core: Specify your pipeline's command line flags
+ // Input options
+ input = null
+
+ // References
+ genome = null
+ igenomes_base = 's3://ngi-igenomes/igenomes/'
+ igenomes_ignore = false
+
+ // MultiQC options
+ multiqc_config = null
+ multiqc_title = null
+ multiqc_logo = null
+ max_multiqc_email_size = '25.MB'
+ multiqc_methods_description = null
+
+ // Boilerplate options
+ outdir = null
+ publish_dir_mode = 'copy'
+ monochrome_logs = false
+
+ help = false
+ help_full = false
+ show_hidden = false
+ version = false
+ pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/'
+
+ // Config options
+ config_profile_name = null
+ config_profile_description = null
+
+ custom_config_version = 'master'
+ custom_config_base = "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}"
+ config_profile_contact = null
+ config_profile_url = null
+
+ // Schema validation default options
+ validate_params = true
+}
+
+// Load base.config by default for all pipelines
+includeConfig 'conf/base.config'
+
+profiles {
+ debug {
+ dumpHashes = true
+ process.beforeScript = 'echo $HOSTNAME'
+ cleanup = false
+ nextflow.enable.configProcessNamesValidation = true
+ }
+ conda {
+ conda.enabled = true
+ docker.enabled = false
+ singularity.enabled = false
+ podman.enabled = false
+ shifter.enabled = false
+ charliecloud.enabled = false
+ conda.channels = ['conda-forge', 'bioconda']
+ apptainer.enabled = false
+ }
+ mamba {
+ conda.enabled = true
+ conda.useMamba = true
+ docker.enabled = false
+ singularity.enabled = false
+ podman.enabled = false
+ shifter.enabled = false
+ charliecloud.enabled = false
+ apptainer.enabled = false
+ }
+ docker {
+ docker.enabled = true
+ conda.enabled = false
+ singularity.enabled = false
+ podman.enabled = false
+ shifter.enabled = false
+ charliecloud.enabled = false
+ apptainer.enabled = false
+ docker.runOptions = '-u $(id -u):$(id -g)'
+ }
+ arm {
+ docker.runOptions = '-u $(id -u):$(id -g) --platform=linux/amd64'
+ }
+ singularity {
+ singularity.enabled = true
+ singularity.autoMounts = true
+ conda.enabled = false
+ docker.enabled = false
+ podman.enabled = false
+ shifter.enabled = false
+ charliecloud.enabled = false
+ apptainer.enabled = false
+ }
+ podman {
+ podman.enabled = true
+ conda.enabled = false
+ docker.enabled = false
+ singularity.enabled = false
+ shifter.enabled = false
+ charliecloud.enabled = false
+ apptainer.enabled = false
+ }
+ shifter {
+ shifter.enabled = true
+ conda.enabled = false
+ docker.enabled = false
+ singularity.enabled = false
+ podman.enabled = false
+ charliecloud.enabled = false
+ apptainer.enabled = false
+ }
+ charliecloud {
+ charliecloud.enabled = true
+ conda.enabled = false
+ docker.enabled = false
+ singularity.enabled = false
+ podman.enabled = false
+ shifter.enabled = false
+ apptainer.enabled = false
+ }
+ apptainer {
+ apptainer.enabled = true
+ apptainer.autoMounts = true
+ conda.enabled = false
+ docker.enabled = false
+ singularity.enabled = false
+ podman.enabled = false
+ shifter.enabled = false
+ charliecloud.enabled = false
+ }
+ wave {
+ apptainer.ociAutoPull = true
+ singularity.ociAutoPull = true
+ wave.enabled = true
+ wave.freeze = true
+ wave.strategy = 'conda,container'
+ }
+
+ test { includeConfig 'conf/test.config' }
+ test_full { includeConfig 'conf/test_full.config' }
+}
+
+// Load nf-core custom profiles from different Institutions
+includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/nfcore_custom.config" : "/dev/null"
+
+// Load mobidic/mobict custom profiles from different institutions.
+// TODO nf-core: Optionally, you can add a pipeline-specific nf-core config at https://github.com/nf-core/configs
+// includeConfig !System.getenv('NXF_OFFLINE') && params.custom_config_base ? "${params.custom_config_base}/pipeline/mobict.config" : "/dev/null"
+
+// Set default registry for Apptainer, Docker, Podman, Charliecloud and Singularity independent of -profile
+// Will not be used unless Apptainer / Docker / Podman / Charliecloud / Singularity are enabled
+// Set to your registry if you have a mirror of containers
+apptainer.registry = 'quay.io'
+docker.registry = 'quay.io'
+podman.registry = 'quay.io'
+singularity.registry = 'quay.io'
+charliecloud.registry = 'quay.io'
+
+// Load igenomes.config if required
+includeConfig !params.igenomes_ignore ? 'conf/igenomes.config' : 'conf/igenomes_ignored.config'
+
+// Export these variables to prevent local Python/R libraries from conflicting with those in the container
+// The JULIA depot path has been adjusted to a fixed path `/usr/local/share/julia` that needs to be used for packages in the container.
+// See https://apeltzer.github.io/post/03-julia-lang-nextflow/ for details on that. Once we have a common agreement on where to keep Julia packages, this is adjustable.
+
+env {
+ PYTHONNOUSERSITE = 1
+ R_PROFILE_USER = "/.Rprofile"
+ R_ENVIRON_USER = "/.Renviron"
+ JULIA_DEPOT_PATH = "/usr/local/share/julia"
+}
+
+// Set bash options
+process.shell = """\
+bash
+
+set -e # Exit if a tool returns a non-zero status/exit code
+set -u # Treat unset variables and parameters as an error
+set -o pipefail # Returns the status of the last command to exit with a non-zero status or zero if all successfully execute
+set -C # No clobber - prevent output redirection from overwriting files.
+"""
+
+// Disable process selector warnings by default. Use debug profile to enable warnings.
+nextflow.enable.configProcessNamesValidation = false
+
+def trace_timestamp = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss')
+timeline {
+ enabled = true
+ file = "${params.outdir}/pipeline_info/execution_timeline_${trace_timestamp}.html"
+}
+report {
+ enabled = true
+ file = "${params.outdir}/pipeline_info/execution_report_${trace_timestamp}.html"
+}
+trace {
+ enabled = true
+ file = "${params.outdir}/pipeline_info/execution_trace_${trace_timestamp}.txt"
}
+dag {
+ enabled = true
+ file = "${params.outdir}/pipeline_info/pipeline_dag_${trace_timestamp}.html"
+}
+
+manifest {
+ name = 'mobidic/mobict'
+ author = """Simon Cabello-Aguilar"""
+ homePage = 'https://github.com/mobidic/mobict'
+ description = """ctDNA Analysis pipeline"""
+ mainScript = 'main.nf'
+ nextflowVersion = '!>=24.04.2'
+ version = '1.0.0dev'
+ doi = ''
+}
+
+// Nextflow plugins
+plugins {
+ id 'nf-schema@2.1.1' // Validation of pipeline parameters and creation of an input channel from a sample sheet
+}
+
+validation {
+ defaultIgnoreParams = ["genomes"]
+ help {
+ enabled = true
+ command = "nextflow run $manifest.name -profile --input samplesheet.csv --outdir "
+ fullParameter = "help_full"
+ showHiddenParameter = "show_hidden"
+
+ }
+}
+
+// Load modules.config for DSL2 module specific options
+includeConfig 'conf/modules.config'
diff --git a/nextflow_schema.json b/nextflow_schema.json
new file mode 100644
index 0000000..c15f4e1
--- /dev/null
+++ b/nextflow_schema.json
@@ -0,0 +1,211 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://raw.githubusercontent.com/mobidic/mobict/master/nextflow_schema.json",
+ "title": "mobidic/mobict pipeline parameters",
+ "description": "ctDNA Analysis pipeline",
+ "type": "object",
+ "$defs": {
+ "input_output_options": {
+ "title": "Input/output options",
+ "type": "object",
+ "fa_icon": "fas fa-terminal",
+ "description": "Define where the pipeline should find input data and save output data.",
+ "required": ["input", "outdir"],
+ "properties": {
+ "input": {
+ "type": "string",
+ "format": "file-path",
+ "exists": true,
+ "schema": "assets/schema_input.json",
+ "mimetype": "text/csv",
+ "pattern": "^\\S+\\.csv$",
+ "description": "Path to comma-separated file containing information about the samples in the experiment.",
+ "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.",
+ "fa_icon": "fas fa-file-csv"
+ },
+ "outdir": {
+ "type": "string",
+ "format": "directory-path",
+ "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.",
+ "fa_icon": "fas fa-folder-open"
+ },
+ "multiqc_title": {
+ "type": "string",
+ "description": "MultiQC report title. Printed as page header, used for filename if not otherwise specified.",
+ "fa_icon": "fas fa-file-signature"
+ }
+ }
+ },
+ "reference_genome_options": {
+ "title": "Reference genome options",
+ "type": "object",
+ "fa_icon": "fas fa-dna",
+ "description": "Reference genome related files and options required for the workflow.",
+ "properties": {
+ "genome": {
+ "type": "string",
+ "description": "Name of iGenomes reference.",
+ "fa_icon": "fas fa-book",
+ "help_text": "If using a reference genome configured in the pipeline using iGenomes, use this parameter to give the ID for the reference. This is then used to build the full paths for all required reference genome files e.g. `--genome GRCh38`. \n\nSee the [nf-core website docs](https://nf-co.re/usage/reference_genomes) for more details."
+ },
+ "fasta": {
+ "type": "string",
+ "format": "file-path",
+ "exists": true,
+ "mimetype": "text/plain",
+ "pattern": "^\\S+\\.fn?a(sta)?(\\.gz)?$",
+ "description": "Path to FASTA genome file.",
+ "help_text": "This parameter is *mandatory* if `--genome` is not specified. If you don't have a BWA index available this will be generated for you automatically. Combine with `--save_reference` to save BWA index for future runs.",
+ "fa_icon": "far fa-file-code"
+ },
+ "igenomes_ignore": {
+ "type": "boolean",
+ "description": "Do not load the iGenomes reference config.",
+ "fa_icon": "fas fa-ban",
+ "hidden": true,
+ "help_text": "Do not load `igenomes.config` when running the pipeline. You may choose this option if you observe clashes between custom parameters and those supplied in `igenomes.config`."
+ },
+ "igenomes_base": {
+ "type": "string",
+ "format": "directory-path",
+ "description": "The base path to the igenomes reference files",
+ "fa_icon": "fas fa-ban",
+ "hidden": true,
+ "default": "s3://ngi-igenomes/igenomes/"
+ }
+ }
+ },
+ "institutional_config_options": {
+ "title": "Institutional config options",
+ "type": "object",
+ "fa_icon": "fas fa-university",
+ "description": "Parameters used to describe centralised config profiles. These should not be edited.",
+ "help_text": "The centralised nf-core configuration profiles use a handful of pipeline parameters to describe themselves. This information is then printed to the Nextflow log when you run a pipeline. You should not need to change these values when you run a pipeline.",
+ "properties": {
+ "custom_config_version": {
+ "type": "string",
+ "description": "Git commit id for Institutional configs.",
+ "default": "master",
+ "hidden": true,
+ "fa_icon": "fas fa-users-cog"
+ },
+ "custom_config_base": {
+ "type": "string",
+ "description": "Base directory for Institutional configs.",
+ "default": "https://raw.githubusercontent.com/nf-core/configs/master",
+ "hidden": true,
+ "help_text": "If you're running offline, Nextflow will not be able to fetch the institutional config files from the internet. If you don't need them, then this is not a problem. If you do need them, you should download the files from the repo and tell Nextflow where to find them with this parameter.",
+ "fa_icon": "fas fa-users-cog"
+ },
+ "config_profile_name": {
+ "type": "string",
+ "description": "Institutional config name.",
+ "hidden": true,
+ "fa_icon": "fas fa-users-cog"
+ },
+ "config_profile_description": {
+ "type": "string",
+ "description": "Institutional config description.",
+ "hidden": true,
+ "fa_icon": "fas fa-users-cog"
+ },
+ "config_profile_contact": {
+ "type": "string",
+ "description": "Institutional config contact information.",
+ "hidden": true,
+ "fa_icon": "fas fa-users-cog"
+ },
+ "config_profile_url": {
+ "type": "string",
+ "description": "Institutional config URL link.",
+ "hidden": true,
+ "fa_icon": "fas fa-users-cog"
+ }
+ }
+ },
+ "generic_options": {
+ "title": "Generic options",
+ "type": "object",
+ "fa_icon": "fas fa-file-import",
+ "description": "Less common options for the pipeline, typically set in a config file.",
+ "help_text": "These options are common to all nf-core pipelines and allow you to customise some of the core preferences for how the pipeline runs.\n\nTypically these options would be set in a Nextflow config file loaded for all pipeline runs, such as `~/.nextflow/config`.",
+ "properties": {
+ "version": {
+ "type": "boolean",
+ "description": "Display version and exit.",
+ "fa_icon": "fas fa-question-circle",
+ "hidden": true
+ },
+ "publish_dir_mode": {
+ "type": "string",
+ "default": "copy",
+ "description": "Method used to save pipeline results to output directory.",
+ "help_text": "The Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.",
+ "fa_icon": "fas fa-copy",
+ "enum": ["symlink", "rellink", "link", "copy", "copyNoFollow", "move"],
+ "hidden": true
+ },
+ "max_multiqc_email_size": {
+ "type": "string",
+ "description": "File size limit when attaching MultiQC reports to summary emails.",
+ "pattern": "^\\d+(\\.\\d+)?\\.?\\s*(K|M|G|T)?B$",
+ "default": "25.MB",
+ "fa_icon": "fas fa-file-upload",
+ "hidden": true
+ },
+ "monochrome_logs": {
+ "type": "boolean",
+ "description": "Do not use coloured log outputs.",
+ "fa_icon": "fas fa-palette",
+ "hidden": true
+ },
+ "multiqc_config": {
+ "type": "string",
+ "format": "file-path",
+ "description": "Custom config file to supply to MultiQC.",
+ "fa_icon": "fas fa-cog",
+ "hidden": true
+ },
+ "multiqc_logo": {
+ "type": "string",
+ "description": "Custom logo file to supply to MultiQC. File name must also be set in the MultiQC config file",
+ "fa_icon": "fas fa-image",
+ "hidden": true
+ },
+ "multiqc_methods_description": {
+ "type": "string",
+ "description": "Custom MultiQC yaml file containing HTML including a methods description.",
+ "fa_icon": "fas fa-cog"
+ },
+ "validate_params": {
+ "type": "boolean",
+ "description": "Boolean whether to validate parameters against the schema at runtime",
+ "default": true,
+ "fa_icon": "fas fa-check-square",
+ "hidden": true
+ },
+ "pipelines_testdata_base_path": {
+ "type": "string",
+ "fa_icon": "far fa-check-circle",
+ "description": "Base URL or local path to location of pipeline test dataset files",
+ "default": "https://raw.githubusercontent.com/nf-core/test-datasets/",
+ "hidden": true
+ }
+ }
+ }
+ },
+ "allOf": [
+ {
+ "$ref": "#/$defs/input_output_options"
+ },
+ {
+ "$ref": "#/$defs/reference_genome_options"
+ },
+ {
+ "$ref": "#/$defs/institutional_config_options"
+ },
+ {
+ "$ref": "#/$defs/generic_options"
+ }
+ ]
+}
diff --git a/nf-core-MobiCT_logo_light.png b/nf-core-MobiCT_logo_light.png
new file mode 100644
index 0000000..d3c02c5
Binary files /dev/null and b/nf-core-MobiCT_logo_light.png differ
diff --git a/nf-core-ctDNA_logo_light.png b/nf-core-ctDNA_logo_light.png
new file mode 100644
index 0000000..ac96edc
Binary files /dev/null and b/nf-core-ctDNA_logo_light.png differ
diff --git a/subworkflows/local/utils_nfcore_mobict_pipeline/main.nf b/subworkflows/local/utils_nfcore_mobict_pipeline/main.nf
new file mode 100644
index 0000000..3b92381
--- /dev/null
+++ b/subworkflows/local/utils_nfcore_mobict_pipeline/main.nf
@@ -0,0 +1,244 @@
+//
+// Subworkflow with functionality specific to the mobidic/mobict pipeline
+//
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin'
+include { paramsSummaryMap } from 'plugin/nf-schema'
+include { samplesheetToList } from 'plugin/nf-schema'
+include { completionSummary } from '../../nf-core/utils_nfcore_pipeline'
+include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline'
+include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline'
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ SUBWORKFLOW TO INITIALISE PIPELINE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+workflow PIPELINE_INITIALISATION {
+
+ take:
+ version // boolean: Display version and exit
+ validate_params // boolean: Boolean whether to validate parameters against the schema at runtime
+ monochrome_logs // boolean: Do not use coloured log outputs
+ nextflow_cli_args // array: List of positional nextflow CLI args
+ outdir // string: The output directory where the results will be saved
+ input // string: Path to input samplesheet
+
+ main:
+
+ ch_versions = Channel.empty()
+
+ //
+ // Print version and exit if required and dump pipeline parameters to JSON file
+ //
+ UTILS_NEXTFLOW_PIPELINE (
+ version,
+ true,
+ outdir,
+ workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1
+ )
+
+ //
+ // Validate parameters and generate parameter summary to stdout
+ //
+ UTILS_NFSCHEMA_PLUGIN (
+ workflow,
+ validate_params,
+ null
+ )
+
+ //
+ // Check config provided to the pipeline
+ //
+ UTILS_NFCORE_PIPELINE (
+ nextflow_cli_args
+ )
+
+ //
+ // Custom validation for pipeline parameters
+ //
+ validateInputParameters()
+
+ //
+ // Create channel from input file provided through params.input
+ //
+
+ Channel
+ .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json"))
+ .map {
+ meta, fastq_1, fastq_2 ->
+ if (!fastq_2) {
+ return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ]
+ } else {
+ return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ]
+ }
+ }
+ .groupTuple()
+ .map { samplesheet ->
+ validateInputSamplesheet(samplesheet)
+ }
+ .map {
+ meta, fastqs ->
+ return [ meta, fastqs.flatten() ]
+ }
+ .set { ch_samplesheet }
+
+ emit:
+ samplesheet = ch_samplesheet
+ versions = ch_versions
+}
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ SUBWORKFLOW FOR PIPELINE COMPLETION
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+workflow PIPELINE_COMPLETION {
+
+ take:
+ outdir // path: Path to output directory where results will be published
+ monochrome_logs // boolean: Disable ANSI colour codes in log output
+
+ multiqc_report // string: Path to MultiQC report
+
+ main:
+ summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json")
+
+ //
+ // Completion email and summary
+ //
+ workflow.onComplete {
+
+ completionSummary(monochrome_logs)
+ }
+
+ workflow.onError {
+ log.error "Pipeline failed. Please refer to troubleshooting docs: https://nf-co.re/docs/usage/troubleshooting"
+ }
+}
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ FUNCTIONS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+//
+// Check and validate pipeline parameters
+//
+def validateInputParameters() {
+ genomeExistsError()
+}
+
+//
+// Validate channels from input samplesheet
+//
+def validateInputSamplesheet(input) {
+ def (metas, fastqs) = input[1..2]
+
+ // Check that multiple runs of the same sample are of the same datatype i.e. single-end / paired-end
+ def endedness_ok = metas.collect{ meta -> meta.single_end }.unique().size == 1
+ if (!endedness_ok) {
+ error("Please check input samplesheet -> Multiple runs of a sample must be of the same datatype i.e. single-end or paired-end: ${metas[0].id}")
+ }
+
+ return [ metas[0], fastqs ]
+}
+//
+// Get attribute from genome config file e.g. fasta
+//
+def getGenomeAttribute(attribute) {
+ if (params.genomes && params.genome && params.genomes.containsKey(params.genome)) {
+ if (params.genomes[ params.genome ].containsKey(attribute)) {
+ return params.genomes[ params.genome ][ attribute ]
+ }
+ }
+ return null
+}
+
+//
+// Exit pipeline if incorrect --genome key provided
+//
+def genomeExistsError() {
+ if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) {
+ def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
+ " Genome '${params.genome}' not found in any config files provided to the pipeline.\n" +
+ " Currently, the available genome keys are:\n" +
+ " ${params.genomes.keySet().join(", ")}\n" +
+ "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+ error(error_string)
+ }
+}
+//
+// Generate methods description for MultiQC
+//
+def toolCitationText() {
+ // TODO nf-core: Optionally add in-text citation tools to this list.
+ // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "Tool (Foo et al. 2023)" : "",
+ // Uncomment function in methodsDescriptionText to render in MultiQC report
+ def citation_text = [
+ "Tools used in the workflow included:",
+
+ "MultiQC (Ewels et al. 2016)",
+ "."
+ ].join(' ').trim()
+
+ return citation_text
+}
+
+def toolBibliographyText() {
+ // TODO nf-core: Optionally add bibliographic entries to this list.
+ // Can use ternary operators to dynamically construct based conditions, e.g. params["run_xyz"] ? "Author (2023) Pub name, Journal, DOI" : "",
+ // Uncomment function in methodsDescriptionText to render in MultiQC report
+ def reference_text = [
+
+ "Ewels, P., Magnusson, M., Lundin, S., & Käller, M. (2016). MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics , 32(19), 3047–3048. doi: /10.1093/bioinformatics/btw354"
+ ].join(' ').trim()
+
+ return reference_text
+}
+
+def methodsDescriptionText(mqc_methods_yaml) {
+ // Convert to a named map so can be used as with familar NXF ${workflow} variable syntax in the MultiQC YML file
+ def meta = [:]
+ meta.workflow = workflow.toMap()
+ meta["manifest_map"] = workflow.manifest.toMap()
+
+ // Pipeline DOI
+ if (meta.manifest_map.doi) {
+ // Using a loop to handle multiple DOIs
+ // Removing `https://doi.org/` to handle pipelines using DOIs vs DOI resolvers
+ // Removing ` ` since the manifest.doi is a string and not a proper list
+ def temp_doi_ref = ""
+ def manifest_doi = meta.manifest_map.doi.tokenize(",")
+ manifest_doi.each { doi_ref ->
+ temp_doi_ref += "(doi: ${doi_ref.replace("https://doi.org/", "").replace(" ", "")}), "
+ }
+ meta["doi_text"] = temp_doi_ref.substring(0, temp_doi_ref.length() - 2)
+ } else meta["doi_text"] = ""
+ meta["nodoi_text"] = meta.manifest_map.doi ? "" : "If available, make sure to update the text to include the Zenodo DOI of version of the pipeline used. "
+
+ // Tool references
+ meta["tool_citations"] = ""
+ meta["tool_bibliography"] = ""
+
+ // TODO nf-core: Only uncomment below if logic in toolCitationText/toolBibliographyText has been filled!
+ // meta["tool_citations"] = toolCitationText().replaceAll(", \\.", ".").replaceAll("\\. \\.", ".").replaceAll(", \\.", ".")
+ // meta["tool_bibliography"] = toolBibliographyText()
+
+
+ def methods_text = mqc_methods_yaml.text
+
+ def engine = new groovy.text.SimpleTemplateEngine()
+ def description_html = engine.createTemplate(methods_text).make(meta)
+
+ return description_html.toString()
+}
+
diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/main.nf b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf
new file mode 100644
index 0000000..0fcbf7b
--- /dev/null
+++ b/subworkflows/nf-core/utils_nextflow_pipeline/main.nf
@@ -0,0 +1,124 @@
+//
+// Subworkflow with functionality that may be useful for any Nextflow pipeline
+//
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ SUBWORKFLOW DEFINITION
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+workflow UTILS_NEXTFLOW_PIPELINE {
+ take:
+ print_version // boolean: print version
+ dump_parameters // boolean: dump parameters
+ outdir // path: base directory used to publish pipeline results
+ check_conda_channels // boolean: check conda channels
+
+ main:
+
+ //
+ // Print workflow version and exit on --version
+ //
+ if (print_version) {
+ log.info("${workflow.manifest.name} ${getWorkflowVersion()}")
+ System.exit(0)
+ }
+
+ //
+ // Dump pipeline parameters to a JSON file
+ //
+ if (dump_parameters && outdir) {
+ dumpParametersToJSON(outdir)
+ }
+
+ //
+ // When running with Conda, warn if channels have not been set-up appropriately
+ //
+ if (check_conda_channels) {
+ checkCondaChannels()
+ }
+
+ emit:
+ dummy_emit = true
+}
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ FUNCTIONS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+//
+// Generate version string
+//
+def getWorkflowVersion() {
+ def version_string = "" as String
+ if (workflow.manifest.version) {
+ def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : ''
+ version_string += "${prefix_v}${workflow.manifest.version}"
+ }
+
+ if (workflow.commitId) {
+ def git_shortsha = workflow.commitId.substring(0, 7)
+ version_string += "-g${git_shortsha}"
+ }
+
+ return version_string
+}
+
+//
+// Dump pipeline parameters to a JSON file
+//
+def dumpParametersToJSON(outdir) {
+ def timestamp = new java.util.Date().format('yyyy-MM-dd_HH-mm-ss')
+ def filename = "params_${timestamp}.json"
+ def temp_pf = new File(workflow.launchDir.toString(), ".${filename}")
+ def jsonStr = groovy.json.JsonOutput.toJson(params)
+ temp_pf.text = groovy.json.JsonOutput.prettyPrint(jsonStr)
+
+ nextflow.extension.FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json")
+ temp_pf.delete()
+}
+
+//
+// When running with -profile conda, warn if channels have not been set-up appropriately
+//
+def checkCondaChannels() {
+ def parser = new org.yaml.snakeyaml.Yaml()
+ def channels = []
+ try {
+ def config = parser.load("conda config --show channels".execute().text)
+ channels = config.channels
+ }
+ catch (NullPointerException e) {
+ log.warn("Could not verify conda channel configuration.")
+ return null
+ }
+ catch (IOException e) {
+ log.warn("Could not verify conda channel configuration.")
+ return null
+ }
+
+ // Check that all channels are present
+ // This channel list is ordered by required channel priority.
+ def required_channels_in_order = ['conda-forge', 'bioconda']
+ def channels_missing = ((required_channels_in_order as Set) - (channels as Set)) as Boolean
+
+ // Check that they are in the right order
+ def channel_priority_violation = required_channels_in_order != channels.findAll { ch -> ch in required_channels_in_order }
+
+ if (channels_missing | channel_priority_violation) {
+ log.warn """\
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ There is a problem with your Conda configuration!
+ You will need to set-up the conda-forge and bioconda channels correctly.
+ Please refer to https://bioconda.github.io/
+ The observed channel order is
+ ${channels}
+ but the following channel order is required:
+ ${required_channels_in_order}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+ """.stripIndent(true)
+ }
+}
diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/meta.yml b/subworkflows/nf-core/utils_nextflow_pipeline/meta.yml
new file mode 100644
index 0000000..e5c3a0a
--- /dev/null
+++ b/subworkflows/nf-core/utils_nextflow_pipeline/meta.yml
@@ -0,0 +1,38 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json
+name: "UTILS_NEXTFLOW_PIPELINE"
+description: Subworkflow with functionality that may be useful for any Nextflow pipeline
+keywords:
+ - utility
+ - pipeline
+ - initialise
+ - version
+components: []
+input:
+ - print_version:
+ type: boolean
+ description: |
+ Print the version of the pipeline and exit
+ - dump_parameters:
+ type: boolean
+ description: |
+ Dump the parameters of the pipeline to a JSON file
+ - output_directory:
+ type: directory
+ description: Path to output dir to write JSON file to.
+ pattern: "results/"
+ - check_conda_channel:
+ type: boolean
+ description: |
+ Check if the conda channel priority is correct.
+output:
+ - dummy_emit:
+ type: boolean
+ description: |
+ Dummy emit to make nf-core subworkflows lint happy
+authors:
+ - "@adamrtalbot"
+ - "@drpatelh"
+maintainers:
+ - "@adamrtalbot"
+ - "@drpatelh"
+ - "@maxulysse"
diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test
new file mode 100644
index 0000000..68718e4
--- /dev/null
+++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test
@@ -0,0 +1,54 @@
+
+nextflow_function {
+
+ name "Test Functions"
+ script "subworkflows/nf-core/utils_nextflow_pipeline/main.nf"
+ config "subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config"
+ tag 'subworkflows'
+ tag 'utils_nextflow_pipeline'
+ tag 'subworkflows/utils_nextflow_pipeline'
+
+ test("Test Function getWorkflowVersion") {
+
+ function "getWorkflowVersion"
+
+ then {
+ assertAll(
+ { assert function.success },
+ { assert snapshot(function.result).match() }
+ )
+ }
+ }
+
+ test("Test Function dumpParametersToJSON") {
+
+ function "dumpParametersToJSON"
+
+ when {
+ function {
+ """
+ // define inputs of the function here. Example:
+ input[0] = "$outputDir"
+ """.stripIndent()
+ }
+ }
+
+ then {
+ assertAll(
+ { assert function.success }
+ )
+ }
+ }
+
+ test("Test Function checkCondaChannels") {
+
+ function "checkCondaChannels"
+
+ then {
+ assertAll(
+ { assert function.success },
+ { assert snapshot(function.result).match() }
+ )
+ }
+ }
+}
diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test.snap b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test.snap
new file mode 100644
index 0000000..e3f0baf
--- /dev/null
+++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test.snap
@@ -0,0 +1,20 @@
+{
+ "Test Function getWorkflowVersion": {
+ "content": [
+ "v9.9.9"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.10.1"
+ },
+ "timestamp": "2024-02-28T12:02:05.308243"
+ },
+ "Test Function checkCondaChannels": {
+ "content": null,
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.10.1"
+ },
+ "timestamp": "2024-02-28T12:02:12.425833"
+ }
+}
\ No newline at end of file
diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test
new file mode 100644
index 0000000..ca964ce
--- /dev/null
+++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test
@@ -0,0 +1,111 @@
+nextflow_workflow {
+
+ name "Test Workflow UTILS_NEXTFLOW_PIPELINE"
+ script "../main.nf"
+ config "subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config"
+ workflow "UTILS_NEXTFLOW_PIPELINE"
+ tag 'subworkflows'
+ tag 'utils_nextflow_pipeline'
+ tag 'subworkflows/utils_nextflow_pipeline'
+
+ test("Should run no inputs") {
+
+ when {
+ workflow {
+ """
+ print_version = false
+ dump_parameters = false
+ outdir = null
+ check_conda_channels = false
+
+ input[0] = print_version
+ input[1] = dump_parameters
+ input[2] = outdir
+ input[3] = check_conda_channels
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert workflow.success }
+ )
+ }
+ }
+
+ test("Should print version") {
+
+ when {
+ workflow {
+ """
+ print_version = true
+ dump_parameters = false
+ outdir = null
+ check_conda_channels = false
+
+ input[0] = print_version
+ input[1] = dump_parameters
+ input[2] = outdir
+ input[3] = check_conda_channels
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert workflow.success },
+ { assert workflow.stdout.contains("nextflow_workflow v9.9.9") }
+ )
+ }
+ }
+
+ test("Should dump params") {
+
+ when {
+ workflow {
+ """
+ print_version = false
+ dump_parameters = true
+ outdir = 'results'
+ check_conda_channels = false
+
+ input[0] = false
+ input[1] = true
+ input[2] = outdir
+ input[3] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert workflow.success }
+ )
+ }
+ }
+
+ test("Should not create params JSON if no output directory") {
+
+ when {
+ workflow {
+ """
+ print_version = false
+ dump_parameters = true
+ outdir = null
+ check_conda_channels = false
+
+ input[0] = false
+ input[1] = true
+ input[2] = outdir
+ input[3] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert workflow.success }
+ )
+ }
+ }
+}
diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config b/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config
new file mode 100644
index 0000000..a09572e
--- /dev/null
+++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config
@@ -0,0 +1,9 @@
+manifest {
+ name = 'nextflow_workflow'
+ author = """nf-core"""
+ homePage = 'https://127.0.0.1'
+ description = """Dummy pipeline"""
+ nextflowVersion = '!>=23.04.0'
+ version = '9.9.9'
+ doi = 'https://doi.org/10.5281/zenodo.5070524'
+}
diff --git a/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml b/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml
new file mode 100644
index 0000000..f847611
--- /dev/null
+++ b/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml
@@ -0,0 +1,2 @@
+subworkflows/utils_nextflow_pipeline:
+ - subworkflows/nf-core/utils_nextflow_pipeline/**
diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/main.nf b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf
new file mode 100644
index 0000000..5cb7baf
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfcore_pipeline/main.nf
@@ -0,0 +1,462 @@
+//
+// Subworkflow with utility functions specific to the nf-core pipeline template
+//
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ SUBWORKFLOW DEFINITION
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+workflow UTILS_NFCORE_PIPELINE {
+ take:
+ nextflow_cli_args
+
+ main:
+ valid_config = checkConfigProvided()
+ checkProfileProvided(nextflow_cli_args)
+
+ emit:
+ valid_config
+}
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ FUNCTIONS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+//
+// Warn if a -profile or Nextflow config has not been provided to run the pipeline
+//
+def checkConfigProvided() {
+ def valid_config = true as Boolean
+ if (workflow.profile == 'standard' && workflow.configFiles.size() <= 1) {
+ log.warn(
+ "[${workflow.manifest.name}] You are attempting to run the pipeline without any custom configuration!\n\n" + "This will be dependent on your local compute environment but can be achieved via one or more of the following:\n" + " (1) Using an existing pipeline profile e.g. `-profile docker` or `-profile singularity`\n" + " (2) Using an existing nf-core/configs for your Institution e.g. `-profile crick` or `-profile uppmax`\n" + " (3) Using your own local custom config e.g. `-c /path/to/your/custom.config`\n\n" + "Please refer to the quick start section and usage docs for the pipeline.\n "
+ )
+ valid_config = false
+ }
+ return valid_config
+}
+
+//
+// Exit pipeline if --profile contains spaces
+//
+def checkProfileProvided(nextflow_cli_args) {
+ if (workflow.profile.endsWith(',')) {
+ error(
+ "The `-profile` option cannot end with a trailing comma, please remove it and re-run the pipeline!\n" + "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n"
+ )
+ }
+ if (nextflow_cli_args[0]) {
+ log.warn(
+ "nf-core pipelines do not accept positional arguments. The positional argument `${nextflow_cli_args[0]}` has been detected.\n" + "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n"
+ )
+ }
+}
+
+//
+// Citation string for pipeline
+//
+def workflowCitation() {
+ def temp_doi_ref = ""
+ def manifest_doi = workflow.manifest.doi.tokenize(",")
+ // Handling multiple DOIs
+ // Removing `https://doi.org/` to handle pipelines using DOIs vs DOI resolvers
+ // Removing ` ` since the manifest.doi is a string and not a proper list
+ manifest_doi.each { doi_ref ->
+ temp_doi_ref += " https://doi.org/${doi_ref.replace('https://doi.org/', '').replace(' ', '')}\n"
+ }
+ return "If you use ${workflow.manifest.name} for your analysis please cite:\n\n" + "* The pipeline\n" + temp_doi_ref + "\n" + "* The nf-core framework\n" + " https://doi.org/10.1038/s41587-020-0439-x\n\n" + "* Software dependencies\n" + " https://github.com/${workflow.manifest.name}/blob/master/CITATIONS.md"
+}
+
+//
+// Generate workflow version string
+//
+def getWorkflowVersion() {
+ def version_string = "" as String
+ if (workflow.manifest.version) {
+ def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : ''
+ version_string += "${prefix_v}${workflow.manifest.version}"
+ }
+
+ if (workflow.commitId) {
+ def git_shortsha = workflow.commitId.substring(0, 7)
+ version_string += "-g${git_shortsha}"
+ }
+
+ return version_string
+}
+
+//
+// Get software versions for pipeline
+//
+def processVersionsFromYAML(yaml_file) {
+ def yaml = new org.yaml.snakeyaml.Yaml()
+ def versions = yaml.load(yaml_file).collectEntries { k, v -> [k.tokenize(':')[-1], v] }
+ return yaml.dumpAsMap(versions).trim()
+}
+
+//
+// Get workflow version for pipeline
+//
+def workflowVersionToYAML() {
+ return """
+ Workflow:
+ ${workflow.manifest.name}: ${getWorkflowVersion()}
+ Nextflow: ${workflow.nextflow.version}
+ """.stripIndent().trim()
+}
+
+//
+// Get channel of software versions used in pipeline in YAML format
+//
+def softwareVersionsToYAML(ch_versions) {
+ return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(Channel.of(workflowVersionToYAML()))
+}
+
+//
+// Get workflow summary for MultiQC
+//
+def paramsSummaryMultiqc(summary_params) {
+ def summary_section = ''
+ summary_params
+ .keySet()
+ .each { group ->
+ def group_params = summary_params.get(group)
+ // This gets the parameters of that particular group
+ if (group_params) {
+ summary_section += " ${group}
\n"
+ summary_section += " \n"
+ group_params
+ .keySet()
+ .sort()
+ .each { param ->
+ summary_section += " - ${param}
- ${group_params.get(param) ?: 'N/A'}
\n"
+ }
+ summary_section += "
\n"
+ }
+ }
+
+ def yaml_file_text = "id: '${workflow.manifest.name.replace('/', '-')}-summary'\n" as String
+ yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n"
+ yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n"
+ yaml_file_text += "section_href: 'https://github.com/${workflow.manifest.name}'\n"
+ yaml_file_text += "plot_type: 'html'\n"
+ yaml_file_text += "data: |\n"
+ yaml_file_text += "${summary_section}"
+
+ return yaml_file_text
+}
+
+//
+// nf-core logo
+//
+def nfCoreLogo(monochrome_logs=true) {
+ def colors = logColours(monochrome_logs) as Map
+ String.format(
+ """\n
+ ${dashedLine(monochrome_logs)}
+ ${colors.green},--.${colors.black}/${colors.green},-.${colors.reset}
+ ${colors.blue} ___ __ __ __ ___ ${colors.green}/,-._.--~\'${colors.reset}
+ ${colors.blue} |\\ | |__ __ / ` / \\ |__) |__ ${colors.yellow}} {${colors.reset}
+ ${colors.blue} | \\| | \\__, \\__/ | \\ |___ ${colors.green}\\`-._,-`-,${colors.reset}
+ ${colors.green}`._,._,\'${colors.reset}
+ ${colors.purple} ${workflow.manifest.name} ${getWorkflowVersion()}${colors.reset}
+ ${dashedLine(monochrome_logs)}
+ """.stripIndent()
+ )
+}
+
+//
+// Return dashed line
+//
+def dashedLine(monochrome_logs=true) {
+ def colors = logColours(monochrome_logs) as Map
+ return "-${colors.dim}----------------------------------------------------${colors.reset}-"
+}
+
+//
+// ANSII colours used for terminal logging
+//
+def logColours(monochrome_logs=true) {
+ def colorcodes = [:] as Map
+
+ // Reset / Meta
+ colorcodes['reset'] = monochrome_logs ? '' : "\033[0m"
+ colorcodes['bold'] = monochrome_logs ? '' : "\033[1m"
+ colorcodes['dim'] = monochrome_logs ? '' : "\033[2m"
+ colorcodes['underlined'] = monochrome_logs ? '' : "\033[4m"
+ colorcodes['blink'] = monochrome_logs ? '' : "\033[5m"
+ colorcodes['reverse'] = monochrome_logs ? '' : "\033[7m"
+ colorcodes['hidden'] = monochrome_logs ? '' : "\033[8m"
+
+ // Regular Colors
+ colorcodes['black'] = monochrome_logs ? '' : "\033[0;30m"
+ colorcodes['red'] = monochrome_logs ? '' : "\033[0;31m"
+ colorcodes['green'] = monochrome_logs ? '' : "\033[0;32m"
+ colorcodes['yellow'] = monochrome_logs ? '' : "\033[0;33m"
+ colorcodes['blue'] = monochrome_logs ? '' : "\033[0;34m"
+ colorcodes['purple'] = monochrome_logs ? '' : "\033[0;35m"
+ colorcodes['cyan'] = monochrome_logs ? '' : "\033[0;36m"
+ colorcodes['white'] = monochrome_logs ? '' : "\033[0;37m"
+
+ // Bold
+ colorcodes['bblack'] = monochrome_logs ? '' : "\033[1;30m"
+ colorcodes['bred'] = monochrome_logs ? '' : "\033[1;31m"
+ colorcodes['bgreen'] = monochrome_logs ? '' : "\033[1;32m"
+ colorcodes['byellow'] = monochrome_logs ? '' : "\033[1;33m"
+ colorcodes['bblue'] = monochrome_logs ? '' : "\033[1;34m"
+ colorcodes['bpurple'] = monochrome_logs ? '' : "\033[1;35m"
+ colorcodes['bcyan'] = monochrome_logs ? '' : "\033[1;36m"
+ colorcodes['bwhite'] = monochrome_logs ? '' : "\033[1;37m"
+
+ // Underline
+ colorcodes['ublack'] = monochrome_logs ? '' : "\033[4;30m"
+ colorcodes['ured'] = monochrome_logs ? '' : "\033[4;31m"
+ colorcodes['ugreen'] = monochrome_logs ? '' : "\033[4;32m"
+ colorcodes['uyellow'] = monochrome_logs ? '' : "\033[4;33m"
+ colorcodes['ublue'] = monochrome_logs ? '' : "\033[4;34m"
+ colorcodes['upurple'] = monochrome_logs ? '' : "\033[4;35m"
+ colorcodes['ucyan'] = monochrome_logs ? '' : "\033[4;36m"
+ colorcodes['uwhite'] = monochrome_logs ? '' : "\033[4;37m"
+
+ // High Intensity
+ colorcodes['iblack'] = monochrome_logs ? '' : "\033[0;90m"
+ colorcodes['ired'] = monochrome_logs ? '' : "\033[0;91m"
+ colorcodes['igreen'] = monochrome_logs ? '' : "\033[0;92m"
+ colorcodes['iyellow'] = monochrome_logs ? '' : "\033[0;93m"
+ colorcodes['iblue'] = monochrome_logs ? '' : "\033[0;94m"
+ colorcodes['ipurple'] = monochrome_logs ? '' : "\033[0;95m"
+ colorcodes['icyan'] = monochrome_logs ? '' : "\033[0;96m"
+ colorcodes['iwhite'] = monochrome_logs ? '' : "\033[0;97m"
+
+ // Bold High Intensity
+ colorcodes['biblack'] = monochrome_logs ? '' : "\033[1;90m"
+ colorcodes['bired'] = monochrome_logs ? '' : "\033[1;91m"
+ colorcodes['bigreen'] = monochrome_logs ? '' : "\033[1;92m"
+ colorcodes['biyellow'] = monochrome_logs ? '' : "\033[1;93m"
+ colorcodes['biblue'] = monochrome_logs ? '' : "\033[1;94m"
+ colorcodes['bipurple'] = monochrome_logs ? '' : "\033[1;95m"
+ colorcodes['bicyan'] = monochrome_logs ? '' : "\033[1;96m"
+ colorcodes['biwhite'] = monochrome_logs ? '' : "\033[1;97m"
+
+ return colorcodes
+}
+
+//
+// Attach the multiqc report to email
+//
+def attachMultiqcReport(multiqc_report) {
+ def mqc_report = null
+ try {
+ if (workflow.success) {
+ mqc_report = multiqc_report.getVal()
+ if (mqc_report.getClass() == ArrayList && mqc_report.size() >= 1) {
+ if (mqc_report.size() > 1) {
+ log.warn("[${workflow.manifest.name}] Found multiple reports from process 'MULTIQC', will use only one")
+ }
+ mqc_report = mqc_report[0]
+ }
+ }
+ }
+ catch (Exception all) {
+ if (multiqc_report) {
+ log.warn("[${workflow.manifest.name}] Could not attach MultiQC report to summary email")
+ }
+ }
+ return mqc_report
+}
+
+//
+// Construct and send completion email
+//
+def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdir, monochrome_logs=true, multiqc_report=null) {
+
+ // Set up the e-mail variables
+ def subject = "[${workflow.manifest.name}] Successful: ${workflow.runName}"
+ if (!workflow.success) {
+ subject = "[${workflow.manifest.name}] FAILED: ${workflow.runName}"
+ }
+
+ def summary = [:]
+ summary_params
+ .keySet()
+ .sort()
+ .each { group ->
+ summary << summary_params[group]
+ }
+
+ def misc_fields = [:]
+ misc_fields['Date Started'] = workflow.start
+ misc_fields['Date Completed'] = workflow.complete
+ misc_fields['Pipeline script file path'] = workflow.scriptFile
+ misc_fields['Pipeline script hash ID'] = workflow.scriptId
+ if (workflow.repository) {
+ misc_fields['Pipeline repository Git URL'] = workflow.repository
+ }
+ if (workflow.commitId) {
+ misc_fields['Pipeline repository Git Commit'] = workflow.commitId
+ }
+ if (workflow.revision) {
+ misc_fields['Pipeline Git branch/tag'] = workflow.revision
+ }
+ misc_fields['Nextflow Version'] = workflow.nextflow.version
+ misc_fields['Nextflow Build'] = workflow.nextflow.build
+ misc_fields['Nextflow Compile Timestamp'] = workflow.nextflow.timestamp
+
+ def email_fields = [:]
+ email_fields['version'] = getWorkflowVersion()
+ email_fields['runName'] = workflow.runName
+ email_fields['success'] = workflow.success
+ email_fields['dateComplete'] = workflow.complete
+ email_fields['duration'] = workflow.duration
+ email_fields['exitStatus'] = workflow.exitStatus
+ email_fields['errorMessage'] = (workflow.errorMessage ?: 'None')
+ email_fields['errorReport'] = (workflow.errorReport ?: 'None')
+ email_fields['commandLine'] = workflow.commandLine
+ email_fields['projectDir'] = workflow.projectDir
+ email_fields['summary'] = summary << misc_fields
+
+ // On success try attach the multiqc report
+ def mqc_report = attachMultiqcReport(multiqc_report)
+
+ // Check if we are only sending emails on failure
+ def email_address = email
+ if (!email && email_on_fail && !workflow.success) {
+ email_address = email_on_fail
+ }
+
+ // Render the TXT template
+ def engine = new groovy.text.GStringTemplateEngine()
+ def tf = new File("${workflow.projectDir}/assets/email_template.txt")
+ def txt_template = engine.createTemplate(tf).make(email_fields)
+ def email_txt = txt_template.toString()
+
+ // Render the HTML template
+ def hf = new File("${workflow.projectDir}/assets/email_template.html")
+ def html_template = engine.createTemplate(hf).make(email_fields)
+ def email_html = html_template.toString()
+
+ // Render the sendmail template
+ def max_multiqc_email_size = (params.containsKey('max_multiqc_email_size') ? params.max_multiqc_email_size : 0) as nextflow.util.MemoryUnit
+ def smail_fields = [email: email_address, subject: subject, email_txt: email_txt, email_html: email_html, projectDir: "${workflow.projectDir}", mqcFile: mqc_report, mqcMaxSize: max_multiqc_email_size.toBytes()]
+ def sf = new File("${workflow.projectDir}/assets/sendmail_template.txt")
+ def sendmail_template = engine.createTemplate(sf).make(smail_fields)
+ def sendmail_html = sendmail_template.toString()
+
+ // Send the HTML e-mail
+ def colors = logColours(monochrome_logs) as Map
+ if (email_address) {
+ try {
+ if (plaintext_email) {
+new org.codehaus.groovy.GroovyException('Send plaintext e-mail, not HTML') }
+ // Try to send HTML e-mail using sendmail
+ def sendmail_tf = new File(workflow.launchDir.toString(), ".sendmail_tmp.html")
+ sendmail_tf.withWriter { w -> w << sendmail_html }
+ ['sendmail', '-t'].execute() << sendmail_html
+ log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (sendmail)-")
+ }
+ catch (Exception all) {
+ // Catch failures and try with plaintext
+ def mail_cmd = ['mail', '-s', subject, '--content-type=text/html', email_address]
+ mail_cmd.execute() << email_html
+ log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (mail)-")
+ }
+ }
+
+ // Write summary e-mail HTML to a file
+ def output_hf = new File(workflow.launchDir.toString(), ".pipeline_report.html")
+ output_hf.withWriter { w -> w << email_html }
+ nextflow.extension.FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html")
+ output_hf.delete()
+
+ // Write summary e-mail TXT to a file
+ def output_tf = new File(workflow.launchDir.toString(), ".pipeline_report.txt")
+ output_tf.withWriter { w -> w << email_txt }
+ nextflow.extension.FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt")
+ output_tf.delete()
+}
+
+//
+// Print pipeline summary on completion
+//
+def completionSummary(monochrome_logs=true) {
+ def colors = logColours(monochrome_logs) as Map
+ if (workflow.success) {
+ if (workflow.stats.ignoredCount == 0) {
+ log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Pipeline completed successfully${colors.reset}-")
+ }
+ else {
+ log.info("-${colors.purple}[${workflow.manifest.name}]${colors.yellow} Pipeline completed successfully, but with errored process(es) ${colors.reset}-")
+ }
+ }
+ else {
+ log.info("-${colors.purple}[${workflow.manifest.name}]${colors.red} Pipeline completed with errors${colors.reset}-")
+ }
+}
+
+//
+// Construct and send a notification to a web server as JSON e.g. Microsoft Teams and Slack
+//
+def imNotification(summary_params, hook_url) {
+ def summary = [:]
+ summary_params
+ .keySet()
+ .sort()
+ .each { group ->
+ summary << summary_params[group]
+ }
+
+ def misc_fields = [:]
+ misc_fields['start'] = workflow.start
+ misc_fields['complete'] = workflow.complete
+ misc_fields['scriptfile'] = workflow.scriptFile
+ misc_fields['scriptid'] = workflow.scriptId
+ if (workflow.repository) {
+ misc_fields['repository'] = workflow.repository
+ }
+ if (workflow.commitId) {
+ misc_fields['commitid'] = workflow.commitId
+ }
+ if (workflow.revision) {
+ misc_fields['revision'] = workflow.revision
+ }
+ misc_fields['nxf_version'] = workflow.nextflow.version
+ misc_fields['nxf_build'] = workflow.nextflow.build
+ misc_fields['nxf_timestamp'] = workflow.nextflow.timestamp
+
+ def msg_fields = [:]
+ msg_fields['version'] = getWorkflowVersion()
+ msg_fields['runName'] = workflow.runName
+ msg_fields['success'] = workflow.success
+ msg_fields['dateComplete'] = workflow.complete
+ msg_fields['duration'] = workflow.duration
+ msg_fields['exitStatus'] = workflow.exitStatus
+ msg_fields['errorMessage'] = (workflow.errorMessage ?: 'None')
+ msg_fields['errorReport'] = (workflow.errorReport ?: 'None')
+ msg_fields['commandLine'] = workflow.commandLine.replaceFirst(/ +--hook_url +[^ ]+/, "")
+ msg_fields['projectDir'] = workflow.projectDir
+ msg_fields['summary'] = summary << misc_fields
+
+ // Render the JSON template
+ def engine = new groovy.text.GStringTemplateEngine()
+ // Different JSON depending on the service provider
+ // Defaults to "Adaptive Cards" (https://adaptivecards.io), except Slack which has its own format
+ def json_path = hook_url.contains("hooks.slack.com") ? "slackreport.json" : "adaptivecard.json"
+ def hf = new File("${workflow.projectDir}/assets/${json_path}")
+ def json_template = engine.createTemplate(hf).make(msg_fields)
+ def json_message = json_template.toString()
+
+ // POST
+ def post = new URL(hook_url).openConnection()
+ post.setRequestMethod("POST")
+ post.setDoOutput(true)
+ post.setRequestProperty("Content-Type", "application/json")
+ post.getOutputStream().write(json_message.getBytes("UTF-8"))
+ def postRC = post.getResponseCode()
+ if (!postRC.equals(200)) {
+ log.warn(post.getErrorStream().getText())
+ }
+}
diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/meta.yml b/subworkflows/nf-core/utils_nfcore_pipeline/meta.yml
new file mode 100644
index 0000000..d08d243
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfcore_pipeline/meta.yml
@@ -0,0 +1,24 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json
+name: "UTILS_NFCORE_PIPELINE"
+description: Subworkflow with utility functions specific to the nf-core pipeline template
+keywords:
+ - utility
+ - pipeline
+ - initialise
+ - version
+components: []
+input:
+ - nextflow_cli_args:
+ type: list
+ description: |
+ Nextflow CLI positional arguments
+output:
+ - success:
+ type: boolean
+ description: |
+ Dummy output to indicate success
+authors:
+ - "@adamrtalbot"
+maintainers:
+ - "@adamrtalbot"
+ - "@maxulysse"
diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test
new file mode 100644
index 0000000..1dc317f
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test
@@ -0,0 +1,134 @@
+
+nextflow_function {
+
+ name "Test Functions"
+ script "../main.nf"
+ config "subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config"
+ tag "subworkflows"
+ tag "subworkflows_nfcore"
+ tag "utils_nfcore_pipeline"
+ tag "subworkflows/utils_nfcore_pipeline"
+
+ test("Test Function checkConfigProvided") {
+
+ function "checkConfigProvided"
+
+ then {
+ assertAll(
+ { assert function.success },
+ { assert snapshot(function.result).match() }
+ )
+ }
+ }
+
+ test("Test Function checkProfileProvided") {
+
+ function "checkProfileProvided"
+
+ when {
+ function {
+ """
+ input[0] = []
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert function.success },
+ { assert snapshot(function.result).match() }
+ )
+ }
+ }
+
+ test("Test Function workflowCitation") {
+
+ function "workflowCitation"
+
+ then {
+ assertAll(
+ { assert function.success },
+ { assert snapshot(function.result).match() }
+ )
+ }
+ }
+
+ test("Test Function nfCoreLogo") {
+
+ function "nfCoreLogo"
+
+ when {
+ function {
+ """
+ input[0] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert function.success },
+ { assert snapshot(function.result).match() }
+ )
+ }
+ }
+
+ test("Test Function dashedLine") {
+
+ function "dashedLine"
+
+ when {
+ function {
+ """
+ input[0] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert function.success },
+ { assert snapshot(function.result).match() }
+ )
+ }
+ }
+
+ test("Test Function without logColours") {
+
+ function "logColours"
+
+ when {
+ function {
+ """
+ input[0] = true
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert function.success },
+ { assert snapshot(function.result).match() }
+ )
+ }
+ }
+
+ test("Test Function with logColours") {
+ function "logColours"
+
+ when {
+ function {
+ """
+ input[0] = false
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert function.success },
+ { assert snapshot(function.result).match() }
+ )
+ }
+ }
+}
diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test.snap b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test.snap
new file mode 100644
index 0000000..1037232
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test.snap
@@ -0,0 +1,166 @@
+{
+ "Test Function checkProfileProvided": {
+ "content": null,
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.10.1"
+ },
+ "timestamp": "2024-02-28T12:03:03.360873"
+ },
+ "Test Function checkConfigProvided": {
+ "content": [
+ true
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.10.1"
+ },
+ "timestamp": "2024-02-28T12:02:59.729647"
+ },
+ "Test Function nfCoreLogo": {
+ "content": [
+ "\n\n-\u001b[2m----------------------------------------------------\u001b[0m-\n \u001b[0;32m,--.\u001b[0;30m/\u001b[0;32m,-.\u001b[0m\n\u001b[0;34m ___ __ __ __ ___ \u001b[0;32m/,-._.--~'\u001b[0m\n\u001b[0;34m |\\ | |__ __ / ` / \\ |__) |__ \u001b[0;33m} {\u001b[0m\n\u001b[0;34m | \\| | \\__, \\__/ | \\ |___ \u001b[0;32m\\`-._,-`-,\u001b[0m\n \u001b[0;32m`._,._,'\u001b[0m\n\u001b[0;35m nextflow_workflow v9.9.9\u001b[0m\n-\u001b[2m----------------------------------------------------\u001b[0m-\n"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.10.1"
+ },
+ "timestamp": "2024-02-28T12:03:10.562934"
+ },
+ "Test Function workflowCitation": {
+ "content": [
+ "If you use nextflow_workflow for your analysis please cite:\n\n* The pipeline\n https://doi.org/10.5281/zenodo.5070524\n\n* The nf-core framework\n https://doi.org/10.1038/s41587-020-0439-x\n\n* Software dependencies\n https://github.com/nextflow_workflow/blob/master/CITATIONS.md"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.10.1"
+ },
+ "timestamp": "2024-02-28T12:03:07.019761"
+ },
+ "Test Function without logColours": {
+ "content": [
+ {
+ "reset": "",
+ "bold": "",
+ "dim": "",
+ "underlined": "",
+ "blink": "",
+ "reverse": "",
+ "hidden": "",
+ "black": "",
+ "red": "",
+ "green": "",
+ "yellow": "",
+ "blue": "",
+ "purple": "",
+ "cyan": "",
+ "white": "",
+ "bblack": "",
+ "bred": "",
+ "bgreen": "",
+ "byellow": "",
+ "bblue": "",
+ "bpurple": "",
+ "bcyan": "",
+ "bwhite": "",
+ "ublack": "",
+ "ured": "",
+ "ugreen": "",
+ "uyellow": "",
+ "ublue": "",
+ "upurple": "",
+ "ucyan": "",
+ "uwhite": "",
+ "iblack": "",
+ "ired": "",
+ "igreen": "",
+ "iyellow": "",
+ "iblue": "",
+ "ipurple": "",
+ "icyan": "",
+ "iwhite": "",
+ "biblack": "",
+ "bired": "",
+ "bigreen": "",
+ "biyellow": "",
+ "biblue": "",
+ "bipurple": "",
+ "bicyan": "",
+ "biwhite": ""
+ }
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.10.1"
+ },
+ "timestamp": "2024-02-28T12:03:17.969323"
+ },
+ "Test Function dashedLine": {
+ "content": [
+ "-\u001b[2m----------------------------------------------------\u001b[0m-"
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.10.1"
+ },
+ "timestamp": "2024-02-28T12:03:14.366181"
+ },
+ "Test Function with logColours": {
+ "content": [
+ {
+ "reset": "\u001b[0m",
+ "bold": "\u001b[1m",
+ "dim": "\u001b[2m",
+ "underlined": "\u001b[4m",
+ "blink": "\u001b[5m",
+ "reverse": "\u001b[7m",
+ "hidden": "\u001b[8m",
+ "black": "\u001b[0;30m",
+ "red": "\u001b[0;31m",
+ "green": "\u001b[0;32m",
+ "yellow": "\u001b[0;33m",
+ "blue": "\u001b[0;34m",
+ "purple": "\u001b[0;35m",
+ "cyan": "\u001b[0;36m",
+ "white": "\u001b[0;37m",
+ "bblack": "\u001b[1;30m",
+ "bred": "\u001b[1;31m",
+ "bgreen": "\u001b[1;32m",
+ "byellow": "\u001b[1;33m",
+ "bblue": "\u001b[1;34m",
+ "bpurple": "\u001b[1;35m",
+ "bcyan": "\u001b[1;36m",
+ "bwhite": "\u001b[1;37m",
+ "ublack": "\u001b[4;30m",
+ "ured": "\u001b[4;31m",
+ "ugreen": "\u001b[4;32m",
+ "uyellow": "\u001b[4;33m",
+ "ublue": "\u001b[4;34m",
+ "upurple": "\u001b[4;35m",
+ "ucyan": "\u001b[4;36m",
+ "uwhite": "\u001b[4;37m",
+ "iblack": "\u001b[0;90m",
+ "ired": "\u001b[0;91m",
+ "igreen": "\u001b[0;92m",
+ "iyellow": "\u001b[0;93m",
+ "iblue": "\u001b[0;94m",
+ "ipurple": "\u001b[0;95m",
+ "icyan": "\u001b[0;96m",
+ "iwhite": "\u001b[0;97m",
+ "biblack": "\u001b[1;90m",
+ "bired": "\u001b[1;91m",
+ "bigreen": "\u001b[1;92m",
+ "biyellow": "\u001b[1;93m",
+ "biblue": "\u001b[1;94m",
+ "bipurple": "\u001b[1;95m",
+ "bicyan": "\u001b[1;96m",
+ "biwhite": "\u001b[1;97m"
+ }
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.10.1"
+ },
+ "timestamp": "2024-02-28T12:03:21.714424"
+ }
+}
\ No newline at end of file
diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test
new file mode 100644
index 0000000..8940d32
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test
@@ -0,0 +1,29 @@
+nextflow_workflow {
+
+ name "Test Workflow UTILS_NFCORE_PIPELINE"
+ script "../main.nf"
+ config "subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config"
+ workflow "UTILS_NFCORE_PIPELINE"
+ tag "subworkflows"
+ tag "subworkflows_nfcore"
+ tag "utils_nfcore_pipeline"
+ tag "subworkflows/utils_nfcore_pipeline"
+
+ test("Should run without failures") {
+
+ when {
+ workflow {
+ """
+ input[0] = []
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert workflow.success },
+ { assert snapshot(workflow.out).match() }
+ )
+ }
+ }
+}
diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap
new file mode 100644
index 0000000..859d103
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap
@@ -0,0 +1,19 @@
+{
+ "Should run without failures": {
+ "content": [
+ {
+ "0": [
+ true
+ ],
+ "valid_config": [
+ true
+ ]
+ }
+ ],
+ "meta": {
+ "nf-test": "0.8.4",
+ "nextflow": "23.10.1"
+ },
+ "timestamp": "2024-02-28T12:03:25.726491"
+ }
+}
\ No newline at end of file
diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config b/subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config
new file mode 100644
index 0000000..d0a926b
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config
@@ -0,0 +1,9 @@
+manifest {
+ name = 'nextflow_workflow'
+ author = """nf-core"""
+ homePage = 'https://127.0.0.1'
+ description = """Dummy pipeline"""
+ nextflowVersion = '!>=23.04.0'
+ version = '9.9.9'
+ doi = 'https://doi.org/10.5281/zenodo.5070524'
+}
diff --git a/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml b/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml
new file mode 100644
index 0000000..ac8523c
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml
@@ -0,0 +1,2 @@
+subworkflows/utils_nfcore_pipeline:
+ - subworkflows/nf-core/utils_nfcore_pipeline/**
diff --git a/subworkflows/nf-core/utils_nfschema_plugin/main.nf b/subworkflows/nf-core/utils_nfschema_plugin/main.nf
new file mode 100644
index 0000000..4994303
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfschema_plugin/main.nf
@@ -0,0 +1,46 @@
+//
+// Subworkflow that uses the nf-schema plugin to validate parameters and render the parameter summary
+//
+
+include { paramsSummaryLog } from 'plugin/nf-schema'
+include { validateParameters } from 'plugin/nf-schema'
+
+workflow UTILS_NFSCHEMA_PLUGIN {
+
+ take:
+ input_workflow // workflow: the workflow object used by nf-schema to get metadata from the workflow
+ validate_params // boolean: validate the parameters
+ parameters_schema // string: path to the parameters JSON schema.
+ // this has to be the same as the schema given to `validation.parametersSchema`
+ // when this input is empty it will automatically use the configured schema or
+ // "${projectDir}/nextflow_schema.json" as default. This input should not be empty
+ // for meta pipelines
+
+ main:
+
+ //
+ // Print parameter summary to stdout. This will display the parameters
+ // that differ from the default given in the JSON schema
+ //
+ if(parameters_schema) {
+ log.info paramsSummaryLog(input_workflow, parameters_schema:parameters_schema)
+ } else {
+ log.info paramsSummaryLog(input_workflow)
+ }
+
+ //
+ // Validate the parameters using nextflow_schema.json or the schema
+ // given via the validation.parametersSchema configuration option
+ //
+ if(validate_params) {
+ if(parameters_schema) {
+ validateParameters(parameters_schema:parameters_schema)
+ } else {
+ validateParameters()
+ }
+ }
+
+ emit:
+ dummy_emit = true
+}
+
diff --git a/subworkflows/nf-core/utils_nfschema_plugin/meta.yml b/subworkflows/nf-core/utils_nfschema_plugin/meta.yml
new file mode 100644
index 0000000..f7d9f02
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfschema_plugin/meta.yml
@@ -0,0 +1,35 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json
+name: "utils_nfschema_plugin"
+description: Run nf-schema to validate parameters and create a summary of changed parameters
+keywords:
+ - validation
+ - JSON schema
+ - plugin
+ - parameters
+ - summary
+components: []
+input:
+ - input_workflow:
+ type: object
+ description: |
+ The workflow object of the used pipeline.
+ This object contains meta data used to create the params summary log
+ - validate_params:
+ type: boolean
+ description: Validate the parameters and error if invalid.
+ - parameters_schema:
+ type: string
+ description: |
+ Path to the parameters JSON schema.
+ This has to be the same as the schema given to the `validation.parametersSchema` config
+ option. When this input is empty it will automatically use the configured schema or
+ "${projectDir}/nextflow_schema.json" as default. The schema should not be given in this way
+ for meta pipelines.
+output:
+ - dummy_emit:
+ type: boolean
+ description: Dummy emit to make nf-core subworkflows lint happy
+authors:
+ - "@nvnieuwk"
+maintainers:
+ - "@nvnieuwk"
diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test
new file mode 100644
index 0000000..842dc43
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test
@@ -0,0 +1,117 @@
+nextflow_workflow {
+
+ name "Test Subworkflow UTILS_NFSCHEMA_PLUGIN"
+ script "../main.nf"
+ workflow "UTILS_NFSCHEMA_PLUGIN"
+
+ tag "subworkflows"
+ tag "subworkflows_nfcore"
+ tag "subworkflows/utils_nfschema_plugin"
+ tag "plugin/nf-schema"
+
+ config "./nextflow.config"
+
+ test("Should run nothing") {
+
+ when {
+
+ params {
+ test_data = ''
+ }
+
+ workflow {
+ """
+ validate_params = false
+ input[0] = workflow
+ input[1] = validate_params
+ input[2] = ""
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert workflow.success }
+ )
+ }
+ }
+
+ test("Should validate params") {
+
+ when {
+
+ params {
+ test_data = ''
+ outdir = 1
+ }
+
+ workflow {
+ """
+ validate_params = true
+ input[0] = workflow
+ input[1] = validate_params
+ input[2] = ""
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert workflow.failed },
+ { assert workflow.stdout.any { it.contains('ERROR ~ Validation of pipeline parameters failed!') } }
+ )
+ }
+ }
+
+ test("Should run nothing - custom schema") {
+
+ when {
+
+ params {
+ test_data = ''
+ }
+
+ workflow {
+ """
+ validate_params = false
+ input[0] = workflow
+ input[1] = validate_params
+ input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json"
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert workflow.success }
+ )
+ }
+ }
+
+ test("Should validate params - custom schema") {
+
+ when {
+
+ params {
+ test_data = ''
+ outdir = 1
+ }
+
+ workflow {
+ """
+ validate_params = true
+ input[0] = workflow
+ input[1] = validate_params
+ input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json"
+ """
+ }
+ }
+
+ then {
+ assertAll(
+ { assert workflow.failed },
+ { assert workflow.stdout.any { it.contains('ERROR ~ Validation of pipeline parameters failed!') } }
+ )
+ }
+ }
+}
diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config
new file mode 100644
index 0000000..0907ac5
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config
@@ -0,0 +1,8 @@
+plugins {
+ id "nf-schema@2.1.0"
+}
+
+validation {
+ parametersSchema = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json"
+ monochromeLogs = true
+}
\ No newline at end of file
diff --git a/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json
new file mode 100644
index 0000000..331e0d2
--- /dev/null
+++ b/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json
@@ -0,0 +1,96 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://raw.githubusercontent.com/./master/nextflow_schema.json",
+ "title": ". pipeline parameters",
+ "description": "",
+ "type": "object",
+ "$defs": {
+ "input_output_options": {
+ "title": "Input/output options",
+ "type": "object",
+ "fa_icon": "fas fa-terminal",
+ "description": "Define where the pipeline should find input data and save output data.",
+ "required": ["outdir"],
+ "properties": {
+ "validate_params": {
+ "type": "boolean",
+ "description": "Validate parameters?",
+ "default": true,
+ "hidden": true
+ },
+ "outdir": {
+ "type": "string",
+ "format": "directory-path",
+ "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.",
+ "fa_icon": "fas fa-folder-open"
+ },
+ "test_data_base": {
+ "type": "string",
+ "default": "https://raw.githubusercontent.com/nf-core/test-datasets/modules",
+ "description": "Base for test data directory",
+ "hidden": true
+ },
+ "test_data": {
+ "type": "string",
+ "description": "Fake test data param",
+ "hidden": true
+ }
+ }
+ },
+ "generic_options": {
+ "title": "Generic options",
+ "type": "object",
+ "fa_icon": "fas fa-file-import",
+ "description": "Less common options for the pipeline, typically set in a config file.",
+ "help_text": "These options are common to all nf-core pipelines and allow you to customise some of the core preferences for how the pipeline runs.\n\nTypically these options would be set in a Nextflow config file loaded for all pipeline runs, such as `~/.nextflow/config`.",
+ "properties": {
+ "help": {
+ "type": "boolean",
+ "description": "Display help text.",
+ "fa_icon": "fas fa-question-circle",
+ "hidden": true
+ },
+ "version": {
+ "type": "boolean",
+ "description": "Display version and exit.",
+ "fa_icon": "fas fa-question-circle",
+ "hidden": true
+ },
+ "logo": {
+ "type": "boolean",
+ "default": true,
+ "description": "Display nf-core logo in console output.",
+ "fa_icon": "fas fa-image",
+ "hidden": true
+ },
+ "singularity_pull_docker_container": {
+ "type": "boolean",
+ "description": "Pull Singularity container from Docker?",
+ "hidden": true
+ },
+ "publish_dir_mode": {
+ "type": "string",
+ "default": "copy",
+ "description": "Method used to save pipeline results to output directory.",
+ "help_text": "The Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.",
+ "fa_icon": "fas fa-copy",
+ "enum": ["symlink", "rellink", "link", "copy", "copyNoFollow", "move"],
+ "hidden": true
+ },
+ "monochrome_logs": {
+ "type": "boolean",
+ "description": "Use monochrome_logs",
+ "hidden": true
+ }
+ }
+ }
+ },
+ "allOf": [
+ {
+ "$ref": "#/$defs/input_output_options"
+ },
+ {
+ "$ref": "#/$defs/generic_options"
+ }
+ ]
+}
diff --git a/workflows/mobict.nf b/workflows/mobict.nf
new file mode 100644
index 0000000..944e885
--- /dev/null
+++ b/workflows/mobict.nf
@@ -0,0 +1,168 @@
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+include { BCFTOOLS_STATS } from '../modules/nf-core/bcftools/stats/main'
+include { BWA_MEM } from '../modules/nf-core/bwa/mem/main'
+include { BWA_MEM as rerunBWA_MEM } from '../modules/nf-core/bwa/mem/main'
+include { ENSEMBLVEP_VEP } from '../modules/nf-core/ensemblvep/vep/main'
+include { FASTP } from '../modules/nf-core/fastp/main'
+include { FGBIO_CALLMOLECULARCONSENSUSREADS } from '../modules/nf-core/fgbio/callmolecularconsensusreads/main'
+include { FGBIO_GROUPREADSBYUMI } from '../modules/nf-core/fgbio/groupreadsbyumi/main'
+include { GATK4_FASTQTOSAM } from '../modules/nf-core/gatk4/fastqtosam/main'
+include { GATK4_SAMTOFASTQ } from '../modules/nf-core/gatk4/samtofastq/main'
+include { GATK4_SAMTOFASTQ as rerunGATK4_SAMTOFASTQ } from '../modules/nf-core/gatk4/samtofastq/main'
+include { GATK4_MERGEBAMALIGNMENT } from '../modules/nf-core/gatk4/mergebamalignment/main'
+include { GATK4_MERGEBAMALIGNMENT as rerunGATK4_MERGEBAMALIGNMENT } from '../modules/nf-core/gatk4/mergebamalignment/main'
+include { PICARD_BEDTOINTERVALLIST } from '../modules/nf-core/picard/bedtointervallist/main'
+include { PICARD_COLLECTHSMETRICS } from '../modules/nf-core/picard/collecthsmetrics/main'
+include { PICARD_SORTSAM } from '../modules/nf-core/picard/sortsam/main'
+include { PICARD_SORTSAM as rerunPICARD_SORTSAM } from '../modules/nf-core/picard/sortsam/main'
+include { SAMTOOLS_INDEX } from '../modules/nf-core/samtools/index/main'
+include { SAMTOOLS_VIEW } from '../modules/nf-core/samtools/view/main'
+include { VARDICTJAVA } from '../modules/nf-core/vardictjava/main'
+include { FGBIO_EXTRACTUMISFROMBAM } from '../modules/local/fgbio/extractumisfrombam/main'
+
+include { MULTIQC } from '../modules/nf-core/multiqc/main'
+include { paramsSummaryMap } from 'plugin/nf-schema'
+include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline'
+include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline'
+include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_mobict_pipeline'
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ RUN MAIN WORKFLOW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/
+
+workflow MOBICT {
+
+ take:
+ ch_samplesheet // channel: samplesheet read in from --input
+ main:
+
+ ch_versions = Channel.empty()
+ ch_multiqc_files = Channel.empty()
+
+ GATK4_FASTQTOSAM(ch_samplesheet)
+ ch_versions = ch_versions.mix(GATK4_FASTQTOSAM.out.versions)
+
+ FGBIO_EXTRACTUMISFROMBAM(GATK4_FASTQTOSAM.out.bam, params.read_structure, params.molecular_index_tags)
+ ch_versions = ch_versions.mix(FGBIO_EXTRACTUMISFROMBAM.out.versions)
+
+ GATK4_SAMTOFASTQ(FGBIO_EXTRACTUMISFROMBAM.out.bam)
+ ch_versions = ch_versions.mix(GATK4_SAMTOFASTQ.out.versions)
+
+ FASTP(GATK4_SAMTOFASTQ.out.fastq, [], false, false, false)
+ ch_versions = ch_versions.mix(FASTP.out.versions)
+
+ BWA_MEM(FASTP.out.reads,["idx", params.index_alignment], ["fasta", params.fasta], false)
+ ch_versions = ch_versions.mix(BWA_MEM.out.versions)
+
+ BWA_MEM.out.bam.join(FGBIO_EXTRACTUMISFROMBAM.out.bam).set{bams_umis}
+ GATK4_MERGEBAMALIGNMENT(bams_umis, ["fasta", params.fasta], ["dict", params.dict])
+ ch_versions = ch_versions.mix(GATK4_MERGEBAMALIGNMENT.out.versions)
+
+ // NEEDS TO BE IMPROVED - bai expected but cannot be generated due to srt order by 'queryname'
+ // As bai is not necessecary, use join with another to avoir emty data expected (and mandatory) by SAMTOOLS_VIEW
+ GATK4_MERGEBAMALIGNMENT.out.bam.join( BWA_MEM.out.bam ).set{bam_merged}
+ ch_versions = ch_versions.mix(GATK4_MERGEBAMALIGNMENT.out.versions)
+ SAMTOOLS_VIEW(bam_merged, ["fasta", params.fasta], [])
+ ch_versions = ch_versions.mix(SAMTOOLS_VIEW.out.versions)
+
+ FGBIO_GROUPREADSBYUMI(SAMTOOLS_VIEW.out.bam, "adjacency")
+ ch_versions = ch_versions.mix(FGBIO_GROUPREADSBYUMI.out.versions)
+ ch_multiqc_files = ch_multiqc_files.mix(FGBIO_GROUPREADSBYUMI.out.histogram)
+
+ FGBIO_CALLMOLECULARCONSENSUSREADS(FGBIO_GROUPREADSBYUMI.out.bam, 2, 10)
+ ch_versions = ch_versions.mix(FGBIO_CALLMOLECULARCONSENSUSREADS.out.versions)
+
+ rerunGATK4_SAMTOFASTQ(FGBIO_CALLMOLECULARCONSENSUSREADS.out.bam)
+ ch_versions = ch_versions.mix(rerunGATK4_SAMTOFASTQ.out.versions)
+ rerunBWA_MEM(rerunGATK4_SAMTOFASTQ.out.fastq, ["idx", params.index_alignment], ["fasta", params.fasta], false)
+ ch_versions = ch_versions.mix(rerunBWA_MEM.out.versions)
+
+ PICARD_SORTSAM(FGBIO_CALLMOLECULARCONSENSUSREADS.out.bam, "queryname")
+ ch_versions = ch_versions.mix(PICARD_SORTSAM.out.versions)
+ rerunPICARD_SORTSAM(rerunBWA_MEM.out.bam, "queryname")
+ ch_versions = ch_versions.mix(rerunPICARD_SORTSAM.out.versions)
+
+ rerunPICARD_SORTSAM.out.bam.join(PICARD_SORTSAM.out.bam).set{ bams_sorted }
+ rerunGATK4_MERGEBAMALIGNMENT(bams_sorted, ["fasta", params.fasta], ["dict", params.dict])
+ ch_versions = ch_versions.mix(rerunGATK4_MERGEBAMALIGNMENT.out.versions)
+
+ SAMTOOLS_INDEX(rerunGATK4_MERGEBAMALIGNMENT.out.bam)
+ ch_versions = ch_versions.mix(SAMTOOLS_INDEX.out.versions)
+
+ rerunGATK4_MERGEBAMALIGNMENT.out.bam.join(SAMTOOLS_INDEX.out.bai).combine([params.bed]).set{ bams_aligned }
+ VARDICTJAVA(bams_aligned, ["fasta", params.fasta], ["fai", params.fai])
+ ch_versions = ch_versions.mix(VARDICTJAVA.out.versions)
+
+ VARDICTJAVA.out.vcf.join(BWA_MEM.out.bam ).set{vcf}
+ ENSEMBLVEP_VEP(vcf, params.assembly, params.species, params.cache_version, params.cache_dir, ["fasta", params.fasta], params.index_alignment)
+ ch_versions = ch_versions.mix(ENSEMBLVEP_VEP.out.versions)
+
+ //
+ // Collate and save software versions
+ //
+ softwareVersionsToYAML(ch_versions)
+ .collectFile(
+ storeDir: "${params.outdir}/pipeline_info",
+ name: '' + 'pipeline_software_' + 'mqc_' + 'versions.yml',
+ sort: true,
+ newLine: true
+ ).set { ch_collated_versions }
+
+
+ //
+ // MODULE: MultiQC
+ //
+ ch_multiqc_config = Channel.fromPath(
+ "$projectDir/assets/multiqc_config.yml", checkIfExists: true)
+ ch_multiqc_custom_config = params.multiqc_config ?
+ Channel.fromPath(params.multiqc_config, checkIfExists: true) :
+ Channel.empty()
+ ch_multiqc_logo = params.multiqc_logo ?
+ Channel.fromPath(params.multiqc_logo, checkIfExists: true) :
+ Channel.empty()
+
+ summary_params = paramsSummaryMap(
+ workflow, parameters_schema: "nextflow_schema.json")
+ ch_workflow_summary = Channel.value(paramsSummaryMultiqc(summary_params))
+ ch_multiqc_files = ch_multiqc_files.mix(
+ ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml'))
+ ch_multiqc_custom_methods_description = params.multiqc_methods_description ?
+ file(params.multiqc_methods_description, checkIfExists: true) :
+ file("$projectDir/assets/methods_description_template.yml", checkIfExists: true)
+ ch_methods_description = Channel.value(
+ methodsDescriptionText(ch_multiqc_custom_methods_description))
+
+ ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions)
+ ch_multiqc_files = ch_multiqc_files.mix(
+ ch_methods_description.collectFile(
+ name: 'methods_description_mqc.yaml',
+ sort: true
+ )
+ )
+
+ MULTIQC (
+ ch_multiqc_files.collect(),
+ ch_multiqc_config.toList(),
+ ch_multiqc_custom_config.toList(),
+ ch_multiqc_logo.toList(),
+ [],
+ []
+ )
+
+ emit:multiqc_report = MULTIQC.out.report.toList() // channel: /path/to/multiqc_report.html
+ versions = ch_versions // channel: [ path(versions.yml) ]
+
+}
+
+/*
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ THE END
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*/