Skip to content

Commit f3fb87a

Browse files
9396 new subworkflow fastq decontaminate deacon hostile (#9441)
* initial commit * first main.nf version * added tests * added the metadata * implemented first review changes --------- Co-authored-by: Evangelos Karatzas <32259775+vagkaratzas@users.noreply.github.com>
1 parent 99590bc commit f3fb87a

5 files changed

Lines changed: 605 additions & 0 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
include { FASTQ_FETCH_CLEAN_HOSTILE } from '../fastq_fetch_clean_hostile/main'
2+
include { FASTQ_INDEX_FILTER_DEACON } from '../fastq_index_filter_deacon/main'
3+
4+
workflow FASTQ_DECONTAMINATE_DEACON_HOSTILE {
5+
6+
take:
7+
ch_reads // channel: [ val(meta), [ reads ] ]
8+
ch_fasta // channel: [ val(meta), [ fasta ] ] (optional)
9+
ch_reference // channel: [ val(reference_name), path(reference_dir) ] (optional)
10+
index_name // val (optional)
11+
decontaminator // string (enum): 'hostile' or 'deacon'
12+
13+
main:
14+
15+
ch_versions = channel.empty()
16+
reference = channel.empty()
17+
json = channel.empty()
18+
index = channel.empty()
19+
summary = channel.empty()
20+
21+
if (decontaminator != "hostile" && decontaminator != "deacon"){
22+
error("Unknown decontaminator '${decontaminator}'")
23+
}
24+
25+
// Fastq decontamination
26+
if (decontaminator == "hostile") {
27+
FASTQ_FETCH_CLEAN_HOSTILE (
28+
ch_reads,
29+
ch_reference,
30+
index_name
31+
)
32+
fastq_filtered = FASTQ_FETCH_CLEAN_HOSTILE.out.fastq
33+
ch_versions = ch_versions.mix(FASTQ_FETCH_CLEAN_HOSTILE.out.versions.first())
34+
reference = FASTQ_FETCH_CLEAN_HOSTILE.out.reference
35+
json = FASTQ_FETCH_CLEAN_HOSTILE.out.json
36+
} else if (decontaminator == "deacon") {
37+
FASTQ_INDEX_FILTER_DEACON (
38+
ch_fasta.join(ch_reads)
39+
)
40+
fastq_filtered = FASTQ_INDEX_FILTER_DEACON.out.fastq_filtered
41+
ch_versions = ch_versions.mix(FASTQ_INDEX_FILTER_DEACON.out.versions.first())
42+
index = FASTQ_INDEX_FILTER_DEACON.out.index
43+
summary = FASTQ_INDEX_FILTER_DEACON.out.summary
44+
}
45+
46+
47+
emit:
48+
fastq_filtered = fastq_filtered // channel: [ val(meta), [ fastq ] ]
49+
reference = reference // channel: [ val(reference_name), path(reference_dir) ] (hostile only)
50+
json = json // channel: [ val(meta), [ *.json ] ] (hostile only)
51+
index = index // channel: [ val(meta), [ index ] ] (deacon only)
52+
summary = summary // channel: [ val(meta), [ log ] ] (deacon only)
53+
versions = ch_versions // channel: [ versions.yml ]
54+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json
2+
name: "fastq_decontaminate_deacon_hostile"
3+
description: Decontaminate FastQ files by filtering reads that match a reference genome using Deacon or Hostile
4+
keywords:
5+
- hostile
6+
- deacon
7+
- filter
8+
- index
9+
- fasta
10+
- fastq
11+
- genome
12+
- reference
13+
- minimizer
14+
- decontamination
15+
components:
16+
- hostile/fetch
17+
- hostile/clean
18+
- deacon/index
19+
- deacon/filter
20+
- fastq_fetch_clean_hostile
21+
- fastq_index_filter_deacon
22+
input:
23+
- ch_reads:
24+
type: file
25+
description: |
26+
List of FastQ files of size 1 and 2 for single-end and paired-end data, respectively.
27+
Structure: [ val(meta), [ path(reads) ] ]
28+
- ch_fasta:
29+
type: file
30+
description: |
31+
Input genome fasta file used by Deacon. Meta must match the meta of ch_reads.
32+
Structure: [ val(meta), [ path(fasta) ] ]
33+
- ch_reference:
34+
type: directory
35+
description: |
36+
Directory containing index file(s) corresponding to the preferred aligner (bowtie2 short reads or minimap for long reads) used by Hostile.
37+
Note that single end data is assumed to be long reads. If you have single-end short read you must supply both the BowTie2
38+
indices AND explicitly specify `--aligner bowtie2`
39+
- index_name:
40+
type: string
41+
description: Name of the reference genome index to download for Hostile fetch if the reference is not provided.
42+
- decontaminator:
43+
type: string
44+
description: Name of the deacontamination tool to use.
45+
enum: ["deacon", "hostile"]
46+
output:
47+
- fastq_filtered:
48+
type: file
49+
description: |
50+
List of output filtered FastQ files of size 1 and 2 for single-end and paired-end data, respectively.
51+
Structure: [ val(meta), path(${prefix}*.fq.gz) ]
52+
pattern: "*.fq.gz"
53+
- reference:
54+
type: channel
55+
description: |
56+
Channel containing reference name and directory with index files for Hostile.
57+
Structure: [ val(reference_name), path(reference_dir) ]
58+
- json:
59+
type: channel
60+
description: |
61+
Channel containing sample metadata and Hostile cleaning log in JSON format.
62+
Structure: [ val(meta), path(*.json) ]
63+
pattern: "*.json"
64+
- index:
65+
type: file
66+
description: |
67+
Deacon minimizer index file.
68+
Structure: [ val(meta), path(index) ]
69+
pattern: ".idx"
70+
- summary:
71+
type: file
72+
description: |
73+
JSON file containing summary of results.
74+
Structure: [ val(meta), path(${prefix}.json) ]
75+
pattern: "*.json"
76+
- versions:
77+
type: file
78+
description: |
79+
File containing software versions
80+
Structure: [ path(versions.yml) ]
81+
pattern: "versions.yml"
82+
authors:
83+
- "@Baksic-Ivan"
84+
maintainers:
85+
- "@Baksic-Ivan"
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
nextflow_workflow {
2+
3+
name "Test Subworkflow FASTQ_DECONTAMINATE_DEACON_HOSTILE"
4+
script "../main.nf"
5+
workflow "FASTQ_DECONTAMINATE_DEACON_HOSTILE"
6+
config './nextflow.config'
7+
8+
tag "subworkflows"
9+
tag "subworkflows_nfcore"
10+
tag "subworkflows/fastq_index_filter_deacon"
11+
tag "subworkflows/fastq_fetch_clean_hostile"
12+
tag "subworkflows/fastq_decontaminate_deacon_hostile"
13+
tag "hostile"
14+
tag "hostile/fetch"
15+
tag "hostile/clean"
16+
tag "bowtie2/build"
17+
tag "deacon"
18+
tag "deacon/filter"
19+
tag "deacon/index"
20+
21+
test("sarscov2 - fastq - single-end - hostile") {
22+
setup {
23+
run("BOWTIE2_BUILD") {
24+
script "../../../../modules/nf-core/bowtie2/build/main.nf"
25+
process {
26+
"""
27+
input[0] = [
28+
[ id:'test' ],
29+
file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)
30+
]
31+
"""
32+
}
33+
}
34+
}
35+
when {
36+
workflow {
37+
"""
38+
input[0] = channel.of([
39+
[ id:'test_single', single_end:true ],
40+
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_1.fastq.gz', checkIfExists: true)
41+
])
42+
input[1] = []
43+
input[2] = BOWTIE2_BUILD.out.index.map { meta, index -> tuple('genome', index) }
44+
input[3] = []
45+
input[4] = 'hostile'
46+
"""
47+
}
48+
}
49+
then {
50+
assertAll(
51+
{ assert workflow.success },
52+
{ assert snapshot(
53+
workflow.out.fastq_filtered,
54+
workflow.out.reference,
55+
file(workflow.out.json[0][1]).name,
56+
workflow.out.versions.collect { path(it).yaml }
57+
).match() }
58+
)
59+
}
60+
}
61+
62+
test("sarscov2 - fastq - paired-end - hostile") {
63+
setup {
64+
run("BOWTIE2_BUILD") {
65+
script "../../../../modules/nf-core/bowtie2/build/main.nf"
66+
process {
67+
"""
68+
input[0] = [
69+
[ id:'test' ],
70+
file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)
71+
]
72+
"""
73+
}
74+
}
75+
}
76+
when {
77+
workflow {
78+
"""
79+
input[0] = channel.of([
80+
[ id:'test_paired', single_end:false ],
81+
[
82+
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
83+
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/fastq/test_2.fastq.gz', checkIfExists: true)
84+
]
85+
])
86+
input[1] = []
87+
input[2] = BOWTIE2_BUILD.out.index.map { meta, index -> tuple('genome', index) }
88+
input[3] = []
89+
input[4] = 'hostile'
90+
"""
91+
}
92+
}
93+
then {
94+
assertAll(
95+
{ assert workflow.success },
96+
{ assert snapshot(
97+
workflow.out.fastq_filtered,
98+
workflow.out.reference,
99+
file(workflow.out.json[0][1]).name,
100+
workflow.out.versions.collect { path(it).yaml }
101+
).match() }
102+
)
103+
}
104+
}
105+
106+
test("sarscov2 - fastq - single-end - deacon") {
107+
when {
108+
workflow {
109+
"""
110+
input[0] = channel.of(
111+
[
112+
[ id:'test', single_end:true ],
113+
file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)
114+
]
115+
)
116+
input[1] = channel.of(
117+
[
118+
[ id:'test', single_end:true ],
119+
file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)
120+
]
121+
)
122+
input[2] = []
123+
input[3] = []
124+
input[4] = 'deacon'
125+
"""
126+
}
127+
}
128+
then {
129+
assertAll(
130+
{ assert workflow.success },
131+
{ assert snapshot(
132+
workflow.out.fastq_filtered,
133+
workflow.out.index,
134+
file(workflow.out.summary[0][1]).name,
135+
workflow.out.versions.collect { path(it).yaml }
136+
).match()}
137+
)
138+
}
139+
}
140+
141+
test("sarscov2 - fastq - paired-end - deacon") {
142+
when {
143+
workflow {
144+
"""
145+
input[0] = channel.of(
146+
[
147+
[ id:'test', single_end:false ],
148+
[
149+
file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
150+
file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true)
151+
]
152+
]
153+
)
154+
input[1] = channel.of(
155+
[
156+
[ id:'test', single_end:false ],
157+
file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)
158+
]
159+
)
160+
input[2] = []
161+
input[3] = []
162+
input[4] = 'deacon'
163+
"""
164+
}
165+
}
166+
then {
167+
assertAll(
168+
{ assert workflow.success },
169+
{ assert snapshot(
170+
workflow.out.fastq_filtered,
171+
workflow.out.index,
172+
file(workflow.out.summary[0][1]).name,
173+
workflow.out.versions.collect { path(it).yaml }
174+
).match()}
175+
)
176+
}
177+
}
178+
179+
test("sarscov2 - fastq - single-end - deacon - stub") {
180+
181+
options "-stub"
182+
183+
when {
184+
workflow {
185+
"""
186+
input[0] = channel.of(
187+
[
188+
[ id:'test', single_end:true ],
189+
file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)
190+
]
191+
)
192+
input[1] = channel.of(
193+
[
194+
[ id:'test', single_end:true ],
195+
file(params.modules_testdata_base_path + 'genomics/sarscov2/genome/genome.fasta', checkIfExists: true)
196+
]
197+
)
198+
input[2] = []
199+
input[3] = []
200+
input[4] = 'deacon'
201+
"""
202+
}
203+
}
204+
205+
then {
206+
assertAll(
207+
{ assert workflow.success },
208+
{ assert snapshot(
209+
workflow.out,
210+
workflow.out.versions.collect { path(it).yaml }
211+
).match()}
212+
)
213+
}
214+
}
215+
}

0 commit comments

Comments
 (0)