Skip to content

Commit 18e1a95

Browse files
authored
move BCL* readgroup functions to subwf (nf-core#10132)
move readgroup functions to subwf
1 parent 7834f94 commit 18e1a95

3 files changed

Lines changed: 93 additions & 95 deletions

File tree

modules/nf-core/bcl2fastq/main.nf

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -80,54 +80,3 @@ process BCL2FASTQ {
8080
echo "fake stats" > output/Stats/Stats.json
8181
"""
8282
}
83-
84-
def generateReadgroup(ch_fastq) {
85-
ch_fastq
86-
.transpose()
87-
.map { fc_meta, fastq ->
88-
def meta = [:]
89-
meta.id = fastq.getSimpleName().toString() - ~/_R[0-9]_001.*$/
90-
meta.samplename = fastq.getSimpleName().toString() - ~/_S[0-9]+.*$/
91-
meta.fcid = fc_meta.id
92-
meta.lane = fc_meta.lane
93-
// The buffered input stream allows reading directly from cloud storage
94-
// It will not make a local copy of the file.
95-
def line = ""
96-
fastq.withInputStream { fq ->
97-
def gzipStream = new java.util.zip.GZIPInputStream(fq)
98-
def decoder = new InputStreamReader(gzipStream, 'ASCII')
99-
def buffered = new BufferedReader(decoder)
100-
line = buffered.readLine()
101-
buffered.close()
102-
}
103-
if (line != null && line.startsWith('@')) {
104-
line = line.substring(1)
105-
// expected format is like:
106-
// xx:yy:FLOWCELLID:LANE:... (seven fields)
107-
def fields = line.split(':')
108-
// CASAVA 1.8+ format, from https://support.illumina.com/help/BaseSpace_OLH_009008/Content/Source/Informatics/BS/FileFormat_FASTQ-files_swBS.htm
109-
// "@<instrument>:<run number>:<flowcell ID>:<lane>:<tile>:<x-pos>:<y-pos>:<UMI> <read>:<is filtered>:<control number>:<index>"
110-
//def sequencer_serial = fields[0]
111-
//def run_nubmer = fields[1]
112-
def fcid = fields[2]
113-
def lane = fields[3]
114-
def index = fields[-1] =~ /[GATC+-]/ ? fields[-1] : ""
115-
def ID = [index, lane].join(".")
116-
def LB = ""
117-
def PL = "ILLUMINA"
118-
def PU = [fcid, lane].findAll().join(".")
119-
def SM = fastq.getSimpleName().toString() - ~/_S[0-9]+.*$/
120-
meta.readgroup = ["ID": ID, "SM": SM, "PL": PL, "PU": PU, "LB": LB]
121-
}
122-
else {
123-
println("No reads were found in FASTQ file: ${fastq}")
124-
meta.readgroup = [:]
125-
}
126-
return [meta, fastq]
127-
}
128-
.groupTuple(by: [0])
129-
.map { meta, fastq ->
130-
meta.single_end = fastq.size() == 1
131-
return [meta, fastq.flatten()]
132-
}
133-
}

modules/nf-core/bclconvert/main.nf

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -103,45 +103,3 @@ process BCLCONVERT {
103103
echo "fake InterOp file" > output/InterOp/TileMetricsOut.bin
104104
"""
105105
}
106-
107-
def generateReadgroup(ch_fastq_list_csv, ch_fastq) {
108-
return ch_fastq_list_csv
109-
.collect() // make it a value channel
110-
.map { meta, csv_file ->
111-
def fastq_metadata = []
112-
csv_file
113-
.splitCsv(header: true)
114-
.each { row ->
115-
// Create the readgroup tuple
116-
// RGID,RGSM,RGLB,Lane,Read1File,Read2File
117-
def rg = [:]
118-
// row.RGID is index1.index2.lane
119-
rg.ID = row.RGID
120-
// RGPU is a custom column in the samplesheet containing the flowcell ID
121-
rg.PU = row.RGPU ? row.RGPU : meta.id + "." + row.Lane
122-
rg.SM = row.RGSM
123-
rg.LB = row.RGLB ? row.RGLB : ""
124-
rg.PL = "ILLUMINA"
125-
126-
// replace the meta id with the sample name
127-
def new_meta = [id: row.RGSM, readgroup: rg]
128-
// Return the new meta with fastq file
129-
fastq_metadata << [new_meta, file(row.Read1File).name]
130-
if (row.Read2File) {
131-
fastq_metadata << [new_meta, file(row.Read2File).name]
132-
}
133-
}
134-
return [meta, fastq_metadata]
135-
}
136-
.join(ch_fastq, by:[0]) // -> [ meta, [fq_meta, fastq_filename], [fastq_file, ...] ]
137-
.transpose(by:[2]) // -> [ meta, [fq_meta, fastq_filename], fastq_file ]
138-
.map { meta, fastq_metadata, fastq_file ->
139-
def fastq_meta = fastq_metadata.find { _meta, filename -> filename == file(fastq_file).name }
140-
return [meta + fastq_meta[0], file(fastq_file)]
141-
}
142-
.groupTuple(by: [0])
143-
.map { meta, fastq ->
144-
meta.single_end = fastq.size() == 1
145-
return [meta, fastq.flatten()]
146-
}
147-
}

subworkflows/nf-core/bcl_demultiplex/main.nf

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
//
66

77
include { BCLCONVERT } from "../../../modules/nf-core/bclconvert/main"
8-
include { generateReadgroup as generateReadgroupBCLCONVERT } from "../../../modules/nf-core/bclconvert/main"
98
include { BCL2FASTQ } from "../../../modules/nf-core/bcl2fastq/main"
10-
include { generateReadgroup as generateReadgroupBCL2FASTQ } from "../../../modules/nf-core/bcl2fastq/main"
119

1210
workflow BCL_DEMULTIPLEX {
1311
take:
@@ -92,3 +90,96 @@ workflow BCL_DEMULTIPLEX {
9290
interop = ch_interop
9391
logs = ch_logs
9492
}
93+
94+
def generateReadgroupBCLCONVERT(ch_fastq_list_csv, ch_fastq) {
95+
return ch_fastq_list_csv
96+
.collect() // make it a value channel
97+
.map { meta, csv_file ->
98+
def fastq_metadata = []
99+
csv_file
100+
.splitCsv(header: true)
101+
.each { row ->
102+
// Create the readgroup tuple
103+
// RGID,RGSM,RGLB,Lane,Read1File,Read2File
104+
def rg = [:]
105+
// row.RGID is index1.index2.lane
106+
rg.ID = row.RGID
107+
// RGPU is a custom column in the samplesheet containing the flowcell ID
108+
rg.PU = row.RGPU ? row.RGPU : meta.id + "." + row.Lane
109+
rg.SM = row.RGSM
110+
rg.LB = row.RGLB ? row.RGLB : ""
111+
rg.PL = "ILLUMINA"
112+
113+
// replace the meta id with the sample name
114+
def new_meta = [id: row.RGSM, readgroup: rg]
115+
// Return the new meta with fastq file
116+
fastq_metadata << [new_meta, file(row.Read1File).name]
117+
if (row.Read2File) {
118+
fastq_metadata << [new_meta, file(row.Read2File).name]
119+
}
120+
}
121+
return [meta, fastq_metadata]
122+
}
123+
.join(ch_fastq, by:[0]) // -> [ meta, [fq_meta, fastq_filename], [fastq_file, ...] ]
124+
.transpose(by:[2]) // -> [ meta, [fq_meta, fastq_filename], fastq_file ]
125+
.map { meta, fastq_metadata, fastq_file ->
126+
def fastq_meta = fastq_metadata.find { _meta, filename -> filename == file(fastq_file).name }
127+
return [meta + fastq_meta[0], file(fastq_file)]
128+
}
129+
.groupTuple(by: [0])
130+
.map { meta, fastq ->
131+
meta.single_end = fastq.size() == 1
132+
return [meta, fastq.flatten()]
133+
}
134+
}
135+
136+
def generateReadgroupBCL2FASTQ(ch_fastq) {
137+
ch_fastq
138+
.transpose()
139+
.map { fc_meta, fastq ->
140+
def meta = [:]
141+
meta.id = fastq.getSimpleName().toString() - ~/_R[0-9]_001.*$/
142+
meta.samplename = fastq.getSimpleName().toString() - ~/_S[0-9]+.*$/
143+
meta.fcid = fc_meta.id
144+
meta.lane = fc_meta.lane
145+
// The buffered input stream allows reading directly from cloud storage
146+
// It will not make a local copy of the file.
147+
def line = ""
148+
fastq.withInputStream { fq ->
149+
def gzipStream = new java.util.zip.GZIPInputStream(fq)
150+
def decoder = new InputStreamReader(gzipStream, 'ASCII')
151+
def buffered = new BufferedReader(decoder)
152+
line = buffered.readLine()
153+
buffered.close()
154+
}
155+
if (line != null && line.startsWith('@')) {
156+
line = line.substring(1)
157+
// expected format is like:
158+
// xx:yy:FLOWCELLID:LANE:... (seven fields)
159+
def fields = line.split(':')
160+
// CASAVA 1.8+ format, from https://support.illumina.com/help/BaseSpace_OLH_009008/Content/Source/Informatics/BS/FileFormat_FASTQ-files_swBS.htm
161+
// "@<instrument>:<run number>:<flowcell ID>:<lane>:<tile>:<x-pos>:<y-pos>:<UMI> <read>:<is filtered>:<control number>:<index>"
162+
//def sequencer_serial = fields[0]
163+
//def run_nubmer = fields[1]
164+
def fcid = fields[2]
165+
def lane = fields[3]
166+
def index = fields[-1] =~ /[GATC+-]/ ? fields[-1] : ""
167+
def ID = [index, lane].join(".")
168+
def LB = ""
169+
def PL = "ILLUMINA"
170+
def PU = [fcid, lane].findAll().join(".")
171+
def SM = fastq.getSimpleName().toString() - ~/_S[0-9]+.*$/
172+
meta.readgroup = ["ID": ID, "SM": SM, "PL": PL, "PU": PU, "LB": LB]
173+
}
174+
else {
175+
println("No reads were found in FASTQ file: ${fastq}")
176+
meta.readgroup = [:]
177+
}
178+
return [meta, fastq]
179+
}
180+
.groupTuple(by: [0])
181+
.map { meta, fastq ->
182+
meta.single_end = fastq.size() == 1
183+
return [meta, fastq.flatten()]
184+
}
185+
}

0 commit comments

Comments
 (0)