Skip to content

Commit a1dd9c2

Browse files
authored
Merge pull request #401 from bjlang/dev
create subworkflows/local/bam_peaks_call_qc_annotate_macs2_homer similar to nf-core/atacseq
2 parents 209e589 + f4f8b68 commit a1dd9c2

File tree

3 files changed

+191
-109
lines changed

3 files changed

+191
-109
lines changed

conf/modules.config

+7-7
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ if (!params.skip_plot_fingerprint) {
540540
}
541541

542542
process {
543-
withName: '.*:BAM_PEAKS_CALL_QC_ANNOTATE_MACS2_HOMER:MACS2_CALLPEAK' {
543+
withName: 'MACS2_CALLPEAK' {
544544
ext.args = [
545545
'--keep-dup all',
546546
params.narrow_peak ? '' : "--broad --broad-cutoff ${params.broad_cutoff}",
@@ -559,15 +559,15 @@ process {
559559
]
560560
}
561561

562-
withName: '.*:BAM_PEAKS_CALL_QC_ANNOTATE_MACS2_HOMER:FRIP_SCORE' {
562+
withName: 'FRIP_SCORE' {
563563
ext.args = '-bed -c -f 0.20'
564564
publishDir = [
565565
path: { "${params.outdir}/${params.aligner}/merged_library/macs2/${params.narrow_peak ? '/narrow_peak' : '/broad_peak'}/qc" },
566566
enabled: false
567567
]
568568
}
569569

570-
withName: '.*:BAM_PEAKS_CALL_QC_ANNOTATE_MACS2_HOMER:MULTIQC_CUSTOM_PEAKS' {
570+
withName: 'MULTIQC_CUSTOM_PEAKS' {
571571
publishDir = [
572572
path: { "${params.outdir}/${params.aligner}/merged_library/macs2/${params.narrow_peak ? '/narrow_peak' : '/broad_peak'}/qc" },
573573
mode: params.publish_dir_mode,
@@ -591,7 +591,7 @@ if (!params.skip_peak_annotation) {
591591

592592
if (!params.skip_peak_qc) {
593593
process {
594-
withName: '.*:BAM_PEAKS_CALL_QC_ANNOTATE_MACS2_HOMER:PLOT_MACS2_QC' {
594+
withName: 'PLOT_MACS2_QC' {
595595
ext.args = '-o ./ -p macs2_peak'
596596
publishDir = [
597597
path: { "${params.outdir}/${params.aligner}/merged_library/macs2/${params.narrow_peak ? '/narrow_peak' : '/broad_peak'}/qc" },
@@ -600,7 +600,7 @@ if (!params.skip_peak_annotation) {
600600
]
601601
}
602602

603-
withName: '.*:BAM_PEAKS_CALL_QC_ANNOTATE_MACS2_HOMER:PLOT_HOMER_ANNOTATEPEAKS' {
603+
withName: 'PLOT_HOMER_ANNOTATEPEAKS' {
604604
ext.args = '-o ./'
605605
ext.prefix = 'macs2_annotatePeaks'
606606
publishDir = [
@@ -638,7 +638,7 @@ if (!params.skip_consensus_peaks) {
638638

639639
if (!params.skip_peak_annotation) {
640640
process {
641-
withName: 'HOMER_ANNOTATEPEAKS_CONSENSUS' {
641+
withName: '.*:BED_CONSENSUS_QUANTIFY_QC_BEDTOOLS_FEATURECOUNTS_DESEQ2:HOMER_ANNOTATEPEAKS' {
642642
ext.args = '-gid'
643643
ext.prefix = { "${meta.id}.consensus_peaks" }
644644
publishDir = [
@@ -661,7 +661,7 @@ if (!params.skip_consensus_peaks) {
661661

662662
if (!params.skip_deseq2_qc) {
663663
process {
664-
withName: DESEQ2_QC {
664+
withName: 'DESEQ2_QC' {
665665
ext.when = { meta.multiple_groups && meta.replicates_exist }
666666
ext.args = [
667667
'--id_col 1',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
//
2+
// Call consensus peaks with BEDTools and custom scripts, annotate with HOMER, quantify with featureCounts and QC with DESeq2
3+
//
4+
5+
include { HOMER_ANNOTATEPEAKS } from '../../modules/nf-core/homer/annotatepeaks/main'
6+
include { SUBREAD_FEATURECOUNTS } from '../../modules/nf-core/subread/featurecounts/main'
7+
8+
include { MACS2_CONSENSUS } from '../../modules/local/macs2_consensus'
9+
include { ANNOTATE_BOOLEAN_PEAKS } from '../../modules/local/annotate_boolean_peaks'
10+
include { DESEQ2_QC } from '../../modules/local/deseq2_qc'
11+
12+
workflow BED_CONSENSUS_QUANTIFY_QC_BEDTOOLS_FEATURECOUNTS_DESEQ2 {
13+
take:
14+
ch_peaks // channel: [ val(meta), [ peaks ] ]
15+
ch_bams // channel: [ val(meta), [ ip_bams ] ]
16+
ch_fasta // channel: [ fasta ]
17+
ch_gtf // channel: [ gtf ]
18+
ch_deseq2_pca_header_multiqc // channel: [ header_file ]
19+
ch_deseq2_clustering_header_multiqc // channel: [ header_file ]
20+
is_narrow_peak // boolean: true/false
21+
skip_peak_annotation // boolean: true/false
22+
skip_deseq2_qc // boolean: true/false
23+
24+
main:
25+
26+
ch_versions = Channel.empty()
27+
28+
// Create channels: [ meta , [ peaks ] ]
29+
// Where meta = [ id:antibody, multiple_groups:true/false, replicates_exist:true/false ]
30+
ch_peaks
31+
.map {
32+
meta, peak ->
33+
[ meta.antibody, meta.id.split('_')[0..-2].join('_'), peak ]
34+
}
35+
.groupTuple()
36+
.map {
37+
antibody, groups, peaks ->
38+
[
39+
antibody,
40+
groups.groupBy().collectEntries { [(it.key) : it.value.size()] },
41+
peaks
42+
]
43+
}
44+
.map {
45+
antibody, groups, peaks ->
46+
def meta_new = [:]
47+
meta_new.id = antibody
48+
meta_new.multiple_groups = groups.size() > 1
49+
meta_new.replicates_exist = groups.max { groups.value }.value > 1
50+
[ meta_new, peaks ]
51+
}
52+
.set { ch_antibody_peaks }
53+
54+
//
55+
// Generate consensus peaks across samples
56+
//
57+
MACS2_CONSENSUS (
58+
ch_antibody_peaks,
59+
is_narrow_peak
60+
)
61+
ch_versions = ch_versions.mix(MACS2_CONSENSUS.out.versions)
62+
63+
//
64+
// Annotate consensus peaks
65+
//
66+
if (!skip_peak_annotation) {
67+
HOMER_ANNOTATEPEAKS (
68+
MACS2_CONSENSUS.out.bed,
69+
ch_fasta,
70+
ch_gtf
71+
)
72+
ch_versions = ch_versions.mix(HOMER_ANNOTATEPEAKS.out.versions)
73+
74+
//
75+
// MODULE: Add boolean fields to annotated consensus peaks to aid filtering
76+
//
77+
ANNOTATE_BOOLEAN_PEAKS (
78+
MACS2_CONSENSUS.out.boolean_txt.join(HOMER_ANNOTATEPEAKS.out.txt, by: [0]),
79+
)
80+
ch_versions = ch_versions.mix(ANNOTATE_BOOLEAN_PEAKS.out.versions)
81+
}
82+
83+
// Create channels: [ meta, [ ip_bams ], saf ]
84+
MACS2_CONSENSUS
85+
.out
86+
.saf
87+
.map {
88+
meta, saf ->
89+
[ meta.id, meta, saf ]
90+
}
91+
.join(ch_bams)
92+
.map {
93+
antibody, meta, saf, bams ->
94+
[ meta, bams.flatten().sort(), saf ]
95+
}
96+
.set { ch_bam_saf }
97+
98+
//
99+
// Quantify peaks across samples with featureCounts
100+
//
101+
SUBREAD_FEATURECOUNTS (
102+
ch_bam_saf
103+
)
104+
ch_versions = ch_versions.mix(SUBREAD_FEATURECOUNTS.out.versions)
105+
106+
//
107+
// Generate QC plots with DESeq2
108+
//
109+
ch_deseq2_qc_pdf = Channel.empty()
110+
ch_deseq2_qc_rdata = Channel.empty()
111+
ch_deseq2_qc_rds = Channel.empty()
112+
ch_deseq2_qc_pca_txt = Channel.empty()
113+
ch_deseq2_qc_pca_multiqc = Channel.empty()
114+
ch_deseq2_qc_dists_txt = Channel.empty()
115+
ch_deseq2_qc_dists_multiqc = Channel.empty()
116+
ch_deseq2_qc_log = Channel.empty()
117+
ch_deseq2_qc_size_factors = Channel.empty()
118+
if (!skip_deseq2_qc) {
119+
DESEQ2_QC (
120+
SUBREAD_FEATURECOUNTS.out.counts,
121+
ch_deseq2_pca_header_multiqc,
122+
ch_deseq2_clustering_header_multiqc
123+
)
124+
ch_deseq2_qc_pdf = DESEQ2_QC.out.pdf
125+
ch_deseq2_qc_rdata = DESEQ2_QC.out.rdata
126+
ch_deseq2_qc_rds = DESEQ2_QC.out.rds
127+
ch_deseq2_qc_pca_txt = DESEQ2_QC.out.pca_txt
128+
ch_deseq2_qc_pca_multiqc = DESEQ2_QC.out.pca_multiqc
129+
ch_deseq2_qc_dists_txt = DESEQ2_QC.out.dists_txt
130+
ch_deseq2_qc_dists_multiqc = DESEQ2_QC.out.dists_multiqc
131+
ch_deseq2_qc_log = DESEQ2_QC.out.log
132+
ch_deseq2_qc_size_factors = DESEQ2_QC.out.size_factors
133+
ch_versions = ch_versions.mix(DESEQ2_QC.out.versions)
134+
}
135+
136+
emit:
137+
consensus_bed = MACS2_CONSENSUS.out.bed // channel: [ bed ]
138+
consensus_saf = MACS2_CONSENSUS.out.saf // channel: [ saf ]
139+
consensus_pdf = MACS2_CONSENSUS.out.pdf // channel: [ pdf ]
140+
consensus_txt = MACS2_CONSENSUS.out.txt // channel: [ pdf ]
141+
consensus_boolean_txt = MACS2_CONSENSUS.out.boolean_txt // channel: [ txt ]
142+
consensus_intersect_txt = MACS2_CONSENSUS.out.intersect_txt // channel: [ txt ]
143+
144+
featurecounts_txt = SUBREAD_FEATURECOUNTS.out.counts // channel: [ txt ]
145+
featurecounts_summary = SUBREAD_FEATURECOUNTS.out.summary // channel: [ txt ]
146+
147+
deseq2_qc_pdf = ch_deseq2_qc_pdf // channel: [ pdf ]
148+
deseq2_qc_rdata = ch_deseq2_qc_rdata // channel: [ rdata ]
149+
deseq2_qc_rds = ch_deseq2_qc_rds // channel: [ rds ]
150+
deseq2_qc_pca_txt = ch_deseq2_qc_pca_txt // channel: [ txt ]
151+
deseq2_qc_pca_multiqc = ch_deseq2_qc_pca_multiqc // channel: [ txt ]
152+
deseq2_qc_dists_txt = ch_deseq2_qc_dists_txt // channel: [ txt ]
153+
deseq2_qc_dists_multiqc = ch_deseq2_qc_dists_multiqc // channel: [ txt ]
154+
deseq2_qc_log = ch_deseq2_qc_log // channel: [ txt ]
155+
deseq2_qc_size_factors = ch_deseq2_qc_size_factors // channel: [ txt ]
156+
157+
versions = ch_versions // channel: [ versions.yml ]
158+
}

workflows/chipseq.nf

+26-102
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
// MODULE: Loaded from modules/local/
99
//
1010
include { MACS2_CONSENSUS } from '../modules/local/macs2_consensus'
11-
include { ANNOTATE_BOOLEAN_PEAKS } from '../modules/local/annotate_boolean_peaks'
1211
include { DESEQ2_QC } from '../modules/local/deseq2_qc'
1312
include { IGV } from '../modules/local/igv'
1413
include { MULTIQC } from '../modules/local/multiqc'
@@ -17,15 +16,16 @@ include { MULTIQC_CUSTOM_PHANTOMPEAKQUALTOOLS } from '../modules/local/multiqc_c
1716
//
1817
// SUBWORKFLOW: Consisting of a mix of local and nf-core/modules
1918
//
20-
include { paramsSummaryMap } from 'plugin/nf-validation'
21-
include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline'
22-
include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline'
23-
include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_chipseq_pipeline'
24-
include { INPUT_CHECK } from '../subworkflows/local/input_check'
25-
include { ALIGN_STAR } from '../subworkflows/local/align_star'
26-
include { BAM_FILTER_BAMTOOLS } from '../subworkflows/local/bam_filter_bamtools'
27-
include { BAM_BEDGRAPH_BIGWIG_BEDTOOLS_UCSC } from '../subworkflows/local/bam_bedgraph_bigwig_bedtools_ucsc'
28-
include { BAM_PEAKS_CALL_QC_ANNOTATE_MACS2_HOMER } from '../subworkflows/local/bam_peaks_call_qc_annotate_macs2_homer.nf'
19+
include { paramsSummaryMap } from 'plugin/nf-validation'
20+
include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline'
21+
include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline'
22+
include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_chipseq_pipeline'
23+
include { INPUT_CHECK } from '../subworkflows/local/input_check'
24+
include { ALIGN_STAR } from '../subworkflows/local/align_star'
25+
include { BAM_FILTER_BAMTOOLS } from '../subworkflows/local/bam_filter_bamtools'
26+
include { BAM_BEDGRAPH_BIGWIG_BEDTOOLS_UCSC } from '../subworkflows/local/bam_bedgraph_bigwig_bedtools_ucsc'
27+
include { BAM_PEAKS_CALL_QC_ANNOTATE_MACS2_HOMER } from '../subworkflows/local/bam_peaks_call_qc_annotate_macs2_homer.nf'
28+
include { BED_CONSENSUS_QUANTIFY_QC_BEDTOOLS_FEATURECOUNTS_DESEQ2 } from '../subworkflows/local/bed_consensus_quantify_qc_bedtools_featurecounts_deseq2.nf'
2929

3030
/*
3131
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -476,63 +476,6 @@ workflow CHIPSEQ {
476476
ch_deseq2_pca_multiqc = Channel.empty()
477477
ch_deseq2_clustering_multiqc = Channel.empty()
478478
if (!params.skip_consensus_peaks) {
479-
// Create channels: [ meta , [ peaks ] ]
480-
// Where meta = [ id:antibody, multiple_groups:true/false, replicates_exist:true/false ]
481-
BAM_PEAKS_CALL_QC_ANNOTATE_MACS2_HOMER.out.peaks
482-
.map {
483-
meta, peak ->
484-
[ meta.antibody, meta.id.split('_')[0..-2].join('_'), peak ]
485-
}
486-
.groupTuple()
487-
.map {
488-
antibody, groups, peaks ->
489-
[
490-
antibody,
491-
groups.groupBy().collectEntries { [(it.key) : it.value.size()] },
492-
peaks
493-
]
494-
}
495-
.map {
496-
antibody, groups, peaks ->
497-
def meta_new = [:]
498-
meta_new.id = antibody
499-
meta_new.multiple_groups = groups.size() > 1
500-
meta_new.replicates_exist = groups.max { groups.value }.value > 1
501-
[ meta_new, peaks ]
502-
}
503-
.set { ch_antibody_peaks }
504-
505-
//
506-
// MODULE: Generate consensus peaks across samples
507-
//
508-
MACS2_CONSENSUS (
509-
ch_antibody_peaks,
510-
params.narrow_peak
511-
)
512-
ch_macs2_consensus_bed_lib = MACS2_CONSENSUS.out.bed
513-
ch_macs2_consensus_txt_lib = MACS2_CONSENSUS.out.txt
514-
ch_versions = ch_versions.mix(MACS2_CONSENSUS.out.versions)
515-
516-
if (!params.skip_peak_annotation) {
517-
//
518-
// MODULE: Annotate consensus peaks
519-
//
520-
HOMER_ANNOTATEPEAKS_CONSENSUS (
521-
MACS2_CONSENSUS.out.bed,
522-
ch_fasta,
523-
ch_gtf
524-
)
525-
ch_versions = ch_versions.mix(HOMER_ANNOTATEPEAKS_CONSENSUS.out.versions)
526-
527-
//
528-
// MODULE: Add boolean fields to annotated consensus peaks to aid filtering
529-
//
530-
ANNOTATE_BOOLEAN_PEAKS (
531-
MACS2_CONSENSUS.out.boolean_txt.join(HOMER_ANNOTATEPEAKS_CONSENSUS.out.txt, by: [0]),
532-
)
533-
ch_versions = ch_versions.mix(ANNOTATE_BOOLEAN_PEAKS.out.versions)
534-
}
535-
536479
// Create channels: [ antibody, [ ip_bams ] ]
537480
ch_ip_control_bam
538481
.map {
@@ -542,42 +485,23 @@ workflow CHIPSEQ {
542485
.groupTuple()
543486
.set { ch_antibody_bams }
544487

545-
// Create channels: [ meta, [ ip_bams ], saf ]
546-
MACS2_CONSENSUS
547-
.out
548-
.saf
549-
.map {
550-
meta, saf ->
551-
[ meta.id, meta, saf ]
552-
}
553-
.join(ch_antibody_bams)
554-
.map {
555-
antibody, meta, saf, bams ->
556-
[ meta, bams.flatten().sort(), saf ]
557-
}
558-
.set { ch_saf_bams }
559-
560-
//
561-
// MODULE: Quantify peaks across samples with featureCounts
562-
//
563-
SUBREAD_FEATURECOUNTS (
564-
ch_saf_bams
488+
BED_CONSENSUS_QUANTIFY_QC_BEDTOOLS_FEATURECOUNTS_DESEQ2 (
489+
BAM_PEAKS_CALL_QC_ANNOTATE_MACS2_HOMER.out.peaks,
490+
ch_antibody_bams,
491+
ch_fasta,
492+
ch_gtf,
493+
ch_deseq2_pca_header,
494+
ch_deseq2_clustering_header,
495+
params.narrow_peak,
496+
params.skip_peak_annotation,
497+
params.skip_deseq2_qc
565498
)
566-
ch_subreadfeaturecounts_multiqc = SUBREAD_FEATURECOUNTS.out.summary
567-
ch_versions = ch_versions.mix(SUBREAD_FEATURECOUNTS.out.versions.first())
568-
569-
if (!params.skip_deseq2_qc) {
570-
//
571-
// MODULE: Generate QC plots with DESeq2
572-
//
573-
DESEQ2_QC (
574-
SUBREAD_FEATURECOUNTS.out.counts,
575-
ch_deseq2_pca_header,
576-
ch_deseq2_clustering_header
577-
)
578-
ch_deseq2_pca_multiqc = DESEQ2_QC.out.pca_multiqc
579-
ch_deseq2_clustering_multiqc = DESEQ2_QC.out.dists_multiqc
580-
}
499+
ch_macs2_consensus_bed_lib = BED_CONSENSUS_QUANTIFY_QC_BEDTOOLS_FEATURECOUNTS_DESEQ2.out.consensus_bed
500+
ch_macs2_consensus_txt_lib = BED_CONSENSUS_QUANTIFY_QC_BEDTOOLS_FEATURECOUNTS_DESEQ2.out.consensus_txt
501+
ch_subreadfeaturecounts_multiqc = BED_CONSENSUS_QUANTIFY_QC_BEDTOOLS_FEATURECOUNTS_DESEQ2.out.featurecounts_summary
502+
ch_deseq2_pca_multiqc = BED_CONSENSUS_QUANTIFY_QC_BEDTOOLS_FEATURECOUNTS_DESEQ2.out.deseq2_qc_pca_multiqc
503+
ch_deseq2_clustering_multiqc = BED_CONSENSUS_QUANTIFY_QC_BEDTOOLS_FEATURECOUNTS_DESEQ2.out.deseq2_qc_dists_multiqc
504+
ch_versions = ch_versions.mix(BED_CONSENSUS_QUANTIFY_QC_BEDTOOLS_FEATURECOUNTS_DESEQ2.out.versions)
581505
}
582506

583507
//

0 commit comments

Comments
 (0)