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.
Files changed (134) hide show
  1. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/PKG-INFO +103 -32
  2. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/README.md +102 -31
  3. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/__init__.py +1 -1
  4. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/rdf.py +26 -0
  5. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/user/attributes.py +5 -1
  6. h5rdmtoolbox-2.7.3/h5rdmtoolbox/ld/user/datasets.py +76 -0
  7. h5rdmtoolbox-2.7.3/h5rdmtoolbox/ld/user/groups.py +113 -0
  8. h5rdmtoolbox-2.7.3/h5rdmtoolbox/ld/user/utils.py +53 -0
  9. h5rdmtoolbox-2.7.3/h5rdmtoolbox/repository/utils.py +199 -0
  10. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/core.py +1 -0
  11. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox.egg-info/PKG-INFO +103 -32
  12. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/pyproject.toml +1 -1
  13. h5rdmtoolbox-2.7.3/tests/test_readme.py +33 -0
  14. h5rdmtoolbox-2.7.1/h5rdmtoolbox/ld/user/datasets.py +0 -24
  15. h5rdmtoolbox-2.7.1/h5rdmtoolbox/ld/user/groups.py +0 -68
  16. h5rdmtoolbox-2.7.1/h5rdmtoolbox/ld/user/utils.py +0 -33
  17. h5rdmtoolbox-2.7.1/h5rdmtoolbox/repository/utils.py +0 -144
  18. h5rdmtoolbox-2.7.1/tests/test_readme.py +0 -22
  19. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/LICENSE +0 -0
  20. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/_cfg.py +0 -0
  21. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/_repr.py +0 -0
  22. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/_version.py +0 -0
  23. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/__init__.py +0 -0
  24. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/_initialization.py +0 -0
  25. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/abstracts.py +0 -0
  26. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/core.py +0 -0
  27. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/profiles.py +0 -0
  28. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/query_templates.py +0 -0
  29. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/stores/__init__.py +0 -0
  30. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/stores/hdf5.py +0 -0
  31. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/catalog/utils.py +0 -0
  32. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/cli.py +0 -0
  33. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/consts.py +0 -0
  34. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/__init__.py +0 -0
  35. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/cfg.py +0 -0
  36. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/consts.py +0 -0
  37. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/core.py +0 -0
  38. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/errors.py +0 -0
  39. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/generate.py +0 -0
  40. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/ontology/__init__.py +0 -0
  41. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/ontology/h5ontocls.py +0 -0
  42. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/ontology/hdf_datatypes.py +0 -0
  43. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/references.py +0 -0
  44. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/standard_attributes.py +0 -0
  45. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/toolbox_validators.py +0 -0
  46. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/convention/utils.py +0 -0
  47. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/def_icon.png +0 -0
  48. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/fluid-v1.yml +0 -0
  49. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/h5tbx.yaml +0 -0
  50. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/id_icon.png +0 -0
  51. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/iri_icon.png +0 -0
  52. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/ld_icon.png +0 -0
  53. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/piv-v1.yml +0 -0
  54. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/style.css +0 -0
  55. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/tutorial_convention.yaml +0 -0
  56. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/tutorial_convention_vfuncs.py +0 -0
  57. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/tutorial_standard_name_table.yaml +0 -0
  58. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/data/type_icon.png +0 -0
  59. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/__init__.py +0 -0
  60. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/hdfdb/__init__.py +0 -0
  61. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/hdfdb/filedb.py +0 -0
  62. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/hdfdb/objdb.py +0 -0
  63. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/hdfdb/query.py +0 -0
  64. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/hdfdb/utils.py +0 -0
  65. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/interface.py +0 -0
  66. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/lazy.py +0 -0
  67. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/database/mongo.py +0 -0
  68. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/errors.py +0 -0
  69. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/extensions/__init__.py +0 -0
  70. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/extensions/magnitude.py +0 -0
  71. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/extensions/normalize.py +0 -0
  72. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/extensions/onto.py +0 -0
  73. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/extensions/units.py +0 -0
  74. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/extensions/vector.py +0 -0
  75. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/gui/__init__.py +0 -0
  76. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/gui/fairify.py +0 -0
  77. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/gui/src/__init__.py +0 -0
  78. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/gui/src/main.py +0 -0
  79. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/identifiers.py +0 -0
  80. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/layout/__init__.py +0 -0
  81. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/layout/core.py +0 -0
  82. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/__init__.py +0 -0
  83. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/_types.py +0 -0
  84. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/globals.py +0 -0
  85. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/hdf/__init__.py +0 -0
  86. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/hdf/attributes.py +0 -0
  87. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/hdf/datasets.py +0 -0
  88. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/hdf/file.py +0 -0
  89. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/hdf/groups.py +0 -0
  90. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/shacl.py +0 -0
  91. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/user/__init__.py +0 -0
  92. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/user/file.py +0 -0
  93. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/ld/utils.py +0 -0
  94. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/plotting.py +0 -0
  95. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/protected_attributes.py +0 -0
  96. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/protocols.py +0 -0
  97. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/__init__.py +0 -0
  98. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/default_metamapper.py +0 -0
  99. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/interface.py +0 -0
  100. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/zenodo/__init__.py +0 -0
  101. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/zenodo/core.py +0 -0
  102. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/zenodo/metadata.py +0 -0
  103. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/zenodo/tokens.py +0 -0
  104. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/repository/zenodo/utils.py +0 -0
  105. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/tutorial.py +0 -0
  106. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/user.py +0 -0
  107. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/utils.py +0 -0
  108. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/__init__.py +0 -0
  109. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/accessor.py +0 -0
  110. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/accessors/__init__.py +0 -0
  111. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/accessors/provenance.py +0 -0
  112. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/ds_decoder.py +0 -0
  113. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/h5attr.py +0 -0
  114. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/h5ext.py +0 -0
  115. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/h5utils.py +0 -0
  116. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/h5yaml.py +0 -0
  117. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/jsonld.py +0 -0
  118. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox/wrapper/xr2hdf.py +0 -0
  119. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox.egg-info/SOURCES.txt +0 -0
  120. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox.egg-info/dependency_links.txt +0 -0
  121. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox.egg-info/entry_points.txt +0 -0
  122. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox.egg-info/requires.txt +0 -0
  123. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/h5rdmtoolbox.egg-info/top_level.txt +0 -0
  124. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/setup.cfg +0 -0
  125. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_cli.py +0 -0
  126. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_config.py +0 -0
  127. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_extensions.py +0 -0
  128. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_identifiers.py +0 -0
  129. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_plotting.py +0 -0
  130. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_repr.py +0 -0
  131. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_user.py +0 -0
  132. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_utils.py +0 -0
  133. {h5rdmtoolbox-2.7.1 → h5rdmtoolbox-2.7.3}/tests/test_version.py +0 -0
  134. {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.1
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
- h5.attrs["units", M4I.hasUnit] = "degree_Celsius"
125
- h5.rdf["units"].object = "http://qudt.org/vocab/unit/DEG_C"
126
- h5.attrs["description", "https://schema.org/description"] = "Room temperature measurements"
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
- ttl = h5.serialize("ttl")
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
- The serialization in Turtle (ttl) is teh RDF serialization of the HDF5 data (without arrays):
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
- [] a hdf:File ;
141
- hdf:rootGroup [ a hdf:Group ;
142
- hdf:attribute [ a hdf:StringAttribute ;
143
- hdf:data "Room temperature measurements" ;
144
- hdf:name "description" ],
145
- [ a hdf:StringAttribute ;
146
- hdf:data "degree_Celsius" ;
147
- hdf:name "units" ] ;
148
- hdf:member [ a hdf:Dataset ;
149
- hdf:dataspace [ a hdf:SimpleDataspace ;
150
- hdf:dimension [ a hdf:DataspaceDimension ;
151
- hdf:dimensionIndex 0 ;
152
- hdf:size 4 ] ] ;
153
- hdf:datatype hdf:H5T_INTEGER,
154
- hdf:H5T_INTEL_I64 ;
155
- hdf:layout hdf:H5D_CONTIGUOUS ;
156
- hdf:maximumSize 4 ;
157
- hdf:name "/temperature" ;
158
- hdf:rank 1 ;
159
- hdf:size 4 ] ;
160
- hdf:name "/" ;
161
- m4i:hasUnit <http://qudt.org/vocab/unit/DEG_C> ;
162
- schema:description "Room temperature measurements" ] .
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" &#40;h5RDMtoolbox&#41; 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
- h5.attrs["units", M4I.hasUnit] = "degree_Celsius"
43
- h5.rdf["units"].object = "http://qudt.org/vocab/unit/DEG_C"
44
- h5.attrs["description", "https://schema.org/description"] = "Room temperature measurements"
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
- ttl = h5.serialize("ttl")
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
- The serialization in Turtle (ttl) is teh RDF serialization of the HDF5 data (without arrays):
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
- [] a hdf:File ;
59
- hdf:rootGroup [ a hdf:Group ;
60
- hdf:attribute [ a hdf:StringAttribute ;
61
- hdf:data "Room temperature measurements" ;
62
- hdf:name "description" ],
63
- [ a hdf:StringAttribute ;
64
- hdf:data "degree_Celsius" ;
65
- hdf:name "units" ] ;
66
- hdf:member [ a hdf:Dataset ;
67
- hdf:dataspace [ a hdf:SimpleDataspace ;
68
- hdf:dimension [ a hdf:DataspaceDimension ;
69
- hdf:dimensionIndex 0 ;
70
- hdf:size 4 ] ] ;
71
- hdf:datatype hdf:H5T_INTEGER,
72
- hdf:H5T_INTEL_I64 ;
73
- hdf:layout hdf:H5D_CONTIGUOUS ;
74
- hdf:maximumSize 4 ;
75
- hdf:name "/temperature" ;
76
- hdf:rank 1 ;
77
- hdf:size 4 ] ;
78
- hdf:name "/" ;
79
- m4i:hasUnit <http://qudt.org/vocab/unit/DEG_C> ;
80
- schema:description "Room temperature measurements" ] .
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" &#40;h5RDMtoolbox&#41; 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
- rdf_user_type = rdf_manager.type
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)))