Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update 223P to public advisory review version #309

Merged
merged 163 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from 132 commits
Commits
Show all changes
163 commits
Select commit Hold shift + click to select a range
22330fc
updating 223p again
gtfierro Jan 19, 2023
87b3862
Merge pull request #282 from NREL/develop
MatthewSteen Sep 15, 2023
e69a94a
update 223p templates
gtfierro Nov 30, 2023
742e7ae
update 223
gtfierro Nov 30, 2023
c9030d7
Merge branch 'develop' into gtf-update-223p-templates
gtfierro Dec 6, 2023
3ce1cd1
add QUDT
gtfierro Dec 6, 2023
a5ec71f
Merge branch 'gtf-update-223p-templates' of github.com:NREL/BuildingM…
gtfierro Dec 6, 2023
85cf110
update templates
gtfierro Dec 6, 2023
606a8a4
allow Library to find template definitions from dependent libraries
gtfierro Mar 5, 2024
58cebb1
fixing tests to catch warnings, test dependency tracking
gtfierro Mar 6, 2024
550e263
use non-deprecated warnings; make sure warnings are emitted when nece…
gtfierro Mar 6, 2024
b483f71
clarify when dependencies are infered for SHACL shapes -> templates
gtfierro Mar 6, 2024
1bbdc3a
update dependencies
gtfierro Mar 6, 2024
82e575c
adding documentation on templates
gtfierro Mar 6, 2024
f036bc8
placeholder for further template docs
gtfierro Mar 6, 2024
569c468
clarify load order
gtfierro Mar 6, 2024
40a1b78
update jsonschema, skip mypy checking on imports
gtfierro Mar 6, 2024
87ade9e
fix API response and test to handle Brick
gtfierro Mar 6, 2024
1255b23
updating 223p and templates
gtfierro Mar 12, 2024
5231e71
filtering validationcontext by severity
gtfierro Mar 12, 2024
cdeba72
add shacl_validate/infer functions and use these as the entrypoint. A…
gtfierro Mar 12, 2024
95cee3f
fix interactions with shacl inference
gtfierro Mar 12, 2024
91e90d2
tightening up the implementation and use of the shacl_* methods
gtfierro Mar 14, 2024
936e830
support specifying shacl engine in the API
gtfierro Mar 14, 2024
7a1a786
update tests; test both pyshacl and topquadrant
gtfierro Mar 14, 2024
f5e9465
add brick-tq-shacl dep
gtfierro Mar 14, 2024
1c29f61
add TODOs
gtfierro Mar 14, 2024
37c29d2
Formatting
gtfierro Mar 14, 2024
1174e7b
no more 3.8!
gtfierro Mar 14, 2024
eef32da
ignoring some imported packages without type annotations
gtfierro Mar 14, 2024
1bd0a94
more type annotations
gtfierro Mar 14, 2024
9194ac0
add types, ignore type errors for imports
gtfierro Mar 14, 2024
5246f9e
update mypy, fix some issues and ignore some others
gtfierro Mar 14, 2024
ab4ee7d
fix union type annotation
gtfierro Mar 14, 2024
ea59b4a
update docker containers
gtfierro Mar 14, 2024
9804f10
3.8.1 python for higher
gtfierro Mar 15, 2024
0427587
add back python 3.8
gtfierro Mar 15, 2024
b68be1f
Merge remote-tracking branch 'origin/develop' into topquadrant-shacl
gtfierro Mar 17, 2024
ec350db
change 3.8 version
gtfierro Mar 17, 2024
f7116c6
add test for finding reasons with a given severity
gtfierro Mar 17, 2024
695290b
update brick-tq-shacl, fix type signature
gtfierro Mar 18, 2024
e4098ac
remove debug serializations
gtfierro Mar 18, 2024
2b8893f
bump shacl version
gtfierro Mar 18, 2024
b06f8c1
fixing skolemization for validation
gtfierro Mar 19, 2024
409f7ad
Merge remote-tracking branch 'origin/develop' into update-223p
gtfierro Mar 20, 2024
30c591b
Merge remote-tracking branch 'origin/topquadrant-shacl' into update-223p
gtfierro Mar 20, 2024
dce13f4
Merge remote-tracking branch 'origin/gtf-update-223p-templates' into …
gtfierro Mar 20, 2024
1e4c316
update 223p, fix merge error
gtfierro Mar 20, 2024
aa819d9
fix notebook
gtfierro Mar 20, 2024
81d0205
fix more templates; test 223p again
gtfierro Mar 21, 2024
43d3565
move shacl engine config inside buildingmotif object
gtfierro Mar 22, 2024
eb3d28b
parameterize testing of templates for 223p
gtfierro Apr 10, 2024
262a2a6
Merge branch 'update-223p' of github.com:NREL/BuildingMOTIF into upda…
gtfierro Apr 10, 2024
4405efd
Merge remote-tracking branch 'origin/topquadrant-shacl' into update-223p
gtfierro Apr 10, 2024
845d2d1
Merge remote-tracking branch 'origin/develop' into update-223p
gtfierro Apr 16, 2024
4cfcee0
change some brick templates to make tests less noisy
gtfierro Apr 16, 2024
e8e18d2
fixing up templates
gtfierro Apr 19, 2024
73008dc
add brick integration tests
gtfierro Apr 19, 2024
829ba1a
upadte QUDT
gtfierro Apr 20, 2024
cbe85cb
223p fixup
gtfierro Apr 20, 2024
a96e3ec
add shacl engine and qudt to tests
gtfierro Apr 20, 2024
bab464f
use public review version of 223p
gtfierro Apr 23, 2024
bb72890
add qudt 2.1.37 release
gtfierro Apr 23, 2024
cbabbb6
better exception message
gtfierro Apr 23, 2024
a23c4b9
fixing system, sensor templates
gtfierro Apr 25, 2024
3255426
fixing up 223 templates
gtfierro Apr 28, 2024
6800a03
fix plugging connection points in 223p
gtfierro Apr 28, 2024
ac0c7bd
add the shape graph to the data graph for validation
gtfierro Apr 30, 2024
6ee012a
Merge branch 'update-223p' of github.com:NREL/BuildingMOTIF into upda…
gtfierro Apr 30, 2024
797d7a6
clean up a little; skip some templates for pyshacl + 223p
gtfierro Apr 30, 2024
cea5fb5
fixing use of tmpdir -> tmp_path
gtfierro Apr 30, 2024
fd173c5
try persistence test without path
gtfierro May 1, 2024
1708b1a
use path again; try print statements
gtfierro May 1, 2024
9a1886b
Merge branch 'update-223p' of github.com:NREL/BuildingMOTIF into upda…
gtfierro May 1, 2024
ad6a385
Add new transitive_parameters method to accelerate library loading
gtfierro May 1, 2024
ead2b25
use cached_property
gtfierro May 1, 2024
89640d1
tryin-memory?
gtfierro May 1, 2024
9d543fc
skip the test -- is this the only one that iss broken?
gtfierro May 1, 2024
89c5977
remove this file
gtfierro May 1, 2024
065c457
add back path, remove other conftest
gtfierro May 1, 2024
4426e9c
add back path, remove other conftest
gtfierro May 1, 2024
25994d1
remove test from in-progress code
gtfierro May 1, 2024
316d180
remove cached_property
gtfierro May 2, 2024
b92bbe8
Merge remote-tracking branch 'origin/gtf-accelerate-load-from-ontolog…
gtfierro May 2, 2024
62be255
add back conf tests with optimized loading
gtfierro May 2, 2024
131f7e8
fix docker
gtfierro May 2, 2024
b649431
more test hacking
gtfierro May 2, 2024
1ba064a
remove duplicate parameterization
gtfierro May 2, 2024
ffe6c04
remove bad merge
gtfierro May 2, 2024
eb01e22
fix bacnet docker container
gtfierro May 2, 2024
69a7891
bump workflow action versions
gtfierro May 2, 2024
38f3599
use more recent Brick, try to write to local db file for persistence …
gtfierro May 3, 2024
60c5334
Merge remote-tracking branch 'origin/develop' into update-223p
gtfierro May 10, 2024
a4bf16b
fix brick references, fix persistence test
gtfierro May 10, 2024
fdfd86b
support configuring the shacl engine when starting the buildingmotif API
gtfierro May 14, 2024
0f78b9a
make sure SHACL engine is passed around
gtfierro May 14, 2024
ae3d6cf
handle dependencies for Brick validation in integration tests
gtfierro May 14, 2024
646bd48
bump deps
gtfierro May 14, 2024
03ced86
Merge remote-tracking branch 'origin/develop' into update-223p
gtfierro May 15, 2024
ad1aecf
remove debug
gtfierro May 15, 2024
0d6b5f7
add imports for brick
gtfierro May 15, 2024
d11fe90
Merge branch 'gtf-accelerate-load-from-ontology' into update-223p
gtfierro May 16, 2024
e6ae228
update brick 1.3 -> 1.4
gtfierro May 17, 2024
1d5af06
Merge branch 'update-223p' of github.com:NREL/BuildingMOTIF into upda…
gtfierro May 17, 2024
f7d6f45
reduce tests temporarily
gtfierro May 21, 2024
abc3890
Merge remote-tracking branch 'origin/develop' into update-223p
gtfierro May 21, 2024
fbdc091
Merge branch 'develop' into update-223p
gtfierro May 21, 2024
fc5ccf6
Merge branch 'update-223p' of github.com:NREL/BuildingMOTIF into upda…
gtfierro May 21, 2024
fb45770
fixing flags to customize how much work gets done when a library is l…
gtfierro May 21, 2024
f83ce19
build templates off of imports closure
gtfierro May 22, 2024
47b88ed
Merge remote-tracking branch 'origin/develop' into update-223p
gtfierro May 28, 2024
e6bf45a
Merge remote-tracking branch 'origin/develop' into update-223p
gtfierro May 29, 2024
1c3847e
more recent 223p build
gtfierro Jun 1, 2024
20dcf48
Merge remote-tracking branch 'origin/develop' into update-223p
gtfierro Jun 17, 2024
1a9f1d9
update again
gtfierro Jun 19, 2024
2b74341
newer 223p
gtfierro Jun 20, 2024
d54734f
temporarily pause bacnet integration
gtfierro Jun 20, 2024
90f7a02
Merge branch 'update-223p' of github.com:NREL/BuildingMOTIF into upda…
gtfierro Jun 20, 2024
d27dffe
add custom option; this needs to be done at the "top level" of the py…
gtfierro Jun 20, 2024
ff538b5
add bacnet back
gtfierro Jun 20, 2024
519213b
fix ci configuration
gtfierro Jun 21, 2024
a49102a
fix dependencies on template
gtfierro Jun 23, 2024
83ea75e
Merge remote-tracking branch 'origin/main' into update-223p
gtfierro Jun 23, 2024
2f792a8
fixing some libraries
gtfierro Jun 24, 2024
db0013f
add _strip_param function and tests to support inlining
gtfierro Jun 24, 2024
b78e781
fix last class
gtfierro Jun 24, 2024
0066f43
fix test
gtfierro Jun 25, 2024
01e06e0
Merge remote-tracking branch 'origin/strip-param-inline-fix' into upd…
gtfierro Jun 25, 2024
1d8e4f2
add _strip_param function and tests to support inlining
gtfierro Jun 24, 2024
bb6d7fb
fix test
gtfierro Jun 25, 2024
0982eda
Merge branch 'strip-param-inlining' into update-223p
gtfierro Jun 25, 2024
542a588
revert db persistence test
gtfierro Jun 25, 2024
11c3a9c
Merge branch 'develop' into update-223p
gtfierro Jun 26, 2024
5a69e32
Merge remote-tracking branch 'origin/develop' into update-223p
gtfierro Jun 26, 2024
0c3fdef
change how we indicate buildingMOTIF's singleton metaclass
gtfierro Jun 27, 2024
3cf346e
update chiller pointlist library
gtfierro Jun 27, 2024
89c5eac
add new test subdirectory to fucus on library/template tests
gtfierro Jun 27, 2024
6dd380e
remove debugs
gtfierro Jun 27, 2024
ab755f3
Merge branch 'update-223p' of github.com:NREL/BuildingMOTIF into upda…
gtfierro Jun 27, 2024
13af3de
monkeypatching to handle the singleton
gtfierro Jun 28, 2024
7617f8c
more adjustments on the monkeypatching
gtfierro Jun 28, 2024
f4acbe7
more monkeypatching
gtfierro Jun 28, 2024
84f5fde
add comments for explaining the library conftest
gtfierro Jun 29, 2024
cb9f08f
add library tests for github, add back notebook fixture
gtfierro Jul 1, 2024
81ba1df
add IDs to notebook tests
gtfierro Jul 1, 2024
0c30788
factor out the guarantee method and add unit tests
gtfierro Jul 2, 2024
37bcb80
add function to utils
gtfierro Jul 2, 2024
fc62cae
Merge remote-tracking branch 'origin/gtf-fix-autogen-template-names' …
gtfierro Jul 2, 2024
8b3922a
update internal Brick
gtfierro Jul 2, 2024
80c5a2a
update notebooks to match buildingmotif API
gtfierro Jul 3, 2024
b228c6f
fixing a couple notebooks
gtfierro Jul 3, 2024
d9b98e5
fix kernel
gtfierro Jul 3, 2024
ee9615b
skip some 223p templates that cannot stand on their own
gtfierro Jul 3, 2024
fea4cdd
more templates to skip for 223p
gtfierro Jul 3, 2024
2028938
increase notebook run time
gtfierro Jul 3, 2024
d2c2d8f
Merge branch 'develop' into update-223p
gtfierro Jul 4, 2024
46c997e
remove unneeded flag
gtfierro Jul 4, 2024
e727f0e
small changes to template compilation
gtfierro Jul 4, 2024
a08d061
fix chiller templates
gtfierro Jul 4, 2024
13b24e6
add libraries to dockerfile so that pytest can enumerate the tests
gtfierro Jul 5, 2024
4bcde24
Merge branch 'update-223p' of github.com:NREL/BuildingMOTIF into upda…
gtfierro Jul 5, 2024
8bae03d
add docstring for shacl_engine
gtfierro Jul 5, 2024
112a127
cleaner bypass of the singleton for library tests
gtfierro Jul 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ name: continuous integration
on:
push

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:

styling:
Expand Down Expand Up @@ -59,13 +63,13 @@ jobs:
- name: unit tests
run: poetry run pytest tests/unit --cov=./ --cov-report=xml
- name: integration tests
run: poetry run pytest tests/integration
run: poetry run pytest tests/integration -k 'topquadrant'
TShapinsky marked this conversation as resolved.
Show resolved Hide resolved
- name: bacnet tests
run: |
cd tests/integration/fixtures/bacnet
docker compose build device buildingmotif
docker compose run -d device
docker compose run buildingmotif poetry run pytest -m bacnet
docker compose run buildingmotif poetry run pytest -m bacnet --skip-library-tests
docker compose down
- name: build tests
run: poetry build
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ repos:
entry: poetry run flake8 buildingmotif
# can't poetry run becuase not present in repository https://github.com/pre-commit/mirrors-mypy
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.9.0
rev: v1.10.0
hooks:
- id: mypy
args: ["--install-types", "--non-interactive", "--ignore-missing-imports", "--follow-imports=skip", "--disable-error-code=import-untyped"]
Expand Down
5 changes: 3 additions & 2 deletions buildingmotif/api/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
from typing import Optional

from flask import Flask, current_app
from flask_api import status
Expand Down Expand Up @@ -42,7 +43,7 @@ def _after_error(error):
return str(error), status.HTTP_500_INTERNAL_SERVER_ERROR


def create_app(DB_URI):
def create_app(DB_URI, shacl_engine: Optional[str] = "pyshacl"):
gtfierro marked this conversation as resolved.
Show resolved Hide resolved
"""Creates a Flask API.

:param db_uri: database URI
Expand All @@ -54,7 +55,7 @@ def create_app(DB_URI):
app.config.from_mapping(
DB_URI=DB_URI,
)
app.building_motif = BuildingMOTIF(app.config["DB_URI"])
app.building_motif = BuildingMOTIF(app.config["DB_URI"], shacl_engine=shacl_engine)

app.after_request(_after_request)
app.register_error_handler(Exception, _after_error)
Expand Down
98 changes: 84 additions & 14 deletions buildingmotif/dataclasses/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from buildingmotif.schemas import validate_libraries_yaml
from buildingmotif.template_compilation import compile_template_spec
from buildingmotif.utils import (
copy_graph,
get_ontology_files,
get_template_parts_from_shape,
shacl_inference,
Expand Down Expand Up @@ -141,6 +142,8 @@ def load(
directory: Optional[str] = None,
name: Optional[str] = None,
overwrite: Optional[bool] = True,
infer_templates: Optional[bool] = True,
run_shacl_inference: Optional[bool] = True,
) -> "Library":
"""Loads a library from the database or an external source.
When specifying a path to load a library or ontology_graph from,
Expand All @@ -162,6 +165,12 @@ def load(
:param overwrite: if true, replace any existing copy of the
library, defaults to True
:type overwrite: Optional[true], optional
:param infer_templates: if true, infer shapes from the ontology graph,
defaults to True
:type infer_templates: Optional[bool], optional
:param run_shacl_inference: if true, run SHACL inference on the ontology graph,
using the BuildingMOTIF SHACL engine, defaults to True
:type run_shacl_inference: Optional[bool], optional
:return: the loaded library
:rtype: Library
:raises Exception: if the library cannot be loaded
Expand All @@ -180,7 +189,12 @@ def load(
ontology_graph.parse(
ontology_graph_path, format=guess_format(ontology_graph_path)
)
return cls._load_from_ontology(ontology_graph, overwrite=overwrite)
return cls._load_from_ontology(
ontology_graph,
overwrite=overwrite,
infer_templates=infer_templates,
run_shacl_inference=run_shacl_inference,
)
elif directory is not None:
if resource_exists("buildingmotif.libraries", directory):
logging.debug(f"Loading builtin library: {directory}")
Expand All @@ -191,7 +205,12 @@ def load(
src = pathlib.Path(directory)
if not src.exists():
raise Exception(f"Directory {src} does not exist")
return cls._load_from_directory(src, overwrite=overwrite)
return cls._load_from_directory(
src,
overwrite=overwrite,
infer_templates=infer_templates,
run_shacl_inference=run_shacl_inference,
)
elif name is not None:
bm = get_building_motif()
db_library = bm.table_connection.get_db_library_by_name(name)
Expand All @@ -215,7 +234,11 @@ def _load_from_db(cls, id: int) -> "Library":

@classmethod
def _load_from_ontology(
cls, ontology: rdflib.Graph, overwrite: Optional[bool] = True
cls,
ontology: rdflib.Graph,
overwrite: Optional[bool] = True,
infer_templates: Optional[bool] = True,
run_shacl_inference: Optional[bool] = True,
) -> "Library":
"""
Load a library from an ontology graph. This proceeds as follows.
Expand All @@ -229,14 +252,18 @@ def _load_from_ontology(
:type ontology: rdflib.Graph
:param overwrite: if true, overwrite the existing copy of the Library
:type overwrite: bool
:param infer_templates: if true, infer shapes from the ontology graph
:type infer_templates: bool
:param run_shacl_inference: if true, run SHACL inference on the ontology graph
:type run_shacl_inference: bool
:return: the loaded Library
:rtype: "Library"
"""
# get the name of the ontology; this will be the name of the library
# any=False will raise an error if there is more than one ontology defined in the graph
ontology_name = ontology.value(
predicate=rdflib.RDF.type, object=rdflib.OWL.Ontology, any=False
)
) or rdflib.URIRef("urn:unnamed/")

if not overwrite:
if cls._library_exists(ontology_name):
Expand All @@ -248,12 +275,16 @@ def _load_from_ontology(
# expand the ontology graph before we insert it into the database. This will ensure
# that the output of compiled models will not contain triples that really belong to
# the ontology
ontology = shacl_inference(ontology, engine=get_building_motif().shacl_engine)
if run_shacl_inference:
ontology = shacl_inference(
ontology, engine=get_building_motif().shacl_engine
)

lib = cls.create(ontology_name, overwrite=overwrite)

# infer shapes from any class/nodeshape candidates in the graph
lib._infer_shapes_from_graph(ontology)
if infer_templates:
# infer shapes from any class/nodeshape candidates in the graph
lib._infer_templates_from_graph(ontology)

# load the ontology graph as a shape_collection
shape_col_id = lib.get_shape_collection().id
Expand All @@ -263,12 +294,26 @@ def _load_from_ontology(

return lib

def _infer_shapes_from_graph(self, graph: rdflib.Graph):
"""Infer shapes from a graph and add them to this library.
def _infer_templates_from_graph(self, graph: rdflib.Graph):
"""Infer templates from a graph (by interpreting shapes) and add them to this library.

:param graph: graph to infer shapes from
:param graph: graph to infer templates from
:type graph: rdflib.Graph
"""
# add all imports to the same graph so we can resolve everything
imports_closure = copy_graph(graph)
# import dependencies into 'graph'
# get all imports from the graph
for dependency in graph.objects(predicate=rdflib.OWL.imports):
# attempt to load from BuildingMOTIF
try:
lib = Library.load(name=str(dependency))
imports_closure += lib.get_shape_collection().graph
except Exception as e: # TODO: replace with a more specific exception
logging.warning(
f"An ontology could not resolve a dependency on {dependency} ({e}). Check this is loaded into BuildingMOTIF"
)
continue
class_candidates = set(graph.subjects(rdflib.RDF.type, rdflib.OWL.Class))
shape_candidates = set(graph.subjects(rdflib.RDF.type, rdflib.SH.NodeShape))
candidates = class_candidates.intersection(shape_candidates)
Expand All @@ -277,19 +322,30 @@ def _infer_shapes_from_graph(self, graph: rdflib.Graph):
for candidate in candidates:
assert isinstance(candidate, rdflib.URIRef)
# TODO: mincount 0 (or unspecified) should be optional args on the generated template
partial_body, deps = get_template_parts_from_shape(candidate, graph)
partial_body, deps = get_template_parts_from_shape(
candidate, imports_closure
)
templ = self.create_template(str(candidate), partial_body)
dependency_cache[templ.id] = deps
template_id_lookup[str(candidate)] = templ.id

self._resolve_template_dependencies(template_id_lookup, dependency_cache)

def _load_shapes_from_directory(self, directory: pathlib.Path):
def _load_shapes_from_directory(
self,
directory: pathlib.Path,
infer_templates: Optional[bool] = True,
run_shacl_inference: Optional[bool] = True,
):
"""Helper method to read all graphs in the given directory into this
library.

:param directory: directory containing graph files
:type directory: pathlib.Path
:param infer_templates: if true, infer shapes from the ontology graph
:type infer_templates: bool
:param run_shacl_inference: if true, run SHACL inference on the ontology graph
:type run_shacl_inference: bool
"""
shape_col_id = self.get_shape_collection().id
assert shape_col_id is not None # this should always pass
Expand All @@ -302,12 +358,21 @@ def _load_shapes_from_directory(self, directory: pathlib.Path):
f"Could not parse file {filename}: {e}"
)
raise e
if run_shacl_inference:
shape_col.graph = shacl_inference(
shape_col.graph, engine=get_building_motif().shacl_engine
)
# infer shapes from any class/nodeshape candidates in the graph
self._infer_shapes_from_graph(shape_col.graph)
if infer_templates:
self._infer_templates_from_graph(shape_col.graph)

@classmethod
def _load_from_directory(
cls, directory: pathlib.Path, overwrite: Optional[bool] = True
cls,
directory: pathlib.Path,
overwrite: Optional[bool] = True,
infer_templates: Optional[bool] = True,
run_shacl_inference: Optional[bool] = True,
) -> "Library":
"""
Load a library from a directory.
Expand All @@ -319,6 +384,10 @@ def _load_from_directory(
:type directory: pathlib.Path
:param overwrite: if true, overwrite the existing copy of the Library
:type overwrite: bool
:param infer_templates: if true, infer shapes from the ontology graph
:type infer_templates: bool
:param run_shacl_inference: if true, run SHACL inference on the ontology graph
:type run_shacl_inference: bool
:raises e: if cannot create template
:raises e: if cannot resolve dependencies
:return: library
Expand Down Expand Up @@ -416,6 +485,7 @@ def _resolve_dependency(
# check documentation for skip_uri for what URIs get skipped
if skip_uri(dep["template"]):
return

# if the dependency is not in the local cache, then search through this library's imports
# for the template
for imp in self.graph_imports:
Expand Down
5 changes: 4 additions & 1 deletion buildingmotif/dataclasses/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ def validate(
# TODO: do we want to preserve the materialized triples added to data_graph via reasoning?
data_graph = copy_graph(self.graph)

# remove imports from data graph
data_graph.remove((None, OWL.imports, None))

# validate the data graph
valid, report_g, report_str = shacl_validate(
data_graph, shapeg, engine=self._bm.shacl_engine
Expand Down Expand Up @@ -276,7 +279,7 @@ def test_model_against_shapes(
ontology_graph = ontology_graph.skolemize()

valid, report_g, report_str = shacl_validate(
temp_model_graph, ontology_graph
temp_model_graph, ontology_graph, engine=self._bm.shacl_engine
)

results[shape_uri] = ValidationContext(
Expand Down
6 changes: 4 additions & 2 deletions buildingmotif/dataclasses/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from buildingmotif.template_matcher import Mapping, TemplateMatcher
from buildingmotif.utils import (
PARAM,
_strip_param,
combine_graphs,
copy_graph,
remove_triples_with_node,
Expand Down Expand Up @@ -280,17 +281,18 @@ def inline_dependencies(self) -> "Template":
# replace dependency parameters with the names they inherit
# through the provided bindings
rename_params: Dict[str, str] = {
ours: theirs for ours, theirs in dep.args.items()
ours: _strip_param(theirs) for ours, theirs in dep.args.items()
}
# replace all parameters *not* mentioned in the args by prefixing
# them with the 'name' parameter binding; this is guaranteed
# to exist
name_prefix = dep.args.get("name")
name_prefix = _strip_param(dep.args["name"])
# for each parameter in the dependency...
for param in deptempl.parameters:
# if it does *not* have a mapping in the dependency, then
# prefix the parameter with the value of the 'name' binding
# to scope it properly
param = _strip_param(param)
if param not in dep.args and param != "name":
rename_params[param] = f"{name_prefix}-{param}"

Expand Down
1 change: 1 addition & 0 deletions buildingmotif/namespaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

BM = Namespace("https://nrel.gov/BuildingMOTIF#")
CONSTRAINT = Namespace("https://nrel.gov/BuildingMOTIF/constraints#")
S223 = Namespace("http://data.ashrae.org/standard223#")

A = RDF.type

Expand Down
17 changes: 15 additions & 2 deletions buildingmotif/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from dataclasses import dataclass
from itertools import chain
from pathlib import Path
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, Union

import pyshacl # type: ignore
from rdflib import BNode, Graph, Literal, URIRef
Expand All @@ -22,6 +22,16 @@
_gensym_counter = 0


def _strip_param(param: Union[Node, str]) -> str:
"""
Strips all PARAM namespaces from the input parameter
"""
param = str(param)
while param.startswith(PARAM):
param = param[len(PARAM) :]
return param


def _gensym(prefix: str = "p") -> URIRef:
"""
Generate a unique identifier.
Expand Down Expand Up @@ -208,7 +218,9 @@ def get_template_parts_from_shape(
for pshape in pshapes:
property_path = shape_graph.value(pshape, SH["path"])
if property_path is None:
raise Exception(f"no sh:path detected on {shape_name}")
raise Exception(
f"no sh:path detected on {shape_name} property shape {pshape}"
)
# TODO: expand otypes to include sh:in, sh:or, or no datatype at all!
otypes = list(
shape_graph.objects(
Expand Down Expand Up @@ -576,6 +588,7 @@ def shacl_validate(
)
pass

data_graph = data_graph + (shape_graph or Graph())
return pyshacl.validate(
data_graph,
shacl_graph=shape_graph,
Expand Down
Loading
Loading