diff --git a/.gitattributes b/.gitattributes index 7fe55006..050bb120 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,3 @@ *.config linguist-language=nextflow +modules/nf-core/** linguist-generated +subworkflows/nf-core/** linguist-generated diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 05fd627c..1312f3db 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -68,16 +68,13 @@ If you wish to contribute a new step, please use the following coding standards: 1. Define the corresponding input channel into your new process from the expected previous process channel 2. Write the process block (see below). 3. Define the output channel if needed (see below). -4. Add any new flags/options to `nextflow.config` with a default (see below). -5. Add any new flags/options to `nextflow_schema.json` with help text (with `nf-core schema build`). -6. Add any new flags/options to the help message (for integer/text parameters, print to help the corresponding `nextflow.config` parameter). -7. Add sanity checks for all relevant parameters. -8. Add any new software to the `scrape_software_versions.py` script in `bin/` and the version command to the `scrape_software_versions` process in `main.nf`. -9. Do local tests that the new code works properly and as expected. -10. Add a new test command in `.github/workflow/ci.yml`. -11. If applicable add a [MultiQC](https://https://multiqc.info/) module. -12. Update MultiQC config `assets/multiqc_config.yaml` so relevant suffixes, name clean up, General Statistics Table column order, and module figures are in the right order. -13. Optional: Add any descriptions of MultiQC report sections and output files to `docs/output.md`. +4. Add any new parameters to `nextflow.config` with a default (see below). +5. Add any new parameters to `nextflow_schema.json` with help text (via the `nf-core schema build` tool). +6. Add sanity checks and validation for all relevant parameters. +7. Perform local tests to validate that the new code works as expected. +8. If applicable, add a new test command in `.github/workflow/ci.yml`. +9. Update MultiQC config `assets/multiqc_config.yaml` so relevant suffixes, file name clean up and module plots are in the appropriate order. If applicable, add a [MultiQC](https://https://multiqc.info/) module. +10. Add a description of the output files and if relevant any appropriate images from the MultiQC report to `docs/output.md`. ### Default values @@ -102,27 +99,6 @@ Please use the following naming schemes, to make it easy to understand what is g If you are using a new feature from core Nextflow, you may bump the minimum required version of nextflow in the pipeline with: `nf-core bump-version --nextflow . [min-nf-version]` -### Software version reporting - -If you add a new tool to the pipeline, please ensure you add the information of the tool to the `get_software_version` process. - -Add to the script block of the process, something like the following: - -```bash - --version &> v_.txt 2>&1 || true -``` - -or - -```bash - --help | head -n 1 &> v_.txt 2>&1 || true -``` - -You then need to edit the script `bin/scrape_software_versions.py` to: - -1. Add a Python regex for your tool's `--version` output (as in stored in the `v_.txt` file), to ensure the version is reported as a `v` and the version number e.g. `v2.1.1` -2. Add a HTML entry to the `OrderedDict` for formatting in MultiQC. - ### Images and figures For overview images and other documents we follow the nf-core [style guidelines and examples](https://nf-co.re/developers/design_guidelines). diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index ea229fab..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: Bug report -about: Report something that is broken or incorrect -labels: bug ---- - - - -## Check Documentation - -I have checked the following places for your error: - -- [ ] [nf-core website: troubleshooting](https://nf-co.re/usage/troubleshooting) -- [ ] [nf-core/mhcquant pipeline documentation](https://nf-co.re/mhcquant/usage) - -## Description of the bug - - - -## Steps to reproduce - -Steps to reproduce the behaviour: - -1. Command line: -2. See error: - -## Expected behaviour - - - -## Log files - -Have you provided the following extra information/files: - -- [ ] The command used to run the pipeline -- [ ] The `.nextflow.log` file - -## System - -- Hardware: -- Executor: -- OS: -- Version - -## Nextflow Installation - -- Version: - -## Container engine - -- Engine: -- version: - -## Additional context - - diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..816a6f87 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,52 @@ + +name: Bug report +description: Report something that is broken or incorrect +labels: bug +body: + + - type: markdown + attributes: + value: | + Before you post this issue, please check the documentation: + + - [nf-core website: troubleshooting](https://nf-co.re/usage/troubleshooting) + - [nf-core/mhcquant pipeline documentation](https://nf-co.re/mhcquant/usage) + + - type: textarea + id: description + attributes: + label: Description of the bug + description: A clear and concise description of what the bug is. + validations: + required: true + + - type: textarea + id: command_used + attributes: + label: Command used and terminal output + description: Steps to reproduce the behaviour. Please paste the command you used to launch the pipeline and the output from your terminal. + render: console + placeholder: | + $ nextflow run ... + + Some output where something broke + + - type: textarea + id: files + attributes: + label: Relevant files + description: | + Please drag and drop the relevant files here. Create a `.zip` archive if the extension is not allowed. + Your verbose log file `.nextflow.log` is often useful _(this is a hidden file in the directory where you launched the pipeline)_ as well as custom Nextflow configuration files. + + - type: textarea + id: system + attributes: + label: System information + description: | + * Nextflow version _(eg. 21.10.3)_ + * Hardware _(eg. HPC, Desktop, Cloud)_ + * Executor _(eg. slurm, local, awsbatch)_ + * Container engine: _(e.g. Docker, Singularity, Conda, Podman, Shifter or Charliecloud)_ + * OS _(eg. CentOS Linux, macOS, Linux Mint)_ + * Version of nf-core/mhcquant _(eg. 1.1, 1.5, 1.8.2)_ diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index c283b9b4..51b0d6a8 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,3 @@ -blank_issues_enabled: false contact_links: - name: Join nf-core url: https://nf-co.re/join diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 7a90e846..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for the nf-core/mhcquant pipeline -labels: enhancement ---- - - - -## Is your feature request related to a problem? Please describe - - - - - -## Describe the solution you'd like - - - -## Describe alternatives you've considered - - - -## Additional context - - diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..747f7388 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,11 @@ +name: Feature request +description: Suggest an idea for the nf-core/mhcquant pipeline +labels: enhancement +body: + - type: textarea + id: description + attributes: + label: Description of feature + description: Please describe your suggestion for a new feature. It might help to describe a problem or use case, plus any alternatives that you have considered. + validations: + required: true diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 6c6c71d7..00ac8dfd 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -20,11 +20,11 @@ jobs: access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} compute_env: ${{ secrets.TOWER_COMPUTE_ENV }} pipeline: ${{ github.repository }} - revision: ${{ github.sha } } + 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 + profiles: test_full,aws_tower pre_run_script: 'export NXF_VER=21.10.3' diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index acc6f70b..15e5b355 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Launch workflow via tower uses: nf-core/tower-action@v2 - + with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} @@ -22,7 +22,7 @@ jobs: 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-test-${{ 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 510e8f01..dde5a265 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,8 +8,9 @@ on: release: types: [published] -# Uncomment if we need an edge release of Nextflow again -# env: NXF_EDGE: 1 +env: + NXF_ANSI_LOG: false + CAPSULE_LOG: none jobs: test: @@ -17,20 +18,26 @@ jobs: # Only run on push if this is the nf-core dev branch (merged PRs) if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/mhcquant') }} runs-on: ubuntu-latest - env: - NXF_VER: ${{ matrix.nxf_ver }} - NXF_ANSI_LOG: false strategy: matrix: - # Nextflow versions: check pipeline minimum and current latest - nxf_ver: ['21.10.3', ''] + # Nextflow versions + include: + # Test pipeline minimum Nextflow version + - NXF_VER: '21.10.3' + NXF_EDGE: '' + # Test latest edge release of Nextflow + - NXF_VER: '' + NXF_EDGE: '1' steps: - name: Check out pipeline code uses: actions/checkout@v2 - name: Install Nextflow env: - CAPSULE_LOG: none + NXF_VER: ${{ matrix.NXF_VER }} + # Uncomment only if the edge release is more recent than the latest stable release + # See https://github.com/nextflow-io/nextflow/issues/2467 + # NXF_EDGE: ${{ matrix.NXF_EDGE }} run: | wget -qO- get.nextflow.io | bash sudo mv nextflow /usr/local/bin/ @@ -44,17 +51,30 @@ jobs: # Only run on push if this is the nf-core dev branch (merged PRs) if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/mhcquant') }} runs-on: ubuntu-latest - env: - NXF_VER: ${{ matrix.nxf_ver }} - NXF_ANSI_LOG: false + strategy: + matrix: + # Nextflow versions + include: + # Test pipeline minimum Nextflow version + - NXF_VER: '21.10.3' + NXF_EDGE: '' + # Test latest edge release of Nextflow + - NXF_VER: '' + NXF_EDGE: '1' steps: - name: Check out pipeline code uses: actions/checkout@v2 - name: Install Nextflow + env: + NXF_VER: ${{ matrix.NXF_VER }} + # Uncomment only if the edge release is more recent than the latest stable release + # See https://github.com/nextflow-io/nextflow/issues/2467 + # NXF_EDGE: ${{ matrix.NXF_EDGE }} run: | wget -qO- get.nextflow.io | bash sudo mv nextflow /usr/local/bin/ + - name: Run pipeline with additional params run: | nextflow run ${GITHUB_WORKSPACE} -profile test,docker --predict_class_1 --predict_class_2 --predict_RT diff --git a/.github/workflows/linting_comment.yml b/.github/workflows/linting_comment.yml index 90f03c6f..44d72994 100644 --- a/.github/workflows/linting_comment.yml +++ b/.github/workflows/linting_comment.yml @@ -15,6 +15,7 @@ jobs: uses: dawidd6/action-download-artifact@v2 with: workflow: linting.yml + workflow_conclusion: completed - name: Get PR number id: pr_number diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fe851e9..b493caef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # nf-core/mhcquant: Changelog +## v2.2.0 nfcore/mhcquant "Silver Titanium Ostrich" - 2021/01/14 + +### `Added` + +- Included the newest nf-core template (version 2.2) +- Adjustment of the README, including all contributors +- Inclusion of the PSMs files (tsv format) per replicates in `results/PSMs` +- Include check in WorkflowMhcquant, to determine if the allele and vcf sheet has been provided under specific circumstances + +### `Fixed` + +- Changed parameters in the nextflow_schema.json to be in coherence with the nextflow.config +- Error that was raised in generate_proteins_from_vcf +- Problems that were detected in predict_possible_class1_neoepitopes and predict_possible_class2_neoepitopes +- Error that occurred in mhcnuggets_predictneoepitopesclass2 (faulty container set up) + +### `Dependencies` + +| Dependency | Old version | New version | +| --------------------- | ----------- | ----------- | +| `fred2` | 2.0.6 | 2.0.7 | + +### `Deprecated` + ## v2.1.0 nf-core/mhcquant "Olive Tin Hamster" - 2021/12/09 ### `Added` diff --git a/CITATIONS.md b/CITATIONS.md index 68d4abe9..fdf7a5dc 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -22,7 +22,7 @@ * [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/) +* [MultiQC](https://pubmed.ncbi.nlm.nih.gov/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 diff --git a/README.md b/README.md index 2a9651db..b71cfe63 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# ![nf-core/mhcquant](docs/images/nf-core-mhcquant_logo.png) +# ![nf-core/mhcquant](docs/images/nf-core-mhcquant_logo_light.png#gh-light-mode-only) ![nf-core/mhcquant](docs/images/nf-core-mhcquant_logo_dark.png#gh-dark-mode-only) [![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) +[![Cite with Zenodo](http://img.shields.io/badge/DOI-10.5281/zenodo.1569909-1073c8?labelColor=000000)](https://doi.org/10.5281/zenodo.1569909) [![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/) @@ -37,16 +37,19 @@ On release, automated continuous integration tests run the pipeline on a full-si 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: ```console - nextflow run nf-core/mhcquant -profile test, + nextflow run nf-core/mhcquant -profile test,YOURPROFILE ``` + Note that some form of configuration will be needed so that Nextflow knows how to fetch the required software. This is usually done in the form of a config profile (`YOURPROFILE` in the example command above). You can chain multiple config profiles in a comma-separated string. + + > * The pipeline comes with config profiles called `docker`, `singularity`, `podman`, `shifter`, `charliecloud` and `conda` which instruct the pipeline to use the named tool for software management. For example, `-profile test,docker`. > * Please check [nf-core/configs](https://github.com/nf-core/configs#documentation) to see if a custom config file to run nf-core pipelines already exists for your Institute. If so, you can simply use `-profile ` in your command. This will enable either `docker` or `singularity` and set the appropriate execution settings for your local compute environment. - > * 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 `singularity` and are persistently observing issues downloading Singularity images directly due to timeout or network issues, then you can use the `--singularity_pull_docker_container` parameter to pull and convert the Docker image instead. Alternatively, you can use the [`nf-core download`](https://nf-co.re/tools/#downloading-pipelines-for-offline-use) command to download images first, before running the pipeline. Setting the [`NXF_SINGULARITY_CACHEDIR` or `singularity.cacheDir`](https://www.nextflow.io/docs/latest/singularity.html?#singularity-docker-hub) Nextflow options enables you 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! @@ -60,33 +63,24 @@ On release, automated continuous integration tests run the pipeline on a full-si --refine_fdr_on_predicted_subset ``` -See [usage docs](https://nf-co.re/mhcquant/usage) for all of the available options when running the pipeline. - -## Pipeline Summary - -By default, the pipeline currently performs the following: - -* Protein database addition by mutated genome variants (`Fred2 Immunoinformatics Toolbox`) -* Database search ('Comet') -* False discovery rate estimation ('Percolator') -* Retention time alignment ('OpenMS-MapAlignerIdentification') -* Targeted peptide quantification ('OpenMS-FeatureFinderIdentification') -* MHC peptide affinity prediction ('MHCFlurry','MHCNuggets') - ## Documentation -The nf-core/mhcquant pipeline comes with documentation about the pipeline: [usage](https://nf-co.re/mhcquant/usage) and [output](https://nf-co.re/mhcquant/output). +The nf-core/mhcquant pipeline comes with documentation about the pipeline [usage](https://nf-co.re/mhcquant/usage), [parameters](https://nf-co.re/mhcquant/parameters) and [output](https://nf-co.re/mhcquant/output). ## Credits -We thank the following people for their extensive assistance in the development -of this pipeline: - -* Leon Bichmann (@Leon-Bichmann) -* Lukas Heumos (@Zethson) -* Alexander Peltzer (@apeltzer) +nf-core/mhcquant was originally written by [Leon Bichmann](https://github.com/Leon-Bichmann) from the [Kohlbacher Lab](https://kohlbacherlab.org/).The pipeline was re-written in Nextflow DSL2 and is primarily maintained by [Marissa Dubbelaar](https://github.com/marissaDubbelaar) from [Clinical Collaboration Unit Translational Immunology](https://www.medizin.uni-tuebingen.de/en-de/das-klinikum/einrichtungen/kliniken/medizinische-klinik/kke-translationale-immunologie) and [Quantitative Biology Center](https://uni-tuebingen.de/forschung/forschungsinfrastruktur/zentrum-fuer-quantitative-biologie-qbic/) in Tübingen. -The pipeline was converted to Nextflow DSL2 by Marissa Dubbelaar (@marissaDubbelaar) +Helpful contributors: + - [Lukas Heumos](https://github.com/Zethson) + - [Alexander Peltzer](https://github.com/apeltzer) + - [Maxime Garcia](https://github.com/maxulysse) + - [Gisela Gabernet](https://github.com/ggabernet) + - [Leon Kuchenbecker](https://github.com/lkuchenb) + - [Phil Ewels](https://github.com/ewels) + - [Christian Fufezan](https://github.com/fu) + - [Sven Fillinger](https://github.com/sven1103) + - [Kevin Menden](https://github.com/KevinMenden) ## Contributions and Support @@ -96,14 +90,13 @@ 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 it using the following doi: [10.5281/zenodo.5407955](https://doi.org/10.5281/zenodo.5407955) and the corresponding manuscript: +If you use nf-core/mhcquant for your analysis, please cite it using the following doi: [10.5281/zenodo.1569909](https://doi.org/10.5281/zenodo.1569909) and the corresponding manuscript: > **MHCquant: Automated and Reproducible Data Analysis for Immunopeptidomics** > > Leon Bichmann, Annika Nelde, Michael Ghosh, Lukas Heumos, Christopher Mohr, Alexander Peltzer, Leon Kuchenbecker, Timo Sachsenberg, Juliane S. Walz, Stefan Stevanović, Hans-Georg Rammensee & Oliver Kohlbacher > -> Journal of Proteome Research 2019 18 (11), 3876-3884 -> DOI: 10.1021/acs.jproteome.9b00313 +> _Journal of Proteome Research_ 2019 18 (11), 3876-3884. doi: [10.1021/acs.jproteome.9b00313](https://pubs.acs.org/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. diff --git a/assets/multiqc_config.yaml b/assets/multiqc_config.yaml index a0e5fa3c..76398921 100644 --- a/assets/multiqc_config.yaml +++ b/assets/multiqc_config.yaml @@ -1,7 +1,7 @@ report_comment: > This report has been generated by the nf-core/mhcquant analysis pipeline. For information about how to interpret these results, please see the - documentation. + documentation. report_section_order: software_versions: order: -1000 diff --git a/assets/nf-core-mhcquant_logo.png b/assets/nf-core-mhcquant_logo.png deleted file mode 100644 index 378f944c..00000000 Binary files a/assets/nf-core-mhcquant_logo.png and /dev/null differ diff --git a/assets/nf-core-mhcquant_logo_light.png b/assets/nf-core-mhcquant_logo_light.png new file mode 100644 index 00000000..c470ddb2 Binary files /dev/null and b/assets/nf-core-mhcquant_logo_light.png differ diff --git a/assets/sendmail_template.txt b/assets/sendmail_template.txt index 43aaddfb..f3b6b8cf 100644 --- a/assets/sendmail_template.txt +++ b/assets/sendmail_template.txt @@ -12,9 +12,9 @@ $email_html Content-Type: image/png;name="nf-core-mhcquant_logo.png" Content-Transfer-Encoding: base64 Content-ID: -Content-Disposition: inline; filename="nf-core-mhcquant_logo.png" +Content-Disposition: inline; filename="nf-core-mhcquant_logo_light.png" -<% out << new File("$projectDir/assets/nf-core-mhcquant_logo.png"). +<% out << new File("$projectDir/assets/nf-core-mhcquant_logo_light.png"). bytes. encodeBase64(). toString(). diff --git a/bin/scrape_software_versions.py b/bin/scrape_software_versions.py deleted file mode 100755 index 44a9c393..00000000 --- a/bin/scrape_software_versions.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function -import os - -results = {} -version_files = [x for x in os.listdir(".") if x.endswith(".version.txt")] -for version_file in version_files: - - software = version_file.replace(".version.txt", "") - if software == "pipeline": - software = "nf-core/mhcquant" - - with open(version_file) as fin: - version = fin.read().strip() - results[software] = version - -# Dump to YAML -print( - """ -id: 'software_versions' -section_name: 'nf-core/mhcquant Software Versions' -section_href: 'https://github.com/nf-core/mhcquant' -plot_type: 'html' -description: 'are collected at run time from the software output.' -data: | -
-""" -) -for k, v in sorted(results.items()): - print("
{}
{}
".format(k, v)) -print("
") - -# Write out as tsv file: -with open("software_versions.tsv", "w") as f: - for k, v in sorted(results.items()): - f.write("{}\t{}\n".format(k, v)) diff --git a/bin/variants2fasta.py b/bin/variants2fasta.py index d564d450..33c63f26 100755 --- a/bin/variants2fasta.py +++ b/bin/variants2fasta.py @@ -197,29 +197,24 @@ def main(): #generate proteins proteins = generate_proteins_from_transcripts(transcripts) - print(proteins) - #write fasta file - with open(args.output.replace('.fasta','_vcf.fasta'), "w") as f: + with open(args.output, "w") as f: for p in proteins: f.write('>' + str(p.transcript_id) + '|' + str(p.vars) + '_var_' + '\n') f.write(str(p)+ '\n') #concatenate fasta file with fasta reference - op=open(args.output.replace('.fasta','_vcf.fasta')) - opr1=op.read() - op.close() + with open(args.output) as op: + opr1 = op.read() - op=open(args.fasta_ref) - opr2=op.read() - op.close() + with open(args.fasta_ref) as op: + opr2 = op.read() - concat=opr1+opr2 + concat = opr1+opr2 - op=open(args.output,'w') - op.write(concat) - op.close() + with open(args.output, "w") as op: + op.write(concat) else: sys.stderr.write("At least a vcf file or a protein id file has to be provided.\n") diff --git a/conf/base.config b/conf/base.config index bf02eda6..6ef3aa50 100644 --- a/conf/base.config +++ b/conf/base.config @@ -1,4 +1,3 @@ - /* ======================================================================================== nf-core/mhcquant Nextflow base config file @@ -11,9 +10,9 @@ process { - cpus = { check_max( 1 * task.attempt, 'cpus' ) } + cpus = { check_max( 1 * task.attempt, 'cpus' ) } memory = { check_max( 4.GB * task.attempt, 'memory' ) } - time = { check_max( 2.h * task.attempt, 'time' ) } + time = { check_max( 2.h * task.attempt, 'time' ) } errorStrategy = { task.exitStatus in [143,137,104,134,139] ? 'retry' : 'finish' } maxRetries = 1 @@ -49,4 +48,7 @@ process { errorStrategy = 'retry' maxRetries = 2 } + withName:CUSTOM_DUMPSOFTWAREVERSIONS { + cache = false + } } diff --git a/conf/modules.config b/conf/modules.config index 5f31dc23..882dfb29 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -1,84 +1,379 @@ /* ======================================================================================== - Config file for defining DSL2 per module options + Config file for defining DSL2 per module options and publishing paths ======================================================================================== 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. + ext.args = Additional arguments appended to command in module. + ext.args2 = Second set of arguments appended to command in module (multi-tool modules). + ext.args3 = Third set of arguments appended to command in module (multi-tool modules). + ext.prefix = File name prefix for output files. ---------------------------------------------------------------------------------------- */ -params { - modules { +process { - 'generate_proteins_from_vcf' { - args= "-t ${params.variant_annotation_style} -r ${params.variant_reference}" + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: 'copy', + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: SAMPLESHEET_CHECK { + publishDir = [ + path: { "${params.outdir}/pipeline_info" }, + mode: 'copy', + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + + withName: CUSTOM_DUMPSOFTWAREVERSIONS { + publishDir = [ + path: { "${params.outdir}/pipeline_info" }, + mode: 'copy', + pattern: '*_versions.yml' + ] + } + +} + +process { + + withName: GENERATE_PROTEINS_FROM_VCF { + ext.args = [ + "-t ${params.variant_annotation_style}", + "-r ${params.variant_reference}", + params.variant_indel_filter ? "-fINDEL" : "", + params.variant_frameshift_filter ? "-fFS" : "", + params.variant_snp_filter ? "-fSNP" : "" + ].join(' ').trim() + publishDir = [ + path: { "${params.outdir}" }, + mode: 'copy', + pattern: '*.fasta' + ] + } + + withName: OPENMS_MAPALIGNERIDENTIFICATION { + ext.args = [ + "-model:type linear", + "-algorithm:max_rt_shift ${params.max_rt_alignment_shift}" + ].join(' ').trim() + publishDir = [ enabled: false ] + } + + withName: OPENMS_COMETADAPTER { + ext.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(" ") }", + "-enzyme '${params.enzyme}'", + "-spectrum_batch_size ${params.spectrum_batch_size}" + ].join(' ').trim() + publishDir = [ enabled: false ] + } + + withName: OPENMS_IDFILTER_FOR_ALIGNMENT { + ext.args = [ + "-remove_decoys", + "-precursor:length '${params.peptide_min_length}:${params.peptide_max_length}'", + "-delete_unreferenced_peptide_hits", + (params.fdr_threshold == '0.01') ? "-score:pep 0.05" : "-score:pep " + params.fdr_threshold + ].join(' ').trim() + publishDir = [ + path: { "${params.outdir}/Intermediate_Results" }, + mode: 'copy', + pattern: '*.idXML' + ] + } + + withName: OPENMS_IDFILTER_Q_VALUE { + ext.prefix = { "${meta.id}_filtered" } + ext.args = [ + "-remove_decoys", + "-precursor:length '${params.peptide_min_length}:${params.peptide_max_length}'", + "-delete_unreferenced_peptide_hits", + (params.fdr_threshold == '0.01') ? "-score:pep 0.05" : "-score:pep " + params.fdr_threshold + ].join(' ').trim() + publishDir = [ + path: { "${params.outdir}/Intermediate_Results" }, + mode: 'copy', + pattern: '*.idXML' + ] + } + + withName: OPENMS_PERCOLATORADAPTER { + ext.prefix = { "${meta.id}_all_ids_merged_psm_perc" } + ext.args = [ + "-seed 4711", + "-trainFDR 0.05", + "-testFDR 0.05", + "-enzyme no_enzyme", + "-subset_max_train ${params.subset_max_train}", + "-doc ${params.description_correct_features} ", + (params.fdr_level != 'psm-level-fdrs') ? "-" + params.fdr_level : "" + ].join(' ').trim() + publishDir = [ + path: { "${params.outdir}/Intermediate_Results" }, + mode: 'copy', + pattern: '*.idXML' + ] + } + + withName: OPENMS_PSMFEATUREEXTRACTOR { + publishDir = [ + path: { "${params.outdir}/Intermediate_Results" }, + mode: 'copy', + pattern: '*.idXML' + ] + } + + withName: 'OPENMS_DECOYDATABASE|OPENMS_THERMORAWFILEPARSER|OPENMS_PEAKPICKERHIRES|OPENMS_PEPTIDEINDEXER|OPENMS_FALSEDISCOVERYRATE|OPENMS_IDMERGER|OPENMS_MAPRTTRANSFORMER.*ML|OPENMS_FEATURE.*|OPENMS_IDCONFLICTRESOLVER|OPENMS_MZTABEXPORTER' { + publishDir = [ enabled: false ] + } + + withName: 'OPENMS_TEXTEXPORTER_CSV' { + ext.args = [ + "-id:add_metavalues 0" + ].join(' ').trim() + publishDir = [ + path: { "${params.outdir}/" }, + mode: 'copy', + pattern: '*.tsv' + ] + } + + withName: 'OPENMS_TEXTEXPORTER_PSMS' { + publishDir = [ + path: { "${params.outdir}/PSMs" }, + mode: 'copy', + pattern: '*.tsv' + ] + } +} + + +// Refine on predicted subset +process { + + if ( params.refine_fdr_on_predicted_subset && params.predict_class_1 ) { + withName: OPENMS_MZTABEXPORTERPERC { + ext.prefix = { "${meta.sample}_${meta.condition}_all_ids_merged_psm_perc_filtered" } + publishDir = [ + path: { "${params.outdir}/Intermediate_Results" }, + mode: 'copy', + pattern: '*.mzTab' + ] + } + + withName: OPENMS_MZTABEXPORTERPSM { + ext.prefix = { "${meta.sample}_${meta.condition}_all_ids_merged" } + publishDir = [ + path: { "${params.outdir}/Intermediate_Results" }, + mode: 'copy', + pattern: '*.mzTab' + ] + } + + withName: MHCFLURRY_PREDICTPSMS { + publishDir = [ enabled: false ] + } + + withName: REFINE_FDR:OPENMS_PERCOLATORADAPTER { + ext.prefix = { "${meta.id}_perc_subset" } + ext.args = [ + "-seed 4711", + "-trainFDR 0.05", + "-testFDR 0.05", + "-enzyme no_enzyme", + "-subset_max_train ${params.subset_max_train}", + "-doc ${params.description_correct_features} ", + (params.fdr_level != 'psm-level-fdrs') ? "-" + params.fdr_level : "" + ].join(' ').trim() + publishDir = [ + path: { "${params.outdir}/Intermediate_Results" }, + mode: 'copy', + pattern: '*.idXML' + ] + } + + withName: OPENMS_IDFILTER_PSMS { + ext.prefix = { "${meta.id}_pred_filtered" } + ext.args = [ + "-whitelist:ignore_modifications", + "-whitelist:peptides" + ].join(' ').trim() + publishDir = [ + path: { "${params.outdir}/Intermediate_Results" }, + mode: 'copy', + pattern: '*.idXML' + ] + } + + withName: OPENMS_IDFILTER_REFINED { + ext.args = [ + "-remove_decoys", + "-precursor:length '${params.peptide_min_length}:${params.peptide_max_length}'", + "-delete_unreferenced_peptide_hits", + (params.fdr_threshold == '0.01') ? "-score:pep 0.05" : "-score:pep " + params.fdr_threshold + ].join(' ').trim() + publishDir = [ + path: { "${params.outdir}/Intermediate_Results" }, + mode: 'copy', + pattern: '*.idXML' + ] + } + } +} + +// Class I prediction +process { + + if ( params.predict_class_1 & !params.skip_quantification ) { + withName: MHCFLURRY_PREDICTPEPTIDESCLASS1 { + publishDir = [ + path: { "${params.outdir}/class_1_bindings" }, + mode: 'copy', + pattern: '*.fasta' + ] } + } - 'multiqc' { - args = '' - publish_dir = "multiqc/" + if ( params.predict_class_1 & !params.skip_quantification & params.include_proteins_from_vcf ) { + withName: PREDICT_POSSIBLE_CLASS1_NEOEPITOPES { + ext.prefix = { "${meta}_vcf_neoepitopes" } + publishDir = [ + path: {"${params.outdir}/class_1_bindings"}, + mode: 'copy', + pattern: '*.csv' + ] } - 'openms_map_aligner_identification' { - args = "-model:type linear -algorithm:max_rt_shift ${params.max_rt_alignment_shift} " + withName: RESOLVE_FOUND_CLASS1_NEOEPITOPES { + ext.prefix = { "${meta.sample}_found_neoepitopes" } + publishDir = [ + path: {"${params.outdir}/class_1_bindings"}, + mode: 'copy', + pattern: '*.csv' + ] } - 'openms_comet_adapter' { - 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} " + withName: MHCFLURRY_PREDICTNEOEPITOPESCLASS1 { + publishDir = [ + path: {"${params.outdir}/class_1_bindings"}, + mode: 'copy', + pattern: '*.csv' + ] } + } +} - 'openms_id_filter' { - args = "-remove_decoys -precursor:length '${params.peptide_min_length}:${params.peptide_max_length}' -delete_unreferenced_peptide_hits " +// Class II prediction +process { + + if ( params.predict_class_2 & !params.skip_quantification ) { + + withName: MHCNUGGETS_PEPTIDESCLASS2PRE { + publishDir = [ + path: { "${params.outdir}/class_2_bindings" }, + mode: 'copy', + pattern: '*_peptides' + ] } - '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" + withName: MHCNUGGETS_PREDICTPEPTIDESCLASS2 { + publishDir = [ + path: { "${params.outdir}/class_2_bindings" }, + mode: 'copy', + pattern: '*_class_2' + ] } - 'openms_id_filter_whitelist' { - args = "-whitelist:ignore_modifications -whitelist:peptides " - suffix = "pred_filtered" + withName: MHCNUGGETS_PEPTIDESCLASS2POST { + publishDir = [ + path: { "${params.outdir}/class_2_bindings" }, + mode: 'copy', + pattern: '*.csv' + ] } + } + + if ( params.predict_class_2 & !params.skip_quantification & params.include_proteins_from_vcf ) { - 'openms_mztab_exporter_perc' { - suffix = "all_ids_merged_psm_perc_filtered" + withName: PREDICT_POSSIBLE_CLASS2_NEOEPITOPES { + publishDir = [ + path: { "${params.outdir}/class_2_bindings" }, + mode: 'copy', + pattern: '*.csv' + ] } - 'openms_mztab_exporter_psm' { - suffix = "all_ids_merged" + withName: RESOLVE_FOUND_CLASS2_NEOEPITOPES { + publishDir = [ + path: { "${params.outdir}/class_2_bindings" }, + mode: 'copy', + pattern: '*.csv' + ] } - '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" + withName: MHCNUGGETS_NEOEPITOPESCLASS2PRE { + ext.prefix = { "${meta}_mhcnuggets_preprocessed" } + publishDir = [ + path: { "${params.outdir}/class_2_bindings" }, + mode: 'copy', + pattern: '*${ext.prefix}' + ] } - '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" + withName: MHCNUGGETS_PREDICTNEOEPITOPESCLASS2 { + ext.prefix = { "${meta}_predicted_neoepitopes_class_2" } + publishDir = [ + path: { "${params.outdir}/class_2_bindings" }, + mode: 'copy', + pattern: '*${ext.prefix}' + ] } - 'openms_rt_predict_peptides' { - suffix = "_id_files_for_rt_prediction_RTpredicted" + withName: MHCNUGGETS_NEOEPITOPESCLASS2POST { + publishDir = [ + path: { "${params.outdir}/class_2_bindings" }, + mode: 'copy', + pattern: '*.csv' + ] } + } +} + +process { + + if ( params.predict_RT ) { - 'openms_rt_predict_neo_epitopes' { - suffix = "_txt_file_for_rt_prediction_RTpredicted" + withName: OPENMS_RTMODEL { + publishDir = [ enabled: false ] } + withName: OPENMS_RTPREDICT_FOUND_PEPTIDES { + ext.prefix = { "${meta.sample}_id_files_for_rt_prediction_RTpredicted" } + publishDir = [ + path: { "${params.outdir}/RT_prediction" }, + mode: 'copy', + pattern: '*.csv' + ] + } + + withName: OPENMS_RTPREDICT_NEOEPITOPES { + ext.prefix = { "${meta.sample}_txt_file_for_rt_prediction_RTpredicted" } + publishDir = [ + path: { "${params.outdir}/RT_prediction" }, + mode: 'copy', + pattern: '*.csv' + ] + } } } diff --git a/conf/test.config b/conf/test.config index 8a830171..34296e61 100644 --- a/conf/test.config +++ b/conf/test.config @@ -16,8 +16,8 @@ params { // Limit resources so that this can run on GitHub Actions max_cpus = 2 - max_memory = 6.GB - max_time = 6.h + max_memory = '6.GB' + max_time = '6.h' // Input data fasta = 'https://raw.githubusercontent.com/nf-core/test-datasets/mhcquant/test.fasta' diff --git a/docs/images/nf-core-mhcquant_logo.png b/docs/images/nf-core-mhcquant_logo.png deleted file mode 100644 index d7d6801b..00000000 Binary files a/docs/images/nf-core-mhcquant_logo.png and /dev/null differ diff --git a/docs/images/nf-core-mhcquant_logo_dark.png b/docs/images/nf-core-mhcquant_logo_dark.png new file mode 100644 index 00000000..098ca5f2 Binary files /dev/null and b/docs/images/nf-core-mhcquant_logo_dark.png differ diff --git a/docs/images/nf-core-mhcquant_logo_light.png b/docs/images/nf-core-mhcquant_logo_light.png new file mode 100644 index 00000000..6c1dcf66 Binary files /dev/null and b/docs/images/nf-core-mhcquant_logo_light.png differ diff --git a/docs/output.md b/docs/output.md index 38e993f9..780c3982 100644 --- a/docs/output.md +++ b/docs/output.md @@ -2,11 +2,7 @@ ## Introduction -This document describes the output produced by the pipeline. - -```console -nextflow run mhcquant -profile test, -``` +This document describes the output produced by the pipeline. Most of the plots are taken from the MultiQC report, which summarises results at the end of the pipeline. The directories listed below will be created in the results directory after the pipeline has finished. All paths are relative to the top-level results directory. @@ -99,7 +95,6 @@ PEP sequence accession best_search_engine_score[1] retention_time char ``` Most important to know that in this format we annotated the q-value of each peptide identification in the `best_seach_engine_score[1]` column and peptide quantities in the peptide_abundance_study_variable` columns. - [mzTab](http://www.psidev.info/mztab) is a light-weight format to report mass spectrometry search results. It provides all important information about identified peptide hits and is compatible with the PRIDE Archive - proteomics data repository. ## VCF @@ -191,8 +186,6 @@ peptide allele prediction prediction_low prediction_high prediction_pe -## Workflow reporting and documentation - ### MultiQC
@@ -201,12 +194,13 @@ peptide allele prediction prediction_low prediction_high prediction_pe * `multiqc/` * `multiqc_report.html`: a standalone HTML file that can be viewed in your web browser. * `multiqc_data/`: directory containing parsed statistics from the different tools used in the pipeline. + * `multiqc_plots/`: directory containing static images from the report in various formats.
-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. +[MultiQC](http://multiqc.info) 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 . +Results generated by MultiQC collate pipeline QC from supported tools e.g. FastQC. The pipeline has special steps which also allow the software versions to be reported in the MultiQC output for future traceability. For more information about how to use MultiQC reports, see . ### Pipeline information @@ -215,9 +209,9 @@ The pipeline has special steps which allow the software versions to be reported * `pipeline_info/` * Reports generated by Nextflow: `execution_report.html`, `execution_timeline.html`, `execution_trace.txt` and `pipeline_dag.dot`/`pipeline_dag.svg`. - * Reports generated by the pipeline: `pipeline_report.html`, `pipeline_report.txt` and `software_versions.tsv`. - * Reformatted sample-sheet files used as input to the pipeline: `samplesheet.valid.csv`. + * Reports generated by the pipeline: `pipeline_report.html`, `pipeline_report.txt` and `software_versions.yml`. The `pipeline_report*` files will only be present if the `--email` / `--email_on_fail` parameter's are used when running the pipeline. + * Reformatted samplesheet files used as input to the pipeline: `samplesheet.valid.csv`. -[Nextflow](https://www.nextflow.io/docs/latest/tracing.html) provides excellent functionality for generating various reports relevant to the running and execution of the pipeline. This will allow you to troubleshoot errors with the running of the pipeline and provide you with other information such as launch commands, run times and resource usage. +[Nextflow](https://www.nextflow.io/docs/latest/tracing.html) provides excellent functionality for generating various reports relevant to the running and execution of the pipeline. This will allow you to troubleshoot errors with the running of the pipeline, and also provide you with other information such as launch commands, run times and resource usage. diff --git a/docs/usage.md b/docs/usage.md index 879ed17d..11cf718a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -14,6 +14,7 @@ - [`-resume`](#-resume) - [Custom configuration](#custom-configuration) - [Resource requests](#resource-requests) + - [Updating containers](#updating-containers) - [nf-core/configs](#nf-core-configs) - [Running in the background](#running-in-the-background) - [Nextflow memory requirements](#nextflow-memory-requirements) @@ -202,6 +203,46 @@ process { > **NB:** We specify just the process name i.e. `STAR_ALIGN` in the config file and not the full task name string that is printed to screen in the error message or on the terminal whilst the pipeline is running i.e. `RNASEQ:ALIGN_STAR:STAR_ALIGN`. You may get a warning suggesting that the process selector isn't recognised but you can ignore that if the process name has been specified correctly. This is something that needs to be fixed upstream in core Nextflow. +### Updating containers + +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. If for some reason you need to use a different version of a particular tool with the pipeline then you just need to identify the `process` name and override the Nextflow `container` definition for that process using the `withName` declaration. For example, in the [nf-core/viralrecon](https://nf-co.re/viralrecon) pipeline a tool called [Pangolin](https://github.com/cov-lineages/pangolin) has been used during the COVID-19 pandemic to assign lineages to SARS-CoV-2 genome sequenced samples. Given that the lineage assignments change quite frequently it doesn't make sense to re-release the nf-core/viralrecon everytime a new version of Pangolin has been released. However, you can override the default container used by the pipeline by creating a custom config file and passing it as a command-line argument via `-c custom.config`. + +1. Check the default version used by the pipeline in the module file for [Pangolin](https://github.com/nf-core/viralrecon/blob/a85d5969f9025409e3618d6c280ef15ce417df65/modules/nf-core/software/pangolin/main.nf#L14-L19) +2. Find the latest version of the Biocontainer available on [Quay.io](https://quay.io/repository/biocontainers/pangolin?tag=latest&tab=tags) +3. Create the custom config accordingly: + + - For Docker: + + ```nextflow + process { + withName: PANGOLIN { + container = 'quay.io/biocontainers/pangolin:3.0.5--pyhdfd78af_0' + } + } + ``` + + - For Singularity: + + ```nextflow + process { + withName: PANGOLIN { + container = 'https://depot.galaxyproject.org/singularity/pangolin:3.0.5--pyhdfd78af_0' + } + } + ``` + + - For Conda: + + ```nextflow + process { + withName: PANGOLIN { + conda = 'bioconda::pangolin=3.0.5' + } + } + ``` + +> **NB:** If you wish to periodically update individual tool-specific results (e.g. Pangolin) generated by the pipeline then you must ensure to keep the `work/` directory otherwise the `-resume` ability of the pipeline will be compromised and it will restart from scratch. + ### nf-core/configs In most cases, you will only need to create a custom config as a one-off but if you and others within your organisation are likely to be running nf-core pipelines regularly and need to use the same settings regularly it may be a good idea to request that your custom config file is uploaded to the `nf-core/configs` git repository. Before you do this please can you test that the config file works with your pipeline of choice using the `-c` parameter. You can then create a pull request to the `nf-core/configs` repository with the addition of your config file, associated documentation file (see examples in [`nf-core/configs/docs`](https://github.com/nf-core/configs/tree/master/docs)), and amending [`nfcore_custom.config`](https://github.com/nf-core/configs/blob/master/nfcore_custom.config) to include your custom profile. diff --git a/lib/NfcoreSchema.groovy b/lib/NfcoreSchema.groovy index 8d6920dd..40ab65f2 100755 --- a/lib/NfcoreSchema.groovy +++ b/lib/NfcoreSchema.groovy @@ -105,9 +105,13 @@ class NfcoreSchema { // Collect expected parameters from the schema def expectedParams = [] + def enums = [:] for (group in schemaParams) { for (p in group.value['properties']) { expectedParams.push(p.key) + if (group.value['properties'][p.key].containsKey('enum')) { + enums[p.key] = group.value['properties'][p.key]['enum'] + } } } @@ -155,7 +159,7 @@ class NfcoreSchema { println '' log.error 'ERROR: Validation of pipeline parameters failed!' JSONObject exceptionJSON = e.toJSON() - printExceptions(exceptionJSON, params_json, log) + printExceptions(exceptionJSON, params_json, log, enums) println '' has_error = true } @@ -202,7 +206,7 @@ class NfcoreSchema { } def type = '[' + group_params.get(param).type + ']' def description = group_params.get(param).description - def defaultValue = group_params.get(param).default ? " [default: " + group_params.get(param).default.toString() + "]" : '' + def defaultValue = group_params.get(param).default != null ? " [default: " + group_params.get(param).default.toString() + "]" : '' def description_default = description + colors.dim + defaultValue + colors.reset // Wrap long description texts // Loosely based on https://dzone.com/articles/groovy-plain-text-word-wrap @@ -260,13 +264,12 @@ class NfcoreSchema { // Get pipeline parameters defined in JSON Schema def Map params_summary = [:] - def blacklist = ['hostnames'] def params_map = paramsLoad(getSchemaPath(workflow, schema_filename=schema_filename)) for (group in params_map.keySet()) { def sub_params = new LinkedHashMap() def group_params = params_map.get(group) // This gets the parameters of that particular group for (param in group_params.keySet()) { - if (params.containsKey(param) && !blacklist.contains(param)) { + if (params.containsKey(param)) { def params_value = params.get(param) def schema_value = group_params.get(param).default def param_type = group_params.get(param).type @@ -330,7 +333,7 @@ class NfcoreSchema { // // Loop over nested exceptions and print the causingException // - private static void printExceptions(ex_json, params_json, log) { + private static void printExceptions(ex_json, params_json, log, enums, limit=5) { def causingExceptions = ex_json['causingExceptions'] if (causingExceptions.length() == 0) { def m = ex_json['message'] =~ /required key \[([^\]]+)\] not found/ @@ -346,11 +349,20 @@ class NfcoreSchema { else { def param = ex_json['pointerToViolation'] - ~/^#\// def param_val = params_json[param].toString() - log.error "* --${param}: ${ex_json['message']} (${param_val})" + if (enums.containsKey(param)) { + def error_msg = "* --${param}: '${param_val}' is not a valid choice (Available choices" + if (enums[param].size() > limit) { + log.error "${error_msg} (${limit} of ${enums[param].size()}): ${enums[param][0..limit-1].join(', ')}, ... )" + } else { + log.error "${error_msg}: ${enums[param].join(', ')})" + } + } else { + log.error "* --${param}: ${ex_json['message']} (${param_val})" + } } } for (ex in causingExceptions) { - printExceptions(ex, params_json, log) + printExceptions(ex, params_json, log, enums) } } diff --git a/lib/NfcoreTemplate.groovy b/lib/NfcoreTemplate.groovy index 44551e0a..2fc0a9b9 100755 --- a/lib/NfcoreTemplate.groovy +++ b/lib/NfcoreTemplate.groovy @@ -19,27 +19,16 @@ class NfcoreTemplate { } // - // Check params.hostnames + // Warn if a -profile or Nextflow config has not been provided to run the pipeline // - public static void hostName(workflow, params, log) { - Map colors = logColours(params.monochrome_logs) - if (params.hostnames) { - try { - def hostname = "hostname".execute().text.trim() - params.hostnames.each { prof, hnames -> - hnames.each { hname -> - if (hostname.contains(hname) && !workflow.profile.contains(prof)) { - log.info "=${colors.yellow}====================================================${colors.reset}=\n" + - "${colors.yellow}WARN: You are running with `-profile $workflow.profile`\n" + - " but your machine hostname is ${colors.white}'$hostname'${colors.reset}.\n" + - " ${colors.yellow_bold}Please use `-profile $prof${colors.reset}`\n" + - "=${colors.yellow}====================================================${colors.reset}=" - } - } - } - } catch (Exception e) { - log.warn "[$workflow.manifest.name] Could not determine 'hostname' - skipping check. Reason: ${e.message}." - } + public static void checkConfigProvided(workflow, log) { + if (workflow.profile == 'standard' && workflow.configFiles.size() <= 1) { + log.warn "[$workflow.manifest.name] You are attempting to run the pipeline without any custom configuration!\n\n" + + "This will be dependent on your local compute environment but can be achieved via one or more of the following:\n" + + " (1) Using an existing pipeline profile e.g. `-profile docker` or `-profile singularity`\n" + + " (2) Using an existing nf-core/configs for your Institution e.g. `-profile crick` or `-profile uppmax`\n" + + " (3) Using your own local custom config e.g. `-c /path/to/your/custom.config`\n\n" + + "Please refer to the quick start section and usage docs for the pipeline.\n " } } @@ -168,7 +157,6 @@ class NfcoreTemplate { log.info "-${colors.purple}[$workflow.manifest.name]${colors.red} Pipeline completed successfully, but with errored process(es) ${colors.reset}-" } } else { - hostName(workflow, params, log) log.info "-${colors.purple}[$workflow.manifest.name]${colors.red} Pipeline completed with errors${colors.reset}-" } } diff --git a/lib/Utils.groovy b/lib/Utils.groovy index 18173e98..1b88aec0 100644 --- a/lib/Utils.groovy +++ b/lib/Utils.groovy @@ -37,11 +37,4 @@ class Utils { "===================================================================================" } } - - // - // Join module args with appropriate spacing - // - public static String joinModuleArgs(args_list) { - return ' ' + args_list.join(' ') - } } diff --git a/lib/WorkflowMain.groovy b/lib/WorkflowMain.groovy index d12756c7..c34a530f 100644 --- a/lib/WorkflowMain.groovy +++ b/lib/WorkflowMain.groovy @@ -62,6 +62,9 @@ class WorkflowMain { // Print parameter summary log to screen log.info paramsSummaryLog(workflow, params, log) + // Check that a -profile or Nextflow config has been provided to run the pipeline + NfcoreTemplate.checkConfigProvided(workflow, log) + // Check that conda channels are set-up correctly if (params.enable_conda) { Utils.checkCondaChannels(log) @@ -70,9 +73,6 @@ class WorkflowMain { // Check AWS batch settings NfcoreTemplate.awsBatch(workflow, params) - // Check the hostnames against configured profiles - NfcoreTemplate.hostName(workflow, params, log) - // Check input has been provided if (!params.input) { log.error "Please provide an input samplesheet to the pipeline e.g. '--input samplesheet.tsv'" diff --git a/lib/WorkflowMhcquant.groovy b/lib/WorkflowMhcquant.groovy index b9450083..10d5fc98 100644 --- a/lib/WorkflowMhcquant.groovy +++ b/lib/WorkflowMhcquant.groovy @@ -34,46 +34,79 @@ class WorkflowMhcquant { if (params.quantification_fdr) { enabledFDRWarn(log) } - } + // Allele sheet + if ( ( params.predict_class_1 || params.predict_class_2 ) && !params.allele_sheet) { + // If no allele sheet is provided + noAllelesError(log) + System.exit(1) + } + + if ( params.include_proteins_from_vcf && !params.vcf_sheet) { + // If no vcf sheet is provided + noVcfError(log) + System.exit(1) + } + } // // Print a warning when the output directory is undefined // private static void outdirWarn(log) { - log.warn "=============================================================================\n" + + log.warn "======================================================================================================\n" + " Results into \'./results\'.\n" + " If you want to define a result directory, please use the --outdir option" + - "=============================================================================" + "======================================================================================================" } // // Print a warning when the parameter skip_decoy_generation is used // private static void skipDecoyWarn(log) { - log.warn "=============================================================================\n" + + log.warn "================================================================================================\n" + " Be aware: skipping decoy generation will prevent generating variants and subset FDR refinement\n" + " Decoys have to be named with DECOY_ as prefix in your fasta database\n" + - "===================================================================================" + "======================================================================================================" } // // Print a warning when the parameter skip_decoy_generation is used // private static void klammerConflictWarn(log) { - log.warn "=============================================================================\n" + + log.warn "================================================================================================\n" + " Quantification FDR enabled\n" + - "===================================================================================" + "======================================================================================================" } // // Print a warning when the parameter skip_decoy_generation is used // private static void enabledFDRWarn(log) { - log.warn "=============================================================================\n" + - " Klammer was specified, but description of correct features was still 0. Please provide a description of correct features greater than 0.\n" + + log.warn "================================================================================================\n" + + " Klammer was specified, but description of correct features was still 0\n."+ + " Please provide a description of correct features greater than 0.\n" + " Klammer has been turned off!\n" + - "===================================================================================" + "======================================================================================================" + } + + // + // Print an error when the no allele_sheet is provided + // + private static void noAllelesError(log) { + log.error "======================================================================================================\n" + + " --predict_class_1 or --predict_class_2 was used but no allele sheet has been provided. \n" + + " Make sure you have used the '--allele_sheet' option and include an allele sheet.\n" + + "======================================================================================================" + } + + // + // Print an error when there is no vcf_sheet provided + // + private static void noVcfError(log) { + log.error "======================================================================================================\n" + + " --include_proteins_from_vcf was used but no vcf sheet has been provided. \n" + + " Make sure you have used the '--vcf_sheet' option and include an vcf sheet.\n" + + "======================================================================================================" } // diff --git a/modules.json b/modules.json index 554d418c..1d7e0f6a 100644 --- a/modules.json +++ b/modules.json @@ -4,11 +4,11 @@ "repos": { "nf-core/modules": { "custom/dumpsoftwareversions": { - "git_sha": "3aacd46da2b221ed47aaa05c413a828538d2c2ae" + "git_sha": "20d8250d9f39ddb05dfb437603aaf99b5c0b2b41" }, "multiqc": { - "git_sha": "3aacd46da2b221ed47aaa05c413a828538d2c2ae" + "git_sha": "20d8250d9f39ddb05dfb437603aaf99b5c0b2b41" } } } -} +} \ No newline at end of file diff --git a/modules/local/functions.nf b/modules/local/functions.nf deleted file mode 100644 index 2405335a..00000000 --- a/modules/local/functions.nf +++ /dev/null @@ -1,84 +0,0 @@ -// -// Utility functions used in nf-core DSL2 module files -// - -// -// Extract name of software tool from process name using $task.process -// -def getSoftwareName(task_process) { - return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() -} - -// -// 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" - } -} -/* - * Function to check the file extension - */ -def hasExtension(it, extension) { - it.toString().toLowerCase().endsWith(extension.toLowerCase()) -} diff --git a/modules/local/generate_proteins_from_vcf.nf b/modules/local/generate_proteins_from_vcf.nf index 2be51a72..2d86d99b 100644 --- a/modules/local/generate_proteins_from_vcf.nf +++ b/modules/local/generate_proteins_from_vcf.nf @@ -1,42 +1,31 @@ -// Import generic module functions -include { initOptions; saveFiles } from './functions' - -params.options = [:] -options = initOptions(params.options) - process GENERATE_PROTEINS_FROM_VCF { tag "$meta" label 'process_medium' - publishDir "${params.outdir}", - mode: params.publish_dir_mode, - saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'.', publish_id:meta.id) } - - 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" - } + conda (params.enable_conda ? "bioconda::fred2=2.0.7 bioconda::mhcflurry=1.4.3 bioconda::mhcnuggets=2.3.2" : null) + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' : + 'quay.io/biocontainers/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' }" input: tuple val(meta), path(fasta), path(vcf) output: tuple val(meta), path("*.fasta"), emit: vcf_fasta - path "*.version.txt" , emit: version + path "versions.yml" , emit: versions script: - def prefix = options.suffix ? "${fasta.baseName}_${options.suffix}" : "${fasta.baseName}_added_vcf" + def prefix = task.ext.prefix ?: "${fasta.baseName}_added_vcf" + def args = task.ext.args ?: '' """ variants2fasta.py -v $vcf \\ -f $fasta \\ - -o $meta.sample_${prefix}.fasta \\ - $options.args + -o ${meta.sample}_${prefix}.fasta \\ + $args cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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/ .*\$//') ) diff --git a/modules/local/get_software_versions.nf b/modules/local/get_software_versions.nf deleted file mode 100644 index 647ea324..00000000 --- a/modules/local/get_software_versions.nf +++ /dev/null @@ -1,34 +0,0 @@ -// Import generic module functions -include { saveFiles } from './functions' - -params.options = [:] -options = initOptions(params.options) - -process GET_SOFTWARE_VERSIONS { - publishDir "${params.outdir}", - mode: params.publish_dir_mode, - 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) { - container "https://depot.galaxyproject.org/singularity/python:3.8.3" - } else { - container "quay.io/biocontainers/python:3.8.3" - } - - cache false - - input: - path versions - - output: - path "software_versions.tsv" , emit: tsv - path 'software_versions_mqc.yaml', emit: yaml - - 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/mhcflurry_predictneoepitopesclass1.nf b/modules/local/mhcflurry_predictneoepitopesclass1.nf index 37c938cc..08e64aba 100644 --- a/modules/local/mhcflurry_predictneoepitopesclass1.nf +++ b/modules/local/mhcflurry_predictneoepitopesclass1.nf @@ -1,24 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process MHCFLURRY_PREDICTNEOEPITOPESCLASS1 { tag "$meta" label 'process_low' - publishDir "${params.outdir}", - 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" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/mhcflurry:1.4.3--py_0" - } else { - container "quay.io/biocontainers/mhcflurry:1.4.3--py_0" - } - + conda (params.enable_conda ? "bioconda::fred2=2.0.7 bioconda::mhcflurry=1.4.3 bioconda::mhcnuggets=2.3.2" : null) + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' : + 'quay.io/biocontainers/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' }" input: tuple val(meta), val(allotypes), path(neoepitopes) @@ -28,14 +15,14 @@ process MHCFLURRY_PREDICTNEOEPITOPESCLASS1 { path "versions.yml" , emit: versions script: - def prefix = options.suffix ? "${neoepitopes}_${meta}_${options.suffix}" : "${neoepitopes}_${meta}_predicted_neoepitopes_class_1" + def prefix = task.ext.suffix ?: "${neoepitopes}_${meta}_predicted_neoepitopes_class_1" """ mhcflurry-downloads --quiet fetch models_class1 mhcflurry_neoepitope_binding_prediction.py '$allotypes' ${prefix}.csv cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${task.process}": mhcflurry: \$(echo \$(mhcflurry-predict --version 2>&1 | sed 's/^mhcflurry //; s/ .*\$//') ) END_VERSIONS """ diff --git a/modules/local/mhcflurry_predictpeptidesclass1.nf b/modules/local/mhcflurry_predictpeptidesclass1.nf index a5509ed0..93e9ab79 100644 --- a/modules/local/mhcflurry_predictpeptidesclass1.nf +++ b/modules/local/mhcflurry_predictpeptidesclass1.nf @@ -1,23 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process MHCFLURRY_PREDICTPEPTIDESCLASS1 { tag "$meta" label 'process_low' - publishDir "${params.outdir}", - 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::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" - } + conda (params.enable_conda ? "bioconda::fred2=2.0.7 bioconda::mhcflurry=1.4.3 bioconda::mhcnuggets=2.3.2" : null) + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' : + 'quay.io/biocontainers/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' }" input: tuple val(meta), path(mztab), val(alleles) @@ -27,14 +15,14 @@ process MHCFLURRY_PREDICTPEPTIDESCLASS1 { path "versions.yml" , emit: versions script: - def prefix = options.suffix ? "${meta.id}_${options.suffix}" : "${meta.id}_predicted_peptides_class_1" + def prefix = task.ext.suffix ?: "${meta.id}_predicted_peptides_class_1" """ mhcflurry-downloads --quiet fetch models_class1 mhcflurry_predict_mztab.py '$alleles' $mztab ${prefix}.csv cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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/ .*\$//')) diff --git a/modules/local/mhcflurry_predictpsms.nf b/modules/local/mhcflurry_predictpsms.nf index 469b061b..8065590f 100644 --- a/modules/local/mhcflurry_predictpsms.nf +++ b/modules/local/mhcflurry_predictpsms.nf @@ -1,23 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process MHCFLURRY_PREDICTPSMS { tag "$meta" 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::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" - } + conda (params.enable_conda ? "bioconda::fred2=2.0.7 bioconda::mhcflurry=1.4.3 bioconda::mhcnuggets=2.3.2" : null) + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' : + 'quay.io/biocontainers/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' }" input: tuple val(meta), path(perc_mztab), path(psm_mztab), val(allotypes) @@ -27,14 +15,14 @@ process MHCFLURRY_PREDICTPSMS { path "versions.yml" , emit: versions script: - def prefix = options.suffix ? "${meta.id}_${options.suffix}" : "${meta.id}_peptide_filter" + def prefix = task.ext.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 cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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/ .*\$//')) diff --git a/modules/local/mhcnuggets_neoepitopesclass2post.nf b/modules/local/mhcnuggets_neoepitopesclass2post.nf index 90eeead8..92760a25 100644 --- a/modules/local/mhcnuggets_neoepitopesclass2post.nf +++ b/modules/local/mhcnuggets_neoepitopesclass2post.nf @@ -1,24 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process MHCNUGGETS_NEOEPITOPESCLASS2POST { 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" - } - + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/mhcnuggets:2.3.2--py_0' : + 'quay.io/biocontainers/mhcnuggets:2.3.2--py_0' }" input: tuple val(meta), path(neoepitopes), path(predicted) @@ -33,7 +20,7 @@ process MHCNUGGETS_NEOEPITOPESCLASS2POST { postprocess_neoepitopes_mhcnuggets.py --input $predicted --neoepitopes $neoepitopes cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 index 98d0f503..3f466f27 100644 --- a/modules/local/mhcnuggets_neoepitopesclass2pre.nf +++ b/modules/local/mhcnuggets_neoepitopesclass2pre.nf @@ -1,39 +1,29 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - -process MHCNUGGETS_NEOEPITOPESCLASS2RE { +process MHCNUGGETS_NEOEPITOPESCLASS2PRE { 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" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/mhcnuggets:2.3.2--py_0' : + '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 + tuple val(meta), path("*.csv") , emit: preprocessed + path "versions.yml" , emit: versions script: - def prefix = options.suffix ? "${meta}_${options.suffix}" : "${meta}_mhcnuggets_preprocessed" + def prefix = task.ext.prefix ?: "${meta}_mhcnuggets_preprocessed" """ - preprocess_neoepitopes_mhcnuggets.py --neoepitopes $neoepitopes --output ${prefix} + preprocess_neoepitopes_mhcnuggets.py \\ + --neoepitopes $neoepitopes \\ + --output ${prefix}.csv cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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_peptidesclass2post.nf b/modules/local/mhcnuggets_peptidesclass2post.nf index 0af8cb0f..48f901b7 100644 --- a/modules/local/mhcnuggets_peptidesclass2post.nf +++ b/modules/local/mhcnuggets_peptidesclass2post.nf @@ -1,23 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process MHCNUGGETS_PEPTIDESCLASS2POST { 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" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/mhcnuggets:2.3.2--py_0' : + 'quay.io/biocontainers/mhcnuggets:2.3.2--py_0' }" input: tuple val(meta), path(peptides), path(peptide_to_geneID) @@ -27,7 +15,7 @@ process MHCNUGGETS_PEPTIDESCLASS2POST { path "versions.yml" , emit: versions script: - def prefix = options.suffix ? "${meta.sample}_${options.suffix}" : "${meta.sample}_postprocessed" + def prefix = task.ext.prefix ?: "${meta.sample}_postprocessed" """ postprocess_peptides_mhcnuggets.py --input $peptides \\ @@ -35,7 +23,7 @@ process MHCNUGGETS_PEPTIDESCLASS2POST { --output ${prefix}.csv cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 index 665749e9..d2ad8c60 100644 --- a/modules/local/mhcnuggets_peptidesclass2pre.nf +++ b/modules/local/mhcnuggets_peptidesclass2pre.nf @@ -1,23 +1,11 @@ -// 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" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/mhcnuggets:2.3.2--py_0' : + 'quay.io/biocontainers/mhcnuggets:2.3.2--py_0' }" input: tuple val(meta), path(mztab) @@ -28,14 +16,14 @@ process MHCNUGGETS_PEPTIDESCLASS2PRE { path "versions.yml" , emit: versions script: - def prefix = options.suffix ? "${meta.sample}_${options.suffix}_peptides" : "${meta.sample}_preprocessed_mhcnuggets_peptides" + def prefix = task.ext.prefix ?: "${meta.sample}_preprocessed_mhcnuggets_peptides" """ preprocess_peptides_mhcnuggets.py --mztab $mztab \\ --output ${prefix} cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 index 446ee885..263fffa9 100644 --- a/modules/local/mhcnuggets_predictneoepitopesclass2.nf +++ b/modules/local/mhcnuggets_predictneoepitopesclass2.nf @@ -1,41 +1,29 @@ -// 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" - } + conda (params.enable_conda ? "bioconda::fred2=2.0.7 bioconda::mhcflurry=1.4.3 bioconda::mhcnuggets=2.3.2" : null) + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' : + 'quay.io/biocontainers/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' }" input: tuple val(meta), path(neoepitopes), val(alleles) output: - tuple val(meta), path("*${prefix}"), emit: csv - path "versions.yml" , emit: versions + tuple val(meta), path("*.csv"), emit: csv + path "versions.yml" , emit: versions script: - def prefix = options.suffix ? "${meta}_${options.suffix}" : "${meta}_predicted_neoepitopes_class_2" + def prefix = task.ext.prefix ?: "${meta}_predicted_neoepitopes_class_2" """ mhcnuggets_predict_peptides.py --peptides $neoepitopes \\ --alleles '$alleles' \\ - --output ${prefix} + --output ${prefix}.csv cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 index f85c8208..2481d379 100644 --- a/modules/local/mhcnuggets_predictpeptidesclass2.nf +++ b/modules/local/mhcnuggets_predictpeptidesclass2.nf @@ -1,23 +1,11 @@ -// 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" - } + conda (params.enable_conda ? "bioconda::fred2=2.0.7 bioconda::mhcflurry=1.4.3 bioconda::mhcnuggets=2.3.2" : null) + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' : + 'quay.io/biocontainers/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' }" input: tuple val(meta), path(peptides), val(alleles) @@ -27,7 +15,7 @@ process MHCNUGGETS_PREDICTPEPTIDESCLASS2 { path "versions.yml" , emit: versions script: - def prefix = options.suffix ? "${meta.sample}_${options.suffix}_class_2" : "${meta.sample}_predicted_peptides_class_2" + def prefix = task.ext.prefix ?: "${meta.sample}_predicted_peptides_class_2" """ mhcnuggets_predict_peptides.py --peptides $peptides \\ @@ -35,7 +23,7 @@ process MHCNUGGETS_PREDICTPEPTIDESCLASS2 { --output ${prefix} cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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/ .*\$//')) diff --git a/modules/local/openms_cometadapter.nf b/modules/local/openms_cometadapter.nf index ad49aa2b..7f43043d 100644 --- a/modules/local/openms_cometadapter.nf +++ b/modules/local/openms_cometadapter.nf @@ -1,19 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_COMETADAPTER { tag "$meta.id" label 'process_high' 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.6.0--0" - } else { - container "quay.io/biocontainers/openms-thirdparty:2.6.0--0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms-thirdparty:2.6.0--0' : + 'quay.io/biocontainers/openms-thirdparty:2.6.0--0' }" input: tuple val(meta), path(mzml), path(fasta) @@ -23,18 +15,33 @@ process OPENMS_COMETADAPTER { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${mzml.baseName}_${options.suffix}" : "${mzml.baseName}" + def prefix = task.ext.prefix ?: "${mzml.baseName}" + def args = task.ext.args ?: '' + + def mods = params.fixed_mods != " " ? "-fixed_modifications ${params.fixed_mods.tokenize(',').collect { "'${it}'"}.join(" ")}" : "" + def xions = params.use_x_ions ? "-use_X_ions true" : "" + def zions = params.use_z_ions ? "-use_Z_ions true" : "" + def aions = params.use_a_ions ? "-use_A_ions true" : "" + def cions = params.use_c_ions ? "-use_C_ions true" : "" + def nlions = params.use_NL_ions ? "-use_NL_ions true" : "" + def remove_precursor = params.remove_precursor_peak ? "-remove_precursor_peak yes" : "" """ CometAdapter -in $mzml \\ -out ${prefix}.idXML \\ -database $fasta \\ -threads $task.cpus \\ - $options.args + $args \\ + $mods \\ + $xions \\ + $zions \\ + $aions \\ + $cions \\ + $nlions \\ + $remove_precursor cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 2f9ebc4a..7b74286c 100644 --- a/modules/local/openms_decoydatabase.nf +++ b/modules/local/openms_decoydatabase.nf @@ -1,19 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_DECOYDATABASE { tag "$meta.id" label 'process_medium' 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.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(fasta) @@ -23,8 +15,7 @@ process OPENMS_DECOYDATABASE { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${fasta.baseName}_${options.suffix}" : "${fasta.baseName}_decoy" + def prefix = task.ext.prefix ?: "${fasta.baseName}_decoy" """ DecoyDatabase -in $fasta \\ @@ -33,7 +24,7 @@ process OPENMS_DECOYDATABASE { -decoy_string_position prefix cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 c25d7058..3e934bd0 100644 --- a/modules/local/openms_falsediscoveryrate.nf +++ b/modules/local/openms_falsediscoveryrate.nf @@ -1,19 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_FALSEDISCOVERYRATE { tag "$meta.id" label 'process_low' 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.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(idxml) @@ -23,8 +15,7 @@ process OPENMS_FALSEDISCOVERYRATE { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${idxml.baseName}_${options.suffix}" : "${idxml.baseName}_fdr" + def prefix = task.ext.prefix ?: "${idxml.baseName}_fdr" """ FalseDiscoveryRate -in $idxml \\ @@ -33,7 +24,7 @@ process OPENMS_FALSEDISCOVERYRATE { -threads $task.cpus cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 eacb21a3..02211102 100644 --- a/modules/local/openms_featurefinderidentification.nf +++ b/modules/local/openms_featurefinderidentification.nf @@ -1,23 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_FEATUREFINDERIDENTIFICATION { tag "$meta.id" 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.6.0" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(id_quant_int), path(mzml), path(id_quant) @@ -27,24 +15,17 @@ process OPENMS_FEATUREFINDERIDENTIFICATION { 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" - } else { - arguments = "-id $id_quant_int -id_ext $id_quant -svm:min_prob ${params.quantification_min_prob}" - } + def prefix = task.ext.prefix ?: "${meta.sample}_${meta.id}" + def arguments = params.quantification_fdr ? "-id $id_quant_int -id_ext $id_quant -svm:min_prob ${params.quantification_min_prob}" : "-id $id_quant" """ FeatureFinderIdentification -in $mzml \\ -out ${prefix}.featureXML \\ -threads $task.cpus \\ - ${arguments} \\ - $options.args + ${arguments} cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 ad8db0ba..61276b64 100644 --- a/modules/local/openms_featurelinkerunlabeledkd.nf +++ b/modules/local/openms_featurelinkerunlabeledkd.nf @@ -1,23 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_FEATURELINKERUNLABELEDKD { tag "$meta.id" label 'process_low' - 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-thirdparty=2.6.0" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms-thirdparty:2.6.0--0" - } else { - container "quay.io/biocontainers/openms-thirdparty:2.6.0--0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms-thirdparty:2.6.0--0' : + 'quay.io/biocontainers/openms-thirdparty:2.6.0--0' }" input: tuple val(meta), path(features) @@ -27,8 +15,7 @@ process OPENMS_FEATURELINKERUNLABELEDKD { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${meta.id}_${options.suffix}" : "${meta.id}_all_features_merged" + def prefix = task.ext.prefix ?: "${meta.id}_all_features_merged" """ FeatureLinkerUnlabeledKD -in $features \\ @@ -36,7 +23,7 @@ process OPENMS_FEATURELINKERUNLABELEDKD { -threads $task.cpus cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 5053c53b..2bf8f16d 100644 --- a/modules/local/openms_idconflictresolver.nf +++ b/modules/local/openms_idconflictresolver.nf @@ -1,19 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_IDCONFLICTRESOLVER { tag "$meta.id" label 'process_low' 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.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(consensus) @@ -23,8 +15,7 @@ process OPENMS_IDCONFLICTRESOLVER { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${meta.id}_${options.suffix}" : "${meta.id}_resolved" + def prefix = task.ext.prefix ?: "${meta.id}_resolved" """ IDConflictResolver -in $consensus \\ @@ -32,7 +23,7 @@ process OPENMS_IDCONFLICTRESOLVER { -threads $task.cpus cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 b59321a0..2908b7d7 100644 --- a/modules/local/openms_idfilter.nf +++ b/modules/local/openms_idfilter.nf @@ -1,23 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_IDFILTER { tag "$meta.id" 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.6.0" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(idxml), file(peptide_filter) @@ -27,9 +15,9 @@ process OPENMS_IDFILTER { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def whitelist = "$peptide_filter" - def prefix = options.suffix ? "${idxml.baseName}_${options.suffix}" : "${meta.id}_-_idx_fdr_filtered" + def whitelist = "$peptide_filter" + def prefix = task.ext.prefix ?: "${meta.id}_-_${idxml.baseName}_filtered" + def args = task.ext.args ?: '' if (whitelist == "input.2") { whitelist = " " @@ -39,11 +27,11 @@ process OPENMS_IDFILTER { IDFilter -in $idxml \\ -out ${prefix}.idXML \\ -threads $task.cpus \\ - $options.args \\ + $args \\ $whitelist cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 289d250b..623b11a0 100644 --- a/modules/local/openms_idmerger.nf +++ b/modules/local/openms_idmerger.nf @@ -1,19 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_IDMERGER { tag "$meta.id" label 'process_low' 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.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(aligned) @@ -23,8 +15,7 @@ process OPENMS_IDMERGER { 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" + def prefix = task.ext.prefix ?: "${meta.sample}_${meta.condition}_all_ids_merged" """ IDMerger -in $aligned \\ @@ -34,7 +25,7 @@ process OPENMS_IDMERGER { -merge_proteins_add_PSMs cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 80ac9ba3..d9ece728 100644 --- a/modules/local/openms_mapaligneridentification.nf +++ b/modules/local/openms_mapaligneridentification.nf @@ -1,19 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_MAPALIGNERIDENTIFICATION { tag "$meta.id" label 'process_low' 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.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(idxml) @@ -23,16 +15,16 @@ process OPENMS_MAPALIGNERIDENTIFICATION { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def out_names = idxml.collect { it.baseName+'.trafoXML' }.join(' ') + def out_names = idxml.collect { it.baseName+'.trafoXML' }.join(' ') + def args = task.ext.args ?: '' """ MapAlignerIdentification -in $idxml \\ -trafo_out ${out_names} \\ - $options.args + $args cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 171bc744..618e72b2 100644 --- a/modules/local/openms_maprttransformer.nf +++ b/modules/local/openms_maprttransformer.nf @@ -1,19 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_MAPRTTRANSFORMER { tag "$meta.id" label 'process_low' 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.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(alignment_file), path(trafoxml) @@ -23,17 +15,17 @@ process OPENMS_MAPRTTRANSFORMER { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def fileExt = alignment_file.collect { it.name.tokenize("\\.")[1] }.join(' ') + def prefix = task.ext.prefix ?: "${meta.id}_aligned" + def fileExt = alignment_file.collect { it.name.tokenize("\\.")[1] }.join(' ') """ MapRTTransformer -in $alignment_file \\ -trafo_in $trafoxml \\ - -out ${meta.id}_aligned.${fileExt} \\ + -out ${prefix}.${fileExt} \\ -threads $task.cpus cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 bfdcece6..a24fd829 100644 --- a/modules/local/openms_mztabexporter.nf +++ b/modules/local/openms_mztabexporter.nf @@ -1,23 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_MZTABEXPORTER { tag "$meta.id" label 'process_low' - 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.6.0" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(mztab) @@ -27,16 +15,17 @@ process OPENMS_MZTABEXPORTER { 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}" + def prefix = task.ext.prefix ?: "${meta.sample}_${meta.condition}" + def args = task.ext.args ?: '' """ MzTabExporter -in $mztab \\ -out ${prefix}.mzTab \\ - -threads $task.cpus + -threads $task.cpus \\ + $args cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 76718e40..5441b2cd 100644 --- a/modules/local/openms_peakpickerhires.nf +++ b/modules/local/openms_peakpickerhires.nf @@ -1,19 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_PEAKPICKERHIRES { tag "$meta.id" label 'process_medium' 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.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(mzml) @@ -23,8 +15,7 @@ process OPENMS_PEAKPICKERHIRES { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${mzml.baseName}_${options.suffix}" : "${mzml.baseName}" + def prefix = task.ext.prefix ?: "${mzml.baseName}" """ PeakPickerHiRes -in $mzml \\ @@ -32,7 +23,7 @@ process OPENMS_PEAKPICKERHIRES { -algorithm:ms_levels ${params.pick_ms_levels} cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 935bfa23..7d850dca 100644 --- a/modules/local/openms_peptideindexer.nf +++ b/modules/local/openms_peptideindexer.nf @@ -1,19 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_PEPTIDEINDEXER { tag "$meta.id" label 'process_low' 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.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(idxml), path(fasta) @@ -23,8 +15,7 @@ process OPENMS_PEPTIDEINDEXER { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${idxml.baseName}_${options.suffix}" : "${idxml.baseName}_idx" + def prefix = task.ext.prefix ?: "${idxml.baseName}_-_idx" """ PeptideIndexer -in $idxml \\ @@ -35,7 +26,7 @@ process OPENMS_PEPTIDEINDEXER { -enzyme:specificity none cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 e9a07e5c..01538745 100644 --- a/modules/local/openms_percolatoradapter.nf +++ b/modules/local/openms_percolatoradapter.nf @@ -1,23 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_PERCOLATORADAPTER { tag "$meta.id" label 'process_high' - 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-thirdparty=2.6.0" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms-thirdparty:2.6.0--0" - } else { - container "quay.io/biocontainers/openms-thirdparty:2.6.0--0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms-thirdparty:2.6.0--0' : + 'quay.io/biocontainers/openms-thirdparty:2.6.0--0' }" input: tuple val(meta), path(psm) @@ -27,17 +15,19 @@ process OPENMS_PERCOLATORADAPTER { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${meta.id}_${options.suffix}" : "${meta.id}" + def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' + def klammer = (params.description_correct_features > 0 && params.klammer) ? "-klammer" : "" """ OMP_NUM_THREADS=$task.cpus \\ PercolatorAdapter -in $psm \\ -out ${prefix}.idXML \\ - $options.args + $klammer \\ + $args cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 bc8fc3e3..e6272f70 100644 --- a/modules/local/openms_psmfeatureextractor.nf +++ b/modules/local/openms_psmfeatureextractor.nf @@ -1,23 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_PSMFEATUREEXTRACTOR { tag "$meta.id" label 'process_low' - 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.6.0" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(merged) @@ -27,16 +15,17 @@ process OPENMS_PSMFEATUREEXTRACTOR { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${merged.baseName}_${options.suffix}" : "${merged.baseName}_psm" + def prefix = task.ext.prefix ?: "${merged.baseName}_psm" + def args = task.ext.args ?: '' """ PSMFeatureExtractor -in $merged \\ -out ${prefix}.idXML \\ - -threads $task.cpus + -threads $task.cpus \\ + $args cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 79687b59..c16c2f0f 100644 --- a/modules/local/openms_rtmodel.nf +++ b/modules/local/openms_rtmodel.nf @@ -1,19 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_RTMODEL { tag "$meta.id" label 'process_medium' 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.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(rt_training) @@ -23,8 +15,7 @@ process OPENMS_RTMODEL { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${meta.sample}_${options.suffix}" : "${meta.sample}" + def prefix = task.ext.prefix ?: "${meta.sample}" """ RTModel -in $rt_training \\ @@ -34,7 +25,7 @@ process OPENMS_RTMODEL { -out_oligo_trainset ${prefix}_trainset.txt cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 31f95c9f..481905b7 100644 --- a/modules/local/openms_rtpredict.nf +++ b/modules/local/openms_rtpredict.nf @@ -1,23 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_RTPREDICT { tag "$meta.id" label 'process_low' - publishDir "${params.outdir}", - 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.6.0" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { - container "https://depot.galaxyproject.org/singularity/openms-thirdparty:2.6.0--0" - } else { - container "quay.io/biocontainers/openms-thirdparty:2.6.0--0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms-thirdparty:2.6.0--0' : + 'quay.io/biocontainers/openms-thirdparty:2.6.0--0' }" input: tuple val(meta), path(idxml), path(rt_model), path(rt_params), path(trainset) @@ -27,8 +15,7 @@ process OPENMS_RTPREDICT { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${meta.sample}_${options.suffix}" : "${meta.sample}_RTpredicted" + def prefix = task.ext.prefix ?: "${meta.sample}_RTpredicted" """ RTPredict -in_id $idxml \\ @@ -38,7 +25,7 @@ process OPENMS_RTPREDICT { -out_text:file ${prefix}.csv cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 075dc1d5..3d771255 100644 --- a/modules/local/openms_textexporter.nf +++ b/modules/local/openms_textexporter.nf @@ -1,23 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_TEXTEXPORTER { tag "$meta.id" label 'process_low' - publishDir "${params.outdir}", - mode: params.publish_dir_mode, - saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'.', publish_id:'') } - 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.6.0--h4afb90d_0" - } else { - container "quay.io/biocontainers/openms:2.6.0--h4afb90d_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/openms:2.6.0--h4afb90d_0' : + 'quay.io/biocontainers/openms:2.6.0--h4afb90d_0' }" input: tuple val(meta), path(consensus_resolved) @@ -27,19 +15,19 @@ process OPENMS_TEXTEXPORTER { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${meta.id}_${options.suffix}" : "${meta.id}" + def prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: '' """ TextExporter -in $consensus_resolved \\ -out ${prefix}.tsv \\ -threads $task.cpus \\ -id:add_hit_metavalues 0 \\ - -id:add_metavalues 0 \\ - -id:peptides_only + -id:peptides_only \\ + $args cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${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 166cde7e..b2541369 100644 --- a/modules/local/openms_thermorawfileparser.nf +++ b/modules/local/openms_thermorawfileparser.nf @@ -1,19 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process OPENMS_THERMORAWFILEPARSER { tag "$meta.id" label 'process_medium' 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.3.4--ha8f3691_0" - } else { - container "quay.io/biocontainers/thermorawfileparser:1.3.4--ha8f3691_0" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/thermorawfileparser:1.3.4--ha8f3691_0' : + 'quay.io/biocontainers/thermorawfileparser:1.3.4--ha8f3691_0' }" input: tuple val(meta), path(rawfile) @@ -23,15 +15,16 @@ process OPENMS_THERMORAWFILEPARSER { path "versions.yml" , emit: versions script: - def software = getSoftwareName(task.process) - def prefix = options.suffix ? "${rawfile.baseName}_${options.suffix}" : "${rawfile.baseName}" + def prefix = task.ext.prefix ?: "${rawfile.baseName}" """ - ThermoRawFileParser.sh -i=$rawfile \\ - -f=2 \\ - -b=${prefix}.mzML + ThermoRawFileParser.sh \\ + -i $rawfile \\ + -f 2 \\ + -b ${prefix}.mzML + cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + "${task.process}": thermorawfileparser: \$(ThermoRawFileParser.sh --version) END_VERSIONS """ diff --git a/modules/local/predict_possible_class_2_neoepitopes.nf b/modules/local/predict_possible_class_2_neoepitopes.nf deleted file mode 100644 index 11162f1c..00000000 --- a/modules/local/predict_possible_class_2_neoepitopes.nf +++ /dev/null @@ -1,49 +0,0 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - -process PREDICT_POSSIBLE_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:'') } - - 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), val(alleles), path(vcf) - - output: - tuple val(meta), path("*.csv") , emit: csv - tuple val(meta), path("${prefix}.txt"), emit: txt - 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 - - 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 e775e982..c4192643 100644 --- a/modules/local/predict_possible_neoepitopes.nf +++ b/modules/local/predict_possible_neoepitopes.nf @@ -1,46 +1,35 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process PREDICT_POSSIBLE_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:'') } - - 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" - } + conda (params.enable_conda ? "bioconda::fred2=2.0.7 bioconda::mhcflurry=1.4.3 bioconda::mhcnuggets=2.3.2" : null) + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' : + 'quay.io/biocontainers/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' }" input: tuple val(meta), val(alleles), path(vcf) output: - tuple val(meta), path("${prefix}.csv"), emit: csv - tuple val(meta), path("${prefix}.txt"), emit: txt - path "versions.yml" , emit: versions + tuple val(meta), path("*.csv"), emit: csv + tuple val(meta), path("*.txt"), emit: txt + path "versions.yml" , emit: versions script: - def prefix = options.suffix ? "${meta}_${options.suffix}" : "${meta}_vcf_neoepitopes_class1" + def prefix = task.ext.prefix ?: "${meta}_vcf_neoepitopes" """ vcf_neoepitope_predictor.py \\ -t ${params.variant_annotation_style} \\ -r ${params.variant_reference} \\ - -a '$alleles' -minl ${params.peptide_min_length} \\ + -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)}: + "${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/ .*\$//')) diff --git a/modules/local/resolve_found_class_2_neoepitopes.nf b/modules/local/resolve_found_class_2_neoepitopes.nf deleted file mode 100644 index 80fd21c5..00000000 --- a/modules/local/resolve_found_class_2_neoepitopes.nf +++ /dev/null @@ -1,47 +0,0 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - -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:'class_2_bindings', publish_id:'class_2_bindings') } - - echo true - - 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(mztab), path(neoepitopes) - - output: - tuple val(meta), path("*.csv"), emit: csv - 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} - - 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 ece53e31..ce5bb7f4 100644 --- a/modules/local/resolve_found_neoepitopes.nf +++ b/modules/local/resolve_found_neoepitopes.nf @@ -1,23 +1,11 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process RESOLVE_FOUND_NEOEPITOPES { tag "$meta" label 'process_low' - publishDir "${params.outdir}", - 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::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" - } + conda (params.enable_conda ? "bioconda::fred2=2.0.7 bioconda::mhcflurry=1.4.3 bioconda::mhcnuggets=2.3.2" : null) + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' : + 'quay.io/biocontainers/mulled-v2-c3f301504f7fa2e7bf81c3783de19a9990ea3001:12b1b9f040fd92a80629d58f8a558dde4820eb15-0' }" input: tuple val(meta), path(mztab), path(neoepitopes) @@ -27,7 +15,7 @@ process RESOLVE_FOUND_NEOEPITOPES { path "versions.yml" , emit: versions script: - def prefix = options.suffix ? "${meta}_${options.suffix}" : "${meta}_found_neoepitopes_class_1" + def prefix = task.ext.prefix ?: "${meta}_found_neoepitopes" """ resolve_neoepitopes.py -n $neoepitopes \\ @@ -36,7 +24,7 @@ process RESOLVE_FOUND_NEOEPITOPES { -o ${prefix} cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: + ${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/ .*\$//')) diff --git a/modules/local/samplesheet_check.nf b/modules/local/samplesheet_check.nf index 15a9665a..9fe13398 100644 --- a/modules/local/samplesheet_check.nf +++ b/modules/local/samplesheet_check.nf @@ -1,28 +1,17 @@ -// Import generic module functions -include { initOptions; saveFiles; getSoftwareName; getProcessName } from './functions' - -params.options = [:] -options = initOptions(params.options) - process SAMPLESHEET_CHECK { tag "$samplesheet" - publishDir "${params.outdir}", - mode: params.publish_dir_mode, - saveAs: { filename -> saveFiles(filename:filename, options:params.options, publish_dir:'pipeline_info', meta:[:], publish_by_meta:[]) } 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" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/python:3.8.3' : + 'quay.io/biocontainers/python:3.8.3' }" input: - path samplesheet + path samplesheet output: - path '*.csv' , emit: csv - path "versions.yml", emit: versions + path '*.csv' , emit: csv + path "versions.yml", emit: versions script: // This script is bundled with the pipeline, in nf-core/mhcquant/bin/ """ @@ -31,8 +20,8 @@ process SAMPLESHEET_CHECK { samplesheet.valid.csv cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: - python: \$(echo \$(python --version | sed 's/Python //g')) + "${task.process}": + python: \$(python --version | sed 's/Python //g') END_VERSIONS """ } diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/functions.nf b/modules/nf-core/modules/custom/dumpsoftwareversions/functions.nf deleted file mode 100644 index 85628ee0..00000000 --- a/modules/nf-core/modules/custom/dumpsoftwareversions/functions.nf +++ /dev/null @@ -1,78 +0,0 @@ -// -// Utility functions used in nf-core DSL2 module files -// - -// -// Extract name of software tool from process name using $task.process -// -def getSoftwareName(task_process) { - return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() -} - -// -// 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 index faf2073f..934bb467 100644 --- a/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf +++ b/modules/nf-core/modules/custom/dumpsoftwareversions/main.nf @@ -1,22 +1,11 @@ -// 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" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/multiqc:1.11--pyhdfd78af_0' : + 'quay.io/biocontainers/multiqc:1.11--pyhdfd78af_0' }" input: path versions @@ -27,80 +16,6 @@ process CUSTOM_DUMPSOFTWAREVERSIONS { 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) - """ + def args = task.ext.args ?: '' + template 'dumpsoftwareversions.py' } diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml b/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml index c8310e35..5b5b8a60 100644 --- a/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml +++ b/modules/nf-core/modules/custom/dumpsoftwareversions/meta.yml @@ -31,3 +31,4 @@ output: authors: - "@drpatelh" + - "@grst" diff --git a/modules/nf-core/modules/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py b/modules/nf-core/modules/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py new file mode 100644 index 00000000..d1390392 --- /dev/null +++ b/modules/nf-core/modules/custom/dumpsoftwareversions/templates/dumpsoftwareversions.py @@ -0,0 +1,89 @@ +#!/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) + + +versions_this_module = {} +versions_this_module["${task.process}"] = { + "python": platform.python_version(), + "yaml": yaml.__version__, +} + +with open("$versions") as f: + versions_by_process = yaml.load(f, Loader=yaml.BaseLoader) | versions_this_module + +# aggregate versions by the module name (derived from fully-qualified process name) +versions_by_module = {} +for process, process_versions in versions_by_process.items(): + module = process.split(":")[-1] + try: + assert versions_by_module[module] == process_versions, ( + "We assume that software versions are the same between all modules. " + "If you see this error-message it means you discovered an edge-case " + "and should open an issue in nf-core/tools. " + ) + except KeyError: + versions_by_module[module] = process_versions + +versions_by_module["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(versions_by_module), +} + +with open("software_versions.yml", "w") as f: + yaml.dump(versions_by_module, 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(versions_this_module, f, default_flow_style=False) diff --git a/modules/nf-core/modules/multiqc/functions.nf b/modules/nf-core/modules/multiqc/functions.nf deleted file mode 100644 index 85628ee0..00000000 --- a/modules/nf-core/modules/multiqc/functions.nf +++ /dev/null @@ -1,78 +0,0 @@ -// -// Utility functions used in nf-core DSL2 module files -// - -// -// Extract name of software tool from process name using $task.process -// -def getSoftwareName(task_process) { - return task_process.tokenize(':')[-1].tokenize('_')[0].toLowerCase() -} - -// -// 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 index 0861aa59..3dceb162 100644 --- a/modules/nf-core/modules/multiqc/main.nf +++ b/modules/nf-core/modules/multiqc/main.nf @@ -1,21 +1,10 @@ -// 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" - } + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/multiqc:1.11--pyhdfd78af_0' : + 'quay.io/biocontainers/multiqc:1.11--pyhdfd78af_0' }" input: path multiqc_files @@ -27,12 +16,13 @@ process MULTIQC { path "versions.yml" , emit: versions script: + def args = task.ext.args ?: '' """ - multiqc -f $options.args . + multiqc -f $args . cat <<-END_VERSIONS > versions.yml - ${getProcessName(task.process)}: - ${getSoftwareName(task.process)}: \$( multiqc --version | sed -e "s/multiqc, version //g" ) + "${task.process}": + multiqc: \$( multiqc --version | sed -e "s/multiqc, version //g" ) END_VERSIONS """ } diff --git a/nextflow.config b/nextflow.config index f895cfc9..9db0570e 100644 --- a/nextflow.config +++ b/nextflow.config @@ -10,102 +10,97 @@ 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" // References - genomes = null + genomes = null // Workflow options - allele_sheet = false - include_proteins_from_vcf = false - predict_class_1 = false - predict_class_2 = false + allele_sheet = null + include_proteins_from_vcf = false + predict_class_1 = false + predict_class_2 = false refine_fdr_on_predicted_subset = 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 + schema_ignore_params = 'genomes' + 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' + 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 = null + 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 = null // Boilerplate options - 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 + outdir = './results' + tracedir = "${params.outdir}/pipeline_info" + email = null + email_on_fail = null + plaintext_email = false + monochrome_logs = false + help = false + validate_params = true + show_hidden_params = false + enable_conda = false // Config options - 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 + custom_config_version = 'master' + custom_config_base = "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}" + 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' + max_memory = '128.GB' + max_cpus = 16 + max_time = '240.h' } // Load base.config by default for all pipelines @@ -180,10 +175,14 @@ profiles { } // Export these variables to prevent local Python/R libraries from conflicting with those in the container +// The JULIA depot path has been adjusted to a fixed path `/usr/local/share/julia` that needs to be used for packages in the container. +// See https://apeltzer.github.io/post/03-julia-lang-nextflow/ for details on that. Once we have a common agreement on where to keep Julia packages, this is adjustable. + env { PYTHONNOUSERSITE = 1 R_PROFILE_USER = "/.Rprofile" R_ENVIRON_USER = "/.Renviron" + JULIA_DEPOT_PATH = "/usr/local/share/julia" } // Capture exit codes from upstream processes when piping @@ -214,7 +213,7 @@ manifest { description = 'Identify and quantify peptides from mass spectrometry raw data' mainScript = 'main.nf' nextflowVersion = '!>=21.10.3' - version = '2.1.0' + version = '2.2.0' } // Function to ensure that resource requirements don't go beyond diff --git a/nextflow_schema.json b/nextflow_schema.json index 31e20e0c..4ffb8977 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -53,6 +53,7 @@ "fasta": { "type": "string", "fa_icon": "fas fa-dna", + "pattern": ".fasta$", "description": "Input FASTA protein database", "help_text": "If you have no genome reference available, the pipeline can build one using a FASTA file. This requires additional time and resources, so it's better to use a pre-build index if possible." }, @@ -114,6 +115,7 @@ }, "fragment_bin_offset": { "type": "integer", + "default": 0, "description": "Specify the fragment bin offset used for the comet database search.", "help_text": "For High-Resolution instruments a fragment bin offset of 0 is recommended. (See the Comet parameter documentation: eg. 0)" }, @@ -197,7 +199,7 @@ "remove_precursor_peak": { "type": "boolean", "description": "Include precursor ions into the peptide spectrum matching", - "default": true + "default": false }, "spectrum_batch_size": { "type": "integer", @@ -206,6 +208,7 @@ }, "vcf_sheet": { "type": "string", + "pattern": "^\\S+\\.tsv$", "description": "Specify a .tsv file containing the information about genomic variants (vcf files < v.4.2) for each sample.", "help_text": "| Sample | VCF_FileName |\n| -------------| :---------------------:|\n| MM15_Melanom | data/MM15_variants.vcf |\n| MM17_Melanom | data/MM17_variants.vcf |" } @@ -287,6 +290,7 @@ "properties": { "allele_sheet": { "type": "string", + "pattern": "^\\S+\\.tsv$", "description": "Specify a .tsv file containing the MHC alleles of your probes as well as their metadata such as SampleID.", "help_text": "| Sample | HLA_Alleles_Class_1 | HLA_Alleles_Class_2 |\n| -------------| :----------------------------------------------:| ------------------------------------------:|\n| MM15_Melanom | A* 03:01;A* 68:01;B* 27:05;B* 35:03;C* 02:02;C* 04:01 |HLA-DRB1* 01:01;HLA-DQB1* 03:19;HLA-DQA1* 05:01|\n| MM17_Melanom | A* 02:01;B* 07:01;B* 26:01;C* 11:01;C* 01:01 |HLA-DRB1* 01:02;HLA-DRB3* 02:02;HLA-DRB4* 01:03|\n" }, @@ -328,12 +332,12 @@ "variant_indel_filter": { "type": "boolean", "description": "Specify whether insertions and deletions should not be considered for variant translation", - "default": true + "default": false }, "variant_frameshift_filter": { "type": "boolean", "description": "Specify whether frameshifts should not be considered for variant translation", - "default": true + "default": false }, "variant_snp_filter": { "type": "boolean", @@ -382,12 +386,6 @@ "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" }, - "hostnames": { - "type": "string", - "description": "Institutional configs hostname.", - "hidden": true, - "fa_icon": "fas fa-users-cog" - }, "config_profile_name": { "type": "string", "description": "Institutional config name.", @@ -462,23 +460,6 @@ "fa_icon": "fas fa-question-circle", "hidden": true }, - - "publish_dir_mode": { - "type": "string", - "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 - }, "email_on_fail": { "type": "string", "description": "Email address for completion summary, only when pipeline fails.", @@ -539,13 +520,6 @@ "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." } } } diff --git a/subworkflows/local/include_proteins.nf b/subworkflows/local/include_proteins.nf new file mode 100644 index 00000000..3235cc9c --- /dev/null +++ b/subworkflows/local/include_proteins.nf @@ -0,0 +1,36 @@ +/* + * Perform the necessary steps to make the data uniform for further processing + */ + +include { GENERATE_PROTEINS_FROM_VCF } from '../../modules/local/generate_proteins_from_vcf' + +workflow INCLUDE_PROTEINS { + take: + input_fasta + + main: + ch_versions = Channel.empty() + + // Variant + vcf_sheet = file(params.vcf_sheet, checkIfExists: true) + + Channel.from( vcf_sheet ) + .splitCsv(header: ['Sample', 'VCF_FileName'], sep:'\t', skip: 1) + .map { col -> tuple("${col.Sample}", file("${col.VCF_FileName}"),) } + .set { ch_vcf_from_sheet } + + // Combine the vcf information with the meta information + ch_vcf = input_fasta + .map{ it -> [it[0].sample, it[0], it[1]] } + .combine( ch_vcf_from_sheet, by: 0 ) + .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)) + + emit: + // Define the information that is returned by this workflow + versions = ch_versions + ch_vcf_from_sheet = ch_vcf_from_sheet + ch_fasta_file = GENERATE_PROTEINS_FROM_VCF.out.vcf_fasta +} diff --git a/subworkflows/local/input_check.nf b/subworkflows/local/input_check.nf index 1c3ccc2e..05002623 100644 --- a/subworkflows/local/input_check.nf +++ b/subworkflows/local/input_check.nf @@ -2,24 +2,22 @@ // Check input samplesheet and get read channels // -params.options = [:] - -include { SAMPLESHEET_CHECK } from '../../modules/local/samplesheet_check' addParams(options: [:]) +include { SAMPLESHEET_CHECK } from '../../modules/local/samplesheet_check' workflow INPUT_CHECK { take: - samplesheet // file: /path/to/samplesheet.csv + samplesheet // file: /path/to/samplesheet.csv main: - SAMPLESHEET_CHECK ( samplesheet ) + 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 ] + reads // channel: [ val(meta), [ reads ] ] + versions = SAMPLESHEET_CHECK.out.versions // channel: [ versions.yml ] } // Function to get list of [ meta, filenames ] diff --git a/subworkflows/local/post_quantification.nf b/subworkflows/local/post_quantification.nf new file mode 100644 index 00000000..3d9ffbae --- /dev/null +++ b/subworkflows/local/post_quantification.nf @@ -0,0 +1,51 @@ +/* + * Perform the quantification of the samples when the parameter --skip_quantification is not provided + */ + +include { OPENMS_FEATUREFINDERIDENTIFICATION } from '../../modules/local/openms_featurefinderidentification' +include { OPENMS_FEATURELINKERUNLABELEDKD } from '../../modules/local/openms_featurelinkerunlabeledkd' +include { OPENMS_IDCONFLICTRESOLVER } from '../../modules/local/openms_idconflictresolver' +include { OPENMS_TEXTEXPORTER as OPENMS_TEXTEXPORTER_CSV } from '../../modules/local/openms_textexporter' +include { OPENMS_MZTABEXPORTER } from '../../modules/local/openms_mztabexporter' + +workflow POST_QUANTIFICATION { + take: + psms_outcome + aligned_mzml + filter_q_value + + main: + ch_versions = Channel.empty() + // Combining the necessary information into one channel + psms_outcome + .join( aligned_mzml, 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 + .flatMap { + meta, raw -> + [[[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_CSV(OPENMS_IDCONFLICTRESOLVER.out.consensusxml) + ch_versions = ch_versions.mix(OPENMS_TEXTEXPORTER_CSV.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)) + emit: + // Define the information that is returned by this workflow + versions = ch_versions + mztab = OPENMS_MZTABEXPORTER.out.mztab +} diff --git a/subworkflows/local/pre_quantification.nf b/subworkflows/local/pre_quantification.nf new file mode 100644 index 00000000..7c44d85d --- /dev/null +++ b/subworkflows/local/pre_quantification.nf @@ -0,0 +1,93 @@ +/* + * Perform the quantification of the samples when the parameter --skip_quantification is not provided + */ + +include { OPENMS_FALSEDISCOVERYRATE } from '../../modules/local/openms_falsediscoveryrate' +include { OPENMS_IDFILTER as OPENMS_IDFILTER_FOR_ALIGNMENT } from '../../modules/local/openms_idfilter' +include { OPENMS_TEXTEXPORTER as OPENMS_TEXTEXPORTER_PSMS } from '../../modules/local/openms_textexporter' +include { OPENMS_MAPALIGNERIDENTIFICATION } from '../../modules/local/openms_mapaligneridentification' +include { + OPENMS_MAPRTTRANSFORMER as OPENMS_MAPRTTRANSFORMERMZML + OPENMS_MAPRTTRANSFORMER as OPENMS_MAPRTTRANSFORMERIDXML } from '../../modules/local/openms_maprttransformer' + + +workflow PRE_QUANTIFICATION { + take: + indexed_hits + ch_mzml_file + mzml_files + raw_files + + main: + ch_versions = Channel.empty() + // Calculate fdr for id based alignment + OPENMS_FALSEDISCOVERYRATE(indexed_hits) + 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)) + // Write the content to a PSMs file + OPENMS_TEXTEXPORTER_PSMS( + OPENMS_IDFILTER_FOR_ALIGNMENT.out.idxml + .flatMap { + meta, idxml -> + ident = idxml.baseName.split('_-_')[1] + [[[id:ident, sample:meta.sample, condition:meta.condition, ext:meta.ext], idxml]] + } + ) + // Group samples together if they are replicates + ch_grouped_fdr_filtered = OPENMS_IDFILTER_FOR_ALIGNMENT.out.idxml + .map { + meta, raw -> + [[id:meta.sample + "_" + meta.condition, sample:meta.sample, condition:meta.condition, ext:meta.ext], raw] + } + .groupTuple(by: [0]) + // 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 + mzml_files + .mix(raw_files) + .mix(ch_mzml_file) + .join( + OPENMS_MAPALIGNERIDENTIFICATION.out.trafoxml + .transpose() + .flatMap { + meta, trafoxml -> + ident = trafoxml.baseName.split('_-_')[0] + [[[id:ident, sample:meta.sample, condition:meta.condition, ext:meta.ext], trafoxml]] + }, by: [0] ) + .set { joined_trafos_mzmls } + + indexed_hits + .join( + OPENMS_MAPALIGNERIDENTIFICATION.out.trafoxml + .transpose() + .flatMap { + meta, trafoxml -> + ident = trafoxml.baseName.split('_-_')[0] + [[[id:ident, sample:meta.sample, condition:meta.condition, ext:meta.ext], trafoxml]] + }, by: [0] ) + .set { joined_trafos_ids } + // 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 -> + [[id:meta.sample + "_" + meta.condition, sample:meta.sample, condition:meta.condition, ext:meta.ext], raw] + } + .groupTuple(by: [0]) + + emit: + // Define the information that is returned by this workflow + versions = ch_versions + ch_proceeding_idx + aligned_mzml = OPENMS_MAPRTTRANSFORMERMZML.out.aligned + psms_outcome = OPENMS_IDFILTER_FOR_ALIGNMENT.out.idxml +} diff --git a/subworkflows/local/predict_class1.nf b/subworkflows/local/predict_class1.nf new file mode 100644 index 00000000..70532717 --- /dev/null +++ b/subworkflows/local/predict_class1.nf @@ -0,0 +1,50 @@ +/* + * Perform the class 1 prediction when the parameter --predict_class_1 is provided and --skip_quantification is not + */ + +include { MHCFLURRY_PREDICTPEPTIDESCLASS1 } from '../../modules/local/mhcflurry_predictpeptidesclass1' +include { PREDICT_POSSIBLE_NEOEPITOPES as PREDICT_POSSIBLE_CLASS1_NEOEPITOPES } from '../../modules/local/predict_possible_neoepitopes' +include { RESOLVE_FOUND_NEOEPITOPES as RESOLVE_FOUND_CLASS1_NEOEPITOPES } from '../../modules/local/resolve_found_neoepitopes' +include { MHCFLURRY_PREDICTNEOEPITOPESCLASS1 } from '../../modules/local/mhcflurry_predictneoepitopesclass1' + +workflow PREDICT_CLASS1 { + take: + mztab + peptides_class_1_alleles + ch_vcf_from_sheet + + main: + ch_versions = Channel.empty() + ch_predicted_possible_neoepitopes = Channel.empty() + + // If specified predict peptides using MHCFlurry + MHCFLURRY_PREDICTPEPTIDESCLASS1( + 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_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_CLASS1_NEOEPITOPES(peptides_class_1_alleles.combine(ch_vcf_from_sheet, by:0)) + ch_versions = ch_versions.mix(PREDICT_POSSIBLE_CLASS1_NEOEPITOPES.out.versions.first().ifEmpty(null)) + ch_predicted_possible_neoepitopes = PREDICT_POSSIBLE_CLASS1_NEOEPITOPES.out.csv + // Resolve found neoepitopes + RESOLVE_FOUND_CLASS1_NEOEPITOPES( + mztab + .map{ it -> [it[0].sample, it[0], it[1]] } + .combine( ch_predicted_possible_neoepitopes, by:0) + .map( it -> [it[1], it[2], it[3]]) + ) + ch_versions = ch_versions.mix(RESOLVE_FOUND_CLASS1_NEOEPITOPES.out.versions.first().ifEmpty(null)) + // Predict class 1 neoepitopes MHCFlurry + MHCFLURRY_PREDICTNEOEPITOPESCLASS1(peptides_class_1_alleles.join(RESOLVE_FOUND_CLASS1_NEOEPITOPES.out.csv, by:0)) + ch_versions = ch_versions.mix(MHCFLURRY_PREDICTNEOEPITOPESCLASS1.out.versions.first().ifEmpty(null)) + } + + emit: + // Define the information that is returned by this workflow + versions = ch_versions + ch_predicted_possible_neoepitopes = ch_predicted_possible_neoepitopes +} diff --git a/subworkflows/local/predict_class2.nf b/subworkflows/local/predict_class2.nf new file mode 100644 index 00000000..4baa282d --- /dev/null +++ b/subworkflows/local/predict_class2.nf @@ -0,0 +1,65 @@ +/* + * Perform the class 2 prediction when the parameter --predict_class_2 is provided and --skip_quantification is not + */ + +include { MHCNUGGETS_PEPTIDESCLASS2PRE } from '../../modules/local/mhcnuggets_peptidesclass2pre' +include { MHCNUGGETS_PREDICTPEPTIDESCLASS2 } from '../../modules/local/mhcnuggets_predictpeptidesclass2' +include { MHCNUGGETS_PEPTIDESCLASS2POST } from '../../modules/local/mhcnuggets_peptidesclass2post' +include { PREDICT_POSSIBLE_NEOEPITOPES as PREDICT_POSSIBLE_CLASS2_NEOEPITOPES } from '../../modules/local/predict_possible_neoepitopes' +include { RESOLVE_FOUND_NEOEPITOPES as RESOLVE_FOUND_CLASS2_NEOEPITOPES } from '../../modules/local/resolve_found_neoepitopes' +include { MHCNUGGETS_NEOEPITOPESCLASS2PRE } from '../../modules/local/mhcnuggets_neoepitopesclass2pre' +include { MHCNUGGETS_PREDICTNEOEPITOPESCLASS2 } from '../../modules/local/mhcnuggets_predictneoepitopesclass2' +include { MHCNUGGETS_NEOEPITOPESCLASS2POST } from '../../modules/local/mhcnuggets_neoepitopesclass2post' + +workflow PREDICT_CLASS2 { + take: + mztab + peptides_class_2_alleles + ch_vcf_from_sheet + + main: + ch_versions = Channel.empty() + ch_predicted_possible_neoepitopes = Channel.empty() + + // Preprocess found peptides for MHCNuggets prediction class 2 + MHCNUGGETS_PEPTIDESCLASS2PRE(mztab) + ch_versions = ch_versions.mix(MHCNUGGETS_PEPTIDESCLASS2PRE.out.versions.first().ifEmpty(null)) + // Predict found peptides using MHCNuggets class 2 + 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 + 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_CLASS2_NEOEPITOPES(peptides_class_2_alleles.combine(ch_vcf_from_sheet, by:0)) + ch_versions = ch_versions.mix(PREDICT_POSSIBLE_CLASS2_NEOEPITOPES.out.versions.first().ifEmpty(null)) + ch_predicted_possible_neoepitopes = PREDICT_POSSIBLE_CLASS2_NEOEPITOPES.out.csv + // Resolve found class 2 neoepitopes + RESOLVE_FOUND_CLASS2_NEOEPITOPES( + mztab + .map{ it -> [it[0].sample, it[1]] } + .combine( ch_predicted_possible_neoepitopes, by:0) + ) + ch_versions = ch_versions.mix(RESOLVE_FOUND_CLASS2_NEOEPITOPES.out.versions.first().ifEmpty(null)) + // Preprocess resolved neoepitopes in a format that MHCNuggets understands + MHCNUGGETS_NEOEPITOPESCLASS2PRE(RESOLVE_FOUND_CLASS2_NEOEPITOPES.out.csv) + ch_versions = ch_versions.mix(MHCNUGGETS_NEOEPITOPESCLASS2PRE.out.versions.first().ifEmpty(null)) + // Predict class 2 MHCNuggets + MHCNUGGETS_PREDICTNEOEPITOPESCLASS2(MHCNUGGETS_NEOEPITOPESCLASS2PRE.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 + MHCNUGGETS_NEOEPITOPESCLASS2POST(RESOLVE_FOUND_CLASS2_NEOEPITOPES.out.csv.join(MHCNUGGETS_PREDICTNEOEPITOPESCLASS2.out.csv, by:0)) + ch_versions = ch_versions.mix(MHCNUGGETS_NEOEPITOPESCLASS2POST.out.versions.first().ifEmpty(null)) + } + + emit: + // Define the information that is returned by this workflow + versions = ch_versions + ch_predicted_possible_neoepitopes = ch_predicted_possible_neoepitopes +} diff --git a/subworkflows/local/predict_rt.nf b/subworkflows/local/predict_rt.nf new file mode 100644 index 00000000..894eddf9 --- /dev/null +++ b/subworkflows/local/predict_rt.nf @@ -0,0 +1,33 @@ +/* + * Perform the Retention time prediction when the parameter --predict_RT is provided + */ + +include { OPENMS_RTMODEL } from '../../modules/local/openms_rtmodel' +include { + OPENMS_RTPREDICT as OPENMS_RTPREDICT_FOUND_PEPTIDES + OPENMS_RTPREDICT as OPENMS_RTPREDICT_NEOEPITOPES} from '../../modules/local/openms_rtpredict' + + +workflow PREDICT_RT { + take: + filter_q_value + ch_predicted_possible_neoepitopes + ch_predicted_possible_neoepitopes_II + + main: + ch_versions = Channel.empty() + + // 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)) + + emit: + // Define the information that is returned by this workflow + versions = ch_versions +} diff --git a/subworkflows/local/refine_fdr_on_predicted_subset.nf b/subworkflows/local/refine_fdr.nf similarity index 60% rename from subworkflows/local/refine_fdr_on_predicted_subset.nf rename to subworkflows/local/refine_fdr.nf index b786d649..162ab9b9 100644 --- a/subworkflows/local/refine_fdr_on_predicted_subset.nf +++ b/subworkflows/local/refine_fdr.nf @@ -1,28 +1,16 @@ /* * Perform an additional step where the process are collected - * that are called when the paramater "refine_fdr_on_predicted_subset" is provided + * that are called when the parameter "refine_fdr" is provided */ -params.exporter_prec_options = [:] -params.exporter_psm_options = [:] -params.percolator_adapter_refine_options = [:] -params.whitelist_filter_options = [:] -params.filter_options = [:] +include { OPENMS_MZTABEXPORTER as OPENMS_MZTABEXPORTERPERC } from '../../modules/local/openms_mztabexporter' +include { OPENMS_MZTABEXPORTER as OPENMS_MZTABEXPORTERPSM } from '../../modules/local/openms_mztabexporter' +include { MHCFLURRY_PREDICTPSMS } from '../../modules/local/mhcflurry_predictpsms' +include { OPENMS_PERCOLATORADAPTER } from '../../modules/local/openms_percolatoradapter' +include { OPENMS_IDFILTER as OPENMS_IDFILTER_PSMS } from '../../modules/local/openms_idfilter' +include { OPENMS_IDFILTER as OPENMS_IDFILTER_REFINED } from '../../modules/local/openms_idfilter' -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 { +workflow REFINE_FDR { // Define the input parameters take: filtered_perc_output diff --git a/workflows/mhcquant.nf b/workflows/mhcquant.nf index 818c0389..94384ca8 100644 --- a/workflows/mhcquant.nf +++ b/workflows/mhcquant.nf @@ -39,15 +39,6 @@ if (params.predict_class_1 || params.predict_class_2) { } } -// Variant -if (params.include_proteins_from_vcf) { - vcf_sheet = file(params.vcf_sheet, checkIfExists: true) - Channel.from( vcf_sheet ) - .splitCsv(header: ['Sample', 'VCF_FileName'], sep:'\t', skip: 1) - .map { col -> tuple("${col.Sample}", file("${col.VCF_FileName}"),) } - .set { ch_vcf_from_sheet } - } - /* ======================================================================================== CONFIG FILES @@ -57,107 +48,38 @@ if (params.include_proteins_from_vcf) { 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() - /* ======================================================================================== - IMPORT LOCAL MODULES/SUBWORKFLOWS + CREATE CHANNELS ======================================================================================== */ -// Don't overwrite global params.modules, create a copy instead and use that within the main script. -def modules = params.modules.clone() - -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 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 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 '../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: [:] ) -include { OPENMS_PEAKPICKERHIRES } from '../modules/local/openms_peakpickerhires' addParams( options: [:] ) -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: 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 { - OPENMS_MAPRTTRANSFORMER as OPENMS_MAPRTTRANSFORMERMZML - OPENMS_MAPRTTRANSFORMER as OPENMS_MAPRTTRANSFORMERIDXML } from '../modules/local/openms_maprttransformer' addParams( options: [:] ) - -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: 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 '../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: [:] ) -include { OPENMS_IDCONFLICTRESOLVER } from '../modules/local/openms_idconflictresolver' addParams( options: [:] ) -include { OPENMS_TEXTEXPORTER } from '../modules/local/openms_textexporter' addParams( options: [:] ) -include { OPENMS_MZTABEXPORTER } from '../modules/local/openms_mztabexporter' 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 { 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: 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 ) - -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 ) +// +// MODULE: Loaded from modules/local/ +// +include { OPENMS_DECOYDATABASE } from '../modules/local/openms_decoydatabase' +include { OPENMS_THERMORAWFILEPARSER } from '../modules/local/openms_thermorawfileparser' +include { OPENMS_PEAKPICKERHIRES } from '../modules/local/openms_peakpickerhires' +include { OPENMS_COMETADAPTER } from '../modules/local/openms_cometadapter' +include { OPENMS_PEPTIDEINDEXER } from '../modules/local/openms_peptideindexer' +include { OPENMS_IDFILTER as OPENMS_IDFILTER_Q_VALUE } from '../modules/local/openms_idfilter' +include { OPENMS_IDMERGER } from '../modules/local/openms_idmerger' +include { OPENMS_PSMFEATUREEXTRACTOR } from '../modules/local/openms_psmfeatureextractor' +include { OPENMS_PERCOLATORADAPTER } from '../modules/local/openms_percolatoradapter' +include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/modules/custom/dumpsoftwareversions/main' +include { MULTIQC } from '../modules/nf-core/modules/multiqc/main' + +// +// SUBWORKFLOW: Consisting of a mix of local and nf-core/modules +// +include { INPUT_CHECK } from '../subworkflows/local/input_check' +include { INCLUDE_PROTEINS } from '../subworkflows/local/include_proteins' +include { PRE_QUANTIFICATION } from '../subworkflows/local/pre_quantification' +include { REFINE_FDR } from '../subworkflows/local/refine_fdr' +include { POST_QUANTIFICATION } from '../subworkflows/local/post_quantification' +include { PREDICT_CLASS1 } from '../subworkflows/local/predict_class1' +include { PREDICT_CLASS2 } from '../subworkflows/local/predict_class2' +include { PREDICT_RT } from '../subworkflows/local/predict_rt' //////////////////////////////////////////////////// /* -- RUN MAIN WORKFLOW -- */ @@ -166,9 +88,13 @@ workflow MHCQUANT { ch_versions = Channel.empty() + // + // SUBWORKFLOW: Check the input file + // INPUT_CHECK( params.input ) .reads .set { ch_samples_from_sheet } + ch_versions = ch_versions.mix(INPUT_CHECK.out.versions) ch_samples_from_sheet .branch { @@ -179,7 +105,8 @@ workflow MHCQUANT { return [ meta, filename ] other : true } .set { ms_files } - + // 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 } // Input fasta file Channel.fromPath( params.fasta ) @@ -188,27 +115,24 @@ workflow MHCQUANT { .ifEmpty { exit 1, "params.fasta was empty - no input file supplied" } .set { input_fasta } - // 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 } - + // + // SUBWORKFLOW: Include protein information + // if ( params.include_proteins_from_vcf ) { - // Combine the vcf information with the meta information - ch_vcf = input_fasta - .map{ it -> [it[0].sample, it[0], it[1]] } - .join( ch_vcf_from_sheet ) - .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 + // Include the proteins from the vcf file to the fasta file + INCLUDE_PROTEINS( input_fasta ) + ch_versions = ch_versions.mix(INCLUDE_PROTEINS.out.versions.ifEmpty(null)) + ch_fasta_file = INCLUDE_PROTEINS.out.ch_fasta_file + ch_vcf_from_sheet = INCLUDE_PROTEINS.out.ch_vcf_from_sheet } else { ch_fasta_file = input_fasta + ch_vcf_from_sheet = Channel.empty() } 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_versions = ch_versions.mix(OPENMS_DECOYDATABASE.out.versions.ifEmpty(null)) ch_decoy_db = OPENMS_DECOYDATABASE.out.decoy } else { ch_decoy_db = ch_fasta_file @@ -216,85 +140,37 @@ workflow MHCQUANT { // Raw file conversion OPENMS_THERMORAWFILEPARSER(ms_files.raw) - ch_versions = ch_versions.mix(OPENMS_THERMORAWFILEPARSER.out.versions.first().ifEmpty(null)) - + ch_versions = ch_versions.mix(OPENMS_THERMORAWFILEPARSER.out.versions.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_versions = ch_versions.mix(OPENMS_PEAKPICKERHIRES.out.versions.ifEmpty(null)) ch_mzml_file = OPENMS_PEAKPICKERHIRES.out.mzml } else { ch_mzml_file = ms_files.mzml } - // Run comet database search OPENMS_COMETADAPTER( OPENMS_THERMORAWFILEPARSER.out.mzml .mix(ch_mzml_file) .join(ch_decoy_db, remainder:true)) - ch_versions = ch_versions.mix(OPENMS_COMETADAPTER.out.versions.first().ifEmpty(null)) - + ch_versions = ch_versions.mix(OPENMS_COMETADAPTER.out.versions.ifEmpty(null)) // Index decoy and target hits OPENMS_PEPTIDEINDEXER(OPENMS_COMETADAPTER.out.idxml.join(ch_decoy_db)) - ch_versions = ch_versions.mix(OPENMS_PEPTIDEINDEXER.out.versions.first().ifEmpty(null)) + ch_versions = ch_versions.mix(OPENMS_PEPTIDEINDEXER.out.versions.ifEmpty(null)) + // + // SUBWORKFLOW: Pre-process step for the quantification of the data + // 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 { - meta, raw -> - [[id:meta.sample + "_" + meta.condition, sample:meta.sample, condition:meta.condition, ext:meta.ext], raw] - } - .groupTuple(by: [0]) - - // 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) - .mix(ch_mzml_file) - .join( - OPENMS_MAPALIGNERIDENTIFICATION.out.trafoxml - .transpose() - .flatMap { - meta, trafoxml -> - ident = trafoxml.baseName.split('_-_')[0] - [[[id:ident, sample:meta.sample, condition:meta.condition, ext:meta.ext], trafoxml]] - }, by: [0] ) - .set { joined_trafos_mzmls } - - OPENMS_PEPTIDEINDEXER.out.idxml - .join( - OPENMS_MAPALIGNERIDENTIFICATION.out.trafoxml - .transpose() - .flatMap { - meta, trafoxml -> - ident = trafoxml.baseName.split('_-_')[0] - [[[id:ident, sample:meta.sample, condition:meta.condition, ext:meta.ext], trafoxml]] - }, by: [0] ) - .set { joined_trafos_ids } - - // 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 -> - [[id:meta.sample + "_" + meta.condition, sample:meta.sample, condition:meta.condition, ext:meta.ext], raw] - } - .groupTuple(by: [0]) - + PRE_QUANTIFICATION( + OPENMS_PEPTIDEINDEXER.out.idxml, + ch_mzml_file, + ms_files.mzml, + OPENMS_THERMORAWFILEPARSER.out.mzml + ) + ch_proceeding_idx = PRE_QUANTIFICATION.out.ch_proceeding_idx + ch_versions = ch_versions.mix(PRE_QUANTIFICATION.out.versions.ifEmpty(null)) } else { ch_proceeding_idx = OPENMS_PEPTIDEINDEXER.out.idxml .map { @@ -306,164 +182,94 @@ workflow MHCQUANT { // Merge aligned idXMLfiles OPENMS_IDMERGER(ch_proceeding_idx) - ch_versions = ch_versions.mix(OPENMS_IDMERGER.out.versions.first().ifEmpty(null)) + ch_versions = ch_versions.mix(OPENMS_IDMERGER.out.versions.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)) + ch_versions = ch_versions.mix(OPENMS_PSMFEATUREEXTRACTOR.out.versions.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 - } - + OPENMS_PERCOLATORADAPTER(OPENMS_PSMFEATUREEXTRACTOR.out.idxml) + ch_versions = ch_versions.mix(OPENMS_PERCOLATORADAPTER.out.versions.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)) + ch_versions = ch_versions.mix(OPENMS_IDFILTER_Q_VALUE.out.versions.ifEmpty(null)) - // Refine_fdr_on_predicted_subset + // + // SUBWORKFLOW: Refine the FDR values on the predicted subset + // if ( params.refine_fdr_on_predicted_subset && params.predict_class_1 ) { // Run the following subworkflow - REFINE_FDR_ON_PREDICTED_SUBSET ( + REFINE_FDR ( OPENMS_IDFILTER_Q_VALUE.out.idxml, OPENMS_PSMFEATUREEXTRACTOR.out.idxml, peptides_class_1_alleles ) - ch_versions = ch_versions.mix(REFINE_FDR_ON_PREDICTED_SUBSET.out.versions.first().ifEmpty(null)) - + ch_versions = ch_versions.mix(REFINE_FDR.out.versions.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]) ] } + filter_q_value = REFINE_FDR.out.filter_refined_q_value.flatMap { it -> [ tuple(it[0].sample, it[0], it[1]) ] } } else { // Make sure that the columns that consists of the ID's, sample names and the idXML file names are returned filter_q_value = OPENMS_IDFILTER_Q_VALUE.out.idxml.map{ it -> [it[0].sample, it[0], it[1]] } } + // + // SUBWORKFLOW: Perform the post quantification step + // 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 - .flatMap { - meta, raw -> - [[[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)) + POST_QUANTIFICATION ( + PRE_QUANTIFICATION.out.psms_outcome, + PRE_QUANTIFICATION.out.aligned_mzml, + filter_q_value + ) + ch_versions = ch_versions.mix(POST_QUANTIFICATION.out.versions.ifEmpty(null)) } - ////////////////////////////////////////////////////////////////////////////////////////////// - // TODO: Replacement of custom scripts with epytope - ch_predicted_possible_neoepitopes = Channel.empty() + // + // SUBWORKFLOW: Predict class I (neoepitopes) + // if ( params.predict_class_1 & !params.skip_quantification ) { - // If specified predict peptides using MHCFlurry - 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_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( - OPENMS_MZTABEXPORTER.out.mztab - .map{ it -> [it[0].sample, it[0], it[1]] } - .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 - 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)) - } + PREDICT_CLASS1 ( + POST_QUANTIFICATION.out.mztab, + peptides_class_1_alleles, + ch_vcf_from_sheet + ) + ch_versions = ch_versions.mix(PREDICT_CLASS1.out.versions.ifEmpty(null)) + ch_predicted_possible_neoepitopes = PREDICT_CLASS1.out.ch_predicted_possible_neoepitopes + } else { + ch_predicted_possible_neoepitopes = Channel.empty() } - ch_predicted_possible_neoepitopes_II = Channel.empty() - if ( params.predict_class_2 & !params.skip_quantification ) { - // Preprocess found peptides for MHCNuggets prediction class 2 - 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 - 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]]) + // + // SUBWORKFLOW: Predict class II (neoepitopes) + // + if ( params.predict_class_2 & !params.skip_quantification ) { + PREDICT_CLASS2 ( + POST_QUANTIFICATION.out.mztab, + peptides_class_2_alleles, + ch_vcf_from_sheet ) - ch_versions = ch_versions.mix(MHCNUGGETS_PREDICTPEPTIDESCLASS2.out.versions.first().ifEmpty(null)) - // Postprocess predicted MHCNuggets peptides class 2 - 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( - OPENMS_MZTABEXPORTER.out.mztab - .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 - 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 - 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 - 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)) - } + ch_versions = ch_versions.mix(PREDICT_CLASS2.out.versions.ifEmpty(null)) + ch_predicted_possible_neoepitopes_II = PREDICT_CLASS2.out.ch_predicted_possible_neoepitopes + } else { + ch_predicted_possible_neoepitopes_II = Channel.empty() } - ////////////////////////////////////////////////////////////////////////////////////////////// + + // + // SUBWORKFLOW: Predict retention time + // if ( params.predict_RT ) { - 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)) + PREDICT_RT ( + filter_q_value.map{ it -> [it[1], it[2]] }, + ch_predicted_possible_neoepitopes, + ch_predicted_possible_neoepitopes_II + ) } // // MODULE: Pipeline reporting // CUSTOM_DUMPSOFTWAREVERSIONS ( - ch_versions.unique().collectFile() + ch_versions.unique().collectFile(name: 'collated_versions.yml') ) // @@ -484,8 +290,8 @@ workflow MHCQUANT { ) multiqc_report = MULTIQC.out.report.toList() + ch_versions = ch_versions.mix(MULTIQC.out.versions) } - } /*