/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    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.
----------------------------------------------------------------------------------------
*/

def rseqc_modules = params.rseqc_modules ? params.rseqc_modules.split(',').collect{ it.trim().toLowerCase() } : []

//
// General configuration options
//

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

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

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

//
// Genome preparation options
//

process {
    withName: 'GUNZIP_.*|MAKE_TRANSCRIPTS_FASTA' {
        publishDir = [
            path: { "${params.outdir}/genome" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: 'UNTAR_.*' {
        ext.args2 = '--no-same-owner'
    }

    withName: 'UNTAR_.*|STAR_GENOMEGENERATE|STAR_GENOMEGENERATE_IGENOMES|HISAT2_BUILD' {
        publishDir = [
            path: { "${params.outdir}/genome/index" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: 'GFFREAD' {
        ext.args   = '--keep-exon-attrs -F -T'
        publishDir = [
            path: { "${params.outdir}/genome" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: 'HISAT2_EXTRACTSPLICESITES' {
        publishDir = [
            path: { "${params.outdir}/genome/index" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: 'SALMON_INDEX' {
        ext.args   = params.gencode ? '--gencode' : ''
        publishDir = [
            path: { "${params.outdir}/genome/index" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: 'RSEM_PREPAREREFERENCE_GENOME' {
        ext.args   = '--star'
        publishDir = [
            path: { "${params.outdir}/genome/index" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: 'GTF2BED' {
        publishDir = [
            path: { "${params.outdir}/genome" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: 'CAT_ADDITIONAL_FASTA|PREPROCESS_TRANSCRIPTS_FASTA_GENCODE' {
        publishDir = [
            path: { "${params.outdir}/genome" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: 'GTF_GENE_FILTER' {
        publishDir = [
            path: { "${params.outdir}/genome" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: 'CUSTOM_GETCHROMSIZES' {
        publishDir = [
            path: { "${params.outdir}/genome" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: 'CAT_FASTQ' {
        publishDir = [
            path: { "${params.outdir}/fastq" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_merged_fastq
        ]
    }
}

if (!params.skip_bbsplit && params.bbsplit_fasta_list) {
    process {
        withName: '.*:PREPARE_GENOME:BBMAP_BBSPLIT' {
            ext.args   = 'build=1'
            publishDir = [
                path: { "${params.outdir}/genome/index" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
                enabled: params.save_reference
            ]
        }
    }
}

//
// Read QC and trimming options
//

if (!(params.skip_fastqc || params.skip_qc)) {
    process {
        withName: '.*:FASTQC_UMITOOLS_TRIMGALORE:FASTQC' {
            ext.args   = '--quiet'
        }
    }
}

if (!params.skip_trimming) {
    process {
        withName: '.*:FASTQC_UMITOOLS_TRIMGALORE:TRIMGALORE' {
            ext.args   = {
                [
                    "--fastqc_args '-t ${task.cpus}' ",
                    params.trim_nextseq > 0 ? "--nextseq ${params.trim_nextseq}" : ''
                ].join(' ').trim()
            }
            publishDir = [
                [
                    path: { "${params.outdir}/trimgalore/fastqc" },
                    mode: params.publish_dir_mode,
                    pattern: "*.{html,zip}"
                ],
                [
                    path: { "${params.outdir}/trimgalore" },
                    mode: params.publish_dir_mode,
                    pattern: "*.fq.gz",
                    enabled: params.save_trimmed
                ],
                [
                    path: { "${params.outdir}/trimgalore" },
                    mode: params.publish_dir_mode,
                    pattern: "*.txt"
                ]
            ]
        }

        withName: 'MULTIQC_TSV_FAIL_TRIMMED' {
            publishDir = [
                path: { "${params.outdir}/multiqc" },
                enabled: false
            ]
        }
    }
}

if (params.with_umi && !params.skip_umi_extract) {
    process {
        withName: '.*:FASTQC_UMITOOLS_TRIMGALORE:UMITOOLS_EXTRACT' {
            ext.args   = [
                    params.umitools_extract_method ? "--extract-method=${params.umitools_extract_method}" : '',
                    params.umitools_bc_pattern     ? "--bc-pattern='${params.umitools_bc_pattern}'" : '',
                    params.umitools_bc_pattern2    ? "--bc-pattern2='${params.umitools_bc_pattern2}'" : ''
                ].join(' ').trim()
            publishDir = [
                [
                    path: { "${params.outdir}/umitools" },
                    mode: params.publish_dir_mode,
                    pattern: "*.log"
                ],
                [
                    path: { "${params.outdir}/umitools" },
                    mode: params.publish_dir_mode,
                    pattern: "*.fastq.gz",
                    enabled: params.save_umi_intermeds
                ]
            ]
        }
    }
}

//
// Contaminant removal options
//

if (!params.skip_bbsplit) {
    process {
        withName: 'BBMAP_BBSPLIT' {
            ext.args   = 'build=1 ambiguous2=all maxindel=150000'
            publishDir = [
                [
                    path: { "${params.outdir}/bbsplit" },
                    mode: params.publish_dir_mode,
                    pattern: '*.txt'
                ],
                [
                    path: { "${params.outdir}/bbsplit" },
                    mode: params.publish_dir_mode,
                    pattern: '*.fastq.gz',
                    enabled: params.save_bbsplit_reads
                ]
            ]
        }
    }
}

if (params.remove_ribo_rna) {
    process {
        withName: 'SORTMERNA' {
            ext.args   = '--num_alignments 1 --fastx -v'
            publishDir = [
                [
                    path: { "${params.outdir}/sortmerna" },
                    mode: params.publish_dir_mode,
                    pattern: "*.log"
                ],
                [
                    path: { "${params.outdir}/sortmerna" },
                    mode: params.publish_dir_mode,
                    pattern: "*.fastq.gz",
                    enabled: params.save_non_ribo_reads
                ]
            ]
        }
    }
}

//
// General alignment options
//

if (!params.skip_alignment) {
    process {
        withName: 'NFCORE_RNASEQ:RNASEQ:.*:BAM_SORT_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' {
            ext.prefix = { "${meta.id}.sorted.bam" }
            publishDir = [
                path: { "${params.outdir}/${params.aligner}/samtools_stats" },
                mode: params.publish_dir_mode,
                pattern: "*.{stats,flagstat,idxstats}"
            ]
        }

        withName: 'NFCORE_RNASEQ:RNASEQ:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_SORT' {
            ext.prefix = { "${meta.id}.sorted" }
            publishDir = [
                path: { "${params.outdir}/${params.aligner}" },
                mode: params.publish_dir_mode,
                pattern: "*.bam",
                enabled: ( ['star_salmon','hisat2'].contains(params.aligner) &&
                    ( params.save_align_intermeds ||
                        ( !params.with_umi && params.skip_markduplicates )
                    )
                ) || params.save_align_intermeds || params.skip_markduplicates
            ]
        }

        withName: 'NFCORE_RNASEQ:RNASEQ:.*:BAM_SORT_SAMTOOLS:SAMTOOLS_INDEX' {
            ext.args   = params.bam_csi_index ? '-c' : ''
            publishDir = [
                path: { "${params.outdir}/${params.aligner}" },
                mode: params.publish_dir_mode,
                pattern: "*.{bam,csi}",
                enabled: ( ['star_salmon','hisat2'].contains(params.aligner) &&
                    ( params.save_align_intermeds ||
                        ( !params.with_umi && params.skip_markduplicates )
                    )
                ) || params.save_align_intermeds || params.skip_markduplicates
            ]
        }
    }

    if (!params.skip_markduplicates) {
        process {
            withName: '.*:MARK_DUPLICATES_PICARD:PICARD_MARKDUPLICATES' {
                ext.args   = '--ASSUME_SORTED true --REMOVE_DUPLICATES false --VALIDATION_STRINGENCY LENIENT --TMP_DIR tmp'
                ext.prefix = { "${meta.id}.markdup.sorted" }
                publishDir = [
                    [
                        path: { "${params.outdir}/${params.aligner}/picard_metrics" },
                        mode: params.publish_dir_mode,
                        pattern: '*metrics.txt'
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}" },
                        mode: params.publish_dir_mode,
                        pattern: '*.bam'
                    ]
                ]
            }

            withName: '.*:MARK_DUPLICATES_PICARD:SAMTOOLS_INDEX' {
                ext.args   = params.bam_csi_index ? '-c' : ''
                ext.prefix = { "${meta.id}.markdup.sorted" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}" },
                    mode: params.publish_dir_mode,
                    pattern: '*.{bai,csi}'
                ]
            }

            withName: '.*:MARK_DUPLICATES_PICARD:BAM_STATS_SAMTOOLS:.*' {
                ext.prefix = { "${meta.id}.markdup.sorted.bam" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/samtools_stats" },
                    mode: params.publish_dir_mode,
                    pattern: '*.{stats,flagstat,idxstats}'
                ]
            }
        }
    }

    if (params.with_umi && ['star_salmon','hisat2'].contains(params.aligner)) {
        process {
            withName: '.*:DEDUP_UMI_UMITOOLS_GENOME:UMITOOLS_DEDUP' {
                ext.args   = { [
                    meta.single_end                 ? '' : '--unpaired-reads=discard --chimeric-pairs=discard',
                    params.umitools_grouping_method ? "--method='${params.umitools_grouping_method}'" : '',
                    params.umitools_umi_separator   ? "--umi-separator='${params.umitools_umi_separator}'" : ''
                ].join(' ').trim() }
                ext.prefix = { "${meta.id}.umi_dedup.sorted" }
                publishDir = [
                    [
                        path: { "${params.outdir}/${params.aligner}/umitools" },
                        mode: params.publish_dir_mode,
                        pattern: '*.tsv'
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}" },
                        mode: params.publish_dir_mode,
                        pattern: '*.bam',
                        enabled: (
                            params.save_align_intermeds ||
                            params.skip_markduplicates ||
                            params.save_umi_intermeds
                        )
                    ]
                ]
            }

            withName: '.*:DEDUP_UMI_UMITOOLS_GENOME:SAMTOOLS_INDEX' {
                ext.args   = params.bam_csi_index ? '-c' : ''
                ext.prefix = { "${meta.id}.umi_dedup.sorted" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}" },
                    mode: params.publish_dir_mode,
                    pattern: '*.{bai,csi}',
                    enabled: (
                        params.save_align_intermeds ||
                        params.skip_markduplicates ||
                        params.save_umi_intermeds
                    )
                ]
            }

            withName: '.*:DEDUP_UMI_UMITOOLS_GENOME:BAM_STATS_SAMTOOLS:.*' {
                ext.prefix = { "${meta.id}.umi_dedup.sorted.bam" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/samtools_stats" },
                    mode: params.publish_dir_mode,
                    pattern: '*.{stats,flagstat,idxstats}'
                ]
            }
        }
    }

    if (!params.skip_bigwig) {
        process {
            withName: 'BEDTOOLS_GENOMECOV' {
                ext.args   = '-split -du'
                publishDir = [
                    path: { "${params.outdir}/bedtools/${meta.id}" },
                    enabled: false
                ]
            }

            withName: '.*:BEDGRAPH_TO_BIGWIG_FORWARD:UCSC_BEDCLIP' {
                ext.prefix = { "${meta.id}.clip.forward" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}" },
                    enabled: false
                ]
            }

            withName: '.*:BEDGRAPH_TO_BIGWIG_FORWARD:UCSC_BEDGRAPHTOBIGWIG' {
                ext.prefix = { "${meta.id}.forward" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/bigwig" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }

            withName: '.*:BEDGRAPH_TO_BIGWIG_REVERSE:UCSC_BEDCLIP' {
                ext.prefix = { "${meta.id}.clip.reverse" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}" },
                    enabled: false
                ]
            }

            withName: '.*:BEDGRAPH_TO_BIGWIG_REVERSE:UCSC_BEDGRAPHTOBIGWIG' {
                ext.prefix = { "${meta.id}.reverse" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/bigwig" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }

    if (!params.skip_stringtie) {
        process {
            withName: 'STRINGTIE_STRINGTIE' {
                ext.args   = [
                    '-v',
                    params.stringtie_ignore_gtf ? '' : '-e'
                ].join(' ').trim()
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/stringtie" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }

    if (params.aligner.contains('star')) {
        process {
            withName: 'MULTIQC_TSV_FAIL_MAPPED' {
                publishDir = [
                    path: { "${params.outdir}/multiqc" },
                    enabled: false
                ]
            }
        }
    }
}

//
// STAR Salmon alignment options
//

if (!params.skip_alignment && params.aligner == 'star_salmon') {
    process {
        withName: '.*:ALIGN_STAR:STAR_ALIGN|.*:ALIGN_STAR:STAR_ALIGN_IGENOMES' {
            ext.args   = [
                '--quantMode TranscriptomeSAM',
                '--twopassMode Basic',
                '--outSAMtype BAM Unsorted',
                '--readFilesCommand zcat',
                '--runRNGseed 0',
                '--outFilterMultimapNmax 20',
                '--alignSJDBoverhangMin 1',
                '--outSAMattributes NH HI AS NM MD',
                '--quantTranscriptomeBan Singleend',
                '--outSAMstrandField intronMotif',
                params.save_unaligned ? '--outReadsUnmapped Fastx' : ''
            ].join(' ').trim()
            publishDir = [
                [
                    path: { "${params.outdir}/${params.aligner}/log" },
                    mode: params.publish_dir_mode,
                    pattern: '*.{out,tab}'
                ],
                [
                    path: { "${params.outdir}/${params.aligner}" },
                    mode: params.publish_dir_mode,
                    pattern: '*.bam',
                    enabled: params.save_align_intermeds
                ],
                [
                    path: { "${params.outdir}/${params.aligner}/unmapped" },
                    mode: params.publish_dir_mode,
                    pattern: '*.fastq.gz',
                    enabled: params.save_unaligned
                ]
            ]
        }

        withName: '.*:QUANTIFY_STAR_SALMON:SALMON_QUANT' {
            publishDir = [
                path: { "${params.outdir}/${params.aligner}" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        }

        withName: '.*:QUANTIFY_STAR_SALMON:SALMON_TX2GENE' {
            publishDir = [
                path: { "${params.outdir}/${params.aligner}" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        }

        withName: '.*:QUANTIFY_STAR_SALMON:SALMON_TXIMPORT' {
            publishDir = [
                path: { "${params.outdir}/${params.aligner}" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        }

        withName: '.*:QUANTIFY_STAR_SALMON:SALMON_SE_.*' {
            publishDir = [
                path: { "${params.outdir}/${params.aligner}" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        }
    }

    if (params.with_umi) {
        process {
            withName: 'NFCORE_RNASEQ:RNASEQ:SAMTOOLS_SORT' {
                ext.args   = '-n'
                ext.prefix = { "${meta.id}.umi_dedup.transcriptome" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}" },
                    enabled: false
                ]
            }

            withName: 'NFCORE_RNASEQ:RNASEQ:UMITOOLS_PREPAREFORRSEM' {
                ext.prefix = { "${meta.id}.umi_dedup.transcriptome.filtered" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/umitools/log" },
                    mode: params.publish_dir_mode,
                    pattern: '*.log'
                ]
            }

            withName: 'NFCORE_RNASEQ:RNASEQ:BAM_SORT_SAMTOOLS:SAMTOOLS_SORT' {
                ext.prefix = { "${meta.id}.transcriptome.sorted" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}" },
                    enabled: false
                ]
            }

            withName: 'NFCORE_RNASEQ:RNASEQ:BAM_SORT_SAMTOOLS:SAMTOOLS_INDEX' {
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}" },
                    enabled: false
                ]
            }

            withName: 'NFCORE_RNASEQ:RNASEQ:BAM_SORT_SAMTOOLS:BAM_STATS_SAMTOOLS:.*' {
                ext.prefix = { "${meta.id}.transcriptome.sorted.bam" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}" },
                    enabled: false
                ]
            }

            withName: '.*:DEDUP_UMI_UMITOOLS_TRANSCRIPTOME:UMITOOLS_DEDUP' {
                ext.args   = { [
                    meta.single_end                 ? '' : '--unpaired-reads=discard --chimeric-pairs=discard',
                    params.umitools_grouping_method ? "--method='${params.umitools_grouping_method}'" : '',
                    params.umitools_umi_separator   ? "--umi-separator='${params.umitools_umi_separator}'" : '',
                ].join(' ').trim() }
                ext.prefix = { "${meta.id}.umi_dedup.transcriptome.sorted" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/umitools" },
                    mode: params.publish_dir_mode,
                    pattern: '*.tsv'
                ]
            }

            withName: '.*:DEDUP_UMI_UMITOOLS_TRANSCRIPTOME:SAMTOOLS_INDEX' {
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}" },
                    enabled: false
                ]
            }

            withName: '.*:DEDUP_UMI_UMITOOLS_TRANSCRIPTOME:BAM_STATS_SAMTOOLS:.*' {
                ext.prefix = { "${meta.id}.umi_dedup.transcriptome.sorted.bam" }
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/samtools_stats" },
                    mode: params.publish_dir_mode,
                    pattern: '*.{stats,flagstat,idxstats}'
                ]
            }
        }
    }

    if (!params.skip_qc & !params.skip_deseq2_qc) {
        process {
            withName: 'DESEQ2_QC_STAR_SALMON' {
                ext.args   = [
                    "--id_col 1",
                    "--sample_suffix ''",
                    "--outprefix deseq2",
                    "--count_col 3",
                    params.deseq2_vst ? '--vst TRUE' : ''
                ].join(' ').trim()
                ext.args2  = 'star_salmon'
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/deseq2_qc" },
                    mode: params.publish_dir_mode,
                    pattern: "*{RData,pca.vals.txt,plots.pdf,sample.dists.txt,size_factors,log}"
                ]
            }
        }
    }
}

//
// STAR RSEM alignment options
//

if (!params.skip_alignment && params.aligner == 'star_rsem') {
    process {
        withName: '.*:QUANTIFY_RSEM:RSEM_CALCULATEEXPRESSION' {
            ext.args   = [
                '--star',
                '--star-output-genome-bam',
                '--star-gzipped-read-file',
                '--estimate-rspd',
                '--seed 1'
            ].join(' ').trim()
            publishDir = [
                [
                    path: { "${params.outdir}/${params.aligner}" },
                    mode: params.publish_dir_mode,
                    pattern: "*.{stat,results}"
                ],
                [
                    path: { "${params.outdir}/${params.aligner}" },
                    mode: params.publish_dir_mode,
                    pattern: "*.bam",
                    enabled: params.save_align_intermeds
                ],
                [
                    path: { "${params.outdir}/${params.aligner}/log" },
                    mode: params.publish_dir_mode,
                    pattern: "*.log"
                ]
            ]
        }

        withName: '.*:QUANTIFY_RSEM:RSEM_MERGE_COUNTS' {
            publishDir = [
                path: { "${params.outdir}/${params.aligner}" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        }
    }

    if (!params.skip_qc & !params.skip_deseq2_qc) {
        process {
            withName: 'DESEQ2_QC_RSEM' {
                ext.args   = [
                    "--id_col 1",
                    "--sample_suffix ''",
                    "--outprefix deseq2",
                    "--count_col 3",
                    params.deseq2_vst ? '--vst TRUE' : ''
                ].join(' ').trim()
                ext.args2  = 'star_rsem'
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/deseq2_qc" },
                    mode: params.publish_dir_mode,
                    pattern: "*{RData,pca.vals.txt,plots.pdf,sample.dists.txt,size_factors,log}"
                ]
            }
        }
    }
}

//
// HISAT2 alignment options
//

if (!params.skip_alignment && params.aligner == 'hisat2') {
    process {
        withName: '.*:ALIGN_HISAT2:HISAT2_ALIGN' {
            ext.args   = '--met-stderr --new-summary --dta'
            publishDir = [
                [
                    path: { "${params.outdir}/${params.aligner}/log" },
                    mode: params.publish_dir_mode,
                    pattern: '*.log'
                ],
                [
                    path: { "${params.outdir}/${params.aligner}" },
                    mode: params.publish_dir_mode,
                    pattern: '*.bam',
                    enabled: params.save_align_intermeds
                ],
                [
                    path: { "${params.outdir}/${params.aligner}/unmapped" },
                    mode: params.publish_dir_mode,
                    pattern: '*.fastq.gz',
                    enabled: params.save_unaligned
                ]
            ]
        }
    }
}

//
// Post-alignment QC options
//

if (!params.skip_alignment && !params.skip_qc) {
    if (!params.skip_preseq) {
        process {
            withName: 'PRESEQ_LCEXTRAP' {
                ext.args   = '-verbose -bam -seed 1 -seg_len 100000000'
                publishDir = [
                    [
                        path: { "${params.outdir}/${params.aligner}/preseq" },
                        mode: params.publish_dir_mode,
                        pattern: "*.txt"
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/preseq/log" },
                        mode: params.publish_dir_mode,
                        pattern: "*.log"
                    ]
                ]
            }
        }
    }

    if (!params.skip_qualimap) {
        process {
            withName: 'QUALIMAP_RNASEQ' {
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/qualimap" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }

    if (!params.skip_dupradar) {
        process {
            withName: 'DUPRADAR' {
                publishDir = [
                    [
                        path: { "${params.outdir}/${params.aligner}/dupradar/scatter_plot" },
                        mode: params.publish_dir_mode,
                        pattern: "*Dens.pdf"
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/dupradar/box_plot" },
                        mode: params.publish_dir_mode,
                        pattern: "*Boxplot.pdf"
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/dupradar/histogram" },
                        mode: params.publish_dir_mode,
                        pattern: "*Hist.pdf"
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/dupradar/gene_data" },
                        mode: params.publish_dir_mode,
                        pattern: "*Matrix.txt"
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/dupradar/intercepts_slope" },
                        mode: params.publish_dir_mode,
                        pattern: "*slope.txt"
                    ]
                ]
            }
        }
    }

    if (!params.skip_biotype_qc && params.featurecounts_group_type) {
        process {
            withName: 'SUBREAD_FEATURECOUNTS' {
                ext.args   = [
                    '-B -C',
                    params.gencode ? "-g gene_type" : "-g $params.featurecounts_group_type",
                    "-t $params.featurecounts_feature_type"
                ].join(' ').trim()
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/featurecounts" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }

            withName: 'MULTIQC_CUSTOM_BIOTYPE' {
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/featurecounts" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }

    if (!params.skip_rseqc && 'bam_stat' in rseqc_modules) {
        process {
            withName: '.*:RSEQC:RSEQC_BAMSTAT' {
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/rseqc/bam_stat" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }

    if (!params.skip_rseqc && 'infer_experiment' in rseqc_modules) {
        process {
            withName: '.*:RSEQC:RSEQC_INFEREXPERIMENT' {
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/rseqc/infer_experiment" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }

    if (!params.skip_rseqc && 'junction_annotation' in rseqc_modules) {
        process {
            withName: '.*:RSEQC:RSEQC_JUNCTIONANNOTATION' {
                publishDir = [
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/pdf" },
                        mode: params.publish_dir_mode,
                        pattern: '*.pdf'
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/bed" },
                        mode: params.publish_dir_mode,
                        pattern: '*.bed'
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/xls" },
                        mode: params.publish_dir_mode,
                        pattern: '*.xls'
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/log" },
                        mode: params.publish_dir_mode,
                        pattern: '*.log'
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/junction_annotation/rscript" },
                        mode: params.publish_dir_mode,
                        pattern: '*.r'
                    ]
                ]
            }
        }
    }

    if (!params.skip_rseqc && 'junction_saturation' in rseqc_modules) {
        process {
            withName: '.*:RSEQC:RSEQC_JUNCTIONSATURATION' {
                publishDir = [
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/junction_saturation/pdf" },
                        mode: params.publish_dir_mode,
                        pattern: '*.pdf'
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/junction_saturation/rscript" },
                        mode: params.publish_dir_mode,
                        pattern: '*.r'
                    ]
                ]
            }
        }
    }

    if (!params.skip_rseqc && 'read_duplication' in rseqc_modules) {
        process {
            withName: '.*:RSEQC:RSEQC_READDUPLICATION' {
                publishDir = [
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/pdf" },
                        mode: params.publish_dir_mode,
                        pattern: '*.pdf'
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/xls" },
                        mode: params.publish_dir_mode,
                        pattern: '*.xls'
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/read_duplication/rscript" },
                        mode: params.publish_dir_mode,
                        pattern: '*.r'
                    ]
                ]
            }
        }
    }

    if (!params.skip_rseqc && 'read_distribution' in rseqc_modules && !params.bam_csi_index) {
        process {
            withName: '.*:RSEQC:RSEQC_READDISTRIBUTION' {
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/rseqc/read_distribution" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }

    if (!params.skip_rseqc && 'inner_distance' in rseqc_modules && !params.bam_csi_index) {
        process {
            withName: '.*:RSEQC:RSEQC_INNERDISTANCE' {
                publishDir = [
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/txt" },
                        mode: params.publish_dir_mode,
                        pattern: '*.txt',
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/pdf" },
                        mode: params.publish_dir_mode,
                        pattern: '*.pdf'
                    ],
                    [
                        path: { "${params.outdir}/${params.aligner}/rseqc/inner_distance/rscript" },
                        mode: params.publish_dir_mode,
                        pattern: '*.r'
                    ]
                ]
            }
        }
    }

    if (!params.skip_rseqc && 'tin' in rseqc_modules && !params.bam_csi_index) {
        process {
            withName: '.*:RSEQC:RSEQC_TIN' {
                publishDir = [
                    path: { "${params.outdir}/${params.aligner}/rseqc/tin" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }

    if (!params.skip_rseqc && rseqc_modules) {
        process {
            withName: 'MULTIQC_TSV_STRAND_CHECK' {
                publishDir = [
                    path: { "${params.outdir}/multiqc" },
                    enabled: false
                ]
            }
        }
    }
}

if (!params.skip_multiqc) {
    process {
        withName: 'MULTIQC' {
            ext.args   = params.multiqc_title ? "--title \"$params.multiqc_title\"" : ''
            publishDir = [
                path: { [
                    "${params.outdir}/multiqc",
                    params.skip_alignment? '' : "/${params.aligner}"
                    ].join('') },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        }
    }
}

//
// Salmon pseudo-alignment options
//

if (params.pseudo_aligner == 'salmon') {
    process {
        withName: '.*:QUANTIFY_SALMON:SALMON_QUANT' {
            publishDir = [
                path: { "${params.outdir}/${params.pseudo_aligner}" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        }

        withName: '.*:QUANTIFY_SALMON:SALMON_TX2GENE' {
            publishDir = [
                path: { "${params.outdir}/${params.pseudo_aligner}" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        }

        withName: '.*:QUANTIFY_SALMON:SALMON_TXIMPORT' {
            publishDir = [
                path: { "${params.outdir}/${params.pseudo_aligner}" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        }

        withName: '.*:QUANTIFY_SALMON:SALMON_SE_.*' {
            publishDir = [
                path: { "${params.outdir}/${params.pseudo_aligner}" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        }
    }

    if (!params.skip_qc & !params.skip_deseq2_qc) {
        process {
            withName: 'DESEQ2_QC_SALMON' {
                ext.args   = [
                    "--id_col 1",
                    "--sample_suffix ''",
                    "--outprefix deseq2",
                    "--count_col 3",
                    params.deseq2_vst ? '--vst TRUE' : ''
                ].join(' ').trim()
                ext.args2  = 'salmon'
                publishDir = [
                    path: { "${params.outdir}/${params.pseudo_aligner}/deseq2_qc" },
                    mode: params.publish_dir_mode,
                    pattern: "*{RData,pca.vals.txt,plots.pdf,sample.dists.txt,size_factors,log}"
                ]
            }
        }
    }
}
