Skip to content

Commit 0c2ca6e

Browse files
improve semantic serialization
1 parent a3ae45b commit 0c2ca6e

32 files changed

+919
-553
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
Log of changes in the versions
44

5+
## v2.2.0
6+
7+
- use fragments in internal HDF5 URIs to align with semantic web standards (fragments are not resolved in the web
8+
interface, but are used to identify the HDF5 object in the file)
9+
- housekeeping
10+
511
## v2.1.0
612

713
- upgrade setuptools due to cve and therefore limit minimum python version to 3.9

CITATION.cff

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ authors:
1111
given-names: "Lucas"
1212
orcid: "https://orcid.org/0000-0002-4116-0065"
1313
title: "h5rdmtoolbox - HDF5 Research Data Management Toolbox"
14-
version: 2.1.0
15-
doi: 10.5281/zenodo.15600840
16-
date-released: 2025-06-05
14+
version: 2.2.0
15+
doi: 10.5281/zenodo.16686040
16+
date-released: 2025-08-01
1717
url: "https://github.com/matthiasprobst/h5rdmtoolbox"

PLANNED_CHANGES.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
# Planned changes
22

3-
## v1.8.0
43

5-
- remove `skipND` and replace with `serialize_0d_datasets`, which only supports serialization of 0D datasets
4+
## v3.0.0
5+
66
- remove `resolve_keys` from `dump_jsonld()` and `serialize()`
77
- remove `semantic` from `dump_jsonld()` and `serialize()`
8-
9-
## v2.0.0
10-
118
- remove `dump_jsonld()` and only use `serialize()`

codemeta.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"license": "https://spdx.org/licenses/MIT",
55
"codeRepository": "git+https://github.com/matthiasprobst/h5RDMtoolbox.git",
66
"name": "h5RDMtoolbox",
7-
"version": "2.1.0",
7+
"version": "2.2.0",
88
"description": "Supporting a FAIR Research Data lifecycle using Python and HDF5.",
99
"applicationCategory": "Engineering",
1010
"programmingLanguage": [
-18.6 KB
Loading
-1.8 KB
Loading

docs/colab/quickstart.ipynb

Lines changed: 226 additions & 82 deletions
Large diffs are not rendered by default.

docs/practical_examples/knowledge_graph.ipynb

Lines changed: 109 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"outputs": [],
3131
"source": [
3232
"import kglab\n",
33-
"import rdflib"
33+
"import rdflib\n",
34+
"import numpy as np"
3435
]
3536
},
3637
{
@@ -55,55 +56,113 @@
5556
"name": "stdout",
5657
"output_type": "stream",
5758
"text": [
58-
"{\n",
59-
" \"@context\": {\n",
60-
" \"foaf\": \"http://xmlns.com/foaf/0.1/\",\n",
61-
" \"hdf\": \"http://purl.allotrope.org/ontologies/hdf5/1.8#\",\n",
62-
" \"prov\": \"http://www.w3.org/ns/prov#\",\n",
63-
" \"rdf\": \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n",
64-
" },\n",
65-
" \"@graph\": [\n",
66-
" {\n",
67-
" \"@id\": \"_:69ad64a678055ecde7601c70b432cdd3\",\n",
68-
" \"@type\": \"hdf:File\"\n",
69-
" },\n",
70-
" {\n",
71-
" \"@id\": \"hdf:scalarDataspace\",\n",
72-
" \"@type\": \"hdf:scalarDataspace\"\n",
73-
" },\n",
74-
" {\n",
75-
" \"@id\": \"hdf:H5T_IEEE_F64LE\",\n",
76-
" \"@type\": \"hdf:Datatype\"\n",
77-
" },\n",
78-
" {\n",
79-
" \"@id\": \"_:03e43b66f42e2e7f00f2288985db2abf\",\n",
80-
" \"@type\": \"prov:Person\",\n",
81-
" \"foaf:firstName\": \"Matthias\",\n",
82-
" \"foaf:lastName\": \"Probst\"\n",
83-
" },\n",
84-
" {\n",
85-
" \"@id\": \"https://orcid.org/0000-0001-8729-0482\",\n",
86-
" \"@type\": \"prov:Person\"\n",
87-
" }\n",
88-
" ]\n",
89-
"}\n"
59+
"@prefix dcterms: <http://purl.org/dc/terms/> .\n",
60+
"@prefix ex: <https://example.org#> .\n",
61+
"@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n",
62+
"@prefix hdf: <http://purl.allotrope.org/ontologies/hdf5/1.8#> .\n",
63+
"@prefix prov: <http://www.w3.org/ns/prov#> .\n",
64+
"@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n",
65+
"\n",
66+
"ex:tmp0.hdf a hdf:File ;\n",
67+
" hdf:rootGroup <https://example.org#tmp0.hdf/> .\n",
68+
"\n",
69+
"<https://example.org#tmp0.hdf/> a hdf:Group ;\n",
70+
" hdf:member <https://example.org#tmp0.hdf/contact>,\n",
71+
" <https://example.org#tmp0.hdf/nd-array>,\n",
72+
" <https://example.org#tmp0.hdf/test> ;\n",
73+
" hdf:name \"/\"^^xsd:string .\n",
74+
"\n",
75+
"<https://example.org#tmp0.hdf/contact> a hdf:Group ;\n",
76+
" hdf:attribute <https://example.org#tmp0.hdf/contact@fname>,\n",
77+
" <https://example.org#tmp0.hdf/contact@hint>,\n",
78+
" <https://example.org#tmp0.hdf/contact@lname> ;\n",
79+
" hdf:name \"/contact\"^^xsd:string ;\n",
80+
" dcterms:relation <https://orcid.org/0000-0001-8729-0482> .\n",
81+
"\n",
82+
"<https://example.org#tmp0.hdf/contact@fname> a hdf:StringAttribute ;\n",
83+
" hdf:data \"Matthias\"^^xsd:string ;\n",
84+
" hdf:name \"fname\" .\n",
85+
"\n",
86+
"<https://example.org#tmp0.hdf/contact@hint> a hdf:StringAttribute ;\n",
87+
" hdf:data \"This group could be representing a person.\"^^xsd:string ;\n",
88+
" hdf:name \"hint\" .\n",
89+
"\n",
90+
"<https://example.org#tmp0.hdf/contact@lname> a hdf:StringAttribute ;\n",
91+
" hdf:data \"Probst\"^^xsd:string ;\n",
92+
" hdf:name \"lname\" .\n",
93+
"\n",
94+
"<https://example.org#tmp0.hdf/nd-array> a hdf:Dataset ;\n",
95+
" hdf:chunk <https://example.org#tmp0.hdf/nd-array__chunk_dimensions> ;\n",
96+
" hdf:dataspace <https://example.org#tmp0.hdf/nd-array__dataspace> ;\n",
97+
" hdf:datatype hdf:H5T_IEEE_F64LE,\n",
98+
" \"H5T_FLOAT\" ;\n",
99+
" hdf:layout hdf:H5D_CHUNKED ;\n",
100+
" hdf:maximumSize 6 ;\n",
101+
" hdf:name \"/nd-array\" ;\n",
102+
" hdf:rank 2 ;\n",
103+
" hdf:size 6 .\n",
104+
"\n",
105+
"<https://example.org#tmp0.hdf/nd-array__chunk_dimension_0> a hdf:DataspaceDimension ;\n",
106+
" hdf:dimensionIndex 0 ;\n",
107+
" hdf:size 1 .\n",
108+
"\n",
109+
"<https://example.org#tmp0.hdf/nd-array__chunk_dimension_1> a hdf:DataspaceDimension ;\n",
110+
" hdf:dimensionIndex 1 ;\n",
111+
" hdf:size 3 .\n",
112+
"\n",
113+
"<https://example.org#tmp0.hdf/nd-array__chunk_dimensions> a hdf:ChunkDimension ;\n",
114+
" hdf:dimension <https://example.org#tmp0.hdf/nd-array__chunk_dimension_0>,\n",
115+
" <https://example.org#tmp0.hdf/nd-array__chunk_dimension_1> .\n",
116+
"\n",
117+
"<https://example.org#tmp0.hdf/nd-array__dataspace> a hdf:SimpleDataspace ;\n",
118+
" hdf:dimension <https://example.org#tmp0.hdf/nd-array__dataspace_dimension_0>,\n",
119+
" <https://example.org#tmp0.hdf/nd-array__dataspace_dimension_1> .\n",
120+
"\n",
121+
"<https://example.org#tmp0.hdf/nd-array__dataspace_dimension_0> a hdf:DataspaceDimension ;\n",
122+
" hdf:dimensionIndex 0 ;\n",
123+
" hdf:size 2 .\n",
124+
"\n",
125+
"<https://example.org#tmp0.hdf/nd-array__dataspace_dimension_1> a hdf:DataspaceDimension ;\n",
126+
" hdf:dimensionIndex 1 ;\n",
127+
" hdf:size 3 .\n",
128+
"\n",
129+
"<https://example.org#tmp0.hdf/test> a hdf:Dataset ;\n",
130+
" hdf:dataspace <https://example.org#tmp0.hdf/test__dataspace> ;\n",
131+
" hdf:datatype hdf:H5T_IEEE_F64LE,\n",
132+
" \"H5T_FLOAT\" ;\n",
133+
" hdf:layout hdf:H5D_CONTIGUOUS ;\n",
134+
" hdf:maximumSize -1 ;\n",
135+
" hdf:name \"/test\" ;\n",
136+
" hdf:rank 0 ;\n",
137+
" hdf:size 1 ;\n",
138+
" hdf:value 4.3e+00 .\n",
139+
"\n",
140+
"<https://example.org#tmp0.hdf/test__dataspace> a hdf:ScalarDataspace .\n",
141+
"\n",
142+
"<https://orcid.org/0000-0001-8729-0482> a prov:Person ;\n",
143+
" foaf:firstName \"Matthias\"^^xsd:string ;\n",
144+
" foaf:lastName \"Probst\"^^xsd:string .\n",
145+
"\n",
146+
"hdf:H5T_IEEE_F64LE a hdf:Datatype .\n",
147+
"\n",
148+
"\n"
90149
]
91150
}
92151
],
93152
"source": [
94153
"with h5tbx.File() as h5:\n",
95154
" h5.create_dataset(name='test', data=4.3)\n",
155+
" h5.create_dataset(name='nd-array', data=np.random.rand(2, 3), chunks=(1,3))\n",
96156
" grp = h5.create_group(name='contact')\n",
97157
" grp.attrs['fname', rdflib.FOAF.firstName] = 'Matthias'\n",
98158
" grp.attrs['lname', rdflib.FOAF.lastName] = 'Probst'\n",
99159
" grp.attrs['hint'] = 'This group could be representing a person.'\n",
100160
" grp.rdf['hint'].definition = 'A hint gives helpful information on something.'\n",
101161
" grp.rdf.type = rdflib.PROV.Person # --> rdf.type = Person\n",
102162
" grp.rdf.subject = 'https://orcid.org/0000-0001-8729-0482' # -> @id='https://orcid.org/0000-0001-8729-0482'\n",
103-
"\n",
104-
" print(h5.dump_jsonld(indent=2, structural=True, resolve_keys=True))\n",
105163
" \n",
106-
"graph = h5tbx.get_ld(h5.hdf_filename)"
164+
"graph = h5tbx.get_ld(h5.hdf_filename, structural=True, file_uri=\"https://example.org#\", context={\"ex\": \"https://example.org#\"})\n",
165+
"print(graph.serialize())"
107166
]
108167
},
109168
{
@@ -113,9 +172,10 @@
113172
"metadata": {},
114173
"outputs": [],
115174
"source": [
175+
"namespaces = {k: str(v) for k, v in dict(graph.namespaces()).items()}\n",
116176
"kg = kglab.KnowledgeGraph(\n",
117177
" import_graph=graph,\n",
118-
" namespaces={k: str(v) for k, v in dict(graph.namespaces()).items()})"
178+
" namespaces=namespaces)"
119179
]
120180
},
121181
{
@@ -182,19 +242,21 @@
182242
"text": [
183243
"{\n",
184244
" \"@context\": {\n",
245+
" \"dcterms\": \"http://purl.org/dc/terms/\",\n",
185246
" \"foaf\": \"http://xmlns.com/foaf/0.1/\",\n",
186-
" \"hdf\": \"http://purl.allotrope.org/ontologies/hdf5/1.8#\",\n",
187-
" \"rdf\": \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n",
247+
" \"prov\": \"http://www.w3.org/ns/prov#\"\n",
188248
" },\n",
189249
" \"@graph\": [\n",
190250
" {\n",
191-
" \"@id\": \"_:af3b30750dbfd021eb8843274633ba46\",\n",
192-
" \"@type\": \"hdf:File\"\n",
193-
" },\n",
194-
" {\n",
195-
" \"@id\": \"_:33501378e9a891ca7b7655ee472f25b4\",\n",
251+
" \"@id\": \"prov:Person\",\n",
196252
" \"foaf:firstName\": \"Matthias\",\n",
197253
" \"foaf:lastName\": \"Probst\"\n",
254+
" },\n",
255+
" {\n",
256+
" \"@id\": \"https://example.org#tmp1.hdf/contact\",\n",
257+
" \"dcterms:relation\": {\n",
258+
" \"@id\": \"prov:Person\"\n",
259+
" }\n",
198260
" }\n",
199261
" ]\n",
200262
"}\n"
@@ -211,9 +273,9 @@
211273
" grp.rdf['hint'].definition = 'A hint'\n",
212274
" grp.rdf.subject = rdflib.PROV.Person\n",
213275
" grp.attrs['@id'] = 'https://orcid.org/0000-0001-8729-0482'\n",
214-
" print(h5.dump_jsonld(indent=2, structural=False))\n",
276+
" print(h5.dump_jsonld(indent=2, structural=False, file_uri=\"https://example.org#\"))\n",
215277
"\n",
216-
"graph = h5tbx.get_ld(h5.hdf_filename, structural=False, use_simple_bnode_value=True)"
278+
"graph = h5tbx.get_ld(h5.hdf_filename, structural=False, file_uri=\"https://example.org#\")"
217279
]
218280
},
219281
{
@@ -291,7 +353,7 @@
291353
"name": "python",
292354
"nbconvert_exporter": "python",
293355
"pygments_lexer": "ipython3",
294-
"version": "3.10.12"
356+
"version": "3.10.18"
295357
}
296358
},
297359
"nbformat": 4,

docs/practical_examples/tmp.grpah.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ <h1></h1>
8888

8989

9090
// parsing and collecting nodes and edges from the python
91-
nodes = new vis.DataSet([{"color": "black", "id": 0, "label": "_:na2e7d0a818084743bae90da894fc6b22b2", "shape": "dot", "size": 20, "title": "_:na2e7d0a818084743bae90da894fc6b22b2"}, {"color": "red", "id": 1, "label": "hdf:File", "shape": "dot", "size": 30, "title": "hdf:File"}, {"color": "black", "id": 2, "label": "_:na2e7d0a818084743bae90da894fc6b22b1", "shape": "dot", "size": 20, "title": "_:na2e7d0a818084743bae90da894fc6b22b1"}, {"color": "#97c2fc", "id": 3, "label": "Matthias", "shape": "dot", "title": "Matthias"}, {"color": "#97c2fc", "id": 4, "label": "Probst", "shape": "dot", "title": "Probst"}]);
92-
edges = new vis.DataSet([{"from": 0, "label": "rdf:type", "to": 1}, {"from": 2, "label": "foaf:firstName", "to": 3}, {"from": 2, "label": "foaf:lastName", "to": 4}]);
91+
nodes = new vis.DataSet([{"color": "#97c2fc", "id": 0, "label": "prov:Person", "shape": "dot", "title": "prov:Person"}, {"color": "#97c2fc", "id": 1, "label": "Probst", "shape": "dot", "title": "Probst"}, {"color": "#97c2fc", "id": 2, "label": "Matthias", "shape": "dot", "title": "Matthias"}, {"color": "#97c2fc", "id": 3, "label": "\u003chttps://example.org#tmp3.hdf/contact\u003e", "shape": "dot", "title": "\u003chttps://example.org#tmp3.hdf/contact\u003e"}]);
92+
edges = new vis.DataSet([{"from": 0, "label": "foaf:lastName", "to": 1}, {"from": 0, "label": "foaf:firstName", "to": 2}, {"from": 3, "label": "dcterms:relation", "to": 0}]);
9393

9494
nodeColors = {};
9595
allNodes = nodes.get({ returnType: "Object" });

0 commit comments

Comments
 (0)