From 4c299ae69db4d3376cb78f8c2487b74c9259d349 Mon Sep 17 00:00:00 2001 From: Edmund Miller Date: Fri, 8 Mar 2024 15:18:18 -0600 Subject: [PATCH] style: Fix editorconfig errors --- .editorconfig | 3 + bin/mapped_2hic_fragments.py | 2 +- bin/mergeSAM.py | 2 +- bin/src/build_matrix.cpp | 290 +++++++++++----------- docs/benchmark.md | 6 +- docs/output.md | 9 +- nextflow.config | 44 ++-- subworkflows/local/compartments.nf | 32 +-- subworkflows/local/cooler.nf | 158 ++++++------ subworkflows/local/hicpro.nf | 242 +++++++++--------- subworkflows/local/hicpro_mapping.nf | 174 ++++++------- subworkflows/local/input_check.nf | 84 +++---- subworkflows/local/pairtools.nf | 176 +++++++------- subworkflows/local/prepare_genome.nf | 134 +++++----- subworkflows/local/tads.nf | 40 +-- workflows/hic.nf | 350 +++++++++++++-------------- 16 files changed, 874 insertions(+), 872 deletions(-) diff --git a/.editorconfig b/.editorconfig index a552680..7da0b52 100644 --- a/.editorconfig +++ b/.editorconfig @@ -43,3 +43,6 @@ insert_final_newline = unset trim_trailing_whitespace = unset indent_style = unset indent_size = unset + +[*.cpp] +indent_size = 2 diff --git a/bin/mapped_2hic_fragments.py b/bin/mapped_2hic_fragments.py index a129871..dfeff70 100755 --- a/bin/mapped_2hic_fragments.py +++ b/bin/mapped_2hic_fragments.py @@ -10,7 +10,7 @@ """ Script to keep only valid 3C products - DE and SC are removed -Output is : readname / +Output is : readname / """ import time import getopt diff --git a/bin/mergeSAM.py b/bin/mergeSAM.py index d670ec2..6dc0701 100755 --- a/bin/mergeSAM.py +++ b/bin/mergeSAM.py @@ -10,7 +10,7 @@ """ Script to pair 2 SAM/BAM files into one PE BAM -- On 03/05/16 Ferhat made changes starting from ~/bin/HiC-Pro_2.7.2b/scripts/mergeSAM.py +- On 03/05/16 Ferhat made changes starting from ~/bin/HiC-Pro_2.7.2b/scripts/mergeSAM.py to make singletons possible to be reported """ diff --git a/bin/src/build_matrix.cpp b/bin/src/build_matrix.cpp index e366d5b..b4cd812 100644 --- a/bin/src/build_matrix.cpp +++ b/bin/src/build_matrix.cpp @@ -1,5 +1,5 @@ // HiC-Pro -// Copyright 2015 Institut Curie +// Copyright 2015 Institut Curie // Author(s): Eric Viara // Contact: nicolas.servant@curie.fr // This software is distributed without any guarantee under the terms of the BSD-3 License @@ -62,7 +62,7 @@ struct Interval { Interval(chrsize_t start = 0, chrsize_t end = 0) : start(start), end(end) { } }; - + class ChrRegions { std::vector chr_v; @@ -85,36 +85,36 @@ class ChrRegions { ifs.getline(buffer, sizeof(buffer)-1); line_num++; if (is_empty_line(buffer)) { - continue; + continue; } chrsize_t start = 0; chrsize_t end = 0; char chr[2048]; if (bed_line_parse(buffer, chr, start, end, bedfile, line_num)) { - return 1; + return 1; } if (intervals.find(chr) == intervals.end()) { - intervals[chr] = new std::vector(); - chr_v.push_back(chr); + intervals[chr] = new std::vector(); + chr_v.push_back(chr); } /* - if (lastend != 0 && !strcmp(lastchr, chr) && start != lastend) { - std::cerr << "warning: discontinuous segment for chromosome " << chr << " at position " << start << " " << end << std::endl; - } - */ + if (lastend != 0 && !strcmp(lastchr, chr) && start != lastend) { + std::cerr << "warning: discontinuous segment for chromosome " << chr << " at position " << start << " " << end << std::endl; + } + */ if (*lastchr && strcmp(lastchr, chr)) { - lastend = 0; + lastend = 0; } if (lastend != 0 && start < lastend) { - std::cerr << "error: bedfile not sorted at line #" << line_num << std::endl; - exit(1); + std::cerr << "error: bedfile not sorted at line #" << line_num << std::endl; + exit(1); } strcpy(lastchr, chr); lastend = end; intervals[chr]->push_back(Interval(start, end)); if (progress && (line_num % 100000) == 0) { - std::cerr << '.' << std::flush; + std::cerr << '.' << std::flush; } } if (progress) { @@ -135,13 +135,13 @@ class ChrRegions { std::vector::const_iterator itv_begin = itv_vect->begin(); std::vector::const_iterator itv_end = itv_vect->end(); while (itv_begin != itv_end) { - const Interval& itv = (*itv_begin); - ofs << chrname << '\t' << itv.start << '\t' << itv.end << '\t' << num << '\n'; - if (progress && (num % 100000) == 0) { - std::cerr << '.' << std::flush; - } - num++; - ++itv_begin; + const Interval& itv = (*itv_begin); + ofs << chrname << '\t' << itv.start << '\t' << itv.end << '\t' << num << '\n'; + if (progress && (num % 100000) == 0) { + std::cerr << '.' << std::flush; + } + num++; + ++itv_begin; } ++begin; } @@ -184,15 +184,15 @@ class Dichotomic { n = (l + r) >> 1; const Interval& itv = intervals[n]; if (value >= itv.start+1 && value <= itv.end) { - return n; + return n; } int x = middle(itv) - value; - + if (x < 0) { - l = n + 1; + l = n + 1; } else { - r = n - 1; + r = n - 1; } //std::cout << "l: " << l << '\n'; //std::cout << "r: " << r << '\n'; @@ -260,10 +260,10 @@ class AxisChromosome { } binend = binstart + chr->getBincount(); /* - if (verbose) { + if (verbose) { std::cerr << "AxisChromosome: " << chr->getName() << " " << binstart << " " << binend << " " << chr->getBincount() << std::endl; - } - */ + } + */ } chrsize_t getBinstart() const {return binstart;} @@ -282,15 +282,15 @@ class AxisChromosome { assert(intervals != NULL); if (!NO_DICHO) { - Dichotomic dicho(*intervals); - int where = dicho.find(start); - if (where < 0) { - if (!quiet) { - std::cerr << "warning: no bin at position " << chr->getName() << ":" << start << std::endl; - } - return BIN_NOT_FOUND; - } - return where + getBinstart(); + Dichotomic dicho(*intervals); + int where = dicho.find(start); + if (where < 0) { + if (!quiet) { + std::cerr << "warning: no bin at position " << chr->getName() << ":" << start << std::endl; + } + return BIN_NOT_FOUND; + } + return where + getBinstart(); } std::vector::const_iterator begin = intervals->begin(); @@ -298,14 +298,14 @@ class AxisChromosome { chrsize_t binidx = 1; while (begin != end) { - const Interval& itv = *begin; - if (start >= itv.start+1 && start <= itv.end) { - break; - } - ++binidx; - ++begin; + const Interval& itv = *begin; + if (start >= itv.start+1 && start <= itv.end) { + break; + } + ++binidx; + ++begin; } - + return binidx + getBinstart() - 1; } @@ -318,7 +318,7 @@ class AxisChromosome { int chrsize = getChrsize(); if (cur_binend > chrsize) { cur_binend = chrsize; - } + } return cur_binidx + getBinstart() - 1; } }; @@ -354,13 +354,13 @@ class Matrix { chrsize_t chrsize = axis_chr->getChrsize(); binend -= binstart; for (chrsize_t bin = 0; bin < binend; ++bin) { - // bed are 0-based begin, 1-based end - chrsize_t beg = bin * binsize; - chrsize_t end = beg + binsize - 1; - if (end > chrsize) { - end = chrsize-1; - } - ofs << name << '\t' << beg << '\t' << (end+1) << '\t' << (bin+binstart) << '\n'; + // bed are 0-based begin, 1-based end + chrsize_t beg = bin * binsize; + chrsize_t end = beg + binsize - 1; + if (end > chrsize) { + end = chrsize-1; + } + ofs << name << '\t' << beg << '\t' << (end+1) << '\t' << (bin+binstart) << '\n'; } ++begin; } @@ -398,9 +398,9 @@ class Matrix { size_t line_total = 0; if (progress) { while (begin != end) { - const std::map& line = (*begin).second; - line_total += line.size(); - ++begin; + const std::map& line = (*begin).second; + line_total += line.size(); + ++begin; } begin = mat.begin(); } @@ -418,13 +418,13 @@ class Matrix { std::map::const_iterator bb = line.begin(); std::map::const_iterator ee = line.end(); while (bb != ee) { - if (progress && (line_cnt % modulo) == 0) { - double percent = (double(line_cnt)/line_total)*100; - std::cerr << "" << percent << "% " << line_cnt << " / " << line_total << std::endl; - } - ofs << abs << '\t' << (*bb).first << '\t' << (*bb).second << '\n'; - line_cnt++; - ++bb; + if (progress && (line_cnt % modulo) == 0) { + double percent = (double(line_cnt)/line_total)*100; + std::cerr << "" << percent << "% " << line_cnt << " / " << line_total << std::endl; + } + ofs << abs << '\t' << (*bb).first << '\t' << (*bb).second << '\n'; + line_cnt++; + ++bb; } ++begin; } @@ -490,10 +490,10 @@ void Chromosome::computeSizes(chrsize_t ori_binsize, chrsize_t step, bool binadj assert(intervals != NULL); bincount = intervals->size(); /* - if (verbose) { + if (verbose) { std::cerr << name << " bincount: " << bincount << std::endl; - } - */ + } + */ } else { if (chrsize < ori_binsize) { binsize = chrsize; @@ -509,10 +509,10 @@ void Chromosome::computeSizes(chrsize_t ori_binsize, chrsize_t step, bool binadj bincount = remainder > 0 ? tmp_bincount+1 : tmp_bincount; } /* - if (verbose) { + if (verbose) { std::cerr << name << " sizes: " << chrsize << " " << binsize << " " << stepsize << " " << bincount << std::endl; - } - */ + } + */ } } @@ -559,7 +559,7 @@ enum MatrixFormat { LOWER_MATRIX, COMPLETE_MATRIX }; - + static int get_options(int argc, char* argv[], chrsize_t& binsize, const char*& binfile, const char*& chrsize_file, const char*& ifile, const char*& oprefix, Format& format, std::string& bed_prefix, bool& binadjust, MatrixFormat& matrix_format, chrsize_t& step, bool& whole_genome, int& binoffset, const char*& chrA, const char*& chrB) { prog = argv[0]; @@ -567,85 +567,85 @@ static int get_options(int argc, char* argv[], chrsize_t& binsize, const char*& const char* opt = argv[ac]; if (*opt == '-') { if (!strcmp(opt, "--binadjust")) { - binadjust = true; + binadjust = true; } else if (!strcmp(opt, "--version")) { - std::cout << "build_matrix version " << VERSION << "\n"; - exit(0); + std::cout << "build_matrix version " << VERSION << "\n"; + exit(0); } else if (!strcmp(opt, "--progress")) { - progress = true; + progress = true; } else if (!strcmp(opt, "--quiet")) { - quiet = true; + quiet = true; } else if (!strcmp(opt, "--detail-progress")) { - progress = true; - detail_progress = true; + progress = true; + detail_progress = true; } else if (!strcmp(opt, "--matrix-format")) { - if (ac == argc-1) { - return usage(); - } - std::string matrix_format_str = argv[++ac]; - if (matrix_format_str == "asis") { - matrix_format = ASIS_MATRIX; - } else if (matrix_format_str == "upper") { - matrix_format = UPPER_MATRIX; - } else if (matrix_format_str == "lower") { - matrix_format = LOWER_MATRIX; - } else if (matrix_format_str == "complete") { - matrix_format = COMPLETE_MATRIX; - } else { - return usage(); - } + if (ac == argc-1) { + return usage(); + } + std::string matrix_format_str = argv[++ac]; + if (matrix_format_str == "asis") { + matrix_format = ASIS_MATRIX; + } else if (matrix_format_str == "upper") { + matrix_format = UPPER_MATRIX; + } else if (matrix_format_str == "lower") { + matrix_format = LOWER_MATRIX; + } else if (matrix_format_str == "complete") { + matrix_format = COMPLETE_MATRIX; + } else { + return usage(); + } } else if (!strcmp(opt, "--step")) { - if (ac == argc-1) { - return usage(); - } - step = atoi(argv[++ac]); + if (ac == argc-1) { + return usage(); + } + step = atoi(argv[++ac]); } else if (!strcmp(opt, "--binfile")) { - if (ac == argc-1) { - return usage(); - } - binfile = argv[++ac]; + if (ac == argc-1) { + return usage(); + } + binfile = argv[++ac]; } else if (!strcmp(opt, "--binsize")) { - if (ac == argc-1) { - return usage(); - } - binsize = atoi(argv[++ac]); + if (ac == argc-1) { + return usage(); + } + binsize = atoi(argv[++ac]); } else if (!strcmp(opt, "--binoffset")) { - if (ac == argc-1) { - return usage(); - } - binoffset = atoi(argv[++ac]); + if (ac == argc-1) { + return usage(); + } + binoffset = atoi(argv[++ac]); } else if (!strcmp(opt, "--ifile")) { - if (ac == argc-1) { - return usage(); - } - ifile = argv[++ac]; + if (ac == argc-1) { + return usage(); + } + ifile = argv[++ac]; } else if (!strcmp(opt, "--oprefix")) { - if (ac == argc-1) { - return usage(); - } - oprefix = argv[++ac]; + if (ac == argc-1) { + return usage(); + } + oprefix = argv[++ac]; } else if (!strcmp(opt, "--chrsizes")) { - if (ac == argc-1) { - return usage(); - } - chrsize_file = argv[++ac]; + if (ac == argc-1) { + return usage(); + } + chrsize_file = argv[++ac]; } else if (!strcmp(opt, "--chrA")) { - if (ac == argc-1) { - return usage(); - } - chrA = argv[++ac]; - whole_genome = false; + if (ac == argc-1) { + return usage(); + } + chrA = argv[++ac]; + whole_genome = false; } else if (!strcmp(opt, "--chrB")) { - if (ac == argc-1) { - return usage(); - } - chrB = argv[++ac]; - whole_genome = false; + if (ac == argc-1) { + return usage(); + } + chrB = argv[++ac]; + whole_genome = false; } else if (!strcmp(opt, "--help")) { - return help(); + return help(); } else { - std::cerr << '\n' << prog << ": unknown option " << opt << std::endl; - return usage(); + std::cerr << '\n' << prog << ": unknown option " << opt << std::endl; + return usage(); } } } @@ -759,19 +759,19 @@ static int build_matrix_init(Matrix& matrix, const char* ifile, std::ifstream& i while ((nn = read(fd, p_buffer, sizeof(p_buffer))) > 0) { const char *p = p_buffer; while (nn-- > 0) { - if (*p++ == '\n') { - line_total++; - } + if (*p++ == '\n') { + line_total++; + } } if ((cnt % 200) == 0) { - std::cerr << '.' << std::flush; + std::cerr << '.' << std::flush; } cnt++; } std::cerr << std::endl; close(fd); } - + std::ifstream chrsizefs; chrsizefs.open(chrsize_file); if (chrsizefs.bad() || chrsizefs.fail()) { @@ -917,34 +917,34 @@ static int build_matrix(int binoffset, chrsize_t ori_binsize, const char* binfil case UPPER_MATRIX: if (abs_bin < ord_bin) { - matrix.add(abs_bin, ord_bin); + matrix.add(abs_bin, ord_bin); } else { - matrix.add(ord_bin, abs_bin); + matrix.add(ord_bin, abs_bin); } break; case LOWER_MATRIX: if (abs_bin > ord_bin) { - matrix.add(abs_bin, ord_bin); + matrix.add(abs_bin, ord_bin); } else { - matrix.add(ord_bin, abs_bin); + matrix.add(ord_bin, abs_bin); } break; case COMPLETE_MATRIX: matrix.add(abs_bin, ord_bin); if (abs_bin != ord_bin) { - matrix.add(ord_bin, abs_bin); + matrix.add(ord_bin, abs_bin); } break; } line_cnt++; if (progress && (line_cnt % 100000) == 0) { if (detail_progress) { - double percent = (double(line_cnt)/line_total)*100; - std::cerr << "" << percent << "% " << line_cnt << " / " << line_total << std::endl; + double percent = (double(line_cnt)/line_total)*100; + std::cerr << "" << percent << "% " << line_cnt << " / " << line_total << std::endl; } else { - std::cerr << line_cnt << std::endl; + std::cerr << line_cnt << std::endl; } } } diff --git a/docs/benchmark.md b/docs/benchmark.md index 19a023c..eb90636 100644 --- a/docs/benchmark.md +++ b/docs/benchmark.md @@ -46,7 +46,7 @@ Here is a quick summary statistics ; # Filtered by Pairtools only = 4686 (11.58%) ``` -Overall, we can see that **70%** of valid interactions are called by both `HiC-Pro` and `Pairtools`. +Overall, we can see that **70%** of valid interactions are called by both `HiC-Pro` and `Pairtools`. Regarding the 30% of read pairs which are different between the two tools, we can see that a large majority (>75%) are due to differences in the read mapping (`bowtie2` versus `bwa-mem`). @@ -107,12 +107,12 @@ As before, small statistics were computed to compare the list of valid (and not # Filtered by Pairtools only = 6386317 (10.65%) ``` -Almost **80%** of valid interactions are called in common by `HiC-Pro` and `pairtools`. +Almost **80%** of valid interactions are called in common by `HiC-Pro` and `pairtools`. As previously observed, most of the differences observed between the two tools are explained by distinct mapping procedures. Finally, we generated the contact maps around a specific regions on the X chromosome -using the `cool` files and the TADs calling generated with both tools. +using the `cool` files and the TADs calling generated with both tools. **No difference is observed at the contact map level.** ![X Inactivation Center - HiC-Pro processing](./images/SRX2636669_hicpro_pygentracks.png) diff --git a/docs/output.md b/docs/output.md index d5a01db..a107f13 100644 --- a/docs/output.md +++ b/docs/output.md @@ -109,7 +109,7 @@ can thus be discarded using the `--min_cis_dist` parameter. - `*.FiltPairs` - List of filtered pairs - `*RSstat` - Statitics of number of read pairs falling in each category -Of note, these results are saved only if `--save_pairs_intermediates` is used. +Of note, these results are saved only if `--save_pairs_intermediates` is used. The `validPairs` are stored using a simple tab-delimited text format ; ```bash @@ -195,9 +195,8 @@ is specified on the command line. - `*.matrix` - genome-wide contact maps - `*_iced.matrix` - genome-wide iced contact maps -The contact maps are generated for all specified resolutions -(see `--bin_size` argument). -A contact map is defined by : +The contact maps are generated for all specified resolutions (see `--bin_size` argument). +A contact map is defined by: - A list of genomic intervals related to the specified resolution (BED format). - A matrix, stored as standard triplet sparse format (i.e. list format). @@ -221,7 +220,7 @@ downstream analysis. ## Hi-C contact maps Contact maps are usually stored as simple txt (`HiC-Pro`), .hic (`Juicer/Juicebox`) and .(m)cool (`cooler/Higlass`) formats. -The .cool and .hic format are compressed and indexed and usually much more efficient than the txt format. +The .cool and .hic format are compressed and indexed and usually much more efficient than the txt format. In the current workflow, we propose to use the `cooler` format as a standard to build the raw and normalised maps after valid pairs detection as it is used by several downstream analysis and visualisation tools. diff --git a/nextflow.config b/nextflow.config index f8e0b88..2d07c7b 100644 --- a/nextflow.config +++ b/nextflow.config @@ -1,8 +1,8 @@ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - nf-core/hic Nextflow config file +nf-core/hic Nextflow config file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Default config options for all compute environments +Default config options for all compute environments ---------------------------------------------------------------------------------------- */ @@ -40,26 +40,26 @@ params { ligation_site = null restriction_site = null digest { - 'hindiii'{ - restriction_site='A^AGCTT' - ligation_site='AAGCTAGCTT' - } - 'mboi' { - restriction_site='^GATC' - ligation_site='GATCGATC' - } - 'dpnii' { - restriction_site='^GATC' - ligation_site='GATCGATC' - } - 'arima' { - restriction_site='^GATC,G^ANTC' - ligation_site='GATCGATC,GATCANTC,GANTGATC,GANTANTC' - } - 'arimaV2' { - restriction_site='^GATC,G^ANTC,C^TNAG,T^TAA' - ligation_site='GATCGATC,GATCANTC,GANTGATC,GANTANTC,GATCTNAG,GANTTNAG,CTNAGATC,CTNAANTC,TTAGATC,TTAANTC,TTATTNAG,GATCTAA,GANTTAA,CTNATAA,TTATAA,CTNATNAG' - } + 'hindiii'{ + restriction_site='A^AGCTT' + ligation_site='AAGCTAGCTT' + } + 'mboi' { + restriction_site='^GATC' + ligation_site='GATCGATC' + } + 'dpnii' { + restriction_site='^GATC' + ligation_site='GATCGATC' + } + 'arima' { + restriction_site='^GATC,G^ANTC' + ligation_site='GATCGATC,GATCANTC,GANTGATC,GANTANTC' + } + 'arimaV2' { + restriction_site='^GATC,G^ANTC,C^TNAG,T^TAA' + ligation_site='GATCGATC,GATCANTC,GANTGATC,GANTANTC,GATCTNAG,GANTTNAG,CTNAGATC,CTNAANTC,TTAGATC,TTAANTC,TTATTNAG,GATCTAA,GANTTAA,CTNATAA,TTATAA,CTNATNAG' + } } min_restriction_fragment_size = 0 diff --git a/subworkflows/local/compartments.nf b/subworkflows/local/compartments.nf index fee68a5..7497e36 100644 --- a/subworkflows/local/compartments.nf +++ b/subworkflows/local/compartments.nf @@ -2,22 +2,22 @@ include { COOLTOOLS_EIGSCIS } from '../../modules/local/cooltools/eigscis' workflow COMPARTMENTS { - take: - cool - fasta - chrsize + take: + cool + fasta + chrsize - main: - ch_versions = Channel.empty() + main: + ch_versions = Channel.empty() - COOLTOOLS_EIGSCIS( - cool, - fasta.map{it -> it[1]}.collect(), - chrsize.map{it -> it[1]}.collect() - ) - ch_versions = ch_versions.mix(COOLTOOLS_EIGSCIS.out.versions) + COOLTOOLS_EIGSCIS( + cool, + fasta.map{it -> it[1]}.collect(), + chrsize.map{it -> it[1]}.collect() + ) + ch_versions = ch_versions.mix(COOLTOOLS_EIGSCIS.out.versions) - emit: - versions = ch_versions - compartments = COOLTOOLS_EIGSCIS.out.results -} \ No newline at end of file + emit: + versions = ch_versions + compartments = COOLTOOLS_EIGSCIS.out.results +} diff --git a/subworkflows/local/cooler.nf b/subworkflows/local/cooler.nf index 1299266..3857033 100644 --- a/subworkflows/local/cooler.nf +++ b/subworkflows/local/cooler.nf @@ -5,8 +5,8 @@ */ include { COOLER_ZOOMIFY } from '../../modules/nf-core/cooler/zoomify/main' -include { COOLER_DUMP } from '../../modules/nf-core/cooler/dump/main' -include { COOLER_CLOAD } from '../../modules/nf-core/cooler/cload/main' +include { COOLER_DUMP } from '../../modules/nf-core/cooler/dump/main' +include { COOLER_CLOAD } from '../../modules/nf-core/cooler/cload/main' include { COOLER_BALANCE } from '../../modules/nf-core/cooler/balance/main' include { COOLER_MAKEBINS } from '../../modules/nf-core/cooler/makebins/main' @@ -14,84 +14,84 @@ include { SPLIT_COOLER_DUMP } from '../../modules/local/split_cooler_dump' // add resolution in meta def addResolution(row) { - def meta = [:] - meta.id = row[0].id - meta.resolution = row[2] - return [meta, row[1], row[2]] + def meta = [:] + meta.id = row[0].id + meta.resolution = row[2] + return [meta, row[1], row[2]] } workflow COOLER { - take: - pairs // [meta, pairs, index] - chromsize // [meta, chromsize] - cool_bins - - main: - ch_versions = Channel.empty() - - //***************************************** - // EXPORT BINS - - COOLER_MAKEBINS( - chromsize.combine(cool_bins) - ) - ch_versions = ch_versions.mix(COOLER_MAKEBINS.out.versions) - - //***************************************** - // BUILD COOL FILE PER RESOLUTION - // [meta, pairs, resolution] - - COOLER_CLOAD( - pairs.combine(cool_bins), - chromsize.map{it -> it[1]}.collect() - ) - ch_versions = ch_versions.mix(COOLER_CLOAD.out.versions) - - // Add resolution in meta - COOLER_CLOAD.out.cool - .map{ it -> addResolution(it) } - .set{ ch_cool } - - COOLER_BALANCE( - ch_cool.map{[it[0], it[1], ""]} - ) - ch_versions = ch_versions.mix(COOLER_BALANCE.out.versions) - - // Zoomify at minimum bin resolution - if (!params.res_zoomify){ - ch_res_zoomify = cool_bins.min() - }else{ - ch_res_zoomify = Channel.from(params.res_zoomify).splitCsv().flatten().unique().toInteger() - } - - ch_cool - .combine(ch_res_zoomify) - .filter{ it[2] == it[3] } - .map{ it->[it[0], it[1]] } - .set{ ch_cool_zoomify } - - COOLER_ZOOMIFY( - ch_cool_zoomify - ) - ch_versions = ch_versions.mix(COOLER_ZOOMIFY.out.versions) - - //***************************************** - // DUMP DATA - // [meta, cool] / resolution - - COOLER_DUMP( - COOLER_BALANCE.out.cool.map{[it[0], it[1], ""]} - ) - ch_versions = ch_versions.mix(COOLER_DUMP.out.versions) - - SPLIT_COOLER_DUMP( - COOLER_DUMP.out.bedpe - ) - ch_versions = ch_versions.mix(SPLIT_COOLER_DUMP.out.versions) - - emit: - versions = ch_versions - cool = COOLER_BALANCE.out.cool - mcool = COOLER_ZOOMIFY.out.mcool -} \ No newline at end of file + take: + pairs // [meta, pairs, index] + chromsize // [meta, chromsize] + cool_bins + + main: + ch_versions = Channel.empty() + + //***************************************** + // EXPORT BINS + + COOLER_MAKEBINS( + chromsize.combine(cool_bins) + ) + ch_versions = ch_versions.mix(COOLER_MAKEBINS.out.versions) + + //***************************************** + // BUILD COOL FILE PER RESOLUTION + // [meta, pairs, resolution] + + COOLER_CLOAD( + pairs.combine(cool_bins), + chromsize.map{it -> it[1]}.collect() + ) + ch_versions = ch_versions.mix(COOLER_CLOAD.out.versions) + + // Add resolution in meta + COOLER_CLOAD.out.cool + .map{ it -> addResolution(it) } + .set{ ch_cool } + + COOLER_BALANCE( + ch_cool.map{[it[0], it[1], ""]} + ) + ch_versions = ch_versions.mix(COOLER_BALANCE.out.versions) + + // Zoomify at minimum bin resolution + if (!params.res_zoomify){ + ch_res_zoomify = cool_bins.min() + }else{ + ch_res_zoomify = Channel.from(params.res_zoomify).splitCsv().flatten().unique().toInteger() + } + + ch_cool + .combine(ch_res_zoomify) + .filter{ it[2] == it[3] } + .map{ it->[it[0], it[1]] } + .set{ ch_cool_zoomify } + + COOLER_ZOOMIFY( + ch_cool_zoomify + ) + ch_versions = ch_versions.mix(COOLER_ZOOMIFY.out.versions) + + //***************************************** + // DUMP DATA + // [meta, cool] / resolution + + COOLER_DUMP( + COOLER_BALANCE.out.cool.map{[it[0], it[1], ""]} + ) + ch_versions = ch_versions.mix(COOLER_DUMP.out.versions) + + SPLIT_COOLER_DUMP( + COOLER_DUMP.out.bedpe + ) + ch_versions = ch_versions.mix(SPLIT_COOLER_DUMP.out.versions) + + emit: + versions = ch_versions + cool = COOLER_BALANCE.out.cool + mcool = COOLER_ZOOMIFY.out.mcool +} diff --git a/subworkflows/local/hicpro.nf b/subworkflows/local/hicpro.nf index d13737c..0ee5fbc 100644 --- a/subworkflows/local/hicpro.nf +++ b/subworkflows/local/hicpro.nf @@ -3,7 +3,7 @@ * MAIN WORKFLOW * From the raw sequencing reads to the list of valid interactions */ - + include { HICPRO_MAPPING } from './hicpro_mapping' include { GET_VALID_INTERACTION } from '../../modules/local/hicpro/get_valid_interaction' include { GET_VALID_INTERACTION_DNASE } from '../../modules/local/hicpro/get_valid_interaction_dnase' @@ -15,134 +15,134 @@ include { ICE_NORMALIZATION } from '../../modules/local/hicpro/run_ice' // Remove meta.chunks def removeChunks(row){ - meta = row[0].clone() - meta.remove('chunk') - return [meta, row[1]] + meta = row[0].clone() + meta.remove('chunk') + return [meta, row[1]] } workflow HICPRO { - take: - reads // [meta, read1, read2] - index // path - fragments // path - chrsize // path - ligation_site // value - map_res // values - - main: - ch_versions = Channel.empty() - - // Fastq to paired-end bam - HICPRO_MAPPING( - reads, - index, - ligation_site - ) - ch_versions = ch_versions.mix(HICPRO_MAPPING.out.versions) - - //*************************************** - // DIGESTION PROTOCOLS - - if (!params.dnase){ - GET_VALID_INTERACTION ( - HICPRO_MAPPING.out.bam, - fragments.collect() + take: + reads // [meta, read1, read2] + index // path + fragments // path + chrsize // path + ligation_site // value + map_res // values + + main: + ch_versions = Channel.empty() + + // Fastq to paired-end bam + HICPRO_MAPPING( + reads, + index, + ligation_site + ) + ch_versions = ch_versions.mix(HICPRO_MAPPING.out.versions) + + //*************************************** + // DIGESTION PROTOCOLS + + if (!params.dnase){ + GET_VALID_INTERACTION ( + HICPRO_MAPPING.out.bam, + fragments.collect() + ) + ch_versions = ch_versions.mix(GET_VALID_INTERACTION.out.versions) + ch_valid_pairs = GET_VALID_INTERACTION.out.valid_pairs + ch_valid_stats = GET_VALID_INTERACTION.out.stats + + }else{ + + //**************************************** + // DNASE-LIKE PROTOCOLS + + GET_VALID_INTERACTION_DNASE ( + HICPRO_MAPPING.out.bam + ) + ch_versions = ch_versions.mix(GET_VALID_INTERACTION_DNASE.out.versions) + ch_valid_pairs = GET_VALID_INTERACTION_DNASE.out.valid_pairs + ch_valid_stats = GET_VALID_INTERACTION_DNASE.out.stats + } + + + //************************************** + // MERGE AND REMOVE DUPLICATES + + //if (params.split_fastq){ + ch_valid_pairs = ch_valid_pairs + .map{ meta, valid_pairs -> + def newMeta = [ id: meta.id, single_end: meta.singleEnd, part:meta.part ] + [ groupKey(newMeta, meta.part), valid_pairs ] + }.groupTuple() + + MERGE_VALID_INTERACTION ( + ch_valid_pairs ) - ch_versions = ch_versions.mix(GET_VALID_INTERACTION.out.versions) - ch_valid_pairs = GET_VALID_INTERACTION.out.valid_pairs - ch_valid_stats = GET_VALID_INTERACTION.out.stats + ch_versions = ch_versions.mix(MERGE_VALID_INTERACTION.out.versions) - }else{ - //**************************************** - // DNASE-LIKE PROTOCOLS + ch_hicpro_mappingstats = HICPRO_MAPPING.out.mapstats + .map{ meta, stats -> + def newMeta = [ id: meta.id, single_end: meta.singleEnd, part:meta.part ] + [ groupKey(newMeta, meta.part), stats ] + }.groupTuple() - GET_VALID_INTERACTION_DNASE ( - HICPRO_MAPPING.out.bam - ) - ch_versions = ch_versions.mix(GET_VALID_INTERACTION_DNASE.out.versions) - ch_valid_pairs = GET_VALID_INTERACTION_DNASE.out.valid_pairs - ch_valid_stats = GET_VALID_INTERACTION_DNASE.out.stats - } - - - //************************************** - // MERGE AND REMOVE DUPLICATES - - //if (params.split_fastq){ - ch_valid_pairs = ch_valid_pairs - .map{ meta, valid_pairs -> - def newMeta = [ id: meta.id, single_end: meta.singleEnd, part:meta.part ] - [ groupKey(newMeta, meta.part), valid_pairs ] - }.groupTuple() - - MERGE_VALID_INTERACTION ( - ch_valid_pairs - ) - ch_versions = ch_versions.mix(MERGE_VALID_INTERACTION.out.versions) - - - ch_hicpro_mappingstats = HICPRO_MAPPING.out.mapstats - .map{ meta, stats -> - def newMeta = [ id: meta.id, single_end: meta.singleEnd, part:meta.part ] - [ groupKey(newMeta, meta.part), stats ] - }.groupTuple() - - ch_hicpro_pairstats = HICPRO_MAPPING.out.pairstats - .map{ meta, stats -> - def newMeta = [ id: meta.id, single_end: meta.singleEnd, part:meta.part ] - [ groupKey(newMeta, meta.part), stats ] - }.groupTuple() - - ch_hicpro_validstats = ch_valid_stats - .map{ meta, stats -> - def newMeta = [ id: meta.id, single_end: meta.singleEnd, part:meta.part ] - [ groupKey(newMeta, meta.part), stats ] - }.groupTuple() - - MERGE_STATS( - ch_hicpro_mappingstats.concat(ch_hicpro_pairstats, ch_hicpro_validstats) - ) - ch_versions = ch_versions.mix(MERGE_STATS.out.versions) - - //*************************************** - // CONVERTS TO PAIRS - - HICPRO2PAIRS ( - MERGE_VALID_INTERACTION.out.valid_pairs, - chrsize.collect() - ) - ch_versions = ch_versions.mix(HICPRO2PAIRS.out.versions) - - //*************************************** - // CONTACT MAPS - - if (params.hicpro_maps){ - - //build_contact_maps - BUILD_CONTACT_MAPS( - MERGE_VALID_INTERACTION.out.valid_pairs.combine(map_res), - chrsize.collect() + ch_hicpro_pairstats = HICPRO_MAPPING.out.pairstats + .map{ meta, stats -> + def newMeta = [ id: meta.id, single_end: meta.singleEnd, part:meta.part ] + [ groupKey(newMeta, meta.part), stats ] + }.groupTuple() + + ch_hicpro_validstats = ch_valid_stats + .map{ meta, stats -> + def newMeta = [ id: meta.id, single_end: meta.singleEnd, part:meta.part ] + [ groupKey(newMeta, meta.part), stats ] + }.groupTuple() + + MERGE_STATS( + ch_hicpro_mappingstats.concat(ch_hicpro_pairstats, ch_hicpro_validstats) ) - ch_hicpro_raw_maps = BUILD_CONTACT_MAPS.out.maps - - // run_ice - ICE_NORMALIZATION( - BUILD_CONTACT_MAPS.out.maps + ch_versions = ch_versions.mix(MERGE_STATS.out.versions) + + //*************************************** + // CONVERTS TO PAIRS + + HICPRO2PAIRS ( + MERGE_VALID_INTERACTION.out.valid_pairs, + chrsize.collect() ) - ch_hicpro_iced_maps = ICE_NORMALIZATION.out.maps - ch_versions = ch_versions.mix(ICE_NORMALIZATION.out.versions) - - }else{ - ch_hicpro_raw_maps = Channel.empty() - ch_hicpro_iced_maps = Channel.empty() - } - - emit: - versions = ch_versions - pairs = HICPRO2PAIRS.out.pairs - mqc = MERGE_VALID_INTERACTION.out.mqc.concat(MERGE_STATS.out.mqc) - raw_maps = ch_hicpro_raw_maps - iced_maps = ch_hicpro_iced_maps + ch_versions = ch_versions.mix(HICPRO2PAIRS.out.versions) + + //*************************************** + // CONTACT MAPS + + if (params.hicpro_maps){ + + //build_contact_maps + BUILD_CONTACT_MAPS( + MERGE_VALID_INTERACTION.out.valid_pairs.combine(map_res), + chrsize.collect() + ) + ch_hicpro_raw_maps = BUILD_CONTACT_MAPS.out.maps + + // run_ice + ICE_NORMALIZATION( + BUILD_CONTACT_MAPS.out.maps + ) + ch_hicpro_iced_maps = ICE_NORMALIZATION.out.maps + ch_versions = ch_versions.mix(ICE_NORMALIZATION.out.versions) + + }else{ + ch_hicpro_raw_maps = Channel.empty() + ch_hicpro_iced_maps = Channel.empty() + } + + emit: + versions = ch_versions + pairs = HICPRO2PAIRS.out.pairs + mqc = MERGE_VALID_INTERACTION.out.mqc.concat(MERGE_STATS.out.mqc) + raw_maps = ch_hicpro_raw_maps + iced_maps = ch_hicpro_iced_maps } diff --git a/subworkflows/local/hicpro_mapping.nf b/subworkflows/local/hicpro_mapping.nf index 4f6b9e9..15166e9 100644 --- a/subworkflows/local/hicpro_mapping.nf +++ b/subworkflows/local/hicpro_mapping.nf @@ -13,95 +13,95 @@ include { MAPPING_STATS_DNASE } from '../../modules/local/hicpro/dnase_mapping_s workflow HICPRO_MAPPING { - take: - reads // [meta, read1, read2] - index // [meta, path] - ligation_site // value - - main: - ch_versions = Channel.empty() - - // Align each mates separetly and add mates information in [meta] - ch_reads_r1 = reads - .map{ meta, fastq -> - def newMeta = [ id: meta.id, single_end:true, chunk:meta.chunk, part:meta.part, mates:'R1' ] - [ newMeta, fastq[0] ] - } - - ch_reads_r2 = reads - .map{ meta, fastq -> - def newMeta = [ id: meta.id, single_end:true, chunk:meta.chunk, part:meta.part, mates:'R2' ] - [ newMeta, fastq[1] ] + take: + reads // [meta, read1, read2] + index // [meta, path] + ligation_site // value + + main: + ch_versions = Channel.empty() + + // Align each mates separetly and add mates information in [meta] + ch_reads_r1 = reads + .map{ meta, fastq -> + def newMeta = [ id: meta.id, single_end:true, chunk:meta.chunk, part:meta.part, mates:'R1' ] + [ newMeta, fastq[0] ] + } + + ch_reads_r2 = reads + .map{ meta, fastq -> + def newMeta = [ id: meta.id, single_end:true, chunk:meta.chunk, part:meta.part, mates:'R2' ] + [ newMeta, fastq[1] ] + } + + ch_reads = ch_reads_r1.concat(ch_reads_r2) + + // bowtie2 - save_unaligned=true - sort_bam=false + BOWTIE2_ALIGN( + ch_reads, + index.collect(), + true, + false + ) + ch_versions = ch_versions.mix(BOWTIE2_ALIGN.out.versions) + + if (!params.dnase){ + + // trim reads + TRIM_READS( + BOWTIE2_ALIGN.out.fastq, + ligation_site.collect() + ) + ch_versions = ch_versions.mix(TRIM_READS.out.versions) + + // bowtie2 on trimmed reads - save_unaligned=false - sort_bam=false + BOWTIE2_ALIGN_TRIMMED( + TRIM_READS.out.fastq, + index.collect(), + false, + false + ) + ch_versions = ch_versions.mix(BOWTIE2_ALIGN_TRIMMED.out.versions) + + // Merge the two mapping steps + ch_bowtie2_align = BOWTIE2_ALIGN.out.aligned + .combine(BOWTIE2_ALIGN_TRIMMED.out.aligned, by:[0]) + + MERGE_BOWTIE2( + ch_bowtie2_align + ) + ch_versions = ch_versions.mix(MERGE_BOWTIE2.out.versions) + ch_mapping_stats = MERGE_BOWTIE2.out.stats + + ch_bams = MERGE_BOWTIE2.out.bam + .map{ meta, bam -> + def newMeta = [ id: meta.id, single_end:false, chunk:meta.chunk, part:meta.part ] + [ newMeta, bam ] + }.groupTuple() + + + }else{ + + MAPPING_STATS_DNASE( + BOWTIE2_ALIGN.out.aligned + ) + ch_mapping_stats = MAPPING_STATS_DNASE.out.stats + + ch_bams = BOWTIE2_ALIGN.out.aligned + .map{ meta, bam -> + def newMeta = [ id: meta.id, single_end: false, chunk:meta.chunk, part:meta.part ] + [ newMeta, bam ] + }.groupTuple() } - ch_reads = ch_reads_r1.concat(ch_reads_r2) - - // bowtie2 - save_unaligned=true - sort_bam=false - BOWTIE2_ALIGN( - ch_reads, - index.collect(), - true, - false - ) - ch_versions = ch_versions.mix(BOWTIE2_ALIGN.out.versions) - - if (!params.dnase){ - - // trim reads - TRIM_READS( - BOWTIE2_ALIGN.out.fastq, - ligation_site.collect() - ) - ch_versions = ch_versions.mix(TRIM_READS.out.versions) - - // bowtie2 on trimmed reads - save_unaligned=false - sort_bam=false - BOWTIE2_ALIGN_TRIMMED( - TRIM_READS.out.fastq, - index.collect(), - false, - false + COMBINE_MATES ( + ch_bams ) - ch_versions = ch_versions.mix(BOWTIE2_ALIGN_TRIMMED.out.versions) - - // Merge the two mapping steps - ch_bowtie2_align = BOWTIE2_ALIGN.out.aligned - .combine(BOWTIE2_ALIGN_TRIMMED.out.aligned, by:[0]) + ch_versions = ch_versions.mix(COMBINE_MATES.out.versions) - MERGE_BOWTIE2( - ch_bowtie2_align - ) - ch_versions = ch_versions.mix(MERGE_BOWTIE2.out.versions) - ch_mapping_stats = MERGE_BOWTIE2.out.stats - - ch_bams = MERGE_BOWTIE2.out.bam - .map{ meta, bam -> - def newMeta = [ id: meta.id, single_end:false, chunk:meta.chunk, part:meta.part ] - [ newMeta, bam ] - }.groupTuple() - - - }else{ - - MAPPING_STATS_DNASE( - BOWTIE2_ALIGN.out.aligned - ) - ch_mapping_stats = MAPPING_STATS_DNASE.out.stats - - ch_bams = BOWTIE2_ALIGN.out.aligned - .map{ meta, bam -> - def newMeta = [ id: meta.id, single_end: false, chunk:meta.chunk, part:meta.part ] - [ newMeta, bam ] - }.groupTuple() - } - - COMBINE_MATES ( - ch_bams - ) - ch_versions = ch_versions.mix(COMBINE_MATES.out.versions) - - emit: - versions = ch_versions - bam = COMBINE_MATES.out.bam - mapstats = ch_mapping_stats - pairstats = COMBINE_MATES.out.stats + emit: + versions = ch_versions + bam = COMBINE_MATES.out.bam + mapstats = ch_mapping_stats + pairstats = COMBINE_MATES.out.stats } diff --git a/subworkflows/local/input_check.nf b/subworkflows/local/input_check.nf index 37181fc..79b7954 100644 --- a/subworkflows/local/input_check.nf +++ b/subworkflows/local/input_check.nf @@ -11,28 +11,28 @@ workflow INPUT_CHECK { main: if (params.split_fastq){ - SAMPLESHEET_CHECK ( samplesheet ) - .csv - .splitCsv ( header:true, sep:',' ) - .map { create_fastq_channels(it) } - .splitFastq( by: params.fastq_chunks_size, pe:true, file: true, compress:true) - .map { it -> [it[0], [it[1], it[2]]]} - .groupTuple(by: [0]) - .flatMap { it -> setMetaChunk(it) } - .collate(2) - .set { reads } + SAMPLESHEET_CHECK ( samplesheet ) + .csv + .splitCsv ( header:true, sep:',' ) + .map { create_fastq_channels(it) } + .splitFastq( by: params.fastq_chunks_size, pe:true, file: true, compress:true) + .map { it -> [it[0], [it[1], it[2]]]} + .groupTuple(by: [0]) + .flatMap { it -> setMetaChunk(it) } + .collate(2) + .set { reads } - }else{ - SAMPLESHEET_CHECK ( samplesheet ) - .csv - .splitCsv ( header:true, sep:',' ) - .map { create_fastq_channels(it) } - .map { it -> [it[0], [it[1], it[2]]]} - .groupTuple(by: [0]) - .flatMap { it -> setMetaChunk(it) } - .collate(2) - .set { reads } - } + } else { + SAMPLESHEET_CHECK ( samplesheet ) + .csv + .splitCsv ( header:true, sep:',' ) + .map { create_fastq_channels(it) } + .map { it -> [it[0], [it[1], it[2]]]} + .groupTuple(by: [0]) + .flatMap { it -> setMetaChunk(it) } + .collate(2) + .set { reads } + } emit: reads // channel: [ val(meta), [ reads ] ] @@ -40,29 +40,29 @@ workflow INPUT_CHECK { // Function to get list of [ meta, [ fastq_1, fastq_2 ] ] def create_fastq_channels(LinkedHashMap row) { - def meta = [:] - meta.id = row.sample - meta.single_end = false + def meta = [:] + meta.id = row.sample + meta.single_end = false - def array = [] - if (!file(row.fastq_1).exists()) { - exit 1, "ERROR: Please check input samplesheet -> Read 1 FastQ file does not exist!\n${row.fastq_1}" - } - if (!file(row.fastq_2).exists()) { - exit 1, "ERROR: Please check input samplesheet -> Read 2 FastQ file does not exist!\n${row.fastq_2}" - } - array = [ meta, file(row.fastq_1), file(row.fastq_2) ] - return array + def array = [] + if (!file(row.fastq_1).exists()) { + exit 1, "ERROR: Please check input samplesheet -> Read 1 FastQ file does not exist!\n${row.fastq_1}" + } + if (!file(row.fastq_2).exists()) { + exit 1, "ERROR: Please check input samplesheet -> Read 2 FastQ file does not exist!\n${row.fastq_2}" + } + array = [ meta, file(row.fastq_1), file(row.fastq_2) ] + return array } // Set the meta.chunk value in case of technical replicates def setMetaChunk(row){ - def map = [] - row[1].eachWithIndex() { file,i -> - meta = row[0].clone() - meta.chunk = i - meta.part = row[1].size() - map += [meta, file] - } - return map -} \ No newline at end of file + def map = [] + row[1].eachWithIndex() { file,i -> + meta = row[0].clone() + meta.chunk = i + meta.part = row[1].size() + map += [meta, file] + } + return map +} diff --git a/subworkflows/local/pairtools.nf b/subworkflows/local/pairtools.nf index ef2ca93..7eec885 100644 --- a/subworkflows/local/pairtools.nf +++ b/subworkflows/local/pairtools.nf @@ -3,7 +3,7 @@ * MAIN WORKFLOW * From the raw sequencing reads to the list of valid interactions */ - + //include { BWAMEM2_MEM } from '../../modules/nf-core/bwamem2/mem/main' include { BWA_MEM } from '../../modules/nf-core/bwa/mem/main' include { PAIRTOOLS_DEDUP } from '../../modules/nf-core/pairtools/dedup/main' @@ -25,91 +25,91 @@ include { PAIRTOOLS_PARSE } from '../../modules/local/pairtools/pairtools_parse' workflow PAIRTOOLS { - take: - reads // [meta, read1, read2] - index // [meta2, path] - frag // path - chrsize // path - - main: - ch_versions = Channel.empty() - - BWA_MEM( - reads, - index.collect(), - Channel.value([]) - ) - - PAIRTOOLS_PARSE( - BWA_MEM.out.bam, - chrsize.collect() - ) - - PAIRTOOLS_RESTRICT( - PAIRTOOLS_PARSE.out.pairsam, - frag.map{it->it[1]}.collect() - ) - - ch_pairsam = params.dnase ? PAIRTOOLS_PARSE.out.pairsam : PAIRTOOLS_RESTRICT.out.restrict - PAIRTOOLS_SORT( - ch_pairsam - ) - - ch_valid_pairs = PAIRTOOLS_SORT.out.sorted - .map{ meta, pairs -> - def newMeta = [ id: meta.id, single_end: meta.single_end, part:meta.part ] - [ groupKey(newMeta, meta.part), pairs ] - } - .groupTuple() - .view() - .branch { - single: it[0].part <=1 - multiple: it[0].part > 1 - } - - PAIRTOOLS_MERGE( - ch_valid_pairs.multiple - ) - - // Separate pairs/bam files - PAIRTOOLS_SPLIT( - PAIRTOOLS_MERGE.out.pairs.mix(ch_valid_pairs.single) - ) - - // Manage BAM files - SAMTOOLS_SORT( - PAIRTOOLS_SPLIT.out.bam - ) - - SAMTOOLS_INDEX( - SAMTOOLS_SORT.out.bam - ) - - SAMTOOLS_FLAGSTAT( - SAMTOOLS_SORT.out.bam.join(SAMTOOLS_INDEX.out.bai) - ) - - PAIRTOOLS_DEDUP( - PAIRTOOLS_SPLIT.out.pairs - ) - - ch_pairselect = params.keep_dups ? PAIRTOOLS_SPLIT.out.pairs : PAIRTOOLS_DEDUP.out.pairs - PAIRTOOLS_SELECT( - ch_pairselect - ) - - PAIRTOOLS_STATS( - PAIRTOOLS_SELECT.out.selected - ) - - PAIRIX( - PAIRTOOLS_SELECT.out.selected - ) - - emit: - versions = ch_versions - pairs = PAIRIX.out.index - bam = PAIRTOOLS_SPLIT.out.bam.join(SAMTOOLS_INDEX.out.bai) - stats = PAIRTOOLS_STATS.out.stats.map{it->it[1]} - flagstat = SAMTOOLS_FLAGSTAT.out.flagstat + take: + reads // [meta, read1, read2] + index // [meta2, path] + frag // path + chrsize // path + + main: + ch_versions = Channel.empty() + + BWA_MEM( + reads, + index.collect(), + Channel.value([]) + ) + + PAIRTOOLS_PARSE( + BWA_MEM.out.bam, + chrsize.collect() + ) + + PAIRTOOLS_RESTRICT( + PAIRTOOLS_PARSE.out.pairsam, + frag.map{it->it[1]}.collect() + ) + + ch_pairsam = params.dnase ? PAIRTOOLS_PARSE.out.pairsam : PAIRTOOLS_RESTRICT.out.restrict + PAIRTOOLS_SORT( + ch_pairsam + ) + + ch_valid_pairs = PAIRTOOLS_SORT.out.sorted + .map{ meta, pairs -> + def newMeta = [ id: meta.id, single_end: meta.single_end, part:meta.part ] + [ groupKey(newMeta, meta.part), pairs ] + } + .groupTuple() + .view() + .branch { + single: it[0].part <=1 + multiple: it[0].part > 1 + } + + PAIRTOOLS_MERGE( + ch_valid_pairs.multiple + ) + + // Separate pairs/bam files + PAIRTOOLS_SPLIT( + PAIRTOOLS_MERGE.out.pairs.mix(ch_valid_pairs.single) + ) + + // Manage BAM files + SAMTOOLS_SORT( + PAIRTOOLS_SPLIT.out.bam + ) + + SAMTOOLS_INDEX( + SAMTOOLS_SORT.out.bam + ) + + SAMTOOLS_FLAGSTAT( + SAMTOOLS_SORT.out.bam.join(SAMTOOLS_INDEX.out.bai) + ) + + PAIRTOOLS_DEDUP( + PAIRTOOLS_SPLIT.out.pairs + ) + + ch_pairselect = params.keep_dups ? PAIRTOOLS_SPLIT.out.pairs : PAIRTOOLS_DEDUP.out.pairs + PAIRTOOLS_SELECT( + ch_pairselect + ) + + PAIRTOOLS_STATS( + PAIRTOOLS_SELECT.out.selected + ) + + PAIRIX( + PAIRTOOLS_SELECT.out.selected + ) + + emit: + versions = ch_versions + pairs = PAIRIX.out.index + bam = PAIRTOOLS_SPLIT.out.bam.join(SAMTOOLS_INDEX.out.bai) + stats = PAIRTOOLS_STATS.out.stats.map{it->it[1]} + flagstat = SAMTOOLS_FLAGSTAT.out.flagstat } diff --git a/subworkflows/local/prepare_genome.nf b/subworkflows/local/prepare_genome.nf index dd0c5f4..2eee2b4 100644 --- a/subworkflows/local/prepare_genome.nf +++ b/subworkflows/local/prepare_genome.nf @@ -9,81 +9,81 @@ include { GET_RESTRICTION_FRAGMENTS } from '../../modules/local/hicpro/get_restr workflow PREPARE_GENOME { - take: - fasta - restriction_site + take: + fasta + restriction_site - main: - ch_versions = Channel.empty() + main: + ch_versions = Channel.empty() - //*************************************** - // Bowtie index - if (params.processing == "hicpro"){ - if(!params.bwt2_index){ - BOWTIE2_BUILD ( - fasta - ) - ch_index = BOWTIE2_BUILD.out.index - ch_versions = ch_versions.mix(BOWTIE2_BUILD.out.versions) - }else{ - Channel.fromPath( params.bwt2_index , checkIfExists: true) - .map { it -> [[:], it]} - .ifEmpty { exit 1, "Genome index: Provided index not found: ${params.bwt2_index}" } - .set { ch_index } + //*************************************** + // Bowtie index + if (params.processing == "hicpro"){ + if(!params.bwt2_index){ + BOWTIE2_BUILD ( + fasta + ) + ch_index = BOWTIE2_BUILD.out.index + ch_versions = ch_versions.mix(BOWTIE2_BUILD.out.versions) + }else{ + Channel.fromPath( params.bwt2_index , checkIfExists: true) + .map { it -> [[:], it]} + .ifEmpty { exit 1, "Genome index: Provided index not found: ${params.bwt2_index}" } + .set { ch_index } + } } - } - //*************************************** - // Bwa-mem index - if (params.processing == "pairtools"){ - if(!params.bwa_index){ - BWA_INDEX ( - fasta - ) - ch_index = BWA_INDEX.out.index - ch_versions = ch_versions.mix(BWA_INDEX.out.versions) - }else{ - Channel.fromPath( params.bwa_index , checkIfExists: true) - .map { it -> [[:], it]} - .ifEmpty { exit 1, "Genome index: Provided index not found: ${params.bwa_index}" } - .set { ch_index } + //*************************************** + // Bwa-mem index + if (params.processing == "pairtools"){ + if(!params.bwa_index){ + BWA_INDEX ( + fasta + ) + ch_index = BWA_INDEX.out.index + ch_versions = ch_versions.mix(BWA_INDEX.out.versions) + }else{ + Channel.fromPath( params.bwa_index , checkIfExists: true) + .map { it -> [[:], it]} + .ifEmpty { exit 1, "Genome index: Provided index not found: ${params.bwa_index}" } + .set { ch_index } + } } - } - //*************************************** - // Chromosome size - if(!params.chromosome_size){ - CUSTOM_GETCHROMSIZES( - fasta - ) - ch_chromsize = CUSTOM_GETCHROMSIZES.out.sizes - ch_versions = ch_versions.mix(CUSTOM_GETCHROMSIZES.out.versions) - }else{ - Channel.fromPath( params.chromosome_size , checkIfExists: true) - .map { it -> [[:], it]} - .set {ch_chromsize} - } + //*************************************** + // Chromosome size + if(!params.chromosome_size){ + CUSTOM_GETCHROMSIZES( + fasta + ) + ch_chromsize = CUSTOM_GETCHROMSIZES.out.sizes + ch_versions = ch_versions.mix(CUSTOM_GETCHROMSIZES.out.versions) + }else{ + Channel.fromPath( params.chromosome_size , checkIfExists: true) + .map { it -> [[:], it]} + .set {ch_chromsize} + } - //*************************************** - // Restriction fragments - if(!params.restriction_fragments && !params.dnase){ - GET_RESTRICTION_FRAGMENTS( - fasta, - restriction_site - ) - ch_resfrag = GET_RESTRICTION_FRAGMENTS.out.results - ch_versions = ch_versions.mix(GET_RESTRICTION_FRAGMENTS.out.versions) - }else if (!params.dnase){ - Channel.fromPath( params.restriction_fragments, checkIfExists: true ) + //*************************************** + // Restriction fragments + if(!params.restriction_fragments && !params.dnase){ + GET_RESTRICTION_FRAGMENTS( + fasta, + restriction_site + ) + ch_resfrag = GET_RESTRICTION_FRAGMENTS.out.results + ch_versions = ch_versions.mix(GET_RESTRICTION_FRAGMENTS.out.versions) + }else if (!params.dnase){ + Channel.fromPath( params.restriction_fragments, checkIfExists: true ) .map { it -> [[:], it] } .set {ch_resfrag} - }else{ - ch_resfrag = Channel.empty() - } + }else{ + ch_resfrag = Channel.empty() + } - emit: - index = ch_index - chromosome_size = ch_chromsize - res_frag = ch_resfrag - versions = ch_versions + emit: + index = ch_index + chromosome_size = ch_chromsize + res_frag = ch_resfrag + versions = ch_versions } diff --git a/subworkflows/local/tads.nf b/subworkflows/local/tads.nf index 31c1e38..f70a01f 100644 --- a/subworkflows/local/tads.nf +++ b/subworkflows/local/tads.nf @@ -3,26 +3,26 @@ include { HIC_FIND_TADS } from '../../modules/local/hicexplorer/hicFindTADs' workflow TADS { - take: - cool + take: + cool - main: - ch_versions = Channel.empty() - ch_tads = Channel.empty() + main: + ch_versions = Channel.empty() + ch_tads = Channel.empty() - if (params.tads_caller =~ 'insulation'){ - COOLTOOLS_INSULATION(cool) - ch_versions = ch_versions.mix(COOLTOOLS_INSULATION.out.versions) - ch_tads = ch_tads.mix(COOLTOOLS_INSULATION.out.tsv) - } - - if (params.tads_caller =~ 'hicexplorer'){ - HIC_FIND_TADS(cool) - ch_versions = ch_versions.mix(HIC_FIND_TADS.out.versions) - ch_tads = ch_tads.mix(HIC_FIND_TADS.out.results) - } + if (params.tads_caller =~ 'insulation'){ + COOLTOOLS_INSULATION(cool) + ch_versions = ch_versions.mix(COOLTOOLS_INSULATION.out.versions) + ch_tads = ch_tads.mix(COOLTOOLS_INSULATION.out.tsv) + } - emit: - tads = ch_tads - versions = ch_versions -} \ No newline at end of file + if (params.tads_caller =~ 'hicexplorer'){ + HIC_FIND_TADS(cool) + ch_versions = ch_versions.mix(HIC_FIND_TADS.out.versions) + ch_tads = ch_tads.mix(HIC_FIND_TADS.out.results) + } + + emit: + tads = ch_tads + versions = ch_versions +} diff --git a/workflows/hic.nf b/workflows/hic.nf index d3122d1..9bf022d 100644 --- a/workflows/hic.nf +++ b/workflows/hic.nf @@ -12,7 +12,7 @@ include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pi include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_hic_pipeline' // MODULE: Local to the pipeline -include { HIC_PLOT_DIST_VS_COUNTS } from '../modules/local/hicexplorer/hicPlotDistVsCounts' +include { HIC_PLOT_DIST_VS_COUNTS } from '../modules/local/hicexplorer/hicPlotDistVsCounts' // SUBWORKFLOW: Consisting of a mix of local and nf-core/modules include { PREPARE_GENOME } from '../subworkflows/local/prepare_genome' @@ -25,18 +25,18 @@ include { TADS } from '../subworkflows/local/tads' //***************************************** // Digestion parameters if (params.digestion){ - restriction_site = params.digestion ? params.digest[ params.digestion ].restriction_site ?: false : false - ch_restriction_site = Channel.value(restriction_site) - ligation_site = params.digestion ? params.digest[ params.digestion ].ligation_site ?: false : false - ch_ligation_site = Channel.value(ligation_site) + restriction_site = params.digestion ? params.digest[ params.digestion ].restriction_site ?: false : false + ch_restriction_site = Channel.value(restriction_site) + ligation_site = params.digestion ? params.digest[ params.digestion ].ligation_site ?: false : false + ch_ligation_site = Channel.value(ligation_site) }else if (params.restriction_site && params.ligation_site){ - ch_restriction_site = Channel.value(params.restriction_site) - ch_ligation_site = Channel.value(params.ligation_site) + ch_restriction_site = Channel.value(params.restriction_site) + ch_ligation_site = Channel.value(params.ligation_site) }else if (params.dnase){ - ch_restriction_site = Channel.empty() - ch_ligation_site = Channel.empty() + ch_restriction_site = Channel.empty() + ch_ligation_site = Channel.empty() }else{ - exit 1, "Ligation motif not found. Please either use the `--digestion` parameters or specify the `--restriction_site` and `--ligation_site`. For DNase Hi-C, please use '--dnase' option" + exit 1, "Ligation motif not found. Please either use the `--digestion` parameters or specify the `--restriction_site` and `--ligation_site`. For DNase Hi-C, please use '--dnase' option" } //**************************************** @@ -45,47 +45,47 @@ if (params.digestion){ ch_map_res = Channel.from( params.bin_size ).splitCsv().flatten().toInteger() if (params.res_zoomify){ - ch_zoom_res = Channel.from( params.res_zoomify ).splitCsv().flatten().toInteger() - ch_map_res = ch_map_res.concat(ch_zoom_res) + ch_zoom_res = Channel.from( params.res_zoomify ).splitCsv().flatten().toInteger() + ch_map_res = ch_map_res.concat(ch_zoom_res) } if (params.res_tads && !params.skip_tads){ - ch_tads_res = Channel.from( "${params.res_tads}" ).splitCsv().flatten().toInteger() - ch_map_res = ch_map_res.concat(ch_tads_res) + ch_tads_res = Channel.from( "${params.res_tads}" ).splitCsv().flatten().toInteger() + ch_map_res = ch_map_res.concat(ch_tads_res) }else{ - ch_tads_res=Channel.empty() - if (!params.skip_tads){ - log.warn "[nf-core/hic] Hi-C resolution for TADs calling not specified. See --res_tads" - } + ch_tads_res=Channel.empty() + if (!params.skip_tads){ + log.warn "[nf-core/hic] Hi-C resolution for TADs calling not specified. See --res_tads" + } } if (params.res_dist_decay && !params.skip_dist_decay){ - ch_ddecay_res = Channel.from( "${params.res_dist_decay}" ).splitCsv().flatten().toInteger() - ch_map_res = ch_map_res.concat(ch_ddecay_res) + ch_ddecay_res = Channel.from( "${params.res_dist_decay}" ).splitCsv().flatten().toInteger() + ch_map_res = ch_map_res.concat(ch_ddecay_res) }else{ - ch_ddecay_res = Channel.empty() - if (!params.skip_dist_decay){ - log.warn "[nf-core/hic] Hi-C resolution for distance decay not specified. See --res_dist_decay" - } + ch_ddecay_res = Channel.empty() + if (!params.skip_dist_decay){ + log.warn "[nf-core/hic] Hi-C resolution for distance decay not specified. See --res_dist_decay" + } } if (params.res_compartments && !params.skip_compartments){ - ch_comp_res = Channel.from( "${params.res_compartments}" ).splitCsv().flatten().toInteger() - ch_map_res = ch_map_res.concat(ch_comp_res) + ch_comp_res = Channel.from( "${params.res_compartments}" ).splitCsv().flatten().toInteger() + ch_map_res = ch_map_res.concat(ch_comp_res) }else{ - ch_comp_res = Channel.empty() - if (!params.skip_compartments){ - log.warn "[nf-core/hic] Hi-C resolution for compartment calling not specified. See --res_compartments" - } + ch_comp_res = Channel.empty() + if (!params.skip_compartments){ + log.warn "[nf-core/hic] Hi-C resolution for compartment calling not specified. See --res_compartments" + } } ch_map_res = ch_map_res.unique() def genomeName = params.genome ?: params.fasta.substring(params.fasta.lastIndexOf(File.separator)+1) Channel.fromPath( params.fasta ) - .ifEmpty { exit 1, "Genome index: Fasta file not found: ${params.fasta}" } - .map{it->[[id:genomeName],it]} - .set { ch_fasta } + .ifEmpty { exit 1, "Genome index: Fasta file not found: ${params.fasta}" } + .map{it->[[id:genomeName],it]} + .set { ch_fasta } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -95,152 +95,152 @@ Channel.fromPath( params.fasta ) workflow HIC { - take: - ch_samplesheet // channel: samplesheet read in from --input - - main: - - ch_versions = Channel.empty() - ch_multiqc_files = Channel.empty() - - // - // MODULE: Run FastQC - // - FASTQC ( - ch_samplesheet - ) - ch_multiqc_files = ch_multiqc_files.mix(FASTQC.out.zip.collect{it[1]}) - ch_versions = ch_versions.mix(FASTQC.out.versions.first()) - - // - // SUBWORKFLOW: Prepare genome annotation - // - PREPARE_GENOME( - ch_fasta, - ch_restriction_site - ) - ch_versions = ch_versions.mix(PREPARE_GENOME.out.versions) - - // - // SUB-WORFLOW: HiC-Pro - // - if (params.processing == 'hicpro'){ - HICPRO ( - ch_samplesheet, - PREPARE_GENOME.out.index, - PREPARE_GENOME.out.res_frag, - PREPARE_GENOME.out.chromosome_size, - ch_ligation_site, - ch_map_res - ) - ch_versions = ch_versions.mix(HICPRO.out.versions) - ch_pairs = HICPRO.out.pairs - ch_process_mqc = HICPRO.out.mqc - }else if (params.processing == 'pairtools'){ - PAIRTOOLS( - ch_samplesheet, - PREPARE_GENOME.out.index, - PREPARE_GENOME.out.res_frag, - PREPARE_GENOME.out.chromosome_size + take: + ch_samplesheet // channel: samplesheet read in from --input + + main: + + ch_versions = Channel.empty() + ch_multiqc_files = Channel.empty() + + // + // MODULE: Run FastQC + // + FASTQC ( + ch_samplesheet ) - ch_versions = ch_versions.mix(PAIRTOOLS.out.versions) - ch_pairs = PAIRTOOLS.out.pairs - ch_process_mqc = PAIRTOOLS.out.stats - } - - // - // SUB-WORKFLOW: COOLER - // - COOLER ( - ch_pairs, - PREPARE_GENOME.out.chromosome_size, - ch_map_res - ) - ch_versions = ch_versions.mix(COOLER.out.versions) - - // - // MODULE: HICEXPLORER/HIC_PLOT_DIST_VS_COUNTS - // - if (!params.skip_dist_decay){ - COOLER.out.cool - .combine(ch_ddecay_res) - .filter{ it[0].resolution == it[2] } - .map { it -> [it[0], it[1]]} - .set{ ch_distdecay } - - HIC_PLOT_DIST_VS_COUNTS( - ch_distdecay + ch_multiqc_files = ch_multiqc_files.mix(FASTQC.out.zip.collect{it[1]}) + ch_versions = ch_versions.mix(FASTQC.out.versions.first()) + + // + // SUBWORKFLOW: Prepare genome annotation + // + PREPARE_GENOME( + ch_fasta, + ch_restriction_site ) - ch_versions = ch_versions.mix(HIC_PLOT_DIST_VS_COUNTS.out.versions) - } - - // - // SUB-WORKFLOW: COMPARTMENT CALLING - // - if (!params.skip_compartments){ - COOLER.out.cool - .combine(ch_comp_res) - .filter{ it[0].resolution == it[2] } - .map { it -> [it[0], it[1], it[2]]} - .set{ ch_cool_compartments } - - COMPARTMENTS ( - ch_cool_compartments, - ch_fasta, - PREPARE_GENOME.out.chromosome_size + ch_versions = ch_versions.mix(PREPARE_GENOME.out.versions) + + // + // SUB-WORFLOW: HiC-Pro + // + if (params.processing == 'hicpro'){ + HICPRO ( + ch_samplesheet, + PREPARE_GENOME.out.index, + PREPARE_GENOME.out.res_frag, + PREPARE_GENOME.out.chromosome_size, + ch_ligation_site, + ch_map_res + ) + ch_versions = ch_versions.mix(HICPRO.out.versions) + ch_pairs = HICPRO.out.pairs + ch_process_mqc = HICPRO.out.mqc + }else if (params.processing == 'pairtools'){ + PAIRTOOLS( + ch_samplesheet, + PREPARE_GENOME.out.index, + PREPARE_GENOME.out.res_frag, + PREPARE_GENOME.out.chromosome_size + ) + ch_versions = ch_versions.mix(PAIRTOOLS.out.versions) + ch_pairs = PAIRTOOLS.out.pairs + ch_process_mqc = PAIRTOOLS.out.stats + } + + // + // SUB-WORKFLOW: COOLER + // + COOLER ( + ch_pairs, + PREPARE_GENOME.out.chromosome_size, + ch_map_res ) - ch_versions = ch_versions.mix(COMPARTMENTS.out.versions) - } - - // - // SUB-WORKFLOW : TADS CALLING - // - if (!params.skip_tads){ - COOLER.out.cool - .combine(ch_tads_res) - .filter{ it[0].resolution == it[2] } - .map { it -> [it[0], it[1]]} - .set{ ch_cool_tads } - - TADS( - ch_cool_tads + ch_versions = ch_versions.mix(COOLER.out.versions) + + // + // MODULE: HICEXPLORER/HIC_PLOT_DIST_VS_COUNTS + // + if (!params.skip_dist_decay){ + COOLER.out.cool + .combine(ch_ddecay_res) + .filter{ it[0].resolution == it[2] } + .map { it -> [it[0], it[1]]} + .set{ ch_distdecay } + + HIC_PLOT_DIST_VS_COUNTS( + ch_distdecay + ) + ch_versions = ch_versions.mix(HIC_PLOT_DIST_VS_COUNTS.out.versions) + } + + // + // SUB-WORKFLOW: COMPARTMENT CALLING + // + if (!params.skip_compartments){ + COOLER.out.cool + .combine(ch_comp_res) + .filter{ it[0].resolution == it[2] } + .map { it -> [it[0], it[1], it[2]]} + .set{ ch_cool_compartments } + + COMPARTMENTS ( + ch_cool_compartments, + ch_fasta, + PREPARE_GENOME.out.chromosome_size + ) + ch_versions = ch_versions.mix(COMPARTMENTS.out.versions) + } + + // + // SUB-WORKFLOW : TADS CALLING + // + if (!params.skip_tads){ + COOLER.out.cool + .combine(ch_tads_res) + .filter{ it[0].resolution == it[2] } + .map { it -> [it[0], it[1]]} + .set{ ch_cool_tads } + + TADS( + ch_cool_tads + ) + ch_versions = ch_versions.mix(TADS.out.versions) + } + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile(storeDir: "${params.outdir}/pipeline_info", name: 'nf_core_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_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_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) + 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: false)) + + ch_multiqc_files = ch_multiqc_files.mix(HICPRO.out.mqc) + + MULTIQC ( + ch_multiqc_files.collect(), + ch_multiqc_config.toList(), + ch_multiqc_custom_config.toList(), + ch_multiqc_logo.toList() ) - ch_versions = ch_versions.mix(TADS.out.versions) - } - - // - // Collate and save software versions - // - softwareVersionsToYAML(ch_versions) - .collectFile(storeDir: "${params.outdir}/pipeline_info", name: 'nf_core_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_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_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) - 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: false)) - - ch_multiqc_files = ch_multiqc_files.mix(HICPRO.out.mqc) - - 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) ] + + emit: + multiqc_report = MULTIQC.out.report.toList() // channel: /path/to/multiqc_report.html + versions = ch_versions // channel: [ path(versions.yml) ] } /*