From 541b6c5073c38b441562a8e28eab959070e383c8 Mon Sep 17 00:00:00 2001 From: Abhinav Sharma Date: Sat, 5 Dec 2020 18:01:26 +0530 Subject: [PATCH 1/5] Initial commit with DSL2 template --- .travis.yml | 36 -- CHANGELOG.md | 24 +- CODE_OF_CONDUCT.md | 8 +- Dockerfile | 20 +- LICENSE | 2 + README.md | 97 ++- Singularity | 18 - assets/email_template.html | 4 +- assets/email_template.txt | 29 +- {conf => assets}/multiqc_config.yaml | 6 +- assets/nf-core-deepvariant_logo.png | Bin 0 -> 115948 bytes assets/samplesheet.csv | 8 + assets/sendmail_template.txt | 48 +- bin/check_samplesheet.py | 168 ++++++ bin/markdown_to_html.r | 51 -- bin/scrape_software_versions.py | 60 +- conf/awsbatch.config | 25 - conf/base.config | 69 ++- conf/binac.config | 22 - conf/genomes.config | 49 -- conf/igenomes.config | 420 +++++++++++++ conf/modules.config | 35 ++ conf/test.config | 21 +- conf/test_full.config | 21 + docs/README.md | 15 +- docs/configuration/adding_your_own.md | 86 --- docs/images/deepvariant_logo.png | Bin 16720 -> 0 bytes docs/images/deepvariant_logo.svg | 205 ------- docs/images/nf-core-deepvariant_logo.png | Bin 0 -> 115948 bytes docs/installation.md | 115 ---- docs/output.md | 73 ++- docs/troubleshooting.md | 16 - docs/usage.md | 363 ++++-------- environment.yml | 18 +- lib/Checks.groovy | 48 ++ lib/Completion.groovy | 127 ++++ lib/Headers.groovy | 43 ++ lib/Schema.groovy | 228 +++++++ main.nf | 558 +++--------------- modules/local/process/cat_fastq.nf | 54 ++ modules/local/process/functions.nf | 59 ++ .../local/process/get_software_versions.nf | 32 + modules/local/process/samplesheet_check.nf | 44 ++ modules/local/subworkflow/input_check.nf | 23 + modules/nf-core/software/fastqc/functions.nf | 59 ++ modules/nf-core/software/fastqc/main.nf | 43 ++ modules/nf-core/software/fastqc/meta.yml | 67 +++ nextflow.config | 198 ++++--- nextflow_schema.json | 253 ++++++++ pics/pic_workflow.jpg | Bin 39852 -> 0 bytes 50 files changed, 2303 insertions(+), 1665 deletions(-) delete mode 100644 .travis.yml delete mode 100644 Singularity rename {conf => assets}/multiqc_config.yaml (79%) create mode 100644 assets/nf-core-deepvariant_logo.png create mode 100644 assets/samplesheet.csv create mode 100755 bin/check_samplesheet.py delete mode 100755 bin/markdown_to_html.r delete mode 100644 conf/awsbatch.config delete mode 100644 conf/binac.config delete mode 100644 conf/genomes.config create mode 100644 conf/igenomes.config create mode 100644 conf/modules.config create mode 100644 conf/test_full.config delete mode 100644 docs/configuration/adding_your_own.md delete mode 100644 docs/images/deepvariant_logo.png delete mode 100644 docs/images/deepvariant_logo.svg create mode 100644 docs/images/nf-core-deepvariant_logo.png delete mode 100644 docs/installation.md delete mode 100644 docs/troubleshooting.md create mode 100644 lib/Checks.groovy create mode 100644 lib/Completion.groovy create mode 100644 lib/Headers.groovy create mode 100644 lib/Schema.groovy create mode 100644 modules/local/process/cat_fastq.nf create mode 100644 modules/local/process/functions.nf create mode 100644 modules/local/process/get_software_versions.nf create mode 100644 modules/local/process/samplesheet_check.nf create mode 100644 modules/local/subworkflow/input_check.nf create mode 100644 modules/nf-core/software/fastqc/functions.nf create mode 100644 modules/nf-core/software/fastqc/main.nf create mode 100644 modules/nf-core/software/fastqc/meta.yml create mode 100644 nextflow_schema.json delete mode 100644 pics/pic_workflow.jpg diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 93addc2..0000000 --- a/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -sudo: required -language: python -jdk: openjdk8 -services: docker -python: "3.6" -cache: pip -matrix: - fast_finish: true - -before_install: - # PRs to master are only ok if coming from dev branch - - '[ $TRAVIS_PULL_REQUEST = "false" ] || [ $TRAVIS_BRANCH != "master" ] || ([ $TRAVIS_PULL_REQUEST_SLUG = $TRAVIS_REPO_SLUG ] && [ $TRAVIS_PULL_REQUEST_BRANCH = "dev" ])' - # Pull the docker image first so the test doesn't wait for this - - docker pull nfcore/deepvariant - # Fake the tag locally so that the pipeline runs properly - - docker tag nfcore/deepvariant nfcore/deepvariant:1.0 - -install: - # Install Nextflow - - mkdir /tmp/nextflow && cd /tmp/nextflow - - wget -qO- get.nextflow.io | bash - - sudo ln -s /tmp/nextflow/nextflow /usr/local/bin/nextflow - # Install nf-core/tools - - pip install nf-core - # Reset - - mkdir ${TRAVIS_BUILD_DIR}/tests && cd ${TRAVIS_BUILD_DIR}/tests - -env: - - NXF_VER='18.10.1' # Specify a minimum NF version that should be tested and work - - NXF_VER='' # Plus: get the latest NF version and check that it works - -script: - # Lint the pipeline code - - nf-core lint ${TRAVIS_BUILD_DIR} - # Run the pipeline with the test profile - - nextflow run ${TRAVIS_BUILD_DIR} -profile test,docker diff --git a/CHANGELOG.md b/CHANGELOG.md index d1ae7e5..0611c17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,22 +1,16 @@ # nf-core/deepvariant: Changelog -## v1.0 - 2018-11-19 +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). -This release marks the point where the pipeline was moved from lifebit-ai/DeepVariant over to the new nf-core community, at nf-core/DeepVariant. The [nf-core](http://nf-co.re/) template was used to help ensure that the pipeline meets the standards of nf-core. +## v1.0dev - [date] -In summary, the main changes are: +Initial release of nf-core/deepvariant, created with the [nf-core](https://nf-co.re/) template. -- Rebranding and renaming throughout the pipeline to nf-core -- Updating many parts of the pipeline config and style to meet nf-core standards -- Continuous integration tests with Travis CI -- Dependencies installed via conda -- Added support for BAM input as file, not just a folder -- Added channels to process input files -- Added separate processes for each of the steps in FASTA file preprocessing -- Use of genomes config to specify relevant reference genome files similar to igenomes -- Added BAM size dependent setting of memory -- Slightly improved documentation +### `Added` -...and many more minor tweaks. +### `Fixed` -Thanks to everyone who has worked on this release! +### `Dependencies` + +### `Deprecated` diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 2109619..405fb1b 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -34,13 +34,13 @@ This Code of Conduct applies both within project spaces and in public spaces whe ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team on the [Gitter channel](https://gitter.im/nf-core/Lobby). The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team on [Slack](https://nf-co.re/join/slack). The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct/][version] -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ +[homepage]: https://contributor-covenant.org +[version]: https://www.contributor-covenant.org/version/1/4/code-of-conduct/ diff --git a/Dockerfile b/Dockerfile index 7330b7d..32ceea4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,17 @@ -FROM nfcore/base -LABEL authors="phil@lifebit.ai" \ - description="Docker image containing all requirements for nf-core/deepvariant pipeline" +FROM nfcore/base:dev +LABEL authors="Abhinav Sharma" \ + description="Docker image containing all software requirements for the nf-core/deepvariant pipeline" +# Install the conda environment COPY environment.yml / -RUN conda env create -f /environment.yml && conda clean -a -ENV PATH /opt/conda/envs/nf-core-deepvariant-1.0/bin:$PATH +RUN conda env create --quiet -f /environment.yml && conda clean -a + +# Add conda installation dir to PATH (instead of doing 'conda activate') +ENV PATH /opt/conda/envs/nf-core-deepvariant-1.0dev/bin:$PATH + +# Dump the details of the installed packages to a file for posterity +RUN conda env export --name nf-core-deepvariant-1.0dev > nf-core-deepvariant-1.0dev.yml + +# Instruct R processes to use these empty files instead of clashing with a local version +RUN touch .Rprofile +RUN touch .Renviron diff --git a/LICENSE b/LICENSE index 9cf1062..3d82551 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,7 @@ MIT License +Copyright (c) Abhinav Sharma + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights diff --git a/README.md b/README.md index a878b94..ab70d3e 100644 --- a/README.md +++ b/README.md @@ -1,84 +1,69 @@ -![deepvariant](https://raw.githubusercontent.com/nf-core/deepvariant/master/docs/images/deepvariant_logo.png) +# ![nf-core/deepvariant](docs/images/nf-core-deepvariant_logo.png) -# nf-core/deepvariant +**Google's DeepVariant as a Nextflow workflow.**. -**Deep Variant as a Nextflow pipeline** +[![GitHub Actions CI Status](https://github.com/nf-core/deepvariant/workflows/nf-core%20CI/badge.svg)](https://github.com/nf-core/deepvariant/actions) +[![GitHub Actions Linting Status](https://github.com/nf-core/deepvariant/workflows/nf-core%20linting/badge.svg)](https://github.com/nf-core/deepvariant/actions) +[![Nextflow](https://img.shields.io/badge/nextflow-%E2%89%A520.04.0-brightgreen.svg)](https://www.nextflow.io/) -[![Build Status](https://travis-ci.org/nf-core/deepvariant.svg?branch=master)](https://travis-ci.org/nf-core/deepvariant) -[![Nextflow](https://img.shields.io/badge/nextflow-%E2%89%A518.10.1-brightgreen.svg)](https://www.nextflow.io/) -[![Gitter](https://img.shields.io/badge/gitter-%20join%20chat%20%E2%86%92-4fb99a.svg)](https://gitter.im/nf-core/Lobby) - -[![install with bioconda](https://img.shields.io/badge/install%20with-bioconda-brightgreen.svg)](http://bioconda.github.io/) +[![install with bioconda](https://img.shields.io/badge/install%20with-bioconda-brightgreen.svg)](https://bioconda.github.io/) [![Docker](https://img.shields.io/docker/automated/nfcore/deepvariant.svg)](https://hub.docker.com/r/nfcore/deepvariant) -![Singularity Container available](https://img.shields.io/badge/singularity-available-7E4C74.svg) - -A Nextflow pipeline for running the [Google DeepVariant variant caller](https://github.com/google/deepvariant). - -## What is DeepVariant and why in Nextflow? - -The Google Brain Team in December 2017 released a [Variant Caller](https://www.ebi.ac.uk/training/online/course/human-genetic-variation-i-introduction/variant-identification-and-analysis/what-variant) based on DeepLearning: DeepVariant. - -In practice, DeepVariant first builds images based on the BAM file, then it uses a DeepLearning image recognition approach to obtain the variants and eventually it converts the output of the prediction in the standard VCF format. +[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23deepvariant-4A154B?logo=slack)](https://nfcore.slack.com/channels/deepvariant) -DeepVariant as a Nextflow pipeline provides several advantages to the users. It handles automatically, through **preprocessing steps**, the creation of some extra needed indexed and compressed files which are a necessary input for DeepVariant, and which should normally manually be produced by the users. -Variant Calling can be performed at the same time on **multiple BAM files** and thanks to the internal parallelization of Nextflow no resources are wasted. -Nextflow's support of Docker allows to produce the results in a computational reproducible and clean way by running every step inside of a **Docker container**. +## Introduction -For more detailed information about Google's DeepVariant please refer to [google/deepvariant](https://github.com/google/deepvariant) or this [blog post](https://research.googleblog.com/2017/12/deepvariant-highly-accurate-genomes.html).
-For more information about DeepVariant in Nextflow please refer to this [blog post](https://blog.lifebit.ai/post/deepvariant/?utm_campaign=documentation&utm_source=github&utm_medium=web) +The pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It comes with docker containers making installation trivial and results highly reproducible. ## Quick Start -**Warning DeepVariant can be very computationally intensive to run.** +1. Install [`nextflow`](https://nf-co.re/usage/installation) -To **test** the pipeline you can run: +2. Install any of [`Docker`](https://docs.docker.com/engine/installation/), [`Singularity`](https://www.sylabs.io/guides/3.0/user-guide/) or [`Podman`](https://podman.io/) for full pipeline reproducibility _(please only use [`Conda`](https://conda.io/miniconda.html) as a last resort; see [docs](https://nf-co.re/usage/configuration#basic-configuration-profiles))_ -```bash -nextflow run nf-core/deepvariant -profile test,docker -``` +3. Download the pipeline and test it on a minimal dataset with a single command: -A typical run on **whole genome data** looks like this: + ```bash + nextflow run nf-core/deepvariant -profile test, + ``` -```bash -nextflow run nf-core/deepvariant --genome hg19 --bam yourBamFile --bed yourBedFile -profile standard,docker -``` + > Please check [nf-core/configs](https://github.com/nf-core/configs#documentation) to see if a custom config file to run nf-core pipelines already exists for your Institute. If so, you can simply use `-profile ` in your command. This will enable either `docker` or `singularity` and set the appropriate execution settings for your local compute environment. -In this case variants are called on the bam files contained in the testdata directory. The hg19 version of the reference genome is used. -One vcf files is produced and can be found in the folder "results" +4. Start running your own analysis! -A typical run on **whole exome data** looks like this: + -```bash -nextflow run nf-core/deepvariant --exome --genome hg19 --bam_folder myBamFolder --bed myBedFile -profile standard,docker -``` + ```bash + nextflow run nf-core/deepvariant -profile --input samplesheet.csv --genome GRCh37 + ``` + +See [usage docs](https://nf-co.re/deepvariant/usage) for all of the available options when running the pipeline. ## Documentation -The nf-core/deepvariant documentation is split into the following files: +The nf-core/deepvariant pipeline comes with documentation about the pipeline: [usage](https://nf-co.re/deepvariant/usage) and [output](https://nf-co.re/deepvariant/output). + + -1. [Installation](docs/installation.md) -2. [Running the pipeline](docs/usage.md) -3. Pipeline configuration - - [Adding your own system](docs/configuration/adding_your_own.md) - - [Reference genomes](docs/configuration/reference_genomes.md) -4. [Output and how to interpret the results](docs/output.md) -5. [Troubleshooting](docs/troubleshooting.md) -6. [More about DeepVariant](docs/about.md) +## Credits -## More about the pipeline +nf-core/deepvariant was originally written by Abhinav Sharma. -As shown in the following picture, the worklow both contains **preprocessing steps** ( light blue ones ) and proper **variant calling steps** ( darker blue ones ). +## Contributions and Support -Some input files ar optional and if not given, they will be automatically created for the user during the preprocessing steps. If these are given, the preprocessing steps are skipped. For more information about preprocessing, please refer to the "INPUT PARAMETERS" section. +If you would like to contribute to this pipeline, please see the [contributing guidelines](.github/CONTRIBUTING.md). -The worklow **accepts one reference genome and multiple BAM files as input**. The variant calling for the several input BAM files will be processed completely indipendently and will produce indipendent VCF result files. The advantage of this approach is that the variant calling of the different BAM files can be parallelized internally by Nextflow and take advantage of all the cores of the machine in order to get the results at the fastest. +For further information or help, don't hesitate to get in touch on the [Slack `#deepvariant` channel](https://nfcore.slack.com/channels/deepvariant) (you can join with [this invite](https://nf-co.re/join/slack)). -

- -

+## Citation -## Credits + + -This pipeline was originally developed at [Lifebit](https://lifebit.ai/?utm_campaign=documentation&utm_source=github&utm_medium=web), by @luisas, to ease and reduce cost for variant calling analyses +You can cite the `nf-core` publication as follows: -Many thanks to nf-core and those who have helped out along the way too, including (but not limited to): @ewels, @MaxUlysse, @apeltzer, @sven1103 & @pditommaso +> **The nf-core framework for community-curated bioinformatics pipelines.** +> +> Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen. +> +> _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x). +> ReadCube: [Full Access Link](https://rdcu.be/b1GjZ) diff --git a/Singularity b/Singularity deleted file mode 100644 index bbeecf8..0000000 --- a/Singularity +++ /dev/null @@ -1,18 +0,0 @@ -From:nfcore/base -Bootstrap:docker - -%labels - MAINTAINER Phil Palmer - DESCRIPTION Singularity image containing all requirements for the nf-core/deepvariant pipeline - VERSION 1.0 - -%environment - PATH=/opt/conda/envs/nf-core-deepvariant-1.0/bin:$PATH - export PATH - -%files - environment.yml / - -%post - /opt/conda/bin/conda env create -f /environment.yml - /opt/conda/bin/conda clean -a diff --git a/assets/email_template.html b/assets/email_template.html index dcd3574..0275b73 100644 --- a/assets/email_template.html +++ b/assets/email_template.html @@ -5,12 +5,14 @@ - + nf-core/deepvariant Pipeline Report
+ +

nf-core/deepvariant v${version}

Run Name: $runName

diff --git a/assets/email_template.txt b/assets/email_template.txt index e82c6c3..4f37348 100644 --- a/assets/email_template.txt +++ b/assets/email_template.txt @@ -1,6 +1,12 @@ -======================================== - nf-core/deepvariant v${version} -======================================== +---------------------------------------------------- + ,--./,-. + ___ __ __ __ ___ /,-._.--~\\ + |\\ | |__ __ / ` / \\ |__) |__ } { + | \\| | \\__, \\__/ | \\ |___ \\`-._,-`-, + `._,._,' + nf-core/deepvariant v${version} +---------------------------------------------------- + Run Name: $runName <% if (success){ @@ -17,23 +23,6 @@ ${errorReport} } %> -<% if (!success){ - out << """#################################################### -## nf-core/deepvariant execution completed unsuccessfully! ## -#################################################### -The exit status of the task that caused the workflow execution to fail was: $exitStatus. -The full error message was: - -${errorReport} -""" -} else { - out << "## nf-core/deepvariant execution completed successfully! ##" -} -%> - - - - The workflow was completed at $dateComplete (duration: $duration) The command used to launch the workflow was as follows: diff --git a/conf/multiqc_config.yaml b/assets/multiqc_config.yaml similarity index 79% rename from conf/multiqc_config.yaml rename to assets/multiqc_config.yaml index fcd5aa8..ea163f0 100644 --- a/conf/multiqc_config.yaml +++ b/assets/multiqc_config.yaml @@ -3,5 +3,9 @@ report_comment: > analysis pipeline. For information about how to interpret these results, please see the documentation. report_section_order: - nf-core/deepvariant-software-versions: + software_versions: order: -1000 + nf-core-deepvariant-summary: + order: -1001 + +export_plots: true diff --git a/assets/nf-core-deepvariant_logo.png b/assets/nf-core-deepvariant_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4f2545e137a8ee5d9bf7f9f714fc5c79511da687 GIT binary patch literal 115948 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

nKHNJ3P*ny8Z6pY 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

$m zo*x_;V=18Z%{dQ>8N*FM!A@h^o79J;;nj)o*mhnI96{2PDYAToIszAE=MK44hL3vR z1A>5Pxb>%g?x0r-WvE$+ci>hAk902C*G;AVWAQp!v1yaixn@6`^z_a=79{pyDVU%= zvDxe89evx+1Rx_>vEs&(ak5su>FgWR0N>-dPi_C9g&PYX5w%HCESMK91a!z#xZP#s zHp7;DojPjQ_J~rgMC^MDGPDgBwN@6B$@JDQE*9i)&@7(~IG03^@jyeSGAe{V8Dt zt!@M~J@l=%9G_DGq_0;zKvLy1K>AZ+yJcMZ-ab7c#T7$fRfQiL2~c6KTG=3AI~#C-Q> z_PhLOI{oxqi`Vju4pRu)KOXvs&E9!5HD}OH>)G2?XT>m1y)c#6v9dY+AZ}MSavPyg zEl~gU3$0&rQPirvc(`ID&PldpQYsmRh?)(rnb=Ur92$>YTjy$a+KewO6!u0@`WixS&KLW5-n`5-r#)Y0Q7>fg!u9o40@x90Vn6h~A{}LW z9S#N;fy+blLJRhpV_s}teY;yQ!Dt$7xTJv8gQiGd@wdNb;6d;f54c+Dop zM`h)?#+t-+)<%(^m-rZJ>Lx5*=6!mq7?wOK5ZvsTXo9V~cC7h_)Ch8_&S4w5>A=QYf#r z^WbWDG~qk28Y7XdZ8(Z)Den$OxFb;S%yfQ-L`)^5PW{}atj^_QEAFN)-kGYJd~n7P z(rqDI9kT$1Y>b!;BW7g=8M#M|M;kP{Wj1j|FbIDXim^7_?=0-XoV)oYYRiwY(3SMD zxOCSmOcPBF^Rd}|NyA+I^d&GUr*v)D*eTyrdbhTz<=f*?w^?fHDOmbQ;c#@0%&QYD z55`BrRz1_X-FX}7V|PV1dYXSY-&q#*4i4Gq_e>Q&zH^zeVepW8*dwT1Bd=`d$>yJo zB=a}{h!q$*Ls0c*s=sxZUCMN<*D!eS&;WsLSix)-i_7rygVGVudKY6)Lkf%d5!#4m z+e~u@Nb9k>6Mv4%FvCSOqZ(EY4`4SgGw##g4$n!hZHAW7JME6cs(gix**4I-a!X^M zZZ>um&&ncoBD1!F7|hh}?U;gn)jaXmev)%9EhHArnNBJPqz58?+7!ZK%Qr7i&u%x; zl9XUPkP)~nIsg=28!vGfZZ4Zbmc!{~p{dalarT~W7_~poGzfcr@*H-TINP2dsMtkE z2r#)oCmP z_S#QoSDL|`Wb;>Ua^(k@hm|aZYqb>%SeT$CPR#4sv=|2m}dS20#r?Y4_Ab?07FBj+xBzR|L?nby_PikilZ zb&Y7rFqjk?>v~*lO^xO1mbqc`${b_L@P5+o8_B2N*olB8L`72P#E+mo+ds-uugtF;H=UOiXw~+ww zzc-yafDiQs8spKg_S^l-}CDBtfwiPSL zCwZ*9G_LY}1#KaztMdV2CB*O7TRGpVW*^c-%RYydt|UGT&#R0jCa9QuZV$cg^9EK=7C;zF#30@pO_)oz|@Z#^k{;7HeUi@kPzn=|J{`cZh z|M{5zV@68>TMq;R-Qd&+_`mB8?|Q&)3xS{ojO?+o3umPgigRSZ>;HWH#{&OvE%3c) Z7j~yg1`;jha-CxYxS5S<jMA) literal 0 HcmV?d00001 diff --git a/assets/samplesheet.csv b/assets/samplesheet.csv new file mode 100644 index 0000000..cd5a39a --- /dev/null +++ b/assets/samplesheet.csv @@ -0,0 +1,8 @@ +group,replicate,fastq_1,fastq_2 +control,1,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz +control,2,/path/to/fastq/files/AEG588A2_S2_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A2_S2_L002_R2_001.fastq.gz +control,3,/path/to/fastq/files/AEG588A3_S3_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A3_S3_L002_R2_001.fastq.gz +treatment,1,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz, +treatment,2,/path/to/fastq/files/AEG588A5_S5_L003_R1_001.fastq.gz, +treatment,3,/path/to/fastq/files/AEG588A6_S6_L003_R1_001.fastq.gz, +treatment,3,/path/to/fastq/files/AEG588A6_S6_L004_R1_001.fastq.gz, diff --git a/assets/sendmail_template.txt b/assets/sendmail_template.txt index fd1cd73..95a365b 100644 --- a/assets/sendmail_template.txt +++ b/assets/sendmail_template.txt @@ -1,11 +1,53 @@ To: $email Subject: $subject Mime-Version: 1.0 -Content-Type: multipart/related;boundary="nfmimeboundary" +Content-Type: multipart/related;boundary="nfcoremimeboundary" ---nfmimeboundary +--nfcoremimeboundary Content-Type: text/html; charset=utf-8 $email_html ---nfmimeboundary-- +--nfcoremimeboundary +Content-Type: image/png;name="nf-core-deepvariant_logo.png" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: inline; filename="nf-core-deepvariant_logo.png" + +<% out << new File("$projectDir/assets/nf-core-deepvariant_logo.png"). + bytes. + encodeBase64(). + toString(). + tokenize( '\n' )*. + toList()*. + collate( 76 )*. + collect { it.join() }. + flatten(). + join( '\n' ) %> + +<% +if (mqcFile){ +def mqcFileObj = new File("$mqcFile") +if (mqcFileObj.length() < mqcMaxSize){ +out << """ +--nfcoremimeboundary +Content-Type: text/html; name=\"multiqc_report\" +Content-Transfer-Encoding: base64 +Content-ID: +Content-Disposition: attachment; filename=\"${mqcFileObj.getName()}\" + +${mqcFileObj. + bytes. + encodeBase64(). + toString(). + tokenize( '\n' )*. + toList()*. + collate( 76 )*. + collect { it.join() }. + flatten(). + join( '\n' )} +""" +}} +%> + +--nfcoremimeboundary-- diff --git a/bin/check_samplesheet.py b/bin/check_samplesheet.py new file mode 100755 index 0000000..51b1846 --- /dev/null +++ b/bin/check_samplesheet.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python + +# TODO nf-core: Update the script to check the samplesheet +# This script is based on the example at: https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_sispa.csv + +import os +import sys +import errno +import argparse + + +def parse_args(args=None): + Description = "Reformat nf-core/deepvariant samplesheet file and check its contents." + Epilog = "Example usage: python check_samplesheet.py " + + parser = argparse.ArgumentParser(description=Description, epilog=Epilog) + parser.add_argument("FILE_IN", help="Input samplesheet file.") + parser.add_argument("FILE_OUT", help="Output file.") + return parser.parse_args(args) + + +def make_dir(path): + if len(path) > 0: + try: + os.makedirs(path) + except OSError as exception: + if exception.errno != errno.EEXIST: + raise exception + + +def print_error(error, context="Line", context_str=""): + error_str = "ERROR: Please check samplesheet -> {}".format(error) + if context != "" and context_str != "": + error_str = "ERROR: Please check samplesheet -> {}\n{}: '{}'".format( + error, context.strip(), context_str.strip() + ) + print(error_str) + sys.exit(1) + + +# TODO nf-core: Update the check_samplesheet function +def check_samplesheet(file_in, file_out): + """ + This function checks that the samplesheet follows the following structure: + + group,replicate,fastq_1,fastq_2 + WT,1,WT_LIB1_REP1_1.fastq.gz,WT_LIB1_REP1_2.fastq.gz + WT,1,WT_LIB2_REP1_1.fastq.gz,WT_LIB2_REP1_2.fastq.gz + WT,2,WT_LIB1_REP2_1.fastq.gz,WT_LIB1_REP2_2.fastq.gz + KO,1,KO_LIB1_REP1_1.fastq.gz,KO_LIB1_REP1_2.fastq.gz + """ + + sample_run_dict = {} + with open(file_in, "r") as fin: + + ## Check header + MIN_COLS = 3 + # TODO nf-core: Update the column names for the input samplesheet + HEADER = ["group", "replicate", "fastq_1", "fastq_2"] + header = [x.strip('"') for x in fin.readline().strip().split(",")] + if header[: len(HEADER)] != HEADER: + print("ERROR: Please check samplesheet header -> {} != {}".format(",".join(header), ",".join(HEADER))) + sys.exit(1) + + ## Check sample entries + for line in fin: + lspl = [x.strip().strip('"') for x in line.strip().split(",")] + + ## Check valid number of columns per row + if len(lspl) < len(HEADER): + print_error( + "Invalid number of columns (minimum = {})!".format(len(HEADER)), + "Line", + line, + ) + num_cols = len([x for x in lspl if x]) + if num_cols < MIN_COLS: + print_error( + "Invalid number of populated columns (minimum = {})!".format(MIN_COLS), + "Line", + line, + ) + + ## Check sample name entries + sample, replicate, fastq_1, fastq_2 = lspl[: len(HEADER)] + if sample: + if sample.find(" ") != -1: + print_error("Group entry contains spaces!", "Line", line) + else: + print_error("Group entry has not been specified!", "Line", line) + + ## Check replicate entry is integer + if not replicate.isdigit(): + print_error("Replicate id not an integer!", "Line", line) + replicate = int(replicate) + + ## Check FastQ file extension + for fastq in [fastq_1, fastq_2]: + if fastq: + if fastq.find(" ") != -1: + print_error("FastQ file contains spaces!", "Line", line) + if not fastq.endswith(".fastq.gz") and not fastq.endswith(".fq.gz"): + print_error( + "FastQ file does not have extension '.fastq.gz' or '.fq.gz'!", + "Line", + line, + ) + + ## Auto-detect paired-end/single-end + sample_info = [] ## [single_end, fastq_1, fastq_2] + if sample and fastq_1 and fastq_2: ## Paired-end short reads + sample_info = ["0", fastq_1, fastq_2] + elif sample and fastq_1 and not fastq_2: ## Single-end short reads + sample_info = ["1", fastq_1, fastq_2] + else: + print_error("Invalid combination of columns provided!", "Line", line) + ## Create sample mapping dictionary = {sample: {replicate : [ single_end, fastq_1, fastq_2 ]}} + if sample not in sample_run_dict: + sample_run_dict[sample] = {} + if replicate not in sample_run_dict[sample]: + sample_run_dict[sample][replicate] = [sample_info] + else: + if sample_info in sample_run_dict[sample][replicate]: + print_error("Samplesheet contains duplicate rows!", "Line", line) + else: + sample_run_dict[sample][replicate].append(sample_info) + + ## Write validated samplesheet with appropriate columns + if len(sample_run_dict) > 0: + out_dir = os.path.dirname(file_out) + make_dir(out_dir) + with open(file_out, "w") as fout: + + fout.write(",".join(["sample", "single_end", "fastq_1", "fastq_2"]) + "\n") + for sample in sorted(sample_run_dict.keys()): + + ## Check that replicate ids are in format 1.. + uniq_rep_ids = set(sample_run_dict[sample].keys()) + if len(uniq_rep_ids) != max(uniq_rep_ids): + print_error( + "Replicate ids must start with 1..!", + "Group", + sample, + ) + for replicate in sorted(sample_run_dict[sample].keys()): + + ## Check that multiple runs of the same sample are of the same datatype + if not all( + x[0] == sample_run_dict[sample][replicate][0][0] for x in sample_run_dict[sample][replicate] + ): + print_error( + "Multiple runs of a sample must be of the same datatype!", + "Group", + sample, + ) + ## Write to file + for idx, sample_info in enumerate(sample_run_dict[sample][replicate]): + sample_id = "{}_R{}_T{}".format(sample, replicate, idx + 1) + fout.write(",".join([sample_id] + sample_info) + "\n") + + +def main(args=None): + args = parse_args(args) + check_samplesheet(args.FILE_IN, args.FILE_OUT) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/bin/markdown_to_html.r b/bin/markdown_to_html.r deleted file mode 100755 index abe1335..0000000 --- a/bin/markdown_to_html.r +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env Rscript - -# Command line argument processing -args = commandArgs(trailingOnly=TRUE) -if (length(args) < 2) { - stop("Usage: markdown_to_html.r ", call.=FALSE) -} -markdown_fn <- args[1] -output_fn <- args[2] - -# Load / install packages -if (!require("markdown")) { - install.packages("markdown", dependencies=TRUE, repos='http://cloud.r-project.org/') - library("markdown") -} - -base_css_fn <- getOption("markdown.HTML.stylesheet") -base_css <- readChar(base_css_fn, file.info(base_css_fn)$size) -custom_css <- paste(base_css, " -body { - padding: 3em; - margin-right: 350px; - max-width: 100%; -} -#toc { - position: fixed; - right: 20px; - width: 300px; - padding-top: 20px; - overflow: scroll; - height: calc(100% - 3em - 20px); -} -#toc_header { - font-size: 1.8em; - font-weight: bold; -} -#toc > ul { - padding-left: 0; - list-style-type: none; -} -#toc > ul ul { padding-left: 20px; } -#toc > ul > li > a { display: none; } -img { max-width: 800px; } -") - -markdownToHTML( - file = markdown_fn, - output = output_fn, - stylesheet = custom_css, - options = c('toc', 'base64_images', 'highlight_code') -) diff --git a/bin/scrape_software_versions.py b/bin/scrape_software_versions.py index d427718..e240ebf 100755 --- a/bin/scrape_software_versions.py +++ b/bin/scrape_software_versions.py @@ -1,48 +1,36 @@ #!/usr/bin/env python from __future__ import print_function -from collections import OrderedDict -import re +import os -regexes = { - 'nf-core/deepvariant': ['v_nf_deepvariant.txt', r"(\S+)"], - 'Nextflow': ['v_nextflow.txt', r"(\S+)"], - 'DeepVariant': ['v_deepvariant.txt', r"deepvariant-(\S+)-"], - 'Python': ['v_python.txt', r"Python (\S+)"], - 'Pip': ['v_pip.txt', r"pip (\S+)"], - 'Samtools': ['v_samtools.txt', r"samtools (\S+)"], - 'Htslib': ['v_samtools.txt', r"Using htslib (\S+)"], - 'Lbzip2': ['v_lbzip2.txt', r"lbzip2 version (\S+)"], - 'Bzip2': ['v_bzip2.txt', r"bzip2, Version (\S+)"], -} -results = OrderedDict() -results['nf-core/deepvariant'] = 'N/A' -results['Nextflow'] = 'N/A' -results['DeepVariant'] = 'N/A' -results['Python'] = 'N/A' -results['Pip'] = 'N/A' -results['Samtools'] = 'N/A' -results['Htslib'] = 'N/A' -results['Lbzip2'] = 'N/A' -results['Bzip2'] = 'N/A' +results = {} +version_files = [x for x in os.listdir(".") if x.endswith(".version.txt")] +for version_file in version_files: -# Search each file using its regex -for k, v in regexes.items(): - with open(v[0]) as x: - versions = x.read() - match = re.search(v[1], versions) - if match: - results[k] = "v{}".format(match.group(1)) + software = version_file.replace(".version.txt", "") + if software == "pipeline": + software = "nf-core/deepvariant" + + with open(version_file) as fin: + version = fin.read().strip() + results[software] = version # Dump to YAML -print (''' -id: 'nf-core/deepvariant-software-versions' +print( + """ +id: 'software_versions' section_name: 'nf-core/deepvariant Software Versions' section_href: 'https://github.com/nf-core/deepvariant' plot_type: 'html' description: 'are collected at run time from the software output.' data: |
-''') -for k,v in results.items(): - print("
{}
{}
".format(k,v)) -print ("
") +""" +) +for k, v in sorted(results.items()): + print("
{}
{}
".format(k, v)) +print(" ") + +# Write out regexes as csv file: +with open("software_versions.csv", "w") as f: + for k, v in sorted(results.items()): + f.write("{}\t{}\n".format(k, v)) diff --git a/conf/awsbatch.config b/conf/awsbatch.config deleted file mode 100644 index 4a4a002..0000000 --- a/conf/awsbatch.config +++ /dev/null @@ -1,25 +0,0 @@ -/* - * ------------------------------------------------- - * Nextflow config file for AWS Batch - * ------------------------------------------------- - * Imported under the 'awsbatch' Nextflow profile in nextflow.config - * Uses docker for software depedencies automagically, so not specified here. - */ - -aws.region = params.awsregion -process.executor = 'awsbatch' -process.queue = params.awsqueue -executor.awscli = '/home/ec2-user/miniconda/bin/aws' -params.tracedir = './' - -process { - withName:makeExamples_with_bed { - cpus = 4 - } - withName:makeExamples { - cpus = 4 - } - withName:call_variants { - cpus = 4 - } -} diff --git a/conf/base.config b/conf/base.config index 71be5f2..f523a6f 100644 --- a/conf/base.config +++ b/conf/base.config @@ -11,38 +11,45 @@ process { - container = params.container - - cpus = { check_max( 1 * task.attempt, 'cpus' ) } - memory = { check_max( 8.GB * task.attempt, 'memory' ) } - time = { check_max( 2.h * task.attempt, 'time' ) } - - errorStrategy = { task.exitStatus in [143,137] ? 'retry' : 'finish' } - maxRetries = 1 - maxErrors = '-1' - - withName:make_examples { - cpus = { check_max( 20, 'cpus' ) } - memory = { bam.size() < 1000000000 ? 4.GB : check_max( (bam.size() >> 30) * 10.GB * task.attempt, 'memory')} - time = { check_max( 10.h * task.attempt, 'time' ) } + // TODO nf-core: Check the defaults for all processes + cpus = { check_max( 1 * task.attempt, 'cpus' ) } + memory = { check_max( 6.GB * task.attempt, 'memory' ) } + time = { check_max( 4.h * task.attempt, 'time' ) } + + errorStrategy = { task.exitStatus in [143,137,104,134,139] ? 'retry' : 'finish' } + maxRetries = 1 + maxErrors = '-1' + + // Process-specific resource requirements + // NOTE - Please try and re-use the labels below as much as possible. + // These labels are used and recognised by default in DSL2 files hosted on nf-core/modules. + // If possible, it would be nice to keep the same label naming convention when + // adding in your local modules too. + // TODO nf-core: Customise requirements for specific processes. + // See https://www.nextflow.io/docs/latest/config.html#config-process-selectors + withLabel:process_low { + cpus = { check_max( 2 * task.attempt, 'cpus' ) } + memory = { check_max( 12.GB * task.attempt, 'memory' ) } + time = { check_max( 4.h * task.attempt, 'time' ) } } - withName:call_variants { - cpus = { check_max( 20, 'cpus' ) } - memory = { bam.size() < 1000000000 ? 4.GB : check_max( (bam.size() >> 30) * 10.GB * task.attempt, 'memory')} - time = { check_max( 10.h * task.attempt, 'time' ) } + withLabel:process_medium { + cpus = { check_max( 6 * task.attempt, 'cpus' ) } + memory = { check_max( 36.GB * task.attempt, 'memory' ) } + time = { check_max( 8.h * task.attempt, 'time' ) } } - withName:postprocess_variants { - cpus = { check_max( 20, 'cpus' ) } - memory = { bam.size() < 1000000000 ? 4.GB : check_max( (bam.size() >> 30) * 10.GB * task.attempt, 'memory')} - time = { check_max( 10.h * task.attempt, 'time' ) } + withLabel:process_high { + cpus = { check_max( 12 * task.attempt, 'cpus' ) } + memory = { check_max( 72.GB * task.attempt, 'memory' ) } + time = { check_max( 16.h * task.attempt, 'time' ) } } - - -} - -params { - // Defaults only, expecting to be overwritten - max_memory = 128.GB - max_cpus = 16 - max_time = 240.h + withLabel:process_long { + time = { check_max( 20.h * task.attempt, 'time' ) } + } + withLabel:error_ignore { + errorStrategy = 'ignore' + } + withLabel:error_retry { + errorStrategy = 'retry' + maxRetries = 2 + } } diff --git a/conf/binac.config b/conf/binac.config deleted file mode 100644 index 68ba98f..0000000 --- a/conf/binac.config +++ /dev/null @@ -1,22 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * Nextflow config file for use with Singularity on BINAC cluster in Tuebingen - * ---------------------------------------------------------------------------- - * Defines basic usage limits and singularity image id. - */ - -singularity { - enabled = true -} - -process { - beforeScript = 'module load devel/singularity/2.6.0' - executor = 'pbs' - queue = 'short' -} - -params { - max_memory = 128.GB - max_cpus = 28 - max_time = 48.h -} diff --git a/conf/genomes.config b/conf/genomes.config deleted file mode 100644 index 2d08bc5..0000000 --- a/conf/genomes.config +++ /dev/null @@ -1,49 +0,0 @@ -/* - * ------------------------------------------------- - * Nextflow config file for Genomes paths - * ------------------------------------------------- - * Defines reference genomes, using s3 paths - * Can be used by any config that customises the base - * path using $params.genomes_base / --genomes_base - */ - -params { - // Genomes reference file paths on UPPMAX - genomes { - 'h38' { - fasta="${params.genomes_base}/h38/GRCh38.p10.genome.fa" - fai="${params.genomes_base}/h38/GRCh38.p10.genome.fa.fai" - fastagz="${params.genomes_base}/h38/GRCh38.p10.genome.fa.gz" - gzfai="${params.genomes_base}/h38/GRCh38.p10.genome.fa.gz.fai" - gzi="${params.genomes_base}/h38/GRCh38.p10.genome.fa.gz.gzi" - } - 'hs37d5' { - fasta="${params.genomes_base}/hs37d5/hs37d5.fa" - fai="${params.genomes_base}/hs37d5/hs37d5.fa.fai" - fastagz="${params.genomes_base}/hs37d5/hs37d5.fa.gz" - gzfai="${params.genomes_base}/hs37d5/hs37d5.fa.gz.fai" - gzi="${params.genomes_base}/hs37d5/hs37d5.fa.gz.gzi" - } - 'grch37primary' { - fasta="${params.genomes_base}/GRCh37.dna.primary/Homo_sapiens.GRCh37.dna.primary_assembly.fa" - fai="${params.genomes_base}/GRCh37.dna.primary/Homo_sapiens.GRCh37.dna.primary_assembly.fa.fai" - fastagz="${params.genomes_base}/GRCh37.dna.primary/Homo_sapiens.GRCh37.dna.primary_assembly.fa.gz" - gzfai="${params.genomes_base}/GRCh37.dna.primary/Homo_sapiens.GRCh37.dna.primary_assembly.fa.gz.fai" - gzi="${params.genomes_base}/GRCh37.dna.primary/Homo_sapiens.GRCh37.dna.primary_assembly.fa.gz.gzi" - } - 'hg19chr20' { - fasta="${params.genomes_base}/hg19chr20/chr20.fa" - fai="${params.genomes_base}/hg19chr20/chr20.fa.fai" - fastagz="${params.genomes_base}/hg19chr20/chr20.fa.gz" - gzfai="${params.genomes_base}/hg19chr20/chr20.fa.gz.fai" - gzi="${params.genomes_base}/hg19chr20/chr20.fa.gz.gzi" - } - 'hg19' { - fasta="${params.genomes_base}/hg19/hg19.fa" - fai="${params.genomes_base}/hg19/hg19.fa.fai" - fastagz="${params.genomes_base}/hg19/hg19.fa.gz" - gzfai="${params.genomes_base}/hg19/hg19.fa.gz.fai" - gzi="${params.genomes_base}/hg19/hg19.fa.gz.gzi" - } - } -} diff --git a/conf/igenomes.config b/conf/igenomes.config new file mode 100644 index 0000000..eae4e6a --- /dev/null +++ b/conf/igenomes.config @@ -0,0 +1,420 @@ +/* + * ------------------------------------------------- + * Nextflow config file for iGenomes paths + * ------------------------------------------------- + * Defines reference genomes, using iGenome paths + * Can be used by any config that customises the base + * path using $params.igenomes_base / --igenomes_base + */ + +params { + // illumina iGenomes reference file paths + genomes { + 'GRCh37' { + fasta = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/README.txt" + mito_name = "MT" + macs_gsize = "2.7e9" + blacklist = "${projectDir}/assets/blacklists/GRCh37-blacklist.bed" + } + 'GRCh38' { + fasta = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.bed" + mito_name = "chrM" + macs_gsize = "2.7e9" + blacklist = "${projectDir}/assets/blacklists/hg38-blacklist.bed" + } + 'GRCm38' { + fasta = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/README.txt" + mito_name = "MT" + macs_gsize = "1.87e9" + blacklist = "${projectDir}/assets/blacklists/GRCm38-blacklist.bed" + } + 'TAIR10' { + fasta = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/README.txt" + mito_name = "Mt" + } + 'EB2' { + fasta = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/README.txt" + } + 'UMD3.1' { + fasta = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/README.txt" + mito_name = "MT" + } + 'WBcel235' { + fasta = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.bed" + mito_name = "MtDNA" + macs_gsize = "9e7" + } + 'CanFam3.1' { + fasta = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/README.txt" + mito_name = "MT" + } + 'GRCz10' { + fasta = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.bed" + mito_name = "MT" + } + 'BDGP6' { + fasta = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.bed" + mito_name = "M" + macs_gsize = "1.2e8" + } + 'EquCab2' { + fasta = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/README.txt" + mito_name = "MT" + } + 'EB1' { + fasta = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/README.txt" + } + 'Galgal4' { + fasta = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.bed" + mito_name = "MT" + } + 'Gm01' { + fasta = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/README.txt" + } + 'Mmul_1' { + fasta = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/README.txt" + mito_name = "MT" + } + 'IRGSP-1.0' { + fasta = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.bed" + mito_name = "Mt" + } + 'CHIMP2.1.4' { + fasta = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/README.txt" + mito_name = "MT" + } + 'Rnor_6.0' { + fasta = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.bed" + mito_name = "MT" + } + 'R64-1-1' { + fasta = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.bed" + mito_name = "MT" + macs_gsize = "1.2e7" + } + 'EF2' { + fasta = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/README.txt" + mito_name = "MT" + macs_gsize = "1.21e7" + } + 'Sbi1' { + fasta = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/README.txt" + } + 'Sscrofa10.2' { + fasta = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/README.txt" + mito_name = "MT" + } + 'AGPv3' { + fasta = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.bed" + mito_name = "Mt" + } + 'hg38' { + fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.bed" + mito_name = "chrM" + macs_gsize = "2.7e9" + blacklist = "${projectDir}/assets/blacklists/hg38-blacklist.bed" + } + 'hg19' { + fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/README.txt" + mito_name = "chrM" + macs_gsize = "2.7e9" + blacklist = "${projectDir}/assets/blacklists/hg19-blacklist.bed" + } + 'mm10' { + fasta = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/README.txt" + mito_name = "chrM" + macs_gsize = "1.87e9" + blacklist = "${projectDir}/assets/blacklists/mm10-blacklist.bed" + } + 'bosTau8' { + fasta = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.bed" + mito_name = "chrM" + } + 'ce10' { + fasta = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/README.txt" + mito_name = "chrM" + macs_gsize = "9e7" + } + 'canFam3' { + fasta = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/README.txt" + mito_name = "chrM" + } + 'danRer10' { + fasta = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.bed" + mito_name = "chrM" + } + 'dm6' { + fasta = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.bed" + mito_name = "chrM" + macs_gsize = "1.2e8" + } + 'equCab2' { + fasta = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/README.txt" + mito_name = "chrM" + } + 'galGal4' { + fasta = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/README.txt" + mito_name = "chrM" + } + 'panTro4' { + fasta = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/README.txt" + mito_name = "chrM" + } + 'rn6' { + fasta = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.bed" + mito_name = "chrM" + } + 'sacCer3' { + fasta = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BismarkIndex/" + readme = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Annotation/README.txt" + mito_name = "chrM" + macs_gsize = "1.2e7" + } + 'susScr3' { + fasta = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BWAIndex/genome.fa.{amb,ann,bwt,pac,sa}" + bowtie2 = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/Bowtie2Index/genome.{1.bt2,2.bt2,3.bt2,4.bt2,rev.1.bt2,rev.2.bt2}" + star = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/STARIndex/" + bismark = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BismarkIndex/" + gtf = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.gtf" + bed12 = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.bed" + readme = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/README.txt" + mito_name = "chrM" + } + } +} diff --git a/conf/modules.config b/conf/modules.config new file mode 100644 index 0000000..145a725 --- /dev/null +++ b/conf/modules.config @@ -0,0 +1,35 @@ +/* + * -------------------------------------------------- + * Config file for defining DSL2 per module options + * -------------------------------------------------- + * + * Available keys to override module options: + * args = Additional arguments appended to command in module. + * args2 = Second set of arguments appended to command in module (multi-tool modules). + * publish_dir = Directory to publish results. + * publish_by_id = Publish results in separate folders by meta.id value. + * publish_files = Groovy map where key = "file_ext" and value = "directory" to publish results for that file extension + * The value of "directory" is appended to the standard "publish_dir" path as defined above. + * If publish_files == null (unspecified) - All files are published. + * If publish_files == false - No files are published. + * suffix = File name suffix for output files. + * + */ + +params { + modules { + 'cat_fastq' { + publish_dir = 'fastq' + } + 'fastqc' { + args = "--quiet" + } + 'trimgalore' { + args = "--fastqc" + publish_files = ['txt':'', 'html':'fastqc', 'zip':'fastqc'] + } + 'multiqc' { + args = "" + } + } +} diff --git a/conf/test.config b/conf/test.config index f05b94e..a33b6a3 100644 --- a/conf/test.config +++ b/conf/test.config @@ -4,14 +4,23 @@ * ------------------------------------------------- * Defines bundled input files and everything required * to run a fast and simple test. Use as follows: - * nextflow run nf-core/deepvariant -profile test + * nextflow run nf-core/deepvariant -profile test, */ params { - max_cpus = 2 + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Limit resources so that this can run on GitHub Actions + max_cpus = 2 max_memory = 6.GB - max_time = 48.h - bam = 'https://github.com/nf-core/test-datasets/raw/deepvariant/testdata/NA12878_S1.chr20.10_10p1mb.bam' - bed = 'https://github.com/nf-core/test-datasets/raw/deepvariant/testdata/test_nist.b37_chr20_100kbp_at_10mb.bed' - genome = 'hg19chr20' + max_time = 6.h + + // Input data + // TODO nf-core: Specify the paths to your test data on nf-core/test-datasets + // TODO nf-core: Give any required params for the test so that command line flags are not needed + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_amplicon.csv' + + // Genome references + fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/genome/MN908947.3/GCA_009858895.3_ASM985889v3_genomic.200409.fna.gz' } diff --git a/conf/test_full.config b/conf/test_full.config new file mode 100644 index 0000000..b1a15f1 --- /dev/null +++ b/conf/test_full.config @@ -0,0 +1,21 @@ +/* + * ------------------------------------------------- + * Nextflow config file for running full-size tests + * ------------------------------------------------- + * Defines bundled input files and everything required + * to run a full size pipeline test. Use as follows: + * nextflow run nf-core/deepvariant -profile test_full, + */ + +params { + config_profile_name = 'Full test profile' + config_profile_description = 'Full test dataset to check pipeline function' + + // Input data for full size test + // TODO nf-core: Specify the paths to your full test data ( on nf-core/test-datasets or directly in repositories, e.g. SRA) + // TODO nf-core: Give any required params for the test so that command line flags are not needed + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_amplicon.csv' + + // Genome references + fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/genome/MN908947.3/GCA_009858895.3_ASM985889v3_genomic.200409.fna.gz' +} diff --git a/docs/README.md b/docs/README.md index 3a40edd..7d7078b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,11 +1,10 @@ # nf-core/deepvariant: Documentation -The nf-core/deepvariant documentation is split into the following files: +The nf-core/deepvariant documentation is split into the following pages: -1. [Installation](installation.md) -2. [Running the pipeline](usage.md) -3. Pipeline configuration - * [Adding your own system](configuration/adding_your_own.md) - * [Reference genomes](configuration/reference_genomes.md) -4. [Output and how to interpret the results](output.md) -5. [Troubleshooting](troubleshooting.md) +* [Usage](usage.md) + * An overview of how the pipeline works, how to run it and a description of all of the different command-line flags. +* [Output](output.md) + * An overview of the different results produced by the pipeline and how to interpret them. + +You can find a lot more documentation about installing, configuring and running nf-core pipelines on the website: [https://nf-co.re](https://nf-co.re) diff --git a/docs/configuration/adding_your_own.md b/docs/configuration/adding_your_own.md deleted file mode 100644 index 9647c3a..0000000 --- a/docs/configuration/adding_your_own.md +++ /dev/null @@ -1,86 +0,0 @@ -# nf-core/deepvariant: Configuration for other clusters - -It is entirely possible to run this pipeline on other clusters, though you will need to set up your own config file so that the pipeline knows how to work with your cluster. - -> If you think that there are other people using the pipeline who would benefit from your configuration (eg. other common cluster setups), please let us know. We can add a new configuration and profile which can used by specifying `-profile ` when running the pipeline. - -If you are the only person to be running this pipeline, you can create your config file as `~/.nextflow/config` and it will be applied every time you run Nextflow. Alternatively, save the file anywhere and reference it when running the pipeline with `-c path/to/config` (see the [Nextflow documentation](https://www.nextflow.io/docs/latest/config.html) for more). - -A basic configuration comes with the pipeline, which runs by default (the `standard` config profile - see [`conf/base.config`](../conf/base.config)). This means that you only need to configure the specifics for your system and overwrite any defaults that you want to change. - -## Cluster Environment -By default, pipeline uses the `local` Nextflow executor - in other words, all jobs are run in the login session. If you're using a simple server, this may be fine. If you're using a compute cluster, this is bad as all jobs will run on the head node. - -To specify your cluster environment, add the following line to your config file: - -```nextflow -process.executor = 'YOUR_SYSTEM_TYPE' -``` - -Many different cluster types are supported by Nextflow. For more information, please see the [Nextflow documentation](https://www.nextflow.io/docs/latest/executor.html). - -Note that you may need to specify cluster options, such as a project or queue. To do so, use the `clusterOptions` config option: - -```nextflow -process { - executor = 'SLURM' - clusterOptions = '-A myproject' -} -``` - - -## Software Requirements -To run the pipeline, several software packages are required. How you satisfy these requirements is essentially up to you and depends on your system. If possible, we _highly_ recommend using either Docker or Singularity. - -Please see the [`installation documentation`](../installation.md) for how to run using the below as a one-off. These instructions are about configuring a config file for repeated use. - -### Docker -Docker is a great way to run nf-core/deepvariant, as it manages all software installations and allows the pipeline to be run in an identical software environment across a range of systems. - -Nextflow has [excellent integration](https://www.nextflow.io/docs/latest/docker.html) with Docker, and beyond installing the two tools, not much else is required - nextflow will automatically fetch the [nfcore/deepvariant](https://hub.docker.com/r/nfcore/deepvariant/) image that we have created and is hosted at dockerhub at run time. - -To add docker support to your own config file, add the following: - -```nextflow -docker.enabled = true -process.container = "nfcore/deepvariant" -``` - -Note that the dockerhub organisation name annoyingly can't have a hyphen, so is `nfcore` and not `nf-core`. - - -### Singularity image -Many HPC environments are not able to run Docker due to security issues. -[Singularity](http://singularity.lbl.gov/) is a tool designed to run on such HPC systems which is very similar to Docker. - -To specify singularity usage in your pipeline config file, add the following: - -```nextflow -singularity.enabled = true -process.container = "shub://nf-core/deepvariant" -``` - -If you intend to run the pipeline offline, nextflow will not be able to automatically download the singularity image for you. -Instead, you'll have to do this yourself manually first, transfer the image file and then point to that. - -First, pull the image file where you have an internet connection: - -```bash -singularity pull --name nf-core-deepvariant.simg shub://nf-core/deepvariant -``` - -Then transfer this file and point the config file to the image: - -```nextflow -singularity.enabled = true -process.container = "/path/to/nf-core-deepvariant.simg" -``` - - -### Conda -If you're not able to use Docker or Singularity, you can instead use conda to manage the software requirements. -To use conda in your own config file, add the following: - -```nextflow -process.conda = "$baseDir/environment.yml" -``` diff --git a/docs/images/deepvariant_logo.png b/docs/images/deepvariant_logo.png deleted file mode 100644 index 34e2e17b64dbbca1161af714408b1163c27ee1be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16720 zcma+4byOS96E}?FPH~DufZ%S$-L*h*C{WzpU5iVwLb2lRt|=}B3N3EI-QC~x`+MGd z|GDSfCnuil%z4R#{-Gd=W8Vs{x`cTFctcP~>{3m7jiFE$%TJ2x{^ zXA3qbSF7)*!Xz*-R4@wC5}&-YPjbAz5zIc^i&>qXHlWYoNLSSHNZ2oYVV{;RghOK_ zk*Y7wsxdYLa7LHB#trF8q!7hphm=k8VBSVz${-SA*N3==AbQ^Au2Y`XRE?*%@BLcI z?0gE$wW3&96>wW~vpUVb>)K;Ql2ON(vDqTycHMR~Z=}~XO9XN}nJ%L5Tf?C9f{}@| zO(y)mH)A>3tiK+-|LpyP$+X@;gw6&QA36@mn6O~ApRdg4hI$UnmwKnN-W>9BY*yRz zV5?lfD6T#O#}HG%px7g@`^_xo_-iFQy&XH!l7L|W79T&#M<7u4lLC~v`V#)|ajWtB zr;Q2$FegQZPdg7o2R(IiDjf=lQ2gH)E(bZKzTVbpEx!$`A`a?%6CG#3*~wZcRruFqZi-!=G}(j&p|KRRNt{OmjyG65I;h>ruuUf8O-Mq^LO43V`2Q< zxFTfpuc>#_sruY)SxeC=7W;!t*Jk5A?9XjENk2fc zp-?uSB&1rP`gSwiEJuqau7?ov(5ubbIJ=Yl zCn_LM$7&%%%#1G)TsG0=%F!l1tqcPA{ZSwX?`{o(g}SRWDot}sXixw@d{RIi1!tz*GBBaCQIq-;n>~fc zf!JXq^@(ijj8PRUKEvk5Ykh>O3zKGuDqzw8bHYN?!H9@|bBnTS_RcBfhoU0-b&kM~ zs;06l3!%caxo=w=p3fb zV5R}8Wli7@Qn_AO=Z@K-MbQ;mS+0i`+8_8DMI~JDk$Di>aUv&k8`$aYkt^~UVnBhB zaCz^1PH$Y$Kzz2!Dz!xxAD=%0i(vz-R2jyRo(cAonpmKU3uudS_E^Y;C1EX@*XK+> z&AS))K3mX%7|Fzl$-sK(k28m%rvDDA4A|}f{{7lq>5rYx> zk_zM{^S*i*q&)7a*32tiJN|TapI-BG_jov{lH&Jic-Rod%R&6psfTzAKlj2HPFavM z+_y*6It*Qwh2VG*y9(r~%#OcA-0LQkzsxINZ+7p+sweIimZ&R={`QlI*4jYNBO|sd zB2omulTbD7vG@MV-gUiD%v~d~tmy&PF=`9_x6dPRjYqP!429p~%_4i}d%SNp-(mIM z>02tzqEMMB?ti|Xp4;jaxp*w8_PfdI^)Q*@1az`-abVbe)#I;R!kT zm5SXfoXAFlI3~3nLNAef7ZXkl<~R2^I^lki#Ti+fR7QLzO!$zV5=?E@@Rg0&uhUZa z6Fv~_6`hQ7vr8y=^dbfqiw3%*cHcJG^(J4}@-_HyqS%^GX4GI^b4^4MN#GQEzQ z4kLrec)VsrLs&cdzh%{ygP;Z$;TW?^w$1Ba0{rYf7@hvJk^MNj{IMhiJ%mF2^Rj)d zZ|9#)ulH$Hi#$mCkJC}F?Dorr;~}{j&0x$N9jl(o9_Hx+C_gDnwf5g6ZiNPRPv2u) zxO>)Dh-s_>9a>L5rE4j7y-2l+LhX;}E*&Hkdr#yY89^gUvdgcx5`yl=jT5Kf2hNQ{ zYyqI??a6G;E2v_EwHq`0VF~9__JW zxB}ki`Hp9eL_jU$Vj3G*D1139S3U$Ek0npQ$15f*6U_N=+md>=P)0Y-Qlj$bffw#ts%j9arB$=P%80D~pXX3X2KYB`tFKTr}AVplg*y_<*d9|bAgKS!=K1-9AjaAhuFiQ?PSGvB(i5Eoq?yKFT zf`mOierg+mFF!T1ICtq4V%7JhbALHp_x7xq9<_je%q@lJ{z0~%g7Gy~rbj1c=`>x4 zd3ih!figk6ud(>!cw!)vY|pZSrM&YgWaT*uO`C)CrfRb_7c(~u9J_T@X$@X zp!;+t2gZe9ny8;lDNIxF!w_K}!(U68uZQI{yr;<&ZG~A5zOzl-0mDHoAOut=V~(7z zLGNH9;a8LW{t`s@m62{~n~=LE64IC%;5OR71otO>Ty{0rS}WDwWs?sEN9q%=Bc=nU zCN;r$BaK=panxN?vWJ!AiP-|p%bxvO3gbA;L%F>BuUG8Go`o)|a$y>}1hYTl0i>U%zk5FE(Vh?OyMvcJo@N}r7R zq*M=bxupT8&bKJH{Gue~k2yJT%1Zi4l0biyhCz(Sry}(s%LKm2!eE;EW1Ku|N^UH> znrfn;<@EqIF8ABifX1ONvb2wE)&)xS4N??UahJls zpzHS)&LMgbWXKb~s_h z!S`Tf!@Qza>qFQeEMGmlLyQ4)DQ#CmtkR;18DCE6-v>r9)UaLAnMgc!Ya{wFDU>B5qr(&KADtLbS{^CR$T`h@Cmlsj*v7^x52D*^t+eP7ze80}%() z@RCnr8%NaO#*)E};C7#VW(;D89bl?EBo%5hbh$Zga4r>w{`xc75Tm83b$O5PsfslF zPyT)28!rUo&sfFSS;e&%`=9=eO(B#<9V{Q&#w|h7U%H3oAYBkK6^NvH<+GA@@5Y6o znIN9y4Z!kE_`mm#dVXTVrvY?{jk)#4y9jPby0^moF-sr(F2Ox@hSB07d(9(3*l0Y% zh0l~{NUmRFu2b4`ZQ9=9f7)(E#~L}qVk~z%7{EfT-~v2Xn$hGdz^|89x$K(c7#QWh z?O?!hL2Z~#H?IiKqn0@Z(b_LuwODMqxNe;w1stD9dZ{*y20M#lRi0?ovBdRPO+wp=1jOj28 zk)Qkw^){se!+Pgm9G~1&;h6~pp&D^&nbd2JH0O7LHbrD@$=A9cNi;B?2}VajXCrz3 zuKWetB@xsnNCh1BV{YrF)eKlP?|RGW?fCyn6SyIhH5n`(8J{lR^qUp~b7J9B^tuZz zw{j}yGM>%0cEecsSl4&hcCd11%Qv@sx1Syuz0qbt)Vkb0(1@V*mj6j|QyhX-pwE#{mjf1Dp=lu!K@Wr+5ef#3TCjtXJ_ z+&iD^N4fIjcz-hUSKx_C-4xh!P|k3!ckd@w0@1l-Yk{(D>VvX}-qK62h62Dq17>Nt z;*dM!JBU#F2R!cQtd>zA3w??>qPCo>WHuvuL7zjy^Ec;a8xX`F(kef+d#d3pa>$T-!3;UHj_F`MD7?=GFeqG|GmkaFp#xyxQczPVEO|; z%2T~9{)3rOw_o>@f&%=yT*C+!E})(cY_-bD|Q0`u;q!44K;2x zgZ0g#hZ*1<&_ZBHIHDQ7+QNsf&aOeP1p$`awxQ%JrzQUoMd*(Aw$fR&K&s6jxDpk+ zTP1yqiAZH|6`fjLxT3>4O05Y>T2X1qQp;TGeK!se$ixRTMV0b`M*GE7I;Jlc z5o9F|TlwZ>MXRGKMw{Is!1i+$H$$e1qgUFNcGfDO`dEzybz@StVXPyy?;h@4q)1df zJ5J_Mw|PJge8M@7OHQ|38{PYfMgd)j?@z}ViQg%6>FQ%?2Uf|SD5ZJ0#$Y|Wj92@Z z=3QA5VJVs4XSGs~-H(eOblj`!TNb@!_6mMI+T9&?J4@Si_FD@ccMg%9*3B9IX?%WT zI(##QWGnPee1i-RWz|lb1fCe_H+{Es8_y|AO>HJ}1Y5p-;yg_+HYJH`yL(>Kl9;#) zaoTEaI2N}4YY>*v{Bgkkf%uOOOguey!?(-!jl(mZnd>Q~;k8@RjF##sC&1vff1NyL z+EFkvN-x)O__nD4{OI^5*G1mR?-J1G7KO!z_+(FFC!hI`z8@=5L ztC1Ls?`;ISV>wgr-AWI_?RZq5{#$1kF%qFZjI;;F$sqyeJ zuWf3*r{6{IUu*;afItp4 z@9O};iCW=5vX~8sb3}Q=-P*rr!!RQ5Fir38R+a^obl>K zYR7#KoNTz@&h_31HK>4Lnru7CiE;T;J4tA9E5TwMY?Om}Tu(5;z~JFdc^TA*4Rn7$ z6=vt%5T;CL^%`AqBN zTtBW=OJjq-)BHG2EPX1+7pEa~B$H*xs}i7vkr{A`Vt0IGI=One`{aM!XOMSq^if~A zq$)hW>UMp`_l=zypsB6=Q9E>$=dbz%xzf;TR^{kR6WLVl6f@XrbQKLJatHhdO;O)l zb&}nqZsI|tR%xG`>7DL7AnoZBb{iP(cM|HY4rx<=G)(UqHgFuBGH-FefzvSrrxa> zqqELkbS76U!BG*Rq@6OMyb^FfsJebryk#lObG^ohtn*!&X?IzY#zhGY1}WC%tq*yw zgC9&F9M8l6ltDO&L0uZ{Eh*aHdK>R;?p>FWaG?%kAZGgn&<^LvPc?L&Sp10i45TJ@ zl)2qA;;-7#)R=N<6A;sZzw^F5senA(Fl0ftan;0I#B=y2|Xb!uUr9d!q(L7KWS8>U12KsVUT~1#X(5MV5)j6Nq7R8E2hbN-_AQJQ{lSF)CB+%NCfx82LYQDIL9X zzg`ng=HS@n7^7%%oTs#KoBIpYR?}dy*>uztU9>bBqSO-D*$C^uNDIU@d{)){y10CC z7h!utbSz~;q9%ls&hkN;HeplVHWj}_Wt_{Zf{AhBBa}=06mL!bw@5_=g$p(VF}kR( zmDnS+K#GHrq{ZbzhpbfmJQrFOKWEjHK$nwb{IDohg~dGQ<4G3xo6hdEy z&Ry?*WQdafkdJ|{z{W>WVPq)bZ>+p2D)P>#rqslbT@JO|KebC%+(=L(vPs!UNvIkY ziM0VRGy2i71|x@2cg@KFrk;>BD&=fKppilYK2|U1cLzGDb`Z4w#|Xp3tPQn5=AlF6 zW~7c+sRNcAZdw{M8Wj0qWIyX$E9i_r45ZNXelF1z99>J#oP7NO=}SoIBQnEe zaduo6ME52nt0*cWQ~#KLdN@q^Z7ATQqNkSrmx0;5eqe|;S(~7!Hm;g^gqlXHWN{Kf zRf)#)-WX!|c*~REw2*zPEz3~z;d#ud6q}0Fwdr@cv{d{*MWK>LqNzv%>Ygs?tZ;bk zl#1j?cVC=sM!WX2B3FUtyciDZ3NGEqHdJW9Vxl$>D2S6j>W2J5gu5 z;VT@a0{((@{J}J)#1{3gl|nFYPDdrXl2ThBTUxSWvax?|VNvv#Bd^VXw<4d>F#u91qo}KWYZ@UgI^P!8=0Cu{bn}4S5C@_=2IMnoNoQLemsNw zNzb^by;5ze4zc@*_Py&w6v8^yvqY<>lsryhoA!xcMuQ`0mqEd<>J~l1Jw{ckO`-7StJIF zAmQXOCE=OqY>R@GQ&>^rypc^nhNCFlV#G5NeOQ)JJ{OhLvkPV=ww7sbbjr@|;+B@x zT~P!IEckoR7M|!OD{M@9u2f^!+*oF9nk2SF9B;Q`s(&&hl5$6#y;MNm=ueo9*$m+v zvO#aYqy7s5;r<(XuHX~|IPiWo9Cp?((vWAUK&Sjm5fNuMQ$-CSRYwES)8S5n+K}3q zE%o$y=h_4gY7ggrBwgJ#G0ku&Fhq>|C$@ySdnRk0MR!?gnWXKY)&k6V$}s9%tIw9jI2v6 z5#*45GhXT;QLyVelvTyV$S9G9KbYYsvP>Bsen~+Q!UBT~6C^>`(`X}bup|p%9PWw1 z$%CC&u73&XbjdT!*x2jJrhDC8eEl*|u$hHj%P9zxl6+Ez7$tci<@G%waFASOw?z7<+BrMGDfps!7zsjbj@U^wTGjzOioJ{ojc4#Oh2J5Mi9F>- z+z&T-*$2^{BRM0U(`QYYcOsvAK#=dXVAfz)PNzj3st{gd7>Go#B~E`fgO#Np0#JPt zNOsK_C0a=Cr2J*xAtg}dE@_kYNiS5k)Dz2S-NAkO&(B))tt=jjyMYHP1a;ht+E{A?1I@L#(2mBKW-&O z%ZcpGts<8lr8{~5;^LuNIT*w<*u~J#Ed|6kW`N?ET-7e1A_X!{O10=;K5Qm}jH&Um zDtU_&a3O!1*IvZ91l5>%RPDZf=-iwws9JyDfO2TFr2NGEn5tV!*KN`-efQ}0= zy*l_+Pvc>WuStApYLc>?{U%GX5SE;S?c&~ zBy9DN$l~u`nt+Z-qF<%u38+tkub|0FCqJT%5<)s2O?y(at%3q+@r`#IP)@dgW;O z1ipACMn%yDI73tn#K0J3uuJ{BdI*MOLq^Y;PqzaYE2KO5`oTqwt}^-KKA@>4uA%1> z^^MOh@~iwS-HlfgLI5&c>+bK<^CdpkdU8ymggB3YW%94IYH^Xumbz@E8B;lrn4SNl|}u*gFj9K z(x1Y{7Dkf|_souoXpejKZoA%|Z%-=i90xCpA7}8L*6TlTSavu?6D)G(NGfUV8@ zD3RjCV@^*ZtD=@@QtoAo=qBmRJ)Y3cxi+~$pT0Ea$}zBi6-GpeVB??_0p4L*+9E&Vx~AK8ouq2uI!j@IUG00i3M-6*sR=yN zos3TA<^Q)Az-@BXmgSA5oK3)LV?fOQwtepFcnyhVL*~4-aEdSRW8OObGQ0Kwm*v^5p%5FXl6q(gmNoJ`X5bV-#$AN;8q_ z(BuUHFV@5I0O`5u-nfj`3v|S{cZ}qA4J9>1do$o~qp{FTziqs^Du=MjNdM9aa{t&{ z+t9_~w>nh(A+XNz?}8(_aZj1oof&3{7u)4zZzsa1z4Z|E-*IsCF{< z`m^%!&VC(`B9QBR1?f}tj1%$vDMZ6*2zwih?Ev#6KG;TF8Y!e>g8|(F8TA4)(TxIM zHpH3)z4TAq+h>}I4SEy~8%^Y3CEdmmlBW<(d-#?wD#Q!9QCKt9`QO7(vh$d=YSqwhRFU0tK=c|3$I=l(fJ}o0j(!@%CVj5BtTb1A|P9GwR``0M2 zQtnpZ7=04n*wSQcTW1iKK0gWs1Bm>hU_FOmWNl_%auzVjO(XKzNu@{znq0rPK`9Ks>Ld9<-h<2(^+i1@~9H zeR?H(fCt?r;aJu07oyd|wCi)9-q@iI$SN{7n=iU4Vr;n^Fy+ zQGfhP2(6yOvI1)4)$s@OKBN%lQ`HMc+7v6s)a&~(!?|}tQ8gKbaH={iI#wy=DyP=| zmDDEeYS{mFAXR!K-QAl^H>HV8-K?tHePiI@2$WvP3w1RGP$|0=$>3K<* z>h?Nh&9dN=)JQp1`v(hlrcUJu;*EzF?Kqpn*6+>$x12iJY$Wt)Z2#+j0hO9BwvnVt5Vtfb`I8f5>60(sb; z>goFh2$S8taQaNrM1$^Cb<9QU>hH}=DDAOWp&*>&PY~z)wl!lNQ}0pzCt<#CI*s*@ z<*jt<^%JHx^kGxH%2 zKS~36!=mSSMnbPmbM1;E57aqBbq62e9{@1w$V_TBa%vTSKxs10;vbHh`=jXiH72EY zJ+~?D-){b2Ulr|(7}du1f^FWN*ak}#5I_|RdVGp(gx!p}+>zh8TkDWFQ~gJdRt=ga z|Fc_xx3H?7_D{m+^5G2(ia*Z@z=C923MiEfF&g>GLnlUdA?tKhwKI{Z|EGfqznJrX zy-xVRv@*5-O|6{^W`w^b0BeD8SNcEY#FrUOD-9MQU#376#@Utr?-W3JrTuT!P!;&k zWve`%e6Gl8QQf z6~bo(3aOzk4sFKOefVq?vdEQj*X_XtGD=vbVEW|x7gF_KGt!h01`{5RvbAYe^QRjy zH3VoP$~ELw@Ltm*;(3>foOq;*c@_jq z*bwMo;6K(DSAr@<))MwRMBSy=n#~T$U#PoYk-;xu5irfY*j6WOug&h670p!?`W@g>b_{!4 z>0>;G=%HDJS!dg?JUIYiDF2Xc$X!TnN>Fb;7laEUg|%oPNFk}+`|!mWB50yAuw{L^ z0J{>Yi)F;$*Z9URa7!BbAlEltvT+?D|{%%%g!_?+Dhupo_ zBZXZP*XlbDb;XatQHa5LZ9{T4ilP~7@c-6xUEmikOIeRdPGIZz8>=wxp4Lp5bbf4{AFf* z!7j}%LbN}KQdD>#8x=J%aK2NwPQV>lO4=5Ar2O(27h{8(SX#a%Wll=ZLXIuRKmS@Y z`J=Y3NscVvXj@O}{>eYyjM9a?a@65_1tZ301|GQlB`0VidnHX5D>4zjNmLRZ{zINA52BD$ z8WyCj;=t%XUyc+KF&8t zUC<&28{ ziw-M*+!0S{v$;>GA*P8vlQ-7ONo-&%@@3I*{sKb5C;0c!{1>FdHYlQ4`Dg2%Q#L4I2j~V^L3tIVjqXq#Lmta5mHYG0EV$+)iQ$`BkVNtyJ6Dq(E zAZ|H(x!w{>Eky}2RVPJ%8Rv6oDs`CfTUXH!Hnc7)GL&0>aHT+0PJjp!D&$@(p48)V zu0NRsR|+o~e+_bFNc#8_C@&iJ0Vj{xH~~R)Yr(S@<#CE$OuD5^e=~5q-31VqhuR}* z>~7zRfqG)kdfmTTP=rsHk|guV0AfvR;4AUbSV17cy49y5c?Bj2p+?44!7zcgr9F?R zVPa=w>fC^UMXKxmiHdpg#WwMEB=;;M>A0cBAF0**l@sip7|6XE$oEa%M7?SLbq9X9qGoFs(izfA{XoUme=;5byOClx z>(VYI=23+>DUSP#HxiNXFGY|zE@8au{vHP{%}J#|)5XNQ4#YNe#{N2(dc#j2TtBl* zO9&x8u=q=rmQwfdvoeae0>-{8okn&iHEq7RSQ`u@tW=ey$!C5oE0>tb5{oRV4sI1snf9p!GzY*5Kkox)Iu_#K9hVv@J<+>Hqd#?{7~6gM|l>Jto>Fr^Ee)L>aV%lT5Rqzb(v1A?4;Ii_QkAde%=WSHjc#5 z&tr80j9rd}bb!UAr|fm5F6e43Ln6zY;be~w$!3&<)4z@QC+d6Cwk?e=)in}a$Vi*H z*0!fxWyV;-H=GkiTL6GCHjDugjHTJ1ojsriVjojEJ&H~5XH9eruYH}g)DpeVXM##e zCzoX{&X^6s*X`@frj0; z?4HMGdc&{csi}g-Wb25kn#z4IjZNTEvPb(9#Td1bC)WYwW64d_-yHI;eDn3~$}0+t zj4-Xf*W?jzMxRqtVK^xt_@4d1AZ!qcq@j}JeH{~m;LyprJh zbJOwCEB!#&PIbZV=E> zq4QS!*9Gf^%}Ny@O};4&3yZ%cwz2HXU*UNE)ecvak*m`_k-vUUuEx&C@zVA?VV-gf zMckWWtpuZhhTNRp(+98}kK^pkD5y$NF|cg8WQBBbsit$?C~0H_^SEozsqQMb)_T*o z=B^9-%nM%+tf_*t`FF2x8Gj9VTYszQ{U%j5KC4y+YkvUg5k6?5Mj*=i%k5P}B?x3k za!Bf|sUhCt-^ajM^R7{S{@@@=dNVshT4}pMU#$0bU6FQpEFfyI((!59YLjt5f!VR3 zp$J3jbX8hEkbORJveLNsC}2SCSX8>acKr7t9>Pa!{DNNsIFQ_av6z!Y|1HpOX3VBk zv4W4oh|{}6BgjttEk~-3dTx~Bgm7$eKX%SfVKS*)Ef~+)zk0^2V?4v?;TV6V4Rg;y z7!OWKc7WQ}TcdgT9zp#Vgd~^%Y~!K%ZYmx)t$<|0~m0H2za^5Hv zC|ns)!e<9FXsY=c%F$OFUDOxF$)u*RZyMWG0LYW}e++`}$ZLPx2}K~ZeKiWeFQ)S8 z(*h`wNL}&bqInoXPD@kpMW+I4070!Ar)7SG6Z7P*i-*w_s#DIi0-qP^>?v<=tt(Ts z-3?KG(PbSTPb5pk6m;bOM{f^~K^j<0wb}PQzkRgp_vX_P-VKwWqkmtsTfnRKmbMy# zbh$`lbT0u-#J%f|;|i;S$8iEafHhp>LeSQ)Qk6EXeIY3wS8TUHr3sJdkD@JW{KeOSVqjI7rRe@eIM^Yx~QtLOwak`!b zCh&C#sMBkq3_&MJ5q~I}17y_o^q|{2ItX$loMx3=Lt+YU2FnhN&DP%%1&32S5u*Hk z%8`so3g?f{3^({f3;hw1e6!!2V2j;X@6snh%%MS?kgltSDhOpcZMRo|7?ofhh+ z$8{I$WpsYbw$@v#jOtv5!|Qv;D|?B)yffL{#dNwUZMKfo2k% zd55z$EzJS`+^ozDR8t3%w2b+7fq;M7l7H}sY1jTtEn8A&l! z^*62+R>oN2r_Z6`ryb7Jo0J^6EB&*S2y3p#t)ex&eM})PIHO6-P!&|v1r~oeRsWg@ zZ%p&1?fZ|gxHe;rzW@{x9gs|HvD$nsm_Qaad-`my(c~!l)lZdV9&O>q#Up=$%D|Tm zb)}%<&sLV+z39Mu0IK_p>u_^A5xAKaPp^2|5USB1{Ua-mNt1)M@#7M;=5YL9F1NQw!dV+`z7r46ZtEQ-&JEB18R&Fro`xac4 zoZQEGH^As-=6@1Z8Y4^;1$F$73qGs|V^4re$GW(1g^}G>6LJZE%Y;Yq9X9ChXPPHi z8KPKFiTD>w!Mz#bp8Ztucb@PLKY}+Lf8Uj$hk5W;uu$@Tx?M;Jj**aYD%>56nQ+a< zcQa_W;x-Fv|0+-3cX}Pe{x`LlkCBGc3ghH??wEPe$}uaypK?e=iC3_untxKrV^SXZ ze1b6sw2nS~g!m+i_J^19ZjYfrYXik##5TQ>vi}3bnEXH<**V(*ZSBSuRf4H8SVa_|Ctb=xBYTB?nCkN zl+NruRCsnH&sMm*kNR9Z>Hh-TfXOwfx&Kpsru@4t@;TAwert_(8JD@x51|GXci~e& zj)yssx}kHW`~XOiYh5Z7s$=J>dAXQ+CgR-#pypD*y(Yw23B((0_|i=6 zco+FrI+-^0Zk$%F;!jZ}w5c=WV%Aau(UYclbuiA~4@kTbe7zOjxS1<-FtCCKrS>+| zwsEjg&CbG(sMtnsm-{c1n3Q&U@1@1=an9LkV|k+bZzPVD`xbfv3%8u-V?e@zXZL^? zTEvDA9&P#>;@QUQ3O|Xm1VMF0Jf8Lv1>L!_sp%afwG2-q)MEx@%JI5$k6-N~=XQzq z82?z(W*R(2zITk23Q3~~Nbn@GvTH5c2Ho7(QoQKWK3K9%7s@nW&U#;GFgq-QxcUpv zB8LgH7ADHiQ0`F*rfJ)ekNd>PmS4#3g}+SOsMt%kBwNz6%8%KoJrk!`ZL~aM^{;|! zqt-Tr+43@iXxOQBm<^DN0;h}RPgD1j(tLRvCKibmDCWrPbty28Pv{#m&a&X#lDw*z z`;!F@FbB{c(KeSq#Ylg3m#o_GqbfE^0JC4~oq0KSk!>_fvWwnIv|tp>By5U)2Hw?; zJ(7iW&XMnJm?@NRt>MQN*3+=2r?w@kM6Ii5Khq(#Z~a1a_rtgx@@R9MZuV3f^K#oS z#aO&mc>EkGQZr?0@6lwTG-jRHBSi_Dx2=U%nf-``1ME-pX`Z)^SN_S4UcEVdcV0XH z2UmTUGi3kpnrCqKKEU{DR7wH;H(HrA{(+>#nU5n271m-tDH9`1uaxqr%^pdCPg!7? zbWjr?ANA;Pf#=dE{ar`eTE!LVOdP^zuBAv*&hurWT1tZS{V~`kK35OgUc$Eytp^j- zhUTK}NITBq-#jHny0o~PPA*=jKXamVoIm;JSmWswN3>!OH@4|qkEv2vSnFLZiUTh>rO~r1i0XL&gQZ#8CS#b4@7_@tMT<}1))O;k+m@j*}CrX#uJ{xX3 zN~X_l3ZT#J#oHj_ig-ZcgwG;gKvuxuT*@=W4K8nsQ0c(cO8b(>G~Ql^S$|&a;qgM& zV69Fv45SSb<;vTp(QH81+0}Oaj#X?4IM!BQfK_!Z)ApQCY&uQtZ z5NAEuKXIH|;Z)TvRj7Jegc8MmlG|Iz`@zcpZm0qvO-q5yTA0}EwNi|Is((gKIPkHAU{NfUwAvnnaur3 zT8G-3lxK}mi&b6}Lt5e6?A~lxTT9`8@gG@E5g);73hhXv9HcvK6-i%$T+H8jZX~uP z0x4B{CZ!|=65GOXW=R}_VB$q%@uO+`RtX=xr&rCZBB0(VlBB^p3- zp6mXOe}9h5jnqfU9&*Emn1A;}yT`({z}CTKdGAX_%&jIt;k@2-rbjD$&spR-wMDzP z;)?N<}G@POdMCoxK=mt3lnWLZa6ro*}j{ZQif=>q|EPGMKsOb|$ z`coRUWeA7kM&`qFMgB>~e_W;R@+8zV6#2@6aw^p#QMd~?fcu@9J()6(3VZzi1Nri# zlxT0+0{XY$dsp&MTASDy#iFkMtC6RDiGsWLNAdUa9nSATIE!BcT-ZmvSugHUZzRVi z@7Z8lU|QvhRZfxOq(MJ1r5p_@X=zMW-}8xo#wW$WdsrSB=t3DaY{gdpG^5H`N6CRU zsw+rFY&E<@Bi@5zkX-L5HPl{ps~e+?@^EW}B4xb&gEHFu=s0YpH$nbpkEMXYUP}3z z6g#N+(abud35b7Kz+Zrfr`piQMG)D7edau5a2@0{JudIhvjtF@Fn5qF2sdp_x}FfcdS% zr-&`yceT@#;4(J=E7L%mYJKsrD?z+m4cXlEo_GM+fnC4F#6g^}6^kmiv{~V_P$19j z3-r$en*aST0J9>SboqZjZhx@&ux+$bd|P%Ewj64Y!}=pRpJ1JpqPXf zWYYi8EL^Go4^RYc%ln6n72*CL%t- -image/svg+xmlnf- -core/ -deepvariant - \ No newline at end of file diff --git a/docs/images/nf-core-deepvariant_logo.png b/docs/images/nf-core-deepvariant_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4f2545e137a8ee5d9bf7f9f714fc5c79511da687 GIT binary patch literal 115948 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

nKHNJ3P*ny8Z6pY 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

$m zo*x_;V=18Z%{dQ>8N*FM!A@h^o79J;;nj)o*mhnI96{2PDYAToIszAE=MK44hL3vR z1A>5Pxb>%g?x0r-WvE$+ci>hAk902C*G;AVWAQp!v1yaixn@6`^z_a=79{pyDVU%= zvDxe89evx+1Rx_>vEs&(ak5su>FgWR0N>-dPi_C9g&PYX5w%HCESMK91a!z#xZP#s zHp7;DojPjQ_J~rgMC^MDGPDgBwN@6B$@JDQE*9i)&@7(~IG03^@jyeSGAe{V8Dt zt!@M~J@l=%9G_DGq_0;zKvLy1K>AZ+yJcMZ-ab7c#T7$fRfQiL2~c6KTG=3AI~#C-Q> z_PhLOI{oxqi`Vju4pRu)KOXvs&E9!5HD}OH>)G2?XT>m1y)c#6v9dY+AZ}MSavPyg zEl~gU3$0&rQPirvc(`ID&PldpQYsmRh?)(rnb=Ur92$>YTjy$a+KewO6!u0@`WixS&KLW5-n`5-r#)Y0Q7>fg!u9o40@x90Vn6h~A{}LW z9S#N;fy+blLJRhpV_s}teY;yQ!Dt$7xTJv8gQiGd@wdNb;6d;f54c+Dop zM`h)?#+t-+)<%(^m-rZJ>Lx5*=6!mq7?wOK5ZvsTXo9V~cC7h_)Ch8_&S4w5>A=QYf#r z^WbWDG~qk28Y7XdZ8(Z)Den$OxFb;S%yfQ-L`)^5PW{}atj^_QEAFN)-kGYJd~n7P z(rqDI9kT$1Y>b!;BW7g=8M#M|M;kP{Wj1j|FbIDXim^7_?=0-XoV)oYYRiwY(3SMD zxOCSmOcPBF^Rd}|NyA+I^d&GUr*v)D*eTyrdbhTz<=f*?w^?fHDOmbQ;c#@0%&QYD z55`BrRz1_X-FX}7V|PV1dYXSY-&q#*4i4Gq_e>Q&zH^zeVepW8*dwT1Bd=`d$>yJo zB=a}{h!q$*Ls0c*s=sxZUCMN<*D!eS&;WsLSix)-i_7rygVGVudKY6)Lkf%d5!#4m z+e~u@Nb9k>6Mv4%FvCSOqZ(EY4`4SgGw##g4$n!hZHAW7JME6cs(gix**4I-a!X^M zZZ>um&&ncoBD1!F7|hh}?U;gn)jaXmev)%9EhHArnNBJPqz58?+7!ZK%Qr7i&u%x; zl9XUPkP)~nIsg=28!vGfZZ4Zbmc!{~p{dalarT~W7_~poGzfcr@*H-TINP2dsMtkE z2r#)oCmP z_S#QoSDL|`Wb;>Ua^(k@hm|aZYqb>%SeT$CPR#4sv=|2m}dS20#r?Y4_Ab?07FBj+xBzR|L?nby_PikilZ zb&Y7rFqjk?>v~*lO^xO1mbqc`${b_L@P5+o8_B2N*olB8L`72P#E+mo+ds-uugtF;H=UOiXw~+ww zzc-yafDiQs8spKg_S^l-}CDBtfwiPSL zCwZ*9G_LY}1#KaztMdV2CB*O7TRGpVW*^c-%RYydt|UGT&#R0jCa9QuZV$cg^9EK=7C;zF#30@pO_)oz|@Z#^k{;7HeUi@kPzn=|J{`cZh z|M{5zV@68>TMq;R-Qd&+_`mB8?|Q&)3xS{ojO?+o3umPgigRSZ>;HWH#{&OvE%3c) Z7j~yg1`;jha-CxYxS5S<jMA) literal 0 HcmV?d00001 diff --git a/docs/installation.md b/docs/installation.md deleted file mode 100644 index f6153b3..0000000 --- a/docs/installation.md +++ /dev/null @@ -1,115 +0,0 @@ -# nf-core/deepvariant: Installation - -To start using the nf-core/deepvariant pipeline, follow the steps below: - -1. [Install Nextflow](#1-install-nextflow) -2. [Install the pipeline](#2-install-the-pipeline) - * [Automatic](#21-automatic) - * [Offline](#22-offline) - * [Development](#23-development) -3. [Pipeline configuration](#3-pipeline-configuration) - * [Software deps: Docker and Singularity](#31-software-deps-docker-and-singularity) - * [Software deps: Bioconda](#32-software-deps-bioconda) - * [Configuration profiles](#33-configuration-profiles) -4. [Reference genomes](#4-reference-genomes) -5. [Appendices](#appendices) - * [Running on UPPMAX](#running-on-uppmax) - -## 1) Install NextFlow -Nextflow runs on most POSIX systems (Linux, Mac OSX etc). It can be installed by running the following commands: - -```bash -# Make sure that Java v8+ is installed: -java -version - -# Install Nextflow -curl -fsSL get.nextflow.io | bash - -# Add Nextflow binary to your PATH: -mv nextflow ~/bin/ -# OR system-wide installation: -# sudo mv nextflow /usr/local/bin -``` - -See [nextflow.io](https://www.nextflow.io/) for further instructions on how to install and configure Nextflow. - -## 2) Install the pipeline - -#### 2.1) Automatic -This pipeline itself needs no installation - NextFlow will automatically fetch it from GitHub if `nf-core/deepvariant` is specified as the pipeline name. - -#### 2.2) Offline -The above method requires an internet connection so that Nextflow can download the pipeline files. If you're running on a system that has no internet connection, you'll need to download and transfer the pipeline files manually: - -```bash -wget https://github.com/nf-core/deepvariant/archive/master.zip -mkdir -p ~/my-pipelines/nf-core/ -unzip master.zip -d ~/my-pipelines/nf-core/ -cd ~/my_data/ -nextflow run ~/my-pipelines/nf-core/deepvariant-master -``` - -To stop nextflow from looking for updates online, you can tell it to run in offline mode by specifying the following environment variable in your ~/.bashrc file: - -```bash -export NXF_OFFLINE='TRUE' -``` - -#### 2.3) Development - -If you would like to make changes to the pipeline, it's best to make a fork on GitHub and then clone the files. Once cloned you can run the pipeline directly as above. - - -## 3) Pipeline configuration -By default, the pipeline runs with the `standard` configuration profile. This uses a number of sensible defaults for process requirements and is suitable for running on a simple (if powerful!) basic server. You can see this configuration in [`conf/base.config`](../conf/base.config). - -Be warned of two important points about this default configuration: - -1. The default profile uses the `local` executor - * All jobs are run in the login session. If you're using a simple server, this may be fine. If you're using a compute cluster, this is bad as all jobs will run on the head node. - * See the [nextflow docs](https://www.nextflow.io/docs/latest/executor.html) for information about running with other hardware backends. Most job scheduler systems are natively supported. -2. Nextflow will expect all software to be installed and available on the `PATH` - -#### 3.1) Software deps: Docker -First, install docker on your system: [Docker Installation Instructions](https://docs.docker.com/engine/installation/) - -Then, running the pipeline with the option `-profile standard,docker` tells Nextflow to enable Docker for this run. An image containing all of the software requirements will be automatically fetched and used from dockerhub (https://hub.docker.com/r/nfcore/deepvariant). - -#### 3.1) Software deps: Singularity -If you're not able to use Docker then [Singularity](http://singularity.lbl.gov/) is a great alternative. -The process is very similar: running the pipeline with the option `-profile standard,singularity` tells Nextflow to enable singularity for this run. An image containing all of the software requirements will be automatically fetched and used from singularity hub. - -If running offline with Singularity, you'll need to download and transfer the Singularity image first: - -```bash -singularity pull --name nf-core-deepvariant.simg shub://nf-core/deepvariant -``` - -Once transferred, use `-with-singularity` and specify the path to the image file: - -```bash -nextflow run /path/to/nf-core-deepvariant -with-singularity nf-core-deepvariant.simg -``` - -Remember to pull updated versions of the singularity image if you update the pipeline. - - -#### 3.2) Software deps: conda -If you're not able to use Docker _or_ Singularity, you can instead use conda to manage the software requirements. -This is slower and less reproducible than the above, but is still better than having to install all requirements yourself! -The pipeline ships with a conda environment file and nextflow has built-in support for this. -To use it first ensure that you have conda installed (we recommend [miniconda](https://conda.io/miniconda.html)), then follow the same pattern as above and use the flag `-profile standard,conda` - - -## Appendices - -#### Running on UPPMAX -To run the pipeline on the [Swedish UPPMAX](https://www.uppmax.uu.se/) clusters (`rackham`, `irma`, `bianca` etc), use the command line flag `-profile uppmax`. This tells Nextflow to submit jobs using the SLURM job executor with Singularity for software dependencies. - -Note that you will need to specify your UPPMAX project ID when running a pipeline. To do this, use the command line flag `--project `. The pipeline will exit with an error message if you try to run it pipeline with the default UPPMAX config profile without a project. - -**Optional Extra:** To avoid having to specify your project every time you run Nextflow, you can add it to your personal Nextflow config file instead. Add this line to `~/.nextflow/config`: - -```nextflow -params.project = 'project_ID' // eg. b2017123 -``` diff --git a/docs/output.md b/docs/output.md index 2ff00dc..47192fe 100644 --- a/docs/output.md +++ b/docs/output.md @@ -1,30 +1,63 @@ # nf-core/deepvariant: Output -This document describes the processes and output produced by the pipeline. +## :warning: Please read this documentation on the nf-core website: [https://nf-co.re/deepvariant/output](https://nf-co.re/deepvariant/output) -Main steps: +> _Documentation of pipeline parameters is generated automatically from the pipeline schema and can no longer be found in markdown files._ -- preprocessing of fasta/reference files (fai, fastagz, gzfai & gzi) - - These steps can be skipped if the the `--genome` options is used or the fai, fastagz, gzfai & gzi files are supplied. -- preprocessing of BAM files - - Also can be skipped if BAM files contain necessary read group line -- make examples - - Gets bam files and converts them to images ( named examples ) -- call variants - - Does the variant calling based on the ML trained model. -- post processing +## Introduction - - Trasforms the variant calling output (tfrecord file) into a standard vcf file. +This document describes the output produced by the pipeline. Most of the plots are taken from the MultiQC report, which summarises results at the end of the pipeline. -For further reading and documentation about deepvariant see [google/deepvariant](https://github.com/google/deepvariant) +The directories listed below will be created in the results directory after the pipeline has finished. All paths are relative to the top-level results directory. -## VCF + -The output from DeepVariant is a variant call file or [vcf v4.2](https://samtools.github.io/hts-specs/VCFv4.2.pdf) +## Pipeline overview -**Output directory: `results`** (by default) +The pipeline is built using [Nextflow](https://www.nextflow.io/) +and processes data using the following steps: -- `pipeline_info` - - produced by nextflow -- `{bamSampleName}.vcf` - - output vcf file produced by deepvariant +* [FastQC](#fastqc) - Read quality control +* [MultiQC](#multiqc) - Aggregate report describing results from the whole pipeline +* [Pipeline information](#pipeline-information) - Report metrics generated during the workflow execution + +## FastQC + +[FastQC](http://www.bioinformatics.babraham.ac.uk/projects/fastqc/) gives general quality metrics about your sequenced reads. It provides information about the quality score distribution across your reads, per base sequence content (%A/T/G/C), adapter contamination and overrepresented sequences. + +For further reading and documentation see the [FastQC help pages](http://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/). + +**Output files:** + +* `fastqc/` + * `*_fastqc.html`: FastQC report containing quality metrics for your untrimmed raw fastq files. +* `fastqc/zips/` + * `*_fastqc.zip`: Zip archive containing the FastQC report, tab-delimited data file and plot images. + +> **NB:** The FastQC plots displayed in the MultiQC report shows _untrimmed_ reads. They may contain adapter sequence and potentially regions with low quality. + +## MultiQC + +[MultiQC](http://multiqc.info) is a visualization tool that generates a single HTML report summarizing all samples in your project. Most of the pipeline QC results are visualised in the report and further statistics are available in the report data directory. + +The pipeline has special steps which also allow the software versions to be reported in the MultiQC output for future traceability. + +For more information about how to use MultiQC reports, see [https://multiqc.info](https://multiqc.info). + +**Output files:** + +* `multiqc/` + * `multiqc_report.html`: a standalone HTML file that can be viewed in your web browser. + * `multiqc_data/`: directory containing parsed statistics from the different tools used in the pipeline. + * `multiqc_plots/`: directory containing static images from the report in various formats. + +## Pipeline information + +[Nextflow](https://www.nextflow.io/docs/latest/tracing.html) provides excellent functionality for generating various reports relevant to the running and execution of the pipeline. This will allow you to troubleshoot errors with the running of the pipeline, and also provide you with other information such as launch commands, run times and resource usage. + +**Output files:** + +* `pipeline_info/` + * Reports generated by Nextflow: `execution_report.html`, `execution_timeline.html`, `execution_trace.txt` and `pipeline_dag.dot`/`pipeline_dag.svg`. + * Reports generated by the pipeline: `pipeline_report.html`, `pipeline_report.txt` and `software_versions.csv`. + * Documentation for interpretation of results in HTML format: `results_description.html`. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md deleted file mode 100644 index d9c4a79..0000000 --- a/docs/troubleshooting.md +++ /dev/null @@ -1,16 +0,0 @@ -# nf-core/deepvariant: Troubleshooting - -## Input files not found - -If you are having trouble with the inputs for the tool its recommended that you read [about preprocessing](usage.md#about-preprocessing) and [BAM folder input](usage.md#--bam_folder) - -## Data organization - -The pipeline can't take a list of multiple input files - it takes a glob expression. If your input files are scattered in different paths then we recommend that you generate a directory with symlinked files. If running in paired end mode please make sure that your files are sensibly named so that they can be properly paired. See the previous point. - -## Extra resources and getting help - -If you still have an issue with running the pipeline then feel free to contact us. -Have a look at the [pipeline website](https://github.com/nf-core/deepvariant) to find out how. - -If you have problems that are related to Nextflow and not our pipeline then check out the [Nextflow gitter channel](https://gitter.im/nextflow-io/nextflow) or the [google group](https://groups.google.com/forum/#!forum/nextflow). diff --git a/docs/usage.md b/docs/usage.md index 71dce65..556461d 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -1,287 +1,138 @@ # nf-core/deepvariant: Usage -## Table of contents - -- [Introduction](#general-nextflow-info) -- [Running the pipeline](#running-the-pipeline) - - [About preprocessing](#about-preprocessing) -- [Updating the pipeline](#updating-the-pipeline) -- [Reproducibility](#reproducibility) -- [Main arguments](#main-arguments) - - [`-profile`](#-profile-single-dash) - - [`docker`](#docker) - - [`awsbatch`](#awsbatch) - - [`standard`](#standard) - - [`none`](#none) - - [`--bam`](#--bam) - - [`--bam_folder`](#--bam_folder) - - [`--bam_file_prefix`](#--bam_file_prefix) - - [`--bed`](#--bed) -- [Reference Genomes](#reference-genomes) - - [`--genome`](#--genome) - - [`hg19`](#hg19) - - [`hg19chr20`](#hg19chr20) - - [`h38`](#h38) - - [`grch37primary`](#grch37primary) - - [`hs37d5`](#hs37d5) - - [`--genomes_base`](#--genomes_base) - - [`--fasta`](#--fasta) - - [`--fai`](#--fai) - - [`--fastagz`](#--fastagz) - - [`--gzfai`](#--gzfai) - - [`--gzi`](#--gzi) -- [Exome Data](#exome-data) - - [`--exome`](#--exome) -- [Job Resources](#job-resources) -- [Automatic resubmission](#automatic-resubmission) -- [Custom resource requests](#custom-resource-requests) -- [AWS batch specific parameters](#aws-batch-specific-parameters) - - [`-awsbatch`](#-awsbatch) - - [`--awsqueue`](#--awsqueue) - - [`--awsregion`](#--awsregion) -- [Other command line parameters](#other-command-line-parameters) - - [`--outdir`](#--outdir) - - [`--email`](#--email) - - [`-name`](#-name-single-dash) - - [`-resume`](#-resume-single-dash) - - [`-c`](#-c-single-dash) - - [`--max_memory`](#--max_memory) - - [`--max_time`](#--max_time) - - [`--max_cpus`](#--max_cpus) - - [`--plaintext_emails`](#--plaintext_emails) - - [`--sampleLevel`](#--sampleLevel) - - [`--multiqc_config`](#--multiqc_config) -- [Memory](#memory) - -## General Nextflow info - -Nextflow handles job submissions on SLURM or other environments, and supervises running the jobs. Thus the Nextflow process must run until the pipeline is finished. We recommend that you put the process running in the background through `screen` / `tmux` or similar tool. Alternatively you can run nextflow within a cluster job submitted your job scheduler. - -It is recommended to limit the Nextflow Java virtual machines memory. We recommend adding the following line to your environment (typically in `~/.bashrc` or `~./bash_profile`): +## :warning: Please read this documentation on the nf-core website: [https://nf-co.re/deepvariant/usage](https://nf-co.re/deepvariant/usage) -```bash -NXF_OPTS='-Xms1g -Xmx4g' -``` +> _Documentation of pipeline parameters is generated automatically from the pipeline schema and can no longer be found in markdown files._ -## Running the pipeline +## Introduction -The typical command for running the pipeline is as follows: + -```bash -nextflow run nf-core/deepvariant --genome hg19 --bam testdata/test.bam --bed testdata/test.bed -profile standard,docker -``` +## Samplesheet input -Note that the pipeline will create the following files in your working directory: +You will need to create a samplesheet file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 4 columns, and a header row as shown in the examples below. ```bash -work # Directory containing the nextflow working files -results # Finished results (configurable, see below) -.nextflow_log # Log file from Nextflow -# Other nextflow hidden files, eg. history of pipeline runs and old logs. +--input '[path to samplesheet file]' ``` -### About preprocessing +### Multiple replicates -DeepVariant, in order to run at its fastest, requires some indexed and compressed versions of both the reference genome and the BAM files. With DeepVariant in Nextflow, if you wish, you can only use as an input the fasta and the BAM file and let us do the work for you in a clean and standarized way (standard tools like [samtools](http://samtools.sourceforge.net/) are used for indexing and every step is run inside of a Docker container). +The `group` identifier is the same when you have multiple replicates from the same experimental group, just increment the `replicate` identifier appropriately. The first replicate value for any given experimental group must be 1. Below is an example for a single experimental group in triplicate: -This is how the list of the needed input files looks like. If these are passed all as input parameters, the preprocessing steps will be skipped. - -``` -NA12878_S1.chr20.10_10p1mb.bam test_nist.b37_chr20_100kbp_at_10mb.bed NA12878_S1.chr20.10_10p1mb.bam.bai -ucsc.hg19.chr20.unittest.fasta ucsc.hg19.chr20.unittest.fasta.fai ucsc.hg19.chr20.unittest.fasta.gz -ucsc.hg19.chr20.unittest.fasta.gz.fai ucsc.hg19.chr20.unittest.fasta.gz.gzi -``` - -If you do not have all of them, these are the file you can give as input to the Nextflow pipeline, and the rest will be automatically produced for you . - -``` -NA12878_S1.chr20.10_10p1b.bam -test_nist.b37_chr20_100kbp_at_10mb.bed -ucsc.hg19.chr20.unittest.fasta +```bash +group,replicate,fastq_1,fastq_2 +control,1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz +control,2,AEG588A2_S2_L002_R1_001.fastq.gz,AEG588A2_S2_L002_R2_001.fastq.gz +control,3,AEG588A3_S3_L002_R1_001.fastq.gz,AEG588A3_S3_L002_R2_001.fastq.gz ``` -### Updating the pipeline +### Multiple runs of the same library -When you run the above command, Nextflow automatically pulls the pipeline code from GitHub and stores it as a cached version. When running the pipeline after this, it will always use the cached version if available - even if the pipeline has been updated since. To make sure that you're running the latest version of the pipeline, make sure that you regularly update the cached version of the pipeline: +The `group` and `replicate` identifiers are the same when you have re-sequenced the same sample more than once (e.g. to increase sequencing depth). The pipeline will concatenate the raw reads before alignment. Below is an example for two samples sequenced across multiple lanes: ```bash -nextflow pull nf-core/deepvariant +group,replicate,fastq_1,fastq_2 +control,1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz +control,1,AEG588A1_S1_L003_R1_001.fastq.gz,AEG588A1_S1_L003_R2_001.fastq.gz +treatment,1,AEG588A4_S4_L003_R1_001.fastq.gz,AEG588A4_S4_L003_R2_001.fastq.gz +treatment,1,AEG588A4_S4_L004_R1_001.fastq.gz,AEG588A4_S4_L004_R2_001.fastq.gz ``` -### Reproducibility +### Full design -It's a good idea to specify a pipeline version when running the pipeline on your data. This ensures that a specific version of the pipeline code and software are used when you run your pipeline. If you keep using the same tag, you'll be running the same version of the pipeline, even if there have been changes to the code since. +A final design file consisting of both single- and paired-end data may look something like the one below. This is for two experimental groups in triplicate, where the last replicate of the `treatment` group has been sequenced twice. -First, go to the [nf-core/deepvariant releases page](https://github.com/nf-core/deepvariant/releases) and find the latest version number - numeric only (eg. `1.3.1`). Then specify this when running the pipeline with `-r` (one hyphen) - eg. `-r 1.3.1`. - -This version number will be logged in reports when you run the pipeline, so that you'll know what you used when you look back in the future. - -## Main Arguments - -### `-profile` - -Use this parameter to choose a configuration profile. Profiles can give configuration presets for different compute environments. Note that multiple profiles can be loaded, for example: `-profile standard,docker` - the order of arguments is important! - -- `standard` - - The default profile, used if `-profile` is not specified at all. - - Runs locally and expects all software to be installed and available on the `PATH`. -- `docker` - - A generic configuration profile to be used with [Docker](http://docker.com/) - - Pulls software from dockerhub: [`nfcore/deepvariant`](http://hub.docker.com/r/nfcore/deepvariant/) -- `singularity` - - A generic configuration profile to be used with [Singularity](http://singularity.lbl.gov/) - - Pulls software from singularity-hub -- `conda` - - A generic configuration profile to be used with [conda](https://conda.io/docs/) - - Pulls most software from [Bioconda](https://bioconda.github.io/) -- `awsbatch` - - A generic configuration profile to be used with AWS Batch. -- `test` - - A profile with a complete configuration for automated testing - - Includes links to test data so needs no other parameters -- `test_s3` - - A profile for testing the pipeline with files on an s3 bucket - - Other than the `docker` profile no further inputs are required -- `none` - - No configuration at all. Useful if you want to build your own config from scratch and want to avoid loading in the default `base` config profile (not recommended). - -### `--bam` - -Use this to specify the BAM file - -``` ---bam "/path/to/bam/file" +```bash +group,replicate,fastq_1,fastq_2 +control,1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz +control,2,AEG588A2_S2_L002_R1_001.fastq.gz,AEG588A2_S2_L002_R2_001.fastq.gz +control,3,AEG588A3_S3_L002_R1_001.fastq.gz,AEG588A3_S3_L002_R2_001.fastq.gz +treatment,1,AEG588A4_S4_L003_R1_001.fastq.gz, +treatment,2,AEG588A5_S5_L003_R1_001.fastq.gz, +treatment,3,AEG588A6_S6_L003_R1_001.fastq.gz, +treatment,3,AEG588A6_S6_L004_R1_001.fastq.gz, ``` -OR - -### `--bam_folder` +| Column | Description | +|----------------|-------------------------------------------------------------------------------------------------------------| +| `group` | Group identifier for sample. This will be identical for replicate samples from the same experimental group. | +| `replicate` | Integer representing replicate number. Must start from `1..`. | +| `fastq_1` | Full path to FastQ file for read 1. File has to be zipped and have the extension ".fastq.gz" or ".fq.gz". | +| `fastq_2` | Full path to FastQ file for read 2. File has to be zipped and have the extension ".fastq.gz" or ".fq.gz". | -Use this to specify a folder containing BAM files. Allows multiple BAM files to be analyzed at once. All BAM files will be analyzed unless `--bame_file_prefix` is used (see below). For example: +An [example samplesheet](../assets/samplesheet.csv) has been provided with the pipeline. -``` ---bam_folder "/path/to/folder/where/bam/files/are" -``` - -**! TIP** -All the input files can be used in s3 buckets too and the s3://path/to/files/in/bucket can be used instead of a local path. - -### `--bam_file_prefix` +## Running the pipeline -- In case only some specific files inside the BAM folder should be used as input, a file prefix can be defined by: - - `--bam_file_prefix` +The typical command for running the pipeline is as follows: +```bash +nextflow run nf-core/deepvariant --input samplesheet.csv -profile docker ``` ---bam_file_prefix MYPREFIX OPTIONAL -``` - -### `--bed` - -- Path to bedfile, specifying region to be analysed must also be supplied - -### Reference Genomes - -The pipelines can acccept the refernece genome that was used to create the BAM file(s) in one of two ways. Either the reference genome can be specified eg `--genome hg19` (default) or by supplying a relevant fasta file (and optionally the indexes). -### `--genome` +This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles. -Standard versions of the genome are prepared with all their compressed and indexed file in a lifebit s3 bucket. -They can be used with the following values for the `--genome` tag: - -- `hg19` - - Use if reads were aligned against hg19 reference genome to produce input bam file(s) -- `hg19chr20` - - For testing purposes: chromosome 20 of the hg19 reference genome -- `h38` - - Use if reads were aligned against GRCh38 reference genome to produce input bam file(s) -- `grch37primary` - - Use if reads were aligned against GRCh37 primary reference genome to produce input bam file(s) -- `hs37d5` - - Use if reads were aligned against hs37d5 reference genome to produce input bam file(s) - -### `--genomes_base` - -Base directory location of genomes (default = "s3://deepvariant-data/genomes") for use on computing clusters - -OR you can use your own reference genome version, by using the following parameters: - -The following parameter are optional: - -### `--fasta` - -- Path to fasta reference - -### `--fai` - -- Path to fasta index generated using `samtools faidx` - -### `--fastagz` - -- Path to gzipped fasta - -### `--gzfai` - -- Path to index of gzipped fasta generated using `samtools faidx` - -### `--gzi` - -- Path to bgzip index format (.gzi) - -If the `fai`, `fastagz`, `gzfai` and `gzi` parameters are not passed, they will be automatically be produced for you and you will be able to find them in the "preprocessingOUTPUT" folder. - -### Exome Data - -### `--exome` - -- For exome bam files - -If you are running on exome data you need to prodive the `--exome` flag so that the right verison of the model will be used. +Note that the pipeline will create the following files in your working directory: ```bash -nextflow run nf-core/deepvariant --genome hg19 --bam_folder myBamFolder --bed myBedFile --exome +work # Directory containing the nextflow working files +results # Finished results (configurable, see below) +.nextflow_log # Log file from Nextflow +# Other nextflow hidden files, eg. history of pipeline runs and old logs. ``` -## Job Resources - -### Automatic resubmission - -Each step in the pipeline has a default set of requirements for number of CPUs, memory and time. For most of the steps in the pipeline, if the job exits with an error code of `143` (exceeded requested resources) it will automatically resubmit with higher requests (2 x original, then 3 x original). If it still fails after three times then the pipeline is stopped. - -### Custom resource requests - -Wherever process-specific requirements are set in the pipeline, the default value can be changed by creating a custom config file. See the files in [`conf`](../conf) for examples. +### Updating the pipeline -## AWS Batch specific parameters +When you run the above command, Nextflow automatically pulls the pipeline code from GitHub and stores it as a cached version. When running the pipeline after this, it will always use the cached version if available - even if the pipeline has been updated since. To make sure that you're running the latest version of the pipeline, make sure that you regularly update the cached version of the pipeline: -Running the pipeline on AWS Batch requires a couple of specific parameters to be set according to your AWS Batch configuration. Please use the `-awsbatch` profile and then specify all of the following parameters. +```bash +nextflow pull nf-core/deepvariant +``` -### `--awsqueue` +### Reproducibility -The JobQueue that you intend to use on AWS Batch. +It's a good idea to specify a pipeline version when running the pipeline on your data. This ensures that a specific version of the pipeline code and software are used when you run your pipeline. If you keep using the same tag, you'll be running the same version of the pipeline, even if there have been changes to the code since. -### `--awsregion` +First, go to the [nf-core/deepvariant releases page](https://github.com/nf-core/deepvariant/releases) and find the latest version number - numeric only (eg. `1.3.1`). Then specify this when running the pipeline with `-r` (one hyphen) - eg. `-r 1.3.1`. -The AWS region to run your job in. Default is set to `eu-west-1` but can be adjusted to your needs. +This version number will be logged in reports when you run the pipeline, so that you'll know what you used when you look back in the future. -Please make sure to also set the `-w/--work-dir` and `--outdir` parameters to a S3 storage bucket of your choice - you'll get an error message notifying you if you didn't. +## Core Nextflow arguments -## Other command line parameters +> **NB:** These options are part of Nextflow and use a _single_ hyphen (pipeline parameters use a double-hyphen). -### `--outdir` +### `-profile` -The output directory where the results will be saved. +Use this parameter to choose a configuration profile. Profiles can give configuration presets for different compute environments. -### `--email` +Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Podman, Conda) - see below. -Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits. If set in your user config file (`~/.nextflow/config`) then you don't need to speicfy this on the command line for every run. +> We highly recommend the use of Docker or Singularity containers for full pipeline reproducibility, however when this is not possible, Conda is also supported. -### `-name` +The pipeline also dynamically loads configurations from [https://github.com/nf-core/configs](https://github.com/nf-core/configs) when it runs, making multiple config profiles for various institutional clusters available at run time. For more information and to see if your system is available in these configs please see the [nf-core/configs documentation](https://github.com/nf-core/configs#documentation). -Name for the pipeline run. If not specified, Nextflow will automatically generate a random mnemonic. +Note that multiple profiles can be loaded, for example: `-profile test,docker` - the order of arguments is important! +They are loaded in sequence, so later profiles can overwrite earlier profiles. -This is used in the MultiQC report (if not default) and in the summary HTML / e-mail (always). +If `-profile` is not specified, the pipeline will run locally and expect all software to be installed and available on the `PATH`. This is _not_ recommended. -**NB:** Single hyphen (core Nextflow option) +* `docker` + * A generic configuration profile to be used with [Docker](https://docker.com/) + * Pulls software from Docker Hub: [`nfcore/deepvariant`](https://hub.docker.com/r/nfcore/deepvariant/) +* `singularity` + * A generic configuration profile to be used with [Singularity](https://sylabs.io/docs/) + * Pulls software from Docker Hub: [`nfcore/deepvariant`](https://hub.docker.com/r/nfcore/deepvariant/) +* `podman` + * A generic configuration profile to be used with [Podman](https://podman.io/) + * Pulls software from Docker Hub: [`nfcore/deepvariant`](https://hub.docker.com/r/nfcore/deepvariant/) +* `conda` + * Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker, Singularity or Podman. + * A generic configuration profile to be used with [Conda](https://conda.io/docs/) + * Pulls most software from [Bioconda](https://bioconda.github.io/) +* `test` + * A profile with a complete configuration for automated testing + * Includes links to test data so needs no other parameters ### `-resume` @@ -289,40 +140,44 @@ Specify this when restarting a pipeline. Nextflow will used cached results from You can also supply a run name to resume a specific run: `-resume [run-name]`. Use the `nextflow log` command to show previous run names. -**NB:** Single hyphen (core Nextflow option) - ### `-c` -Specify the path to a specific config file (this is a core NextFlow command). +Specify the path to a specific config file (this is a core Nextflow command). See the [nf-core website documentation](https://nf-co.re/usage/configuration) for more information. -**NB:** Single hyphen (core Nextflow option) +#### Custom resource requests -Note - you can use this to override defaults. For example, you can specify a config file using `-c` that contains the following: +Each step in the pipeline has a default set of requirements for number of CPUs, memory and time. For most of the steps in the pipeline, if the job exits with an error code of `143` (exceeded requested resources) it will automatically resubmit with higher requests (2 x original, then 3 x original). If it still fails after three times then the pipeline is stopped. + +Whilst these default requirements will hopefully work for most people with most data, you may find that you want to customise the compute resources that the pipeline requests. You can do this by creating a custom config file. For example, to give the workflow process `star` 32GB of memory, you could use the following config: ```nextflow -process.$multiqc.module = [] +process { + withName: star { + memory = 32.GB + } +} ``` -### `--max_memory` +See the main [Nextflow documentation](https://www.nextflow.io/docs/latest/config.html) for more information. + +If you are likely to be running `nf-core` pipelines regularly it may be a good idea to request that your custom config file is uploaded to the `nf-core/configs` git repository. Before you do this please can you test that the config file works with your pipeline of choice using the `-c` parameter (see definition above). You can then create a pull request to the `nf-core/configs` repository with the addition of your config file, associated documentation file (see examples in [`nf-core/configs/docs`](https://github.com/nf-core/configs/tree/master/docs)), and amending [`nfcore_custom.config`](https://github.com/nf-core/configs/blob/master/nfcore_custom.config) to include your custom profile. -Use to set a top-limit for the default memory requirement for each process. -Should be a string in the format integer-unit. eg. `--max_memory '8.GB'`` +If you have any questions or issues please send us a message on [Slack](https://nf-co.re/join/slack) on the [`#configs` channel](https://nfcore.slack.com/channels/configs). -### `--max_time` -Use to set a top-limit for the default time requirement for each process. -Should be a string in the format integer-unit. eg. `--max_time '2.h'` +### Running in the background -### `--max_cpus` +Nextflow handles job submissions and supervises the running jobs. The Nextflow process must run until the pipeline is finished. -Use to set a top-limit for the default CPU requirement for each process. -Should be a string in the format integer-unit. eg. `--max_cpus 1` +The Nextflow `-bg` flag launches Nextflow in the background, detached from your terminal so that the workflow does not stop if you log out of your session. The logs are saved to a file. -### `--plaintext_email` +Alternatively, you can use `screen` / `tmux` or similar tool to create a detached session which you can log back into at a later time. +Some HPC setups also allow you to run nextflow within a cluster job submitted your job scheduler (from where it submits more jobs). -Set to receive plain-text e-mails instead of HTML formatted. +#### Nextflow memory requirements -### `--multiqc_config` -Specify a path to a custom MultiQC configuration file. +In some cases, the Nextflow Java virtual machines can start to request a large amount of memory. +We recommend adding the following line to your environment to limit this (typically in `~/.bashrc` or `~./bash_profile`): -## Memory -DeepVariant is quite memory intensive. The most memory intensive process is `make_examples`. The memory requirement should be approximately 10-15x the size of your BAM file. For example, for a 5GB BAM file the memory should be set to 50GB. Fortunately this is set automaticaally for you in `base.config` for all of the man deepvariant processes, so you don't need change anything more and can run the pipeline as normal. +```bash +NXF_OPTS='-Xms1g -Xmx4g' +``` diff --git a/environment.yml b/environment.yml index 8ddc57f..d773247 100644 --- a/environment.yml +++ b/environment.yml @@ -1,14 +1,12 @@ -name: nf-core-deepvariant-1.0 +# You can use this file to create a conda environment for this pipeline: +# conda env create -f environment.yml +name: nf-core-deepvariant-1.0dev channels: - - bioconda - conda-forge + - bioconda - defaults dependencies: - - python=2.7.15 - - pip=10.0.1 - - deepvariant=0.7.0 - - picard=2.18.7 - - samtools=1.9 - - htslib=1.9 - - lbzip2=2.5 - - bzip2=1.0.6 + # TODO nf-core: Add required software dependencies here + - bioconda::fastqc=0.11.9 + - bioconda::trim-galore=0.6.5 + - bioconda::multiqc=1.9 diff --git a/lib/Checks.groovy b/lib/Checks.groovy new file mode 100644 index 0000000..f9103a5 --- /dev/null +++ b/lib/Checks.groovy @@ -0,0 +1,48 @@ +/* + * This file holds several functions used to perform standard checks for the nf-core pipeline template. + */ + +class Checks { + + static void aws_batch(workflow, params) { + if (workflow.profile.contains('awsbatch')) { + assert !params.awsqueue || !params.awsregion : "Specify correct --awsqueue and --awsregion parameters on AWSBatch!" + // Check outdir paths to be S3 buckets if running on AWSBatch + // related: https://github.com/nextflow-io/nextflow/issues/813 + assert !params.outdir.startsWith('s3:') : "Outdir not on S3 - specify S3 Bucket to run on AWSBatch!" + // Prevent trace files to be stored on S3 since S3 does not support rolling files. + assert params.tracedir.startsWith('s3:') : "Specify a local tracedir or run without trace! S3 cannot be used for tracefiles." + } + } + + static void hostname(workflow, params, log) { + Map colors = Headers.log_colours(params.monochrome_logs) + if (params.hostnames) { + def hostname = "hostname".execute().text.trim() + params.hostnames.each { prof, hnames -> + hnames.each { hname -> + if (hostname.contains(hname) && !workflow.profile.contains(prof)) { + log.info "=${colors.yellow}====================================================${colors.reset}=\n" + + "${colors.yellow}WARN: You are running with `-profile $workflow.profile`\n" + + " but your machine hostname is ${colors.white}'$hostname'${colors.reset}.\n" + + " ${colors.yellow_bold}Please use `-profile $prof${colors.reset}`\n" + + "=${colors.yellow}====================================================${colors.reset}=" + } + } + } + } + } + + // Citation string + private static String citation(workflow) { + return "If you use ${workflow.manifest.name} for your analysis please cite:\n\n" + + "* The pipeline\n" + + " https://doi.org/10.5281/zenodo.1400710\n\n" + + "* The nf-core framework\n" + + " https://dx.doi.org/10.1038/s41587-020-0439-x\n" + + " https://rdcu.be/b1GjZ\n\n" + + "* Software dependencies\n" + + " https://github.com/${workflow.manifest.name}/blob/master/CITATIONS.md" + } + +} \ No newline at end of file diff --git a/lib/Completion.groovy b/lib/Completion.groovy new file mode 100644 index 0000000..e745c98 --- /dev/null +++ b/lib/Completion.groovy @@ -0,0 +1,127 @@ +/* + * Functions to be run on completion of pipeline + */ + +class Completion { + static void email(workflow, params, summary_params, projectDir, log, multiqc_report=[]) { + + // Set up the e-mail variables + def subject = "[$workflow.manifest.name] Successful: $workflow.runName" + if (!workflow.success) { + subject = "[$workflow.manifest.name] FAILED: $workflow.runName" + } + + def summary = [:] + for (group in summary_params.keySet()) { + summary << summary_params[group] + } + + def misc_fields = [:] + misc_fields['Date Started'] = workflow.start + misc_fields['Date Completed'] = workflow.complete + misc_fields['Pipeline script file path'] = workflow.scriptFile + misc_fields['Pipeline script hash ID'] = workflow.scriptId + if (workflow.repository) misc_fields['Pipeline repository Git URL'] = workflow.repository + if (workflow.commitId) misc_fields['Pipeline repository Git Commit'] = workflow.commitId + if (workflow.revision) misc_fields['Pipeline Git branch/tag'] = workflow.revision + misc_fields['Nextflow Version'] = workflow.nextflow.version + misc_fields['Nextflow Build'] = workflow.nextflow.build + misc_fields['Nextflow Compile Timestamp'] = workflow.nextflow.timestamp + + def email_fields = [:] + email_fields['version'] = workflow.manifest.version + email_fields['runName'] = workflow.runName + email_fields['success'] = workflow.success + email_fields['dateComplete'] = workflow.complete + email_fields['duration'] = workflow.duration + email_fields['exitStatus'] = workflow.exitStatus + email_fields['errorMessage'] = (workflow.errorMessage ?: 'None') + email_fields['errorReport'] = (workflow.errorReport ?: 'None') + email_fields['commandLine'] = workflow.commandLine + email_fields['projectDir'] = workflow.projectDir + email_fields['summary'] = summary << misc_fields + + // On success try attach the multiqc report + def mqc_report = null + try { + if (workflow.success && !params.skip_multiqc) { + mqc_report = multiqc_report.getVal() + if (mqc_report.getClass() == ArrayList && mqc_report.size() >= 1) { + if (mqc_report.size() > 1) { + log.warn "[$workflow.manifest.name] Found multiple reports from process 'MULTIQC', will use only one" + } + mqc_report = mqc_report[0] + } + } + } catch (all) { + log.warn "[$workflow.manifest.name] Could not attach MultiQC report to summary email" + } + + // Check if we are only sending emails on failure + def email_address = params.email + if (!params.email && params.email_on_fail && !workflow.success) { + email_address = params.email_on_fail + } + + // Render the TXT template + def engine = new groovy.text.GStringTemplateEngine() + def tf = new File("$projectDir/assets/email_template.txt") + def txt_template = engine.createTemplate(tf).make(email_fields) + def email_txt = txt_template.toString() + + // Render the HTML template + def hf = new File("$projectDir/assets/email_template.html") + def html_template = engine.createTemplate(hf).make(email_fields) + def email_html = html_template.toString() + + // Render the sendmail template + def max_multiqc_email_size = params.max_multiqc_email_size as nextflow.util.MemoryUnit + def smail_fields = [ email: email_address, subject: subject, email_txt: email_txt, email_html: email_html, projectDir: "$projectDir", mqcFile: mqc_report, mqcMaxSize: max_multiqc_email_size.toBytes()] + def sf = new File("$projectDir/assets/sendmail_template.txt") + def sendmail_template = engine.createTemplate(sf).make(smail_fields) + def sendmail_html = sendmail_template.toString() + + // Send the HTML e-mail + Map colors = Headers.log_colours(params.monochrome_logs) + if (email_address) { + try { + if (params.plaintext_email) { throw GroovyException('Send plaintext e-mail, not HTML') } + // Try to send HTML e-mail using sendmail + [ 'sendmail', '-t' ].execute() << sendmail_html + log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} Sent summary e-mail to $email_address (sendmail)-" + } catch (all) { + // Catch failures and try with plaintext + def mail_cmd = [ 'mail', '-s', subject, '--content-type=text/html', email_address ] + if ( mqc_report.size() <= max_multiqc_email_size.toBytes() ) { + mail_cmd += [ '-A', mqc_report ] + } + mail_cmd.execute() << email_html + log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} Sent summary e-mail to $email_address (mail)-" + } + } + + // Write summary e-mail HTML to a file + def output_d = new File("${params.outdir}/pipeline_info/") + if (!output_d.exists()) { + output_d.mkdirs() + } + def output_hf = new File(output_d, "pipeline_report.html") + output_hf.withWriter { w -> w << email_html } + def output_tf = new File(output_d, "pipeline_report.txt") + output_tf.withWriter { w -> w << email_txt } + } + + static void summary(workflow, params, log) { + Map colors = Headers.log_colours(params.monochrome_logs) + if (workflow.success) { + if (workflow.stats.ignoredCount == 0) { + log.info "-${colors.purple}[$workflow.manifest.name]${colors.green} Pipeline completed successfully${colors.reset}-" + } else { + log.info "-${colors.purple}[$workflow.manifest.name]${colors.red} Pipeline completed successfully, but with errored process(es) ${colors.reset}-" + } + } else { + Checks.hostname(workflow, params, log) + log.info "-${colors.purple}[$workflow.manifest.name]${colors.red} Pipeline completed with errors${colors.reset}-" + } + } +} \ No newline at end of file diff --git a/lib/Headers.groovy b/lib/Headers.groovy new file mode 100644 index 0000000..15d1d38 --- /dev/null +++ b/lib/Headers.groovy @@ -0,0 +1,43 @@ +/* + * This file holds several functions used to render the nf-core ANSI header. + */ + +class Headers { + + private static Map log_colours(Boolean monochrome_logs) { + Map colorcodes = [:] + colorcodes['reset'] = monochrome_logs ? '' : "\033[0m" + colorcodes['dim'] = monochrome_logs ? '' : "\033[2m" + colorcodes['black'] = monochrome_logs ? '' : "\033[0;30m" + colorcodes['green'] = monochrome_logs ? '' : "\033[0;32m" + colorcodes['yellow'] = monochrome_logs ? '' : "\033[0;33m" + colorcodes['yellow_bold'] = monochrome_logs ? '' : "\033[1;93m" + colorcodes['blue'] = monochrome_logs ? '' : "\033[0;34m" + colorcodes['purple'] = monochrome_logs ? '' : "\033[0;35m" + colorcodes['cyan'] = monochrome_logs ? '' : "\033[0;36m" + colorcodes['white'] = monochrome_logs ? '' : "\033[0;37m" + colorcodes['red'] = monochrome_logs ? '' : "\033[1;91m" + return colorcodes + } + + static String dashed_line(monochrome_logs) { + Map colors = log_colours(monochrome_logs) + return "-${colors.dim}----------------------------------------------------${colors.reset}-" + } + + static String nf_core(workflow, monochrome_logs) { + Map colors = log_colours(monochrome_logs) + String.format( + """\n + ${dashed_line(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} + ${dashed_line(monochrome_logs)} + """.stripIndent() + ) + } +} diff --git a/lib/Schema.groovy b/lib/Schema.groovy new file mode 100644 index 0000000..e241f0c --- /dev/null +++ b/lib/Schema.groovy @@ -0,0 +1,228 @@ +/* + * This file holds several functions used to perform JSON parameter validation, help and summary rendering for the nf-core pipeline template. + */ + +import groovy.json.JsonSlurper + +class Schema { + /* + * This method tries to read a JSON params file + */ + private static LinkedHashMap params_load(String json_schema) { + def params_map = new LinkedHashMap() + try { + params_map = params_read(json_schema) + } catch (Exception e) { + println "Could not read parameters settings from JSON. $e" + params_map = new LinkedHashMap() + } + return params_map + } + + /* + Method to actually read in JSON file using Groovy. + Group (as Key), values are all parameters + - Parameter1 as Key, Description as Value + - Parameter2 as Key, Description as Value + .... + Group + - + */ + private static LinkedHashMap params_read(String json_schema) throws Exception { + def json = new File(json_schema).text + def Map json_params = (Map) new JsonSlurper().parseText(json).get('definitions') + /* Tree looks like this in nf-core schema + * definitions <- this is what the first get('definitions') gets us + group 1 + title + description + properties + parameter 1 + type + description + parameter 2 + type + description + group 2 + title + description + properties + parameter 1 + type + description + */ + def params_map = new LinkedHashMap() + json_params.each { key, val -> + def Map group = json_params."$key".properties // Gets the property object of the group + def title = json_params."$key".title + def sub_params = new LinkedHashMap() + group.each { innerkey, value -> + sub_params.put(innerkey, value) + } + params_map.put(title, sub_params) + } + return params_map + } + + /* + * Get maximum number of characters across all parameter names + */ + private static Integer params_max_chars(params_map) { + Integer max_chars = 0 + for (group in params_map.keySet()) { + def group_params = params_map.get(group) // This gets the parameters of that particular group + for (param in group_params.keySet()) { + if (param.size() > max_chars) { + max_chars = param.size() + } + } + } + return max_chars + } + + /* + * Beautify parameters for --help + */ + private static String params_help(workflow, params, json_schema, command) { + String output = Headers.nf_core(workflow, params.monochrome_logs) + "\n" + output += "Typical pipeline command:\n\n" + output += " ${command}\n\n" + def params_map = params_load(json_schema) + def max_chars = params_max_chars(params_map) + 1 + for (group in params_map.keySet()) { + output += group + "\n" + def group_params = params_map.get(group) // This gets the parameters of that particular group + for (param in group_params.keySet()) { + def type = "[" + group_params.get(param).type + "]" + def description = group_params.get(param).description + output += " \u001B[1m--" + param.padRight(max_chars) + "\u001B[1m" + type.padRight(10) + description + "\n" + } + output += "\n" + } + output += Headers.dashed_line(params.monochrome_logs) + output += "\n\n" + Checks.citation(workflow) + output += "\n\n" + Headers.dashed_line(params.monochrome_logs) + return output + } + + /* + * Groovy Map summarising parameters/workflow options used by the pipeline + */ + private static LinkedHashMap params_summary_map(workflow, params, json_schema) { + // Get a selection of core Nextflow workflow options + def Map workflow_summary = [:] + if (workflow.revision) { + workflow_summary['revision'] = workflow.revision + } + workflow_summary['runName'] = workflow.runName + if (workflow.containerEngine) { + workflow_summary['containerEngine'] = "$workflow.containerEngine" + } + if (workflow.container) { + workflow_summary['container'] = "$workflow.container" + } + workflow_summary['launchDir'] = workflow.launchDir + workflow_summary['workDir'] = workflow.workDir + workflow_summary['projectDir'] = workflow.projectDir + workflow_summary['userName'] = workflow.userName + workflow_summary['profile'] = workflow.profile + workflow_summary['configFiles'] = workflow.configFiles.join(', ') + + // Get pipeline parameters defined in JSON Schema + def Map params_summary = [:] + def blacklist = ['hostnames'] + def params_map = params_load(json_schema) + for (group in params_map.keySet()) { + def sub_params = new LinkedHashMap() + def group_params = params_map.get(group) // This gets the parameters of that particular group + for (param in group_params.keySet()) { + if (params.containsKey(param) && !blacklist.contains(param)) { + def params_value = params.get(param) + def schema_value = group_params.get(param).default + def param_type = group_params.get(param).type + if (schema_value == null) { + if (param_type == 'boolean') { + schema_value = false + } + if (param_type == 'string') { + schema_value = '' + } + if (param_type == 'integer') { + schema_value = 0 + } + } else { + if (param_type == 'string') { + if (schema_value.contains('$baseDir') || schema_value.contains('${baseDir}')) { + def sub_string = schema_value.replace('\$baseDir','') + sub_string = sub_string.replace('\${baseDir}','') + if (params_value.contains(sub_string)) { + schema_value = params_value + } + } + if (schema_value.contains('$params.outdir') || schema_value.contains('${params.outdir}')) { + def sub_string = schema_value.replace('\$params.outdir','') + sub_string = sub_string.replace('\${params.outdir}','') + if ("${params.outdir}${sub_string}" == params_value) { + schema_value = params_value + } + } + } + } + + if (params_value != schema_value) { + sub_params.put("$param", params_value) + } + } + } + params_summary.put(group, sub_params) + } + return [ 'Core Nextflow options' : workflow_summary ] << params_summary + } + + /* + * Beautify parameters for summary and return as string + */ + private static String params_summary_log(workflow, params, json_schema) { + String output = Headers.nf_core(workflow, params.monochrome_logs) + "\n" + def params_map = params_summary_map(workflow, params, json_schema) + def max_chars = params_max_chars(params_map) + for (group in params_map.keySet()) { + def group_params = params_map.get(group) // This gets the parameters of that particular group + if (group_params) { + output += group + "\n" + for (param in group_params.keySet()) { + output += " \u001B[1m" + param.padRight(max_chars) + ": \u001B[1m" + group_params.get(param) + "\n" + } + output += "\n" + } + } + output += Headers.dashed_line(params.monochrome_logs) + output += "\n\n" + Checks.citation(workflow) + output += "\n\n" + Headers.dashed_line(params.monochrome_logs) + return output + } + + static String params_summary_multiqc(workflow, summary) { + String summary_section = '' + for (group in summary.keySet()) { + def group_params = summary.get(group) // This gets the parameters of that particular group + if (group_params) { + summary_section += "

$group

\n" + summary_section += "
\n" + for (param in group_params.keySet()) { + summary_section += "
$param
${group_params.get(param) ?: 'N/A'}
\n" + } + summary_section += "
\n" + } + } + + String yaml_file_text = "id: '${workflow.manifest.name.replace('/','-')}-summary'\n" + yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n" + yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n" + yaml_file_text += "section_href: 'https://github.com/${workflow.manifest.name}'\n" + yaml_file_text += "plot_type: 'html'\n" + yaml_file_text += "data: |\n" + yaml_file_text += "${summary_section}" + return yaml_file_text + } +} \ No newline at end of file diff --git a/main.nf b/main.nf index f75c67b..57de4b7 100644 --- a/main.nf +++ b/main.nf @@ -9,509 +9,111 @@ ---------------------------------------------------------------------------------------- */ - -def helpMessage() { - log.info""" - ========================================= - nf-core/deepvariant v${workflow.manifest.version} - ========================================= - Usage: - - The typical command for running the pipeline is as follows: - - nextflow run nf-core/deepvariant --genome hg19 --bam_folder "s3://deepvariant-data/test-bam/" --bed testdata/test.bed -profile standard,docker - - Mandatory arguments: - --bam_folder Path to folder containing BAM files (reads must have been aligned to specified reference file, see below) - OR - --bam Path to BAM file (reads must have been aligned to specified reference file, see below) - --bed Path to bed file specifying regions to be analyzed - - References: If you wish to overwrite default reference of hg19. - --genome Reference genome: hg19 | hg19chr20 (for testing) | h38 | grch37primary | hs37d5 - --genomes_base Base directory location of genomes (default = "s3://deepvariant-data/genomes") - OR - --fasta Path to fasta reference - --fai Path to fasta index generated using `samtools faidx` - --fastagz Path to gzipped fasta - --gzfai Path to index of gzipped fasta - --gzi Path to bgzip index format (.gzi) produced by faidx - *Pass all five files above to skip the fasta preprocessing step - - Options: - -profile Configuration profile to use. Can use multiple (comma separated) - Available: standard, conda, docker, singularity, awsbatch, test - --exome For exome bam files - --rgid Bam file read group line id incase its needed (default = 4) - --rglb Bam file read group line library incase its needed (default = 'lib1') - --rgpl Bam file read group line platform incase its needed (default = 'illumina') - --rgpu Bam file read group line platform unit incase its needed (default = 'unit1') - --rgsm Bam file read group line sample incase its needed (default = 20) - - Other options: - --outdir The output directory where the results will be saved (default = results) - --email Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits - -name Name for the pipeline run. If not specified, Nextflow will automatically generate a random mnemonic. - --help Bring up this help message - - AWSBatch options: - --awsqueue The AWSBatch JobQueue that needs to be set when running on AWSBatch - --awsregion The AWS Region for your AWS Batch job to run on - """.stripIndent() -} +nextflow.preview.dsl = 2 /* - * SET UP CONFIGURATION VARIABLES + * Print help message if required */ - -// Show help emssage -if (params.help){ - helpMessage() +if (params.help) { + // TODO nf-core: Update typical command used to run pipeline + def command = "nextflow run nf-core/deepvariant --input samplesheet.csv -profile docker" + log.info Headers.nf_core(workflow, params.monochrome_logs) + log.info Schema.params_help("$baseDir/nextflow_schema.json", command) exit 0 } -//set model for call variants either whole genome or exome -model= params.exome ? 'wes' : 'wgs' - -//set fasta files equal to genome option if used -params.fasta = params.genome ? params.genomes[ params.genome ].fasta : false -params.fai = params.genome ? params.genomes[ params.genome ].fai : false -params.fastagz = params.genome ? params.genomes[ params.genome ].fastagz : false -params.gzfai = params.genome ? params.genomes[ params.genome ].gzfai : false -params.gzi = params.genome ? params.genomes[ params.genome ].gzi : false - -//setup fasta channels -(fastaToIndexCh, fastaToGzCh, fastaToGzFaiCh, fastaToGziCh) = Channel.fromPath(params.fasta).into(4) - -bedToExamples = Channel - .fromPath(params.bed) - .ifEmpty { exit 1, "please specify --bed option (--bed bedfile)"} - -if(params.fai){ -faiToExamples = Channel - .fromPath(params.fai) - .ifEmpty{exit 1, "Fai file not found: ${params.fai}"} -} +/* + * Stage config files + */ +ch_multiqc_config = file("$baseDir/assets/multiqc_config.yaml", checkIfExists: true) +ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath(params.multiqc_config, checkIfExists: true) : Channel.empty() +ch_output_docs = file("$projectDir/docs/output.md", checkIfExists: true) +ch_output_docs_images = file("$projectDir/docs/images/", checkIfExists: true) -if(params.fastagz){ -fastaGz = Channel - .fromPath(params.fastagz) - .ifEmpty{exit 1, "Fastagz file not found: ${params.fastagz}"} - .into {fastaGzToExamples; fastaGzToVariants } -} +/* + * Validate parameters + */ +if (params.input) { ch_input = file(params.input, checkIfExists: true) } else { exit 1, "Input samplesheet file not specified!" } -if(params.gzfai){ -gzFai = Channel - .fromPath(params.gzfai) - .ifEmpty{exit 1, "gzfai file not found: ${params.gzfai}"} - .into{gzFaiToExamples; gzFaiToVariants } +/* + * Reference genomes + */ +// TODO nf-core: Add any reference files that are needed +// NOTE - FOR SIMPLICITY THIS IS NOT USED IN THIS PIPELINE +// EXAMPLE ONLY TO DEMONSTRATE USAGE OF AWS IGENOMES +if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) { + exit 1, "The provided genome '${params.genome}' is not available in the iGenomes file. Currently the available genomes are ${params.genomes.keySet().join(", ")}" } +params.fasta = params.genomes[params.genome]?.fasta +if (params.fasta) { ch_fasta = file(params.fasta, checkIfExists: true) } -if(params.gzi){ -gzi = Channel - .fromPath(params.gzi) - .ifEmpty{exit 1, "gzi file not found: ${params.gzi}"} - .into {gziToExamples; gziToVariants} -} -/*-------------------------------------------------- - Bam related input files ----------------------------------------------------*/ -if(params.bam_folder) { - Channel - .fromPath("${params.bam_folder}/${params.bam_file_prefix}*.bam") - .ifEmpty { exit 1, "${params.bam_folder}/${params.bam_file_prefix}*.bam not found"} - .set{bamChannel} -} else if(params.bam) { - Channel - .fromPath(params.bam) - .ifEmpty { exit 1, "${params.bam} not found"} - .set{bamChannel} -} else { - exit 1, "please specify --bam OR --bam_folder" -} +/* + * Check parameters + */ +Checks.aws_batch(workflow, params) // Check AWS batch settings +Checks.hostname(workflow, params, log) // Check the hostnames against configured profiles -/*-------------------------------------------------- - For workflow summary ----------------------------------------------------*/ +/* + * Print parameter summary + */ // Has the run name been specified by the user? -// this has the bonus effect of catching both -name and --name -custom_runName = params.name -if( !(workflow.runName ==~ /[a-z]+_[a-z]+/) ){ - custom_runName = workflow.runName -} - -// Check workDir/outdir paths to be S3 buckets if running on AWSBatch -// related: https://github.com/nextflow-io/nextflow/issues/813 -if( workflow.profile == 'awsbatch') { - if(!workflow.workDir.startsWith('s3:') || !params.outdir.startsWith('s3:')) exit 1, "Workdir or Outdir not on S3 - specify S3 Buckets for each to run on AWSBatch!" -} - - -// Header log info -log.info """======================================================= - ,--./,-. - ___ __ __ __ ___ /,-._.--~\' - |\\ | |__ __ / ` / \\ |__) |__ } { - | \\| | \\__, \\__/ | \\ |___ \\`-._,-`-, - `._,._,\' -nf-core/deepvariant v${workflow.manifest.version}" -=======================================================""" -def summary = [:] -summary['Pipeline Name'] = 'nf-core/deepvariant' -summary['Pipeline Version'] = workflow.manifest.version -if(params.bam_folder) summary['Bam folder'] = params.bam_folder -if(params.bam) summary['Bam file'] = params.bam -summary['Bed file'] = params.bed -if(params.genome) summary['Reference genome'] = params.genome -if(params.fasta) summary['Fasta Ref'] = params.fasta -if(params.fai) summary['Fasta Index'] = params.fai -if(params.fastagz) summary['Fasta gzipped '] = params.fastagz -if(params.gzfai) summary['Fasta gzipped Index'] = params.gzfai -if(params.gzi) summary['Fasta bgzip Index'] = params.gzi -if(params.rgid != 4) summary['BAM Read Group ID'] = params.rgid -if(params.rglb != 'lib1') summary['BAM Read Group Library'] = params.rglb -if(params.rgpl != 'illumina') summary['BAM Read Group Platform'] = params.rgpl -if(params.rgpu != 'unit1') summary['BAM Read Group Platform Unit'] = params.rgpu -if(params.rgsm != 20) summary['BAM Read Group Sample'] = params.rgsm -summary['Max Memory'] = params.max_memory -summary['Max CPUs'] = params.max_cpus -summary['Max Time'] = params.max_time -summary['Model'] = model -summary['Output dir'] = params.outdir -summary['Working dir'] = workflow.workDir -summary['Container Engine'] = workflow.containerEngine -if(workflow.containerEngine) summary['Container'] = workflow.container -summary['Current home'] = "$HOME" -summary['Current user'] = "$USER" -summary['Current path'] = "$PWD" -summary['Working dir'] = workflow.workDir -summary['Output dir'] = params.outdir -summary['Script dir'] = workflow.projectDir -summary['Config Profile'] = workflow.profile -if(workflow.profile == 'awsbatch'){ - summary['AWS Region'] = params.awsregion - summary['AWS Queue'] = params.awsqueue -} -if(params.email) summary['E-mail Address'] = params.email -log.info summary.collect { k,v -> "${k.padRight(15)}: $v" }.join("\n") -log.info "=========================================" - - -def create_workflow_summary(summary) { - - def yaml_file = workDir.resolve('workflow_summary_mqc.yaml') - yaml_file.text = """ - id: 'nf-core-deepvariant-summary' - description: " - this information is collected when the pipeline is started." - section_name: 'nf-core/deepvariant Workflow Summary' - section_href: 'https://github.com/nf-core/deepvariant' - plot_type: 'html' - data: | -
-${summary.collect { k,v -> "
$k
${v ?: 'N/A'}
" }.join("\n")} -
- """.stripIndent() - - return yaml_file -} - - -/******************************************************************** - preprocess fasta files processes - Collects all the files related to the reference genome, like - .fai,.gz ... - If the user gives them as an input, they are used - If not they are produced in this process given only the fasta file. -********************************************************************/ - -if(!params.fai) { - process preprocess_fai { - tag "${fasta}.fai" - publishDir "$baseDir/sampleDerivatives" - - input: - file(fasta) from fastaToIndexCh - - output: - file("${fasta}.fai") into faiToExamples - - script: - """ - samtools faidx $fasta - """ - } -} - -if(!params.fastagz) { - process preprocess_fastagz { - tag "${fasta}.gz" - publishDir "$baseDir/sampleDerivatives" - - input: - file(fasta) from fastaToGzCh - - output: - file("*.gz") into (tmpFastaGzCh, fastaGzToExamples, fastaGzToVariants) - - script: - """ - bgzip -c ${fasta} > ${fasta}.gz - """ - } -} - -if(!params.gzfai) { - process preprocess_gzfai { - tag "${fasta}.gz.fai" - publishDir "$baseDir/sampleDerivatives" - - input: - file(fasta) from fastaToGzFaiCh - file(fastagz) from tmpFastaGzCh - - output: - file("*.gz.fai") into (gzFaiToExamples, gzFaiToVariants) - - script: - """ - samtools faidx $fastagz - """ - } -} - -if(!params.gzi){ - process preprocess_gzi { - tag "${fasta}.gz.gzi" - publishDir "$baseDir/sampleDerivatives" - - input: - file(fasta) from fastaToGziCh - - output: - file("*.gz.gzi") into (gziToExamples, gziToVariants) - - script: - """ - bgzip -c -i ${fasta} > ${fasta}.gz - """ - } -} - -/******************************************************************** - process preprocess_bam - Takes care of the read group line. -********************************************************************/ - -process preprocess_bam{ - - tag "${bam}" - publishDir "$baseDir/sampleDerivatives" - - input: - file(bam) from bamChannel - - output: - set file("ready/${bam}"), file("ready/${bam}.bai") into completeChannel - - script: - """ - mkdir ready - [[ `samtools view -H ${bam} | grep '@RG' | wc -l` > 0 ]] && { mv $bam ready;}|| { picard AddOrReplaceReadGroups \ - I=${bam} \ - O=ready/${bam} \ - RGID=${params.rgid} \ - RGLB=${params.rglb} \ - RGPL=${params.rgpl} \ - RGPU=${params.rgpu} \ - RGSM=${params.rgsm};} - cd ready ;samtools index ${bam}; - """ -} - -/******************************************************************** - process make_examples - Getting bam files and converting them to images ( named examples ) -********************************************************************/ - -process make_examples{ - - tag "${bam}" - publishDir "${params.outdir}/make_examples", mode: 'copy', - saveAs: {filename -> "logs/log"} - - input: - file fai from faiToExamples.collect() - file fastagz from fastaGzToExamples.collect() - file gzfai from gzFaiToExamples.collect() - file gzi from gziToExamples.collect() - file bed from bedToExamples.collect() - set file(bam), file(bai) from completeChannel - - output: - set file("${bam}"),file('*_shardedExamples') into examples - - script: - """ - mkdir logs - mkdir ${bam.baseName}_shardedExamples - dv_make_examples.py \ - --cores ${task.cpus} \ - --sample ${bam} \ - --ref ${fastagz} \ - --reads ${bam} \ - --regions ${bed} \ - --logdir logs \ - --examples ${bam.baseName}_shardedExamples - """ -} -/******************************************************************** - process call_variants - Doing the variant calling based on the ML trained model. -********************************************************************/ - -process call_variants{ - - tag "${bam}" - - input: - set file(bam),file(shardedExamples) from examples - - output: - set file(bam),file('*_call_variants_output.tfrecord') into called_variants - - script: - """ - dv_call_variants.py \ - --cores ${task.cpus} \ - --sample ${bam} \ - --outfile ${bam.baseName}_call_variants_output.tfrecord \ - --examples $shardedExamples \ - --model ${model} - """ +// this has the bonus effect of catching both -name and --name +run_name = params.name +if (!(workflow.runName ==~ /[a-z]+_[a-z]+/)) { + run_name = workflow.runName } +summary = Schema.params_summary(workflow, params, run_name) +log.info Headers.nf_core(workflow, params.monochrome_logs) +log.info summary.collect { k,v -> "${k.padRight(20)}: $v" }.join("\n") +log.info "-\033[2m----------------------------------------------------\033[0m-" +workflow_summary = Schema.params_mqc_summary(summary) +ch_workflow_summary = Channel.value(workflow_summary) +/* + * Include local pipeline modules + */ +include { OUTPUT_DOCUMENTATION } from './modules/local/output_documentation' params(params) +include { GET_SOFTWARE_VERSIONS } from './modules/local/get_software_versions' params(params) +include { CHECK_SAMPLESHEET; check_samplesheet_paths } from './modules/local/check_samplesheet' params(params) -/******************************************************************** - process postprocess_variants - Trasforming the variant calling output (tfrecord file) into a standard vcf file. -********************************************************************/ +/* + * Include nf-core modules + */ +include { FASTQC } from './modules/nf-core/fastqc' params(params) +include { MULTIQC } from './modules/nf-core/multiqc' params(params) -process postprocess_variants{ +/* + * Run the workflow + */ +workflow { - tag "${bam}" + CHECK_SAMPLESHEET(ch_input) + .splitCsv(header:true, sep:',') + .map { check_samplesheet_paths(it) } + .set { ch_raw_reads } - publishDir params.outdir, mode: 'copy' + FASTQC(ch_raw_reads) - input: - file fastagz from fastaGzToVariants.collect() - file gzfai from gzFaiToVariants.collect() - file gzi from gziToVariants.collect() - set file(bam),file('call_variants_output.tfrecord') from called_variants + OUTPUT_DOCUMENTATION( + ch_output_docs, + ch_output_docs_images) - output: - set val("${bam}"),file("${bam}.vcf") into postout + GET_SOFTWARE_VERSIONS() - script: - """ - dv_postprocess_variants.py \ - --ref ${fastagz} \ - --infile call_variants_output.tfrecord \ - --outfile "${bam}.vcf" - """ + MULTIQC( + ch_multiqc_config, + ch_multiqc_custom_config.collect().ifEmpty([]), + FASTQC.out.collect(), + GET_SOFTWARE_VERSIONS.out.yml.collect(), + ch_workflow_summary) } /* - * Parse software version numbers + * Send completion email */ -process get_software_versions { - - output: - file 'software_versions_mqc.yaml' into software_versions_yaml - - script: - """ - echo $workflow.manifest.version &> v_nf_deepvariant.txt - echo $workflow.nextflow.version &> v_nextflow.txt - ls /opt/conda/pkgs/ &> v_deepvariant.txt - python --version &> v_python.txt - pip --version &> v_pip.txt - samtools --version &> v_samtools.txt - lbzip2 --version &> v_lbzip2.txt - bzip2 --version &> v_bzip2.txt - scrape_software_versions.py &> software_versions_mqc.yaml - """ -} - workflow.onComplete { - // Set up the e-mail variables - def subject = "[nf-core/deepvariant] Successful: $workflow.runName" - if(!workflow.success){ - subject = "[nf-core/deepvariant] FAILED: $workflow.runName" - } - def email_fields = [:] - email_fields['version'] = workflow.manifest.version - email_fields['runName'] = custom_runName ?: workflow.runName - email_fields['success'] = workflow.success - email_fields['dateComplete'] = workflow.complete - email_fields['duration'] = workflow.duration - email_fields['exitStatus'] = workflow.exitStatus - email_fields['errorMessage'] = (workflow.errorMessage ?: 'None') - email_fields['errorReport'] = (workflow.errorReport ?: 'None') - email_fields['commandLine'] = workflow.commandLine - email_fields['projectDir'] = workflow.projectDir - email_fields['summary'] = summary - email_fields['summary']['Date Started'] = workflow.start - email_fields['summary']['Date Completed'] = workflow.complete - email_fields['summary']['Pipeline script file path'] = workflow.scriptFile - email_fields['summary']['Pipeline script hash ID'] = workflow.scriptId - if(workflow.repository) email_fields['summary']['Pipeline repository Git URL'] = workflow.repository - if(workflow.commitId) email_fields['summary']['Pipeline repository Git Commit'] = workflow.commitId - if(workflow.revision) email_fields['summary']['Pipeline Git branch/tag'] = workflow.revision - email_fields['summary']['Nextflow Version'] = workflow.nextflow.version - email_fields['summary']['Nextflow Build'] = workflow.nextflow.build - email_fields['summary']['Nextflow Compile Timestamp'] = workflow.nextflow.timestamp - - // Render the TXT template - def engine = new groovy.text.GStringTemplateEngine() - def tf = new File("$baseDir/assets/email_template.txt") - def txt_template = engine.createTemplate(tf).make(email_fields) - def email_txt = txt_template.toString() - - // Render the HTML template - def hf = new File("$baseDir/assets/email_template.html") - def html_template = engine.createTemplate(hf).make(email_fields) - def email_html = html_template.toString() - - // Render the sendmail template - def smail_fields = [ email: params.email, subject: subject, email_txt: email_txt, email_html: email_html, baseDir: "$baseDir" ] - def sf = new File("$baseDir/assets/sendmail_template.txt") - def sendmail_template = engine.createTemplate(sf).make(smail_fields) - def sendmail_html = sendmail_template.toString() - - // Send the HTML e-mail - if (params.email) { - try { - if( params.plaintext_email ){ throw GroovyException('Send plaintext e-mail, not HTML') } - // Try to send HTML e-mail using sendmail - [ 'sendmail', '-t' ].execute() << sendmail_html - log.info "[nf-core/deepvariant] Sent summary e-mail to $params.email (sendmail)" - } catch (all) { - // Catch failures and try with plaintext - [ 'mail', '-s', subject, params.email ].execute() << email_txt - log.info "[nf-core/deepvariant] Sent summary e-mail to $params.email (mail)" - } - } - - // Write summary e-mail HTML to a file - def output_d = new File( "${params.outdir}/Documentation/" ) - if( !output_d.exists() ) { - output_d.mkdirs() - } - def output_hf = new File( output_d, "pipeline_report.html" ) - output_hf.withWriter { w -> w << email_html } - def output_tf = new File( output_d, "pipeline_report.txt" ) - output_tf.withWriter { w -> w << email_txt } - - log.info "[nf-core/deepvariant] Pipeline Complete! You can find your results in $baseDir/${params.outdir}" + def multiqc_report = [] + Completion.email(workflow, params, summary, run_name, baseDir, multiqc_report, log) + Completion.summary(workflow, params, log) } diff --git a/modules/local/process/cat_fastq.nf b/modules/local/process/cat_fastq.nf new file mode 100644 index 0000000..83a2d72 --- /dev/null +++ b/modules/local/process/cat_fastq.nf @@ -0,0 +1,54 @@ +// Import generic module functions +include { initOptions; saveFiles } from './functions' + +params.options = [:] +def options = initOptions(params.options) + +/* + * Concatenate FastQ files + */ +process CAT_FASTQ { + tag "$meta.id" + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'merged_fastq', publish_id:meta.id) } + + conda (params.enable_conda ? "conda-forge::sed=4.7" : null) + container "biocontainers/biocontainers:v1.2.0_cv1" + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*.merged.fastq.gz"), emit: reads + + script: + def prefix = options.suffix ? "${meta.id}${options.suffix}" : "${meta.id}" + readList = reads.collect{it.toString()} + if (!meta.single_end) { + if (readList.size > 2) { + def read1 = [] + def read2 = [] + readList.eachWithIndex{ v, ix -> ( ix & 1 ? read2 : read1 ) << v } + """ + cat ${read1.sort().join(' ')} > ${prefix}_1.merged.fastq.gz + cat ${read2.sort().join(' ')} > ${prefix}_2.merged.fastq.gz + """ + } else { + """ + ln -s ${reads[0]} ${prefix}_1.merged.fastq.gz + ln -s ${reads[1]} ${prefix}_2.merged.fastq.gz + """ + } + } else { + if (readList.size > 1) { + """ + cat ${readList.sort().join(' ')} > ${prefix}.merged.fastq.gz + """ + } else { + """ + ln -s $reads ${prefix}.merged.fastq.gz + """ + } + } +} diff --git a/modules/local/process/functions.nf b/modules/local/process/functions.nf new file mode 100644 index 0000000..d25eea8 --- /dev/null +++ b/modules/local/process/functions.nf @@ -0,0 +1,59 @@ +/* + * ----------------------------------------------------- + * Utility functions used in nf-core DSL2 module files + * ----------------------------------------------------- + */ + +/* + * Extract name of software tool from process name using $task.process + */ +def getSoftwareName(task_process) { + return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() +} + +/* + * Function to initialise default values and to generate a Groovy Map of available options for nf-core modules + */ +def initOptions(Map args) { + def Map options = [:] + options.args = args.args ?: '' + options.args2 = args.args2 ?: '' + options.publish_by_id = args.publish_by_id ?: false + options.publish_dir = args.publish_dir ?: '' + options.publish_files = args.publish_files + options.suffix = args.suffix ?: '' + return options +} + +/* + * Tidy up and join elements of a list to return a path string + */ +def getPathFromList(path_list) { + def paths = path_list.findAll { item -> !item?.trim().isEmpty() } // Remove empty entries + paths = paths.collect { it.trim().replaceAll("^[/]+|[/]+\$", "") } // Trim whitespace and trailing slashes + return paths.join('/') +} + +/* + * Function to save/publish module results + */ +def saveFiles(Map args) { + if (!args.filename.endsWith('.version.txt')) { + def ioptions = initOptions(args.options) + def path_list = [ ioptions.publish_dir ?: args.publish_dir ] + if (ioptions.publish_by_id) { + path_list.add(args.publish_id) + } + if (ioptions.publish_files instanceof Map) { + for (ext in ioptions.publish_files) { + if (args.filename.endsWith(ext.key)) { + def ext_list = path_list.collect() + ext_list.add(ext.value) + return "${getPathFromList(ext_list)}/$args.filename" + } + } + } else if (ioptions.publish_files == null) { + return "${getPathFromList(path_list)}/$args.filename" + } + } +} diff --git a/modules/local/process/get_software_versions.nf b/modules/local/process/get_software_versions.nf new file mode 100644 index 0000000..7ad0405 --- /dev/null +++ b/modules/local/process/get_software_versions.nf @@ -0,0 +1,32 @@ +// Import generic module functions +include { saveFiles } from './functions' + +params.options = [:] + +/* + * Parse software version numbers + */ +process GET_SOFTWARE_VERSIONS { + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', publish_id:'') } + + conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) + container "quay.io/biocontainers/python:3.8.3" + + cache false + + input: + path versions + + output: + path "software_versions.csv" , emit: csv + path 'software_versions_mqc.yaml', emit: yaml + + script: + """ + echo $workflow.manifest.version > pipeline.version.txt + echo $workflow.nextflow.version > nextflow.version.txt + scrape_software_versions.py &> software_versions_mqc.yaml + """ +} diff --git a/modules/local/process/samplesheet_check.nf b/modules/local/process/samplesheet_check.nf new file mode 100644 index 0000000..c238ad6 --- /dev/null +++ b/modules/local/process/samplesheet_check.nf @@ -0,0 +1,44 @@ +// Import generic module functions +include { saveFiles } from './functions' + +params.options = [:] + +/* + * Reformat design file and check validity + */ +process SAMPLESHEET_CHECK { + tag "$samplesheet" + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', publish_id:'') } + + conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) + container "quay.io/biocontainers/python:3.8.3" + + input: + path samplesheet + + output: + path '*.csv' + + + script: // This script is bundled with the pipeline, in nf-core/deepvariant/bin/ + """ + check_samplesheet.py $samplesheet samplesheet.valid.csv + """ +} + +// Function to get list of [ meta, [ fastq_1, fastq_2 ] ] +def get_samplesheet_paths(LinkedHashMap row) { + def meta = [:] + meta.id = row.sample + meta.single_end = row.single_end.toBoolean() + + def array = [] + if (meta.single_end) { + array = [ meta, [ file(row.fastq_1, checkIfExists: true) ] ] + } else { + array = [ meta, [ file(row.fastq_1, checkIfExists: true), file(row.fastq_2, checkIfExists: true) ] ] + } + return array +} diff --git a/modules/local/subworkflow/input_check.nf b/modules/local/subworkflow/input_check.nf new file mode 100644 index 0000000..cb6a902 --- /dev/null +++ b/modules/local/subworkflow/input_check.nf @@ -0,0 +1,23 @@ +/* + * Check input samplesheet and get read channels + */ + +params.options = [:] + +include { + SAMPLESHEET_CHECK; + get_samplesheet_paths } from '../process/samplesheet_check' addParams( options: params.options ) + +workflow INPUT_CHECK { + take: + samplesheet // file: /path/to/samplesheet.csv + + main: + SAMPLESHEET_CHECK ( samplesheet ) + .splitCsv ( header:true, sep:',' ) + .map { get_samplesheet_paths(it) } + .set { reads } + + emit: + reads // channel: [ val(meta), [ reads ] ] +} diff --git a/modules/nf-core/software/fastqc/functions.nf b/modules/nf-core/software/fastqc/functions.nf new file mode 100644 index 0000000..d25eea8 --- /dev/null +++ b/modules/nf-core/software/fastqc/functions.nf @@ -0,0 +1,59 @@ +/* + * ----------------------------------------------------- + * Utility functions used in nf-core DSL2 module files + * ----------------------------------------------------- + */ + +/* + * Extract name of software tool from process name using $task.process + */ +def getSoftwareName(task_process) { + return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() +} + +/* + * Function to initialise default values and to generate a Groovy Map of available options for nf-core modules + */ +def initOptions(Map args) { + def Map options = [:] + options.args = args.args ?: '' + options.args2 = args.args2 ?: '' + options.publish_by_id = args.publish_by_id ?: false + options.publish_dir = args.publish_dir ?: '' + options.publish_files = args.publish_files + options.suffix = args.suffix ?: '' + return options +} + +/* + * Tidy up and join elements of a list to return a path string + */ +def getPathFromList(path_list) { + def paths = path_list.findAll { item -> !item?.trim().isEmpty() } // Remove empty entries + paths = paths.collect { it.trim().replaceAll("^[/]+|[/]+\$", "") } // Trim whitespace and trailing slashes + return paths.join('/') +} + +/* + * Function to save/publish module results + */ +def saveFiles(Map args) { + if (!args.filename.endsWith('.version.txt')) { + def ioptions = initOptions(args.options) + def path_list = [ ioptions.publish_dir ?: args.publish_dir ] + if (ioptions.publish_by_id) { + path_list.add(args.publish_id) + } + if (ioptions.publish_files instanceof Map) { + for (ext in ioptions.publish_files) { + if (args.filename.endsWith(ext.key)) { + def ext_list = path_list.collect() + ext_list.add(ext.value) + return "${getPathFromList(ext_list)}/$args.filename" + } + } + } else if (ioptions.publish_files == null) { + return "${getPathFromList(path_list)}/$args.filename" + } + } +} diff --git a/modules/nf-core/software/fastqc/main.nf b/modules/nf-core/software/fastqc/main.nf new file mode 100644 index 0000000..3edc97a --- /dev/null +++ b/modules/nf-core/software/fastqc/main.nf @@ -0,0 +1,43 @@ +// Import generic module functions +include { initOptions; saveFiles; getSoftwareName } from './functions' + +params.options = [:] +def options = initOptions(params.options) + +process FASTQC { + tag "$meta.id" + label 'process_medium' + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:getSoftwareName(task.process), publish_id:meta.id) } + + conda (params.enable_conda ? "bioconda::fastqc=0.11.9" : null) + container "quay.io/biocontainers/fastqc:0.11.9--0" + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*.html"), emit: html + tuple val(meta), path("*.zip") , emit: zip + path "*.version.txt" , emit: version + + script: + // Add soft-links to original FastQs for consistent naming in pipeline + def software = getSoftwareName(task.process) + def prefix = options.suffix ? "${meta.id}.${options.suffix}" : "${meta.id}" + if (meta.single_end) { + """ + [ ! -f ${prefix}.fastq.gz ] && ln -s $reads ${prefix}.fastq.gz + fastqc $options.args --threads $task.cpus ${prefix}.fastq.gz + fastqc --version | sed -e "s/FastQC v//g" > ${software}.version.txt + """ + } else { + """ + [ ! -f ${prefix}_1.fastq.gz ] && ln -s ${reads[0]} ${prefix}_1.fastq.gz + [ ! -f ${prefix}_2.fastq.gz ] && ln -s ${reads[1]} ${prefix}_2.fastq.gz + fastqc $options.args --threads $task.cpus ${prefix}_1.fastq.gz ${prefix}_2.fastq.gz + fastqc --version | sed -e "s/FastQC v//g" > ${software}.version.txt + """ + } +} diff --git a/modules/nf-core/software/fastqc/meta.yml b/modules/nf-core/software/fastqc/meta.yml new file mode 100644 index 0000000..337fc37 --- /dev/null +++ b/modules/nf-core/software/fastqc/meta.yml @@ -0,0 +1,67 @@ +name: fastqc +description: Run FastQC on sequenced reads +keywords: + - quality control + - qc + - adapters + - fastq +tools: + - fastqc: + description: | + FastQC gives general quality metrics about your reads. + It provides information about the quality score distribution + across your reads, the per base sequence content (%A/C/G/T). + You get information about adapter contamination and other + overrepresented sequences. + homepage: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/ + documentation: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/ +params: + - outdir: + type: string + description: | + The pipeline's output directory. By default, the module will + output files into `$params.outdir/` + - publish_dir_mode: + type: string + description: | + Value for the Nextflow `publishDir` mode parameter. + Available: symlink, rellink, link, copy, copyNoFollow, move. + - enable_conda: + type: boolean + description: | + Run the module with Conda using the software specified + via the `conda` directive +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - reads: + type: file + description: | + List of input FastQ files of size 1 and 2 for single-end and paired-end data, + respectively. +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - html: + type: file + description: FastQC report + pattern: "*_{fastqc.html}" + - zip: + type: file + description: FastQC report archive + pattern: "*_{fastqc.zip}" + - version: + type: file + description: File containing software version + pattern: "*.{version.txt}" +authors: + - "@drpatelh" + - "@grst" + - "@ewels" + - "@FelixKrueger" diff --git a/nextflow.config b/nextflow.config index 51eb851..ed9ed5a 100644 --- a/nextflow.config +++ b/nextflow.config @@ -3,94 +3,104 @@ * nf-core/deepvariant Nextflow config file * ------------------------------------------------- * Default config options for all environments. - * Cluster-specific config options should be saved - * in the conf folder and imported under a profile - * name here. */ - // Global default params, used in configs - params { - - container = 'nfcore/deepvariant:1.0' - - help = false - outdir = 'results' - email = false - name = false - - // BAM files - bam=false - bam_folder=false - bam_file_prefix="*" - getBai=false - - // Reference genomes - genome = false - genomes_base = 's3://deepvariant-data/genomes' - testBaseFolder = 's3://deepvariant-test/input' - - // Exome data - exome=false - bed=false - - // Params for the Read Group Line to be added just in case its needed. - rgid=4 - rglb="lib1" - rgpl="illumina" - rgpu="unit1" - rgsm=20 - - tracedir = "${params.outdir}/pipeline_info" - clusterOptions = false - awsqueue = false - awsregion = 'eu-west-1' - manifest.version = '1.0' - } +// Global default params, used in configs +params { + + // TODO nf-core: Specify your pipeline's command line flags + // Input options + input = '' + + // References + genome = '' + igenomes_base = 's3://ngi-igenomes/igenomes/' + igenomes_ignore = false + + // MultiQC options + multiqc_config = '' + multiqc_title = '' + max_multiqc_email_size = '25.MB' + + // Boilerplate options + enable_conda = false + outdir = './results' + tracedir = "${params.outdir}/pipeline_info" + publish_dir_mode = 'copy' + email = '' + email_on_fail = '' + plaintext_email = false + monochrome_logs = false + help = false + clusterOptions = '' + + // Config options + custom_config_version = 'master' + custom_config_base = "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}" + hostnames = [:] + config_profile_description = '' + config_profile_contact = '' + config_profile_url = '' + + // Max resource options + // Defaults only, expecting to be overwritten + max_memory = '128.GB' + max_cpus = 16 + max_time = '240.h' -profiles { +} - standard { - includeConfig 'conf/base.config' - includeConfig 'conf/genomes.config' - } - conda { process.conda = "$baseDir/environment.yml" } - docker { docker.enabled = true } - singularity { - singularity.enabled = true - } +// Container slug. Stable releases should specify release tag! +// Developmental code should specify :dev +process.container = 'nfcore/deepvariant:dev' - binac { - includeConfig 'conf/base.config' - includeConfig 'conf/binac.config' - includeConfig 'conf/genomes.config' - } - awsbatch { - includeConfig 'conf/base.config' - includeConfig 'conf/awsbatch.config' - includeConfig 'conf/genomes.config' +// Load base.config by default for all pipelines +includeConfig 'conf/base.config' + +// Load modules.config for DSL2 module specific options +includeConfig 'conf/modules.config' + +// Load nf-core custom profiles from different Institutions +try { + includeConfig "${params.custom_config_base}/nfcore_custom.config" +} catch (Exception e) { + System.err.println("WARNING: Could not load nf-core/config profiles: ${params.custom_config_base}/nfcore_custom.config") +} + +profiles { + debug { process.beforeScript = 'echo $HOSTNAME' } + conda { params.enable_conda = true } + docker { + docker.enabled = true + // Avoid this error: + // WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap. + // Testing this in nf-core after discussion here https://github.com/nf-core/tools/pull/351 + // once this is established and works well, nextflow might implement this behavior as new default. + docker.runOptions = '-u \$(id -u):\$(id -g)' } - test { - includeConfig 'conf/base.config' - includeConfig 'conf/test.config' - includeConfig 'conf/genomes.config' + singularity { + singularity.enabled = true + singularity.autoMounts = true } - debug { process.beforeScript = 'echo $HOSTNAME' } - none { - // Don't load any config (for use with custom home configs) + podman { + podman.enabled = true } + test { includeConfig 'conf/test.config' } + test_full { includeConfig 'conf/test_full.config' } +} - // Profile for testing s3 environment - test_s3{ - includeConfig 'conf/base.config' - params.fasta="${params.testBaseFolder}/ucsc.hg19.chr20.unittest.fasta" - params.fai="${params.testBaseFolder}/ucsc.hg19.chr20.unittest.fasta.fai" - params.fastagz="${params.testBaseFolder}/ucsc.hg19.chr20.unittest.fasta.gz" - params.gzfai="${params.testBaseFolder}/ucsc.hg19.chr20.unittest.fasta.gz.fai" - params.gzi="${params.testBaseFolder}/ucsc.hg19.chr20.unittest.fasta.gz.gzi" - params.bam_folder="${params.testBaseFolder}" - params.bed = 'https://github.com/nf-core/test-datasets/raw/deepvariant/testdata/test_nist.b37_chr20_100kbp_at_10mb.bed' - } +// Load igenomes.config if required +if (!params.igenomes_ignore) { + includeConfig 'conf/igenomes.config' +} else { + params.genomes = [:] +} +// Export these variables to prevent local Python/R libraries from conflicting with those in the container +env { + PYTHONNOUSERSITE = 1 + R_PROFILE_USER = "/.Rprofile" + R_ENVIRON_USER = "/.Renviron" } // Capture exit codes from upstream processes when piping @@ -98,37 +108,37 @@ process.shell = ['/bin/bash', '-euo', 'pipefail'] timeline { enabled = true - file = "${params.tracedir}/nf-core/deepvariant_timeline.html" + file = "${params.tracedir}/execution_timeline.html" } report { enabled = true - file = "${params.tracedir}/nf-core/deepvariant_report.html" + file = "${params.tracedir}/execution_report.html" } trace { enabled = true - file = "${params.tracedir}/nf-core/deepvariant_trace.txt" + file = "${params.tracedir}/execution_trace.txt" } dag { enabled = true - file = "${params.tracedir}/nf-core/deepvariant_dag.svg" + file = "${params.tracedir}/pipeline_dag.svg" } manifest { - name = 'nf-core/deepvariant' - author = 'Phil Palmer' - homePage = 'https://github.com/nf-core/deepvariant' - description = 'Google DeepVariant variant caller as a Nextflow pipeline' - mainScript = 'main.nf' - nextflowVersion = '>=18.10.1' - version = '1.0' + name = 'nf-core/deepvariant' + author = 'Abhinav Sharma' + homePage = 'https://github.com/nf-core/deepvariant' + description = 'Google's DeepVariant as a Nextflow workflow.' + mainScript = 'main.nf' + nextflowVersion = '>=20.04.0' + version = '1.0dev' } // Function to ensure that resource requirements don't go beyond // a maximum limit def check_max(obj, type) { - if(type == 'memory'){ + if (type == 'memory') { try { - if(obj.compareTo(params.max_memory as nextflow.util.MemoryUnit) == 1) + if (obj.compareTo(params.max_memory as nextflow.util.MemoryUnit) == 1) return params.max_memory as nextflow.util.MemoryUnit else return obj @@ -136,9 +146,9 @@ def check_max(obj, type) { println " ### ERROR ### Max memory '${params.max_memory}' is not valid! Using default value: $obj" return obj } - } else if(type == 'time'){ + } else if (type == 'time') { try { - if(obj.compareTo(params.max_time as nextflow.util.Duration) == 1) + if (obj.compareTo(params.max_time as nextflow.util.Duration) == 1) return params.max_time as nextflow.util.Duration else return obj @@ -146,7 +156,7 @@ def check_max(obj, type) { println " ### ERROR ### Max time '${params.max_time}' is not valid! Using default value: $obj" return obj } - } else if(type == 'cpus'){ + } else if (type == 'cpus') { try { return Math.min( obj, params.max_cpus as int ) } catch (all) { diff --git a/nextflow_schema.json b/nextflow_schema.json new file mode 100644 index 0000000..9f1f670 --- /dev/null +++ b/nextflow_schema.json @@ -0,0 +1,253 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "https://raw.githubusercontent.com/nf-core/deepvariant/master/nextflow_schema.json", + "title": "nf-core/deepvariant pipeline parameters", + "description": "Google's DeepVariant as a Nextflow workflow.", + "type": "object", + "definitions": { + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": [ + "input" + ], + "properties": { + "input": { + "type": "string", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a samplesheet with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 4 columns, and a header row. See [usage docs](https://nf-co.re/deepvariant/docs/usage#--input).", + "fa_icon": "fas fa-file-csv" + }, + "outdir": { + "type": "string", + "description": "The output directory where the results will be saved.", + "default": "./results", + "fa_icon": "fas fa-folder-open" + }, + "email": { + "type": "string", + "description": "Email address for completion summary.", + "fa_icon": "fas fa-envelope", + "help_text": "Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits. If set in your user config file (`~/.nextflow/config`) then you don't need to specify this on the command line for every run.", + "pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$" + } + } + }, + "reference_genome_options": { + "title": "Reference genome options", + "type": "object", + "fa_icon": "fas fa-dna", + "description": "Options for the reference genome indices used to align reads.", + "properties": { + "genome": { + "type": "string", + "description": "Name of iGenomes reference.", + "fa_icon": "fas fa-book", + "help_text": "If using a reference genome configured in the pipeline using iGenomes, use this parameter to give the ID for the reference. This is then used to build the full paths for all required reference genome files e.g. `--genome GRCh38`.\n\nSee the [nf-core website docs](https://nf-co.re/usage/reference_genomes) for more details." + }, + "fasta": { + "type": "string", + "fa_icon": "fas fa-font", + "description": "Path to FASTA genome file.", + "help_text": "If you have no genome reference available, the pipeline can build one using a FASTA file. This requires additional time and resources, so it's better to use a pre-build index if possible." + }, + "igenomes_base": { + "type": "string", + "description": "Directory / URL base for iGenomes references.", + "default": "s3://ngi-igenomes/igenomes/", + "fa_icon": "fas fa-cloud-download-alt", + "hidden": true + }, + "igenomes_ignore": { + "type": "boolean", + "description": "Do not load the iGenomes reference config.", + "fa_icon": "fas fa-ban", + "hidden": true, + "help_text": "Do not load `igenomes.config` when running the pipeline. You may choose this option if you observe clashes between custom parameters and those supplied in `igenomes.config`." + } + } + }, + "generic_options": { + "title": "Generic options", + "type": "object", + "fa_icon": "fas fa-file-import", + "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`.", + "properties": { + "help": { + "type": "boolean", + "description": "Display help text.", + "hidden": true, + "fa_icon": "fas fa-question-circle" + }, + "publish_dir_mode": { + "type": "string", + "default": "copy", + "hidden": true, + "description": "Method used to save pipeline results to output directory.", + "help_text": "The Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.", + "fa_icon": "fas fa-copy", + "enum": [ + "symlink", + "rellink", + "link", + "copy", + "copyNoFollow", + "move" + ] + }, + "name": { + "type": "string", + "description": "Workflow name.", + "fa_icon": "fas fa-fingerprint", + "hidden": true, + "help_text": "A custom name for the pipeline run. Unlike the core nextflow `-name` option with one hyphen this parameter can be reused multiple times, for example if using `-resume`. Passed through to steps such as MultiQC and used for things like report filenames and titles." + }, + "email_on_fail": { + "type": "string", + "description": "Email address for completion summary, only when pipeline fails.", + "fa_icon": "fas fa-exclamation-triangle", + "pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$", + "hidden": true, + "help_text": "This works exactly as with `--email`, except emails are only sent if the workflow is not successful." + }, + "plaintext_email": { + "type": "boolean", + "description": "Send plain-text email instead of HTML.", + "fa_icon": "fas fa-remove-format", + "hidden": true, + "help_text": "Set to receive plain-text e-mails instead of HTML formatted." + }, + "max_multiqc_email_size": { + "type": "string", + "description": "File size limit when attaching MultiQC reports to summary emails.", + "default": "25.MB", + "fa_icon": "fas fa-file-upload", + "hidden": true, + "help_text": "If file generated by pipeline exceeds the threshold, it will not be attached." + }, + "monochrome_logs": { + "type": "boolean", + "description": "Do not use coloured log outputs.", + "fa_icon": "fas fa-palette", + "hidden": true, + "help_text": "Set to disable colourful command line output and live life in monochrome." + }, + "multiqc_config": { + "type": "string", + "description": "Custom config file to supply to MultiQC.", + "fa_icon": "fas fa-cog", + "hidden": true + }, + "tracedir": { + "type": "string", + "description": "Directory to keep pipeline Nextflow logs and reports.", + "default": "${params.outdir}/pipeline_info", + "fa_icon": "fas fa-cogs", + "hidden": true + } + } + }, + "max_job_request_options": { + "title": "Max job request options", + "type": "object", + "fa_icon": "fab fa-acquisitions-incorporated", + "description": "Set the top limit for requested resources for any single job.", + "help_text": "If you are running on a smaller system, a pipeline step requesting more resources than are available may cause the Nextflow to stop the run with an error. These options allow you to cap the maximum resources requested by any single job so that the pipeline will run on your system.\n\nNote that you can not _increase_ the resources requested by any job using these options. For that you will need your own configuration file. See [the nf-core website](https://nf-co.re/usage/configuration) for details.", + "properties": { + "max_cpus": { + "type": "integer", + "description": "Maximum number of CPUs that can be requested for any single job.", + "default": 16, + "fa_icon": "fas fa-microchip", + "hidden": true, + "help_text": "Use to set an upper-limit for the CPU requirement for each process. Should be an integer e.g. `--max_cpus 1`" + }, + "max_memory": { + "type": "string", + "description": "Maximum amount of memory that can be requested for any single job.", + "default": "128.GB", + "fa_icon": "fas fa-memory", + "hidden": true, + "help_text": "Use to set an upper-limit for the memory requirement for each process. Should be a string in the format integer-unit e.g. `--max_memory '8.GB'`" + }, + "max_time": { + "type": "string", + "description": "Maximum amount of time that can be requested for any single job.", + "default": "240.h", + "fa_icon": "far fa-clock", + "hidden": true, + "help_text": "Use to set an upper-limit for the time requirement for each process. Should be a string in the format integer-unit e.g. `--max_time '2.h'`" + } + } + }, + "institutional_config_options": { + "title": "Institutional config options", + "type": "object", + "fa_icon": "fas fa-university", + "description": "Parameters used to describe centralised config profiles. These should not be edited.", + "help_text": "The centralised nf-core configuration profiles use a handful of pipeline parameters to describe themselves. This information is then printed to the Nextflow log when you run a pipeline. You should not need to change these values when you run a pipeline.", + "properties": { + "custom_config_version": { + "type": "string", + "description": "Git commit id for Institutional configs.", + "default": "master", + "hidden": true, + "fa_icon": "fas fa-users-cog", + "help_text": "Provide git commit id for custom Institutional configs hosted at `nf-core/configs`. This was implemented for reproducibility purposes. Default: `master`.\n\n```bash\n## Download and use config file with following git commit id\n--custom_config_version d52db660777c4bf36546ddb188ec530c3ada1b96\n```" + }, + "custom_config_base": { + "type": "string", + "description": "Base directory for Institutional configs.", + "default": "https://raw.githubusercontent.com/nf-core/configs/master", + "hidden": true, + "help_text": "If you're running offline, nextflow will not be able to fetch the institutional config files from the internet. If you don't need them, then this is not a problem. If you do need them, you should download the files from the repo and tell nextflow where to find them with the `custom_config_base` option. For example:\n\n```bash\n## Download and unzip the config files\ncd /path/to/my/configs\nwget https://github.com/nf-core/configs/archive/master.zip\nunzip master.zip\n\n## Run the pipeline\ncd /path/to/my/data\nnextflow run /path/to/pipeline/ --custom_config_base /path/to/my/configs/configs-master/\n```\n\n> Note that the nf-core/tools helper package has a `download` command to download all required pipeline files + singularity containers + institutional configs in one go for you, to make this process easier.", + "fa_icon": "fas fa-users-cog" + }, + "hostnames": { + "type": "string", + "description": "Institutional configs hostname.", + "hidden": true, + "fa_icon": "fas fa-users-cog" + }, + "config_profile_description": { + "type": "string", + "description": "Institutional config description.", + "hidden": true, + "fa_icon": "fas fa-users-cog" + }, + "config_profile_contact": { + "type": "string", + "description": "Institutional config contact information.", + "hidden": true, + "fa_icon": "fas fa-users-cog" + }, + "config_profile_url": { + "type": "string", + "description": "Institutional config URL link.", + "hidden": true, + "fa_icon": "fas fa-users-cog" + } + } + } + }, + "allOf": [ + { + "$ref": "#/definitions/input_output_options" + }, + { + "$ref": "#/definitions/reference_genome_options" + }, + { + "$ref": "#/definitions/generic_options" + }, + { + "$ref": "#/definitions/max_job_request_options" + }, + { + "$ref": "#/definitions/institutional_config_options" + } + ] +} diff --git a/pics/pic_workflow.jpg b/pics/pic_workflow.jpg deleted file mode 100644 index 4cb296b750e51d7ccbf6557e46b2c72300520814..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39852 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

{o@jDKwb^Pj2Oid2C;PO^bSEM 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 U5s9VPEW{S_e}0>VejWTj07Oq|vH$=8 From 6bf20e18de690d3dbb73847afce2409bcba25953 Mon Sep 17 00:00:00 2001 From: Abhinav Sharma Date: Sat, 5 Dec 2020 18:10:44 +0530 Subject: [PATCH 2/5] Minor updates to readme to start the dev PR --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ab70d3e..ebb7628 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ ## Introduction +This pipeline simplifies the use of [Google's DeepVariant](https://github.com/google/deepvariant) and packages it as a workflow. + The pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It comes with docker containers making installation trivial and results highly reproducible. ## Quick Start @@ -46,7 +48,12 @@ The nf-core/deepvariant pipeline comes with documentation about the pipeline: [u ## Credits -nf-core/deepvariant was originally written by Abhinav Sharma. +This workflow was originally developed at [Lifebit](https://lifebit.ai/?utm_campaign=documentation&utm_source=github&utm_medium=web), by @luisas, to ease and reduce cost for variant calling analyses + + +The `v2.0` of `nf-core/deepvariant` workflow was modernized by Abhinav Sharma ( @abhi18av ), Alain Coletta ( @alaincoletta). + +Many thanks to nf-core and those who have helped out along the way too, including (but not limited to): @ewels, @MaxUlysse, @apeltzer, @sven1103 & @pditommaso ## Contributions and Support From 10ea35c966098556876b439cdea74b9fe6e0dc63 Mon Sep 17 00:00:00 2001 From: Abhinav Sharma Date: Sat, 5 Dec 2020 21:02:36 +0530 Subject: [PATCH 3/5] Get the sample test working --- deepvariant_test.nf | 68 ++++++++++++++++++++ modules/local/happy/cat_fastq.nf | 54 ++++++++++++++++ modules/local/happy/functions.nf | 59 +++++++++++++++++ modules/local/happy/get_software_versions.nf | 32 +++++++++ modules/local/happy/samplesheet_check.nf | 44 +++++++++++++ 5 files changed, 257 insertions(+) create mode 100644 deepvariant_test.nf create mode 100644 modules/local/happy/cat_fastq.nf create mode 100644 modules/local/happy/functions.nf create mode 100644 modules/local/happy/get_software_versions.nf create mode 100644 modules/local/happy/samplesheet_check.nf diff --git a/deepvariant_test.nf b/deepvariant_test.nf new file mode 100644 index 0000000..80dbabb --- /dev/null +++ b/deepvariant_test.nf @@ -0,0 +1,68 @@ +nextflow.enable.dsl = 2 + + +// References +REF_FTPDIR = "ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCA/000/001/405/GCA_000001405.15_GRCh38/seqs_for_alignment_pipelines.ucsc_ids" +ref_fasta_gz = "${REF_FTPDIR}/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.gz" +ref_fasta_fai = "${REF_FTPDIR}/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.fai" + + +// Genomes +READS_FTPDIR = "ftp://ftp.ncbi.nlm.nih.gov//giab/ftp/data/AshkenazimTrio/analysis/NIST_v4.2_SmallVariantDraftBenchmark_07092020" +BED_FILE = "${READS_FTPDIR}/HG002_GRCh38_1_22_v4.2_benchmark.bed" +VCF_FILE = "${READS_FTPDIR}/HG002_GRCh38_1_22_v4.2_benchmark.vcf.gz" +VCF_INDEX_FILE = "${READS_FTPDIR}/HG002_GRCh38_1_22_v4.2_benchmark.vcf.gz.tbi" + +// HG002 chr20 BAM +HTTPDIR = "https://storage.googleapis.com/deepvariant/case-study-testdata" +CHR_BAM = "${HTTPDIR}/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam" +CHR_BAM_BAI = "${HTTPDIR}/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam.bai" + +process DEEP_VARIANT { + container "google/deepvariant:1.0.0" + + shell: + + ''' + +mkdir -p reference + +FTPDIR=ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCA/000/001/405/GCA_000001405.15_GRCh38/seqs_for_alignment_pipelines.ucsc_ids + +curl ${FTPDIR}/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.gz | gunzip > reference/GRCh38_no_alt_analysis_set.fasta +curl ${FTPDIR}/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.fai > reference/GRCh38_no_alt_analysis_set.fasta.fai + + +mkdir -p benchmark + +FTPDIR=ftp://ftp.ncbi.nlm.nih.gov//giab/ftp/data/AshkenazimTrio/analysis/NIST_v4.2_SmallVariantDraftBenchmark_07092020 + +curl ${FTPDIR}/HG002_GRCh38_1_22_v4.2_benchmark.bed > benchmark/HG002_GRCh38_1_22_v4.2_benchmark.bed +curl ${FTPDIR}/HG002_GRCh38_1_22_v4.2_benchmark.vcf.gz > benchmark/HG002_GRCh38_1_22_v4.2_benchmark.vcf.gz +curl ${FTPDIR}/HG002_GRCh38_1_22_v4.2_benchmark.vcf.gz.tbi > benchmark/HG002_GRCh38_1_22_v4.2_benchmark.vcf.gz.tbi + + +mkdir -p input +HTTPDIR=https://storage.googleapis.com/deepvariant/case-study-testdata + +curl ${HTTPDIR}/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam > input/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam +curl ${HTTPDIR}/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam.bai > input/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam.bai + + + run_deepvariant \ + --model_type WGS \ + --ref /reference/GRCh38_no_alt_analysis_set.fasta \ + --reads /input/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam \ + --output_vcf /output/HG002.output.vcf.gz \ + --output_gvcf /output/HG002.output.g.vcf.gz \ + --num_shards $(nproc) \ + --regions chr20 + + ''' + +} + + +workflow { + DEEP_VARIANT() +} diff --git a/modules/local/happy/cat_fastq.nf b/modules/local/happy/cat_fastq.nf new file mode 100644 index 0000000..83a2d72 --- /dev/null +++ b/modules/local/happy/cat_fastq.nf @@ -0,0 +1,54 @@ +// Import generic module functions +include { initOptions; saveFiles } from './functions' + +params.options = [:] +def options = initOptions(params.options) + +/* + * Concatenate FastQ files + */ +process CAT_FASTQ { + tag "$meta.id" + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'merged_fastq', publish_id:meta.id) } + + conda (params.enable_conda ? "conda-forge::sed=4.7" : null) + container "biocontainers/biocontainers:v1.2.0_cv1" + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*.merged.fastq.gz"), emit: reads + + script: + def prefix = options.suffix ? "${meta.id}${options.suffix}" : "${meta.id}" + readList = reads.collect{it.toString()} + if (!meta.single_end) { + if (readList.size > 2) { + def read1 = [] + def read2 = [] + readList.eachWithIndex{ v, ix -> ( ix & 1 ? read2 : read1 ) << v } + """ + cat ${read1.sort().join(' ')} > ${prefix}_1.merged.fastq.gz + cat ${read2.sort().join(' ')} > ${prefix}_2.merged.fastq.gz + """ + } else { + """ + ln -s ${reads[0]} ${prefix}_1.merged.fastq.gz + ln -s ${reads[1]} ${prefix}_2.merged.fastq.gz + """ + } + } else { + if (readList.size > 1) { + """ + cat ${readList.sort().join(' ')} > ${prefix}.merged.fastq.gz + """ + } else { + """ + ln -s $reads ${prefix}.merged.fastq.gz + """ + } + } +} diff --git a/modules/local/happy/functions.nf b/modules/local/happy/functions.nf new file mode 100644 index 0000000..d25eea8 --- /dev/null +++ b/modules/local/happy/functions.nf @@ -0,0 +1,59 @@ +/* + * ----------------------------------------------------- + * Utility functions used in nf-core DSL2 module files + * ----------------------------------------------------- + */ + +/* + * Extract name of software tool from process name using $task.process + */ +def getSoftwareName(task_process) { + return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() +} + +/* + * Function to initialise default values and to generate a Groovy Map of available options for nf-core modules + */ +def initOptions(Map args) { + def Map options = [:] + options.args = args.args ?: '' + options.args2 = args.args2 ?: '' + options.publish_by_id = args.publish_by_id ?: false + options.publish_dir = args.publish_dir ?: '' + options.publish_files = args.publish_files + options.suffix = args.suffix ?: '' + return options +} + +/* + * Tidy up and join elements of a list to return a path string + */ +def getPathFromList(path_list) { + def paths = path_list.findAll { item -> !item?.trim().isEmpty() } // Remove empty entries + paths = paths.collect { it.trim().replaceAll("^[/]+|[/]+\$", "") } // Trim whitespace and trailing slashes + return paths.join('/') +} + +/* + * Function to save/publish module results + */ +def saveFiles(Map args) { + if (!args.filename.endsWith('.version.txt')) { + def ioptions = initOptions(args.options) + def path_list = [ ioptions.publish_dir ?: args.publish_dir ] + if (ioptions.publish_by_id) { + path_list.add(args.publish_id) + } + if (ioptions.publish_files instanceof Map) { + for (ext in ioptions.publish_files) { + if (args.filename.endsWith(ext.key)) { + def ext_list = path_list.collect() + ext_list.add(ext.value) + return "${getPathFromList(ext_list)}/$args.filename" + } + } + } else if (ioptions.publish_files == null) { + return "${getPathFromList(path_list)}/$args.filename" + } + } +} diff --git a/modules/local/happy/get_software_versions.nf b/modules/local/happy/get_software_versions.nf new file mode 100644 index 0000000..7ad0405 --- /dev/null +++ b/modules/local/happy/get_software_versions.nf @@ -0,0 +1,32 @@ +// Import generic module functions +include { saveFiles } from './functions' + +params.options = [:] + +/* + * Parse software version numbers + */ +process GET_SOFTWARE_VERSIONS { + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', publish_id:'') } + + conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) + container "quay.io/biocontainers/python:3.8.3" + + cache false + + input: + path versions + + output: + path "software_versions.csv" , emit: csv + path 'software_versions_mqc.yaml', emit: yaml + + script: + """ + echo $workflow.manifest.version > pipeline.version.txt + echo $workflow.nextflow.version > nextflow.version.txt + scrape_software_versions.py &> software_versions_mqc.yaml + """ +} diff --git a/modules/local/happy/samplesheet_check.nf b/modules/local/happy/samplesheet_check.nf new file mode 100644 index 0000000..c238ad6 --- /dev/null +++ b/modules/local/happy/samplesheet_check.nf @@ -0,0 +1,44 @@ +// Import generic module functions +include { saveFiles } from './functions' + +params.options = [:] + +/* + * Reformat design file and check validity + */ +process SAMPLESHEET_CHECK { + tag "$samplesheet" + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', publish_id:'') } + + conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) + container "quay.io/biocontainers/python:3.8.3" + + input: + path samplesheet + + output: + path '*.csv' + + + script: // This script is bundled with the pipeline, in nf-core/deepvariant/bin/ + """ + check_samplesheet.py $samplesheet samplesheet.valid.csv + """ +} + +// Function to get list of [ meta, [ fastq_1, fastq_2 ] ] +def get_samplesheet_paths(LinkedHashMap row) { + def meta = [:] + meta.id = row.sample + meta.single_end = row.single_end.toBoolean() + + def array = [] + if (meta.single_end) { + array = [ meta, [ file(row.fastq_1, checkIfExists: true) ] ] + } else { + array = [ meta, [ file(row.fastq_1, checkIfExists: true), file(row.fastq_2, checkIfExists: true) ] ] + } + return array +} From 4809db17ce77c83a1f2dbfc00125b4e9d6c13b99 Mon Sep 17 00:00:00 2001 From: Abhinav Sharma Date: Sun, 6 Dec 2020 13:59:55 +0530 Subject: [PATCH 4/5] Remove the benchmarking and test code --- deepvariant_test.nf | 68 -------------------- modules/local/happy/cat_fastq.nf | 54 ---------------- modules/local/happy/functions.nf | 59 ----------------- modules/local/happy/get_software_versions.nf | 32 --------- modules/local/happy/samplesheet_check.nf | 44 ------------- 5 files changed, 257 deletions(-) delete mode 100644 deepvariant_test.nf delete mode 100644 modules/local/happy/cat_fastq.nf delete mode 100644 modules/local/happy/functions.nf delete mode 100644 modules/local/happy/get_software_versions.nf delete mode 100644 modules/local/happy/samplesheet_check.nf diff --git a/deepvariant_test.nf b/deepvariant_test.nf deleted file mode 100644 index 80dbabb..0000000 --- a/deepvariant_test.nf +++ /dev/null @@ -1,68 +0,0 @@ -nextflow.enable.dsl = 2 - - -// References -REF_FTPDIR = "ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCA/000/001/405/GCA_000001405.15_GRCh38/seqs_for_alignment_pipelines.ucsc_ids" -ref_fasta_gz = "${REF_FTPDIR}/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.gz" -ref_fasta_fai = "${REF_FTPDIR}/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.fai" - - -// Genomes -READS_FTPDIR = "ftp://ftp.ncbi.nlm.nih.gov//giab/ftp/data/AshkenazimTrio/analysis/NIST_v4.2_SmallVariantDraftBenchmark_07092020" -BED_FILE = "${READS_FTPDIR}/HG002_GRCh38_1_22_v4.2_benchmark.bed" -VCF_FILE = "${READS_FTPDIR}/HG002_GRCh38_1_22_v4.2_benchmark.vcf.gz" -VCF_INDEX_FILE = "${READS_FTPDIR}/HG002_GRCh38_1_22_v4.2_benchmark.vcf.gz.tbi" - -// HG002 chr20 BAM -HTTPDIR = "https://storage.googleapis.com/deepvariant/case-study-testdata" -CHR_BAM = "${HTTPDIR}/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam" -CHR_BAM_BAI = "${HTTPDIR}/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam.bai" - -process DEEP_VARIANT { - container "google/deepvariant:1.0.0" - - shell: - - ''' - -mkdir -p reference - -FTPDIR=ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCA/000/001/405/GCA_000001405.15_GRCh38/seqs_for_alignment_pipelines.ucsc_ids - -curl ${FTPDIR}/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.gz | gunzip > reference/GRCh38_no_alt_analysis_set.fasta -curl ${FTPDIR}/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.fai > reference/GRCh38_no_alt_analysis_set.fasta.fai - - -mkdir -p benchmark - -FTPDIR=ftp://ftp.ncbi.nlm.nih.gov//giab/ftp/data/AshkenazimTrio/analysis/NIST_v4.2_SmallVariantDraftBenchmark_07092020 - -curl ${FTPDIR}/HG002_GRCh38_1_22_v4.2_benchmark.bed > benchmark/HG002_GRCh38_1_22_v4.2_benchmark.bed -curl ${FTPDIR}/HG002_GRCh38_1_22_v4.2_benchmark.vcf.gz > benchmark/HG002_GRCh38_1_22_v4.2_benchmark.vcf.gz -curl ${FTPDIR}/HG002_GRCh38_1_22_v4.2_benchmark.vcf.gz.tbi > benchmark/HG002_GRCh38_1_22_v4.2_benchmark.vcf.gz.tbi - - -mkdir -p input -HTTPDIR=https://storage.googleapis.com/deepvariant/case-study-testdata - -curl ${HTTPDIR}/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam > input/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam -curl ${HTTPDIR}/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam.bai > input/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam.bai - - - run_deepvariant \ - --model_type WGS \ - --ref /reference/GRCh38_no_alt_analysis_set.fasta \ - --reads /input/HG002.novaseq.pcr-free.35x.dedup.grch38_no_alt.chr20.bam \ - --output_vcf /output/HG002.output.vcf.gz \ - --output_gvcf /output/HG002.output.g.vcf.gz \ - --num_shards $(nproc) \ - --regions chr20 - - ''' - -} - - -workflow { - DEEP_VARIANT() -} diff --git a/modules/local/happy/cat_fastq.nf b/modules/local/happy/cat_fastq.nf deleted file mode 100644 index 83a2d72..0000000 --- a/modules/local/happy/cat_fastq.nf +++ /dev/null @@ -1,54 +0,0 @@ -// Import generic module functions -include { initOptions; saveFiles } from './functions' - -params.options = [:] -def options = initOptions(params.options) - -/* - * Concatenate FastQ files - */ -process CAT_FASTQ { - tag "$meta.id" - publishDir "${params.outdir}", - mode: params.publish_dir_mode, - saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'merged_fastq', publish_id:meta.id) } - - conda (params.enable_conda ? "conda-forge::sed=4.7" : null) - container "biocontainers/biocontainers:v1.2.0_cv1" - - input: - tuple val(meta), path(reads) - - output: - tuple val(meta), path("*.merged.fastq.gz"), emit: reads - - script: - def prefix = options.suffix ? "${meta.id}${options.suffix}" : "${meta.id}" - readList = reads.collect{it.toString()} - if (!meta.single_end) { - if (readList.size > 2) { - def read1 = [] - def read2 = [] - readList.eachWithIndex{ v, ix -> ( ix & 1 ? read2 : read1 ) << v } - """ - cat ${read1.sort().join(' ')} > ${prefix}_1.merged.fastq.gz - cat ${read2.sort().join(' ')} > ${prefix}_2.merged.fastq.gz - """ - } else { - """ - ln -s ${reads[0]} ${prefix}_1.merged.fastq.gz - ln -s ${reads[1]} ${prefix}_2.merged.fastq.gz - """ - } - } else { - if (readList.size > 1) { - """ - cat ${readList.sort().join(' ')} > ${prefix}.merged.fastq.gz - """ - } else { - """ - ln -s $reads ${prefix}.merged.fastq.gz - """ - } - } -} diff --git a/modules/local/happy/functions.nf b/modules/local/happy/functions.nf deleted file mode 100644 index d25eea8..0000000 --- a/modules/local/happy/functions.nf +++ /dev/null @@ -1,59 +0,0 @@ -/* - * ----------------------------------------------------- - * Utility functions used in nf-core DSL2 module files - * ----------------------------------------------------- - */ - -/* - * Extract name of software tool from process name using $task.process - */ -def getSoftwareName(task_process) { - return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() -} - -/* - * Function to initialise default values and to generate a Groovy Map of available options for nf-core modules - */ -def initOptions(Map args) { - def Map options = [:] - options.args = args.args ?: '' - options.args2 = args.args2 ?: '' - options.publish_by_id = args.publish_by_id ?: false - options.publish_dir = args.publish_dir ?: '' - options.publish_files = args.publish_files - options.suffix = args.suffix ?: '' - return options -} - -/* - * Tidy up and join elements of a list to return a path string - */ -def getPathFromList(path_list) { - def paths = path_list.findAll { item -> !item?.trim().isEmpty() } // Remove empty entries - paths = paths.collect { it.trim().replaceAll("^[/]+|[/]+\$", "") } // Trim whitespace and trailing slashes - return paths.join('/') -} - -/* - * Function to save/publish module results - */ -def saveFiles(Map args) { - if (!args.filename.endsWith('.version.txt')) { - def ioptions = initOptions(args.options) - def path_list = [ ioptions.publish_dir ?: args.publish_dir ] - if (ioptions.publish_by_id) { - path_list.add(args.publish_id) - } - if (ioptions.publish_files instanceof Map) { - for (ext in ioptions.publish_files) { - if (args.filename.endsWith(ext.key)) { - def ext_list = path_list.collect() - ext_list.add(ext.value) - return "${getPathFromList(ext_list)}/$args.filename" - } - } - } else if (ioptions.publish_files == null) { - return "${getPathFromList(path_list)}/$args.filename" - } - } -} diff --git a/modules/local/happy/get_software_versions.nf b/modules/local/happy/get_software_versions.nf deleted file mode 100644 index 7ad0405..0000000 --- a/modules/local/happy/get_software_versions.nf +++ /dev/null @@ -1,32 +0,0 @@ -// Import generic module functions -include { saveFiles } from './functions' - -params.options = [:] - -/* - * Parse software version numbers - */ -process GET_SOFTWARE_VERSIONS { - publishDir "${params.outdir}", - mode: params.publish_dir_mode, - saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', publish_id:'') } - - conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) - container "quay.io/biocontainers/python:3.8.3" - - cache false - - input: - path versions - - output: - path "software_versions.csv" , emit: csv - path 'software_versions_mqc.yaml', emit: yaml - - script: - """ - echo $workflow.manifest.version > pipeline.version.txt - echo $workflow.nextflow.version > nextflow.version.txt - scrape_software_versions.py &> software_versions_mqc.yaml - """ -} diff --git a/modules/local/happy/samplesheet_check.nf b/modules/local/happy/samplesheet_check.nf deleted file mode 100644 index c238ad6..0000000 --- a/modules/local/happy/samplesheet_check.nf +++ /dev/null @@ -1,44 +0,0 @@ -// Import generic module functions -include { saveFiles } from './functions' - -params.options = [:] - -/* - * Reformat design file and check validity - */ -process SAMPLESHEET_CHECK { - tag "$samplesheet" - publishDir "${params.outdir}", - mode: params.publish_dir_mode, - saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', publish_id:'') } - - conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) - container "quay.io/biocontainers/python:3.8.3" - - input: - path samplesheet - - output: - path '*.csv' - - - script: // This script is bundled with the pipeline, in nf-core/deepvariant/bin/ - """ - check_samplesheet.py $samplesheet samplesheet.valid.csv - """ -} - -// Function to get list of [ meta, [ fastq_1, fastq_2 ] ] -def get_samplesheet_paths(LinkedHashMap row) { - def meta = [:] - meta.id = row.sample - meta.single_end = row.single_end.toBoolean() - - def array = [] - if (meta.single_end) { - array = [ meta, [ file(row.fastq_1, checkIfExists: true) ] ] - } else { - array = [ meta, [ file(row.fastq_1, checkIfExists: true), file(row.fastq_2, checkIfExists: true) ] ] - } - return array -} From fe727c8ca7555264fefa3ddd92ce66df9998b221 Mon Sep 17 00:00:00 2001 From: Abhinav Sharma Date: Sun, 6 Dec 2020 18:56:53 +0530 Subject: [PATCH 5/5] Add stubs for deepvariant, bwa and samtools --- conf/base.config | 18 ++---- main.nf | 35 ----------- modules/local/software/bwa/index/functions.nf | 59 +++++++++++++++++++ modules/local/software/bwa/index/main.nf | 43 ++++++++++++++ modules/local/software/bwa/mem/functions.nf | 59 +++++++++++++++++++ modules/local/software/bwa/mem/main.nf | 43 ++++++++++++++ .../local/software/deepvariant/functions.nf | 59 +++++++++++++++++++ modules/local/software/deepvariant/main.nf | 41 +++++++++++++ .../software/samtools/faidx/functions.nf | 59 +++++++++++++++++++ modules/local/software/samtools/faidx/main.nf | 32 ++++++++++ 10 files changed, 401 insertions(+), 47 deletions(-) create mode 100644 modules/local/software/bwa/index/functions.nf create mode 100644 modules/local/software/bwa/index/main.nf create mode 100644 modules/local/software/bwa/mem/functions.nf create mode 100644 modules/local/software/bwa/mem/main.nf create mode 100644 modules/local/software/deepvariant/functions.nf create mode 100644 modules/local/software/deepvariant/main.nf create mode 100644 modules/local/software/samtools/faidx/functions.nf create mode 100644 modules/local/software/samtools/faidx/main.nf diff --git a/conf/base.config b/conf/base.config index f523a6f..cacd2f1 100644 --- a/conf/base.config +++ b/conf/base.config @@ -11,8 +11,7 @@ process { - // TODO nf-core: Check the defaults for all processes - cpus = { check_max( 1 * task.attempt, 'cpus' ) } + cpus = { check_max( 2 * task.attempt, 'cpus' ) } memory = { check_max( 6.GB * task.attempt, 'memory' ) } time = { check_max( 4.h * task.attempt, 'time' ) } @@ -21,25 +20,20 @@ process { maxErrors = '-1' // Process-specific resource requirements - // NOTE - Please try and re-use the labels below as much as possible. - // These labels are used and recognised by default in DSL2 files hosted on nf-core/modules. - // If possible, it would be nice to keep the same label naming convention when - // adding in your local modules too. - // TODO nf-core: Customise requirements for specific processes. // See https://www.nextflow.io/docs/latest/config.html#config-process-selectors withLabel:process_low { cpus = { check_max( 2 * task.attempt, 'cpus' ) } - memory = { check_max( 12.GB * task.attempt, 'memory' ) } + memory = { check_max( 8.GB * task.attempt, 'memory' ) } time = { check_max( 4.h * task.attempt, 'time' ) } } withLabel:process_medium { cpus = { check_max( 6 * task.attempt, 'cpus' ) } - memory = { check_max( 36.GB * task.attempt, 'memory' ) } + memory = { check_max( 12.GB * task.attempt, 'memory' ) } time = { check_max( 8.h * task.attempt, 'time' ) } } withLabel:process_high { - cpus = { check_max( 12 * task.attempt, 'cpus' ) } - memory = { check_max( 72.GB * task.attempt, 'memory' ) } + cpus = { check_max( 16 * task.attempt, 'cpus' ) } + memory = { check_max( 16.GB * task.attempt, 'memory' ) } time = { check_max( 16.h * task.attempt, 'time' ) } } withLabel:process_long { @@ -51,5 +45,5 @@ process { withLabel:error_retry { errorStrategy = 'retry' maxRetries = 2 - } + } } diff --git a/main.nf b/main.nf index 57de4b7..8c205be 100644 --- a/main.nf +++ b/main.nf @@ -15,21 +15,12 @@ nextflow.preview.dsl = 2 * Print help message if required */ if (params.help) { - // TODO nf-core: Update typical command used to run pipeline def command = "nextflow run nf-core/deepvariant --input samplesheet.csv -profile docker" log.info Headers.nf_core(workflow, params.monochrome_logs) log.info Schema.params_help("$baseDir/nextflow_schema.json", command) exit 0 } -/* - * Stage config files - */ -ch_multiqc_config = file("$baseDir/assets/multiqc_config.yaml", checkIfExists: true) -ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath(params.multiqc_config, checkIfExists: true) : Channel.empty() -ch_output_docs = file("$projectDir/docs/output.md", checkIfExists: true) -ch_output_docs_images = file("$projectDir/docs/images/", checkIfExists: true) - /* * Validate parameters */ @@ -38,12 +29,6 @@ if (params.input) { ch_input = file(params.input, checkIfExists: true) } else { /* * Reference genomes */ -// TODO nf-core: Add any reference files that are needed -// NOTE - FOR SIMPLICITY THIS IS NOT USED IN THIS PIPELINE -// EXAMPLE ONLY TO DEMONSTRATE USAGE OF AWS IGENOMES -if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) { - exit 1, "The provided genome '${params.genome}' is not available in the iGenomes file. Currently the available genomes are ${params.genomes.keySet().join(", ")}" -} params.fasta = params.genomes[params.genome]?.fasta if (params.fasta) { ch_fasta = file(params.fasta, checkIfExists: true) } @@ -74,14 +59,8 @@ ch_workflow_summary = Channel.value(workflow_summary) * Include local pipeline modules */ include { OUTPUT_DOCUMENTATION } from './modules/local/output_documentation' params(params) -include { GET_SOFTWARE_VERSIONS } from './modules/local/get_software_versions' params(params) include { CHECK_SAMPLESHEET; check_samplesheet_paths } from './modules/local/check_samplesheet' params(params) -/* - * Include nf-core modules - */ -include { FASTQC } from './modules/nf-core/fastqc' params(params) -include { MULTIQC } from './modules/nf-core/multiqc' params(params) /* * Run the workflow @@ -93,20 +72,6 @@ workflow { .map { check_samplesheet_paths(it) } .set { ch_raw_reads } - FASTQC(ch_raw_reads) - - OUTPUT_DOCUMENTATION( - ch_output_docs, - ch_output_docs_images) - - GET_SOFTWARE_VERSIONS() - - MULTIQC( - ch_multiqc_config, - ch_multiqc_custom_config.collect().ifEmpty([]), - FASTQC.out.collect(), - GET_SOFTWARE_VERSIONS.out.yml.collect(), - ch_workflow_summary) } /* diff --git a/modules/local/software/bwa/index/functions.nf b/modules/local/software/bwa/index/functions.nf new file mode 100644 index 0000000..d25eea8 --- /dev/null +++ b/modules/local/software/bwa/index/functions.nf @@ -0,0 +1,59 @@ +/* + * ----------------------------------------------------- + * Utility functions used in nf-core DSL2 module files + * ----------------------------------------------------- + */ + +/* + * Extract name of software tool from process name using $task.process + */ +def getSoftwareName(task_process) { + return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() +} + +/* + * Function to initialise default values and to generate a Groovy Map of available options for nf-core modules + */ +def initOptions(Map args) { + def Map options = [:] + options.args = args.args ?: '' + options.args2 = args.args2 ?: '' + options.publish_by_id = args.publish_by_id ?: false + options.publish_dir = args.publish_dir ?: '' + options.publish_files = args.publish_files + options.suffix = args.suffix ?: '' + return options +} + +/* + * Tidy up and join elements of a list to return a path string + */ +def getPathFromList(path_list) { + def paths = path_list.findAll { item -> !item?.trim().isEmpty() } // Remove empty entries + paths = paths.collect { it.trim().replaceAll("^[/]+|[/]+\$", "") } // Trim whitespace and trailing slashes + return paths.join('/') +} + +/* + * Function to save/publish module results + */ +def saveFiles(Map args) { + if (!args.filename.endsWith('.version.txt')) { + def ioptions = initOptions(args.options) + def path_list = [ ioptions.publish_dir ?: args.publish_dir ] + if (ioptions.publish_by_id) { + path_list.add(args.publish_id) + } + if (ioptions.publish_files instanceof Map) { + for (ext in ioptions.publish_files) { + if (args.filename.endsWith(ext.key)) { + def ext_list = path_list.collect() + ext_list.add(ext.value) + return "${getPathFromList(ext_list)}/$args.filename" + } + } + } else if (ioptions.publish_files == null) { + return "${getPathFromList(path_list)}/$args.filename" + } + } +} diff --git a/modules/local/software/bwa/index/main.nf b/modules/local/software/bwa/index/main.nf new file mode 100644 index 0000000..3edc97a --- /dev/null +++ b/modules/local/software/bwa/index/main.nf @@ -0,0 +1,43 @@ +// Import generic module functions +include { initOptions; saveFiles; getSoftwareName } from './functions' + +params.options = [:] +def options = initOptions(params.options) + +process FASTQC { + tag "$meta.id" + label 'process_medium' + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:getSoftwareName(task.process), publish_id:meta.id) } + + conda (params.enable_conda ? "bioconda::fastqc=0.11.9" : null) + container "quay.io/biocontainers/fastqc:0.11.9--0" + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*.html"), emit: html + tuple val(meta), path("*.zip") , emit: zip + path "*.version.txt" , emit: version + + script: + // Add soft-links to original FastQs for consistent naming in pipeline + def software = getSoftwareName(task.process) + def prefix = options.suffix ? "${meta.id}.${options.suffix}" : "${meta.id}" + if (meta.single_end) { + """ + [ ! -f ${prefix}.fastq.gz ] && ln -s $reads ${prefix}.fastq.gz + fastqc $options.args --threads $task.cpus ${prefix}.fastq.gz + fastqc --version | sed -e "s/FastQC v//g" > ${software}.version.txt + """ + } else { + """ + [ ! -f ${prefix}_1.fastq.gz ] && ln -s ${reads[0]} ${prefix}_1.fastq.gz + [ ! -f ${prefix}_2.fastq.gz ] && ln -s ${reads[1]} ${prefix}_2.fastq.gz + fastqc $options.args --threads $task.cpus ${prefix}_1.fastq.gz ${prefix}_2.fastq.gz + fastqc --version | sed -e "s/FastQC v//g" > ${software}.version.txt + """ + } +} diff --git a/modules/local/software/bwa/mem/functions.nf b/modules/local/software/bwa/mem/functions.nf new file mode 100644 index 0000000..d25eea8 --- /dev/null +++ b/modules/local/software/bwa/mem/functions.nf @@ -0,0 +1,59 @@ +/* + * ----------------------------------------------------- + * Utility functions used in nf-core DSL2 module files + * ----------------------------------------------------- + */ + +/* + * Extract name of software tool from process name using $task.process + */ +def getSoftwareName(task_process) { + return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() +} + +/* + * Function to initialise default values and to generate a Groovy Map of available options for nf-core modules + */ +def initOptions(Map args) { + def Map options = [:] + options.args = args.args ?: '' + options.args2 = args.args2 ?: '' + options.publish_by_id = args.publish_by_id ?: false + options.publish_dir = args.publish_dir ?: '' + options.publish_files = args.publish_files + options.suffix = args.suffix ?: '' + return options +} + +/* + * Tidy up and join elements of a list to return a path string + */ +def getPathFromList(path_list) { + def paths = path_list.findAll { item -> !item?.trim().isEmpty() } // Remove empty entries + paths = paths.collect { it.trim().replaceAll("^[/]+|[/]+\$", "") } // Trim whitespace and trailing slashes + return paths.join('/') +} + +/* + * Function to save/publish module results + */ +def saveFiles(Map args) { + if (!args.filename.endsWith('.version.txt')) { + def ioptions = initOptions(args.options) + def path_list = [ ioptions.publish_dir ?: args.publish_dir ] + if (ioptions.publish_by_id) { + path_list.add(args.publish_id) + } + if (ioptions.publish_files instanceof Map) { + for (ext in ioptions.publish_files) { + if (args.filename.endsWith(ext.key)) { + def ext_list = path_list.collect() + ext_list.add(ext.value) + return "${getPathFromList(ext_list)}/$args.filename" + } + } + } else if (ioptions.publish_files == null) { + return "${getPathFromList(path_list)}/$args.filename" + } + } +} diff --git a/modules/local/software/bwa/mem/main.nf b/modules/local/software/bwa/mem/main.nf new file mode 100644 index 0000000..3edc97a --- /dev/null +++ b/modules/local/software/bwa/mem/main.nf @@ -0,0 +1,43 @@ +// Import generic module functions +include { initOptions; saveFiles; getSoftwareName } from './functions' + +params.options = [:] +def options = initOptions(params.options) + +process FASTQC { + tag "$meta.id" + label 'process_medium' + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:getSoftwareName(task.process), publish_id:meta.id) } + + conda (params.enable_conda ? "bioconda::fastqc=0.11.9" : null) + container "quay.io/biocontainers/fastqc:0.11.9--0" + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*.html"), emit: html + tuple val(meta), path("*.zip") , emit: zip + path "*.version.txt" , emit: version + + script: + // Add soft-links to original FastQs for consistent naming in pipeline + def software = getSoftwareName(task.process) + def prefix = options.suffix ? "${meta.id}.${options.suffix}" : "${meta.id}" + if (meta.single_end) { + """ + [ ! -f ${prefix}.fastq.gz ] && ln -s $reads ${prefix}.fastq.gz + fastqc $options.args --threads $task.cpus ${prefix}.fastq.gz + fastqc --version | sed -e "s/FastQC v//g" > ${software}.version.txt + """ + } else { + """ + [ ! -f ${prefix}_1.fastq.gz ] && ln -s ${reads[0]} ${prefix}_1.fastq.gz + [ ! -f ${prefix}_2.fastq.gz ] && ln -s ${reads[1]} ${prefix}_2.fastq.gz + fastqc $options.args --threads $task.cpus ${prefix}_1.fastq.gz ${prefix}_2.fastq.gz + fastqc --version | sed -e "s/FastQC v//g" > ${software}.version.txt + """ + } +} diff --git a/modules/local/software/deepvariant/functions.nf b/modules/local/software/deepvariant/functions.nf new file mode 100644 index 0000000..d25eea8 --- /dev/null +++ b/modules/local/software/deepvariant/functions.nf @@ -0,0 +1,59 @@ +/* + * ----------------------------------------------------- + * Utility functions used in nf-core DSL2 module files + * ----------------------------------------------------- + */ + +/* + * Extract name of software tool from process name using $task.process + */ +def getSoftwareName(task_process) { + return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() +} + +/* + * Function to initialise default values and to generate a Groovy Map of available options for nf-core modules + */ +def initOptions(Map args) { + def Map options = [:] + options.args = args.args ?: '' + options.args2 = args.args2 ?: '' + options.publish_by_id = args.publish_by_id ?: false + options.publish_dir = args.publish_dir ?: '' + options.publish_files = args.publish_files + options.suffix = args.suffix ?: '' + return options +} + +/* + * Tidy up and join elements of a list to return a path string + */ +def getPathFromList(path_list) { + def paths = path_list.findAll { item -> !item?.trim().isEmpty() } // Remove empty entries + paths = paths.collect { it.trim().replaceAll("^[/]+|[/]+\$", "") } // Trim whitespace and trailing slashes + return paths.join('/') +} + +/* + * Function to save/publish module results + */ +def saveFiles(Map args) { + if (!args.filename.endsWith('.version.txt')) { + def ioptions = initOptions(args.options) + def path_list = [ ioptions.publish_dir ?: args.publish_dir ] + if (ioptions.publish_by_id) { + path_list.add(args.publish_id) + } + if (ioptions.publish_files instanceof Map) { + for (ext in ioptions.publish_files) { + if (args.filename.endsWith(ext.key)) { + def ext_list = path_list.collect() + ext_list.add(ext.value) + return "${getPathFromList(ext_list)}/$args.filename" + } + } + } else if (ioptions.publish_files == null) { + return "${getPathFromList(path_list)}/$args.filename" + } + } +} diff --git a/modules/local/software/deepvariant/main.nf b/modules/local/software/deepvariant/main.nf new file mode 100644 index 0000000..a7b5790 --- /dev/null +++ b/modules/local/software/deepvariant/main.nf @@ -0,0 +1,41 @@ +// Import generic module functions +include { initOptions; saveFiles; getSoftwareName } from './functions' + +params.options = [:] +def options = initOptions(params.options) + +process DEEP_VARIANT { + tag "$meta.id" + label 'process_high' + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename: filename, options: params.options, publish_dir: getSoftwareName(task.process), publish_id: meta.id) } + + conda(params.enable_conda ? "bioconda::deepvariant=1.0.0" : null) + container "google/deepvariant:1.0.0" + + input: + tuple val(meta), val(sample_name), path(bam), path(bai) + tuple val(regions), val(model_type) + tuple path(ref_fasta), path(ref_fasta_fai) + + output: + tuple val(meta), path("${sample_name}.vcf.gz"), path("${sample_name}.vcf.gz.tbi"), emit: vcf + tuple val(meta), path("${sample_name}.g.vcf.gz"), path("${sample_name}.g.vcf.gz.tbi"), emit: gvcf + tuple val(meta), path("*html"), emit: report + + script: + + """ + + /opt/deepvariant/bin/run_deepvariant \ + --model_type ${model_type} \ + --ref ${ref_fasta} \ + --reads ${chr_bam} \ + --output_vcf ${sample_name}.vcf.gz \ + --output_gvcf ${sample_name}.g.vcf.gz \ + --num_shards ${task.cpus} \ + --regions ${regions} + + """ +} diff --git a/modules/local/software/samtools/faidx/functions.nf b/modules/local/software/samtools/faidx/functions.nf new file mode 100644 index 0000000..d25eea8 --- /dev/null +++ b/modules/local/software/samtools/faidx/functions.nf @@ -0,0 +1,59 @@ +/* + * ----------------------------------------------------- + * Utility functions used in nf-core DSL2 module files + * ----------------------------------------------------- + */ + +/* + * Extract name of software tool from process name using $task.process + */ +def getSoftwareName(task_process) { + return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() +} + +/* + * Function to initialise default values and to generate a Groovy Map of available options for nf-core modules + */ +def initOptions(Map args) { + def Map options = [:] + options.args = args.args ?: '' + options.args2 = args.args2 ?: '' + options.publish_by_id = args.publish_by_id ?: false + options.publish_dir = args.publish_dir ?: '' + options.publish_files = args.publish_files + options.suffix = args.suffix ?: '' + return options +} + +/* + * Tidy up and join elements of a list to return a path string + */ +def getPathFromList(path_list) { + def paths = path_list.findAll { item -> !item?.trim().isEmpty() } // Remove empty entries + paths = paths.collect { it.trim().replaceAll("^[/]+|[/]+\$", "") } // Trim whitespace and trailing slashes + return paths.join('/') +} + +/* + * Function to save/publish module results + */ +def saveFiles(Map args) { + if (!args.filename.endsWith('.version.txt')) { + def ioptions = initOptions(args.options) + def path_list = [ ioptions.publish_dir ?: args.publish_dir ] + if (ioptions.publish_by_id) { + path_list.add(args.publish_id) + } + if (ioptions.publish_files instanceof Map) { + for (ext in ioptions.publish_files) { + if (args.filename.endsWith(ext.key)) { + def ext_list = path_list.collect() + ext_list.add(ext.value) + return "${getPathFromList(ext_list)}/$args.filename" + } + } + } else if (ioptions.publish_files == null) { + return "${getPathFromList(path_list)}/$args.filename" + } + } +} diff --git a/modules/local/software/samtools/faidx/main.nf b/modules/local/software/samtools/faidx/main.nf new file mode 100644 index 0000000..d754e29 --- /dev/null +++ b/modules/local/software/samtools/faidx/main.nf @@ -0,0 +1,32 @@ +// Import generic module functions +include { saveFiles; getSoftwareName } from './functions' + +params.options = [:] + +process SAMTOOLS_FAIDX { + tag "$meta.id" + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename: filename, options: params.options, publish_dir: getSoftwareName(task.process), publish_id: meta.id) } + + conda(params.enable_conda ? "bioconda::samtools=1.10" : null) + if (workflow.containerEngine == 'singularity' && !params.pull_docker_container) { + container "https://depot.galaxyproject.org/singularity/samtools:1.10--h9402c20_2" + } else { + container "quay.io/biocontainers/samtools:1.10--h9402c20_2" + } + + input: + tuple val(meta), path(bam) + + output: + tuple val(meta), path("*fasta*"), emit: fasta_and_fai + path "*.version.txt", emit: version + + script: + def software = getSoftwareName(task.process) + """ + samtools faidx $fasta + echo \$(samtools --version 2>&1) | sed 's/^.*samtools //; s/Using.*\$//' > ${software}.version.txt + """ +}