From 66800aaa16ddc97a5709da5e0ff8aa942160b29d Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:12:39 +0200 Subject: [PATCH 01/31] Add MetaPhlAn4 citation to CITATIONS.md --- CITATIONS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CITATIONS.md b/CITATIONS.md index 83669139..6a482af0 100644 --- a/CITATIONS.md +++ b/CITATIONS.md @@ -62,9 +62,9 @@ > Breitwieser, Florian P., Daniel N. Baker, and Steven L. Salzberg. 2018. KrakenUniq: confident and fast metagenomics classification using unique k-mer counts. Genome Biology 19 (1): 198. doi: 10.1186/s13059-018-1568-0 -- [MetaPhlAn3](https://doi.org/10.7554/eLife.65088) +- [MetaPhlAn](https://doi.org/10.1038/s41587-023-01688-w) - > Beghini, Francesco, Lauren J McIver, Aitor Blanco-Míguez, Leonard Dubois, Francesco Asnicar, Sagun Maharjan, Ana Mailyan, et al. 2021. “Integrating Taxonomic, Functional, and Strain-Level Profiling of Diverse Microbial Communities with BioBakery 3.” Edited by Peter Turnbaugh, Eduardo Franco, and C Titus Brown. ELife 10 (May): e65088. doi: 10.7554/eLife.65088 + > Blanco-Míguez, A., Beghini, F., Cumbo, F. et al. Extending and improving metagenomic taxonomic profiling with uncharacterized species using MetaPhlAn 4. Nat Biotechnol (2023). doi: 10.1038/s41587-023-01688-w - [MALT](https://doi.org/10.1038/s41559-017-0446-6) From e10027bd03e4a6123d76846bb990faa061eb8ef1 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:13:04 +0200 Subject: [PATCH 02/31] Add MetaPhlAn4 to README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2332d820..256720f6 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ 3. Supports statistics for host-read removal ([Samtools](http://www.htslib.org/)) 4. Performs taxonomic classification and/or profiling using one or more of: - [Kraken2](https://ccb.jhu.edu/software/kraken2/) - - [MetaPhlAn3](https://huttenhower.sph.harvard.edu/metaphlan/) + - [MetaPhlAn](https://huttenhower.sph.harvard.edu/metaphlan/) - [MALT](https://uni-tuebingen.de/fakultaeten/mathematisch-naturwissenschaftliche-fakultaet/fachbereiche/informatik/lehrstuehle/algorithms-in-bioinformatics/software/malt/) - [DIAMOND](https://github.com/bbuchfink/diamond) - [Centrifuge](https://ccb.jhu.edu/software/centrifuge/) @@ -68,7 +68,7 @@ Additionally, you will need a database sheet that looks as follows: ``` tool,db_name,db_params,db_path kraken2,db2,--quick,///kraken2/testdb-kraken2.tar.gz -metaphlan3,db1,,///metaphlan3/metaphlan_database/ +metaphlan,db1,,///metaphlan/metaphlan_database/ ``` That includes directories or `.tar.gz` archives containing databases for the tools you wish to run the pipeline against. @@ -81,7 +81,7 @@ nextflow run nf-core/taxprofiler \ --input samplesheet.csv \ --databases databases.csv \ --outdir \ - --run_kraken2 --run_metaphlan3 + --run_kraken2 --run_metaphlan ``` > **Warning:** From 71dc96372efd2cf3f8efac50b552a5a2f4161e14 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:14:11 +0200 Subject: [PATCH 03/31] Add profiler MetaPhlAn4 to modules.config --- conf/modules.config | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/conf/modules.config b/conf/modules.config index 150f8218..5e90e06a 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -523,20 +523,20 @@ process { ] } - withName: METAPHLAN3_METAPHLAN3 { + withName: METAPHLAN_METAPHLAN { ext.args = { "${meta.db_params}" } - ext.prefix = params.perform_runmerging ? { "${meta.id}_${meta.db_name}.metaphlan3" } : { "${meta.id}_${meta.run_accession}_${meta.db_name}.metaphlan3" } + ext.prefix = params.perform_runmerging ? { "${meta.id}_${meta.db_name}.metaphlan" } : { "${meta.id}_${meta.run_accession}_${meta.db_name}.metaphlan" } publishDir = [ - path: { "${params.outdir}/metaphlan3/${meta.db_name}/" }, + path: { "${params.outdir}/metaphlan/${meta.db_name}/" }, mode: params.publish_dir_mode, pattern: '*.{biom,txt}' ] } - withName: METAPHLAN3_MERGEMETAPHLANTABLES { - ext.prefix = { "metaphlan3_${meta.id}_combined_reports" } + withName: METAPHLAN_MERGEMETAPHLANTABLES { + ext.prefix = { "metaphlan_${meta.id}_combined_reports" } publishDir = [ - path: { "${params.outdir}/metaphlan3/" }, + path: { "${params.outdir}/metaphlan/" }, mode: params.publish_dir_mode, pattern: '*.{txt}' ] From 44df24f31bface59078f7cb5e401963d2383f5ab Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:14:49 +0200 Subject: [PATCH 04/31] Add profiler MetaPhlAn4 to conf/test.config --- conf/test.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test.config b/conf/test.config index 2d7ec074..4be47467 100644 --- a/conf/test.config +++ b/conf/test.config @@ -34,7 +34,7 @@ params { run_kraken2 = true run_bracken = true run_malt = false - run_metaphlan3 = true + run_metaphlan = true run_centrifuge = true run_diamond = true run_krakenuniq = true From 9ce1282fea3bf005c5e46a4f8172da2b56da6f55 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:15:24 +0200 Subject: [PATCH 05/31] Add profiler MetaPhlAn4 to conf/test_full.config --- conf/test_full.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test_full.config b/conf/test_full.config index 2e2f2679..75bfb019 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -59,7 +59,7 @@ params { malt_save_reads = false malt_generate_megansummary = true - run_metaphlan3 = true + run_metaphlan = true run_motus = true motus_save_mgc_read_counts = true From 7537c0bcd61834fe32f94083a22978e74911df38 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:15:45 +0200 Subject: [PATCH 06/31] Add profiler MetaPhlAn4 to conf/test_krakenuniq.config --- conf/test_krakenuniq.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test_krakenuniq.config b/conf/test_krakenuniq.config index 6d119887..2ab2c1ca 100644 --- a/conf/test_krakenuniq.config +++ b/conf/test_krakenuniq.config @@ -38,7 +38,7 @@ params { run_kraken2 = false run_bracken = false run_malt = false - run_metaphlan3 = false + run_metaphlan = false run_centrifuge = false run_diamond = false run_krakenuniq = true From b212e94fb75ac2b0f0e0d2df76e031ab7a641132 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:16:00 +0200 Subject: [PATCH 07/31] Add profiler MetaPhlAn4 to conf/test_motus.config --- conf/test_motus.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test_motus.config b/conf/test_motus.config index 9563f34e..15833549 100644 --- a/conf/test_motus.config +++ b/conf/test_motus.config @@ -37,7 +37,7 @@ params { run_kraken2 = false run_bracken = false run_malt = false - run_metaphlan3 = false + run_metaphlan = false run_centrifuge = false run_diamond = false run_krakenuniq = false From b6b49b38246e968e0435838253a4fb59d6d9b968 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:16:27 +0200 Subject: [PATCH 08/31] Add profiler MetaPhlAn4 to conf/test_nopreprocessing.coconfig --- conf/test_nopreprocessing.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test_nopreprocessing.config b/conf/test_nopreprocessing.config index ee3b589b..43e01929 100644 --- a/conf/test_nopreprocessing.config +++ b/conf/test_nopreprocessing.config @@ -33,7 +33,7 @@ params { run_kraken2 = true run_bracken = true run_malt = true - run_metaphlan3 = true + run_metaphlan = true run_centrifuge = true run_diamond = true run_krakenuniq = true From 15a4e1b8b69823e18422dbbcb82a0c2d46a61cb3 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:17:30 +0200 Subject: [PATCH 09/31] Add profiler MetaPhlAn4 to conf/test_noprofiling.config --- conf/test_noprofiling.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test_noprofiling.config b/conf/test_noprofiling.config index 93b491ef..284c43ee 100644 --- a/conf/test_noprofiling.config +++ b/conf/test_noprofiling.config @@ -34,7 +34,7 @@ params { run_kraken2 = false run_bracken = false run_malt = false - run_metaphlan3 = false + run_metaphlan = false run_centrifuge = false run_diamond = false run_krakenuniq = false From 708e81d1c766f7add842b799044e3711a252cb15 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:17:53 +0200 Subject: [PATCH 10/31] Add profiler MetaPhlAn4 to conf/test_nothing.config --- conf/test_nothing.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/test_nothing.config b/conf/test_nothing.config index c9b3b1da..e8fa96a8 100644 --- a/conf/test_nothing.config +++ b/conf/test_nothing.config @@ -33,7 +33,7 @@ params { run_kraken2 = false run_bracken = false run_malt = false - run_metaphlan3 = false + run_metaphlan = false run_centrifuge = false run_diamond = false run_krakenuniq = false From 4fd9d55a0f14e43b83ba6081702dcfa772a2e2fd Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:18:43 +0200 Subject: [PATCH 11/31] Add profiler MetaPhlAn4 to docs/images/taxprofiler_tube.svg --- docs/images/taxprofiler_tube.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/images/taxprofiler_tube.svg b/docs/images/taxprofiler_tube.svg index 6eb06cd5..a663e68d 100644 --- a/docs/images/taxprofiler_tube.svg +++ b/docs/images/taxprofiler_tube.svg @@ -3186,7 +3186,7 @@ id="tspan44956-3" style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Maven Pro';-inkscape-font-specification:'Maven Pro Bold';text-align:end;text-anchor:end;stroke-width:0.264583" x="-347.26553" - y="100.45697">MetaPhlAn3MetaPhlAn Date: Fri, 7 Jul 2023 09:19:44 +0200 Subject: [PATCH 12/31] Add MetaPhlAn4 to docs/output.md, docs/usage.md --- docs/output.md | 18 +++++++++--------- docs/usage.md | 37 ++++++++++++++++++------------------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/docs/output.md b/docs/output.md index 5c24d516..4569ddb6 100644 --- a/docs/output.md +++ b/docs/output.md @@ -30,7 +30,7 @@ The pipeline is built using [Nextflow](https://www.nextflow.io/) and processes d - [Kaiju](#kaiju) - Taxonomic classifier that finds maximum (in-)exact matches on the protein-level. - [Diamond](#diamond) - Sequence aligner for protein and translated DNA searches. - [MALT](#malt) - Sequence alignment and analysis tool designed for processing high-throughput sequencing data, especially in the context of metagenomics -- [MetaPhlAn3](#metaphlan3) - Genome-level marker gene based taxonomic classifier +- [MetaPhlAn](#metaphlan) - Genome-level marker gene based taxonomic classifier - [mOTUs](#motus) - Tool for marker gene-based OTU (mOTU) profiling. - [ganon](#ganon) - Taxonomic classifier and profile that uses Interleaved Bloom Filters as indices based on k-mers/minimizers. - [TAXPASTA](#taxpasta) - Tool to standardise taxonomic profiles as well as merge profiles across samples from the same database and classifier/profiler. @@ -429,23 +429,23 @@ The main output of MALT is the `.rma6` file format, which can be only loaded int You will only receive the `.sam` and `.megan` files if you supply `--malt_save_reads` and/or `--malt_generate_megansummary` parameters to the pipeline. -### MetaPhlAn3 +### MetaPhlAn -[MetaPhlAn3](https://github.com/biobakery/metaphlan) is a computational tool for profiling the composition of microbial communities (Bacteria, Archaea and Eukaryotes) from metagenomic shotgun sequencing data (i.e. not 16S) with species-level resolution via marker genes. +[MetaPhlAn](https://github.com/biobakery/metaphlan) is a computational tool for profiling the composition of microbial communities (Bacteria, Archaea and Eukaryotes) from metagenomic shotgun sequencing data (i.e. not 16S) with species-level resolution via marker genes.
Output files -- `metaphlan3/` - - `metaphlan3__combined_reports.txt`: A combined profile of all samples aligned to a given database (as generated by `metaphlan_merge_tables`) +- `metaphlan/` + - `metaphlan__combined_reports.txt`: A combined profile of all samples aligned to a given database (as generated by `metaphlan_merge_tables`) - `/` - `.biom`: taxonomic profile in BIOM format - - `.bowtie2out.txt`: BowTie2 alignment information (can be re-used for skipping alignment when re-running MetaPhlAn3 with different parameters) - - `_profile.txt`: MetaPhlAn3 taxonomic profile including abundance estimates + - `.bowtie2out.txt`: BowTie2 alignment information (can be re-used for skipping alignment when re-running MetaPhlAn with different parameters) + - `_profile.txt`: MetaPhlAn taxonomic profile including abundance estimates
-The main taxonomic profiling file from MetaPhlAn3 is the `*_profile.txt` file. This provides the abundance estimates from MetaPhlAn3 however does not include raw counts by default. +The main taxonomic profiling file from MetaPhlAn is the `*_profile.txt` file. This provides the abundance estimates from MetaPhlAn however does not include raw counts by default. ### mOTUs @@ -535,7 +535,7 @@ The following report files are used for the taxpasta step: - KrakenUniq: `_.report.txt` Taxpasta uses the `reads` column for the standardised profile. - Kraken2: `_.report.txt` Taxpasta uses the `direct_assigned_reads` column for the standardised profile. - MALT: `.txt.gz` Taxpasta uses the `count` (second) column from the output of MEGAN6's rma2info for the standardised profile. -- MetaPhlAn3: `_profile.txt` Taxpasta uses the `relative_abundance` column multiplied with a fixed number to yield an integer for the standardised profile. +- MetaPhlAn: `_profile.txt` Taxpasta uses the `relative_abundance` column multiplied with a fixed number to yield an integer for the standardised profile. - mOTUs: `.out` Taxpasta uses the `read_count` column for the standardised profile. > ⚠️ Please aware the outputs of each tool's standardised profile _may not_ be directly comparable between each tool. Some may report raw read counts, whereas others may report abundance information. Please always refer to the list above, for which information is used for each tool. diff --git a/docs/usage.md b/docs/usage.md index d52d9be1..80aabf98 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -101,7 +101,7 @@ bracken,db1,;-r 150,///bracken/testdb-bracken.tar.gz kraken2,db2,--quick,///kraken2/testdb-kraken2.tar.gz krakenuniq,db3,,///krakenuniq/testdb-krakenuniq.tar.gz centrifuge,db1,,///centrifuge/minigut_cf.tar.gz -metaphlan3,db1,,///metaphlan3/metaphlan_database/ +metaphlan,db1,,///metaphlan/metaphlan_database/ motus,db_mOTU,,///motus/motus_database/ ganon,db1,,///ganon/test-db-ganon.tar.gz ``` @@ -130,7 +130,7 @@ The (uncompressed) database paths (`db_path`) for each tool are expected to cont - [**Kraken2**:](#kraken2-custom-database) output of `kraken2-build` command(s). - [**KrakenUniq**:](#krakenuniq-custom-database) output of `krakenuniq-build` command(s). - [**MALT**](#malt-custom-database) output of `malt-build`. -- [**MetaPhlAn3**:](#metaphlan3-custom-database) output of with `metaphlan --install` or downloaded from links on the [MetaPhlAn3 wiki](https://github.com/biobakery/MetaPhlAn/wiki/MetaPhlAn-3.0#customizing-the-database). +- [**MetaPhlAn**:](#metaphlan-custom-database) output of with `metaphlan --install` or downloaded from links on the [MetaPhlAn wiki](https://github.com/biobakery/MetaPhlAn/wiki/MetaPhlAn-4#customizing-the-database). - [**mOTUs**:](#motus-custom-database) the directory `db_mOTU/` that is downloaded via `motus downloadDB`. - [**ganon**:](#ganon-custom-database) output of `ganon build` or `ganon build-custom`. @@ -298,9 +298,9 @@ MALT does not support paired-end reads alignment (unlike other tools), therefore Krona can only be run on MALT output if path to Krona taxonomy database supplied to `--krona_taxonomy_directory`. Therefore if you do not supply the a Krona directory, Krona plots will not be produced for MALT. -##### MetaPhlAn3 +##### MetaPhlAn -MetaPhlAn3 currently does not accept FASTA files as input, therefore no output will be produced for these input files. +MetaPhlAn currently does not accept FASTA files as input, therefore no output will be produced for these input files. ##### mOTUs @@ -339,7 +339,7 @@ The following tools will produce multi-sample taxon tables: - **Centrifuge** (via KrakenTools' `combine_kreports.py` script) - **Kaiju** (via Kaiju's `kaiju2table` tool) - **Kraken2** (via KrakenTools' `combine_kreports.py` script) -- **MetaPhlAn3** (via MetaPhlAn's `merge_metaphlan_tables.py` script) +- **MetaPhlAn** (via MetaPhlAn's `merge_metaphlan_tables.py` script) - **mOTUs** (via the `motus merge` command) - **ganon** (via the `ganon table` command) @@ -712,11 +712,11 @@ You can then add the `/` path to your nf-core/taxprofiler database See the [MALT manual](https://software-ab.informatik.uni-tuebingen.de/download/malt/manual.pdf) for more information. -#### MetaPhlAn3 custom database +#### MetaPhlAn custom database -MetaPhlAn3 does not allow (easy) construction of custom databases. Therefore we recommend to use the prebuilt database of marker genes that is provided by the developers. +MetaPhlAn does not allow (easy) construction of custom databases. Therefore we recommend to use the prebuilt database of marker genes that is provided by the developers. -To do this you need to have `MetaPhlAn3` installed on your machine. +To do this you need to have `MetaPhlAn` installed on your machine. ```bash metaphlan --install --bowtie2db / @@ -731,21 +731,20 @@ You can then add the `/` path to your nf-core/taxprofiler database
Expected files in database directory -- `metaphlan3` - - `mpa_v30_CHOCOPhlAn_201901.pkl` - - `mpa_v30_CHOCOPhlAn_201901.pkl` - - `mpa_v30_CHOCOPhlAn_201901.fasta` - - `mpa_v30_CHOCOPhlAn_201901.3.bt2` - - `mpa_v30_CHOCOPhlAn_201901.4.bt2` - - `mpa_v30_CHOCOPhlAn_201901.1.bt2` - - `mpa_v30_CHOCOPhlAn_201901.2.bt2` - - `mpa_v30_CHOCOPhlAn_201901.rev.1.bt2` - - `mpa_v30_CHOCOPhlAn_201901.rev.2.bt2` +- `metaphlan` + - `mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.pkl` + - `mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.fna.bz2` + - `mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.1.bt2l` + - `mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.2.bt2l` + - `mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.3.bt2l` + - `mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.4.bt2l` + - `mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.rev.1.bt2l` + - `mpa_vJan21_TOY_CHOCOPhlAnSGB_202103.rev.2.bt2l` - `mpa_latest`
-More information on the MetaPhlAn3 database can be found [here](https://github.com/biobakery/MetaPhlAn/wiki/MetaPhlAn-3.1#installation). +More information on the MetaPhlAn database can be found [here](https://github.com/biobakery/MetaPhlAn/wiki/MetaPhlAn-4#Pre-requisites). #### mOTUs custom database From de4baeb8483bee7e3ae93198fd8e99d46c51ad5f Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:20:44 +0200 Subject: [PATCH 13/31] Added parameters to nextflow.config --- nextflow.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nextflow.config b/nextflow.config index 18820eb6..344cf063 100644 --- a/nextflow.config +++ b/nextflow.config @@ -134,8 +134,8 @@ params { run_centrifuge = false centrifuge_save_reads = false // added directly to module in profiling.nf - // metaphlan3 - run_metaphlan3 = false + // metaphlan + run_metaphlan = false // kaiju run_kaiju = false From 1706cc321b8d09593486f0e1712af9983e02ff25 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:21:54 +0200 Subject: [PATCH 14/31] remove the module metaphlan3/metaphlan3 --- modules/nf-core/metaphlan3/metaphlan3/main.nf | 48 --------------- .../nf-core/metaphlan3/metaphlan3/meta.yml | 58 ------------------- 2 files changed, 106 deletions(-) delete mode 100644 modules/nf-core/metaphlan3/metaphlan3/main.nf delete mode 100644 modules/nf-core/metaphlan3/metaphlan3/meta.yml diff --git a/modules/nf-core/metaphlan3/metaphlan3/main.nf b/modules/nf-core/metaphlan3/metaphlan3/main.nf deleted file mode 100644 index 34f8705c..00000000 --- a/modules/nf-core/metaphlan3/metaphlan3/main.nf +++ /dev/null @@ -1,48 +0,0 @@ -process METAPHLAN3_METAPHLAN3 { - tag "$meta.id" - label 'process_high' - - conda "bioconda::metaphlan=3.0.12" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/metaphlan:3.0.12--pyhb7b1952_0' : - 'quay.io/biocontainers/metaphlan:3.0.12--pyhb7b1952_0' }" - - input: - tuple val(meta), path(input) - path metaphlan_db - - output: - tuple val(meta), path("*_profile.txt") , emit: profile - tuple val(meta), path("*.biom") , emit: biom - tuple val(meta), path('*.bowtie2out.txt'), optional:true, emit: bt2out - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - def prefix = task.ext.prefix ?: "${meta.id}" - def input_type = ("$input".endsWith(".fastq.gz") || "$input".endsWith(".fq.gz")) ? "--input_type fastq" : ("$input".contains(".fasta")) ? "--input_type fasta" : ("$input".endsWith(".bowtie2out.txt")) ? "--input_type bowtie2out" : "--input_type sam" - def input_data = ("$input_type".contains("fastq")) && !meta.single_end ? "${input[0]},${input[1]}" : "$input" - def bowtie2_out = "$input_type" == "--input_type bowtie2out" || "$input_type" == "--input_type sam" ? '' : "--bowtie2out ${prefix}.bowtie2out.txt" - - """ - BT2_DB=`find -L "${metaphlan_db}" -name "*rev.1.bt2" -exec dirname {} \\;` - - metaphlan \\ - --nproc $task.cpus \\ - $input_type \\ - $input_data \\ - $args \\ - $bowtie2_out \\ - --bowtie2db \$BT2_DB \\ - --biom ${prefix}.biom \\ - --output_file ${prefix}_profile.txt - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - metaphlan3: \$(metaphlan --version 2>&1 | awk '{print \$3}') - END_VERSIONS - """ -} diff --git a/modules/nf-core/metaphlan3/metaphlan3/meta.yml b/modules/nf-core/metaphlan3/metaphlan3/meta.yml deleted file mode 100644 index 659d83a9..00000000 --- a/modules/nf-core/metaphlan3/metaphlan3/meta.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: metaphlan3_metaphlan3 -description: MetaPhlAn is a tool for profiling the composition of microbial communities from metagenomic shotgun sequencing data. -keywords: - - metagenomics - - classification - - fastq - - bam - - fasta -tools: - - metaphlan3: - description: Identify clades (phyla to species) present in the metagenome obtained from a microbiome sample and their relative abundance - homepage: https://huttenhower.sph.harvard.edu/metaphlan/ - documentation: https://github.com/biobakery/MetaPhlAn - doi: "10.7554/eLife.65088" - licence: ["MIT License"] - -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - input: - type: file - description: Metaphlan 3.0 can classify the metagenome from a variety of input data types, including FASTQ files (single-end and paired-end), FASTA, bowtie2-produced SAM files (produced from alignments to the MetaPHlAn marker database) and intermediate bowtie2 alignment files (bowtie2out) - pattern: "*.{fastq.gz, fasta, fasta.gz, sam, bowtie2out.txt}" - - metaphlan_db: - type: file - description: | - Directory containing pre-downloaded and uncompressed MetaPhlAn3 database downloaded from: http://cmprod1.cibio.unitn.it/biobakery3/metaphlan_databases/. - Note that you will also need to specify `--index` and the database version name (e.g. 'mpa_v31_CHOCOPhlAn_201901') in your module.conf ext.args for METAPHLAN3_METAPHLAN3! - pattern: "*/" - -output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - profile: - type: file - description: Tab-separated output file of the predicted taxon relative abundances - pattern: "*.{txt}" - - biom: - type: file - description: General-use format for representing biological sample by observation contingency tables - pattern: "*.{biom}" - - bowtie2out: - type: file - description: Intermediate Bowtie2 output produced from mapping the metagenome against the MetaPHlAn marker database ( not compatible with `bowtie2out` files generated with MetaPhlAn versions below 3 ) - pattern: "*.{bowtie2out.txt}" - -authors: - - "@MGordon09" From 55d89f9b1192bb31c30795e984408cbb5bd6c84a Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:23:12 +0200 Subject: [PATCH 15/31] Remove the module metaphlan3/mergemetaphlantables --- .../metaphlan3/mergemetaphlantables/main.nf | 33 -------------- .../metaphlan3/mergemetaphlantables/meta.yml | 44 ------------------- 2 files changed, 77 deletions(-) delete mode 100644 modules/nf-core/metaphlan3/mergemetaphlantables/main.nf delete mode 100644 modules/nf-core/metaphlan3/mergemetaphlantables/meta.yml diff --git a/modules/nf-core/metaphlan3/mergemetaphlantables/main.nf b/modules/nf-core/metaphlan3/mergemetaphlantables/main.nf deleted file mode 100644 index 5be6e4f1..00000000 --- a/modules/nf-core/metaphlan3/mergemetaphlantables/main.nf +++ /dev/null @@ -1,33 +0,0 @@ -process METAPHLAN3_MERGEMETAPHLANTABLES { - label 'process_single' - - conda "bioconda::metaphlan=3.0.12" - container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/metaphlan:3.0.12--pyhb7b1952_0' : - 'quay.io/biocontainers/metaphlan:3.0.12--pyhb7b1952_0' }" - - input: - tuple val(meta), path(profiles) - - output: - tuple val(meta), path("${prefix}.txt") , emit: txt - path "versions.yml" , emit: versions - - when: - task.ext.when == null || task.ext.when - - script: - def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: "${meta.id}" - """ - merge_metaphlan_tables.py \\ - $args \\ - -o ${prefix}.txt \\ - ${profiles} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - metaphlan3: \$(metaphlan --version 2>&1 | awk '{print \$3}') - END_VERSIONS - """ -} diff --git a/modules/nf-core/metaphlan3/mergemetaphlantables/meta.yml b/modules/nf-core/metaphlan3/mergemetaphlantables/meta.yml deleted file mode 100644 index 365973ef..00000000 --- a/modules/nf-core/metaphlan3/mergemetaphlantables/meta.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: "metaphlan3_mergemetaphlantables" -description: Merges output abundance tables from MetaPhlAn3 -keywords: - - metagenomics - - classification - - merge - - table - - profiles -tools: - - metaphlan3: - description: Identify clades (phyla to species) present in the metagenome obtained from a microbiome sample and their relative abundance - homepage: https://huttenhower.sph.harvard.edu/metaphlan/ - documentation: https://github.com/biobakery/MetaPhlAn - doi: "10.7554/eLife.65088" - licence: ["MIT License"] - -input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - profiles: - type: file - description: List of per-sample MetaPhlAn3 taxonomic abundance tables - pattern: "*" - -output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - - txt: - type: txt - description: Combined MetaPhlAn3 table - pattern: "*.txt" - -authors: - - "@jfy133" From b21f113da49e1c8318f29447941a39195fc28ce2 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:25:54 +0200 Subject: [PATCH 16/31] update the version of module taxpasta/merge, taxpasta/standardise --- modules/nf-core/taxpasta/merge/main.nf | 6 +++--- modules/nf-core/taxpasta/standardise/main.nf | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/nf-core/taxpasta/merge/main.nf b/modules/nf-core/taxpasta/merge/main.nf index 58824258..dcbca616 100644 --- a/modules/nf-core/taxpasta/merge/main.nf +++ b/modules/nf-core/taxpasta/merge/main.nf @@ -2,10 +2,10 @@ process TAXPASTA_MERGE { tag "$meta.id" label 'process_single' - conda "bioconda::taxpasta=0.2.3" + conda "bioconda::taxpasta=0.4.0" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/taxpasta:0.2.3--pyhdfd78af_0': - 'quay.io/biocontainers/taxpasta:0.2.3--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/taxpasta:0.4.0--pyhdfd78af_0': + 'biocontainers/taxpasta:0.4.0--pyhdfd78af_0' }" input: diff --git a/modules/nf-core/taxpasta/standardise/main.nf b/modules/nf-core/taxpasta/standardise/main.nf index e6663096..4dde7967 100644 --- a/modules/nf-core/taxpasta/standardise/main.nf +++ b/modules/nf-core/taxpasta/standardise/main.nf @@ -2,10 +2,10 @@ process TAXPASTA_STANDARDISE { tag "$meta.id" label 'process_single' - conda "bioconda::taxpasta=0.2.3" + conda "bioconda::taxpasta=0.4.0" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/taxpasta:0.2.3--pyhdfd78af_0': - 'biocontainers/taxpasta:0.2.3--pyhdfd78af_0' }" + 'https://depot.galaxyproject.org/singularity/taxpasta:0.4.0--pyhdfd78af_0': + 'biocontainers/taxpasta:0.4.0--pyhdfd78af_0' }" input: tuple val(meta), path(profile) From d10e79db05dab37d6bf67406c3775a21f7b33f42 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:26:40 +0200 Subject: [PATCH 17/31] Added profiler to expected tools in subworkflows/local/db_check.nf --- subworkflows/local/db_check.nf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subworkflows/local/db_check.nf b/subworkflows/local/db_check.nf index b5fcb100..c5b99415 100644 --- a/subworkflows/local/db_check.nf +++ b/subworkflows/local/db_check.nf @@ -62,7 +62,7 @@ def validate_db_rows(LinkedHashMap row) { if ( !row.keySet().containsAll(expected_headers) ) error("[nf-core/taxprofiler] ERROR: Invalid database input sheet - malformed column names. Please check input TSV. Column names should be: ${expected_headers.join(", ")}") // valid tools specified - def expected_tools = [ "bracken", "centrifuge", "diamond", "kaiju", "kraken2", "krakenuniq", "malt", "metaphlan3", "motus", "ganon", "metaphlan", "kmcp" ] + def expected_tools = [ "bracken", "centrifuge", "diamond", "kaiju", "kraken2", "krakenuniq", "malt", "metaphlan3", "metaphlan", "motus", "ganon", "kmcp" ] if ( !expected_tools.contains(row.tool) ) error("[nf-core/taxprofiler] ERROR: Invalid tool name. Please see documentation for all supported profilers. Error in: ${row}") // detect quotes in params From 0b279c044d79ff5b2e3189eee4f71ceccdd0512b Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:27:14 +0200 Subject: [PATCH 18/31] Added profiler to subworkflows/local/profiling.nf --- subworkflows/local/profiling.nf | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/subworkflows/local/profiling.nf b/subworkflows/local/profiling.nf index 2f11100d..3eb99d92 100644 --- a/subworkflows/local/profiling.nf +++ b/subworkflows/local/profiling.nf @@ -9,7 +9,7 @@ include { KRAKEN2_STANDARD_REPORT } from '../../modules/lo include { BRACKEN_BRACKEN } from '../../modules/nf-core/bracken/bracken/main' include { CENTRIFUGE_CENTRIFUGE } from '../../modules/nf-core/centrifuge/centrifuge/main' include { CENTRIFUGE_KREPORT } from '../../modules/nf-core/centrifuge/kreport/main' -include { METAPHLAN3_METAPHLAN3 } from '../../modules/nf-core/metaphlan3/metaphlan3/main' +include { METAPHLAN_METAPHLAN } from '../../modules/nf-core/metaphlan/metaphlan/main' include { KAIJU_KAIJU } from '../../modules/nf-core/kaiju/kaiju/main' include { KAIJU_KAIJU2TABLE as KAIJU_KAIJU2TABLE_SINGLE } from '../../modules/nf-core/kaiju/kaiju2table/main' include { DIAMOND_BLASTX } from '../../modules/nf-core/diamond/blastx/main' @@ -47,7 +47,7 @@ workflow PROFILING { kraken2: it[2]['tool'] == 'kraken2' || it[2]['tool'] == 'bracken' // to reuse the kraken module to produce the input data for bracken krakenuniq: it[2]['tool'] == 'krakenuniq' malt: it[2]['tool'] == 'malt' - metaphlan3: it[2]['tool'] == 'metaphlan3' + metaphlan: it[2]['tool'] == 'metaphlan' motus: it[2]['tool'] == 'motus' ganon: it[2]['tool'] == 'ganon' unknown: true @@ -239,22 +239,18 @@ workflow PROFILING { } - if ( params.run_metaphlan3 ) { + if ( params.run_metaphlan ) { - ch_input_for_metaphlan3 = ch_input_for_profiling.metaphlan3 - .filter{ - if (it[0].is_fasta) log.warn "[nf-core/taxprofiler] MetaPhlAn3 currently does not accept FASTA files as input. Skipping MetaPhlAn3 for sample ${it[0].id}." - !it[0].is_fasta - } + ch_input_for_metaphlan = ch_input_for_profiling.metaphlan .multiMap { it -> reads: [it[0] + it[2], it[1]] db: it[3] } - METAPHLAN3_METAPHLAN3 ( ch_input_for_metaphlan3.reads, ch_input_for_metaphlan3.db ) - ch_versions = ch_versions.mix( METAPHLAN3_METAPHLAN3.out.versions.first() ) - ch_raw_profiles = ch_raw_profiles.mix( METAPHLAN3_METAPHLAN3.out.profile ) + METAPHLAN_METAPHLAN ( ch_input_for_metaphlan.reads, ch_input_for_metaphlan.db ) + ch_versions = ch_versions.mix( METAPHLAN_METAPHLAN.out.versions.first() ) + ch_raw_profiles = ch_raw_profiles.mix( METAPHLAN_METAPHLAN.out.profile ) } From 3b3a527eb6d030c36de217a0eb284eff4baeb55c Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:27:56 +0200 Subject: [PATCH 19/31] Added profiler to subworkflows/local/standardisation_profiles.nf --- subworkflows/local/standardisation_profiles.nf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/subworkflows/local/standardisation_profiles.nf b/subworkflows/local/standardisation_profiles.nf index 24631e7c..540d5a0e 100644 --- a/subworkflows/local/standardisation_profiles.nf +++ b/subworkflows/local/standardisation_profiles.nf @@ -8,7 +8,7 @@ include { BRACKEN_COMBINEBRACKENOUTPUTS include { KAIJU_KAIJU2TABLE as KAIJU_KAIJU2TABLE_COMBINED } from '../../modules/nf-core/kaiju/kaiju2table/main' include { KRAKENTOOLS_COMBINEKREPORTS as KRAKENTOOLS_COMBINEKREPORTS_KRAKEN } from '../../modules/nf-core/krakentools/combinekreports/main' include { KRAKENTOOLS_COMBINEKREPORTS as KRAKENTOOLS_COMBINEKREPORTS_CENTRIFUGE } from '../../modules/nf-core/krakentools/combinekreports/main' -include { METAPHLAN3_MERGEMETAPHLANTABLES } from '../../modules/nf-core/metaphlan3/mergemetaphlantables/main' +include { METAPHLAN_MERGEMETAPHLANTABLES } from '../../modules/nf-core/metaphlan/mergemetaphlantables/main' include { MOTUS_MERGE } from '../../modules/nf-core/motus/merge/main' include { GANON_TABLE } from '../../modules/nf-core/ganon/table/main' @@ -35,7 +35,7 @@ workflow STANDARDISATION_PROFILES { meta, profile -> def meta_new = [:] meta_new.id = meta.db_name - meta_new.tool = meta.tool == 'metaphlan3' ? 'metaphlan' : meta.tool == 'malt' ? 'megan6' : meta.tool + meta_new.tool = meta.tool == 'metaphlan' ? 'metaphlan' : meta.tool == 'malt' ? 'megan6' : meta.tool [meta_new, profile] } .groupTuple () @@ -62,7 +62,7 @@ workflow STANDARDISATION_PROFILES { bracken: it[0]['tool'] == 'bracken' centrifuge: it[0]['tool'] == 'centrifuge' kraken2: it[0]['tool'] == 'kraken2' - metaphlan3: it[0]['tool'] == 'metaphlan3' + metaphlan: it[0]['tool'] == 'metaphlan' motus: it[0]['tool'] == 'motus' ganon: it[0]['tool'] == 'ganon' unknown: true @@ -143,18 +143,18 @@ workflow STANDARDISATION_PROFILES { ch_multiqc_files = ch_multiqc_files.mix( KRAKENTOOLS_COMBINEKREPORTS_KRAKEN.out.txt ) ch_versions = ch_versions.mix( KRAKENTOOLS_COMBINEKREPORTS_KRAKEN.out.versions ) - // MetaPhlAn3 + // MetaPhlAn - ch_profiles_for_metaphlan3 = ch_input_profiles.metaphlan3 + ch_profiles_for_metaphlan = ch_input_profiles.metaphlan .map { [it[0]['db_name'], it[1]] } .groupTuple() .map { [[id:it[0]], it[1]] } - METAPHLAN3_MERGEMETAPHLANTABLES ( ch_profiles_for_metaphlan3 ) - ch_multiqc_files = ch_multiqc_files.mix( METAPHLAN3_MERGEMETAPHLANTABLES.out.txt ) - ch_versions = ch_versions.mix( METAPHLAN3_MERGEMETAPHLANTABLES.out.versions ) + METAPHLAN_MERGEMETAPHLANTABLES ( ch_profiles_for_metaphlan ) + ch_multiqc_files = ch_multiqc_files.mix( METAPHLAN_MERGEMETAPHLANTABLES.out.txt ) + ch_versions = ch_versions.mix( METAPHLAN_MERGEMETAPHLANTABLES.out.versions ) // mOTUs From 61e4ecad1d5dd79ce4d9d832420501a6d7b0fcc5 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:28:38 +0200 Subject: [PATCH 20/31] update the pipeline schema --- modules.json | 12 ++++++------ nextflow_schema.json | 20 +++++++++++++++----- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/modules.json b/modules.json index 82b9f02c..7d907540 100644 --- a/modules.json +++ b/modules.json @@ -156,14 +156,14 @@ "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", "installed_by": ["modules"] }, - "metaphlan3/mergemetaphlantables": { + "metaphlan/mergemetaphlantables": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "9aa59197c0fb35c29e315bcd10c0fc9e1afc70a8", "installed_by": ["modules"] }, - "metaphlan3/metaphlan3": { + "metaphlan/metaphlan": { "branch": "master", - "git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c", + "git_sha": "31ec4470b455fe88c072151a5ea7821bfb2add38", "installed_by": ["modules"] }, "minimap2/align": { @@ -224,12 +224,12 @@ }, "taxpasta/merge": { "branch": "master", - "git_sha": "ffa9641ee18f88aff974257cb50ba3cf8f7d143c", + "git_sha": "ef280893021dd1e877db163966022cabae06dfdb", "installed_by": ["modules"] }, "taxpasta/standardise": { "branch": "master", - "git_sha": "911696ea0b62df80e900ef244d7867d177971f73", + "git_sha": "ef280893021dd1e877db163966022cabae06dfdb", "installed_by": ["modules"] }, "untar": { diff --git a/nextflow_schema.json b/nextflow_schema.json index f58bcd06..46a1e514 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -159,7 +159,7 @@ }, "shortread_complexityfilter_entropy": { "type": "number", - "default": 0.3, + "default": 0.299999999999999988897769753748434595763683319091796875, "fa_icon": "fas fa-random", "description": "Specify the minimum sequence entropy level for complexity filtering", "help_text": "Specify the minimum 'entropy' value for complexity filtering for BBDuk or PRINSEQ++.\n\nNote that this value will only be used for PRINSEQ++ if `--shortread_complexityfilter_prinseqplusplus_mode` is set to `entropy`.\n\nEntropy here corresponds to the amount of sequence variation exists within the read. Higher values correspond to more variety, and thus will likely reslut in more specific matching to a taxon's reference genome. The trade off here is fewer reads (or abundance information) available for having a confident identification.\n\n\n> Modifies tool parameter(s):\n> - BBDuk: `entropy=`\n> - PRINSEQ++: `-lc_entropy`\n\n" @@ -468,9 +468,9 @@ "description": "Turn on generation of MEGAN summary file from MALT results", "help_text": "Turns on saving of MALT output in an additional MEGAN summary file (`.megan`) that can be loaded into the MEGAN metagenomic exploration tool.\n\nNote: this file is generated not directly from MALT but rather then MEGAN utility script `rma2info`.\n\n> Modifies tool parameter(s):\n> - rma2info: `-es`" }, - "run_metaphlan3": { + "run_metaphlan": { "type": "boolean", - "description": "Turn on profiling with MetaPhlAn3. Requires database to be present CSV file passed to --databases", + "description": "Turn on profiling with MetaPhlAn. Requires database to be present CSV file passed to --databases", "fa_icon": "fas fa-toggle-on" }, "run_motus": { @@ -555,7 +555,7 @@ "type": "boolean", "fa_icon": "fas fa-toggle-on", "description": "Turn on standardisation of taxon tables across profilers", - "help_text": "Turns on standardisation of output OTU tables across all tools.\n\nThis happens in two forms, firstly - if available - by a given classifiers/profilers 'native' profile merger and standardisation (for Bracken, Kaiju, Kraken, Centrifuge, MetaPhlAn3, mOTUs), and secondly for _all_ classifier/profilers in the pipeline using [`taxpasta`](https://taxpasta.readthedocs.io).\n\nIn the latter case, taxpasta generates a standardised output as follows:\n\n|TAXON | SAMPLE_A | SAMPLE_B |\n|-------------|----------------|-----------------|\n| taxon_a | 32 | 123 |\n| taxon_b | 1 | 5 |\n\nwhereas all other 'native' tools have varying format outputs. See pipeline [output](https://nf-co.re/taxprofiler) documentation for more information." + "help_text": "Turns on standardisation of output OTU tables across all tools.\n\nThis happens in two forms, firstly - if available - by a given classifiers/profilers 'native' profile merger and standardisation (for Bracken, Kaiju, Kraken, Centrifuge, MetaPhlAn, mOTUs), and secondly for _all_ classifier/profilers in the pipeline using [`taxpasta`](https://taxpasta.readthedocs.io).\n\nIn the latter case, taxpasta generates a standardised output as follows:\n\n|TAXON | SAMPLE_A | SAMPLE_B |\n|-------------|----------------|-----------------|\n| taxon_a | 32 | 123 |\n| taxon_b | 1 | 5 |\n\nwhereas all other 'native' tools have varying format outputs. See pipeline [output](https://nf-co.re/taxprofiler) documentation for more information." }, "standardisation_motus_generatebiom": { "type": "boolean", @@ -870,5 +870,15 @@ { "$ref": "#/definitions/reference_genome_options" } - ] + ], + "properties": { + "schema_ignore_params": { + "type": "string", + "default": "genomes,fasta" + }, + "fasta": { + "type": "string", + "default": null + } + } } From 4531549fc1b14bd8a8c7671deb3c99831e0a43e0 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 09:29:13 +0200 Subject: [PATCH 21/31] install the module metaphlan --- .../metaphlan/mergemetaphlantables/main.nf | 33 +++++++++++ .../metaphlan/mergemetaphlantables/meta.yml | 45 ++++++++++++++ modules/nf-core/metaphlan/metaphlan/main.nf | 50 ++++++++++++++++ modules/nf-core/metaphlan/metaphlan/meta.yml | 59 +++++++++++++++++++ 4 files changed, 187 insertions(+) create mode 100644 modules/nf-core/metaphlan/mergemetaphlantables/main.nf create mode 100644 modules/nf-core/metaphlan/mergemetaphlantables/meta.yml create mode 100644 modules/nf-core/metaphlan/metaphlan/main.nf create mode 100644 modules/nf-core/metaphlan/metaphlan/meta.yml diff --git a/modules/nf-core/metaphlan/mergemetaphlantables/main.nf b/modules/nf-core/metaphlan/mergemetaphlantables/main.nf new file mode 100644 index 00000000..94c70cd6 --- /dev/null +++ b/modules/nf-core/metaphlan/mergemetaphlantables/main.nf @@ -0,0 +1,33 @@ +process METAPHLAN_MERGEMETAPHLANTABLES { + label 'process_single' + + conda "bioconda::metaphlan=4.0.6" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/metaphlan:4.0.6--pyhca03a8a_0' : + 'quay.io/biocontainers/metaphlan:4.0.6--pyhca03a8a_0' }" + + input: + tuple val(meta), path(profiles) + + output: + tuple val(meta), path("${prefix}.txt") , emit: txt + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + merge_metaphlan_tables.py \\ + $args \\ + -o ${prefix}.txt \\ + ${profiles} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + metaphlan: \$(metaphlan --version 2>&1 | awk '{print \$3}') + END_VERSIONS + """ +} diff --git a/modules/nf-core/metaphlan/mergemetaphlantables/meta.yml b/modules/nf-core/metaphlan/mergemetaphlantables/meta.yml new file mode 100644 index 00000000..3c93964b --- /dev/null +++ b/modules/nf-core/metaphlan/mergemetaphlantables/meta.yml @@ -0,0 +1,45 @@ +name: "metaphlan_mergemetaphlantables" +description: Merges output abundance tables from MetaPhlAn4 +keywords: + - metagenomics + - classification + - merge + - table + - profiles +tools: + - metaphlan4: + description: Identify clades (phyla to species) present in the metagenome obtained from a microbiome sample and their relative abundance + homepage: https://huttenhower.sph.harvard.edu/metaphlan/ + documentation: https://github.com/biobakery/MetaPhlAn + doi: "10.1038/s41587-023-01688-w" + licence: ["MIT License"] + +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - profiles: + type: file + description: List of per-sample MetaPhlAn4 taxonomic abundance tables + pattern: "*" + +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + - txt: + type: file + description: Combined MetaPhlAn4 table + pattern: "*.txt" + +authors: + - "@jfy133" + - "@LilyAnderssonLee" diff --git a/modules/nf-core/metaphlan/metaphlan/main.nf b/modules/nf-core/metaphlan/metaphlan/main.nf new file mode 100644 index 00000000..477f1f28 --- /dev/null +++ b/modules/nf-core/metaphlan/metaphlan/main.nf @@ -0,0 +1,50 @@ +process METAPHLAN_METAPHLAN { + tag "$meta.id" + label 'process_medium' + + conda "bioconda::metaphlan=4.0.6" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/metaphlan:4.0.6--pyhca03a8a_0' : + 'biocontainers/metaphlan:4.0.6--pyhca03a8a_0' }" + + input: + tuple val(meta), path(input) + path metaphlan_db_latest + + output: + tuple val(meta), path("*_profile.txt") , emit: profile + tuple val(meta), path("*.biom") , emit: biom + tuple val(meta), path('*.bowtie2out.txt'), optional:true, emit: bt2out + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def input_type = "$input" =~ /.*\.(fastq|fq)/ ? "--input_type fastq" : "$input" =~ /.*\.(fasta|fna|fa)/ ? "--input_type fasta" : "$input".endsWith(".bowtie2out.txt") ? "--input_type bowtie2out" : "--input_type sam" + def input_data = ("$input_type".contains("fastq")) && !meta.single_end ? "${input[0]},${input[1]}" : "$input" + def bowtie2_out = "$input_type" == "--input_type bowtie2out" || "$input_type" == "--input_type sam" ? '' : "--bowtie2out ${prefix}.bowtie2out.txt" + + """ + BT2_DB=`find -L "${metaphlan_db_latest}" -name "*rev.1.bt2l" -exec dirname {} \\;` + BT2_DB_INDEX=`find -L ${metaphlan_db_latest} -name "*.rev.1.bt2l" | sed 's/\\.rev.1.bt2l\$//' | sed 's/.*\\///'` + + metaphlan \\ + --nproc $task.cpus \\ + $input_type \\ + $input_data \\ + $args \\ + $bowtie2_out \\ + --bowtie2db \$BT2_DB \\ + --index \$BT2_DB_INDEX \\ + --biom ${prefix}.biom \\ + --output_file ${prefix}_profile.txt + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + metaphlan: \$(metaphlan --version 2>&1 | awk '{print \$3}') + END_VERSIONS + """ +} diff --git a/modules/nf-core/metaphlan/metaphlan/meta.yml b/modules/nf-core/metaphlan/metaphlan/meta.yml new file mode 100644 index 00000000..cb74bd59 --- /dev/null +++ b/modules/nf-core/metaphlan/metaphlan/meta.yml @@ -0,0 +1,59 @@ +name: metaphlan_metaphlan +description: MetaPhlAn is a tool for profiling the composition of microbial communities from metagenomic shotgun sequencing data. +keywords: + - metagenomics + - classification + - fastq + - fasta + - sam +tools: + - metaphlan: + description: Identify clades (phyla to species) present in the metagenome obtained from a microbiome sample and their relative abundance + homepage: https://huttenhower.sph.harvard.edu/metaphlan/ + documentation: https://github.com/biobakery/MetaPhlAn + doi: "10.1038/s41587-023-01688-w" + licence: ["MIT License"] + +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - input: + type: file + description: Metaphlan can classify the metagenome from a variety of input data types, including FASTQ files (single-end and paired-end), FASTA, bowtie2-produced SAM files (produced from alignments to the MetaPHlAn marker database) and intermediate bowtie2 alignment files (bowtie2out) + pattern: "*.{fastq.gz, fasta, fasta.gz, sam, bowtie2out.txt}" + - metaphlan_db: + type: file + description: | + Directory containing pre-downloaded and uncompressed MetaPhlAn database downloaded from: http://cmprod1.cibio.unitn.it/biobakery4/metaphlan_databases/. + Note that you will also need to specify `--index` and the database version name (e.g. 'mpa_vJan21_TOY_CHOCOPhlAnSGB_202103') in your module.conf ext.args for METAPHLAN_METAPHLAN! + pattern: "*/" + +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + - profile: + type: file + description: Tab-separated output file of the predicted taxon relative abundances + pattern: "*.{txt}" + - biom: + type: file + description: General-use format for representing biological sample by observation contingency tables + pattern: "*.{biom}" + - bowtie2out: + type: file + description: Intermediate Bowtie2 output produced from mapping the metagenome against the MetaPHlAn marker database ( not compatible with `bowtie2out` files generated with MetaPhlAn versions below 3 ) + pattern: "*.{bowtie2out.txt}" + +authors: + - "@MGordon09" + - "@LilyAnderssonLee" From 4f945e3f92e74484b79f16aa9fa66d888946beac Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 11:17:39 +0200 Subject: [PATCH 22/31] nf-core lint fix format .github/CONTRIBUTING.md --- .github/CONTRIBUTING.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d6f5aa41..4b2f0c9f 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -116,4 +116,3 @@ To get started: Devcontainer specs: - [DevContainer config](.devcontainer/devcontainer.json) -- [Dockerfile](.devcontainer/Dockerfile) From 985464e24db2dae6c8b426ad9b66af69b9a44bbf Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 11:17:59 +0200 Subject: [PATCH 23/31] nf-core lint fix format --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- assets/nf-core-taxprofiler_logo_light.png | Bin 11915 -> 78065 bytes lib/NfcoreTemplate.groovy | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 4f0c0602..61971716 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -42,7 +42,7 @@ body: attributes: label: System information description: | - * Nextflow version _(eg. 22.10.1)_ + * Nextflow version _(eg. 23.04.0)_ * Hardware _(eg. HPC, Desktop, Cloud)_ * Executor _(eg. slurm, local, awsbatch)_ * Container engine: _(e.g. Docker, Singularity, Conda, Podman, Shifter, Charliecloud, or Apptainer)_ diff --git a/assets/nf-core-taxprofiler_logo_light.png b/assets/nf-core-taxprofiler_logo_light.png index 18ede344948b182bbec65f39d20212043eca8ae6..7e61612f944d0e56afc5d28e44896d9ea4306850 100644 GIT binary patch literal 78065 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�ev`Q}H7y#R1zKkC5n?0_OP7^FqWWeXhX0t0pNK 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

)bNtXB<>| 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 literal 11915 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 JgtC3i{{s?E(Wd|a diff --git a/lib/NfcoreTemplate.groovy b/lib/NfcoreTemplate.groovy index 25a0a74a..408951ae 100755 --- a/lib/NfcoreTemplate.groovy +++ b/lib/NfcoreTemplate.groovy @@ -128,7 +128,7 @@ class NfcoreTemplate { def email_html = html_template.toString() // Render the sendmail template - def max_multiqc_email_size = params.max_multiqc_email_size as nextflow.util.MemoryUnit + def max_multiqc_email_size = (params.containsKey('max_multiqc_email_size') ? params.max_multiqc_email_size : 0) as nextflow.util.MemoryUnit def smail_fields = [ email: email_address, subject: subject, email_txt: email_txt, email_html: email_html, projectDir: "$projectDir", mqcFile: mqc_report, mqcMaxSize: max_multiqc_email_size.toBytes() ] def sf = new File("$projectDir/assets/sendmail_template.txt") def sendmail_template = engine.createTemplate(sf).make(smail_fields) From 2f8e3709b84883fe36acb76c65151c0ad4e6b8ba Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 7 Jul 2023 11:18:37 +0200 Subject: [PATCH 24/31] Update into the most recent version on dev --- nextflow.config | 57 +++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/nextflow.config b/nextflow.config index 344cf063..c97667fb 100644 --- a/nextflow.config +++ b/nextflow.config @@ -11,12 +11,12 @@ params { // Input options input = null - - // References genome = null igenomes_base = 's3://ngi-igenomes/igenomes' igenomes_ignore = false + + // MultiQC options multiqc_config = null multiqc_title = null @@ -26,7 +26,6 @@ params { // Boilerplate options outdir = null - tracedir = "${params.outdir}/pipeline_info" publish_dir_mode = 'copy' email = null email_on_fail = null @@ -35,19 +34,15 @@ params { hook_url = null help = false version = false - validate_params = true - show_hidden_params = false - schema_ignore_params = 'genomes,fasta' - // Config options + config_profile_name = null + config_profile_description = null custom_config_version = 'master' custom_config_base = "https://raw.githubusercontent.com/nf-core/configs/${params.custom_config_version}" - config_profile_description = null config_profile_contact = null config_profile_url = null - config_profile_name = null - + // Max resource options // Defaults only, expecting to be overwritten @@ -55,6 +50,13 @@ params { max_cpus = 16 max_time = '240.h' + // Schema validation default options + validationFailUnrecognisedParams = false + validationLenientMode = false + validationSchemaIgnoreParams = 'genomes,fasta' + validationShowHiddenParams = false + validate_params = true + // Databases databases = null @@ -189,17 +191,16 @@ try { // Load nf-core/taxprofiler custom profiles from different institutions. // Warning: Uncomment only if a pipeline-specific instititutional config already exists on nf-core/configs! try { - includeConfig "${params.custom_config_base}/pipeline/taxprofiler.config" -} catch (Exception e) { - System.err.println("WARNING: Could not load nf-core/config/taxprofiler profiles: ${params.custom_config_base}/pipeline/taxprofiler.config") -} - + includeConfig "${params.custom_config_base}/pipeline/taxprofiler.config" + } catch (Exception e) { + System.err.println("WARNING: Could not load nf-core/config/taxprofiler profiles: ${params.custom_config_base}/pipeline/taxprofiler.config") + } profiles { debug { dumpHashes = true process.beforeScript = 'echo $HOSTNAME' - cleanup = false + cleanup = false } conda { conda.enabled = true @@ -293,6 +294,18 @@ profiles { test_krakenuniq { includeConfig 'conf/test_krakenuniq.config' } } +// Set default registry for Apptainer, Docker, Podman and Singularity independent of -profile +// Will not be used unless Apptainer / Docker / Podman / Singularity are enabled +// Set to your registry if you have a mirror of containers +apptainer.registry = 'quay.io' +docker.registry = 'quay.io' +podman.registry = 'quay.io' +singularity.registry = 'quay.io' + +// Nextflow plugins +plugins { + id 'nf-validation' // Validation of pipeline parameters and creation of an input channel from a sample sheet +} // Load igenomes.config if required @@ -301,8 +314,6 @@ if (!params.igenomes_ignore) { } else { params.genomes = [:] } - - // Export these variables to prevent local Python/R libraries from conflicting with those in the container // The JULIA depot path has been adjusted to a fixed path `/usr/local/share/julia` that needs to be used for packages in the container. // See https://apeltzer.github.io/post/03-julia-lang-nextflow/ for details on that. Once we have a common agreement on where to keep Julia packages, this is adjustable. @@ -326,19 +337,19 @@ podman.registry = 'quay.io' def trace_timestamp = new java.util.Date().format( 'yyyy-MM-dd_HH-mm-ss') timeline { enabled = true - file = "${params.tracedir}/execution_timeline_${trace_timestamp}.html" + file = "${params.outdir}/pipeline_info/execution_timeline_${trace_timestamp}.html" } report { enabled = true - file = "${params.tracedir}/execution_report_${trace_timestamp}.html" + file = "${params.outdir}/pipeline_info/execution_report_${trace_timestamp}.html" } trace { enabled = true - file = "${params.tracedir}/execution_trace_${trace_timestamp}.txt" + file = "${params.outdir}/pipeline_info/execution_trace_${trace_timestamp}.txt" } dag { enabled = true - file = "${params.tracedir}/pipeline_dag_${trace_timestamp}.html" + file = "${params.outdir}/pipeline_info/pipeline_dag_${trace_timestamp}.html" } manifest { @@ -347,7 +358,7 @@ manifest { homePage = 'https://github.com/nf-core/taxprofiler' description = """Taxonomic classification and profiling of shotgun and long-read metagenomic data""" mainScript = 'main.nf' - nextflowVersion = '!>=22.10.1' + nextflowVersion = '!>=23.04.0' version = '1.1.0dev' doi = '10.5281/zenodo.7728364' } From 5cb7d970a836bdd7c17493161185afadb0d2bbb9 Mon Sep 17 00:00:00 2001 From: Lili Andersson-Li <64467552+LilyAnderssonLee@users.noreply.github.com> Date: Mon, 10 Jul 2023 11:36:33 +0200 Subject: [PATCH 25/31] Modify nextflow_schema.json --- nextflow_schema.json | 55 ++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/nextflow_schema.json b/nextflow_schema.json index 46a1e514..e28f191a 100644 --- a/nextflow_schema.json +++ b/nextflow_schema.json @@ -2,7 +2,7 @@ "$schema": "http://json-schema.org/draft-07/schema", "$id": "https://raw.githubusercontent.com/nf-core/taxprofiler/master/nextflow_schema.json", "title": "nf-core/taxprofiler pipeline parameters", - "description": "Taxonomic classification and profiling of shotgun metagenomic data", + "description": "Taxonomic classification and profiling of shotgun and long-read metagenomic data", "type": "object", "definitions": { "input_output_options": { @@ -15,9 +15,9 @@ "input": { "type": "string", "format": "file-path", + "exists": true, "mimetype": "text/csv", - "pattern": "^\\S+\\.(csv)$", - "schema": "assets/schema_input.json", + "pattern": "^\\S+\\.csv$", "description": "Path to comma-separated file containing information about the samples and libraries/runs.", "help_text": "You will need to create a design file with information about the samples and libraries/runs you want to running in your pipeline run. Use this parameter to specify its location. It has to be a comma-separated file with 6 columns, and a header row. See [usage docs](https://nf-co.re/taxprofiler/usage#samplesheet-input).", "fa_icon": "fas fa-file-csv" @@ -159,7 +159,7 @@ }, "shortread_complexityfilter_entropy": { "type": "number", - "default": 0.299999999999999988897769753748434595763683319091796875, + "default": 0.3, "fa_icon": "fas fa-random", "description": "Specify the minimum sequence entropy level for complexity filtering", "help_text": "Specify the minimum 'entropy' value for complexity filtering for BBDuk or PRINSEQ++.\n\nNote that this value will only be used for PRINSEQ++ if `--shortread_complexityfilter_prinseqplusplus_mode` is set to `entropy`.\n\nEntropy here corresponds to the amount of sequence variation exists within the read. Higher values correspond to more variety, and thus will likely reslut in more specific matching to a taxon's reference genome. The trade off here is fewer reads (or abundance information) available for having a confident identification.\n\n\n> Modifies tool parameter(s):\n> - BBDuk: `entropy=`\n> - PRINSEQ++: `-lc_entropy`\n\n" @@ -555,7 +555,7 @@ "type": "boolean", "fa_icon": "fas fa-toggle-on", "description": "Turn on standardisation of taxon tables across profilers", - "help_text": "Turns on standardisation of output OTU tables across all tools.\n\nThis happens in two forms, firstly - if available - by a given classifiers/profilers 'native' profile merger and standardisation (for Bracken, Kaiju, Kraken, Centrifuge, MetaPhlAn, mOTUs), and secondly for _all_ classifier/profilers in the pipeline using [`taxpasta`](https://taxpasta.readthedocs.io).\n\nIn the latter case, taxpasta generates a standardised output as follows:\n\n|TAXON | SAMPLE_A | SAMPLE_B |\n|-------------|----------------|-----------------|\n| taxon_a | 32 | 123 |\n| taxon_b | 1 | 5 |\n\nwhereas all other 'native' tools have varying format outputs. See pipeline [output](https://nf-co.re/taxprofiler) documentation for more information." + "help_text": "Turns on standardisation of output OTU tables across all tools.\n\nThis happens in two forms, firstly - if available - by a given classifiers/profilers 'native' profile merger and standardisation (for Bracken, Kaiju, Kraken, Centrifuge, MetaPhlAn3, mOTUs), and secondly for _all_ classifier/profilers in the pipeline using [`taxpasta`](https://taxpasta.readthedocs.io).\n\nIn the latter case, taxpasta generates a standardised output as follows:\n\n|TAXON | SAMPLE_A | SAMPLE_B |\n|-------------|----------------|-----------------|\n| taxon_a | 32 | 123 |\n| taxon_b | 1 | 5 |\n\nwhereas all other 'native' tools have varying format outputs. See pipeline [output](https://nf-co.re/taxprofiler) documentation for more information." }, "standardisation_motus_generatebiom": { "type": "boolean", @@ -693,7 +693,7 @@ "description": "Maximum amount of time that can be requested for any single job.", "default": "240.h", "fa_icon": "far fa-clock", - "pattern": "^(\\d+\\.?\\s*(s|m|h|day)\\s*)+$", + "pattern": "^(\\d+\\.?\\s*(s|m|h|d|day)\\s*)+$", "hidden": true, "help_text": "Use to set an upper-limit for the time requirement for each process. Should be a string in the format integer-unit e.g. `--max_time '2.h'`" } @@ -710,12 +710,14 @@ "type": "boolean", "description": "Display help text.", "fa_icon": "fas fa-question-circle", + "default": false, "hidden": true }, "version": { "type": "boolean", "description": "Display version and exit.", "fa_icon": "fas fa-question-circle", + "default": false, "hidden": true }, "publish_dir_mode": { @@ -739,6 +741,7 @@ "type": "boolean", "description": "Send plain-text email instead of HTML.", "fa_icon": "fas fa-remove-format", + "default": false, "hidden": true }, "max_multiqc_email_size": { @@ -753,6 +756,7 @@ "type": "boolean", "description": "Do not use coloured log outputs.", "fa_icon": "fas fa-palette", + "default": false, "hidden": true }, "hook_url": { @@ -764,6 +768,7 @@ }, "multiqc_config": { "type": "string", + "format": "file-path", "description": "Custom config file to supply to MultiQC.", "fa_icon": "fas fa-cog", "hidden": true @@ -779,13 +784,6 @@ "description": "Custom MultiQC yaml file containing HTML including a methods description.", "fa_icon": "fas fa-cog" }, - "tracedir": { - "type": "string", - "description": "Directory to keep pipeline Nextflow logs and reports.", - "default": "${params.outdir}/pipeline_info", - "fa_icon": "fas fa-cogs", - "hidden": true - }, "validate_params": { "type": "boolean", "description": "Boolean whether to validate parameters against the schema at runtime", @@ -793,12 +791,29 @@ "fa_icon": "fas fa-check-square", "hidden": true }, - "show_hidden_params": { + "validationShowHiddenParams": { "type": "boolean", "fa_icon": "far fa-eye-slash", "description": "Show all params when using `--help`", + "default": false, "hidden": true, "help_text": "By default, parameters set as _hidden_ in the schema are not shown on the command line when a user runs with `--help`. Specifying this option will tell the pipeline to show all parameters." + }, + "validationFailUnrecognisedParams": { + "type": "boolean", + "fa_icon": "far fa-check-circle", + "description": "Validation of parameters fails when an unrecognised parameter is found.", + "default": false, + "hidden": true, + "help_text": "By default, when an unrecognised parameter is found, it returns a warinig." + }, + "validationLenientMode": { + "type": "boolean", + "fa_icon": "far fa-check-circle", + "description": "Validation of parameters in lenient more.", + "default": false, + "hidden": true, + "help_text": "Allows string values that are parseable as numbers or booleans. For further information see [JSONSchema docs](https://github.com/everit-org/json-schema#lenient-mode)." } } }, @@ -870,15 +885,5 @@ { "$ref": "#/definitions/reference_genome_options" } - ], - "properties": { - "schema_ignore_params": { - "type": "string", - "default": "genomes,fasta" - }, - "fasta": { - "type": "string", - "default": null - } - } + ] } From e03f3170a625a72c95c3d956305d3cdb009bc37f Mon Sep 17 00:00:00 2001 From: Lili Andersson-Li <64467552+LilyAnderssonLee@users.noreply.github.com> Date: Thu, 13 Jul 2023 13:36:10 +0200 Subject: [PATCH 26/31] comment krakenuniq step ci.yml --- .github/workflows/ci.yml | 66 ++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 89598447..3b59a6b4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,39 +97,39 @@ jobs: command: nextflow run ${GITHUB_WORKSPACE} -profile test_motus,docker --outdir ./results --databases ./database_motus.csv attempt_limit: 3 - krakenuniq: - name: Test KrakenUniq with workflow parameters - if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/taxprofiler') }} - runs-on: ubuntu-latest - strategy: - matrix: - NXF_VER: - - "22.10.1" - - "latest-everything" - - steps: - - name: Check out pipeline code - uses: actions/checkout@v2 - - - name: Install Nextflow - uses: nf-core/setup-nextflow@v1 - with: - version: "${{ matrix.NXF_VER }}" - - - name: Show current locale - run: locale - - - name: Set UTF-8 enabled locale - run: | - sudo locale-gen en_US.UTF-8 - sudo update-locale LANG=en_US.UTF-8 - - - name: Run pipeline with test data - uses: Wandalen/wretry.action@v1.0.11 - with: - command: nextflow run ${GITHUB_WORKSPACE} -profile test_krakenuniq,docker --outdir ./results - attempt_limit: 3 - +# krakenuniq: +# name: Test KrakenUniq with workflow parameters +# if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/taxprofiler') }} +# runs-on: ubuntu-latest +# strategy: +# matrix: +# NXF_VER: +# - "22.10.1" +# - "latest-everything" +# +# steps: +# - name: Check out pipeline code +# uses: actions/checkout@v2 +# +# - name: Install Nextflow +# uses: nf-core/setup-nextflow@v1 +# with: +# version: "${{ matrix.NXF_VER }}" +# +# - name: Show current locale +# run: locale +# +# - name: Set UTF-8 enabled locale +# run: | +# sudo locale-gen en_US.UTF-8 +# sudo update-locale LANG=en_US.UTF-8 +# +# - name: Run pipeline with test data +# uses: Wandalen/wretry.action@v1.0.11 +# with: +# command: nextflow run ${GITHUB_WORKSPACE} -profile test_krakenuniq,docker --outdir ./results +# attempt_limit: 3 +# malt: name: Test MALT with workflow parameters if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/taxprofiler') }} From 9b7ffb84b6ec64450cb71a80e42cb7ee73ae66ee Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Thu, 13 Jul 2023 14:56:26 +0200 Subject: [PATCH 27/31] Add MetaPhlAn4 to docs/usage.md --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 40eb5739..b43194f4 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -300,7 +300,7 @@ Krona can only be run on MALT output if path to Krona taxonomy database supplied ##### MetaPhlAn -MetaPhlAn currently does not accept FASTA files as input, therefore no output will be produced for these input files. +MetaPhlAn4 is compatible with the MetaPhlAn3 database by adding the `--mpa3` paramter to the MetaPhlAn process in the config file `module.config`. ##### mOTUs From 9061278edd2959a45046531351769b85bdebdc76 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Thu, 13 Jul 2023 15:07:32 +0200 Subject: [PATCH 28/31] Add contribution to the CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77a8dfb2..6eba489f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#303](https://github.com/nf-core/taxprofiler/pull/303) Add support for taxpasta profile standardisation in single sample pipeline runs (❤️ to @artur-matysik for request, added by @jfy133) - [#315](https://github.com/nf-core/taxprofiler/pull/315) Updated to nf-core pipeline template v2.9 (added by @sofstam & @jfy133) - [#319](https://github.com/nf-core/taxprofiler/pull/319) Added support for virus hit expansion in Kaiju (❤️ to @dnlrxn for requesting, added by @jfy133) + - [#318](https://github.com/nf-core/taxprofiler/pull/318) Added the profiler MetaPhlAn4 and removed MetaPhlAn3 (added by@LilyAnderssonLee) ### `Fixed` From 75581b0bf92264d7c9be3127af903bcbf483b036 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 14 Jul 2023 13:00:53 +0200 Subject: [PATCH 29/31] uncomment KrakenUniq in ci.yml --- .github/workflows/ci.yml | 64 ++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3d0648dc..e054932c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,38 +97,38 @@ jobs: command: nextflow run ${GITHUB_WORKSPACE} -profile test_motus,docker --outdir ./results --databases ./database_motus.csv attempt_limit: 3 - # krakenuniq: - # name: Test KrakenUniq with workflow parameters - # if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/taxprofiler') }} - # runs-on: ubuntu-latest - # strategy: - # matrix: - # NXF_VER: - # - "23.04.0" - # - "latest-everything" - # - # steps: - # - name: Check out pipeline code - # uses: actions/checkout@v2 - # - # - name: Install Nextflow - # uses: nf-core/setup-nextflow@v1 - # with: - # version: "${{ matrix.NXF_VER }}" - # - # - name: Show current locale - # run: locale - # - # - name: Set UTF-8 enabled locale - # run: | - # sudo locale-gen en_US.UTF-8 - # sudo update-locale LANG=en_US.UTF-8 - # - # - name: Run pipeline with test data - # uses: Wandalen/wretry.action@v1.0.11 - # with: - # command: nextflow run ${GITHUB_WORKSPACE} -profile test_krakenuniq,docker --outdir ./results - # attempt_limit: 3 + krakenuniq: + name: Test KrakenUniq with workflow parameters + if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/taxprofiler') }} + runs-on: ubuntu-latest + strategy: + matrix: + NXF_VER: + - "23.04.0" + - "latest-everything" + + steps: + - name: Check out pipeline code + uses: actions/checkout@v2 + + - name: Install Nextflow + uses: nf-core/setup-nextflow@v1 + with: + version: "${{ matrix.NXF_VER }}" + + - name: Show current locale + run: locale + + - name: Set UTF-8 enabled locale + run: | + sudo locale-gen en_US.UTF-8 + sudo update-locale LANG=en_US.UTF-8 + + - name: Run pipeline with test data + uses: Wandalen/wretry.action@v1.0.11 + with: + command: nextflow run ${GITHUB_WORKSPACE} -profile test_krakenuniq,docker --outdir ./results + attempt_limit: 3 malt: name: Test MALT with workflow parameters From bc27e8a7a68bcc767c93a223318046a09e8b24d9 Mon Sep 17 00:00:00 2001 From: LilyAnderssonLee Date: Fri, 14 Jul 2023 16:12:22 +0200 Subject: [PATCH 30/31] pull the ci.yml from dev branch --- .github/workflows/ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e054932c..c706a4b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,7 +97,7 @@ jobs: command: nextflow run ${GITHUB_WORKSPACE} -profile test_motus,docker --outdir ./results --databases ./database_motus.csv attempt_limit: 3 - krakenuniq: + krakenuniq: name: Test KrakenUniq with workflow parameters if: ${{ github.event_name != 'push' || (github.event_name == 'push' && github.repository == 'nf-core/taxprofiler') }} runs-on: ubuntu-latest @@ -106,24 +106,24 @@ jobs: NXF_VER: - "23.04.0" - "latest-everything" - + steps: - name: Check out pipeline code uses: actions/checkout@v2 - + - name: Install Nextflow uses: nf-core/setup-nextflow@v1 with: version: "${{ matrix.NXF_VER }}" - + - name: Show current locale run: locale - + - name: Set UTF-8 enabled locale run: | sudo locale-gen en_US.UTF-8 sudo update-locale LANG=en_US.UTF-8 - + - name: Run pipeline with test data uses: Wandalen/wretry.action@v1.0.11 with: From 1be2aaa0594f22a395abd5be41ff6c5c0722eda2 Mon Sep 17 00:00:00 2001 From: Lili Andersson-Li <64467552+LilyAnderssonLee@users.noreply.github.com> Date: Mon, 17 Jul 2023 08:00:32 +0200 Subject: [PATCH 31/31] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08624715..8030912e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#315](https://github.com/nf-core/taxprofiler/pull/315) Updated to nf-core pipeline template v2.9 (added by @sofstam & @jfy133) - [#319](https://github.com/nf-core/taxprofiler/pull/319) Added support for virus hit expansion in Kaiju (❤️ to @dnlrxn for requesting, added by @jfy133) - [#323](https://github.com/nf-core/taxprofiler/pull/323) Add ability to skip sequencing quality control tools (❤️ to @vinisalazar for requesting, added by @jfy133) - - [#318](https://github.com/nf-core/taxprofiler/pull/318) Added the profiler MetaPhlAn4 and removed MetaPhlAn3 (added by@LilyAnderssonLee) + - [#318](https://github.com/nf-core/taxprofiler/pull/318) Added the profiler MetaPhlAn4 and removed MetaPhlAn3 (added by @LilyAnderssonLee) ### `Fixed`