diff --git a/.github/markdownlint.yml b/.github/markdownlint.yml deleted file mode 100644 index 8d7eb53b..00000000 --- a/.github/markdownlint.yml +++ /dev/null @@ -1,12 +0,0 @@ -# Markdownlint configuration file -default: true -line-length: false -no-duplicate-header: - siblings_only: true -no-inline-html: - allowed_elements: - - img - - p - - kbd - - details - - summary diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 3f7f793b..6c6c71d7 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -14,19 +14,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Launch workflow via tower - uses: nf-core/tower-action@master + uses: nf-core/tower-action@v2 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} - bearer_token: ${{ secrets.TOWER_BEARER_TOKEN }} + access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_COMPUTE_ENV }} pipeline: ${{ github.repository }} - revision: ${{ github.sha }} - workdir: s3://${{ secrets.AWS_S3_BUCKET }}/mhcquant/work-${{ github.sha }} - # Add full size test data (but still relatively small datasets for few samples) - # on the `test_full.config` test runs with only one set of parameters - # Then specify `-profile test_full` instead of `-profile test` on the AWS batch command + revision: ${{ github.sha } } + workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/mhcquant/work-${{ github.sha }} parameters: | { - "outdir" : "s3://${{ secrets.AWS_S3_BUCKET }}/mhcquant/results-${{ github.sha }}", + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/mhcquant/results-${{ github.sha }}" } - profiles: '[ "test_full", "aws_tower" ]' + profiles: test,aws_tower + pre_run_script: 'export NXF_VER=21.10.3' diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index 1247ea86..acc6f70b 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -1,40 +1,28 @@ name: nf-core AWS test -# This workflow is triggered on push to the master branch. -# It can be additionally triggered manually with GitHub actions workflow dispatch. -# It runs the -profile 'test' on AWS batch. +# This workflow can be triggered manually with the GitHub actions workflow dispatch button. +# It runs the -profile 'test' on AWS batch on: workflow_dispatch: - -env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - TOWER_ACCESS_TOKEN: ${{ secrets.AWS_TOWER_TOKEN }} - AWS_JOB_DEFINITION: ${{ secrets.AWS_JOB_DEFINITION }} - AWS_JOB_QUEUE: ${{ secrets.AWS_JOB_QUEUE }} - AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} - jobs: - run-awstest: + run-tower: name: Run AWS tests if: github.repository == 'nf-core/mhcquant' runs-on: ubuntu-latest steps: - - name: Setup Miniconda - uses: conda-incubator/setup-miniconda@v2 - with: - auto-update-conda: true - python-version: 3.7 - - name: Install awscli - run: conda install -c conda-forge awscli - - name: Start AWS batch job + - name: Launch workflow via tower + uses: nf-core/tower-action@v2 - # For example: adding multiple test runs with different parameters - # Remember that you can parallelise this by using strategy.matrix - run: | - aws batch submit-job \ - --region eu-west-1 \ - --job-name nf-core-mhcquant \ - --job-queue $AWS_JOB_QUEUE \ - --job-definition $AWS_JOB_DEFINITION \ - --container-overrides '{"command": ["nf-core/mhcquant", "-r '"${GITHUB_SHA}"' -profile test --outdir s3://'"${AWS_S3_BUCKET}"'/mhcquant/results-'"${GITHUB_SHA}"' -w s3://'"${AWS_S3_BUCKET}"'/mhcquant/work-'"${GITHUB_SHA}"' -with-tower"], "environment": [{"name": "TOWER_ACCESS_TOKEN", "value": "'"$TOWER_ACCESS_TOKEN"'"}]}' + with: + workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} + access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} + compute_env: ${{ secrets.TOWER_COMPUTE_ENV }} + pipeline: ${{ github.repository }} + revision: ${{ github.sha }} + workdir: s3://${{ secrets.AWS_S3_BUCKET }}/work/mhcquant/work-${{ github.sha }} + parameters: | + { + "outdir": "s3://${{ secrets.AWS_S3_BUCKET }}/mhcquant/results-${{ github.sha }}" + } + profiles: test,aws_tower + pre_run_script: 'export NXF_VER=21.10.3' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8bdbcb6c..510e8f01 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: strategy: matrix: # Nextflow versions: check pipeline minimum and current latest - nxf_ver: ["21.04.0", ""] + nxf_ver: ['21.10.3', ''] steps: - name: Check out pipeline code uses: actions/checkout@v2 diff --git a/CHANGELOG.md b/CHANGELOG.md index b4be8e18..c720e121 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # nf-core/mhcquant: Changelog +## v2.1.0 nf-core/mhcquant "Olive Tin Hamster" - 2021/12/09 + +### `Added` + +- Inclusion of assets/schema_input.json +- Added the multiQC again to report the versions +- MHCquant parameters are now directly assigned to the argument of the + +### `Fixed` + +- Fixed typos +- [#165] - Raise memory requirements of FeatureFinderIdentification step +- [#176] - Pipeline crashes when setting the --skip_quantification flag + +### `Dependencies` + +Note, since the pipeline is now using Nextflow DSL2, each process will be run with its own [Biocontainer](https://biocontainers.pro/#/registry). This means that on occasion it is entirely possible for the pipeline to be using different versions of the same tool. However, the overall software dependency changes compared to the last release have been listed below for reference. + +| Dependency | Old version | New version | +| --------------------- | ----------- | ----------- | +| `openms` | 2.5.0 | 2.6.0 | +| `openms-thirdparty` | 2.5.0 | 2.6.0 | +| `thermorawfileparser` | 1.2.3 | 1.3.4 | + +> **NB:** Dependency has been **updated** if both old and new version information is present. +> **NB:** Dependency has been **added** if just the new version information is present. +> **NB:** Dependency has been **removed** if version information isn't present. + +### `Deprecated` + ## v2.0.0 nf-core/mhcquant "Steel Beagle" - 2021/09/03 ### `Added` @@ -60,7 +90,7 @@ DSL1 to DSL2 conversion - raise OpenMS version to 2.5 - adapt workflow accoringly with new options -- remove specifying input as file dirs eg "data/*.mzML" +- remove specifying input as file dirs eg "data/\*.mzML" ### `Dependencies` diff --git a/CITATIONS.md b/CITATIONS.md index c0923c3d..68d4abe9 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -1,4 +1,4 @@ -# nf-core/rnaseq: Citations +# nf-core/mhcquant: Citations ## [nf-core](https://pubmed.ncbi.nlm.nih.gov/32055031/) @@ -22,6 +22,9 @@ * [OpenMS](https://pubmed.ncbi.nlm.nih.gov/27575624/) > Röst H, Sachsenberg T, Aiche S, Bielow C, Weisser H, Aicheler F, Andreotti S, Ehrlich HC, Gutenbrunner P, Kenar E, Liang X, Nahnsen S, Nilse L, Pfeuffer J, Rosenberger G, Rurik M, Schmitt U, Veit J, Walzer M, Wojnar D, Wolski WE, Schilling O, Choudhary JS, Malmström L, Aebersold R, Reinert K, Kohlbacher O. OpenMS: a flexible open-source software platform for mass spectrometry data analysis. Nat Methods 13, 741–748 (2016). doi: 10.1038/nmeth.3959. PubMed PMID: 27575624 +* [MultiQC](https://www.ncbi.nlm.nih.gov/pubmed/27312411/) + > Ewels P, Magnusson M, Lundin S, Käller M. MultiQC: summarize analysis results for multiple tools and samples in a single report. Bioinformatics. 2016 Oct 1;32(19):3047-8. doi: 10.1093/bioinformatics/btw354. Epub 2016 Jun 16. PubMed PMID: 27312411; PubMed Central PMCID: PMC5039924. + ## Software packaging/containerisation tools * [Anaconda](https://anaconda.com) diff --git a/LICENSE b/LICENSE index dcab23b0..43eea689 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) Leon Bichmann +Copyright (c) Leon Bichmann, Marissa Dubbelaar Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index df4296f4..2a9651db 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,53 @@ # ![nf-core/mhcquant](docs/images/nf-core-mhcquant_logo.png) -**Identify and quantify peptides from mass spectrometry raw data**. +[![GitHub Actions CI Status](https://github.com/nf-core/mhcquant/workflows/nf-core%20CI/badge.svg)](https://github.com/nf-core/mhcquant/actions?query=workflow%3A%22nf-core+CI%22) +[![GitHub Actions Linting Status](https://github.com/nf-core/mhcquant/workflows/nf-core%20linting/badge.svg)](https://github.com/nf-core/mhcquant/actions?query=workflow%3A%22nf-core+linting%22) +[![AWS CI](https://img.shields.io/badge/CI%20tests-full%20size-FF9900?labelColor=000000&logo=Amazon%20AWS)](https://nf-co.re/mhcquant/results) +[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.5407955-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.5407955) -[![GitHub Actions CI Status](https://github.com/nf-core/mhcquant/workflows/nf-core%20CI/badge.svg)](https://github.com/nf-core/mhcquant/actions) -[![GitHub Actions Linting Status](https://github.com/nf-core/mhcquant/workflows/nf-core%20linting/badge.svg)](https://github.com/nf-core/mhcquant/actions) -[![Nextflow](https://img.shields.io/badge/nextflow-%E2%89%A521.04.0-brightgreen.svg)](https://www.nextflow.io/) +[![Nextflow](https://img.shields.io/badge/nextflow%20DSL2-%E2%89%A521.10.3-23aa62.svg?labelColor=000000)](https://www.nextflow.io/) +[![run with conda](http://img.shields.io/badge/run%20with-conda-3EB049?labelColor=000000&logo=anaconda)](https://docs.conda.io/en/latest/) +[![run with docker](https://img.shields.io/badge/run%20with-docker-0db7ed?labelColor=000000&logo=docker)](https://www.docker.com/) +[![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/) -[![install with bioconda](https://img.shields.io/badge/install%20with-bioconda-brightgreen.svg)](https://bioconda.github.io/) -[![Docker](https://img.shields.io/docker/automated/nfcore/mhcquant.svg)](https://hub.docker.com/r/nfcore/mhcquant) -[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23mhcquant-4A154B?logo=slack)](https://nfcore.slack.com/channels/mhcquant) +[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23mhcquant-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/mhcquant) +[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core) +[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core) ## Introduction -nfcore/mhcquant is a bioinformatics analysis pipeline used for quantitative processing of data dependent (DDA) peptidomics data. +**nfcore/mhcquant** is a bioinformatics analysis pipeline used for quantitative processing of data dependent (DDA) peptidomics data. It was specifically designed to analyse immunopeptidomics data, which deals with the analysis of affinity purified, unspecifically cleaved peptides that have recently been discussed intensively in [the context of cancer vaccines](https://www.nature.com/articles/ncomms13404). The workflow is based on the OpenMS C++ framework for computational mass spectrometry. RAW files (mzML) serve as inputs and a database search (Comet) is performed based on a given input protein database. FDR rescoring is applied using Percolator based on a competitive target-decoy approach (reversed decoys). For label free quantification all input files undergo identification based retention time alignment (MapAlignerIdentification), and targeted feature extraction matching ids between runs (FeatureFinderIdentification). In addition, a variant calling file (vcf) can be specified to translate variants into proteins that will be included in the database search and binding predictions on specified alleles (alleles.tsv) using MHCFlurry (Class 1) or MHCNugget (Class 2) can be directly run on the output peptide lists. Moreover, if a vcf file was specified, neoepitopes will automatically be determined and binding predictions can also directly be predicted for them. -The pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It comes with docker containers making installation trivial and results highly reproducible. +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/Singularity containers making installation trivial and results highly reproducible. The [Nextflow DSL2](https://www.nextflow.io/docs/latest/dsl2.html) implementation of this pipeline uses one container per process which makes it much easier to maintain and update software dependencies. Where possible, these processes have been submitted to and installed from [nf-core/modules](https://github.com/nf-core/modules) in order to make them available to all nf-core pipelines, and to everyone within the Nextflow community! + +On release, automated continuous integration tests run the pipeline on a full-sized dataset on the AWS cloud infrastructure. This ensures that the pipeline runs on AWS, has sensible resource allocation defaults set to run on real-world datasets, and permits the persistent storage of results to benchmark between pipeline releases and other analysis sources. The results obtained from the full-sized test can be viewed on the [nf-core website](https://nf-co.re/mhcquant/results). + +## Pipeline summary + +1. Present QC for raw reads ([`MultiQC`](http://multiqc.info/)) ![overview](assets/MHCquant_scheme.png) (This chart was created with the help of [Lucidchart](https://www.lucidchart.com)) ## Quick Start -1. Install [`nextflow`](https://nf-co.re/usage/installation) (`>=21.04.0`) +1. Install [`Nextflow`](https://www.nextflow.io/docs/latest/getstarted.html#installation) (`>=21.10.3`) -2. Install any of [`Docker`](https://docs.docker.com/engine/installation/), [`Singularity`](https://www.sylabs.io/guides/3.0/user-guide/), [`Podman`](https://podman.io/), [`Shifter`](https://nersc.gitlab.io/development/shifter/how-to-use/) or [`Charliecloud`](https://hpc.github.io/charliecloud/) for full pipeline reproducibility _(please only use [`Conda`](https://conda.io/miniconda.html) as a last resort; see [docs](https://nf-co.re/usage/configuration#basic-configuration-profiles))_ +2. Install any of [`Docker`](https://docs.docker.com/engine/installation/), [`Singularity`](https://www.sylabs.io/guides/3.0/user-guide/), [`Podman`](https://podman.io/), [`Shifter`](https://nersc.gitlab.io/development/shifter/how-to-use/) or [`Charliecloud`](https://hpc.github.io/charliecloud/) for full pipeline reproducibility _(please only use [`Conda`](https://conda.io/miniconda.html) as a last resort; see [docs](https://nf-co.re/usage/configuration#basic-configuration-profiles))_. 3. Download the pipeline and test it on a minimal dataset with a single command: - ```bash + ```console nextflow run nf-core/mhcquant -profile test, ``` - > Please check [nf-core/configs](https://github.com/nf-core/configs#documentation) to see if a custom config file to run nf-core pipelines already exists for your Institute. If so, you can simply use `-profile ` in your command. This will enable either `docker` or `singularity` and set the appropriate execution settings for your local compute environment. + > * Please check [nf-core/configs](https://github.com/nf-core/configs#documentation) to see if a custom config file to run nf-core pipelines already exists for your Institute. If so, you can simply use `-profile ` in your command. This will enable either `docker` or `singularity` and set the appropriate execution settings for your local compute environment. + > * If you are using `singularity` then the pipeline will auto-detect this and attempt to download the Singularity images directly as opposed to performing a conversion from Docker images. If you are persistently observing issues downloading Singularity images directly due to timeout or network issues then please use the `--singularity_pull_docker_container` parameter to pull and convert the Docker image instead. Alternatively, it is highly recommended to use the [`nf-core download`](https://nf-co.re/tools/#downloading-pipelines-for-offline-use) command to pre-download all of the required containers before running the pipeline and to set the [`NXF_SINGULARITY_CACHEDIR` or `singularity.cacheDir`](https://www.nextflow.io/docs/latest/singularity.html?#singularity-docker-hub) Nextflow options to be able to store and re-use the images from a central location for future pipeline runs. + > * If you are using `conda`, it is highly recommended to use the [`NXF_CONDA_CACHEDIR` or `conda.cacheDir`](https://www.nextflow.io/docs/latest/conda.html) settings to store the environments in a central location for future pipeline runs. 4. Start running your own analysis! @@ -43,8 +55,8 @@ The pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool nextflow run nf-core/mhcquant -profile test, --input 'samples.tsv' --fasta 'SWISSPROT_2020.fasta' - --allele_sheet 'alleles.tsv' - --predict_class_1 + --allele_sheet 'alleles.tsv' + --predict_class_1 --refine_fdr_on_predicted_subset ``` @@ -84,7 +96,7 @@ For further information or help, don't hesitate to get in touch on the [Slack `# ## Citations -If you use `nf-core/mhcquant` for your analysis, please cite: +If you use `nf-core/mhcquant` for your analysis, please cite it using the following doi: [10.5281/zenodo.5407955](https://doi.org/10.5281/zenodo.5407955) and the corresponding manuscript: > **MHCquant: Automated and Reproducible Data Analysis for Immunopeptidomics** > @@ -93,6 +105,8 @@ If you use `nf-core/mhcquant` for your analysis, please cite: > Journal of Proteome Research 2019 18 (11), 3876-3884 > DOI: 10.1021/acs.jproteome.9b00313 +An extensive list of references for the tools used by the pipeline can be found in the [`CITATIONS.md`](CITATIONS.md) file. + You can cite the `nf-core` publication as follows: > **The nf-core framework for community-curated bioinformatics pipelines.** diff --git a/assets/schema_input.json b/assets/schema_input.json new file mode 100644 index 00000000..f8583477 --- /dev/null +++ b/assets/schema_input.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "https://raw.githubusercontent.com/nf-core/mhcquant/master/assets/schema_input.json", + "title": "nf-core/mhcquant pipeline - params.input schema", + "description": "Schema for the file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "ID": { + "type": "integer", + "errorMessage": "Provide an unique identifier for the replicate, must be a numeric value" + }, + "Sample": { + "type": "string", + "pattern": "^\\S+-?", + "errorMessage": "Sample name must be provided and cannot contain spaces" + }, + "Condition": { + "type": "string", + "pattern": "^\\S+-?", + "errorMessage": "Sample condition must be provided and cannot contain spaces" + }, + "ReplicateFileName": { + "type": "string", + "errorMessage": "MS file spaces and must have extension '.raw' or '.mzml'", + "anyOf": [ + { + "type": "string", + "pattern": "^\\S+-?\\.raw$" + }, + { + "type": "string", + "pattern": "^\\S+-?\\.mzml$" + } + ] + } + }, + "required": [ + "ID", + "Sample", + "Condition", + "ReplicateFileName" + ] + } +} diff --git a/bin/check_samplesheet.py b/bin/check_samplesheet.py index 0176acf3..d39d8ff3 100755 --- a/bin/check_samplesheet.py +++ b/bin/check_samplesheet.py @@ -1,7 +1,6 @@ #!/usr/bin/env python -# This script is based on the example at: https://raw.githubusercontent.com/nf-core/test-datasets/atacseq/design.csv - +# This script is based on the example at: https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv import os import sys @@ -10,7 +9,7 @@ def parse_args(args=None): - Description = "Reformat nf-core/MHCquant samplesheet file and check its contents." + Description = "Reformat nf-core/mhcquant samplesheet file and check its contents." Epilog = "Example usage: python check_samplesheet.py " parser = argparse.ArgumentParser(description=Description, epilog=Epilog) @@ -37,6 +36,7 @@ def print_error(error, context="Line", context_str=""): print(error_str) sys.exit(1) + def check_samplesheet(file_in, file_out): """ This function checks that the samplesheet follows the following structure: diff --git a/conf/base.config b/conf/base.config index 90315def..bf02eda6 100644 --- a/conf/base.config +++ b/conf/base.config @@ -1,13 +1,13 @@ + /* - * ------------------------------------------------- - * nf-core/mhcquant Nextflow base config file - * ------------------------------------------------- - * A 'blank slate' config file, appropriate for general - * use on most high performance compute environments. - * Assumes that all software is installed and available - * on the PATH. Runs in `local` mode - all jobs will be - * run on the logged in environment. - */ +======================================================================================== + nf-core/mhcquant Nextflow base config file +======================================================================================== + A 'blank slate' config file, appropriate for general use on most high performance + compute environments. Assumes that all software is installed and available on + the PATH. Runs in `local` mode - all jobs will be run on the logged in environment. +---------------------------------------------------------------------------------------- +*/ process { @@ -16,39 +16,37 @@ process { time = { check_max( 2.h * task.attempt, 'time' ) } errorStrategy = { task.exitStatus in [143,137,104,134,139] ? 'retry' : 'finish' } - maxRetries = 1 - maxErrors = '-1' + maxRetries = 1 + maxErrors = '-1' // Process-specific resource requirements // See https://www.nextflow.io/docs/latest/config.html#config-process-selectors withLabel:process_low { - cpus = { check_max( 2 * task.attempt, 'cpus' ) } - memory = { check_max( 14.GB * task.attempt, 'memory' ) } - time = { check_max( 6.h * task.attempt, 'time' ) } + cpus = { check_max( 2 * task.attempt, 'cpus' ) } + memory = { check_max( 12.GB * task.attempt, 'memory' ) } + time = { check_max( 4.h * task.attempt, 'time' ) } } withLabel:process_medium { - cpus = { check_max( 6 * task.attempt, 'cpus' ) } - memory = { check_max( 8.GB * task.attempt, 'memory' ) } - time = { check_max( 2.h * task.attempt, 'time' ) } + cpus = { check_max( 6 * task.attempt, 'cpus' ) } + memory = { check_max( 36.GB * task.attempt, 'memory' ) } + time = { check_max( 8.h * task.attempt, 'time' ) } } - withLabel:process_medium_long { - cpus = { check_max( 6 * task.attempt, 'cpus' ) } - memory = { check_max( 8.GB * task.attempt, 'memory' ) } - time = { check_max( 8.h * task.attempt, 'time' ) } + withLabel:process_high { + cpus = { check_max( 12 * task.attempt, 'cpus' ) } + memory = { check_max( 72.GB * task.attempt, 'memory' ) } + time = { check_max( 16.h * task.attempt, 'time' ) } } - withLabel:process_web { - time = { check_max( 6.h * task.attempt, 'time' ) } - errorStrategy = 'retry' - maxRetries = 10 + withLabel:process_long { + time = { check_max( 20.h * task.attempt, 'time' ) } } - withName:get_software_versions { - cache = false + withLabel:process_high_memory { + memory = { check_max( 200.GB * task.attempt, 'memory' ) } + } + withLabel:error_ignore { + errorStrategy = 'ignore' + } + withLabel:error_retry { + errorStrategy = 'retry' + maxRetries = 2 } -} - -params { - // Defaults only, expecting to be overwritten - max_memory = 128.GB - max_cpus = 12 - max_time = 240.h } diff --git a/conf/modules.config b/conf/modules.config index 954bcb81..5f31dc23 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -1,45 +1,84 @@ /* - * -------------------------------------------------- - * Config file for defining DSL2 per module options - * -------------------------------------------------- - * - * Available keys to override module options: - * args = Additional arguments appended to command in module. - * args2 = Second set of arguments appended to command in module (multi-tool modules). - * publish_dir = Directory to publish results. - * publish_by_id = Publish results in separate folders by meta.id value. - * publish_files = Groovy map where key = "file_ext" and value = "directory" to publish results for that file extension - * The value of "directory" is appended to the standard "publish_dir" path as defined above. - * If publish_files == null (unspecified) - All files are published. - * If publish_files == false - No files are published. - * suffix = File name suffix for output files. - * - */ +======================================================================================== + Config file for defining DSL2 per module options +======================================================================================== + Available keys to override module options: + args = Additional arguments appended to command in module. + args2 = Second set of arguments appended to command in module (multi-tool modules). + args3 = Third set of arguments appended to command in module (multi-tool modules). + publish_dir = Directory to publish results. + publish_by_meta = Groovy list of keys available in meta map to append as directories to "publish_dir" path + If publish_by_meta = true - Value of ${meta['id']} is appended as a directory to "publish_dir" path + If publish_by_meta = ['id', 'custompath'] - If "id" is in meta map and "custompath" isn't then "${meta['id']}/custompath/" + is appended as a directory to "publish_dir" path + If publish_by_meta = false / null - No directories are appended to "publish_dir" path + publish_files = Groovy map where key = "file_ext" and value = "directory" to publish results for that file extension + The value of "directory" is appended to the standard "publish_dir" path as defined above. + If publish_files = null (unspecified) - All files are published. + If publish_files = false - No files are published. + suffix = File name suffix for output files. +---------------------------------------------------------------------------------------- +*/ params { modules { + + 'generate_proteins_from_vcf' { + args= "-t ${params.variant_annotation_style} -r ${params.variant_reference}" + } + + 'multiqc' { + args = '' + publish_dir = "multiqc/" + } + 'openms_map_aligner_identification' { args = "-model:type linear -algorithm:max_rt_shift ${params.max_rt_alignment_shift} " } 'openms_comet_adapter' { - args = "-precursor_mass_tolerance ${params.precursor_mass_tolerance} -fragment_bin_tolerance ${params.fragment_mass_tolerance} -fragment_bin_offset ${params.fragment_bin_offset} -num_hits ${params.num_hits} -digest_mass_range ${params.digest_mass_range} -max_variable_mods_in_peptide ${params.number_mods} -allowed_missed_cleavages 0 -precursor_charge ${params.prec_charge} -activation_method ${params.activation_method} -variable_modifications ${params.variable_mods.tokenize(',').collect { "'${it}'" }.join(" ") } -fixed_modifications ${params.fixed_mods.tokenize(',').collect { "'${it}'"}.join(" ")} -enzyme '${params.enzyme}' -spectrum_batch_size ${params.spectrum_batch_size} " + args = "-precursor_mass_tolerance ${params.precursor_mass_tolerance} -fragment_mass_tolerance ${params.fragment_mass_tolerance} -fragment_bin_offset ${params.fragment_bin_offset} -num_hits ${params.num_hits} -digest_mass_range ${params.digest_mass_range} -max_variable_mods_in_peptide ${params.number_mods} -missed_cleavages 0 -precursor_charge ${params.prec_charge} -activation_method ${params.activation_method} -variable_modifications ${params.variable_mods.tokenize(',').collect { "'${it}'" }.join(" ") } -fixed_modifications ${params.fixed_mods.tokenize(',').collect { "'${it}'"}.join(" ")} -enzyme '${params.enzyme}' -spectrum_batch_size ${params.spectrum_batch_size} " } - 'generate_proteins_from_vcf' { - args= "-t ${params.variant_annotation_style} -r ${params.variant_reference}" - } - - 'percolator_adapter' { - args = "-seed 4711 -trainFDR 0.05 -testFDR 0.05 -enzyme no_enzyme -subset-max-train ${params.subset_max_train} -doc ${params.description_correct_features} " + 'openms_id_filter' { + args = "-remove_decoys -precursor:length '${params.peptide_min_length}:${params.peptide_max_length}' -delete_unreferenced_peptide_hits " } - 'id_filter' { + 'openms_id_filter_refiner' { args = "-remove_decoys -precursor:length '${params.peptide_min_length}:${params.peptide_max_length}' -delete_unreferenced_peptide_hits " + suffix = "perc_subset_filtered" } - 'id_filter_whitelist' { + 'openms_id_filter_whitelist' { args = "-whitelist:ignore_modifications -whitelist:peptides " + suffix = "pred_filtered" } + + 'openms_mztab_exporter_perc' { + suffix = "all_ids_merged_psm_perc_filtered" + } + + 'openms_mztab_exporter_psm' { + suffix = "all_ids_merged" + } + + 'openms_percolator_adapter' { + args = "-seed 4711 -trainFDR 0.05 -testFDR 0.05 -enzyme no_enzyme -subset_max_train ${params.subset_max_train} -doc ${params.description_correct_features} " + suffix = "all_ids_merged_psm_perc" + } + + 'openms_percolator_adapter_refine' { + args = "-seed 4711 -trainFDR 0.05 -testFDR 0.05 -enzyme no_enzyme -subset_max_train ${params.subset_max_train} -doc ${params.description_correct_features} " + suffix = "perc_subset" + } + + 'openms_rt_predict_peptides' { + suffix = "_id_files_for_rt_prediction_RTpredicted" + } + + 'openms_rt_predict_neo_epitopes' { + suffix = "_txt_file_for_rt_prediction_RTpredicted" + } + } } diff --git a/conf/test.config b/conf/test.config index 5249a374..8a830171 100644 --- a/conf/test.config +++ b/conf/test.config @@ -1,22 +1,26 @@ /* - * ------------------------------------------------- - * Nextflow config file for running tests - * ------------------------------------------------- - * Defines bundled input files and everything required - * to run a fast and simple test. Use as follows: - * nextflow run nf-core/mhcquant -profile test, - */ +======================================================================================== + Nextflow config file for running minimal tests +======================================================================================== + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/mhcquant -profile test, + +---------------------------------------------------------------------------------------- +*/ params { - config_profile_name = 'Test profile' - config_profile_description = 'Minimal test dataset to check pipeline function' - // Limit resources so that this can run on GitHub Actions - max_cpus = 2 - max_memory = 6.GB - max_time = 48.h + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Limit resources so that this can run on GitHub Actions + max_cpus = 2 + max_memory = 6.GB + max_time = 6.h - // Input data - fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/test.fasta' - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/sample_sheet.tsv' - allele_sheet = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/allele_sheet.tsv' + // Input data + fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/test.fasta' + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/sample_sheet.tsv' + allele_sheet = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/allele_sheet.tsv' } diff --git a/conf/test_full.config b/conf/test_full.config index fb96dfb8..c12dfe1b 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -1,20 +1,23 @@ /* - * ------------------------------------------------- - * Nextflow config file for running full-size tests - * ------------------------------------------------- - * Defines bundled input files and everything required - * to run a full size pipeline test. Use as follows: - * nextflow run nf-core/mhcquant -profile test_full, - */ +======================================================================================== + Nextflow config file for running full-size tests +======================================================================================== + Defines input files and everything required to run a full size pipeline test. + + Use as follows: + nextflow run nf-core/mhcquant -profile test_full, + +---------------------------------------------------------------------------------------- +*/ params { - config_profile_name = 'Full test profile' - config_profile_description = 'Full test dataset to check pipeline function' + config_profile_name = 'Full test profile' + config_profile_description = 'Full test dataset to check pipeline function' - predict_class_1 = true + predict_class_1 = true - // Input data - fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/test.fasta' - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/sample_sheet_full.tsv' - allele_sheet = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/allele_sheet_full.tsv' + // Input data + fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/test.fasta' + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/sample_sheet_full.tsv' + allele_sheet = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/allele_sheet_full.tsv' } diff --git a/docs/images/mqc_fastqc_adapter.png b/docs/images/mqc_fastqc_adapter.png new file mode 100755 index 00000000..361d0e47 Binary files /dev/null and b/docs/images/mqc_fastqc_adapter.png differ diff --git a/docs/images/mqc_fastqc_counts.png b/docs/images/mqc_fastqc_counts.png new file mode 100755 index 00000000..cb39ebb8 Binary files /dev/null and b/docs/images/mqc_fastqc_counts.png differ diff --git a/docs/images/mqc_fastqc_quality.png b/docs/images/mqc_fastqc_quality.png new file mode 100755 index 00000000..a4b89bf5 Binary files /dev/null and b/docs/images/mqc_fastqc_quality.png differ diff --git a/docs/output.md b/docs/output.md index b5cb02fc..38e993f9 100644 --- a/docs/output.md +++ b/docs/output.md @@ -22,6 +22,7 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d * [Class (1|2) bindings](#class-12-bindings) * [Rotation time prediction](#rotation-time-prediction) * [Workflow reporting and documentation](#workflow-reporting-and-documentation) + * [MultiQC](#multiqc) * [Pipeline information](#pipeline-information) ## General @@ -31,7 +32,7 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d
Output files -* `csv` : If `--skip_quantification` is not specified. +* `*.tsv` : If `--skip_quantification` is not specified.
@@ -122,8 +123,11 @@ These CSV files list all of the theoretically possible neoepitope sequences from
Output files -* `*found_neoepitopes_class1.csv`: Generated when `--include_proteins_from_vcf` and `--predict_class_1` are specified -* `*found_neoepitopes_class2.csv`: Generated when `--include_proteins_from_vcf` and `--predict_class_2` are specified +* `class_1_bindings/` + * `*found_neoepitopes_class1.csv`: Generated when `--include_proteins_from_vcf` and `--predict_class_1` are specified + +* `class_2_bindings/` + * `*found_neoepitopes_class2.csv`: Generated when `--include_proteins_from_vcf` and `--predict_class_2` are specified
@@ -139,8 +143,11 @@ peptide sequence geneID
Output files -* `*vcf_neoepitopes_class1.csv`: Generated when `--include_proteins_from_vcf` and `--predict_class_1` are specified -* `*vcf_neoepitopes_class2.csv`: Generated when `--include_proteins_from_vcf` and `--predict_class_2` are specified +* `class_1_bindings/` + * `*vcf_neoepitopes_class1.csv`: Generated when `--include_proteins_from_vcf` and `--predict_class_1` are specified + +* `class_2_bindings/` + * `*vcf_neoepitopes_class2.csv`: Generated when `--include_proteins_from_vcf` and `--predict_class_2` are specified
@@ -158,8 +165,11 @@ Sequence Antigen ID Variants
Output files -* `*predicted_peptides_class_1.csv`: If `--predict_class_1` is specified, then this CSV is generated -* `*predicted_peptides_class_2.csv`: If `--predict_class_2` is specified, then this CSV is generated +* `class_1_bindings/` + * `*predicted_peptides_class_1.csv`: If `--predict_class_1` is specified, then this CSV is generated + +* `class_2_bindings/` + * `*predicted_peptides_class_2.csv`: If `--predict_class_2` is specified, then this CSV is generated
@@ -183,6 +193,21 @@ peptide allele prediction prediction_low prediction_high prediction_pe ## Workflow reporting and documentation +### MultiQC + +
+Output files + +* `multiqc/` + * `multiqc_report.html`: a standalone HTML file that can be viewed in your web browser. + * `multiqc_data/`: directory containing parsed statistics from the different tools used in the pipeline. + +
+ +MultiQC is a visualization tool that generates a single HTML report summarising all samples in your project. Most of the pipeline QC results are visualised in the report and further statistics are available in the report data directory. + +The pipeline has special steps which allow the software versions to be reported in the MultiQC output for future traceability. For more information about how to use MultiQC reports, see . + ### Pipeline information
diff --git a/docs/usage.md b/docs/usage.md index a33f632b..879ed17d 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -2,21 +2,21 @@ ## Table of contents -* [Table of contents](#table-of-contents) -* [Samplesheet input](#samplesheet-input) - * [Multiple runs of the same sample](#multiple-runs-of-the-same-sample) - * [Full samplesheet](#full-samplesheet) -* [Running the pipeline](#running-the-pipeline) - * [Updating the pipeline](#updating-the-pipeline) - * [Reproducibility](#reproducibility) -* [Core Nextflow arguments](#core-nextflow-arguments) - * [`-profile`](#-profile) - * [`-resume`](#-resume) -* [Custom configuration](#custom-configuration) - * [Resource requests](#resource-requests) - * [nf-core/configs](#nf-core-configs) -* [Running in the background](#running-in-the-background) -* [Nextflow memory requirements](#nextflow-memory-requirements) +- [Table of contents](#table-of-contents) +- [Samplesheet input](#samplesheet-input) + - [Multiple runs of the same sample](#multiple-runs-of-the-same-sample) + - [Full samplesheet](#full-samplesheet) +- [Running the pipeline](#running-the-pipeline) + - [Updating the pipeline](#updating-the-pipeline) + - [Reproducibility](#reproducibility) +- [Core Nextflow arguments](#core-nextflow-arguments) + - [`-profile`](#-profile) + - [`-resume`](#-resume) +- [Custom configuration](#custom-configuration) + - [Resource requests](#resource-requests) + - [nf-core/configs](#nf-core-configs) +- [Running in the background](#running-in-the-background) +- [Nextflow memory requirements](#nextflow-memory-requirements) ## :warning: Please read this documentation on the nf-core website: [https://nf-co.re/mhcquant/usage](https://nf-co.re/mhcquant/usage) @@ -66,12 +66,12 @@ ID\tSample\tCondition\tReplicateFileName ``` -| Column | Description | -|----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `ID` | An incrementing value which acts as a unique number for the given sample | -| `Sample` | Custom sample name. This entry will be identical for multiple MS runs from the same sample. Spaces in sample names are automatically converted to underscores (`_`). | -| `Condition` | Additional information of the sample can be defined here.| -| `ReplicateFileName` | Full path to the MS outcome file. These files have the extentions ".raw" or ".mzML" | +| Column | Description | +| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ID` | An incrementing value which acts as a unique number for the given sample | +| `Sample` | Custom sample name. This entry will be identical for multiple MS runs from the same sample. Spaces in sample names are automatically converted to underscores (`_`). | +| `Condition` | Additional information of the sample can be defined here. | +| `ReplicateFileName` | Full path to the MS outcome file. These files have the extentions ".raw" or ".mzML" | An [example samplesheet](../assets/samplesheet.tsv) has been provided with the pipeline. @@ -118,7 +118,7 @@ This version number will be logged in reports when you run the pipeline, so that Use this parameter to choose a configuration profile. Profiles can give configuration presets for different compute environments. -Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Conda) - see below. +Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Podman, Shifter, Charliecloud, Conda) - see below. When using Biocontainers, most of these software packaging methods pull Docker containers from quay.io e.g [FastQC](https://quay.io/repository/biocontainers/fastqc) except for Singularity which directly downloads Singularity images via https hosted by the [Galaxy project](https://depot.galaxyproject.org/singularity/) and Conda which downloads and installs software locally from [Bioconda](https://bioconda.github.io/). > We highly recommend the use of Docker or Singularity containers for full pipeline reproducibility, however when this is not possible, Conda is also supported. @@ -129,28 +129,21 @@ They are loaded in sequence, so later profiles can overwrite earlier profiles. 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. -* `docker` - * A generic configuration profile to be used with [Docker](https://docker.com/) - * Pulls software from Docker Hub: [`nfcore/mhcquant`](https://hub.docker.com/r/nfcore/mhcquant/) -* `singularity` - * A generic configuration profile to be used with [Singularity](https://sylabs.io/docs/) - * Pulls software from Docker Hub: [`nfcore/mhcquant`](https://hub.docker.com/r/nfcore/mhcquant/) -* `conda` - * Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker or Singularity. - * A generic configuration profile to be used with [Conda](https://conda.io/docs/) - * Pulls most software from [Bioconda](https://bioconda.github.io/) -* `test` - * A profile with a complete configuration for automated testing - * Includes links to test data so needs no other parameters -* `podman` - * A generic configuration profile to be used with [Podman](https://podman.io/) - * Pulls software from Docker Hub: [`nfcore/mhcquant`](https://hub.docker.com/r/nfcore/mhcquant/) -* `shifter` - * A generic configuration profile to be used with [Shifter](https://nersc.gitlab.io/development/shifter/how-to-use/) - * Pulls software from Docker Hub: [`nfcore/mhcquant`](https://hub.docker.com/r/nfcore/mhcquant/) -* `charliecloud` - * A generic configuration profile to be used with [Charliecloud](https://hpc.github.io/charliecloud/) - * Pulls software from Docker Hub: [`nfcore/mhcquant`](https://hub.docker.com/r/nfcore/mhcquant/) +- `docker` + - A generic configuration profile to be used with [Docker](https://docker.com/) +- `singularity` + - A generic configuration profile to be used with [Singularity](https://sylabs.io/docs/) +- `podman` + - A generic configuration profile to be used with [Podman](https://podman.io/) +- `shifter` + - A generic configuration profile to be used with [Shifter](https://nersc.gitlab.io/development/shifter/how-to-use/) +- `charliecloud` + - A generic configuration profile to be used with [Charliecloud](https://hpc.github.io/charliecloud/) +- `conda` + - 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 or Charliecloud. +- `test` + - A profile with a complete configuration for automated testing + - Includes links to test data so needs no other parameters ### `-resume` @@ -197,7 +190,7 @@ Work dir: Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` ``` -To bypass this error you would need to find exactly which resources are set by the `STAR_ALIGN` process. The quickest way is to search for `process STAR_ALIGN` in the [nf-core/rnaseq Github repo](https://github.com/nf-core/rnaseq/search?q=process+STAR_ALIGN). We have standardised the structure of Nextflow DSL2 pipelines such that all module files will be present in the `modules/` directory and so based on the search results the file we want is `modules/nf-core/software/star/align/main.nf`. If you click on the link to that file you will notice that there is a `label` directive at the top of the module that is set to [`label process_high`](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/modules/nf-core/software/star/align/main.nf#L9). The [Nextflow `label`](https://www.nextflow.io/docs/latest/process.html#label) directive allows us to organise workflow processes in separate groups which can be referenced in a configuration file to select and configure subset of processes having similar computing requirements. The default values for the `process_high` label are set in the pipeline's [`base.config`](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/conf/base.config#L33-L37) which in this case is defined as 72GB. Providing you haven't set any other standard nf-core parameters to __cap__ the [maximum resources](https://nf-co.re/usage/configuration#max-resources) used by the pipeline then we can try and bypass the `STAR_ALIGN` process failure by creating a custom config file that sets at least 72GB of memory, in this case increased to 100GB. The custom config below can then be provided to the pipeline via the [`-c`](#-c) parameter as highlighted in previous sections. +To bypass this error you would need to find exactly which resources are set by the `STAR_ALIGN` process. The quickest way is to search for `process STAR_ALIGN` in the [nf-core/rnaseq Github repo](https://github.com/nf-core/rnaseq/search?q=process+STAR_ALIGN). We have standardised the structure of Nextflow DSL2 pipelines such that all module files will be present in the `modules/` directory and so based on the search results the file we want is `modules/nf-core/software/star/align/main.nf`. If you click on the link to that file you will notice that there is a `label` directive at the top of the module that is set to [`label process_high`](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/modules/nf-core/software/star/align/main.nf#L9). The [Nextflow `label`](https://www.nextflow.io/docs/latest/process.html#label) directive allows us to organise workflow processes in separate groups which can be referenced in a configuration file to select and configure subset of processes having similar computing requirements. The default values for the `process_high` label are set in the pipeline's [`base.config`](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/conf/base.config#L33-L37) which in this case is defined as 72GB. Providing you haven't set any other standard nf-core parameters to **cap** the [maximum resources](https://nf-co.re/usage/configuration#max-resources) used by the pipeline then we can try and bypass the `STAR_ALIGN` process failure by creating a custom config file that sets at least 72GB of memory, in this case increased to 100GB. The custom config below can then be provided to the pipeline via the [`-c`](#-c) parameter as highlighted in previous sections. ```nextflow process { diff --git a/lib/WorkflowMain.groovy b/lib/WorkflowMain.groovy index 25ed0c6d..d12756c7 100644 --- a/lib/WorkflowMain.groovy +++ b/lib/WorkflowMain.groovy @@ -1,5 +1,5 @@ // -// This file holds several functions specific to the main.nf workflow in the nf-core/rnaseq pipeline +// This file holds several functions specific to the main.nf workflow in the nf-core/mhcquant pipeline // class WorkflowMain { @@ -9,19 +9,21 @@ class WorkflowMain { // public static String citation(workflow) { return "If you use ${workflow.manifest.name} for your analysis please cite:\n\n" + + "* The pipeline publication\n" + + " https://doi.org/10.1021/acs.jproteome.9b00313\n\n" + "* The pipeline\n" + - " https://doi.org/10.5281/zenodo.1400710\n\n" + + " https://doi.org/10.5281/zenodo.1569909\n\n" + "* The nf-core framework\n" + - " https://dx.doi.org/10.1038/s41587-020-0439-x\n" + - " https://rdcu.be/b1GjZ\n\n" + + " https://doi.org/10.1038/s41587-020-0439-x\n\n" + "* Software dependencies\n" + " https://github.com/${workflow.manifest.name}/blob/master/CITATIONS.md" } + // // Print help to screen if required // public static String help(workflow, params, log) { - def command = "nextflow run ${workflow.manifest.name} --input 'samples.tsv' --fasta 'SWISSPROT_2020.fasta' --allele_sheet 'alleles.tsv' --predict_class_1 --refine_fdr_on_predicted_subset" + def command = "nextflow run ${workflow.manifest.name} ⁠-⁠-⁠input 'samples.tsv' ⁠-⁠-⁠fasta 'SWISSPROT_2020.fasta' ⁠-⁠-⁠allele_sheet 'alleles.tsv' ⁠-⁠-⁠vcf_sheet 'variants.tsv' ⁠-⁠-⁠include_proteins_from_vcf ⁠-⁠-⁠predict_class_1 -profile docker" def help_string = '' help_string += NfcoreTemplate.logo(workflow, params.monochrome_logs) help_string += NfcoreSchema.paramsHelp(workflow, params, command) @@ -73,7 +75,7 @@ class WorkflowMain { // Check input has been provided if (!params.input) { - log.error "Please provide an input samplesheet to the pipeline e.g. '--input samplesheet.csv'" + log.error "Please provide an input samplesheet to the pipeline e.g. '--input samplesheet.tsv'" System.exit(1) } } diff --git a/lib/WorkflowMhcquant.groovy b/lib/WorkflowMhcquant.groovy index 0febad33..b9450083 100644 --- a/lib/WorkflowMhcquant.groovy +++ b/lib/WorkflowMhcquant.groovy @@ -1,5 +1,5 @@ // -// This file holds several functions specific to the workflow/rnaseq.nf in the nf-core/rnaseq pipeline +// This file holds several functions specific to the workflow/mhcquant.nf in the nf-core/mhcquant pipeline // class WorkflowMhcquant { @@ -76,4 +76,31 @@ class WorkflowMhcquant { "===================================================================================" } + // + // Get workflow summary for MultiQC + // + public static String paramsSummaryMultiqc(workflow, summary) { + String summary_section = '' + for (group in summary.keySet()) { + def group_params = summary.get(group) // This gets the parameters of that particular group + if (group_params) { + summary_section += "

$group

\n" + summary_section += "
\n" + for (param in group_params.keySet()) { + summary_section += "
$param
${group_params.get(param) ?: 'N/A'}
\n" + } + summary_section += "
\n" + } + } + + String yaml_file_text = "id: '${workflow.manifest.name.replace('/','-')}-summary'\n" + yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n" + yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n" + yaml_file_text += "section_href: 'https://github.com/${workflow.manifest.name}'\n" + yaml_file_text += "plot_type: 'html'\n" + yaml_file_text += "data: |\n" + yaml_file_text += "${summary_section}" + return yaml_file_text + } + } diff --git a/main.nf b/main.nf index ea4382b0..1cff392d 100644 --- a/main.nf +++ b/main.nf @@ -11,6 +11,14 @@ nextflow.enable.dsl = 2 +/* +======================================================================================== + GENOME PARAMETER VALUES +======================================================================================== +*/ + +params.fasta = WorkflowMain.getGenomeAttribute(params, 'fasta') + /* ======================================================================================== VALIDATE & PRINT PARAMETER SUMMARY @@ -28,7 +36,7 @@ WorkflowMain.initialise(workflow, params, log) include { MHCQUANT } from './workflows/mhcquant' // -// WORKFLOW: Run main nf-core/rnaseq analysis pipeline +// WORKFLOW: Run main nf-core/mhcquant analysis pipeline // workflow NFCORE_MHCQUANT { MHCQUANT () @@ -47,3 +55,9 @@ workflow NFCORE_MHCQUANT { workflow { NFCORE_MHCQUANT () } + +/* +======================================================================================== + THE END +======================================================================================== +*/ diff --git a/modules.json b/modules.json index e5f4a905..554d418c 100644 --- a/modules.json +++ b/modules.json @@ -1,5 +1,14 @@ { "name": "nf-core/mhcquant", "homePage": "https://github.com/nf-core/mhcquant", - "repos": {} -} \ No newline at end of file + "repos": { + "nf-core/modules": { + "custom/dumpsoftwareversions": { + "git_sha": "3aacd46da2b221ed47aaa05c413a828538d2c2ae" + }, + "multiqc": { + "git_sha": "3aacd46da2b221ed47aaa05c413a828538d2c2ae" + } + } + } +} diff --git a/modules/local/functions.nf b/modules/local/functions.nf index 7e182723..2405335a 100644 --- a/modules/local/functions.nf +++ b/modules/local/functions.nf @@ -1,63 +1,81 @@ -/* - * ----------------------------------------------------- - * Utility functions used in nf-core DSL2 module files - * ----------------------------------------------------- - */ +// +// Utility functions used in nf-core DSL2 module files +// -/* - * Extract name of software tool from process name using $task.process - */ +// +// Extract name of software tool from process name using $task.process +// def getSoftwareName(task_process) { return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() } -/* - * Function to initialise default values and to generate a Groovy Map of available options for nf-core modules - */ +// +// Extract name of module from process name using $task.process +// +def getProcessName(task_process) { + return task_process.tokenize(':')[-1] +} + +// +// Function to initialise default values and to generate a Groovy Map of available options for nf-core modules +// def initOptions(Map args) { def Map options = [:] - options.args = args.args ?: '' - options.args2 = args.args2 ?: '' - options.publish_by_id = args.publish_by_id ?: false - options.publish_dir = args.publish_dir ?: '' - options.publish_files = args.publish_files - options.suffix = args.suffix ?: '' + options.args = args.args ?: '' + options.args2 = args.args2 ?: '' + options.args3 = args.args3 ?: '' + options.publish_by_meta = args.publish_by_meta ?: [] + options.publish_dir = args.publish_dir ?: '' + options.publish_files = args.publish_files + options.suffix = args.suffix ?: '' return options } -/* - * Tidy up and join elements of a list to return a path string - */ +// +// Tidy up and join elements of a list to return a path string +// def getPathFromList(path_list) { - def paths = path_list.findAll { item -> !item?.trim().isEmpty() } // Remove empty entries - paths = paths.collect { it.trim().replaceAll("^[/]+|[/]+\$", "") } // Trim whitespace and trailing slashes + def paths = path_list.findAll { item -> !item?.trim().isEmpty() } // Remove empty entries + paths = paths.collect { it.trim().replaceAll("^[/]+|[/]+\$", "") } // Trim whitespace and trailing slashes return paths.join('/') } -/* - * Function to save/publish module results - */ +// +// Function to save/publish module results +// def saveFiles(Map args) { - if (!args.filename.endsWith('.version.txt')) { - def ioptions = initOptions(args.options) - def path_list = [ ioptions.publish_dir ?: args.publish_dir ] - if (ioptions.publish_by_id) { - path_list.add(args.publish_id) - } - if (ioptions.publish_files instanceof Map) { - for (ext in ioptions.publish_files) { - if (args.filename.endsWith(ext.key)) { - def ext_list = path_list.collect() - ext_list.add(ext.value) - return "${getPathFromList(ext_list)}/$args.filename" + def ioptions = initOptions(args.options) + def path_list = [ ioptions.publish_dir ?: args.publish_dir ] + + // Do not publish versions.yml unless running from pytest workflow + if (args.filename.equals('versions.yml') && !System.getenv("NF_CORE_MODULES_TEST")) { + return null + } + if (ioptions.publish_by_meta) { + def key_list = ioptions.publish_by_meta instanceof List ? ioptions.publish_by_meta : args.publish_by_meta + for (key in key_list) { + if (args.meta && key instanceof String) { + def path = key + if (args.meta.containsKey(key)) { + path = args.meta[key] instanceof Boolean ? "${key}_${args.meta[key]}".toString() : args.meta[key] } + path = path instanceof String ? path : '' + path_list.add(path) } - } else if (ioptions.publish_files == null) { - return "${getPathFromList(path_list)}/$args.filename" } } + if (ioptions.publish_files instanceof Map) { + for (ext in ioptions.publish_files) { + if (args.filename.endsWith(ext.key)) { + def ext_list = path_list.collect() + ext_list.add(ext.value) + return "${getPathFromList(ext_list)}/$args.filename" + } + } + } else if (ioptions.publish_files == null) { + return "${getPathFromList(path_list)}/$args.filename" + } } - /* * Function to check the file extension */ diff --git a/modules/local/generate_proteins_from_vcf.nf b/modules/local/generate_proteins_from_vcf.nf index 6bf8f397..b07589de 100644 --- a/modules/local/generate_proteins_from_vcf.nf +++ b/modules/local/generate_proteins_from_vcf.nf @@ -26,17 +26,23 @@ process GENERATE_PROTEINS_FROM_VCF { tuple val(meta), path(fasta), path(vcf) output: - tuple val(meta), path("*_vcf.fasta"), emit: vcf_fasta - path "*.version.txt", emit: version + tuple val(meta), path("*.fasta"), emit: vcf_fasta + path "*.version.txt" , emit: version script: def prefix = options.suffix ? "${fasta.baseName}_${options.suffix}" : "${fasta.baseName}_added_vcf" - """ - variants2fasta.py -v ${vcf} -f ${fasta} -o ${meta.sample}_${prefix}.fasta $options.args - - echo $VERSIONFRED2 > fred2.version.txt - echo $VERSIONMHCNUGGETS > mhcnuggets.version.txt - echo \$(mhcflurry-predict --version 2>&1) | sed 's/^.*mhcflurry //; s/ .*\$//' &> mhcflurry.version.txt - """ + """ + variants2fasta.py -v $vcf \\ + -f $fasta \\ + -o $meta.sample_${prefix}.fasta \\ + $options.args + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + fred2: \$(echo \$(python -c "import pkg_resources; print('fred2' + pkg_resources.get_distribution('Fred2').version)" | sed 's/^fred2//; s/ .*\$//')) + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//' )) + mhcflurry: \$(echo \$(mhcflurry-predict --version 2>&1 | sed 's/^mhcflurry //; s/ .*\$//') ) + END_VERSIONS + """ } diff --git a/modules/local/get_software_versions.nf b/modules/local/get_software_versions.nf index 309d2037..647ea324 100644 --- a/modules/local/get_software_versions.nf +++ b/modules/local/get_software_versions.nf @@ -1,16 +1,13 @@ // Import generic module functions -include { initOptions; saveFiles } from './functions' +include { saveFiles } from './functions' params.options = [:] options = initOptions(params.options) -/* - * Parse software version numbers - */ process GET_SOFTWARE_VERSIONS { publishDir "${params.outdir}", mode: params.publish_dir_mode, - saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', publish_id:'pipeline_info') } + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', meta:[:], publish_by_meta:[]) } conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { @@ -22,16 +19,16 @@ process GET_SOFTWARE_VERSIONS { cache false input: - path versions + path versions output: - path "software_versions.tsv" , emit: tsv - path 'software_versions_mqc.yaml', emit: yaml + path "software_versions.tsv" , emit: tsv + path 'software_versions_mqc.yaml', emit: yaml - script: - """ + script: // This script is bundled with the pipeline, in nf-core/mhcquant/bin/ + """ echo $workflow.manifest.version > pipeline.version.txt echo $workflow.nextflow.version > nextflow.version.txt scrape_software_versions.py &> software_versions_mqc.yaml - """ + """ } diff --git a/modules/local/predict_neoepitopes_mhcflurry_class_1.nf b/modules/local/mhcflurry_predictneoepitopesclass1.nf similarity index 61% rename from modules/local/predict_neoepitopes_mhcflurry_class_1.nf rename to modules/local/mhcflurry_predictneoepitopesclass1.nf index 1bebedf7..37c938cc 100644 --- a/modules/local/predict_neoepitopes_mhcflurry_class_1.nf +++ b/modules/local/mhcflurry_predictneoepitopesclass1.nf @@ -1,10 +1,10 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) -process PREDICT_NEOEPITOPES_MHCFLURRY_CLASS_1 { +process MHCFLURRY_PREDICTNEOEPITOPESCLASS1 { tag "$meta" label 'process_low' @@ -12,7 +12,7 @@ process PREDICT_NEOEPITOPES_MHCFLURRY_CLASS_1 { mode: params.publish_dir_mode, saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'class_1_bindings', publish_id:'class_1_bindings') } - conda (params.enable_conda ? "bioconda::mhcflurry=1.4.3--py_0" : null) + conda (params.enable_conda ? "bioconda::mhcflurry=1.4.3" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { container "https://depot.galaxyproject.org/singularity/mhcflurry:1.4.3--py_0" } else { @@ -25,14 +25,18 @@ process PREDICT_NEOEPITOPES_MHCFLURRY_CLASS_1 { output: tuple val(meta), path("*.csv"), emit: csv - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def prefix = options.suffix ? "${neoepitopes}_${meta}_${options.suffix}" : "${neoepitopes}_${meta}_predicted_neoepitopes_class_1" """ - mhcflurry-downloads --quiet fetch models_class1 - mhcflurry_neoepitope_binding_prediction.py '${allotypes}' ${prefix}.csv - mhcflurry-predict --version &> mhcflurry.version.txt + mhcflurry-downloads --quiet fetch models_class1 + mhcflurry_neoepitope_binding_prediction.py '$allotypes' ${prefix}.csv + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcflurry: \$(echo \$(mhcflurry-predict --version 2>&1 | sed 's/^mhcflurry //; s/ .*\$//') ) + END_VERSIONS """ } diff --git a/modules/local/predict_peptides_mhcflurry_class_1.nf b/modules/local/mhcflurry_predictpeptidesclass1.nf similarity index 55% rename from modules/local/predict_peptides_mhcflurry_class_1.nf rename to modules/local/mhcflurry_predictpeptidesclass1.nf index 04b9821a..a5509ed0 100644 --- a/modules/local/predict_peptides_mhcflurry_class_1.nf +++ b/modules/local/mhcflurry_predictpeptidesclass1.nf @@ -1,13 +1,10 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) -def VERSIONFRED2 = '2.0.6' -def VERSIONMHCNUGGETS = '2.3.2' - -process PREDICT_PEPTIDES_MHCFLURRY_CLASS_1 { +process MHCFLURRY_PREDICTPEPTIDESCLASS1 { tag "$meta" label 'process_low' @@ -26,17 +23,21 @@ process PREDICT_PEPTIDES_MHCFLURRY_CLASS_1 { tuple val(meta), path(mztab), val(alleles) output: - tuple val(meta), path("*predicted_peptides_class_1.csv"), emit: csv - path "*.version.txt", emit: version + tuple val(meta), path("*.csv"), emit: csv + path "versions.yml" , emit: versions script: def prefix = options.suffix ? "${meta.id}_${options.suffix}" : "${meta.id}_predicted_peptides_class_1" """ - mhcflurry-downloads --quiet fetch models_class1 - mhcflurry_predict_mztab.py '${alleles}' ${mztab} ${prefix}.csv - echo $VERSIONFRED2 > fred2.version.txt - echo $VERSIONMHCNUGGETS > mhcnuggets.version.txt - mhcflurry-predict --version &> mhcflurry.version.txt + mhcflurry-downloads --quiet fetch models_class1 + mhcflurry_predict_mztab.py '$alleles' $mztab ${prefix}.csv + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//' )) + mhcflurry: \$(echo \$(mhcflurry-predict --version 2>&1 | sed 's/^mhcflurry //; s/ .*\$//') ) + fred2: \$(echo \$(python -c "import pkg_resources; print('fred2' + pkg_resources.get_distribution('Fred2').version)" | sed 's/^fred2//; s/ .*\$//')) + END_VERSIONS """ } diff --git a/modules/local/predict_psms.nf b/modules/local/mhcflurry_predictpsms.nf similarity index 61% rename from modules/local/predict_psms.nf rename to modules/local/mhcflurry_predictpsms.nf index 6b95acec..469b061b 100644 --- a/modules/local/predict_psms.nf +++ b/modules/local/mhcflurry_predictpsms.nf @@ -1,10 +1,10 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) -process PREDICT_PSMS { +process MHCFLURRY_PREDICTPSMS { tag "$meta" label 'process_medium' @@ -24,15 +24,21 @@ process PREDICT_PSMS { output: tuple val(meta), path("*.idXML"), emit: idxml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def prefix = options.suffix ? "${meta.id}_${options.suffix}" : "${meta.id}_peptide_filter" - """ + """ mhcflurry-downloads --quiet fetch models_class1 - mhcflurry_predict_mztab_for_filtering.py ${params.subset_affinity_threshold} '${allotypes}' ${perc_mztab} ${psm_mztab} ${prefix}.idXML - mhcflurry-predict --version &> mhcflurry.version.txt - """ + mhcflurry_predict_mztab_for_filtering.py ${params.subset_affinity_threshold} '$allotypes' $perc_mztab $psm_mztab ${prefix}.idXML + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//' )) + mhcflurry: \$(echo \$(mhcflurry-predict --version 2>&1 | sed 's/^mhcflurry //; s/ .*\$//') ) + fred2: \$(echo \$(python -c "import pkg_resources; print('fred2' + pkg_resources.get_distribution('Fred2').version)" | sed 's/^fred2//; s/ .*\$//')) + END_VERSIONS + """ } diff --git a/modules/local/postprocess_neoepitopes_mhcnuggets_class_2.nf b/modules/local/mhcnuggets_neoepitopesclass2post.nf similarity index 56% rename from modules/local/postprocess_neoepitopes_mhcnuggets_class_2.nf rename to modules/local/mhcnuggets_neoepitopesclass2post.nf index 502928d1..90eeead8 100644 --- a/modules/local/postprocess_neoepitopes_mhcnuggets_class_2.nf +++ b/modules/local/mhcnuggets_neoepitopesclass2post.nf @@ -1,12 +1,10 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) -def VERSION = '2.3.2' - -process POSTPROCESS_NEOEPITOPES_MHCNUGGETS_CLASS_2 { +process MHCNUGGETS_NEOEPITOPESCLASS2POST { tag "$meta" label 'process_low' @@ -14,7 +12,7 @@ process POSTPROCESS_NEOEPITOPES_MHCNUGGETS_CLASS_2 { mode: params.publish_dir_mode, saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'class_2_bindings', publish_id:'class_2_bindings') } - conda (params.enable_conda ? "bioconda::mhcnuggets=2.3.2--py_0" : null) + conda (params.enable_conda ? "bioconda::mhcnuggets=2.3.2" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { container "https://depot.galaxyproject.org/singularity/mhcnuggets:2.3.2--py_0" } else { @@ -27,12 +25,16 @@ process POSTPROCESS_NEOEPITOPES_MHCNUGGETS_CLASS_2 { output: tuple val(meta), path("*.csv"), emit: csv - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: """ - postprocess_neoepitopes_mhcnuggets.py --input ${predicted} --neoepitopes ${neoepitopes} - echo $VERSION > mhcnuggets.version.txt + postprocess_neoepitopes_mhcnuggets.py --input $predicted --neoepitopes $neoepitopes + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//' )) + END_VERSIONS """ } diff --git a/modules/local/mhcnuggets_neoepitopesclass2pre.nf b/modules/local/mhcnuggets_neoepitopesclass2pre.nf new file mode 100644 index 00000000..98d0f503 --- /dev/null +++ b/modules/local/mhcnuggets_neoepitopesclass2pre.nf @@ -0,0 +1,40 @@ +// Import generic module functions +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' + +params.options = [:] +options = initOptions(params.options) + +process MHCNUGGETS_NEOEPITOPESCLASS2RE { + tag "$meta" + label 'process_low' + + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'class_2_bindings', publish_id:'class_2_bindings') } + + conda (params.enable_conda ? "bioconda::mhcnuggets=2.3.2" : null) + if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { + container "https://depot.galaxyproject.org/singularity/mhcnuggets:2.3.2--py_0" + } else { + container "quay.io/biocontainers/mhcnuggets:2.3.2--py_0" + } + + input: + tuple val(meta), path(neoepitopes) + + output: + tuple val(meta), path("*${prefix}"), emit: preprocessed + path "versions.yml" , emit: versions + + script: + def prefix = options.suffix ? "${meta}_${options.suffix}" : "${meta}_mhcnuggets_preprocessed" + + """ + preprocess_neoepitopes_mhcnuggets.py --neoepitopes $neoepitopes --output ${prefix} + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//' )) + END_VERSIONS + """ +} diff --git a/modules/local/postprocess_peptides_mhcnuggets_class_2.nf b/modules/local/mhcnuggets_peptidesclass2post.nf similarity index 57% rename from modules/local/postprocess_peptides_mhcnuggets_class_2.nf rename to modules/local/mhcnuggets_peptidesclass2post.nf index 2c817907..0af8cb0f 100644 --- a/modules/local/postprocess_peptides_mhcnuggets_class_2.nf +++ b/modules/local/mhcnuggets_peptidesclass2post.nf @@ -1,12 +1,10 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) -def VERSION = '2.3.2' - -process POSTPROCESS_PEPTIDES_MHCNUGGETS_CLASS_2 { +process MHCNUGGETS_PEPTIDESCLASS2POST { tag "$meta" label 'process_low' @@ -14,7 +12,7 @@ process POSTPROCESS_PEPTIDES_MHCNUGGETS_CLASS_2 { mode: params.publish_dir_mode, saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'class_2_bindings', publish_id:'class_2_bindings') } - conda (params.enable_conda ? "bioconda::mhcnuggets=2.3.2--py_0" : null) + conda (params.enable_conda ? "bioconda::mhcnuggets=2.3.2" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { container "https://depot.galaxyproject.org/singularity/mhcnuggets:2.3.2--py_0" } else { @@ -26,13 +24,19 @@ process POSTPROCESS_PEPTIDES_MHCNUGGETS_CLASS_2 { output: tuple val(meta), path('*.csv'), emit: csv - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def prefix = options.suffix ? "${meta.sample}_${options.suffix}" : "${meta.sample}_postprocessed" """ - postprocess_peptides_mhcnuggets.py --input ${peptides} --peptides_seq_ID ${peptide_to_geneID} --output ${prefix}.csv - echo $VERSION > mhcnuggets.version.txt + postprocess_peptides_mhcnuggets.py --input $peptides \\ + --peptides_seq_ID $peptide_to_geneID \\ + --output ${prefix}.csv + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//' )) + END_VERSIONS """ } diff --git a/modules/local/mhcnuggets_peptidesclass2pre.nf b/modules/local/mhcnuggets_peptidesclass2pre.nf new file mode 100644 index 00000000..665749e9 --- /dev/null +++ b/modules/local/mhcnuggets_peptidesclass2pre.nf @@ -0,0 +1,42 @@ +// Import generic module functions +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' + +params.options = [:] +options = initOptions(params.options) + +process MHCNUGGETS_PEPTIDESCLASS2PRE { + tag "$meta" + label 'process_low' + + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'class_2_bindings', publish_id:'class_2_bindings') } + + conda (params.enable_conda ? "bioconda::mhcnuggets=2.3.2" : null) + if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { + container "https://depot.galaxyproject.org/singularity/mhcnuggets:2.3.2--py_0" + } else { + container "quay.io/biocontainers/mhcnuggets:2.3.2--py_0" + } + + input: + tuple val(meta), path(mztab) + + output: + tuple val(meta), path("*_peptides") , emit: preprocessed + tuple val(meta), path('peptide_to_geneID'), emit: geneID + path "versions.yml" , emit: versions + + script: + def prefix = options.suffix ? "${meta.sample}_${options.suffix}_peptides" : "${meta.sample}_preprocessed_mhcnuggets_peptides" + + """ + preprocess_peptides_mhcnuggets.py --mztab $mztab \\ + --output ${prefix} + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//' )) + END_VERSIONS + """ +} diff --git a/modules/local/mhcnuggets_predictneoepitopesclass2.nf b/modules/local/mhcnuggets_predictneoepitopesclass2.nf new file mode 100644 index 00000000..446ee885 --- /dev/null +++ b/modules/local/mhcnuggets_predictneoepitopesclass2.nf @@ -0,0 +1,42 @@ +// Import generic module functions +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' + +params.options = [:] +options = initOptions(params.options) + +process MHCNUGGETS_PREDICTNEOEPITOPESCLASS2 { + tag "$meta" + label 'process_low' + + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'class_2_bindings', publish_id:'class_2_bindings') } + + conda (params.enable_conda ? "bioconda::mhcnuggets=2.3.2--py_0" : null) + if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { + container "https://depot.galaxyproject.org/singularity/mhcnuggets:2.3.2--py_0" + } else { + container "quay.io/biocontainers/mhcnuggets:2.3.2--py_0" + } + + input: + tuple val(meta), path(neoepitopes), val(alleles) + + output: + tuple val(meta), path("*${prefix}"), emit: csv + path "versions.yml" , emit: versions + + script: + def prefix = options.suffix ? "${meta}_${options.suffix}" : "${meta}_predicted_neoepitopes_class_2" + + """ + mhcnuggets_predict_peptides.py --peptides $neoepitopes \\ + --alleles '$alleles' \\ + --output ${prefix} + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//' )) + END_VERSIONS + """ +} diff --git a/modules/local/mhcnuggets_predictpeptidesclass2.nf b/modules/local/mhcnuggets_predictpeptidesclass2.nf new file mode 100644 index 00000000..f85c8208 --- /dev/null +++ b/modules/local/mhcnuggets_predictpeptidesclass2.nf @@ -0,0 +1,44 @@ +// Import generic module functions +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' + +params.options = [:] +options = initOptions(params.options) + +process MHCNUGGETS_PREDICTPEPTIDESCLASS2 { + tag "$meta" + label 'process_low' + + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'class_2_bindings', publish_id:'class_2_bindings') } + + conda (params.enable_conda ? "bioconda::fred2=2.0.6 bioconda::mhcflurry=1.4.3 bioconda::mhcnuggets=2.3.2" : null) + if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { + container "https://depot.galaxyproject.org/singularity/mulled-v2-689ae0756dd82c61400782baaa8a7a1c2289930d:a9e10ca22d4cbcabf6b54f0fb5d766ea16bb171e-0" + } else { + container "quay.io/biocontainers/mulled-v2-689ae0756dd82c61400782baaa8a7a1c2289930d:a9e10ca22d4cbcabf6b54f0fb5d766ea16bb171e-0" + } + + input: + tuple val(meta), path(peptides), val(alleles) + + output: + tuple val(meta), path("*_class_2"), emit: csv + path "versions.yml" , emit: versions + + script: + def prefix = options.suffix ? "${meta.sample}_${options.suffix}_class_2" : "${meta.sample}_predicted_peptides_class_2" + + """ + mhcnuggets_predict_peptides.py --peptides $peptides \\ + --alleles '$alleles' \\ + --output ${prefix} + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcflurry: \$(echo \$(mhcflurry-predict --version 2>&1 | sed 's/^mhcflurry //; s/ .*\$//') ) + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//' )) + fred2: \$(echo \$(python -c "import pkg_resources; print('fred2' + pkg_resources.get_distribution('Fred2').version)" | sed 's/^fred2//; s/ .*\$//')) + END_VERSIONS + """ +} diff --git a/modules/local/openms_cometadapter.nf b/modules/local/openms_cometadapter.nf index 860e55b7..ad49aa2b 100644 --- a/modules/local/openms_cometadapter.nf +++ b/modules/local/openms_cometadapter.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -8,11 +8,11 @@ process OPENMS_COMETADAPTER { tag "$meta.id" label 'process_high' - conda (params.enable_conda ? "bioconda::openms-thirdparty=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms-thirdparty=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms-thirdparty:2.5.0--6" + container "https://depot.galaxyproject.org/singularity/openms-thirdparty:2.6.0--0" } else { - container "quay.io/biocontainers/openms-thirdparty:2.5.0--6" + container "quay.io/biocontainers/openms-thirdparty:2.6.0--0" } input: @@ -20,17 +20,22 @@ process OPENMS_COMETADAPTER { output: tuple val(meta), path("*.idXML"), emit: idxml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${mzml.baseName}_${options.suffix}" : "${mzml.baseName}" """ - CometAdapter -in ${mzml} \\ - -out ${prefix}.idXML \\ - -database ${fasta} \\ - -threads $task.cpus $options.args - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}-thirdparty.version.txt + CometAdapter -in $mzml \\ + -out ${prefix}.idXML \\ + -database $fasta \\ + -threads $task.cpus \\ + $options.args + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms-thirdparty: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_decoydatabase.nf b/modules/local/openms_decoydatabase.nf index 8161c32f..2f9ebc4a 100644 --- a/modules/local/openms_decoydatabase.nf +++ b/modules/local/openms_decoydatabase.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -8,29 +8,33 @@ process OPENMS_DECOYDATABASE { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: tuple val(meta), path(fasta) output: - tuple val(meta), path("*_decoy.fasta"), emit: decoy - path "*.version.txt", emit: version + tuple val(meta), path("*.fasta"), emit: decoy + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${fasta.baseName}_${options.suffix}" : "${fasta.baseName}_decoy" """ - DecoyDatabase -in ${fasta} \\ - -out ${prefix}.fasta \\ - -decoy_string DECOY_ \\ - -decoy_string_position prefix - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + DecoyDatabase -in $fasta \\ + -out ${prefix}.fasta \\ + -decoy_string DECOY_ \\ + -decoy_string_position prefix + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_falsediscoveryrate.nf b/modules/local/openms_falsediscoveryrate.nf index 93363e45..c25d7058 100644 --- a/modules/local/openms_falsediscoveryrate.nf +++ b/modules/local/openms_falsediscoveryrate.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -8,11 +8,11 @@ process OPENMS_FALSEDISCOVERYRATE { tag "$meta.id" label 'process_low' - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: @@ -20,17 +20,21 @@ process OPENMS_FALSEDISCOVERYRATE { output: tuple val(meta), path("*.idXML"), emit: idxml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${idxml.baseName}_${options.suffix}" : "${idxml.baseName}_fdr" """ - FalseDiscoveryRate -in ${idxml} \\ - -protein 'false' \\ - -out ${prefix}.idXML \\ - -threads ${task.cpus} - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + FalseDiscoveryRate -in $idxml \\ + -protein 'false' \\ + -out ${prefix}.idXML \\ + -threads $task.cpus + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_featurefinderidentification.nf b/modules/local/openms_featurefinderidentification.nf index ffb0acdc..eacb21a3 100644 --- a/modules/local/openms_featurefinderidentification.nf +++ b/modules/local/openms_featurefinderidentification.nf @@ -1,22 +1,22 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) process OPENMS_FEATUREFINDERIDENTIFICATION { tag "$meta.id" - label 'process_low' + label 'process_medium' publishDir "${params.outdir}", mode: params.publish_dir_mode, saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'Intermediate_Results', publish_id:'Intermediate_Results') } - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: @@ -24,23 +24,28 @@ process OPENMS_FEATUREFINDERIDENTIFICATION { output: tuple val(meta), path("*.featureXML"), emit: featurexml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${meta.sample}_${options.suffix}" : "${meta.sample}_${meta.id}" if (!params.quantification_fdr){ - arguments = "-id ${id_quant}" + arguments = "-id $id_quant" } else { - arguments = "-id ${id_quant_int} -id_ext ${id_quant} -svm:min_prob ${params.quantification_min_prob}" + arguments = "-id $id_quant_int -id_ext $id_quant -svm:min_prob ${params.quantification_min_prob}" } """ - FeatureFinderIdentification -in ${mzml} \\ - -out ${prefix}.featureXML \\ - -threads ${task.cpus} \\ - $arguments - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + FeatureFinderIdentification -in $mzml \\ + -out ${prefix}.featureXML \\ + -threads $task.cpus \\ + ${arguments} \\ + $options.args + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_featurelinkerunlabeledkd.nf b/modules/local/openms_featurelinkerunlabeledkd.nf index c2c69e1d..ad8db0ba 100644 --- a/modules/local/openms_featurelinkerunlabeledkd.nf +++ b/modules/local/openms_featurelinkerunlabeledkd.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -10,13 +10,13 @@ process OPENMS_FEATURELINKERUNLABELEDKD { publishDir "${params.outdir}", mode: params.publish_dir_mode, - saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'RT_prediction', publish_id:'RT_prediction') } + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'Intermediate_Results', publish_id:'Intermediate_Results') } - conda (params.enable_conda ? "bioconda::openms-thirdparty=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms-thirdparty=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms-thirdparty:2.5.0--6" + container "https://depot.galaxyproject.org/singularity/openms-thirdparty:2.6.0--0" } else { - container "quay.io/biocontainers/openms-thirdparty:2.5.0--6" + container "quay.io/biocontainers/openms-thirdparty:2.6.0--0" } input: @@ -24,18 +24,20 @@ process OPENMS_FEATURELINKERUNLABELEDKD { output: tuple val(meta), path("*.consensusXML"), emit: consensusxml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${meta.id}_${options.suffix}" : "${meta.id}_all_features_merged" """ - FeatureLinkerUnlabeledKD -in ${features} \\ - -out '${prefix}.consensusXML' \\ - -threads ${task.cpus} - - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}-thirdparty.version.txt - + FeatureLinkerUnlabeledKD -in $features \\ + -out '${prefix}.consensusXML' \\ + -threads $task.cpus + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms-thirdparty: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_idconflictresolver.nf b/modules/local/openms_idconflictresolver.nf index 5d05d0c0..5053c53b 100644 --- a/modules/local/openms_idconflictresolver.nf +++ b/modules/local/openms_idconflictresolver.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -8,11 +8,11 @@ process OPENMS_IDCONFLICTRESOLVER { tag "$meta.id" label 'process_low' - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: @@ -20,16 +20,20 @@ process OPENMS_IDCONFLICTRESOLVER { output: tuple val(meta), path("*.consensusXML"), emit: consensusxml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${meta.id}_${options.suffix}" : "${meta.id}_resolved" """ - IDConflictResolver -in ${consensus} \\ - -out ${prefix}.consensusXML \\ - -threads ${task.cpus} - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + IDConflictResolver -in $consensus \\ + -out ${prefix}.consensusXML \\ + -threads $task.cpus + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_idfilter.nf b/modules/local/openms_idfilter.nf index 70ac8a8d..b59321a0 100644 --- a/modules/local/openms_idfilter.nf +++ b/modules/local/openms_idfilter.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -12,11 +12,11 @@ process OPENMS_IDFILTER { mode: params.publish_dir_mode, saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'Intermediate_Results', publish_id:'Intermediate_Results') } - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: @@ -24,11 +24,11 @@ process OPENMS_IDFILTER { output: tuple val(meta), path("*.idXML"), emit: idxml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) - def whitelist = "${peptide_filter}" + def whitelist = "$peptide_filter" def prefix = options.suffix ? "${idxml.baseName}_${options.suffix}" : "${meta.id}_-_idx_fdr_filtered" if (whitelist == "input.2") { @@ -36,10 +36,15 @@ process OPENMS_IDFILTER { } """ - IDFilter -in ${idxml} \\ - -out ${prefix}.idXML \\ - -threads ${task.cpus} \\ - $options.args ${whitelist} - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + IDFilter -in $idxml \\ + -out ${prefix}.idXML \\ + -threads $task.cpus \\ + $options.args \\ + $whitelist + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_idmerger.nf b/modules/local/openms_idmerger.nf index c61fa631..289d250b 100644 --- a/modules/local/openms_idmerger.nf +++ b/modules/local/openms_idmerger.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -8,11 +8,11 @@ process OPENMS_IDMERGER { tag "$meta.id" label 'process_low' - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: @@ -20,18 +20,22 @@ process OPENMS_IDMERGER { output: tuple val(meta), path("*.idXML"), emit: idxml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${aligned.baseName}_${options.suffix}" : "${meta.sample}_${meta.condition}_all_ids_merged" """ - IDMerger -in $aligned \\ - -out ${prefix}.idXML \\ - -threads ${task.cpus} \\ - -annotate_file_origin \\ - -merge_proteins_add_PSMs - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + IDMerger -in $aligned \\ + -out ${prefix}.idXML \\ + -threads $task.cpus \\ + -annotate_file_origin \\ + -merge_proteins_add_PSMs + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_mapaligneridentification.nf b/modules/local/openms_mapaligneridentification.nf index 24714583..80ac9ba3 100644 --- a/modules/local/openms_mapaligneridentification.nf +++ b/modules/local/openms_mapaligneridentification.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -8,11 +8,11 @@ process OPENMS_MAPALIGNERIDENTIFICATION { tag "$meta.id" label 'process_low' - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: @@ -20,16 +20,20 @@ process OPENMS_MAPALIGNERIDENTIFICATION { output: tuple val(meta), path("*.trafoXML"), emit: trafoxml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def out_names = idxml.collect { it.baseName+'.trafoXML' }.join(' ') """ - MapAlignerIdentification -in ${idxml} \\ - -trafo_out ${out_names} \\ - $options.args - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + MapAlignerIdentification -in $idxml \\ + -trafo_out ${out_names} \\ + $options.args + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_maprttransformer.nf b/modules/local/openms_maprttransformer.nf index e04b964f..171bc744 100644 --- a/modules/local/openms_maprttransformer.nf +++ b/modules/local/openms_maprttransformer.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -8,11 +8,11 @@ process OPENMS_MAPRTTRANSFORMER { tag "$meta.id" label 'process_low' - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: @@ -20,17 +20,21 @@ process OPENMS_MAPRTTRANSFORMER { output: tuple val(meta), path("*_aligned.*"), emit: aligned - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def fileExt = alignment_file.collect { it.name.tokenize("\\.")[1] }.join(' ') """ - MapRTTransformer -in ${alignment_file} \\ - -trafo_in ${trafoxml} \\ - -out ${meta.id}_aligned.${fileExt} \\ - -threads $task.cpus - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + MapRTTransformer -in $alignment_file \\ + -trafo_in $trafoxml \\ + -out ${meta.id}_aligned.${fileExt} \\ + -threads $task.cpus + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_mztabexporter.nf b/modules/local/openms_mztabexporter.nf index 28884aa7..bfdcece6 100644 --- a/modules/local/openms_mztabexporter.nf +++ b/modules/local/openms_mztabexporter.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -12,11 +12,11 @@ process OPENMS_MZTABEXPORTER { mode: params.publish_dir_mode, saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'Intermediate_Results', publish_id:'Intermediate_Results') } - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: @@ -24,16 +24,20 @@ process OPENMS_MZTABEXPORTER { output: tuple val(meta), path("*.mzTab"), emit: mztab - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${meta.sample}_${meta.condition}_${options.suffix}" : "${meta.sample}_${meta.condition}" """ - MzTabExporter -in ${mztab} \\ - -out ${prefix}.mzTab \\ - -threads ${task.cpus} - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + MzTabExporter -in $mztab \\ + -out ${prefix}.mzTab \\ + -threads $task.cpus + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_peakpickerhires.nf b/modules/local/openms_peakpickerhires.nf index 57b33d7e..76718e40 100644 --- a/modules/local/openms_peakpickerhires.nf +++ b/modules/local/openms_peakpickerhires.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -8,11 +8,11 @@ process OPENMS_PEAKPICKERHIRES { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: @@ -20,16 +20,20 @@ process OPENMS_PEAKPICKERHIRES { output: tuple val(meta), path("*.mzML"), emit: mzml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${mzml.baseName}_${options.suffix}" : "${mzml.baseName}" """ - PeakPickerHiRes -in ${mzml} \\ - -out ${prefix}.mzML \\ - -algorithm:ms_levels ${params.pick_ms_levels} - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + PeakPickerHiRes -in $mzml \\ + -out ${prefix}.mzML \\ + -algorithm:ms_levels ${params.pick_ms_levels} + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_peptideindexer.nf b/modules/local/openms_peptideindexer.nf index fb2ac0f5..935bfa23 100644 --- a/modules/local/openms_peptideindexer.nf +++ b/modules/local/openms_peptideindexer.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -8,11 +8,11 @@ process OPENMS_PEPTIDEINDEXER { tag "$meta.id" label 'process_low' - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: @@ -20,19 +20,23 @@ process OPENMS_PEPTIDEINDEXER { output: tuple val(meta), path("*.idXML"), emit: idxml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${idxml.baseName}_${options.suffix}" : "${idxml.baseName}_idx" """ - PeptideIndexer -in ${idxml} \\ - -out ${prefix}.idXML \\ - -threads ${task.cpus} \\ - -fasta ${fasta} \\ - -decoy_string DECOY \\ - -enzyme:specificity none - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + PeptideIndexer -in $idxml \\ + -out ${prefix}.idXML \\ + -threads $task.cpus \\ + -fasta $fasta \\ + -decoy_string DECOY \\ + -enzyme:specificity none + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_percolatoradapter.nf b/modules/local/openms_percolatoradapter.nf index 153d4bc0..e9a07e5c 100644 --- a/modules/local/openms_percolatoradapter.nf +++ b/modules/local/openms_percolatoradapter.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -12,11 +12,11 @@ process OPENMS_PERCOLATORADAPTER { mode: params.publish_dir_mode, saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'Intermediate_Results', publish_id:'Intermediate_Results') } - conda (params.enable_conda ? "bioconda::openms-thirdparty=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms-thirdparty=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms-thirdparty:2.5.0--6" + container "https://depot.galaxyproject.org/singularity/openms-thirdparty:2.6.0--0" } else { - container "quay.io/biocontainers/openms-thirdparty:2.5.0--6" + container "quay.io/biocontainers/openms-thirdparty:2.6.0--0" } input: @@ -24,17 +24,21 @@ process OPENMS_PERCOLATORADAPTER { output: tuple val(meta), path("*.idXML"), emit: idxml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${meta.id}_${options.suffix}" : "${meta.id}" """ - OMP_NUM_THREADS=${task.cpus} \\ - PercolatorAdapter -in ${psm} \\ - -out ${prefix}.idXML \\ - $options.args - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}-thirdparty.version.txt + OMP_NUM_THREADS=$task.cpus \\ + PercolatorAdapter -in $psm \\ + -out ${prefix}.idXML \\ + $options.args + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms-thirdparty: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_psmfeatureextractor.nf b/modules/local/openms_psmfeatureextractor.nf index 9a93672b..bc8fc3e3 100644 --- a/modules/local/openms_psmfeatureextractor.nf +++ b/modules/local/openms_psmfeatureextractor.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -12,11 +12,11 @@ process OPENMS_PSMFEATUREEXTRACTOR { mode: params.publish_dir_mode, saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'Intermediate_Results', publish_id:'Intermediate_Results') } - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: @@ -24,16 +24,20 @@ process OPENMS_PSMFEATUREEXTRACTOR { output: tuple val(meta), path("*.idXML"), emit: idxml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${merged.baseName}_${options.suffix}" : "${merged.baseName}_psm" """ - PSMFeatureExtractor -in ${merged} \\ - -out ${prefix}.idXML \\ - -threads ${task.cpus} - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + PSMFeatureExtractor -in $merged \\ + -out ${prefix}.idXML \\ + -threads $task.cpus + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_rtmodel.nf b/modules/local/openms_rtmodel.nf index 429a9a95..79687b59 100644 --- a/modules/local/openms_rtmodel.nf +++ b/modules/local/openms_rtmodel.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -8,11 +8,11 @@ process OPENMS_RTMODEL { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: @@ -20,18 +20,22 @@ process OPENMS_RTMODEL { output: tuple val(meta), path("*_rt_training.txt"), path("*.paramXML"), path("*_trainset.txt"), emit: complete - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${meta.sample}_${options.suffix}" : "${meta.sample}" """ - RTModel -in ${rt_training} \\ - -cv:skip_cv \\ - -out ${prefix}_rt_training.txt \\ - -out_oligo_params ${prefix}_params.paramXML \\ - -out_oligo_trainset ${prefix}_trainset.txt - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + RTModel -in $rt_training \\ + -cv:skip_cv \\ + -out ${prefix}_rt_training.txt \\ + -out_oligo_params ${prefix}_params.paramXML \\ + -out_oligo_trainset ${prefix}_trainset.txt + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_rtpredict.nf b/modules/local/openms_rtpredict.nf index cca312bc..31f95c9f 100644 --- a/modules/local/openms_rtpredict.nf +++ b/modules/local/openms_rtpredict.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -12,11 +12,11 @@ process OPENMS_RTPREDICT { mode: params.publish_dir_mode, saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'RT_prediction', publish_id:'RT_prediction') } - conda (params.enable_conda ? "bioconda::openms-thirdparty=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms-thirdparty=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms-thirdparty:2.5.0--6" + container "https://depot.galaxyproject.org/singularity/openms-thirdparty:2.6.0--0" } else { - container "quay.io/biocontainers/openms-thirdparty:2.5.0--6" + container "quay.io/biocontainers/openms-thirdparty:2.6.0--0" } input: @@ -24,18 +24,22 @@ process OPENMS_RTPREDICT { output: tuple val(meta), path("*.csv"), emit: csv - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${meta.sample}_${options.suffix}" : "${meta.sample}_RTpredicted" """ - RTPredict -in_id ${idxml} \\ - -svm_model ${rt_model} \\ - -in_oligo_params ${rt_params} \\ - -in_oligo_trainset ${trainset} \\ - -out_text:file ${prefix}.csv - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}-thirdparty.version.txt + RTPredict -in_id $idxml \\ + -svm_model $rt_model \\ + -in_oligo_params $rt_params \\ + -in_oligo_trainset $trainset \\ + -out_text:file ${prefix}.csv + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms-thirdparty: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_textexporter.nf b/modules/local/openms_textexporter.nf index 72c955a8..075dc1d5 100644 --- a/modules/local/openms_textexporter.nf +++ b/modules/local/openms_textexporter.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -12,31 +12,35 @@ process OPENMS_TEXTEXPORTER { mode: params.publish_dir_mode, saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'.', publish_id:'') } - conda (params.enable_conda ? "bioconda::openms=2.5.0" : null) + conda (params.enable_conda ? "bioconda::openms=2.6.0" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.5.0--h4afb90d_6" + container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" } else { - container "quay.io/biocontainers/openms:2.5.0--h4afb90d_6" + container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" } input: tuple val(meta), path(consensus_resolved) output: - tuple val(meta), path("*.csv"), emit: csv - path "*.version.txt", emit: version + tuple val(meta), path("*.tsv"), emit: tsv + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${meta.id}_${options.suffix}" : "${meta.id}" """ - TextExporter -in ${consensus_resolved} \\ - -out ${prefix}.csv \\ - -threads ${task.cpus} \\ - -id:add_hit_metavalues 0 \\ - -id:add_metavalues 0 \\ - -id:peptides_only - echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/ .*\$//' &> ${software}.version.txt + TextExporter -in $consensus_resolved \\ + -out ${prefix}.tsv \\ + -threads $task.cpus \\ + -id:add_hit_metavalues 0 \\ + -id:add_metavalues 0 \\ + -id:peptides_only + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + openms: \$(echo \$(FileInfo --help 2>&1) | sed 's/^.*Version: //; s/-.*\$//' | sed 's/ -*//; s/ .*\$//') + END_VERSIONS """ } diff --git a/modules/local/openms_thermorawfileparser.nf b/modules/local/openms_thermorawfileparser.nf index 00481838..166cde7e 100644 --- a/modules/local/openms_thermorawfileparser.nf +++ b/modules/local/openms_thermorawfileparser.nf @@ -1,5 +1,5 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) @@ -8,11 +8,11 @@ process OPENMS_THERMORAWFILEPARSER { tag "$meta.id" label 'process_medium' - conda (params.enable_conda ? "bioconda::thermorawfileparser::1.2.3" : null) + conda (params.enable_conda ? "bioconda::thermorawfileparser::1.3.4" : null) if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/thermorawfileparser:1.2.3--1" + container "https://depot.galaxyproject.org/singularity/thermorawfileparser:1.3.4--ha8f3691_0" } else { - container "quay.io/biocontainers/thermorawfileparser:1.2.3--1" + container "quay.io/biocontainers/thermorawfileparser:1.3.4--ha8f3691_0" } input: @@ -20,16 +20,19 @@ process OPENMS_THERMORAWFILEPARSER { output: tuple val(meta), path("*.mzML"), emit: mzml - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def software = getSoftwareName(task.process) def prefix = options.suffix ? "${rawfile.baseName}_${options.suffix}" : "${rawfile.baseName}" """ - ThermoRawFileParser.sh -i=${rawfile} \\ - -f=2 \\ - -b=${prefix}.mzML - ThermoRawFileParser.sh --version &> ThermoRawFileParser.version.txt + ThermoRawFileParser.sh -i=$rawfile \\ + -f=2 \\ + -b=${prefix}.mzML + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + thermorawfileparser: \$(ThermoRawFileParser.sh --version) + END_VERSIONS """ } diff --git a/modules/local/predict_neoepitopes_mhcnuggets_class_2.nf b/modules/local/predict_neoepitopes_mhcnuggets_class_2.nf deleted file mode 100644 index ed60d928..00000000 --- a/modules/local/predict_neoepitopes_mhcnuggets_class_2.nf +++ /dev/null @@ -1,34 +0,0 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' - -params.options = [:] -options = initOptions(params.options) - -def VERSION = '2.3.2' - -process PREDICT_NEOEPITOPES_MHCNUGGETS_CLASS_2 { - tag "$meta" - label 'process_low' - - conda (params.enable_conda ? "bioconda::mhcnuggets=2.3.2--py_0" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/mhcnuggets:2.3.2--py_0" - } else { - container "quay.io/biocontainers/mhcnuggets:2.3.2--py_0" - } - - input: - tuple val(meta), path(neoepitopes), val(alleles) - - output: - tuple val(meta), path("*_predicted_neoepitopes_class_2"), emit: csv - path "*.version.txt", emit: version - - script: - def prefix = options.suffix ? "${meta}_${options.suffix}" : "${meta}_predicted_neoepitopes_class_2" - - """ - mhcnuggets_predict_peptides.py --peptides ${neoepitopes} --alleles '${alleles}' --output ${prefix} - echo $VERSION > mhcnuggets.version.txt - """ -} diff --git a/modules/local/predict_peptides_mhcnuggets_class_2.nf b/modules/local/predict_peptides_mhcnuggets_class_2.nf deleted file mode 100644 index 4fb51a6e..00000000 --- a/modules/local/predict_peptides_mhcnuggets_class_2.nf +++ /dev/null @@ -1,36 +0,0 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' - -params.options = [:] -options = initOptions(params.options) - -def VERSIONFRED2 = '2.0.6' -def VERSIONMHCNUGGETS = '2.3.2' - -process PREDICT_PEPTIDES_MHCNUGGETS_CLASS_2 { - tag "$meta" - label 'process_low' - - conda (params.enable_conda ? "bioconda::fred2=2.0.6 bioconda::mhcflurry=1.4.3 bioconda::mhcnuggets=2.3.2" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/mulled-v2-689ae0756dd82c61400782baaa8a7a1c2289930d:a9e10ca22d4cbcabf6b54f0fb5d766ea16bb171e-0" - } else { - container "quay.io/biocontainers/mulled-v2-689ae0756dd82c61400782baaa8a7a1c2289930d:a9e10ca22d4cbcabf6b54f0fb5d766ea16bb171e-0" - } - - input: - tuple val(meta), path(peptides), val(alleles) - - output: - tuple val(meta), path("*_predicted_peptides_class_2"), emit: csv - path "*.version.txt", emit: version - - script: - def prefix = options.suffix ? "${meta.sample}_${options.suffix}" : "${meta.sample}_predicted_peptides_class_2" - - """ - mhcnuggets_predict_peptides.py --peptides ${peptides} --alleles '${alleles}' --output ${prefix} - echo $VERSIONFRED2 > fred2.version.txt - echo $VERSIONMHCNUGGETS > mhcnuggets.version.txt - """ -} diff --git a/modules/local/predict_possible_class_2_neoepitopes.nf b/modules/local/predict_possible_class_2_neoepitopes.nf index 85eddb38..11162f1c 100644 --- a/modules/local/predict_possible_class_2_neoepitopes.nf +++ b/modules/local/predict_possible_class_2_neoepitopes.nf @@ -1,12 +1,9 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) -def VERSIONFRED2 = '2.0.6' -def VERSIONMHCNUGGETS = '2.3.2' - process PREDICT_POSSIBLE_CLASS_2_NEOEPITOPES { tag "$meta" label 'process_low' @@ -26,17 +23,27 @@ process PREDICT_POSSIBLE_CLASS_2_NEOEPITOPES { tuple val(meta), val(alleles), path(vcf) output: - tuple val(meta), path("*.csv"), emit: csv + tuple val(meta), path("*.csv") , emit: csv tuple val(meta), path("${prefix}.txt"), emit: txt - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def prefix = options.suffix ? "${meta}_${options.suffix}" : "${meta}_vcf_neoepitopes_class2" """ - vcf_neoepitope_predictor.py -t ${params.variant_annotation_style} -r ${params.variant_reference} -a '${alleles}' -minl ${params.peptide_min_length} -maxl ${params.peptide_max_length} -v ${vcf} -o ${prefix}.csv - echo $VERSIONFRED2 > fred2.version.txt - echo $VERSIONMHCNUGGETS > mhcnuggets.version.txt - mhcflurry-predict --version &> mhcflurry.version.txt + vcf_neoepitope_predictor.py -t ${params.variant_annotation_style} \\ + -r ${params.variant_reference} \\ + -a '$alleles' \\ + -minl ${params.peptide_min_length} \\ + -maxl ${params.peptide_max_length} \\ + -v $vcf \\ + -o ${prefix}.csv + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcflurry: \$(echo \$(mhcflurry-predict --version 2>&1 | sed 's/^mhcflurry //; s/ .*\$//') ) + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//' )) + fred2: \$(echo \$(python -c "import pkg_resources; print('fred2' + pkg_resources.get_distribution('Fred2').version)" | sed 's/^fred2//; s/ .*\$//')) + END_VERSIONS """ } diff --git a/modules/local/predict_possible_neoepitopes.nf b/modules/local/predict_possible_neoepitopes.nf index 07b5adf7..e775e982 100644 --- a/modules/local/predict_possible_neoepitopes.nf +++ b/modules/local/predict_possible_neoepitopes.nf @@ -1,12 +1,9 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) -def VERSIONFRED2 = '2.0.6' -def VERSIONMHCNUGGETS = '2.3.2' - process PREDICT_POSSIBLE_NEOEPITOPES { tag "$meta" label 'process_low' @@ -28,15 +25,25 @@ process PREDICT_POSSIBLE_NEOEPITOPES { output: tuple val(meta), path("${prefix}.csv"), emit: csv tuple val(meta), path("${prefix}.txt"), emit: txt - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def prefix = options.suffix ? "${meta}_${options.suffix}" : "${meta}_vcf_neoepitopes_class1" """ - vcf_neoepitope_predictor.py -t ${params.variant_annotation_style} -r ${params.variant_reference} -a '${alleles}' -minl ${params.peptide_min_length} -maxl ${params.peptide_max_length} -v ${vcf} -o ${prefix}.csv - echo $VERSIONFRED2 > fred2.version.txt - echo $VERSIONMHCNUGGETS > mhcnuggets.version.txt - mhcflurry-predict --version &> mhcflurry.version.txt + vcf_neoepitope_predictor.py \\ + -t ${params.variant_annotation_style} \\ + -r ${params.variant_reference} \\ + -a '$alleles' -minl ${params.peptide_min_length} \\ + -maxl ${params.peptide_max_length} \\ + -v $vcf \\ + -o ${prefix}.csv + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcflurry: \$(echo \$(mhcflurry-predict --version 2>&1 | sed 's/^mhcflurry //; s/ .*\$//') ) + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//' )) + fred2: \$(echo \$(python -c "import pkg_resources; print('fred2' + pkg_resources.get_distribution('Fred2').version)" | sed 's/^fred2//; s/ .*\$//')) + END_VERSIONS """ } diff --git a/modules/local/preprocess_neoepitopes_mhcnuggets_class_2.nf b/modules/local/preprocess_neoepitopes_mhcnuggets_class_2.nf deleted file mode 100644 index e770d025..00000000 --- a/modules/local/preprocess_neoepitopes_mhcnuggets_class_2.nf +++ /dev/null @@ -1,34 +0,0 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' - -params.options = [:] -options = initOptions(params.options) - -def VERSION = '2.3.2' - -process PREPROCESS_NEOEPITOPES_MHCNUGGETS_CLASS_2 { - tag "$meta" - label 'process_low' - - conda (params.enable_conda ? "bioconda::mhcnuggets=2.3.2--py_0" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/mhcnuggets:2.3.2--py_0" - } else { - container "quay.io/biocontainers/mhcnuggets:2.3.2--py_0" - } - - input: - tuple val(meta), path(neoepitopes) - - output: - tuple val(meta), path("*${prefix}*"), emit: preprocessed - path "*.version.txt", emit: version - - script: - def prefix = options.suffix ? "${meta}_${options.suffix}" : "${meta}_mhcnuggets_preprocessed" - - """ - preprocess_neoepitopes_mhcnuggets.py --neoepitopes ${neoepitopes} --output ${prefix} - echo $VERSION > mhcnuggets.version.txt - """ -} diff --git a/modules/local/preprocess_peptides_mhcnuggets_class_2.nf b/modules/local/preprocess_peptides_mhcnuggets_class_2.nf deleted file mode 100644 index 945337de..00000000 --- a/modules/local/preprocess_peptides_mhcnuggets_class_2.nf +++ /dev/null @@ -1,35 +0,0 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' - -params.options = [:] -options = initOptions(params.options) - -def VERSION = '2.3.2' - -process PREPROCESS_PEPTIDES_MHCNUGGETS_CLASS_2 { - tag "$meta" - label 'process_low' - - conda (params.enable_conda ? "bioconda::mhcnuggets=2.3.2--py_0" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/mhcnuggets:2.3.2--py_0" - } else { - container "quay.io/biocontainers/mhcnuggets:2.3.2--py_0" - } - - input: - tuple val(meta), path(mztab) - - output: - tuple val(meta), path("*_preprocessed_mhcnuggets_peptides"), emit: preprocessed - tuple val(meta), path('*peptide_to_geneID*'), emit: geneID - path "*.version.txt", emit: version - - script: - def prefix = options.suffix ? "${meta.sample}_${options.suffix}" : "${meta.sample}_preprocessed_mhcnuggets_peptides" - - """ - preprocess_peptides_mhcnuggets.py --mztab ${mztab} --output ${prefix} - echo $VERSION > mhcnuggets.version.txt - """ -} diff --git a/modules/local/resolve_found_class_2_neoepitopes.nf b/modules/local/resolve_found_class_2_neoepitopes.nf index caad6e93..80fd21c5 100644 --- a/modules/local/resolve_found_class_2_neoepitopes.nf +++ b/modules/local/resolve_found_class_2_neoepitopes.nf @@ -1,19 +1,16 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) -def VERSIONFRED2 = '2.0.6' -def VERSIONMHCNUGGETS = '2.3.2' - process RESOLVE_FOUND_CLASS_2_NEOEPITOPES { tag "$meta" label 'process_low' publishDir "${params.outdir}", mode: params.publish_dir_mode, - saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'.', publish_id:'') } + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'class_2_bindings', publish_id:'class_2_bindings') } echo true @@ -29,15 +26,22 @@ process RESOLVE_FOUND_CLASS_2_NEOEPITOPES { output: tuple val(meta), path("*.csv"), emit: csv - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def prefix = options.suffix ? "${meta}_${options.suffix}" : "${meta}_found_neoepitopes_class_2" """ - resolve_neoepitopes.py -n ${neoepitopes} -m ${mztab} -f csv -o ${prefix} - echo $VERSIONFRED2 > fred2.version.txt - echo $VERSIONMHCNUGGETS > mhcnuggets.version.txt - mhcflurry-predict --version &> mhcflurry.version.txt + resolve_neoepitopes.py -n $neoepitopes \\ + -m $mztab \\ + -f csv \\ + -o ${prefix} + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcflurry: \$(echo \$(mhcflurry-predict --version 2>&1 | sed 's/^mhcflurry //; s/ .*\$//') ) + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//' )) + fred2: \$(echo \$(python -c "import pkg_resources; print('fred2' + pkg_resources.get_distribution('Fred2').version)" | sed 's/^fred2//; s/ .*\$//')) + END_VERSIONS """ } diff --git a/modules/local/resolve_found_neoepitopes.nf b/modules/local/resolve_found_neoepitopes.nf index 85ad65bf..ece53e31 100644 --- a/modules/local/resolve_found_neoepitopes.nf +++ b/modules/local/resolve_found_neoepitopes.nf @@ -1,12 +1,9 @@ // Import generic module functions -include { initOptions; saveFiles; getSoftwareName } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) -def VERSIONFRED2 = '2.0.6' -def VERSIONMHCNUGGETS = '2.3.2' - process RESOLVE_FOUND_NEOEPITOPES { tag "$meta" label 'process_low' @@ -27,15 +24,22 @@ process RESOLVE_FOUND_NEOEPITOPES { output: tuple val(meta), path("*.csv"), emit: csv - path "*.version.txt", emit: version + path "versions.yml" , emit: versions script: def prefix = options.suffix ? "${meta}_${options.suffix}" : "${meta}_found_neoepitopes_class_1" """ - resolve_neoepitopes.py -n ${neoepitopes} -m ${mztab} -f csv -o ${prefix} - echo $VERSIONFRED2 > fred2.version.txt - echo $VERSIONMHCNUGGETS > mhcnuggets.version.txt - mhcflurry-predict --version &> mhcflurry.version.txt + resolve_neoepitopes.py -n $neoepitopes \\ + -m $mztab \\ + -f csv \\ + -o ${prefix} + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + mhcflurry: \$(echo \$(mhcflurry-predict --version 2>&1 | sed 's/^mhcflurry //; s/ .*\$//') ) + mhcnuggets: \$(echo \$(python -c "import pkg_resources; print('mhcnuggets' + pkg_resources.get_distribution('mhcnuggets').version)" | sed 's/^mhcnuggets//; s/ .*\$//')) + fred2: \$(echo \$(python -c "import pkg_resources; print('fred2' + pkg_resources.get_distribution('Fred2').version)" | sed 's/^fred2//; s/ .*\$//')) + END_VERSIONS """ } diff --git a/modules/local/samplesheet_check.nf b/modules/local/samplesheet_check.nf index 476f8c81..15a9665a 100644 --- a/modules/local/samplesheet_check.nf +++ b/modules/local/samplesheet_check.nf @@ -1,50 +1,38 @@ // Import generic module functions -include { initOptions; saveFiles } from './functions' +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' params.options = [:] options = initOptions(params.options) -/* - * Reformat design file and check validity - */ process SAMPLESHEET_CHECK { tag "$samplesheet" - label 'process_low' - publishDir "${params.outdir}", mode: params.publish_dir_mode, - saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', publish_id:'') } + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', meta:[:], publish_by_meta:[]) } - conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) - container "quay.io/biocontainers/python:3.8.3" + conda (params.enable_conda ? "conda-forge::python=3.8.3" : null) + if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { + container "https://depot.galaxyproject.org/singularity/python:3.8.3" + } else { + container "quay.io/biocontainers/python:3.8.3" + } input: - path samplesheet + path samplesheet output: - path '*.csv' - - - script: + path '*.csv' , emit: csv + path "versions.yml", emit: versions + script: // This script is bundled with the pipeline, in nf-core/mhcquant/bin/ """ - check_samplesheet.py $samplesheet samplesheet.valid.csv + check_samplesheet.py \\ + $samplesheet \\ + samplesheet.valid.csv + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + python: \$(echo \$(python --version | sed 's/Python //g')) + END_VERSIONS """ } - -// Function to get list of [ meta, filenames ] -def get_samplesheet_paths(LinkedHashMap row) { - def meta = [:] - meta.id = row.ID - meta.sample = row.Sample - meta.condition = row.Condition - meta.ext = row.FileExt - - def array = [] - if (!file(row.Filename).exists()) { - exit 1, "ERROR: Please check input samplesheet -> MS file does not exist!\n${row.Filename}" - } else { - array = [ meta, file(row.Filename) ] - } - return array -} diff --git a/modules/local/subworkflow/input_check.nf b/modules/local/subworkflow/input_check.nf deleted file mode 100644 index ab1c3846..00000000 --- a/modules/local/subworkflow/input_check.nf +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Check input samplesheet and get read channels - */ - -params.options = [:] - -include { - SAMPLESHEET_CHECK; - get_samplesheet_paths } from '../samplesheet_check' addParams( options: params.options ) - -workflow INPUT_CHECK { - take: - samplesheet // file: /path/to/samplesheet.csv - - main: - SAMPLESHEET_CHECK ( samplesheet ) - .splitCsv ( header:true, sep:'\t' ) - .map { get_samplesheet_paths(it) } - .set { reads } - - emit: - reads // channel: [ val(meta), [ reads ] ] -} diff --git a/modules/local/subworkflow/refine_fdr_on_predicted_subset.nf b/modules/local/subworkflow/refine_fdr_on_predicted_subset.nf deleted file mode 100644 index 1dab5184..00000000 --- a/modules/local/subworkflow/refine_fdr_on_predicted_subset.nf +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Perform an additional step where the process are collected - * that are called when the paramater "refine_fdr_on_predicted_subset" is provided - */ - -// VALIDATED (EQUAL TO THE OLD CODE) - -params.percolator_adapter_options = [:] -params.filter_options = [:] -params.whitelist_filter_options = [:] - -def percolator_adapter_options = params.percolator_adapter_options.clone() -percolator_adapter_options.suffix = "perc_subset" - -def filter_psms_options = params.whitelist_filter_options.clone() -def filter_refined_qvalue_options = params.filter_options.clone() - -filter_psms_options.suffix = "pred_filtered" -filter_refined_qvalue_options.suffix = "perc_subset_filtered" - -include { OPENMS_MZTABEXPORTER as OPENMS_MZTABEXPORTERPERC } from '../openms_mztabexporter' addParams( options: [ suffix: "all_ids_merged_psm_perc_filtered" ] ) -include { OPENMS_MZTABEXPORTER as OPENMS_MZTABEXPORTERPSM } from '../openms_mztabexporter' addParams( options: [ suffix: "all_ids_merged" ] ) -include { PREDICT_PSMS } from '../predict_psms' addParams( options: [:] ) -include { OPENMS_PERCOLATORADAPTER } from '../openms_percolatoradapter' addParams( options: percolator_adapter_options ) -include { OPENMS_IDFILTER as OPENMS_IDFILTER_PSMS } from '../openms_idfilter' addParams( options: filter_psms_options ) -include { OPENMS_IDFILTER as OPENMS_IDFILTER_REFINED } from '../openms_idfilter' addParams( options: filter_refined_qvalue_options ) - -workflow REFINE_FDR_ON_PREDICTED_SUBSET { - // Define the input parameters - take: - filtered_perc_output - psm_features - classI_alleles - - main: - ch_software_versions = Channel.empty() - // Export filtered percolator results as mztab - OPENMS_MZTABEXPORTERPERC( filtered_perc_output ) - ch_software_versions = ch_software_versions.mix(OPENMS_MZTABEXPORTERPERC.out.version.first().ifEmpty(null)) - // Export psm results as mztab - OPENMS_MZTABEXPORTERPSM( psm_features ) - // Predict psm results using mhcflurry to shrink search space - PREDICT_PSMS( - OPENMS_MZTABEXPORTERPERC.out.mztab - .join( OPENMS_MZTABEXPORTERPSM.out.mztab, by:[0] ) - .map{ it -> [it[0].sample, it[0], it[1], it[2]] } - .combine( classI_alleles, by:0) - .map(it -> [it[1], it[2], it[3], it[4]]) - ) - - // Filter psm results by shrinked search space - OPENMS_IDFILTER_PSMS(psm_features.combine( PREDICT_PSMS.out.idxml, by: [0] )) - // Recompute percolator fdr on shrinked search space - OPENMS_PERCOLATORADAPTER( OPENMS_IDFILTER_PSMS.out.idxml ) - // Filter results by refined fdr - OPENMS_IDFILTER_REFINED(OPENMS_PERCOLATORADAPTER.out.idxml.flatMap { it -> [tuple(it[0], it[1], null)]}) - emit: - // Define the information that is returned by this workflow - filter_refined_q_value = OPENMS_IDFILTER_REFINED.out.idxml - version = ch_software_versions -} diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/functions.nf b/modules/nf-core/modules/custom/dumpsoftwareversions/functions.nf new file mode 100644 index 00000000..85628ee0 --- /dev/null +++ b/modules/nf-core/modules/custom/dumpsoftwareversions/functions.nf @@ -0,0 +1,78 @@ +// +// Utility functions used in nf-core DSL2 module files +// + +// +// Extract name of software tool from process name using $task.process +// +def getSoftwareName(task_process) { + return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() +} + +// +// Extract name of module from process name using $task.process +// +def getProcessName(task_process) { + return task_process.tokenize(':')[-1] +} + +// +// Function to initialise default values and to generate a Groovy Map of available options for nf-core modules +// +def initOptions(Map args) { + def Map options = [:] + options.args = args.args ?: '' + options.args2 = args.args2 ?: '' + options.args3 = args.args3 ?: '' + options.publish_by_meta = args.publish_by_meta ?: [] + options.publish_dir = args.publish_dir ?: '' + options.publish_files = args.publish_files + options.suffix = args.suffix ?: '' + return options +} + +// +// Tidy up and join elements of a list to return a path string +// +def getPathFromList(path_list) { + def paths = path_list.findAll { item -> !item?.trim().isEmpty() } // Remove empty entries + paths = paths.collect { it.trim().replaceAll("^[/]+|[/]+\$", "") } // Trim whitespace and trailing slashes + return paths.join('/') +} + +// +// Function to save/publish module results +// +def saveFiles(Map args) { + def ioptions = initOptions(args.options) + def path_list = [ ioptions.publish_dir ?: args.publish_dir ] + + // Do not publish versions.yml unless running from pytest workflow + if (args.filename.equals('versions.yml') && !System.getenv("NF_CORE_MODULES_TEST")) { + return null + } + if (ioptions.publish_by_meta) { + def key_list = ioptions.publish_by_meta instanceof List ? ioptions.publish_by_meta : args.publish_by_meta + for (key in key_list) { + if (args.meta && key instanceof String) { + def path = key + if (args.meta.containsKey(key)) { + path = args.meta[key] instanceof Boolean ? "${key}_${args.meta[key]}".toString() : args.meta[key] + } + path = path instanceof String ? path : '' + path_list.add(path) + } + } + } + if (ioptions.publish_files instanceof Map) { + for (ext in ioptions.publish_files) { + if (args.filename.endsWith(ext.key)) { + def ext_list = path_list.collect() + ext_list.add(ext.value) + return "${getPathFromList(ext_list)}/$args.filename" + } + } + } else if (ioptions.publish_files == null) { + return "${getPathFromList(path_list)}/$args.filename" + } +} diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf b/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf new file mode 100644 index 00000000..faf2073f --- /dev/null +++ b/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf @@ -0,0 +1,106 @@ +// Import generic module functions +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' + +params.options = [:] +options = initOptions(params.options) + +process CUSTOM_DUMPSOFTWAREVERSIONS { + label 'process_low' + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', meta:[:], publish_by_meta:[]) } + + // Requires `pyyaml` which does not have a dedicated container but is in the MultiQC container + conda (params.enable_conda ? "bioconda::multiqc=1.11" : null) + if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { + container "https://depot.galaxyproject.org/singularity/multiqc:1.11--pyhdfd78af_0" + } else { + container "quay.io/biocontainers/multiqc:1.11--pyhdfd78af_0" + } + + input: + path versions + + output: + path "software_versions.yml" , emit: yml + path "software_versions_mqc.yml", emit: mqc_yml + path "versions.yml" , emit: versions + + script: + """ + #!/usr/bin/env python + + import yaml + import platform + from textwrap import dedent + + def _make_versions_html(versions): + html = [ + dedent( + '''\\ + + + + + + + + + + ''' + ) + ] + for process, tmp_versions in sorted(versions.items()): + html.append("") + for i, (tool, version) in enumerate(sorted(tmp_versions.items())): + html.append( + dedent( + f'''\\ + + + + + + ''' + ) + ) + html.append("") + html.append("
Process Name Software Version
{process if (i == 0) else ''}{tool}{version}
") + return "\\n".join(html) + + module_versions = {} + module_versions["${getProcessName(task.process)}"] = { + 'python': platform.python_version(), + 'yaml': yaml.__version__ + } + + with open("$versions") as f: + workflow_versions = yaml.load(f, Loader=yaml.BaseLoader) | module_versions + + workflow_versions["Workflow"] = { + "Nextflow": "$workflow.nextflow.version", + "$workflow.manifest.name": "$workflow.manifest.version" + } + + versions_mqc = { + 'id': 'software_versions', + 'section_name': '${workflow.manifest.name} Software Versions', + 'section_href': 'https://github.com/${workflow.manifest.name}', + 'plot_type': 'html', + 'description': 'are collected at run time from the software output.', + 'data': _make_versions_html(workflow_versions) + } + + with open("software_versions.yml", 'w') as f: + yaml.dump(workflow_versions, f, default_flow_style=False) + with open("software_versions_mqc.yml", 'w') as f: + yaml.dump(versions_mqc, f, default_flow_style=False) + + with open('versions.yml', 'w') as f: + yaml.dump(module_versions, f, default_flow_style=False) + """ +} diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml b/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml new file mode 100644 index 00000000..c8310e35 --- /dev/null +++ b/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml @@ -0,0 +1,33 @@ +name: custom_dumpsoftwareversions +description: Custom module used to dump software versions within the nf-core pipeline template +keywords: + - custom + - version +tools: + - custom: + description: Custom module used to dump software versions within the nf-core pipeline template + homepage: https://github.com/nf-core/tools + documentation: https://github.com/nf-core/tools + licence: ['MIT'] +input: + - versions: + type: file + description: YML file containing software versions + pattern: "*.yml" + +output: + - yml: + type: file + description: Standard YML file containing software versions + pattern: "software_versions.yml" + - mqc_yml: + type: file + description: MultiQC custom content YML file containing software versions + pattern: "software_versions_mqc.yml" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + +authors: + - "@drpatelh" diff --git a/modules/nf-core/modules/multiqc/functions.nf b/modules/nf-core/modules/multiqc/functions.nf new file mode 100644 index 00000000..85628ee0 --- /dev/null +++ b/modules/nf-core/modules/multiqc/functions.nf @@ -0,0 +1,78 @@ +// +// Utility functions used in nf-core DSL2 module files +// + +// +// Extract name of software tool from process name using $task.process +// +def getSoftwareName(task_process) { + return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() +} + +// +// Extract name of module from process name using $task.process +// +def getProcessName(task_process) { + return task_process.tokenize(':')[-1] +} + +// +// Function to initialise default values and to generate a Groovy Map of available options for nf-core modules +// +def initOptions(Map args) { + def Map options = [:] + options.args = args.args ?: '' + options.args2 = args.args2 ?: '' + options.args3 = args.args3 ?: '' + options.publish_by_meta = args.publish_by_meta ?: [] + options.publish_dir = args.publish_dir ?: '' + options.publish_files = args.publish_files + options.suffix = args.suffix ?: '' + return options +} + +// +// Tidy up and join elements of a list to return a path string +// +def getPathFromList(path_list) { + def paths = path_list.findAll { item -> !item?.trim().isEmpty() } // Remove empty entries + paths = paths.collect { it.trim().replaceAll("^[/]+|[/]+\$", "") } // Trim whitespace and trailing slashes + return paths.join('/') +} + +// +// Function to save/publish module results +// +def saveFiles(Map args) { + def ioptions = initOptions(args.options) + def path_list = [ ioptions.publish_dir ?: args.publish_dir ] + + // Do not publish versions.yml unless running from pytest workflow + if (args.filename.equals('versions.yml') && !System.getenv("NF_CORE_MODULES_TEST")) { + return null + } + if (ioptions.publish_by_meta) { + def key_list = ioptions.publish_by_meta instanceof List ? ioptions.publish_by_meta : args.publish_by_meta + for (key in key_list) { + if (args.meta && key instanceof String) { + def path = key + if (args.meta.containsKey(key)) { + path = args.meta[key] instanceof Boolean ? "${key}_${args.meta[key]}".toString() : args.meta[key] + } + path = path instanceof String ? path : '' + path_list.add(path) + } + } + } + if (ioptions.publish_files instanceof Map) { + for (ext in ioptions.publish_files) { + if (args.filename.endsWith(ext.key)) { + def ext_list = path_list.collect() + ext_list.add(ext.value) + return "${getPathFromList(ext_list)}/$args.filename" + } + } + } else if (ioptions.publish_files == null) { + return "${getPathFromList(path_list)}/$args.filename" + } +} diff --git a/modules/nf-core/modules/multiqc/main.nf b/modules/nf-core/modules/multiqc/main.nf new file mode 100644 index 00000000..0861aa59 --- /dev/null +++ b/modules/nf-core/modules/multiqc/main.nf @@ -0,0 +1,38 @@ +// Import generic module functions +include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' + +params.options = [:] +options = initOptions(params.options) + +process MULTIQC { + label 'process_medium' + publishDir "${params.outdir}", + mode: params.publish_dir_mode, + saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:getSoftwareName(task.process), meta:[:], publish_by_meta:[]) } + + conda (params.enable_conda ? 'bioconda::multiqc=1.11' : null) + if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { + container "https://depot.galaxyproject.org/singularity/multiqc:1.11--pyhdfd78af_0" + } else { + container "quay.io/biocontainers/multiqc:1.11--pyhdfd78af_0" + } + + input: + path multiqc_files + + output: + path "*multiqc_report.html", emit: report + path "*_data" , emit: data + path "*_plots" , optional:true, emit: plots + path "versions.yml" , emit: versions + + script: + """ + multiqc -f $options.args . + + cat <<-END_VERSIONS > versions.yml + ${getProcessName(task.process)}: + ${getSoftwareName(task.process)}: \$( multiqc --version | sed -e "s/multiqc, version //g" ) + END_VERSIONS + """ +} diff --git a/modules/nf-core/modules/multiqc/meta.yml b/modules/nf-core/modules/multiqc/meta.yml new file mode 100644 index 00000000..63c75a45 --- /dev/null +++ b/modules/nf-core/modules/multiqc/meta.yml @@ -0,0 +1,40 @@ +name: MultiQC +description: Aggregate results from bioinformatics analyses across many samples into a single report +keywords: + - QC + - bioinformatics tools + - Beautiful stand-alone HTML report +tools: + - multiqc: + description: | + MultiQC searches a given directory for analysis logs and compiles a HTML report. + It's a general use tool, perfect for summarising the output from numerous bioinformatics tools. + homepage: https://multiqc.info/ + documentation: https://multiqc.info/docs/ + licence: ['GPL-3.0-or-later'] +input: + - multiqc_files: + type: file + description: | + List of reports / files recognised by MultiQC, for example the html and zip output of FastQC +output: + - report: + type: file + description: MultiQC report file + pattern: "multiqc_report.html" + - data: + type: dir + description: MultiQC data dir + pattern: "multiqc_data" + - plots: + type: file + description: Plots created by MultiQC + pattern: "*_data" + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" +authors: + - "@abhi18av" + - "@bunop" + - "@drpatelh" diff --git a/nextflow.config b/nextflow.config index 541c3117..f895cfc9 100644 --- a/nextflow.config +++ b/nextflow.config @@ -1,94 +1,111 @@ /* - * ------------------------------------------------- - * nf-core/mhcquant Nextflow config file - * ------------------------------------------------- - * Default config options for all environments. - */ +======================================================================================== + nf-core/mhcquant Nextflow config file +======================================================================================== + Default config options for all compute environments +---------------------------------------------------------------------------------------- +*/ // Global default params, used in configs params { // Workflow flags - help = false - input = "sample_sheet.tsv" - outdir = './results' - fasta = "data/*.fasta" - publish_dir_mode = 'copy' + help = false + input = "sample_sheet.tsv" + outdir = './results' + fasta = "data/*.fasta" + publish_dir_mode = 'copy' + + // References + genomes = null // Workflow options - allele_sheet = false - include_proteins_from_vcf = false - predict_class_1 = false - predict_class_2 = false + allele_sheet = false + include_proteins_from_vcf = false + predict_class_1 = false + predict_class_2 = false refine_fdr_on_predicted_subset = false - schema_ignore_params = 'genomes,input_paths' - skip_decoy_generation = false - subset_affinity_threshold = 500 - variant_annotation_style = "SNPEFF" - variant_frameshift_filter = false - variant_indel_filter = false - variant_reference = "GRCH38" - variant_snp_filter = false + schema_ignore_params = 'genome,input_paths' + skip_decoy_generation = false + subset_affinity_threshold = 500 + variant_annotation_style = "SNPEFF" + variant_frameshift_filter = false + variant_indel_filter = false + variant_reference = "GRCH38" + variant_snp_filter = false + + // MultiQC options + skip_multiqc = false + multiqc_config = null + multiqc_title = null + max_multiqc_email_size = '25.MB' // Workflow defaults - activation_method = 'ALL' - description_correct_features = 0 - digest_mass_range = "800:2500" - enzyme = 'unspecific cleavage' - fdr_threshold = 0.01 - fdr_level = 'peptide-level-fdrs' - fixed_mods = '' - fragment_bin_offset = 0 - fragment_mass_tolerance = 0.02 - klammer = false - max_rt_alignment_shift = 300 - number_mods = 3 - num_hits = 1 - peptide_min_length = 8 - peptide_max_length = 12 - pick_ms_levels = 2 - predict_RT = false - prec_charge = '2:3' - precursor_mass_tolerance = 5 - quantification_fdr = false - quantification_min_prob = 0 + activation_method = 'ALL' + description_correct_features = 0 + digest_mass_range = "800:2500" + enzyme = 'unspecific cleavage' + fdr_threshold = 0.01 + fdr_level = 'peptide_level_fdrs' + fixed_mods = '' + fragment_bin_offset = 0 + fragment_mass_tolerance = 0.02 + klammer = false + max_rt_alignment_shift = 300 + number_mods = 3 + num_hits = 1 + peptide_min_length = 8 + peptide_max_length = 12 + pick_ms_levels = 2 + predict_RT = false + prec_charge = '2:3' + precursor_mass_tolerance = 5 + quantification_fdr = false + quantification_min_prob = 0 refine_fdr_on_predicted_subset = false - remove_precursor_peak = false - run_centroidisation = false - skip_quantification = false - spectrum_batch_size = 500 - subset_max_train = 0 - tracedir = "${params.outdir}/pipeline_info" - use_x_ions = false - use_z_ions = false - use_a_ions = false - use_c_ions = false - use_NL_ions = false - variable_mods = 'Oxidation (M)' - vcf_sheet = false + remove_precursor_peak = false + run_centroidisation = false + skip_quantification = false + spectrum_batch_size = 500 + subset_max_train = 0 + tracedir = "${params.outdir}/pipeline_info" + use_x_ions = false + use_z_ions = false + use_a_ions = false + use_c_ions = false + use_NL_ions = false + variable_mods = 'Oxidation (M)' + vcf_sheet = false // Boilerplate options - email = false - email_on_fail = false - enable_conda = false - max_multiqc_email_size = '25.MB' - monochrome_logs = false - multiqc_config = false - plaintext_email = false - publish_dir_mode = 'copy' - show_hidden_params = true - skip_multiqc = true - tracedir = "${params.outdir}/pipeline_info" - validate_params = true + outdir = './results' + tracedir = "${params.outdir}/pipeline_info" + publish_dir_mode = 'copy' + email = null + email_on_fail = null + plaintext_email = false + monochrome_logs = false + help = false + validate_params = true + show_hidden_params = false + schema_ignore_params = 'genomes,modules' + enable_conda = false + singularity_pull_docker_container = false // Config options - custom_config_version = 'master' - custom_config_base = "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}" - hostnames = [:] - config_profile_name = false - config_profile_description = false - config_profile_contact = false - config_profile_url = false + custom_config_version = 'master' + custom_config_base = "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}" + hostnames = [:] + config_profile_description = null + config_profile_contact = null + config_profile_url = null + config_profile_name = null + + // Max resource options + // Defaults only, expecting to be overwritten + max_memory = '128.GB' + max_cpus = 16 + max_time = '240.h' } // Load base.config by default for all pipelines @@ -114,65 +131,59 @@ try { profiles { debug { process.beforeScript = 'echo $HOSTNAME' } conda { - params.enable_conda = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false + params.enable_conda = true + docker.enabled = false + singularity.enabled = false + podman.enabled = false + shifter.enabled = false + charliecloud.enabled = false } docker { - docker.enabled = true - docker.userEmulation = true - singularity.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false - // Avoid this error: - // WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap. - // Testing this in nf-core after discussion here https://github.com/nf-core/tools/pull/351 - // once this is established and works well, nextflow might implement this behavior as new default. - // NOTE: This breaks MHCFlurry! - // docker.runOptions = '-u \$(id -u):\$(id -g)' + docker.enabled = true + docker.userEmulation = true + singularity.enabled = false + podman.enabled = false + shifter.enabled = false + charliecloud.enabled = false } singularity { - singularity.enabled = true - singularity.autoMounts = true - docker.enabled = false - podman.enabled = false - shifter.enabled = false - charliecloud.enabled = false + singularity.enabled = true + singularity.autoMounts = true + docker.enabled = false + podman.enabled = false + shifter.enabled = false + charliecloud.enabled = false } podman { - podman.enabled = true - docker.enabled = false - singularity.enabled = false - shifter.enabled = false - charliecloud.enabled = false + podman.enabled = true + docker.enabled = false + singularity.enabled = false + shifter.enabled = false + charliecloud.enabled = false } shifter { - shifter.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - charliecloud.enabled = false + shifter.enabled = true + docker.enabled = false + singularity.enabled = false + podman.enabled = false + charliecloud.enabled = false } charliecloud { - charliecloud.enabled = true - docker.enabled = false - singularity.enabled = false - podman.enabled = false - shifter.enabled = false + charliecloud.enabled = true + docker.enabled = false + singularity.enabled = false + podman.enabled = false + shifter.enabled = false } - test { includeConfig 'conf/test.config' } + test { includeConfig 'conf/test.config' } test_full { includeConfig 'conf/test_full.config' } } // Export these variables to prevent local Python/R libraries from conflicting with those in the container env { PYTHONNOUSERSITE = 1 - R_PROFILE_USER = "/.Rprofile" - R_ENVIRON_USER = "/.Renviron" + R_PROFILE_USER = "/.Rprofile" + R_ENVIRON_USER = "/.Renviron" } // Capture exit codes from upstream processes when piping @@ -181,29 +192,29 @@ process.shell = ['/bin/bash', '-euo', 'pipefail'] def trace_timestamp = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss') timeline { enabled = true - file = "${params.tracedir}/execution_timeline_${trace_timestamp}.html" + file = "${params.tracedir}/execution_timeline_${trace_timestamp}.html" } report { enabled = true - file = "${params.tracedir}/execution_report_${trace_timestamp}.html" + file = "${params.tracedir}/execution_report_${trace_timestamp}.html" } trace { enabled = true - file = "${params.tracedir}/execution_trace_${trace_timestamp}.txt" + file = "${params.tracedir}/execution_trace_${trace_timestamp}.txt" } dag { enabled = true - file = "${params.tracedir}/pipeline_dag_${trace_timestamp}.svg" + file = "${params.tracedir}/pipeline_dag_${trace_timestamp}.svg" } manifest { - name = 'nf-core/mhcquant' - author = 'Leon Bichmann' - homePage = 'https://github.com/nf-core/mhcquant' - description = 'Identify and quantify peptides from mass spectrometry raw data' - mainScript = 'main.nf' - nextflowVersion = '>=21.04.0' - version = '2.0.0' + name = 'nf-core/mhcquant' + author = 'Leon Bichmann, Marissa Dubbelaar' + homePage = 'https://github.com/nf-core/mhcquant' + description = 'Identify and quantify peptides from mass spectrometry raw data' + mainScript = 'main.nf' + nextflowVersion = '!>=21.10.3' + version = '2.1.0' } // Function to ensure that resource requirements don't go beyond diff --git a/nextflow_schema.json b/nextflow_schema.json index 58a46ace..31e20e0c 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -16,13 +16,17 @@ "properties": { "input": { "type": "string", - "fa_icon": "fab fa-think-peaks", "description": "Input raw / mzML files listed in a tsv file (see help for details)", - "help_text": "Use this to specify a sample sheet table including your input raw or mzml files as well as their meta information such as SampleID and Condition. For example:\n\n| ID | Sample | Condition | ReplicateFileName |\n| -----|:------------:| ----------:|------------------------------------------:|\n| 1 | MM15_Melanom | A | data/MM15_Melanom_W_1_A_standard.raw |\n| 2 | MM15_Melanom | B | data/MM15_Melanom_W_1_B_standard.raw |\n| 3 | MM17_Melanom | B | data/MM17_Melanom_W_1_B_standard.raw |\n\n```bash\n--input 'path/samples.tsv'\n```" + "help_text": "Use this to specify a sample sheet table including your input raw or mzml files as well as their meta information such as SampleID and Condition. For example:\n\n| ID | Sample | Condition | ReplicateFileName |\n| -----|:------------:| ----------:|------------------------------------------:|\n| 1 | MM15_Melanom | A | data/MM15_Melanom_W_1_A_standard.raw |\n| 2 | MM15_Melanom | B | data/MM15_Melanom_W_1_B_standard.raw |\n| 3 | MM17_Melanom | B | data/MM17_Melanom_W_1_B_standard.raw |\n\n```bash\n--input 'path/samples.tsv'\n```", + "format": "file-path", + "mimetype": "text/csv", + "pattern": "^\\S+\\.tsv$", + "schema": "assets/schema_input.json", + "fa_icon": "fas fa-file-csv" }, "outdir": { "type": "string", - "description": "The output directory where the results will be saved.", + "description": "Path to the output directory where the results will be saved.", "default": "./results", "fa_icon": "fas fa-folder-open" }, @@ -32,6 +36,11 @@ "fa_icon": "fas fa-envelope", "help_text": "Set this parameter to your e-mail address to get a summary e-mail with details of the run sent to you when the workflow exits. If set in your user config file (`~/.nextflow/config`) then you don't need to specify this on the command line for every run.", "pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$" + }, + "multiqc_title": { + "type": "string", + "description": "MultiQC report title. Printed as page header, used for filename if not otherwise specified.", + "fa_icon": "fas fa-file-signature" } } }, @@ -210,12 +219,12 @@ "properties": { "fdr_level": { "type": "string", - "default": "peptide-level-fdrs", + "default": "peptide_level_fdrs", "description": "Specify the level at which the false discovery rate should be computed.", "enum": [ - "peptide-level-fdrs", + "peptide_level_fdrs", "psm-level-fdrs", - "protein-level-fdrs" + "protein_level_fdrs" ] }, "fdr_threshold": { @@ -344,96 +353,64 @@ } } }, - "generic_options": { - "title": "Generic options", + "institutional_config_options": { + "title": "Institutional config options", "type": "object", - "fa_icon": "fas fa-file-import", - "description": "Less common options for the pipeline, typically set in a config file.", - "help_text": "These options are common to all nf-core pipelines and allow you to customise some of the core preferences for how the pipeline runs.\n\nTypically these options would be set in a Nextflow config file loaded for all pipeline runs, such as `~/.nextflow/config`.", + "fa_icon": "fas fa-university", + "description": "Parameters used to describe centralised config profiles. These should not be edited.", + "help_text": "The centralised nf-core configuration profiles use a handful of pipeline parameters to describe themselves. This information is then printed to the Nextflow log when you run a pipeline. You should not need to change these values when you run a pipeline.", "properties": { - "help": { - "type": "boolean", - "description": "Display help text.", - "hidden": true, - "fa_icon": "fas fa-question-circle" - }, - "publish_dir_mode": { + "custom_config_version": { "type": "string", - "default": "copy", + "description": "Git commit id for Institutional configs.", + "default": "master", "hidden": true, - "description": "Method used to save pipeline results to output directory.", - "help_text": "The Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.", - "fa_icon": "fas fa-copy", - "enum": [ - "symlink", - "rellink", - "link", - "copy", - "copyNoFollow", - "move" - ] - }, - "validate_params": { - "type": "boolean", - "description": "Boolean whether to validate parameters against the schema at runtime", - "default": true, - "fa_icon": "fas fa-check-square", - "hidden": true + "fa_icon": "fas fa-users-cog" }, "skip_multiqc": { "type": "boolean", "description": "Skip MultiQC.", "fa_icon": "fas fa-fast-forward", - "default": true + "hidden": true, + "default": false }, - "email_on_fail": { + "custom_config_base": { "type": "string", - "description": "Email address for completion summary, only when pipeline fails.", - "fa_icon": "fas fa-exclamation-triangle", - "pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$", + "description": "Base directory for Institutional configs.", + "default": "https://raw.githubusercontent.com/nf-core/configs/master", "hidden": true, - "help_text": "This works exactly as with `--email`, except emails are only sent if the workflow is not successful." + "help_text": "If you're running offline, Nextflow will not be able to fetch the institutional config files from the internet. If you don't need them, then this is not a problem. If you do need them, you should download the files from the repo and tell Nextflow where to find them with this parameter.", + "fa_icon": "fas fa-users-cog" }, - "plaintext_email": { - "type": "boolean", - "description": "Send plain-text email instead of HTML.", - "fa_icon": "fas fa-remove-format", + "hostnames": { + "type": "string", + "description": "Institutional configs hostname.", "hidden": true, - "help_text": "Set to receive plain-text e-mails instead of HTML formatted." + "fa_icon": "fas fa-users-cog" }, - "monochrome_logs": { - "type": "boolean", - "description": "Do not use coloured log outputs.", - "fa_icon": "fas fa-palette", + "config_profile_name": { + "type": "string", + "description": "Institutional config name.", "hidden": true, - "help_text": "Set to disable colourful command line output and live life in monochrome." + "fa_icon": "fas fa-users-cog" }, - "tracedir": { + "config_profile_description": { "type": "string", - "description": "Directory to keep pipeline Nextflow logs and reports.", - "default": "${params.outdir}/pipeline_info", - "fa_icon": "fas fa-cogs", - "hidden": true - }, - "show_hidden_params": { - "type": "boolean", - "fa_icon": "far fa-eye-slash", - "description": "Show all params when using `--help`", + "description": "Institutional config description.", "hidden": true, - "help_text": "By default, parameters set as _hidden_ in the schema are not shown on the command line when a user runs with `--help`. Specifying this option will tell the pipeline to show all parameters." + "fa_icon": "fas fa-users-cog" }, - "max_multiqc_email_size": { + "config_profile_contact": { "type": "string", - "description": "File size limit when attaching MultiQC reports to summary emails.", - "default": "25.MB", - "fa_icon": "fas fa-file-upload", - "hidden": true + "description": "Institutional config contact information.", + "hidden": true, + "fa_icon": "fas fa-users-cog" }, - "enable_conda": { - "type": "boolean", - "description": "Run this workflow with Conda. You can also use '-profile conda' instead of providing this parameter.", + "config_profile_url": { + "type": "string", + "description": "Institutional config URL link.", "hidden": true, - "fa_icon": "fas fa-bacon" + "fa_icon": "fas fa-users-cog" } } }, @@ -446,7 +423,7 @@ "properties": { "max_cpus": { "type": "integer", - "description": "Maximum number of CPUs that can be requested for any single job.", + "description": "Maximum number of CPUs that can be requested for any single job.", "default": 16, "fa_icon": "fas fa-microchip", "hidden": true, @@ -472,64 +449,103 @@ } } }, - "institutional_config_options": { - "title": "Institutional config options", + "generic_options": { + "title": "Generic options", "type": "object", - "fa_icon": "fas fa-university", - "description": "Parameters used to describe centralised config profiles. These should not be edited.", - "help_text": "The centralised nf-core configuration profiles use a handful of pipeline parameters to describe themselves. This information is then printed to the Nextflow log when you run a pipeline. You should not need to change these values when you run a pipeline.", + "fa_icon": "fas fa-file-import", + "description": "Less common options for the pipeline, typically set in a config file.", + "help_text": "These options are common to all nf-core pipelines and allow you to customise some of the core preferences for how the pipeline runs.\n\nTypically these options would be set in a Nextflow config file loaded for all pipeline runs, such as `~/.nextflow/config`.", "properties": { - "custom_config_version": { - "type": "string", - "description": "Git commit id for Institutional configs.", - "default": "master", - "hidden": true, - "fa_icon": "fas fa-users-cog", - "help_text": "Provide git commit id for custom Institutional configs hosted at `nf-core/configs`. This was implemented for reproducibility purposes. Default: `master`.\n\n```bash\n## Download and use config file with following git commit id\n--custom_config_version d52db660777c4bf36546ddb188ec530c3ada1b96\n```" - }, - "custom_config_base": { - "type": "string", - "description": "Base directory for Institutional configs.", - "default": "https://raw.githubusercontent.com/nf-core/configs/master", - "hidden": true, - "help_text": "If you're running offline, nextflow will not be able to fetch the institutional config files from the internet. If you don't need them, then this is not a problem. If you do need them, you should download the files from the repo and tell nextflow where to find them with the `custom_config_base` option. For example:\n\n```bash\n## Download and unzip the config files\ncd /path/to/my/configs\nwget https://github.com/nf-core/configs/archive/master.zip\nunzip master.zip\n\n## Run the pipeline\ncd /path/to/my/data\nnextflow run /path/to/pipeline/ --custom_config_base /path/to/my/configs/configs-master/\n```\n\n> Note that the nf-core/tools helper package has a `download` command to download all required pipeline files + singularity containers + institutional configs in one go for you, to make this process easier.", - "fa_icon": "fas fa-users-cog" + "help": { + "type": "boolean", + "description": "Display help text.", + "fa_icon": "fas fa-question-circle", + "hidden": true }, - "hostnames": { + + "publish_dir_mode": { "type": "string", - "description": "Institutional configs hostname.", - "hidden": true, - "fa_icon": "fas fa-users-cog" + "default": "copy", + "description": "Method used to save pipeline results to output directory.", + "help_text": "The Nextflow `publishDir` option specifies which intermediate files should be saved to the output directory. This option tells the pipeline what method should be used to move these files. See [Nextflow docs](https://www.nextflow.io/docs/latest/process.html#publishdir) for details.", + "fa_icon": "fas fa-copy", + "enum": [ + "symlink", + "rellink", + "link", + "copy", + "copyNoFollow", + "move" + ], + "hidden": true }, - "config_profile_name": { + "email_on_fail": { "type": "string", - "description": "Institutional config name.", - "hidden": true, - "fa_icon": "fas fa-users-cog" + "description": "Email address for completion summary, only when pipeline fails.", + "fa_icon": "fas fa-exclamation-triangle", + "pattern": "^([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\\.([a-zA-Z]{2,5})$", + "help_text": "An email address to send a summary email to when the pipeline is completed - ONLY sent if the pipeline does not exit successfully.", + "hidden": true }, - "config_profile_description": { - "type": "string", - "description": "Institutional config description.", - "hidden": true, - "fa_icon": "fas fa-users-cog" + "plaintext_email": { + "type": "boolean", + "description": "Send plain-text email instead of HTML.", + "fa_icon": "fas fa-remove-format", + "hidden": true }, - "config_profile_contact": { + "max_multiqc_email_size": { "type": "string", - "description": "Institutional config contact information.", - "hidden": true, - "fa_icon": "fas fa-users-cog" + "description": "File size limit when attaching MultiQC reports to summary emails.", + "pattern": "^\\d+(\\.\\d+)?\\.?\\s*(K|M|G|T)?B$", + "default": "25.MB", + "fa_icon": "fas fa-file-upload", + "hidden": true }, - "config_profile_url": { - "type": "string", - "description": "Institutional config URL link.", - "hidden": true, - "fa_icon": "fas fa-users-cog" + "monochrome_logs": { + "type": "boolean", + "description": "Do not use coloured log outputs.", + "fa_icon": "fas fa-palette", + "hidden": true }, "multiqc_config": { "type": "string", "description": "Custom config file to supply to MultiQC.", "fa_icon": "fas fa-cog", "hidden": true + }, + "tracedir": { + "type": "string", + "description": "Directory to keep pipeline Nextflow logs and reports.", + "default": "${params.outdir}/pipeline_info", + "fa_icon": "fas fa-cogs", + "hidden": true + }, + "validate_params": { + "type": "boolean", + "description": "Boolean whether to validate parameters against the schema at runtime", + "default": true, + "fa_icon": "fas fa-check-square", + "hidden": true + }, + "show_hidden_params": { + "type": "boolean", + "fa_icon": "far fa-eye-slash", + "description": "Show all params when using `--help`", + "hidden": true, + "help_text": "By default, parameters set as _hidden_ in the schema are not shown on the command line when a user runs with `--help`. Specifying this option will tell the pipeline to show all parameters." + }, + "enable_conda": { + "type": "boolean", + "description": "Run this workflow with Conda. You can also use '-profile conda' instead of providing this parameter.", + "hidden": true, + "fa_icon": "fas fa-bacon" + }, + "singularity_pull_docker_container": { + "type": "boolean", + "description": "Instead of directly downloading Singularity images for use with Singularity, force the workflow to pull and convert Docker containers instead.", + "hidden": true, + "fa_icon": "fas fa-toolbox", + "help_text": "This may be useful for example if you are unable to directly pull Singularity containers to run the pipeline due to http/https proxy issues." } } } @@ -563,13 +579,13 @@ "$ref": "#/definitions/rt_prediction" }, { - "$ref": "#/definitions/generic_options" + "$ref": "#/definitions/institutional_config_options" }, { "$ref": "#/definitions/max_job_request_options" }, { - "$ref": "#/definitions/institutional_config_options" + "$ref": "#/definitions/generic_options" } ] } \ No newline at end of file diff --git a/subworkflows/local/input_check.nf b/subworkflows/local/input_check.nf new file mode 100644 index 00000000..1c3ccc2e --- /dev/null +++ b/subworkflows/local/input_check.nf @@ -0,0 +1,40 @@ +// +// Check input samplesheet and get read channels +// + +params.options = [:] + +include { SAMPLESHEET_CHECK } from '../../modules/local/samplesheet_check' addParams(options: [:]) + +workflow INPUT_CHECK { + take: + samplesheet // file: /path/to/samplesheet.csv + + main: + SAMPLESHEET_CHECK ( samplesheet ) + .csv + .splitCsv ( header:true, sep:"\t" ) + .map { get_samplesheet_paths(it) } + .set { reads } + + emit: + reads // channel: [ val(meta), [ reads ] ] + versions = SAMPLESHEET_CHECK.out.versions // channel: [ versions.yml ] +} + +// Function to get list of [ meta, filenames ] +def get_samplesheet_paths(LinkedHashMap row) { + def meta = [:] + meta.id = row.ID + meta.sample = row.Sample + meta.condition = row.Condition + meta.ext = row.FileExt + + def array = [] + if (!file(row.Filename).exists()) { + exit 1, "ERROR: Please check input samplesheet -> MS file does not exist!\n${row.Filename}" + } else { + array = [ meta, file(row.Filename) ] + } + return array +} diff --git a/subworkflows/local/refine_fdr_on_predicted_subset.nf b/subworkflows/local/refine_fdr_on_predicted_subset.nf new file mode 100644 index 00000000..b786d649 --- /dev/null +++ b/subworkflows/local/refine_fdr_on_predicted_subset.nf @@ -0,0 +1,63 @@ +/* + * Perform an additional step where the process are collected + * that are called when the paramater "refine_fdr_on_predicted_subset" is provided + */ + +params.exporter_prec_options = [:] +params.exporter_psm_options = [:] +params.percolator_adapter_refine_options = [:] +params.whitelist_filter_options = [:] +params.filter_options = [:] + +def openms_mztab_exporter_prec_options = params.exporter_prec_options.clone() +def openms_mztab_exporter_psm_options = params.exporter_psm_options.clone() +def openms_percolator_adapter_options = params.percolator_adapter_refine_options.clone() +def openms_id_filter_psms_options = params.whitelist_filter_options.clone() +def openms_id_filter_qvalue_options = params.filter_options.clone() + +include { OPENMS_MZTABEXPORTER as OPENMS_MZTABEXPORTERPERC } from '../../modules/local/openms_mztabexporter' addParams( options: openms_mztab_exporter_prec_options ) +include { OPENMS_MZTABEXPORTER as OPENMS_MZTABEXPORTERPSM } from '../../modules/local/openms_mztabexporter' addParams( options: openms_mztab_exporter_psm_options ) +include { MHCFLURRY_PREDICTPSMS } from '../../modules/local/mhcflurry_predictpsms' addParams( options: [:] ) +include { OPENMS_PERCOLATORADAPTER } from '../../modules/local/openms_percolatoradapter' addParams( options: openms_percolator_adapter_options ) +include { OPENMS_IDFILTER as OPENMS_IDFILTER_PSMS } from '../../modules/local/openms_idfilter' addParams( options: openms_id_filter_psms_options ) +include { OPENMS_IDFILTER as OPENMS_IDFILTER_REFINED } from '../../modules/local/openms_idfilter' addParams( options: openms_id_filter_qvalue_options ) + +workflow REFINE_FDR_ON_PREDICTED_SUBSET { + // Define the input parameters + take: + filtered_perc_output + psm_features + classI_alleles + + main: + ch_versions = Channel.empty() + // Export filtered percolator results as mztab + OPENMS_MZTABEXPORTERPERC( filtered_perc_output ) + ch_versions = ch_versions.mix(OPENMS_MZTABEXPORTERPERC.out.versions) + // Export psm results as mztab + OPENMS_MZTABEXPORTERPSM( psm_features ) + ch_versions = ch_versions.mix(OPENMS_MZTABEXPORTERPSM.out.versions) + // Predict psm results using mhcflurry to shrink search space + MHCFLURRY_PREDICTPSMS( + OPENMS_MZTABEXPORTERPERC.out.mztab + .join( OPENMS_MZTABEXPORTERPSM.out.mztab, by:[0] ) + .map{ it -> [it[0].sample, it[0], it[1], it[2]] } + .combine( classI_alleles, by:0) + .map(it -> [it[1], it[2], it[3], it[4]]) + ) + ch_versions = ch_versions.mix(MHCFLURRY_PREDICTPSMS.out.versions) + + // Filter psm results by shrinked search space + OPENMS_IDFILTER_PSMS(psm_features.combine( MHCFLURRY_PREDICTPSMS.out.idxml, by: [0] )) + ch_versions = ch_versions.mix(OPENMS_IDFILTER_PSMS.out.versions) + // Recompute percolator fdr on shrinked search space + OPENMS_PERCOLATORADAPTER( OPENMS_IDFILTER_PSMS.out.idxml ) + ch_versions = ch_versions.mix(OPENMS_PERCOLATORADAPTER.out.versions) + // Filter results by refined fdr + OPENMS_IDFILTER_REFINED(OPENMS_PERCOLATORADAPTER.out.idxml.flatMap { it -> [tuple(it[0], it[1], null)]}) + ch_versions = ch_versions.mix(OPENMS_IDFILTER_REFINED.out.versions) + emit: + // Define the information that is returned by this workflow + filter_refined_q_value = OPENMS_IDFILTER_REFINED.out.idxml + versions = ch_versions +} diff --git a/workflows/mhcquant.nf b/workflows/mhcquant.nf index 7d3c0b54..818c0389 100644 --- a/workflows/mhcquant.nf +++ b/workflows/mhcquant.nf @@ -1,17 +1,8 @@ -#!/usr/bin/env nextflow /* ======================================================================================== - nf-core/mhcquant + VALIDATE INPUTS ======================================================================================== -nf-core/mhcquant Analysis Pipeline. -#### Homepage / Documentation -https://github.com/nf-core/mhcquant ----------------------------------------------------------------------------------------- */ - -//////////////////////////////////////////////////// -/* -- VALIDATE INPUTS -- */ -//////////////////////////////////////////////////// def summary_params = NfcoreSchema.paramsSummaryMap(workflow, params) // Validate input parameters @@ -57,53 +48,69 @@ if (params.include_proteins_from_vcf) { .set { ch_vcf_from_sheet } } -if (params.variant_indel_filter) { variant_indel_filter="-fINDEL" } else { variant_indel_filter="" } -if (params.variant_frameshift_filter) { variant_frameshift_filter="-fFS" } else { variant_frameshift_filter="" } -if (params.variant_snp_filter) { variant_snp_filter="-fSNP" } else { variant_snp_filter="" } +/* +======================================================================================== + CONFIG FILES +======================================================================================== +*/ + +ch_multiqc_config = file("$projectDir/assets/multiqc_config.yaml", checkIfExists: true) +ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath(params.multiqc_config) : Channel.empty() -// Mass Spectronomy data processing options -x_ions = params.use_x_ions ? '-use_X_ions true' : '' -z_ions = params.use_z_ions ? '-use_Z_ions true' : '' -a_ions = params.use_a_ions ? '-use_A_ions true' : '' -c_ions = params.use_c_ions ? '-use_C_ions true' : '' -NL_ions = params.use_NL_ions ? '-use_NL_ions true' : '' -rm_precursor = params.remove_precursor_peak ? '-remove_precursor_peak true' : '' -fdr_level = (params.fdr_level == 'psm-level-fdrs') ? '' : '-'+params.fdr_level -fdr_adj_threshold = (params.fdr_threshold == '0.01') ? '0.05' : params.fdr_threshold -//////////////////////////////////////////////////// -/* -- IMPORT LOCAL MODULES/SUBWORKFLOWS -- */ -//////////////////////////////////////////////////// +/* +======================================================================================== + IMPORT LOCAL MODULES/SUBWORKFLOWS +======================================================================================== +*/ +// Don't overwrite global params.modules, create a copy instead and use that within the main script. def modules = params.modules.clone() -def openms_map_aligner_identification_options = modules['openms_map_aligner_identification'] -def openms_comet_adapter_options = modules['openms_comet_adapter'] +def multiqc_options = modules['multiqc'] +multiqc_options.args += params.multiqc_title ? Utils.joinModuleArgs(["--title \"$params.multiqc_title\""]) : '' def generate_proteins_from_vcf_options = modules['generate_proteins_from_vcf'] +generate_proteins_from_vcf_options.args += params.variant_indel_filter ? Utils.joinModuleArgs(['-fINDEL']) : '' +generate_proteins_from_vcf_options.args += params.variant_frameshift_filter ? Utils.joinModuleArgs(['-fFS']) : '' +generate_proteins_from_vcf_options.args += params.variant_snp_filter ? Utils.joinModuleArgs(['-fSNP']) : '' -def percolator_adapter_options = modules['percolator_adapter'] - -def id_filter_options = modules['id_filter'] -def id_filter_for_alignment_options = id_filter_options.clone() -def id_filter_whitelist_options = modules['id_filter_whitelist'] - -id_filter_options.args += " -score:pep " + params.fdr_threshold -id_filter_for_alignment_options.args += " -score:pep " + fdr_adj_threshold - -openms_comet_adapter_options.args += x_ions + z_ions + c_ions + a_ions + NL_ions + rm_precursor -generate_proteins_from_vcf_options.args += variant_indel_filter + variant_snp_filter + variant_frameshift_filter -percolator_adapter_options.args += fdr_level -percolator_adapter_options.suffix = "all_ids_merged_psm_perc" - -def percolator_adapter_klammer_options = percolator_adapter_options.clone() -percolator_adapter_klammer_options.args += " -klammer" +def openms_comet_adapter_options = modules['openms_comet_adapter'] +openms_comet_adapter_options.args += params.use_x_ions ? Utils.joinModuleArgs(['-use_X_ions true']) : '' +openms_comet_adapter_options.args += params.use_z_ions ? Utils.joinModuleArgs(['-use_Z_ions true']) : '' +openms_comet_adapter_options.args += params.use_a_ions ? Utils.joinModuleArgs(['-use_A_ions true']) : '' +openms_comet_adapter_options.args += params.use_c_ions ? Utils.joinModuleArgs(['-use_C_ions true']) : '' +openms_comet_adapter_options.args += params.use_NL_ions ? Utils.joinModuleArgs(['-use_NL_ions true']) : '' +openms_comet_adapter_options.args += params.remove_precursor_peak ? Utils.joinModuleArgs(['-remove_precursor_peak yes']) : '' + +def openms_id_filter_options = modules['openms_id_filter'] +def openms_id_filter_refiner_options = modules['openms_id_filter_refiner'] +def openms_id_filter_for_alignment_options = openms_id_filter_options.clone() +def openms_id_filter_whitelist_options = modules['openms_id_filter_whitelist'] +openms_id_filter_options.args += " -score:pep " + params.fdr_threshold +openms_id_filter_refiner_options.args += " -score:pep " + params.fdr_threshold +openms_id_filter_for_alignment_options.args += " -score:pep " + (params.fdr_threshold == '0.01') ? Utils.joinModuleArgs(['-score:pep 0.05']) : Utils.joinModuleArgs(['-score:pep ' + params.fdr_threshold]) +def openms_id_filter_qvalue_options = openms_id_filter_options.clone() +openms_id_filter_qvalue_options.suffix = "filtered" -def id_filter_qvalue_options = id_filter_options.clone() -id_filter_qvalue_options.suffix = "filtered" +def openms_map_aligner_identification_options = modules['openms_map_aligner_identification'] +def openms_mztab_exporter_perc_options = modules['openms_mztab_exporter_perc'] +def openms_mztab_exporter_psm_options = modules['openms_mztab_exporter_psm'] +def openms_percolator_adapter_options = modules['openms_percolator_adapter'] +def openms_percolator_adapter_refine_options = modules['openms_percolator_adapter_refine'] +openms_percolator_adapter_options.args += (params.fdr_level != 'psm-level-fdrs') ? Utils.joinModuleArgs(['-'+params.fdr_level]) : '' +openms_percolator_adapter_refine_options.args += (params.fdr_level != 'psm-level-fdrs') ? Utils.joinModuleArgs(['-'+params.fdr_level]) : '' +def openms_percolator_adapter_klammer_options = openms_percolator_adapter_options.clone() +openms_percolator_adapter_klammer_options.args += " -klammer" + +def openms_rt_predict_peptides_options = modules['openms_rt_predict_peptides'] +def openms_rt_predict_neo_epitopes_options = modules['openms_rt_predict_neo_epitopes'] +//////////////////////////////////////////////////// +/* -- CREATE CHANNELS -- */ +//////////////////////////////////////////////////// include { hasExtension } from '../modules/local/functions' -include { INPUT_CHECK } from '../modules/local/subworkflow/input_check' addParams( options: [:] ) +include { INPUT_CHECK } from '../subworkflows/local/input_check' addParams( options: [:] ) include { GENERATE_PROTEINS_FROM_VCF } from '../modules/local/generate_proteins_from_vcf' addParams( options: generate_proteins_from_vcf_options ) include { OPENMS_DECOYDATABASE } from '../modules/local/openms_decoydatabase' addParams( options: [:] ) include { OPENMS_THERMORAWFILEPARSER } from '../modules/local/openms_thermorawfileparser' addParams( options: [:] ) @@ -111,8 +118,8 @@ include { OPENMS_PEAKPICKERHIRES } from '../modules/loc include { OPENMS_COMETADAPTER } from '../modules/local/openms_cometadapter' addParams( options: openms_comet_adapter_options ) include { OPENMS_PEPTIDEINDEXER } from '../modules/local/openms_peptideindexer' addParams( options: [:] ) include { OPENMS_FALSEDISCOVERYRATE } from '../modules/local/openms_falsediscoveryrate' addParams( options: [:] ) -include { OPENMS_IDFILTER as OPENMS_IDFILTER_FOR_ALIGNMENT }from '../modules/local/openms_idfilter' addParams( options: id_filter_for_alignment_options ) -include { OPENMS_IDFILTER as OPENMS_IDFILTER_Q_VALUE } from '../modules/local/openms_idfilter' addParams( options: id_filter_qvalue_options ) +include { OPENMS_IDFILTER as OPENMS_IDFILTER_FOR_ALIGNMENT }from '../modules/local/openms_idfilter' addParams( options: openms_id_filter_for_alignment_options ) +include { OPENMS_IDFILTER as OPENMS_IDFILTER_Q_VALUE } from '../modules/local/openms_idfilter' addParams( options: openms_id_filter_qvalue_options ) include { OPENMS_MAPALIGNERIDENTIFICATION } from '../modules/local/openms_mapaligneridentification' addParams( options: openms_map_aligner_identification_options ) include { @@ -121,10 +128,10 @@ include { include { OPENMS_IDMERGER } from '../modules/local/openms_idmerger' addParams( options: [:] ) include { OPENMS_PSMFEATUREEXTRACTOR } from '../modules/local/openms_psmfeatureextractor' addParams( options: [:] ) -include { OPENMS_PERCOLATORADAPTER } from '../modules/local/openms_percolatoradapter' addParams( options: percolator_adapter_options ) -include { OPENMS_PERCOLATORADAPTER as OPENMS_PERCOLATORADAPTER_KLAMMER } from '../modules/local/openms_percolatoradapter' addParams( options: percolator_adapter_klammer_options ) +include { OPENMS_PERCOLATORADAPTER } from '../modules/local/openms_percolatoradapter' addParams( options: openms_percolator_adapter_options ) +include { OPENMS_PERCOLATORADAPTER as OPENMS_PERCOLATORADAPTER_KLAMMER } from '../modules/local/openms_percolatoradapter' addParams( options: openms_percolator_adapter_klammer_options ) -include { REFINE_FDR_ON_PREDICTED_SUBSET } from '../modules/local/subworkflow/refine_fdr_on_predicted_subset' addParams( run_percolator_options : percolator_adapter_options, filter_options: id_filter_options, whitelist_filter_options: id_filter_whitelist_options) +include { REFINE_FDR_ON_PREDICTED_SUBSET } from '../subworkflows/local/refine_fdr_on_predicted_subset' addParams( exporter_prec_options : openms_mztab_exporter_perc_options, exporter_psm_options : openms_mztab_exporter_psm_options, run_percolator_options : openms_percolator_adapter_refine_options, whitelist_filter_options: openms_id_filter_whitelist_options, filter_options: openms_id_filter_refiner_options) include { OPENMS_FEATUREFINDERIDENTIFICATION } from '../modules/local/openms_featurefinderidentification' addParams( options: [:] ) include { OPENMS_FEATURELINKERUNLABELEDKD } from '../modules/local/openms_featurelinkerunlabeledkd' addParams( options: [:] ) @@ -132,36 +139,35 @@ include { OPENMS_IDCONFLICTRESOLVER } from '../modules/loc include { OPENMS_TEXTEXPORTER } from '../modules/local/openms_textexporter' addParams( options: [:] ) include { OPENMS_MZTABEXPORTER } from '../modules/local/openms_mztabexporter' addParams( options: [:] ) -include { PREDICT_PEPTIDES_MHCFLURRY_CLASS_1 } from '../modules/local/predict_peptides_mhcflurry_class_1' addParams( options: [:] ) -include { PREPROCESS_PEPTIDES_MHCNUGGETS_CLASS_2 } from '../modules/local/preprocess_peptides_mhcnuggets_class_2' addParams( options: [:] ) -include { PREDICT_PEPTIDES_MHCNUGGETS_CLASS_2 } from '../modules/local/predict_peptides_mhcnuggets_class_2' addParams( options: [:] ) -include { POSTPROCESS_PEPTIDES_MHCNUGGETS_CLASS_2 } from '../modules/local/postprocess_peptides_mhcnuggets_class_2' addParams( options: [:] ) +include { MHCFLURRY_PREDICTPEPTIDESCLASS1 } from '../modules/local/mhcflurry_predictpeptidesclass1' addParams( options: [:] ) +include { MHCNUGGETS_PEPTIDESCLASS2PRE } from '../modules/local/mhcnuggets_peptidesclass2pre' addParams( options: [:] ) +include { MHCNUGGETS_PREDICTPEPTIDESCLASS2 } from '../modules/local/mhcnuggets_predictpeptidesclass2' addParams( options: [:] ) +include { MHCNUGGETS_PEPTIDESCLASS2POST } from '../modules/local/mhcnuggets_peptidesclass2post' addParams( options: [:] ) include { PREDICT_POSSIBLE_NEOEPITOPES } from '../modules/local/predict_possible_neoepitopes' addParams( options: [:] ) include { PREDICT_POSSIBLE_CLASS_2_NEOEPITOPES } from '../modules/local/predict_possible_class_2_neoepitopes' addParams( options: [:] ) include { RESOLVE_FOUND_NEOEPITOPES } from '../modules/local/resolve_found_neoepitopes' addParams( options: [:] ) include { RESOLVE_FOUND_CLASS_2_NEOEPITOPES } from '../modules/local/resolve_found_class_2_neoepitopes' addParams( options: [:] ) -include { PREDICT_NEOEPITOPES_MHCFLURRY_CLASS_1 } from '../modules/local/predict_neoepitopes_mhcflurry_class_1' addParams( options: [:] ) -include { PREPROCESS_NEOEPITOPES_MHCNUGGETS_CLASS_2 } from '../modules/local/preprocess_neoepitopes_mhcnuggets_class_2' addParams( options: [:] ) -include { PREDICT_NEOEPITOPES_MHCNUGGETS_CLASS_2 } from '../modules/local/predict_neoepitopes_mhcnuggets_class_2' addParams( options: [:] ) -include { POSTPROCESS_NEOEPITOPES_MHCNUGGETS_CLASS_2 } from '../modules/local/postprocess_neoepitopes_mhcnuggets_class_2' addParams( options: [:] ) +include { MHCFLURRY_PREDICTNEOEPITOPESCLASS1 } from '../modules/local/mhcflurry_predictneoepitopesclass1' addParams( options: [:] ) +include { MHCNUGGETS_NEOEPITOPESCLASS2RE } from '../modules/local/mhcnuggets_neoepitopesclass2pre' addParams( options: [:] ) +include { MHCNUGGETS_PREDICTNEOEPITOPESCLASS2 } from '../modules/local/mhcnuggets_predictneoepitopesclass2' addParams( options: [:] ) +include { MHCNUGGETS_NEOEPITOPESCLASS2POST } from '../modules/local/mhcnuggets_neoepitopesclass2post' addParams( options: [:] ) include { OPENMS_RTMODEL } from '../modules/local/openms_rtmodel' addParams( options: [:] ) -include { OPENMS_RTPREDICT as OPENMS_RTPREDICT_FOUND_PEPTIDES} from '../modules/local/openms_rtpredict' addParams( options: [suffix:"_id_files_for_rt_prediction_RTpredicted"] ) -include { OPENMS_RTPREDICT as OPENMS_RTPREDICT_NEOEPITOPES} from '../modules/local/openms_rtpredict' addParams( options: [suffix:"_txt_file_for_rt_prediction_RTpredicted"] ) - -include { GET_SOFTWARE_VERSIONS } from '../modules/local/get_software_versions' addParams( options: [publish_files : ['tsv':'']] ) +include { OPENMS_RTPREDICT as OPENMS_RTPREDICT_FOUND_PEPTIDES} from '../modules/local/openms_rtpredict' addParams( options: openms_rt_predict_peptides_options ) +include { OPENMS_RTPREDICT as OPENMS_RTPREDICT_NEOEPITOPES} from '../modules/local/openms_rtpredict' addParams( options: openms_rt_predict_neo_epitopes_options ) -//////////////////////////////////////////////////// -/* -- CREATE CHANNELS -- */ -//////////////////////////////////////////////////// -params.summary_params = [:] +include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/modules/custom/dumpsoftwareversions/main' addParams( options: [publish_files : ['_versions.yml':'']] ) +include { MULTIQC } from '../modules/nf-core/modules/multiqc/main' addParams( options: multiqc_options ) //////////////////////////////////////////////////// /* -- RUN MAIN WORKFLOW -- */ //////////////////////////////////////////////////// workflow MHCQUANT { + ch_versions = Channel.empty() + INPUT_CHECK( params.input ) + .reads .set { ch_samples_from_sheet } ch_samples_from_sheet @@ -174,6 +180,7 @@ workflow MHCQUANT { other : true } .set { ms_files } + // Input fasta file Channel.fromPath( params.fasta ) .combine( ch_samples_from_sheet ) @@ -181,7 +188,6 @@ workflow MHCQUANT { .ifEmpty { exit 1, "params.fasta was empty - no input file supplied" } .set { input_fasta } - ch_software_versions = Channel.empty() // A warning message will be given when the format differs from the '.raw' or '.mzML' extention ms_files.other.subscribe { row -> log.warn("Unknown format for entry " + row[3] + " in provided sample sheet, line will be ignored."); exit 1 } @@ -193,6 +199,7 @@ workflow MHCQUANT { .map(it -> [it[1], it[2], it[3]]) // If specified translate variants to proteins and include in reference fasta GENERATE_PROTEINS_FROM_VCF( ch_vcf ) + ch_versions = ch_versions.mix(GENERATE_PROTEINS_FROM_VCF.out.versions.first().ifEmpty(null)) ch_fasta_file = GENERATE_PROTEINS_FROM_VCF.out.vcf_fasta } else { ch_fasta_file = input_fasta @@ -201,6 +208,7 @@ workflow MHCQUANT { if (!params.skip_decoy_generation) { // Generate reversed decoy database OPENMS_DECOYDATABASE(ch_fasta_file) + ch_versions = ch_versions.mix(OPENMS_DECOYDATABASE.out.versions.first().ifEmpty(null)) ch_decoy_db = OPENMS_DECOYDATABASE.out.decoy } else { ch_decoy_db = ch_fasta_file @@ -208,11 +216,12 @@ workflow MHCQUANT { // Raw file conversion OPENMS_THERMORAWFILEPARSER(ms_files.raw) - ch_software_versions = ch_software_versions.mix(OPENMS_THERMORAWFILEPARSER.out.version.first().ifEmpty(null)) + ch_versions = ch_versions.mix(OPENMS_THERMORAWFILEPARSER.out.versions.first().ifEmpty(null)) if ( params.run_centroidisation ) { // Optional: Run Peak Picking as Preprocessing OPENMS_PEAKPICKERHIRES(ms_files.mzml) + ch_versions = ch_versions.mix(OPENMS_PEAKPICKERHIRES.out.versions.first().ifEmpty(null)) ch_mzml_file = OPENMS_PEAKPICKERHIRES.out.mzml } else { ch_mzml_file = ms_files.mzml @@ -223,18 +232,20 @@ workflow MHCQUANT { OPENMS_THERMORAWFILEPARSER.out.mzml .mix(ch_mzml_file) .join(ch_decoy_db, remainder:true)) - ch_software_versions = ch_software_versions.mix(OPENMS_COMETADAPTER.out.version.first().ifEmpty(null)) + ch_versions = ch_versions.mix(OPENMS_COMETADAPTER.out.versions.first().ifEmpty(null)) // Index decoy and target hits OPENMS_PEPTIDEINDEXER(OPENMS_COMETADAPTER.out.idxml.join(ch_decoy_db)) - ch_software_versions = ch_software_versions.mix(OPENMS_PEPTIDEINDEXER.out.version.first().ifEmpty(null)) + ch_versions = ch_versions.mix(OPENMS_PEPTIDEINDEXER.out.versions.first().ifEmpty(null)) if(!params.skip_quantification) { // Calculate fdr for id based alignment OPENMS_FALSEDISCOVERYRATE(OPENMS_PEPTIDEINDEXER.out.idxml) + ch_versions = ch_versions.mix(OPENMS_FALSEDISCOVERYRATE.out.versions.first().ifEmpty(null)) // Filter fdr for id based alignment OPENMS_IDFILTER_FOR_ALIGNMENT(OPENMS_FALSEDISCOVERYRATE.out.idxml .flatMap { it -> [tuple(it[0], it[1], null)]}) + ch_versions = ch_versions.mix(OPENMS_IDFILTER_FOR_ALIGNMENT.out.versions.first().ifEmpty(null)) ch_grouped_fdr_filtered = OPENMS_IDFILTER_FOR_ALIGNMENT.out.idxml .map { @@ -245,7 +256,7 @@ workflow MHCQUANT { // Compute alignment rt transformatio OPENMS_MAPALIGNERIDENTIFICATION(ch_grouped_fdr_filtered) - + ch_versions = ch_versions.mix(OPENMS_MAPALIGNERIDENTIFICATION.out.versions.first().ifEmpty(null)) // Intermediate step to join RT transformation files with mzml and idxml channels ms_files.mzml .mix(OPENMS_THERMORAWFILEPARSER.out.mzml) @@ -273,8 +284,10 @@ workflow MHCQUANT { // Align mzML files using trafoXMLs OPENMS_MAPRTTRANSFORMERMZML(joined_trafos_mzmls) + ch_versions = ch_versions.mix(OPENMS_MAPRTTRANSFORMERMZML.out.versions.first().ifEmpty(null)) // Align unfiltered idXMLfiles using trafoXMLs OPENMS_MAPRTTRANSFORMERIDXML(joined_trafos_ids) + ch_versions = ch_versions.mix(OPENMS_MAPRTTRANSFORMERIDXML.out.versions.first().ifEmpty(null)) ch_proceeding_idx = OPENMS_MAPRTTRANSFORMERIDXML.out.aligned .map { meta, raw -> @@ -283,7 +296,7 @@ workflow MHCQUANT { .groupTuple(by: [0]) } else { - ch_proceeding_idx = OPENMS_PEPTIDEINDEXER.out.idXML + ch_proceeding_idx = OPENMS_PEPTIDEINDEXER.out.idxml .map { meta, raw -> [[id:meta.sample + "_" + meta.condition, sample:meta.sample, condition:meta.condition, ext:meta.ext], raw] @@ -293,20 +306,25 @@ workflow MHCQUANT { // Merge aligned idXMLfiles OPENMS_IDMERGER(ch_proceeding_idx) + ch_versions = ch_versions.mix(OPENMS_IDMERGER.out.versions.first().ifEmpty(null)) // Extract PSM features for Percolator OPENMS_PSMFEATUREEXTRACTOR(OPENMS_IDMERGER.out.idxml) + ch_versions = ch_versions.mix(OPENMS_PSMFEATUREEXTRACTOR.out.versions.first().ifEmpty(null)) // Run Percolator if (params.description_correct_features > 0 && params.klammer) { OPENMS_PERCOLATORADAPTER_KLAMMER(OPENMS_PSMFEATUREEXTRACTOR.out.idxml) + ch_versions = ch_versions.mix(OPENMS_PERCOLATORADAPTER_KLAMMER.out.versions.first().ifEmpty(null)) ch_percolator_adapter_outcome = OPENMS_PERCOLATORADAPTER_KLAMMER.out.idxml } else { OPENMS_PERCOLATORADAPTER(OPENMS_PSMFEATUREEXTRACTOR.out.idxml) + ch_versions = ch_versions.mix(OPENMS_PERCOLATORADAPTER.out.versions.first().ifEmpty(null)) ch_percolator_adapter_outcome = OPENMS_PERCOLATORADAPTER.out.idxml } // Filter by percolator q-value OPENMS_IDFILTER_Q_VALUE(ch_percolator_adapter_outcome.flatMap { it -> [tuple(it[0], it[1], null)]}) + ch_versions = ch_versions.mix(OPENMS_IDFILTER_Q_VALUE.out.versions.first().ifEmpty(null)) // Refine_fdr_on_predicted_subset if ( params.refine_fdr_on_predicted_subset && params.predict_class_1 ) { @@ -316,6 +334,7 @@ workflow MHCQUANT { OPENMS_PSMFEATUREEXTRACTOR.out.idxml, peptides_class_1_alleles ) + ch_versions = ch_versions.mix(REFINE_FDR_ON_PREDICTED_SUBSET.out.versions.first().ifEmpty(null)) // Define the outcome of the paramer to a fixed variable filter_q_value = REFINE_FDR_ON_PREDICTED_SUBSET.out.filter_refined_q_value.flatMap { it -> [ tuple(it[0].sample, it[0], it[1]) ] } @@ -324,16 +343,17 @@ workflow MHCQUANT { filter_q_value = OPENMS_IDFILTER_Q_VALUE.out.idxml.map{ it -> [it[0].sample, it[0], it[1]] } } - OPENMS_IDFILTER_FOR_ALIGNMENT.out[0] - .join( OPENMS_MAPRTTRANSFORMERMZML.out[0], by: [0] ) - .map { it -> [it[0].sample, it[0], it[1], it[2]] } - .combine( filter_q_value , by: [0] ) - .map { it -> [it[1], it[2], it[3], it[5]] } - .set{ joined_mzmls_ids_quant } - if ( !params.skip_quantification) { + // Combining the necessary information into one channel + OPENMS_IDFILTER_FOR_ALIGNMENT.out[0] + .join( OPENMS_MAPRTTRANSFORMERMZML.out[0], by: [0] ) + .map { it -> [it[0].sample, it[0], it[1], it[2]] } + .combine( filter_q_value , by: [0] ) + .map { it -> [it[1], it[2], it[3], it[5]] } + .set{ joined_mzmls_ids_quant } // Quantify identifications using targeted feature extraction OPENMS_FEATUREFINDERIDENTIFICATION(joined_mzmls_ids_quant) + ch_versions = ch_versions.mix(OPENMS_FEATUREFINDERIDENTIFICATION.out.versions.first().ifEmpty(null)) // Link extracted features OPENMS_FEATURELINKERUNLABELEDKD( OPENMS_FEATUREFINDERIDENTIFICATION.out.featurexml @@ -342,30 +362,34 @@ workflow MHCQUANT { [[[id:meta.sample + "_" + meta.condition, sample:meta.sample, condition:meta.condition, ext:meta.ext], raw]] } .groupTuple(by:[0])) + ch_versions = ch_versions.mix(OPENMS_FEATURELINKERUNLABELEDKD.out.versions.first().ifEmpty(null)) // Resolve conflicting ids matching to the same feature OPENMS_IDCONFLICTRESOLVER(OPENMS_FEATURELINKERUNLABELEDKD.out.consensusxml) + ch_versions = ch_versions.mix(OPENMS_IDCONFLICTRESOLVER.out.versions.first().ifEmpty(null)) + // Export all information as text to csv + OPENMS_TEXTEXPORTER(OPENMS_IDCONFLICTRESOLVER.out.consensusxml) + ch_versions = ch_versions.mix(OPENMS_TEXTEXPORTER.out.versions.first().ifEmpty(null)) + // Export all information as mzTab + OPENMS_MZTABEXPORTER(OPENMS_IDCONFLICTRESOLVER.out.consensusxml) + ch_versions = ch_versions.mix(OPENMS_MZTABEXPORTER.out.versions.first().ifEmpty(null)) } - // Export all information as text to csv - OPENMS_TEXTEXPORTER(OPENMS_IDCONFLICTRESOLVER.out.consensusxml) - // Export all information as mzTab - OPENMS_MZTABEXPORTER(OPENMS_IDCONFLICTRESOLVER.out.consensusxml) ////////////////////////////////////////////////////////////////////////////////////////////// // TODO: Replacement of custom scripts with epytope ch_predicted_possible_neoepitopes = Channel.empty() - if ( params.predict_class_1 ) { + if ( params.predict_class_1 & !params.skip_quantification ) { // If specified predict peptides using MHCFlurry - PREDICT_PEPTIDES_MHCFLURRY_CLASS_1( + MHCFLURRY_PREDICTPEPTIDESCLASS1( OPENMS_MZTABEXPORTER.out.mztab .map{ it -> [it[0].sample, it[0], it[1]] } .combine( peptides_class_1_alleles, by:0) .map( it -> [it[1], it[2], it[3]]) ) - - ch_software_versions = ch_software_versions.mix(PREDICT_PEPTIDES_MHCFLURRY_CLASS_1.out.version.first().ifEmpty(null)) + ch_versions = ch_versions.mix(MHCFLURRY_PREDICTPEPTIDESCLASS1.out.versions.first().ifEmpty(null)) if ( params.include_proteins_from_vcf ) { // Predict all possible neoepitopes from vcf PREDICT_POSSIBLE_NEOEPITOPES(peptides_class_1_alleles.join(ch_vcf_from_sheet, by:0, remainder:true)) + ch_versions = ch_versions.mix(PREDICT_POSSIBLE_NEOEPITOPES.out.versions.first().ifEmpty(null)) ch_predicted_possible_neoepitopes = PREDICT_POSSIBLE_NEOEPITOPES.out.csv // Resolve found neoepitopes RESOLVE_FOUND_NEOEPITOPES( @@ -374,28 +398,34 @@ workflow MHCQUANT { .combine( ch_predicted_possible_neoepitopes, by:0, remainder:true) .map( it -> [it[1], it[2], it[3]]) ) + ch_versions = ch_versions.mix(RESOLVE_FOUND_NEOEPITOPES.out.versions.first().ifEmpty(null)) // Predict class 1 neoepitopes MHCFlurry - PREDICT_NEOEPITOPES_MHCFLURRY_CLASS_1(peptides_class_1_alleles.join(RESOLVE_FOUND_NEOEPITOPES.out.csv, by:0)) + MHCFLURRY_PREDICTNEOEPITOPESCLASS1(peptides_class_1_alleles.join(RESOLVE_FOUND_NEOEPITOPES.out.csv, by:0)) + ch_versions = ch_versions.mix(MHCFLURRY_PREDICTNEOEPITOPESCLASS1.out.versions.first().ifEmpty(null)) } } ch_predicted_possible_neoepitopes_II = Channel.empty() - if ( params.predict_class_2 ) { + if ( params.predict_class_2 & !params.skip_quantification ) { // Preprocess found peptides for MHCNuggets prediction class 2 - PREPROCESS_PEPTIDES_MHCNUGGETS_CLASS_2(OPENMS_MZTABEXPORTER.out.mztab) + MHCNUGGETS_PEPTIDESCLASS2PRE(OPENMS_MZTABEXPORTER.out.mztab) + ch_versions = ch_versions.mix(MHCNUGGETS_PEPTIDESCLASS2PRE.out.versions.first().ifEmpty(null)) // Predict found peptides using MHCNuggets class 2 - PREDICT_PEPTIDES_MHCNUGGETS_CLASS_2( - PREPROCESS_PEPTIDES_MHCNUGGETS_CLASS_2.out.preprocessed + MHCNUGGETS_PREDICTPEPTIDESCLASS2( + MHCNUGGETS_PEPTIDESCLASS2PRE.out.preprocessed .map{ it -> [it[0].sample, it[0], it[1]] } .join(peptides_class_2_alleles, by:0) .map( it -> [it[1], it[2], it[3]]) ) + ch_versions = ch_versions.mix(MHCNUGGETS_PREDICTPEPTIDESCLASS2.out.versions.first().ifEmpty(null)) // Postprocess predicted MHCNuggets peptides class 2 - POSTPROCESS_PEPTIDES_MHCNUGGETS_CLASS_2( PREDICT_PEPTIDES_MHCNUGGETS_CLASS_2.out.csv.join(PREPROCESS_PEPTIDES_MHCNUGGETS_CLASS_2.out.geneID, by:0) ) + MHCNUGGETS_PEPTIDESCLASS2POST( MHCNUGGETS_PREDICTPEPTIDESCLASS2.out.csv.join(MHCNUGGETS_PEPTIDESCLASS2PRE.out.geneID, by:0) ) + ch_versions = ch_versions.mix(MHCNUGGETS_PEPTIDESCLASS2POST.out.versions.first().ifEmpty(null)) if ( params.include_proteins_from_vcf ) { // Predict all possible class 2 neoepitopes from vcf PREDICT_POSSIBLE_CLASS_2_NEOEPITOPES(peptides_class_2_alleles.join(ch_vcf_from_sheet, by:0, remainder:true)) + ch_versions = ch_versions.mix(PREDICT_POSSIBLE_CLASS_2_NEOEPITOPES.out.versions.first().ifEmpty(null)) ch_predicted_possible_neoepitopes_II = PREDICT_POSSIBLE_CLASS_2_NEOEPITOPES.out.csv // Resolve found class 2 neoepitopes RESOLVE_FOUND_CLASS_2_NEOEPITOPES( @@ -403,20 +433,16 @@ workflow MHCQUANT { .map{ it -> [it[0].sample, it[1]] } .combine( ch_predicted_possible_neoepitopes_II, by:0, remainder:true) ) + ch_versions = ch_versions.mix(RESOLVE_FOUND_CLASS_2_NEOEPITOPES.out.versions.first().ifEmpty(null)) // Preprocess resolved neoepitopes in a format that MHCNuggets understands - PREPROCESS_NEOEPITOPES_MHCNUGGETS_CLASS_2(RESOLVE_FOUND_CLASS_2_NEOEPITOPES.out.csv) + MHCNUGGETS_NEOEPITOPESCLASS2RE(RESOLVE_FOUND_CLASS_2_NEOEPITOPES.out.csv) + ch_versions = ch_versions.mix(MHCNUGGETS_NEOEPITOPESCLASS2RE.out.versions.first().ifEmpty(null)) // Predict class 2 MHCNuggets - PREDICT_NEOEPITOPES_MHCNUGGETS_CLASS_2(PREPROCESS_NEOEPITOPES_MHCNUGGETS_CLASS_2.out.preprocessed.join(peptides_class_2_alleles, by:0)) + MHCNUGGETS_PREDICTNEOEPITOPESCLASS2(MHCNUGGETS_NEOEPITOPESCLASS2RE.out.preprocessed.join(peptides_class_2_alleles, by:0)) + ch_versions = ch_versions.mix(MHCNUGGETS_PREDICTNEOEPITOPESCLASS2.out.versions.first().ifEmpty(null)) // Class 2 MHCNuggets Postprocessing - POSTPROCESS_NEOEPITOPES_MHCNUGGETS_CLASS_2(RESOLVE_FOUND_CLASS_2_NEOEPITOPES.out.csv.join(PREDICT_NEOEPITOPES_MHCNUGGETS_CLASS_2.out.csv, by:0)) - // If there was no prediction performed on class 1 - if ( !params.predict_class_1 ) { - // Add information to software versions - ch_software_versions = ch_software_versions.mix(PREDICT_POSSIBLE_CLASS_2_NEOEPITOPES.out.version.ifEmpty(null)) - } - } else if (!params.include_proteins_from_vcf && !params.predict_class_1) { - // Add the information to software versions - ch_software_versions = ch_software_versions.mix(PREDICT_PEPTIDES_MHCNUGGETS_CLASS_2.out.version.first().ifEmpty(null)) + MHCNUGGETS_NEOEPITOPESCLASS2POST(RESOLVE_FOUND_CLASS_2_NEOEPITOPES.out.csv.join(PREDICT_NEOEPITOPES_MHCNUGGETS_CLASS_2.out.csv, by:0)) + ch_versions = ch_versions.mix(MHCNUGGETS_NEOEPITOPESCLASS2POST.out.versions.first().ifEmpty(null)) } } ////////////////////////////////////////////////////////////////////////////////////////////// @@ -424,36 +450,59 @@ workflow MHCQUANT { filter_q_value = filter_q_value.map{ it -> [it[1], it[2]] } // Train Retention Times Predictor OPENMS_RTMODEL(filter_q_value) + ch_versions = ch_versions.mix(OPENMS_RTMODEL.out.versions.first().ifEmpty(null)) // Retention Times Predictor Found Peptides OPENMS_RTPREDICT_FOUND_PEPTIDES(filter_q_value.join(OPENMS_RTMODEL.out.complete, by:[0])) + ch_versions = ch_versions.mix(OPENMS_RTPREDICT_FOUND_PEPTIDES.out.versions.first().ifEmpty(null)) // Retention Times Predictor possible Neoepitopes OPENMS_RTPREDICT_NEOEPITOPES(ch_predicted_possible_neoepitopes.mix(ch_predicted_possible_neoepitopes_II).join(OPENMS_RTMODEL.out.complete, by:[0])) + ch_versions = ch_versions.mix(OPENMS_RTPREDICT_FOUND_PEPTIDES.out.versions.first().ifEmpty(null)) } - /* - * MODULE: Pipeline reporting - */ - ch_software_versions - .map { it -> if (it) [ it.baseName, it ] } - .groupTuple() - .map { it[1][0] } - .flatten() - .collect() - .set { ch_software_versions } - - GET_SOFTWARE_VERSIONS ( - ch_software_versions.map { it }.collect() + // + // MODULE: Pipeline reporting + // + CUSTOM_DUMPSOFTWAREVERSIONS ( + ch_versions.unique().collectFile() ) + + // + // MODULE: MultiQC + // + if (!params.skip_multiqc) { + workflow_summary = WorkflowMhcquant.paramsSummaryMultiqc(workflow, summary_params) + ch_workflow_summary = Channel.value(workflow_summary) + + ch_multiqc_files = Channel.empty() + ch_multiqc_files = ch_multiqc_files.mix(Channel.from(ch_multiqc_config)) + ch_multiqc_files = ch_multiqc_files.mix(ch_multiqc_custom_config.collect().ifEmpty([])) + ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) + ch_multiqc_files = ch_multiqc_files.mix(CUSTOM_DUMPSOFTWAREVERSIONS.out.mqc_yml.collect()) + + MULTIQC ( + ch_multiqc_files.collect() + ) + + multiqc_report = MULTIQC.out.report.toList() + } + } -//////////////////////////////////////////////////// -/* -- COMPLETION EMAIL -- */ -//////////////////////////////////////////////////// +/* +======================================================================================== + COMPLETION EMAIL AND SUMMARY +======================================================================================== +*/ + workflow.onComplete { - NfcoreTemplate.email(workflow, params, summary_params, projectDir, log) + if (params.email || params.email_on_fail) { + NfcoreTemplate.email(workflow, params, summary_params, projectDir, log, multiqc_report) + } NfcoreTemplate.summary(workflow, params, log) } -//////////////////////////////////////////////////// -/* -- THE END -- */ -//////////////////////////////////////////////////// +/* +======================================================================================== + THE END +======================================================================================== +*/