diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index a3dac6d..be48b3a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -51,12 +51,11 @@ body: - type: dropdown id: profile attributes: - label: Workflow Execution - Execution Profile + label: Workflow Execution - CLI Execution Profile description: If you're using the CLI to run the workflow, what profile are you using? options: - Docker - Singularity - - Conda validations: required: false - type: input diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fdcb33c..eb9fe3f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,7 @@ variables: --ref_genome chr20/hg38_chr20.fa --ref_annotation chr20/gencode.v22.annotation.chr20.gtf \ --jaffal_refBase chr20/ --jaffal_genome hg38_chr20 --jaffal_annotation genCode22" NF_IGNORE_PROCESSES: preprocess_reads,merge_transcriptomes + CI_FLAVOUR: "new" docker-run: @@ -31,13 +32,13 @@ docker-run: - if: $MATRIX_NAME == "isoforms" variables: NF_BEFORE_SCRIPT: wget -O test_data.tar.gz https://ont-exd-int-s3-euwst1-epi2me-labs.s3.amazonaws.com/wf-isoforms/wf-isoforms_test_data.tar.gz && tar -xzvf test_data.tar.gz - NF_WORKFLOW_OPTS: "--fastq ERR6053095_chr20.fastq \ + NF_WORKFLOW_OPTS: "--fastq ERR6053095_chr20.fastq --transcriptome-source reference-guided \ --ref_genome chr20/hg38_chr20.fa --ref_annotation chr20/gencode.v22.annotation.chr20.gtf" NF_IGNORE_PROCESSES: preprocess_reads,merge_transcriptomes - if: $MATRIX_NAME == "fusions" variables: NF_BEFORE_SCRIPT: wget -O test_data.tar.gz https://ont-exd-int-s3-euwst1-epi2me-labs.s3.amazonaws.com/wf-isoforms/wf-isoforms_test_data.tar.gz && tar -xzvf test_data.tar.gz - NF_WORKFLOW_OPTS: "--fastq ERR6053095_chr20.fastq \ + NF_WORKFLOW_OPTS: "--fastq ERR6053095_chr20.fastq --transcriptome-source reference-guided \ --ref_genome chr20/hg38_chr20.fa --ref_annotation chr20/gencode.v22.annotation.chr20.gtf \ --jaffal_refBase chr20/ --jaffal_genome hg38_chr20 --jaffal_annotation genCode22" NF_IGNORE_PROCESSES: preprocess_reads,merge_transcriptomes @@ -46,7 +47,7 @@ docker-run: NF_BEFORE_SCRIPT: wget -O differential_expression.tar.gz https://ont-exd-int-s3-euwst1-epi2me-labs.s3.amazonaws.com/wf-isoforms/differential_expression.tar.gz && tar -xzvf differential_expression.tar.gz NF_WORKFLOW_OPTS: "--fastq differential_expression/differential_expression_fastq \ --de_analysis \ - --ref_genome differential_expression/hg38_chr20.fa \ + --ref_genome differential_expression/hg38_chr20.fa --transcriptome-source reference-guided \ --ref_annotation differential_expression/gencode.v22.annotation.chr20.gtf \ --direct_rna --minimap_index_opts \\-k15" NF_IGNORE_PROCESSES: preprocess_reads,merge_transcriptomes @@ -54,6 +55,7 @@ docker-run: variables: NF_BEFORE_SCRIPT: wget -O differential_expression.tar.gz https://ont-exd-int-s3-euwst1-epi2me-labs.s3.amazonaws.com/wf-isoforms/differential_expression.tar.gz && tar -xzvf differential_expression.tar.gz NF_WORKFLOW_OPTS: "--fastq differential_expression/differential_expression_fastq \ + --transcriptome-source precomputed \ --de_analysis \ --ref_genome differential_expression/hg38_chr20.fa \ --ref_annotation differential_expression/gencode.v22.annotation.chr20.gtf \ diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aa1582..4ade34a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [unreleased] +### Updated +- `-profile conda` is no longer supported, users should use `-profile standard` (Docker) or `-profile singularity` instead +- `nextflow run epi2me-labs/wf-transcriptomes --version` will now print the workflow version number and exit +- Use parameter `--transcriptome-source` to define precalculated, reference-based or denovo + ## [v0.1.6] ### Updated - Removed sanitize option diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 453715c..0000000 --- a/Dockerfile +++ /dev/null @@ -1,24 +0,0 @@ -ARG BASEIMAGE=ontresearch/base-workflow-image:v0.2.0 -FROM $BASEIMAGE -ARG ENVFILE=environment.yaml - -COPY $ENVFILE $HOME/environment.yaml -RUN \ - . $CONDA_DIR/etc/profile.d/micromamba.sh \ - && micromamba activate \ - && micromamba install -n base --file $HOME/environment.yaml \ - && micromamba clean --all --yes \ - && fix-permissions $CONDA_DIR \ - && fix-permissions $HOME \ - && rm -rf $CONDA_DIR/conda-meta \ - && rm -rf $CONDA_DIR/include \ - && rm -rf $CONDA_DIR/lib/python3.*/site-packages/pip \ - && find $CONDA_DIR -name '__pycache__' -type d -exec rm -rf '{}' '+' - -USER $WF_UID -WORKDIR $HOME - -# Install JAFFA -ADD subworkflows $HOME/subworkflows -RUN /bin/sh -c $HOME/subworkflows/JAFFAL/install_jaffa.sh - diff --git a/README.md b/README.md index 6ad9709..68060d5 100644 --- a/README.md +++ b/README.md @@ -88,10 +88,9 @@ to run the workflow. The workflow can currently be run using either [Docker](https://www.docker.com/products/docker-desktop), -[Singularity](https://sylabs.io/singularity/) or -[conda](https://docs.conda.io/en/latest/miniconda.html) to provide isolation of +[Singularity](https://sylabs.io/singularity/) to provide isolation of the required software. Each method is automated out-of-the-box provided -either docker, singularity or conda is installed. +either docker or singularity is installed. It is not required to clone or download the git repository in order to run the workflow. For more information on running EPI2ME Labs workflows [visit out website](https://labs.epi2me.io/wfindex). @@ -290,7 +289,6 @@ in `${out_dir}/jaffal_output_${sample_id}` you will find: * [nextflow](https://www.nextflow.io/) * [docker](https://www.docker.com/products/docker-desktop) * [Singularity](https://sylabs.io/singularity/) -* [conda](https://docs.conda.io/en/latest/miniconda.html) * [racon](https://github.com/isovic/racon) * [spoa](https://github.com/rvaser/spoa) * [inONclust](https://github.com/ksahlin/isONclust) diff --git a/bin/report.py b/bin/report.py index 366b6b1..807d2aa 100755 --- a/bin/report.py +++ b/bin/report.py @@ -511,7 +511,7 @@ def pychopper_plots(report, pychop_report): ### Pychopper summary statisitcs The following plots summarize [pychopper] output - (https://github.com/nanoporetech/pychopper) + (https://github.com/epi2me-labs/pychopper) * **Pr.found**: Reads with primers found in correct orientation at both ends. @@ -604,7 +604,7 @@ def transcript_table(report, df_tmaps, max_rows): """ section = report.add_section() - # Should wße put data from each sample into it's own table or have it + # Should we put data from each sample into it's own table or have it # all in single table and sample_id column? Currently it's the latter # drop some columns for the big table and do some filtering @@ -932,7 +932,9 @@ def main(): [Path(x) for x in args.gffcompare_dir], sample_ids) - transcript_table(report, df_tmaps, args.isoform_table_nrows) + if df_tmaps is not None: + # Skip this section. This needs some work + transcript_table(report, df_tmaps, args.isoform_table_nrows) if args.cluster_qc_dirs is not None: cluster_quality(args.cluster_qc_dirs, report, sample_ids) diff --git a/bin/run_isonclust2.py b/bin/run_isonclust2.py index f29cb5c..fb16301 100755 --- a/bin/run_isonclust2.py +++ b/bin/run_isonclust2.py @@ -53,19 +53,19 @@ def build_job_tree(): for x in batches] levels = OrderedDict() levels[0] = [] - for k, bf in sorted(zip(batch_ids, batches), key=lambda x: x[0]): + for id_, bf in sorted(zip(batch_ids, batches), key=lambda x: x[0]): n = Node( - k, - "clusters/isONcluster_{}.cer".format(k), + id_, + "clusters/isONcluster_{}.cer".format(id_), None, None, None, 0) n.Done = True - job_tree[k] = n + job_tree[id_] = n levels[0].append(n) level = 0 - max_id = levels[0][-1].k + max_id = levels[0][-1].Id while len(levels[level]) != 1: # Final level will be link next_level = level + 1 levels[next_level] = [] @@ -84,7 +84,7 @@ def build_job_tree(): levels[next_level].append(new_node) job_tree[max_id] = new_node level = next_level - root = job_tree[len(job_tree) - 1].k + root = job_tree[len(job_tree) - 1].Id job_tree[root].RightSide = True return job_tree, levels @@ -121,7 +121,7 @@ def main(): sub.call(cmd, shell=True) sub.call(( "ln -s `realpath clusters/isONcluster_{}.cer` " - "isONcluster_root.cer".format(n.Id)), shell=True) + "isONcluster_ROOT.cer".format(n.Id)), shell=True) if __name__ == '__main__': diff --git a/docs/links.md b/docs/links.md index 8dd5236..9d2b74c 100644 --- a/docs/links.md +++ b/docs/links.md @@ -3,7 +3,6 @@ * [nextflow](https://www.nextflow.io/) * [docker](https://www.docker.com/products/docker-desktop) * [Singularity](https://sylabs.io/singularity/) -* [conda](https://docs.conda.io/en/latest/miniconda.html) * [racon](https://github.com/isovic/racon) * [spoa](https://github.com/rvaser/spoa) * [inONclust](https://github.com/ksahlin/isONclust) diff --git a/docs/quickstart.md b/docs/quickstart.md index c443bdf..4adb6b2 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -6,10 +6,9 @@ to run the workflow. The workflow can currently be run using either [Docker](https://www.docker.com/products/docker-desktop), -[Singularity](https://sylabs.io/singularity/) or -[conda](https://docs.conda.io/en/latest/miniconda.html) to provide isolation of +[Singularity](https://sylabs.io/singularity/) to provide isolation of the required software. Each method is automated out-of-the-box provided -either docker, singularity or conda is installed. +either docker or singularity is installed. It is not required to clone or download the git repository in order to run the workflow. For more information on running EPI2ME Labs workflows [visit out website](https://labs.epi2me.io/wfindex). diff --git a/environment.yaml b/environment.yaml deleted file mode 100644 index 86b80bb..0000000 --- a/environment.yaml +++ /dev/null @@ -1,44 +0,0 @@ -name: epi2melabs-wf-transcriptomes -channels: - - epi2melabs - - conda-forge - - bioconda - - defaults -dependencies: - - python==3.8.* - - bokeh==2.4.3 - - aplanat>=0.6.15 - - epi2melabs - - minimap2==2.24 - - samtools==1.14 - - bedtools==2.30.0 - - pychopper>=2.7.0 - - pandas==1.3.5 - - gffread==0.12.7 - - gffcompare==0.11.2 - - gffutils==0.10.1 - - seqkit==2.2.0 - - stringtie==2.1.1 - - curl - - pysam==0.17.0 - - racon==1.4.20 - - spoa==3.4.0 - - fastcat==0.4.10 - - isonclust2==2.3 - - parallel - - scikit-learn==1.0.2 - - natsort -# Fusion detection dependencies -# - bpipe=0.9.9.2 - - java-jdk - - r-base - - gxx -# Differential expression dependencies - - bioconductor-genomicfeatures - - bioconductor-drimseq - - bioconductor-edger - - bioconductor-dexseq - - bioconductor-stager - - r-dplyr - - r-tidyr - - salmon==1.9.0 \ No newline at end of file diff --git a/lib/NfcoreSchema.groovy b/lib/NfcoreSchema.groovy index 1c5f12c..e82d47a 100644 --- a/lib/NfcoreSchema.groovy +++ b/lib/NfcoreSchema.groovy @@ -70,7 +70,6 @@ class NfcoreSchema { 'quiet', 'syslog', 'v', - 'version', // Options for `nextflow run` command 'ansi', diff --git a/lib/NfcoreTemplate.groovy b/lib/NfcoreTemplate.groovy index 700a476..4c1c9db 100644 --- a/lib/NfcoreTemplate.groovy +++ b/lib/NfcoreTemplate.groovy @@ -66,6 +66,25 @@ class NfcoreTemplate { } } + // + // Generate version string + // + public static String version(workflow) { + String version_string = "" + + if (workflow.manifest.version) { + def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : '' + version_string += "${prefix_v}${workflow.manifest.version}" + } + + if (workflow.commitId) { + def git_shortsha = workflow.commitId.substring(0, 7) + version_string += "-g${git_shortsha}" + } + + return version_string + } + // // Construct and send completion email // @@ -98,7 +117,7 @@ class NfcoreTemplate { misc_fields['Nextflow Compile Timestamp'] = workflow.nextflow.timestamp def email_fields = [:] - email_fields['version'] = workflow.manifest.version + email_fields['version'] = NfcoreTemplate.version(workflow) email_fields['runName'] = workflow.runName email_fields['success'] = workflow.success email_fields['dateComplete'] = workflow.complete @@ -297,24 +316,23 @@ class NfcoreTemplate { // public static String dashedLine(monochrome_logs) { Map colors = logColours(monochrome_logs) - return "-${colors.dim}----------------------------------------------------${colors.reset}-" + return "${colors.dim}--------------------------------------------------------------------------------${colors.reset}" } - // - // nf-core logo - // + // epi2me-labs logo public static String logo(workflow, monochrome_logs) { - Map colors = logColours(monochrome_logs) + Map colors = NfcoreTemplate.logColours(monochrome_logs) + String workflow_name = workflow.manifest.name.split("/")[1] + String workflow_version = version(workflow) String.format( - """\n - ${dashedLine(monochrome_logs)} - ${colors.green},--.${colors.black}/${colors.green},-.${colors.reset} - ${colors.blue} ___ __ __ __ ___ ${colors.green}/,-._.--~\'${colors.reset} - ${colors.blue} |\\ | |__ __ / ` / \\ |__) |__ ${colors.yellow}} {${colors.reset} - ${colors.blue} | \\| | \\__, \\__/ | \\ |___ ${colors.green}\\`-._,-`-,${colors.reset} - ${colors.green}`._,._,\'${colors.reset} - ${colors.purple} ${workflow.manifest.name} v${workflow.manifest.version}${colors.reset} - ${dashedLine(monochrome_logs)} + """ + ${colors.igreen}|||||||||| ${colors.reset}${colors.dim}_____ ____ ___ ____ __ __ _____ _ _ + ${colors.igreen}|||||||||| ${colors.reset}${colors.dim}| ____| _ \\_ _|___ \\| \\/ | ____| | | __ _| |__ ___ + ${colors.yellow}||||| ${colors.reset}${colors.dim}| _| | |_) | | __) | |\\/| | _| _____| |/ _` | '_ \\/ __| + ${colors.yellow}||||| ${colors.reset}${colors.dim}| |___| __/| | / __/| | | | |__|_____| | (_| | |_) \\__ \\ + ${colors.iblue}|||||||||| ${colors.reset}${colors.dim}|_____|_| |___|_____|_| |_|_____| |_|\\__,_|_.__/|___/ + ${colors.iblue}|||||||||| ${colors.reset}${colors.bold}${workflow_name} ${workflow_version}${colors.reset} + ${NfcoreTemplate.dashedLine(monochrome_logs)} """.stripIndent() ) } diff --git a/lib/WorkflowMain.groovy b/lib/WorkflowMain.groovy index c518e53..bfb8f20 100644 --- a/lib/WorkflowMain.groovy +++ b/lib/WorkflowMain.groovy @@ -10,22 +10,28 @@ class WorkflowMain { " https://doi.org/10.1038/s41587-020-0439-x\n\n" } - // Print help to screen + // Generate help string public static String help(workflow, params, log) { String line_sep = ' \\ \n\t' - def command_example = params.wf.example_cmd.join(line_sep) - def command = 'nextflow run ' + workflow.manifest.name + line_sep + command_example - def help_string = '' + String command_example = params.wf.example_cmd.join(line_sep) + String command = 'nextflow run ' + workflow.manifest.name + line_sep + command_example + String help_string = '' + help_string += NfcoreTemplate.logo(workflow, params.monochrome_logs) help_string += NfcoreSchema.paramsHelp(workflow, params, command) help_string += '\n' + citation(workflow) + '\n' return help_string } - // Print parameter summary log to screen + // Generate parameter summary log string public static String paramsSummaryLog(workflow, params, log) { - def summary_log = '' + String workflow_version = NfcoreTemplate.version(workflow) + String summary_log = '' + summary_log += NfcoreTemplate.logo(workflow, params.monochrome_logs) summary_log += NfcoreSchema.paramsSummaryLog(workflow, params) summary_log += '\n' + citation(workflow) + '\n' + summary_log += NfcoreTemplate.dashedLine(params.monochrome_logs) + summary_log += "\nThis is ${workflow.manifest.name} ${workflow_version}.\n" + summary_log += NfcoreTemplate.dashedLine(params.monochrome_logs) return summary_log } @@ -37,6 +43,23 @@ class WorkflowMain { System.exit(0) } + // Print workflow version and exit on --version + if (params.version) { + String workflow_version = NfcoreTemplate.version(workflow) + log.info "${workflow.manifest.name} ${workflow_version}" + System.exit(0) + } + + // Explode on conda + // conda.enabled seems to be backward compatible but wrap this + // in a generic catch just in case + try { + if (workflow.session.config.conda.enabled) { + log.error "Sorry, this workflow is not compatible with Conda, please use -profile standard (Docker) or -profile singularity." + System.exit(1) + } + } catch(Exception e) {} + // Validate workflow parameters via the JSON schema if (params.validate_params) { NfcoreSchema.validateParameters(workflow, params, log) diff --git a/main.nf b/main.nf index bc7ff02..d21d8eb 100644 --- a/main.nf +++ b/main.nf @@ -306,7 +306,6 @@ process makeReport { input: path versions path "params.json" - val denovo path "pychopper_report/*" path"jaffal_csv/*" val sample_ids @@ -322,7 +321,7 @@ process makeReport { // Convert the sample_id arrayList. sids = new BlankSeparatedList(sample_ids) def report_name = "wf-transcriptomes-report.html" - def OPT_DENOVO = denovo ? "--denovo" : '' + def OPT_DENOVO = params.transcriptome_source == "denovo" ? "--denovo" : '' """ if [ -f "de_report/OPTIONAL_FILE" ]; then dereport="" @@ -432,15 +431,15 @@ workflow pipeline { full_len_reads = summariseConcatReads.out.input_reads pychopper_report = file("$projectDir/data/OPTIONAL_FILE") } - if (params.transcriptome_assembly){ + if (params.transcriptome_source != "precomputed"){ - if (params.denovo){ - println("Doing de novo assembly") + if (params.transcriptome_source == "denovo"){ + log.info("Doing de novo assembly") assembly = denovo_assembly(full_len_reads, ref_genome) } else { build_minimap_index(ref_genome) - println("Doing reference based transcript analysis") + log.info("Doing reference based transcript analysis") assembly = reference_assembly(build_minimap_index.out.index, ref_genome, full_len_reads) } assembly_stats = assembly.stats.map{ it -> it[1]}.collect() @@ -455,7 +454,7 @@ workflow pipeline { run_gffcompare(merge_gff_bundles.out.gff, ref_annotation) - if (params.denovo){ + if (params.transcriptome_source == "denovo"){ // Use the per-sample, de novo-assembled CDS seq_for_transcriptome_build = assembly.cds }else { @@ -463,7 +462,7 @@ workflow pipeline { // So map this reference to all sample_ids seq_for_transcriptome_build = sample_ids.flatten().combine(Channel.fromPath(params.ref_genome)) } - + get_transcriptome( merge_gff_bundles.out.gff .join(run_gffcompare.out.gffcmp_dir) @@ -517,7 +516,6 @@ workflow pipeline { makeReport( software_versions, workflow_params, - params.denovo, pychopper_report, jaffal_out, summariseConcatReads.out.summary.map{it->it[0]}.collect(), @@ -541,19 +539,18 @@ workflow pipeline { } - if (!use_ref_ann && !params.denovo && params.transcriptome_assembly){ + if (!use_ref_ann && params.transcriptome_source == "reference-guided"){ results = assembly.stats.concat( get_transcriptome.out.transcriptome.flatMap(map_sample_ids_cls)) .map {it -> it[1]} .concat(results) } - if (params.denovo){ + if (params.transcriptome_source == "denovo"){ results = assembly.cds.concat( assembly.stats, seq_for_transcriptome_build, get_transcriptome.out.transcriptome.flatMap(map_sample_ids_cls), - merge_gff_bundles.out.gff, assembly.opt_qual_ch.flatMap { it -> l = [] @@ -596,10 +593,12 @@ workflow { error = "--fastq: File doesn't exist, check path." } - if (!params.denovo && !params.ref_genome){ - error = "--ref_genome must be supplied unless doing de novo assembly (--denovo)" + if (params.transcriptome_source == "precomputed" && !params.ref_transcriptome){ + error = "As transcriptome source parameter is precomputed you must include a ref_transcriptome parameter" + } + if (params.transcriptome_source == "reference-guided" && !params.ref_genome){ + error = "As transcriptome source is reference guided you must include a ref_genome parameter" } - if (params.ref_genome){ ref_genome = file(params.ref_genome, type: "file") if (!ref_genome.exists()) { @@ -609,7 +608,7 @@ workflow { ref_genome = file("$projectDir/data/OPTIONAL_FILE") } - if (params.denovo && params.ref_annotation) { + if (params.transcriptome_source == "denovo" && params.ref_annotation) { error = "Reference annotation with de denovo assembly is not supported" } @@ -648,7 +647,7 @@ workflow { condition_sheet = file("$projectDir/data/OPTIONAL_FILE") } if (error){ - println(error) + throw new Exception(error) }else{ reads = fastq_ingress([ "input":params.fastq, diff --git a/nextflow.config b/nextflow.config index fbd9124..42f8562 100644 --- a/nextflow.config +++ b/nextflow.config @@ -15,10 +15,11 @@ params { fastq = null ref_genome = null ref_annotation = null - transcriptome_assembly = true + transcriptome_source = "reference-guided" threads = 4 // Thresholds for viewing isoforms in report table isoform_table_nrows = 5000 + out_dir = "output" sample = null @@ -26,8 +27,9 @@ params { wfversion = "v0.1.6" aws_image_prefix = null aws_queue = null - report_name = "report" process_label = "isoforms" + analyse_unclassified = false + version = false monochrome_logs = false validate_params = true @@ -72,52 +74,9 @@ params { disable_ping = false //// Denovo-specific parameters - denovo = false - - // Batch size in kilobases (if -1 then it is calculated based on the number of cores and bases): - batch_size = -1 - - // Maximum sequences per input batch (-1 means no limit): - batch_max_seq = -1 - - // Clustering mode: - cls_mode = "sahlin" - - // Kmer size: - kmer_size = 11 - - // Window size: - window_size = 15 - - // Minimum cluser size in the left batch: - min_left_cls = 2 - - // Consensus period (-1 means no consensus): - consensus_period = 500 - - // Minimum consensus sample size: - consensus_minimum = 50 - - // Maximum consensus sample size: - consensus_maximum = -150 - - // Minimum number of minimizers shared between read and cluster: - min_shared = 5 - - // Minimum average quality value: - min_qual = 7.0 - - // Minmum mapped fraction of read to be included in cluster: - mapped_threshold = 0.65 - - // Minimum aligned fraction of read to be included in cluster: - aligned_threshold = 0.2 - - // Minimum fraction of minimizers shared compared to best hit, in order to continue mapping: - min_fraction = 0.8 - - // Minimum probability for i consecutive minimizers to be different between read and representative: - min_prob_no_hits = 0.1 + + isOnClust2_batch_size = -1 + isOnClust2_sort_options = "--batch-size -1 --kmer-size 11 --window-size 15 --min-shared 5 --min-qual 7.0 --mapped-threshold 0.65 --aligned-threshold 0.2 --min-fraction 0.8 --min-prob-no-hits 0.0 -M -1 -P 500 -g 50 -c 150 -F 2" ////// Fusion detection parameters jaffal_refBase = null @@ -146,6 +105,8 @@ params { "--jaffal_genome hg38", "--jaffal_annotation genCode22" ] + agent = null + container_sha = "sha3d3c83523695550f398cbe095551b1192de5085a" } } @@ -153,10 +114,10 @@ manifest { name = 'epi2me-labs/wf-transcriptomes' author = 'Oxford Nanopore Technologies' homePage = 'https://github.com/epi2me-labs/wf-transcriptomes' - description = 'RNA/cDNA isoform analysis workflow' + description = 'Transcriptome analysis workflow including gene fusions and differential expression' mainScript = 'main.nf' nextflowVersion = '>=20.10.0' - //version = 'v0.0.1' + version = 'v0.1.6' } executor { @@ -166,11 +127,15 @@ executor { } } +epi2melabs { + tags = "isoforms, transcriptomics, denovo" +} + // used by default for "standard" (docker) and singularity profiles, // other profiles may override. process { withLabel:isoforms { - container = "ontresearch/wf-transcriptomes:${params.wfversion}" + container = "ontresearch/wf-transcriptomes:${params.wf.container_sha}" } shell = ['/bin/bash', '-euo', 'pipefail'] } @@ -197,21 +162,9 @@ profiles { } - // profile using conda environments conda { - docker.enabled = false - process { - withLabel:isoforms { - conda = "${projectDir}/environment.yaml" - } - shell = ['/bin/bash', '-euo', 'pipefail'] + conda.enabled = true } - conda { - enabled = true // required for 22.08 - cacheDir = "" - useMamba = true - } -} // Using AWS batch. // May need to set aws.region and aws.batch.cliPath @@ -221,7 +174,7 @@ profiles { queue = "${params.aws_queue}" memory = '8G' withLabel:isoforms { - container = "${params.aws_image_prefix}-wf-transcriptomes:${params.wfversion}" + container = "${params.aws_image_prefix}-wf-transcriptomes:${params.wf.container_sha}-root" } shell = ['/bin/bash', '-euo', 'pipefail'] } diff --git a/nextflow_schema.json b/nextflow_schema.json index 53abca7..9a46326 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -2,138 +2,156 @@ "$schema": "http://json-schema.org/draft-07/schema", "$id": "https://raw.githubusercontent.com/./master/nextflow_schema.json", "title": "epi2me-labs/wf-transcriptomes", - "description": "Isoform detection and characterisation.", + "description": "Transcriptome analysis workflow including gene fusions and differential expression.", + "demo_url": "https://ont-exd-int-s3-euwst1-epi2me-labs.s3.amazonaws.com/wf-transcriptomes/wf-transcriptomes-demo.tar.gz", "url": "https://github.com/epi2me-labs/wf-transcriptomes", "type": "object", "definitions": { - "basic_input_output_options": { - "title": "Basic Input/Output Options", + "input_options": { + "title": "Input Options", "type": "object", "fa_icon": "fas fa-terminal", - "description": "Define where the pipeline should find input data and save output data.", + "description": "Parameters for finding and handling input data for analysis.", + "properties": { + "fastq": { + "type": "string", + "format": "path", + "demo_data": "${projectDir}/test_data/fastq", + "description": "FASTQ files to use in the analysis.", + "help_text": "This accepts one of three cases: (i) the path to a single FASTQ file; (ii) the path to a top-level directory containing FASTQ files; (iii) the path to a directory containing one level of sub-directories which in turn contain FASTQ files. In the first and second case, a sample name can be supplied with `--sample`. In the last case, the data is assumed to be multiplexed with the names of the sub-directories as barcodes. In this case, a sample sheet can be provided with `--sample_sheet`." + }, + "transcriptome_source": { + "type": "string", + "enum": [ + "precomputed", + "reference-guided", + "denovo" + ], + "description": "Select how the transcriptome used for analysis should be prepared.", + "help_text": "To analyse only gene fusions and differential expression use of an existing transcriptome may be preferred and so 'precomputed' should be selected. In this case the 'ref_transcriptome' parameter should be specified. To create a reference transcriptome using an existing reference genome, select 'reference guided' and specify the 'ref_genome' parameter. To create a transcriptome from your sequencing data select 'denovo'." + }, + "ref_genome": { + "type": "string", + "format": "file-path", + "demo_data": "${projectDir}/test_data/SIRV_150601a.fasta", + "description": "Path to reference genome sequence [.fa/.fq/.fa.gz/fq.gz]. Required for reference-based workflow.", + "help_text": "A reference genome is required for reference-based assembly of a transcriptome." + }, + "ref_transcriptome": { + "type": "string", + "default": "null", + "format": "file-path", + "description": "Transcriptome reference file. Required for precomputed transcriptome calculation and for differential expression analysis.", + "help_text": "A reference transcriptome related to the sample under study. Must be supplied when the 'Transcriptome source' parameter has been set to 'precomputed' or to perform differential expression." + }, + "ref_annotation": { + "type": "string", + "format": "file-path", + "demo_data": "${projectDir}/test_data/SIRV_isoforms.gtf", + "description": "A reference annotation in GTF format", + "help_text": "This will be used for guiding the transcriptome assembly and to label transcripts with their corresponding gene identifiers." + }, + "direct_rna": { + "type": "boolean", + "description": "Set to true for direct RNA sequencing.", + "help_text": " Omits the pychopper step." + }, + "analyse_unclassified": { + "type": "boolean", + "description": "Analyse unclassified reads from input directory. By default the workflow will not process reads in the unclassified directory.", + "help_text": "If selected and if the input is a multiplex directory the workflow will also process the unclassified directory." + } + }, + "required": [ + "fastq", + "transcriptome_source" + ] + }, + "output_options": { + "title": "Output Options", + "type": "object", + "description": "Parameters for saving and naming workflow outputs.", + "default": "", "properties": { "out_dir": { "type": "string", "format": "directory-path", "default": "output", "description": "Directory for output of all user-facing files." - }, - "fastq": { - "type": "string", - "format": "file-path", - "demo_data": "${projectDir}/test_data/fastq", - "description": "A fastq file or directory containing fastq input files or directories of input files.", - "help_text": "If directories named \\\"barcode*\\\" are found under the `--fastq` directory the data is assumed to be multiplex and each barcode directory will be processed independently. If `.fastq(.gz)` files are found under the `--fastq` directory the sample is assumed to not be multiplexed. In this second case `--samples` should be a simple name rather than a CSV file." - }, - "sample": { - "type": "string", - "description": "A sample name for non-multiplexed data. Permissible if passing a file or directory of .fastq(.gz)." - }, - "sample_sheet": { - "type": "string", - "format": "file-path", - "description": "CSV file with columns named `barcode`, `sample_name` and `type`. Permissible if passing a directory containing barcodeXX sub-directories." - }, - "ref_genome": { - "type": "string", - "format": "file-path", - "demo_data": "${projectDir}/test_data/SIRV_150601a.fasta", - "description": "Path to reference genome sequence [.fa/.fq/.fa.gz/fq.gz]. Required for reference-based workflow" - }, - "ref_annotation": { - "type": "string", - "format": "file-path", - "demo_data": "${projectDir}/test_data/SIRV_isoforms.gtf", - "description": "A reference annotation of gff format" - }, - "transcriptome_assembly": { - "type": "boolean", - "default": true, - "description": "Find a reference assembly and use in differential expression analysis, set to false if you want to use exisiting ref_transcriptome." - } - }, - "required": [ - "fastq" - ] - }, - "global_options": { - "title": "Global options", - "type": "object", - "description": "Options for both sub-workflows", - "properties": { - "threads": { - "type": "integer", - "default": 4 - }, - "pychopper_opts": { - "type": "string", - "description": "Extra pychopper opts", - "default": "-m edlib" - }, - "direct_rna": { - "type": "boolean", - "description": "Set to true for direct RNA sequencing. Omits the pychopper step.", - "default": false - }, - "bundle_min_reads": { - "type": "integer", - "description": "Minimum size of bam bundle for parallel processing." - }, - "stringtie_opts": { - "type": "string", - "description": "Extra options for stringtie transcript assembly.", - "default": " --conservative " - }, - "isoform_table_nrows": { - "type": "integer", - "description": "Maximum rows to dispay in the isoform report table", - "default": 5000 - }, - "denovo": { - "type": "boolean", - "description": "Use denovo transcript assembly rather than reference guided", - "default": false } } }, - "reference_wf_options": { + "sample_options": { + "title": "Sample Options", + "type": "object", + "description": "Parameters that relate to samples such as sample sheets and sample names.", + "default": "", + "properties": { + "sample_sheet": { + "type": "string", + "format": "file-path", + "description": "A CSV file used to map barcodes to sample aliases. The sample sheet can be provided when the input data is a directory containing sub-directories with FASTQ files.", + "help_text": "The sample sheet is a CSV file with, minimally, columns named `barcode` and `alias`. Extra columns are allowed. A `type` column is required for certain workflows and should have the following values; `test_sample`, `positive_control`, `negative_control`, `no_template_control`." + }, + "sample": { + "type": "string", + "description": "A single sample name for non-multiplexed data. Permissible if passing a single .fastq(.gz) file or directory of .fastq(.gz) files." + } + } + }, + "options_for_reference_based_workflow": { "title": "Options for reference-based workflow", "type": "object", "description": "Parameters that are used solely for the reference-guided workflow", "properties": { "plot_gffcmp_stats": { "type": "boolean", - "description": "Create a pdf of plots from showing gffcompare results" + "description": "Create a PDF of plots from showing gffcompare results", + "help_text": "If set to true, a PDF file containing detailed gffcompare reults will be output" }, "gffcompare_opts": { "type": "string", - "description": "Extra options for gffcompare -r", - "default": " -R " + "description": "Extra command-line options to give to gffcompare -r", + "default": " -R ", + "help_text": "For a list of possible options see [gffcompare](https://ccb.jhu.edu/software/stringtie/gffcompare.shtml)." }, "minimap_index_opts": { "type": "string", - "description": "minimap2 extra indexing options.", - "default": "-k14" + "description": "Extra command-line options for minimap2 indexing.", + "default": "-k14", + "help_text": "See [minimap2 index options](https://lh3.github.io/minimap2/minimap2.html#4) for more information. These will only be relevant in the reference based transcriptome assembly." }, "minimap2_opts": { "type": "string", - "description": "minimap2 extra mapping options.", - "default": "-uf" + "description": "Additional command-line options for minimap2 alignment.", + "default": "-uf", + "help_text": "See [minimap2 options](https://lh3.github.io/minimap2/minimap2.html#5) for further information. These will only be relevant in the reference based transcriptome assembly." }, "minimum_mapping_quality": { "type": "integer", "description": "filter aligned reads by MAPQ quality.", - "default": 40 + "default": 40, + "help_text": "Reads that do not meet this mapping quality after minimap2 alignment, will be filtered out." }, "poly_context": { "type": "integer", "description": "Region size at end of reads to apply poly(A) filter.", + "help_text": "Mispriming of polyT primers can occur when, instead of priming transcription from a polyA tail, it is primed from internal polyA rich regions in the genome. In these cases the 3` end of the transcript will not be captured and should be discarded. This parameter defines the size of a genomic region centered around the 3` alignment position from which to search for polyA rich regions.", + "hidden": true, "default": 24 }, "max_poly_run": { "type": "integer", "description": "Max poly(A) region allowed with poly_context-sized end regions.", + "help_text": "See `poly_context` parameter. This parameter defines the maximum allowed polyA tract within a `poly_context` defined genomic region.", + "hidden": true, "default": 8 + }, + "stringtie_opts": { + "type": "string", + "description": "Extra command-line options for stringtie transcript assembly.", + "default": " --conservative ", + "help_text": "For additional String tie options see [here](https://github.com/gpertea/stringtie#stringtie-options)." } } }, @@ -142,115 +160,55 @@ "type": "object", "description": "Parameters that are used solely for the de novo workflow", "properties": { - "batch_size": { + "isOnClust2_batch_size": { "type": "integer", - "description": "Maximum sequences per input batch (-1 means no limit)", + "description": "Number of batches to to process the data in.", + "help_text": "If set to -1 number of batches witll be the same as the number of threads avaiable.", "default": -1 }, - "batch_max_seq": { - "type": "integer", - "description": "Maximum sequences per input batch (-1 means no limit)", - "default": -1 - }, - "cls_mode": { + "isOnClust2_sort_options": { "type": "string", - "description": "Clustering mode", - "default": "sahlin" - }, - "kmer_size": { - "type": "integer", - "description": "Kmer size", - "default": 11 - }, - "window_size": { - "type": "integer", - "description": "Window size", - "default": 15 - }, - "min_left_cls": { - "type": "integer", - "description": "Minimum cluser size in the left batch", - "default": 2 - }, - "consensus_period": { - "type": "integer", - "description": "Consensus period (-1 means no consensus)", - "default": 500 - }, - "consensus_minimum": { - "type": "integer", - "description": "Minimum consensus sample size:", - "default": 50 - }, - "consensus_maximum": { - "type": "integer", - "description": "Maximum consensus sample size", - "default": -150 - }, - "min_shared": { - "type": "integer", - "description": "Minimum number of minimizers shared between read and cluster", - "default": 5 - }, - "min_qual": { - "description": "Minimum average quality value", - "type": "number", - "default": 7.0 - }, - "mapped_threshold": { - "description": "Minimum mapped fraction of read to be included in cluster", - "type": "number", - "default": 0.65 - }, - "aligned_threshold": { - "type": "number", - "description": "Minimum aligned fraction of read to be included in cluster", - "default": 0.2 - }, - "min_fraction": { - "type": "number", - "description": "Minimum fraction of minimizers shared compared to best hit, in order to continue mapping", - "default": 0.8 - }, - "min_prob_no_hits": { - "type": "number", - "description": "Minimum probability for i consecutive minimizers to be different between read and representative", - "default": 0.2 + "description": "Additional command-line options for isOnClust2 sort.", + "help_text": "isOnClust2 is used for **de novo** transcript assembly. Options for the sort command can be be supplied like so `-opt1 arg -opt2 arg`. Available arguments can be found at [isOnClust2](https://github.com/nanoporetech/isONclust2). It is recommended not to alter this parameter.", + "default": "--kmer-size 11 --window-size 15 --min-shared 5 --min-qual 7.0 --mapped-threshold 0.65 --aligned-threshold 0.2 --min-fraction 0.8 --min-prob-no-hits 0.0 -M -1 -P 500 -g 50 -c 150 -F 2" } } }, - "fusion_detection_options": { - "title": "Gene fusion detection options", + "gene_fusion_detection_options": { + "title": "Gene Fusion Detection Options", "type": "object", "description": "Parameters for gene fusion detection", "properties": { "jaffal_refBase": { "type": "string", - "format": "path", - "description": "JAFFAl reference genome directory" + "format": "directory-path", + "description": "JAFFAl reference genome directory.", + "help_text": "JAFFAL human hg38 reference data directory can be downloaded from here: https://figshare.com/ndownloader/files/25410494 or see the README for alternative instructions. If custom gemome files are required, see the instructions here: https://github.com/Oshlack/JAFFA/wiki/FAQandTroubleshooting#how-can-i-generate-the-reference-files-for-a-non-supported-genome." }, "jaffal_genome": { "type": "string", - "description": "Genome reference prefix. e.g. hg38", + "description": "Genome reference prefix. e.g. hg38.", + "help_text": "JAFFAL reference files are prefixed with the genome reference file name and need to be supplied . If using the human reference data provided by JAFFAL, this can be left at `hg38`.", "default": "hg38" }, "jaffal_annotation": { "type": "string", - "description": "Annotation prefix", + "description": "Annotation suffix.", + "help_text": "JAFFAL reference files are suffixed with the annotation filename and this needs to be supplied. For the human hg38 reference data supplied by JAFFAL, this is `genCode22`.", "default": "genCode22" }, "jaffal_dir": { "type": "string", - "format": "path", - "description": "Path to JAFFAL git code directory. Defaults is epi2me-labs container location", + "format": "directory-path", + "description": "Path to the JAFFAL code directory. If running within EPI2ME-Labs, the default path of /home/epi2melabs/JAFFA within the application container will be used. If using outside of EPI2ME-Labs, the path to the code directory downloaded from github should be supplied.", "default": "/home/epi2melabs/JAFFA" } } }, "differential_expression_options": { - "title": "Differential expression options", + "title": "Differential Expression Options", "type": "object", - "description": "", + "description": "Options relevant to the differential expression section of the workflow, only need to set if running DE.", "default": "", "properties": { "de_analysis": { @@ -261,98 +219,118 @@ "condition_sheet": { "type": "string", "format": "file-path", - "description": "tsv with (sample, condition, type)", - "default": "null" - }, - "ref_transcriptome": { - "type": "string", + "description": "TSV file with sample_id, condition", "default": "null", - "format": "file-path", - "description": "Transcriptome reference file, if supplied will be used instead of finding transcriptome using reference assembly or denovo methods" + "help_text": "The condition sheet should be a headed TSV file with two columns sample_id,condition. Should be at least 3 repeats for each condition." }, "min_gene_expr": { "type": "integer", "default": 10, - "description": "Minimum gene counts" + "description": "Minimum gene counts", + "help_text": "The minimum number of total mapped sequence reads for a gene to be considered expressed." }, "min_feature_expr": { "type": "integer", "default": 3, - "description": "Minimum transcript counts" + "description": "Minimum transcript counts", + "help_text": "The minimum number of total mapped sequence reads for a transcript to be considered." + }, + "min_samps_gene_expr": { + "type": "integer", + "description": "Genes expressed in a minimum of this many samples will be included in the differential expression analysis.", + "default": 3, + "help_text": "A gene must be mapped to at least this minimum number of samples for the gene be included in the analysis." }, "min_samps_feature_expr": { "type": "integer", "default": 1, - "description": "Transcripts expressed in minimum this many samples" - }, - "min_samps_gene_expr": { - "type": "integer", - "description": "Genes expressed in minimum this many samples", - "default": 3 + "description": "Transcripts expressed in minimum this many samples", + "help_text": "A transcript must be mapped in at least this this minimum number of samples to be included in the analysis." } } }, - "meta_data": { - "title": "Meta Data", + "advanced_options": { + "title": "Advanced Options", "type": "object", - "description": "", - "default": "", + "description": "Advanced options for configuring processes inside the workflow.", "properties": { - "report_name": { - "type": "string", - "default": "report", - "description": "Output report filename suffix." + "threads": { + "type": "integer", + "default": 2, + "description": "Number of CPU threads.", + "help_text": "Only provided to processes including alignment and and assembly that benefit from multiple threads." }, - "disable_ping": { - "type": "boolean", - "default": false, - "description": "Enable to prevent sending a workflow ping." + "pychopper_opts": { + "type": "string", + "description": "Extra pychopper opts", + "default": "-m edlib", + "help_text": "See available options (here)[https://github.com/epi2me-labs/pychopper#usage]" + }, + "bundle_min_reads": { + "type": "integer", + "description": "Minimum size of bam bundle for parallel processing." + }, + "isoform_table_nrows": { + "type": "integer", + "description": "Maximum rows to dispay in the isoform report table", + "default": 5000 } } }, - "generic_options": { - "title": "Generic options", + "miscellaneous_options": { + "title": "Miscellaneous Options", "type": "object", - "fa_icon": "far fa-question-circle", - "description": "Less common options for the pipeline, typically set in a config file.", - "help_text": "These options are common to all nf-core pipelines and allow you to customise some of the core preferences for how the pipeline runs.\n\nTypically these options would be set in a Nextflow config file loaded for all pipeline runs, such as `~/.nextflow/config`.", + "description": "Everything else.", + "default": "", "properties": { "help": { "type": "boolean", "description": "Display help text.", "fa_icon": "fas fa-question-circle", "hidden": true + }, + "disable_ping": { + "type": "boolean", + "description": "Enable to prevent sending a workflow ping." } } } }, "allOf": [ { - "$ref": "#/definitions/basic_input_output_options" + "$ref": "#/definitions/input_options" }, { - "$ref": "#/definitions/global_options" + "$ref": "#/definitions/output_options" }, { - "$ref": "#/definitions/reference_wf_options" + "$ref": "#/definitions/sample_options" + }, + { + "$ref": "#/definitions/options_for_reference_based_workflow" }, { "$ref": "#/definitions/denovo_wf_options" }, { - "$ref": "#/definitions/fusion_detection_options" + "$ref": "#/definitions/gene_fusion_detection_options" }, { "$ref": "#/definitions/differential_expression_options" }, { - "$ref": "#/definitions/meta_data" + "$ref": "#/definitions/advanced_options" }, { - "$ref": "#/definitions/generic_options" + "$ref": "#/definitions/miscellaneous_options" } ], "properties": { + "version": { + "type": "boolean", + "description": "Display version and exit.", + "hidden": true + }, "aws_image_prefix": { "type": "string", "hidden": true @@ -379,6 +357,6 @@ }, "docs": { "intro": "## Introduction\n\nThis workflow identifies RNA isoforms using either cDNA or direct RNA (dRNA) \nOxford Nanopore reads.\n\n### Preprocesing\ncDNA reads are initially preprocessed by [pychopper](https://github.com/epi2me-labs/pychopper) \nfor the identification of full-length reads, as well as trimming and orientation correction (This step is omitted for \n direct RNA reads).\n\n\n### Transcript assembly\n\n#### Reference-aided transcript assembly approach\n* Full length reads are mapped to a supplied reference genome using [minimap2](https://github.com/lh3/minimap2)\n* Transcripts are assembled by [stringtie](http://ccb.jhu.edu/software/stringtie) \nin long read mode (with or without a guide reference annotation) to generate the GFF annotation.\n* The annotation generated by the pipeline is compared to the reference annotation. \nusing [gffcompare](http://ccb.jhu.edu/software/stringtie/gffcompare.shtml)\n\n#### de novo-based transcript assembly (experimental!)\n* Sequence clusters are generated using [isONclust2](https://github.com/nanoporetech/isONclust2)\n * If a reference genome is supplied, cluster quality metrics are determined by comparing \n with clusters generated from a minimap2 alignment.\n* A consensus sequence for each cluster is generated using [spoa](https://github.com/rvaser/spoa)\n* Three rounds of polishing using racon and minimap2 to give a final polished CDS for each gene.\n* Full-length reads are then mapped to these polished CDS.\n* Transcripts are assembled by stringtie as for the reference-based approach.\n* __Note__: This approach is currently not supported with direct RNA reads.\n\n### Fusion gene detection\nFusion gene detection is performed using [JAFFA](https://github.com/Oshlack/JAFFA), with the JAFFAL extension for use \nwith ONT long reads. \n\n### Differential expression analysis\n\nDifferential gene expression (DGE) and differential transcript usage (DTU) analyses aim to identify genes and/or transcripts that show statistically altered expression patterns in a studied biological system. The results of the differential analyses are presented in a quantitative format and therefore the degree of change (up or down regulation) between experimental conditions can be calculated for each gene identified.\n\nThese differential analyses work by taking a \u201csnapshot\u201d of mRNA abundance and calculating the relative levels of transcripts and isoforms. In this context, expression corresponds to the number of messenger RNAs (mRNA) measured from each gene isoform within the organism / tissue / culture being investigated. In order to determine expression levels across the whole genome, sequence data specifically targeting the mRNA molecules can be generated.\n\nOxford Nanopore Technologies provides a number of sequencing solutions to allow users to generate the required snapshot of gene expression. This can be achieved by both sequencing the mRNA directly, or via a complementary DNA (cDNA) proxy. In contrast to short read sequencing technologies, entire mRNA transcripts can be captured as single reads. The example data provided with this tutorial is from a study based on the PCR-cDNA kit. This is a robust choice for performing differential transcript usage studies. This kit is suitable for preparation of sequence libraries from low mRNA input quantities. The cDNA population is enriched through PCR with low bias; an important prerequisite for the subsequent statistical analysis.\n\n[Workflow-transcriptomes](https://github.com/epi2me-labs/wf-transcriptomes) includes a subworkflow for DGE and DTU. The first step involves using either a reference alignment or _de novo_ assembly approach to create a set of mRNA sequences per sample. These are merged into a non-redundant transcriptome using [stringtie merge](http://ccb.jhu.edu/software/stringtie). The reads are then aligned to the transcriptome using minimap2 in a splice-aware manner. [Salmon](https://github.com/COMBINE-lab/salmon) is used for transcript quantification, giving per transcript counts and then the following R packages are used for analysis.\n\n### Pre-filtering of quantitative data using DRIMSeq\nDRIMSeq (Nowicka and Robinson (2016)) is used to filter the transcript count data from the salmon analysis. The filter step will be used to select for genes and transcripts that satisfy rules for the number of samples in which a gene or transcript must be observed and minimum threshold levels for the number of observed reads. The parameters used for filtering are defined in the config.yaml file. The default parameters defined for this analysis include\n* min_samps_gene_expr = 3 - a transcript must be mapped to a gene in at least this minimum number of samples for the gene be included in the analysis\n*\tmin_samps_feature_expr = 1 - a transcript must be mapped to an isoform in at least this this minimum number of samples for the gene isoform to be included in the analysis\n*\tmin_gene_expr = 10 - the minimum number of total mapped sequence reads for a gene to be considered expressed\n*\tmin_feature_expr = 3 - the minimum number of total mapped sequence reads for a gene isoform to be considered\n\n### edgeR based differential expression analysis\n+A statistical analysis is first performed using edgeR (Robinson, McCarthy, and Smyth (2010), McCarthy et al. (2012)) to identify the subset of differentially expressed genes. The filtered list of gene counts is used as input. A normalisation factor is calculated for each sequence library (using the default TMM method - please see McCarthy et al. (2012) for further details). The defined experimental design is used to calculate estimates of dispersion for each of the gene features. Statistical tests are calculated using the contrasts defined in the experimental design. The differentially expressed genes are corrected for false discovery (fdr) using the method of Benjamini & Hochberg (Benjamini and Hochberg (1995))\n\n### Differential transcript usage using DEXSeq\nDifferential transcript usage analysis is performed using the R DEXSeq package (Reyes et al. (2013)). Similar to the edgeR package, DEXSeq estimates the variance between the biological replicates and applies generalised linear models for the statistical testing. The key difference is that the DEXSeq method looks for differences at the exon count level. DEXSeq uses the filtered transcript count data prepared earlier in this analysis. \n\n### StageR stage-wise analysis of DGE and DTU\nThe final component of this isoform analysis is a stage-wise statistical test using the R software package `stageR` (Van den Berge and Clement (2018)). stageR uses (1) the raw p-values for DTU from the DEXSeq analysis in the previous section and (2) a false-discovery corrected set of p-values from testing whether individual genes contain at least one exon showing DTU. A hierarchical two-stage statistical testing evaluates the set of genes for DTU.\n\n## Running the workflow\nFor the differential expression analysis section you should have at least 3 repeats for each sample. \nYour fastq data will need to be organised in to 6 directories that represent 3 repeats for each condition. You may also need to provide a condition sheet. \n\n\n## Analysis \nDifferential gene expression is sensitive to the input data quantity and quality. There should be equivalence between samples in the number of sequence reads, mapped reads and quality scores. The sequence and alignment summary plots in the report can be used to assess these metrics. There is also a table that shows the transcript per million(TPM) calculated from the salmon counts. TPM normalizes the data for gene length and then sequencing depth, and makes it easier to compare across samples compared to counts.\n\n### Workflow inputs\n- Directory containing cDNA/direct RNA reads. Or a directory containing subdirectories each with reads from different samples\n (in fastq/fastq.gz format)\n- Reference genome in fasta format (required for reference-based assembly).\n- Optional reference annotation in GFF2/3 format (required for differential expression analysis `--de_analysis`).\n- For fusion detection, JAFFAL reference files (see Quickstart) \n", - "links": "## Useful links\n\n* [nextflow](https://www.nextflow.io/)\n* [docker](https://www.docker.com/products/docker-desktop)\n* [Singularity](https://sylabs.io/singularity/)\n* [conda](https://docs.conda.io/en/latest/miniconda.html)\n* [racon](https://github.com/isovic/racon)\n* [spoa](https://github.com/rvaser/spoa)\n* [inONclust](https://github.com/ksahlin/isONclust)\n* [isONclust2](https://github.com/nanoporetech/isONclust2)" + "links": "## Useful links\n\n* [nextflow](https://www.nextflow.io/)\n* [docker](https://www.docker.com/products/docker-desktop)\n* [Singularity](https://sylabs.io/singularity/)\n* [racon](https://github.com/isovic/racon)\n* [spoa](https://github.com/rvaser/spoa)\n* [inONclust](https://github.com/ksahlin/isONclust)\n* [isONclust2](https://github.com/nanoporetech/isONclust2)" } } \ No newline at end of file diff --git a/subworkflows/denovo_assembly.nf b/subworkflows/denovo_assembly.nf index e813e87..8c3571f 100644 --- a/subworkflows/denovo_assembly.nf +++ b/subworkflows/denovo_assembly.nf @@ -170,7 +170,7 @@ process make_batches { minimum_batch_size = 2000 """ b=0 - if [ ${params.batch_size} -lt \$b ]; + if [ ${params.isOnClust2_batch_size} -lt \$b ]; then nr_bases=\$(seqkit stats -T $fastq|cut -f 5| sed '2q;d') let batch_size=\$nr_bases/1000/$maxcpus @@ -179,19 +179,13 @@ process make_batches { batch_size=$minimum_batch_size fi else - batch_size=${params.batch_size} + batch_size=${params.isOnClust2_batch_size} fi echo "Batch size:\$batch_size"; echo "Num bases: \$nr_bases"; - init_cls_options="--batch-size \$batch_size --kmer-size ${params.kmer_size} --window-size ${params.window_size} \ - --min-shared ${params.min_shared} --min-qual ${params.min_qual} \ - --mapped-threshold ${params.mapped_threshold} --aligned-threshold ${params.aligned_threshold} \ - --min-fraction ${params.min_fraction} --min-prob-no-hits ${params.min_prob_no_hits} \ - -M ${params.batch_max_seq} -P ${params.consensus_period} -g ${params.consensus_minimum} \ - -c ${params.consensus_maximum} -F ${params.min_left_cls} " - mkdir -p sorted; isONclust2 sort \$init_cls_options -v -o sorted $fastq; + mkdir -p sorted; isONclust2 sort $params.isOnClust2_sort_options -v -o sorted $fastq; """ }