From 49415412de269d374b421e2d79dfc3d12100e130 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Wed, 15 Feb 2023 11:20:01 +0100 Subject: [PATCH 001/269] Bump to version 1.1.0dev --- nextflow.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nextflow.config b/nextflow.config index ec71afb5..56b3c01e 100644 --- a/nextflow.config +++ b/nextflow.config @@ -244,7 +244,7 @@ manifest { description = """Protein 3D structure prediction pipeline""" mainScript = 'main.nf' nextflowVersion = '!>=22.10.1' - version = '1.0.0' + version = '1.1.0dev' doi = '10.5281/zenodo.7629996' } From fa0e9e0f7ef140a78deecab89ff296e151383334 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Wed, 15 Feb 2023 11:29:41 +0100 Subject: [PATCH 002/269] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b5c164e..49907a78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,3 +10,7 @@ Initial release of nf-core/proteinfold, created with the [nf-core](https://nf-co ### Enhancements & fixes - Updated pipeline template to [nf-core/tools 2.7.2](https://github.com/nf-core/tools/releases/tag/2.7.2) + +## 1.1.0 + +### Enhancements & fixes From c7ac5661b9c2ec89e83c26b560e8a35592af9008 Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Mon, 27 Feb 2023 22:16:58 -0500 Subject: [PATCH 003/269] Add accelerator directive to GPU processes --- conf/modules_alphafold2.config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conf/modules_alphafold2.config b/conf/modules_alphafold2.config index 25190dbf..3bee4018 100644 --- a/conf/modules_alphafold2.config +++ b/conf/modules_alphafold2.config @@ -27,6 +27,7 @@ process { if (params.alphafold2_mode == 'standard') { process { withName: 'RUN_ALPHAFOLD2' { + accelerator = params.use_gpu ? 1 : 0 ext.args = [ params.use_gpu ? '--use_gpu_relax=true' : '--use_gpu_relax=false', params.max_template_date ? "--max_template_date ${params.max_template_date}" : '' @@ -53,6 +54,7 @@ if (params.alphafold2_mode == 'split_msa_prediction') { } withName: 'RUN_ALPHAFOLD2_PRED' { + accelerator = params.use_gpu ? 1 : 0 ext.args = params.use_gpu ? '--use_gpu_relax=true' : '--use_gpu_relax=false' publishDir = [ path: { "${params.outdir}/${params.mode}/${params.alphafold2_mode}" }, From cbe63cb31f82a268a2c7a079b5393b56b6a67f0e Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Mon, 27 Feb 2023 22:19:21 -0500 Subject: [PATCH 004/269] Add gpu to COLABFOLD_BATCH --- conf/modules_colabfold.config | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/modules_colabfold.config b/conf/modules_colabfold.config index 83015351..a2137847 100644 --- a/conf/modules_colabfold.config +++ b/conf/modules_colabfold.config @@ -49,6 +49,7 @@ if (params.colabfold_server == 'local') { ] } withName: 'COLABFOLD_BATCH' { + accelerator = params.use_gpu ? 1 : 0 ext.args = [ params.use_gpu ? '' : '--cpu', params.use_amber ? '--amber' : '', From b3c4ca9040281e1cf697f326a40f8a00ac94ca45 Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 1 Mar 2023 09:20:11 -0500 Subject: [PATCH 005/269] Accelerator null instead of zero --- conf/modules_colabfold.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/modules_colabfold.config b/conf/modules_colabfold.config index a2137847..faaa229d 100644 --- a/conf/modules_colabfold.config +++ b/conf/modules_colabfold.config @@ -49,7 +49,7 @@ if (params.colabfold_server == 'local') { ] } withName: 'COLABFOLD_BATCH' { - accelerator = params.use_gpu ? 1 : 0 + accelerator = params.use_gpu ? 1 : null ext.args = [ params.use_gpu ? '' : '--cpu', params.use_amber ? '--amber' : '', From 455d02633c994846c23780e0d7ac983871658ceb Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Wed, 1 Mar 2023 09:34:21 -0500 Subject: [PATCH 006/269] If statement for accelerator --- conf/modules_alphafold2.config | 4 ++-- conf/modules_colabfold.config | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/conf/modules_alphafold2.config b/conf/modules_alphafold2.config index 3bee4018..9a266160 100644 --- a/conf/modules_alphafold2.config +++ b/conf/modules_alphafold2.config @@ -27,7 +27,7 @@ process { if (params.alphafold2_mode == 'standard') { process { withName: 'RUN_ALPHAFOLD2' { - accelerator = params.use_gpu ? 1 : 0 + if(params.use_gpu) { accelerator = 1 } ext.args = [ params.use_gpu ? '--use_gpu_relax=true' : '--use_gpu_relax=false', params.max_template_date ? "--max_template_date ${params.max_template_date}" : '' @@ -54,7 +54,7 @@ if (params.alphafold2_mode == 'split_msa_prediction') { } withName: 'RUN_ALPHAFOLD2_PRED' { - accelerator = params.use_gpu ? 1 : 0 + if(params.use_gpu) { accelerator = 1 } ext.args = params.use_gpu ? '--use_gpu_relax=true' : '--use_gpu_relax=false' publishDir = [ path: { "${params.outdir}/${params.mode}/${params.alphafold2_mode}" }, diff --git a/conf/modules_colabfold.config b/conf/modules_colabfold.config index faaa229d..2e2773eb 100644 --- a/conf/modules_colabfold.config +++ b/conf/modules_colabfold.config @@ -49,7 +49,7 @@ if (params.colabfold_server == 'local') { ] } withName: 'COLABFOLD_BATCH' { - accelerator = params.use_gpu ? 1 : null + if(params.use_gpu) { accelerator = 1 } ext.args = [ params.use_gpu ? '' : '--cpu', params.use_amber ? '--amber' : '', From fc3d7f8badb24b34a8c10110191af083d3366e8c Mon Sep 17 00:00:00 2001 From: Rob Syme Date: Thu, 2 Mar 2023 09:22:27 -0500 Subject: [PATCH 007/269] Changelog fix --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49907a78..4afe30e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,3 +14,5 @@ Initial release of nf-core/proteinfold, created with the [nf-core](https://nf-co ## 1.1.0 ### Enhancements & fixes + +Add `accelerator` directive to GPU processes when `params.use_gpu` is true. From 708b04c9e74ccf6fa380254224796d73e68fa85f Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 14 Mar 2023 20:34:38 +0100 Subject: [PATCH 008/269] Deal with multiline fasta for colabfold multimers --- modules/local/multifasta_to_csv.nf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/local/multifasta_to_csv.nf b/modules/local/multifasta_to_csv.nf index dfd67457..ee54f872 100644 --- a/modules/local/multifasta_to_csv.nf +++ b/modules/local/multifasta_to_csv.nf @@ -18,7 +18,8 @@ process MULTIFASTA_TO_CSV { script: """ - echo -e id,sequence'\\n'${meta.id},`awk '!/^>/ {print \$0}' ${fasta} | tr '\\n' ':' | sed 's/:\$//'` > input.csv + awk '/^>/ {printf("\\n%s\\n",\$0);next; } { printf("%s",\$0);} END {printf("\\n");}' ${fasta} > single_line.fasta + echo -e id,sequence'\\n'${meta.id},`awk '!/^>/ {print \$0}' single_line.fasta | tr '\\n' ':' | sed 's/:\$//' | sed 's/^://'` > input.csv cat <<-END_VERSIONS > versions.yml "${task.process}": From 45cc382b277cbdb96d5aea8e4cbae276a3a07138 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 14 Mar 2023 20:38:06 +0100 Subject: [PATCH 009/269] Update CHANGELOG --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4afe30e5..7cef8643 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,4 +15,6 @@ Initial release of nf-core/proteinfold, created with the [nf-core](https://nf-co ### Enhancements & fixes -Add `accelerator` directive to GPU processes when `params.use_gpu` is true. +- Add `accelerator` directive to GPU processes when `params.use_gpu` is true. + +- Support multiline fasta for colabfold multimer predictions From 8ae2552f1f15c1e1fc7eb36a71939ba13beff94f Mon Sep 17 00:00:00 2001 From: Rike Date: Wed, 15 Mar 2023 16:25:19 +0100 Subject: [PATCH 010/269] update paths --- conf/test_full.config | 2 +- conf/test_full_alphafold_multimer.config | 2 +- conf/test_full_alphafold_split.config | 2 +- conf/test_full_colabfold_local.config | 2 +- conf/test_full_colabfold_webserver.config | 2 +- conf/test_full_colabfold_webserver_multimer.config | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/conf/test_full.config b/conf/test_full.config index 7b301f90..dc8ff985 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -18,5 +18,5 @@ params { mode = 'alphafold2' alphafold2_mode = 'standard' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet.csv' - alphafold2_db = 's3://nf-core-awsmegatests/proteinfold/input_data/db/alphafold_mini' + alphafold2_db = 's3://ngi-igenomes/test-data/proteinfold/db/alphafold_mini' } diff --git a/conf/test_full_alphafold_multimer.config b/conf/test_full_alphafold_multimer.config index 7eec75e5..eca98ba4 100644 --- a/conf/test_full_alphafold_multimer.config +++ b/conf/test_full_alphafold_multimer.config @@ -19,5 +19,5 @@ params { alphafold2_mode = 'standard' alphafold2_model_preset = 'multimer' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet_multimer.csv' - alphafold2_db = 's3://nf-core-awsmegatests/proteinfold/input_data/db/alphafold_mini' + alphafold2_db = 's3://ngi-igenomes/test-data/proteinfold/db/alphafold_mini' } diff --git a/conf/test_full_alphafold_split.config b/conf/test_full_alphafold_split.config index 9b5b8b4f..b7262d1f 100644 --- a/conf/test_full_alphafold_split.config +++ b/conf/test_full_alphafold_split.config @@ -18,5 +18,5 @@ params { mode = 'alphafold2' alphafold2_mode = 'split_msa_prediction' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet.csv' - alphafold2_db = 's3://nf-core-awsmegatests/proteinfold/input_data/db/alphafold_mini' + alphafold2_db = 's3://ngi-igenomes/test-data/proteinfold/db/alphafold_mini' } diff --git a/conf/test_full_colabfold_local.config b/conf/test_full_colabfold_local.config index ffa1ba04..e34ff152 100644 --- a/conf/test_full_colabfold_local.config +++ b/conf/test_full_colabfold_local.config @@ -20,7 +20,7 @@ params { colabfold_server = 'local' colabfold_model_preset = 'AlphaFold2-ptm' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet.csv' - colabfold_db = 's3://nf-core-awsmegatests/proteinfold/input_data/db/colabfold_mini' + colabfold_db = 's3://ngi-igenomes/test-data/proteinfold/db/colabfold_mini' } process { withName:MMSEQS_COLABFOLDSEARCH { diff --git a/conf/test_full_colabfold_webserver.config b/conf/test_full_colabfold_webserver.config index 0cdc08ca..b54347de 100644 --- a/conf/test_full_colabfold_webserver.config +++ b/conf/test_full_colabfold_webserver.config @@ -19,5 +19,5 @@ params { colabfold_server = 'webserver' colabfold_model_preset = 'AlphaFold2-ptm' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet.csv' - colabfold_db = 's3://nf-core-awsmegatests/proteinfold/input_data/db/colabfold_mini' + colabfold_db = 's3://ngi-igenomes/test-data/proteinfold/db/colabfold_mini' } diff --git a/conf/test_full_colabfold_webserver_multimer.config b/conf/test_full_colabfold_webserver_multimer.config index f8a1f323..8b50a4a1 100644 --- a/conf/test_full_colabfold_webserver_multimer.config +++ b/conf/test_full_colabfold_webserver_multimer.config @@ -19,5 +19,5 @@ params { colabfold_server = 'webserver' colabfold_model_preset = 'AlphaFold2-multimer-v2' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet_multimer.csv' - colabfold_db = 's3://nf-core-awsmegatests/proteinfold/input_data/db/colabfold_mini' + colabfold_db = 's3://ngi-igenomes/test-data/proteinfold/db/colabfold_mini' } From b58dbd2d17834a5e11ffd48a970574999a6955b0 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Fri, 28 Apr 2023 14:25:23 +0000 Subject: [PATCH 011/269] Template update for nf-core/tools version 2.8 --- .editorconfig | 2 +- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 3 +- .github/workflows/awsfulltest.yml | 2 +- .github/workflows/awstest.yml | 2 +- .github/workflows/branch.yml | 2 +- .github/workflows/clean-up.yml | 24 ++++ .github/workflows/linting.yml | 2 +- .pre-commit-config.yaml | 5 + CHANGELOG.md | 2 +- README.md | 74 ++++++---- bin/check_samplesheet.py | 3 - conf/base.config | 2 +- conf/igenomes.config | 8 ++ conf/test_full.config | 2 + docs/usage.md | 130 +++++------------- lib/NfcoreSchema.groovy | 4 +- lib/WorkflowMain.groovy | 13 +- lib/WorkflowProteinfold.groovy | 12 +- main.nf | 1 - modules.json | 4 +- modules/local/samplesheet_check.nf | 2 +- .../custom/dumpsoftwareversions/main.nf | 6 +- .../custom/dumpsoftwareversions/meta.yml | 2 + modules/nf-core/multiqc/main.nf | 6 +- modules/nf-core/multiqc/meta.yml | 3 +- nextflow.config | 31 ++++- tower.yml | 5 + 28 files changed, 195 insertions(+), 159 deletions(-) create mode 100644 .github/workflows/clean-up.yml create mode 100644 .pre-commit-config.yaml create mode 100644 tower.yml diff --git a/.editorconfig b/.editorconfig index b78de6e6..b6b31907 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,7 +8,7 @@ trim_trailing_whitespace = true indent_size = 4 indent_style = space -[*.{md,yml,yaml,html,css,scss,js,cff}] +[*.{md,yml,yaml,html,css,scss,js}] indent_size = 2 # These files are edited and tested upstream in nf-core/modules diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 396fa3a8..93ef6491 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -45,6 +45,6 @@ body: * Nextflow version _(eg. 22.10.1)_ * Hardware _(eg. HPC, Desktop, Cloud)_ * Executor _(eg. slurm, local, awsbatch)_ - * Container engine: _(e.g. Docker, Singularity, Conda, Podman, Shifter or Charliecloud)_ + * Container engine: _(e.g. Docker, Singularity, Conda, Podman, Shifter, Charliecloud, or Apptainer)_ * OS _(eg. CentOS Linux, macOS, Linux Mint)_ * Version of nf-core/proteinfold _(eg. 1.1, 1.5, 1.8.2)_ diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 64d45b17..652d1bfe 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -15,7 +15,8 @@ Learn more about contributing: [CONTRIBUTING.md](https://github.com/nf-core/prot - [ ] This comment contains a description of changes (with reason). - [ ] If you've fixed a bug or added code that should be tested, add tests! -- [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/nf-core/proteinfold/tree/master/.github/CONTRIBUTING.md)- [ ] If necessary, also make a PR on the nf-core/proteinfold _branch_ on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository. +- [ ] If you've added a new tool - have you followed the pipeline conventions in the [contribution docs](https://github.com/nf-core/proteinfold/tree/master/.github/CONTRIBUTING.md) +- [ ] If necessary, also make a PR on the nf-core/proteinfold _branch_ on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository. - [ ] Make sure your code lints (`nf-core lint`). - [ ] Ensure the test suite passes (`nextflow run . -profile test,docker --outdir `). - [ ] Usage Documentation in `docs/usage.md` is updated. diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index be8aee04..9b01d45a 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Launch workflow via tower - uses: nf-core/tower-action@v3 + uses: seqeralabs/action-tower-launch@v1 # TODO nf-core: You can customise AWS full pipeline tests as required # Add full size test data (but still relatively small datasets for few samples) # on the `test_full.config` test runs with only one set of parameters diff --git a/.github/workflows/awstest.yml b/.github/workflows/awstest.yml index f4025204..9bd51e81 100644 --- a/.github/workflows/awstest.yml +++ b/.github/workflows/awstest.yml @@ -12,7 +12,7 @@ jobs: steps: # Launch workflow using Tower CLI tool action - name: Launch workflow via tower - uses: nf-core/tower-action@v3 + uses: seqeralabs/action-tower-launch@v1 with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index 649c9b99..3784bfd9 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -13,7 +13,7 @@ jobs: - name: Check PRs if: github.repository == 'nf-core/proteinfold' run: | - { [[ ${{github.event.pull_request.head.repo.full_name }} == nf-core/proteinfold ]] && [[ $GITHUB_HEAD_REF = "dev" ]]; } || [[ $GITHUB_HEAD_REF == "patch" ]] + { [[ ${{github.event.pull_request.head.repo.full_name }} == nf-core/proteinfold ]] && [[ $GITHUB_HEAD_REF == "dev" ]]; } || [[ $GITHUB_HEAD_REF == "patch" ]] # If the above check failed, post a comment on the PR explaining the failure # NOTE - this doesn't currently work if the PR is coming from a fork, due to limitations in GitHub actions secrets diff --git a/.github/workflows/clean-up.yml b/.github/workflows/clean-up.yml new file mode 100644 index 00000000..694e90ec --- /dev/null +++ b/.github/workflows/clean-up.yml @@ -0,0 +1,24 @@ +name: "Close user-tagged issues and PRs" +on: + schedule: + - cron: "0 0 * * 0" # Once a week + +jobs: + clean-up: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v7 + with: + stale-issue-message: "This issue has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment otherwise this issue will be closed in 20 days." + stale-pr-message: "This PR has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment if it is still useful." + close-issue-message: "This issue was closed because it has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor and then staled for 20 days with no activity." + days-before-stale: 30 + days-before-close: 20 + days-before-pr-close: -1 + any-of-labels: "awaiting-changes,awaiting-feedback" + exempt-issue-labels: "WIP" + exempt-pr-labels: "WIP" + repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 858d622e..888cb4bc 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -78,7 +78,7 @@ jobs: - uses: actions/setup-python@v4 with: - python-version: "3.7" + python-version: "3.8" architecture: "x64" - name: Install dependencies diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..0c31cdb9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,5 @@ +repos: + - repo: https://github.com/pre-commit/mirrors-prettier + rev: "v2.7.1" + hooks: + - id: prettier diff --git a/CHANGELOG.md b/CHANGELOG.md index 454eed04..0494b3da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## v1.0dev - [date] +## v1.1.0dev - [date] Initial release of nf-core/proteinfold, created with the [nf-core](https://nf-co.re/) template. diff --git a/README.md b/README.md index a93e3d3e..e48ced68 100644 --- a/README.md +++ b/README.md @@ -8,57 +8,71 @@ [![run with singularity](https://img.shields.io/badge/run%20with-singularity-1d355c.svg?labelColor=000000)](https://sylabs.io/docs/) [![Launch on Nextflow Tower](https://img.shields.io/badge/Launch%20%F0%9F%9A%80-Nextflow%20Tower-%234256e7)](https://tower.nf/launch?pipeline=https://github.com/nf-core/proteinfold) -[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23proteinfold-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/proteinfold)[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core) +[![Get help on Slack](http://img.shields.io/badge/slack-nf--core%20%23proteinfold-4A154B?labelColor=000000&logo=slack)](https://nfcore.slack.com/channels/proteinfold)[![Follow on Twitter](http://img.shields.io/badge/twitter-%40nf__core-1DA1F2?labelColor=000000&logo=twitter)](https://twitter.com/nf_core)[![Follow on Mastodon](https://img.shields.io/badge/mastodon-nf__core-6364ff?labelColor=FFFFFF&logo=mastodon)](https://mstdn.science/@nf_core)[![Watch on YouTube](http://img.shields.io/badge/youtube-nf--core-FF0000?labelColor=000000&logo=youtube)](https://www.youtube.com/c/nf-core) ## Introduction - +**nf-core/proteinfold** is a bioinformatics pipeline that ... -**nf-core/proteinfold** is a bioinformatics best-practice analysis pipeline for Protein 3D structure prediction pipeline. - -The pipeline is built using [Nextflow](https://www.nextflow.io), a workflow tool to run tasks across multiple compute infrastructures in a very portable manner. It uses Docker/Singularity containers making installation trivial and results highly reproducible. The [Nextflow DSL2](https://www.nextflow.io/docs/latest/dsl2.html) implementation of this pipeline uses one container per process which makes it much easier to maintain and update software dependencies. Where possible, these processes have been submitted to and installed from [nf-core/modules](https://github.com/nf-core/modules) in order to make them available to all nf-core pipelines, and to everyone within the Nextflow community! - - - -On release, automated continuous integration tests run the pipeline on a full-sized dataset on the AWS cloud infrastructure. This ensures that the pipeline runs on AWS, has sensible resource allocation defaults set to run on real-world datasets, and permits the persistent storage of results to benchmark between pipeline releases and other analysis sources.The results obtained from the full-sized test can be viewed on the [nf-core website](https://nf-co.re/proteinfold/results). - -## Pipeline summary + + 1. Read QC ([`FastQC`](https://www.bioinformatics.babraham.ac.uk/projects/fastqc/)) 2. Present QC for raw reads ([`MultiQC`](http://multiqc.info/)) -## Quick Start +## Usage + +> **Note** +> If you are new to Nextflow and nf-core, please refer to [this page](https://nf-co.re/docs/usage/installation) on how +> to set-up Nextflow. Make sure to [test your setup](https://nf-co.re/docs/usage/introduction#how-to-run-a-pipeline) +> with `-profile test` before running the workflow on actual data. + + - 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. +Now, you can run the pipeline using: - > - 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`, please 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! +```bash +nextflow run nf-core/proteinfold \ + -profile \ + --input samplesheet.csv \ + --outdir +``` - +> **Warning:** +> Please provide pipeline parameters via the CLI or Nextflow `-params-file` option. Custom config files including those +> provided by the `-c` Nextflow option can be used to provide any configuration _**except for parameters**_; +> see [docs](https://nf-co.re/usage/configuration#custom-configuration-files). - ```bash - nextflow run nf-core/proteinfold --input samplesheet.csv --outdir --genome GRCh37 -profile - ``` +For more details, please refer to the [usage documentation](https://nf-co.re/proteinfold/usage) and the [parameter documentation](https://nf-co.re/proteinfold/parameters). -## Documentation +## Pipeline output -The nf-core/proteinfold pipeline comes with documentation about the pipeline [usage](https://nf-co.re/proteinfold/usage), [parameters](https://nf-co.re/proteinfold/parameters) and [output](https://nf-co.re/proteinfold/output). +To see the the results of a test run with a full size dataset refer to the [results](https://nf-co.re/proteinfold/results) tab on the nf-core website pipeline page. +For more details about the output files and reports, please refer to the +[output documentation](https://nf-co.re/proteinfold/output). ## Credits diff --git a/bin/check_samplesheet.py b/bin/check_samplesheet.py index 11b15572..4a758fe0 100755 --- a/bin/check_samplesheet.py +++ b/bin/check_samplesheet.py @@ -158,9 +158,6 @@ def sniff_format(handle): peek = read_head(handle) handle.seek(0) sniffer = csv.Sniffer() - if not sniffer.has_header(peek): - logger.critical("The given sample sheet does not appear to contain a header.") - sys.exit(1) dialect = sniffer.sniff(peek) return dialect diff --git a/conf/base.config b/conf/base.config index 37479a30..f13f56b2 100644 --- a/conf/base.config +++ b/conf/base.config @@ -15,7 +15,7 @@ process { memory = { check_max( 6.GB * task.attempt, 'memory' ) } time = { check_max( 4.h * task.attempt, 'time' ) } - errorStrategy = { task.exitStatus in [143,137,104,134,139] ? 'retry' : 'finish' } + errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' } maxRetries = 1 maxErrors = '-1' diff --git a/conf/igenomes.config b/conf/igenomes.config index 7a1b3ac6..3f114377 100644 --- a/conf/igenomes.config +++ b/conf/igenomes.config @@ -36,6 +36,14 @@ params { macs_gsize = "2.7e9" blacklist = "${projectDir}/assets/blacklists/hg38-blacklist.bed" } + 'CHM13' { + fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/WholeGenomeFasta/genome.fa" + bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/BWAIndex/" + bwamem2 = "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/BWAmem2Index/" + gtf = "${params.igenomes_base}/Homo_sapiens/NCBI/CHM13/Annotation/Genes/genes.gtf" + gff = "ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/009/914/755/GCF_009914755.1_T2T-CHM13v2.0/GCF_009914755.1_T2T-CHM13v2.0_genomic.gff.gz" + mito_name = "chrM" + } 'GRCm38' { fasta = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/WholeGenomeFasta/genome.fa" bwa = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BWAIndex/version0.6.0/" diff --git a/conf/test_full.config b/conf/test_full.config index 81242116..fba83f97 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -10,6 +10,8 @@ ---------------------------------------------------------------------------------------- */ +cleanup = true + params { config_profile_name = 'Full test profile' config_profile_description = 'Full test dataset to check pipeline function' diff --git a/docs/usage.md b/docs/usage.md index 4c40ab67..19411bb6 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -71,6 +71,29 @@ work # Directory containing the nextflow working files # Other nextflow hidden files, eg. history of pipeline runs and old logs. ``` +If you wish to repeatedly use the same parameters for multiple runs, rather than specifying each flag in the command, you can specify these in a params file. + +Pipeline settings can be provided in a `yaml` or `json` file via `-params-file `. + +> ⚠️ Do not use `-c ` to specify parameters as this will result in errors. Custom config files specified with `-c` must only be used for [tuning process resource specifications](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources), other infrastructural tweaks (such as output directories), or module arguments (args). +> The above pipeline run specified with a params file in yaml format: + +```bash +nextflow run nf-core/proteinfold -profile docker -params-file params.yaml +``` + +with `params.yaml` containing: + +```yaml +input: './samplesheet.csv' +outdir: './results/' +genome: 'GRCh37' +input: 'data' +<...> +``` + +You can also generate such `YAML`/`JSON` files via [nf-core/launch](https://nf-co.re/launch). + ### Updating the pipeline When you run the above command, Nextflow automatically pulls the pipeline code from GitHub and stores it as a cached version. When running the pipeline after this, it will always use the cached version if available - even if the pipeline has been updated since. To make sure that you're running the latest version of the pipeline, make sure that you regularly update the cached version of the pipeline: @@ -87,6 +110,10 @@ First, go to the [nf-core/proteinfold releases page](https://github.com/nf-core/ This version number will be logged in reports when you run the pipeline, so that you'll know what you used when you look back in the future. For example, at the bottom of the MultiQC reports. +To further assist in reproducbility, you can use share and re-use [parameter files](#running-the-pipeline) to repeat pipeline runs with the same settings without having to write out a command with every single parameter. + +> πŸ’‘ If you wish to share such profile (such as upload as supplementary material for academic publications), make sure to NOT include cluster specific paths to files, nor institutional specific profiles. + ## Core Nextflow arguments > **NB:** These options are part of Nextflow and use a _single_ hyphen (pipeline parameters use a double-hyphen). @@ -95,7 +122,7 @@ This version number will be logged in reports when you run the pipeline, so that Use this parameter to choose a configuration profile. Profiles can give configuration presets for different compute environments. -Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Podman, Shifter, Charliecloud, Conda) - see below. +Several generic profiles are bundled with the pipeline which instruct the pipeline to use software packaged using different methods (Docker, Singularity, Podman, Shifter, Charliecloud, Apptainer, Conda) - see below. > We highly recommend the use of Docker or Singularity containers for full pipeline reproducibility, however when this is not possible, Conda is also supported. @@ -119,8 +146,10 @@ If `-profile` is not specified, the pipeline will run locally and expect all sof - A generic configuration profile to be used with [Shifter](https://nersc.gitlab.io/development/shifter/how-to-use/) - `charliecloud` - A generic configuration profile to be used with [Charliecloud](https://hpc.github.io/charliecloud/) +- `apptainer` + - A generic configuration profile to be used with [Apptainer](https://apptainer.org/) - `conda` - - A generic configuration profile to be used with [Conda](https://conda.io/docs/). Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker, Singularity, Podman, Shifter or Charliecloud. + - A generic configuration profile to be used with [Conda](https://conda.io/docs/). Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker, Singularity, Podman, Shifter, Charliecloud, or Apptainer. ### `-resume` @@ -138,102 +167,19 @@ Specify the path to a specific config file (this is a core Nextflow command). Se Whilst the default requirements set within the pipeline will hopefully work for most people and with most input data, you may find that you want to customise the compute resources that the pipeline requests. Each step in the pipeline has a default set of requirements for number of CPUs, memory and time. For most of the steps in the pipeline, if the job exits with any of the error codes specified [here](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/conf/base.config#L18) it will automatically be resubmitted with higher requests (2 x original, then 3 x original). If it still fails after the third attempt then the pipeline execution is stopped. -For example, if the nf-core/rnaseq pipeline is failing after multiple re-submissions of the `STAR_ALIGN` process due to an exit code of `137` this would indicate that there is an out of memory issue: - -```console -[62/149eb0] NOTE: Process `NFCORE_RNASEQ:RNASEQ:ALIGN_STAR:STAR_ALIGN (WT_REP1)` terminated with an error exit status (137) -- Execution is retried (1) -Error executing process > 'NFCORE_RNASEQ:RNASEQ:ALIGN_STAR:STAR_ALIGN (WT_REP1)' - -Caused by: - Process `NFCORE_RNASEQ:RNASEQ:ALIGN_STAR:STAR_ALIGN (WT_REP1)` terminated with an error exit status (137) - -Command executed: - STAR \ - --genomeDir star \ - --readFilesIn WT_REP1_trimmed.fq.gz \ - --runThreadN 2 \ - --outFileNamePrefix WT_REP1. \ - - -Command exit status: - 137 - -Command output: - (empty) - -Command error: - .command.sh: line 9: 30 Killed STAR --genomeDir star --readFilesIn WT_REP1_trimmed.fq.gz --runThreadN 2 --outFileNamePrefix WT_REP1. -Work dir: - /home/pipelinetest/work/9d/172ca5881234073e8d76f2a19c88fb - -Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` -``` - -#### For beginners - -A first step to bypass this error, you could try to increase the amount of CPUs, memory, and time for the whole pipeline. Therefor you can try to increase the resource for the parameters `--max_cpus`, `--max_memory`, and `--max_time`. Based on the error above, you have to increase the amount of memory. Therefore you can go to the [parameter documentation of rnaseq](https://nf-co.re/rnaseq/3.9/parameters) and scroll down to the `show hidden parameter` button to get the default value for `--max_memory`. In this case 128GB, you than can try to run your pipeline again with `--max_memory 200GB -resume` to skip all process, that were already calculated. If you can not increase the resource of the complete pipeline, you can try to adapt the resource for a single process as mentioned below. - -#### Advanced option on process level - -To bypass this error you would need to find exactly which resources are set by the `STAR_ALIGN` process. The quickest way is to search for `process STAR_ALIGN` in the [nf-core/rnaseq Github repo](https://github.com/nf-core/rnaseq/search?q=process+STAR_ALIGN). -We have standardised the structure of Nextflow DSL2 pipelines such that all module files will be present in the `modules/` directory and so, based on the search results, the file we want is `modules/nf-core/star/align/main.nf`. -If you click on the link to that file you will notice that there is a `label` directive at the top of the module that is set to [`label process_high`](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/modules/nf-core/software/star/align/main.nf#L9). -The [Nextflow `label`](https://www.nextflow.io/docs/latest/process.html#label) directive allows us to organise workflow processes in separate groups which can be referenced in a configuration file to select and configure subset of processes having similar computing requirements. -The default values for the `process_high` label are set in the pipeline's [`base.config`](https://github.com/nf-core/rnaseq/blob/4c27ef5610c87db00c3c5a3eed10b1d161abf575/conf/base.config#L33-L37) which in this case is defined as 72GB. -Providing you haven't set any other standard nf-core parameters to **cap** the [maximum resources](https://nf-co.re/usage/configuration#max-resources) used by the pipeline then we can try and bypass the `STAR_ALIGN` process failure by creating a custom config file that sets at least 72GB of memory, in this case increased to 100GB. -The custom config below can then be provided to the pipeline via the [`-c`](#-c) parameter as highlighted in previous sections. - -```nextflow -process { - withName: 'NFCORE_RNASEQ:RNASEQ:ALIGN_STAR:STAR_ALIGN' { - memory = 100.GB - } -} -``` - -> **NB:** We specify the full process name i.e. `NFCORE_RNASEQ:RNASEQ:ALIGN_STAR:STAR_ALIGN` in the config file because this takes priority over the short name (`STAR_ALIGN`) and allows existing configuration using the full process name to be correctly overridden. -> -> If you get a warning suggesting that the process selector isn't recognised check that the process name has been specified correctly. - -### Updating containers (advanced users) - -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: +To change the resource requests, please see the [max resources](https://nf-co.re/docs/usage/configuration#max-resources) and [tuning workflow resources](https://nf-co.re/docs/usage/configuration#tuning-workflow-resources) section of the nf-core website. - ```nextflow - process { - withName: PANGOLIN { - container = 'quay.io/biocontainers/pangolin:3.0.5--pyhdfd78af_0' - } - } - ``` +### Custom Containers - - For Singularity: +In some cases you may wish to change which container or conda environment a step of the pipeline uses for a particular tool. By default nf-core pipelines use containers and software from the [biocontainers](https://biocontainers.pro/) or [bioconda](https://bioconda.github.io/) projects. However in some cases the pipeline specified version maybe out of date. - ```nextflow - process { - withName: PANGOLIN { - container = 'https://depot.galaxyproject.org/singularity/pangolin:3.0.5--pyhdfd78af_0' - } - } - ``` +To use a different container from the default container or conda environment specified in a pipeline, please see the [updating tool versions](https://nf-co.re/docs/usage/configuration#updating-tool-versions) section of the nf-core website. - - For Conda: +### Custom Tool Arguments - ```nextflow - process { - withName: PANGOLIN { - conda = 'bioconda::pangolin=3.0.5' - } - } - ``` +A pipeline might not always support every possible argument or option of a particular tool used in pipeline. Fortunately, nf-core pipelines provide some freedom to users to insert additional parameters that the pipeline does not include by default. -> **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. +To learn how to provide additional arguments to a particular tool of the pipeline, please see the [customising tool arguments](https://nf-co.re/docs/usage/configuration#customising-tool-arguments) section of the nf-core website. ### nf-core/configs diff --git a/lib/NfcoreSchema.groovy b/lib/NfcoreSchema.groovy index 33cd4f6e..9b34804d 100755 --- a/lib/NfcoreSchema.groovy +++ b/lib/NfcoreSchema.groovy @@ -2,6 +2,7 @@ // This file holds several functions used to perform JSON parameter validation, help and summary rendering for the nf-core pipeline template. // +import nextflow.Nextflow import org.everit.json.schema.Schema import org.everit.json.schema.loader.SchemaLoader import org.everit.json.schema.ValidationException @@ -83,6 +84,7 @@ class NfcoreSchema { 'stub-run', 'test', 'w', + 'with-apptainer', 'with-charliecloud', 'with-conda', 'with-dag', @@ -177,7 +179,7 @@ class NfcoreSchema { } if (has_error) { - System.exit(1) + Nextflow.error('Exiting!') } } diff --git a/lib/WorkflowMain.groovy b/lib/WorkflowMain.groovy index ddae1253..acaf5539 100755 --- a/lib/WorkflowMain.groovy +++ b/lib/WorkflowMain.groovy @@ -2,6 +2,8 @@ // This file holds several functions specific to the main.nf workflow in the nf-core/proteinfold pipeline // +import nextflow.Nextflow + class WorkflowMain { // @@ -21,7 +23,7 @@ class WorkflowMain { // // Generate help string // - public static String help(workflow, params, log) { + public static String help(workflow, params) { def command = "nextflow run ${workflow.manifest.name} --input samplesheet.csv --genome GRCh37 -profile docker" def help_string = '' help_string += NfcoreTemplate.logo(workflow, params.monochrome_logs) @@ -34,7 +36,7 @@ class WorkflowMain { // // Generate parameter summary log string // - public static String paramsSummaryLog(workflow, params, log) { + public static String paramsSummaryLog(workflow, params) { def summary_log = '' summary_log += NfcoreTemplate.logo(workflow, params.monochrome_logs) summary_log += NfcoreSchema.paramsSummaryLog(workflow, params) @@ -49,7 +51,7 @@ class WorkflowMain { public static void initialise(workflow, params, log) { // Print help to screen if required if (params.help) { - log.info help(workflow, params, log) + log.info help(workflow, params) System.exit(0) } @@ -61,7 +63,7 @@ class WorkflowMain { } // Print parameter summary log to screen - log.info paramsSummaryLog(workflow, params, log) + log.info paramsSummaryLog(workflow, params) // Validate workflow parameters via the JSON schema if (params.validate_params) { @@ -81,8 +83,7 @@ class WorkflowMain { // Check input has been provided if (!params.input) { - log.error "Please provide an input samplesheet to the pipeline e.g. '--input samplesheet.csv'" - System.exit(1) + Nextflow.error("Please provide an input samplesheet to the pipeline e.g. '--input samplesheet.csv'") } } // diff --git a/lib/WorkflowProteinfold.groovy b/lib/WorkflowProteinfold.groovy index 5e6d86e9..332225b5 100755 --- a/lib/WorkflowProteinfold.groovy +++ b/lib/WorkflowProteinfold.groovy @@ -2,6 +2,7 @@ // This file holds several functions specific to the workflow/proteinfold.nf in the nf-core/proteinfold pipeline // +import nextflow.Nextflow import groovy.text.SimpleTemplateEngine class WorkflowProteinfold { @@ -14,8 +15,7 @@ class WorkflowProteinfold { if (!params.fasta) { - log.error "Genome fasta file not specified with e.g. '--fasta genome.fa' or via a detectable config file." - System.exit(1) + Nextflow.error "Genome fasta file not specified with e.g. '--fasta genome.fa' or via a detectable config file." } } @@ -61,17 +61,19 @@ class WorkflowProteinfold { def description_html = engine.createTemplate(methods_text).make(meta) return description_html - }// + } + + // // Exit pipeline if incorrect --genome key provided // private static void genomeExistsError(params, log) { if (params.genomes && params.genome && !params.genomes.containsKey(params.genome)) { - log.error "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + def error_string = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + " Genome '${params.genome}' not found in any config files provided to the pipeline.\n" + " Currently, the available genome keys are:\n" + " ${params.genomes.keySet().join(", ")}\n" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - System.exit(1) + Nextflow.error(error_string) } } } diff --git a/main.nf b/main.nf index 6b1b2983..c07174fb 100644 --- a/main.nf +++ b/main.nf @@ -4,7 +4,6 @@ nf-core/proteinfold ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Github : https://github.com/nf-core/proteinfold - Website: https://nf-co.re/proteinfold Slack : https://nfcore.slack.com/channels/proteinfold ---------------------------------------------------------------------------------------- diff --git a/modules.json b/modules.json index 76d36142..2ff0eb2d 100644 --- a/modules.json +++ b/modules.json @@ -7,7 +7,7 @@ "nf-core": { "custom/dumpsoftwareversions": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "76cc4938c1f6ea5c7d83fed1eeffc146787f9543", "installed_by": ["modules"] }, "fastqc": { @@ -17,7 +17,7 @@ }, "multiqc": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "f2d63bd5b68925f98f572eed70993d205cc694b7", "installed_by": ["modules"] } } diff --git a/modules/local/samplesheet_check.nf b/modules/local/samplesheet_check.nf index ad6022c0..58027d71 100644 --- a/modules/local/samplesheet_check.nf +++ b/modules/local/samplesheet_check.nf @@ -5,7 +5,7 @@ process SAMPLESHEET_CHECK { conda "conda-forge::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' }" + 'biocontainers/python:3.8.3' }" input: path samplesheet diff --git a/modules/nf-core/custom/dumpsoftwareversions/main.nf b/modules/nf-core/custom/dumpsoftwareversions/main.nf index 3df21765..800a6099 100644 --- a/modules/nf-core/custom/dumpsoftwareversions/main.nf +++ b/modules/nf-core/custom/dumpsoftwareversions/main.nf @@ -2,10 +2,10 @@ process CUSTOM_DUMPSOFTWAREVERSIONS { label 'process_single' // Requires `pyyaml` which does not have a dedicated container but is in the MultiQC container - conda "bioconda::multiqc=1.13" + conda "bioconda::multiqc=1.14" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.13--pyhdfd78af_0' : - 'quay.io/biocontainers/multiqc:1.13--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.14--pyhdfd78af_0' : + 'quay.io/biocontainers/multiqc:1.14--pyhdfd78af_0' }" input: path versions diff --git a/modules/nf-core/custom/dumpsoftwareversions/meta.yml b/modules/nf-core/custom/dumpsoftwareversions/meta.yml index 60b546a0..c32657de 100644 --- a/modules/nf-core/custom/dumpsoftwareversions/meta.yml +++ b/modules/nf-core/custom/dumpsoftwareversions/meta.yml @@ -1,7 +1,9 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/yaml-schema.json name: custom_dumpsoftwareversions description: Custom module used to dump software versions within the nf-core pipeline template keywords: - custom + - dump - version tools: - custom: diff --git a/modules/nf-core/multiqc/main.nf b/modules/nf-core/multiqc/main.nf index 68f66bea..4b604749 100644 --- a/modules/nf-core/multiqc/main.nf +++ b/modules/nf-core/multiqc/main.nf @@ -1,10 +1,10 @@ process MULTIQC { label 'process_single' - conda "bioconda::multiqc=1.13" + conda "bioconda::multiqc=1.14" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/multiqc:1.13--pyhdfd78af_0' : - 'quay.io/biocontainers/multiqc:1.13--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/multiqc:1.14--pyhdfd78af_0' : + 'quay.io/biocontainers/multiqc:1.14--pyhdfd78af_0' }" input: path multiqc_files, stageAs: "?/*" diff --git a/modules/nf-core/multiqc/meta.yml b/modules/nf-core/multiqc/meta.yml index ebc29b27..f93b5ee5 100644 --- a/modules/nf-core/multiqc/meta.yml +++ b/modules/nf-core/multiqc/meta.yml @@ -1,3 +1,4 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/yaml-schema.json name: MultiQC description: Aggregate results from bioinformatics analyses across many samples into a single report keywords: @@ -37,7 +38,7 @@ output: description: MultiQC report file pattern: "multiqc_report.html" - data: - type: dir + type: directory description: MultiQC data dir pattern: "multiqc_data" - plots: diff --git a/nextflow.config b/nextflow.config index d709b78a..6a1e9a3f 100644 --- a/nextflow.config +++ b/nextflow.config @@ -78,7 +78,11 @@ try { profiles { - debug { process.beforeScript = 'echo $HOSTNAME' } + debug { + dumpHashes = true + process.beforeScript = 'echo $HOSTNAME' + cleanup = false + } conda { conda.enabled = true docker.enabled = false @@ -86,6 +90,7 @@ profiles { podman.enabled = false shifter.enabled = false charliecloud.enabled = false + apptainer.enabled = false } mamba { conda.enabled = true @@ -95,14 +100,18 @@ profiles { podman.enabled = false shifter.enabled = false charliecloud.enabled = false + apptainer.enabled = false } docker { docker.enabled = true + docker.registry = 'quay.io' docker.userEmulation = true + conda.enabled = false singularity.enabled = false podman.enabled = false shifter.enabled = false charliecloud.enabled = false + apptainer.enabled = false } arm { docker.runOptions = '-u $(id -u):$(id -g) --platform=linux/amd64' @@ -110,31 +119,49 @@ profiles { singularity { singularity.enabled = true singularity.autoMounts = true + conda.enabled = false docker.enabled = false podman.enabled = false shifter.enabled = false charliecloud.enabled = false + apptainer.enabled = false } podman { podman.enabled = true + podman.registry = 'quay.io' + conda.enabled = false docker.enabled = false singularity.enabled = false shifter.enabled = false charliecloud.enabled = false + apptainer.enabled = false } shifter { shifter.enabled = true + conda.enabled = false docker.enabled = false singularity.enabled = false podman.enabled = false charliecloud.enabled = false + apptainer.enabled = false } charliecloud { charliecloud.enabled = true + conda.enabled = false docker.enabled = false singularity.enabled = false podman.enabled = false shifter.enabled = false + apptainer.enabled = false + } + apptainer { + apptainer.enabled = true + conda.enabled = false + docker.enabled = false + singularity.enabled = false + podman.enabled = false + shifter.enabled = false + charliecloud.enabled = false } gitpod { executor.name = 'local' @@ -193,7 +220,7 @@ manifest { description = """Protein 3D structure prediction pipeline""" mainScript = 'main.nf' nextflowVersion = '!>=22.10.1' - version = '1.0dev' + version = '1.1.0dev' doi = '' } diff --git a/tower.yml b/tower.yml new file mode 100644 index 00000000..787aedfe --- /dev/null +++ b/tower.yml @@ -0,0 +1,5 @@ +reports: + multiqc_report.html: + display: "MultiQC HTML report" + samplesheet.csv: + display: "Auto-created samplesheet with collated metadata and FASTQ paths" From 1d93b5c08b88f3f1ef01d2b4d09dddc7ba3fc9c9 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Fri, 28 Apr 2023 19:00:43 +0200 Subject: [PATCH 012/269] Create esmfold module and workflow --- modules/local/run_esmfold.nf | 49 +++++++++++ workflows/esmfold.nf | 166 +++++++++++++++++++++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 modules/local/run_esmfold.nf create mode 100644 workflows/esmfold.nf diff --git a/modules/local/run_esmfold.nf b/modules/local/run_esmfold.nf new file mode 100644 index 00000000..f48e2db9 --- /dev/null +++ b/modules/local/run_esmfold.nf @@ -0,0 +1,49 @@ +process RUN_ESMFOLD { + tag "$meta.id" + label 'process_medium' + + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'docker://athbaltzis/esmfold:v0.1' : + 'athbaltzis/esmfold:v0.1' }" + + input: + tuple val(meta), path(fasta) + + output: + path ("${fasta.baseName}*.pdb"), emit: pdb + path ("${fasta.baseName}_plddt_mqc.tsv"), emit: multiqc + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def VERSION = '1.0.3' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + + """ + esm-fold \ + -i ${fasta} \ + -o \$PWD \ + $args + + awk '{print \$6"\\t"\$11}' "${fasta.baseName}"*.pdb | uniq > "${fasta.baseName}"_plddt_mqc.tsv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + esm-fold: $VERSION + END_VERSIONS + """ + + stub: + def VERSION = '1.0.3' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + """ + touch ./"${fasta.baseName}".pdb + touch ./"${fasta.baseName}"_mqc.tsv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + esm-fold: $VERSION + END_VERSIONS + """ +} diff --git a/workflows/esmfold.nf b/workflows/esmfold.nf new file mode 100644 index 00000000..6ff82ffa --- /dev/null +++ b/workflows/esmfold.nf @@ -0,0 +1,166 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + VALIDATE INPUTS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +def summary_params = NfcoreSchema.paramsSummaryMap(workflow, params) + +// Validate input parameters +WorkflowEsmfold.initialise(params, log) + +// Check input path parameters to see if they exist +def checkPathParamList = [ + params.input +] +for (param in checkPathParamList) { if (param) { file(param, checkIfExists: true) } } + +// Check mandatory parameters +if (params.input) { ch_input = file(params.input) } else { exit 1, 'Input file not specified!' } + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CONFIG FILES +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +ch_multiqc_config = Channel.fromPath("$projectDir/assets/multiqc_config.yml", checkIfExists: true) +ch_multiqc_custom_config = params.multiqc_config ? Channel.fromPath( params.multiqc_config, checkIfExists: true ) : Channel.empty() +ch_multiqc_logo = params.multiqc_logo ? Channel.fromPath( params.multiqc_logo, checkIfExists: true ) : Channel.empty() +ch_multiqc_custom_methods_description = params.multiqc_methods_description ? file(params.multiqc_methods_description, checkIfExists: true) : file("$projectDir/assets/methods_description_template.yml", checkIfExists: true) + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT LOCAL MODULES/SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// SUBWORKFLOW: Consisting of a mix of local and nf-core/modules +// +include { INPUT_CHECK } from '../subworkflows/local/input_check' +//include { PREPARE_COLABFOLD_DBS } from '../subworkflows/local/prepare_colabfold_dbs' + +// +// MODULE: Local to the pipeline +// +include { RUN_ESMFOLD } from '../modules/local/run_esmfold' +include { MULTIFASTA_TO_CSV } from '../modules/local/multifasta_to_csv' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT NF-CORE MODULES/SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// MODULE: Installed directly from nf-core/modules +// +include { MULTIQC } from '../modules/nf-core/multiqc/main' +include { CUSTOM_DUMPSOFTWAREVERSIONS } from '../modules/nf-core/custom/dumpsoftwareversions/main' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// Info required for completion email and summary +def multiqc_report = [] + +workflow ESMFOLD { + + ch_versions = Channel.empty() + + // + // SUBWORKFLOW: Read in samplesheet, validate and stage input files + // + INPUT_CHECK ( + ch_input + ) + ch_versions = ch_versions.mix(INPUT_CHECK.out.versions) + + PREPARE_ESMFOLD( ) + ch_versions = ch_versions.mix(PREPARE_ESMFOLD.out.versions) + + // + // MODULE: Run colabfold + // + if (params.colabfold_model_preset != 'AlphaFold2-ptm') { + MULTIFASTA_TO_CSV( + INPUT_CHECK.out.fastas + ) + ch_versions = ch_versions.mix(MULTIFASTA_TO_CSV.out.versions) + RUN_ESMFOLD( + MULTIFASTA_TO_CSV.out.input_csv, + params.colabfold_model_preset, + PREPARE_COLABFOLD_DBS.out.params, + [], + [], + params.num_recycle + ) + ch_versions = ch_versions.mix(RUN_ESMFOLD.out.versions) + } else { + RUN_ESMFOLD( + INPUT_CHECK.out.fastas, + params.colabfold_model_preset, + PREPARE_COLABFOLD_DBS.out.params, + [], + [], + params.num_recycle + ) + ch_versions = ch_versions.mix(COLABFOLD_BATCH.out.versions) + } + + // + // MODULE: Pipeline reporting + // + CUSTOM_DUMPSOFTWAREVERSIONS ( + ch_versions.unique().collectFile(name: 'collated_versions.yml') + ) + + // + // MODULE: MultiQC + // + workflow_summary = WorkflowColabfold.paramsSummaryMultiqc(workflow, summary_params) + ch_workflow_summary = Channel.value(workflow_summary) + + methods_description = WorkflowColabfold.methodsDescriptionText(workflow, ch_multiqc_custom_methods_description) + ch_methods_description = Channel.value(methods_description) + + ch_multiqc_files = Channel.empty() + ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) + ch_multiqc_files = ch_multiqc_files.mix(ch_methods_description.collectFile(name: 'methods_description_mqc.yaml')) + ch_multiqc_files = ch_multiqc_files.mix(CUSTOM_DUMPSOFTWAREVERSIONS.out.mqc_yml.collect()) + ch_multiqc_files = ch_multiqc_files.mix(COLABFOLD_BATCH.out.multiqc.collect()) + + MULTIQC ( + ch_multiqc_files.collect(), + ch_multiqc_config.toList(), + ch_multiqc_custom_config.toList(), + ch_multiqc_logo.toList() + ) + multiqc_report = MULTIQC.out.report.toList() +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + COMPLETION EMAIL AND SUMMARY +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow.onComplete { + if (params.email || params.email_on_fail) { + NfcoreTemplate.email(workflow, params, summary_params, projectDir, log, multiqc_report) + } + NfcoreTemplate.summary(workflow, params, log) + if (params.hook_url) { + NfcoreTemplate.IM_notification(workflow, params, summary_params, projectDir, log) + } +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ From 54c3d167b8bbabdaad27afb0e2cd67f1a33fcf07 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 08:57:38 +0200 Subject: [PATCH 013/269] Reduce pdb_mmcif excessive symlinking --- conf/dbs.config | 2 +- subworkflows/local/prepare_alphafold2_dbs.nf | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/conf/dbs.config b/conf/dbs.config index e186f9c0..3f116951 100644 --- a/conf/dbs.config +++ b/conf/dbs.config @@ -28,7 +28,7 @@ params { alphafold2_params_path = "${params.alphafold2_db}/alphafold_params_*/*" mgnify_path = "${params.alphafold2_db}/mgnify/*" pdb70_path = "${params.alphafold2_db}/pdb70/**" - pdb_mmcif_path = "${params.alphafold2_db}/pdb_mmcif/**" + pdb_mmcif_path = "${params.alphafold2_db}/pdb_mmcif/*" uniclust30_path = "${params.alphafold2_db}/uniclust30/**" uniref90_path = "${params.alphafold2_db}/uniref90/*" pdb_seqres_path = "${params.alphafold2_db}/pdb_seqres/*" diff --git a/subworkflows/local/prepare_alphafold2_dbs.nf b/subworkflows/local/prepare_alphafold2_dbs.nf index 20adc42e..f4653019 100644 --- a/subworkflows/local/prepare_alphafold2_dbs.nf +++ b/subworkflows/local/prepare_alphafold2_dbs.nf @@ -36,9 +36,11 @@ workflow PREPARE_ALPHAFOLD2_DBS { ch_params = file( params.alphafold2_params_path ) ch_mgnify = file( params.mgnify_path ) - ch_pdb70 = file( params.pdb70_path, type: 'any' ) - ch_mmcif = file( params.pdb_mmcif_path, type: 'any' ) - ch_uniclust30 = file( params.uniclust30_path, type: 'any' ) + ch_pdb70 = file( params.pdb70_path, type: 'dir' ) + ch_mmcif_files = file( params.pdb_mmcif_path, type: 'dir' ) + ch_mmcif_obsolete = file( params.pdb_mmcif_path, type: 'file' ) + ch_mmcif = ch_mmcif_files + ch_mmcif_obsolete + ch_uniclust30 = file( params.uniclust30_path, type: 'dir' ) ch_uniref90 = file( params.uniref90_path ) ch_pdb_seqres = file( params.pdb_seqres_path ) ch_uniprot = file( params.uniprot_path ) From 202edfde79a96266b2de96b3b428791723ab27fa Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 09:11:11 +0200 Subject: [PATCH 014/269] Update documentation --- docs/usage.md | 291 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) diff --git a/docs/usage.md b/docs/usage.md index c04ff2c0..26c2ccbd 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -63,6 +63,161 @@ nextflow run nf-core/proteinfold \ --use_gpu \ -profile ``` +If you specify the `--alphafold2_db ` parameter, the directory structure of your path should be like this: +``` +β”œβ”€β”€ mgnify +β”‚Β Β  └── mgy_clusters_2018_12.fa +β”œβ”€β”€ alphafold_params_2022-03-02 +β”‚Β Β  β”œβ”€β”€ LICENSE +β”‚Β Β  β”œβ”€β”€ params_model_1_multimer.npz +β”‚Β Β  β”œβ”€β”€ params_model_1_multimer_v2.npz +β”‚Β Β  β”œβ”€β”€ params_model_1.npz +β”‚Β Β  β”œβ”€β”€ params_model_1_ptm.npz +β”‚Β Β  β”œβ”€β”€ params_model_2_multimer.npz +β”‚Β Β  β”œβ”€β”€ params_model_2_multimer_v2.npz +β”‚Β Β  β”œβ”€β”€ params_model_2.npz +β”‚Β Β  β”œβ”€β”€ params_model_2_ptm.npz +β”‚Β Β  β”œβ”€β”€ params_model_3_multimer.npz +β”‚Β Β  β”œβ”€β”€ params_model_3_multimer_v2.npz +β”‚Β Β  β”œβ”€β”€ params_model_3.npz +β”‚Β Β  β”œβ”€β”€ params_model_3_ptm.npz +β”‚Β Β  β”œβ”€β”€ params_model_4_multimer.npz +β”‚Β Β  β”œβ”€β”€ params_model_4_multimer_v2.npz +β”‚Β Β  β”œβ”€β”€ params_model_4.npz +β”‚Β Β  β”œβ”€β”€ params_model_4_ptm.npz +β”‚Β Β  β”œβ”€β”€ params_model_5_multimer.npz +β”‚Β Β  β”œβ”€β”€ params_model_5_multimer_v2.npz +β”‚Β Β  β”œβ”€β”€ params_model_5.npz +β”‚Β Β  └── params_model_5_ptm.npz +β”œβ”€β”€ pdb70 +β”‚Β Β  └── pdb70_from_mmcif_200916 +β”‚Β Β  β”œβ”€β”€ md5sum +β”‚Β Β  β”œβ”€β”€ pdb70_a3m.ffdata +β”‚Β Β  β”œβ”€β”€ pdb70_a3m.ffindex +β”‚Β Β  β”œβ”€β”€ pdb70_clu.tsv +β”‚Β Β  β”œβ”€β”€ pdb70_cs219.ffdata +β”‚Β Β  β”œβ”€β”€ pdb70_cs219.ffindex +β”‚Β Β  β”œβ”€β”€ pdb70_hhm.ffdata +β”‚Β Β  β”œβ”€β”€ pdb70_hhm.ffindex +β”‚Β Β  └── pdb_filter.dat +β”œβ”€β”€ pdb_mmcif +β”‚Β Β  β”œβ”€β”€ mmcif_files +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1g6g.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1go4.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1isn.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1kuu.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1m7s.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1mwq.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1ni5.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1qgd.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1tp9.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1wa9.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1ye5.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 1yhl.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2bjd.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2bo9.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2e7t.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2fyg.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2j0q.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2jcq.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2m4k.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2n9o.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2nsx.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2w4u.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2wd6.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2wh5.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2wji.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 2yu3.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3cw2.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3d45.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3gnz.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3j0a.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3jaj.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3mzo.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3nrn.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3piv.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3pof.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3pvd.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3q45.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3qh6.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3rg2.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3sxe.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3uai.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3uid.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3wae.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3wt1.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3wtr.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3wy2.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 3zud.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4bix.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4bzx.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4c1n.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4cej.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4chm.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4fzo.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4i1f.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4ioa.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4j6o.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4m9q.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4mal.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4nhe.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4o2w.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4pzo.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4qlx.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4uex.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4zm4.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 4zv1.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5aj4.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5frs.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5hwo.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5kbk.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5odq.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5u5t.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5wzq.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5x9z.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5xe5.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5ynv.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5yud.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5z5c.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5zb3.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 5zlg.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 6a6i.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 6az3.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 6ban.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 6g1f.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 6ix4.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 6jwp.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 6ng9.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 6ojj.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 6s0x.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 6sg9.cif +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ 6vi4.cif +β”‚Β Β  β”‚Β Β  └── 7sp5.cif +β”‚Β Β  └── obsolete.dat +β”œβ”€β”€ pdb_seqres +β”‚Β Β  └── pdb_seqres.txt +β”œβ”€β”€ small_bfd +β”‚Β Β  └── bfd-first_non_consensus_sequences.fasta +β”œβ”€β”€ uniclust30 +β”‚Β Β  └── uniclust30_2018_08 +β”‚Β Β  β”œβ”€β”€ uniclust30_2018_08_a3m_db -> uniclust30_2018_08_a3m.ffdata +β”‚Β Β  β”œβ”€β”€ uniclust30_2018_08_a3m_db.index +β”‚Β Β  β”œβ”€β”€ uniclust30_2018_08_a3m.ffdata +β”‚Β Β  β”œβ”€β”€ uniclust30_2018_08_a3m.ffindex +β”‚Β Β  β”œβ”€β”€ uniclust30_2018_08.cs219 +β”‚Β Β  β”œβ”€β”€ uniclust30_2018_08_cs219.ffdata +β”‚Β Β  β”œβ”€β”€ uniclust30_2018_08_cs219.ffindex +β”‚Β Β  β”œβ”€β”€ uniclust30_2018_08.cs219.sizes +β”‚Β Β  β”œβ”€β”€ uniclust30_2018_08_hhm_db -> uniclust30_2018_08_hhm.ffdata +β”‚Β Β  β”œβ”€β”€ uniclust30_2018_08_hhm_db.index +β”‚Β Β  β”œβ”€β”€ uniclust30_2018_08_hhm.ffdata +β”‚Β Β  β”œβ”€β”€ uniclust30_2018_08_hhm.ffindex +β”‚Β Β  └── uniclust30_2018_08_md5sum +β”œβ”€β”€ uniprot +β”‚Β Β  └── uniprot.fasta +└── uniref90 + └── uniref90.fasta +``` ```console nextflow run nf-core/proteinfold \ @@ -94,8 +249,144 @@ nextflow run nf-core/proteinfold \ -profile ``` +If you specify the `--colabfold_db ` parameter, the directory structure of your path should be like this: +``` +β”œβ”€β”€ colabfold_envdb_202108 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.0 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.1 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.10 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.11 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.12 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.13 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.14 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.15 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.2 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.3 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.4 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.5 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.6 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.7 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.8 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.9 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.0 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.1 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.10 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.11 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.12 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.13 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.14 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.15 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.2 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.3 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.4 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.5 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.6 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.7 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.8 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.9 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.dbtype +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_aln.index +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.dbtype +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_h +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_h.dbtype +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_h.index +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.idx +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.idx.dbtype +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.idx.index +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.index +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.0 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.1 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.10 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.11 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.12 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.13 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.14 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.15 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.2 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.3 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.4 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.5 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.6 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.7 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.8 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.9 +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.dbtype +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq_h -> colabfold_envdb_202108_db_h +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq_h.dbtype -> colabfold_envdb_202108_db_h.dbtype +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq_h.index -> colabfold_envdb_202108_db_h.index +β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db_seq.index +β”œβ”€β”€ params +β”‚Β Β  β”œβ”€β”€ alphafold_params_2021-07-14 +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ LICENSE +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ params_model_1.npz +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ params_model_1_ptm.npz +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ params_model_2.npz +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ params_model_2_ptm.npz +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ params_model_3.npz +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ params_model_3_ptm.npz +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ params_model_4.npz +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ params_model_4_ptm.npz +β”‚Β Β  β”‚Β Β  β”œβ”€β”€ params_model_5.npz +β”‚Β Β  β”‚Β Β  └── params_model_5_ptm.npz +β”‚Β Β  └── alphafold_params_colab_2022-03-02 +β”‚Β Β  β”œβ”€β”€ LICENSE +β”‚Β Β  β”œβ”€β”€ params_model_1_multimer_v2.npz +β”‚Β Β  β”œβ”€β”€ params_model_1.npz +β”‚Β Β  β”œβ”€β”€ params_model_2_multimer_v2.npz +β”‚Β Β  β”œβ”€β”€ params_model_2.npz +β”‚Β Β  β”œβ”€β”€ params_model_2_ptm.npz +β”‚Β Β  β”œβ”€β”€ params_model_3_multimer_v2.npz +β”‚Β Β  β”œβ”€β”€ params_model_3.npz +β”‚Β Β  β”œβ”€β”€ params_model_4_multimer_v2.npz +β”‚Β Β  β”œβ”€β”€ params_model_4.npz +β”‚Β Β  β”œβ”€β”€ params_model_5_multimer_v2.npz +β”‚Β Β  └── params_model_5.npz +└── uniref30_2202 + β”œβ”€β”€ uniref30_2202_db.0 + β”œβ”€β”€ uniref30_2202_db.1 + β”œβ”€β”€ uniref30_2202_db.2 + β”œβ”€β”€ uniref30_2202_db.3 + β”œβ”€β”€ uniref30_2202_db.4 + β”œβ”€β”€ uniref30_2202_db.5 + β”œβ”€β”€ uniref30_2202_db.6 + β”œβ”€β”€ uniref30_2202_db.7 + β”œβ”€β”€ uniref30_2202_db_aln.0 + β”œβ”€β”€ uniref30_2202_db_aln.1 + β”œβ”€β”€ uniref30_2202_db_aln.2 + β”œβ”€β”€ uniref30_2202_db_aln.3 + β”œβ”€β”€ uniref30_2202_db_aln.4 + β”œβ”€β”€ uniref30_2202_db_aln.5 + β”œβ”€β”€ uniref30_2202_db_aln.6 + β”œβ”€β”€ uniref30_2202_db_aln.7 + β”œβ”€β”€ uniref30_2202_db_aln.dbtype + β”œβ”€β”€ uniref30_2202_db_aln.index + β”œβ”€β”€ uniref30_2202_db.dbtype + β”œβ”€β”€ uniref30_2202_db_h + β”œβ”€β”€ uniref30_2202_db_h.dbtype + β”œβ”€β”€ uniref30_2202_db_h.index + β”œβ”€β”€ uniref30_2202_db.idx + β”œβ”€β”€ uniref30_2202_db.idx.dbtype + β”œβ”€β”€ uniref30_2202_db.idx.index + β”œβ”€β”€ uniref30_2202_db.index + β”œβ”€β”€ uniref30_2202_db_seq.0 + β”œβ”€β”€ uniref30_2202_db_seq.1 + β”œβ”€β”€ uniref30_2202_db_seq.2 + β”œβ”€β”€ uniref30_2202_db_seq.3 + β”œβ”€β”€ uniref30_2202_db_seq.4 + β”œβ”€β”€ uniref30_2202_db_seq.5 + β”œβ”€β”€ uniref30_2202_db_seq.6 + β”œβ”€β”€ uniref30_2202_db_seq.7 + β”œβ”€β”€ uniref30_2202_db_seq.dbtype + β”œβ”€β”€ uniref30_2202_db_seq_h -> uniref30_2202_db_h + β”œβ”€β”€ uniref30_2202_db_seq_h.dbtype -> uniref30_2202_db_h.dbtype + β”œβ”€β”€ uniref30_2202_db_seq_h.index -> uniref30_2202_db_h.index + └── uniref30_2202_db_seq.index +``` + This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles. + + Note that the pipeline will create the following files in your working directory: ```bash From 9c657b0733a8f3a16f30486d6fb0d771f1b4915a Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 09:22:30 +0200 Subject: [PATCH 015/269] Update modules.json --- modules.json | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/modules.json b/modules.json index d4f7f84b..499933af 100644 --- a/modules.json +++ b/modules.json @@ -8,41 +8,55 @@ "aria2": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "custom/dumpsoftwareversions": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "gunzip": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "mmseqs/createindex": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "mmseqs/tsv2exprofiledb": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "multiqc": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "untar": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": [ + "modules" + ], "patch": "modules/nf-core/untar/untar.diff" } } } } } -} +} \ No newline at end of file From 574566293d98af477494071c2e50d2cce91c21bf Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 09:22:41 +0200 Subject: [PATCH 016/269] Update modules.json --- modules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules.json b/modules.json index 499933af..9a42796b 100644 --- a/modules.json +++ b/modules.json @@ -59,4 +59,4 @@ } } } -} \ No newline at end of file +} From dc45259f551b731b147b499449aa69703b1020ec Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 09:27:34 +0200 Subject: [PATCH 017/269] Make prettier happy --- docs/usage.md | 5 +++-- modules.json | 28 +++++++--------------------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 26c2ccbd..c33aaa36 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -63,7 +63,9 @@ nextflow run nf-core/proteinfold \ --use_gpu \ -profile ``` + If you specify the `--alphafold2_db ` parameter, the directory structure of your path should be like this: + ``` β”œβ”€β”€ mgnify β”‚Β Β  └── mgy_clusters_2018_12.fa @@ -250,6 +252,7 @@ nextflow run nf-core/proteinfold \ ``` If you specify the `--colabfold_db ` parameter, the directory structure of your path should be like this: + ``` β”œβ”€β”€ colabfold_envdb_202108 β”‚Β Β  β”œβ”€β”€ colabfold_envdb_202108_db.0 @@ -385,8 +388,6 @@ If you specify the `--colabfold_db ` parameter, the directory structure of your This will launch the pipeline with the `docker` configuration profile. See below for more information about profiles. - - Note that the pipeline will create the following files in your working directory: ```bash diff --git a/modules.json b/modules.json index 9a42796b..d4f7f84b 100644 --- a/modules.json +++ b/modules.json @@ -8,51 +8,37 @@ "aria2": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "custom/dumpsoftwareversions": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "gunzip": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "mmseqs/createindex": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "mmseqs/tsv2exprofiledb": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "multiqc": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "untar": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": [ - "modules" - ], + "installed_by": ["modules"], "patch": "modules/nf-core/untar/untar.diff" } } From f611b41a646dba0e4a740889abad17b482651b6d Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 09:37:23 +0200 Subject: [PATCH 018/269] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cef8643..509dbbfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ Initial release of nf-core/proteinfold, created with the [nf-core](https://nf-co ### Enhancements & fixes -- Add `accelerator` directive to GPU processes when `params.use_gpu` is true. +- [#80] Add `accelerator` directive to GPU processes when `params.use_gpu` is true. -- Support multiline fasta for colabfold multimer predictions +- [#81] Support multiline fasta for colabfold multimer predictions + +- [#89] Fix issue with excessive symlinking in the pdb_mmcif database From 8ddf60734473122c8eb61ff11e1d5481a308f8a7 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 10:06:41 +0200 Subject: [PATCH 019/269] Update dbs.config --- conf/dbs.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/dbs.config b/conf/dbs.config index 3f116951..9a8e0317 100644 --- a/conf/dbs.config +++ b/conf/dbs.config @@ -29,7 +29,7 @@ params { mgnify_path = "${params.alphafold2_db}/mgnify/*" pdb70_path = "${params.alphafold2_db}/pdb70/**" pdb_mmcif_path = "${params.alphafold2_db}/pdb_mmcif/*" - uniclust30_path = "${params.alphafold2_db}/uniclust30/**" + uniclust30_path = "${params.alphafold2_db}/uniclust30/*" uniref90_path = "${params.alphafold2_db}/uniref90/*" pdb_seqres_path = "${params.alphafold2_db}/pdb_seqres/*" uniprot_path = "${params.alphafold2_db}/uniprot/*" From 68dd22d0217988e7452c21d315aa8e41f485abe3 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 14:48:24 +0200 Subject: [PATCH 020/269] Run prettier --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 880713c4..a645203a 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ nextflow run nf-core/proteinfold \ --outdir ``` - The pipeline takes care of downloading the required databases and parameters required by AlphaFold2 and/or Colabfold. In case you have already downloaded the required files, you can skip this step by providing the path using the corresponding parameter [`--alphafold2_db`] or [`--colabfold_db`] +The pipeline takes care of downloading the required databases and parameters required by AlphaFold2 and/or Colabfold. In case you have already downloaded the required files, you can skip this step by providing the path using the corresponding parameter [`--alphafold2_db`] or [`--colabfold_db`] - Typical command to run AlphaFold2 mode: From bc4af2d0ed628262346bbc7a94539ce85db7fbb5 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 16:27:10 +0200 Subject: [PATCH 021/269] Update .github/workflows/awsfulltest.yml Co-authored-by: Jose Espinosa-Carrasco --- .github/workflows/awsfulltest.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index c0f93016..0f5968cc 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -27,9 +27,6 @@ jobs: steps: - name: Launch workflow via tower uses: seqeralabs/action-tower-launch@v1 - # TODO nf-core: You can customise AWS full pipeline tests as required - # Add full size test data (but still relatively small datasets for few samples) - # on the `test_full.config` test runs with only one set of parameters with: workspace_id: ${{ secrets.TOWER_WORKSPACE_ID }} access_token: ${{ secrets.TOWER_ACCESS_TOKEN }} From 84906e906fcf86729bacdf7e77d067357e413db7 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 18:32:59 +0200 Subject: [PATCH 022/269] Add WorkflowEsmofld.groovy --- lib/WorkflowEsmfold.groovy | 58 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 lib/WorkflowEsmfold.groovy diff --git a/lib/WorkflowEsmfold.groovy b/lib/WorkflowEsmfold.groovy new file mode 100644 index 00000000..8b0d755b --- /dev/null +++ b/lib/WorkflowEsmfold.groovy @@ -0,0 +1,58 @@ +// +// This file holds several functions specific to the workflow/proteinfold.nf in the nf-core/proteinfold pipeline +// + +import groovy.text.SimpleTemplateEngine + +class WorkflowEsmfold { + + // + // Check and validate parameters + // + public static void initialise(params, log) { + } + + // + // Get workflow summary for MultiQC + // + public static String paramsSummaryMultiqc(workflow, summary) { + String summary_section = '' + for (group in summary.keySet()) { + def group_params = summary.get(group) // This gets the parameters of that particular group + if (group_params) { + summary_section += "

$group

\n" + summary_section += "
\n" + for (param in group_params.keySet()) { + summary_section += "
$param
${group_params.get(param) ?: 'N/A'}
\n" + } + summary_section += "
\n" + } + } + + String yaml_file_text = "id: '${workflow.manifest.name.replace('/','-')}-summary'\n" + yaml_file_text += "description: ' - this information is collected when the pipeline is started.'\n" + yaml_file_text += "section_name: '${workflow.manifest.name} Workflow Summary'\n" + yaml_file_text += "section_href: 'https://github.com/${workflow.manifest.name}'\n" + yaml_file_text += "plot_type: 'html'\n" + yaml_file_text += "data: |\n" + yaml_file_text += "${summary_section}" + return yaml_file_text + } + + public static String methodsDescriptionText(run_workflow, mqc_methods_yaml) { + // Convert to a named map so can be used as with familar NXF ${workflow} variable syntax in the MultiQC YML file + def meta = [:] + meta.workflow = run_workflow.toMap() + meta["manifest_map"] = run_workflow.manifest.toMap() + + meta["doi_text"] = meta.manifest_map.doi ? "(doi: ${meta.manifest_map.doi})" : "" + meta["nodoi_text"] = meta.manifest_map.doi ? "": "
  • If available, make sure to update the text to include the Zenodo DOI of version of the pipeline used.
  • " + + def methods_text = mqc_methods_yaml.text + + def engine = new SimpleTemplateEngine() + def description_html = engine.createTemplate(methods_text).make(meta) + + return description_html + } +} From 6cc4064ed3e3787459530125b07b1944ec0cf2d1 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 18:46:53 +0200 Subject: [PATCH 023/269] Add modules_esmfold config and fix arguments --- conf/modules_esmfold.config | 23 +++++++++++++++++++++++ modules/local/run_esmfold.nf | 2 ++ 2 files changed, 25 insertions(+) create mode 100644 conf/modules_esmfold.config diff --git a/conf/modules_esmfold.config b/conf/modules_esmfold.config new file mode 100644 index 00000000..230dd343 --- /dev/null +++ b/conf/modules_esmfold.config @@ -0,0 +1,23 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Config file for defining DSL2 per module options and publishing paths +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Available keys to override module options: + 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. +---------------------------------------------------------------------------------------- +*/ + +process { + withName: 'RUN_ESMFOLD' { + ext.args = {params.use_gpu ? '' : '--cpu-only'} + publishDir = [ + path: { "${params.outdir}/esmfold" }, + mode: 'copy', + saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, + pattern: '*.*' + ] + } +} diff --git a/modules/local/run_esmfold.nf b/modules/local/run_esmfold.nf index f48e2db9..6f3607ec 100644 --- a/modules/local/run_esmfold.nf +++ b/modules/local/run_esmfold.nf @@ -8,6 +8,7 @@ process RUN_ESMFOLD { input: tuple val(meta), path(fasta) + path ('./checkpoint') output: path ("${fasta.baseName}*.pdb"), emit: pdb @@ -25,6 +26,7 @@ process RUN_ESMFOLD { esm-fold \ -i ${fasta} \ -o \$PWD \ + -m ./checkpoints $args awk '{print \$6"\\t"\$11}' "${fasta.baseName}"*.pdb | uniq > "${fasta.baseName}"_plddt_mqc.tsv From 6ea60379ae0a0240d9f01fe1928dce8ca4924e5e Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 19:33:13 +0200 Subject: [PATCH 024/269] Update nextflow_schema and nextflow.config --- modules/local/run_esmfold.nf | 4 +++- nextflow.config | 5 ++++- nextflow_schema.json | 22 +++++++++++++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/modules/local/run_esmfold.nf b/modules/local/run_esmfold.nf index 6f3607ec..39837091 100644 --- a/modules/local/run_esmfold.nf +++ b/modules/local/run_esmfold.nf @@ -9,6 +9,7 @@ process RUN_ESMFOLD { input: tuple val(meta), path(fasta) path ('./checkpoint') + val numRec output: path ("${fasta.baseName}*.pdb"), emit: pdb @@ -26,7 +27,8 @@ process RUN_ESMFOLD { esm-fold \ -i ${fasta} \ -o \$PWD \ - -m ./checkpoints + -m ./checkpoints \ + --num-recycles ${numRec} \ $args awk '{print \$6"\\t"\$11}' "${fasta.baseName}"*.pdb | uniq > "${fasta.baseName}"_plddt_mqc.tsv diff --git a/nextflow.config b/nextflow.config index 56b3c01e..ed5dbadb 100644 --- a/nextflow.config +++ b/nextflow.config @@ -11,7 +11,7 @@ params { // Input options input = null - mode = 'alphafold2' // {alphafold2, colabfold} + mode = 'alphafold2' // {alphafold2, colabfold, esmfold} use_gpu = false // Alphafold2 parameters @@ -66,6 +66,9 @@ params { colabfold_db_path = null uniref30_path = null + // Esmfold parameters + num_recycles = 4 + // MultiQC options multiqc_config = null multiqc_title = null diff --git a/nextflow_schema.json b/nextflow_schema.json index dbe9832c..ab1fbc81 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -32,7 +32,7 @@ "type": "string", "default": "alphafold2", "description": "Specifies the mode in which the pipeline will be run", - "enum": ["alphafold2", "colabfold"], + "enum": ["alphafold2", "colabfold", "esmfold"], "fa_icon": "fas fa-cogs" }, "use_gpu": { @@ -155,6 +155,26 @@ } } }, + "esmfold_options": { + "title": "Esmfold options", + "type": "object", + "fa_icon": "fas fa-coins", + "description": "Esmfold options.", + "properties": { + "esmfold_db": { + "type": "string", + "description": "Specifies the PARAMS path used by 'esmfold' mode", + "fa_icon": "fas fa-folder-open" + }, + "num_recycles": { + "type": "integer", + "default": 4, + "description": "Specifies the number of recycles used by Esmfold", + "enum": ["webserver", "local"], + "fa_icon": "fas fa-server" + } + } + }, "institutional_config_options": { "title": "Institutional config options", "type": "object", From c1ca4c3176d75b21f267115885c2fee9abcda2f3 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 20:12:23 +0200 Subject: [PATCH 025/269] Create ESMFOLD workflow --- conf/dbs.config | 8 +++++ nextflow.config | 9 ++++++ nextflow_schema.json | 6 ++++ subworkflows/local/prepare_esmfold_dbs.nf | 36 +++++++++++++++++++++++ workflows/esmfold.nf | 29 ++++++++---------- 5 files changed, 72 insertions(+), 16 deletions(-) create mode 100644 subworkflows/local/prepare_esmfold_dbs.nf diff --git a/conf/dbs.config b/conf/dbs.config index e186f9c0..861ab340 100644 --- a/conf/dbs.config +++ b/conf/dbs.config @@ -46,4 +46,12 @@ params { "AlphaFold2-multimer-v2" : "alphafold_params_colab_2022-03-02", "AlphaFold2-ptm" : "alphafold_params_2021-07-14" ] + + // Esmfold links + esmfold_3B_v1 = 'https://dl.fbaipublicfiles.com/fair-esm/models/esmfold_3B_v1.pt' + esm2_t36_3B_UR50D = 'https://dl.fbaipublicfiles.com/fair-esm/models/esm2_t36_3B_UR50D.pt' + esm2_t36_3B_UR50D_contact_regression = 'https://dl.fbaipublicfiles.com/fair-esm/regression/esm2_t36_3B_UR50D-contact-regression.pt' + + // Esmfold paths + esmfold_params_path = "${params.esmfold_db}/esmfold_params/*" } diff --git a/nextflow.config b/nextflow.config index ed5dbadb..51c21c48 100644 --- a/nextflow.config +++ b/nextflow.config @@ -67,8 +67,17 @@ params { uniref30_path = null // Esmfold parameters + esmfold_model_preset = "monomer" num_recycles = 4 + // Esmfold links + esmfold_3B_v1 = null + esm2_t36_3B_UR50D = null + esm2_t36_3B_UR50D_contact_regression = null + + // Esmfold paths + esmfold_params_path = null + // MultiQC options multiqc_config = null multiqc_title = null diff --git a/nextflow_schema.json b/nextflow_schema.json index ab1fbc81..da68952e 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -172,6 +172,12 @@ "description": "Specifies the number of recycles used by Esmfold", "enum": ["webserver", "local"], "fa_icon": "fas fa-server" + }, + "esmfold_model_preset": { + "type": "string", + "description": "Specifies whether is a 'monomer' or 'multimer' prediction", + "enum": ["monomer","multimer"], + "fa_icon": "fas fa-stream" } } }, diff --git a/subworkflows/local/prepare_esmfold_dbs.nf b/subworkflows/local/prepare_esmfold_dbs.nf new file mode 100644 index 00000000..db8c39d7 --- /dev/null +++ b/subworkflows/local/prepare_esmfold_dbs.nf @@ -0,0 +1,36 @@ +// +// Download all the required Esmfold parameters +// + +include { ARIA2 as ARIA2_ESMFOLD_3B_V1 } from '../../modules/nf-core/aria2/main' +include { ARIA2 as ARIA2_ESM2_T36_3B_UR50D } from '../../modules/nf-core/aria2/main' +include { ARIA2 as ARIA2_ESM2_T36_3B_UR50D_CONTACT_REGRESSION } from '../../modules/nf-core/aria2/main' + + +workflow PREPARE_ESMFOLD_DBS { + main: + ch_versions = Channel.empty() + + + if (params.esmfold_db) { + ch_params = file( params.esmfold_params_path ) + } + else { + ARIA2_ESMFOLD_3B_V1 ( + params.esmfold_3B_v1 + ) + ARIA2_ESM2_T36_3B_UR50D ( + params.esm2_t36_3B_UR50D + ) + ARIA2_ESM2_T36_3B_UR50D_CONTACT_REGRESSION ( + params.esm2_t36_3B_UR50D_contact_regression + ) + ch_params = ARIA2_ESMFOLD_3B_V1.out.downloaded_file.mix(ARIA2_ESM2_T36_3B_UR50D.out.downloaded_file,ARIA2_ESM2_T36_3B_UR50D_CONTACT_REGRESSION.out.downloaded_file) + ch_versions = ch_versions.mix(ARIA2_ESMFOLD_3B_V1.out.versions) + + } + + emit: + params = ch_params + versions = ch_versions +} diff --git a/workflows/esmfold.nf b/workflows/esmfold.nf index 6ff82ffa..7381ff9b 100644 --- a/workflows/esmfold.nf +++ b/workflows/esmfold.nf @@ -11,7 +11,8 @@ WorkflowEsmfold.initialise(params, log) // Check input path parameters to see if they exist def checkPathParamList = [ - params.input + params.input, + params.esmfold_db ] for (param in checkPathParamList) { if (param) { file(param, checkIfExists: true) } } @@ -39,7 +40,7 @@ ch_multiqc_custom_methods_description = params.multiqc_methods_description ? fil // SUBWORKFLOW: Consisting of a mix of local and nf-core/modules // include { INPUT_CHECK } from '../subworkflows/local/input_check' -//include { PREPARE_COLABFOLD_DBS } from '../subworkflows/local/prepare_colabfold_dbs' +include { PREPARE_ESMFOLD_DBS } from '../subworkflows/local/prepare_esmfold_dbs' // // MODULE: Local to the pipeline @@ -84,32 +85,28 @@ workflow ESMFOLD { ch_versions = ch_versions.mix(PREPARE_ESMFOLD.out.versions) // - // MODULE: Run colabfold + // MODULE: Run esmfold // - if (params.colabfold_model_preset != 'AlphaFold2-ptm') { + if (params.esmfold_model_preset != 'monomer') { MULTIFASTA_TO_CSV( INPUT_CHECK.out.fastas ) ch_versions = ch_versions.mix(MULTIFASTA_TO_CSV.out.versions) RUN_ESMFOLD( MULTIFASTA_TO_CSV.out.input_csv, - params.colabfold_model_preset, - PREPARE_COLABFOLD_DBS.out.params, - [], - [], - params.num_recycle + PREPARE_ESMFOLD_DBS.out.params, + params.num_recycles ) ch_versions = ch_versions.mix(RUN_ESMFOLD.out.versions) } else { RUN_ESMFOLD( INPUT_CHECK.out.fastas, - params.colabfold_model_preset, - PREPARE_COLABFOLD_DBS.out.params, + PREPARE_ESMFOLD_DBS.out.params, [], [], - params.num_recycle + params.num_recycles ) - ch_versions = ch_versions.mix(COLABFOLD_BATCH.out.versions) + ch_versions = ch_versions.mix(RUN_ESMFOLD.out.versions) } // @@ -122,17 +119,17 @@ workflow ESMFOLD { // // MODULE: MultiQC // - workflow_summary = WorkflowColabfold.paramsSummaryMultiqc(workflow, summary_params) + workflow_summary = WorkflowEsmfold.paramsSummaryMultiqc(workflow, summary_params) ch_workflow_summary = Channel.value(workflow_summary) - methods_description = WorkflowColabfold.methodsDescriptionText(workflow, ch_multiqc_custom_methods_description) + methods_description = WorkflowEsmfold.methodsDescriptionText(workflow, ch_multiqc_custom_methods_description) ch_methods_description = Channel.value(methods_description) ch_multiqc_files = Channel.empty() ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')) ch_multiqc_files = ch_multiqc_files.mix(ch_methods_description.collectFile(name: 'methods_description_mqc.yaml')) ch_multiqc_files = ch_multiqc_files.mix(CUSTOM_DUMPSOFTWAREVERSIONS.out.mqc_yml.collect()) - ch_multiqc_files = ch_multiqc_files.mix(COLABFOLD_BATCH.out.multiqc.collect()) + ch_multiqc_files = ch_multiqc_files.mix(RUN_ESMFOLD.out.multiqc.collect()) MULTIQC ( ch_multiqc_files.collect(), From 22cd017656bb6d9848050f6d0e53587f4c3ba8fb Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Tue, 2 May 2023 20:23:40 +0200 Subject: [PATCH 026/269] Add test profiles for esmfold --- .github/workflows/awsfulltest.yml | 2 ++ conf/test_esmfold.config | 33 ++++++++++++++++++++++++++ conf/test_full_esmfold.config | 22 +++++++++++++++++ conf/test_full_esmfold_multimer.config | 22 +++++++++++++++++ nextflow.config | 2 ++ 5 files changed, 81 insertions(+) create mode 100644 conf/test_esmfold.config create mode 100644 conf/test_full_esmfold.config create mode 100644 conf/test_full_esmfold_multimer.config diff --git a/.github/workflows/awsfulltest.yml b/.github/workflows/awsfulltest.yml index 0ea067af..0ebb2fcb 100644 --- a/.github/workflows/awsfulltest.yml +++ b/.github/workflows/awsfulltest.yml @@ -23,6 +23,8 @@ jobs: "_colabfold_local", "_colabfold_webserver", "_colabfold_multimer", + "_esmfold", + "_esmfold_multimer" ] steps: - name: Launch workflow via tower diff --git a/conf/test_esmfold.config b/conf/test_esmfold.config new file mode 100644 index 00000000..38202ac8 --- /dev/null +++ b/conf/test_esmfold.config @@ -0,0 +1,33 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + Use as follows: + nextflow run nf-core/proteinfold -profile test, --outdir +---------------------------------------------------------------------------------------- +*/ + +stubRun = true + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Limit resources so that this can run on GitHub Actions + max_cpus = 2 + max_memory = '6.GB' + max_time = '6.h' + + // Input data to test esmfold + mode = 'esmfold' + esmfold_db = "${projectDir}/assets/dummy_db_dir" + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet.csv' +} + +process { + withName: 'RUN_ESMFOLD' { + container = 'quay.io/biocontainers/gawk:5.1.0' + } +} + diff --git a/conf/test_full_esmfold.config b/conf/test_full_esmfold.config new file mode 100644 index 00000000..b7edbe46 --- /dev/null +++ b/conf/test_full_esmfold.config @@ -0,0 +1,22 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running full-size tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a full size pipeline test. + + Use as follows: + nextflow run nf-core/proteinfold -profile test_full_colabfold_webserver, --outdir + +---------------------------------------------------------------------------------------- +*/ + +params { + config_profile_name = 'Full test profile for esmfold monomer' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Input data for full test of esmfold monomer + mode = 'esmfold' + esmfold_model_preset = 'monomer' + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet.csv' + esmfold_db = 's3://nf-core-awsmegatests/proteinfold/input_data/db/esmfold' +} diff --git a/conf/test_full_esmfold_multimer.config b/conf/test_full_esmfold_multimer.config new file mode 100644 index 00000000..ee42df0a --- /dev/null +++ b/conf/test_full_esmfold_multimer.config @@ -0,0 +1,22 @@ +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running full-size tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a full size pipeline test. + + Use as follows: + nextflow run nf-core/proteinfold -profile test_full_colabfold_webserver, --outdir + +---------------------------------------------------------------------------------------- +*/ + +params { + config_profile_name = 'Full test profile for esmfold multimer' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Input data for full test of esmfold multimer + mode = 'esmfold' + esmfold_model_preset = 'multimer' + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet.csv' + esmfold_db = 's3://nf-core-awsmegatests/proteinfold/input_data/db/esmfold' +} diff --git a/nextflow.config b/nextflow.config index 51c21c48..4b822768 100644 --- a/nextflow.config +++ b/nextflow.config @@ -215,6 +215,8 @@ profiles { test_full_colabfold_local { includeConfig 'conf/test_full_colabfold_local.config' } test_full_colabfold_webserver { includeConfig 'conf/test_full_colabfold_webserver.config' } test_full_colabfold_multimer { includeConfig 'conf/test_full_colabfold_webserver_multimer.config' } + test_full_esmfold { includeConfig 'conf/test_full_esmfold.config' } + test_full_esmfold_multimer { includeConfig 'conf/test_full_esmfold_multimer.config' } } // Export these variables to prevent local Python/R libraries from conflicting with those in the container From 9284d5ebe86091524fd7bc55e182ea0950d3249b Mon Sep 17 00:00:00 2001 From: Leila Mansouri Date: Wed, 3 May 2023 11:06:22 +0200 Subject: [PATCH 027/269] Added changes to run with new versions of colabfold (v.1.5.2) and alphafold (v.2.3.2) --- conf/dbs.config | 39 ++++++++++--------- conf/test_full_colabfold_local.config | 2 +- conf/test_full_colabfold_webserver.config | 2 +- ...t_full_colabfold_webserver_multimer.config | 2 +- modules/local/colabfold_batch.nf | 8 ++-- modules/local/mmseqs_colabfoldsearch.nf | 11 +++--- modules/local/run_alphafold2.nf | 6 +-- modules/local/run_alphafold2_msa.nf | 9 +++-- modules/local/run_alphafold2_pred.nf | 6 +-- nextflow.config | 13 ++++--- nextflow_schema.json | 16 ++++---- subworkflows/local/prepare_alphafold2_dbs.nf | 16 +++++--- workflows/alphafold2.nf | 6 +-- 13 files changed, 74 insertions(+), 62 deletions(-) diff --git a/conf/dbs.config b/conf/dbs.config index 9a8e0317..ea668852 100644 --- a/conf/dbs.config +++ b/conf/dbs.config @@ -9,18 +9,18 @@ params { // AlphaFold2 links - bfd = 'https://storage.googleapis.com/alphafold-databases/casp14_versions/bfd_metaclust_clu_complete_id30_c90_final_seq.sorted_opt.tar.gz' - small_bfd = 'https://storage.googleapis.com/alphafold-databases/reduced_dbs/bfd-first_non_consensus_sequences.fasta.gz' - alphafold2_params = 'https://storage.googleapis.com/alphafold/alphafold_params_2022-03-02.tar' - mgnify = 'https://storage.googleapis.com/alphafold-databases/casp14_versions/mgy_clusters_2018_12.fa.gz' - pdb70 = 'http://wwwuser.gwdg.de/~compbiol/data/hhsuite/databases/hhsuite_dbs/old-releases/pdb70_from_mmcif_200916.tar.gz' - pdb_mmcif = 'rsync.rcsb.org::ftp_data/structures/divided/mmCIF/' //'rsync.rcsb.org::ftp_data/structures/divided/mmCIF/' ftp.pdbj.org::ftp_data/structures/divided/mmCIF/ rsync.ebi.ac.uk::pub/databases/pdb/data/structures/divided/mmCIF/ - pdb_obsolete = 'ftp://ftp.wwpdb.org/pub/pdb/data/status/obsolete.dat' - uniclust30 = 'https://storage.googleapis.com/alphafold-databases/casp14_versions/uniclust30_2018_08_hhsuite.tar.gz' - uniref90 = 'ftp://ftp.uniprot.org/pub/databases/uniprot/uniref/uniref90/uniref90.fasta.gz' - pdb_seqres = 'ftp://ftp.wwpdb.org/pub/pdb/derived_data/pdb_seqres.txt' - uniprot_sprot = 'ftp://ftp.ebi.ac.uk/pub/databases/uniprot/current_release/knowledgebase/complete/uniprot_sprot.fasta.gz' - uniprot_trembl = 'ftp://ftp.ebi.ac.uk/pub/databases/uniprot/current_release/knowledgebase/complete/uniprot_trembl.fasta.gz' + bfd = 'https://storage.googleapis.com/alphafold-databases/casp14_versions/bfd_metaclust_clu_complete_id30_c90_final_seq.sorted_opt.tar.gz' + small_bfd = 'https://storage.googleapis.com/alphafold-databases/reduced_dbs/bfd-first_non_consensus_sequences.fasta.gz' + alphafold2_params = 'https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar' + mgnify = 'https://storage.googleapis.com/alphafold-databases/casp14_versions/mgy_clusters_2018_12.fa.gz' + pdb70 = 'http://wwwuser.gwdg.de/~compbiol/data/hhsuite/databases/hhsuite_dbs/old-releases/pdb70_from_mmcif_200916.tar.gz' + pdb_mmcif = 'rsync.rcsb.org::ftp_data/structures/divided/mmCIF/' //'rsync.rcsb.org::ftp_data/structures/divided/mmCIF/' ftp.pdbj.org::ftp_data/structures/divided/mmCIF/ rsync.ebi.ac.uk::pub/databases/pdb/data/structures/divided/mmCIF/ + pdb_obsolete = 'ftp://ftp.wwpdb.org/pub/pdb/data/status/obsolete.dat' + uniref30_alphafold2 = 'https://storage.googleapis.com/alphafold-databases/v2.3/UniRef30_2021_03.tar.gz' + uniref90 = 'ftp://ftp.uniprot.org/pub/databases/uniprot/uniref/uniref90/uniref90.fasta.gz' + pdb_seqres = 'ftp://ftp.wwpdb.org/pub/pdb/derived_data/pdb_seqres.txt' + uniprot_sprot = 'ftp://ftp.ebi.ac.uk/pub/databases/uniprot/current_release/knowledgebase/complete/uniprot_sprot.fasta.gz' + uniprot_trembl = 'ftp://ftp.ebi.ac.uk/pub/databases/uniprot/current_release/knowledgebase/complete/uniprot_trembl.fasta.gz' // Alphafold paths bfd_path = "${params.alphafold2_db}/bfd/*" @@ -29,21 +29,22 @@ params { mgnify_path = "${params.alphafold2_db}/mgnify/*" pdb70_path = "${params.alphafold2_db}/pdb70/**" pdb_mmcif_path = "${params.alphafold2_db}/pdb_mmcif/*" - uniclust30_path = "${params.alphafold2_db}/uniclust30/*" + uniref30_alphafold2_path = "${params.alphafold2_db}/uniref30/**" uniref90_path = "${params.alphafold2_db}/uniref90/*" pdb_seqres_path = "${params.alphafold2_db}/pdb_seqres/*" uniprot_path = "${params.alphafold2_db}/uniprot/*" // Colabfold links - colabfold_db_link = 'http://wwwuser.gwdg.de/~compbiol/colabfold/colabfold_envdb_202108.tar.gz' - uniref30 = 'https://wwwuser.gwdg.de/~compbiol/colabfold/uniref30_2202.tar.gz' + colabfold_db_link = 'http://wwwuser.gwdg.de/~compbiol/colabfold/colabfold_envdb_202108.tar.gz' + uniref30_colabfold_link = 'https://wwwuser.gwdg.de/~compbiol/colabfold/uniref30_2202.tar.gz' // Colabfold paths colabfold_db_path = "${params.colabfold_db}/colabfold_envdb_202108" - uniref30_path = "${params.colabfold_db}/uniref30_2202" + uniref30_colabfold_path = "${params.colabfold_db}/uniref30_2202" colabfold_alphafold2_params_tags = [ - "AlphaFold2-multimer-v1" : "alphafold_params_colab_2021-10-27", - "AlphaFold2-multimer-v2" : "alphafold_params_colab_2022-03-02", - "AlphaFold2-ptm" : "alphafold_params_2021-07-14" + "alphafold2_multimer_v1" : "alphafold_params_colab_2021-10-27", + "alphafold2_multimer_v2" : "alphafold_params_colab_2022-03-02", + "alphafold2_multimer_v3" : "alphafold_params_colab_2022-12-06", + "alphafold2_ptm" : "alphafold_params_2021-07-14" ] } diff --git a/conf/test_full_colabfold_local.config b/conf/test_full_colabfold_local.config index e34ff152..44dd270f 100644 --- a/conf/test_full_colabfold_local.config +++ b/conf/test_full_colabfold_local.config @@ -18,7 +18,7 @@ params { // Input data to test colabfold with a local server analysis mode = 'colabfold' colabfold_server = 'local' - colabfold_model_preset = 'AlphaFold2-ptm' + colabfold_model_preset = 'alphafold2_ptm' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet.csv' colabfold_db = 's3://ngi-igenomes/test-data/proteinfold/db/colabfold_mini' } diff --git a/conf/test_full_colabfold_webserver.config b/conf/test_full_colabfold_webserver.config index b54347de..8c503b09 100644 --- a/conf/test_full_colabfold_webserver.config +++ b/conf/test_full_colabfold_webserver.config @@ -17,7 +17,7 @@ params { // Input data for full test of colabfold with Colabfold server mode = 'colabfold' colabfold_server = 'webserver' - colabfold_model_preset = 'AlphaFold2-ptm' + colabfold_model_preset = 'alphafold2_ptm' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet.csv' colabfold_db = 's3://ngi-igenomes/test-data/proteinfold/db/colabfold_mini' } diff --git a/conf/test_full_colabfold_webserver_multimer.config b/conf/test_full_colabfold_webserver_multimer.config index 8b50a4a1..99063c91 100644 --- a/conf/test_full_colabfold_webserver_multimer.config +++ b/conf/test_full_colabfold_webserver_multimer.config @@ -17,7 +17,7 @@ params { // Input data for full test of colabfold with Colabfold server mode = 'colabfold' colabfold_server = 'webserver' - colabfold_model_preset = 'AlphaFold2-multimer-v2' + colabfold_model_preset = 'alphafold2_multimer_v3' input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet_multimer.csv' colabfold_db = 's3://ngi-igenomes/test-data/proteinfold/db/colabfold_mini' } diff --git a/modules/local/colabfold_batch.nf b/modules/local/colabfold_batch.nf index e6312fed..b693bb65 100644 --- a/modules/local/colabfold_batch.nf +++ b/modules/local/colabfold_batch.nf @@ -3,8 +3,8 @@ process COLABFOLD_BATCH { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://nfcore/proteinfold_colabfold:1.0.0' : - 'nfcore/proteinfold_colabfold:1.0.0' }" + 'docker://lmansouri/colabfold:no_download' : + 'lmansouri/colabfold:no_download' }" input: tuple val(meta), path(fasta) @@ -24,7 +24,7 @@ process COLABFOLD_BATCH { script: def args = task.ext.args ?: '' - def VERSION = '1.2.0' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + def VERSION = '1.5.2' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. """ ln -r -s params/alphafold_params_*/* params/ @@ -45,7 +45,7 @@ process COLABFOLD_BATCH { """ stub: - def VERSION = '1.2.0' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + def VERSION = '1.5.2' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. """ touch ./"${fasta.baseName}"_colabfold.pdb touch ./"${fasta.baseName}"_mqc.png diff --git a/modules/local/mmseqs_colabfoldsearch.nf b/modules/local/mmseqs_colabfoldsearch.nf index 55cb17b1..6ecbb59e 100644 --- a/modules/local/mmseqs_colabfoldsearch.nf +++ b/modules/local/mmseqs_colabfoldsearch.nf @@ -3,8 +3,9 @@ process MMSEQS_COLABFOLDSEARCH { label 'process_high_memory' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://nfcore/proteinfold_colabfold:1.0.0' : - 'nfcore/proteinfold_colabfold:1.0.0' }" + 'docker://lmansouri/colabfold:no_download' : + 'lmansouri/colabfold:no_download' }" + input: tuple val(meta), path(fasta) @@ -21,13 +22,13 @@ process MMSEQS_COLABFOLDSEARCH { script: def args = task.ext.args ?: '' - def VERSION = '1.2.0' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + def VERSION = '1.5.2' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. """ ln -r -s $uniref30/uniref30_* ./db ln -r -s $colabfold_db/colabfold_envdb* ./db - /colabfold_batch/colabfold-conda/bin/colabfold_search \\ + /localcolabfold/colabfold-conda/bin/colabfold_search \\ $args \\ --threads $task.cpus ${fasta} \\ ./db \\ @@ -42,7 +43,7 @@ process MMSEQS_COLABFOLDSEARCH { """ stub: - def VERSION = '1.2.0' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. + def VERSION = '1.5.2' // WARN: Version information not provided by tool on CLI. Please update this string when bumping container versions. """ touch ${meta.id}.a3m diff --git a/modules/local/run_alphafold2.nf b/modules/local/run_alphafold2.nf index 559ad4e5..8013beb2 100644 --- a/modules/local/run_alphafold2.nf +++ b/modules/local/run_alphafold2.nf @@ -6,8 +6,8 @@ process RUN_ALPHAFOLD2 { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://nfcore/proteinfold_alphafold2_standard:1.0.0' : - 'nfcore/proteinfold_alphafold2_standard:1.0.0' }" + 'docker://lmansouri/alphafold-standard:2.0.0' : + 'lmansouri/alphafold-standard:2.0.0' }" input: tuple val(meta), path(fasta) @@ -19,7 +19,7 @@ process RUN_ALPHAFOLD2 { path ('mgnify/*') path ('pdb70/*') path ('pdb_mmcif/*') - path ('uniclust30/*') + path ('uniref30/*') path ('uniref90/*') path ('pdb_seqres/*') path ('uniprot/*') diff --git a/modules/local/run_alphafold2_msa.nf b/modules/local/run_alphafold2_msa.nf index 78278810..164b35d1 100644 --- a/modules/local/run_alphafold2_msa.nf +++ b/modules/local/run_alphafold2_msa.nf @@ -6,8 +6,9 @@ process RUN_ALPHAFOLD2_MSA { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://nfcore/proteinfold_alphafold2_msa:1.0.0' : - 'nfcore/proteinfold_alphafold2_msa:1.0.0' }" + 'docker://lmansouri/alphafold-msa:2.0.0' : + 'lmansouri/alphafold-msa:2.0.0' }" + input: tuple val(meta), path(fasta) @@ -19,7 +20,7 @@ process RUN_ALPHAFOLD2_MSA { path ('mgnify/*') path ('pdb70/*') path ('pdb_mmcif/*') - path ('uniclust30/*') + path ('uniref30/*') path ('uniref90/*') path ('pdb_seqres/*') path ('uniprot/*') @@ -34,7 +35,7 @@ process RUN_ALPHAFOLD2_MSA { script: def args = task.ext.args ?: '' - def db_preset = db_preset ? "full_dbs --bfd_database_path=./bfd/bfd_metaclust_clu_complete_id30_c90_final_seq.sorted_opt --uniclust30_database_path=./uniclust30/uniclust30_2018_08/uniclust30_2018_08" : + def db_preset = db_preset ? "full_dbs --bfd_database_path=./bfd/bfd_metaclust_clu_complete_id30_c90_final_seq.sorted_opt --uniref30_database_path=./uniref30/" : "reduced_dbs --small_bfd_database_path=./small_bfd/bfd-first_non_consensus_sequences.fasta" if (alphafold2_model_preset == 'multimer') { alphafold2_model_preset += " --pdb_seqres_database_path=./pdb_seqres/pdb_seqres.txt --uniprot_database_path=./uniprot/uniprot.fasta " diff --git a/modules/local/run_alphafold2_pred.nf b/modules/local/run_alphafold2_pred.nf index 43143b9d..7ec1c6e2 100644 --- a/modules/local/run_alphafold2_pred.nf +++ b/modules/local/run_alphafold2_pred.nf @@ -6,8 +6,8 @@ process RUN_ALPHAFOLD2_PRED { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://nfcore/proteinfold_alphafold2_split:1.0.0' : - 'nfcore/proteinfold_alphafold2_split:1.0.0' }" + 'docker://lmansouri/alphafold-split:2.0.0' : + 'lmansouri/alphafold-split:2.0.0' }" input: tuple val(meta), path(fasta) @@ -19,7 +19,7 @@ process RUN_ALPHAFOLD2_PRED { path ('mgnify/*') path ('pdb70/*') path ('pdb_mmcif/*') - path ('uniclust30/*') + path ('uniref30/*') path ('uniref90/*') path ('pdb_seqres/*') path ('uniprot/*') diff --git a/nextflow.config b/nextflow.config index b3edd8ca..2ea1841e 100644 --- a/nextflow.config +++ b/nextflow.config @@ -29,7 +29,7 @@ params { pdb70 = null pdb_mmcif = null pdb_obsolete = null - uniclust30 = null + uniref30_alphafold = null uniref90 = null pdb_seqres = null uniprot_sprot = null @@ -42,14 +42,14 @@ params { mgnify_path = null pdb70_path = null pdb_mmcif_path = null - uniclust30_path = null + uniref30_alphafold_path = null uniref90_path = null pdb_seqres_path = null uniprot_path = null // Colabfold parameters colabfold_server = "webserver" - colabfold_model_preset = "AlphaFold2-ptm" // {AlphaFold2-ptm,AlphaFold2-multimer-v1,AlphaFold2-multimer-v2} + colabfold_model_preset = "alphafold2_ptm" // {'auto', 'alphafold2', 'alphafold2_ptm', 'alphafold2_multimer_v1', 'alphafold2_multimer_v2', 'alphafold2_multimer_v3'} num_recycle = 3 use_amber = true colabfold_db = null @@ -60,11 +60,11 @@ params { // Colabfold links colabfold_db_link = null - uniref30 = null + uniref30_colabfold_path = null // Colabfold paths colabfold_db_path = null - uniref30_path = null + uniref30_0_colabfold_path = null // MultiQC options multiqc_config = null @@ -320,3 +320,6 @@ def check_max(obj, type) { } } } + + + diff --git a/nextflow_schema.json b/nextflow_schema.json index dbe9832c..cf7fc87b 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -113,9 +113,9 @@ }, "colabfold_model_preset": { "type": "string", - "default": "AlphaFold2-ptm", + "default": "alphafold2_ptm", "description": "Model preset for 'colabfold' mode", - "enum": ["AlphaFold2-ptm", "AlphaFold2-multimer-v1", "AlphaFold2-multimer-v2"], + "enum": ["auto", "alphafold2", "alphafold2_ptm", "alphafold2_multimer_v1", "alphafold2_multimer_v2", "alphafold2_multimer_v3"], "fa_icon": "fas fa-stream" }, "num_recycle": { @@ -258,7 +258,7 @@ }, "alphafold2_params": { "type": "string", - "default": "https://storage.googleapis.com/alphafold/alphafold_params_2022-03-02.tar", + "default": "https://storage.googleapis.com/alphafold/alphafold_params_2022-12-06.tar", "description": "Link to the Alphafold2 parameters", "fa_icon": "fas fa-link" }, @@ -286,9 +286,9 @@ "description": "Link to the PDV obsolete database", "fa_icon": "fas fa-link" }, - "uniclust30": { + "uniref30_alphafold2": { "type": "string", - "default": "https://storage.googleapis.com/alphafold-databases/casp14_versions/uniclust30_2018_08_hhsuite.tar.gz", + "default": "https://storage.googleapis.com/alphafold-databases/v2.3/UniRef30_2021_03.tar.gz", "description": "Link to the Uniclust30 database", "fa_icon": "fas fa-link" }, @@ -354,9 +354,9 @@ "description": "Path to the PDB mmCIF database", "fa_icon": "fas fa-folder-open" }, - "uniclust30_path": { + "uniref30_alphafold2_path": { "type": "string", - "description": "Path to the Uniclust30 database", + "description": "Path to the Uniref30 database", "fa_icon": "fas fa-folder-open" }, "uniref90_path": { @@ -412,7 +412,7 @@ "description": "Link to the Colabfold database", "fa_icon": "fas fa-folder-open" }, - "uniref30_path": { + "uniref30_colabfold_path": { "type": "string", "description": "Link to the UniRef30 database", "fa_icon": "fas fa-folder-open" diff --git a/subworkflows/local/prepare_alphafold2_dbs.nf b/subworkflows/local/prepare_alphafold2_dbs.nf index f4653019..ba583e54 100644 --- a/subworkflows/local/prepare_alphafold2_dbs.nf +++ b/subworkflows/local/prepare_alphafold2_dbs.nf @@ -36,11 +36,17 @@ workflow PREPARE_ALPHAFOLD2_DBS { ch_params = file( params.alphafold2_params_path ) ch_mgnify = file( params.mgnify_path ) +<<<<<<< Updated upstream ch_pdb70 = file( params.pdb70_path, type: 'dir' ) ch_mmcif_files = file( params.pdb_mmcif_path, type: 'dir' ) ch_mmcif_obsolete = file( params.pdb_mmcif_path, type: 'file' ) ch_mmcif = ch_mmcif_files + ch_mmcif_obsolete ch_uniclust30 = file( params.uniclust30_path, type: 'dir' ) +======= + ch_pdb70 = file( params.pdb70_path, type: 'any' ) + ch_mmcif = file( params.pdb_mmcif_path, type: 'any' ) + ch_uniref30 = file( params.uniref30_alphafold_path, type: 'any' ) +>>>>>>> Stashed changes ch_uniref90 = file( params.uniref90_path ) ch_pdb_seqres = file( params.pdb_seqres_path ) ch_uniprot = file( params.uniprot_path ) @@ -86,11 +92,11 @@ workflow PREPARE_ALPHAFOLD2_DBS { ch_mmcif = DOWNLOAD_PDBMMCIF.out.ch_db ch_versions = ch_versions.mix(DOWNLOAD_PDBMMCIF.out.versions) - ARIA2_UNICLUST30( - params.uniclust30 + ARIA2_UNIREF30( + params.uniref30 ) - ch_uniclust30 = ARIA2_UNICLUST30.out.db - ch_versions = ch_versions.mix(ARIA2_UNICLUST30.out.versions) + ch_uniref30 = ARIA2_UNICLUST30.out.db + ch_versions = ch_versions.mix(ARIA2_UNIref30.out.versions) ARIA2_UNIREF90( params.uniref90 @@ -127,7 +133,7 @@ workflow PREPARE_ALPHAFOLD2_DBS { mgnify = ch_mgnify pdb70 = ch_pdb70 pdb_mmcif = ch_mmcif - uniclust30 = ch_uniclust30 + uniref30 = ch_uniref30 uniref90 = ch_uniref90 pdb_seqres = ch_pdb_seqres uniprot = ch_uniprot diff --git a/workflows/alphafold2.nf b/workflows/alphafold2.nf index 67a53a60..72809296 100644 --- a/workflows/alphafold2.nf +++ b/workflows/alphafold2.nf @@ -117,7 +117,7 @@ workflow ALPHAFOLD2 { PREPARE_ALPHAFOLD2_DBS.out.mgnify, PREPARE_ALPHAFOLD2_DBS.out.pdb70, PREPARE_ALPHAFOLD2_DBS.out.pdb_mmcif, - PREPARE_ALPHAFOLD2_DBS.out.uniclust30, + PREPARE_ALPHAFOLD2_DBS.out.uniref30, PREPARE_ALPHAFOLD2_DBS.out.uniref90, PREPARE_ALPHAFOLD2_DBS.out.pdb_seqres, PREPARE_ALPHAFOLD2_DBS.out.uniprot, @@ -138,7 +138,7 @@ workflow ALPHAFOLD2 { PREPARE_ALPHAFOLD2_DBS.out.mgnify, PREPARE_ALPHAFOLD2_DBS.out.pdb70, PREPARE_ALPHAFOLD2_DBS.out.pdb_mmcif, - PREPARE_ALPHAFOLD2_DBS.out.uniclust30, + PREPARE_ALPHAFOLD2_DBS.out.uniref30, PREPARE_ALPHAFOLD2_DBS.out.uniref90, PREPARE_ALPHAFOLD2_DBS.out.pdb_seqres, PREPARE_ALPHAFOLD2_DBS.out.uniprot @@ -156,7 +156,7 @@ workflow ALPHAFOLD2 { PREPARE_ALPHAFOLD2_DBS.out.mgnify, PREPARE_ALPHAFOLD2_DBS.out.pdb70, PREPARE_ALPHAFOLD2_DBS.out.pdb_mmcif, - PREPARE_ALPHAFOLD2_DBS.out.uniclust30, + PREPARE_ALPHAFOLD2_DBS.out.uniref30, PREPARE_ALPHAFOLD2_DBS.out.uniref90, PREPARE_ALPHAFOLD2_DBS.out.pdb_seqres, PREPARE_ALPHAFOLD2_DBS.out.uniprot, From ae120c206c0e55e3c2178cf9a62418eeaf8bf5f0 Mon Sep 17 00:00:00 2001 From: l-mansouri Date: Wed, 3 May 2023 11:38:19 +0200 Subject: [PATCH 028/269] Added changes to run with new versions of colabfold (v.1.5.2) and alphafold (v.2.3.2) --- modules.json | 30 ++++++++++++++------ nextflow.config | 8 +++--- nextflow_schema.json | 2 +- subworkflows/local/prepare_alphafold2_dbs.nf | 6 ---- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/modules.json b/modules.json index 4bc44595..d22eb6f5 100644 --- a/modules.json +++ b/modules.json @@ -8,41 +8,55 @@ "aria2": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "custom/dumpsoftwareversions": { "branch": "master", "git_sha": "76cc4938c1f6ea5c7d83fed1eeffc146787f9543", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "gunzip": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "mmseqs/createindex": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "mmseqs/tsv2exprofiledb": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "multiqc": { "branch": "master", "git_sha": "f2d63bd5b68925f98f572eed70993d205cc694b7", - "installed_by": ["modules"] + "installed_by": [ + "modules" + ] }, "untar": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": ["modules"], + "installed_by": [ + "modules" + ], "patch": "modules/nf-core/untar/untar.diff" } } } } } -} +} \ No newline at end of file diff --git a/nextflow.config b/nextflow.config index 2ea1841e..3e18b6e7 100644 --- a/nextflow.config +++ b/nextflow.config @@ -29,7 +29,7 @@ params { pdb70 = null pdb_mmcif = null pdb_obsolete = null - uniref30_alphafold = null + uniref30_alphafold2 = null uniref90 = null pdb_seqres = null uniprot_sprot = null @@ -42,7 +42,7 @@ params { mgnify_path = null pdb70_path = null pdb_mmcif_path = null - uniref30_alphafold_path = null + uniref30_alphafold2_path = null uniref90_path = null pdb_seqres_path = null uniprot_path = null @@ -60,11 +60,11 @@ params { // Colabfold links colabfold_db_link = null - uniref30_colabfold_path = null + uniref30_colabfold_link = null // Colabfold paths colabfold_db_path = null - uniref30_0_colabfold_path = null + uniref30_colabfold_path = null // MultiQC options multiqc_config = null diff --git a/nextflow_schema.json b/nextflow_schema.json index cf7fc87b..aecc6b20 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -388,7 +388,7 @@ "description": "Link to the Colabfold database", "fa_icon": "fas fa-link" }, - "uniref30": { + "uniref30_colabfold_link": { "type": "string", "default": "http://wwwuser.gwdg.de/~compbiol/colabfold/uniref30_2103.tar.gz", "description": "Link to the UniRef30 database", diff --git a/subworkflows/local/prepare_alphafold2_dbs.nf b/subworkflows/local/prepare_alphafold2_dbs.nf index ba583e54..49e7a844 100644 --- a/subworkflows/local/prepare_alphafold2_dbs.nf +++ b/subworkflows/local/prepare_alphafold2_dbs.nf @@ -36,17 +36,11 @@ workflow PREPARE_ALPHAFOLD2_DBS { ch_params = file( params.alphafold2_params_path ) ch_mgnify = file( params.mgnify_path ) -<<<<<<< Updated upstream ch_pdb70 = file( params.pdb70_path, type: 'dir' ) ch_mmcif_files = file( params.pdb_mmcif_path, type: 'dir' ) ch_mmcif_obsolete = file( params.pdb_mmcif_path, type: 'file' ) ch_mmcif = ch_mmcif_files + ch_mmcif_obsolete - ch_uniclust30 = file( params.uniclust30_path, type: 'dir' ) -======= - ch_pdb70 = file( params.pdb70_path, type: 'any' ) - ch_mmcif = file( params.pdb_mmcif_path, type: 'any' ) ch_uniref30 = file( params.uniref30_alphafold_path, type: 'any' ) ->>>>>>> Stashed changes ch_uniref90 = file( params.uniref90_path ) ch_pdb_seqres = file( params.pdb_seqres_path ) ch_uniprot = file( params.uniprot_path ) From b759d588eb5182e2f7442bed5668f45f2390695a Mon Sep 17 00:00:00 2001 From: l-mansouri Date: Wed, 3 May 2023 11:54:09 +0200 Subject: [PATCH 029/269] Added changes to run with new versions of colabfold (v.1.5.2) and alphafold (v.2.3.2) --- modules.json | 30 ++++++-------------- nextflow_schema.json | 9 +++++- subworkflows/local/prepare_alphafold2_dbs.nf | 2 +- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/modules.json b/modules.json index d22eb6f5..4bc44595 100644 --- a/modules.json +++ b/modules.json @@ -8,55 +8,41 @@ "aria2": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "custom/dumpsoftwareversions": { "branch": "master", "git_sha": "76cc4938c1f6ea5c7d83fed1eeffc146787f9543", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "gunzip": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "mmseqs/createindex": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "mmseqs/tsv2exprofiledb": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "multiqc": { "branch": "master", "git_sha": "f2d63bd5b68925f98f572eed70993d205cc694b7", - "installed_by": [ - "modules" - ] + "installed_by": ["modules"] }, "untar": { "branch": "master", "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", - "installed_by": [ - "modules" - ], + "installed_by": ["modules"], "patch": "modules/nf-core/untar/untar.diff" } } } } } -} \ No newline at end of file +} diff --git a/nextflow_schema.json b/nextflow_schema.json index aecc6b20..26ba21dd 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -115,7 +115,14 @@ "type": "string", "default": "alphafold2_ptm", "description": "Model preset for 'colabfold' mode", - "enum": ["auto", "alphafold2", "alphafold2_ptm", "alphafold2_multimer_v1", "alphafold2_multimer_v2", "alphafold2_multimer_v3"], + "enum": [ + "auto", + "alphafold2", + "alphafold2_ptm", + "alphafold2_multimer_v1", + "alphafold2_multimer_v2", + "alphafold2_multimer_v3" + ], "fa_icon": "fas fa-stream" }, "num_recycle": { diff --git a/subworkflows/local/prepare_alphafold2_dbs.nf b/subworkflows/local/prepare_alphafold2_dbs.nf index 49e7a844..6419d3dc 100644 --- a/subworkflows/local/prepare_alphafold2_dbs.nf +++ b/subworkflows/local/prepare_alphafold2_dbs.nf @@ -40,7 +40,7 @@ workflow PREPARE_ALPHAFOLD2_DBS { ch_mmcif_files = file( params.pdb_mmcif_path, type: 'dir' ) ch_mmcif_obsolete = file( params.pdb_mmcif_path, type: 'file' ) ch_mmcif = ch_mmcif_files + ch_mmcif_obsolete - ch_uniref30 = file( params.uniref30_alphafold_path, type: 'any' ) + ch_uniref30 = file( params.uniref30_alphafold2_path, type: 'any' ) ch_uniref90 = file( params.uniref90_path ) ch_pdb_seqres = file( params.pdb_seqres_path ) ch_uniprot = file( params.uniprot_path ) From 13c6a1b19185cb17b6a8ee143433973eca0a779f Mon Sep 17 00:00:00 2001 From: Leila Mansouri Date: Wed, 3 May 2023 15:02:34 +0200 Subject: [PATCH 030/269] changed params name in the stub run --- subworkflows/local/prepare_colabfold_dbs.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/local/prepare_colabfold_dbs.nf b/subworkflows/local/prepare_colabfold_dbs.nf index 0b6c39ac..33155c46 100644 --- a/subworkflows/local/prepare_colabfold_dbs.nf +++ b/subworkflows/local/prepare_colabfold_dbs.nf @@ -21,7 +21,7 @@ workflow PREPARE_COLABFOLD_DBS { ch_params = file( params.colabfold_alphafold2_params_path, type: 'any' ) if (params.colabfold_server == 'local') { ch_colabfold_db = file( params.colabfold_db_path, type: 'any' ) - ch_uniref30 = file( params.uniref30_path , type: 'any' ) + ch_uniref30 = file( params.uniref30_colabfold_path , type: 'any' ) } } else { From 8ab5876af4c1002c5c2ce549b2bf84f88bccf725 Mon Sep 17 00:00:00 2001 From: Leila Mansouri Date: Wed, 3 May 2023 15:24:58 +0200 Subject: [PATCH 031/269] specified where to fetch the ubuntu docker containers --- modules/local/combine_uniprot.nf | 2 +- modules/local/multifasta_to_csv.nf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/local/combine_uniprot.nf b/modules/local/combine_uniprot.nf index 6bc68e64..0d8e9159 100644 --- a/modules/local/combine_uniprot.nf +++ b/modules/local/combine_uniprot.nf @@ -4,7 +4,7 @@ process COMBINE_UNIPROT { conda "conda-forge::sed=4.7" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : - 'ubuntu:20.04' }" + 'docker.io/ubuntu:20.04' }" input: path uniprot_sprot diff --git a/modules/local/multifasta_to_csv.nf b/modules/local/multifasta_to_csv.nf index ee54f872..87b77412 100644 --- a/modules/local/multifasta_to_csv.nf +++ b/modules/local/multifasta_to_csv.nf @@ -4,7 +4,7 @@ process MULTIFASTA_TO_CSV { container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : - 'ubuntu:20.04' }" + 'docker.io/ubuntu:20.04' }" input: tuple val(meta), path(fasta) From 9323d862ebd25cb4a8a3edb31627be872882ae41 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Thu, 4 May 2023 12:42:35 +0200 Subject: [PATCH 032/269] Add ESMFOLD workflow to the main and fix bugs --- conf/dbs.config | 2 +- conf/modules_esmfold.config | 2 +- conf/test_full_esmfold_multimer.config | 2 +- main.nf | 10 +++++- modules/local/multifasta_to_singlefasta.nf | 39 +++++++++++++++++++++ modules/local/params_to_dir.nf | 38 ++++++++++++++++++++ modules/local/run_esmfold.nf | 8 ++--- nextflow.config | 3 ++ nextflow_schema.json | 40 +++++++++++++++++++++- subworkflows/local/prepare_esmfold_dbs.nf | 13 ++++--- workflows/esmfold.nf | 14 ++++---- 11 files changed, 149 insertions(+), 22 deletions(-) create mode 100644 modules/local/multifasta_to_singlefasta.nf create mode 100644 modules/local/params_to_dir.nf diff --git a/conf/dbs.config b/conf/dbs.config index 861ab340..f954b400 100644 --- a/conf/dbs.config +++ b/conf/dbs.config @@ -53,5 +53,5 @@ params { esm2_t36_3B_UR50D_contact_regression = 'https://dl.fbaipublicfiles.com/fair-esm/regression/esm2_t36_3B_UR50D-contact-regression.pt' // Esmfold paths - esmfold_params_path = "${params.esmfold_db}/esmfold_params/*" + esmfold_params_path = "${params.esmfold_db}/*" } diff --git a/conf/modules_esmfold.config b/conf/modules_esmfold.config index 230dd343..81b3048f 100644 --- a/conf/modules_esmfold.config +++ b/conf/modules_esmfold.config @@ -14,7 +14,7 @@ process { withName: 'RUN_ESMFOLD' { ext.args = {params.use_gpu ? '' : '--cpu-only'} publishDir = [ - path: { "${params.outdir}/esmfold" }, + path: { "${params.outdir}/${params.mode}" }, mode: 'copy', saveAs: { filename -> filename.equals('versions.yml') ? null : filename }, pattern: '*.*' diff --git a/conf/test_full_esmfold_multimer.config b/conf/test_full_esmfold_multimer.config index ee42df0a..b6e594fc 100644 --- a/conf/test_full_esmfold_multimer.config +++ b/conf/test_full_esmfold_multimer.config @@ -17,6 +17,6 @@ params { // Input data for full test of esmfold multimer mode = 'esmfold' esmfold_model_preset = 'multimer' - input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet.csv' + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/proteinfold/testdata/samplesheet/v1.0/samplesheet_multimer.csv' esmfold_db = 's3://nf-core-awsmegatests/proteinfold/input_data/db/esmfold' } diff --git a/main.nf b/main.nf index eebc1469..8841d5ca 100644 --- a/main.nf +++ b/main.nf @@ -39,6 +39,8 @@ if (params.mode == "alphafold2") { include { ALPHAFOLD2 } from './workflows/alphafold2' } else if (params.mode == "colabfold") { include { COLABFOLD } from './workflows/colabfold' +} else if (params.mode == "esmfold") { + include { ESMFOLD } from './workflows/esmfold' } workflow NFCORE_PROTEINFOLD { @@ -52,10 +54,16 @@ workflow NFCORE_PROTEINFOLD { // // WORKFLOW: Run colabfold // - // else if(params.mode == "colabfold_webserver" || params.mode == "colabfold_local") { else if(params.mode == "colabfold") { COLABFOLD () } + + // + // WORKFLOW: Run esmfold + // + else if(params.mode == "esmfold") { + ESMFOLD () + } } /* diff --git a/modules/local/multifasta_to_singlefasta.nf b/modules/local/multifasta_to_singlefasta.nf new file mode 100644 index 00000000..f4b58cf8 --- /dev/null +++ b/modules/local/multifasta_to_singlefasta.nf @@ -0,0 +1,39 @@ +process MULTIFASTA_TO_SINGLEFASTA { + tag "$meta.id" + label 'process_single' + + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : + 'ubuntu:20.04' }" + + input: + tuple val(meta), path(fasta) + + output: + tuple val(meta), path("${meta.id}.fasta"), emit: input_fasta + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + """ + awk '/^>/ {printf("\\n%s\\n",\$0);next; } { printf("%s",\$0);} END {printf("\\n");}' ${fasta} > single_line.fasta + echo -e '>'${meta.id}'\\n'`awk '!/^>/ {print \$0}' single_line.fasta | tr '\\n' ':' | sed 's/:\$//' | sed 's/^://'` > ${meta.id}.fasta + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sed: \$(echo \$(sed --version 2>&1) | sed 's/^.*GNU sed) //; s/ .*\$//') + END_VERSIONS + """ + + stub: + """ + touch input.csv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sed: \$(echo \$(sed --version 2>&1) | sed 's/^.*GNU sed) //; s/ .*\$//') + END_VERSIONS + """ +} diff --git a/modules/local/params_to_dir.nf b/modules/local/params_to_dir.nf new file mode 100644 index 00000000..6bc0de89 --- /dev/null +++ b/modules/local/params_to_dir.nf @@ -0,0 +1,38 @@ +process PARAMS_TO_DIR { + label 'process_single' + + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : + 'docker.io/ubuntu:20.04' }" + + input: + path(models) + + output: + path("checkpoints"), emit: input_models + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + """ + mkdir checkpoints + cp *.pt checkpoints + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sed: \$(echo \$(sed --version 2>&1) | sed 's/^.*GNU sed) //; s/ .*\$//') + END_VERSIONS + """ + + stub: + """ + mkdir checkpoints + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + sed: \$(echo \$(sed --version 2>&1) | sed 's/^.*GNU sed) //; s/ .*\$//') + END_VERSIONS + """ +} diff --git a/modules/local/run_esmfold.nf b/modules/local/run_esmfold.nf index 39837091..5c102e46 100644 --- a/modules/local/run_esmfold.nf +++ b/modules/local/run_esmfold.nf @@ -3,12 +3,12 @@ process RUN_ESMFOLD { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://athbaltzis/esmfold:v0.1' : - 'athbaltzis/esmfold:v0.1' }" + 'docker://athbaltzis/esmfold:1.1.0' : + 'athbaltzis/esmfold:1.1.0' }" input: tuple val(meta), path(fasta) - path ('./checkpoint') + path ('./checkpoints') val numRec output: @@ -27,7 +27,7 @@ process RUN_ESMFOLD { esm-fold \ -i ${fasta} \ -o \$PWD \ - -m ./checkpoints \ + -m \$PWD \ --num-recycles ${numRec} \ $args diff --git a/nextflow.config b/nextflow.config index 4b822768..9df7776c 100644 --- a/nextflow.config +++ b/nextflow.config @@ -67,6 +67,7 @@ params { uniref30_path = null // Esmfold parameters + esmfold_db = null esmfold_model_preset = "monomer" num_recycles = 4 @@ -270,6 +271,8 @@ if (params.mode == 'alphafold2') { includeConfig 'conf/modules_alphafold2.config' } else if (params.mode == 'colabfold') { includeConfig 'conf/modules_colabfold.config' +} else if (params.mode == 'esmfold') { + includeConfig 'conf/modules_esmfold.config' } // Load links to DBs and parameters diff --git a/nextflow_schema.json b/nextflow_schema.json index da68952e..d66131ee 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -170,7 +170,6 @@ "type": "integer", "default": 4, "description": "Specifies the number of recycles used by Esmfold", - "enum": ["webserver", "local"], "fa_icon": "fas fa-server" }, "esmfold_model_preset": { @@ -455,6 +454,45 @@ } } }, + "esmfold_parameters_link_options": { + "title": "Esmfold parameters links options", + "type": "object", + "description": "Parameters used to provide the links to the parameters public resources to Esmfold.", + "fa_icon": "fas fa-database", + "properties": { + "esmfold_3B_v1": { + "type": "string", + "default": "https://dl.fbaipublicfiles.com/fair-esm/models/esmfold_3B_v1.pt", + "description": "Link to the Esmfold 3B-v1 model", + "fa_icon": "fas fa-link" + }, + "esm2_t36_3B_UR50D": { + "type": "string", + "default": "https://dl.fbaipublicfiles.com/fair-esm/models/esm2_t36_3B_UR50D.pt", + "description": "Link to the Esmfold t36-3B-UR50D model", + "fa_icon": "fas fa-link" + }, + "esm2_t36_3B_UR50D_contact_regression": { + "type": "string", + "default": "https://dl.fbaipublicfiles.com/fair-esm/regression/esm2_t36_3B_UR50D-contact-regression.pt", + "description": "Link to the Esmfold t36-3B-UR50D-contact-regression model", + "fa_icon": "fas fa-link" + } + } + }, + "esmfold_parameters_path_options": { + "title": "Esmfold parameters links options", + "type": "object", + "description": "Parameters used to provide the links to the parameters public resources to Esmfold.", + "fa_icon": "fas fa-database", + "properties": { + "esmfold_params_path": { + "type": "string", + "description": "Link to the Esmfold parameters", + "fa_icon": "fas fa-folder-open" + } + } + }, "generic_options": { "title": "Generic options", "type": "object", diff --git a/subworkflows/local/prepare_esmfold_dbs.nf b/subworkflows/local/prepare_esmfold_dbs.nf index db8c39d7..35b705ba 100644 --- a/subworkflows/local/prepare_esmfold_dbs.nf +++ b/subworkflows/local/prepare_esmfold_dbs.nf @@ -5,15 +5,14 @@ include { ARIA2 as ARIA2_ESMFOLD_3B_V1 } from '../../modules/nf-core/aria2/main' include { ARIA2 as ARIA2_ESM2_T36_3B_UR50D } from '../../modules/nf-core/aria2/main' include { ARIA2 as ARIA2_ESM2_T36_3B_UR50D_CONTACT_REGRESSION } from '../../modules/nf-core/aria2/main' - +include { PARAMS_TO_DIR } from '../../modules/local/params_to_dir' workflow PREPARE_ESMFOLD_DBS { main: ch_versions = Channel.empty() - if (params.esmfold_db) { - ch_params = file( params.esmfold_params_path ) + ch_params = file( params.esmfold_params_path, type: 'dir' ) } else { ARIA2_ESMFOLD_3B_V1 ( @@ -25,9 +24,13 @@ workflow PREPARE_ESMFOLD_DBS { ARIA2_ESM2_T36_3B_UR50D_CONTACT_REGRESSION ( params.esm2_t36_3B_UR50D_contact_regression ) - ch_params = ARIA2_ESMFOLD_3B_V1.out.downloaded_file.mix(ARIA2_ESM2_T36_3B_UR50D.out.downloaded_file,ARIA2_ESM2_T36_3B_UR50D_CONTACT_REGRESSION.out.downloaded_file) + collect_params = ARIA2_ESMFOLD_3B_V1.out.downloaded_file.mix(ARIA2_ESM2_T36_3B_UR50D.out.downloaded_file,ARIA2_ESM2_T36_3B_UR50D_CONTACT_REGRESSION.out.downloaded_file).collect() ch_versions = ch_versions.mix(ARIA2_ESMFOLD_3B_V1.out.versions) - + PARAMS_TO_DIR ( + collect_params + ) + ch_params = PARAMS_TO_DIR.out.input_models + ch_versions = ch_versions.mix(PARAMS_TO_DIR.out.versions) } emit: diff --git a/workflows/esmfold.nf b/workflows/esmfold.nf index 7381ff9b..df9d14c0 100644 --- a/workflows/esmfold.nf +++ b/workflows/esmfold.nf @@ -46,7 +46,7 @@ include { PREPARE_ESMFOLD_DBS } from '../subworkflows/local/prepare_esmfold_dbs' // MODULE: Local to the pipeline // include { RUN_ESMFOLD } from '../modules/local/run_esmfold' -include { MULTIFASTA_TO_CSV } from '../modules/local/multifasta_to_csv' +include { MULTIFASTA_TO_SINGLEFASTA } from '../modules/local/multifasta_to_singlefasta' /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -81,19 +81,19 @@ workflow ESMFOLD { ) ch_versions = ch_versions.mix(INPUT_CHECK.out.versions) - PREPARE_ESMFOLD( ) - ch_versions = ch_versions.mix(PREPARE_ESMFOLD.out.versions) + PREPARE_ESMFOLD_DBS( ) + ch_versions = ch_versions.mix(PREPARE_ESMFOLD_DBS.out.versions) // // MODULE: Run esmfold // if (params.esmfold_model_preset != 'monomer') { - MULTIFASTA_TO_CSV( + MULTIFASTA_TO_SINGLEFASTA( INPUT_CHECK.out.fastas ) - ch_versions = ch_versions.mix(MULTIFASTA_TO_CSV.out.versions) + ch_versions = ch_versions.mix(MULTIFASTA_TO_SINGLEFASTA.out.versions) RUN_ESMFOLD( - MULTIFASTA_TO_CSV.out.input_csv, + MULTIFASTA_TO_SINGLEFASTA.out.input_fasta, PREPARE_ESMFOLD_DBS.out.params, params.num_recycles ) @@ -102,8 +102,6 @@ workflow ESMFOLD { RUN_ESMFOLD( INPUT_CHECK.out.fastas, PREPARE_ESMFOLD_DBS.out.params, - [], - [], params.num_recycles ) ch_versions = ch_versions.mix(RUN_ESMFOLD.out.versions) From 581de2cef7ac9f108968e3e0669ba152e38b212d Mon Sep 17 00:00:00 2001 From: l-mansouri Date: Thu, 4 May 2023 14:54:16 +0200 Subject: [PATCH 033/269] changed container names to be consisten with pipeline realease version --- modules/local/colabfold_batch.nf | 4 ++-- modules/local/run_alphafold2.nf | 4 ++-- modules/local/run_alphafold2_msa.nf | 4 ++-- modules/local/run_alphafold2_pred.nf | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/local/colabfold_batch.nf b/modules/local/colabfold_batch.nf index b693bb65..101748b6 100644 --- a/modules/local/colabfold_batch.nf +++ b/modules/local/colabfold_batch.nf @@ -3,8 +3,8 @@ process COLABFOLD_BATCH { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://lmansouri/colabfold:no_download' : - 'lmansouri/colabfold:no_download' }" + 'docker://lmansouri/colabfold:1.1.0' : + 'lmansouri/colabfold:1.1.0' }" input: tuple val(meta), path(fasta) diff --git a/modules/local/run_alphafold2.nf b/modules/local/run_alphafold2.nf index 8013beb2..9e5cb896 100644 --- a/modules/local/run_alphafold2.nf +++ b/modules/local/run_alphafold2.nf @@ -6,8 +6,8 @@ process RUN_ALPHAFOLD2 { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://lmansouri/alphafold-standard:2.0.0' : - 'lmansouri/alphafold-standard:2.0.0' }" + 'docker://lmansouri/alphafold-standard:1.1.0' : + 'lmansouri/alphafold-standard:1.1.0' }" input: tuple val(meta), path(fasta) diff --git a/modules/local/run_alphafold2_msa.nf b/modules/local/run_alphafold2_msa.nf index 164b35d1..117c32a0 100644 --- a/modules/local/run_alphafold2_msa.nf +++ b/modules/local/run_alphafold2_msa.nf @@ -6,8 +6,8 @@ process RUN_ALPHAFOLD2_MSA { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://lmansouri/alphafold-msa:2.0.0' : - 'lmansouri/alphafold-msa:2.0.0' }" + 'docker://lmansouri/alphafold-msa:1.1.0' : + 'lmansouri/alphafold-msa:1.1.0' }" input: diff --git a/modules/local/run_alphafold2_pred.nf b/modules/local/run_alphafold2_pred.nf index 7ec1c6e2..d6385250 100644 --- a/modules/local/run_alphafold2_pred.nf +++ b/modules/local/run_alphafold2_pred.nf @@ -6,8 +6,8 @@ process RUN_ALPHAFOLD2_PRED { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://lmansouri/alphafold-split:2.0.0' : - 'lmansouri/alphafold-split:2.0.0' }" + 'docker://lmansouri/alphafold-split:1.1.0' : + 'lmansouri/alphafold-split:1.1.0' }" input: tuple val(meta), path(fasta) From 74263de2186646fd0b0e556dfeb010a0cbaaa4ee Mon Sep 17 00:00:00 2001 From: l-mansouri Date: Fri, 5 May 2023 10:29:00 +0200 Subject: [PATCH 034/269] updated the name of the containers to the nf-core ones --- modules/local/colabfold_batch.nf | 4 ++-- modules/local/run_alphafold2.nf | 4 ++-- modules/local/run_alphafold2_msa.nf | 4 ++-- modules/local/run_alphafold2_pred.nf | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/local/colabfold_batch.nf b/modules/local/colabfold_batch.nf index 101748b6..20ce2904 100644 --- a/modules/local/colabfold_batch.nf +++ b/modules/local/colabfold_batch.nf @@ -3,8 +3,8 @@ process COLABFOLD_BATCH { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://lmansouri/colabfold:1.1.0' : - 'lmansouri/colabfold:1.1.0' }" + 'docker://nfcore/proteinfold_colabfold:1.1.0' : + 'nfcore/proteinfold_colabfold:1.1.0' }" input: tuple val(meta), path(fasta) diff --git a/modules/local/run_alphafold2.nf b/modules/local/run_alphafold2.nf index 9e5cb896..5cc0c813 100644 --- a/modules/local/run_alphafold2.nf +++ b/modules/local/run_alphafold2.nf @@ -6,8 +6,8 @@ process RUN_ALPHAFOLD2 { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://lmansouri/alphafold-standard:1.1.0' : - 'lmansouri/alphafold-standard:1.1.0' }" + 'docker://nfcore/proteinfold_alphafold2_standard:1.1.0' : + 'nfcore/proteinfold_alphafold2_standard:1.1.0' }" input: tuple val(meta), path(fasta) diff --git a/modules/local/run_alphafold2_msa.nf b/modules/local/run_alphafold2_msa.nf index 117c32a0..c2197ca5 100644 --- a/modules/local/run_alphafold2_msa.nf +++ b/modules/local/run_alphafold2_msa.nf @@ -6,8 +6,8 @@ process RUN_ALPHAFOLD2_MSA { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://lmansouri/alphafold-msa:1.1.0' : - 'lmansouri/alphafold-msa:1.1.0' }" + 'docker://nfcore/proteinfold_alphafold2_msa:1.1.0' : + 'nfcore/proteinfold_alphafold2_msa:1.1.0' }" input: diff --git a/modules/local/run_alphafold2_pred.nf b/modules/local/run_alphafold2_pred.nf index d6385250..e76432e9 100644 --- a/modules/local/run_alphafold2_pred.nf +++ b/modules/local/run_alphafold2_pred.nf @@ -6,8 +6,8 @@ process RUN_ALPHAFOLD2_PRED { label 'process_medium' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://lmansouri/alphafold-split:1.1.0' : - 'lmansouri/alphafold-split:1.1.0' }" + 'docker://nfcore/proteinfold_alphafold2_split:1.1.0' : + 'nfcore/proteinfold_alphafold2_split:1.1.0' }" input: tuple val(meta), path(fasta) From 7c327e96b969096fdfa2f03b81c4d77a53e02887 Mon Sep 17 00:00:00 2001 From: l-mansouri Date: Fri, 5 May 2023 10:31:56 +0200 Subject: [PATCH 035/269] updated the name of the containers to the nf-core ones --- modules/local/mmseqs_colabfoldsearch.nf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/local/mmseqs_colabfoldsearch.nf b/modules/local/mmseqs_colabfoldsearch.nf index 6ecbb59e..6fb754e5 100644 --- a/modules/local/mmseqs_colabfoldsearch.nf +++ b/modules/local/mmseqs_colabfoldsearch.nf @@ -3,8 +3,8 @@ process MMSEQS_COLABFOLDSEARCH { label 'process_high_memory' container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'docker://lmansouri/colabfold:no_download' : - 'lmansouri/colabfold:no_download' }" + 'docker://nfcore/proteinfold_colabfold:1.1.0' : + 'nfcore/proteinfold_colabfold:1.1.0' }" input: From f24c50637bb158dc63df5c0fb9a6860014dfe264 Mon Sep 17 00:00:00 2001 From: Leila Mansouri <48998340+l-mansouri@users.noreply.github.com> Date: Fri, 5 May 2023 10:55:09 +0200 Subject: [PATCH 036/269] Update modules/local/combine_uniprot.nf Co-authored-by: Jose Espinosa-Carrasco --- modules/local/combine_uniprot.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/combine_uniprot.nf b/modules/local/combine_uniprot.nf index 0d8e9159..c658c2f1 100644 --- a/modules/local/combine_uniprot.nf +++ b/modules/local/combine_uniprot.nf @@ -4,7 +4,7 @@ process COMBINE_UNIPROT { conda "conda-forge::sed=4.7" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : - 'docker.io/ubuntu:20.04' }" + 'docker.io/library/ubuntu:20.04' }" input: path uniprot_sprot From 19fed6846141d3d1a76ba98571ab6bd8ae6442f3 Mon Sep 17 00:00:00 2001 From: Leila Mansouri <48998340+l-mansouri@users.noreply.github.com> Date: Fri, 5 May 2023 10:58:45 +0200 Subject: [PATCH 037/269] Update modules/local/multifasta_to_csv.nf Co-authored-by: Jose Espinosa-Carrasco --- modules/local/multifasta_to_csv.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/local/multifasta_to_csv.nf b/modules/local/multifasta_to_csv.nf index 87b77412..09824884 100644 --- a/modules/local/multifasta_to_csv.nf +++ b/modules/local/multifasta_to_csv.nf @@ -4,7 +4,7 @@ process MULTIFASTA_TO_CSV { container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/ubuntu:20.04' : - 'docker.io/ubuntu:20.04' }" + 'docker.io/library/ubuntu:20.04' }" input: tuple val(meta), path(fasta) From 89befff784d4a114e9e9421e1d8adbafafc797f8 Mon Sep 17 00:00:00 2001 From: l-mansouri Date: Fri, 5 May 2023 11:28:08 +0200 Subject: [PATCH 038/269] updated redfundant path --- conf/dbs.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/dbs.config b/conf/dbs.config index ea668852..d06329e5 100644 --- a/conf/dbs.config +++ b/conf/dbs.config @@ -29,7 +29,7 @@ params { mgnify_path = "${params.alphafold2_db}/mgnify/*" pdb70_path = "${params.alphafold2_db}/pdb70/**" pdb_mmcif_path = "${params.alphafold2_db}/pdb_mmcif/*" - uniref30_alphafold2_path = "${params.alphafold2_db}/uniref30/**" + uniref30_alphafold2_path = "${params.alphafold2_db}/uniref30/*" uniref90_path = "${params.alphafold2_db}/uniref90/*" pdb_seqres_path = "${params.alphafold2_db}/pdb_seqres/*" uniprot_path = "${params.alphafold2_db}/uniprot/*" From adc2b705f34d22420e969f211253cfd6a66439aa Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Fri, 5 May 2023 12:36:38 +0200 Subject: [PATCH 039/269] Update nextflow_schema --- nextflow_schema.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/nextflow_schema.json b/nextflow_schema.json index d66131ee..a42fe4aa 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -175,7 +175,7 @@ "esmfold_model_preset": { "type": "string", "description": "Specifies whether is a 'monomer' or 'multimer' prediction", - "enum": ["monomer","multimer"], + "enum": ["monomer", "multimer"], "fa_icon": "fas fa-stream" } } @@ -607,6 +607,9 @@ { "$ref": "#/definitions/colabfold_options" }, + { + "$ref": "#/definitions/esmfold_options" + }, { "$ref": "#/definitions/institutional_config_options" }, @@ -625,6 +628,12 @@ { "$ref": "#/definitions/colabfold_dbs_and_parameters_path_options" }, + { + "$ref": "#/definitions/esmfold_parameters_link_options" + }, + { + "$ref": "#/definitions/esmfold_parameters_path_options" + }, { "$ref": "#/definitions/generic_options" } From a90350fdb65054751ae0a58a16c078ff2c0f32f1 Mon Sep 17 00:00:00 2001 From: Athanasios Baltzis Date: Fri, 5 May 2023 16:00:15 +0200 Subject: [PATCH 040/269] Update metromap --- .../nf-core-proteinfold_metro_map_1.1.0.png | Bin 0 -> 202826 bytes .../nf-core-proteinfold_metro_map_1.1.0.svg | 1640 +++++++++++++++++ 2 files changed, 1640 insertions(+) create mode 100644 docs/images/nf-core-proteinfold_metro_map_1.1.0.png create mode 100644 docs/images/nf-core-proteinfold_metro_map_1.1.0.svg diff --git a/docs/images/nf-core-proteinfold_metro_map_1.1.0.png b/docs/images/nf-core-proteinfold_metro_map_1.1.0.png new file mode 100644 index 0000000000000000000000000000000000000000..8db0e9b001b3e96de61eb4afb7f6a9d3e374aca7 GIT binary patch literal 202826 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­Su*LqoTu)hqEbvV z+x^Lvtnli^{-&suxVQJ)G!`81^UIYfs;mKch zK5S6@y4{&XJ5r_T^xWq~=a6TB7LxpA{go4jw?@4}HX`J5k;90D(P^o~^j(*?uVgK! zS%sEtuTX}hJ{eMdGmEv;VGNbKWQ)+`uiWs3iS~Q0!OtjrHu`TahbauJ*3az+g zdyPEp!rc?jdAMr~)&iPBFtp_FKPKeYwD(0yj;(iq6c?R+Y&9n>9t%yAAHOFArZ^R% zN_@-^n9R+D;0r+Qv<)(nP{3z(^?Ve?HhZVUSUM3;Ua)CD7Z(#ad`n{ihdD zxkkc6!gvC4m2o&bi&A$lMTMe0f^1h`!sa4ploLA#XK3CN; zb6ok|>)v2c(+>6nwJi`oG1(v{bWX* z?so}j*~~~v5Zy_fY`jl?qx<#=+D8E9#A{T?9N~MS!GAEO(fk! zbnO(3Zc86_Opk4dGjLu~w*_7G&)t3;Mmuzfs?8kdg2RIp|q9GXiQfV!4Bs zD?xTZF=IIF*gfB=04Iy8Xld@*BQ=Oq&Eih_kpb`gxI=z>Y~7bo3dtAFpP<0-y1=YA z_Z~(tssvf>@fC-TdS~abI*tuNdo1s3&dq)5vh@_!-KpGl-(+)swy0r~ITN3lQ29V! zCQHz;cTbLtPIY<8SSf1?daYatKS8WHQ`>~%lVv>_W`6E)K+CzVE?l&8ZJzgVQHHgy zzLJ$+zmK*ppGdIO<~?vQKm@k8c=-CXY?8+kZaQJb+8YA1Kyt?lLFZYxBD*;C*x@)0 zr!2$FGV~;G)zYzLTQ1JTGrK92MCZT7XxcrPltiSbgiW8Yw zWvB>-rDww?=$QeaPL5kn_s@lJ4^`~<#CE}oLU#jR*HMR&06Eq%J2BIxq{NkIvx%*v zemA$#zVU0;=7(c`F2q%gK1J1PD^Yl0AygC^Tc=U4rFwa`oO1m5`G{boa#N|+9FcZg}n4ApS zURbGZQ{>KYE2oH?&xzL<153-e&_8n-Vv3vX6%v9@Ol${du=VulSNT{PB6a}J7Ph&Y zS7uy>AL~yT8Hj_KMqfQYIXFPkunQa~+|e2qB_fHnQ6qd4j5d{zs{Y+=*ivO6Rzz58 z;g{ zR=|F93l!~TMbE73^;hMMijHQ~7B%)@L<**iOdKZc0?S`z@5Rrrc&X|g2%_Wr?0};5 z;wES{Qhe^v_G>(j%qRCYPxvJ1zzxipll=gT30o2HtK95rFkAQo#L--wHsu}71v~hZG9Dt#(|u!f7{-?ERQiE zbTX){+0mEiX{^VD%EWm0{*^OXG5FfUtO&oEz1@W|)mxS=e)da66jr@MhO!>D`Gst| zx-X|?@Cz8R^_4xRZacR8iVKWe7;fat4=_bcF4|WmiTVwlD%V;_@$hx0)6S5utvqNc z8@Cv)B4(h78kSZbW^Nt|MavAA6)3G{cByEc`mz>DcF9=RvaM1_!zjci zZ-GZN$gDN{{G?bV#o`yZpEw5T2}Z2}Y1ld*pa7jKZ$VQgsP4GPP%GX(>aw1Rzd9so z{MW9yq_O9+4Uez&TwdL6K!Y+yO}8!Fr9sNTZO0RqaW(wl|!LF^xWV(L#Q@moYn zXzh&gF&y--W-o${C+OP8Hy$A6g&N)Y>x>WfL3}(VwJ0Xb0@Jvwp{8<+{A3z9v!4h| zUZP2>Ynhf{HWq{AkC~FtD@A107#4c^WS42+d&+mlgG%( zcBcN%jzQtVD}%y8kB^oVvxYfAJ1dL8?B^bsE^ej`!Y2J5eI$-u zs|MszA_8u?t;KEtKPu?kiz5UoNNsg*Ya}Fs^jJ#|S%zJ-`*E59M@PwKJ7LzEXmPc{ zBU>nG6XZ_Kf&w{dNsw-53CewoRVObag(5?4Q+Uo^14wQB%sRxe{CCt$L8_sX<1NF7 zg0)@+CM{Z8BIS+TgSpA&Kt&>{g9$qUR(U1#fZg$fG&&&z;zYlTIzpDWqOnoCtS(fo7p+I5WpV+2rT)|6)SNDslws=eI8GPE2R zmTS5hmQMDb;*7zG@Xm8#R>oBofQhNf&Sv07*2pr|E(};E{#(RIZ3GRJ&<$dQ^J2;n z(yNy9y^~H=TfgIP_z!5}N)c~JojvEpnfb7tz?YIZV>86~L1G#c)WtRN4SO+S?2*l{ zWOfJ)VFV|94wzpEW)V5BXf5vT4Do=t*whto)yIJjwq@@#jwQ@QkQjQ<2>U#20`Oq3 z0~|>@VEv+IW)y#DTBq!0>sNvrWf_70h1eq=CbI=b6i8#in+Q+#$IGlWQd2)7;UU^p zV6NE@y2E%U--y{k`gBs#Mu};(K;0ZMA4OAaOBzKc^doPn;quy5Jp7GmM{LqjOzJM> z!JxNUbL*DB1Plt-t5Ghd5+y>NMoxB1b&tu^vOX&b`hLOf1^5*lIhltoh7y2ks*ob5 zI#*Iv++hkRe9`k$X5 zZpsso?G1{`)|<&6i-(9svul4ALm{~SSc8%qZ5MnSe_kM!9vNDja@g|h`yk3M4D3(V z$e3Hs#-)vN+hlE;4(L0SCvE7d;5XTgSnPj?q=Tf_54n$HW;$3cG4KKgh5Z(xy#+1V zn8XyA%hH$2uw_W49vIDGkv&@n8=2H3jQ0~7`-9`0%>0!*|XZ*HbmDqkTzeX1CN@S$<_CI3e$uT#%Lwk)w8uAt=b6ty|1VZ%cd{e zkV?Mna&a$RM2V=ZQ@lF#h)Z0{(YZx>ct0>udp2trR_pK(tCOuU*{kOP$@ULGmy99$ z&$EmdMa65|IR$p1R$@lNCDRAiGNR&reC~rKvvzg|oxVWFWlQC3UWT?HM@G#s*ahs` zhHc7RGium-*~cyq8XL)8><%tolUM*ju#wr)DU)|^=(UZYM%+#X#@$v_TWUN={PIG4 zFw4@^tW&U3R6HIr7Bv&qPuNWN*D%~}HTK-JV$SOzk*=DvWPCo|H*_YW9m6GE1ZuHv zJKr2YjtKX4XoyRDySfl^>{b`kFh|d}XMO4WzehsK)}9Ry1{OV?ByQj7BURdOs041j zi&UF5f|Hif9k`jVG+jo7B|cM^r7WKtc8gWXfZmG|l9A)i0xix;id_S_|5YZpUjkVL zp+krXf@N*?0!HG;@4B{a4>O12wn&_NRjvq0vFdqG?ad$7#KUbapQ;0z+u_T57fX+9 z5R>>l>C2CKH+7rhEN?Jb*hyGko1jfZNXL3hhIwR0e#|aj&s-LPv%4pixY|J3de*LY zz`HbB75o7nb{ED@lM%zMmu{xzu)AH?h>AE5aM2$aG^IpqGn4xA|A*R=@fLOk{kAV>~0(8Kxy=+FT3KJ{ZC%mC? zU;hH~1-3W1jbK7tafrx7jxnPpzS(HftX%Gy=Q8x@MV)JSa-64}kP+ritgmyK-=Tyi zHWm<1(UxkE7L?G8+8-_%9kglsqDJQX;%CH`9od`p>OeHO?`LI(9H2b3X^}u@4Ze;# zB;YHW7dd{#Vy=M>ZfY-M-r7xv&+OB4F&S4{U>Jb1&QpR>1E7|=`3DC_xhjQaOLWRM z4t9~%rHvbjhBUKCtF4&eq>!qXUbC^t4ESVXzcP#vo35B409X~~-=F)#K+}_5A08;S zXNMkvvQ{Nz*_Z$5{__nehPD$t8Yu z&dzucUIBfhM6$ZbF@5}Fq+brmiCvXV;mPu*sqXSZuc4%tPLSe_8jtU<=A2}B!F7YP zy{<<~???}QF4<9!tnRBo0tT@5;Js0rPP6?IHkEyi7PCP2s61aI+Gd6-OiW2Yt0*vZ zJHIPz^Fzt#WEG#Y?2*a|=VuokO=uxS=TB@C)zU!8)Vvcy=*st9& zgij}Vzo4h3Jf1x5xMx6yrnxl$LMjI7?QjELW_|l(SdmmIsUuh4?S<|N;V^)XI);Jv zfR(CDd>%zGqT|i#p8=CP0cl1G2N1(!Ei^ar!ViU!v!aq_0>9< zR^IoQkgi$n;FyfpV;BS8WswyPGnG61O*6O!(x+)wi@E?hPK;4kw=-Ow&zPyq_I9zJpAQ7&2@Cf2uvhJd0=LW`>Pq+c~ zR8Faj3*GpBg&Zoh=RP(DV!#y+8U!<-CojkhjSajo;A8aa0AM745o5TlXo0b$0hig~ zA_t&mszHovE{mDEU?CRM>a}v;h#WBdlhk$yjh>*qLiW68*_Z0Ypv|bIjP|35MT`Teg^ecvfEK36o7nrV@JEb0vz5~p8zbt+v;{3Q!QVc z~sQpzEGdRQDnUDo}*gFw7?<$+p{W3 zJB#lV1|+jqiY(?jlH)fvSXm}9{(~!iqMe6{b`oQ_F$eGISEDwX!^MRpp0vnOZK!Mc zYe&J=_H6peEqw;Hj?NDJuzN@ccr`w5Tx40hIHgBEa5F4XdlP`@h1tlg3b?W~%La9L zM_hJmE9@-arby4|6*au-$Vb14mG?=9Y{|4s2{``h7{5^12w+AmaB)T=5)!zz>+(H! zR!eMtwb*~(9kag~GYI_Vahn%(b-<$Lz$Qhj{Mczv6rNRL4f2^^n?n# zj%1*?NmZcRQw{73u27brtii=<-i8{TkfH-nc~u%HE1Y}nfMl2t z=LA9o^==#UfXR67oV&e&;7_V2cxd=fo3Yj&f8Y_-c)$UMFc^}WYeuFmCISEbts4F- zSg4xt^Xg>W0@-l6Er$8e+id11C3~1gBDj!Z?&k+>nfaW$;vEllln+j+%NDQ6JX|O) zR+FyfG3%IVRh1l^IaVtow%Pf|ivS67;nA>!y17c%=2jw){=*wu*bR;7h|FHAP{sYw zI2SjWK##Up(4_}-xrT%l(>Z|Arc6yew?p_1Fd}WZS~;5d9d!aPB%r6hv&E*s6w!B0 zgOuiUD)XJvC9#>`Fj~Mqq{jhm%<-qoZF%=*%n4tCn9nG%xr7UIl7p{_&fg<9L-f$n z+2gHmAj7WIM)vjtH~VHRM)qf0x%B*Ua0Ffx{^8n^Vi*{(Mk$P+FspO?CI_D0>s2J! zG8}0vfn{Y>m7V-ac$06-$yVjAX*JGxYm=g{m#*&SCD;mFvekm@UHBA zt@1Vw)WX26#r|zumi{52N@A`(6s+FiSTn7hOUp0;nzp~VJT@1i3+`f8@H@^Ii*=Bx zApF!mmcquG@Ebg`GjOkOou2H?A@9`fn;x-tAxe`qaPkrvhffisycODzB}`FEgV0PE z-P)Mt{U9J1{t^PjpP#1(KzvbQg2yK&&8?gi$2L%Q2L8M=7>*U)yjciRD z5<=7u-QTIT(6u7pGOZn~@@#4_iI?Ktl$UowOdf^y1^q6qT)Kh=N4cRYw7!wRc0LHL zZzySl{m5%091iVJA7>_ve0k5~-62hM95m(CqW87f3r4!*~0!@BGu&uIB}h3=3HUTtJ19vfEqxz6P& z@`z8aTAQE^_BTfZUQBT5u@O^DtpFUR(Bzx>nna=f-R-2su=neZiC;^aj|AF0r7ON$ zQuzbE+GS@=u-0>@N@m-&v;1|{iE?`}hLiG7mc9Ch0YvU+fULZ>2i`K~8*Z|%!URS08fJ!@BZq(-77|P*G%dg#=3N8t(D6K>sE_~Gz@N*LqSy8OA z&%%xEoPi{b%=Q-cA9h5>I~^>`xJ60U1MAruCA?9|D$xbGb5812inhT00O?#g_q_Dh#!xsGH2t?w@5I` z)v{ZqFaG|PI$KVU+Bpx+o?LKQG>3*T#$fvN*edO?wesW+6Zht$(6W-NJJZFpSibQQ zg^W^>HYU~yH(>o!A)tls=U^?U%VWe_w@Nn)gd|`}A5NzNux57uTrzWvw)c97Nu1Br z3D@j6qIaxIk0G_1u3V#G2)T= zLSvns3^}xFavl6?*tN$Owk*qA;NuGQ_m0Xv@SCor@=@hDD!s*UsmV?UV))`(+) zQvS=HrPNfye{rQLjy#=aaAn$(ZOM<9oXBILGt8KjE)y>%4c6GRJ$Ja_H2A&JRYJ0I z?XY7tQN+gYZAqKLG`7)DJRHpp

    *7n{jf>j*8C*2;Y8j?T`W(ckr!lcR<|OVnH_M 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