/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Config file for defining DSL2 per module options and publishing paths
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Available keys to override module options:
        ext.args   = Additional arguments appended to command in module.
        ext.args2  = Second set of arguments appended to command in module (multi-tool modules).
        ext.args3  = Third set of arguments appended to command in module (multi-tool modules).
        ext.prefix = File name prefix for output files.
        ext.when   = When to run the module.
----------------------------------------------------------------------------------------
*/

process {

    publishDir           = [
        mode: params.publish_dir_mode,
        path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
    ]

    withName: CUSTOM_DUMPSOFTWAREVERSIONS {
        cache = false
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/pipeline_info" },
            pattern: '*_versions.yml'
        ]
    }

// PREPARE_GENOME

    withName: 'BWAMEM1_INDEX' {
        ext.when         = { !params.bwa && params.step == "mapping" && params.aligner == "bwa-mem" }
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference" },
            pattern: "bwa"
        ]
    }

    withName: 'BWAMEM2_INDEX' {
        ext.when         = { !params.bwa && params.step == "mapping" && params.aligner == "bwa-mem2" }
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference" },
            pattern: "bwamem2"
        ]
    }

    withName: 'DRAGMAP_HASHTABLE' {
        ext.when         = { !params.bwa && params.step == "mapping" && params.aligner == "dragmap" }
        publishDir = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference" },
            pattern: "dragmap"
        ]
    }

    withName: 'GATK4_CREATESEQUENCEDICTIONARY' {
        ext.when         = { !params.dict && params.step != "annotate" && params.step != "controlfreec" }
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference/dict" },
            pattern: "*dict"
        ]
    }

    withName: 'MSISENSORPRO_SCAN' {
        ext.when         = { params.tools && params.tools.split(',').contains('msisensorpro') }
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference/msi" },
            pattern: "*list"
        ]
    }

    withName: 'SAMTOOLS_FAIDX' {
        ext.when         = { !params.fasta_fai && params.step != "annotate" }
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference/fai" },
            pattern: "*fai"
        ]
    }

    withName: 'TABIX_DBSNP' {
        ext.when         = { !params.dbsnp_tbi && params.dbsnp && (params.step == "mapping" || params.step == "markduplicates" || params.step == "prepare_recalibration") || params.tools && (params.tools.split(',').contains('controlfreec') || params.tools.split(',').contains('haplotypecaller') || params.tools.split(',').contains('mutect2')) }
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference/dbsnp" },
            pattern: "*vcf.gz.tbi"
        ]
    }

    withName: 'TABIX_GERMLINE_RESOURCE' {
        ext.when         = { !params.germline_resource_tbi && params.germline_resource && params.tools && params.tools.split(',').contains('mutect2') }
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference/germline_resource" },
            pattern: "*vcf.gz.tbi"
        ]
    }

    withName: 'TABIX_KNOWN_INDELS' {
        ext.when         = { !params.known_indels_tbi && params.known_indels && (params.step == 'mapping' || params.step == "markduplicates" || params.step == 'prepare_recalibration' || (params.tools && params.tools.split(',').contains('haplotypecaller')) ) }
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference/known_indels" },
            pattern: "*vcf.gz.tbi"
        ]
    }

    withName: 'TABIX_PON' {
        ext.when         = { !params.pon_tbi && params.pon && params.tools && params.tools.split(',').contains('mutect2') }
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference/pon" },
            pattern: "*vcf.gz.tbi"
        ]
    }

    withName: 'UNZIP_ALLELES|UNZIP_LOCI|UNZIP_GC|UNZIP_RT'{
        ext.when         = { params.tools && params.tools.split(',').contains('ascat')}
    }

    withName: 'UNTAR_CHR_DIR'{
        ext.when         = { params.tools && params.tools.split(',').contains('controlfreec')}
    }

    withName: 'CNVKIT_ANTITARGET' {
        ext.when         = { params.tools && params.tools.split(',').contains('cnvkit') }
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference/cnvkit" },
            pattern: "*{bed}"
        ]
    }

    withName: 'CNVKIT_REFERENCE' {
        ext.prefix       = "cnvkit"
        ext.when         = { params.tools && params.tools.split(',').contains('cnvkit') }
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference/cnvkit" },
            pattern: "*{cnn}"
        ]
    }


// PREPARE INTERVALS

    withName: 'CREATE_INTERVALS_BED' {
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference/intervals" },
            pattern: "*bed"
        ]
    }

    withName: 'GATK4_INTERVALLISTTOBED' {
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference/intervals" },
            pattern: "*bed"
        ]
    }

    withName: 'TABIX_BGZIPTABIX_INTERVAL_SPLIT' {
        ext.prefix       = {"${meta.id}"}
        publishDir       = [
            enabled: params.save_reference,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reference/intervals" },
            pattern: "*bed.gz"
        ]
    }

// BAM TO FASTQ

    withName: 'COLLATE_FASTQ_MAP'{
        ext.args2        = '-N'
        ext.prefix       = {"${meta.id}.mapped"}
    }

    withName: 'COLLATE_FASTQ_UNMAP'{
        ext.args2        = '-N'
        ext.prefix       = {"${meta.id}.unmapped"}
    }

    withName: 'SAMTOOLS_VIEW_MAP_MAP' {
        ext.args         = '-b -f1 -F12'
        ext.prefix       = {"${meta.id}.map_map"}
    }

    withName: 'SAMTOOLS_VIEW_MAP_UNMAP' {
        ext.args         = '-b -f8 -F260'
        ext.prefix       = {"${meta.id}.map_unmap"}
    }

    withName: 'SAMTOOLS_VIEW_UNMAP_MAP' {
        ext.args         = '-b -f4 -F264'
        ext.prefix       = {"${meta.id}.unmap_map"}
    }

    withName: 'SAMTOOLS_VIEW_UNMAP_UNMAP' {
        ext.args         = '-b -f12 -F256'
        ext.prefix       = {"${meta.id}.unmap_unmap"}
    }

// TRIMMING

    withName: FASTP {
        ext.args = [ "",
            params.trim_fastq              ?: "--disable_adapter_trimming",
            params.clip_r1 > 0             ? "--trim_front1 ${params.clip_r1}" : "", // Remove bp from the 5' end of read 1.
            params.three_prime_clip_r1 > 0 ? "--trim_tail1 ${params.three_prime_clip_r1}" : "", // Remove bp from the 3' end of read 1 AFTER adapter/quality trimming has been performed.
            params.clip_r2   > 0           ? "--trim_front2 ${params.clip_r2}" : "", //Remove bp from the 5' end of read 2.
            params.three_prime_clip_r2 > 0 ? "--trim_tail2 ${params.three_prime_clip_r2}" : "", // Remove bp from the 3' end of read 2 AFTER adapter/quality trimming has been performed.
            params.trim_nextseq            ? "--trim_poly_g" : "", // Apply the --nextseq=X option, to trim based on quality after removing poly-G tails.
            params.split_fastq > 0         ? "--split_by_lines ${params.split_fastq * 4}" : "",

        ].join(" ").trim()
        publishDir = [
            [
                path: { "${params.outdir}/reports/fastp/${meta.sample}" },
                mode: params.publish_dir_mode,
                pattern: "*.{html,json,log}"
            ],
            [
                enabled: params.save_trimmed || params.save_split_fastqs,
                path: { "${params.outdir}/preprocessing/fastp/${meta.sample}/" },
                mode: params.publish_dir_mode,
                pattern: "*.fastp.fastq.gz"
            ]
        ]
    }

// UMI Subworkflow

    withName: 'BAM2FASTQ' {
        ext.args         = '-T RX'
        ext.when         = { params.umi_read_structure }
    }

    withName: 'CALLUMICONSENSUS' {
        ext.args         = '-M 1 -S Coordinate'
        ext.prefix       = {"${meta.id}_umi-consensus"}
    }

    if (params.umi_read_structure) {
        withName: "NFCORE_SAREK:SAREK:CREATE_UMI_CONSENSUS:MAPPING_UMI:BWAMEM.*_MEM" {
            ext.args         = { "-K 100000000 -p -C -Y -R ${meta.read_group}" }
            ext.args2        = '-bS'
            ext.prefix       = {"${meta.id}.umi_unsorted"}
        }

        withName: ".*DRAGMAP_ALIGN" {
            ext.args2        = '-bS'
            ext.prefix       = {"${meta.id}.umi_unsorted"}
        }
    }

    withName: 'SAMBLASTER' {
        ext.args         = '-M --addMateTags'
        ext.prefix       = {"${meta.id}_unsorted_tagged"}
    }

// MAPPING
    if (params.step == 'mapping') {
        withName: ".*BWAMEM1_MEM" {
            ext.when         = { params.aligner == "bwa-mem" }
        }
        withName: ".*BWAMEM2_MEM" {
            ext.when         = { params.aligner == "bwa-mem2" }
        }

        withName: ".*DRAGMAP_ALIGN" {
            ext.when         = { params.aligner == "dragmap" }
            ext.args         = { "--RGSM ${meta.read_group}" }
        }

        withName: "NFCORE_SAREK:SAREK:GATK4_MAPPING:(BWAMEM.*_MEM|DRAGMAP_ALIGN)" {
            // Markduplicates Spark NEEDS name-sorted reads or runtime goes through the roof
            // However if it's skipped, reads need to be coordinate-sorted
            // Only name sort if Spark for Markduplicates + duplicate marking is not skipped
            ext.args2        = { params.use_gatk_spark && params.use_gatk_spark.contains('markduplicates') && (!params.skip_tools || (params.skip_tools && !params.skip_tools.split(',').contains('markduplicates'))) ? '-n' : '' }
            ext.prefix       = { params.split_fastq > 1 ? "${meta.id}".concat('.').concat(reads.get(0).name.tokenize('.')[0]) : "" }
            publishDir       = [
                mode: params.publish_dir_mode,
                path: { "${params.outdir}/preprocessing/" },
                pattern: "*bam",
                saveAs: { (params.save_bam_mapped || (params.skip_tools && params.skip_tools.split(',').contains('markduplicates'))) && (meta.size * meta.numLanes == 1) ? "mapped/${meta.id}/${it}" : null }
            ]
        }

        withName: "NFCORE_SAREK:SAREK:GATK4_MAPPING:BWAMEM.*_MEM" {
            // Using -B 3 for tumor samples
            ext.args         = { meta.status == 1 ? "-K 100000000 -Y -B 3 -R ${meta.read_group}" : "-K 100000000 -Y -R ${meta.read_group}" }
        }
    }

    withName: 'MERGE_BAM|INDEX_MERGE_BAM' {
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/preprocessing/mapped/${meta.id}/" },
            pattern: "*{bam,bai}"
        ]
    }

// MARKDUPLICATES

    withName: 'SAMTOOLS_CRAMTOBAM.*'{
        ext.args         = "-b"
    }


    withName: 'SAMTOOLS_STATS_CRAM'{
        ext.prefix       = { (params.skip_tools && params.skip_tools.split(',').contains('markduplicates')) ? "${meta.id}.sorted.cram" : "${meta.id}.md.cram" }
    }

    withName: 'SAMTOOLS_BAMTOCRAM.*' {
        // BAM provided for step Markduplicates either run through MD or Convert -> then saved as md.cram
        // BAM files provided for step prepare_recal are converted and run through BQSR -> then saved as md.cram
        // BAM files provided for step recal are converted and run through BQSR II -> then saved as md.cram
        ext.args         = "-C"
        ext.prefix       = { (params.skip_tools && params.skip_tools.split(',').contains('markduplicates')) ? "${meta.id}.sorted" : "${meta.id}.md" }
        publishDir       = [
            enabled: !params.save_output_as_bam,
            mode: params.publish_dir_mode,
            path: { (params.skip_tools && params.skip_tools.split(',').contains('markduplicates')) ? "${params.outdir}/preprocessing/mapped/${meta.id}/" : "${params.outdir}/preprocessing/markduplicates/${meta.id}/" },
            pattern: "*{cram,crai}"
        ]
    }

    withName: 'GATK4_ESTIMATELIBRARYCOMPLEXITY' {
        ext.prefix       = { "${meta.id}.md" }
        ext.when         = { !(params.skip_tools && params.skip_tools.split(',').contains('markduplicates_report')) }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reports/markduplicates/${meta.id}" },
            pattern: "*metrics"
        ]
    }

    withName: 'GATK4_MARKDUPLICATES' {
        ext.args         = '-REMOVE_DUPLICATES false -VALIDATION_STRINGENCY LENIENT --CREATE_INDEX true'
        ext.prefix       = { "${meta.id}.md" }
        ext.when         = { !(params.skip_tools && params.skip_tools.split(',').contains('markduplicates')) }
        publishDir       = [
            [
                enabled: params.save_output_as_bam,
                mode: params.publish_dir_mode,
                path: { "${params.outdir}/preprocessing/markduplicates/${meta.id}/" },
                pattern: "*{bam,bai}"
            ],
            [
                mode: params.publish_dir_mode,
                path: { "${params.outdir}/reports/" },
                pattern: "*metrics",
                saveAs: { !(params.skip_tools && params.skip_tools.split(',').contains('markduplicates_report')) ? "markduplicates/${meta.id}/${it}" : null}
            ]
        ]
    }

    withName: 'GATK4_MARKDUPLICATES_SPARK' {
        ext.args         = '--remove-sequencing-duplicates false -VS LENIENT'
        ext.prefix       = { "${meta.id}.md.cram" }
        publishDir       = [
            enabled: !params.save_output_as_bam,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/preprocessing/markduplicates/${meta.id}/" },
            pattern: "*{cram,crai}"
        ]
    }

    withName: 'INDEX_MARKDUPLICATES' {
        publishDir       = [
            enabled: !params.save_output_as_bam,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/preprocessing/markduplicates/${meta.id}/" },
            pattern: "*{cram,crai}"
        ]
    }

    if (params.use_gatk_spark && params.use_gatk_spark.split(',').contains('markduplicates')) {
        withName: 'NFCORE_SAREK:SAREK:MARKDUPLICATES_SPARK:SAMTOOLS_CRAMTOBAM'{
            ext.prefix       = { "${meta.id}.md" }
            ext.when         = { params.save_output_as_bam}
            publishDir       = [
                enabled: params.save_output_as_bam,
                mode: params.publish_dir_mode,
                path: { "${params.outdir}/preprocessing/markduplicates/${meta.id}/" },
                pattern: "*{md.bam,md.bam.bai}"
            ]
        }
    }

// PREPARE_RECALIBRATION

    withName: 'BASERECALIBRATOR|BASERECALIBRATOR_SPARK' {
        ext.prefix       = { meta.num_intervals <= 1 ? "${meta.id}.recal" : "${meta.id}_${intervals.simpleName}.recal" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/preprocessing/" },
            pattern: "*table",
            saveAs: { meta.num_intervals > 1 ? null : "recal_table/${meta.id}/${it}" }
        ]
    }

    withName: 'GATHERBQSRREPORTS' {
        ext.prefix       = {"${meta.id}.recal"}
        ext.when         = { meta.num_intervals > 1 }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/preprocessing/recal_table/${meta.id}/" },
            pattern: "*table",
        ]
    }

// RECALIBRATE

    withName: 'APPLYBQSR|APPLYBQSR_SPARK' {
        ext.prefix       = { meta.num_intervals <= 1 ? "${meta.id}.recal" : "${meta.id}_${intervals.simpleName}.recal" }
        publishDir       = [
            enabled: !params.save_output_as_bam,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/preprocessing/" },
            pattern: "*cram",
            saveAs: { meta.num_intervals > 1 ? null : "recalibrated/${meta.id}/${it}" }
        ]
    }


    if ((params.step == 'mapping' || params.step == 'markduplicates'|| params.step == 'prepare_recalibration'|| params.step == 'recalibrate') && (!(params.skip_tools && params.skip_tools.split(',').contains('baserecalibrator')))) {
        withName: 'NFCORE_SAREK:SAREK:(RECALIBRATE|RECALIBRATE_SPARK):MERGE_INDEX_CRAM:MERGE_CRAM' {
            ext.prefix       = { "${meta.id}.recal" }
            ext.when         = { meta.num_intervals > 1 }
            publishDir       = [
                enabled: !params.save_output_as_bam,
                mode: params.publish_dir_mode,
                path: { "${params.outdir}/preprocessing/recalibrated/${meta.id}/" },
                pattern: "*cram"
            ]
        }

        withName: 'NFCORE_SAREK:SAREK:(RECALIBRATE|RECALIBRATE_SPARK):MERGE_INDEX_CRAM:INDEX_CRAM' {
            publishDir       = [
                enabled: !params.save_output_as_bam,
                mode: params.publish_dir_mode,
                path: { "${params.outdir}/preprocessing/recalibrated/${meta.id}/" },
                pattern: "*{recal.cram,recal.cram.crai}"
            ]
        }
    }

    withName: 'SAMTOOLS_CRAMTOBAM_RECAL'{
        ext.prefix       = { "${meta.id}.recal" }
        ext.when         = { params.save_output_as_bam}
        publishDir       = [
            enabled: params.save_output_as_bam,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/preprocessing/recalibrated/${meta.id}/" },
            pattern: "*{recal.bam,recal.bam.bai}"
        ]
    }

    withName: 'SAMTOOLS_BAMTOCRAM_VARIANTCALLING' {
        ext.prefix       = { "${meta.id}.recal" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/preprocessing/recalibrated/${meta.id}/" },
            pattern: "*{cram,crai}"
        ]
    }

// QC

    withName: 'FASTQC' {
        errorStrategy    = {task.exitStatus == 143 ? 'retry' : 'ignore'}
        ext.args         = '--quiet'
        ext.when         = { !(params.skip_tools && params.skip_tools.split(',').contains('fastqc')) }
        publishDir       = [
            [
                path: { "${params.outdir}/reports/fastqc/${meta.id}" },
                mode: params.publish_dir_mode,
                pattern: "*{html,zip}"
            ]
        ]
    }

    if (params.step == 'mapping' || params.step == 'markduplicates') {
        withName: 'NFCORE_SAREK:SAREK:CRAM_QC:SAMTOOLS_STATS' {
            ext.prefix       = { "${meta.id}.cram" }
        }
    }

    withName: 'SAMTOOLS_STATS' {
        ext.when         = { !(params.skip_tools && params.skip_tools.split(',').contains('samtools')) }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reports/samtools/${meta.id}" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'MOSDEPTH' {
        ext.args = { !params.wes ? "-n --fast-mode --by 500" : ""}
        ext.prefix       = { params.skip_tools && params.skip_tools.split(',').contains('markduplicates') ? "${meta.id}.sorted" : "${meta.id}.md" }
        ext.when         = { !(params.skip_tools && params.skip_tools.split(',').contains('mosdepth')) }
        publishDir = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reports/mosdepth/${meta.id}" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
        ]
    }

    if ((params.step == 'mapping' || params.step == 'markduplicates'|| params.step == 'prepare_recalibration'|| params.step == 'recalibrate') && (!(params.skip_tools && params.skip_tools.split(',').contains('baserecalibrator')))) {
        withName: 'NFCORE_SAREK:SAREK:CRAM_QC:MOSDEPTH' {
            ext.prefix       = { "${meta.id}.recal" }
        }

        withName: 'NFCORE_SAREK:SAREK:CRAM_QC:SAMTOOLS_STATS' {
            ext.prefix       = { "${meta.id}.recal.cram" }
            ext.when         = { !(params.skip_tools && params.skip_tools.split(',').contains('samtools')) }
            publishDir       = [
                mode: params.publish_dir_mode,
                path: { "${params.outdir}/reports/samtools/${meta.id}" },
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        }
    }
}

// VARIANT CALLING
process{

    // CNVKIT
    withName: 'CNVKIT_BATCH' {
        ext.args         = { params.wes ? "--method hybrid --diagram --scatter" : "--method wgs --diagram --scatter" }
        ext.when         = { params.tools && params.tools.split(',').contains('cnvkit') }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/cnvkit/${meta.id}/" },
            pattern: "*{bed,cnn,cnr,cns,pdf,png}"
        ]
    }

    // DEEPVARIANT
    withName: 'MERGE_DEEPVARIANT_.*' {
        ext.prefix       = {"${meta.id}.deepvariant"}
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/deepvariant/${meta.id}/" },
            pattern: "*{vcf.gz,vcf.gz.tbi}"
        ]
    }
    withName: 'MERGE_DEEPVARIANT_GVCF' {
        ext.prefix       = {"${meta.id}.deepvariant.g"}
    }
    withName: 'DEEPVARIANT' {
        ext.prefix       = { meta.num_intervals <= 1 ? "${meta.id}.deepvariant" : "${meta.id}.deepvariant.${intervals.simpleName}" }
        ext.args         = { params.wes ?  "--model_type WES" : "--model_type WGS" }
        ext.when         = { params.tools && params.tools.split(',').contains('deepvariant') }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/" },
            pattern: "*vcf.gz",
            saveAs: { meta.num_intervals > 1 ? null : "deepvariant/${meta.id}/${it}" }
        ]
    }
    withName : 'TABIX_VC_DEEPVARIANT_.*' {
        ext.prefix       = {"${meta.id}.deepvariant"}
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/deepvariant/${meta.id}/" },
            pattern: "*tbi"
        ]
    }

    // FREEBAYES
    withName: 'MERGE_FREEBAYES' {
        ext.prefix       = { "${meta.id}.freebayes" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/freebayes/${meta.id}/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'FREEBAYES' {
        //To make sure no naming conflicts ensure with module BCFTOOLS_SORT & the naming being correct in the output folder
        ext.prefix       = { meta.num_intervals <= 1 ? "${meta.id}" : "${meta.id}.${target_bed.simpleName}" }
        ext.args         = '--min-alternate-fraction 0.1 --min-mapping-quality 1'
        ext.when         = { params.tools && params.tools.split(',').contains('freebayes') }
    }

    withName: 'BCFTOOLS_SORT' {
        ext.prefix       = { meta.num_intervals <= 1 ? "${meta.id}.freebayes" : "${vcf.minus("vcf")}.sort" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/" },
            pattern: "*vcf.gz",
            saveAs: { meta.num_intervals > 1 ? null : "freebayes/${meta.id}/${it}" }
        ]
    }

    withName : 'TABIX_VC_FREEBAYES' {
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/freebayes/${meta.id}/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    // HAPLOTYPECALLER
    withName: 'MERGE_HAPLOTYPECALLER.*' {
        ext.prefix       = { params.joint_germline ? "${meta.id}.haplotypecaller.g" : "${meta.id}.haplotypecaller" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/haplotypecaller/${meta.id}/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'HAPLOTYPECALLER' {
        ext.args         = { params.joint_germline ? "-ERC GVCF" : "" }
        ext.prefix       = { meta.num_intervals <= 1 ? ( params.joint_germline ? "${meta.id}.haplotypecaller.g" : "${meta.id}.haplotypecaller" ) : ( params.joint_germline ? "${meta.id}.haplotypecaller.${intervals.simpleName}.g" :"${meta.id}.haplotypecaller.${intervals.simpleName}" ) }
        ext.when         = { params.tools && params.tools.split(',').contains('haplotypecaller') }
        publishDir       = [
            enabled: !params.joint_germline,
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/"},
            pattern: "*{vcf.gz,vcf.gz.tbi}",
            saveAs: { meta.num_intervals > 1 ? null : "haplotypecaller/${meta.id}/${it}" }
        ]
    }

    withName: 'FILTERVARIANTTRANCHES' {
        ext.prefix       = {"${meta.id}.haplotypecaller"}
        ext.args         = { "--info-key CNN_1D" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/haplotypecaller/${meta.id}/"},
            pattern: "*{vcf.gz,vcf.gz.tbi}"
        ]
    }

    withName: 'GATK4_GENOMICSDBIMPORT' {
        ext.prefix       = { meta.num_intervals > 1 ? meta.intervals_name : "joint_interval" }
        ext.when         = { params.tools && params.tools.split(',').contains('haplotypecaller') && params.joint_germline && !params.no_intervals}
    }

    withName: 'GATK4_GENOTYPEGVCFS' {
        ext.prefix       = { meta.num_intervals > 1 ? meta.intervals_name : "joint_germline" }
    }

    withName: 'MERGE_GENOTYPEGVCFS' {
        ext.prefix       = "joint_germline"
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/haplotypecaller/joint_variant_calling/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            pattern: "*{vcf.gz,vcf.gz.tbi}"
        ]
    }

    withName: 'VARIANTRECALIBRATOR_INDEL' {
        ext.prefix = { "${meta.id}_INDEL" }
        ext.args = "-an QD -an MQRankSum -an ReadPosRankSum -an FS -an SOR -an DP  -mode INDEL"
        publishDir = [
            enabled: false
        ]
    }

    withName: 'VARIANTRECALIBRATOR_SNP' {
        ext.prefix = { "${meta.id}_SNP" }
        ext.args = "-an QD -an MQ -an MQRankSum -an ReadPosRankSum -an FS -an SOR -mode SNP"
        publishDir = [
            enabled: false
        ]
    }

    withName: 'GATK4_APPLYVQSR_SNP'{
        ext.prefix = { "${meta.id}_SNP" }
        ext.args = '--truth-sensitivity-filter-level 99.9 -mode SNP'
    }

    withName: 'GATK4_APPLYVQSR_INDEL'{
        ext.prefix    = { "${meta.id}_INDEL" }
        ext.args      = '--truth-sensitivity-filter-level 99.9 -mode INDEL'
    }

    withName: 'MERGE_VQSR' {
        ext.prefix       = "joint_germline_recalibrated"
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/haplotypecaller/joint_variant_calling/"},
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            pattern: "*{vcf.gz,vcf.gz.tbi}"
        ]
    }

    // MANTA
    withName: 'MERGE_MANTA.*' {
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/manta/${meta.id}/" },
            pattern: "*{diploid_sv,tumor_sv,somatic_sv}.{vcf.gz,vcf.gz.tbi}"
        ]
    }
    withName: 'MERGE_MANTA_DIPLOID' {
        ext.prefix       = {"${meta.id}.manta.diploid_sv"}
    }
    withName: 'MERGE_MANTA_SMALL_INDELS' {
        ext.prefix       = {"${meta.id}.manta.candidate_small_indels"}
    }
    withName: 'MERGE_MANTA_SV' {
        ext.prefix       = {"${meta.id}.manta.candidate_sv"}
    }
    withName: 'MANTA.*' {
        ext.prefix       = { meta.num_intervals <= 1 ? "${meta.id}.manta" : "${meta.id}.manta.${target_bed.simpleName}" }
        ext.args         = { params.wes ? "--exome" : "" }
        ext.when         = { params.tools && params.tools.split(',').contains('manta') }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/" },
            pattern: "*{diploid_sv,tumor_sv,somatic_sv}.{vcf.gz,vcf.gz.tbi}",
            saveAs: { meta.num_intervals > 1 ? null : "manta/${meta.id}/${it}" }
        ]
    }

    // STRELKA
    withName: 'MERGE_STRELKA.*' {
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/strelka/${meta.id}/" },
            pattern: "*{vcf.gz,vcf.gz.tbi}"
        ]
    }
    withName: 'MERGE_STRELKA' {
        ext.prefix       = {"${meta.id}.strelka.variants"}
    }
    withName: 'MERGE_STRELKA_GENOME' {
        ext.prefix       = {"${meta.id}.strelka.genome"}
    }
    withName: 'STRELKA_.*' {
        ext.prefix       = { meta.num_intervals <= 1 ? "${meta.id}.strelka" : "${meta.id}.strelka.${target_bed.simpleName}" }
        ext.args         = { params.wes ? "--exome" : "" }
        ext.when         = { params.tools && params.tools.split(',').contains('strelka') }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/" },
            pattern: "*{vcf.gz,vcf.gz.tbi}",
            saveAs: { meta.num_intervals > 1 ? null : "strelka/${meta.id}/${it}" }
        ]
    }

    //TIDDIT
    withName: 'TIDDIT_SV' {
        ext.when         = { params.tools && params.tools.split(',').contains('tiddit') }
        ext.args         = { bwa_index ? "" : "--skip_assembly" }
        ext.prefix       = { "${meta.id}.tiddit" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/tiddit/${meta.id}/" },
            pattern: "*tab",
        ]
    }
    withName : 'TABIX_BGZIP_TIDDIT_SV' {
        ext.prefix       = { "${meta.id}.tiddit" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/tiddit/${meta.id}/" },
            pattern: "*{vcf.gz,vcf.gz.tbi}"
        ]
    }

// TUMOR_VARIANT_CALLING

    //CONTROLFREEC
    withName: 'ASSESS_SIGNIFICANCE' {
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/controlfreec/${meta.id}/" },
            pattern: "*{.p.value.txt}"
        ]
    }

    withName: 'CAT_MPILEUP' {
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/mpileup/${meta.id}/" },
            pattern: "*{mpileup.gz}",
        ]
    }

    withName: 'FREEC_.*' {
        ext.when         = { params.tools && params.tools.split(',').contains('controlfreec') }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/controlfreec/${meta.id}/" },
            pattern: "*{BedGraph,cpn,txt,_CNVs}"
        ]
    }

    withName: 'FREEC_TUMORONLY'{
        ext.args = {[
                    "sample":[
                        inputformat: 'pileup',
                        mateorientation: 'FR'
                    ],
                    "general" :[
                        bedgraphoutput: "TRUE",
                        breakpointthreshold: params.wes ? "1.2" : "0.8", //Values taken from Freec example configs
                        breakpointtype: params.wes ? "4" : "2", // Values taken from Freec example configs
                        coefficientofvariation: params.cf_coeff,
                        contamination: params.cf_contamination ?: "",
                        contaminationadjustment: params.cf_contamination_adjustment ? "TRUE" : "",
                        forcegccontentnormalization: params.wes ? "1" : "0",
                        minimalsubclonepresence: params.wes ? "30" : "20",
                        noisydata: params.wes ? "TRUE" : "FALSE",
                        ploidy: params.cf_ploidy,
                        printNA:  params.wes ? "FALSE" : "TRUE",
                        readcountthreshold:  params.wes ? "50" : "10",
                        sex: meta.sex,
                        //uniquematch: not set
                        window: params.cf_window ?: ""
                        ],
                    "BAF":[
                        minimalcoverageperposition: params.cf_mincov ?: "",
                        minimalqualityperposition: params.cf_minqual ?: "",
                        //"shiftinquality": (optional)not set
                    ]
                ]
            }
    }

    withName: 'FREEC2BED' {
        ext.args = { "${params.cf_ploidy}" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/controlfreec/${meta.id}/" },
            pattern: "*bed"
        ]
    }

    withName: 'FREEC2CIRCOS' {
        ext.args = { "${params.cf_ploidy}" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/controlfreec/${meta.id}/" },
            pattern: "*circos.txt"
        ]
    }

    withName: 'MAKEGRAPH' {
        ext.args = { "${params.cf_ploidy}" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/controlfreec/${meta.id}/" },
            pattern: "*png"
        ]
    }

    withName: 'SAMTOOLS_MPILEUP' {
        ext.when         = { params.tools && (params.tools.split(',').contains('controlfreec') || params.tools.split(',').contains('mpileup')) }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/mpileup/${meta.id}/" },
            pattern: "*mpileup.gz",
            saveAs: { meta.num_intervals > 1 ? null : it }
        ]
    }

    //MANTA
    withName: 'MERGE_MANTA_TUMOR' {
        ext.prefix       = {"${meta.id}.manta.tumor_sv"}
    }

    //MUTECT2
    withName: 'CALCULATECONTAMINATION' {
        ext.prefix       = { "${meta.id}.mutect2" }
        ext.args         = { "-tumor-segmentation ${meta.id}.mutect2.segmentation.table" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : "mutect2/${meta.id}/${filename}" }
        ]
    }

    withName: 'MERGE_MUTECT2.*' {
        ext.prefix       = { "${meta.id}.mutect2" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/mutect2/${meta.id}" },
            pattern: "*{vcf.gz,vcf.gz.tbi}"
        ]
    }

    withName: 'FILTERMUTECTCALLS.*'{
        ext.prefix       = {"${meta.id}.mutect2.filtered"}
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : "mutect2/${meta.id}/${filename}" }
        ]
    }

    withName: 'GATHERPILEUPSUMMARIES' {
        ext.prefix       = { "${meta.id}.mutect2" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/mutect2/${meta.id}/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'GATHERPILEUPSUMMARIES_.*' {
        ext.prefix       = { "${meta.id}.mutect2" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/mutect2/${meta.tumor_id}_vs_${meta.normal_id}/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'GETPILEUPSUMMARIES.*' {
        ext.prefix       = { meta.num_intervals <= 1 ? "${meta.id}.mutect2" : "${meta.id}.mutect2.${intervals.simpleName}" }
        publishDir        = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/" },
            pattern: "*.table",
            saveAs: { meta.num_intervals > 1 ? null : "mutect2/${meta.id}/${it}" }
        ]
    }

    withName: 'GETPILEUPSUMMARIES_.*' {
        ext.prefix        = { meta.num_intervals <= 1 ? "${meta.id}.mutect2" : "${meta.id}.mutect2.${intervals.simpleName}" }
        publishDir        = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/" },
            pattern: "*.table",
            saveAs: { meta.num_intervals > 1 ? null : "mutect2/${meta.tumor_id}_vs_${meta.normal_id}/${it}" }
        ]
    }

    withName: 'LEARNREADORIENTATIONMODEL'{
        ext.prefix       = { "${meta.id}.mutect2.artifactprior" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/mutect2/${meta.id}/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'MERGEMUTECTSTATS' {
        ext.prefix       = { "${meta.id}.mutect2" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/mutect2/${meta.id}/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'MUTECT2'{
        ext.prefix       = { meta.num_intervals <= 1 ? "${meta.id}.mutect2" : "${meta.id}.mutect2.${intervals.simpleName}" }
        ext.when         = { params.tools && params.tools.split(',').contains('mutect2') }
        ext.args         = { params.ignore_soft_clipped_bases ? "--dont-use-soft-clipped-bases true --f1r2-tar-gz ${task.ext.prefix}.f1r2.tar.gz" : "--f1r2-tar-gz ${task.ext.prefix}.f1r2.tar.gz" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/" },
            pattern: "*{vcf.gz,vcf.gz.tbi,stats}",
            saveAs: { meta.num_intervals > 1 ? null : "mutect2/${meta.id}/${it}" }
        ]
    }

// PAIR_VARIANT_CALLING

    //ASCAT
    withName: 'ASCAT' {

        ext.args = {[
            "gender": meta.sex,
            "genomeVersion": params.ascat_genome,
            "purity": params.ascat_purity,
            "ploidy": params.ascat_ploidy,
            "minCounts": params.ascat_min_counts,
            "chrom_names": meta.sex == 'XX' ? "c(1:22, 'X')" : "c(1:22, 'X', 'Y')",
            "min_base_qual": params.ascat_min_base_qual,
            "min_map_qual": params.ascat_min_map_qual
            ]}
        ext.when         = { params.tools && params.tools.split(',').contains('ascat') }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/ascat/${meta.id}/" },
            pattern: "*{png,cnvs.txt,metrics.txt,purityploidy.txt,segments.txt,LogR.txt,BAF.txt}"
        ]

    }

    //CONTROLFREEC
    if (params.tools && (params.tools.split(',').contains('controlfreec') || params.tools.split(',').contains('mpileup'))) {
        withName: 'NFCORE_SAREK:SAREK:PAIR_VARIANT_CALLING:RUN_MPILEUP_NORMAL:SAMTOOLS_MPILEUP' {
            ext.prefix = { meta.num_intervals <= 1 ? "${meta.id}.normal" : "${meta.id}_${intervals.simpleName}.normal" }
        }

        withName: 'NFCORE_SAREK:SAREK:PAIR_VARIANT_CALLING:RUN_MPILEUP_TUMOR:SAMTOOLS_MPILEUP' {
            ext.prefix = { meta.num_intervals <= 1 ? "${meta.id}.tumor" : "${meta.id}_${intervals.simpleName}.tumor" }
        }

        withName: 'NFCORE_SAREK:SAREK:PAIR_VARIANT_CALLING:RUN_MPILEUP_NORMAL:CAT_MPILEUP' {
            ext.prefix = { "${meta.id}.normal.mpileup.gz" }
        }

        withName: 'NFCORE_SAREK:SAREK:PAIR_VARIANT_CALLING:RUN_MPILEUP_TUMOR:CAT_MPILEUP' {
            ext.prefix = { "${meta.id}.tumor.mpileup.gz" }
        }

        withName: 'NFCORE_SAREK:SAREK:TUMOR_ONLY_VARIANT_CALLING:RUN_MPILEUP:CAT_MPILEUP' {
            ext.prefix = { "${meta.id}.tumor.mpileup.gz" }
        }

        withName: 'NFCORE_SAREK:SAREK:GERMLINE_VARIANT_CALLING:RUN_MPILEUP:SAMTOOLS_MPILEUP' {
            ext.prefix = { meta.num_intervals <= 1 ? "${meta.id}.normal" : "${meta.id}_${intervals.simpleName}.normal" }
        }

        withName: 'NFCORE_SAREK:SAREK:GERMLINE_VARIANT_CALLING:RUN_MPILEUP:CAT_MPILEUP' {
            ext.prefix = { "${meta.id}.normal.mpileup.gz" }
        }

        withName: 'NFCORE_SAREK:SAREK:TUMOR_ONLY_VARIANT_CALLING:RUN_MPILEUP:SAMTOOLS_MPILEUP' {
            ext.prefix = { meta.num_intervals <= 1 ? "${meta.id}.tumor" : "${meta.id}_${intervals.simpleName}.tumor" }
        }
    }

    withName: 'FREEC_SOMATIC'{
        ext.args = {[
                    "sample":[
                        inputformat: 'pileup',
                        mateorientation: 'FR'
                    ],
                    "control":[
                        inputformat: "pileup",
                        mateorientation: "FR"
                    ],
                    "general" :[
                        bedgraphoutput: "TRUE",
                        breakpointthreshold: params.wes ? "1.2" : "0.8", //Values taken from Freec example configs
                        breakpointtype: params.wes ? "4" : "2", // Values taken from Freec example configs
                        coefficientofvariation: params.cf_coeff,
                        contamination: params.cf_contamination ?: "",
                        contaminationadjustment: params.cf_contamination_adjustment ? "TRUE" : "",
                        forcegccontentnormalization: params.wes ? "1" : "0",
                        minimalsubclonepresence: params.wes ? "30" : "20",
                        noisydata: params.wes ? "TRUE" : "FALSE",
                        ploidy: params.cf_ploidy,
                        printNA:  params.wes ? "FALSE" : "TRUE",
                        readcountthreshold:  params.wes ? "50" : "10",
                        sex: meta.sex,
                        //uniquematch: not set
                        window: params.cf_window ?: ""
                        ],
                    "BAF":[
                        minimalcoverageperposition: params.cf_mincov ?: "",
                        minimalqualityperposition: params.cf_minqual ?: "",
                        //"shiftinquality": (optional)not set
                    ]
                ]
            }
    }

    //FREEBAYES
    if (params.tools && params.tools.split(',').contains('freebayes')) {
        withName: 'NFCORE_SAREK:SAREK:PAIR_VARIANT_CALLING:RUN_FREEBAYES_SOMATIC:FREEBAYES' {
            ext.args       = "--pooled-continuous \
                            --pooled-discrete \
                            --genotype-qualities \
                            --report-genotype-likelihood-max \
                            --allele-balance-priors-off \
                            --min-alternate-fraction 0.03 \
                            --min-repeat-entropy 1 \
                            --min-alternate-count 2 "
        }
    }

    //MANTA
    withName: 'MERGE_MANTA_SOMATIC' {
        ext.prefix       = {"${meta.id}.manta.somatic_sv"}
    }

    //MUTECT2
    if (params.tools && params.tools.split(',').contains('mutect2')) {
        withName: 'NFCORE_SAREK:SAREK:PAIR_VARIANT_CALLING:GATK_TUMOR_NORMAL_SOMATIC_VARIANT_CALLING:MUTECT2' {
            ext.args         = { params.ignore_soft_clipped_bases ?
                                "--dont-use-soft-clipped-bases true --f1r2-tar-gz ${task.ext.prefix}.f1r2.tar.gz --normal-sample ${meta.patient}_${meta.normal_id}" :
                                "--f1r2-tar-gz ${task.ext.prefix}.f1r2.tar.gz --normal-sample ${meta.patient}_${meta.normal_id}" }
        }
    }

    //MSISENSORPRO
    withName: 'MSISENSORPRO_MSI_SOMATIC' {
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/variant_calling/msisensorpro/${meta.id}/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    //STRELKA
    withName: 'MERGE_STRELKA_INDELS' {
        ext.prefix       = {"${meta.id}.strelka.somatic_indels"}
    }
    withName: 'MERGE_STRELKA_SNVS' {
        ext.prefix       = {"${meta.id}.strelka.somatic_snvs"}
    }

    if (params.tools && params.tools.split(',').contains('tiddit')) {
    //TIDDIT
        withName: 'NFCORE_SAREK:SAREK:PAIR_VARIANT_CALLING:RUN_TIDDIT_SOMATIC:RUN_TIDDIT_NORMAL:TABIX_BGZIP_TIDDIT_SV' {
            ext.prefix       = {"${meta.id}.tiddit.normal"}
        }

        withName: 'NFCORE_SAREK:SAREK:PAIR_VARIANT_CALLING:RUN_TIDDIT_SOMATIC:RUN_TIDDIT_TUMOR:TABIX_BGZIP_TIDDIT_SV' {
            ext.prefix       = {"${meta.id}.tiddit.tumor"}
        }

        //SVDB
        withName: 'NFCORE_SAREK:SAREK:PAIR_VARIANT_CALLING:RUN_TIDDIT_SOMATIC:SVDB_MERGE' {
            ext.prefix       = { "${meta.id}.tiddit" }
            publishDir       = [
                mode: params.publish_dir_mode,
                path: { "${params.outdir}/variant_calling/tiddit/${meta.id}/" },
                pattern: "*vcf.gz"
            ]
        }
    }

    // VCF QC
    withName: 'BCFTOOLS_STATS'{
        ext.when         = { !(params.skip_tools && params.skip_tools.split(',').contains('bcftools')) }
        ext.prefix       = { "${vcf.baseName.minus(".vcf")}" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reports/bcftools/${meta.variantcaller}/${meta.id}/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'VCFTOOLS_.*'{
        ext.when         = { !(params.skip_tools && params.skip_tools.split(',').contains('vcftools')) }
        ext.prefix       = { "${variant_file.baseName.minus(".vcf")}" }
        publishDir       = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reports/vcftools/${meta.variantcaller}/${meta.id}/" },
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'VCFTOOLS_TSTV_COUNT'{
        ext.args         = "--TsTv-by-count"
    }

    withName: 'VCFTOOLS_TSTV_QUAL'{
        ext.args         = "--TsTv-by-qual"
    }

    withName: 'VCFTOOLS_SUMMARY'{
        ext.args         = "--FILTER-summary"
    }

// ANNOTATE

    // SNPEFF
    if (params.tools && (params.tools.split(',').contains('snpeff') || params.tools.split(',').contains('merge'))) {
        withName: 'SNPEFF' {
            ext.prefix       = { "${vcf.baseName.minus(".vcf")}_snpEff" }
            ext.args          = '-nodownload -canon -v'
            if (!params.snpeff_cache) container = { params.snpeff_genome ? "nfcore/snpeff:${params.snpeff_version}.${params.snpeff_genome}" : "nfcore/snpeff:${params.snpeff_version}.${params.genome}" }
            publishDir       = [
                [
                    mode: params.publish_dir_mode,
                    path: { "${params.outdir}/reports/snpeff/${meta.variantcaller}/${meta.id}/" },
                    pattern: "*{csv,html,genes.txt}",
                    saveAs: { params.tools.split(',').contains('snpeff') ? it : null }
                ]
            ]
        }
    }

    // VEP
    if (params.tools && (params.tools.split(',').contains('vep') || params.tools.split(',').contains('merge'))) {
        withName: 'ENSEMBLVEP' {
            ext.args          = [
                '--everything --filter_common --per_gene --total_length --offline --format vcf',
                (params.vep_dbnsfp && params.dbnsfp && !params.dbnsfp_consequence)    ? "--plugin dbNSFP,${params.dbnsfp.split("/")[-1]},${params.dbnsfp_fields}"                                              : '',
                (params.vep_dbnsfp && params.dbnsfp && params.dbnsfp_consequence)     ? "--plugin dbNSFP,'${params.dbnsfp_consequence}',${params.dbnsfp.split("/")[-1]},${params.dbnsfp_fields}"               : '',
                (params.vep_loftee)                                                   ? "--plugin LoF,loftee_path:/opt/conda/envs/nf-core-vep-${params.vep_version}/share/ensembl-vep-${params.vep_version}-0" : '',
                (params.vep_spliceai && params.spliceai_snv && params.spliceai_indel) ? "--plugin SpliceAI,snv=${params.spliceai_snv.split("/")[-1]},${params.spliceai_indel.split("/")[-1]}"                  : '',
                (params.vep_spliceregion)                                             ? '--plugin SpliceRegion'                                                                                                : '',
                (params.vep_out_format)                                               ? "--${params.vep_out_format}"                                                                                           : '--vcf'
            ].join(' ').trim()
            // If just VEP: <vcf prefix>_VEP.ann.vcf
            ext.prefix       = { "${vcf.baseName.minus(".vcf")}_VEP" }
            if (!params.vep_cache)    container = { params.vep_genome ? "nfcore/vep:${params.vep_version}.${params.vep_genome}" : "nfcore/vep:${params.vep_version}.${params.genome}" }
            publishDir       = [
                [
                    mode: params.publish_dir_mode,
                    path: { "${params.outdir}/reports/EnsemblVEP/${meta.variantcaller}/${meta.id}/" },
                    pattern: "*html"
                ],
                [
                    mode: params.publish_dir_mode,
                    path: { "${params.outdir}/annotation/${meta.variantcaller}/${meta.id}/" },
                    pattern: "*{json,tab}"
                ]
            ]
        }
    }

    // SNPEFF THEN VEP
    if (params.tools && params.tools.split(',').contains('merge')) {
        withName: ".*:ANNOTATION_MERGE:ENSEMBLVEP" {
            // If merge: Output file will have format *_snpEff_VEP.ann.vcf, *_snpEff_VEP.ann.json or *_snpEff_VEP.ann.tab
            ext.prefix       = { "${vcf.baseName.minus(".ann.vcf")}_VEP" }
        }
    }

    // ALL ANNOTATION TOOLS
    if (params.tools && (params.tools.split(',').contains('snpeff') || params.tools.split(',').contains('vep') || params.tools.split(',').contains('merge'))) {
        withName: "NFCORE_SAREK:SAREK:ANNOTATE:.*:TABIX_BGZIPTABIX" {
            ext.prefix       = { input.baseName.minus(".vcf") }
            publishDir       = [
                    mode: params.publish_dir_mode,
                    path: { "${params.outdir}/annotation/${meta.variantcaller}/${meta.id}/" },
                    pattern: "*{gz,gz.tbi}"
            ]
        }
    }

    if (params.tools && (params.tools.split(',').contains('snpeff') || params.tools.split(',').contains('merge'))) {
        withName: 'NFCORE_SAREK:SAREK:ANNOTATE:ANNOTATION_SNPEFF:TABIX_BGZIPTABIX' {
            publishDir       = [
                mode: params.publish_dir_mode,
                path: { "${params.outdir}/annotation/${meta.variantcaller}/${meta.id}/" },
                pattern: "*{gz,gz.tbi}",
                saveAs: { params.tools.split(',').contains('snpeff') ? it : null }
            ]
        }
    }

    // MULTIQC
    withName:'MULTIQC' {
        errorStrategy = {task.exitStatus == 143 ? 'retry' : 'ignore'}
    }
}
