From 3a26bf40aff71bd5ff344badd7c8a8b186450f21 Mon Sep 17 00:00:00 2001 From: Elena Del Pup Date: Wed, 10 Dec 2025 10:37:26 +0100 Subject: [PATCH 01/17] Change title index to resource --- index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.md b/index.md index 2d4b6ac..0c61d90 100644 --- a/index.md +++ b/index.md @@ -1,4 +1,4 @@ -SPARQLing Biology: a beginners course. +SPARQLing Plant Metabolic Pathways Wiki ============================================================================================= [HOME](https://bigcat-um.github.io/SPARQLTutorialBioSB2019/) From 20c0387affd2cce97c33c5be613bdc7221faaa90 Mon Sep 17 00:00:00 2001 From: Elena Del Pup Date: Wed, 10 Dec 2025 10:43:49 +0100 Subject: [PATCH 02/17] Proposed change of index to update tutorial --- index.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/index.md b/index.md index 0c61d90..506fbe1 100644 --- a/index.md +++ b/index.md @@ -1,15 +1,16 @@ SPARQLing Plant Metabolic Pathways Wiki ============================================================================================= -[HOME](https://bigcat-um.github.io/SPARQLTutorialBioSB2019/) +[Tutorial Pages](https://pathway-lod.github.io/SPARQLTutorials/) -Program ---------- +[PlantMetWiki webserver](https://plantmetwiki.bioinformatics.nl/) -This workshop consists out of four parts: +Index +--------- -* 30 minutes: Introduction to RDF and SPARQL ([presentation](/Presentation_introRDF.pdf)) +* Introduction to RDF and SPARQL by BiGCaT Maastricht University ([presentation](/Presentation_introRDF.pdf)) +TO DELETE: * 25 minutes: Gene variants in Wikidata: * [Understanding the Basics](Assignments/assignment1A.md) * [Execute the query and retain results](Assignments/assignment1B.md) @@ -28,6 +29,8 @@ An [addendum](Assignments/AddendumBioSb2019.md) is available, where we added: * More information on where to find Biological and Chemical properties (aka relationships) to expand your query. * More detailed explanation of the SERVICE statement (since this is not directly part of SPARQL, but constructed by Wikidata for easier querying). +FINISH Removing + The material for this workshop is available under [CC-BY-SA 4.0 International](https://creativecommons.org/licenses/by-sa/4.0/legalcode) licence. +The material for this tutorial is available under [CC-BY-SA 4.0 International](https://creativecommons.org/licenses/by-sa/4.0/legalcode) licence. - +Feedback +--------- +If you have feedback on this documentation please submit it as a GitHub issue [issue tracker](https://github.com/pathway-lod/SPARQLTutorials/issues). From 659d5b676b1fa9f5607b5644dc0aaabe1ab59d90 Mon Sep 17 00:00:00 2001 From: Elena Del Pup Date: Wed, 10 Dec 2025 15:59:08 +0100 Subject: [PATCH 09/17] Update README formatting --- README.md | 85 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 5d68dfd..8111df6 100644 --- a/README.md +++ b/README.md @@ -42,64 +42,65 @@ The site uses Jekyll with the GitHub Pages theme **`jekyll-theme-tactile`** and ### 1. Install Ruby (via Homebrew) - ``` - brew install ruby - ``` +```bash +brew install ruby +``` ### 2. Ensure Homebrew Ruby is on your PATH - For Apple Silicon (M1/M2/M3): - ``` - echo 'export PATH="/opt/homebrew/opt/ruby/bin:$PATH"' >> ~/.zshrc - source ~/.zshrc - ``` +For Apple Silicon (M1/M2/M3): +``` +echo 'export PATH="/opt/homebrew/opt/ruby/bin:$PATH"' >> ~/.zshrc +source ~/.zshrc +``` - For Intel Macs: - ``` - echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.zshrc - source ~/.zshrc - ``` +For Intel Macs: +``` +echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.zshrc +source ~/.zshrc +``` - You can check Ruby with: - ``` - ruby -v - ``` +You can check Ruby with: +``` +ruby -v +``` ### 3. Install Bundler - ``` - gem install bundler - ``` +``` +gem install bundler +``` ### 4. Install the site dependencies with Bundler - From the repo root (SPARQLTutorials): +From the repo root +(SPARQLTutorials): - ``` - cd /path/to/SPARQLTutorials - bundle install - ``` +``` +cd /path/to/SPARQLTutorials +bundle install +``` - This uses the Gemfile in the repository to install: - • jekyll - • jekyll-theme-tactile - • jekyll-seo-tag - • and any other required gems. +This uses the Gemfile in the repository to install: +- jekyll +- jekyll-theme-tactile +- jekyll-seo-tag +- and any other required gems. ### 5. Serve the site locally - ``` - bundle exec jekyll serve - ``` - - Jekyll will print something like: - ``` - Server address: http://127.0.0.1:4000/ - Server running... press ctrl-c to stop. - ``` - - Open the URL in your browser (usually http://127.0.0.1:4000/). - You should see the tutorial rendered with the same tactile theme as on GitHub Pages. +``` +bundle exec jekyll serve +``` + +Jekyll will print something like: +``` +Server address: http://127.0.0.1:4000/ +Server running... press ctrl-c to stop. +``` + +Open the URL in your browser (usually http://127.0.0.1:4000/). +You should see the tutorial rendered with the same tactile theme as on GitHub Pages. ## Feedback From 38acc16d7e80f637ee1693374f45d7d8aeed0964 Mon Sep 17 00:00:00 2001 From: Elena Del Pup Date: Fri, 12 Dec 2025 16:49:39 +0100 Subject: [PATCH 10/17] Adapt first assignment --- Assignments/assignment1A.md | 212 ++++++++++++++++++++++++------------ index.md | 25 +++-- 2 files changed, 153 insertions(+), 84 deletions(-) diff --git a/Assignments/assignment1A.md b/Assignments/assignment1A.md index 41d31cb..b134c11 100644 --- a/Assignments/assignment1A.md +++ b/Assignments/assignment1A.md @@ -1,130 +1,198 @@ -Assignment 1: Which variant of which gene predicts a positive prognosis in colorectal cancer +1 - Understanding SPARQL Queries on PlantMetWiki ================= -[HOME](https://DeniseSl22.github.io/SPARQLTutorials/) +[HOME](https://pathway-lod.github.io/SPARQLTutorials/) -During this assignment, we will have a closer look at an example SPARQL query of Wikidata, called ["Which variant of which gene predicts a positive prognosis in colorectal cancer"](https://www.wikidata.org/wiki/Wikidata:SPARQL_query_service/queries/examples#Which_variant_of_which_gene_predicts_a_positive_prognosis_in_colorectal_cancer). We will first go through the basics of a SPARQL query. Second, we will find out how to execute the query and retain or share results. Last, we will expand the query and make other (small) changes, to understand the structure of a SPARQL query better, and see what other data is available in Wikidata. +During this assignment, we will have a closer look at an example SPARQL query. + +1. We will go through the basics of a SPARQL query. +2. We will execute the query and learn how to interpret results. +3. We will expand the query with small changes to explore more data, including linking to PlantCyc. + +SPARQL endpoint: https://plantmetwiki.bioinformatics.nl/sparql +Graph used in all queries: FROM ## What goes Where A SPARQL query consist out of several elements, which can be considered as building blocks. -We will use the following [example](https://www.wikidata.org/wiki/Wikidata:SPARQL_query_service/queries/examples#Which_variant_of_which_gene_predicts_a_positive_prognosis_in_colorectal_cancer), which is part of the example page of SPARQL queries for Wikidata. -We will exploring the example question called **"Which variant of which gene predicts a positive prognosis in colorectal cancer"** in more detail below. + +Our PlantMetWiki question + +Which reactions (PlantCyc reactions) are in a given PlantMetWiki pathway, and how can we click through to PlantCyc to validate them? + +We will use this pathway URI throughout: + +``` + +``` ### First element: SELECT -The first element we encouter in this example, is the so-called _result clause_, which identifies what information to return from the query. -This element starts with the word SELECT, and is then followed by two words with a questionmark in front of them: +The SELECT clause defines what will be returned as results. + +For our question, we want: + • the reaction identifier (?reactionId) + • a clickable PlantCyc link (?plantCycReactionURL) ```sparql -SELECT ?geneLabel ?variantLabel +SELECT ?reactionId ?plantCycReactionURL ``` -SELECT is used to indicate with variables from the (to follow) SPARQL query you want to visualise as a result (in other words: which variables we find relevant as output to answer our biological question). In this example, the name(s) of the gene(s) predicting a positive prognosis in colorectal cancer (?geneLabel), and the name of the variant(s) belonging to this gene/these genes (?variantLabel). +SELECT is used to indicate with variables from the (to follow) SPARQL query you want to visualise as a result (in other words: which variables we find relevant as output to answer our biological question). ### Second element: WHERE The second element we encouter, is the _query pattern_, which starts with the word WHERE, with the query itself enclosed in curly brackets: {} . +The WHERE clause defines the graph pattern to match (triples in the form subject–predicate–object). + +For PlantMetWiki pathways, we already discovered the key predicates: + • gpml:hasInteraction (links a pathway to interactions) + • some interactions represent real PlantCyc reactions (e.g. RXN-10730) + • some interactions are GPML anchor helper nodes (contain _anchor_) and should not be linked to PlantCyc + ```sparql -WHERE -{ - query +WHERE { + VALUES ?pathway { <...> } + ?pathway gpml:hasInteraction ?interaction . + ... } ``` +This is a set of RDF triples (subject–predicate–object), just like in the Wikidata tutorial, but with PlantMetWiki predicates. -#### Variable Names -Within these brackets, the data from an RDF is connected to variable names. We already encoutered two variable names, ?geneLabel and ?variantLabel (indicated by the questionmark). These variables can have any name you see fit. +#### Line-by-line explanation (PlantMetWiki version) -**Question1:** Which other variable names are present in the following query? (Answers can be found [here](../Answers/AnswersAssignment1.md)). +##### Line 1 — VALUES (what are we querying about?) -```sparql -{ - VALUES ?disease {wd:Q188874} - ?variant wdt:P3358 ?disease ; # P3358 Positive prognostic predictor - wdt:P3433 ?gene . # P3433 biological variant of +VALUES lets us “pin” the query to one (or multiple) specific items. + +```sparql +VALUES ?pathway { + } -``` +``` +You can add more pathways inside the braces later (separated by spaces) if you want to compare multiple pathways. -#### Query Details +##### Line 2 — Retrieve interactions from the pathway -In between the curly brackets in the query above, we can see three lines to describe the query we want to execute: -1. VALUES ?disease {wd:Q188874} -1. ?variant wdt:P3358 ?disease ; # P3358 Positive prognostic predictor -1. wdt:P3433 ?gene . # P3433 biological variant of +This line uses the pathway as the subject and gets all linked interactions: -##### Line 1 -The first line starts with VALUES; this allows you to queries multiple items, specified in the data block between the brackets at the end of this line. Multiple items should be separated with spaces. The variable after VALUES (in this case ?disease) will be completed with the items in the data block. In this case, we are only interested in "colorectal cancer", with 'Q188874' being the identifier of the entry in Wikidata (these always start with a Q) for **Colon Cancer**. To explain to which database this identifier belongs, we add the 'wd:' before the number of the identifier. +```sparql +?pathway gpml:hasInteraction ?interaction . +``` -##### Line 2 -The second line consists of two main parts, the left part is related to the query (which ends with a semicolon ';' ), the right is a comment, to explain what the line does (starting with a hash '#'). The left part is formed in the triplet structure (which we previously encountered in the presentation): +##### Line 3 — Turn an interaction URI into a PlantCyc reaction link -```sparql -{ -?variant wdt:P3358 ?disease ; -} +PlantMetWiki does not use Wikidata’s label service. Instead, we often extract meaningful identifiers from URIs. + +1. Extract the part after /Interaction/: + +``` +BIND(STRAFTER(STR(?interaction), "/Interaction/") AS ?reactionId) ``` -In this case, we are looking for variant(s) (_subject_), which are related to disease(s) (_object_). The relationship (aka _predicate_) is defined as the center part of the triplet, with 'P3358' being the identifier of the property in Wikidata (these always start with a P) for **Positive prognostic predictor**. To explain to which database this relationship belongs, we add the 'wdt:' before the identifier of the property. Notice the small difference with line one; 'wd:' is used for entries (these can serve as subjects or objects), 'wdt:' for properties (or relationships). +2. Keep only “real” reactions and exclude anchor helper nodes: -This line ends with a semicolon ';' to end our first triplet. +``` +FILTER(CONTAINS(?reactionId, "RXN-")) +FILTER(!CONTAINS(?reactionId, "_anchor_")) +``` -##### Line 3 -The third line again consists out of two parts; we will only discuss the left had side, until the point '.' . +3. Construct a clickable PlantCyc URL: -```sparql -{ -wdt:P3433 ?gene . -} ``` -Even though this line does not directly look like a triplet (since there are only two element), it is read as a triplet. -A point '.' at the end of a triplet really notes the end, while a semicolon ';' notes that another triplet will follow, where the _subject_ may be ommited from writing. Therefore, we need to look back at line 2, to find out which _subject_ is belonging to the triplet in line 3: ?variant. This line of the SPARQL query is therefore read as: +BIND( + IRI(CONCAT( + "https://pmn.plantcyc.org/PLANT/NEW-IMAGE?type=REACTION&object=", + ?reactionId + )) AS ?plantCycReactionURL +) +``` + +#### Full query ```sparql -{ -?variant wdt:P3433 ?gene . -} -``` +PREFIX gpml: -In this case, we are defining how genes are related to the variants in Wikidata. We are connecting the variant(s) (_subject_) with genes (_object_) in Wikidata, with the following relationship(_predicate_): "P3433", which is also known as "biological variant of". +SELECT ?reactionId ?plantCycReactionURL +FROM +WHERE { + VALUES ?pathway { + + } -### Third element: SERVICE + ?pathway gpml:hasInteraction ?interaction . -Note that the ?geneLabel and ?variantLabel are not written down in the query, however the variables ?gene and ?variant are. This is possible with the last part of the query, the SERVICE element. By typing the word "Label" (including the capital!) behind the name of a variable, we can obtain the name of that variable, in stead of the identifier used by the RDF. A name makes much more sense to us humans, and allows us to interpret the results. + BIND(STRAFTER(STR(?interaction), "/Interaction/") AS ?reactionId) -```sparql -{ - SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" } + # Only keep real PlantCyc reactions, not GPML helper anchors + FILTER(CONTAINS(?reactionId, "RXN-")) + FILTER(!CONTAINS(?reactionId, "_anchor_")) + + BIND( + IRI(CONCAT( + "https://pmn.plantcyc.org/PLANT/NEW-IMAGE?type=REACTION&object=", + ?reactionId + )) AS ?plantCycReactionURL + ) } +ORDER BY ?reactionId +LIMIT 200 ``` -Additional Remark: the SERVICE clause is not default SPARQL behaviour; it is part of the Wikidata SPARQL structure (like some of the visualisation options you see later on). Therefore, this statement will (most likely) not work when building a query -in any other database. The actual SPARQL query to retrieve labels without using SERVICE is explained [here](../Assignments/AddendumBioSb2019.md) +### Questions +
+ Question 1: Which part of the query selects the pathway we want to investigate? +

Answer:
+ VALUES ?pathway { <http://rdf.plantmetwiki.bioinformatics.nl/Pathway/RC1000_r20251206224344> } +

+
-### Full query +
+ Question 2: Which line retrieves all interactions that belong to the pathway? +

Answer:
+ ?pathway gpml:hasInteraction ?interaction . +

+
-When we combine the three elements above, we get the full query: +
+ Question 3: Why do we filter out _anchor_ interactions? +

Answer:
+ Interactions that contain _anchor_ are GPML helper nodes used for drawing/connecting edges. They are not real PlantCyc reaction identifiers, so PlantCyc will not recognize them. +

+
-```sparql -SELECT ?geneLabel ?variantLabel -WHERE -{ - VALUES ?disease {wd:Q188874} - ?variant wdt:P3358 ?disease ; # P3358 Positive prognostic predictor - wdt:P3433 ?gene . # P3433 biological variant of - SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" } +#### Small expansion: also list DataNodes (metabolites/genes) in the pathway + +If you want to see which entities are present in the same pathway: + +``` +PREFIX gpml: + +SELECT ?dataNode ?dataNodeId +FROM +WHERE { + VALUES ?pathway { + + } + + ?pathway gpml:hasDataNode ?dataNode . + BIND(STRAFTER(STR(?dataNode), "/DataNode/") AS ?dataNodeId) } +ORDER BY ?dataNodeId +LIMIT 200 ``` -We wanted an answer for the following question: "Which variant of which gene predicts a positive prognosis in colorectal cancer". +#### Notes on labels (why there is no SERVICE clause) -**Question 2A:** Which item in the SPARQL query corresponds to the disease(s) being queried? +Notes on labels (why there is no SERVICE clause) -**Question 2B:** Which item in the SPARQL query adds a name to the results? +Wikidata uses a special label service (SERVICE wikibase:label) to fetch human-readable labels for identifiers. -(Answers can be found [here](../Answers/AnswersAssignment1.md)). +PlantMetWiki does not use this service. Instead: + • some properties already store readable text (e.g. gpml:name, gpml:organism, gpml:textLabel) + • otherwise we often extract readable identifiers from URIs (using STRAFTER() as shown above) -We will now look how to run this query on the data from Wikidata, and how we can save the results from that query in the [next exercise](../Assignments/assignment1B.md). -[HOME](https://DeniseSl22.github.io/SPARQLTutorials/) +Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) \ No newline at end of file diff --git a/index.md b/index.md index c69269f..a09fa09 100644 --- a/index.md +++ b/index.md @@ -54,29 +54,30 @@ Resources * [The WikiPathways Semantic Web Portal](https://classic.wikipathways.org/index.php/Portal:Semantic_Web) -TO DELETE below! Including associated data/pages? + +Tutorial --------- -**TO DELETE: ** -* 25 minutes: Gene variants in Wikidata: - * [Understanding the Basics](Assignments/assignment1A.md) - * [Execute the query and retain results](Assignments/assignment1B.md) +* Understand the Basics + * [Understanding SPARQL Queries](Assignments/assignment1A.md) + * [Execute the query and retain results: an example from Wikidata](Assignments/assignment1B.md) --> Need to adapt !? No Wikidata link to PlantMetWiki * [Expand and change Query](Assignments/assignment1C.md) -* 25 minutes: Drug Targets in Wikidata - * [A more complicated query](Assignments/assignment2A.md) - * [Answering Biological Questions](Assignments/assignment2B.md) +* Federated Queries + * [A more complicated query](Assignments/assignment2A.md) --> TO DELETE! + * [Answering Biological Questions](Assignments/assignment2B.md) --> TO DELETE! + +* Additional Analyses + * Something about the possibility to do coexpression analyses? -* 10 minutes: Recap +* Recap * Other Biological databases with RDF ([presentation](/Presentation_introRDF.pdf)) - * Update your SPARQL query [here](https://github.com/BiGCAT-UM/SPARQLTutorialBioSB2019/tree/master/ParticipantQueries) + * Update your SPARQL query [here](./ParticipantQueries/Example1.md) An [addendum](Assignments/AddendumBioSb2019.md) is available, where we added: * Answers to questions asked during the tutorial. * More information on where to find Biological and Chemical properties (aka relationships) to expand your query. * More detailed explanation of the SERVICE statement (since this is not directly part of SPARQL, but constructed by Wikidata for easier querying). -**FINISH Part to Delete ** - License --------- From 483cda0a8e52eff4f93b134cc338246238b98a66 Mon Sep 17 00:00:00 2001 From: Elena Del Pup Date: Fri, 12 Dec 2025 16:58:11 +0100 Subject: [PATCH 11/17] Adapt assignments and HOME links --- Assignments/assignment1B.md | 2 +- Assignments/assignment1C.md | 175 ++++++++++++++++++++++++++++++------ Assignments/assignment2A.md | 4 +- Assignments/assignment2B.md | 4 +- 4 files changed, 151 insertions(+), 34 deletions(-) diff --git a/Assignments/assignment1B.md b/Assignments/assignment1B.md index 47bb268..c8450aa 100644 --- a/Assignments/assignment1B.md +++ b/Assignments/assignment1B.md @@ -19,4 +19,4 @@ There are several options to work with the results of your query. To save your d We will now make some changes to this query, to understand the structure of SPARQL even better, in the [next exercise](../Assignments/assignment1C.md). -[HOME](https://DeniseSl22.github.io/SPARQLTutorials/) +Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) diff --git a/Assignments/assignment1C.md b/Assignments/assignment1C.md index 411eff6..7d64039 100644 --- a/Assignments/assignment1C.md +++ b/Assignments/assignment1C.md @@ -1,59 +1,176 @@ -[HOME](https://DeniseSl22.github.io/SPARQLTutorials/) +Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) ## Change is Coming -### More diseases: -We have now limited ourselves to only one disease, colorectal cancer. If we would like to add another disease, such as "breast cancer" (Q128581), we would need change the VALUES line in our query (original below): +In the previous exercise, we focused on one PlantMetWiki pathway. +In this section, we will explore how to extend a query by including multiple species, and how to make the results more informative. + +SPARQL endpoint: https://plantmetwiki.bioinformatics.nl/sparql +Graph used in all queries: FROM + +### More species: + +So far, we have implicitly focused on a single species by querying a single pathway. +If we want to explore pathways from multiple species, we can do this by changing the VALUES line in our query. ```sparql { - VALUES ?disease {wd:Q188874} + VALUES ?organism { "Solanum tuberosum" } } ``` -By adding the identifier (Q128581) for the Wikidata entry called "breast cancer" to the VALUES element, we can expand our query to include two diseases. Change the line depicted above in the SPARQL endpoint to the following and click the blue run button again: +This restricts the query to pathways annotated for potato. + +### Adding another species + +Adding another species + +Suppose we also want to include pathways from Arabidopsis thaliana. +We can expand the VALUES block as follows: + ```sparql { - VALUES ?disease {wd:Q188874 wd:Q128581} + VALUES ?organism { + "Solanum tuberosum" + "Arabidopsis thaliana" +} } ``` -You should now see more results, compared to our previous endeavour. +Now the query will return pathways for both species. + +### Full query -**Question 3:** How will the line above look, when we also want to add stomach carcinoma (Q18556832) to our list? +``` +PREFIX gpml: -(Answers can be found [here](../Answers/AnswersAssignment1.md)). +SELECT ?organism ?pathway +FROM +WHERE { + VALUES ?organism { + "Solanum tuberosum" + "Arabidopsis thaliana" + } -### Which diseases? -Since we are obtaining more results by adding more diseases to our query, it would be great if we know to which disease which variant is related. In order to obtain the disease in the results, we should change the _result clause_ section of our SPARQL query: + ?pathway gpml:organism ?organism . +} +LIMIT 200 +``` + +You should now see more results, coming from more than one species. + +### Questions + +
+ How would the VALUES line look if we also want to include Oryza sativa? + +

Answer:
+ + VALUES ?organism {
+   "Solanum tuberosum"
+   "Arabidopsis thaliana"
+   "Oryza sativa"
+ } +
+

+
+ +### Which species? + +Since we are now retrieving pathways from multiple species, it is useful to explicitly show the species in the results. +To do this, we modify the SELECT clause so that the organism is visible: ```sparql -SELECT ?geneLabel ?variantLabel ?disease +SELECT ?organism ?pathway +``` +If we also want to include the pathway name (when available), we can extend this further: + +```sparql +SELECT ?organism ?pathway ?pathwayName +``` + +And add the corresponding triple pattern: +``` +OPTIONAL { ?pathway gpml:name ?pathwayName } +``` + +### Updated query with pathway names +``` +PREFIX gpml: + +SELECT ?organism ?pathway ?pathwayName +FROM +WHERE { + VALUES ?organism { + "Solanum tuberosum" + "Arabidopsis thaliana" + } + + ?pathway gpml:organism ?organism . + OPTIONAL { ?pathway gpml:name ?pathwayName } +} +LIMIT 200 ``` -Click the play button again; there should now be three columns in your results panel... However, the disease column is only giving us the identifier from Wikidata, not the name of the disease. +### Questions -**Question 4:** How should the line above look, when we want to see the name of the disease in our results panel? +
+ Which variable adds the species name to the results? +

Answer:
+ ?organism, filled via ?pathway gpml:organism ?organism +

+
+ +### Easier querying: discovering species in PlantMetWiki + +Unlike Wikidata, PlantMetWiki does not require numeric identifiers (such as Q-numbers). +Species names are stored directly as literals. + +If you are not sure which species are present in the database, you can list them: + +``` +PREFIX gpml: + +SELECT DISTINCT ?organism +FROM +WHERE { + ?pathway gpml:organism ?organism . +} +ORDER BY ?organism +``` + +This query gives you a controlled vocabulary of species that you can copy directly into a VALUES block. + +### Small expansion: count pathways per species + +We can also aggregate results to answer questions such as: + +Which species have the most pathways in PlantMetWiki? + +``` +PREFIX gpml: + +SELECT ?organism (COUNT(DISTINCT ?pathway) AS ?nPathways) +FROM +WHERE { + ?pathway gpml:organism ?organism . +} +GROUP BY ?organism +ORDER BY DESC(?nPathways) +``` -(Answers can be found [here](../Answers/AnswersAssignment1.md)). +### Notes on visualization -### Easier querying: Adding diseases with entry search function -Finding the identifiers for each entry you are interested in, can be done very easily with the entry search function. If we would like to add the disease "ovarian cancer" to our list of diseases of interest, we could do the follwing: -1. In the SPARQL endpoint, find the VALUES line. -1. Click just before the last curly bracket '}' . -1. Type a space ' ', and then 'wd:' . -1. Now hit Ctrl and the spacebar on your keyboard simultaneously (Windows, for Apple: CMD in stead of Ctrl). -This should open up the entry search field of Wikidata (see image below). -![Search Entry query 1](../Images/Search_Entry_Wikidata.jpg) +Unlike Wikidata, the PlantMetWiki SPARQL endpoint does not provide built-in image visualizations. -1. Type the words 'ovarian cancer' in the search field, which should trigger a search in all entries in Wikidata (see image below). -![Search Entry query 1](../Images/Search_Entry_Wikidata_Ovarian_Cancer.jpg) +However, you can: + • export results as tables + • click through to PlantCyc reaction links (as shown in Assignment 1) + • use external tools (e.g. notebooks, R, Python) to visualize pathway statistics -1. Click on the entry with identifier Q172341; this adds the identifier to your list of VALUES. -1. Run your query again. -### Adding protein images +#### Adding protein images on Wikidata The SPARQL endpoint of Wikidata has several interesting data visualisation options; we will use one to add protein domain images for the genes we just queried. 1. Just above the SERVICE element, add the following line: @@ -89,5 +206,5 @@ To continue, you can do one of the following: 1. Progress to [Assignment 2](../Assignments/assignment2A.md), where we will discuss another query in more detail 1. Stay with the current query to adapt it to your own needs. Several example questions to work on are given in this [additional assignment](../Assignments/assignment1D.md). -[HOME](https://DeniseSl22.github.io/SPARQLTutorials/) +Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) diff --git a/Assignments/assignment2A.md b/Assignments/assignment2A.md index d603e6c..4603418 100644 --- a/Assignments/assignment2A.md +++ b/Assignments/assignment2A.md @@ -1,7 +1,7 @@ Assignment 2: Find drugs for cancers that target genes related to cell proliferation ================= -[HOME](https://denisesl22.github.io/SPARQLTutorials/) +Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) During this assignment, we will investigate another example SPARQL query of Wikidata, called ["Find drugs for cancers that target genes related to cell proliferation"](https://www.wikidata.org/wiki/Wikidata:SPARQL_query_service/queries/examples#Find_drugs_for_cancers_that_target_genes_related_to_cell_proliferation). We will first go through the basics of a SPARQL query. Second, we will find out how to execute the query and retain or share results. Last, we will expand the query and make other (small) changes, to understand the structure of a SPARQL query better, and see what other data is available in Wikidata. @@ -78,4 +78,4 @@ The following graph should now appear (click on on of the coloured circles in th In the [last exercise](../Answers/assignment2B.md) related to this assignment, we will look at expansion options for the query above. -[HOME](https://denisesl22.github.io/SPARQLTutorials/) +Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) diff --git a/Assignments/assignment2B.md b/Assignments/assignment2B.md index a5af293..fc6631a 100644 --- a/Assignments/assignment2B.md +++ b/Assignments/assignment2B.md @@ -1,4 +1,4 @@ -[HOME](https://denisesl22.github.io/SPARQLTutorials/) +Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) ## Changing the Question @@ -35,4 +35,4 @@ You can probably think of some other questions you would like to ask to Wikidata of the query we are working on now, or find another example on Wikidata you want to understand and expand (ask your instructors for help if needed). -[HOME](https://denisesl22.github.io/SPARQLTutorials/) +Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) From 3a3a961debec8c0931f1d9d0d8f1fdd82e0a895b Mon Sep 17 00:00:00 2001 From: Elena Del Pup Date: Mon, 15 Dec 2025 22:21:39 +0100 Subject: [PATCH 12/17] Change style outlook and add custom headers, footers and sidebar --- .gitignore | 5 + Assignments/assignment1A.md | 16 +-- Assignments/assignment1B.md | 19 ++- Assignments/assignment1C.md | 9 +- Assignments/assignment1D.md | 9 ++ Assignments/assignment2A.md | 9 ++ Assignments/assignment2B.md | 9 +- Images/plantmetwiki-logo.png | Bin 0 -> 65136 bytes _config.yml | 7 +- _includes/head-custom.html | 1 + _includes/sidebar.html | 52 +++++++ _includes/topbar.html | 19 +++ _layouts/docs.html | 32 +++++ assets/css/docs.css | 255 +++++++++++++++++++++++++++++++++++ index.md | 66 ++++----- 15 files changed, 448 insertions(+), 60 deletions(-) create mode 100644 Images/plantmetwiki-logo.png create mode 100644 _includes/head-custom.html create mode 100644 _includes/sidebar.html create mode 100644 _includes/topbar.html create mode 100644 _layouts/docs.html create mode 100644 assets/css/docs.css diff --git a/.gitignore b/.gitignore index 2bc6e41..2013949 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,8 @@ Gemfile.lock # Editor backups .DS_Store + +.sass-cache/ +.jekyll-cache/ +.bundle/ +vendor/ \ No newline at end of file diff --git a/Assignments/assignment1A.md b/Assignments/assignment1A.md index b134c11..6712c87 100644 --- a/Assignments/assignment1A.md +++ b/Assignments/assignment1A.md @@ -1,7 +1,11 @@ -1 - Understanding SPARQL Queries on PlantMetWiki -================= - -[HOME](https://pathway-lod.github.io/SPARQLTutorials/) +--- +layout: docs +title: "1. Understanding SPARQL Queries" +prev: "/" +prev_title: "Home" +next: "/Assignments/assignment1B/" +next_title: "Execute & retain results" +--- During this assignment, we will have a closer look at an example SPARQL query. @@ -186,13 +190,9 @@ LIMIT 200 #### Notes on labels (why there is no SERVICE clause) -Notes on labels (why there is no SERVICE clause) Wikidata uses a special label service (SERVICE wikibase:label) to fetch human-readable labels for identifiers. PlantMetWiki does not use this service. Instead: • some properties already store readable text (e.g. gpml:name, gpml:organism, gpml:textLabel) • otherwise we often extract readable identifiers from URIs (using STRAFTER() as shown above) - - -Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) \ No newline at end of file diff --git a/Assignments/assignment1B.md b/Assignments/assignment1B.md index c8450aa..41bf4e0 100644 --- a/Assignments/assignment1B.md +++ b/Assignments/assignment1B.md @@ -1,22 +1,29 @@ -[HOME](https://DeniseSl22.github.io/SPARQLTutorials/) +--- +layout: docs +title: "2. Execute and Retain Results" +prev: "/Assignments/assignment1A/" +prev_title: "Previous page" +next: "/Assignments/assignment1C/" +next_title: "Next page" +--- ## Run and Save Click on [this link](https://www.wikidata.org/wiki/Wikidata:SPARQL_query_service/queries/examples#Which_variant_of_which_gene_predicts_a_positive_prognosis_in_colorectal_cancer) to go to the example page of Wikidata. Below the Query titled "Which variant of which gene predicts a positive prognosis in colorectal cancer", click on the "Try it" button, which will open the following page: -![Wikidata SPARQL Endpoint](../Images/WikidaatSPARQL_endpoint.JPG) +![Wikidata SPARQL Endpoint](/Images/WikidaatSPARQL_endpoint.JPG) **Welcome to the SPARQL Endpoint of Wikidata!** Excecute the query by clicking on the blue play button. This will reveal the results of the query in a panel below the query editor: -![results query 1](../Images/Results_Query1_wikidata.JPG) +![results query 1](/Images/Results_Query1_wikidata.JPG) There are several options to work with the results of your query. To save your data, click on the Download button (red arrow in image below), and select the format you want to work with (CSV, TSV, JSON, HTML, SVG-image). To get a weblink to your results, click on the Link button (green arrow in image below). Last, there are also several code examples available (blue arrow in the image below), which could help construct a script to automate (several) queries, or combine the results of multiple queries in a workflow. Examples are available for: R, Python, Ruby, Perl, Java, JavaScript and many others! -![results query 1 Download](../Images/Results_Query1_wikidata_Download.jpg) +![results query 1 Download](/Images/Results_Query1_wikidata_Download.jpg) + +We will now make some changes to this query, to understand the structure of SPARQL even better, in the next page. -We will now make some changes to this query, to understand the structure of SPARQL even better, in the [next exercise](../Assignments/assignment1C.md). -Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) diff --git a/Assignments/assignment1C.md b/Assignments/assignment1C.md index 7d64039..bc8070e 100644 --- a/Assignments/assignment1C.md +++ b/Assignments/assignment1C.md @@ -1,4 +1,11 @@ -Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) +--- +layout: docs +title: "3. Expand and Change Queries" +prev: "/Assignments/assignment1B" +prev_title: "Previous page" +next: "/Assignments/assignment1D/" +next_title: "Next page" +--- ## Change is Coming diff --git a/Assignments/assignment1D.md b/Assignments/assignment1D.md index b78aa3b..1113922 100644 --- a/Assignments/assignment1D.md +++ b/Assignments/assignment1D.md @@ -1,3 +1,12 @@ +--- +layout: docs +title: "A more complicated query on Wikidata" +prev: "/Assignments/assignment1C/" +prev_title: "Previous page" +next: "/Assignments/assignment2A/" +next_title: "Next page" +--- + ### Additional questions Assignment 1: diff --git a/Assignments/assignment2A.md b/Assignments/assignment2A.md index 4603418..910500b 100644 --- a/Assignments/assignment2A.md +++ b/Assignments/assignment2A.md @@ -1,3 +1,12 @@ +--- +layout: docs +title: "Additional analyses" +prev: "/Assignments/assignment1D/" +prev_title: "Previous page" +next: "/Assignments/assignment2B/" +next_title: "Next page" +--- + Assignment 2: Find drugs for cancers that target genes related to cell proliferation ================= diff --git a/Assignments/assignment2B.md b/Assignments/assignment2B.md index fc6631a..7a68a38 100644 --- a/Assignments/assignment2B.md +++ b/Assignments/assignment2B.md @@ -1,4 +1,11 @@ -Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) +--- +layout: docs +title: "Answering Biological Questions on Wikidata" +prev: "/" +prev_title: "Previous page" +next: "index/" +next_title: "Return to Home" +--- ## Changing the Question diff --git a/Images/plantmetwiki-logo.png b/Images/plantmetwiki-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7c4beb80d4420b87aaf21244e9651bed43935dbd GIT binary patch literal 65136 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 LD2UgH8U_CkM5!}P literal 0 HcmV?d00001 diff --git a/_config.yml b/_config.yml index 4d0819b..f94f914 100644 --- a/_config.yml +++ b/_config.yml @@ -1,3 +1,4 @@ -title: "SPARQLing Plant Metabolic Pathways Wiki" -description: "Documentation and Tutorial for the PlantMetWiki SPARQL Explorer" -theme: jekyll-theme-tactile \ No newline at end of file +theme: jekyll-theme-tactile +permalink: pretty +# ensure your custom CSS loads +plugins: [] \ No newline at end of file diff --git a/_includes/head-custom.html b/_includes/head-custom.html new file mode 100644 index 0000000..a7612e5 --- /dev/null +++ b/_includes/head-custom.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_includes/sidebar.html b/_includes/sidebar.html new file mode 100644 index 0000000..93a524f --- /dev/null +++ b/_includes/sidebar.html @@ -0,0 +1,52 @@ + + +{% if page.prev or page.next %} +
+ {% if page.prev %} + ← {{ page.prev_title | default: "Previous" }} + {% endif %} + {% if page.next %} + {{ page.next_title | default: "Next" }} → + {% endif %} +
+{% endif %} + + + +
+

+ The material for this tutorial is available under + + CC-BY-SA 4.0 International + . + If you have feedback on this documentation, please submit it as a + + GitHub issue + . +

+
\ No newline at end of file diff --git a/_includes/topbar.html b/_includes/topbar.html new file mode 100644 index 0000000..f5bb459 --- /dev/null +++ b/_includes/topbar.html @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/_layouts/docs.html b/_layouts/docs.html new file mode 100644 index 0000000..a866445 --- /dev/null +++ b/_layouts/docs.html @@ -0,0 +1,32 @@ +--- +layout: default +--- + +{% include topbar.html %} + +
+ + +
+ {{ content }} + +
+ +
+ +{% if page.prev or page.next %} +
+
+ {% if page.prev %} + ← {{ page.prev_title | default: "Previous" }} + {% endif %} +
+
+ {% if page.next %} + {{ page.next_title | default: "Next" }} → + {% endif %} +
+
+{% endif %} \ No newline at end of file diff --git a/assets/css/docs.css b/assets/css/docs.css new file mode 100644 index 0000000..e1ab352 --- /dev/null +++ b/assets/css/docs.css @@ -0,0 +1,255 @@ +:root { + --pmw-green: #8aa34a; + --pmw-green-dark: #3a5b20; + --pmw-green-soft: #8fa35a; +} + +/* Global link color override */ +a { + color: var(--pmw-green); +} +a:hover { + color: var(--pmw-green-dark); +} + +/* ---------------- Topbar ---------------- */ +.pmw-topbar { + display: flex; + align-items: center; + gap: 12px; + margin: 12px 0 16px 0; +} + +.pmw-home { + display: inline-flex; + align-items: center; + gap: 10px; + text-decoration: none; + font-weight: 700; +} + +.pmw-home img { + height: 80px; +} + +.pmw-topbar-actions { + display: flex; + gap: 10px; + align-items: center; +} + +/* Topbar buttons */ +.pmw-btn { + background-color: var(--pmw-green); + color: #fff !important; + padding: 6px 14px; + border-radius: 6px; + font-size: 0.85rem; + font-weight: 600; + text-decoration: none; +} + +.pmw-btn:hover { + background-color: var(--pmw-green-dark); +} + +.pmw-btn-secondary { + background-color: transparent; + color: var(--pmw-green) !important; + border: 1px solid var(--pmw-green); +} + +.pmw-btn-secondary:hover { + background-color: var(--pmw-green-soft); + color: #fff !important; +} + +/* ---------------- Theme width / centering fixes ---------------- */ +/* Tactile centers a wrapper; make it responsive and less "pushed right" */ +.inner { + max-width: none !important; + width: min(1600px, calc(100% - 48px)) !important; + margin-left: auto !important; + margin-right: auto !important; +} + +#main_content { + width: 100% !important; + float: none !important; + margin: 0 auto !important; + padding-left: 0 !important; + padding-right: 0 !important; +} + +section { + padding-left: 0 !important; + padding-right: 0 !important; +} + +/* ---------------- Docs layout ---------------- */ +.pmw-layout { + display: grid; + grid-template-columns: clamp(220px, 24vw, 300px) minmax(0, 1fr); + column-gap: 24px; + align-items: start; + width: 100%; + margin: 0 auto; +} + +.pmw-content { + min-width: 0; +} + +/* ---------------- Sidebar ---------------- */ +.pmw-sidebar { + font-size: 0.90rem; + line-height: 1.35; + + position: sticky; + top: 16px; + align-self: start; + max-height: calc(100vh - 32px); + overflow-y: auto; +} + +/* Sidebar links */ +.pmw-sidebar a { + color: var(--pmw-green); +} + +.pmw-sidebar a:hover { + color: var(--pmw-green-dark); + text-decoration: underline; +} + +/* Active page (if you add class="active") */ +.pmw-sidebar a.active { + font-weight: 700; + color: var(--pmw-green-dark); +} + +/* Nav links wrap nicely */ +.pmw-nav a { + display: block; + white-space: normal; + word-break: break-word; +} + +/* Sidebar section titles */ +.pmw-nav-title, +.pmw-nav-section { + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.03em; + margin-top: 10px; + margin-bottom: 4px; + color: var(--pmw-green-dark); +} + +/* Sidebar prev/next buttons */ +.pmw-side-prevnext { + margin-top: 16px; + padding-top: 12px; + border-top: 1px solid rgba(0,0,0,0.12); + display: grid; + gap: 8px; +} + +.pmw-side-btn { + display: block; + padding: 6px 10px; + border-radius: 6px; + text-decoration: none; + background: rgba(110,130,59,0.12); + color: var(--pmw-green-dark); + font-weight: 600; +} + +.pmw-side-btn:hover { + background: rgba(110,130,59,0.18); +} + +/* License + feedback block IN sidebar (wrapped paragraph) */ +.pmw-license-inline { + margin-top: 14px; + padding-top: 10px; + border-top: 1px solid rgba(0,0,0,0.12); + font-size: 0.75rem; + line-height: 1.35; + color: #555; +} + +/* Prevent any sidebar content from forcing layout wider */ +.pmw-sidebar, +.pmw-sidebar * { + min-width: 0; +} + +/* Force long strings to wrap (URLs, long tokens) */ +.pmw-license-inline { + overflow-wrap: anywhere; + word-break: break-word; +} +/* Prevent any sidebar content from forcing layout wider */ +.pmw-sidebar, +.pmw-sidebar * { + min-width: 0; +} + +/* Force long strings to wrap (URLs, long tokens) */ +.pmw-license-inline { + overflow-wrap: anywhere; + word-break: break-word; +} +.pmw-license-inline a { + overflow-wrap: anywhere; + word-break: break-word; +} + +/* ---------------- Global heading color override ---------------- */ +/* Fix: var(--pmw-dark-green) didn't exist */ +h1, h2, h3, h4, h5, h6 { + color: #333; +} + +/* ---------------- Optional generic buttons ---------------- */ +button, +.button, +a.button { + background-color: var(--pmw-green); + color: #fff !important; +} + +button:hover, +.button:hover, +a.button:hover { + background-color: var(--pmw-green-dark); +} + +/* ---------------- Footer tweak (theme footer) ---------------- */ +.site-footer { + margin-top: 0.5rem; +} + +/* ---------------- Responsive ---------------- */ +@media (max-width: 900px) { + .pmw-layout { + grid-template-columns: 1fr; + } + + .pmw-sidebar { + position: static; + max-height: none; + overflow: visible; + + width: auto; + max-width: none; + border-right: none; + padding-right: 0; + border-bottom: 1px solid rgba(0,0,0,0.12); + padding-bottom: 12px; + margin-bottom: 12px; + } +} + diff --git a/index.md b/index.md index a09fa09..0f8dde5 100644 --- a/index.md +++ b/index.md @@ -1,25 +1,19 @@ --- -layout: default +layout: docs +title: "SPARQLing Plant Metabolic Pathways Wiki" +description: "Documentation and Tutorial for the PlantMetWiki SPARQL Explorer" +next: "/Assignments/assignment1/" --- SPARQLing Plant Metabolic Pathways Wiki ============================================================================================= -

- - Tutorial Pages Home - - - PlantMetWiki Webserver - -

- -Summary +## Summary --------- Plant Metabolic Pathways Wiki (PlantMetWiki) is an open online portal for querying linked specialized plant pathway information. PlantMetWiki is available in **Semantic Web format** as Resource Description Framework (**RDF**) and can be accessed via an easy-to-use **SNORQL user interface**. **Pre-written SPARQL queries** are available for users to execute or adapt to retrieve pathway information. **Federated queries** with other linked open data tools are supported, thereby expanding the [Wikidata](https://www.wikidata.org/wiki/Wikidata:Main_Page) framework. -Using the SPARQL Explorer +## Using the SPARQL Explorer --------- Visit our PlantMetWiki SPARQL interface at [plantmetwiki.bioinformatics.nl](https://plantmetwiki.bioinformatics.nl/). @@ -39,13 +33,13 @@ Follow the steps below to execute a pre-written query:

-Output +## Output --------- Output data is available for download in native RDF format (.ttl), TSV, CSV, and json. -Resources +## Resources --------- * [Introduction to RDF and SPARQL](/Presentation_introRDF.pdf) by BiGCaT Maastricht University @@ -55,34 +49,24 @@ Resources * [The WikiPathways Semantic Web Portal](https://classic.wikipathways.org/index.php/Portal:Semantic_Web) -Tutorial +## Tutorial --------- -* Understand the Basics - * [Understanding SPARQL Queries](Assignments/assignment1A.md) - * [Execute the query and retain results: an example from Wikidata](Assignments/assignment1B.md) --> Need to adapt !? No Wikidata link to PlantMetWiki - * [Expand and change Query](Assignments/assignment1C.md) - -* Federated Queries - * [A more complicated query](Assignments/assignment2A.md) --> TO DELETE! - * [Answering Biological Questions](Assignments/assignment2B.md) --> TO DELETE! - -* Additional Analyses - * Something about the possibility to do coexpression analyses? - -* Recap - * Other Biological databases with RDF ([presentation](/Presentation_introRDF.pdf)) - * Update your SPARQL query [here](./ParticipantQueries/Example1.md) - -An [addendum](Assignments/AddendumBioSb2019.md) is available, where we added: -* Answers to questions asked during the tutorial. +### Understand the Basics +* [Understanding SPARQL Queries]({{ "/Assignments/assignment1A/" | relative_url }}) +* [Execute & retain results]({{ "/Assignments/assignment1B/" | relative_url }}) +* [Expand and change query]({{ "/Assignments/assignment1C/" | relative_url }}) + +### Federated Queries on Wikidata +* [A more complicated query]({{ "/Assignments/assignment2A/" | relative_url }}) +* [Answering biological questions]({{ "/Assignments/assignment2B/" | relative_url }}) + +### Recap: +* Update your SPARQL query from [this template]({{ "/ParticipantQueries/Example1/" | relative_url }}) +* An [addendum]({{ "/Assignments/AddendumBioSb2019/" | relative_url }}) + +### Addendum +An [addendum](Assignments/AddendumBioSb2019.md) is available, containing: +* Answers to biological questions on Wikidata. * More information on where to find Biological and Chemical properties (aka relationships) to expand your query. * More detailed explanation of the SERVICE statement (since this is not directly part of SPARQL, but constructed by Wikidata for easier querying). -License ---------- - -The material for this tutorial is available under [CC-BY-SA 4.0 International](https://creativecommons.org/licenses/by-sa/4.0/legalcode) licence. - -Feedback ---------- -If you have feedback on this documentation please submit it as a GitHub issue [issue tracker](https://github.com/pathway-lod/SPARQLTutorials/issues). From 4be128de1c06fc69d0a0819f9042c6a686ddf896 Mon Sep 17 00:00:00 2001 From: Elena Del Pup Date: Mon, 15 Dec 2025 22:25:55 +0100 Subject: [PATCH 13/17] Linking missing page to home and Sidebar --- _includes/sidebar.html | 3 ++- index.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/_includes/sidebar.html b/_includes/sidebar.html index 93a524f..6e614d2 100644 --- a/_includes/sidebar.html +++ b/_includes/sidebar.html @@ -16,7 +16,8 @@ Expand and change query
Federated Queries
- A more complicated query + A more complicated query + Additional analyses Answering biological questions
Addendum
diff --git a/index.md b/index.md index 0f8dde5..b0782a5 100644 --- a/index.md +++ b/index.md @@ -57,7 +57,8 @@ Output data is available for download in native RDF format (.ttl), TSV, CSV, and * [Expand and change query]({{ "/Assignments/assignment1C/" | relative_url }}) ### Federated Queries on Wikidata -* [A more complicated query]({{ "/Assignments/assignment2A/" | relative_url }}) +* [A more complicated query]({{ "/Assignments/assignment2D/" | relative_url }}) +* [Additional analyses]({{ "/Assignments/assignment2A/" | relative_url }}) * [Answering biological questions]({{ "/Assignments/assignment2B/" | relative_url }}) ### Recap: From 48d7647e678b6ad221ec45425b44b817555fd811 Mon Sep 17 00:00:00 2001 From: Elena Del Pup Date: Mon, 15 Dec 2025 22:27:44 +0100 Subject: [PATCH 14/17] Fix links to Images --- Assignments/assignment1C.md | 8 ++++---- Assignments/assignment1D.md | 2 +- Assignments/assignment2A.md | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Assignments/assignment1C.md b/Assignments/assignment1C.md index bc8070e..581e85d 100644 --- a/Assignments/assignment1C.md +++ b/Assignments/assignment1C.md @@ -199,19 +199,19 @@ SELECT ?geneLabel ?variantLabel ?diseaseLabel ?image 2. Click on the play button... We do not see the images directly, we do get a link to the images in a Table. If we want to actually see the images, we need to change the visualisation options of the SPARQL endpoint. 3. Directly under the Run button, there is an option called 'Table". Click on this option, and select the option "Image Grid": -![Image Grid query 1](../Images/Image_grid_Wikidata.jpg) +![Image Grid query 1](/Images/Image_grid_Wikidata.jpg) Now, the genes in Wikidata which have an image connected to them, are displayed. -![Image example query 1](../Images/Images_genes_Wikidata.JPG) +![Image example query 1](/Images/Images_genes_Wikidata.JPG) If you would like to have images for all the genes you queried, you can add these to Wikidata yourself. Since the data in Wikidata is built by community efforts, everyone can get involved. If you would like to know more about becoming a database editor and/or curator for Wikidata, ask one of the instructors for more information. ## Next assignments: To continue, you can do one of the following: -1. Progress to [Assignment 2](../Assignments/assignment2A.md), where we will discuss another query in more detail -1. Stay with the current query to adapt it to your own needs. Several example questions to work on are given in this [additional assignment](../Assignments/assignment1D.md). +1. Progress to [Assignment 2](/Assignments/assignment2A.md), where we will discuss another query in more detail +1. Stay with the current query to adapt it to your own needs. Several example questions to work on are given in this [additional assignment](/Assignments/assignment1D.md). Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) diff --git a/Assignments/assignment1D.md b/Assignments/assignment1D.md index 1113922..a41321a 100644 --- a/Assignments/assignment1D.md +++ b/Assignments/assignment1D.md @@ -1,7 +1,7 @@ --- layout: docs title: "A more complicated query on Wikidata" -prev: "/Assignments/assignment1C/" +prev: "/Assignments/assignment2A/" prev_title: "Previous page" next: "/Assignments/assignment2A/" next_title: "Next page" diff --git a/Assignments/assignment2A.md b/Assignments/assignment2A.md index 910500b..45c4ea3 100644 --- a/Assignments/assignment2A.md +++ b/Assignments/assignment2A.md @@ -72,19 +72,19 @@ You can uncomment by removing the '#' sign, and run the query again. 1. Comment the line related to true positives again (from the assignment above). 1. Change the view from 'Table' to 'Scatter chart': -![Select Scatter Chart](../Images/Scatter_chart_example2.jpg) +![Select Scatter Chart](/Images/Scatter_chart_example2.jpg) The following graph should now appear (click on on of the coloured circles in the graph, to obtain the diseaseLabel): -![Select Scatter Chart](../Images/Scatter_chart_visualisation_example2.JPG) +![Select Scatter Chart](/Images/Scatter_chart_visualisation_example2.JPG) **Question 1A:** Which variables are depicted in which manner? **Question 1B:** What would change to the visualisation, if you switch the place of the variables ?geneLabel and ?biological_processLabel with one another? -(Answers can be found [here](../Answers/AnswersAssignment2.md)). +(Answers can be found [here](/Answers/AnswersAssignment2.md)). -In the [last exercise](../Answers/assignment2B.md) related to this assignment, we will look at expansion options for the query above. +In the [last exercise](/Answers/assignment2B.md) related to this assignment, we will look at expansion options for the query above. Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) From a1dd9519d3388e0d29d9e91c9df2be00edbd219d Mon Sep 17 00:00:00 2001 From: Elena Del Pup <62478999+elenadelpup@users.noreply.github.com> Date: Wed, 17 Dec 2025 01:48:35 +0100 Subject: [PATCH 15/17] Archived old pages, created new pages, automate indexing of pages for sidebar build --- .../AddendumBioSb2019.md | 0 README.md | 4 +- _config.yml | 11 +- _includes/sidebar.html | 104 +++++-- _includes/toc.html | 28 ++ _layouts/docs.html | 15 - .../1.UnderstandingSPARQL.md | 138 +++++---- .../2.ExpandQueries.md | 152 +++++----- _tutorial/3.GeneClusterLinks.md | 175 ++++++++++++ _tutorial/4.FederatedQueries.md | 268 ++++++++++++++++++ .../_archivedpages/AdditionalAnalyses.md | 4 - .../BiologicalQuestionsWikidata.md | 4 - .../_archivedpages/ResultsWikidata.md | 6 +- .../_archivedpages/WikidataQueries.md | 0 assets/css/docs.css | 45 +++ index.md | 44 +-- 16 files changed, 790 insertions(+), 208 deletions(-) rename {Assignments => ParticipantQueries}/AddendumBioSb2019.md (100%) create mode 100644 _includes/toc.html rename Assignments/assignment1A.md => _tutorial/1.UnderstandingSPARQL.md (53%) rename Assignments/assignment1C.md => _tutorial/2.ExpandQueries.md (53%) create mode 100644 _tutorial/3.GeneClusterLinks.md create mode 100644 _tutorial/4.FederatedQueries.md rename Assignments/assignment2A.md => _tutorial/_archivedpages/AdditionalAnalyses.md (97%) rename Assignments/assignment2B.md => _tutorial/_archivedpages/BiologicalQuestionsWikidata.md (95%) rename Assignments/assignment1B.md => _tutorial/_archivedpages/ResultsWikidata.md (90%) rename Assignments/assignment1D.md => _tutorial/_archivedpages/WikidataQueries.md (100%) diff --git a/Assignments/AddendumBioSb2019.md b/ParticipantQueries/AddendumBioSb2019.md similarity index 100% rename from Assignments/AddendumBioSb2019.md rename to ParticipantQueries/AddendumBioSb2019.md diff --git a/README.md b/README.md index 8111df6..25705f7 100644 --- a/README.md +++ b/README.md @@ -90,12 +90,12 @@ This uses the Gemfile in the repository to install: ### 5. Serve the site locally ``` -bundle exec jekyll serve +bundle exec jekyll serve --port 4001 ``` Jekyll will print something like: ``` -Server address: http://127.0.0.1:4000/ +Server address: http://127.0.0.1:4001/ Server running... press ctrl-c to stop. ``` diff --git a/_config.yml b/_config.yml index f94f914..9d8dce8 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,13 @@ theme: jekyll-theme-tactile permalink: pretty # ensure your custom CSS loads -plugins: [] \ No newline at end of file +plugins: [] +markdown: kramdown +kramdown: + auto_ids: true + +# made a collection of rendered pages +collections: + tutorial: + output: true + permalink: /Assignments/:name/ \ No newline at end of file diff --git a/_includes/sidebar.html b/_includes/sidebar.html index 6e614d2..8157487 100644 --- a/_includes/sidebar.html +++ b/_includes/sidebar.html @@ -1,40 +1,82 @@ -{% if page.prev or page.next %} + +{%- comment -%} +------------------------------------------------------------ +3 Prev/Next buttons (auto, based on order) +This replaces page.prev/page.next front matter hardcoding. +------------------------------------------------------------ +{%- endcomment -%} + +{%- assign items = site.tutorial | sort: "order" -%} +{%- assign idx = nil -%} +{%- for p in items -%} + {%- if p.url == page.url -%} + {%- assign idx = forloop.index0 -%} + {%- endif -%} +{%- endfor -%} + +{%- if idx != nil -%} + {%- assign prev = items[idx | minus: 1] -%} + {%- assign next = items[idx | plus: 1] -%} +
- {% if page.prev %} - ← {{ page.prev_title | default: "Previous" }} - {% endif %} - {% if page.next %} - {{ page.next_title | default: "Next" }} → - {% endif %} + {%- if prev -%} + ← {{ prev.title }} + {%- endif -%} + {%- if next -%} + {{ next.title }} → + {%- endif -%}
-{% endif %} - +{%- endif -%}
diff --git a/_includes/toc.html b/_includes/toc.html new file mode 100644 index 0000000..4074b02 --- /dev/null +++ b/_includes/toc.html @@ -0,0 +1,28 @@ +{%- assign html = include.html | default: page.content -%} + +{%- comment -%} +If we were passed Markdown (no + {%- assign parts = html | split: "" -%} + {%- assign title = pieces[1] | split: "<" | first | strip -%} + + {%- if id != "" and title != "" -%} +
  • + {{ title }} +
  • + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + \ No newline at end of file diff --git a/_layouts/docs.html b/_layouts/docs.html index a866445..2db00e1 100644 --- a/_layouts/docs.html +++ b/_layouts/docs.html @@ -15,18 +15,3 @@
    - -{% if page.prev or page.next %} -
    -
    - {% if page.prev %} - ← {{ page.prev_title | default: "Previous" }} - {% endif %} -
    -
    - {% if page.next %} - {{ page.next_title | default: "Next" }} → - {% endif %} -
    -
    -{% endif %} \ No newline at end of file diff --git a/Assignments/assignment1A.md b/_tutorial/1.UnderstandingSPARQL.md similarity index 53% rename from Assignments/assignment1A.md rename to _tutorial/1.UnderstandingSPARQL.md index 6712c87..e3718d3 100644 --- a/Assignments/assignment1A.md +++ b/_tutorial/1.UnderstandingSPARQL.md @@ -1,36 +1,43 @@ --- layout: docs -title: "1. Understanding SPARQL Queries" -prev: "/" -prev_title: "Home" -next: "/Assignments/assignment1B/" -next_title: "Execute & retain results" +title: "Understanding SPARQL Queries" +order: 10 --- -During this assignment, we will have a closer look at an example SPARQL query. +This page introduces the basic structure of a SPARQL query using a **real example from PlantMetWiki**. -1. We will go through the basics of a SPARQL query. -2. We will execute the query and learn how to interpret results. -3. We will expand the query with small changes to explore more data, including linking to PlantCyc. +Rather than focusing on abstract syntax, we explain how a concrete biological question is translated into a SPARQL query, and how to interpret each part of the query and its results. -SPARQL endpoint: https://plantmetwiki.bioinformatics.nl/sparql -Graph used in all queries: FROM +By the end of this page, you should be comfortable: -## What goes Where +- reading a SPARQL query used in PlantMetWiki, +- understanding what biological question it answers, +- recognizing how pathway content is represented in RDF, +- following links from PlantMetWiki to external resources such as PlantCyc. + +**SPARQL endpoint**: +https://plantmetwiki.bioinformatics.nl/sparql + +**Graph used in all queries**: +`FROM ` + +We will work with the **α-solanine / α-chaconine biosynthesis pathway**, a well-known plant specialised metabolic pathway involved in glycoalkaloid production in *Solanum* species (e.g. potato and tomato). + +## Anatomy of a SPARQL query A SPARQL query consist out of several elements, which can be considered as building blocks. Our PlantMetWiki question -Which reactions (PlantCyc reactions) are in a given PlantMetWiki pathway, and how can we click through to PlantCyc to validate them? +> ***Which PlantCyc reactions are part of the α-solanine / α-chaconine biosynthesis pathway, and how can we validate them in PlantCyc?*** -We will use this pathway URI throughout: +We will use this pathway URI throughout the tutorial: ``` - + ``` -### First element: SELECT +### SELECT — what do we want to see in the results? The SELECT clause defines what will be returned as results. @@ -42,18 +49,18 @@ For our question, we want: SELECT ?reactionId ?plantCycReactionURL ``` -SELECT is used to indicate with variables from the (to follow) SPARQL query you want to visualise as a result (in other words: which variables we find relevant as output to answer our biological question). +SELECT is used to indicate with variables from the SPARQL query you want to visualise as a result (in other words: which variables we find relevant as output to answer our biological question). -### Second element: WHERE +### WHERE — how do we find that information? -The second element we encouter, is the _query pattern_, which starts with the word WHERE, with the query itself enclosed in curly brackets: {} . +The second element we encouter in a SPARQL query, is the _query pattern_, which starts with the word WHERE, with the query itself enclosed in curly brackets: {} . The WHERE clause defines the graph pattern to match (triples in the form subject–predicate–object). For PlantMetWiki pathways, we already discovered the key predicates: • gpml:hasInteraction (links a pathway to interactions) • some interactions represent real PlantCyc reactions (e.g. RXN-10730) - • some interactions are GPML anchor helper nodes (contain _anchor_) and should not be linked to PlantCyc + • some interactions are GPML anchor helper nodes (contain _anchor_) and should not be linked to PlantCyc or interpreted as reactions ```sparql WHERE { @@ -65,20 +72,20 @@ WHERE { This is a set of RDF triples (subject–predicate–object), just like in the Wikidata tutorial, but with PlantMetWiki predicates. -#### Line-by-line explanation (PlantMetWiki version) +## Step-by-step interpretation of the query -##### Line 1 — VALUES (what are we querying about?) +### Line 1 — VALUES (what are we querying about?) VALUES lets us “pin” the query to one (or multiple) specific items. ```sparql VALUES ?pathway { - + } ``` You can add more pathways inside the braces later (separated by spaces) if you want to compare multiple pathways. -##### Line 2 — Retrieve interactions from the pathway +### Line 2 — Retrieve interactions from the pathway This line uses the pathway as the subject and gets all linked interactions: @@ -86,14 +93,17 @@ This line uses the pathway as the subject and gets all linked interactions: ?pathway gpml:hasInteraction ?interaction . ``` -##### Line 3 — Turn an interaction URI into a PlantCyc reaction link +### Line 3 — Turn an interaction URI into a PlantCyc reaction link PlantMetWiki does not use Wikidata’s label service. Instead, we often extract meaningful identifiers from URIs. 1. Extract the part after /Interaction/: ``` -BIND(STRAFTER(STR(?interaction), "/Interaction/") AS ?reactionId) +BIND( + STRAFTER(STR(?interaction), "/Interaction/") + AS ?reactionId +) ``` 2. Keep only “real” reactions and exclude anchor helper nodes: @@ -110,10 +120,13 @@ BIND( IRI(CONCAT( "https://pmn.plantcyc.org/PLANT/NEW-IMAGE?type=REACTION&object=", ?reactionId - )) AS ?plantCycReactionURL + )) + AS ?plantCycReactionURL ) ``` +This turns the extracted identifier into a clickable external link. + #### Full query ```sparql @@ -123,14 +136,13 @@ SELECT ?reactionId ?plantCycReactionURL FROM WHERE { VALUES ?pathway { - + } ?pathway gpml:hasInteraction ?interaction . BIND(STRAFTER(STR(?interaction), "/Interaction/") AS ?reactionId) - # Only keep real PlantCyc reactions, not GPML helper anchors FILTER(CONTAINS(?reactionId, "RXN-")) FILTER(!CONTAINS(?reactionId, "_anchor_")) @@ -138,18 +150,53 @@ WHERE { IRI(CONCAT( "https://pmn.plantcyc.org/PLANT/NEW-IMAGE?type=REACTION&object=", ?reactionId - )) AS ?plantCycReactionURL + )) + AS ?plantCycReactionURL ) } ORDER BY ?reactionId LIMIT 200 ``` -### Questions +### Listing pathway components (genes, metabolites) + +To see which data nodes (genes, metabolites) are present in the same pathway: + +``` +PREFIX gpml: + +SELECT ?dataNodeId +FROM +WHERE { + VALUES ?pathway { + + } + + ?pathway gpml:hasDataNode ?dataNode . + BIND(STRAFTER(STR(?dataNode), "/DataNode/") AS ?dataNodeId) +} +ORDER BY ?dataNodeId +LIMIT 200 +``` + +## A note on labels and identifiers + +Unlike Wikidata, PlantMetWiki does not provide a dedicated label service (SERVICE wikibase:label). + +Instead: + + • some readable information is stored directly (e.g. gpml:name, gpml:textLabel), + • otherwise, meaningful identifiers are extracted directly from URIs using string functions such as STRAFTER(). + +This approach is used consistently throughout the tutorial. + + +## Questions +
    Question 1: Which part of the query selects the pathway we want to investigate?

    Answer:
    - VALUES ?pathway { <http://rdf.plantmetwiki.bioinformatics.nl/Pathway/RC1000_r20251206224344> } + VALUES ?pathway { <http://rdf-plantmetwiki.bioinformatics.nl/Pathway/RC1000_r20251206224344> }

    @@ -167,32 +214,5 @@ LIMIT 200

    -#### Small expansion: also list DataNodes (metabolites/genes) in the pathway - -If you want to see which entities are present in the same pathway: - -``` -PREFIX gpml: - -SELECT ?dataNode ?dataNodeId -FROM -WHERE { - VALUES ?pathway { - - } - - ?pathway gpml:hasDataNode ?dataNode . - BIND(STRAFTER(STR(?dataNode), "/DataNode/") AS ?dataNodeId) -} -ORDER BY ?dataNodeId -LIMIT 200 -``` - -#### Notes on labels (why there is no SERVICE clause) - -Wikidata uses a special label service (SERVICE wikibase:label) to fetch human-readable labels for identifiers. -PlantMetWiki does not use this service. Instead: - • some properties already store readable text (e.g. gpml:name, gpml:organism, gpml:textLabel) - • otherwise we often extract readable identifiers from URIs (using STRAFTER() as shown above) diff --git a/Assignments/assignment1C.md b/_tutorial/2.ExpandQueries.md similarity index 53% rename from Assignments/assignment1C.md rename to _tutorial/2.ExpandQueries.md index 581e85d..4900054 100644 --- a/Assignments/assignment1C.md +++ b/_tutorial/2.ExpandQueries.md @@ -1,21 +1,37 @@ --- layout: docs -title: "3. Expand and Change Queries" -prev: "/Assignments/assignment1B" -prev_title: "Previous page" -next: "/Assignments/assignment1D/" -next_title: "Next page" +title: "Exploring Species and Pathways" +order: 20 --- -## Change is Coming -In the previous exercise, we focused on one PlantMetWiki pathway. -In this section, we will explore how to extend a query by including multiple species, and how to make the results more informative. +In the previous page, we focused on a **single plant metabolic pathway** and examined how reactions are represented and linked to PlantCyc. -SPARQL endpoint: https://plantmetwiki.bioinformatics.nl/sparql -Graph used in all queries: FROM +In this section, we take a step back and explore **PlantMetWiki as a collection**: +- Which plant species are represented? +- Which pathways exist per species? +- How can we navigate across species and pathways using SPARQL? -### More species: +This page introduces **exploratory queries** that help you understand the scope of the database before asking more detailed biological questions. + +**SPARQL endpoint** +https://plantmetwiki.bioinformatics.nl/sparql + +**Graph used in all queries** +```sparql +FROM +``` + +### How species are represented in PlantMetWiki + +Unlike Wikidata, PlantMetWiki stores species names directly as text literals, rather than numeric identifiers. + +This makes it easy to: + • read queries + • copy species names into VALUES blocks + • explore the database interactively + +Species information is attached to pathways using the predicate: `gpml:organism` So far, we have implicitly focused on a single species by querying a single pathway. If we want to explore pathways from multiple species, we can do this by changing the VALUES line in our query. @@ -28,31 +44,74 @@ If we want to explore pathways from multiple species, we can do this by changing This restricts the query to pathways annotated for potato. -### Adding another species +### Discovering which species are available -Adding another species +Before querying pathways for a specific plant, it is useful to know which species are present at all. -Suppose we also want to include pathways from Arabidopsis thaliana. -We can expand the VALUES block as follows: +The following query lists all species annotated in PlantMetWiki: ```sparql -{ - VALUES ?organism { - "Solanum tuberosum" - "Arabidopsis thaliana" -} +PREFIX gpml: + +SELECT DISTINCT ?organism +FROM +WHERE { + ?pathway gpml:organism ?organism . } +ORDER BY ?organism ``` -Now the query will return pathways for both species. +This gives you a controlled vocabulary of species names that can be reused directly in other queries. -### Full query +### Listing pathways for a given species + +Once you know which species exist, you can retrieve the pathways associated with a specific plant. + +For example, to list pathways annotated for Solanum tuberosum (potato): ``` PREFIX gpml: -SELECT ?organism ?pathway +SELECT ?pathway +FROM +WHERE { + ?pathway gpml:organism "Solanum tuberosum" . +} +LIMIT 200 +``` + +At this stage, the query returns pathway identifiers (URIs). + +## Making results more informative: pathway names + +To make the output easier to interpret, we can include pathway names when they are available. + +We extend the SELECT clause and add an OPTIONAL pattern: + +```sparql +PREFIX gpml: + +SELECT ?pathway ?pathwayName +FROM +WHERE { + ?pathway gpml:organism "Solanum tuberosum" . + OPTIONAL { ?pathway gpml:name ?pathwayName } +} +LIMIT 200 +``` + +Using OPTIONAL ensures that pathways without a name are still returned. + +## Comparing pathways across multiple species + +SPARQL allows you to compare species by listing them explicitly using VALUES. + +For example, to retrieve pathways for potato and Arabidopsis: +``` +PREFIX gpml: + +SELECT ?organism ?pathway ?pathwayName FROM WHERE { VALUES ?organism { @@ -61,11 +120,13 @@ WHERE { } ?pathway gpml:organism ?organism . + OPTIONAL { ?pathway gpml:name ?pathwayName } } LIMIT 200 ``` -You should now see more results, coming from more than one species. +This query makes the species explicit in the results, which is especially useful when comparing model plants with crop species. + ### Questions @@ -172,46 +233,7 @@ ORDER BY DESC(?nPathways) Unlike Wikidata, the PlantMetWiki SPARQL endpoint does not provide built-in image visualizations. However, you can: - • export results as tables + + • export results as tabless • click through to PlantCyc reaction links (as shown in Assignment 1) • use external tools (e.g. notebooks, R, Python) to visualize pathway statistics - - -#### Adding protein images on Wikidata -The SPARQL endpoint of Wikidata has several interesting data visualisation options; we will use one to add protein domain images for the genes we just queried. -1. Just above the SERVICE element, add the following line: - -```SPARQL -?gene wdt:P18 ?image . -``` -2. Click on the play button... What just happened? We had 13 variants, and now the results went down to 6?! - -Since not all genes have an image in Wikidata, we are only retrieving the ones that have an image. This can be avoided by using an OPTIONAL statement, such as: -```SPARQL -OPTIONAL{?gene wdt:P18 ?image }. -``` - -However, we are not seeing the images in our results panel. Every time we want to see a variable that we are querying, we need to add it to the SELECT statement. -1. Change the SELECT statement to the following: -```SPARQL -SELECT ?geneLabel ?variantLabel ?diseaseLabel ?image -``` -2. Click on the play button... We do not see the images directly, we do get a link to the images in a Table. If we want to actually see the images, we need to change the visualisation options of the SPARQL endpoint. -3. Directly under the Run button, there is an option called 'Table". Click on this option, and select the option "Image Grid": - -![Image Grid query 1](/Images/Image_grid_Wikidata.jpg) - -Now, the genes in Wikidata which have an image connected to them, are displayed. - -![Image example query 1](/Images/Images_genes_Wikidata.JPG) - -If you would like to have images for all the genes you queried, you can add these to Wikidata yourself. Since the data in Wikidata is built by community efforts, everyone can get involved. If you would like to know more about becoming a database editor and/or curator for Wikidata, ask one of the instructors for more information. - -## Next assignments: - -To continue, you can do one of the following: -1. Progress to [Assignment 2](/Assignments/assignment2A.md), where we will discuss another query in more detail -1. Stay with the current query to adapt it to your own needs. Several example questions to work on are given in this [additional assignment](/Assignments/assignment1D.md). - -Return to [HOME](https://pathway-lod.github.io/SPARQLTutorials/) - diff --git a/_tutorial/3.GeneClusterLinks.md b/_tutorial/3.GeneClusterLinks.md new file mode 100644 index 0000000..94d0ffb --- /dev/null +++ b/_tutorial/3.GeneClusterLinks.md @@ -0,0 +1,175 @@ +--- +layout: docs +title: "Linking Pathways to Biosynthetic Gene Clusters" +order: 30 +--- + +Plant specialized metabolites are often produced by **biosynthetic gene clusters (BGCs)** — groups of physically co-located genes that together encode a metabolic pathway. + +PlantMetWiki provides explicit **cross-links between metabolic pathways and BGC resources**, allowing you to move from: +- pathway-level knowledge +- to genomic context +- to specialized metabolite biosynthesis + +In this section, we explore how PlantMetWiki connects pathways to: +- **plantiSMASH** predictions +- **MIBiG** curated BGCs +- external metadata describing gene clusters + +**SPARQL endpoint** +https://plantmetwiki.bioinformatics.nl/sparql + +**Graph used in all queries** +```sparql +FROM + +``` + +## What is a BGC cross-link in PlantMetWiki? + +A BGC cross-link connects: + • a PlantMetWiki pathway + • to a gene cluster identifier + • originating from an external resource + +These links are derived from: + • pathway annotations + • genomic metadata + • curated and predicted BGC databases + +PlantMetWiki does not duplicate BGC data; instead, it acts as a hub connecting pathways to specialized genomics resources. + +⸻ + +## Discovering all BGC cross-links + +To get an overview of how many pathway–BGC links exist, you can list all known cross-links: + +``` +SELECT ?pathway ?bgc +FROM +WHERE { + ?pathway ?predicate ?bgc . + FILTER(CONTAINS(STR(?bgc), "BGC")) +} +LIMIT 200 +``` + +This query reveals that: + • pathways may link to multiple BGCs + • BGC identifiers come from different external sources + + +## Linking pathways to plantiSMASH BGCs + +plantiSMASH predicts biosynthetic gene clusters directly from plant genomes. + +PlantMetWiki pathways can link to plantiSMASH BGC identifiers, allowing you to: + • move from pathway → genome + • inspect candidate gene clusters + • evaluate biosynthetic hypotheses + +Example query (from plantiSMASHLinks.rq): + +``` +SELECT ?pathway ?plantiSMASH_BGC +FROM +WHERE { + ?pathway ?p ?plantiSMASH_BGC . + FILTER(CONTAINS(STR(?plantiSMASH_BGC), "plantiSMASH")) +} +LIMIT 200 +``` + + +Each returned BGC identifier can be clicked through to explore: + • predicted cluster boundaries + • gene annotations + • domain architecture + + +## Linking pathways to curated MIBiG clusters + +MIBiG is a manually curated database of experimentally validated biosynthetic gene clusters. + +PlantMetWiki links pathways to MIBiG entries when: + • a pathway is supported by experimental evidence + • a known BGC has been described in the literature + +Example query (from MIBiGLinks.rq): + +``` +SELECT ?pathway ?mibig +FROM +WHERE { + ?pathway ?p ?mibig . + FILTER(CONTAINS(STR(?mibig), "mibig")) +} +LIMIT 200 +``` + +These links allow you to: + • trace pathways to experimentally validated gene clusters + • connect pathway knowledge with publications + • assess confidence in biosynthetic assignments + +## Combining multiple BGC sources + +Some pathways link to both predicted and curated clusters. + +You can retrieve all BGC-related links regardless of source: +``` +SELECT ?pathway ?bgc +FROM +WHERE { + ?pathway ?p ?bgc . + FILTER( + CONTAINS(STR(?bgc), "plantiSMASH") || + CONTAINS(STR(?bgc), "mibig") + ) +} +LIMIT 200 +``` + +This makes it possible to: + • compare predictions with curated knowledge + • identify gaps in experimental validation + • prioritize clusters for follow-up study + +## Pathway-centric view: BGCs for a specific pathway + +You can also start from a specific MIBiG BGC and ask what is the pathway that belongs to that BGC + +``` +PREFIX ro: +PREFIX wp: +PREFIX dc: +PREFIX dcterms: + +# Retrieve thalianol pathway +SELECT DISTINCT ?pw (STR(?titleLit) AS ?title) +FROM +WHERE { + ro:0000051 ?gene . + + ?interaction wp:participants ?gene ; + dcterms:isPartOf ?pw . + + ?pw dc:title ?titleLit . +} +ORDER BY ?title +``` + +## Why BGC cross-links matter + +By linking pathways to gene clusters, PlantMetWiki enables: + • genome-to-metabolite reasoning + • discovery of candidate biosynthetic loci + • comparison of predicted vs curated clusters + • integration with omics pipelines + +This makes PlantMetWiki especially useful for: + • plant specialized metabolism research + • natural product discovery + • functional genomics + • comparative pathway analysis \ No newline at end of file diff --git a/_tutorial/4.FederatedQueries.md b/_tutorial/4.FederatedQueries.md new file mode 100644 index 0000000..0b73ceb --- /dev/null +++ b/_tutorial/4.FederatedQueries.md @@ -0,0 +1,268 @@ +--- +layout: docs +title: "Federated Queries Across Linked Open Data" +order: 40 +--- + +One of the main strengths of SPARQL is that it allows **federated queries**: +a single query can combine data from multiple, independent knowledge bases. + +PlantMetWiki is designed to work *together* with existing Linked Open Data resources such as: +- **Wikidata** +- **ChEBI** +- **PubMed** + +In this section, we show how to move beyond PlantMetWiki alone and place plant metabolic pathways in a **broader biological knowledge graph**. + +**SPARQL endpoint** +https://plantmetwiki.bioinformatics.nl/sparql + +**Graph used in all queries** +```sparql +FROM +``` + +## What is a federated SPARQL query? + +A federated query uses the SERVICE keyword to send part of the query to a remote SPARQL endpoint. + +Conceptually: + • PlantMetWiki provides pathway context + • External endpoints provide chemical, biological, or literature metadata + • SPARQL stitches them together + + +``` +SERVICE { + ... +} +``` + +Each SERVICE block is evaluated remotely, and the results are merged with the local query. + +## Why federate from PlantMetWiki? + +PlantMetWiki focuses on: + + • pathways + • species + • biosynthesis + • gene clusters + +It deliberately does not duplicate: + + • chemical ontologies + • literature databases + • encyclopedic metadata + +Federation lets you: + + • enrich pathways with chemical identifiers + • connect metabolites to publications + • reuse authoritative external resources + +⸻ + +## Example 1 — Sending metabolites to Wikidata + +Many PlantMetWiki pathways contain metabolites with identifiers that are also known to Wikidata. + +Using a federated query, we can: + + 1. extract metabolite identifiers from PlantMetWiki + 2. send them to Wikidata + 3. retrieve additional metadata + +Example (from WikidataTest.rq): +``` +PREFIX gpml: + +SELECT ?metabolite ?wikidataItem +FROM +WHERE { + ?pathway gpml:hasDataNode ?metabolite . + + SERVICE { + ?wikidataItem ?p ?metabolite . + } +} +LIMIT 100 +``` + +This demonstrates the mechanism of federation, even before refining identifiers. + +## Example 2 — Linking metabolites via InChIKeys + +Chemical identifiers such as InChIKeys provide a robust bridge between databases. + +PlantMetWiki → InChIKey → Wikidata → ChEBI + +Example (from WikidataInChiKeys.rq): + +``` +SELECT ?metabolite ?inchiKey ?wikidataItem +FROM +WHERE { + ?metabolite ?p ?inchiKey . + FILTER(CONTAINS(STR(?p), "InChIKey")) + + SERVICE { + ?wikidataItem wdt:P235 ?inchiKey . + } +} +LIMIT 100 +``` + +This pattern allows you to: + + • unify chemical identities across resources + • avoid ambiguous names + • build reliable cross-database links + +⸻ + +## Example 3 — Federating to ChEBI + +ChEBI is the authoritative ontology for chemical entities of biological interest. + +Using InChIKeys or ChEBI IDs, you can retrieve: + + • chemical classifications + • roles (e.g. alkaloid, glycoside) + • ontology relationships + +Example (from FederatedMetabolitesChEBI.rq): +``` +SELECT ?metabolite ?chebi +FROM +WHERE { + ?metabolite ?p ?chebi . + FILTER(CONTAINS(STR(?chebi), "CHEBI")) + + SERVICE { + ?chebiItem wdt:P683 ?chebi . + } +} +LIMIT 100 +``` + +This enables ontology-aware pathway analysis without duplicating ChEBI locally. + + +## Example 4 — Linking pathways to publications (PubMed) + +Many pathways and gene clusters are supported by literature evidence. + +Using federated queries, you can: + + • extract PubMed IDs + • query Wikidata for article metadata + • retrieve titles, journals, and authors + +Example (from ListPubMedIDs.rq): +``` +SELECT DISTINCT ?pmid +FROM +WHERE { + ?pathway ?p ?pmid . + FILTER(CONTAINS(STR(?pmid), "pubmed")) +} +``` +Extended with federation (from WikidataLookupByInChIKeys.rq): + +``` +SERVICE { + ?article wdt:P698 ?pmid ; + rdfs:label ?title . + FILTER(LANG(?title) = "en") +} +``` + +This connects: + + • pathway → metabolite → publication + • enabling traceable biological evidence + + +## Example 5 — Bidirectional federation + +Federation does not have to start from PlantMetWiki. + +You can: + + • query Wikidata first + • then match results against PlantMetWiki + +Example (from SendInChiKeysToWikidata.rq): + +``` +SERVICE { + ?item wdt:P235 ?inchiKey . +} + +?metabolite ?p ?inchiKey . +``` + +This pattern is useful when: + + • starting from literature or chemical knowledge + • and asking whether PlantMetWiki contains related pathways + +⸻ + +Practical considerations + +Performance + + • Federated queries are slower than local queries + • Limit result sizes (LIMIT) + • Avoid unnecessary variables + +Stability + + • External endpoints may change + • Wikidata enforces rate limits + • Queries should be robust to partial results + +## Design philosophy + +PlantMetWiki intentionally stays lightweight: + + • no chemical ontology duplication + • no literature mirroring + • no monolithic data model + +Federation keeps the ecosystem modular and sustainable. + +⸻ + +## What you can do with federated queries + +By combining PlantMetWiki with external resources, you can: + + • trace metabolites from genome → pathway → chemistry → literature + • enrich pathway analyses with ontology information + • integrate PlantMetWiki into larger knowledge graphs + • support FAIR, reusable, interoperable workflows + +⸻ + +## Summary + +Federated SPARQL queries allow PlantMetWiki to function as: + + • a hub for plant metabolic pathways + • a connector between genomics, chemistry, and literature + • a first-class citizen of the Linked Open Data ecosystem + +This closes the loop from: +genes → pathways → metabolites → publications → knowledge + +| Tutorial section | Query file | +|-----------------|------------| +| Wikidata basics | `WikidataTest.rq` | +| InChIKey federation | `WikidataInChiKeys.rq` | +| ChEBI federation | `FederatedMetabolitesChEBI.rq` | +| PubMed links | `ListPubMedIDs.rq` | +| Reverse federation | `SendInChiKeysToWikidata.rq` | +| Advanced lookups | `WikidataLookupByInChIKeys.rq` | \ No newline at end of file diff --git a/Assignments/assignment2A.md b/_tutorial/_archivedpages/AdditionalAnalyses.md similarity index 97% rename from Assignments/assignment2A.md rename to _tutorial/_archivedpages/AdditionalAnalyses.md index 45c4ea3..ebd49df 100644 --- a/Assignments/assignment2A.md +++ b/_tutorial/_archivedpages/AdditionalAnalyses.md @@ -1,10 +1,6 @@ --- layout: docs title: "Additional analyses" -prev: "/Assignments/assignment1D/" -prev_title: "Previous page" -next: "/Assignments/assignment2B/" -next_title: "Next page" --- Assignment 2: Find drugs for cancers that target genes related to cell proliferation diff --git a/Assignments/assignment2B.md b/_tutorial/_archivedpages/BiologicalQuestionsWikidata.md similarity index 95% rename from Assignments/assignment2B.md rename to _tutorial/_archivedpages/BiologicalQuestionsWikidata.md index 7a68a38..1d97d16 100644 --- a/Assignments/assignment2B.md +++ b/_tutorial/_archivedpages/BiologicalQuestionsWikidata.md @@ -1,10 +1,6 @@ --- layout: docs title: "Answering Biological Questions on Wikidata" -prev: "/" -prev_title: "Previous page" -next: "index/" -next_title: "Return to Home" --- ## Changing the Question diff --git a/Assignments/assignment1B.md b/_tutorial/_archivedpages/ResultsWikidata.md similarity index 90% rename from Assignments/assignment1B.md rename to _tutorial/_archivedpages/ResultsWikidata.md index 41bf4e0..8683d06 100644 --- a/Assignments/assignment1B.md +++ b/_tutorial/_archivedpages/ResultsWikidata.md @@ -1,10 +1,6 @@ --- layout: docs -title: "2. Execute and Retain Results" -prev: "/Assignments/assignment1A/" -prev_title: "Previous page" -next: "/Assignments/assignment1C/" -next_title: "Next page" +title: "Execute & retain results" --- ## Run and Save diff --git a/Assignments/assignment1D.md b/_tutorial/_archivedpages/WikidataQueries.md similarity index 100% rename from Assignments/assignment1D.md rename to _tutorial/_archivedpages/WikidataQueries.md diff --git a/assets/css/docs.css b/assets/css/docs.css index e1ab352..1f0fbb9 100644 --- a/assets/css/docs.css +++ b/assets/css/docs.css @@ -180,6 +180,51 @@ section { color: #555; } +.pmw-nav-divider { + margin: 12px 0; + border-top: 1px solid rgba(0,0,0,0.12); +} + +.pmw-nav-muted { + font-size: 0.8rem; + color: #777; +} + +/* make TOC list compact */ +.pmw-toc ul { + margin: 6px 0 0 0; + padding-left: 16px; +} +.pmw-toc li { + margin: 4px 0; +} +.pmw-toc a { + display: block; + white-space: normal; + word-break: break-word; +} + +/* TOC nesting / depth */ +.pmw-toc { list-style: none; margin: 0; padding: 0; } +.pmw-toc li { margin: 4px 0; } + +/* H2 entries */ +.pmw-toc-l2 > a { + font-weight: 600; + font-size: 0.90rem; +} + +/* H3 entries (nested under H2 visually) */ +.pmw-toc-l3 { + padding-left: 14px; +} + +.pmw-toc-l3 > a { + font-weight: 400; + font-size: 0.82rem; + opacity: 0.95; +} + /* Prevent any sidebar content from forcing layout wider */ .pmw-sidebar, .pmw-sidebar * { diff --git a/index.md b/index.md index b0782a5..3d06fcd 100644 --- a/index.md +++ b/index.md @@ -2,12 +2,10 @@ layout: docs title: "SPARQLing Plant Metabolic Pathways Wiki" description: "Documentation and Tutorial for the PlantMetWiki SPARQL Explorer" -next: "/Assignments/assignment1/" +order: 0 +permalink: / --- -SPARQLing Plant Metabolic Pathways Wiki -============================================================================================= - ## Summary --------- Plant Metabolic Pathways Wiki (PlantMetWiki) is an open online portal for querying linked specialized plant pathway information. PlantMetWiki is available in **Semantic Web format** as Resource Description Framework (**RDF**) and can be accessed via an easy-to-use **SNORQL user interface**. **Pre-written SPARQL queries** are available for users to execute or adapt to retrieve pathway information. **Federated queries** with other linked open data tools are supported, thereby expanding the [Wikidata](https://www.wikidata.org/wiki/Wikidata:Main_Page) framework. @@ -20,11 +18,11 @@ Visit our PlantMetWiki SPARQL interface at [plantmetwiki.bioinformatics.nl](http Follow the steps below to execute a pre-written query: -1: **Select a query** from the list of example SPARQL queries. You can **adapt the query** by typing in the SPARQL Query box. +1: **Select a query** from the list of example SPARQL queries. You can **adapt the query** by typing in the SPARQL Query box or from the source repository [pathway-lod/SPARQLQueries](https://github.com/pathway-lod/SPARQLQueries) 2: Press the green **Query** button to execute your selected query. -3: View the **results** on the same page. +3: View the **result s** on the same page. 4: You can **select your own** list of example queries from github, by adding the link and click the **refresh button**. @@ -46,28 +44,30 @@ Output data is available for download in native RDF format (.ttl), TSV, CSV, and * Wikipathway ontology [The WikiPathways WP Ontology](https://vocabularies.wikipathways.org/) +* [Guide to WikiPathways SPARQL Queries](https://www.wikipathways.org/sparql.html) + * [The WikiPathways Semantic Web Portal](https://classic.wikipathways.org/index.php/Portal:Semantic_Web) -## Tutorial + +## Tutorial Pages --------- -### Understand the Basics -* [Understanding SPARQL Queries]({{ "/Assignments/assignment1A/" | relative_url }}) -* [Execute & retain results]({{ "/Assignments/assignment1B/" | relative_url }}) -* [Expand and change query]({{ "/Assignments/assignment1C/" | relative_url }}) -### Federated Queries on Wikidata -* [A more complicated query]({{ "/Assignments/assignment2D/" | relative_url }}) -* [Additional analyses]({{ "/Assignments/assignment2A/" | relative_url }}) -* [Answering biological questions]({{ "/Assignments/assignment2B/" | relative_url }}) +{% assign tutorials = site.tutorial | sort: "order" %} -### Recap: +{% for p in tutorials %} +* [{{ p.title }}]({{ p.url | relative_url }}) +{% endfor %} + +## Recap +--------- * Update your SPARQL query from [this template]({{ "/ParticipantQueries/Example1/" | relative_url }}) -* An [addendum]({{ "/Assignments/AddendumBioSb2019/" | relative_url }}) +* An [addendum]({{ "/ParticipantQueries/AddendumBioSb2019/" | relative_url }}) iw available containing: + * Answers to biological questions on Wikidata. + * More information on where to find Biological and Chemical properties (aka relationships) to expand your query. + * More detailed explanation of the SERVICE statement (since this is not directly part of SPARQL, but constructed by Wikidata for easier querying). -### Addendum -An [addendum](Assignments/AddendumBioSb2019.md) is available, containing: -* Answers to biological questions on Wikidata. -* More information on where to find Biological and Chemical properties (aka relationships) to expand your query. -* More detailed explanation of the SERVICE statement (since this is not directly part of SPARQL, but constructed by Wikidata for easier querying). +## Data availability +--------- +Data related to PlantMetWiki is available at [Zenodo PlantMetWiki Community](https://zenodo.org/communities/plantmetwiki/). \ No newline at end of file From 427ed88f0a6e4146aefcc3bab564f40db64ec5d7 Mon Sep 17 00:00:00 2001 From: Elena Del Pup <62478999+elenadelpup@users.noreply.github.com> Date: Wed, 17 Dec 2025 01:59:54 +0100 Subject: [PATCH 16/17] Add list of project repositories --- .../_archivedpages}/AddendumBioSb2019.md | 0 index.md | 47 +++++++++++++------ 2 files changed, 33 insertions(+), 14 deletions(-) rename {ParticipantQueries => _tutorial/_archivedpages}/AddendumBioSb2019.md (100%) diff --git a/ParticipantQueries/AddendumBioSb2019.md b/_tutorial/_archivedpages/AddendumBioSb2019.md similarity index 100% rename from ParticipantQueries/AddendumBioSb2019.md rename to _tutorial/_archivedpages/AddendumBioSb2019.md diff --git a/index.md b/index.md index 3d06fcd..ed2c997 100644 --- a/index.md +++ b/index.md @@ -30,12 +30,21 @@ Follow the steps below to execute a pre-written query: New Snorql Interface

    +* Update your SPARQL query from [this template]({{ "/ParticipantQueries/Example1/" | relative_url }}) -## Output +## Download Results --------- Output data is available for download in native RDF format (.ttl), TSV, CSV, and json. +## Tutorial Pages +--------- + +{% assign tutorials = site.tutorial | sort: "order" %} + +{% for p in tutorials %} +* [{{ p.title }}]({{ p.url | relative_url }}) +{% endfor %} ## Resources --------- @@ -48,24 +57,34 @@ Output data is available for download in native RDF format (.ttl), TSV, CSV, and * [The WikiPathways Semantic Web Portal](https://classic.wikipathways.org/index.php/Portal:Semantic_Web) +## PlantMetWiki architecture +--------- +PlantMetWiki is built as a modular Linked Open Data ecosystem. +The following repositories together form the data pipeline, infrastructure, +user interfaces, and documentation of the project: -## Tutorial Pages ---------- +* **Cyc_to_wiki** – Data extraction and preparation from pathway databases + -{% assign tutorials = site.tutorial | sort: "order" %} +* **gpml-to-rdf** – Conversion of GPML pathway files into RDF + -{% for p in tutorials %} -* [{{ p.title }}]({{ p.url | relative_url }}) -{% endfor %} +* **map-to-rdf** – Generation of RDF crosslinks with MIBiG and plantiSMASH + + +* **virtuoso-httpd-docker** – Triple store setup and Dockerized deployment of the PlantMetWiki SPARQL endpoint + + +* **Snorql-UI** – Web-based SPARQL query interface for PlantMetWiki + + +* **SPARQLQueries** – Curated example SPARQL queries for PlantMetWiki and federated endpoints + + +* **SPARQLTutorials** – Documentation and tutorial pages for learning how to query PlantMetWiki (this website) + -## Recap ---------- -* Update your SPARQL query from [this template]({{ "/ParticipantQueries/Example1/" | relative_url }}) -* An [addendum]({{ "/ParticipantQueries/AddendumBioSb2019/" | relative_url }}) iw available containing: - * Answers to biological questions on Wikidata. - * More information on where to find Biological and Chemical properties (aka relationships) to expand your query. - * More detailed explanation of the SERVICE statement (since this is not directly part of SPARQL, but constructed by Wikidata for easier querying). ## Data availability --------- From f08af16bae2b42bb0bbfca579e6b4147fc932772 Mon Sep 17 00:00:00 2001 From: Elena Del Pup <62478999+elenadelpup@users.noreply.github.com> Date: Wed, 17 Dec 2025 16:05:54 +0100 Subject: [PATCH 17/17] Add headers for examples --- _tutorial/3.GeneClusterLinks.md | 4 ++++ index.md | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/_tutorial/3.GeneClusterLinks.md b/_tutorial/3.GeneClusterLinks.md index 94d0ffb..75bf736 100644 --- a/_tutorial/3.GeneClusterLinks.md +++ b/_tutorial/3.GeneClusterLinks.md @@ -7,11 +7,13 @@ order: 30 Plant specialized metabolites are often produced by **biosynthetic gene clusters (BGCs)** — groups of physically co-located genes that together encode a metabolic pathway. PlantMetWiki provides explicit **cross-links between metabolic pathways and BGC resources**, allowing you to move from: + - pathway-level knowledge - to genomic context - to specialized metabolite biosynthesis In this section, we explore how PlantMetWiki connects pathways to: + - **plantiSMASH** predictions - **MIBiG** curated BGCs - external metadata describing gene clusters @@ -28,11 +30,13 @@ FROM ## What is a BGC cross-link in PlantMetWiki? A BGC cross-link connects: + • a PlantMetWiki pathway • to a gene cluster identifier • originating from an external resource These links are derived from: + • pathway annotations • genomic metadata • curated and predicted BGC databases diff --git a/index.md b/index.md index ed2c997..ef91b33 100644 --- a/index.md +++ b/index.md @@ -10,6 +10,8 @@ permalink: / --------- Plant Metabolic Pathways Wiki (PlantMetWiki) is an open online portal for querying linked specialized plant pathway information. PlantMetWiki is available in **Semantic Web format** as Resource Description Framework (**RDF**) and can be accessed via an easy-to-use **SNORQL user interface**. **Pre-written SPARQL queries** are available for users to execute or adapt to retrieve pathway information. **Federated queries** with other linked open data tools are supported, thereby expanding the [Wikidata](https://www.wikidata.org/wiki/Wikidata:Main_Page) framework. +By structuring characterized pathways knowledge as Linked Open Data, linking it to predicted biosynthetic clusters, and supporting federated querying, PlantMetWiki supports **hypothesis generation in plant biosynthesis and natural product discovery**. + ## Using the SPARQL Explorer --------- @@ -37,7 +39,18 @@ Follow the steps below to execute a pre-written query: Output data is available for download in native RDF format (.ttl), TSV, CSV, and json. -## Tutorial Pages +## Use Cases +--------- +### 1. Diving into Natural Products : and example from castor oil +--------- + + + +### 2. Resolving Pathways across Species : an example in Capsicum +--------- + + +## Tutorial Pages : the SPARQL PlantMetWiki Explorer --------- {% assign tutorials = site.tutorial | sort: "order" %}