kkonganti@1: // Define any required imports for this specific workflow kkonganti@1: import java.nio.file.Paths kkonganti@1: import java.util.zip.GZIPInputStream kkonganti@1: import java.io.FileInputStream kkonganti@1: import nextflow.file.FileHelper kkonganti@1: kkonganti@1: kkonganti@1: // Include any necessary methods kkonganti@1: include { \ kkonganti@1: summaryOfParams; stopNow; fastqEntryPointHelp; sendMail; \ kkonganti@1: addPadding; wrapUpHelp } from "${params.routines}" kkonganti@1: include { bbmergeHelp } from "${params.toolshelp}${params.fs}bbmerge" kkonganti@1: include { fastpHelp } from "${params.toolshelp}${params.fs}fastp" kkonganti@1: include { mashscreenHelp } from "${params.toolshelp}${params.fs}mashscreen" kkonganti@1: include { tuspyHelp } from "${params.toolshelp}${params.fs}tuspy" kkonganti@1: include { sourmashsketchHelp } from "${params.toolshelp}${params.fs}sourmashsketch" kkonganti@1: include { sourmashgatherHelp } from "${params.toolshelp}${params.fs}sourmashgather" kkonganti@1: include { sourmashsearchHelp } from "${params.toolshelp}${params.fs}sourmashsearch" kkonganti@1: include { sfhpyHelp } from "${params.toolshelp}${params.fs}sfhpy" kkonganti@1: include { kmaindexHelp } from "${params.toolshelp}${params.fs}kmaindex" kkonganti@1: include { kmaalignHelp } from "${params.toolshelp}${params.fs}kmaalign" kkonganti@1: include { salmonidxHelp } from "${params.toolshelp}${params.fs}salmonidx" kkonganti@1: include { gsrpyHelp } from "${params.toolshelp}${params.fs}gsrpy" kkonganti@1: kkonganti@1: // Exit if help requested before any subworkflows kkonganti@1: if (params.help) { kkonganti@1: log.info help() kkonganti@1: exit 0 kkonganti@1: } kkonganti@1: kkonganti@1: kkonganti@1: // Include any necessary modules and subworkflows kkonganti@1: include { PROCESS_FASTQ } from "${params.subworkflows}${params.fs}process_fastq" kkonganti@1: include { CAT_CAT } from "${params.modules}${params.fs}cat_cat${params.fs}main" kkonganti@1: include { FASTQC } from "${params.modules}${params.fs}fastqc${params.fs}main" kkonganti@1: include { BBTOOLS_BBMERGE } from "${params.modules}${params.fs}bbtools${params.fs}bbmerge${params.fs}main" kkonganti@1: include { FASTP } from "${params.modules}${params.fs}fastp${params.fs}main" kkonganti@1: include { MASH_SCREEN } from "${params.modules}${params.fs}mash${params.fs}screen${params.fs}main" kkonganti@1: include { TOP_UNIQUE_SEROVARS } from "${params.modules}${params.fs}top_unique_serovars${params.fs}main" kkonganti@1: include { SOURMASH_SKETCH } from "${params.modules}${params.fs}sourmash${params.fs}sketch${params.fs}main" kkonganti@1: include { SOURMASH_GATHER } from "${params.modules}${params.fs}sourmash${params.fs}gather${params.fs}main" kkonganti@1: include { SOURMASH_SEARCH } from "${params.modules}${params.fs}sourmash${params.fs}search${params.fs}main" kkonganti@1: include { KMA_INDEX } from "${params.modules}${params.fs}kma${params.fs}index${params.fs}main" kkonganti@1: include { KMA_ALIGN } from "${params.modules}${params.fs}kma${params.fs}align${params.fs}main" kkonganti@1: include { OTF_GENOME } from "${params.modules}${params.fs}otf_genome${params.fs}main" kkonganti@1: include { SALMON_INDEX } from "${params.modules}${params.fs}salmon${params.fs}index${params.fs}main" kkonganti@1: include { SALMON_QUANT } from "${params.modules}${params.fs}salmon${params.fs}quant${params.fs}main" kkonganti@1: include { SOURMASH_COMPARE } from "${params.modules}${params.fs}custom${params.fs}sourmash${params.fs}compare${params.fs}main" kkonganti@1: include { BCS_DISTANCE_MATRIX } from "${params.modules}${params.fs}bcs_distance_matrix${params.fs}main" kkonganti@1: include { BCS_RESULTS } from "${params.modules}${params.fs}bcs_results${params.fs}main" kkonganti@1: include { DUMP_SOFTWARE_VERSIONS } from "${params.modules}${params.fs}custom${params.fs}dump_software_versions${params.fs}main" kkonganti@1: include { MULTIQC } from "${params.modules}${params.fs}multiqc${params.fs}main" kkonganti@1: kkonganti@1: /* kkonganti@1: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@1: INPUTS AND ANY CHECKS FOR THE BETTERCALLSAL WORKFLOW kkonganti@1: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@1: */ kkonganti@1: kkonganti@1: def reads_platform = 0 kkonganti@1: def salmon_idx_decoys = file ( "${params.salmonidx_decoys}" ) kkonganti@1: kkonganti@1: reads_platform += (params.input ? 1 : 0) kkonganti@1: kkonganti@1: if (reads_platform < 1 || reads_platform == 0) { kkonganti@1: stopNow("Please mention at least one absolute path to input folder which contains\n" + kkonganti@1: "FASTQ files sequenced using the --input option.\n" + kkonganti@1: "Ex: --input (Illumina or Generic short reads in FASTQ format)") kkonganti@1: } kkonganti@1: kkonganti@1: checkMetadataExists(params.mash_sketch, 'MASH sketch') kkonganti@1: checkMetadataExists(params.tuspy_ps, 'ACC2SERO pickle') kkonganti@1: checkMetadataExists(params.gsrpy_snp_clus_metadata, 'PDG reference target cluster metadata') kkonganti@1: kkonganti@1: /* kkonganti@1: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@1: RUN THE BETTERCALLSAL WORKFLOW kkonganti@1: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@1: */ kkonganti@1: kkonganti@1: workflow BETTERCALLSAL { kkonganti@1: main: kkonganti@1: log.info summaryOfParams() kkonganti@1: kkonganti@1: PROCESS_FASTQ() kkonganti@1: kkonganti@1: PROCESS_FASTQ kkonganti@1: .out kkonganti@1: .versions kkonganti@1: .set { software_versions } kkonganti@1: kkonganti@1: PROCESS_FASTQ kkonganti@1: .out kkonganti@1: .processed_reads kkonganti@1: .set { ch_processed_reads } kkonganti@1: kkonganti@1: if (params.bbmerge_run && !params.fq_single_end) { kkonganti@1: ch_processed_reads kkonganti@1: .map { meta, fastq -> kkonganti@1: meta.adapters = (params.bbmerge_adapters ?: params.dummyfile) kkonganti@1: [ meta, fastq ] kkonganti@1: } kkonganti@1: .set { ch_processed_reads } kkonganti@1: kkonganti@1: BBTOOLS_BBMERGE( ch_processed_reads ) kkonganti@1: kkonganti@1: BBTOOLS_BBMERGE kkonganti@1: .out kkonganti@1: .fastq kkonganti@1: .map { meta, fastq -> kkonganti@1: [ meta, [ fastq ] ] kkonganti@1: } kkonganti@1: .set { ch_processed_reads } kkonganti@1: kkonganti@1: software_versions kkonganti@1: .mix ( BBTOOLS_BBMERGE.out.versions ) kkonganti@1: .set { software_versions } kkonganti@1: } kkonganti@1: kkonganti@1: if (params.fastp_run) { kkonganti@1: FASTP ( ch_processed_reads ) kkonganti@1: kkonganti@1: FASTP kkonganti@1: .out kkonganti@1: .passed_reads kkonganti@1: .set { ch_processed_reads } kkonganti@1: kkonganti@1: FASTP kkonganti@1: .out kkonganti@1: .json kkonganti@1: .map { meta, json -> [ json ] } kkonganti@1: .collect() kkonganti@1: .set { ch_multiqc } kkonganti@1: kkonganti@1: software_versions kkonganti@1: .mix ( FASTP.out.versions ) kkonganti@1: .set { software_versions } kkonganti@1: } else { kkonganti@1: FASTQC ( ch_processed_reads ) kkonganti@1: kkonganti@1: FASTQC kkonganti@1: .out kkonganti@1: .zip kkonganti@1: .map { meta, zip -> [ zip ] } kkonganti@1: .collect() kkonganti@1: .set { ch_multiqc } kkonganti@1: kkonganti@1: software_versions kkonganti@1: .mix ( FASTQC.out.versions ) kkonganti@1: .set { software_versions } kkonganti@1: } kkonganti@1: kkonganti@1: if (params.bcs_concat_pe && !params.fq_single_end && !params.bbmerge_run) { kkonganti@1: CAT_CAT ( ch_processed_reads ) kkonganti@1: kkonganti@1: CAT_CAT kkonganti@1: .out kkonganti@1: .concatenated_reads kkonganti@1: .set { ch_processed_reads } kkonganti@1: kkonganti@1: software_versions kkonganti@1: .mix ( CAT_CAT.out.versions ) kkonganti@1: .set { software_versions } kkonganti@1: } kkonganti@1: kkonganti@1: ch_processed_reads kkonganti@1: .map { meta, fastq -> kkonganti@1: meta.sequence_sketch = params.mash_sketch kkonganti@1: meta.get_kma_hit_accs = true kkonganti@1: meta.single_end = true kkonganti@1: meta.salmon_decoys = params.dummyfile kkonganti@1: meta.salmon_lib_type = (params.salmonalign_libtype ?: false) kkonganti@1: [ meta, fastq ] kkonganti@1: } kkonganti@1: .filter { meta, fastq -> kkonganti@1: fq_file = ( fastq.getClass().toString() =~ /ArrayList/ ? fastq : [ fastq ] ) kkonganti@1: fq_gzip = new GZIPInputStream( new FileInputStream( fq_file[0].toString() ) ) kkonganti@1: fq_gzip.read() != -1 kkonganti@1: } kkonganti@1: .set { ch_processed_reads } kkonganti@1: kkonganti@1: MASH_SCREEN ( ch_processed_reads ) kkonganti@1: kkonganti@1: TOP_UNIQUE_SEROVARS ( MASH_SCREEN.out.screened ) kkonganti@1: kkonganti@1: TOP_UNIQUE_SEROVARS.out.genomes_fasta kkonganti@1: .set { ch_genomes_fasta } kkonganti@1: kkonganti@1: TOP_UNIQUE_SEROVARS.out.failed kkonganti@1: .set { ch_bcs_calls_failed } kkonganti@1: kkonganti@1: if (params.sourmashgather_run || params.sourmashsearch_run) { kkonganti@1: SOURMASH_SKETCH ( kkonganti@1: ch_processed_reads kkonganti@1: .join ( ch_genomes_fasta ) kkonganti@1: ) kkonganti@1: kkonganti@1: if (params.sourmashgather_run) { kkonganti@1: SOURMASH_GATHER ( kkonganti@1: SOURMASH_SKETCH.out.signatures, kkonganti@1: [], [], [], [] kkonganti@1: ) kkonganti@1: kkonganti@1: SOURMASH_GATHER kkonganti@1: .out kkonganti@1: .genomes_fasta kkonganti@1: .set { ch_genomes_fasta } kkonganti@1: kkonganti@1: ch_bcs_calls_failed kkonganti@1: .concat( SOURMASH_GATHER.out.failed ) kkonganti@1: .set { ch_bcs_calls_failed } kkonganti@1: kkonganti@1: software_versions kkonganti@1: .mix ( SOURMASH_GATHER.out.versions.ifEmpty(null) ) kkonganti@1: .set { software_versions } kkonganti@1: } kkonganti@1: kkonganti@1: if (params.sourmashsearch_run) { kkonganti@1: SOURMASH_SEARCH ( kkonganti@1: SOURMASH_SKETCH.out.signatures, kkonganti@1: [] kkonganti@1: ) kkonganti@1: kkonganti@1: SOURMASH_SEARCH kkonganti@1: .out kkonganti@1: .genomes_fasta kkonganti@1: .set { ch_genomes_fasta } kkonganti@1: kkonganti@1: ch_bcs_calls_failed kkonganti@1: .concat( SOURMASH_SEARCH.out.failed ) kkonganti@1: .set { ch_bcs_calls_failed } kkonganti@1: kkonganti@1: software_versions kkonganti@1: .mix ( SOURMASH_SEARCH.out.versions.ifEmpty(null) ) kkonganti@1: .set { software_versions } kkonganti@1: } kkonganti@1: } kkonganti@1: kkonganti@1: KMA_INDEX ( ch_genomes_fasta ) kkonganti@1: kkonganti@1: KMA_ALIGN ( kkonganti@1: ch_processed_reads kkonganti@1: .join(KMA_INDEX.out.idx) kkonganti@1: ) kkonganti@1: kkonganti@1: OTF_GENOME ( KMA_ALIGN.out.hits ) kkonganti@1: kkonganti@1: OTF_GENOME.out.failed kkonganti@1: .concat( ch_bcs_calls_failed ) kkonganti@1: .collectFile(name: 'BCS_NO_CALLS.txt') kkonganti@1: .set { ch_bcs_no_calls } kkonganti@1: kkonganti@1: SALMON_INDEX ( OTF_GENOME.out.genomes_fasta ) kkonganti@1: kkonganti@1: SALMON_QUANT ( kkonganti@1: ch_processed_reads kkonganti@1: .join(SALMON_INDEX.out.idx) kkonganti@1: ) kkonganti@1: kkonganti@1: SALMON_QUANT kkonganti@1: .out kkonganti@1: .results kkonganti@1: .groupTuple(by: [0]) kkonganti@1: .map { it -> tuple ( it[1].flatten() ) } kkonganti@1: .mix ( ch_bcs_no_calls ) kkonganti@1: .collect() kkonganti@1: .set { ch_salmon_res_dirs } kkonganti@1: kkonganti@1: if (params.sourmashsketch_run) { kkonganti@1: SOURMASH_SKETCH kkonganti@1: .out kkonganti@1: .signatures kkonganti@1: .groupTuple(by: [0]) kkonganti@1: .map { meta, qsigs, dsigs -> kkonganti@1: [ qsigs ] kkonganti@1: } kkonganti@1: .collect() kkonganti@1: .flatten() kkonganti@1: .collect() kkonganti@1: .set { ch_query_sigs } kkonganti@1: kkonganti@1: KMA_ALIGN kkonganti@1: .out kkonganti@1: .hits kkonganti@1: .map { meta, hits -> kkonganti@1: [ hits ] kkonganti@1: } kkonganti@1: .collect() kkonganti@1: .flatten() kkonganti@1: .collectFile(name: 'accessions.txt') kkonganti@1: .set { ch_otf_genomes } kkonganti@1: kkonganti@1: SOURMASH_COMPARE ( ch_query_sigs, ch_otf_genomes ) kkonganti@1: kkonganti@1: BCS_DISTANCE_MATRIX ( kkonganti@1: SOURMASH_COMPARE.out.matrix, kkonganti@1: SOURMASH_COMPARE.out.labels kkonganti@1: ) kkonganti@1: kkonganti@1: ch_multiqc kkonganti@1: .concat( BCS_DISTANCE_MATRIX.out.mqc_yml ) kkonganti@1: .set { ch_multiqc } kkonganti@1: kkonganti@1: software_versions kkonganti@1: .mix ( kkonganti@1: SOURMASH_SKETCH.out.versions.ifEmpty(null), kkonganti@1: SOURMASH_COMPARE.out.versions.ifEmpty(null), kkonganti@1: BCS_DISTANCE_MATRIX.out.versions.ifEmpty(null), kkonganti@1: ) kkonganti@1: .set { software_versions } kkonganti@1: } kkonganti@1: kkonganti@1: BCS_RESULTS ( ch_salmon_res_dirs ) kkonganti@1: kkonganti@1: DUMP_SOFTWARE_VERSIONS ( kkonganti@1: software_versions kkonganti@1: .mix ( kkonganti@1: MASH_SCREEN.out.versions, kkonganti@1: TOP_UNIQUE_SEROVARS.out.versions, kkonganti@1: KMA_INDEX.out.versions, kkonganti@1: KMA_ALIGN.out.versions, kkonganti@1: OTF_GENOME.out.versions.ifEmpty(null), kkonganti@1: SALMON_INDEX.out.versions, kkonganti@1: SALMON_QUANT.out.versions, kkonganti@1: BCS_RESULTS.out.versions kkonganti@1: ) kkonganti@1: .unique() kkonganti@1: .collectFile(name: 'collected_versions.yml') kkonganti@1: ) kkonganti@1: kkonganti@1: DUMP_SOFTWARE_VERSIONS kkonganti@1: .out kkonganti@1: .mqc_yml kkonganti@1: .concat ( kkonganti@1: ch_multiqc, kkonganti@1: BCS_RESULTS.out.mqc_yml, kkonganti@1: BCS_RESULTS.out.mqc_json kkonganti@1: ) kkonganti@1: .collect() kkonganti@1: .set { ch_multiqc } kkonganti@1: kkonganti@1: MULTIQC ( ch_multiqc ) kkonganti@1: } kkonganti@1: kkonganti@1: /* kkonganti@1: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@1: ON COMPLETE, SHOW GORY DETAILS OF ALL PARAMS WHICH WILL BE HELPFUL TO DEBUG kkonganti@1: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@1: */ kkonganti@1: kkonganti@1: workflow.onComplete { kkonganti@1: if (workflow.success) { kkonganti@1: sendMail() kkonganti@1: } kkonganti@1: } kkonganti@1: kkonganti@1: workflow.onError { kkonganti@1: sendMail() kkonganti@1: } kkonganti@1: kkonganti@1: /* kkonganti@1: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@1: METHOD TO CHECK METADATA EXISTENCE kkonganti@1: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@1: */ kkonganti@1: kkonganti@1: def checkMetadataExists(file_path, msg) { kkonganti@1: file_path_obj = file( file_path ) kkonganti@1: kkonganti@1: if (!file_path_obj.exists() || file_path_obj.size() == 0) { kkonganti@1: stopNow("Please check if your ${msg} file\n" + kkonganti@1: "[ ${file_path} ]\nexists and is not of size 0.") kkonganti@1: } kkonganti@1: } kkonganti@1: kkonganti@1: /* kkonganti@1: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@1: HELP TEXT METHODS FOR BETTERCALLSAL WORKFLOW kkonganti@1: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@1: */ kkonganti@1: kkonganti@1: def help() { kkonganti@1: kkonganti@1: Map helptext = [:] kkonganti@1: Map bcsConcatHelp = [:] kkonganti@1: Map fastpAdapterHelp = [:] kkonganti@1: kkonganti@1: bcsConcatHelp['--bcs_concat_pe'] = "Concatenate paired-end files. " + kkonganti@1: "Default: ${params.bcs_concat_pe}" kkonganti@1: kkonganti@1: fastpAdapterHelp['--fastp_use_custom_adapaters'] = "Use custom adapter FASTA with fastp on top of " + kkonganti@1: "built-in adapter sequence auto-detection. Enabling this option will attempt to find and remove " + kkonganti@1: "all possible Illumina adapter and primer sequences but will make the workflow run slow. " + kkonganti@1: "Default: ${params.fastp_use_custom_adapters}" kkonganti@1: kkonganti@1: helptext.putAll ( kkonganti@1: fastqEntryPointHelp() + kkonganti@1: bcsConcatHelp + kkonganti@1: bbmergeHelp(params).text + kkonganti@1: fastpHelp(params).text + kkonganti@1: fastpAdapterHelp + kkonganti@1: mashscreenHelp(params).text + kkonganti@1: tuspyHelp(params).text + kkonganti@1: sourmashsketchHelp(params).text + kkonganti@1: sourmashgatherHelp(params).text + kkonganti@1: sourmashsearchHelp(params).text + kkonganti@1: sfhpyHelp(params).text + kkonganti@1: kmaindexHelp(params).text + kkonganti@1: kmaalignHelp(params).text + kkonganti@1: salmonidxHelp(params).text + kkonganti@1: gsrpyHelp(params).text + kkonganti@1: wrapUpHelp() kkonganti@1: ) kkonganti@1: kkonganti@1: return addPadding(helptext) kkonganti@1: }