Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions _tutorial/3.GeneClusterLinks.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ https://plantmetwiki.bioinformatics.nl/sparql

**Graph used in all queries**
```sparql
FROM <http://plantmetwiki.bioinformatics.nl/>
FROM <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways>

```

Expand Down Expand Up @@ -51,7 +51,7 @@ To get an overview of how many pathway–BGC links exist, you can list all known

```
SELECT ?pathway ?bgc
FROM <http://plantmetwiki.bioinformatics.nl/>
FROM <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways>
WHERE {
?pathway ?predicate ?bgc .
FILTER(CONTAINS(STR(?bgc), "BGC"))
Expand All @@ -77,7 +77,7 @@ Example query (from plantiSMASHLinks.rq):

```
SELECT ?pathway ?plantiSMASH_BGC
FROM <http://plantmetwiki.bioinformatics.nl/>
FROM <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways>
WHERE {
?pathway ?p ?plantiSMASH_BGC .
FILTER(CONTAINS(STR(?plantiSMASH_BGC), "plantiSMASH"))
Expand All @@ -104,7 +104,7 @@ Example query (from MIBiGLinks.rq):

```
SELECT ?pathway ?mibig
FROM <http://plantmetwiki.bioinformatics.nl/>
FROM <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways>
WHERE {
?pathway ?p ?mibig .
FILTER(CONTAINS(STR(?mibig), "mibig"))
Expand All @@ -124,7 +124,7 @@ Some pathways link to both predicted and curated clusters.
You can retrieve all BGC-related links regardless of source:
```
SELECT ?pathway ?bgc
FROM <http://plantmetwiki.bioinformatics.nl/>
FROM <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways>
WHERE {
?pathway ?p ?bgc .
FILTER(
Expand Down Expand Up @@ -152,7 +152,7 @@ PREFIX dcterms: <http://purl.org/dc/terms/>

# Retrieve thalianol pathway
SELECT DISTINCT ?pw (STR(?titleLit) AS ?title)
FROM <http://plantmetwiki.bioinformatics.nl/>
FROM <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways>
WHERE {
<https://bioregistry.io/mibig:BGC0000670> ro:0000051 ?gene .

Expand Down
10 changes: 5 additions & 5 deletions _tutorial/4.FederatedQueries.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ https://plantmetwiki.bioinformatics.nl/sparql

**Graph used in all queries**
```sparql
FROM <http://plantmetwiki.bioinformatics.nl/>
FROM <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways>
```

## What is a federated SPARQL query?
Expand Down Expand Up @@ -78,7 +78,7 @@ Example (from WikidataTest.rq):
PREFIX gpml: <http://vocabularies.wikipathways.org/gpml#>

SELECT ?metabolite ?wikidataItem
FROM <http://plantmetwiki.bioinformatics.nl/>
FROM <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways>
WHERE {
?pathway gpml:hasDataNode ?metabolite .

Expand All @@ -101,7 +101,7 @@ Example (from WikidataInChiKeys.rq):

```
SELECT ?metabolite ?inchiKey ?wikidataItem
FROM <http://plantmetwiki.bioinformatics.nl/>
FROM <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways>
WHERE {
?metabolite ?p ?inchiKey .
FILTER(CONTAINS(STR(?p), "InChIKey"))
Expand Down Expand Up @@ -134,7 +134,7 @@ Using InChIKeys or ChEBI IDs, you can retrieve:
Example (from FederatedMetabolitesChEBI.rq):
```
SELECT ?metabolite ?chebi
FROM <http://plantmetwiki.bioinformatics.nl/>
FROM <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways>
WHERE {
?metabolite ?p ?chebi .
FILTER(CONTAINS(STR(?chebi), "CHEBI"))
Expand Down Expand Up @@ -162,7 +162,7 @@ Using federated queries, you can:
Example (from ListPubMedIDs.rq):
```
SELECT DISTINCT ?pmid
FROM <http://plantmetwiki.bioinformatics.nl/>
FROM <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways>
WHERE {
?pathway ?p ?pmid .
FILTER(CONTAINS(STR(?pmid), "pubmed"))
Expand Down
238 changes: 238 additions & 0 deletions _tutorial/MultiSpecies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
---
layout: docs
title: "Modelling Multispecies pathways"
order: 80
---

PlantMetWiki integrates pathway data from **PlantCyc 17.0**, which covers biochemical reactions across **439 plant species** — from *Arabidopsis thaliana* to *Solanum tuberosum*, *Zea mays*, and many non-model species. This section explains how species information is stored and how to query it.

Goals:
1. Understand how multispecies annotation is modelled in PlantMetWiki
2. Retrieve species-specific genes, proteins, and pathways using SPARQL

---

## How species annotation works

In PlantMetWiki, **species annotations are at the DataNode level**, not the pathway level. Each gene or protein DataNode carries a `wp:organism` triple pointing to its NCBI Taxonomy IRI. Every pathway collectively covers Viridiplantae (the green plants clade), but individual genes and enzymes are annotated to the specific organism they come from.

This information is stored across **three named graphs** that need to be joined:

| Named graph | What it contains |
|---|---|
| `graph/pathways` | Core WikiPathways RDF: pathways, DataNodes, interactions |
| `graph/gpml-taxonomy-extra` | Per-DataNode species annotations (`wp:organism`) |
| `graph/ncbitaxon` | NCBITaxon ontology (OBO Foundry, CC0) for label resolution |

**SPARQL endpoint**
```
https://sparql-plantmetwiki.bioinformatics.nl/sparql
```

---

## Query 1 — List all species in PlantMetWiki

Species names are resolved via the local NCBITaxon ontology graph (loaded from the OBO Foundry `ncbitaxon.owl`).

```sparql
PREFIX wp: <http://vocabularies.wikipathways.org/wp#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX ncbi: <http://purl.obolibrary.org/obo/NCBITaxon_>

SELECT DISTINCT ?taxonID ?species
WHERE {
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/gpml-taxonomy-extra> {
?node wp:organism ?taxonID .
FILTER(?taxonID != ncbi:33090) # exclude pathway-level Viridiplantae
}
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/ncbitaxon> {
?taxonID rdfs:label ?species .
}
}
ORDER BY ?species
```

---

## Query 2 — Count pathways per species

```sparql
PREFIX wp: <http://vocabularies.wikipathways.org/wp#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX ncbi: <http://purl.obolibrary.org/obo/NCBITaxon_>

SELECT ?species (COUNT(DISTINCT ?pw) AS ?nPathways)
WHERE {
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/gpml-taxonomy-extra> {
?node wp:organism ?taxonID .
FILTER(?taxonID != ncbi:33090)
}
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways> {
?node dcterms:isPartOf ?pw .
}
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/ncbitaxon> {
?taxonID rdfs:label ?species .
}
}
GROUP BY ?species
ORDER BY DESC(?nPathways)
```

---

## Query 3 — All pathways for a given species (by name)

Replace `"Arabidopsis thaliana"` with any Latin species name.

```sparql
PREFIX wp: <http://vocabularies.wikipathways.org/wp#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX dcterms: <http://purl.org/dc/terms/>

SELECT DISTINCT ?pwID (STR(?titleLit) AS ?title) (COUNT(DISTINCT ?dataNode) AS ?nDataNodes)
WHERE {
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/ncbitaxon> {
?taxon rdfs:label "Arabidopsis thaliana" .
}
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/gpml-taxonomy-extra> {
?dataNode wp:organism ?taxon .
}
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways> {
?dataNode dcterms:isPartOf ?pw .
?pw a wp:Pathway ;
dc:identifier ?pwID ;
dc:title ?titleLit .
}
}
GROUP BY ?pwID ?titleLit
ORDER BY DESC(?nDataNodes)
```

---

## Query 4 — Proteins in pathways for a given taxon ID

Replace `ncbi:4113` with the NCBI Taxonomy ID of your species
(4113 = *Solanum tuberosum* / potato).

```sparql
PREFIX wp: <http://vocabularies.wikipathways.org/wp#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX ncbi: <http://purl.obolibrary.org/obo/NCBITaxon_>

SELECT DISTINCT ?protein (STR(?titleLit) AS ?title)
WHERE {
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/gpml-taxonomy-extra> {
?protein wp:organism ncbi:4113 .
}
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways> {
?protein a wp:Protein ;
dcterms:isPartOf ?pw .
?pw dc:title ?titleLit .
}
}
ORDER BY ?title
```

---

## Query 5 — Show all species in a specific pathway

Replace `pmw:PC159` with the pathway ID of interest.

```sparql
PREFIX wp: <http://vocabularies.wikipathways.org/wp#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX ncbi: <http://purl.obolibrary.org/obo/NCBITaxon_>
PREFIX pmw: <http://rdf-plantmetwiki.bioinformatics.nl/pathways/>

SELECT DISTINCT ?taxonID ?species ?title
WHERE {
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/pathways> {
?pw dc:identifier pmw:PC159 ;
dc:title ?title .
?dataNode dcterms:isPartOf ?pw .
}
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/gpml-taxonomy-extra> {
?dataNode wp:organism ?taxonID .
FILTER(?taxonID != ncbi:33090)
}
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/ncbitaxon> {
?taxonID rdfs:label ?species .
}
}
ORDER BY ?species
```

---

## Taxonomy coverage and known limitations

PlantCyc 17.0 includes species annotations for **439 unique NCBI taxa** across 25,141 DataNodes. When using the local NCBITaxon ontology (OBO Foundry, CC0 licence), 6 taxa are absent from the OBO Foundry release, affecting 54 GeneProduct and Protein nodes (0.2% of annotated nodes). All affected nodes are gene or enzyme annotations — no metabolite nodes are impacted. One taxon (*Lycopersicon hirsutum*, NCBI:283673) is deprecated and merged into *Solanum habrochaites* (NCBI:62890); the remaining five are valid taxa not included in the OBO Foundry release scope.

Use this query to inspect which taxa in your deployment cannot be resolved:

```sparql
PREFIX wp: <http://vocabularies.wikipathways.org/wp#>
PREFIX ncbi: <http://purl.obolibrary.org/obo/NCBITaxon_>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?taxon (STRAFTER(STR(?taxon), "NCBITaxon_") AS ?ncbiID)
(COUNT(DISTINCT ?node) AS ?nNodes)
WHERE {
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/gpml-taxonomy-extra> {
?node wp:organism ?taxon .
FILTER(?taxon != ncbi:33090)
}
FILTER NOT EXISTS {
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/ncbitaxon> {
?taxon rdfs:label ?label .
}
}
}
GROUP BY ?taxon
ORDER BY DESC(?nNodes)
```

---

## Alternative: taxonomy via UniProt federation

If you prefer not to load the NCBITaxon ontology locally, you can federate to the UniProt SPARQL endpoint to resolve taxon labels. UniProt uses a parallel IRI scheme (`http://purl.uniprot.org/taxonomy/4113`) that maps 1:1 to OBO Foundry IRIs (`http://purl.obolibrary.org/obo/NCBITaxon_4113`).

```sparql
PREFIX wp: <http://vocabularies.wikipathways.org/wp#>
PREFIX up: <http://purl.uniprot.org/core/>
PREFIX ncbi: <http://purl.obolibrary.org/obo/NCBITaxon_>

SELECT ?taxon ?scientificName
WHERE {
GRAPH <http://rdf-plantmetwiki.bioinformatics.nl/graph/gpml-taxonomy-extra> {
?node wp:organism ?taxon .
FILTER(?taxon != ncbi:33090)
}
BIND(IRI(REPLACE(STR(?taxon),
"http://purl.obolibrary.org/obo/NCBITaxon_",
"http://purl.uniprot.org/taxonomy/")) AS ?uniprotTaxon)

SERVICE <https://sparql.uniprot.org/sparql> {
?uniprotTaxon up:scientificName ?scientificName .
}
}
LIMIT 20
```

**Advantage:** no local ontology required — enriches pathways with taxonomy labels without importing all taxonomy into your database.
**Disadvantage:** depends on an external endpoint being available; slower for large result sets.

This approach can also answer:
- What scientific name corresponds to this taxon?
- Is this species under Viridiplantae?
- What is the parent taxon?