Modelling guide¶
These are the conventions used in schema/ and examples/. The reasons behind them are in the design notes in docs/adr/.
Principles¶
- Competency questions drive the model. Every class or slot should serve at least one question in
queries/. If no question needs it, it waits. - Reuse before you invent.
- Use an existing ontology identifier for things: NCBITaxon, ENVO, MONDO, ChEBI and so on.
- Use an existing standard property for relations: MIxS, SOSA, RO, DCTERMS, PROV.
- Mint
micokg:terms only when nothing fits, and write down why. - Keep measurements separate from claims. Per-sample measurements are
Observations. Generalised or literature-derived statements areAssociations. - Keep context with the claim. Direction, body site, environment, host, evidence and source live on the association node (ADR-0001).
Identifiers¶
| Kind of thing | Identifier | Example |
|---|---|---|
| Organism, habitat, anatomy, disease, chemical, function, AMR gene family | Ontology CURIE | NCBITaxon:851, ENVO:00002005, ARO:3000186 |
| Sample, observation, association, study, host, gene record | Minted micokg:<type>/<local-id> |
micokg:sample/UC3-S01 |
| Person | ORCID | ORCID:0000-0002-... |
| Publication | doi: or PMID: |
doi:10.1234/abcd |
| Source resource | infores CURIE | infores:gutmdisorder |
Type segments currently in use: study, sample, host, obs, assoc, gene, property.
Slots with ontology values¶
Ontology-valued slots have range: uriorcurie and a pattern restricting the prefix, and they may declare bindings to a dynamic enum (the allowed ontology branch):
env_medium:
slot_uri: mixs:0000014
range: uriorcurie
pattern: "^(ENVO:\\d{8}|UBERON:\\d{7})$"
bindings:
- range: EnvironmentalMaterialEnum
obligation_level: RECOMMENDED
Why not an enum? LinkML writes enum values to RDF as string literals, but queries need IRIs so that they can follow rdfs:subClassOf. tests/test_rdf_shacl.py::test_ontology_slots_are_iris guards this. Static enums are fine for small internal code lists such as direction and compartment.
Naming¶
- Classes are
UpperCamelCase; slots and enum values aresnake_case. - Association classes are named
<Subject><Object>Association, or...Interactionfor organism–organism. - Every slot has a
slot_uri. Choose, in order: - an established standard (MIxS, SOSA, DCTERMS, PROV, SKOS, RDFS);
- an OBO Relation Ontology property (RO);
micokg:<slot_name>.
Adding a new association type (worked recipe)¶
Example: taxon produces a quorum-sensing molecule that affects host inflammation.
- Write the competency question first.
- Check whether an existing class fits. Here
TaxonMetaboliteAssociationplusMetaboliteDiseaseAssociationalready chain. -
If a new class is needed, add it to
schema/associations.yaml:TaxonPhenotypeAssociation: is_a: Association class_uri: micokg:TaxonPhenotypeAssociation description: A taxon is associated with a host phenotype. slot_usage: subject: pattern: "^(NCBITaxon:\\d+|GTDB:.+)$" predicate: pattern: "^RO:(0002610|0003302)$" object: pattern: "^(HP|MP|NCIT):[A-Za-z0-9_]+$" -
Add a list slot to
Containerinschema/micokg.yaml(taxon_phenotype_associations), and any new prefixes. - Add toy data to
examples/valid/, plus anexamples/invalid/file showing a common mistake. - Add the
.rqquery and thecqs.yamlentry, then runmake slims(for the new terms) andmake test.
Observations¶
observed_propertyis amicokg:property/...IRI for now (relative_abundance,gene_presence). Open question: adopt a published property vocabulary (e.g. from OBA, STATO or the MIxS measurement terms).simple_resultis a number. Use0for "tested and not detected", and simply leave out things that weren't tested.used_procedureshould point to an OBI assay or a bio.tools/WorkflowHub identifier.
Open questions¶
| # | Question | Current choice |
|---|---|---|
| 1 | MONDO or DO as the preferred disease ontology? | MONDO first; DO/NCIT/EFO accepted, bridged by SSSOM |
| 2 | NCBITaxon vs GTDB for MAG-derived taxa | Both accepted; mapping file needed |
| 3 | Plasmid is not under mobile_genetic_element in SO. How should "mobile context" be modelled? |
Queries list both roots |
| 4 | How to represent negative findings (no association found)? | negated: true; excluded from shortcuts |
| 5 | Meaning and calibration of confidence across sources |
Free float 0–1; needs a definition |
| 6 | Units and normalisation for abundance | unit slot; no vocabulary chosen yet (QUDT/UO?) |
| 7 | Imaging and clinical data | Future modules (imaging.yaml, clinical.yaml) |
| 8 | Individual-level host data and privacy | Hosts are pseudonymous toy records; real data only aggregated? |
| 9 | Reification in RDF 1.2 (triple terms) vs association nodes | Association nodes (see ADR-0001) |