Skip to content

Repository files navigation

MetaBoKG

An analysis-centric knowledge graph framework for untargeted metabolomics.

MetaBoKG turns the heterogeneous outputs of public mass-spectrometry repositories — spectra, features, GNPS molecular-network jobs, library annotations, confidence evidence, sample metadata, environmental and taxonomic context — into a single, queryable knowledge graph. It is designed to keep the link between every annotation and the analytical artifact, sample, and study it came from explicit, so that biochemical questions can be asked across hundreds of analyses at once instead of one job at a time.

Why another metabolomics KG?

Public infrastructures (GNPS/MassIVE, MetaboLights, Metabolomics Workbench, Pan-ReDU) have made raw data and study metadata broadly reusable. However, stays fragmented: spectra, features, workflow outputs, annotations, confidence evidence, and sample context live in different tables, with different IDs, and rarely point to each other. MetaBoKG addresses that fragmentation with three contributions:

  1. A transformation workflow that preserves links between repository exports, analytical files, spectra, features, and annotation results — from raw download all the way to SPARQL.
  2. A semantic model grounded in PROV-O and SIO, aligned with the Mass Spectrometry ontology (MS), ChEBI, NCBITaxon, ENVO, and NCIT — so provenance, analytical evidence, metadata attributes, and controlled-vocabulary terms all live in the same graph.
  3. A Universal Annotation Identifier (UAI) strategy that extends the Universal Spectrum Identifier (USI) with workflow-specific components, enabling late binding, incremental ingestion, and post-hoc linkage across analyses.

The current release scales to 680 GNPS molecular-networking jobs and is evaluated through a battery of competency questions on biochemical enrichment, environmental specificity, and cross-instrument analytical variation.

Architecture

       ┌────────────────────────────────────────────────────────────┐
       │  Public sources                                            │
       │          PubMed  ── PMC ── GNPS/MassIVE ── ReDU            │
       └────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
  ┌───────────────────────────────────────────────────────────────────┐
  │  Pipeline (main.py)                                               │
  │                                                                   │
  │   fetch ─► extract ─► jobs ─► map ─► load ─► cq                   │
  │   PMIDs   GNPS/MassIVE   GNPS    morph-kgc   Virtuoso   SPARQL    │
  │   PDFs    Zenodo IDs    archives  + RML       graphs    + CQ CSVs │
  └───────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
       ┌────────────────────────────────────────────────────────────┐
       │  Knowledge graph                                           │
       │   SIO · MS · ENVO · NCBITaxon · NCIT · Uberon ·            │
       │   PROV-O · DCAT · CHMO · AFO                               │
       │   anchored on Universal Annotation Identifiers (UAI)       │
       └────────────────────────────────────────────────────────────┘

Pipeline

A single entry point, main.py, drives six stages:

  1. fetchdata_retriever/pmid.py
    Pull PMIDs citing a seed paper from the NIH iCite API, fetch PubMed metadata, download open-access PDFs from the PMC AWS S3 mirror.
  2. extractdata_retriever/find_massive_gnps.py
    Convert PDFs to markdown with docling; regex-mine GNPS task IDs (with OCR-tolerant fuzzy matching), MassIVE accessions, and Zenodo records.
  3. jobsdata_retriever/job_download.py
    Download and extract the GNPS job archives (classical molecular networking and feature-based molecular networking) referenced in every paper.
  4. mapmapping/script.py
    Materialise per-job RDF with morph-kgc and RML mappings from mapping/rml/; write Turtle to mapping/kg/.
  5. loadmapping/load_to_virtuoso.py
    Start OpenLink Virtuoso 7 via docker compose; bulk-load /data (per-job KGs), /schema (project schema), and /ontology (external OWL files) into named graphs. The Ontology/ directory is not tracked in git — pass --populate-ontology once to download SIO, MS, ENVO, NCBITaxon, NCIT, Uberon, PROV-O, DCAT, CHMO, and AFO from their canonical web URLs.
  6. cqmapping/load_and_query_kg.py
    Run the competency questions in mapping/CQ/ — self-contained SPARQL files, each with the natural-language question in a leading # comment block — and write one CSV per query to mapping/CQ/results/.

Getting started

Prerequisites

  • Docker (Virtuoso RDF store)
  • Python 3.10+
  • uv for dependency management

Install

git clone https://github.com/HolobiomicsLab/MetaBoKG.git
cd MetaBoKG
uv sync

Run the full pipeline

uv run python main.py all

Or run any subset, in any order. Extra arguments after the stage name are forwarded to the underlying script:

uv run python main.py fetch
uv run python main.py extract --workers 8
uv run python main.py jobs --gnps-version 1 --max-workers 8
uv run python main.py map
uv run python main.py load --populate-ontology   # first run: fetch external ontologies
uv run python main.py load --reload              # later runs: refresh /data only
uv run python main.py cq                         # run the CQ suite
uv run python main.py cq --only CQ1 CQ2 CQ3      # re-run a subset of the CQs

# chain a subset (extras forwarded to every stage)
uv run python main.py map load cq

fetch reads its seed PMID from SOURCE_PMID in data_retriever/pmid.py; edit it there to retarget.

The Universal Annotation Identifier (UAI)

Every annotation, sample, feature, and scan minted by MetaBoKG is anchored on a MBS:UAI node carrying a strict, machine-checkable subset of properties (MBS:collectionID, MBS:mzml, MBS:annotation, MBS:hit, MBS:featureTable, MBS:feature, MBS:scan). This gives three properties for free:

  • Late binding — an annotation row can be ingested before its sample metadata is available, and re-linked when ReDU lands.
  • Incremental ingestion — re-running a GNPS job overwrites only its own named slice of the graph (main.py load --reload).
  • Post-hoc linkage — two annotations on the same sample, same feature, or same compound across two different studies become a single SPARQL join (see CQ1 and CQ4 in mapping/CQ/).

Knowledge graph layout

Component Location Notes
Per-job materialised TTLs mapping/kg/ One TTL per GNPS / ReDU artifact
Project schema (classes + props) Schema/ Full MetaBoKG schema (classes, properties, ReDU hierarchies)
Imported ontologies Ontology/ SIO, MS, ENVO, NCBITaxon, NCIT, Uberon, PROV-O, DCAT, CHMO, AFO (web-fetched)
RML mappings mapping/rml/ One template per source (GNPS, FBMN, MN, ReDU)
Competency questions mapping/CQ/ Self-contained SPARQL (.rq) files; results in mapping/CQ/results/

Schema and prefixes

Schema/ holds the full schema for MetaBoKG: class declarations, property declarations, and the ReDU class hierarchy (metabokg.ttl, reDU_extraction_collection.ttl, reDU_internal_standard.ttl, reDU_organism.ttl, reDU_sample_type.ttl). Two namespaces are used throughout:

Prefix IRI Role
MBS: <https://ns.inria.fr/metaboKG/schema/> Schema-level terms (classes, props)
MBD: <https://ns.inria.fr/metaboKG/data/> Instance-level resources (data)

A complete visual modeling of the knowledge graph — entities, properties, and external-ontology anchors — is available at doc/MetaboKG.svg. The human-readable schema documentation is published at https://ns.inria.fr/MetaboKG/doc/index-en.html.

Competency questions

Eight competency questions are defined as self-contained SPARQL files in mapping/CQ/ — each with the natural-language question in a leading # comment block, the shared prefix set, and the query body. They are run by mapping/load_and_query_kg.py (main.py cq), which writes one CSV per query to mapping/CQ/results/.

The first four are the paper's core competency questions:

  1. CQ1 — Do GNPS annotations land on samples whose biological and environmental context has been harmonized in Pan-ReDU?
  2. CQ2 — How does spectral match quality vary across studies and across instruments?
  3. CQ3 — For a given annotation, are the ClassyFire and NPClassifier taxonomies consistent, and which pairs co-occur most often?
  4. CQ4 — In which sample types has a given compound been observed across the integrated repositories?

The remaining four target cross-domain needs (taxon context, provenance, sample preparation, study quality):

  1. CQ5 — Which chemical entities are known from a given taxon, and how are they linked to relevant biological context?
  2. CQ6 — Which annotations were asserted for a given entity, by which workflow, and with what supporting evidence?
  3. CQ7 — Which sample preparation steps and instruments were used to generate a given measurement?
  4. CQ8 — Which studies, samples, or observations are associated with particular quality characteristics or statistical analyses?

Running Virtuoso by hand

main.py load wraps everything below. The raw commands are documented here in case you want to drive Virtuoso directly.

Volumes mounted by docker-compose.virtuoso.yml:

Host Container Contents
mapping/kg/ /data morph-kgc materialised TTLs (one per GNPS / ReDU)
Schema/ /schema Project schema (metabokg.ttl and ReDU mappings)
Ontology/ /ontology External ontologies (sio.owl, envo.owl, ncbitaxon.owl, …)

Start Virtuoso

docker compose -f docker-compose.virtuoso.yml up -d

Wait until server is up to be query by checking the logs.

docker logs -f metabokg-virtuoso

SPARQL endpoint at http://localhost:8890/sparql.

Reload only the data graph

ld_dir does not deduplicate against previous loads. To rebuild /data after a fresh materialisation while keeping schema/ontology graphs in place:

uv run python main.py load --reload

or by hand:

docker exec -i metabokg-virtuoso isql 1111 dba dba <<'SQL'
SPARQL CLEAR GRAPH <https://ns.inria.fr/metaboKG/graph/main>;
DELETE FROM DB.DBA.LOAD_LIST WHERE ll_graph = 'https://ns.inria.fr/metaboKG/graph/main';
ld_dir('/data', '*.ttl', 'https://ns.inria.fr/metaboKG/graph/main');
rdf_loader_run();
checkpoint;
SQL

To wipe everything and start fresh: docker compose -f docker-compose.virtuoso.yml down -v && docker compose -f docker-compose.virtuoso.yml up -d.

Contributing

Contributions are welcome — open a pull request or start a discussion if you want to extend the ontology, the RML mappings, the extractor heuristics, or add a competency question. Bug reports with a reproducible job ID are especially appreciated.

License

Licensed under the Apache License, Version 2.0.

Citing

MetaBoKG is described in:

MetaBoKG: an analysis-centric knowledge graph framework for untargeted metabolomics. — https://arxiv.org/abs/2605.24706

Contact

Matthieu Feraud — matthieu.feraud@univ-cotedazur.fr.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages