├── .prettierrc.yml
├── modules
├── nf-core
│ ├── fastqc
│ │ ├── tests
│ │ │ ├── tags.yml
│ │ │ ├── main.nf.test
│ │ │ └── main.nf.test.snap
│ │ ├── environment.yml
│ │ ├── meta.yml
│ │ └── main.nf
│ └── multiqc
│ │ ├── tests
│ │ ├── tags.yml
│ │ ├── nextflow.config
│ │ ├── main.nf.test.snap
│ │ └── main.nf.test
│ │ ├── environment.yml
│ │ ├── main.nf
│ │ └── meta.yml
└── local
│ ├── dragen_buildhashtable.nf
│ └── dragen.nf
├── .gitignore
├── docs
├── images
│ ├── tower_ce_enable_dragen.png
│ ├── tower_pipeline_secrets.png
│ ├── tower_secrets_dragen_password.png
│ └── tower_secrets_dragen_username.png
└── usage.md
├── .prettierignore
├── subworkflows
├── nf-core
│ ├── utils_nfcore_pipeline
│ │ ├── tests
│ │ │ ├── tags.yml
│ │ │ ├── nextflow.config
│ │ │ ├── main.workflow.nf.test.snap
│ │ │ ├── main.workflow.nf.test
│ │ │ ├── main.function.nf.test
│ │ │ └── main.function.nf.test.snap
│ │ ├── meta.yml
│ │ └── main.nf
│ ├── utils_nextflow_pipeline
│ │ ├── tests
│ │ │ ├── tags.yml
│ │ │ ├── nextflow.config
│ │ │ ├── main.function.nf.test.snap
│ │ │ ├── main.function.nf.test
│ │ │ └── main.workflow.nf.test
│ │ ├── meta.yml
│ │ └── main.nf
│ └── utils_nfschema_plugin
│ │ ├── tests
│ │ ├── nextflow.config
│ │ ├── main.nf.test
│ │ └── nextflow_schema.json
│ │ ├── meta.yml
│ │ └── main.nf
└── local
│ └── utils_nfcore_dragen_pipeline
│ └── main.nf
├── .gitattributes
├── tower.yml
├── .github
├── .dockstore.yml
├── ISSUE_TEMPLATE
│ ├── feature_request.yml
│ └── bug_report.yml
├── PULL_REQUEST_TEMPLATE.md
└── CONTRIBUTING.md
├── assets
├── samplesheet.csv
├── multiqc_config.yml
└── schema_input.json
├── .pre-commit-config.yaml
├── conf
├── igenomes_ignored.config
├── test_full.config
├── test.config
├── base.config
└── modules.config
├── tests
└── data
│ └── samplesheets
│ └── samplesheet_test_illumina_amplicon.csv
├── CHANGELOG.md
├── .editorconfig
├── modules.json
├── .nf-core.yml
├── workflows
└── dragen.nf
├── README.md
├── main.nf
├── nextflow.config
├── nextflow_schema.json
└── LICENSE
/.prettierrc.yml:
--------------------------------------------------------------------------------
1 | printWidth: 120
2 |
--------------------------------------------------------------------------------
/modules/nf-core/fastqc/tests/tags.yml:
--------------------------------------------------------------------------------
1 | fastqc:
2 | - modules/nf-core/fastqc/**
3 |
--------------------------------------------------------------------------------
/modules/nf-core/multiqc/tests/tags.yml:
--------------------------------------------------------------------------------
1 | multiqc:
2 | - modules/nf-core/multiqc/**
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .nextflow*
2 | work/
3 | data/
4 | results/
5 | .DS_Store
6 | testing/
7 | testing*
8 | *.pyc
9 | null/
10 |
--------------------------------------------------------------------------------
/docs/images/tower_ce_enable_dragen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seqeralabs/nf-dragen/HEAD/docs/images/tower_ce_enable_dragen.png
--------------------------------------------------------------------------------
/docs/images/tower_pipeline_secrets.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seqeralabs/nf-dragen/HEAD/docs/images/tower_pipeline_secrets.png
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 |
2 | .nextflow*
3 | work/
4 | data/
5 | results/
6 | .DS_Store
7 | testing/
8 | testing*
9 | *.pyc
10 | bin/
11 |
--------------------------------------------------------------------------------
/modules/nf-core/multiqc/tests/nextflow.config:
--------------------------------------------------------------------------------
1 | process {
2 | withName: 'MULTIQC' {
3 | ext.prefix = null
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/modules/nf-core/fastqc/environment.yml:
--------------------------------------------------------------------------------
1 | channels:
2 | - conda-forge
3 | - bioconda
4 | dependencies:
5 | - bioconda::fastqc=0.12.1
6 |
--------------------------------------------------------------------------------
/modules/nf-core/multiqc/environment.yml:
--------------------------------------------------------------------------------
1 | channels:
2 | - conda-forge
3 | - bioconda
4 | dependencies:
5 | - bioconda::multiqc=1.25.1
6 |
--------------------------------------------------------------------------------
/docs/images/tower_secrets_dragen_password.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seqeralabs/nf-dragen/HEAD/docs/images/tower_secrets_dragen_password.png
--------------------------------------------------------------------------------
/docs/images/tower_secrets_dragen_username.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seqeralabs/nf-dragen/HEAD/docs/images/tower_secrets_dragen_username.png
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfcore_pipeline/tests/tags.yml:
--------------------------------------------------------------------------------
1 | subworkflows/utils_nfcore_pipeline:
2 | - subworkflows/nf-core/utils_nfcore_pipeline/**
3 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nextflow_pipeline/tests/tags.yml:
--------------------------------------------------------------------------------
1 | subworkflows/utils_nextflow_pipeline:
2 | - subworkflows/nf-core/utils_nextflow_pipeline/**
3 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.config linguist-language=nextflow
2 | *.nf.test linguist-language=nextflow
3 | modules/nf-core/** linguist-generated
4 | subworkflows/nf-core/** linguist-generated
5 |
--------------------------------------------------------------------------------
/tower.yml:
--------------------------------------------------------------------------------
1 | reports:
2 | multiqc_report.html:
3 | display: "MultiQC HTML report"
4 | samplesheet.csv:
5 | display: "Auto-created samplesheet with collated metadata and FASTQ paths"
6 |
--------------------------------------------------------------------------------
/.github/.dockstore.yml:
--------------------------------------------------------------------------------
1 | # Dockstore config version, not pipeline version
2 | version: 1.2
3 | workflows:
4 | - subclass: nfl
5 | primaryDescriptorPath: /nextflow.config
6 | publish: True
7 |
--------------------------------------------------------------------------------
/assets/samplesheet.csv:
--------------------------------------------------------------------------------
1 | sample,fastq_1,fastq_2
2 | SAMPLE_PAIRED_END,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz
3 | SAMPLE_SINGLE_END,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz,
4 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config:
--------------------------------------------------------------------------------
1 | plugins {
2 | id "nf-schema@2.1.0"
3 | }
4 |
5 | validation {
6 | parametersSchema = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json"
7 | monochromeLogs = true
8 | }
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config:
--------------------------------------------------------------------------------
1 | manifest {
2 | name = 'nextflow_workflow'
3 | author = """nf-core"""
4 | homePage = 'https://127.0.0.1'
5 | description = """Dummy pipeline"""
6 | nextflowVersion = '!>=23.04.0'
7 | version = '9.9.9'
8 | doi = 'https://doi.org/10.5281/zenodo.5070524'
9 | }
10 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config:
--------------------------------------------------------------------------------
1 | manifest {
2 | name = 'nextflow_workflow'
3 | author = """nf-core"""
4 | homePage = 'https://127.0.0.1'
5 | description = """Dummy pipeline"""
6 | nextflowVersion = '!>=23.04.0'
7 | version = '9.9.9'
8 | doi = 'https://doi.org/10.5281/zenodo.5070524'
9 | }
10 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/pre-commit/mirrors-prettier
3 | rev: "v3.1.0"
4 | hooks:
5 | - id: prettier
6 | additional_dependencies:
7 | - prettier@3.2.5
8 |
9 | - repo: https://github.com/editorconfig-checker/editorconfig-checker.python
10 | rev: "3.0.3"
11 | hooks:
12 | - id: editorconfig-checker
13 | alias: ec
14 |
--------------------------------------------------------------------------------
/conf/igenomes_ignored.config:
--------------------------------------------------------------------------------
1 | /*
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 | Nextflow config file for iGenomes paths
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | Empty genomes dictionary to use when igenomes is ignored.
6 | ----------------------------------------------------------------------------------------
7 | */
8 |
9 | params.genomes = [:]
10 |
--------------------------------------------------------------------------------
/assets/multiqc_config.yml:
--------------------------------------------------------------------------------
1 | report_comment: >
2 | This report has been generated by the seqeralabs/dragen
3 | analysis pipeline.
4 | report_section_order:
5 | "seqeralabs-dragen-methods-description":
6 | order: -1000
7 | software_versions:
8 | order: -1001
9 | "seqeralabs-nf-dragen-summary":
10 | order: -1002
11 |
12 | export_plots: true
13 |
14 | disable_version_detection: true
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
1 | name: Feature request
2 | description: Suggest an idea for the seqeralabs/nf-dragen pipeline
3 | labels: enhancement
4 | body:
5 | - type: textarea
6 | id: description
7 | attributes:
8 | label: Description of feature
9 | description: Please describe your suggestion for a new feature. It might help to describe a problem or use case, plus any alternatives that you have considered.
10 | validations:
11 | required: true
12 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test.snap:
--------------------------------------------------------------------------------
1 | {
2 | "Should run without failures": {
3 | "content": [
4 | {
5 | "0": [
6 | true
7 | ],
8 | "valid_config": [
9 | true
10 | ]
11 | }
12 | ],
13 | "meta": {
14 | "nf-test": "0.8.4",
15 | "nextflow": "23.10.1"
16 | },
17 | "timestamp": "2024-02-28T12:03:25.726491"
18 | }
19 | }
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test.snap:
--------------------------------------------------------------------------------
1 | {
2 | "Test Function getWorkflowVersion": {
3 | "content": [
4 | "v9.9.9"
5 | ],
6 | "meta": {
7 | "nf-test": "0.8.4",
8 | "nextflow": "23.10.1"
9 | },
10 | "timestamp": "2024-02-28T12:02:05.308243"
11 | },
12 | "Test Function checkCondaChannels": {
13 | "content": null,
14 | "meta": {
15 | "nf-test": "0.8.4",
16 | "nextflow": "23.10.1"
17 | },
18 | "timestamp": "2024-02-28T12:02:12.425833"
19 | }
20 | }
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfcore_pipeline/meta.yml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json
2 | name: "UTILS_NFCORE_PIPELINE"
3 | description: Subworkflow with utility functions specific to the nf-core pipeline template
4 | keywords:
5 | - utility
6 | - pipeline
7 | - initialise
8 | - version
9 | components: []
10 | input:
11 | - nextflow_cli_args:
12 | type: list
13 | description: |
14 | Nextflow CLI positional arguments
15 | output:
16 | - success:
17 | type: boolean
18 | description: |
19 | Dummy output to indicate success
20 | authors:
21 | - "@adamrtalbot"
22 | maintainers:
23 | - "@adamrtalbot"
24 | - "@maxulysse"
25 |
--------------------------------------------------------------------------------
/tests/data/samplesheets/samplesheet_test_illumina_amplicon.csv:
--------------------------------------------------------------------------------
1 | sample,fastq_1,fastq_2
2 | SAMPLE1_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R2.fastq.gz
3 | SAMPLE2_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R2.fastq.gz
4 | SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz,
5 | SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz,
6 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # seqeralabs/nf-dragen: Changelog
2 |
3 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
4 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5 |
6 | ## v1.0dev - [date]
7 |
8 | Initial release of seqeralabs/nf-dragen, created with the [nf-core](https://nf-co.re/) template.
9 |
10 | ### `Added`
11 |
12 | - (10)[https://github.com/seqeralabs/nf-dragen/pull/10] - Use nf-core template v3.1.1
13 |
14 | ### `Fixed`
15 |
16 | - Fixed error `Access to 'FASTQC.out' is undefined since the workflow 'FASTQC' has not been invoked before accessing the output attribute` when `-skip_fastqc` enabled by adjusting channel generation
17 |
18 | ### `Dependencies`
19 |
20 | ### `Deprecated`
21 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.workflow.nf.test:
--------------------------------------------------------------------------------
1 | nextflow_workflow {
2 |
3 | name "Test Workflow UTILS_NFCORE_PIPELINE"
4 | script "../main.nf"
5 | config "subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config"
6 | workflow "UTILS_NFCORE_PIPELINE"
7 | tag "subworkflows"
8 | tag "subworkflows_nfcore"
9 | tag "utils_nfcore_pipeline"
10 | tag "subworkflows/utils_nfcore_pipeline"
11 |
12 | test("Should run without failures") {
13 |
14 | when {
15 | workflow {
16 | """
17 | input[0] = []
18 | """
19 | }
20 | }
21 |
22 | then {
23 | assertAll(
24 | { assert workflow.success },
25 | { assert snapshot(workflow.out).match() }
26 | )
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/conf/test_full.config:
--------------------------------------------------------------------------------
1 | /*
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 | Nextflow config file for running full-size tests
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | Defines input files and everything required to run a full size pipeline test.
6 |
7 | Use as follows:
8 | nextflow run seqeralabs/nf-dragen -profile test_full, --outdir
9 |
10 | ----------------------------------------------------------------------------------------
11 | */
12 |
13 | params {
14 | config_profile_name = 'Full test profile'
15 | config_profile_description = 'Full test dataset to check pipeline function'
16 |
17 | // Input data
18 | input = "${projectDir}/tests/data/samplesheets/samplesheet_test_illumina_amplicon.csv"
19 |
20 | // Genome references
21 | genome = 'R64-1-1'
22 | }
23 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
7 | trim_trailing_whitespace = true
8 | indent_size = 4
9 | indent_style = space
10 |
11 | [*.{md,yml,yaml,html,css,scss,js}]
12 | indent_size = 2
13 |
14 | # These files are edited and tested upstream in nf-core/modules
15 | [/modules/nf-core/**]
16 | charset = unset
17 | end_of_line = unset
18 | insert_final_newline = unset
19 | trim_trailing_whitespace = unset
20 | indent_style = unset
21 | [/subworkflows/nf-core/**]
22 | charset = unset
23 | end_of_line = unset
24 | insert_final_newline = unset
25 | trim_trailing_whitespace = unset
26 | indent_style = unset
27 |
28 | # ignore Readme
29 | [README.md]
30 | indent_style = unset
31 |
32 | # ignore python and markdown
33 | [*.{py,md}]
34 | indent_style = unset
35 |
36 | # ignore ro-crate metadata files
37 | [**/ro-crate-metadata.json]
38 | insert_final_newline = unset
39 |
40 | [LICENSE.txt]
41 | indent_style = unset
42 | trim_trailing_whitespace = unset
43 |
--------------------------------------------------------------------------------
/conf/test.config:
--------------------------------------------------------------------------------
1 | /*
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 | Nextflow config file for running minimal tests
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | Defines input files and everything required to run a fast and simple pipeline test.
6 |
7 | Use as follows:
8 | nextflow run seqeralabs/nf-dragen -profile test, --outdir
9 |
10 | ----------------------------------------------------------------------------------------
11 | */
12 |
13 | process {
14 | resourceLimits = [
15 | cpus: 8,
16 | memory: '96.GB',
17 | time: '4.h'
18 | ]
19 | }
20 |
21 | params {
22 | config_profile_name = 'Test profile'
23 | config_profile_description = 'Minimal test dataset to check pipeline function'
24 |
25 | // Input data
26 | input = "${projectDir}/tests/data/samplesheets/samplesheet_test_illumina_amplicon.csv"
27 |
28 | // Genome references
29 | genome = 'R64-1-1'
30 | }
31 |
--------------------------------------------------------------------------------
/modules/nf-core/multiqc/tests/main.nf.test.snap:
--------------------------------------------------------------------------------
1 | {
2 | "multiqc_versions_single": {
3 | "content": [
4 | [
5 | "versions.yml:md5,41f391dcedce7f93ca188f3a3ffa0916"
6 | ]
7 | ],
8 | "meta": {
9 | "nf-test": "0.9.0",
10 | "nextflow": "24.04.4"
11 | },
12 | "timestamp": "2024-10-02T17:51:46.317523"
13 | },
14 | "multiqc_stub": {
15 | "content": [
16 | [
17 | "multiqc_report.html",
18 | "multiqc_data",
19 | "multiqc_plots",
20 | "versions.yml:md5,41f391dcedce7f93ca188f3a3ffa0916"
21 | ]
22 | ],
23 | "meta": {
24 | "nf-test": "0.9.0",
25 | "nextflow": "24.04.4"
26 | },
27 | "timestamp": "2024-10-02T17:52:20.680978"
28 | },
29 | "multiqc_versions_config": {
30 | "content": [
31 | [
32 | "versions.yml:md5,41f391dcedce7f93ca188f3a3ffa0916"
33 | ]
34 | ],
35 | "meta": {
36 | "nf-test": "0.9.0",
37 | "nextflow": "24.04.4"
38 | },
39 | "timestamp": "2024-10-02T17:52:09.185842"
40 | }
41 | }
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nextflow_pipeline/meta.yml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json
2 | name: "UTILS_NEXTFLOW_PIPELINE"
3 | description: Subworkflow with functionality that may be useful for any Nextflow pipeline
4 | keywords:
5 | - utility
6 | - pipeline
7 | - initialise
8 | - version
9 | components: []
10 | input:
11 | - print_version:
12 | type: boolean
13 | description: |
14 | Print the version of the pipeline and exit
15 | - dump_parameters:
16 | type: boolean
17 | description: |
18 | Dump the parameters of the pipeline to a JSON file
19 | - output_directory:
20 | type: directory
21 | description: Path to output dir to write JSON file to.
22 | pattern: "results/"
23 | - check_conda_channel:
24 | type: boolean
25 | description: |
26 | Check if the conda channel priority is correct.
27 | output:
28 | - dummy_emit:
29 | type: boolean
30 | description: |
31 | Dummy emit to make nf-core subworkflows lint happy
32 | authors:
33 | - "@adamrtalbot"
34 | - "@drpatelh"
35 | maintainers:
36 | - "@adamrtalbot"
37 | - "@drpatelh"
38 | - "@maxulysse"
39 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfschema_plugin/meta.yml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json
2 | name: "utils_nfschema_plugin"
3 | description: Run nf-schema to validate parameters and create a summary of changed parameters
4 | keywords:
5 | - validation
6 | - JSON schema
7 | - plugin
8 | - parameters
9 | - summary
10 | components: []
11 | input:
12 | - input_workflow:
13 | type: object
14 | description: |
15 | The workflow object of the used pipeline.
16 | This object contains meta data used to create the params summary log
17 | - validate_params:
18 | type: boolean
19 | description: Validate the parameters and error if invalid.
20 | - parameters_schema:
21 | type: string
22 | description: |
23 | Path to the parameters JSON schema.
24 | This has to be the same as the schema given to the `validation.parametersSchema` config
25 | option. When this input is empty it will automatically use the configured schema or
26 | "${projectDir}/nextflow_schema.json" as default. The schema should not be given in this way
27 | for meta pipelines.
28 | output:
29 | - dummy_emit:
30 | type: boolean
31 | description: Dummy emit to make nf-core subworkflows lint happy
32 | authors:
33 | - "@nvnieuwk"
34 | maintainers:
35 | - "@nvnieuwk"
36 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
13 |
14 | ## PR checklist
15 |
16 | - [ ] This comment contains a description of changes (with reason).
17 | - [ ] If you've fixed a bug or added code that should be tested, add tests!
18 | - [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/seqeralabs/dragen/tree/master/.github/CONTRIBUTING.md)
19 | - [ ] Make sure your code lints (`nf-core pipelines lint`).
20 | - [ ] Ensure the test suite passes (`nextflow run . -profile test,docker --outdir `).
21 | - [ ] Check for unexpected warnings in debug mode (`nextflow run . -profile debug,test,docker --outdir `).
22 | - [ ] Usage Documentation in `docs/usage.md` is updated.
23 | - [ ] Output Documentation in `docs/output.md` is updated.
24 | - [ ] `CHANGELOG.md` is updated.
25 | - [ ] `README.md` is updated (including new tool citations and authors/contributors).
26 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.function.nf.test:
--------------------------------------------------------------------------------
1 |
2 | nextflow_function {
3 |
4 | name "Test Functions"
5 | script "subworkflows/nf-core/utils_nextflow_pipeline/main.nf"
6 | config "subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config"
7 | tag 'subworkflows'
8 | tag 'utils_nextflow_pipeline'
9 | tag 'subworkflows/utils_nextflow_pipeline'
10 |
11 | test("Test Function getWorkflowVersion") {
12 |
13 | function "getWorkflowVersion"
14 |
15 | then {
16 | assertAll(
17 | { assert function.success },
18 | { assert snapshot(function.result).match() }
19 | )
20 | }
21 | }
22 |
23 | test("Test Function dumpParametersToJSON") {
24 |
25 | function "dumpParametersToJSON"
26 |
27 | when {
28 | function {
29 | """
30 | // define inputs of the function here. Example:
31 | input[0] = "$outputDir"
32 | """.stripIndent()
33 | }
34 | }
35 |
36 | then {
37 | assertAll(
38 | { assert function.success }
39 | )
40 | }
41 | }
42 |
43 | test("Test Function checkCondaChannels") {
44 |
45 | function "checkCondaChannels"
46 |
47 | then {
48 | assertAll(
49 | { assert function.success },
50 | { assert snapshot(function.result).match() }
51 | )
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/modules/local/dragen_buildhashtable.nf:
--------------------------------------------------------------------------------
1 | process DRAGEN_BUILDHASHTABLE {
2 | tag "$fasta"
3 | label 'dragen'
4 |
5 | secret 'DRAGEN_USERNAME'
6 | secret 'DRAGEN_PASSWORD'
7 |
8 | input:
9 | path(fasta)
10 |
11 | output:
12 | path "$prefix" , emit: index
13 | path "versions.yml", emit: versions
14 |
15 | script:
16 | def args = task.ext.args ?: ''
17 | prefix = task.ext.prefix ?: 'dragen'
18 | """
19 | mkdir -p $prefix
20 |
21 | /opt/edico/bin/dragen \\
22 | --build-hash-table true \\
23 | --output-directory $prefix \\
24 | --ht-reference $fasta \\
25 | --lic-server=\$DRAGEN_USERNAME:\$DRAGEN_PASSWORD@license.edicogenome.com \\
26 | $args
27 |
28 | cat <<-END_VERSIONS > versions.yml
29 | "${task.process}":
30 | dragen: '\$(echo \$(/opt/edico/bin/dragen --version 2>&1) | sed -e "s/dragen Version //g")'
31 | END_VERSIONS
32 | """
33 |
34 | stub:
35 | def args = task.ext.args ?: ''
36 | prefix = task.ext.prefix ?: 'dragen'
37 | """
38 | mkdir -p $prefix
39 |
40 | echo /opt/edico/bin/dragen \\
41 | --build-hash-table true \\
42 | --output-directory $prefix \\
43 | --ht-reference $fasta \\
44 | --lic-server=\$DRAGEN_USERNAME:\$DRAGEN_PASSWORD@license.edicogenome.com \\
45 | $args
46 |
47 | touch ${prefix}/dragen.ht
48 | cat <<-END_VERSIONS > versions.yml
49 | "${task.process}":
50 | dragen: '\$(echo \$(/opt/edico/bin/dragen --version 2>&1) | sed -e "s/dragen Version //g")'
51 | END_VERSIONS
52 | """
53 | }
54 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | name: Bug report
2 | description: Report something that is broken or incorrect
3 | labels: bug
4 | body:
5 | - type: textarea
6 | id: description
7 | attributes:
8 | label: Description of the bug
9 | description: A clear and concise description of what the bug is.
10 | validations:
11 | required: true
12 |
13 | - type: textarea
14 | id: command_used
15 | attributes:
16 | label: Command used and terminal output
17 | description: Steps to reproduce the behaviour. Please paste the command you used to launch the pipeline and the output from your terminal.
18 | render: console
19 | placeholder: |
20 | $ nextflow run ...
21 |
22 | Some output where something broke
23 |
24 | - type: textarea
25 | id: files
26 | attributes:
27 | label: Relevant files
28 | description: |
29 | Please drag and drop the relevant files here. Create a `.zip` archive if the extension is not allowed.
30 | Your verbose log file `.nextflow.log` is often useful _(this is a hidden file in the directory where you launched the pipeline)_ as well as custom Nextflow configuration files.
31 |
32 | - type: textarea
33 | id: system
34 | attributes:
35 | label: System information
36 | description: |
37 | * Nextflow version _(eg. 23.04.0)_
38 | * Hardware _(eg. HPC, Desktop, Cloud)_
39 | * Executor _(eg. slurm, local, awsbatch)_
40 | * Container engine: _(e.g. Docker, Singularity, Conda, Podman, Shifter, Charliecloud, or Apptainer)_
41 | * OS _(eg. CentOS Linux, macOS, Linux Mint)_
42 | * Version of seqeralabs/dragen _(eg. 1.1, 1.5, 1.8.2)_
43 |
--------------------------------------------------------------------------------
/modules.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "seqeralabs/dragen",
3 | "homePage": "https://github.com/seqeralabs/dragen",
4 | "repos": {
5 | "https://github.com/nf-core/modules.git": {
6 | "modules": {
7 | "nf-core": {
8 | "fastqc": {
9 | "branch": "master",
10 | "git_sha": "dc94b6ee04a05ddb9f7ae050712ff30a13149164",
11 | "installed_by": ["modules"]
12 | },
13 | "multiqc": {
14 | "branch": "master",
15 | "git_sha": "cf17ca47590cc578dfb47db1c2a44ef86f89976d",
16 | "installed_by": ["modules"]
17 | }
18 | }
19 | },
20 | "subworkflows": {
21 | "nf-core": {
22 | "utils_nextflow_pipeline": {
23 | "branch": "master",
24 | "git_sha": "c2b22d85f30a706a3073387f30380704fcae013b",
25 | "installed_by": ["subworkflows"]
26 | },
27 | "utils_nfcore_pipeline": {
28 | "branch": "master",
29 | "git_sha": "51ae5406a030d4da1e49e4dab49756844fdd6c7a",
30 | "installed_by": ["subworkflows"]
31 | },
32 | "utils_nfschema_plugin": {
33 | "branch": "master",
34 | "git_sha": "2fd2cd6d0e7b273747f32e465fdc6bcc3ae0814e",
35 | "installed_by": ["subworkflows"]
36 | }
37 | }
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/assets/schema_input.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://raw.githubusercontent.com/seqeralabs/dragen/master/assets/schema_input.json",
4 | "title": "seqeralabs/dragen pipeline - params.input schema",
5 | "description": "Schema for the file provided with params.input",
6 | "type": "array",
7 | "items": {
8 | "type": "object",
9 | "properties": {
10 | "sample": {
11 | "type": "string",
12 | "pattern": "^\\S+$",
13 | "errorMessage": "Sample name must be provided and cannot contain spaces",
14 | "meta": ["id"]
15 | },
16 | "seq_type": {
17 | "type": "string",
18 | "enum": ["dna", "rna"],
19 | "errorMessage": "Type of sequencing data must be provided and must be either 'DNA' or 'RNA'",
20 | "meta": ["seq_type"]
21 | },
22 | "fastq_1": {
23 | "type": "string",
24 | "format": "file-path",
25 | "exists": true,
26 | "pattern": "^\\S+\\.f(ast)?q\\.gz$",
27 | "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'"
28 | },
29 | "fastq_2": {
30 | "type": "string",
31 | "format": "file-path",
32 | "exists": true,
33 | "pattern": "^\\S+\\.f(ast)?q\\.gz$",
34 | "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'"
35 | }
36 | },
37 | "required": ["sample", "fastq_1"]
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfschema_plugin/main.nf:
--------------------------------------------------------------------------------
1 | //
2 | // Subworkflow that uses the nf-schema plugin to validate parameters and render the parameter summary
3 | //
4 |
5 | include { paramsSummaryLog } from 'plugin/nf-schema'
6 | include { validateParameters } from 'plugin/nf-schema'
7 |
8 | workflow UTILS_NFSCHEMA_PLUGIN {
9 |
10 | take:
11 | input_workflow // workflow: the workflow object used by nf-schema to get metadata from the workflow
12 | validate_params // boolean: validate the parameters
13 | parameters_schema // string: path to the parameters JSON schema.
14 | // this has to be the same as the schema given to `validation.parametersSchema`
15 | // when this input is empty it will automatically use the configured schema or
16 | // "${projectDir}/nextflow_schema.json" as default. This input should not be empty
17 | // for meta pipelines
18 |
19 | main:
20 |
21 | //
22 | // Print parameter summary to stdout. This will display the parameters
23 | // that differ from the default given in the JSON schema
24 | //
25 | if(parameters_schema) {
26 | log.info paramsSummaryLog(input_workflow, parameters_schema:parameters_schema)
27 | } else {
28 | log.info paramsSummaryLog(input_workflow)
29 | }
30 |
31 | //
32 | // Validate the parameters using nextflow_schema.json or the schema
33 | // given via the validation.parametersSchema configuration option
34 | //
35 | if(validate_params) {
36 | if(parameters_schema) {
37 | validateParameters(parameters_schema:parameters_schema)
38 | } else {
39 | validateParameters()
40 | }
41 | }
42 |
43 | emit:
44 | dummy_emit = true
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/modules/nf-core/multiqc/main.nf:
--------------------------------------------------------------------------------
1 | process MULTIQC {
2 | label 'process_single'
3 |
4 | conda "${moduleDir}/environment.yml"
5 | container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
6 | 'https://depot.galaxyproject.org/singularity/multiqc:1.25.1--pyhdfd78af_0' :
7 | 'biocontainers/multiqc:1.25.1--pyhdfd78af_0' }"
8 |
9 | input:
10 | path multiqc_files, stageAs: "?/*"
11 | path(multiqc_config)
12 | path(extra_multiqc_config)
13 | path(multiqc_logo)
14 | path(replace_names)
15 | path(sample_names)
16 |
17 | output:
18 | path "*multiqc_report.html", emit: report
19 | path "*_data" , emit: data
20 | path "*_plots" , optional:true, emit: plots
21 | path "versions.yml" , emit: versions
22 |
23 | when:
24 | task.ext.when == null || task.ext.when
25 |
26 | script:
27 | def args = task.ext.args ?: ''
28 | def prefix = task.ext.prefix ? "--filename ${task.ext.prefix}.html" : ''
29 | def config = multiqc_config ? "--config $multiqc_config" : ''
30 | def extra_config = extra_multiqc_config ? "--config $extra_multiqc_config" : ''
31 | def logo = multiqc_logo ? "--cl-config 'custom_logo: \"${multiqc_logo}\"'" : ''
32 | def replace = replace_names ? "--replace-names ${replace_names}" : ''
33 | def samples = sample_names ? "--sample-names ${sample_names}" : ''
34 | """
35 | multiqc \\
36 | --force \\
37 | $args \\
38 | $config \\
39 | $prefix \\
40 | $extra_config \\
41 | $logo \\
42 | $replace \\
43 | $samples \\
44 | .
45 |
46 | cat <<-END_VERSIONS > versions.yml
47 | "${task.process}":
48 | multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" )
49 | END_VERSIONS
50 | """
51 |
52 | stub:
53 | """
54 | mkdir multiqc_data
55 | mkdir multiqc_plots
56 | touch multiqc_report.html
57 |
58 | cat <<-END_VERSIONS > versions.yml
59 | "${task.process}":
60 | multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" )
61 | END_VERSIONS
62 | """
63 | }
64 |
--------------------------------------------------------------------------------
/modules/nf-core/fastqc/meta.yml:
--------------------------------------------------------------------------------
1 | name: fastqc
2 | description: Run FastQC on sequenced reads
3 | keywords:
4 | - quality control
5 | - qc
6 | - adapters
7 | - fastq
8 | tools:
9 | - fastqc:
10 | description: |
11 | FastQC gives general quality metrics about your reads.
12 | It provides information about the quality score distribution
13 | across your reads, the per base sequence content (%A/C/G/T).
14 |
15 | You get information about adapter contamination and other
16 | overrepresented sequences.
17 | homepage: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/
18 | documentation: https://www.bioinformatics.babraham.ac.uk/projects/fastqc/Help/
19 | licence: ["GPL-2.0-only"]
20 | identifier: biotools:fastqc
21 | input:
22 | - - meta:
23 | type: map
24 | description: |
25 | Groovy Map containing sample information
26 | e.g. [ id:'test', single_end:false ]
27 | - reads:
28 | type: file
29 | description: |
30 | List of input FastQ files of size 1 and 2 for single-end and paired-end data,
31 | respectively.
32 | output:
33 | - html:
34 | - meta:
35 | type: map
36 | description: |
37 | Groovy Map containing sample information
38 | e.g. [ id:'test', single_end:false ]
39 | - "*.html":
40 | type: file
41 | description: FastQC report
42 | pattern: "*_{fastqc.html}"
43 | - zip:
44 | - meta:
45 | type: map
46 | description: |
47 | Groovy Map containing sample information
48 | e.g. [ id:'test', single_end:false ]
49 | - "*.zip":
50 | type: file
51 | description: FastQC report archive
52 | pattern: "*_{fastqc.zip}"
53 | - versions:
54 | - versions.yml:
55 | type: file
56 | description: File containing software versions
57 | pattern: "versions.yml"
58 | authors:
59 | - "@drpatelh"
60 | - "@grst"
61 | - "@ewels"
62 | - "@FelixKrueger"
63 | maintainers:
64 | - "@drpatelh"
65 | - "@grst"
66 | - "@ewels"
67 | - "@FelixKrueger"
68 |
--------------------------------------------------------------------------------
/conf/base.config:
--------------------------------------------------------------------------------
1 | /*
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 | seqeralabs/nf-dragen Nextflow base config file
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | A 'blank slate' config file, appropriate for general use on most high performance
6 | compute environments. Assumes that all software is installed and available on
7 | the PATH. Runs in `local` mode - all jobs will be run on the logged in environment.
8 | ----------------------------------------------------------------------------------------
9 | */
10 |
11 | process {
12 |
13 | // TODO nf-core: Check the defaults for all processes
14 | cpus = { 1 * task.attempt }
15 | memory = { 6.GB * task.attempt }
16 | time = { 4.h * task.attempt }
17 |
18 | errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' }
19 | maxRetries = 1
20 | maxErrors = '-1'
21 |
22 | // Process-specific resource requirements
23 | // See https://www.nextflow.io/docs/latest/config.html#config-process-selectors
24 | withLabel:'dragen' {
25 | cpus = 8
26 | memory = 96.GB
27 | time = 24.h
28 | }
29 | withLabel:process_single {
30 | cpus = { 1 }
31 | memory = { 6.GB * task.attempt }
32 | time = { 4.h * task.attempt }
33 | }
34 | withLabel:process_low {
35 | cpus = { 2 * task.attempt }
36 | memory = { 12.GB * task.attempt }
37 | time = { 4.h * task.attempt }
38 | }
39 | withLabel:process_medium {
40 | cpus = { 6 * task.attempt }
41 | memory = { 36.GB * task.attempt }
42 | time = { 8.h * task.attempt }
43 | }
44 | withLabel:process_high {
45 | cpus = { 12 * task.attempt }
46 | memory = { 72.GB * task.attempt }
47 | time = { 16.h * task.attempt }
48 | }
49 | withLabel:process_long {
50 | time = { 20.h * task.attempt }
51 | }
52 | withLabel:process_high_memory {
53 | memory = { 200.GB * task.attempt }
54 | }
55 | withLabel:error_ignore {
56 | errorStrategy = 'ignore'
57 | }
58 | withLabel:error_retry {
59 | errorStrategy = 'retry'
60 | maxRetries = 2
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/.nf-core.yml:
--------------------------------------------------------------------------------
1 | repository_type: pipeline
2 |
3 | nf_core_version: 3.1.1
4 |
5 | lint:
6 | files_exist:
7 | - .github/ISSUE_TEMPLATE/config.yml
8 | - .github/workflows/awsfulltest.yml
9 | - .github/workflows/awstest.yml
10 | - .github/workflows/branch.yml
11 | - .github/workflows/ci.yml
12 | - .github/workflows/linting_comment.yml
13 | - .github/workflows/linting.yml
14 | - assets/email_template.html
15 | - assets/email_template.txt
16 | - assets/nf-core-nf-dragen_logo_light.png
17 | - assets/sendmail_template.txt
18 | - CITATIONS.md
19 | - CODE_OF_CONDUCT.md
20 | - docs/images/nf-core-nf-dragen_logo_light.png
21 | - docs/images/nf-core-nf-dragen_logo_dark.png
22 | - docs/output.md
23 | - docs/README.md
24 | - docs/usage.md
25 | - ro-crate-metadata.json
26 | - LICENSE
27 | files_unchanged:
28 | - .github/CONTRIBUTING.md
29 | - .github/ISSUE_TEMPLATE/bug_report.yml
30 | - .github/ISSUE_TEMPLATE/feature_request.yml
31 | - .github/PULL_REQUEST_TEMPLATE.md
32 | - .prettierignore
33 | - assets/email_template.txt
34 | - assets/nf-core-nf_dragen_logo_light.png
35 | - CODE_OF_CONDUCT.md
36 | - docs/images/nf-core-nf_dragen_logo_dark.png
37 | - docs/images/nf-core-nf_dragen_logo_light.png
38 | - docs/README.md
39 | included_configs: false
40 | multiqc_config:
41 | - report_comment
42 | nextflow_config:
43 | - custom_config
44 | - manifest.homePage
45 | - manifest.name
46 | - params.custom_config_base
47 | - params.custom_config_version
48 | - process.cpus
49 | - process.memory
50 | - process.time
51 | - validation.help.afterText
52 | - validation.help.beforeText
53 | - validation.summary.afterText
54 | - validation.summary.beforeText
55 |
56 | template:
57 | author: Adam Talbot, Harshil Patel, Graham Wright
58 | description: nf-dragen is a simple, proof-of-concept Nextflow pipeline to run the
59 | Illumina DRAGEN licensed suite of tools.
60 | force: false
61 | is_nfcore: false
62 | name: dragen
63 | org: seqeralabs
64 | outdir: .
65 | skip_features:
66 | - ci
67 | - nf_core_configs
68 | - citations
69 | - gitpod
70 | - codespaces
71 | - email
72 | - adaptivecard
73 | - slackreport
74 | - documentation
75 | - rocrate
76 | - vscode
77 | version: 1.0.0dev
78 |
--------------------------------------------------------------------------------
/workflows/dragen.nf:
--------------------------------------------------------------------------------
1 | /*
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 | IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | */
6 |
7 | include { DRAGEN } from '../modules/local/dragen.nf'
8 | include { DRAGEN_BUILDHASHTABLE } from '../modules/local/dragen_buildhashtable.nf'
9 |
10 | include { paramsSummaryMap } from 'plugin/nf-schema'
11 | include { paramsSummaryMultiqc } from '../subworkflows/nf-core/utils_nfcore_pipeline'
12 | include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline'
13 |
14 | /*
15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16 | RUN MAIN WORKFLOW
17 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18 | */
19 |
20 | workflow DRAGEN_WORKFLOW {
21 |
22 | take:
23 | ch_input
24 | index
25 | fasta
26 |
27 | main:
28 | ch_versions = Channel.empty()
29 | if (!index) {
30 | ch_fasta = Channel.fromPath(fasta, checkIfExists: true, type: 'file')
31 | // Use combine to not run the process if ch_input is empty
32 | DRAGEN_BUILDHASHTABLE (
33 | ch_input.combine(ch_fasta).map { meta, fastq_1, fastq_2, _fasta -> _fasta }.first()
34 | )
35 | ch_index = DRAGEN_BUILDHASHTABLE.out.index
36 | ch_versions = ch_versions.mix(DRAGEN_BUILDHASHTABLE.out.versions)
37 | } else {
38 | ch_index = Channel.fromPath(index, checkIfExists: true, type: 'dir')
39 | }
40 |
41 | //
42 | // MODULE: Run DRAGEN on DNA samples to generate BAM from FastQ
43 | //
44 | DRAGEN (
45 | ch_input,
46 | ch_index.collect()
47 | )
48 | ch_versions = ch_versions.mix(DRAGEN.out.versions.first())
49 |
50 |
51 | emit:
52 | index = ch_index
53 | bam = DRAGEN.out.bam
54 | fastq = DRAGEN.out.fastq
55 | vcf = DRAGEN.out.vcf
56 | tbi = DRAGEN.out.tbi
57 | vcf_filtered = DRAGEN.out.vcf_filtered
58 | tbi_filtered = DRAGEN.out.tbi_filtered
59 | versions = DRAGEN.out.versions
60 | }
61 |
62 | /*
63 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
64 | THE END
65 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
66 | */
67 |
--------------------------------------------------------------------------------
/modules/nf-core/fastqc/main.nf:
--------------------------------------------------------------------------------
1 | process FASTQC {
2 | tag "$meta.id"
3 | label 'process_medium'
4 |
5 | conda "${moduleDir}/environment.yml"
6 | container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
7 | 'https://depot.galaxyproject.org/singularity/fastqc:0.12.1--hdfd78af_0' :
8 | 'biocontainers/fastqc:0.12.1--hdfd78af_0' }"
9 |
10 | input:
11 | tuple val(meta), path(reads)
12 |
13 | output:
14 | tuple val(meta), path("*.html"), emit: html
15 | tuple val(meta), path("*.zip") , emit: zip
16 | path "versions.yml" , emit: versions
17 |
18 | when:
19 | task.ext.when == null || task.ext.when
20 |
21 | script:
22 | def args = task.ext.args ?: ''
23 | def prefix = task.ext.prefix ?: "${meta.id}"
24 | // Make list of old name and new name pairs to use for renaming in the bash while loop
25 | def old_new_pairs = reads instanceof Path || reads.size() == 1 ? [[ reads, "${prefix}.${reads.extension}" ]] : reads.withIndex().collect { entry, index -> [ entry, "${prefix}_${index + 1}.${entry.extension}" ] }
26 | def rename_to = old_new_pairs*.join(' ').join(' ')
27 | def renamed_files = old_new_pairs.collect{ _old_name, new_name -> new_name }.join(' ')
28 |
29 | // The total amount of allocated RAM by FastQC is equal to the number of threads defined (--threads) time the amount of RAM defined (--memory)
30 | // https://github.com/s-andrews/FastQC/blob/1faeea0412093224d7f6a07f777fad60a5650795/fastqc#L211-L222
31 | // Dividing the task.memory by task.cpu allows to stick to requested amount of RAM in the label
32 | def memory_in_mb = MemoryUnit.of("${task.memory}").toUnit('MB') / task.cpus
33 | // FastQC memory value allowed range (100 - 10000)
34 | def fastqc_memory = memory_in_mb > 10000 ? 10000 : (memory_in_mb < 100 ? 100 : memory_in_mb)
35 |
36 | """
37 | printf "%s %s\\n" $rename_to | while read old_name new_name; do
38 | [ -f "\${new_name}" ] || ln -s \$old_name \$new_name
39 | done
40 |
41 | fastqc \\
42 | $args \\
43 | --threads $task.cpus \\
44 | --memory $fastqc_memory \\
45 | $renamed_files
46 |
47 | cat <<-END_VERSIONS > versions.yml
48 | "${task.process}":
49 | fastqc: \$( fastqc --version | sed '/FastQC v/!d; s/.*v//' )
50 | END_VERSIONS
51 | """
52 |
53 | stub:
54 | def prefix = task.ext.prefix ?: "${meta.id}"
55 | """
56 | touch ${prefix}.html
57 | touch ${prefix}.zip
58 |
59 | cat <<-END_VERSIONS > versions.yml
60 | "${task.process}":
61 | fastqc: \$( fastqc --version | sed '/FastQC v/!d; s/.*v//' )
62 | END_VERSIONS
63 | """
64 | }
65 |
--------------------------------------------------------------------------------
/modules/nf-core/multiqc/meta.yml:
--------------------------------------------------------------------------------
1 | name: multiqc
2 | description: Aggregate results from bioinformatics analyses across many samples into
3 | a single report
4 | keywords:
5 | - QC
6 | - bioinformatics tools
7 | - Beautiful stand-alone HTML report
8 | tools:
9 | - multiqc:
10 | description: |
11 | MultiQC searches a given directory for analysis logs and compiles a HTML report.
12 | It's a general use tool, perfect for summarising the output from numerous bioinformatics tools.
13 | homepage: https://multiqc.info/
14 | documentation: https://multiqc.info/docs/
15 | licence: ["GPL-3.0-or-later"]
16 | identifier: biotools:multiqc
17 | input:
18 | - - multiqc_files:
19 | type: file
20 | description: |
21 | List of reports / files recognised by MultiQC, for example the html and zip output of FastQC
22 | - - multiqc_config:
23 | type: file
24 | description: Optional config yml for MultiQC
25 | pattern: "*.{yml,yaml}"
26 | - - extra_multiqc_config:
27 | type: file
28 | description: Second optional config yml for MultiQC. Will override common sections
29 | in multiqc_config.
30 | pattern: "*.{yml,yaml}"
31 | - - multiqc_logo:
32 | type: file
33 | description: Optional logo file for MultiQC
34 | pattern: "*.{png}"
35 | - - replace_names:
36 | type: file
37 | description: |
38 | Optional two-column sample renaming file. First column a set of
39 | patterns, second column a set of corresponding replacements. Passed via
40 | MultiQC's `--replace-names` option.
41 | pattern: "*.{tsv}"
42 | - - sample_names:
43 | type: file
44 | description: |
45 | Optional TSV file with headers, passed to the MultiQC --sample_names
46 | argument.
47 | pattern: "*.{tsv}"
48 | output:
49 | - report:
50 | - "*multiqc_report.html":
51 | type: file
52 | description: MultiQC report file
53 | pattern: "multiqc_report.html"
54 | - data:
55 | - "*_data":
56 | type: directory
57 | description: MultiQC data dir
58 | pattern: "multiqc_data"
59 | - plots:
60 | - "*_plots":
61 | type: file
62 | description: Plots created by MultiQC
63 | pattern: "*_data"
64 | - versions:
65 | - versions.yml:
66 | type: file
67 | description: File containing software versions
68 | pattern: "versions.yml"
69 | authors:
70 | - "@abhi18av"
71 | - "@bunop"
72 | - "@drpatelh"
73 | - "@jfy133"
74 | maintainers:
75 | - "@abhi18av"
76 | - "@bunop"
77 | - "@drpatelh"
78 | - "@jfy133"
79 |
--------------------------------------------------------------------------------
/modules/nf-core/multiqc/tests/main.nf.test:
--------------------------------------------------------------------------------
1 | nextflow_process {
2 |
3 | name "Test Process MULTIQC"
4 | script "../main.nf"
5 | process "MULTIQC"
6 |
7 | tag "modules"
8 | tag "modules_nfcore"
9 | tag "multiqc"
10 |
11 | config "./nextflow.config"
12 |
13 | test("sarscov2 single-end [fastqc]") {
14 |
15 | when {
16 | process {
17 | """
18 | input[0] = Channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true))
19 | input[1] = []
20 | input[2] = []
21 | input[3] = []
22 | input[4] = []
23 | input[5] = []
24 | """
25 | }
26 | }
27 |
28 | then {
29 | assertAll(
30 | { assert process.success },
31 | { assert process.out.report[0] ==~ ".*/multiqc_report.html" },
32 | { assert process.out.data[0] ==~ ".*/multiqc_data" },
33 | { assert snapshot(process.out.versions).match("multiqc_versions_single") }
34 | )
35 | }
36 |
37 | }
38 |
39 | test("sarscov2 single-end [fastqc] [config]") {
40 |
41 | when {
42 | process {
43 | """
44 | input[0] = Channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true))
45 | input[1] = Channel.of(file("https://github.com/nf-core/tools/raw/dev/nf_core/pipeline-template/assets/multiqc_config.yml", checkIfExists: true))
46 | input[2] = []
47 | input[3] = []
48 | input[4] = []
49 | input[5] = []
50 | """
51 | }
52 | }
53 |
54 | then {
55 | assertAll(
56 | { assert process.success },
57 | { assert process.out.report[0] ==~ ".*/multiqc_report.html" },
58 | { assert process.out.data[0] ==~ ".*/multiqc_data" },
59 | { assert snapshot(process.out.versions).match("multiqc_versions_config") }
60 | )
61 | }
62 | }
63 |
64 | test("sarscov2 single-end [fastqc] - stub") {
65 |
66 | options "-stub"
67 |
68 | when {
69 | process {
70 | """
71 | input[0] = Channel.of(file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastqc/test_fastqc.zip', checkIfExists: true))
72 | input[1] = []
73 | input[2] = []
74 | input[3] = []
75 | input[4] = []
76 | input[5] = []
77 | """
78 | }
79 | }
80 |
81 | then {
82 | assertAll(
83 | { assert process.success },
84 | { assert snapshot(process.out.report.collect { file(it).getName() } +
85 | process.out.data.collect { file(it).getName() } +
86 | process.out.plots.collect { file(it).getName() } +
87 | process.out.versions ).match("multiqc_stub") }
88 | )
89 | }
90 |
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test:
--------------------------------------------------------------------------------
1 | nextflow_workflow {
2 |
3 | name "Test Subworkflow UTILS_NFSCHEMA_PLUGIN"
4 | script "../main.nf"
5 | workflow "UTILS_NFSCHEMA_PLUGIN"
6 |
7 | tag "subworkflows"
8 | tag "subworkflows_nfcore"
9 | tag "subworkflows/utils_nfschema_plugin"
10 | tag "plugin/nf-schema"
11 |
12 | config "./nextflow.config"
13 |
14 | test("Should run nothing") {
15 |
16 | when {
17 |
18 | params {
19 | test_data = ''
20 | }
21 |
22 | workflow {
23 | """
24 | validate_params = false
25 | input[0] = workflow
26 | input[1] = validate_params
27 | input[2] = ""
28 | """
29 | }
30 | }
31 |
32 | then {
33 | assertAll(
34 | { assert workflow.success }
35 | )
36 | }
37 | }
38 |
39 | test("Should validate params") {
40 |
41 | when {
42 |
43 | params {
44 | test_data = ''
45 | outdir = null
46 | }
47 |
48 | workflow {
49 | """
50 | validate_params = true
51 | input[0] = workflow
52 | input[1] = validate_params
53 | input[2] = ""
54 | """
55 | }
56 | }
57 |
58 | then {
59 | assertAll(
60 | { assert workflow.failed },
61 | { assert workflow.stdout.any { it.contains('ERROR ~ Validation of pipeline parameters failed!') } }
62 | )
63 | }
64 | }
65 |
66 | test("Should run nothing - custom schema") {
67 |
68 | when {
69 |
70 | params {
71 | test_data = ''
72 | }
73 |
74 | workflow {
75 | """
76 | validate_params = false
77 | input[0] = workflow
78 | input[1] = validate_params
79 | input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json"
80 | """
81 | }
82 | }
83 |
84 | then {
85 | assertAll(
86 | { assert workflow.success }
87 | )
88 | }
89 | }
90 |
91 | test("Should validate params - custom schema") {
92 |
93 | when {
94 |
95 | params {
96 | test_data = ''
97 | outdir = null
98 | }
99 |
100 | workflow {
101 | """
102 | validate_params = true
103 | input[0] = workflow
104 | input[1] = validate_params
105 | input[2] = "${projectDir}/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json"
106 | """
107 | }
108 | }
109 |
110 | then {
111 | assertAll(
112 | { assert workflow.failed },
113 | { assert workflow.stdout.any { it.contains('ERROR ~ Validation of pipeline parameters failed!') } }
114 | )
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nextflow_pipeline/tests/main.workflow.nf.test:
--------------------------------------------------------------------------------
1 | nextflow_workflow {
2 |
3 | name "Test Workflow UTILS_NEXTFLOW_PIPELINE"
4 | script "../main.nf"
5 | config "subworkflows/nf-core/utils_nextflow_pipeline/tests/nextflow.config"
6 | workflow "UTILS_NEXTFLOW_PIPELINE"
7 | tag 'subworkflows'
8 | tag 'utils_nextflow_pipeline'
9 | tag 'subworkflows/utils_nextflow_pipeline'
10 |
11 | test("Should run no inputs") {
12 |
13 | when {
14 | workflow {
15 | """
16 | print_version = false
17 | dump_parameters = false
18 | outdir = null
19 | check_conda_channels = false
20 |
21 | input[0] = print_version
22 | input[1] = dump_parameters
23 | input[2] = outdir
24 | input[3] = check_conda_channels
25 | """
26 | }
27 | }
28 |
29 | then {
30 | assertAll(
31 | { assert workflow.success }
32 | )
33 | }
34 | }
35 |
36 | test("Should print version") {
37 |
38 | when {
39 | workflow {
40 | """
41 | print_version = true
42 | dump_parameters = false
43 | outdir = null
44 | check_conda_channels = false
45 |
46 | input[0] = print_version
47 | input[1] = dump_parameters
48 | input[2] = outdir
49 | input[3] = check_conda_channels
50 | """
51 | }
52 | }
53 |
54 | then {
55 | expect {
56 | with(workflow) {
57 | assert success
58 | assert "nextflow_workflow v9.9.9" in stdout
59 | }
60 | }
61 | }
62 | }
63 |
64 | test("Should dump params") {
65 |
66 | when {
67 | workflow {
68 | """
69 | print_version = false
70 | dump_parameters = true
71 | outdir = 'results'
72 | check_conda_channels = false
73 |
74 | input[0] = false
75 | input[1] = true
76 | input[2] = outdir
77 | input[3] = false
78 | """
79 | }
80 | }
81 |
82 | then {
83 | assertAll(
84 | { assert workflow.success }
85 | )
86 | }
87 | }
88 |
89 | test("Should not create params JSON if no output directory") {
90 |
91 | when {
92 | workflow {
93 | """
94 | print_version = false
95 | dump_parameters = true
96 | outdir = null
97 | check_conda_channels = false
98 |
99 | input[0] = false
100 | input[1] = true
101 | input[2] = outdir
102 | input[3] = false
103 | """
104 | }
105 | }
106 |
107 | then {
108 | assertAll(
109 | { assert workflow.success }
110 | )
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/conf/modules.config:
--------------------------------------------------------------------------------
1 | /*
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 | Config file for defining DSL2 per module options and publishing paths
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | Available keys to override module options:
6 | ext.args = Additional arguments appended to command in module.
7 | ext.args2 = Second set of arguments appended to command in module (multi-tool modules).
8 | ext.args3 = Third set of arguments appended to command in module (multi-tool modules).
9 | ext.prefix = File name prefix for output files.
10 | ----------------------------------------------------------------------------------------
11 | */
12 |
13 | process {
14 |
15 | publishDir = [
16 | path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
17 | mode: params.publish_dir_mode,
18 | saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
19 | ]
20 |
21 | withName: FASTQC {
22 | ext.args = '--quiet'
23 | }
24 |
25 | withName: '.*:DRAGEN_DNA:DRAGEN_BUILDHASHTABLE' {
26 | ext.prefix = 'dragen_index_dna'
27 | publishDir = [
28 | path: { "${params.outdir}/genome/index" },
29 | mode: 'copy',
30 | saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
31 | ]
32 | }
33 |
34 | withName: '.*:DRAGEN_RNA:DRAGEN_BUILDHASHTABLE' {
35 | ext.args = '--ht-build-rna-hashtable true'
36 | ext.prefix = 'dragen_index_rna'
37 | publishDir = [
38 | path: { "${params.outdir}/genome/index" },
39 | mode: 'copy',
40 | saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
41 | ]
42 | }
43 |
44 | withName: '.*:DRAGEN_DNA:DRAGEN' {
45 | ext.args = [
46 | '--enable-map-align true',
47 | '--enable-map-align-output true',
48 | '--enable-bam-indexing true',
49 | '--enable-sort=true',
50 | '--enable-variant-caller true',
51 | '--enable-duplicate-marking true',
52 | '--output-format=BAM'
53 | ].join(" ")
54 | publishDir = [
55 | path: { "${params.outdir}/dragen/dna_fastq_to_vcf" },
56 | mode: 'copy',
57 | saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
58 | ]
59 | }
60 |
61 | withName: '.*:DRAGEN_RNA:DRAGEN' {
62 | ext.args = [
63 | '--enable-rna true',
64 | '--enable-map-align true',
65 | '--enable-map-align-output true',
66 | '--enable-bam-indexing true',
67 | '--enable-sort=true',
68 | '--enable-variant-caller true',
69 | '--enable-duplicate-marking true',
70 | '--output-format=BAM'
71 | ].join(" ")
72 | publishDir = [
73 | path: { "${params.outdir}/dragen/rna_fastq_to_bam" },
74 | mode: 'copy',
75 | saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
76 | ]
77 | }
78 |
79 | withName: 'MULTIQC' {
80 | ext.args = { params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' }
81 | publishDir = [
82 | path: { "${params.outdir}/multiqc" },
83 | mode: params.publish_dir_mode,
84 | saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
85 | ]
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/modules/local/dragen.nf:
--------------------------------------------------------------------------------
1 | process DRAGEN {
2 | tag "$meta.id"
3 | label 'dragen'
4 |
5 | secret 'DRAGEN_USERNAME'
6 | secret 'DRAGEN_PASSWORD'
7 |
8 | input:
9 | tuple val(meta), path(fastq_1, stageAs: "input_S1_L001_R1_???.fastq.gz"), path(fastq_2, stageAs: "input_S1_L001_R2_???.fastq.gz")
10 | path index
11 |
12 | output:
13 | tuple val(meta), path('*.{bam,sam,cram}') , emit: bam , optional:true
14 | tuple val(meta), path('*fastq.gz') , emit: fastq , optional:true
15 | tuple val(meta), path("${prefix}.vcf.gz") , emit: vcf , optional:true
16 | tuple val(meta), path("${prefix}.vcf.gz.tbi") , emit: tbi , optional:true
17 | tuple val(meta), path("${prefix}.hard-filtered.vcf.gz") , emit: vcf_filtered, optional:true
18 | tuple val(meta), path("${prefix}.hard-filtered.vcf.gz.tbi") , emit: tbi_filtered, optional:true
19 | path "versions.yml" , emit: versions
20 |
21 | script:
22 | def args = task.ext.args ?: ''
23 | prefix = task.ext.prefix ?: "${meta.id}"
24 |
25 | def ref = index ? "-r $index" : ''
26 |
27 |
28 | // Check FASTQ numbers match
29 | def num_r1 = fastq_1 instanceof List ? fastq_1.size() : 1
30 | def num_r2 = fastq_2 instanceof List ? fastq_2.size() : 1
31 |
32 | if ( fastq_2 && num_r1 != num_r2 ) {
33 | error "Number of R1 and R2 FASTQ files do not match"
34 | }
35 |
36 | // Generate appropriate parameter for input files
37 | r1_in = fastq_1 ? "-1 input_S1_L001_R1_001.fastq.gz" : ""
38 | r2_in = fastq_2 ? "-2 input_S1_L001_R2_001.fastq.gz" : ""
39 | def rgid = meta.rgid ? "--RGID ${meta.rgid}" : "--RGID ${meta.id}"
40 | def rgsm = meta.rgsm ? "--RGSM ${meta.rgsm}" : "--RGSM ${meta.id}"
41 | """
42 | /opt/edico/bin/dragen \\
43 | $ref \\
44 | --output-directory ./ \\
45 | --output-file-prefix $prefix \\
46 | --lic-server=\$DRAGEN_USERNAME:\$DRAGEN_PASSWORD@license.edicogenome.com \\
47 | $r1_in \\
48 | $r2_in \\
49 | $rgid \\
50 | $rgsm \\
51 | $args
52 |
53 | cat <<-END_VERSIONS > versions.yml
54 | "${task.process}":
55 | dragen: '\$(echo \$(/opt/edico/bin/dragen --version 2>&1) | sed -e "s/dragen Version //g")'
56 | END_VERSIONS
57 | """
58 |
59 | stub:
60 | def args = task.ext.args ?: ''
61 | prefix = task.ext.prefix ?: "${meta.id}"
62 |
63 | def ref = index ? "-r $index" : ''
64 |
65 |
66 | // Check FASTQ numbers match
67 | def num_r1 = fastq_1 instanceof List ? fastq_1.size() : 1
68 | def num_r2 = fastq_2 instanceof List ? fastq_2.size() : 1
69 |
70 | if ( fastq_2 && num_r1 != num_r2 ) {
71 | error "Number of R1 and R2 FASTQ files do not match for sample ${prefix}"
72 | }
73 |
74 | // Generate appropriate parameter for input files
75 | r1_in = fastq_1 ? "-1 input_S1_L001_R1_001.fastq.gz" : ""
76 | r2_in = fastq_2 ? "-2 input_S1_L001_R2_001.fastq.gz" : ""
77 | def rgid = meta.rgid ? "--RGID ${meta.rgid}" : "--RGID ${meta.id}"
78 | def rgsm = meta.rgsm ? "--RGSM ${meta.rgsm}" : "--RGSM ${meta.id}"
79 | """
80 | echo /opt/edico/bin/dragen \\
81 | $ref \\
82 | --output-directory ./ \\
83 | --output-file-prefix $prefix \\
84 | --lic-server=\$DRAGEN_USERNAME:\$DRAGEN_PASSWORD@license.edicogenome.com \\
85 | $r1_in \\
86 | $r2_in \\
87 | $rgid \\
88 | $rgsm \\
89 | $args
90 |
91 | cat <<-END_VERSIONS > versions.yml
92 | "${task.process}":
93 | dragen: '\$(echo \$(/opt/edico/bin/dragen --version 2>&1) | sed -e "s/dragen Version //g")'
94 | END_VERSIONS
95 | """
96 | }
97 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test:
--------------------------------------------------------------------------------
1 |
2 | nextflow_function {
3 |
4 | name "Test Functions"
5 | script "../main.nf"
6 | config "subworkflows/nf-core/utils_nfcore_pipeline/tests/nextflow.config"
7 | tag "subworkflows"
8 | tag "subworkflows_nfcore"
9 | tag "utils_nfcore_pipeline"
10 | tag "subworkflows/utils_nfcore_pipeline"
11 |
12 | test("Test Function checkConfigProvided") {
13 |
14 | function "checkConfigProvided"
15 |
16 | then {
17 | assertAll(
18 | { assert function.success },
19 | { assert snapshot(function.result).match() }
20 | )
21 | }
22 | }
23 |
24 | test("Test Function checkProfileProvided") {
25 |
26 | function "checkProfileProvided"
27 |
28 | when {
29 | function {
30 | """
31 | input[0] = []
32 | """
33 | }
34 | }
35 |
36 | then {
37 | assertAll(
38 | { assert function.success },
39 | { assert snapshot(function.result).match() }
40 | )
41 | }
42 | }
43 |
44 | test("Test Function without logColours") {
45 |
46 | function "logColours"
47 |
48 | when {
49 | function {
50 | """
51 | input[0] = true
52 | """
53 | }
54 | }
55 |
56 | then {
57 | assertAll(
58 | { assert function.success },
59 | { assert snapshot(function.result).match() }
60 | )
61 | }
62 | }
63 |
64 | test("Test Function with logColours") {
65 | function "logColours"
66 |
67 | when {
68 | function {
69 | """
70 | input[0] = false
71 | """
72 | }
73 | }
74 |
75 | then {
76 | assertAll(
77 | { assert function.success },
78 | { assert snapshot(function.result).match() }
79 | )
80 | }
81 | }
82 |
83 | test("Test Function getSingleReport with a single file") {
84 | function "getSingleReport"
85 |
86 | when {
87 | function {
88 | """
89 | input[0] = file(params.modules_testdata_base_path + '/generic/tsv/test.tsv', checkIfExists: true)
90 | """
91 | }
92 | }
93 |
94 | then {
95 | assertAll(
96 | { assert function.success },
97 | { assert function.result.contains("test.tsv") }
98 | )
99 | }
100 | }
101 |
102 | test("Test Function getSingleReport with multiple files") {
103 | function "getSingleReport"
104 |
105 | when {
106 | function {
107 | """
108 | input[0] = [
109 | file(params.modules_testdata_base_path + '/generic/tsv/test.tsv', checkIfExists: true),
110 | file(params.modules_testdata_base_path + '/generic/tsv/network.tsv', checkIfExists: true),
111 | file(params.modules_testdata_base_path + '/generic/tsv/expression.tsv', checkIfExists: true)
112 | ]
113 | """
114 | }
115 | }
116 |
117 | then {
118 | assertAll(
119 | { assert function.success },
120 | { assert function.result.contains("test.tsv") },
121 | { assert !function.result.contains("network.tsv") },
122 | { assert !function.result.contains("expression.tsv") }
123 | )
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow_schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://raw.githubusercontent.com/./master/nextflow_schema.json",
4 | "title": ". pipeline parameters",
5 | "description": "",
6 | "type": "object",
7 | "$defs": {
8 | "input_output_options": {
9 | "title": "Input/output options",
10 | "type": "object",
11 | "fa_icon": "fas fa-terminal",
12 | "description": "Define where the pipeline should find input data and save output data.",
13 | "required": ["outdir"],
14 | "properties": {
15 | "validate_params": {
16 | "type": "boolean",
17 | "description": "Validate parameters?",
18 | "default": true,
19 | "hidden": true
20 | },
21 | "outdir": {
22 | "type": "string",
23 | "format": "directory-path",
24 | "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.",
25 | "fa_icon": "fas fa-folder-open"
26 | },
27 | "test_data_base": {
28 | "type": "string",
29 | "default": "https://raw.githubusercontent.com/nf-core/test-datasets/modules",
30 | "description": "Base for test data directory",
31 | "hidden": true
32 | },
33 | "test_data": {
34 | "type": "string",
35 | "description": "Fake test data param",
36 | "hidden": true
37 | }
38 | }
39 | },
40 | "generic_options": {
41 | "title": "Generic options",
42 | "type": "object",
43 | "fa_icon": "fas fa-file-import",
44 | "description": "Less common options for the pipeline, typically set in a config file.",
45 | "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`.",
46 | "properties": {
47 | "help": {
48 | "type": "boolean",
49 | "description": "Display help text.",
50 | "fa_icon": "fas fa-question-circle",
51 | "hidden": true
52 | },
53 | "version": {
54 | "type": "boolean",
55 | "description": "Display version and exit.",
56 | "fa_icon": "fas fa-question-circle",
57 | "hidden": true
58 | },
59 | "logo": {
60 | "type": "boolean",
61 | "default": true,
62 | "description": "Display nf-core logo in console output.",
63 | "fa_icon": "fas fa-image",
64 | "hidden": true
65 | },
66 | "singularity_pull_docker_container": {
67 | "type": "boolean",
68 | "description": "Pull Singularity container from Docker?",
69 | "hidden": true
70 | },
71 | "publish_dir_mode": {
72 | "type": "string",
73 | "default": "copy",
74 | "description": "Method used to save pipeline results to output directory.",
75 | "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.",
76 | "fa_icon": "fas fa-copy",
77 | "enum": ["symlink", "rellink", "link", "copy", "copyNoFollow", "move"],
78 | "hidden": true
79 | },
80 | "monochrome_logs": {
81 | "type": "boolean",
82 | "description": "Use monochrome_logs",
83 | "hidden": true
84 | }
85 | }
86 | }
87 | },
88 | "allOf": [
89 | {
90 | "$ref": "#/$defs/input_output_options"
91 | },
92 | {
93 | "$ref": "#/$defs/generic_options"
94 | }
95 | ]
96 | }
97 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nextflow_pipeline/main.nf:
--------------------------------------------------------------------------------
1 | //
2 | // Subworkflow with functionality that may be useful for any Nextflow pipeline
3 | //
4 |
5 | /*
6 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 | SUBWORKFLOW DEFINITION
8 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 | */
10 |
11 | workflow UTILS_NEXTFLOW_PIPELINE {
12 | take:
13 | print_version // boolean: print version
14 | dump_parameters // boolean: dump parameters
15 | outdir // path: base directory used to publish pipeline results
16 | check_conda_channels // boolean: check conda channels
17 |
18 | main:
19 |
20 | //
21 | // Print workflow version and exit on --version
22 | //
23 | if (print_version) {
24 | log.info("${workflow.manifest.name} ${getWorkflowVersion()}")
25 | System.exit(0)
26 | }
27 |
28 | //
29 | // Dump pipeline parameters to a JSON file
30 | //
31 | if (dump_parameters && outdir) {
32 | dumpParametersToJSON(outdir)
33 | }
34 |
35 | //
36 | // When running with Conda, warn if channels have not been set-up appropriately
37 | //
38 | if (check_conda_channels) {
39 | checkCondaChannels()
40 | }
41 |
42 | emit:
43 | dummy_emit = true
44 | }
45 |
46 | /*
47 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
48 | FUNCTIONS
49 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50 | */
51 |
52 | //
53 | // Generate version string
54 | //
55 | def getWorkflowVersion() {
56 | def version_string = "" as String
57 | if (workflow.manifest.version) {
58 | def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : ''
59 | version_string += "${prefix_v}${workflow.manifest.version}"
60 | }
61 |
62 | if (workflow.commitId) {
63 | def git_shortsha = workflow.commitId.substring(0, 7)
64 | version_string += "-g${git_shortsha}"
65 | }
66 |
67 | return version_string
68 | }
69 |
70 | //
71 | // Dump pipeline parameters to a JSON file
72 | //
73 | def dumpParametersToJSON(outdir) {
74 | def timestamp = new java.util.Date().format('yyyy-MM-dd_HH-mm-ss')
75 | def filename = "params_${timestamp}.json"
76 | def temp_pf = new File(workflow.launchDir.toString(), ".${filename}")
77 | def jsonStr = groovy.json.JsonOutput.toJson(params)
78 | temp_pf.text = groovy.json.JsonOutput.prettyPrint(jsonStr)
79 |
80 | nextflow.extension.FilesEx.copyTo(temp_pf.toPath(), "${outdir}/pipeline_info/params_${timestamp}.json")
81 | temp_pf.delete()
82 | }
83 |
84 | //
85 | // When running with -profile conda, warn if channels have not been set-up appropriately
86 | //
87 | def checkCondaChannels() {
88 | def parser = new org.yaml.snakeyaml.Yaml()
89 | def channels = []
90 | try {
91 | def config = parser.load("conda config --show channels".execute().text)
92 | channels = config.channels
93 | }
94 | catch (NullPointerException e) {
95 | log.debug(e)
96 | log.warn("Could not verify conda channel configuration.")
97 | return null
98 | }
99 | catch (IOException e) {
100 | log.debug(e)
101 | log.warn("Could not verify conda channel configuration.")
102 | return null
103 | }
104 |
105 | // Check that all channels are present
106 | // This channel list is ordered by required channel priority.
107 | def required_channels_in_order = ['conda-forge', 'bioconda']
108 | def channels_missing = ((required_channels_in_order as Set) - (channels as Set)) as Boolean
109 |
110 | // Check that they are in the right order
111 | def channel_priority_violation = required_channels_in_order != channels.findAll { ch -> ch in required_channels_in_order }
112 |
113 | if (channels_missing | channel_priority_violation) {
114 | log.warn """\
115 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
116 | There is a problem with your Conda configuration!
117 | You will need to set-up the conda-forge and bioconda channels correctly.
118 | Please refer to https://bioconda.github.io/
119 | The observed channel order is
120 | ${channels}
121 | but the following channel order is required:
122 | ${required_channels_in_order}
123 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
124 | """.stripIndent(true)
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfcore_pipeline/tests/main.function.nf.test.snap:
--------------------------------------------------------------------------------
1 | {
2 | "Test Function checkProfileProvided": {
3 | "content": null,
4 | "meta": {
5 | "nf-test": "0.8.4",
6 | "nextflow": "23.10.1"
7 | },
8 | "timestamp": "2024-02-28T12:03:03.360873"
9 | },
10 | "Test Function checkConfigProvided": {
11 | "content": [
12 | true
13 | ],
14 | "meta": {
15 | "nf-test": "0.8.4",
16 | "nextflow": "23.10.1"
17 | },
18 | "timestamp": "2024-02-28T12:02:59.729647"
19 | },
20 | "Test Function without logColours": {
21 | "content": [
22 | {
23 | "reset": "",
24 | "bold": "",
25 | "dim": "",
26 | "underlined": "",
27 | "blink": "",
28 | "reverse": "",
29 | "hidden": "",
30 | "black": "",
31 | "red": "",
32 | "green": "",
33 | "yellow": "",
34 | "blue": "",
35 | "purple": "",
36 | "cyan": "",
37 | "white": "",
38 | "bblack": "",
39 | "bred": "",
40 | "bgreen": "",
41 | "byellow": "",
42 | "bblue": "",
43 | "bpurple": "",
44 | "bcyan": "",
45 | "bwhite": "",
46 | "ublack": "",
47 | "ured": "",
48 | "ugreen": "",
49 | "uyellow": "",
50 | "ublue": "",
51 | "upurple": "",
52 | "ucyan": "",
53 | "uwhite": "",
54 | "iblack": "",
55 | "ired": "",
56 | "igreen": "",
57 | "iyellow": "",
58 | "iblue": "",
59 | "ipurple": "",
60 | "icyan": "",
61 | "iwhite": "",
62 | "biblack": "",
63 | "bired": "",
64 | "bigreen": "",
65 | "biyellow": "",
66 | "biblue": "",
67 | "bipurple": "",
68 | "bicyan": "",
69 | "biwhite": ""
70 | }
71 | ],
72 | "meta": {
73 | "nf-test": "0.8.4",
74 | "nextflow": "23.10.1"
75 | },
76 | "timestamp": "2024-02-28T12:03:17.969323"
77 | },
78 | "Test Function with logColours": {
79 | "content": [
80 | {
81 | "reset": "\u001b[0m",
82 | "bold": "\u001b[1m",
83 | "dim": "\u001b[2m",
84 | "underlined": "\u001b[4m",
85 | "blink": "\u001b[5m",
86 | "reverse": "\u001b[7m",
87 | "hidden": "\u001b[8m",
88 | "black": "\u001b[0;30m",
89 | "red": "\u001b[0;31m",
90 | "green": "\u001b[0;32m",
91 | "yellow": "\u001b[0;33m",
92 | "blue": "\u001b[0;34m",
93 | "purple": "\u001b[0;35m",
94 | "cyan": "\u001b[0;36m",
95 | "white": "\u001b[0;37m",
96 | "bblack": "\u001b[1;30m",
97 | "bred": "\u001b[1;31m",
98 | "bgreen": "\u001b[1;32m",
99 | "byellow": "\u001b[1;33m",
100 | "bblue": "\u001b[1;34m",
101 | "bpurple": "\u001b[1;35m",
102 | "bcyan": "\u001b[1;36m",
103 | "bwhite": "\u001b[1;37m",
104 | "ublack": "\u001b[4;30m",
105 | "ured": "\u001b[4;31m",
106 | "ugreen": "\u001b[4;32m",
107 | "uyellow": "\u001b[4;33m",
108 | "ublue": "\u001b[4;34m",
109 | "upurple": "\u001b[4;35m",
110 | "ucyan": "\u001b[4;36m",
111 | "uwhite": "\u001b[4;37m",
112 | "iblack": "\u001b[0;90m",
113 | "ired": "\u001b[0;91m",
114 | "igreen": "\u001b[0;92m",
115 | "iyellow": "\u001b[0;93m",
116 | "iblue": "\u001b[0;94m",
117 | "ipurple": "\u001b[0;95m",
118 | "icyan": "\u001b[0;96m",
119 | "iwhite": "\u001b[0;97m",
120 | "biblack": "\u001b[1;90m",
121 | "bired": "\u001b[1;91m",
122 | "bigreen": "\u001b[1;92m",
123 | "biyellow": "\u001b[1;93m",
124 | "biblue": "\u001b[1;94m",
125 | "bipurple": "\u001b[1;95m",
126 | "bicyan": "\u001b[1;96m",
127 | "biwhite": "\u001b[1;97m"
128 | }
129 | ],
130 | "meta": {
131 | "nf-test": "0.8.4",
132 | "nextflow": "23.10.1"
133 | },
134 | "timestamp": "2024-02-28T12:03:21.714424"
135 | }
136 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.nextflow.io/)
2 |
3 | > THIS IS A PROOF-OF-CONCEPT REPOSITORY THAT IS UNDER ACTIVE DEVELOPMENT. SYNTAX, ORGANISATION AND LAYOUT MAY CHANGE WITHOUT NOTICE!
4 |
5 | ## Introduction
6 |
7 | **nf-dragen** is a simple, proof-of-concept pipeline to run the [Illumina DRAGEN](https://emea.illumina.com/products/by-type/informatics-products/dragen-bio-it-platform.html) licensed suite of tools.
8 |
9 | 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 uses Docker containers making installation trivial and results highly reproducible. This pipeline has only been tested on AWS Batch.
10 |
11 | ## Integration with Seqera Platform
12 |
13 | We have streamlined the process of deploying Nextflow workflows that utilise Illumina DRAGEN on AWS Batch via Seqera.
14 |
15 | ### Prerequisites
16 |
17 | #### Credentials
18 |
19 | You will need to obtain the following information from the Illumina DRAGEN team:
20 |
21 | 1. Private AMI id in an AWS region with DRAGEN F1 instance availability
22 | 2. Username to run DRAGEN on the CLI via Nextflow
23 | 3. Password to run DRAGEN on the CLI via Nextflow
24 |
25 | #### Pipeline implementation
26 |
27 | Please see the [dragen.nf](modules/local/dragen.nf) module implemented in this pipeline for reference.
28 |
29 | Any Nextflow processes calling the `dragen` command must have:
30 |
31 | 1. `label dragen` ([see docs](https://www.nextflow.io/docs/latest/process.html?highlight=label#label)). This is how Seqera will determine which processes need to be specifically executed on DRAGEN F1 instances.
32 |
33 | ```nextflow
34 | process DRAGEN {
35 | label 'dragen'
36 |
37 |
38 | }
39 | ```
40 |
41 | 2. `secret DRAGEN_USERNAME` and `secret DRAGEN_PASSWORD` ([see docs](https://www.nextflow.io/docs/latest/secrets.html?highlight=secrets#secrets)). These Secrets will be provided securely to the `--lic-server` option when running DRAGEN on the CLI to validate the license.
42 |
43 | ```nextflow
44 | process DRAGEN {
45 | secret 'DRAGEN_USERNAME'
46 | secret 'DRAGEN_PASSWORD'
47 |
48 |
49 |
50 | script:
51 | """
52 | /opt/edico/bin/dragen \\
53 | --lic-server=\$DRAGEN_USERNAME:\$DRAGEN_PASSWORD@license.edicogenome.com \\
54 |
55 | """
56 | }
57 | ```
58 |
59 | ### Compute Environment
60 |
61 | You can use Seqera Batch Forge to automatically create a separate AWS Batch queue with dedicated F1 instances to run DRAGEN.
62 |
63 | In the Seqera UI, go to `Compute Environments` -> `Add Compute Environment` and fill in the appropriate settings for your AWS Batch environment. Additionally, you will be able to paste your private DRAGEN AMI id as shown in the image below:
64 |
65 | 
66 |
67 | Click on `Add` to create the Compute Environment.
68 |
69 | > Please ensure that the `Region` you select contains DRAGEN F1 instances.
70 |
71 | ### Secrets
72 |
73 | As outlined in [this blog](https://seqera.io/blog/pipeline-secrets-secure-handling-of-sensitive-information-in-tower/) you can add Secrets to Seqera to safely encrypt the username and password information required to run DRAGEN via Nextflow.
74 |
75 | In the Seqera UI, go to `Secrets` -> `Add Pipeline Secret` and add both of the Secrets as shown in the images below:
76 |
77 | 1. `DRAGEN_USERNAME`
78 |
79 | 
80 |
81 | 2. `DRAGEN_PASSWORD`
82 |
83 | 
84 |
85 | ### Pipeline
86 |
87 | In the Seqera UI, go to `Launchpad` -> `Add Pipeline`. Fill in the appropriate details to add your pipeline and ensure that the Compute Environment and Secrets you created previously are both defined for use by the pipeline:
88 |
89 | 
90 |
91 | Click on `Add` to create the pipeline and launch it when you are ready!
92 |
93 | ## Credits
94 |
95 | nf-dragen was originally written by [Harshil Patel](https://github.com/drpatelh) and [Graham Wright](https://github.com/gwright99) and [Paolo Di Tommasso](https://github.com/pditommaso), [Seqera Labs](https://seqera.io/).
96 |
97 | ## Citations
98 |
99 | The nf-core pipeline template was used to create the skeleton of this pipeline but there are no plans to contribute it to nf-core at this point.
100 |
101 | You can cite the `nf-core` publication as follows:
102 |
103 | > **The nf-core framework for community-curated bioinformatics pipelines.**
104 | >
105 | > Philip Ewels, Alexander Peltzer, Sven Fillinger, Harshil Patel, Johannes Alneberg, Andreas Wilm, Maxime Ulysse Garcia, Paolo Di Tommaso & Sven Nahnsen.
106 | >
107 | > _Nat Biotechnol._ 2020 Feb 13. doi: [10.1038/s41587-020-0439-x](https://dx.doi.org/10.1038/s41587-020-0439-x).
108 |
--------------------------------------------------------------------------------
/subworkflows/local/utils_nfcore_dragen_pipeline/main.nf:
--------------------------------------------------------------------------------
1 | //
2 | // Subworkflow with functionality specific to the seqeralabs/nf-dragen pipeline
3 | //
4 |
5 | /*
6 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 | IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS
8 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 | */
10 |
11 | include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin'
12 | include { paramsSummaryMap } from 'plugin/nf-schema'
13 | include { samplesheetToList } from 'plugin/nf-schema'
14 | include { completionSummary } from '../../nf-core/utils_nfcore_pipeline'
15 | include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline'
16 | include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline'
17 |
18 | /*
19 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 | SUBWORKFLOW TO INITIALISE PIPELINE
21 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22 | */
23 |
24 | workflow PIPELINE_INITIALISATION {
25 |
26 | take:
27 | version // boolean: Display version and exit
28 | help // boolean: Display help text
29 | validate_params // boolean: Boolean whether to validate parameters against the schema at runtime
30 | monochrome_logs // boolean: Do not use coloured log outputs
31 | nextflow_cli_args // array: List of positional nextflow CLI args
32 | outdir // string: The output directory where the results will be saved
33 | input // string: Path to input samplesheet
34 |
35 | main:
36 |
37 | ch_versions = Channel.empty()
38 |
39 | //
40 | // Print version and exit if required and dump pipeline parameters to JSON file
41 | //
42 | UTILS_NEXTFLOW_PIPELINE (
43 | version,
44 | true,
45 | outdir,
46 | workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1
47 | )
48 |
49 | //
50 | // Validate parameters and generate parameter summary to stdout
51 | //
52 | UTILS_NFSCHEMA_PLUGIN (
53 | workflow,
54 | validate_params,
55 | null
56 | )
57 |
58 | //
59 | // Check config provided to the pipeline
60 | //
61 | UTILS_NFCORE_PIPELINE (
62 | nextflow_cli_args
63 | )
64 |
65 | //
66 | // Custom validation for pipeline parameters
67 | //
68 | validateInputParameters()
69 |
70 | //
71 | // Create channel from input file provided through params.input
72 | //
73 |
74 | Channel
75 | .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json"))
76 | .map { meta, fastq_1, fastq_2 ->
77 | return [
78 | meta + [ seq_type: meta.seq_type ?: params.seq_type],
79 | fastq_1,
80 | fastq_2
81 | ]
82 | }
83 | .groupTuple()
84 | .map { meta, fastq_1, fastq_2 ->
85 | return [
86 | meta,
87 | fastq_1.flatten(),
88 | fastq_2.flatten()
89 | ]
90 | }
91 | .set { ch_samplesheet }
92 |
93 | emit:
94 | samplesheet = ch_samplesheet
95 | versions = ch_versions
96 | }
97 |
98 | /*
99 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
100 | SUBWORKFLOW FOR PIPELINE COMPLETION
101 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
102 | */
103 |
104 | workflow PIPELINE_COMPLETION {
105 |
106 | take:
107 | outdir // path: Path to output directory where results will be published
108 | monochrome_logs // boolean: Disable ANSI colour codes in log output
109 | multiqc_report // string: Path to MultiQC report
110 |
111 | main:
112 | summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json")
113 | def multiqc_reports = multiqc_report.toList()
114 |
115 | //
116 | // Completion email and summary
117 | //
118 | workflow.onComplete {
119 |
120 | completionSummary(monochrome_logs)
121 | }
122 |
123 | workflow.onError {
124 | log.error "Pipeline failed. Please refer to troubleshooting docs: https://nf-co.re/docs/usage/troubleshooting"
125 | }
126 | }
127 |
128 | /*
129 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
130 | FUNCTIONS
131 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
132 | */
133 | //
134 | // Check and validate pipeline parameters
135 | //
136 | def validateInputParameters() {
137 | genomeExistsError()
138 | }
139 |
140 | //
141 | // Get attribute from genome config file e.g. fasta
142 | //
143 | def getGenomeAttribute(attribute) {
144 | if (params.genomes && params.genome && params.genomes.containsKey(params.genome)) {
145 | if (params.genomes[ params.genome ].containsKey(attribute)) {
146 | return params.genomes[ params.genome ][ attribute ]
147 | }
148 | }
149 | return null
150 | }
151 |
152 | //
153 | // Exit pipeline if incorrect --genome key provided
154 | //
155 | def genomeExistsError() {
156 | if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) {
157 | def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
158 | " Genome '${params.genome}' not found in any config files provided to the pipeline.\n" +
159 | " Currently, the available genome keys are:\n" +
160 | " ${params.genomes.keySet().join(", ")}\n" +
161 | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
162 | error(error_string)
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # `seqeralabs/nf-dragen`: Contributing Guidelines
2 |
3 | Hi there!
4 | Many thanks for taking an interest in improving seqeralabs/nf-dragen.
5 |
6 | We try to manage the required tasks for seqeralabs/nf-dragen using GitHub issues, you probably came to this page when creating one.
7 | Please use the pre-filled template to save time.
8 |
9 | However, don't be put off by this template - other more general issues and suggestions are welcome!
10 | Contributions to the code are even more welcome ;)
11 |
12 | ## Contribution workflow
13 |
14 | If you'd like to write some code for seqeralabs/nf-dragen, the standard workflow is as follows:
15 |
16 | 1. Check that there isn't already an issue about your idea in the [seqeralabs/nf-dragen issues](https://github.com/seqeralabs/nf-dragen/issues) to avoid duplicating work. If there isn't one already, please create one so that others know you're working on this
17 | 2. [Fork](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) the [seqeralabs/nf-dragen repository](https://github.com/seqeralabs/nf-dragen) to your GitHub account
18 | 3. Make the necessary changes / additions within your forked repository following [Pipeline conventions](#pipeline-contribution-conventions)
19 | 4. Use `nf-core pipelines schema build` and add any new parameters to the pipeline JSON schema (requires [nf-core tools](https://github.com/nf-core/tools) >= 1.10).
20 | 5. Submit a Pull Request against the `dev` branch and wait for the code to be reviewed and merged
21 |
22 | If you're not used to this workflow with git, you can start with some [docs from GitHub](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests) or even their [excellent `git` resources](https://try.github.io/).
23 |
24 | ## Tests
25 |
26 | You have the option to test your changes locally by running the pipeline. For receiving warnings about process selectors and other `debug` information, it is recommended to use the debug profile. Execute all the tests with the following command:
27 |
28 | ```bash
29 | nf-test test --profile debug,test,docker --verbose
30 | ```
31 |
32 | When you create a pull request with changes, [GitHub Actions](https://github.com/features/actions) will run automatic tests.
33 | Typically, pull-requests are only fully reviewed when these tests are passing, though of course we can help out before then.
34 |
35 | There are typically two types of tests that run:
36 |
37 | ### Lint tests
38 |
39 | `nf-core` has a [set of guidelines](https://nf-co.re/developers/guidelines) which all pipelines must adhere to.
40 | To enforce these and ensure that all pipelines stay in sync, we have developed a helper tool which runs checks on the pipeline code. This is in the [nf-core/tools repository](https://github.com/nf-core/tools) and once installed can be run locally with the `nf-core pipelines lint ` command.
41 |
42 | If any failures or warnings are encountered, please follow the listed URL for more documentation.
43 |
44 | ### Pipeline tests
45 |
46 | Each `nf-core` pipeline should be set up with a minimal set of test-data.
47 | `GitHub Actions` then runs the pipeline on this data to ensure that it exits successfully.
48 | If there are any failures then the automated tests fail.
49 | These tests are run both with the latest available version of `Nextflow` and also the minimum required version that is stated in the pipeline code.
50 |
51 | ## Patch
52 |
53 | :warning: Only in the unlikely and regretful event of a release happening with a bug.
54 |
55 | - On your own fork, make a new branch `patch` based on `upstream/main` or `upstream/master`.
56 | - Fix the bug, and bump version (X.Y.Z+1).
57 | - Open a pull-request from `patch` to `main`/`master` with the changes.
58 |
59 | ## Pipeline contribution conventions
60 |
61 | To make the `seqeralabs/nf-dragen` code and processing logic more understandable for new contributors and to ensure quality, we semi-standardise the way the code and other contributions are written.
62 |
63 | ### Adding a new step
64 |
65 | If you wish to contribute a new step, please use the following coding standards:
66 |
67 | 1. Define the corresponding input channel into your new process from the expected previous process channel.
68 | 2. Write the process block (see below).
69 | 3. Define the output channel if needed (see below).
70 | 4. Add any new parameters to `nextflow.config` with a default (see below).
71 | 5. Add any new parameters to `nextflow_schema.json` with help text (via the `nf-core pipelines schema build` tool).
72 | 6. Add sanity checks and validation for all relevant parameters.
73 | 7. Perform local tests to validate that the new code works as expected.
74 | 8. If applicable, add a new test command in `.github/workflow/ci.yml`.
75 | 9. Update MultiQC config `assets/multiqc_config.yml` so relevant suffixes, file name clean up and module plots are in the appropriate order. If applicable, add a [MultiQC](https://https://multiqc.info/) module.
76 | 10. Add a description of the output files and if relevant any appropriate images from the MultiQC report to `docs/output.md`.
77 |
78 | ### Default values
79 |
80 | Parameters should be initialised / defined with default values within the `params` scope in `nextflow.config`.
81 |
82 | Once there, use `nf-core pipelines schema build` to add to `nextflow_schema.json`.
83 |
84 | ### Default processes resource requirements
85 |
86 | Sensible defaults for process resource requirements (CPUs / memory / time) for a process should be defined in `conf/base.config`. These should generally be specified generic with `withLabel:` selectors so they can be shared across multiple processes/steps of the pipeline. A nf-core standard set of labels that should be followed where possible can be seen in the [nf-core pipeline template](https://github.com/nf-core/tools/blob/main/nf_core/pipeline-template/conf/base.config), which has the default process as a single core-process, and then different levels of multi-core configurations for increasingly large memory requirements defined with standardised labels.
87 |
88 | The process resources can be passed on to the tool dynamically within the process with the `${task.cpus}` and `${task.memory}` variables in the `script:` block.
89 |
90 | ### Naming schemes
91 |
92 | Please use the following naming schemes, to make it easy to understand what is going where.
93 |
94 | - initial process channel: `ch_output_from_`
95 | - intermediate and terminal channels: `ch__for_`
96 |
97 | ### Nextflow version bumping
98 |
99 | If you are using a new feature from core Nextflow, you may bump the minimum required version of nextflow in the pipeline with: `nf-core pipelines bump-version --nextflow . [min-nf-version]`
100 |
101 | ### Images and figures
102 |
103 | For overview images and other documents we follow the nf-core [style guidelines and examples](https://nf-co.re/developers/design_guidelines).
104 |
--------------------------------------------------------------------------------
/main.nf:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env nextflow
2 | /*
3 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 | seqeralabs/nf-dragen
5 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 | Github : https://github.com/seqeralabs/nf-dragen
7 | ----------------------------------------------------------------------------------------
8 | */
9 |
10 | /*
11 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12 | IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS
13 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14 | */
15 |
16 | include { paramsSummaryMap } from 'plugin/nf-schema'
17 | include { getGenomeAttribute } from './subworkflows/local/utils_nfcore_dragen_pipeline'
18 | include { softwareVersionsToYAML } from './subworkflows/nf-core/utils_nfcore_pipeline'
19 | include { paramsSummaryMultiqc } from './subworkflows/nf-core/utils_nfcore_pipeline'
20 |
21 | include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_dragen_pipeline'
22 | include { FASTQC } from './modules/nf-core/fastqc/main'
23 | include { DRAGEN_WORKFLOW as DRAGEN_DNA } from './workflows/dragen'
24 | include { DRAGEN_WORKFLOW as DRAGEN_RNA } from './workflows/dragen'
25 | include { MULTIQC } from './modules/nf-core/multiqc/main'
26 | include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_dragen_pipeline'
27 |
28 | /*
29 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
30 | GENOME PARAMETER VALUES
31 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32 | */
33 |
34 |
35 | /*
36 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 | NAMED WORKFLOWS FOR PIPELINE
38 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39 | */
40 |
41 | //
42 | // WORKFLOW: Run main analysis pipeline depending on type of input
43 | //
44 | workflow SEQERALABS_DRAGEN {
45 |
46 | take:
47 | input // tuple: [ meta, [fastq_1, ...], [fastq_2, ...] ]
48 | fasta // str: path to fasta file
49 | dna_index // str: path to dragen index directory for dna
50 | rna_index // str: path to dragen index directory for rna
51 |
52 | main:
53 |
54 | ch_versions = Channel.empty()
55 | ch_multiqc_files = Channel.empty()
56 |
57 | //
58 | // FASTQC
59 | //
60 | input
61 | .filter { !params.skip_fastqc }
62 | // Coerce input to format for FASTQC input
63 | .map { meta, fastq_1, fastq_2 -> [meta, fastq_1 + fastq_2]}
64 | | FASTQC
65 | ch_versions = ch_versions.mix(FASTQC.out.versions)
66 | ch_multiqc_files = ch_multiqc_files.mix(FASTQC.out.zip.map { it[1] })
67 |
68 | //
69 | // WORKFLOW: Run DNA pipeline
70 | //
71 | DRAGEN_DNA (
72 | input.filter { meta, fastq_1, fastq_2 -> meta.seq_type == 'dna' && !params.skip_dragen },
73 | dna_index,
74 | fasta
75 | )
76 | ch_versions = ch_versions.mix(DRAGEN_DNA.out.versions)
77 |
78 | //
79 | // WORKFLOW: Run RNA pipeline
80 | //
81 | DRAGEN_RNA (
82 | input.filter { meta, fastq_1, fastq_2 -> meta.seq_type == 'rna' && !params.skip_dragen },
83 | rna_index,
84 | fasta
85 | )
86 | ch_versions = ch_versions.mix(DRAGEN_RNA.out.versions)
87 |
88 | if ( !params.skip_multiqc ) {
89 | //
90 | // MODULE: MultiQC
91 | //
92 | softwareVersionsToYAML(ch_versions)
93 | .collectFile(storeDir: "${params.outdir}/pipeline_info", name: 'nf_core_pipeline_software_mqc_versions.yml', sort: true, newLine: true)
94 | .set { ch_collated_versions }
95 |
96 | // Build custom multiqc content for the repot
97 | ch_multiqc_config = Channel.fromPath("$projectDir/assets/multiqc_config.yml", checkIfExists: true)
98 | ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath(params.multiqc_config, checkIfExists: true) : Channel.empty()
99 | ch_multiqc_logo = params.multiqc_logo ? Channel.fromPath(params.multiqc_logo, checkIfExists: true) : Channel.empty()
100 | summary_params = paramsSummaryMap(workflow, parameters_schema: "nextflow_schema.json")
101 | ch_workflow_summary = Channel.value(paramsSummaryMultiqc(summary_params))
102 | ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml'))
103 | ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions)
104 |
105 | MULTIQC (
106 | ch_multiqc_files.collect(),
107 | ch_multiqc_config.toList(),
108 | ch_multiqc_custom_config.toList(),
109 | ch_multiqc_logo.toList(),
110 | [],
111 | []
112 | )
113 | multiqc_report = MULTIQC.out.report.toList()
114 | ch_versions = ch_versions.mix(MULTIQC.out.versions)
115 | } else {
116 | multiqc_report = Channel.empty()
117 | }
118 |
119 | emit:
120 | index = DRAGEN_DNA.out.index
121 | bam = DRAGEN_DNA.out.bam
122 | fastq = DRAGEN_DNA.out.fastq
123 | vcf = DRAGEN_DNA.out.vcf
124 | tbi = DRAGEN_DNA.out.tbi
125 | vcf_filtered = DRAGEN_DNA.out.vcf_filtered
126 | tbi_filtered = DRAGEN_DNA.out.tbi_filtered
127 | multiqc_report = multiqc_report
128 | versions = DRAGEN_DNA.out.versions
129 | }
130 |
131 | /*
132 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
133 | RUN MAIN WORKFLOW
134 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
135 | */
136 |
137 | workflow {
138 |
139 | main:
140 | //
141 | // SUBWORKFLOW: Run initialisation tasks
142 | //
143 | PIPELINE_INITIALISATION (
144 | params.version,
145 | params.help,
146 | params.validate_params,
147 | params.monochrome_logs,
148 | args,
149 | params.outdir,
150 | params.input
151 | )
152 |
153 | //
154 | // WORKFLOW: Run main workflow
155 | //
156 | SEQERALABS_DRAGEN (
157 | PIPELINE_INITIALISATION.out.samplesheet,
158 | params.fasta ?: getGenomeAttribute('fasta'),
159 | params.dragen_index_dna ?: getGenomeAttribute('dragen_index_dna'),
160 | params.dragen_index_rna ?: getGenomeAttribute('dragen_index_rna')
161 | )
162 | //
163 | // SUBWORKFLOW: Run completion tasks
164 | //
165 | PIPELINE_COMPLETION (
166 | params.outdir,
167 | params.monochrome_logs,
168 | SEQERALABS_DRAGEN.out.multiqc_report
169 | )
170 | }
171 |
172 | /*
173 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
174 | THE END
175 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
176 | */
177 |
--------------------------------------------------------------------------------
/nextflow.config:
--------------------------------------------------------------------------------
1 | /*
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 | seqeralabs/dragen Nextflow config file
4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | Default config options for all compute environments
6 | ----------------------------------------------------------------------------------------
7 | */
8 |
9 | // Global default params, used in configs
10 | params {
11 |
12 | // Input options
13 | input = null
14 | seq_type = 'dna'
15 |
16 | // References
17 | genome = null
18 | igenomes_ignore = false
19 | igenomes_base = 's3://ngi-igenomes/igenomes/'
20 | fasta = null
21 | dragen_index_dna = null
22 | dragen_index_rna = null
23 | multiqc_config = null
24 | multiqc_title = null
25 | multiqc_logo = null
26 | max_multiqc_email_size = '25.MB'
27 | multiqc_methods_description = null
28 |
29 | // Tools
30 | skip_fastqc = false
31 | skip_multiqc = false
32 | skip_dragen = false
33 |
34 | // Boilerplate options
35 | outdir = null
36 | publish_dir_mode = 'copy'
37 | monochrome_logs = false
38 | help = false
39 | help_full = false
40 | show_hidden = false
41 | version = false
42 | pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/'
43 | trace_report_suffix = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss')
44 |
45 | // Schema validation default options
46 | validate_params = true
47 | }
48 |
49 | // Load base.config by default for all pipelines
50 | includeConfig 'conf/base.config'
51 |
52 | profiles {
53 | debug {
54 | dumpHashes = true
55 | process.beforeScript = 'echo $HOSTNAME'
56 | cleanup = false
57 | nextflow.enable.configProcessNamesValidation = true
58 | }
59 | conda {
60 | conda.enabled = true
61 | docker.enabled = false
62 | singularity.enabled = false
63 | podman.enabled = false
64 | shifter.enabled = false
65 | charliecloud.enabled = false
66 | conda.channels = ['conda-forge', 'bioconda']
67 | apptainer.enabled = false
68 | }
69 | mamba {
70 | conda.enabled = true
71 | conda.useMamba = true
72 | docker.enabled = false
73 | singularity.enabled = false
74 | podman.enabled = false
75 | shifter.enabled = false
76 | charliecloud.enabled = false
77 | apptainer.enabled = false
78 | }
79 | docker {
80 | docker.enabled = true
81 | conda.enabled = false
82 | singularity.enabled = false
83 | podman.enabled = false
84 | shifter.enabled = false
85 | charliecloud.enabled = false
86 | apptainer.enabled = false
87 | docker.runOptions = '-u $(id -u):$(id -g)'
88 | }
89 | arm {
90 | docker.runOptions = '-u $(id -u):$(id -g) --platform=linux/amd64'
91 | }
92 | singularity {
93 | singularity.enabled = true
94 | singularity.autoMounts = true
95 | conda.enabled = false
96 | docker.enabled = false
97 | podman.enabled = false
98 | shifter.enabled = false
99 | charliecloud.enabled = false
100 | apptainer.enabled = false
101 | }
102 | podman {
103 | podman.enabled = true
104 | conda.enabled = false
105 | docker.enabled = false
106 | singularity.enabled = false
107 | shifter.enabled = false
108 | charliecloud.enabled = false
109 | apptainer.enabled = false
110 | }
111 | shifter {
112 | shifter.enabled = true
113 | conda.enabled = false
114 | docker.enabled = false
115 | singularity.enabled = false
116 | podman.enabled = false
117 | charliecloud.enabled = false
118 | apptainer.enabled = false
119 | }
120 | charliecloud {
121 | charliecloud.enabled = true
122 | conda.enabled = false
123 | docker.enabled = false
124 | singularity.enabled = false
125 | podman.enabled = false
126 | shifter.enabled = false
127 | apptainer.enabled = false
128 | }
129 | apptainer {
130 | apptainer.enabled = true
131 | apptainer.autoMounts = true
132 | conda.enabled = false
133 | docker.enabled = false
134 | singularity.enabled = false
135 | podman.enabled = false
136 | shifter.enabled = false
137 | charliecloud.enabled = false
138 | }
139 | wave {
140 | apptainer.ociAutoPull = true
141 | singularity.ociAutoPull = true
142 | wave.enabled = true
143 | wave.freeze = true
144 | wave.strategy = 'conda,container'
145 | }
146 | test { includeConfig 'conf/test.config' }
147 | test_full { includeConfig 'conf/test_full.config' }
148 | }
149 |
150 |
151 |
152 | // Set default registry for Apptainer, Docker, Podman, Charliecloud and Singularity independent of -profile
153 | // Will not be used unless Apptainer / Docker / Podman / Charliecloud / Singularity are enabled
154 | // Set to your registry if you have a mirror of containers
155 | apptainer.registry = 'quay.io'
156 | docker.registry = 'quay.io'
157 | podman.registry = 'quay.io'
158 | singularity.registry = 'quay.io'
159 | charliecloud.registry = 'quay.io'
160 |
161 | // Load igenomes.config if required
162 | includeConfig !params.igenomes_ignore ? 'conf/igenomes.config' : 'conf/igenomes_ignored.config'
163 |
164 | // Export these variables to prevent local Python/R libraries from conflicting with those in the container
165 | // The JULIA depot path has been adjusted to a fixed path `/usr/local/share/julia` that needs to be used for packages in the container.
166 | // See https://apeltzer.github.io/post/03-julia-lang-nextflow/ for details on that. Once we have a common agreement on where to keep Julia packages, this is adjustable.
167 |
168 | env {
169 | PYTHONNOUSERSITE = 1
170 | R_PROFILE_USER = "/.Rprofile"
171 | R_ENVIRON_USER = "/.Renviron"
172 | JULIA_DEPOT_PATH = "/usr/local/share/julia"
173 | }
174 |
175 | // Set bash options
176 | process.shell = """\
177 | bash
178 |
179 | set -e # Exit if a tool returns a non-zero status/exit code
180 | set -u # Treat unset variables and parameters as an error
181 | set -o pipefail # Returns the status of the last command to exit with a non-zero status or zero if all successfully execute
182 | set -C # No clobber - prevent output redirection from overwriting files.
183 | """
184 |
185 | // Disable process selector warnings by default. Use debug profile to enable warnings.
186 | nextflow.enable.configProcessNamesValidation = false
187 |
188 | timeline {
189 | enabled = true
190 | file = "${params.outdir}/pipeline_info/execution_timeline_${params.trace_report_suffix}.html"
191 | }
192 | report {
193 | enabled = true
194 | file = "${params.outdir}/pipeline_info/execution_report_${params.trace_report_suffix}.html"
195 | }
196 | trace {
197 | enabled = true
198 | file = "${params.outdir}/pipeline_info/execution_trace_${params.trace_report_suffix}.txt"
199 | }
200 | dag {
201 | enabled = true
202 | file = "${params.outdir}/pipeline_info/pipeline_dag_${params.trace_report_suffix}.html"
203 | }
204 |
205 | manifest {
206 | name = 'seqeralabs/nf-dragen'
207 | author = """Adam Talbot, Harshil Patel, Graham Wright""" // The author field is deprecated from Nextflow version 24.10.0, use contributors instead
208 | contributors = [
209 | [
210 | name: 'Adam Talbot',
211 | affiliation: 'Seqera',
212 | email: 'adam.talbot@seqera.io',
213 | github: '@adamrtalbot',
214 | contribution: ['maintainer'], // List of contribution types ('author', 'maintainer' or 'contributor')
215 | orcid: ''
216 | ],
217 | [
218 | name: 'Harshil Patel',
219 | affiliation: 'Seqera',
220 | email: 'harshil.patel@seqera.io',
221 | github: '@drpatelh',
222 | contribution: ['author'], // List of contribution types ('author', 'maintainer' or 'contributor')
223 | orcid: ''
224 | ],
225 | [
226 | name: 'Graham Wright',
227 | affiliation: 'Seqera',
228 | email: 'graham.wright@seqera.io',
229 | github: '@gwright99',
230 | contribution: ['contributor'], // List of contribution types ('author', 'maintainer' or 'contributor')
231 | orcid: ''
232 | ],
233 | ]
234 | homePage = 'https://github.com/seqeralabs/nf-dragen'
235 | description = """nf-dragen is a simple, proof-of-concept Nextflow pipeline to run the Illumina DRAGEN licensed suite of tools."""
236 | mainScript = 'main.nf'
237 | defaultBranch = 'master'
238 | nextflowVersion = '!>=24.04.2'
239 | version = '1.0.0dev'
240 | doi = ''
241 | }
242 |
243 | // Nextflow plugins
244 | plugins {
245 | id 'nf-schema@2.1.1' // Validation of pipeline parameters and creation of an input channel from a sample sheet
246 | }
247 |
248 | validation {
249 | defaultIgnoreParams = ["genomes"]
250 | monochromeLogs = params.monochrome_logs
251 | help {
252 | enabled = true
253 | command = "nextflow run seqeralabs/nf-dragen -profile --input samplesheet.csv --outdir "
254 | fullParameter = "help_full"
255 | showHiddenParameter = "show_hidden"
256 | }
257 | }
258 |
259 | // Load modules.config for DSL2 module specific options
260 | includeConfig 'conf/modules.config'
261 |
--------------------------------------------------------------------------------
/nextflow_schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://raw.githubusercontent.com/seqeralabs/nf-dragen/master/nextflow_schema.json",
4 | "title": "seqeralabs/nf-dragen pipeline parameters",
5 | "description": "nf-dragen is a simple, proof-of-concept Nextflow pipeline to run the Illumina DRAGEN licensed suite of tools.",
6 | "type": "object",
7 | "$defs": {
8 | "input_output_options": {
9 | "title": "Input/output options",
10 | "type": "object",
11 | "fa_icon": "fas fa-terminal",
12 | "description": "Define where the pipeline should find input data and save output data.",
13 | "required": ["input", "outdir"],
14 | "properties": {
15 | "input": {
16 | "type": "string",
17 | "format": "file-path",
18 | "exists": true,
19 | "schema": "assets/schema_input.json",
20 | "mimetype": "text/csv",
21 | "pattern": "^\\S+\\.csv$",
22 | "description": "Path to comma-separated file containing information about the samples in the experiment.",
23 | "help_text": "You will need to create a design 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 3 columns, and a header row.",
24 | "fa_icon": "fas fa-file-csv"
25 | },
26 | "outdir": {
27 | "type": "string",
28 | "format": "directory-path",
29 | "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.",
30 | "fa_icon": "fas fa-folder-open"
31 | },
32 | "seq_type": {
33 | "type": "string",
34 | "default": "dna",
35 | "description": "Default type of sequencing (dna, rna etc). Can be overridden in the samplesheet using the column `seq_type`.",
36 | "fa_icon": "fas fa-dna",
37 | "enum": ["dna", "rna"]
38 | },
39 | "multiqc_title": {
40 | "type": "string",
41 | "description": "MultiQC report title. Printed as page header, used for filename if not otherwise specified.",
42 | "fa_icon": "fas fa-file-signature"
43 | }
44 | }
45 | },
46 | "tools": {
47 | "title": "Tools",
48 | "type": "object",
49 | "description": "Control pipeline behaviour",
50 | "default": "",
51 | "properties": {
52 | "skip_fastqc": {
53 | "type": "boolean",
54 | "description": "Skip running FASTQC"
55 | },
56 | "skip_multiqc": {
57 | "type": "boolean",
58 | "description": "Skip running MultiQC"
59 | },
60 | "skip_dragen": {
61 | "type": "boolean",
62 | "description": "Skip running DRAGEN steps"
63 | }
64 | }
65 | },
66 | "reference_genome_options": {
67 | "title": "Reference genome options",
68 | "type": "object",
69 | "fa_icon": "fas fa-dna",
70 | "description": "Reference genome related files and options required for the workflow.",
71 | "properties": {
72 | "genome": {
73 | "type": "string",
74 | "description": "Name of iGenomes reference.",
75 | "fa_icon": "fas fa-book",
76 | "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."
77 | },
78 | "fasta": {
79 | "type": "string",
80 | "description": "Path to FASTA file",
81 | "fa_icon": "fas fa-dna"
82 | },
83 | "dragen_index_dna": {
84 | "type": "string",
85 | "description": "Path to DNA index created by Dragen.",
86 | "help_text": "Use a DNA index created using Dragen with argument '--build-hash-table true'. This parameter is *mandatory* if `--fasta` or `--genome` is not specified.",
87 | "fa_icon": "far fa-file-alt",
88 | "format": "directory-path"
89 | },
90 | "dragen_index_rna": {
91 | "type": "string",
92 | "description": "Path to RNA index created by Dragen.",
93 | "help_text": "Use a DNA index created using Dragen with argument '--build-hash-table true' and '--ht-build-rna-hashtable true'. This parameter is *mandatory* if `--fasta` or `--genome` is not specified.",
94 | "fa_icon": "far fa-file-alt",
95 | "format": "directory-path"
96 | },
97 | "igenomes_ignore": {
98 | "type": "boolean",
99 | "description": "Do not load the iGenomes reference config.",
100 | "fa_icon": "fas fa-ban",
101 | "hidden": true,
102 | "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`."
103 | },
104 | "igenomes_base": {
105 | "type": "string",
106 | "format": "directory-path",
107 | "description": "The base path to the igenomes reference files",
108 | "fa_icon": "fas fa-ban",
109 | "hidden": true,
110 | "default": "s3://ngi-igenomes/igenomes/"
111 | }
112 | }
113 | },
114 | "generic_options": {
115 | "title": "Generic options",
116 | "type": "object",
117 | "fa_icon": "fas fa-file-import",
118 | "description": "Less common options for the pipeline, typically set in a config file.",
119 | "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`.",
120 | "properties": {
121 | "version": {
122 | "type": "boolean",
123 | "description": "Display version and exit.",
124 | "fa_icon": "fas fa-question-circle",
125 | "hidden": true
126 | },
127 | "publish_dir_mode": {
128 | "type": "string",
129 | "default": "copy",
130 | "description": "Method used to save pipeline results to output directory.",
131 | "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.",
132 | "fa_icon": "fas fa-copy",
133 | "enum": ["symlink", "rellink", "link", "copy", "copyNoFollow", "move"],
134 | "hidden": true
135 | },
136 | "max_multiqc_email_size": {
137 | "type": "string",
138 | "description": "File size limit when attaching MultiQC reports to summary emails.",
139 | "pattern": "^\\d+(\\.\\d+)?\\.?\\s*(K|M|G|T)?B$",
140 | "default": "25.MB",
141 | "fa_icon": "fas fa-file-upload",
142 | "hidden": true
143 | },
144 | "monochrome_logs": {
145 | "type": "boolean",
146 | "description": "Do not use coloured log outputs.",
147 | "fa_icon": "fas fa-palette",
148 | "hidden": true
149 | },
150 | "multiqc_config": {
151 | "type": "string",
152 | "format": "file-path",
153 | "description": "Custom config file to supply to MultiQC.",
154 | "fa_icon": "fas fa-cog",
155 | "hidden": true
156 | },
157 | "multiqc_logo": {
158 | "type": "string",
159 | "description": "Custom logo file to supply to MultiQC. File name must also be set in the MultiQC config file",
160 | "fa_icon": "fas fa-image",
161 | "hidden": true
162 | },
163 | "multiqc_methods_description": {
164 | "type": "string",
165 | "description": "Custom MultiQC yaml file containing HTML including a methods description.",
166 | "fa_icon": "fas fa-cog",
167 | "hidden": true
168 | },
169 | "validate_params": {
170 | "type": "boolean",
171 | "description": "Boolean whether to validate parameters against the schema at runtime",
172 | "default": true,
173 | "fa_icon": "fas fa-check-square",
174 | "hidden": true
175 | },
176 | "pipelines_testdata_base_path": {
177 | "type": "string",
178 | "fa_icon": "far fa-check-circle",
179 | "description": "Base URL or local path to location of pipeline test dataset files",
180 | "default": "https://raw.githubusercontent.com/nf-core/test-datasets/",
181 | "hidden": true
182 | },
183 | "trace_report_suffix": {
184 | "type": "string",
185 | "fa_icon": "far calendar",
186 | "description": "Suffix to add to the trace report filename. Default is the date and time in the format yyyy-MM-dd_HH-mm-ss.",
187 | "hidden": true
188 | }
189 | }
190 | }
191 | },
192 | "allOf": [
193 | {
194 | "$ref": "#/$defs/input_output_options"
195 | },
196 | {
197 | "$ref": "#/$defs/tools"
198 | },
199 | {
200 | "$ref": "#/$defs/reference_genome_options"
201 | },
202 | {
203 | "$ref": "#/$defs/generic_options"
204 | }
205 | ]
206 | }
207 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/modules/nf-core/fastqc/tests/main.nf.test:
--------------------------------------------------------------------------------
1 | nextflow_process {
2 |
3 | name "Test Process FASTQC"
4 | script "../main.nf"
5 | process "FASTQC"
6 |
7 | tag "modules"
8 | tag "modules_nfcore"
9 | tag "fastqc"
10 |
11 | test("sarscov2 single-end [fastq]") {
12 |
13 | when {
14 | process {
15 | """
16 | input[0] = Channel.of([
17 | [ id: 'test', single_end:true ],
18 | [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ]
19 | ])
20 | """
21 | }
22 | }
23 |
24 | then {
25 | assertAll (
26 | { assert process.success },
27 | // NOTE The report contains the date inside it, which means that the md5sum is stable per day, but not longer than that. So you can't md5sum it.
28 | // looks like this:
29 | // https://github.com/nf-core/modules/pull/3903#issuecomment-1743620039
30 | { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" },
31 | { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" },
32 | { assert path(process.out.html[0][1]).text.contains("| File type | Conventional base calls |
") },
33 | { assert snapshot(process.out.versions).match() }
34 | )
35 | }
36 | }
37 |
38 | test("sarscov2 paired-end [fastq]") {
39 |
40 | when {
41 | process {
42 | """
43 | input[0] = Channel.of([
44 | [id: 'test', single_end: false], // meta map
45 | [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
46 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ]
47 | ])
48 | """
49 | }
50 | }
51 |
52 | then {
53 | assertAll (
54 | { assert process.success },
55 | { assert process.out.html[0][1][0] ==~ ".*/test_1_fastqc.html" },
56 | { assert process.out.html[0][1][1] ==~ ".*/test_2_fastqc.html" },
57 | { assert process.out.zip[0][1][0] ==~ ".*/test_1_fastqc.zip" },
58 | { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" },
59 | { assert path(process.out.html[0][1][0]).text.contains("| File type | Conventional base calls |
") },
60 | { assert path(process.out.html[0][1][1]).text.contains("| File type | Conventional base calls |
") },
61 | { assert snapshot(process.out.versions).match() }
62 | )
63 | }
64 | }
65 |
66 | test("sarscov2 interleaved [fastq]") {
67 |
68 | when {
69 | process {
70 | """
71 | input[0] = Channel.of([
72 | [id: 'test', single_end: false], // meta map
73 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true)
74 | ])
75 | """
76 | }
77 | }
78 |
79 | then {
80 | assertAll (
81 | { assert process.success },
82 | { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" },
83 | { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" },
84 | { assert path(process.out.html[0][1]).text.contains("| File type | Conventional base calls |
") },
85 | { assert snapshot(process.out.versions).match() }
86 | )
87 | }
88 | }
89 |
90 | test("sarscov2 paired-end [bam]") {
91 |
92 | when {
93 | process {
94 | """
95 | input[0] = Channel.of([
96 | [id: 'test', single_end: false], // meta map
97 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true)
98 | ])
99 | """
100 | }
101 | }
102 |
103 | then {
104 | assertAll (
105 | { assert process.success },
106 | { assert process.out.html[0][1] ==~ ".*/test_fastqc.html" },
107 | { assert process.out.zip[0][1] ==~ ".*/test_fastqc.zip" },
108 | { assert path(process.out.html[0][1]).text.contains("| File type | Conventional base calls |
") },
109 | { assert snapshot(process.out.versions).match() }
110 | )
111 | }
112 | }
113 |
114 | test("sarscov2 multiple [fastq]") {
115 |
116 | when {
117 | process {
118 | """
119 | input[0] = Channel.of([
120 | [id: 'test', single_end: false], // meta map
121 | [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
122 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true),
123 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_1.fastq.gz', checkIfExists: true),
124 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_2.fastq.gz', checkIfExists: true) ]
125 | ])
126 | """
127 | }
128 | }
129 |
130 | then {
131 | assertAll (
132 | { assert process.success },
133 | { assert process.out.html[0][1][0] ==~ ".*/test_1_fastqc.html" },
134 | { assert process.out.html[0][1][1] ==~ ".*/test_2_fastqc.html" },
135 | { assert process.out.html[0][1][2] ==~ ".*/test_3_fastqc.html" },
136 | { assert process.out.html[0][1][3] ==~ ".*/test_4_fastqc.html" },
137 | { assert process.out.zip[0][1][0] ==~ ".*/test_1_fastqc.zip" },
138 | { assert process.out.zip[0][1][1] ==~ ".*/test_2_fastqc.zip" },
139 | { assert process.out.zip[0][1][2] ==~ ".*/test_3_fastqc.zip" },
140 | { assert process.out.zip[0][1][3] ==~ ".*/test_4_fastqc.zip" },
141 | { assert path(process.out.html[0][1][0]).text.contains("| File type | Conventional base calls |
") },
142 | { assert path(process.out.html[0][1][1]).text.contains("| File type | Conventional base calls |
") },
143 | { assert path(process.out.html[0][1][2]).text.contains("| File type | Conventional base calls |
") },
144 | { assert path(process.out.html[0][1][3]).text.contains("| File type | Conventional base calls |
") },
145 | { assert snapshot(process.out.versions).match() }
146 | )
147 | }
148 | }
149 |
150 | test("sarscov2 custom_prefix") {
151 |
152 | when {
153 | process {
154 | """
155 | input[0] = Channel.of([
156 | [ id:'mysample', single_end:true ], // meta map
157 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)
158 | ])
159 | """
160 | }
161 | }
162 |
163 | then {
164 | assertAll (
165 | { assert process.success },
166 | { assert process.out.html[0][1] ==~ ".*/mysample_fastqc.html" },
167 | { assert process.out.zip[0][1] ==~ ".*/mysample_fastqc.zip" },
168 | { assert path(process.out.html[0][1]).text.contains("| File type | Conventional base calls |
") },
169 | { assert snapshot(process.out.versions).match() }
170 | )
171 | }
172 | }
173 |
174 | test("sarscov2 single-end [fastq] - stub") {
175 |
176 | options "-stub"
177 | when {
178 | process {
179 | """
180 | input[0] = Channel.of([
181 | [ id: 'test', single_end:true ],
182 | [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true) ]
183 | ])
184 | """
185 | }
186 | }
187 |
188 | then {
189 | assertAll (
190 | { assert process.success },
191 | { assert snapshot(process.out).match() }
192 | )
193 | }
194 | }
195 |
196 | test("sarscov2 paired-end [fastq] - stub") {
197 |
198 | options "-stub"
199 | when {
200 | process {
201 | """
202 | input[0] = Channel.of([
203 | [id: 'test', single_end: false], // meta map
204 | [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
205 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true) ]
206 | ])
207 | """
208 | }
209 | }
210 |
211 | then {
212 | assertAll (
213 | { assert process.success },
214 | { assert snapshot(process.out).match() }
215 | )
216 | }
217 | }
218 |
219 | test("sarscov2 interleaved [fastq] - stub") {
220 |
221 | options "-stub"
222 | when {
223 | process {
224 | """
225 | input[0] = Channel.of([
226 | [id: 'test', single_end: false], // meta map
227 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_interleaved.fastq.gz', checkIfExists: true)
228 | ])
229 | """
230 | }
231 | }
232 |
233 | then {
234 | assertAll (
235 | { assert process.success },
236 | { assert snapshot(process.out).match() }
237 | )
238 | }
239 | }
240 |
241 | test("sarscov2 paired-end [bam] - stub") {
242 |
243 | options "-stub"
244 | when {
245 | process {
246 | """
247 | input[0] = Channel.of([
248 | [id: 'test', single_end: false], // meta map
249 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true)
250 | ])
251 | """
252 | }
253 | }
254 |
255 | then {
256 | assertAll (
257 | { assert process.success },
258 | { assert snapshot(process.out).match() }
259 | )
260 | }
261 | }
262 |
263 | test("sarscov2 multiple [fastq] - stub") {
264 |
265 | options "-stub"
266 | when {
267 | process {
268 | """
269 | input[0] = Channel.of([
270 | [id: 'test', single_end: false], // meta map
271 | [ file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true),
272 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_2.fastq.gz', checkIfExists: true),
273 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_1.fastq.gz', checkIfExists: true),
274 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test2_2.fastq.gz', checkIfExists: true) ]
275 | ])
276 | """
277 | }
278 | }
279 |
280 | then {
281 | assertAll (
282 | { assert process.success },
283 | { assert snapshot(process.out).match() }
284 | )
285 | }
286 | }
287 |
288 | test("sarscov2 custom_prefix - stub") {
289 |
290 | options "-stub"
291 | when {
292 | process {
293 | """
294 | input[0] = Channel.of([
295 | [ id:'mysample', single_end:true ], // meta map
296 | file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/fastq/test_1.fastq.gz', checkIfExists: true)
297 | ])
298 | """
299 | }
300 | }
301 |
302 | then {
303 | assertAll (
304 | { assert process.success },
305 | { assert snapshot(process.out).match() }
306 | )
307 | }
308 | }
309 | }
310 |
--------------------------------------------------------------------------------
/modules/nf-core/fastqc/tests/main.nf.test.snap:
--------------------------------------------------------------------------------
1 | {
2 | "sarscov2 custom_prefix": {
3 | "content": [
4 | [
5 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
6 | ]
7 | ],
8 | "meta": {
9 | "nf-test": "0.9.0",
10 | "nextflow": "24.04.3"
11 | },
12 | "timestamp": "2024-07-22T11:02:16.374038"
13 | },
14 | "sarscov2 single-end [fastq] - stub": {
15 | "content": [
16 | {
17 | "0": [
18 | [
19 | {
20 | "id": "test",
21 | "single_end": true
22 | },
23 | "test.html:md5,d41d8cd98f00b204e9800998ecf8427e"
24 | ]
25 | ],
26 | "1": [
27 | [
28 | {
29 | "id": "test",
30 | "single_end": true
31 | },
32 | "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e"
33 | ]
34 | ],
35 | "2": [
36 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
37 | ],
38 | "html": [
39 | [
40 | {
41 | "id": "test",
42 | "single_end": true
43 | },
44 | "test.html:md5,d41d8cd98f00b204e9800998ecf8427e"
45 | ]
46 | ],
47 | "versions": [
48 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
49 | ],
50 | "zip": [
51 | [
52 | {
53 | "id": "test",
54 | "single_end": true
55 | },
56 | "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e"
57 | ]
58 | ]
59 | }
60 | ],
61 | "meta": {
62 | "nf-test": "0.9.0",
63 | "nextflow": "24.04.3"
64 | },
65 | "timestamp": "2024-07-22T11:02:24.993809"
66 | },
67 | "sarscov2 custom_prefix - stub": {
68 | "content": [
69 | {
70 | "0": [
71 | [
72 | {
73 | "id": "mysample",
74 | "single_end": true
75 | },
76 | "mysample.html:md5,d41d8cd98f00b204e9800998ecf8427e"
77 | ]
78 | ],
79 | "1": [
80 | [
81 | {
82 | "id": "mysample",
83 | "single_end": true
84 | },
85 | "mysample.zip:md5,d41d8cd98f00b204e9800998ecf8427e"
86 | ]
87 | ],
88 | "2": [
89 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
90 | ],
91 | "html": [
92 | [
93 | {
94 | "id": "mysample",
95 | "single_end": true
96 | },
97 | "mysample.html:md5,d41d8cd98f00b204e9800998ecf8427e"
98 | ]
99 | ],
100 | "versions": [
101 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
102 | ],
103 | "zip": [
104 | [
105 | {
106 | "id": "mysample",
107 | "single_end": true
108 | },
109 | "mysample.zip:md5,d41d8cd98f00b204e9800998ecf8427e"
110 | ]
111 | ]
112 | }
113 | ],
114 | "meta": {
115 | "nf-test": "0.9.0",
116 | "nextflow": "24.04.3"
117 | },
118 | "timestamp": "2024-07-22T11:03:10.93942"
119 | },
120 | "sarscov2 interleaved [fastq]": {
121 | "content": [
122 | [
123 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
124 | ]
125 | ],
126 | "meta": {
127 | "nf-test": "0.9.0",
128 | "nextflow": "24.04.3"
129 | },
130 | "timestamp": "2024-07-22T11:01:42.355718"
131 | },
132 | "sarscov2 paired-end [bam]": {
133 | "content": [
134 | [
135 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
136 | ]
137 | ],
138 | "meta": {
139 | "nf-test": "0.9.0",
140 | "nextflow": "24.04.3"
141 | },
142 | "timestamp": "2024-07-22T11:01:53.276274"
143 | },
144 | "sarscov2 multiple [fastq]": {
145 | "content": [
146 | [
147 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
148 | ]
149 | ],
150 | "meta": {
151 | "nf-test": "0.9.0",
152 | "nextflow": "24.04.3"
153 | },
154 | "timestamp": "2024-07-22T11:02:05.527626"
155 | },
156 | "sarscov2 paired-end [fastq]": {
157 | "content": [
158 | [
159 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
160 | ]
161 | ],
162 | "meta": {
163 | "nf-test": "0.9.0",
164 | "nextflow": "24.04.3"
165 | },
166 | "timestamp": "2024-07-22T11:01:31.188871"
167 | },
168 | "sarscov2 paired-end [fastq] - stub": {
169 | "content": [
170 | {
171 | "0": [
172 | [
173 | {
174 | "id": "test",
175 | "single_end": false
176 | },
177 | "test.html:md5,d41d8cd98f00b204e9800998ecf8427e"
178 | ]
179 | ],
180 | "1": [
181 | [
182 | {
183 | "id": "test",
184 | "single_end": false
185 | },
186 | "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e"
187 | ]
188 | ],
189 | "2": [
190 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
191 | ],
192 | "html": [
193 | [
194 | {
195 | "id": "test",
196 | "single_end": false
197 | },
198 | "test.html:md5,d41d8cd98f00b204e9800998ecf8427e"
199 | ]
200 | ],
201 | "versions": [
202 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
203 | ],
204 | "zip": [
205 | [
206 | {
207 | "id": "test",
208 | "single_end": false
209 | },
210 | "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e"
211 | ]
212 | ]
213 | }
214 | ],
215 | "meta": {
216 | "nf-test": "0.9.0",
217 | "nextflow": "24.04.3"
218 | },
219 | "timestamp": "2024-07-22T11:02:34.273566"
220 | },
221 | "sarscov2 multiple [fastq] - stub": {
222 | "content": [
223 | {
224 | "0": [
225 | [
226 | {
227 | "id": "test",
228 | "single_end": false
229 | },
230 | "test.html:md5,d41d8cd98f00b204e9800998ecf8427e"
231 | ]
232 | ],
233 | "1": [
234 | [
235 | {
236 | "id": "test",
237 | "single_end": false
238 | },
239 | "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e"
240 | ]
241 | ],
242 | "2": [
243 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
244 | ],
245 | "html": [
246 | [
247 | {
248 | "id": "test",
249 | "single_end": false
250 | },
251 | "test.html:md5,d41d8cd98f00b204e9800998ecf8427e"
252 | ]
253 | ],
254 | "versions": [
255 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
256 | ],
257 | "zip": [
258 | [
259 | {
260 | "id": "test",
261 | "single_end": false
262 | },
263 | "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e"
264 | ]
265 | ]
266 | }
267 | ],
268 | "meta": {
269 | "nf-test": "0.9.0",
270 | "nextflow": "24.04.3"
271 | },
272 | "timestamp": "2024-07-22T11:03:02.304411"
273 | },
274 | "sarscov2 single-end [fastq]": {
275 | "content": [
276 | [
277 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
278 | ]
279 | ],
280 | "meta": {
281 | "nf-test": "0.9.0",
282 | "nextflow": "24.04.3"
283 | },
284 | "timestamp": "2024-07-22T11:01:19.095607"
285 | },
286 | "sarscov2 interleaved [fastq] - stub": {
287 | "content": [
288 | {
289 | "0": [
290 | [
291 | {
292 | "id": "test",
293 | "single_end": false
294 | },
295 | "test.html:md5,d41d8cd98f00b204e9800998ecf8427e"
296 | ]
297 | ],
298 | "1": [
299 | [
300 | {
301 | "id": "test",
302 | "single_end": false
303 | },
304 | "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e"
305 | ]
306 | ],
307 | "2": [
308 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
309 | ],
310 | "html": [
311 | [
312 | {
313 | "id": "test",
314 | "single_end": false
315 | },
316 | "test.html:md5,d41d8cd98f00b204e9800998ecf8427e"
317 | ]
318 | ],
319 | "versions": [
320 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
321 | ],
322 | "zip": [
323 | [
324 | {
325 | "id": "test",
326 | "single_end": false
327 | },
328 | "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e"
329 | ]
330 | ]
331 | }
332 | ],
333 | "meta": {
334 | "nf-test": "0.9.0",
335 | "nextflow": "24.04.3"
336 | },
337 | "timestamp": "2024-07-22T11:02:44.640184"
338 | },
339 | "sarscov2 paired-end [bam] - stub": {
340 | "content": [
341 | {
342 | "0": [
343 | [
344 | {
345 | "id": "test",
346 | "single_end": false
347 | },
348 | "test.html:md5,d41d8cd98f00b204e9800998ecf8427e"
349 | ]
350 | ],
351 | "1": [
352 | [
353 | {
354 | "id": "test",
355 | "single_end": false
356 | },
357 | "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e"
358 | ]
359 | ],
360 | "2": [
361 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
362 | ],
363 | "html": [
364 | [
365 | {
366 | "id": "test",
367 | "single_end": false
368 | },
369 | "test.html:md5,d41d8cd98f00b204e9800998ecf8427e"
370 | ]
371 | ],
372 | "versions": [
373 | "versions.yml:md5,e1cc25ca8af856014824abd842e93978"
374 | ],
375 | "zip": [
376 | [
377 | {
378 | "id": "test",
379 | "single_end": false
380 | },
381 | "test.zip:md5,d41d8cd98f00b204e9800998ecf8427e"
382 | ]
383 | ]
384 | }
385 | ],
386 | "meta": {
387 | "nf-test": "0.9.0",
388 | "nextflow": "24.04.3"
389 | },
390 | "timestamp": "2024-07-22T11:02:53.550742"
391 | }
392 | }
--------------------------------------------------------------------------------
/docs/usage.md:
--------------------------------------------------------------------------------
1 | # seqeralabs/nf-dragen: Usage
2 |
3 | > _Documentation of pipeline parameters is generated automatically from the pipeline schema and can no longer be found in markdown files._
4 |
5 | ## Introduction
6 |
7 | ## Samplesheet input
8 |
9 | You will need to create a samplesheet with information about the samples you would like to analyse before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row as shown in the examples below.
10 |
11 | ```bash
12 | --input '[path to samplesheet file]'
13 | ```
14 |
15 | ### Multiple runs of the same sample
16 |
17 | The `sample` identifiers have to be the same when you have re-sequenced the same sample more than once e.g. to increase sequencing depth. The pipeline will analyse the raw reads together in the Dragen software before performing any downstream analysis. Below is an example for the same sample sequenced across 3 lanes:
18 |
19 | ```csv title="samplesheet.csv"
20 | sample,fastq_1,fastq_2
21 | CONTROL_REP1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz
22 | CONTROL_REP1,AEG588A1_S1_L003_R1_001.fastq.gz,AEG588A1_S1_L003_R2_001.fastq.gz
23 | CONTROL_REP1,AEG588A1_S1_L004_R1_001.fastq.gz,AEG588A1_S1_L004_R2_001.fastq.gz
24 | ```
25 |
26 | ### Sequencing type
27 |
28 | The pipeline can handle RNA or DNA samples, including a mixture of both. By default, every sample will be considered to be the type defined as `--seq_type`, which defaults to `dna`. You can override this on a per-sample basis using the `seq_type` column:
29 |
30 | ```csv
31 | sample,seq_type,fastq_1,fastq_2
32 | dnaSample,dna,dna_R1_001.fastq.gz,dna_R2_001.fastq.gz
33 | rnaSample,rna,rna_R1_001.fastq.gz,rna_R2_001.fastq.gz
34 | ```
35 |
36 | ### Full samplesheet
37 |
38 | The pipeline will auto-detect whether a sample is single- or paired-end using the information provided in the samplesheet. The samplesheet can have as many columns as you desire, however, there is a strict requirement for the first 3 columns to match those defined in the table below.
39 |
40 | A final samplesheet file consisting of both single- and paired-end data may look something like the one below. This is for 6 samples, where `TREATMENT_REP3` has been sequenced twice.
41 |
42 | ```csv title="samplesheet.csv"
43 | sample,fastq_1,fastq_2
44 | CONTROL_REP1,AEG588A1_S1_L002_R1_001.fastq.gz,AEG588A1_S1_L002_R2_001.fastq.gz
45 | CONTROL_REP2,AEG588A2_S2_L002_R1_001.fastq.gz,AEG588A2_S2_L002_R2_001.fastq.gz
46 | CONTROL_REP3,AEG588A3_S3_L002_R1_001.fastq.gz,AEG588A3_S3_L002_R2_001.fastq.gz
47 | TREATMENT_REP1,AEG588A4_S4_L003_R1_001.fastq.gz,
48 | TREATMENT_REP2,AEG588A5_S5_L003_R1_001.fastq.gz,
49 | TREATMENT_REP3,AEG588A6_S6_L003_R1_001.fastq.gz,
50 | TREATMENT_REP3,AEG588A6_S6_L004_R1_001.fastq.gz,
51 | ```
52 |
53 | | Column | Description |
54 | | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
55 | | `sample` | Custom sample name. This entry will be identical for multiple sequencing libraries/runs from the same sample. Spaces in sample names are automatically converted to underscores (`_`). |
56 | | `seq_type` | Sequencing type, currently restricted to `dna` or `rna`. This decides the sequencing pathway to take when running the pipeline. The pipeline can handle a mixture of sequencing types. If this is left empty, it will use `params.seq_type` as the value, default `dna`. |
57 | | `fastq_1` | Full path to FastQ file for Illumina short reads 1. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". |
58 | | `fastq_2` | Full path to FastQ file for Illumina short reads 2. File has to be gzipped and have the extension ".fastq.gz" or ".fq.gz". |
59 |
60 | An [example samplesheet](../assets/samplesheet.csv) has been provided with the pipeline.
61 |
62 | ## Configuring the genome
63 |
64 | We can configure a genome in multiple ways:
65 |
66 | 1. Supply a `--genome`, which retrieves uses the genome build FASTA automatically and proceeds from step 2.
67 | 2. Supply a `--fasta` and which Dragen will build a genome index for alignment
68 | 3. If you have already performed a pipeline run using `1.` or `.2.`, the reference index will be written to a results directory at `${params.outdir}/genome/index/dragen_index_dna` or `${params.outdir}/genome/index/dragen_index_rna`. You can reuse these indexes by supplying the parameter `--dragen_index_dna` and/or `--dragen_index_rna` which will skip 1 and 2 for DNA and RNA respectively.
69 |
70 | ## Running the pipeline
71 |
72 | The typical command for running the pipeline is as follows:
73 |
74 | ```console
75 | nextflow run seqeralabs/nf-dragen --input samplesheet.csv --genome GRCh37 -profile docker
76 | ```
77 |
78 | This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles.
79 |
80 | Note that the pipeline will create the following files in your working directory:
81 |
82 | ```bash
83 | work # Directory containing the nextflow working files
84 | # Finished results in specified location (defined with --outdir)
85 | .nextflow_log # Log file from Nextflow
86 | # Other nextflow hidden files, eg. history of pipeline runs and old logs.
87 | ```
88 |
89 | If you wish to repeatedly use the same parameters for multiple runs, rather than specifying each flag in the command, you can specify these in a params file.
90 |
91 | Pipeline settings can be provided in a `yaml` or `json` file via `-params-file `.
92 |
93 | :::warning
94 | Do not use `-c ` to specify parameters as this will result in errors. Custom config files specified with `-c` must only be used for [tuning process resource specifications](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources), other infrastructural tweaks (such as output directories), or module arguments (args).
95 | :::
96 |
97 | The above pipeline run specified with a params file in yaml format:
98 |
99 | ```bash
100 | nextflow run seqeralabs/nf-dragen -profile docker -params-file params.yaml
101 | ```
102 |
103 | with `params.yaml` containing:
104 |
105 | ```yaml
106 | input: './samplesheet.csv'
107 | outdir: './results/'
108 | genome: 'GRCh37'
109 | <...>
110 | ```
111 |
112 | You can also generate such `YAML`/`JSON` files via [nf-core/launch](https://nf-co.re/launch).
113 |
114 | ### Updating the pipeline
115 |
116 | 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:
117 |
118 | ```bash
119 | nextflow pull seqeralabs/nf-dragen
120 | ```
121 |
122 | ### Reproducibility
123 |
124 | It is 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.
125 |
126 | First, go to the [seqeralabs/nf-dragen releases page](https://github.com/seqeralabs/nf-dragen/releases) and find the latest pipeline version - numeric only (eg. `1.3.1`). Then specify this when running the pipeline with `-r` (one hyphen) - eg. `-r 1.3.1`. Of course, you can switch to another version by changing the number after the `-r` flag.
127 |
128 | 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. For example, at the bottom of the MultiQC reports.
129 |
130 | To further assist in reproducbility, you can use share and re-use [parameter files](#running-the-pipeline) to repeat pipeline runs with the same settings without having to write out a command with every single parameter.
131 |
132 | :::tip
133 | If you wish to share such profile (such as upload as supplementary material for academic publications), make sure to NOT include cluster specific paths to files, nor institutional specific profiles.
134 | :::
135 |
136 | ## Core Nextflow arguments
137 |
138 | :::note
139 | These options are part of Nextflow and use a _single_ hyphen (pipeline parameters use a double-hyphen).
140 | :::
141 |
142 | ### `-profile`
143 |
144 | Use this parameter to choose a configuration profile. Profiles can give configuration presets for different compute environments.
145 |
146 | Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Podman, Shifter, Charliecloud, Apptainer, Conda) - see below.
147 |
148 | :::info
149 | We highly recommend the use of Docker or Singularity containers for full pipeline reproducibility, however when this is not possible, Conda is also supported.
150 | :::
151 |
152 | 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).
153 |
154 | Note that multiple profiles can be loaded, for example: `-profile test,docker` - the order of arguments is important!
155 | They are loaded in sequence, so later profiles can overwrite earlier profiles.
156 |
157 | 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, since it can lead to different results on different machines dependent on the computer enviroment.
158 |
159 | - `test`
160 | - A profile with a complete configuration for automated testing
161 | - Includes links to test data so needs no other parameters
162 | - `docker`
163 | - A generic configuration profile to be used with [Docker](https://docker.com/)
164 | - `singularity`
165 | - A generic configuration profile to be used with [Singularity](https://sylabs.io/docs/)
166 | - `podman`
167 | - A generic configuration profile to be used with [Podman](https://podman.io/)
168 | - `shifter`
169 | - A generic configuration profile to be used with [Shifter](https://nersc.gitlab.io/development/shifter/how-to-use/)
170 | - `charliecloud`
171 | - A generic configuration profile to be used with [Charliecloud](https://hpc.github.io/charliecloud/)
172 | - `apptainer`
173 | - A generic configuration profile to be used with [Apptainer](https://apptainer.org/)
174 | - `wave`
175 | - A generic configuration profile to enable [Wave](https://seqera.io/wave/) containers. Use together with one of the above (requires Nextflow ` 24.03.0-edge` or later).
176 | - `conda`
177 | - A generic configuration profile to be used with [Conda](https://conda.io/docs/). Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker, Singularity, Podman, Shifter, Charliecloud, or Apptainer.
178 |
179 | ### `-resume`
180 |
181 | Specify this when restarting a pipeline. Nextflow will use cached results from any pipeline steps where the inputs are the same, continuing from where it got to previously. For input to be considered the same, not only the names must be identical but the files' contents as well. For more info about this parameter, see [this blog post](https://www.nextflow.io/blog/2019/demystifying-nextflow-resume.html).
182 |
183 | 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.
184 |
185 | ### `-c`
186 |
187 | 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.
188 |
189 | ## Custom configuration
190 |
191 | ### Resource requests
192 |
193 | Whilst the default requirements set within the pipeline will hopefully work for most people and with most input data, you may find that you want to customise the compute resources that the pipeline requests. 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 any of the error codes specified [here](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/conf/base.config#L18) it will automatically be resubmitted with higher requests (2 x original, then 3 x original). If it still fails after the third attempt then the pipeline execution is stopped.
194 |
195 | To change the resource requests, please see the [max resources](https://nf-co.re/docs/usage/configuration#max-resources) and [tuning workflow resources](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources) section of the nf-core website.
196 |
197 | ### Custom Containers
198 |
199 | In some cases you may wish to change which container or conda environment a step of the pipeline uses for a particular tool. By default nf-core pipelines use containers and software from the [biocontainers](https://biocontainers.pro/) or [bioconda](https://bioconda.github.io/) projects. However in some cases the pipeline specified version maybe out of date.
200 |
201 | To use a different container from the default container or conda environment specified in a pipeline, please see the [updating tool versions](https://nf-co.re/docs/usage/configuration#updating-tool-versions) section of the nf-core website.
202 |
203 | ### Custom Tool Arguments
204 |
205 | A pipeline might not always support every possible argument or option of a particular tool used in pipeline. Fortunately, nf-core pipelines provide some freedom to users to insert additional parameters that the pipeline does not include by default.
206 |
207 | To learn how to provide additional arguments to a particular tool of the pipeline, please see the [customising tool arguments](https://nf-co.re/docs/usage/configuration#customising-tool-arguments) section of the nf-core website.
208 |
209 | ### nf-core/configs
210 |
211 | In most cases, you will only need to create a custom config as a one-off but if you and others within your organisation are likely to be running nf-core pipelines regularly and need to use the same settings 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. 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.
212 |
213 | See the main [Nextflow documentation](https://www.nextflow.io/docs/latest/config.html) for more information about creating your own configuration files.
214 |
215 | 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).
216 |
217 | ## Azure Resource Requests
218 |
219 | To be used with the `azurebatch` profile by specifying the `-profile azurebatch`.
220 | We recommend providing a compute `params.vm_type` of `Standard_D16_v3` VMs by default but these options can be changed if required.
221 |
222 | Note that the choice of VM size depends on your quota and the overall workload during the analysis.
223 | For a thorough list, please refer the [Azure Sizes for virtual machines in Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes).
224 |
225 | ## Running in the background
226 |
227 | Nextflow handles job submissions and supervises the running jobs. The Nextflow process must run until the pipeline is finished.
228 |
229 | 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.
230 |
231 | Alternatively, you can use `screen` / `tmux` or similar tool to create a detached session which you can log back into at a later time.
232 | Some HPC setups also allow you to run nextflow within a cluster job submitted your job scheduler (from where it submits more jobs).
233 |
234 | ## Nextflow memory requirements
235 |
236 | In some cases, the Nextflow Java virtual machines can start to request a large amount of memory.
237 | We recommend adding the following line to your environment to limit this (typically in `~/.bashrc` or `~./bash_profile`):
238 |
239 | ```bash
240 | NXF_OPTS='-Xms1g -Xmx4g'
241 | ```
242 |
--------------------------------------------------------------------------------
/subworkflows/nf-core/utils_nfcore_pipeline/main.nf:
--------------------------------------------------------------------------------
1 | //
2 | // Subworkflow with utility functions specific to the nf-core pipeline template
3 | //
4 |
5 | /*
6 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 | SUBWORKFLOW DEFINITION
8 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 | */
10 |
11 | workflow UTILS_NFCORE_PIPELINE {
12 | take:
13 | nextflow_cli_args
14 |
15 | main:
16 | valid_config = checkConfigProvided()
17 | checkProfileProvided(nextflow_cli_args)
18 |
19 | emit:
20 | valid_config
21 | }
22 |
23 | /*
24 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 | FUNCTIONS
26 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 | */
28 |
29 | //
30 | // Warn if a -profile or Nextflow config has not been provided to run the pipeline
31 | //
32 | def checkConfigProvided() {
33 | def valid_config = true as Boolean
34 | if (workflow.profile == 'standard' && workflow.configFiles.size() <= 1) {
35 | log.warn(
36 | "[${workflow.manifest.name}] You are attempting to run the pipeline without any custom configuration!\n\n" + "This will be dependent on your local compute environment but can be achieved via one or more of the following:\n" + " (1) Using an existing pipeline profile e.g. `-profile docker` or `-profile singularity`\n" + " (2) Using an existing nf-core/configs for your Institution e.g. `-profile crick` or `-profile uppmax`\n" + " (3) Using your own local custom config e.g. `-c /path/to/your/custom.config`\n\n" + "Please refer to the quick start section and usage docs for the pipeline.\n "
37 | )
38 | valid_config = false
39 | }
40 | return valid_config
41 | }
42 |
43 | //
44 | // Exit pipeline if --profile contains spaces
45 | //
46 | def checkProfileProvided(nextflow_cli_args) {
47 | if (workflow.profile.endsWith(',')) {
48 | error(
49 | "The `-profile` option cannot end with a trailing comma, please remove it and re-run the pipeline!\n" + "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n"
50 | )
51 | }
52 | if (nextflow_cli_args[0]) {
53 | log.warn(
54 | "nf-core pipelines do not accept positional arguments. The positional argument `${nextflow_cli_args[0]}` has been detected.\n" + "HINT: A common mistake is to provide multiple values separated by spaces e.g. `-profile test, docker`.\n"
55 | )
56 | }
57 | }
58 |
59 | //
60 | // Generate workflow version string
61 | //
62 | def getWorkflowVersion() {
63 | def version_string = "" as String
64 | if (workflow.manifest.version) {
65 | def prefix_v = workflow.manifest.version[0] != 'v' ? 'v' : ''
66 | version_string += "${prefix_v}${workflow.manifest.version}"
67 | }
68 |
69 | if (workflow.commitId) {
70 | def git_shortsha = workflow.commitId.substring(0, 7)
71 | version_string += "-g${git_shortsha}"
72 | }
73 |
74 | return version_string
75 | }
76 |
77 | //
78 | // Get software versions for pipeline
79 | //
80 | def processVersionsFromYAML(yaml_file) {
81 | def yaml = new org.yaml.snakeyaml.Yaml()
82 | def versions = yaml.load(yaml_file).collectEntries { k, v -> [k.tokenize(':')[-1], v] }
83 | return yaml.dumpAsMap(versions).trim()
84 | }
85 |
86 | //
87 | // Get workflow version for pipeline
88 | //
89 | def workflowVersionToYAML() {
90 | return """
91 | Workflow:
92 | ${workflow.manifest.name}: ${getWorkflowVersion()}
93 | Nextflow: ${workflow.nextflow.version}
94 | """.stripIndent().trim()
95 | }
96 |
97 | //
98 | // Get channel of software versions used in pipeline in YAML format
99 | //
100 | def softwareVersionsToYAML(ch_versions) {
101 | return ch_versions.unique().map { version -> processVersionsFromYAML(version) }.unique().mix(Channel.of(workflowVersionToYAML()))
102 | }
103 |
104 | //
105 | // Get workflow summary for MultiQC
106 | //
107 | def paramsSummaryMultiqc(summary_params) {
108 | def summary_section = ''
109 | summary_params
110 | .keySet()
111 | .each { group ->
112 | def group_params = summary_params.get(group)
113 | // This gets the parameters of that particular group
114 | if (group_params) {
115 | summary_section += " ${group}
\n"
116 | summary_section += " \n"
117 | group_params
118 | .keySet()
119 | .sort()
120 | .each { param ->
121 | summary_section += " - ${param}
- ${group_params.get(param) ?: 'N/A'}
\n"
122 | }
123 | summary_section += "
\n"
124 | }
125 | }
126 |
127 | def yaml_file_text = "id: '${workflow.manifest.name.replace('/', '-')}-summary'\n" as String
128 | yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n"
129 | yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n"
130 | yaml_file_text += "section_href: 'https://github.com/${workflow.manifest.name}'\n"
131 | yaml_file_text += "plot_type: 'html'\n"
132 | yaml_file_text += "data: |\n"
133 | yaml_file_text += "${summary_section}"
134 |
135 | return yaml_file_text
136 | }
137 |
138 | //
139 | // ANSII colours used for terminal logging
140 | //
141 | def logColours(monochrome_logs=true) {
142 | def colorcodes = [:] as Map
143 |
144 | // Reset / Meta
145 | colorcodes['reset'] = monochrome_logs ? '' : "\033[0m"
146 | colorcodes['bold'] = monochrome_logs ? '' : "\033[1m"
147 | colorcodes['dim'] = monochrome_logs ? '' : "\033[2m"
148 | colorcodes['underlined'] = monochrome_logs ? '' : "\033[4m"
149 | colorcodes['blink'] = monochrome_logs ? '' : "\033[5m"
150 | colorcodes['reverse'] = monochrome_logs ? '' : "\033[7m"
151 | colorcodes['hidden'] = monochrome_logs ? '' : "\033[8m"
152 |
153 | // Regular Colors
154 | colorcodes['black'] = monochrome_logs ? '' : "\033[0;30m"
155 | colorcodes['red'] = monochrome_logs ? '' : "\033[0;31m"
156 | colorcodes['green'] = monochrome_logs ? '' : "\033[0;32m"
157 | colorcodes['yellow'] = monochrome_logs ? '' : "\033[0;33m"
158 | colorcodes['blue'] = monochrome_logs ? '' : "\033[0;34m"
159 | colorcodes['purple'] = monochrome_logs ? '' : "\033[0;35m"
160 | colorcodes['cyan'] = monochrome_logs ? '' : "\033[0;36m"
161 | colorcodes['white'] = monochrome_logs ? '' : "\033[0;37m"
162 |
163 | // Bold
164 | colorcodes['bblack'] = monochrome_logs ? '' : "\033[1;30m"
165 | colorcodes['bred'] = monochrome_logs ? '' : "\033[1;31m"
166 | colorcodes['bgreen'] = monochrome_logs ? '' : "\033[1;32m"
167 | colorcodes['byellow'] = monochrome_logs ? '' : "\033[1;33m"
168 | colorcodes['bblue'] = monochrome_logs ? '' : "\033[1;34m"
169 | colorcodes['bpurple'] = monochrome_logs ? '' : "\033[1;35m"
170 | colorcodes['bcyan'] = monochrome_logs ? '' : "\033[1;36m"
171 | colorcodes['bwhite'] = monochrome_logs ? '' : "\033[1;37m"
172 |
173 | // Underline
174 | colorcodes['ublack'] = monochrome_logs ? '' : "\033[4;30m"
175 | colorcodes['ured'] = monochrome_logs ? '' : "\033[4;31m"
176 | colorcodes['ugreen'] = monochrome_logs ? '' : "\033[4;32m"
177 | colorcodes['uyellow'] = monochrome_logs ? '' : "\033[4;33m"
178 | colorcodes['ublue'] = monochrome_logs ? '' : "\033[4;34m"
179 | colorcodes['upurple'] = monochrome_logs ? '' : "\033[4;35m"
180 | colorcodes['ucyan'] = monochrome_logs ? '' : "\033[4;36m"
181 | colorcodes['uwhite'] = monochrome_logs ? '' : "\033[4;37m"
182 |
183 | // High Intensity
184 | colorcodes['iblack'] = monochrome_logs ? '' : "\033[0;90m"
185 | colorcodes['ired'] = monochrome_logs ? '' : "\033[0;91m"
186 | colorcodes['igreen'] = monochrome_logs ? '' : "\033[0;92m"
187 | colorcodes['iyellow'] = monochrome_logs ? '' : "\033[0;93m"
188 | colorcodes['iblue'] = monochrome_logs ? '' : "\033[0;94m"
189 | colorcodes['ipurple'] = monochrome_logs ? '' : "\033[0;95m"
190 | colorcodes['icyan'] = monochrome_logs ? '' : "\033[0;96m"
191 | colorcodes['iwhite'] = monochrome_logs ? '' : "\033[0;97m"
192 |
193 | // Bold High Intensity
194 | colorcodes['biblack'] = monochrome_logs ? '' : "\033[1;90m"
195 | colorcodes['bired'] = monochrome_logs ? '' : "\033[1;91m"
196 | colorcodes['bigreen'] = monochrome_logs ? '' : "\033[1;92m"
197 | colorcodes['biyellow'] = monochrome_logs ? '' : "\033[1;93m"
198 | colorcodes['biblue'] = monochrome_logs ? '' : "\033[1;94m"
199 | colorcodes['bipurple'] = monochrome_logs ? '' : "\033[1;95m"
200 | colorcodes['bicyan'] = monochrome_logs ? '' : "\033[1;96m"
201 | colorcodes['biwhite'] = monochrome_logs ? '' : "\033[1;97m"
202 |
203 | return colorcodes
204 | }
205 |
206 | // Return a single report from an object that may be a Path or List
207 | //
208 | def getSingleReport(multiqc_reports) {
209 | if (multiqc_reports instanceof Path) {
210 | return multiqc_reports
211 | } else if (multiqc_reports instanceof List) {
212 | if (multiqc_reports.size() == 0) {
213 | log.warn("[${workflow.manifest.name}] No reports found from process 'MULTIQC'")
214 | return null
215 | } else if (multiqc_reports.size() == 1) {
216 | return multiqc_reports.first()
217 | } else {
218 | log.warn("[${workflow.manifest.name}] Found multiple reports from process 'MULTIQC', will use only one")
219 | return multiqc_reports.first()
220 | }
221 | } else {
222 | return null
223 | }
224 | }
225 |
226 | //
227 | // Construct and send completion email
228 | //
229 | def completionEmail(summary_params, email, email_on_fail, plaintext_email, outdir, monochrome_logs=true, multiqc_report=null) {
230 |
231 | // Set up the e-mail variables
232 | def subject = "[${workflow.manifest.name}] Successful: ${workflow.runName}"
233 | if (!workflow.success) {
234 | subject = "[${workflow.manifest.name}] FAILED: ${workflow.runName}"
235 | }
236 |
237 | def summary = [:]
238 | summary_params
239 | .keySet()
240 | .sort()
241 | .each { group ->
242 | summary << summary_params[group]
243 | }
244 |
245 | def misc_fields = [:]
246 | misc_fields['Date Started'] = workflow.start
247 | misc_fields['Date Completed'] = workflow.complete
248 | misc_fields['Pipeline script file path'] = workflow.scriptFile
249 | misc_fields['Pipeline script hash ID'] = workflow.scriptId
250 | if (workflow.repository) {
251 | misc_fields['Pipeline repository Git URL'] = workflow.repository
252 | }
253 | if (workflow.commitId) {
254 | misc_fields['Pipeline repository Git Commit'] = workflow.commitId
255 | }
256 | if (workflow.revision) {
257 | misc_fields['Pipeline Git branch/tag'] = workflow.revision
258 | }
259 | misc_fields['Nextflow Version'] = workflow.nextflow.version
260 | misc_fields['Nextflow Build'] = workflow.nextflow.build
261 | misc_fields['Nextflow Compile Timestamp'] = workflow.nextflow.timestamp
262 |
263 | def email_fields = [:]
264 | email_fields['version'] = getWorkflowVersion()
265 | email_fields['runName'] = workflow.runName
266 | email_fields['success'] = workflow.success
267 | email_fields['dateComplete'] = workflow.complete
268 | email_fields['duration'] = workflow.duration
269 | email_fields['exitStatus'] = workflow.exitStatus
270 | email_fields['errorMessage'] = (workflow.errorMessage ?: 'None')
271 | email_fields['errorReport'] = (workflow.errorReport ?: 'None')
272 | email_fields['commandLine'] = workflow.commandLine
273 | email_fields['projectDir'] = workflow.projectDir
274 | email_fields['summary'] = summary << misc_fields
275 |
276 | // On success try attach the multiqc report
277 | def mqc_report = getSingleReport(multiqc_report)
278 |
279 | // Check if we are only sending emails on failure
280 | def email_address = email
281 | if (!email && email_on_fail && !workflow.success) {
282 | email_address = email_on_fail
283 | }
284 |
285 | // Render the TXT template
286 | def engine = new groovy.text.GStringTemplateEngine()
287 | def tf = new File("${workflow.projectDir}/assets/email_template.txt")
288 | def txt_template = engine.createTemplate(tf).make(email_fields)
289 | def email_txt = txt_template.toString()
290 |
291 | // Render the HTML template
292 | def hf = new File("${workflow.projectDir}/assets/email_template.html")
293 | def html_template = engine.createTemplate(hf).make(email_fields)
294 | def email_html = html_template.toString()
295 |
296 | // Render the sendmail template
297 | def max_multiqc_email_size = (params.containsKey('max_multiqc_email_size') ? params.max_multiqc_email_size : 0) as MemoryUnit
298 | def smail_fields = [email: email_address, subject: subject, email_txt: email_txt, email_html: email_html, projectDir: "${workflow.projectDir}", mqcFile: mqc_report, mqcMaxSize: max_multiqc_email_size.toBytes()]
299 | def sf = new File("${workflow.projectDir}/assets/sendmail_template.txt")
300 | def sendmail_template = engine.createTemplate(sf).make(smail_fields)
301 | def sendmail_html = sendmail_template.toString()
302 |
303 | // Send the HTML e-mail
304 | def colors = logColours(monochrome_logs) as Map
305 | if (email_address) {
306 | try {
307 | if (plaintext_email) {
308 | new org.codehaus.groovy.GroovyException('Send plaintext e-mail, not HTML')
309 | }
310 | // Try to send HTML e-mail using sendmail
311 | def sendmail_tf = new File(workflow.launchDir.toString(), ".sendmail_tmp.html")
312 | sendmail_tf.withWriter { w -> w << sendmail_html }
313 | ['sendmail', '-t'].execute() << sendmail_html
314 | log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (sendmail)-")
315 | }
316 | catch (Exception msg) {
317 | log.debug(msg.toString())
318 | log.debug("Trying with mail instead of sendmail")
319 | // Catch failures and try with plaintext
320 | def mail_cmd = ['mail', '-s', subject, '--content-type=text/html', email_address]
321 | mail_cmd.execute() << email_html
322 | log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Sent summary e-mail to ${email_address} (mail)-")
323 | }
324 | }
325 |
326 | // Write summary e-mail HTML to a file
327 | def output_hf = new File(workflow.launchDir.toString(), ".pipeline_report.html")
328 | output_hf.withWriter { w -> w << email_html }
329 | nextflow.extension.FilesEx.copyTo(output_hf.toPath(), "${outdir}/pipeline_info/pipeline_report.html")
330 | output_hf.delete()
331 |
332 | // Write summary e-mail TXT to a file
333 | def output_tf = new File(workflow.launchDir.toString(), ".pipeline_report.txt")
334 | output_tf.withWriter { w -> w << email_txt }
335 | nextflow.extension.FilesEx.copyTo(output_tf.toPath(), "${outdir}/pipeline_info/pipeline_report.txt")
336 | output_tf.delete()
337 | }
338 |
339 | //
340 | // Print pipeline summary on completion
341 | //
342 | def completionSummary(monochrome_logs=true) {
343 | def colors = logColours(monochrome_logs) as Map
344 | if (workflow.success) {
345 | if (workflow.stats.ignoredCount == 0) {
346 | log.info("-${colors.purple}[${workflow.manifest.name}]${colors.green} Pipeline completed successfully${colors.reset}-")
347 | }
348 | else {
349 | log.info("-${colors.purple}[${workflow.manifest.name}]${colors.yellow} Pipeline completed successfully, but with errored process(es) ${colors.reset}-")
350 | }
351 | }
352 | else {
353 | log.info("-${colors.purple}[${workflow.manifest.name}]${colors.red} Pipeline completed with errors${colors.reset}-")
354 | }
355 | }
356 |
357 | //
358 | // Construct and send a notification to a web server as JSON e.g. Microsoft Teams and Slack
359 | //
360 | def imNotification(summary_params, hook_url) {
361 | def summary = [:]
362 | summary_params
363 | .keySet()
364 | .sort()
365 | .each { group ->
366 | summary << summary_params[group]
367 | }
368 |
369 | def misc_fields = [:]
370 | misc_fields['start'] = workflow.start
371 | misc_fields['complete'] = workflow.complete
372 | misc_fields['scriptfile'] = workflow.scriptFile
373 | misc_fields['scriptid'] = workflow.scriptId
374 | if (workflow.repository) {
375 | misc_fields['repository'] = workflow.repository
376 | }
377 | if (workflow.commitId) {
378 | misc_fields['commitid'] = workflow.commitId
379 | }
380 | if (workflow.revision) {
381 | misc_fields['revision'] = workflow.revision
382 | }
383 | misc_fields['nxf_version'] = workflow.nextflow.version
384 | misc_fields['nxf_build'] = workflow.nextflow.build
385 | misc_fields['nxf_timestamp'] = workflow.nextflow.timestamp
386 |
387 | def msg_fields = [:]
388 | msg_fields['version'] = getWorkflowVersion()
389 | msg_fields['runName'] = workflow.runName
390 | msg_fields['success'] = workflow.success
391 | msg_fields['dateComplete'] = workflow.complete
392 | msg_fields['duration'] = workflow.duration
393 | msg_fields['exitStatus'] = workflow.exitStatus
394 | msg_fields['errorMessage'] = (workflow.errorMessage ?: 'None')
395 | msg_fields['errorReport'] = (workflow.errorReport ?: 'None')
396 | msg_fields['commandLine'] = workflow.commandLine.replaceFirst(/ +--hook_url +[^ ]+/, "")
397 | msg_fields['projectDir'] = workflow.projectDir
398 | msg_fields['summary'] = summary << misc_fields
399 |
400 | // Render the JSON template
401 | def engine = new groovy.text.GStringTemplateEngine()
402 | // Different JSON depending on the service provider
403 | // Defaults to "Adaptive Cards" (https://adaptivecards.io), except Slack which has its own format
404 | def json_path = hook_url.contains("hooks.slack.com") ? "slackreport.json" : "adaptivecard.json"
405 | def hf = new File("${workflow.projectDir}/assets/${json_path}")
406 | def json_template = engine.createTemplate(hf).make(msg_fields)
407 | def json_message = json_template.toString()
408 |
409 | // POST
410 | def post = new URL(hook_url).openConnection()
411 | post.setRequestMethod("POST")
412 | post.setDoOutput(true)
413 | post.setRequestProperty("Content-Type", "application/json")
414 | post.getOutputStream().write(json_message.getBytes("UTF-8"))
415 | def postRC = post.getResponseCode()
416 | if (!postRC.equals(200)) {
417 | log.warn(post.getErrorStream().getText())
418 | }
419 | }
420 |
--------------------------------------------------------------------------------