h5rdmtoolbox 2.7.1__tar.gz → 2.7.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/PKG-INFO +103 -32
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/README.md +102 -31
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/__init__.py +1 -1
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/rdf.py +26 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/user/attributes.py +5 -1
- h5rdmtoolbox-2.7.3/h5rdmtoolbox/ld/user/datasets.py +76 -0
- h5rdmtoolbox-2.7.3/h5rdmtoolbox/ld/user/groups.py +113 -0
- h5rdmtoolbox-2.7.3/h5rdmtoolbox/ld/user/utils.py +53 -0
- h5rdmtoolbox-2.7.3/h5rdmtoolbox/repository/utils.py +199 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/core.py +1 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox.egg-info/PKG-INFO +103 -32
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/pyproject.toml +1 -1
- h5rdmtoolbox-2.7.3/tests/test_readme.py +33 -0
- h5rdmtoolbox-2.7.1/h5rdmtoolbox/ld/user/datasets.py +0 -24
- h5rdmtoolbox-2.7.1/h5rdmtoolbox/ld/user/groups.py +0 -68
- h5rdmtoolbox-2.7.1/h5rdmtoolbox/ld/user/utils.py +0 -33
- h5rdmtoolbox-2.7.1/h5rdmtoolbox/repository/utils.py +0 -144
- h5rdmtoolbox-2.7.1/tests/test_readme.py +0 -22
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/LICENSE +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/_cfg.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/_repr.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/_version.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/_initialization.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/abstracts.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/core.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/profiles.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/query_templates.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/stores/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/stores/hdf5.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/utils.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/cli.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/consts.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/cfg.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/consts.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/core.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/errors.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/generate.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/ontology/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/ontology/h5ontocls.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/ontology/hdf_datatypes.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/references.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/standard_attributes.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/toolbox_validators.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/utils.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/def_icon.png +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/fluid-v1.yml +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/h5tbx.yaml +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/id_icon.png +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/iri_icon.png +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/ld_icon.png +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/piv-v1.yml +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/style.css +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/tutorial_convention.yaml +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/tutorial_convention_vfuncs.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/tutorial_standard_name_table.yaml +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/type_icon.png +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/hdfdb/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/hdfdb/filedb.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/hdfdb/objdb.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/hdfdb/query.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/hdfdb/utils.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/interface.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/lazy.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/mongo.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/errors.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/extensions/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/extensions/magnitude.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/extensions/normalize.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/extensions/onto.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/extensions/units.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/extensions/vector.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/gui/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/gui/fairify.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/gui/src/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/gui/src/main.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/identifiers.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/layout/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/layout/core.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/_types.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/globals.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/hdf/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/hdf/attributes.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/hdf/datasets.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/hdf/file.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/hdf/groups.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/shacl.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/user/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/user/file.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/utils.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/plotting.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/protected_attributes.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/protocols.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/default_metamapper.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/interface.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/zenodo/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/zenodo/core.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/zenodo/metadata.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/zenodo/tokens.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/zenodo/utils.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/tutorial.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/user.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/utils.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/accessor.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/accessors/__init__.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/accessors/provenance.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/ds_decoder.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/h5attr.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/h5ext.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/h5utils.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/h5yaml.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/jsonld.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/xr2hdf.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox.egg-info/SOURCES.txt +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox.egg-info/dependency_links.txt +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox.egg-info/entry_points.txt +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox.egg-info/requires.txt +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox.egg-info/top_level.txt +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/setup.cfg +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_cli.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_config.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_extensions.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_identifiers.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_plotting.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_repr.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_user.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_utils.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_version.py +0 -0
- {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_xarray_export.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: h5rdmtoolbox
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.3
|
|
4
4
|
Summary: Supporting a FAIR Research Data lifecycle using Python and HDF5.
|
|
5
5
|
Author-email: Matthias Probst <matth.probst@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -120,46 +120,117 @@ M4I = rdflib.Namespace("http://w3id.org/nfdi4ing/metadata4ing#")
|
|
|
120
120
|
|
|
121
121
|
# Create a new HDF5 file with FAIR metadata
|
|
122
122
|
with h5tbx.File("example.h5", "w") as h5:
|
|
123
|
-
h5.create_dataset("temperature", data=np.array([20, 21, 19, 22]))
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
ds = h5.create_dataset("temperature", data=np.array([20, 21, 19, 22]))
|
|
124
|
+
ds.attrs["units"] = h5tbx.Attribute(
|
|
125
|
+
value="degree_Celsius",
|
|
126
|
+
rdf_predicate=M4I.hasUnit,
|
|
127
|
+
rdf_object="http://qudt.org/vocab/unit/DEG_C",
|
|
128
|
+
)
|
|
129
|
+
ds.attrs["description", "https://schema.org/description"] = "Room temperature measurements"
|
|
130
|
+
|
|
131
|
+
ds_mean = h5.create_dataset("mean_temperature", data=np.mean(h5["temperature"][()]))
|
|
132
|
+
ds_mean.attrs["units", M4I.hasUnit] = "degree_Celsius"
|
|
133
|
+
ds_mean.rdf["units"].object = "http://qudt.org/vocab/unit/DEG_C"
|
|
134
|
+
ds_mean.attrs["description", "https://schema.org/description"] = "Mean room temperature measurements"
|
|
135
|
+
|
|
136
|
+
ds_mean.rdf.type = M4I.NumericalVariable
|
|
137
|
+
ds_mean.rdf.data_predicate = M4I.hasNumericalValue
|
|
138
|
+
|
|
139
|
+
ttl_ctx = h5.serialize("ttl", structural=False, contextual=True, file_uri="https://example.org#example.h5/")
|
|
140
|
+
ttl_struc = h5.serialize("ttl", structural=True, contextual=False, file_uri="https://example.org#example.h5/")
|
|
141
|
+
ttl_full = h5.serialize("ttl", file_uri="https://example.org#example.h5/")
|
|
142
|
+
```
|
|
127
143
|
|
|
128
|
-
|
|
144
|
+
The above saves three different serializations of the HDF5 content as RDF in Turtle (ttl) format.
|
|
145
|
+
The first one (`ttl_ctx`) is the **contextual** RDF serialization, which only includes the RDF triples that the user
|
|
146
|
+
has enriched the HDF5 file with. The second one (`ttl_struc`) is the **structural** RDF serialization, which includes
|
|
147
|
+
all RDF triples that can be derived from the HDF5 file content. the third one (`ttl_full`) is the combination of the
|
|
148
|
+
first two, which includes both the user enriched RDF triples and the RDF triples that can be derived from the HDF5 file
|
|
149
|
+
content.
|
|
129
150
|
|
|
130
|
-
|
|
131
|
-
|
|
151
|
+
Below we show the first two serializations.
|
|
152
|
+
|
|
153
|
+
`ttl_ctx`:
|
|
132
154
|
```ttl
|
|
133
|
-
@prefix hdf: <http://purl.allotrope.org/ontologies/hdf5/1.8#> .
|
|
134
155
|
@prefix m4i: <http://w3id.org/nfdi4ing/metadata4ing#> .
|
|
135
156
|
@prefix schema: <https://schema.org/> .
|
|
136
157
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
137
158
|
|
|
159
|
+
<https://example.org#example.h5/example.h5/mean_temperature> a m4i:NumericalVariable ;
|
|
160
|
+
m4i:hasNumericalValue "20.5"^^xsd:float ;
|
|
161
|
+
m4i:hasUnit <http://qudt.org/vocab/unit/DEG_C> ;
|
|
162
|
+
schema:description "Mean room temperature measurements" .
|
|
163
|
+
|
|
164
|
+
<https://example.org#example.h5/example.h5/temperature> m4i:hasUnit <http://qudt.org/vocab/unit/DEG_C> ;
|
|
165
|
+
schema:description "Room temperature measurements" .
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`ttl_ctx`:
|
|
169
|
+
```ttl
|
|
170
|
+
@prefix hdf: <http://purl.allotrope.org/ontologies/hdf5/1.8#> .
|
|
171
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
172
|
+
|
|
173
|
+
<https://example.org#example.h5/example.h5> a hdf:File ;
|
|
174
|
+
hdf:rootGroup <https://example.org#example.h5/example.h5/> .
|
|
175
|
+
|
|
176
|
+
hdf:H5T_IEEE_F64LE a hdf:Datatype .
|
|
177
|
+
|
|
138
178
|
hdf:H5T_INTEL_I64 a hdf:Datatype .
|
|
139
179
|
|
|
140
|
-
|
|
141
|
-
hdf:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
180
|
+
<https://example.org#example.h5/example.h5/> a hdf:Group ;
|
|
181
|
+
hdf:member <https://example.org#example.h5/example.h5/mean_temperature>,
|
|
182
|
+
<https://example.org#example.h5/example.h5/temperature> ;
|
|
183
|
+
hdf:name "/" .
|
|
184
|
+
|
|
185
|
+
<https://example.org#example.h5/example.h5/mean_temperature> a hdf:Dataset ;
|
|
186
|
+
hdf:attribute <https://example.org#example.h5/example.h5/mean_temperature@description>,
|
|
187
|
+
<https://example.org#example.h5/example.h5/mean_temperature@units> ;
|
|
188
|
+
hdf:dataspace <https://example.org#example.h5/example.h5/mean_temperature__dataspace> ;
|
|
189
|
+
hdf:datatype hdf:H5T_FLOAT,
|
|
190
|
+
hdf:H5T_IEEE_F64LE ;
|
|
191
|
+
hdf:layout hdf:H5D_CONTIGUOUS ;
|
|
192
|
+
hdf:maximumSize -1 ;
|
|
193
|
+
hdf:name "/mean_temperature" ;
|
|
194
|
+
hdf:rank 0 ;
|
|
195
|
+
hdf:size 1 ;
|
|
196
|
+
hdf:value 2.05e+01 .
|
|
197
|
+
|
|
198
|
+
<https://example.org#example.h5/example.h5/mean_temperature@description> a hdf:StringAttribute ;
|
|
199
|
+
hdf:data "Mean room temperature measurements" ;
|
|
200
|
+
hdf:name "description" .
|
|
201
|
+
|
|
202
|
+
<https://example.org#example.h5/example.h5/mean_temperature@units> a hdf:StringAttribute ;
|
|
203
|
+
hdf:data "degree_Celsius" ;
|
|
204
|
+
hdf:name "units" .
|
|
205
|
+
|
|
206
|
+
<https://example.org#example.h5/example.h5/mean_temperature__dataspace> a hdf:ScalarDataspace .
|
|
207
|
+
|
|
208
|
+
<https://example.org#example.h5/example.h5/temperature> a hdf:Dataset ;
|
|
209
|
+
hdf:attribute <https://example.org#example.h5/example.h5/temperature@description>,
|
|
210
|
+
<https://example.org#example.h5/example.h5/temperature@units> ;
|
|
211
|
+
hdf:dataspace <https://example.org#example.h5/example.h5/temperature__dataspace> ;
|
|
212
|
+
hdf:datatype hdf:H5T_INTEGER,
|
|
213
|
+
hdf:H5T_INTEL_I64 ;
|
|
214
|
+
hdf:layout hdf:H5D_CONTIGUOUS ;
|
|
215
|
+
hdf:maximumSize 4 ;
|
|
216
|
+
hdf:name "/temperature" ;
|
|
217
|
+
hdf:rank 1 ;
|
|
218
|
+
hdf:size 4 .
|
|
219
|
+
|
|
220
|
+
<https://example.org#example.h5/example.h5/temperature@description> a hdf:StringAttribute ;
|
|
221
|
+
hdf:data "Room temperature measurements" ;
|
|
222
|
+
hdf:name "description" .
|
|
223
|
+
|
|
224
|
+
<https://example.org#example.h5/example.h5/temperature@units> a hdf:StringAttribute ;
|
|
225
|
+
hdf:data "degree_Celsius" ;
|
|
226
|
+
hdf:name "units" .
|
|
227
|
+
|
|
228
|
+
<https://example.org#example.h5/example.h5/temperature__dataspace> a hdf:SimpleDataspace ;
|
|
229
|
+
hdf:dimension <https://example.org#example.h5/example.h5/temperature__dataspace_dimension_0> .
|
|
230
|
+
|
|
231
|
+
<https://example.org#example.h5/example.h5/temperature__dataspace_dimension_0> a hdf:DataspaceDimension ;
|
|
232
|
+
hdf:dimensionIndex 0 ;
|
|
233
|
+
hdf:size 4 .
|
|
163
234
|
```
|
|
164
235
|
|
|
165
236
|
[//]: # (The "HDF5 Research Data Management Toolbox" (h5RDMtoolbox) is a Python package supporting everybody who is working with)
|
|
@@ -38,46 +38,117 @@ M4I = rdflib.Namespace("http://w3id.org/nfdi4ing/metadata4ing#")
|
|
|
38
38
|
|
|
39
39
|
# Create a new HDF5 file with FAIR metadata
|
|
40
40
|
with h5tbx.File("example.h5", "w") as h5:
|
|
41
|
-
h5.create_dataset("temperature", data=np.array([20, 21, 19, 22]))
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
ds = h5.create_dataset("temperature", data=np.array([20, 21, 19, 22]))
|
|
42
|
+
ds.attrs["units"] = h5tbx.Attribute(
|
|
43
|
+
value="degree_Celsius",
|
|
44
|
+
rdf_predicate=M4I.hasUnit,
|
|
45
|
+
rdf_object="http://qudt.org/vocab/unit/DEG_C",
|
|
46
|
+
)
|
|
47
|
+
ds.attrs["description", "https://schema.org/description"] = "Room temperature measurements"
|
|
48
|
+
|
|
49
|
+
ds_mean = h5.create_dataset("mean_temperature", data=np.mean(h5["temperature"][()]))
|
|
50
|
+
ds_mean.attrs["units", M4I.hasUnit] = "degree_Celsius"
|
|
51
|
+
ds_mean.rdf["units"].object = "http://qudt.org/vocab/unit/DEG_C"
|
|
52
|
+
ds_mean.attrs["description", "https://schema.org/description"] = "Mean room temperature measurements"
|
|
53
|
+
|
|
54
|
+
ds_mean.rdf.type = M4I.NumericalVariable
|
|
55
|
+
ds_mean.rdf.data_predicate = M4I.hasNumericalValue
|
|
56
|
+
|
|
57
|
+
ttl_ctx = h5.serialize("ttl", structural=False, contextual=True, file_uri="https://example.org#example.h5/")
|
|
58
|
+
ttl_struc = h5.serialize("ttl", structural=True, contextual=False, file_uri="https://example.org#example.h5/")
|
|
59
|
+
ttl_full = h5.serialize("ttl", file_uri="https://example.org#example.h5/")
|
|
60
|
+
```
|
|
45
61
|
|
|
46
|
-
|
|
62
|
+
The above saves three different serializations of the HDF5 content as RDF in Turtle (ttl) format.
|
|
63
|
+
The first one (`ttl_ctx`) is the **contextual** RDF serialization, which only includes the RDF triples that the user
|
|
64
|
+
has enriched the HDF5 file with. The second one (`ttl_struc`) is the **structural** RDF serialization, which includes
|
|
65
|
+
all RDF triples that can be derived from the HDF5 file content. the third one (`ttl_full`) is the combination of the
|
|
66
|
+
first two, which includes both the user enriched RDF triples and the RDF triples that can be derived from the HDF5 file
|
|
67
|
+
content.
|
|
47
68
|
|
|
48
|
-
|
|
49
|
-
|
|
69
|
+
Below we show the first two serializations.
|
|
70
|
+
|
|
71
|
+
`ttl_ctx`:
|
|
50
72
|
```ttl
|
|
51
|
-
@prefix hdf: <http://purl.allotrope.org/ontologies/hdf5/1.8#> .
|
|
52
73
|
@prefix m4i: <http://w3id.org/nfdi4ing/metadata4ing#> .
|
|
53
74
|
@prefix schema: <https://schema.org/> .
|
|
54
75
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
55
76
|
|
|
77
|
+
<https://example.org#example.h5/example.h5/mean_temperature> a m4i:NumericalVariable ;
|
|
78
|
+
m4i:hasNumericalValue "20.5"^^xsd:float ;
|
|
79
|
+
m4i:hasUnit <http://qudt.org/vocab/unit/DEG_C> ;
|
|
80
|
+
schema:description "Mean room temperature measurements" .
|
|
81
|
+
|
|
82
|
+
<https://example.org#example.h5/example.h5/temperature> m4i:hasUnit <http://qudt.org/vocab/unit/DEG_C> ;
|
|
83
|
+
schema:description "Room temperature measurements" .
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`ttl_ctx`:
|
|
87
|
+
```ttl
|
|
88
|
+
@prefix hdf: <http://purl.allotrope.org/ontologies/hdf5/1.8#> .
|
|
89
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
90
|
+
|
|
91
|
+
<https://example.org#example.h5/example.h5> a hdf:File ;
|
|
92
|
+
hdf:rootGroup <https://example.org#example.h5/example.h5/> .
|
|
93
|
+
|
|
94
|
+
hdf:H5T_IEEE_F64LE a hdf:Datatype .
|
|
95
|
+
|
|
56
96
|
hdf:H5T_INTEL_I64 a hdf:Datatype .
|
|
57
97
|
|
|
58
|
-
|
|
59
|
-
hdf:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
98
|
+
<https://example.org#example.h5/example.h5/> a hdf:Group ;
|
|
99
|
+
hdf:member <https://example.org#example.h5/example.h5/mean_temperature>,
|
|
100
|
+
<https://example.org#example.h5/example.h5/temperature> ;
|
|
101
|
+
hdf:name "/" .
|
|
102
|
+
|
|
103
|
+
<https://example.org#example.h5/example.h5/mean_temperature> a hdf:Dataset ;
|
|
104
|
+
hdf:attribute <https://example.org#example.h5/example.h5/mean_temperature@description>,
|
|
105
|
+
<https://example.org#example.h5/example.h5/mean_temperature@units> ;
|
|
106
|
+
hdf:dataspace <https://example.org#example.h5/example.h5/mean_temperature__dataspace> ;
|
|
107
|
+
hdf:datatype hdf:H5T_FLOAT,
|
|
108
|
+
hdf:H5T_IEEE_F64LE ;
|
|
109
|
+
hdf:layout hdf:H5D_CONTIGUOUS ;
|
|
110
|
+
hdf:maximumSize -1 ;
|
|
111
|
+
hdf:name "/mean_temperature" ;
|
|
112
|
+
hdf:rank 0 ;
|
|
113
|
+
hdf:size 1 ;
|
|
114
|
+
hdf:value 2.05e+01 .
|
|
115
|
+
|
|
116
|
+
<https://example.org#example.h5/example.h5/mean_temperature@description> a hdf:StringAttribute ;
|
|
117
|
+
hdf:data "Mean room temperature measurements" ;
|
|
118
|
+
hdf:name "description" .
|
|
119
|
+
|
|
120
|
+
<https://example.org#example.h5/example.h5/mean_temperature@units> a hdf:StringAttribute ;
|
|
121
|
+
hdf:data "degree_Celsius" ;
|
|
122
|
+
hdf:name "units" .
|
|
123
|
+
|
|
124
|
+
<https://example.org#example.h5/example.h5/mean_temperature__dataspace> a hdf:ScalarDataspace .
|
|
125
|
+
|
|
126
|
+
<https://example.org#example.h5/example.h5/temperature> a hdf:Dataset ;
|
|
127
|
+
hdf:attribute <https://example.org#example.h5/example.h5/temperature@description>,
|
|
128
|
+
<https://example.org#example.h5/example.h5/temperature@units> ;
|
|
129
|
+
hdf:dataspace <https://example.org#example.h5/example.h5/temperature__dataspace> ;
|
|
130
|
+
hdf:datatype hdf:H5T_INTEGER,
|
|
131
|
+
hdf:H5T_INTEL_I64 ;
|
|
132
|
+
hdf:layout hdf:H5D_CONTIGUOUS ;
|
|
133
|
+
hdf:maximumSize 4 ;
|
|
134
|
+
hdf:name "/temperature" ;
|
|
135
|
+
hdf:rank 1 ;
|
|
136
|
+
hdf:size 4 .
|
|
137
|
+
|
|
138
|
+
<https://example.org#example.h5/example.h5/temperature@description> a hdf:StringAttribute ;
|
|
139
|
+
hdf:data "Room temperature measurements" ;
|
|
140
|
+
hdf:name "description" .
|
|
141
|
+
|
|
142
|
+
<https://example.org#example.h5/example.h5/temperature@units> a hdf:StringAttribute ;
|
|
143
|
+
hdf:data "degree_Celsius" ;
|
|
144
|
+
hdf:name "units" .
|
|
145
|
+
|
|
146
|
+
<https://example.org#example.h5/example.h5/temperature__dataspace> a hdf:SimpleDataspace ;
|
|
147
|
+
hdf:dimension <https://example.org#example.h5/example.h5/temperature__dataspace_dimension_0> .
|
|
148
|
+
|
|
149
|
+
<https://example.org#example.h5/example.h5/temperature__dataspace_dimension_0> a hdf:DataspaceDimension ;
|
|
150
|
+
hdf:dimensionIndex 0 ;
|
|
151
|
+
hdf:size 4 .
|
|
81
152
|
```
|
|
82
153
|
|
|
83
154
|
[//]: # (The "HDF5 Research Data Management Toolbox" (h5RDMtoolbox) is a Python package supporting everybody who is working with)
|
|
@@ -282,7 +282,7 @@ def serialize(hdf_filename,
|
|
|
282
282
|
skipND: int = 1,
|
|
283
283
|
structural: bool = True,
|
|
284
284
|
contextual: bool = True,
|
|
285
|
-
file_uri: Optional[str] = None,
|
|
285
|
+
file_uri: Optional[Union[str, Dict[str, str]]] = None,
|
|
286
286
|
rdf_mappings: Dict[str, RDFMappingEntry] = None,
|
|
287
287
|
**kwargs):
|
|
288
288
|
"""Alternative to json-ld but allows multiple serialization options"""
|
|
@@ -363,6 +363,12 @@ class _RDFPO(abc.ABC):
|
|
|
363
363
|
def __iter__(self):
|
|
364
364
|
return iter(self.keys())
|
|
365
365
|
|
|
366
|
+
class RDF_Data_Predicate(_RDFPO):
|
|
367
|
+
"""IRI dataset data attribute manager for predicates"""
|
|
368
|
+
IRI_ATTR_NAME = RDF_PREDICATE_ATTR_NAME
|
|
369
|
+
|
|
370
|
+
def __setiri__(self, key, value):
|
|
371
|
+
set_predicate(self._attr, key, value, rdf_predicate_attr_name=RDF_FILE_PREDICATE_ATTR_NAME)
|
|
366
372
|
|
|
367
373
|
class RDF_Predicate(_RDFPO):
|
|
368
374
|
"""IRI class attribute manager"""
|
|
@@ -397,6 +403,7 @@ class RDFManager:
|
|
|
397
403
|
if key not in ('_attr',
|
|
398
404
|
'subject',
|
|
399
405
|
'predicate',
|
|
406
|
+
'data_predicate',
|
|
400
407
|
'file_predicate',
|
|
401
408
|
'type'):
|
|
402
409
|
raise KeyError(f"Cannot set {key}. Only subject, predicate and type can be set!")
|
|
@@ -588,6 +595,25 @@ class RDFManager:
|
|
|
588
595
|
else:
|
|
589
596
|
self._attr[RDF_TYPE_ATTR_NAME] = iri_type_data
|
|
590
597
|
|
|
598
|
+
|
|
599
|
+
@property
|
|
600
|
+
def data_predicate(self) -> RDF_Data_Predicate:
|
|
601
|
+
"""Return the RDF predicate manager"""
|
|
602
|
+
return RDF_Data_Predicate(self._attr)
|
|
603
|
+
|
|
604
|
+
@data_predicate.setter
|
|
605
|
+
def data_predicate(self, data_predicate) -> RDF_Predicate:
|
|
606
|
+
"""Sets the predicate associated with the dataset data. This is useful for JSON-LD export, where the dataset data is represented as a value of a predicate."""
|
|
607
|
+
if not isinstance(data_predicate, str):
|
|
608
|
+
raise TypeError(f'Expecting a string or URL. Got {type(data_predicate)}. Note, that a predicate of '
|
|
609
|
+
'a group or dataset can only be one value. If you meant to set one or multiple RDF types, '
|
|
610
|
+
'use .type instead.')
|
|
611
|
+
iri_predicate_data = self._attr.get(RDF_PREDICATE_ATTR_NAME, None)
|
|
612
|
+
if iri_predicate_data is None:
|
|
613
|
+
iri_predicate_data = {}
|
|
614
|
+
iri_predicate_data.update({'DATA_PREDICATE': data_predicate})
|
|
615
|
+
self._attr[RDF_PREDICATE_ATTR_NAME] = iri_predicate_data
|
|
616
|
+
|
|
591
617
|
@property
|
|
592
618
|
def predicate(self) -> RDF_Predicate:
|
|
593
619
|
"""Return the RDF predicate manager"""
|
|
@@ -155,11 +155,15 @@ def process_attribute(parent_obj, name, data, graph, blank_node_iri_base):
|
|
|
155
155
|
rdf_manager = RDFManager(parent_obj.attrs)
|
|
156
156
|
|
|
157
157
|
parent_uri = rdf_manager.subject
|
|
158
|
+
rdf_user_type = rdf_manager.type
|
|
158
159
|
if parent_uri:
|
|
159
160
|
parent_uri = to_uriref(parent_uri, blank_node_iri_base)
|
|
160
161
|
else:
|
|
162
|
+
# if rdf_user_type:
|
|
163
|
+
# parent_uri = get_obj_bnode(parent_obj, blank_node_iri_base=blank_node_iri_base)
|
|
164
|
+
# else:
|
|
161
165
|
parent_uri = get_obj_bnode(parent_obj, blank_node_iri_base)
|
|
162
|
-
|
|
166
|
+
|
|
163
167
|
if rdf_user_type is not None:
|
|
164
168
|
if isinstance(rdf_user_type, (list, np.ndarray)):
|
|
165
169
|
for t in rdf_user_type:
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import warnings
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
import rdflib
|
|
6
|
+
from ontolutils.namespacelib import SCHEMA
|
|
7
|
+
|
|
8
|
+
from h5rdmtoolbox.ld.rdf import PROTECTED_ATTRIBUTE_NAMES
|
|
9
|
+
from h5rdmtoolbox.ld.user.attributes import process_attribute
|
|
10
|
+
from h5rdmtoolbox.ld.utils import get_obj_bnode, to_literal
|
|
11
|
+
from .utils import apply_rdf_mappings, to_uriref
|
|
12
|
+
from ..rdf import RDFManager
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def process_dataset(*, dataset, graph, rdf_mappings, blank_node_iri_base=None):
|
|
16
|
+
dataset_uri = get_obj_bnode(dataset, blank_node_iri_base=blank_node_iri_base)
|
|
17
|
+
for ak, av in dataset.attrs.items():
|
|
18
|
+
if ak not in PROTECTED_ATTRIBUTE_NAMES:
|
|
19
|
+
process_attribute(dataset, ak, av, graph, blank_node_iri_base=blank_node_iri_base)
|
|
20
|
+
apply_rdf_mappings(dataset, dataset_uri, graph, rdf_mappings)
|
|
21
|
+
|
|
22
|
+
rdf_manager = RDFManager(dataset.attrs)
|
|
23
|
+
rdf_type = rdf_manager.type
|
|
24
|
+
if rdf_type is not None:
|
|
25
|
+
if isinstance(rdf_type, (list, np.ndarray)):
|
|
26
|
+
for t in rdf_type:
|
|
27
|
+
graph.add((dataset_uri, rdflib.RDF.type, rdflib.URIRef(t)))
|
|
28
|
+
else:
|
|
29
|
+
graph.add((dataset_uri, rdflib.RDF.type, rdflib.URIRef(rdf_type)))
|
|
30
|
+
|
|
31
|
+
rdf_subject = rdf_manager.subject
|
|
32
|
+
if rdf_subject:
|
|
33
|
+
if dataset_uri != rdflib.URIRef(rdf_subject):
|
|
34
|
+
graph.add((dataset_uri, SCHEMA.about, rdflib.URIRef(rdf_subject)))
|
|
35
|
+
|
|
36
|
+
rdf_predicate = rdf_manager.predicate
|
|
37
|
+
if rdf_predicate:
|
|
38
|
+
_predicates = dataset.attrs.get("RDF_PREDICATE", None)
|
|
39
|
+
if _predicates:
|
|
40
|
+
_predicate_dict = json.loads(_predicates)
|
|
41
|
+
self_predicate = _predicate_dict.get("SELF", None)
|
|
42
|
+
data_predicate = _predicate_dict.get("DATA_PREDICATE", None)
|
|
43
|
+
|
|
44
|
+
if data_predicate:
|
|
45
|
+
if dataset.ndim > 0:
|
|
46
|
+
warnings.warn(f"DATA_PREDICATE is not applicable to datasets with more than 0 dimensions. Ignoring DATA_PREDICATE for dataset {dataset.name}")
|
|
47
|
+
graph.add((dataset_uri, to_uriref(data_predicate, blank_node_iri_base), to_literal(dataset[()])))
|
|
48
|
+
|
|
49
|
+
if self_predicate:
|
|
50
|
+
parent_uri = get_obj_bnode(dataset.parent, blank_node_iri_base=blank_node_iri_base)
|
|
51
|
+
|
|
52
|
+
_parent_subject = RDFManager(dataset.parent.attrs).subject
|
|
53
|
+
|
|
54
|
+
if _parent_subject:
|
|
55
|
+
if rdf_subject:
|
|
56
|
+
graph.add(
|
|
57
|
+
(rdflib.URIRef(_parent_subject), rdflib.URIRef(self_predicate), rdflib.URIRef(rdf_subject)))
|
|
58
|
+
else:
|
|
59
|
+
graph.add((rdflib.URIRef(_parent_subject), rdflib.URIRef(self_predicate), dataset_uri))
|
|
60
|
+
else:
|
|
61
|
+
if rdf_subject:
|
|
62
|
+
graph.add((parent_uri, rdflib.URIRef(self_predicate), rdflib.URIRef(rdf_subject)))
|
|
63
|
+
else:
|
|
64
|
+
parent_rdf_manager = RDFManager(dataset.parent.attrs)
|
|
65
|
+
_parent_type = parent_rdf_manager.type
|
|
66
|
+
if _parent_type:
|
|
67
|
+
_parent_subject_alternative = get_obj_bnode(dataset.parent, blank_node_iri_base=blank_node_iri_base)
|
|
68
|
+
|
|
69
|
+
dataset_uri_alternative = get_obj_bnode(dataset, blank_node_iri_base=blank_node_iri_base)
|
|
70
|
+
graph.add((_parent_subject_alternative,
|
|
71
|
+
rdflib.URIRef(self_predicate),
|
|
72
|
+
dataset_uri_alternative))
|
|
73
|
+
# graph.add((_parent_subject_alternative, rdflib.URIRef(self_predicate),
|
|
74
|
+
# dataset_uri))
|
|
75
|
+
else:
|
|
76
|
+
graph.add((parent_uri, rdflib.URIRef(self_predicate), dataset_uri))
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
import h5py
|
|
4
|
+
import numpy as np
|
|
5
|
+
import rdflib
|
|
6
|
+
from ontolutils.namespacelib import SCHEMA
|
|
7
|
+
|
|
8
|
+
from h5rdmtoolbox.ld.rdf import PROTECTED_ATTRIBUTE_NAMES
|
|
9
|
+
from h5rdmtoolbox.ld.user.attributes import process_attribute
|
|
10
|
+
from h5rdmtoolbox.ld.user.datasets import process_dataset
|
|
11
|
+
from h5rdmtoolbox.ld.utils import get_obj_bnode, get_file_bnode
|
|
12
|
+
from .utils import apply_rdf_mappings, to_uriref
|
|
13
|
+
from ..rdf import RDFManager
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def process_group(*, group, graph, rdf_mappings, blank_node_iri_base: Optional[str] = None):
|
|
17
|
+
group_uri = get_obj_bnode(group, blank_node_iri_base)
|
|
18
|
+
|
|
19
|
+
for ak, av in group.attrs.items():
|
|
20
|
+
if ak not in PROTECTED_ATTRIBUTE_NAMES:
|
|
21
|
+
process_attribute(group, ak, av, graph, blank_node_iri_base)
|
|
22
|
+
apply_rdf_mappings(group, group_uri, graph, rdf_mappings)
|
|
23
|
+
|
|
24
|
+
rdf_manager = RDFManager(group.attrs)
|
|
25
|
+
|
|
26
|
+
parent_rdf_manager = RDFManager(group.parent.attrs) if group.parent is not None else None
|
|
27
|
+
rdf_type = rdf_manager.type
|
|
28
|
+
rdf_subject = rdf_manager.subject
|
|
29
|
+
|
|
30
|
+
# if rdf_predicate:
|
|
31
|
+
# _predicates = group.attrs.get("RDF_PREDICATE", None)
|
|
32
|
+
# if _predicates:
|
|
33
|
+
# self_predicate = json.loads(_predicates).get("SELF", None)
|
|
34
|
+
# if self_predicate:
|
|
35
|
+
# parent_uri = get_obj_bnode(group.parent, blank_node_iri_base=blank_node_iri_base)
|
|
36
|
+
# _parent_subject = RDFManager(group.parent.attrs).subject
|
|
37
|
+
#
|
|
38
|
+
# if _parent_subject:
|
|
39
|
+
# if rdf_subject:
|
|
40
|
+
# graph.add((rdflib.URIRef(_parent_subject), rdflib.URIRef(self_predicate), rdflib.URIRef(rdf_subject)))
|
|
41
|
+
# else:
|
|
42
|
+
# graph.add((rdflib.URIRef(_parent_subject), rdflib.URIRef(self_predicate), group_uri))
|
|
43
|
+
# else:
|
|
44
|
+
# if rdf_subject:
|
|
45
|
+
# graph.add((parent_uri, rdflib.URIRef(self_predicate), rdflib.URIRef(rdf_subject)))
|
|
46
|
+
# else:
|
|
47
|
+
# graph.add((parent_uri, rdflib.URIRef(self_predicate), group_uri))
|
|
48
|
+
|
|
49
|
+
if rdf_type is not None and not rdf_subject:
|
|
50
|
+
rdf_subject = get_obj_bnode(group, blank_node_iri_base=blank_node_iri_base)
|
|
51
|
+
|
|
52
|
+
if rdf_type is not None:
|
|
53
|
+
if rdf_subject:
|
|
54
|
+
if isinstance(rdf_type, (list, np.ndarray)):
|
|
55
|
+
for t in rdf_type:
|
|
56
|
+
graph.add((to_uriref(rdf_subject, blank_node_iri_base), rdflib.RDF.type, to_uriref(t, blank_node_iri_base)))
|
|
57
|
+
else:
|
|
58
|
+
graph.add((to_uriref(rdf_subject, blank_node_iri_base), rdflib.RDF.type, to_uriref(rdf_type, blank_node_iri_base)))
|
|
59
|
+
else:
|
|
60
|
+
if isinstance(rdf_type, (list, np.ndarray)):
|
|
61
|
+
for t in rdf_type:
|
|
62
|
+
graph.add((group_uri, rdflib.RDF.type, to_uriref(t, blank_node_iri_base)))
|
|
63
|
+
else:
|
|
64
|
+
graph.add((group_uri, rdflib.RDF.type, to_uriref(rdf_type, blank_node_iri_base)))
|
|
65
|
+
|
|
66
|
+
if rdf_subject:
|
|
67
|
+
rdf_subject = to_uriref(rdf_subject, blank_node_iri_base)
|
|
68
|
+
if group_uri != rdf_subject:
|
|
69
|
+
graph.add((group_uri, SCHEMA.about, rdf_subject))
|
|
70
|
+
rdf_predicate = rdf_manager.predicate
|
|
71
|
+
if rdf_predicate.get("SELF", None):
|
|
72
|
+
# graph.add((group_uri, rdflib.URIRef(rdf_predicate["SELF"]), rdf_subject))
|
|
73
|
+
if parent_rdf_manager.subject is not None:
|
|
74
|
+
_parent_subject = to_uriref(parent_rdf_manager.subject)
|
|
75
|
+
else:
|
|
76
|
+
_parent_type = parent_rdf_manager.type
|
|
77
|
+
# if _parent_type is None:
|
|
78
|
+
# _parent_subject = None
|
|
79
|
+
# else:
|
|
80
|
+
_parent_subject = get_obj_bnode(group.parent, blank_node_iri_base=blank_node_iri_base)
|
|
81
|
+
if _parent_subject is not None:
|
|
82
|
+
graph.add(
|
|
83
|
+
(
|
|
84
|
+
_parent_subject,
|
|
85
|
+
rdflib.URIRef(rdf_predicate["SELF"]),
|
|
86
|
+
rdf_subject
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
rdf_file_predicate = rdf_manager.file_predicate
|
|
91
|
+
if rdf_file_predicate is not None:
|
|
92
|
+
file_uri = get_file_bnode(group.file, blank_node_iri_base)
|
|
93
|
+
graph.add(
|
|
94
|
+
(
|
|
95
|
+
file_uri,
|
|
96
|
+
rdflib.URIRef(rdf_file_predicate),
|
|
97
|
+
rdf_subject
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Iterate through items in the group
|
|
102
|
+
for name, sub_group_or_dataset in group.items():
|
|
103
|
+
|
|
104
|
+
# sub_group_or_dataset_uri = rdflib.BNode(sub_group_or_dataset.id.id)
|
|
105
|
+
# graph.add((group_uri, HDF.member, sub_group_or_dataset_uri))
|
|
106
|
+
|
|
107
|
+
if isinstance(sub_group_or_dataset, h5py.Group):
|
|
108
|
+
process_group(group=sub_group_or_dataset, graph=graph, rdf_mappings=rdf_mappings,
|
|
109
|
+
blank_node_iri_base=blank_node_iri_base)
|
|
110
|
+
|
|
111
|
+
elif isinstance(sub_group_or_dataset, h5py.Dataset):
|
|
112
|
+
process_dataset(dataset=sub_group_or_dataset, graph=graph, rdf_mappings=rdf_mappings,
|
|
113
|
+
blank_node_iri_base=blank_node_iri_base)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
from typing import Union
|
|
3
|
+
|
|
4
|
+
import rdflib
|
|
5
|
+
|
|
6
|
+
from h5rdmtoolbox.ld.rdf import PROTECTED_ATTRIBUTE_NAMES
|
|
7
|
+
from ..utils import to_literal
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# def get_obj_bnode(s: str, bits: int = 64, blank_node_iri_base=None) -> rdflib.URIRef:
|
|
11
|
+
# """Create a deterministic blank node from a string."""
|
|
12
|
+
# digest = hashlib.sha256(s.encode("utf-8")).digest()
|
|
13
|
+
# number = int.from_bytes(digest[:bits // 8], "big")
|
|
14
|
+
# return to_uriref(f"_:{str(number)}", blank_node_iri_base)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def to_uriref(value: str, blank_node_iri_base: str = None) -> Union[rdflib.URIRef, rdflib.BNode]:
|
|
18
|
+
"""Convert a value to a URIRef, handling blank nodes if necessary."""
|
|
19
|
+
if isinstance(value, rdflib.BNode):
|
|
20
|
+
if blank_node_iri_base is not None:
|
|
21
|
+
return rdflib.URIRef(blank_node_iri_base + str(value))
|
|
22
|
+
return value
|
|
23
|
+
if isinstance(value, rdflib.URIRef):
|
|
24
|
+
return value
|
|
25
|
+
if value.startswith("_:"):
|
|
26
|
+
if blank_node_iri_base is not None:
|
|
27
|
+
value = blank_node_iri_base + value[2:]
|
|
28
|
+
return rdflib.URIRef(value)
|
|
29
|
+
return rdflib.BNode(value[2:])
|
|
30
|
+
if value.startswith("http://") or value.startswith("https://") or value.startswith("urn:"):
|
|
31
|
+
return rdflib.URIRef(value)
|
|
32
|
+
raise ValueError(f"Cannot convert value '{value}' to URIRef")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def apply_rdf_mappings(obj, obj_uri, graph, rdf_mappings):
|
|
36
|
+
for ak, av in obj.attrs.items():
|
|
37
|
+
if ak not in PROTECTED_ATTRIBUTE_NAMES:
|
|
38
|
+
if ak in rdf_mappings:
|
|
39
|
+
mapping = rdf_mappings[ak]
|
|
40
|
+
predicate_uri = rdflib.URIRef(mapping['predicate'])
|
|
41
|
+
if predicate_uri:
|
|
42
|
+
object_uri = mapping.get('object')
|
|
43
|
+
if object_uri:
|
|
44
|
+
if callable(object_uri):
|
|
45
|
+
object_uri = str(object_uri(av, obj.attrs))
|
|
46
|
+
if object_uri is None:
|
|
47
|
+
return
|
|
48
|
+
graph.add((obj_uri, predicate_uri, rdflib.URIRef(object_uri)))
|
|
49
|
+
else:
|
|
50
|
+
graph.add((obj_uri, predicate_uri, to_literal(av)))
|
|
51
|
+
type_uri = mapping.get('type')
|
|
52
|
+
if type_uri:
|
|
53
|
+
graph.add((obj_uri, rdflib.RDF.type, rdflib.URIRef(type_uri)))
|