kkonganti@0: // Define any required imports for this specific workflow kkonganti@0: import java.nio.file.Paths kkonganti@0: import java.util.zip.GZIPInputStream kkonganti@0: import java.io.FileInputStream kkonganti@0: import nextflow.file.FileHelper kkonganti@0: kkonganti@0: kkonganti@0: // Include any necessary methods kkonganti@0: include { \ kkonganti@0: summaryOfParams; stopNow; fastqEntryPointHelp; sendMail; \ kkonganti@0: addPadding; wrapUpHelp } from "${params.routines}" kkonganti@0: include { fastpHelp } from "${params.toolshelp}${params.fs}fastp" kkonganti@0: include { kmaalignHelp } from "${params.toolshelp}${params.fs}kmaalign" kkonganti@0: include { seqkitgrepHelp } from "${params.toolshelp}${params.fs}seqkitgrep" kkonganti@0: include { salmonidxHelp } from "${params.toolshelp}${params.fs}salmonidx" kkonganti@0: include { sourmashsketchHelp } from "${params.toolshelp}${params.fs}sourmashsketch" kkonganti@0: include { sourmashgatherHelp } from "${params.toolshelp}${params.fs}sourmashgather" kkonganti@0: include { sfhpyHelp } from "${params.toolshelp}${params.fs}sfhpy" kkonganti@0: include { gsalkronapyHelp } from "${params.toolshelp}${params.fs}gsalkronapy" kkonganti@0: include { kronaktimporttextHelp } from "${params.toolshelp}${params.fs}kronaktimporttext" kkonganti@0: kkonganti@0: // Exit if help requested before any subworkflows kkonganti@0: if (params.help) { kkonganti@0: log.info help() kkonganti@0: exit 0 kkonganti@0: } kkonganti@0: kkonganti@0: kkonganti@0: // Include any necessary modules and subworkflows kkonganti@0: include { PROCESS_FASTQ } from "${params.subworkflows}${params.fs}process_fastq" kkonganti@0: include { FASTP } from "${params.modules}${params.fs}fastp${params.fs}main" kkonganti@0: include { KMA_ALIGN } from "${params.modules}${params.fs}kma${params.fs}align${params.fs}main" kkonganti@0: include { OTF_GENOME } from "${params.modules}${params.fs}otf_genome${params.fs}main" kkonganti@0: include { SEQKIT_GREP } from "${params.modules}${params.fs}seqkit${params.fs}grep${params.fs}main" kkonganti@0: include { SALMON_INDEX } from "${params.modules}${params.fs}salmon${params.fs}index${params.fs}main" kkonganti@0: include { SALMON_QUANT } from "${params.modules}${params.fs}salmon${params.fs}quant${params.fs}main" kkonganti@0: include { SOURMASH_SKETCH } from "${params.modules}${params.fs}sourmash${params.fs}sketch${params.fs}main" kkonganti@0: include { SOURMASH_SKETCH \ kkonganti@0: as REDUCE_DB_IDX } from "${params.modules}${params.fs}sourmash${params.fs}sketch${params.fs}main" kkonganti@0: include { SOURMASH_GATHER } from "${params.modules}${params.fs}sourmash${params.fs}gather${params.fs}main" kkonganti@0: include { NOWAYOUT_RESULTS } from "${params.modules}${params.fs}nowayout_results${params.fs}main" kkonganti@0: include { KRONA_KTIMPORTTEXT } from "${params.modules}${params.fs}krona${params.fs}ktimporttext${params.fs}main" kkonganti@0: include { DUMP_SOFTWARE_VERSIONS } from "${params.modules}${params.fs}custom${params.fs}dump_software_versions${params.fs}main" kkonganti@0: include { MULTIQC } from "${params.modules}${params.fs}multiqc${params.fs}main" kkonganti@0: kkonganti@0: /* kkonganti@0: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@0: INPUTS AND ANY CHECKS FOR THE BETTERCALLSAL WORKFLOW kkonganti@0: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@0: */ kkonganti@0: kkonganti@0: def reads_platform = 0 kkonganti@0: reads_platform += (params.input ? 1 : 0) kkonganti@0: kkonganti@0: if (reads_platform < 1 || reads_platform == 0) { kkonganti@0: stopNow("Please mention at least one absolute path to input folder which contains\n" + kkonganti@0: "FASTQ files sequenced using the --input option.\n" + kkonganti@0: "Ex: --input (Illumina or Generic short reads in FASTQ format)") kkonganti@0: } kkonganti@0: kkonganti@0: params.fastp_adapter_fasta ? checkMetadataExists(params.fastp_adapter_fasta, 'Adapter sequences FASTA') : null kkonganti@0: checkMetadataExists(params.lineages_csv, 'Lineages CSV') kkonganti@0: checkMetadataExists(params.kmaalign_idx, 'KMA Indices') kkonganti@0: checkMetadataExists(params.ref_fna, 'FASTA reference') kkonganti@0: kkonganti@0: ch_sourmash_lin = file( params.lineages_csv ) kkonganti@0: kkonganti@0: kkonganti@0: /* kkonganti@0: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@0: RUN THE BETTERCALLSAL WORKFLOW kkonganti@0: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@0: */ kkonganti@0: kkonganti@0: workflow NOWAYOUT { kkonganti@0: main: kkonganti@0: log.info summaryOfParams() kkonganti@0: kkonganti@0: PROCESS_FASTQ() kkonganti@0: kkonganti@0: PROCESS_FASTQ.out.versions kkonganti@0: .set { software_versions } kkonganti@0: kkonganti@0: PROCESS_FASTQ.out.processed_reads kkonganti@0: .set { ch_processed_reads } kkonganti@0: kkonganti@0: ch_processed_reads kkonganti@0: .map { meta, fastq -> kkonganti@0: meta.get_kma_hit_accs = true kkonganti@0: meta.salmon_decoys = params.dummyfile kkonganti@0: meta.salmon_lib_type = (params.salmonalign_libtype ?: false) kkonganti@0: meta.kma_t_db = params.kmaalign_idx kkonganti@0: [ meta, fastq ] kkonganti@0: } kkonganti@0: .filter { meta, fastq -> kkonganti@0: fq_file = ( fastq.getClass().toString() =~ /ArrayList/ ? fastq : [ fastq ] ) kkonganti@0: fq_gzip = new GZIPInputStream( new FileInputStream( fq_file[0].toAbsolutePath().toString() ) ) kkonganti@0: fq_gzip.read() != -1 kkonganti@0: } kkonganti@0: .set { ch_processed_reads } kkonganti@0: kkonganti@0: FASTP( ch_processed_reads ) kkonganti@0: kkonganti@0: FASTP.out.json kkonganti@0: .map { meta, json -> kkonganti@0: json kkonganti@0: } kkonganti@0: .collect() kkonganti@0: .set { ch_multiqc } kkonganti@0: kkonganti@0: KMA_ALIGN( kkonganti@0: FASTP.out.passed_reads kkonganti@0: .map { meta, fastq -> kkonganti@0: [meta, fastq, []] kkonganti@0: } kkonganti@0: ) kkonganti@0: kkonganti@0: OTF_GENOME( kkonganti@0: KMA_ALIGN.out.hits kkonganti@0: .join(KMA_ALIGN.out.frags) kkonganti@0: ) kkonganti@0: kkonganti@0: OTF_GENOME.out.reads_extracted kkonganti@0: .filter { meta, fasta -> kkonganti@0: fa_file = ( fasta.getClass().toString() =~ /ArrayList/ ? fasta : [ fasta ] ) kkonganti@0: fa_gzip = new GZIPInputStream( new FileInputStream( fa_file[0].toAbsolutePath().toString() ) ) kkonganti@0: fa_gzip.read() != -1 kkonganti@0: } kkonganti@0: .set { ch_mito_aln_reads } kkonganti@0: kkonganti@0: SEQKIT_GREP( kkonganti@0: KMA_ALIGN.out.hits kkonganti@0: .filter { meta, mapped_refs -> kkonganti@0: patterns = file( mapped_refs ) kkonganti@0: patterns.size() > 0 kkonganti@0: } kkonganti@0: .map { meta, mapped_refs -> kkonganti@0: [meta, params.ref_fna, mapped_refs] kkonganti@0: } kkonganti@0: ) kkonganti@0: kkonganti@0: SALMON_INDEX( SEQKIT_GREP.out.fastx ) kkonganti@0: kkonganti@0: SALMON_QUANT( kkonganti@0: ch_mito_aln_reads kkonganti@0: .join( SALMON_INDEX.out.idx ) kkonganti@0: ) kkonganti@0: kkonganti@0: REDUCE_DB_IDX( kkonganti@0: SEQKIT_GREP.out.fastx, kkonganti@0: true, kkonganti@0: false, kkonganti@0: 'db' kkonganti@0: ) kkonganti@0: kkonganti@0: SOURMASH_SKETCH( kkonganti@0: ch_mito_aln_reads, kkonganti@0: false, kkonganti@0: false, kkonganti@0: 'query' kkonganti@0: ) kkonganti@0: kkonganti@0: SOURMASH_GATHER( kkonganti@0: SOURMASH_SKETCH.out.signatures kkonganti@0: .join( REDUCE_DB_IDX.out.signatures ), kkonganti@0: [], [], [], [] kkonganti@0: ) kkonganti@0: kkonganti@0: // SOURMASH_TAX_METAGENOME( kkonganti@0: // SOURMASH_GATHER.out.result kkonganti@0: // .groupTuple(by: [0]) kkonganti@0: // .map { meta, csv -> kkonganti@0: // [ meta, csv, ch_sourmash_lin ] kkonganti@0: // } kkonganti@0: // ) kkonganti@0: kkonganti@0: // SOURMASH_TAX_METAGENOME.out.csv kkonganti@0: // .map { meta, csv -> kkonganti@0: // csv kkonganti@0: // } kkonganti@0: // .set { ch_lin_csv } kkonganti@0: kkonganti@0: // SOURMASH_TAX_METAGENOME.out.tsv kkonganti@0: // .tap { ch_lin_krona } kkonganti@0: // .map { meta, tsv -> kkonganti@0: // tsv kkonganti@0: // } kkonganti@0: // .tap { ch_lin_tsv } kkonganti@0: kkonganti@0: SOURMASH_GATHER.out.result kkonganti@0: .groupTuple(by: [0]) kkonganti@0: .map { meta, csv -> kkonganti@0: [ csv ] kkonganti@0: } kkonganti@0: .concat( kkonganti@0: SALMON_QUANT.out.results kkonganti@0: .map { meta, salmon_res -> kkonganti@0: [ salmon_res ] kkonganti@0: } kkonganti@0: ) kkonganti@0: .concat( kkonganti@0: SOURMASH_GATHER.out.failed kkonganti@0: .map { meta, failed -> kkonganti@0: [ failed ] kkonganti@0: } kkonganti@0: ) kkonganti@0: .concat( OTF_GENOME.out.failed ) kkonganti@0: .collect() kkonganti@0: .flatten() kkonganti@0: .collect() kkonganti@0: .set { ch_gene_abn } kkonganti@0: kkonganti@0: NOWAYOUT_RESULTS( ch_gene_abn, ch_sourmash_lin ) kkonganti@0: kkonganti@0: NOWAYOUT_RESULTS.out.tsv kkonganti@0: .flatten() kkonganti@0: .filter { tsv -> tsv.toString() =~ /.*${params.krona_res_suffix}$/ } kkonganti@0: .map { tsv -> kkonganti@0: meta = [:] kkonganti@0: meta.id = "${params.cfsanpipename}_${params.pipeline}_krona" kkonganti@0: [ meta, tsv ] kkonganti@0: } kkonganti@0: .groupTuple(by: [0]) kkonganti@0: .set { ch_lin_krona } kkonganti@0: kkonganti@0: // ch_lin_tsv kkonganti@0: // .mix( ch_lin_csv ) kkonganti@0: // .collect() kkonganti@0: // .set { ch_lin_summary } kkonganti@0: kkonganti@0: // SOURMASH_TAX_METAGENOME.out.txt kkonganti@0: // .map { meta, txt -> kkonganti@0: // txt kkonganti@0: // } kkonganti@0: // .collect() kkonganti@0: // .set { ch_lin_kreport } kkonganti@0: kkonganti@0: // NOWAYOUT_RESULTS( kkonganti@0: // ch_lin_summary kkonganti@0: // .concat( SOURMASH_GATHER.out.failed ) kkonganti@0: // .concat( OTF_GENOME.out.failed ) kkonganti@0: // .collect() kkonganti@0: // ) kkonganti@0: kkonganti@0: KRONA_KTIMPORTTEXT( ch_lin_krona ) kkonganti@0: kkonganti@0: DUMP_SOFTWARE_VERSIONS( kkonganti@0: software_versions kkonganti@0: .mix ( kkonganti@0: FASTP.out.versions, kkonganti@0: KMA_ALIGN.out.versions, kkonganti@0: SEQKIT_GREP.out.versions, kkonganti@0: REDUCE_DB_IDX.out.versions, kkonganti@0: SOURMASH_SKETCH.out.versions, kkonganti@0: SOURMASH_GATHER.out.versions, kkonganti@0: SALMON_INDEX.out.versions, kkonganti@0: SALMON_QUANT.out.versions, kkonganti@0: NOWAYOUT_RESULTS.out.versions, kkonganti@0: KRONA_KTIMPORTTEXT.out.versions kkonganti@0: ) kkonganti@0: .unique() kkonganti@0: .collectFile(name: 'collected_versions.yml') kkonganti@0: ) kkonganti@0: kkonganti@0: DUMP_SOFTWARE_VERSIONS.out.mqc_yml kkonganti@0: .concat( kkonganti@0: ch_multiqc, kkonganti@0: NOWAYOUT_RESULTS.out.mqc_yml kkonganti@0: ) kkonganti@0: .collect() kkonganti@0: .flatten() kkonganti@0: .collect() kkonganti@0: .set { ch_multiqc } kkonganti@0: kkonganti@0: MULTIQC( ch_multiqc ) kkonganti@0: } kkonganti@0: kkonganti@0: /* kkonganti@0: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@0: ON COMPLETE, SHOW GORY DETAILS OF ALL PARAMS WHICH WILL BE HELPFUL TO DEBUG kkonganti@0: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@0: */ kkonganti@0: kkonganti@0: workflow.onComplete { kkonganti@0: if (workflow.success) { kkonganti@0: sendMail() kkonganti@0: } kkonganti@0: } kkonganti@0: kkonganti@0: workflow.onError { kkonganti@0: sendMail() kkonganti@0: } kkonganti@0: kkonganti@0: /* kkonganti@0: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@0: METHOD TO CHECK METADATA EXISTENCE kkonganti@0: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@0: */ kkonganti@0: kkonganti@0: def checkMetadataExists(file_path, msg) { kkonganti@0: file_path_obj = file( file_path ) kkonganti@0: kkonganti@0: if (msg.toString().find(/(?i)KMA/)) { kkonganti@8: if (!file_path_obj.parent.exists()) { kkonganti@0: stopNow("Please check if your ${msg}\n" + kkonganti@0: "[ ${file_path} ]\nexists and that the files are not of size 0.") kkonganti@0: } kkonganti@8: kkonganti@8: // Check if db files within parent path are empty. kkonganti@8: file_path_obj.eachFileRecurse { kkonganti@8: if (it.size() == 0) { kkonganti@8: stopNow("For ${msg}, within\n" + kkonganti@8: "[ ${file_path} ],\nthe following file is of size 0: ${it.name}") kkonganti@8: } kkonganti@8: } kkonganti@8: kkonganti@0: } kkonganti@0: else if (!file_path_obj.exists() || file_path_obj.size() == 0) { kkonganti@0: stopNow("Please check if your ${msg} file\n" + kkonganti@0: "[ ${file_path} ]\nexists and is not of size 0.") kkonganti@0: } kkonganti@0: } kkonganti@0: kkonganti@0: /* kkonganti@0: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@0: HELP TEXT METHODS FOR BETTERCALLSAL WORKFLOW kkonganti@0: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kkonganti@0: */ kkonganti@0: kkonganti@0: def help() { kkonganti@0: kkonganti@0: Map helptext = [:] kkonganti@0: kkonganti@0: helptext.putAll ( kkonganti@0: fastqEntryPointHelp() + kkonganti@0: fastpHelp(params).text + kkonganti@0: kmaalignHelp(params).text + kkonganti@0: seqkitgrepHelp(params).text + kkonganti@0: salmonidxHelp(params).text + kkonganti@0: sourmashsketchHelp(params).text + kkonganti@0: sourmashgatherHelp(params).text + kkonganti@0: sfhpyHelp(params).text + kkonganti@0: gsalkronapyHelp(params).text + kkonganti@0: kronaktimporttextHelp(params).text + kkonganti@0: wrapUpHelp() kkonganti@0: ) kkonganti@0: kkonganti@0: return addPadding(helptext) kkonganti@0: }