Skip to content
10 changes: 9 additions & 1 deletion src/si_ref_point/aboxes/constants_abox.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from si_ref_point.tboxes.si_tbox import SiElements
import si_ref_point.aboxes.symbols_format as sf
from si_ref_point.settings import PKG_ROOT, CC_LICENCE, CC_LICENCE_TEXT_EN, CC_LICENCE_TEXT_FR, \
SI_FILES_FOLDER, GITHUB_BASE_PATH
SI_FILES_FOLDER, GITHUB_BASE_PATH, SIDFWBASE, SIRPVERSION
from si_ref_point.aboxes.units_abox import transform_to_graph


Expand Down Expand Up @@ -46,6 +46,11 @@ def main():
"seven underpinning constants of the SI"),
datatype=XSD.string))
)

# SemVer
version_iri = URIRef(SIDFWBASE + "/" + SIRPVERSION + "/constants/")
constants_graph.add((URIRef(si_graph.namespace_constants), OWL.versionIRI, version_iri))
constants_graph.add((URIRef(si_graph.namespace_constants), OWL.versionInfo, Literal(SIRPVERSION, datatype=XSD.string)))

# 2.2 Versioning (using PROVENANCE vocabulary)
# The `timestamp` variable in the code is used to capture the current system time in UTC timezone.
Expand All @@ -58,6 +63,9 @@ def main():
"%Y-%m-%dT%H:%M:%SZ") # used with the predicate 'startedAtTime' of the corresponding activity
repo = git.Repo(PKG_ROOT, search_parent_directories=True)
sha = repo.head.object.hexsha



# 2.2.1 Agent
# declare this code as an 'agent' (in the sense of PROVENANCE)
# and define URI to a specific version by using its commit on GitHub
Expand Down
60 changes: 37 additions & 23 deletions src/si_ref_point/aboxes/decisions_abox.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,43 @@
import os
import yaml
from datetime import date
from rdflib import RDF, OWL, URIRef, RDFS, DCTERMS, Literal, SKOS, XSD
from rdflib import Graph, RDF, OWL, URIRef, RDFS, DCTERMS, Literal, SKOS, XSD
from si_ref_point.tboxes.si_tbox import SiElements
from si_ref_point.settings import SI_FILES_FOLDER
from si_ref_point.settings import SI_FILES_FOLDER, SIDFWBASE, SIRPVERSION

def cap1(instr):
"""Utility method"""
return instr[0].upper() + instr[1:]

def main():
"""main of Decision A-box"""
# get the predicates and classes that are common to all cuq files
si_graph = SiElements()

# Annotations to the ontology (name, Version number)
si_graph.g.add((URIRef(si_graph.namespace_decisions), RDF.type, OWL.Ontology))
si_graph.g.add((URIRef(si_graph.namespace_decisions), SKOS.prefLabel,
# produce a separate graph for the decisions
decisions_graph = Graph()

# 1) Define the namespaces
decisions_graph.bind("si", si_graph.namespace)
decisions_graph.bind("decisions", si_graph.namespace_decisions)

# 2) Annotations to the ontology (name, Version number)
decisions_graph.add((URIRef(si_graph.namespace_decisions), RDF.type, OWL.Ontology))
decisions_graph.add((URIRef(si_graph.namespace_decisions), SKOS.prefLabel,
Literal("SI Reference Point - Decisions", datatype=XSD.string)))
si_graph.g.add((URIRef(si_graph.namespace_decisions), RDFS.comment,
decisions_graph.add((URIRef(si_graph.namespace_decisions), RDFS.comment,
Literal("Ontology, part of the SI reference point, "
"covering decisions",
datatype=XSD.string)))
si_graph.g.add((URIRef(si_graph.namespace_decisions), DCTERMS.created,
decisions_graph.add((URIRef(si_graph.namespace_decisions), DCTERMS.created,
Literal(str(date.today()), datatype=XSD.date)))

# SemVer

version_iri = URIRef(SIDFWBASE + "/" + SIRPVERSION + "/decisions/")
decisions_graph.add((URIRef(si_graph.namespace_decisions), OWL.versionIRI, version_iri))
decisions_graph.add((URIRef(si_graph.namespace_decisions), OWL.versionInfo, Literal(SIRPVERSION, datatype=XSD.string)))

# crawl through the items of the YAML file
with open(os.path.join(SI_FILES_FOLDER, 'decisions.yaml'),
encoding="utf8") as fp:
Expand All @@ -34,44 +48,44 @@ def main():
# create an instance of scope if necessary, using the scope code as
# local name [TODO] : is it really only doing it if necessary ?
scope = si_graph.set_decision_uri(dec['scopeCode'])
si_graph.g.add((scope, RDF.type, si_graph.si_decision_scope))
decisions_graph.add((scope, RDF.type, si_graph.si_decision_scope))
# add labels to scope (capitalize the first character)
si_graph.g.add((scope, RDFS.label,
decisions_graph.add((scope, RDFS.label,
Literal(cap1(dec['scopeEN']), lang="en")))
si_graph.g.add((scope, RDFS.label,
decisions_graph.add((scope, RDFS.label,
Literal(cap1(dec['scopeFR']), lang="fr")))
# create instance of target if necessary using target code as local
# name
target = si_graph.set_decision_uri(dec['targetCode'])
si_graph.g.add((target, RDF.type, si_graph.si_decision_target))
decisions_graph.add((target, RDF.type, si_graph.si_decision_target))
# add labels to target
si_graph.g.add((target, RDFS.label,
decisions_graph.add((target, RDFS.label,
Literal(cap1(dec['targetEN']), lang="en")))
si_graph.g.add((target, RDFS.label,
decisions_graph.add((target, RDFS.label,
Literal(cap1(dec['targetFR']), lang="fr")))
# add links between target and scope
si_graph.g.add((scope, si_graph.has_target, target))
si_graph.g.add((target, si_graph.is_target_of, scope))
decisions_graph.add((scope, si_graph.has_target, target))
decisions_graph.add((target, si_graph.is_target_of, scope))
# create instance of decision if necessary using decision code as local
# name
decision = si_graph.set_decision_uri(dec['decisionCode'])
si_graph.g.add((decision, RDF.type, si_graph.si_decision))
decisions_graph.add((decision, RDF.type, si_graph.si_decision))
# add labels to decision
si_graph.g.add((decision, RDFS.label,
decisions_graph.add((decision, RDFS.label,
Literal(cap1(dec['decisionEN']), lang="en")))
si_graph.g.add((decision, RDFS.label,
decisions_graph.add((decision, RDFS.label,
Literal(cap1(dec['decisionFR']), lang="fr")))
# add links between decision and target
si_graph.g.add((target, si_graph.has_decision, decision))
si_graph.g.add((decision, si_graph.is_decision_of, target))
decisions_graph.add((target, si_graph.has_decision, decision))
decisions_graph.add((decision, si_graph.is_decision_of, target))
# add link between decision and resolution (retrieved from one of
# cgpm.ttl, cipm.ttl or cctf.ttl) using the ‘correspondingResolution’
# object property
si_graph.g.add((decision, si_graph.corresponding_resolution,
decisions_graph.add((decision, si_graph.corresponding_resolution,
si_graph.set_resolution_uri(dec['ID-resolution'])))
if 'crossReferences' in dec:
for xref in dec['crossReferences']:
# add link between decision and the cross-referenced decision
si_graph.g.add((decision, SKOS.related, si_graph.set_decision_uri(xref)))
decisions_graph.add((decision, SKOS.related, si_graph.set_decision_uri(xref)))

return si_graph.g
return decisions_graph
12 changes: 9 additions & 3 deletions src/si_ref_point/aboxes/prefixes_abox.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from decimal import Decimal
from rdflib import Graph, URIRef, RDF, OWL, SKOS, XSD, RDFS, DCTERMS, Literal, PROV
from si_ref_point.tboxes.si_tbox import SiElements
from si_ref_point.settings import PKG_ROOT, CC_LICENCE, CC_LICENCE_TEXT_EN, CC_LICENCE_TEXT_FR, SI_FILES_FOLDER, GITHUB_BASE_PATH
from si_ref_point.settings import PKG_ROOT, CC_LICENCE, CC_LICENCE_TEXT_EN, CC_LICENCE_TEXT_FR, SI_FILES_FOLDER, \
GITHUB_BASE_PATH, SIDFWBASE, SIRPVERSION


def main():
Expand All @@ -20,8 +21,8 @@ def main():
prefix_graph = Graph()

# 1) Define the namespaces within (base)/SI
prefix_graph.bind("prefixes",si_graph.namespace_prefixes)
prefix_graph.bind("si",si_graph.namespace)
prefix_graph.bind("prefixes", si_graph.namespace_prefixes)
prefix_graph.bind("si", si_graph.namespace)

# 2) Annotations to the prefix-graph

Expand All @@ -43,6 +44,11 @@ def main():
"prefixes for the SI measurement units."))
)

# SemVer
version_iri = URIRef(SIDFWBASE + "/" + SIRPVERSION + "/prefixes/")
prefix_graph.add((URIRef(si_graph.namespace_prefixes), OWL.versionIRI, version_iri))
prefix_graph.add((URIRef(si_graph.namespace_prefixes), OWL.versionInfo, Literal(SIRPVERSION, datatype=XSD.string)))

# 2.2 Versioning (using PROVENANCE vocabulary)
timestamp = datetime.now(timezone.utc) # get the system time (in UTC)
uri_timestamp = timestamp.strftime("%Y%m%d%H%M%SZ") # used to identify uniquely the produced TTL file (entity)
Expand Down
8 changes: 7 additions & 1 deletion src/si_ref_point/aboxes/quantities_abox.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from rdflib import Graph, RDF, OWL, URIRef, RDFS, DCTERMS, Literal, SKOS, XSD, PROV
from si_ref_point.tboxes.si_tbox import SiElements
from si_ref_point.aboxes.units_abox import transform_to_graph
from si_ref_point.settings import PKG_ROOT, CC_LICENCE, CC_LICENCE_TEXT_EN, CC_LICENCE_TEXT_FR, SI_FILES_FOLDER, GITHUB_BASE_PATH
from si_ref_point.settings import PKG_ROOT, CC_LICENCE, CC_LICENCE_TEXT_EN, CC_LICENCE_TEXT_FR, SI_FILES_FOLDER, \
GITHUB_BASE_PATH, SIDFWBASE, SIRPVERSION


def main():
Expand Down Expand Up @@ -46,6 +47,11 @@ def main():
datatype=XSD.string))
)

# SemVer
version_iri = URIRef(SIDFWBASE + "/" + SIRPVERSION + "/quantities/")
quantities_graph.add((URIRef(si_graph.namespace_quantities), OWL.versionIRI, version_iri))
quantities_graph.add((URIRef(si_graph.namespace_quantities), OWL.versionInfo, Literal(SIRPVERSION, datatype=XSD.string)))

# 2.2 Versioning (using PROVENANCE vocabulary)
timestamp = datetime.now(timezone.utc) # get the system time (in UTC)
uri_timestamp = timestamp.strftime("%Y%m%d%H%M%SZ") # used to identify uniquely the produced TTL file (entity)
Expand Down
8 changes: 7 additions & 1 deletion src/si_ref_point/aboxes/rb_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from rdflib import Graph, Literal, Namespace, URIRef
from rdflib.namespace import DCTERMS, OWL, RDF, RDFS, SKOS, XSD
from si_ref_point.tboxes.rb_tbox import RES_BOD_NS
from si_ref_point.settings import SIDFWBASE
from si_ref_point.settings import SIDFWBASE, SIRPVERSION

RB = Namespace(RES_BOD_NS)

Expand Down Expand Up @@ -63,6 +63,12 @@ def add_general_description(self):
)
)

# SemVer
version_iri = URIRef(SIDFWBASE + "/" + SIRPVERSION + "/bodies/" + self.own_acronym + "#")
self.g.add((URIRef(self.OWN_NS), OWL.versionIRI, version_iri))
self.g.add((URIRef(self.OWN_NS), OWL.versionInfo, Literal(SIRPVERSION, datatype=XSD.string)))


self.g.add(
(
URIRef(self.OWN_NS),
Expand Down
8 changes: 7 additions & 1 deletion src/si_ref_point/aboxes/units_abox.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
from rdflib import Graph, URIRef, BNode, Literal, RDF, OWL, SKOS, XSD, RDFS, DCTERMS, PROV
from si_ref_point.tboxes.si_tbox import SiElements
import si_ref_point.aboxes.symbols_format as sf
from si_ref_point.settings import PKG_ROOT, CC_LICENCE, CC_LICENCE_TEXT_EN, CC_LICENCE_TEXT_FR, SI_FILES_FOLDER, GITHUB_BASE_PATH
from si_ref_point.settings import PKG_ROOT, CC_LICENCE, CC_LICENCE_TEXT_EN, CC_LICENCE_TEXT_FR, SI_FILES_FOLDER, \
GITHUB_BASE_PATH, SIDFWBASE, SIRPVERSION


def nest_mult(expr):
Expand Down Expand Up @@ -171,6 +172,11 @@ def main():
datatype=XSD.string))
)

# SemVer
version_iri = URIRef(SIDFWBASE + "/" + SIRPVERSION + "/units/")
units_graph.add((URIRef(si_graph.namespace_units), OWL.versionIRI, version_iri))
units_graph.add((URIRef(si_graph.namespace_units), OWL.versionInfo, Literal(SIRPVERSION, datatype=XSD.string)))

# 2.2 Versioning (using PROVENANCE vocabulary)
timestamp = datetime.now(timezone.utc) # get the system time (in UTC)
uri_timestamp = timestamp.strftime("%Y%m%d%H%M%SZ") # used to identify uniquely the produced TTL file (entity)
Expand Down
3 changes: 2 additions & 1 deletion src/si_ref_point/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
SKOSURL = "http://www.w3.org/2004/02/skos/core#"
DCTURL = "http://purl.org/dc/terms#"
SIDFWBASE = "https://si-digital-framework.org"
SIRPVERSION = "1.0.0"

# Base URL for the SI Digital Framework
# from this URL, sub-URLs are defined
Expand All @@ -35,7 +36,7 @@
# TTL_FILES_FOLDER = TTLPATH
# JSONLD_FILES_FOLDER = JLDPATH

GITHUB_BASE_PATH = "https://github.com/TheBIPM/SI-Reference-Point-2023/"
GITHUB_BASE_PATH = "https://github.com/TheBIPM/SI-Reference-Point-generation-scripts/"

# SI_BROCHURE_PID="SI_Brochure_ed3_V3_01" # will be transformed into a PID '(SIDFWBASE)/SI/entities/(SI_BROCHURE_PID)'

Expand Down
15 changes: 14 additions & 1 deletion src/si_ref_point/tboxes/rb_tbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@

from datetime import date
from rdflib import URIRef, RDF, OWL, SKOS, XSD, RDFS, DCTERMS, Graph, Literal
from si_ref_point.settings import SIDFWBASE, SKOSURL
from si_ref_point.settings import SIDFWBASE, SKOSURL, SIRPVERSION

RES_BOD_NS = SIDFWBASE + "/bodies#"

class ResBod:
def __init__(self, namespace: str = RES_BOD_NS, prefix: str = 'rb'):

# 1) Define namespaces
self.namespace = namespace

# 2) Add annotations to the ontology
# 2.1 General annotations (type, comments etc)
self._g = Graph() # a triple store as the main data structure
self._g.bind(prefix, namespace)
self._g.bind("skos", SKOSURL)
Expand All @@ -21,6 +26,14 @@ def __init__(self, namespace: str = RES_BOD_NS, prefix: str = 'rb'):
"resolutions, decisions, etc", datatype=XSD.string)))
self._g.add((URIRef(RES_BOD_NS), DCTERMS.created, Literal(str(date.today()), datatype=XSD.date)))

# 2.2 Versioning

version_iri = URIRef(SIDFWBASE + "/" + SIRPVERSION + "/bodies#")
self._g.add((URIRef(self.namespace), OWL.versionIRI, version_iri))
self._g.add((URIRef(self.namespace), OWL.versionInfo, Literal(SIRPVERSION, datatype=XSD.string)))


# 3) Define classes and predicates used by different A boxes
self.ResBod = self.set_uri('ResBod')
self._g.add((self.ResBod, RDF.type, SKOS.Concept))
self._g.add((self.ResBod, RDFS.label, Literal('Responsible Body', lang='en')))
Expand Down
11 changes: 10 additions & 1 deletion src/si_ref_point/tboxes/si_tbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from rdflib import Graph, OWL, RDF, RDFS, URIRef, Literal, BNode, SKOS, PROV
from rdflib.collection import Collection
from rdflib.namespace import XSD, DCTERMS
from si_ref_point.settings import PKG_ROOT, CC_LICENCE, CC_LICENCE_TEXT_EN, CC_LICENCE_TEXT_FR, SI_FILES_FOLDER, GITHUB_BASE_PATH, SIDFWBASE
from si_ref_point.settings import PKG_ROOT, CC_LICENCE, CC_LICENCE_TEXT_EN, CC_LICENCE_TEXT_FR, SI_FILES_FOLDER, \
GITHUB_BASE_PATH, SIDFWBASE, SIRPVERSION


RES_BOD_NS = SIDFWBASE + "/bodies#"
bodies_list = ['cgpm', 'cipm', 'cctf']
Expand Down Expand Up @@ -36,6 +38,9 @@ def __init__(self, namespace: str = SIDFWBASE + "/SI#", ns_prefix: str = "si"):
self.namespace_constants = SIDFWBASE + "/constants/"
# Explicitly binding a constants namespace to the URI
self.g.bind("constants", self.namespace_constants)

# Explicitly binding a decisions namespace to the URI
self.g.bind("decisions", self.namespace_decisions)

# Define the namespaces within (base)/bodies
# ~/bodies
Expand Down Expand Up @@ -94,6 +99,10 @@ def __init__(self, namespace: str = SIDFWBASE + "/SI#", ns_prefix: str = "si"):
uri_timestamp = timestamp.strftime("%Y%m%d%H%M%SZ") # used to identify uniquely the produced TTL file (entity)
startedAt_timestamp = timestamp.strftime("%Y-%m-%dT%H:%M:%SZ") # used with the predicate 'startedAtTime' of the corresponding activity

version_iri = URIRef(SIDFWBASE + "/" + SIRPVERSION + "/SI#")
self.g.add((URIRef(self.namespace), OWL.versionIRI, version_iri))
self.g.add((URIRef(self.namespace), OWL.versionInfo, Literal(SIRPVERSION, datatype=XSD.string)))

### `generate_turtle_files`
repo = git.Repo(PKG_ROOT, search_parent_directories=True)
sha = repo.head.object.hexsha
Expand Down