diff --git a/modules/ensembl/taxanomy/environment.yml b/modules/ensembl/taxanomy/environment.yml new file mode 100644 index 0000000..8411965 --- /dev/null +++ b/modules/ensembl/taxanomy/environment.yml @@ -0,0 +1,7 @@ +--- +channels: + - conda-forge + - bioconda +dependencies: + - conda-forge::ncbi-datasets-cli=18.33.1 + - conda-forge::jq=1.7.1 diff --git a/modules/ensembl/taxanomy/main.nf b/modules/ensembl/taxanomy/main.nf new file mode 100644 index 0000000..a4bce40 --- /dev/null +++ b/modules/ensembl/taxanomy/main.nf @@ -0,0 +1,64 @@ +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +nextflow.enable.types = true + +process TAXONOMY_CLASSIFICATION { + tag "${meta.id}" + label 'process_small' + + conda "${moduleDir}/environment.yml" + container 'ensemblorg/datasets-cli:latest' + + input: + record( + meta: Map, + species: String + ) + + output: + record( + meta: meta, + species: species, + json: file("classification.json") + ) + + topic: + tuple("${task.process}", 'datasets', eval('datasets --version | sed "s/^.*datasets version: //"')) >> 'versions' + + script: + """ + echo "Calling datasets-cli for ${species}" + ids=\$(datasets summary taxonomy taxon "${species}" \ + | jq -r '.reports[0].taxonomy | ((.lineage // .parents)[], .tax_id)') + + datasets summary taxonomy taxon \$ids \ + | jq -r '.reports[].taxonomy.current_scientific_name.name' \ + | awk 'NF && !seen[\$0]++' \ + | jq -Rsc 'split("\n") | map(select(length > 0))'> classification.json + + if [ "\$(jq 'length' classification.json)" -eq 0 ]; then + echo "No classification found for ${species}" >&2 + exit 1 + fi + """ + + stub: + """ + cat <<'EOF' > classification.json + ["cellular organisms", "Eukaryota", "Viridiplantae"] + EOF + """ +} + diff --git a/modules/ensembl/taxanomy/meta.yml b/modules/ensembl/taxanomy/meta.yml new file mode 100644 index 0000000..2944b95 --- /dev/null +++ b/modules/ensembl/taxanomy/meta.yml @@ -0,0 +1,47 @@ +name: TAXONOMY_CLASSIFICATION +description: Retrieve a species lineage and write it as a JSON classification using datasets-cli. +keywords: + - taxonomy + - classification + - datasets-cli + - genomics +tools: + - datasets: + description: NCBI Datasets command-line tool. + homepage: https://www.ncbi.nlm.nih.gov/datasets/ + documentation: https://www.ncbi.nlm.nih.gov/datasets/docs/v2/command-line-tools/ + licence: ["Public Domain"] +input: + - - meta: + type: channelMap + description: Groovy map containing sample metadata, including a unique id. + - species: + type: string + description: Scientific species name passed to datasets-cli. +output: + classification: + - - meta: + type: channelMap + description: Sample metadata propagated from the input. + - species: + type: string + description: Species name propagated from the input. + - json: + type: file + description: JSON file containing the retrieved lineage classification. + pattern: "classification.json" +topics: + versions: + - - "${task.process}": + type: string + description: Name of the process producing the version. + - datasets: + type: string + description: Name of the tool. + - 'datasets --version | sed "s/^.*datasets version: //"': + type: eval + description: Command used to obtain the datasets version. +authors: + - "@ensembl-dev" +maintainers: + - "@ensembl-dev" diff --git a/modules/ensembl/taxanomy/tests/main.nf.test b/modules/ensembl/taxanomy/tests/main.nf.test new file mode 100644 index 0000000..e801f2d --- /dev/null +++ b/modules/ensembl/taxanomy/tests/main.nf.test @@ -0,0 +1,47 @@ +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +nextflow_process { + + name "Test Process TAXONOMY_CLASSIFICATION" + script "../main.nf" + process "TAXONOMY_CLASSIFICATION" + tag "modules" + tag "modules_ensembl" + tag "genome_classification" + + test("should create a lineage classification JSON") { + + options "-stub-run" + + when { + process { + """ + input[0] = record( + meta: [id: 'test_species'], + species: 'Arabidopsis thaliana' + ) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } +} diff --git a/modules/ensembl/taxanomy/tests/main.nf.test.snap b/modules/ensembl/taxanomy/tests/main.nf.test.snap new file mode 100644 index 0000000..f3ea752 --- /dev/null +++ b/modules/ensembl/taxanomy/tests/main.nf.test.snap @@ -0,0 +1,22 @@ +{ + "should create a lineage classification JSON": { + "content": [ + { + "0": [ + { + "json": "classification.json:md5,8a1b235fc7b2b83a658f7a9ec282b59e", + "meta": { + "id": "test_species" + }, + "species": "Arabidopsis thaliana" + } + ] + } + ], + "timestamp": "2026-08-06T15:48:40.679892238", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.0" + } + } +} \ No newline at end of file