diff --git a/modules/local/ascat/main.nf b/modules/local/ascat/main.nf index ef8050a..1d4b9f0 100644 --- a/modules/local/ascat/main.nf +++ b/modules/local/ascat/main.nf @@ -10,7 +10,7 @@ process ASCAT_SEG { input: tuple val(meta), path(hets) // channel: [mandatory] [ meta, hets ] tuple val(meta), path(cbs_cov) // channel: [mandatory] [ meta, cbs_cov ] - val(field) // channel: [mandatory] "foreground" for dryclean/ "ratio" + val(field) // channel: [mandatory] "foreground" for dryclean/ "ratio" val(hets_thresh) // channel: cutoff for hetpileups; default=0.2 val(penalty) // channel: penalty for ASCAT; default=70 val(gc) // channel: perform GC correction? Default=TRUE @@ -60,9 +60,9 @@ process ASCAT_SEG { ## find R installation and dryclean exec echo "USING LIBRARIES: \$(Rscript -e 'print(.libPaths())')" - + RSCRIPT_PATH=\$(if [[ ${workflow.containerEngine} == "singularity" && !task.ext.singularity_pull_docker_container ]]; then echo "./ascat_seg.R"; else echo "\${baseDir}/bin/ascat_seg.R"; fi) - + Rscript \$RSCRIPT_PATH \\ --id ${meta.id} \\ --variants ${hets} \\ @@ -102,4 +102,4 @@ process ASCAT_SEG { """ -} \ No newline at end of file +} diff --git a/modules/local/cbs/main.nf b/modules/local/cbs/main.nf index 56fc912..3a40496 100644 --- a/modules/local/cbs/main.nf +++ b/modules/local/cbs/main.nf @@ -15,9 +15,9 @@ process CBS { val name output: - path "*.cov.rds", emit: cbs_cov_rds - path "*seg.rds", emit: cbs_seg_rds - path "*nseg.rds", emit: cbs_nseg_rds + tuple val(meta), path "*.cov.rds", emit: cbs_cov_rds + tuple val(meta), path "*seg.rds", emit: cbs_seg_rds + tuple val(meta), path "*nseg.rds", emit: cbs_nseg_rds when: task.ext.when == null || task.ext.when diff --git a/modules/local/hetpileups/main.nf b/modules/local/hetpileups/main.nf index 10d0316..9bfffe1 100644 --- a/modules/local/hetpileups/main.nf +++ b/modules/local/hetpileups/main.nf @@ -15,7 +15,7 @@ process HETPILEUPS { output: path "versions.yml" , emit: versions - path "sites.txt" , emit: het_pileups_wgs + tuple val(meta), path("*sites.txt") , emit: het_pileups_wgs when: task.ext.when == null || task.ext.when diff --git a/modules/local/jabba/main.nf b/modules/local/jabba/main.nf index 14ef678..4e3fbc9 100644 --- a/modules/local/jabba/main.nf +++ b/modules/local/jabba/main.nf @@ -8,33 +8,43 @@ process JABBA { input: tuple val(meta), path(cov_rds) - tuple val(meta), path(junctionFilePath) - val(field) - path(junctionUnfiltered) + tuple val(meta), path(junction) + tuple val(meta), val(ploidy) + tuple val(meta), path(het_pileups_wgs) + tuple val(meta), path(j_supp) + path(blacklist_junctions) + val(geno) + val(indel) val(tfield) - path(cbs_nseg_rds) + val(iter) + val(rescue_window) + val(rescue_all) + val(nudgebalanced) + val(edgenudge) + val(strict) + val(allin) + val(field) path(cbs_seg_rds) - val(slack) - path(het_pileups_wgs) - val(purity) - val(ploidy) - val(tilim) - val(epgap) - val(pp_method) val(maxna) - val(flags) path(blacklist_coverage) - path(blacklist_junctions) - val(iter) - val(pair) - val(indel) + path(cbs_nseg_rds) + val(purity) + val(pp_method) val(cnsignif) + val(slack) + val(linear) + val(tilim) + val(epgap) + val(outdir) + val(name) + val(fix_thres) val(lp) val(ism) - val(treemem) - val(fix_thres) + val(filter_loose) val(gurobi) val(nonintegral) + val(verbose) + val(help) output: tuple val(meta), path("*.jabba.simple.rds") , emit: jabba_rds, optional: true @@ -53,12 +63,7 @@ process JABBA { def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def VERSION = '1.1' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. - - // TODO nf-core: Where possible, a command MUST be provided to obtain the version number of the software e.g. 1.10 - // If the software is unable to output a version number on the command-line then it can be manually specified - // e.g. https://github.com/nf-core/modules/blob/master/modules/nf-core/homer/annotatepeaks/main.nf - // Each software used MUST provide the software name and version number in the YAML version file (versions.yml) + def VERSION = '1.1' """ #!/bin/bash @@ -95,7 +100,46 @@ process JABBA { echo $jba set +x - export cmd="Rscript $jba \$@" + export cmd="Rscript $jba $cov_rds $junction \\ + --j.supp $j_supp \\ + --blacklist.junctions $blacklist_junctions \\ + --geno $geno \\ + --indel $indel \\ + --tfield $tfield \\ + --iterate $iter \\ + --rescue.window $rescue_window \\ + --rescue.all $rescue_all \\ + --nudgebalanced $nudgebalanced \\ + --edgenudge $edgenudge \\ + --strict $strict \\ + --allin $allin \\ + --field $field \\ + --seg $cbs_seg_rds \\ + --maxna $maxna \\ + --blacklist.coverage $blacklist_coverage \\ + --nseg $cbs_nseg_rds \\ + --hets $het_pileups_wgs \\ + --ploidy $ploidy \\ + --purity $purity \\ + --ppmethod $pp_method \\ + --cnsignif $cnsignif \\ + --slack $slack \\ + --linear $linear \\ + --tilim $tilim \\ + --epgap $epgap \\ + --outdir $outdir \\ + --name $name \\ + --cores $task.cpus \\ + --mem $task.mem \\ + --fix.thres $fix_thres \\ + --lp $lp \\ + --ism $ism \\ + --filter_loose $filter_loose \\ + --gurobi $gurobi \\ + --nonintegral $nonintegral \\ + --verbose $verbose \\ + --help $help \\ + " { echo "Running:" && echo "\$(echo $cmd)" && echo && eval $cmd; } cmdsig=\$? @@ -107,6 +151,11 @@ process JABBA { fi exit 0 + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + JaBbA: ${VERSION} + END_VERSIONS """ stub: diff --git a/nextflow.config b/nextflow.config index c565560..aa46185 100644 --- a/nextflow.config +++ b/nextflow.config @@ -92,32 +92,38 @@ params { name = "tumor" // JaBbA options - //field = "ratio" - //junctionUnfiltered = file("/dev/null") - //tfield = "tier" - //cbs_nseg_rds = file("/dev/null") - //cbs_seg_rds = file("/dev/null") - //slack = 100 - //het_pileups_wgs = file("/dev/null") - //purity = "NA" - //ploidy = "NA" - //tilim = 6000 - //epgap = 1e-8 - //pp_method = "ppgrid" - //maxna = 0.8 - //flags = "" - //blacklist_coverage = file("/dev/null") - //blacklist_junctions = file("/dev/null") - //iter = 0 - //pair = "tumor" - //indel = "exclude" - //cnsignif = 0.00001 - //lp = "TRUE" - //ism = "TRUE" - //treemem = 16 - //fix_thres = -1 - //gurobi = "FALSE" - //nonintegral = "FALSE" + blacklist_junctions = "/dev/null" + geno = "FALSE" + indel = "exclude" + tfield = "tier" + iter = 2 + rescue_window = 10000 + rescue_all = "TRUE" + nudgebalanced = "TRUE" + edgenudge = 0.1 + strict = "FALSE" + allin = "FALSE" + field = "foreground" + cbs_seg_rds = "/dev/null" + maxna = 0.9 + cbs_nseg_rds = "/dev/null" + het_pileups_wgs = "/dev/null" + ploidy = "NA" + purity = "NA" + pp_method = "ppgrid" + cnsignif = 0.00001 + slack = 100 + linear = "TRUE" + tilim = 7200 + epgap = 1e-8 + fix_thres = -1 + lp = "TRUE" + ism = "TRUE" + filter_loose = "FALSE" + gurobi = "FALSE" + nonintegral = "FALSE" + verbose = "TRUE" + help = "FALSE" // Variant Calling only_paired_variant_calling = false // if true, skips germline variant calling for normal-paired samples diff --git a/subworkflows/local/cov_ascat/main.nf b/subworkflows/local/cov_ascat/main.nf index cddfa02..3bba5c3 100644 --- a/subworkflows/local/cov_ascat/main.nf +++ b/subworkflows/local/cov_ascat/main.nf @@ -10,7 +10,7 @@ workflow COV_ASCAT { take: hetpileups // channel: [mandatory] [ meta, hets ] cbs_cov // channel: [mandatory] [ meta, cbs_cov ] - field // channel: [mandatory] "foreground" for dryclean/ "ratio" + field // channel: [mandatory] "foreground" for dryclean/ "ratio" hets_threshold // channel: cutoff for hetpileups; default=0.2 penalty // channel: penalty for ASCAT; default=70 gc_correct // channel: perform GC correction? Default=TRUE @@ -40,4 +40,4 @@ workflow COV_ASCAT { ploidy versions -} \ No newline at end of file +} diff --git a/subworkflows/local/jabba/main.nf b/subworkflows/local/jabba/main.nf new file mode 100644 index 0000000..ef88cf2 --- /dev/null +++ b/subworkflows/local/jabba/main.nf @@ -0,0 +1,91 @@ +// +// JaBbA +// + +include { JABBA } from '../../../modules/local/jabba/main.nf' + +workflow COV_JUNC_JABBA { + + take: + cov_rds_jabba // [ meta, cov] + junction_jabba // [ meta, junction] + ploidy_jabba // [ meta, ploidy ] + het_pileups_wgs_jabba // [ meta, hets ] + cbs_seg_rds_jabba // [ meta, seg_cbs ] + cbs_nseg_rds_jabba // [ meta, nseg_cbs ] + j_supp_jabba // [ meta, unfiltered_som_sv ] + blacklist_junctions_jabba + geno_jabba + indel_jabba + tfield_jabba + iter_jabba + rescue_window_jabba + rescue_all_jabba + nudgebalanced_jabba + edgenudge_jabba + strict_jabba + allin_jabba + field_jabba + maxna_jabba + blacklist_coverage_jabba + purity_jabba + pp_method_jabba + cnsignif_jabba + slack_jabba + linear_jabba + tilim_jabba + epgap_jabba + outdir_jabba + name_jabba + fix_thres_jabba + lp_jabba + ism_jabba + filter_loose_jabba + gurobi_jabba + nonintegral_jabba + verbose_jabba + help_jabba + + main: + versions = Channel.empty() + jabba_rds = Channel.empty() + jabba_gg = Channel.empty() + jabba_vcf = Channel.empty() + jabba_raw_rds = Channel.empty() + opti = Channel.empty() + jabba_seg = Channel.empty() + karyograph = Channel.empty() + + JABBA(cov_rds_jabba, junction_jabba, j_supp_jabba, + blacklist_junctions_jabba, geno_jabba, indel_jabba, tfield_jabba, + iter_jabba, rescue_window_jabba, rescue_all_jabba, nudgebalanced_jabba, + edgenudge_jabba, strict_jabba, allin_jabba, field_jabba, cbs_seg_rds_jabba, + maxna_jabba, blacklist_coverage_jabba, cbs_nseg_rds_jabba, + het_pileups_wgs_jabba, ploidy_jabba, purity_jabba, pp_method_jabba, + cnsignif_jabba, slack_jabba, linear_jabba, tilim_jabba, epgap_jabba, + outdir_jabba, name_jabba, fix_thres_jabba, lp_jabba, ism_jabba, + filter_loose_jabba, gurobi_jabba, nonintegral_jabba, verbose_jabba, + help_jabba) + + jabba_rds = JABBA.out.jabba_rds + jabba_gg = JABBA.out.jabba_gg + jabba_vcf = JABBA.out.jabba_vcf + jabba_raw_rds = JABBA.out.jabba_raw_rds + opti = JABBA.out.opti + jabba_seg = JABBA.out.jabba_seg + karyograph = JABBA.out.karyograph + + versions = JABBA.out.versions + + emit: + jabba_rds + jabba_gg + jabba_vcf + jabba_raw_rds + opti + jabba_seg + karyograph + + versions +} + diff --git a/workflows/heisenbio.nf b/workflows/heisenbio.nf index b6f5955..8d457db 100644 --- a/workflows/heisenbio.nf +++ b/workflows/heisenbio.nf @@ -50,6 +50,7 @@ def checkPathParamList = [ params.pon_tbi, params.gcmapdir_frag, params.pon_dryclean + params.blacklist_coverage ] // only check if we are using the tools if (params.tools && params.tools.contains("snpeff")) checkPathParamList.add(params.snpeff_cache) @@ -172,7 +173,7 @@ input_sample = ch_from_samplesheet } // hetpileups } else if (cov && hets) { - meta = meta + [id: meta.sample, data_type: 'cov'] + meta = meta + [id: meta.sample, data_type: ['cov', 'hets']] if (params.step == 'ascat') return [ meta - meta.subMap('lane'), cov, hets ] else { @@ -180,9 +181,9 @@ input_sample = ch_from_samplesheet } // jabba } else if (cov && vcf) { - meta = meta + [id: meta.sample, data_type: 'cov'] + meta = meta + [id: meta.sample, data_type: ['vcf', 'cov']] - if (params.step == 'jabba') return [ meta - meta.subMap('lane'), cov, vcf ] + if (params.step == 'jabba') return [ meta - meta.subMap('lane'), vcf, cov] else { error("Samplesheet contains cov .rds and vcf files but step is `$params.step`. Please check your samplesheet or adjust the step parameter.") } @@ -194,15 +195,7 @@ input_sample = ch_from_samplesheet else { error("Samplesheet contains cov .rds files but step is `$params.step`. Please check your samplesheet or adjust the step parameter.") } - // annotation - } else if (vcf) { - meta = meta + [id: meta.sample, data_type: 'vcf', variantcaller: variantcaller ?: ''] - - if (params.step == 'annotate') return [ meta - meta.subMap('lane'), vcf ] - else { - error("Samplesheet contains vcf files but step is `$params.step`. Please check your samplesheet or adjust the step parameter.") - } - } else { + } else { error("Missing or unknown field in csv file header. Please check your samplesheet") } } @@ -286,6 +279,10 @@ pon_dryclean = params.pon_dryclean ? Channel.fromPath(params.pon_drycl blacklist_path_dryclean = params.blacklist_path_dryclean ? Channel.fromPath(params.blacklist_path_dryclean).collect() : Channel.empty() // This is the path to the blacklist for Dryclean (optional). germline_file_dryclean = params.germline_file_dryclean ? Channel.fromPath(params.germline_file_dryclean).collect() : Channel.empty() // This is the path to the germline mask for dryclean (optional). +// JaBbA +blacklist_junctions_jabba = params.blacklist_junctions_jabba ? Channel.fromPath(params.blacklist_junctions_jabba).collect() : Channel.empty() +blacklist_coverage_jabba = params.blacklist_coverage_jabba ? Channel.fromPath(params.blacklist_coverage_jabba).collect() : Channel.empty() + // Initialize value channels based on params, defined in the params.genomes[params.genome] scope ascat_genome = params.ascat_genome ?: Channel.empty() dbsnp_vqsr = params.dbsnp_vqsr ? Channel.value(params.dbsnp_vqsr) : Channel.empty() @@ -332,6 +329,37 @@ cnsignif = params.cnsignif_cbs ?: Channel.empty field = params.field_cbs ?: Channel.empty() name = params.name_cbs ?: Channel.empty() +// JaBbA +geno_jabba = params.geno_jabba ?: Channel.empty() +indel_jabba = params.indel_jabba ?: Channel.empty() +tfield_jabba = params.tfield_jabba ?: Channel.empty() +iter_jabba = params.iter_jabba ?: Channel.empty() +rescue_window_jabba = params.rescue_window_jabba ?: Channel.empty() +rescue_all_jabba = params.rescue_all_jabba ?: Channel.empty() +nudgebalanced_jabba = params.nudgebalanced_jabba ?: Channel.empty() +edgenudge_jabba = params.edgenudge_jabba ?: Channel.empty() +strict_jabba = params.strict_jabba ?: Channel.empty() +allin_jabba = params.allin_jabba ?: Channel.empty() +field_jabba = params.field_jabba ?: Channel.empty() +maxna_jabba = params.maxna_jabba ?: Channel.empty() +purity_jabba = params.purity_jabba ?: Channel.empty() +pp_method_jabba = params.pp_method_jabba ?: Channel.empty() +cnsignif_jabba = params.cnsignif_jabba ?: Channel.empty() +slack_jabba = params.slack_jabba ?: Channel.empty() +linear_jabba = params.linear_jabba ?: Channel.empty() +tilim_jabba = params.tilim_jabba ?: Channel.empty() +epgap_jabba = params.epgap_jabba ?: Channel.empty() +outdir_jabba = params.outdir_jabba ?: Channel.empty() +name_jabba = params.name_jabba ?: Channel.empty() +fix_thres_jabba = params.fix_thres_jabba ?: Channel.empty() +lp_jabba = params.lp_jabba ?: Channel.empty() +ism_jabba = params.ism_jabba ?: Channel.empty() +filter_loose_jabba = params.filter_loose_jabba ?: Channel.empty() +gurobi_jabba = params.gurobi_jabba ?: Channel.empty() +nonintegral_jabba = params.nonintegral_jabba ?: Channel.empty() +verbose_jabba = params.verbose_jabba ?: Channel.empty() +help_jabba = params.help_jabba ?: Channel.empty() + // Initialize files channels based on params, not defined within the params.genomes[params.genome] scope if (params.snpeff_cache && params.tools && params.tools.contains("snpeff")) { def snpeff_annotation_cache_key = params.use_annotation_cache_keys ? "${params.snpeff_genome}.${params.snpeff_db}/" : "" @@ -447,6 +475,7 @@ include { COV_ASCAT } from '../subworkflows/lo include { COV_CBS as CBS } from '../subworkflows/local/cbs/main' +include { COV_VCF_JABBA as JABBA } from '../subworkflows/local/jabba/main' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RUN MAIN WORKFLOW @@ -954,7 +983,8 @@ workflow HEISENBIO { vcf_from_sv_calling = Channel.empty() vcf_from_sv_calling = vcf_from_sv_calling.mix(BAM_SVCALLING_SVABA.out.all_output) //This one contains multiple files of vcf, to get individual files, call individual output - + unfiltered_som_sv = Channel.empty() + unfiltered_som_sv = unfiltered_som_sv.mix(BAM_SV_CALLING.out.unfiltered_som_sv) } if (params.tools && params.tools.split(',').contains('gridss')) { @@ -1143,17 +1173,38 @@ workflow HEISENBIO { } if (params.tools && params.tools.split(',').contains('ascat')) { - // TODO: Need to check if the input channel names for hetpileups and CBS match here COV_ASCAT(input_hetpileups, input_dryclean_ascat, field_ascat, hets_thresh_ascat, penalty_ascat, gc_correct_ascat, rebin_width_ascat, from_maf_ascat) versions = versions.mix(COV_ASCAT.out.versions) purityploidy = Channel.empty().mix(COV_ASCAT.out.pp) + purity = Channel.empty().mix(COV_ASCAT.out.purity) + ploidy = Channel.empty().mix(COV_ASCAT.out.ploidy) } // TODO: Add a subworkflow to write the output file paths into a csv } - + if (params.step in ['alignment', 'markduplicates', 'prepare_recalibration', 'recalibrate', 'sv_calling', 'fragcounter', 'hetpileups', 'dryclean', 'jabba']) { + ploidy_jabba = ploidy ? ploidy : ploidy_jabba + ploidy_jabba = [ jabba_meta, ploidy_jabba ] + + JABBA(dryclean_cov, vcf_from_sv_calling, unfiltered_som_sv, ploidy_jabba, + sites_from_het_pileups_wgs, cbs_seg_rds, cbs_nseg_rds, field_jabba, + tfield_jabba, slack_jabba, purity_jabba, tilim_jabba, epgap_jabba, + pp_method_jabba, maxna_jabba, blacklist_coverage_jabba, + blacklist_junctions_jabba, iter_jabba, indel_jabba, cnsignif_jabba, + lp_jabba, ism_jabba, fix_thres_jabba, filter_loose_jabba, gurobi_jabba) + + jabba_rds = Channel.empty().mix(JABBA.out.jabba_rds) + jabba_gg = Channel.empty().mix(JABBA.out.jabba_gg) + jabba_vcf = Channel.empty().mix(JABBA.out.jabba_vcf) + jabba_raw_rds = Channel.empty().mix(JABBA.out.jabba_raw_rds) + opti = Channel.empty().mix(JABBA.out.opti) + jabba_seg = Channel.empty().mix(JABBA.out.jabba_seg) + karyograph = Channel.empty().mix(JABBA.out.karyograph) + versions = versions.mix(JABBA.out.versions) + } + } }