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

process {

    publishDir = [
        path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
        mode: params.publish_dir_mode,
        enabled: false
    ]

    withName: RENAME_RAW_DATA_FILES {
        // copy in case cutadapt is skipped, because the next step (DADA2's filterAndTrim) follows soft links and ignores renamed file names
        ext.args = params.skip_cutadapt ? 'cp' : 'ln -s'
        publishDir = [
            path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
            mode: params.publish_dir_mode,
            enabled: false
        ]
    }

    withName: FASTQC {
        ext.args = '--quiet'
        publishDir = [
            path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
            mode: params.publish_dir_mode,
            pattern: "*.html"
        ]
    }

    withName: CUTADAPT_BASIC {
        ext.args = { [
            "--minimum-length 1",
            "-O ${params.cutadapt_min_overlap}",
            "-e ${params.cutadapt_max_error_rate}",
            params.pacbio ? "--rc -g ${meta.fw_primer}...${meta.rv_primer_revcomp}" :
                params.iontorrent ? "--rc -g ${meta.fw_primer}...${meta.rv_primer_revcomp}" :
                params.single_end ? "-g ${meta.fw_primer}" :
                "-g ${meta.fw_primer} -G ${meta.rv_primer}",
            params.retain_untrimmed ? '' : "--discard-untrimmed"
        ].join(' ').trim() }
        ext.prefix = { "${meta.id}.trimmed" }
        publishDir = [
            path: { "${params.outdir}/cutadapt" },
            mode: params.publish_dir_mode,
            pattern: "*.log"
        ]
    }

    withName: CUTADAPT_READTHROUGH {
        ext.args = { [
            "--minimum-length 1",
            "-O ${params.cutadapt_min_overlap}",
            "-e ${params.cutadapt_max_error_rate}",
            "-a ${meta.rv_primer_revcomp} -A ${meta.fw_primer_revcomp}"
        ].join(' ').trim() }
        ext.prefix = { "${meta.id}.read-through" }
        publishDir = [
            path: { "${params.outdir}/cutadapt" },
            mode: params.publish_dir_mode,
            pattern: "*.log"
        ]
    }

    withName: CUTADAPT_DOUBLEPRIMER {
        ext.args = { [
            "--discard-trimmed --minimum-length 1",
            "-O ${params.cutadapt_min_overlap}",
            "-e ${params.cutadapt_max_error_rate}",
            params.pacbio ? "--rc -g ${meta.fw_primer}...${meta.rv_primer_revcomp}" :
                params.iontorrent ? "--rc -g ${meta.fw_primer}...${meta.rv_primer_revcomp}" :
                params.single_end ? "-g ${meta.fw_primer}" :
                "-g ${meta.fw_primer} -G ${meta.rv_primer}"
        ].join(' ').trim() }
        ext.prefix = { "${meta.id}.double-primer" }
        publishDir = [
            path: { "${params.outdir}/cutadapt" },
            mode: params.publish_dir_mode,
            pattern: "*.log"
        ]
    }

    withName: CUTADAPT_TAXONOMY {
        ext.args = { "--discard-untrimmed --minimum-length 1 -g ${meta.fw_primer}...${meta.rv_primer_revcomp}" }
        publishDir = [
            path: { "${params.outdir}/cutadapt" },
            mode: params.publish_dir_mode,
            pattern: "*.log"
        ]
    }

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

    withName: DADA2_QUALITY1 {
        ext.args = ", n = 5e+04, aggregate = TRUE"
        publishDir = [
            [
                path: { "${params.outdir}/dada2/QC" },
                mode: params.publish_dir_mode,
                pattern: "*{.pdf,plotQualityProfile.txt}"
            ],
            [
                path: { "${params.outdir}/dada2/QC/svg" },
                mode: params.publish_dir_mode,
                pattern: "*{.svg}"
            ],
            [
                path: { "${params.outdir}/dada2/args" },
                mode: params.publish_dir_mode,
                pattern: "*.args.txt"
            ]
        ]
    }

    withName: TRUNCLEN {
        ext.args = "${params.trunc_qmin} ${params.trunc_rmin}"
        publishDir = [
            path: { "${params.outdir}/dada2" },
            mode: params.publish_dir_mode,
            enabled: false
        ]
    }

    max_len = params.max_len ?: "Inf"
    withName: DADA2_FILTNTRIM {
        ext.args = [
            'maxN = 0, truncQ = 2, trimRight = 0, minQ = 0, rm.lowcomplex = 0, orient.fwd = NULL, matchIDs = FALSE, id.sep = "\\\\s", id.field = NULL, n = 1e+05, OMP = TRUE, qualityType = "Auto"',
            params.pacbio || params.iontorrent || params.single_end ? "maxEE = ${params.max_ee}" : "maxEE = c(${params.max_ee}, ${params.max_ee})",
            params.pacbio ? "trimLeft = 0, minLen = ${params.min_len}, maxLen = $max_len, rm.phix = FALSE" :
                params.iontorrent ? "trimLeft = 15, minLen = ${params.min_len}, maxLen = $max_len, rm.phix = TRUE" :
                params.illumina_pe_its ? "trimLeft = 0, minLen = ${params.min_len}, maxLen = $max_len, rm.phix = TRUE" :
                "trimLeft = 0, minLen = ${params.min_len}, maxLen = $max_len, rm.phix = TRUE"
        ].join(',').replaceAll('(,)*$', "")
        publishDir = [
            path: { "${params.outdir}/dada2/args" },
            mode: params.publish_dir_mode,
            pattern: "*.args.txt"
        ]
    }

    withName: DADA2_QUALITY2 {
        ext.args = ", n = 5e+04, aggregate = TRUE"
        ext.prefix = { "${meta}_preprocessed" }
        publishDir = [
            [
                path: { "${params.outdir}/dada2/QC" },
                mode: params.publish_dir_mode,
                pattern: "*{.pdf}"
            ],
            [
                path: { "${params.outdir}/dada2/QC/svg" },
                mode: params.publish_dir_mode,
                pattern: "*{.svg}"
            ],
            [
                path: { "${params.outdir}/dada2/args" },
                mode: params.publish_dir_mode,
                pattern: "*.args.txt"
            ]
        ]
    }

    withName: DADA2_ERR {
        ext.seed = "${params.seed}"
        ext.prefix = { meta.region ? "region-${meta.region}_run-${meta.run}" : "${meta.run}" }
        ext.args = [
            'nbases = 1e8, nreads = NULL, randomize = TRUE, MAX_CONSIST = 10, OMEGA_C = 0, qualityType = "Auto"',
            params.pacbio ? "errorEstimationFunction = PacBioErrfun" : "errorEstimationFunction = loessErrfun"
        ].join(',').replaceAll('(,)*$', "")
        publishDir = [
            [
                path: { "${params.outdir}/dada2/QC" },
                mode: params.publish_dir_mode,
                pattern: "*{.pdf,convergence.txt}"
            ],
            [
                path: { "${params.outdir}/dada2/QC/svg" },
                mode: params.publish_dir_mode,
                pattern: "*{.svg}"
            ],
            [
            path: { "${params.outdir}/dada2/args" },
            mode: params.publish_dir_mode,
            pattern: "*.args.txt"
            ],
            [
            path: { "${params.outdir}/dada2/log" },
            mode: params.publish_dir_mode,
            pattern: "*.log"
            ]
        ]
    }

    withName: NOVASEQ_ERR {
        publishDir = [
            [
                path: { "${params.outdir}/dada2/QC" },
                mode: params.publish_dir_mode,
                pattern: "*{.pdf,convergence.txt}"
            ],
            [
                path: { "${params.outdir}/dada2/QC/svg" },
                mode: params.publish_dir_mode,
                pattern: "*{.svg}"
            ]
        ]
    }

    withName: DADA2_DENOISING {
        ext.prefix = { meta.region ? "region-${meta.region}_run-${meta.run}" : "${meta.run}" }
        // standard setting can be inspected with getDadaOpt(option = NULL)
        ext.args = [
            'selfConsist = FALSE, priors = character(0), DETECT_SINGLETONS = FALSE, GAPLESS = TRUE, GAP_PENALTY = -8, GREEDY = TRUE, KDIST_CUTOFF = 0.42, MATCH = 5, MAX_CLUST = 0, MAX_CONSIST = 10, MIN_ABUNDANCE = 1, MIN_FOLD = 1, MIN_HAMMING = 1, MISMATCH = -4, OMEGA_A = 1e-40, OMEGA_C = 1e-40, OMEGA_P = 1e-4, PSEUDO_ABUNDANCE = Inf, PSEUDO_PREVALENCE = 2, SSE = 2, USE_KMERS = TRUE, USE_QUALS = TRUE, VECTORIZED_ALIGNMENT = TRUE',
            params.iontorrent ? "BAND_SIZE = 32, HOMOPOLYMER_GAP_PENALTY = -1" : "BAND_SIZE = 16, HOMOPOLYMER_GAP_PENALTY = NULL",
            params.sample_inference == "pseudo" ? "pool = \"pseudo\"" :
                params.sample_inference == "pooled" ? "pool = TRUE" : "pool = FALSE"
        ].join(',').replaceAll('(,)*$', "")
        // setting from https://rdrr.io/bioc/dada2/man/mergePairs.html & https://rdrr.io/bioc/dada2/man/nwalign.html & match = getDadaOpt("MATCH"), mismatch = getDadaOpt("MISMATCH"), gap = getDadaOpt("GAP_PENALTY"), missing from the list below is: 'band = -1'
        ext.args2 = [
            'minOverlap = 12, maxMismatch = 0, returnRejects = FALSE, propagateCol = character(0), trimOverhang = FALSE, match = 1, mismatch = -64, gap = -64, homo_gap = NULL, endsfree = TRUE, vec = FALSE',
            params.concatenate_reads ? "justConcatenate = TRUE" : "justConcatenate = FALSE"
        ].join(',').replaceAll('(,)*$', "")
        publishDir = [
            [
                path: { "${params.outdir}/dada2/args" },
                mode: params.publish_dir_mode,
                pattern: "*.args.txt"
            ],
            [
                path: { "${params.outdir}/dada2/log" },
                mode: params.publish_dir_mode,
                pattern: "*.log"
            ]
        ]
    }

    withName: DADA2_RMCHIMERA {
        ext.prefix = { meta.region ? "region-${meta.region}_run-${meta.run}" : "${meta.run}" }
        ext.args = 'method="consensus", minSampleFraction = 0.9, ignoreNNegatives = 1, minFoldParentOverAbundance = 2, minParentAbundance = 8, allowOneOff = FALSE, minOneOffParentDistance = 4, maxShift = 16'
        publishDir = [
            path: { "${params.outdir}/dada2/args" },
            mode: params.publish_dir_mode,
            pattern: "*.args.txt"
        ]
    }

    withName: DADA2_STATS {
        ext.prefix = { meta.region ? "region-${meta.region}_run-${meta.run}" : "${meta.run}" }
    }

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

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

    withName: SIDLE_DBFILT {
        ext.args = { params.sidle_ref_taxonomy.startsWith("greengenes") ? '--p-num-degenerates 3' : '--p-num-degenerates 5' } // 3 for greengenes, 5 for SILVA 128
        ext.args2 = { params.sidle_ref_taxonomy.startsWith("greengenes") ? '--p-exclude "p__;,k__;,mitochondria,chloroplast" --p-mode contains' : '--p-exclude "mitochondria,chloroplast" --p-mode contains' } // "p__;,k__;" for greengenes
        publishDir = [
            path: { "${params.outdir}/sidle/DB/1_prefiltering" },
            mode: params.publish_dir_mode,
            pattern: "*.qza",
            enabled: params.save_intermediates
        ]
    }

    withName: SIDLE_DBEXTRACT {
        ext.args = '--p-identity 2'
        publishDir = [
            path: { "${params.outdir}/sidle/DB/2_primer_extraction" },
            mode: params.publish_dir_mode,
            pattern: "*.qza",
            enabled: params.save_intermediates
        ]
    }

    withName: SIDLE_TRIM {
        publishDir = [
            path: { "${params.outdir}/sidle/ASV/1_trim" },
            mode: params.publish_dir_mode,
            pattern: "*.qza",
            enabled: params.save_intermediates
        ]
    }

    withName: SIDLE_ALIGN {
        ext.args = ''
        publishDir = [
            path: { "${params.outdir}/sidle/ASV/2_align_db" },
            mode: params.publish_dir_mode,
            pattern: "*.qza",
            enabled: params.save_intermediates
        ]
    }

    withName: SIDLE_DBRECON {
        ext.args = ''
        publishDir = [
            [
                path: { "${params.outdir}/sidle/DB/3_reconstructed" },
                mode: params.publish_dir_mode,
                pattern: "*.qza",
                enabled: params.save_intermediates
            ],
            [
                path: { "${params.outdir}/sidle/DB/3_reconstructed" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.endsWith('.qza') || filename.equals('versions.yml') ? null : filename }
            ]
        ]
    }

    withName: SIDLE_TABLERECON {
        ext.args = "--p-min-counts 0"
        publishDir = [
            [
                path: { "${params.outdir}/sidle/reconstructed/qza" },
                mode: params.publish_dir_mode,
                pattern: "*.qza",
                enabled: params.save_intermediates
            ],
            [
                path: { "${params.outdir}/sidle/reconstructed" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.endsWith('.qza') || filename.equals('versions.yml') ? null : filename }
            ]
        ]
    }

    withName: SIDLE_TAXRECON {
        ext.args = {
            params.sidle_ref_taxonomy.startsWith("greengenes") ? '--p-database "greengenes"' :
                params.sidle_ref_taxonomy.startsWith("silva") ? '--p-database "silva"' : '--p-database "none"'
            }
        publishDir = [
            [
                path: { "${params.outdir}/sidle/reconstructed/qza" },
                mode: params.publish_dir_mode,
                pattern: "*.qza",
                enabled: params.save_intermediates
            ],
            [
                path: { "${params.outdir}/sidle/reconstructed" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.endsWith('.qza') || filename.equals('versions.yml') ? null : filename },
                enabled: params.save_intermediates
            ]
        ]
    }

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

    withName: SIDLE_SEQRECON {
        publishDir = [
            [
                path: { "${params.outdir}/sidle/reconstructed/qza" },
                mode: params.publish_dir_mode,
                pattern: "*.qza",
                enabled: params.save_intermediates
            ],
            [
                path: { "${params.outdir}/sidle/reconstructed" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.endsWith('.qza') || filename.equals('versions.yml') ? null : filename },
                enabled: params.save_intermediates
            ]
        ]
    }

    withName: SIDLE_TREERECON {
        publishDir = [
            [
                path: { "${params.outdir}/sidle/reconstructed/qza" },
                mode: params.publish_dir_mode,
                pattern: "*.qza",
                enabled: params.save_intermediates
            ],
            [
                path: { "${params.outdir}/sidle/reconstructed" },
                mode: params.publish_dir_mode,
                pattern: "*.nwk"
            ]
        ]
    }

    withName: BARRNAP {
        ext.kingdom = "bac,arc,mito,euk"
        ext.args = "--quiet --reject 0.1"
        publishDir = [
            path: { "${params.outdir}/barrnap" },
            mode: params.publish_dir_mode,
            pattern: "*.gff"
        ]
    }

    withName: BARRNAPSUMMARY {
        publishDir = [
            path: { "${params.outdir}/barrnap" },
            mode: params.publish_dir_mode,
            pattern: "summary.tsv"
        ]
    }

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

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

    withName: FILTER_CODONS {
        ext.args = [params.orf_start ? "-s ${params.orf_start}" : '',
            params.orf_end ? "-e ${params.orf_end}" : '',
            params.stop_codons ? "-x ${params.stop_codons}" : ''
        ].join(' ')
        publishDir = [
            path: { "${params.outdir}/codon_filter" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'MERGE_STATS_STD|MERGE_STATS_FILTERSSU|MERGE_STATS_FILTERTAXA|MERGE_STATS_CODONS' {
        publishDir = [
            path: { "${params.outdir}" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: ITSX_CUTASV {
        ext.args = [
            '-t all --preserve T --date F --positions F --graphical F',
            params.cut_its == "its1" ? "--save_regions ITS1" :
                params.cut_its == "its2" ? "--save_regions ITS2" : "--save_regions none",
            params.its_partial != 0 ? "--partial ${params.its_partial}" : ""
        ].join(' ').trim()
        publishDir = [
            path: { "${params.outdir}/itsx" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: FILTER_LEN_ITSX {
        ext.min_len_asv = 50
        publishDir = [
            path: { "${params.outdir}/itsx" },
            mode: params.publish_dir_mode,
            pattern: "ASV_*"
        ]
    }

    withName: 'FORMAT_TAXONOMY|FORMAT_TAXRESULTS' {
        publishDir = [
            path: { "${params.outdir}/dada2" },
            mode: params.publish_dir_mode,
            pattern: "{ref_taxonomy*.txt,ASV_tax*.tsv,ASV_tax_species*.tsv}"
        ]
    }

    withName: DADA2_TAXONOMY {
        ext.seed = "${params.seed}"
        ext.args = [
            'minBoot = 50',
            params.dada_taxonomy_rc || params.pacbio || params.iontorrent ? "tryRC = TRUE" : "tryRC = FALSE"
        ].join(',').replaceAll('(,)*$', "")
        publishDir = [
            [
                path: { "${params.outdir}/dada2/args" },
                mode: params.publish_dir_mode,
                pattern: "*.args.txt"
            ],
            [
                path: { "${params.outdir}/dada2" },
                mode: params.publish_dir_mode,
                pattern: "*.tsv"
            ]
        ]
    }

    withName: DADA2_ADDSPECIES {
        ext.seed = "${params.seed}"
        ext.args = [
            'n = 1e5',
            params.dada_addspecies_allowmultiple ? "allowMultiple = TRUE" : "",
            params.dada_taxonomy_rc || params.pacbio || params.iontorrent ? "tryRC = TRUE" : "tryRC = FALSE"
        ].join(',').replaceAll('(,)*$', "")
        publishDir = [
            [
                path: { "${params.outdir}/dada2/args" },
                mode: params.publish_dir_mode,
                pattern: "*.args.txt"
            ],
            [
                path: { "${params.outdir}/dada2" },
                mode: params.publish_dir_mode,
                pattern: "*.tsv"
            ]
        ]
    }

    withName: FORMAT_TAXONOMY_SINTAX {
        publishDir = [
            path: { "${params.outdir}/sintax" },
            mode: params.publish_dir_mode,
            pattern: "{ref_taxonomy_sintax.txt}"
        ]
    }

    withName: VSEARCH_SINTAX {
        ext.args = "--sintax_cutoff 0.8 --randseed ${params.seed}"
        cpus = 1
        publishDir = [
            [
                path: { "${params.outdir}/sintax" },
                mode: params.publish_dir_mode,
                pattern: "*.tsv"
            ]
        ]
    }

    withName: FORMAT_TAXRESULTS_SINTAX {
        publishDir = [
            path: { "${params.outdir}/sintax" },
            mode: params.publish_dir_mode,
            pattern: "*.tsv"
        ]
    }

    withName: KRAKEN2_KRAKEN2 {
        // "--use-names" is required for downstream processes!
        ext.args = "--use-names --confidence ${params.kraken2_confidence}"
        publishDir = [
            path: { "${params.outdir}/kraken2" },
            mode: params.publish_dir_mode,
            pattern: "{*.txt,*classified*}"
        ]
    }

    withName: 'FORMAT_TAXRESULTS_KRAKEN2' {
        publishDir = [
            path: { "${params.outdir}/kraken2" },
            mode: params.publish_dir_mode,
            pattern: "*.tsv"
        ]
    }

    withName: VSEARCH_USEARCHGLOBAL {
        ext.args = '--top_hits_only --output_no_hits --maxaccepts 50 --query_cov 0.9'
        publishDir = [
            [
                path: { "${params.outdir}/assignsh" },
                mode: params.publish_dir_mode,
                pattern: "*.txt"
            ]
        ]
    }

    withName: VSEARCH_CLUSTER {
        ext.args = "--id ${params.vsearch_cluster_id} --usersort --qmask 'none'"
        ext.args2 = '--cluster_smallmem'
        ext.args3 = '--clusters'
    }

    withName: FILTER_CLUSTERS {
        publishDir = [
            [
                path: { "${params.outdir}/vsearch_cluster" },
                mode: params.publish_dir_mode,
                pattern: "*{.tsv,.fna}"
            ]
        ]
    }

    withName: ASSIGNSH {
        publishDir = [
            [
                path: { "${params.outdir}/assignsh" },
                mode: params.publish_dir_mode,
                pattern: "*.tsv"
            ]
        ]
    }

    withName: FORMAT_TAXONOMY_QIIME {
        publishDir = [
            path: { "${params.outdir}/qiime2/taxonomy" },
            mode: params.publish_dir_mode,
            pattern: "ref_taxonomy.txt"
        ]
    }

    withName: 'QIIME2_EXTRACT|QIIME2_TRAIN|QIIME2_CLASSIFY' {
        publishDir = [
            path: { "${params.outdir}/qiime2/taxonomy" },
            mode: params.publish_dir_mode,
            pattern: "*{-classifier.qza,.tsv}"
        ]
    }

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

    withName: HMMER_UNALIGNREF {
        ext.prefix = { "${meta.id}.ref.unaligned" }
        ext.args   = "--gapsym=- afa"
        ext.postprocessing = '| sed "/^>/!s/-//g"'
        publishDir = [
            path: { "${params.outdir}/pplace/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

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

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

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

    withName: 'HMMER_MASKQUERY.*' {
        ext.prefix = { "${meta.id}.query.hmmalign" }
        publishDir = [
            path: { "${params.outdir}/pplace/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'HMMER_MASKREF.*' {
        ext.prefix = { "${meta.id}.ref.hmmalign" }
        publishDir = [
            path: { "${params.outdir}/pplace/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'HMMER_AFAFORMATQUERY.*' {
        ext.prefix = { "${meta.id}.query.hmmalign.masked" }
        ext.args   = 'afa'
        publishDir = [
            path: { "${params.outdir}/pplace/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'HMMER_AFAFORMATREF.*' {
        ext.prefix = { "${meta.id}.ref.hmmalign.masked" }
        ext.args   = 'afa'
        publishDir = [
            path: { "${params.outdir}/pplace/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

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

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

    withName: 'GAPPA_GRAFT' {
        ext.prefix = { "${meta.id}.graft" }
        //test_pplace.graft.test_pplace.epa_result.newick
        publishDir = [
            [
                path: { "${params.outdir}/pplace" },
                mode: params.publish_dir_mode,
                pattern: "*.newick"
            ],
            [
                path: { "${params.outdir}/pplace/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        ]
    }

    withName: 'GAPPA_ASSIGN' {
        ext.prefix = { "${meta.id}.taxonomy" }
        ext.args   = "--per-query-results --krona --sativa"
        ext.when   = { taxonomy }
        publishDir = [
            [
                path: { "${params.outdir}/pplace" },
                mode: params.publish_dir_mode,
                pattern: "*.taxonomy.per_query.tsv"
            ],
            [
                path: { "${params.outdir}/pplace/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        ]
    }

    withName: 'GAPPA_HEATTREE' {
        ext.prefix = { "${meta.id}.heattree" }
        ext.args = "--write-nexus-tree --write-phyloxml-tree --write-svg-tree"
        publishDir = [
            [
                path: { "${params.outdir}/pplace" },
                mode: params.publish_dir_mode,
                pattern: "*.tree.svg"
            ],
            [
                path: { "${params.outdir}/pplace/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        ]
    }

    withName: 'QIIME2_INASV|QIIME2_INSEQ|QIIME2_INTAX|QIIME2_INTREE' {
        publishDir = [
            path: { "${params.outdir}/qiime2/input" },
            mode: params.publish_dir_mode,
            pattern: "*.qza"
        ]
    }

    withName: FORMAT_PPLACETAX {
        publishDir = [
            path: { "${params.outdir}/pplace" },
            mode: params.publish_dir_mode,
            pattern: "*.per_query_unique.tsv"
        ]
    }

    withName: 'QIIME2_INASV_BPAVG' {
        publishDir = [
            path: { "${params.outdir}/qiime2/barplot_average" },
            mode: params.publish_dir_mode,
            pattern: "*.qza",
            enabled: params.save_intermediates
        ]
    }

    withName: 'QIIME2_TABLEFILTERTAXA|QIIME2_SEQFILTERTABLE' {
        publishDir = [
            [
                path: { "${params.outdir}/qiime2/abundance_tables" },
                mode: params.publish_dir_mode,
                pattern: "*table.qza"
            ],
            [
                path: { "${params.outdir}/qiime2/representative_sequences" },
                mode: params.publish_dir_mode,
                pattern: "*sequences.qza"
            ]
        ]
    }

    withName: FILTER_STATS {
        publishDir = [
            path: { "${params.outdir}/qiime2/abundance_tables" },
            mode: params.publish_dir_mode,
            pattern: "*.tsv"
        ]
    }

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

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

    withName: QIIME2_EXPORT_ABSOLUTE {
        publishDir = [
            [
                path: { "${params.outdir}/qiime2/representative_sequences" },
                mode: params.publish_dir_mode,
                pattern: "{descriptive_stats.tsv,seven_number_summary.tsv}"
            ],
            [
                path: { "${params.outdir}/qiime2/abundance_tables" },
                mode: params.publish_dir_mode,
                pattern: "{feature-table.tsv,feature-table.biom}"
            ],
            [
                path: { "${params.outdir}/qiime2/abundance_tables" },
                mode: params.publish_dir_mode,
                pattern: "abs-abund-table-*.tsv"
            ],
            [
                path: { "${params.outdir}/qiime2/representative_sequences" },
                mode: params.publish_dir_mode,
                pattern: "*.fasta"
            ]
        ]
    }

    withName: 'QIIME2_EXPORT_RELASV|QIIME2_EXPORT_RELTAX|COMBINE_TABLE' {
        publishDir = [
            path: { "${params.outdir}/qiime2/rel_abundance_tables" },
            mode: params.publish_dir_mode,
            pattern: "*.tsv"
        ]
    }

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

    withName: QIIME2_FILTERSAMPLES_ANCOM {
        ext.args = { "--p-where \'${filter}<>\"\"\' --p-min-frequency ${params.ancom_sample_min_count}" }
        ext.prefix = { "$filter" }
    }

    withName: QIIME2_ALPHARAREFACTION {
        publishDir = [
            [
                path: { "${params.outdir}/qiime2" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') || filename.endsWith('.qzv') ? null : filename }
            ],
            [
                path: { "${params.outdir}/qiime2/alpha-rarefaction" },
                mode: params.publish_dir_mode,
                pattern: "*.qzv",
                enabled: params.save_intermediates
            ]
        ]
    }

    withName: 'QIIME2_DIVERSITY_CORE|QIIME2_DIVERSITY_ALPHA|QIIME2_DIVERSITY_BETA|QIIME2_DIVERSITY_BETAORD' {
        publishDir = [
            [
                path: { "${params.outdir}/qiime2/diversity" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') || filename.endsWith('.qza') || filename.endsWith('.qzv') ? null : filename }
            ],
            [
                path: { "${params.outdir}/qiime2/diversity/qza_qzv" },
                mode: params.publish_dir_mode,
                pattern: "*{.qza,.qzv}",
                enabled: params.save_intermediates
            ],
            [
                path: { "${params.outdir}/qiime2/diversity/qza_qzv" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.endsWith('.qza') ? filename : null },
                enabled: params.save_intermediates
            ]
        ]
    }

    withName: QIIME2_DIVERSITY_ADONIS {
        publishDir = [
            [
                path: { "${params.outdir}/qiime2/diversity/beta_diversity" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') || filename.endsWith('.qzv') ? null : filename }
            ],
            [
                path: { "${params.outdir}/qiime2/diversity/beta_diversity/adonis" },
                mode: params.publish_dir_mode,
                pattern: "*.qzv",
                enabled: params.save_intermediates
            ]
        ]
    }

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

    withName: 'QIIME2_ANCOMBC_TAX|QIIME2_ANCOMBC_ASV' {
        // additional arguments for "qiime composition ancombc", deviating from default: --p-lib-cut (0), --p-conserve (--p-no-conserve)
        ext.args = '--p-prv-cut 0.1 --p-lib-cut 500 --p-alpha 0.05 --p-conserve'
        // additional arguments for "qiime composition da-barplot"
        ext.args2 = { [
            params.ancombc_effect_size ? "--p-effect-size-threshold ${params.ancombc_effect_size}" : '',
            params.ancombc_significance ? "--p-significance-threshold ${params.ancombc_significance}" : '',
            '--p-label-limit 1000'
        ].join(' ') }
        publishDir = [
            [
                path: { "${params.outdir}/qiime2/ancombc" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') || filename.endsWith('.qzv') || filename.endsWith('.qza') ? null : filename }
            ],
            [
                path: { "${params.outdir}/qiime2/ancombc/qza_qzv" },
                mode: params.publish_dir_mode,
                pattern: "*{.qza,.qzv}",
                enabled: params.save_intermediates
            ]
        ]
    }

    withName: 'ANCOMBC_FORMULA_TAX|ANCOMBC_FORMULA_ASV' {
        // additional arguments for "qiime composition ancombc", deviating from default: --p-lib-cut (0), --p-conserve (--p-no-conserve)
        ext.args = { [
            params.ancombc_formula_reflvl ? "--p-reference-levels ${params.ancombc_formula_reflvl}" : '',
            '--p-prv-cut 0.1 --p-lib-cut 500 --p-alpha 0.05 --p-conserve'
        ].join(' ') }
        // additional arguments for "qiime composition da-barplot"
        ext.args2 = { [
            params.ancombc_effect_size ? "--p-effect-size-threshold ${params.ancombc_effect_size}" : '',
            params.ancombc_significance ? "--p-significance-threshold ${params.ancombc_significance}" : '',
            '--p-label-limit 1000'
        ].join(' ') }
        publishDir = [
            [
                path: { "${params.outdir}/qiime2/ancombc_formula" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') || filename.endsWith('.qzv') || filename.endsWith('.qza') ? null : filename }
            ],
            [
                path: { "${params.outdir}/qiime2/ancombc_formula/qza_qzv" },
                mode: params.publish_dir_mode,
                pattern: "*{.qza,.qzv}",
                enabled: params.save_intermediates
            ]
        ]
    }

    withName: PICRUST {
        ext.args = "-t epa-ng --remove_intermediate"
        publishDir = [
            path: { "${params.outdir}/picrust" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: SBDIEXPORT {
        ext.args = [
            params.single_end ? 'single' : 'paired',
            "${params.FW_primer}",
            "${params.RV_primer}"
        ].join(' ').trim()
        publishDir = [
            path: { "${params.outdir}/SBDI" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

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

    withName: PHYLOSEQ {
        publishDir = [
            path: { "${params.outdir}/phyloseq" },
            mode: params.publish_dir_mode,
            pattern: "*.rds"
        ]
    }
    withName: 'MULTIQC' {
        ext.args   = { params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' }
        publishDir = [
            path: { "${params.outdir}/multiqc" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: SUMMARY_REPORT {
        publishDir = [
            path: { "${params.outdir}/summary_report" },
            mode: params.publish_dir_mode
        ]
    }
}
