h5yaml 0.0.4__py3-none-any.whl → 0.1.0__py3-none-any.whl

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.
@@ -45,7 +45,10 @@ dimensions:
45
45
  # - compound elements must have a data-type, and can have a unit and long_name
46
46
  compounds:
47
47
  stats_dtype:
48
- time: [u8, seconds since 1970-01-01T00:00:00, timestamp]
48
+ time:
49
+ - u8
50
+ - seconds since 1970-01-01T00:00:00
51
+ - timestamp
49
52
  index: [u2, '1', index]
50
53
  tbl_id: [u1, '1', binning id]
51
54
  saa: [u1, '1', saa-flag]
@@ -84,7 +87,6 @@ variables:
84
87
  valid_max: 65534
85
88
  /group_01/stats:
86
89
  _dtype: stats_dtype
87
- _vlen: True
88
90
  _dims: [time]
89
91
  comment: detector map statistics
90
92
  /group_02/detector_images:
@@ -97,3 +99,8 @@ variables:
97
99
  units: '1'
98
100
  valid_min: 0
99
101
  valid_max: 65534
102
+ /group_02/stats:
103
+ _dtype: stats_dtype
104
+ _vlen: True
105
+ _dims: [time]
106
+ comment: detector map statistics (vlen)
@@ -0,0 +1,97 @@
1
+ # YAML
2
+ #
3
+ # Configuration file to test the implementation of classes H5Yaml and NcYaml
4
+ #
5
+ # This file is part of h5_yaml:
6
+ # https://github.com/rmvanhees/h5_yaml.git
7
+ #
8
+ # Copyright (c) 2025 SRON
9
+ # All Rights Reserved
10
+ #
11
+ # License: BSD-3-Clause
12
+ #
13
+ # Define groups
14
+ groups:
15
+ - group_00
16
+ - group_01
17
+ - group_02
18
+
19
+ # Define dimensions
20
+ # Note dimensions with an attribute 'long_name' will also be generated as variable
21
+ dimensions:
22
+ number_of_images:
23
+ _dtype: u2
24
+ _size: 0
25
+ samples_per_image:
26
+ _dtype: u4
27
+ _size: 203500
28
+ column:
29
+ _dtype: u2
30
+ _size: 640
31
+ row:
32
+ _dtype: u2
33
+ _size: 512
34
+ time:
35
+ _dtype: f8
36
+ _size: 0
37
+ _FillValue: -32767
38
+ long_name: Attitude sample time (seconds of day)
39
+ calendar: proleptic_gregorian
40
+ units: seconds since %Y-%m-%d %H:%M:%S
41
+ valid_min: 0
42
+ valid_max: 92400
43
+
44
+ # Define compound types
45
+ # - compound elements must have a data-type, and can have a unit and long_name
46
+ compounds:
47
+ stats_dtype:
48
+ time:
49
+ - u8
50
+ - seconds since 1970-01-01T00:00:00
51
+ - timestamp
52
+ index: [u2, '1', index]
53
+ tbl_id: [u1, '1', binning id]
54
+ saa: [u1, '1', saa-flag]
55
+ coad: [u1, '1', co-addings]
56
+ texp: [f4, ms, exposure time]
57
+ lat: [f4, degree, latitude]
58
+ lon: [f4, degree, longitude]
59
+ avg: [f4, '1', '$S - S_{ref}$']
60
+ unc: [f4, '1', '\u03c3($S - S_{ref}$)']
61
+ dark_offs: [f4, '1', dark-offset]
62
+
63
+ # Define variables
64
+ variables:
65
+ /group_00/detector_images:
66
+ _dtype: u2
67
+ _dims: [number_of_images, column, row]
68
+ _FillValue: 65535
69
+ long_name: Detector pixel values
70
+ comment: unbinned full-frame data
71
+ units: '1'
72
+ valid_min: 0
73
+ valid_max: 65534
74
+ /group_01/detector_images:
75
+ _dtype: u2
76
+ _dims: [number_of_images, samples_per_image]
77
+ _FillValue: 65535
78
+ _compression: 1
79
+ long_name: Detector pixel values
80
+ comment: variable binned data (filled to the largest samples_per_image)
81
+ units: '1'
82
+ valid_min: 0
83
+ valid_max: 65534
84
+ /group_01/stats:
85
+ _dtype: stats_dtype
86
+ _dims: [time]
87
+ comment: detector map statistics
88
+ /group_02/detector_images:
89
+ _dtype: u2
90
+ _dims: [number_of_images]
91
+ _vlen: True
92
+ _FillValue: 65535
93
+ long_name: Detector pixel values
94
+ comment: variable binned (vlen) data
95
+ units: '1'
96
+ valid_min: 0
97
+ valid_max: 65534
@@ -23,7 +23,43 @@ import numpy as np
23
23
  from h5yaml.conf_from_yaml import conf_from_yaml
24
24
  from h5yaml.lib.chunksizes import guess_chunks
25
25
 
26
+
26
27
  # - helper function ------------------------------------
28
+ def adjust_attr(attr_key: str, attr_val: np.ndarray, attr_dtype: str) -> np.ndarray:
29
+ """..."""
30
+ if attr_key in ("valid_min", "valid_max", "valid_range"):
31
+ match attr_dtype:
32
+ case "i1":
33
+ res = np.int8(attr_val)
34
+ case "i2":
35
+ res = np.int16(attr_val)
36
+ case "i4":
37
+ res = np.int32(attr_val)
38
+ case "i8":
39
+ res = np.int64(attr_val)
40
+ case "u1":
41
+ res = np.uint8(attr_val)
42
+ case "u2":
43
+ res = np.uint16(attr_val)
44
+ case "u4":
45
+ res = np.uint32(attr_val)
46
+ case "u8":
47
+ res = np.uint64(attr_val)
48
+ case "f2":
49
+ res = np.float16(attr_val)
50
+ case "f4":
51
+ res = np.float32(attr_val)
52
+ case "f8":
53
+ res = np.float64(attr_val)
54
+ case _:
55
+ res = attr_val
56
+
57
+ return res
58
+
59
+ if attr_key == "flag_values":
60
+ return np.array(attr_val, dtype="u1")
61
+
62
+ return attr_val
27
63
 
28
64
 
29
65
  # - class definition -----------------------------------
@@ -82,6 +118,8 @@ class H5Yaml:
82
118
  )
83
119
  if "_values" in val:
84
120
  dset[:] = val["_values"]
121
+ elif "_range" in val:
122
+ dset[:] = np.arange(*val["_range"], dtype=val["_dtype"])
85
123
 
86
124
  dset.make_scale(
87
125
  Path(key).name
@@ -89,36 +127,8 @@ class H5Yaml:
89
127
  else "This is a netCDF dimension but not a netCDF variable."
90
128
  )
91
129
  for attr, attr_val in val.items():
92
- if attr.startswith("_"):
93
- continue
94
- if attr in ("valid_min", "valid_max"):
95
- match val["_dtype"]:
96
- case "i1":
97
- dset.attrs[attr] = np.int8(attr_val)
98
- case "i2":
99
- dset.attrs[attr] = np.int16(attr_val)
100
- case "i4":
101
- dset.attrs[attr] = np.int32(attr_val)
102
- case "i8":
103
- dset.attrs[attr] = np.int64(attr_val)
104
- case "u1":
105
- dset.attrs[attr] = np.uint8(attr_val)
106
- case "u2":
107
- dset.attrs[attr] = np.uint16(attr_val)
108
- case "u4":
109
- dset.attrs[attr] = np.uint32(attr_val)
110
- case "u8":
111
- dset.attrs[attr] = np.uint64(attr_val)
112
- case "f2":
113
- dset.attrs[attr] = np.float16(attr_val)
114
- case "f4":
115
- dset.attrs[attr] = np.float32(attr_val)
116
- case "f8":
117
- dset.attrs[attr] = np.float64(attr_val)
118
- case _:
119
- dset.attrs[attr] = attr_val
120
- else:
121
- dset.attrs[attr] = attr_val
130
+ if not attr.startswith("_"):
131
+ dset.attrs[attr] = adjust_attr(attr, attr_val, val["_dtype"])
122
132
 
123
133
  def __compounds(self: H5Yaml, fid: h5py.File) -> dict[str, str | int | float]:
124
134
  """Add compound datatypes to HDF5 product."""
@@ -192,9 +202,8 @@ class H5Yaml:
192
202
  fillvalue=fillvalue,
193
203
  )
194
204
  for attr, attr_val in val.items():
195
- if attr.startswith("_"):
196
- continue
197
- dset.attrs[attr] = attr_val
205
+ if not attr.startswith("_"):
206
+ dset.attrs[attr] = adjust_attr(attr, attr_val, val["_dtype"])
198
207
  continue
199
208
 
200
209
  n_udim = 0
@@ -236,7 +245,14 @@ class H5Yaml:
236
245
  shuffle = True
237
246
 
238
247
  if val.get("_vlen"):
239
- ds_dtype = h5py.vlen_dtype(ds_dtype)
248
+ ds_name = (
249
+ val["_dtype"].split("_")[0]
250
+ if "_" in val["_dtype"]
251
+ else val["_dtype"]
252
+ ) + "_vlen"
253
+ if ds_name not in fid:
254
+ fid[ds_name] = h5py.vlen_dtype(ds_dtype)
255
+ ds_dtype = fid[ds_name]
240
256
  fillvalue = None
241
257
  if ds_maxshape == (None,):
242
258
  ds_chunk = (16,)
@@ -256,38 +272,8 @@ class H5Yaml:
256
272
  dset.dims[ii].attach_scale(fid[coord])
257
273
 
258
274
  for attr, attr_val in val.items():
259
- if attr.startswith("_"):
260
- continue
261
- if attr in ("valid_min", "valid_max"):
262
- match val["_dtype"]:
263
- case "i1":
264
- dset.attrs[attr] = np.int8(attr_val)
265
- case "i2":
266
- dset.attrs[attr] = np.int16(attr_val)
267
- case "i4":
268
- dset.attrs[attr] = np.int32(attr_val)
269
- case "i8":
270
- dset.attrs[attr] = np.int64(attr_val)
271
- case "u1":
272
- dset.attrs[attr] = np.uint8(attr_val)
273
- case "u2":
274
- dset.attrs[attr] = np.uint16(attr_val)
275
- case "u4":
276
- dset.attrs[attr] = np.uint32(attr_val)
277
- case "u8":
278
- dset.attrs[attr] = np.uint64(attr_val)
279
- case "f2":
280
- dset.attrs[attr] = np.float16(attr_val)
281
- case "f4":
282
- dset.attrs[attr] = np.float32(attr_val)
283
- case "f8":
284
- dset.attrs[attr] = np.float64(attr_val)
285
- case _:
286
- dset.attrs[attr] = attr_val
287
- elif attr == "flag_values":
288
- dset.attrs[attr] = np.array(attr_val, dtype="u1")
289
- else:
290
- dset.attrs[attr] = attr_val
275
+ if not attr.startswith("_"):
276
+ dset.attrs[attr] = adjust_attr(attr, attr_val, val["_dtype"])
291
277
 
292
278
  if compounds is not None and val["_dtype"] in compounds:
293
279
  if compounds[val["_dtype"]]["units"]:
@@ -311,7 +297,8 @@ class H5Yaml:
311
297
  """
312
298
  try:
313
299
  with h5py.File(l1a_name, "w") as fid:
314
- self.__groups(fid)
300
+ if "groups" in self.h5_def:
301
+ self.__groups(fid)
315
302
  self.__dimensions(fid)
316
303
  self.__variables(fid, self.__compounds(fid))
317
304
  except PermissionError as exc:
h5yaml/yaml_nc.py CHANGED
@@ -258,7 +258,7 @@ class NcYaml:
258
258
  def tests() -> None:
259
259
  """..."""
260
260
  print("Calling NcYaml")
261
- NcYaml(files("h5yaml.Data") / "h5_testing.yaml").create("test_yaml.nc")
261
+ NcYaml(files("h5yaml.Data") / "nc_testing.yaml").create("test_yaml.nc")
262
262
 
263
263
 
264
264
  if __name__ == "__main__":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: h5yaml
3
- Version: 0.0.4
3
+ Version: 0.1.0
4
4
  Summary: Use YAML configuration file to generate HDF5/netCDF4 formated files.
5
5
  Project-URL: Homepage, https://github.com/rmvanhees/h5_yaml
6
6
  Project-URL: Source, https://github.com/rmvanhees/h5_yaml
@@ -9,18 +9,18 @@ Author-email: Richard van Hees <r.m.van.hees@sron.nl>
9
9
  License-Expression: BSD-3-Clause
10
10
  License-File: LICENSE
11
11
  Keywords: HDF5,YAML,netCDF4
12
- Classifier: Development Status :: 4 - Beta
12
+ Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: Intended Audience :: Science/Research
15
15
  Classifier: Operating System :: OS Independent
16
16
  Classifier: Programming Language :: Python :: 3 :: Only
17
- Classifier: Programming Language :: Python :: 3.9
18
17
  Classifier: Programming Language :: Python :: 3.10
19
18
  Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
21
20
  Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
22
  Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
23
- Requires-Python: >=3.9
23
+ Requires-Python: >=3.10
24
24
  Requires-Dist: h5py>=3.13
25
25
  Requires-Dist: netcdf4>=1.7
26
26
  Requires-Dist: numpy>=2.2
@@ -133,10 +133,11 @@ The YAML file should be structured as follows:
133
133
  Alternatively, provide a list with names of YAML files which contain the definitions
134
134
  of the compounds.
135
135
 
136
+ ```
136
137
  compounds:
137
138
  - h5_nomhk_tm.yaml
138
139
  - h5_science_hk.yaml
139
-
140
+ ```
140
141
  * The 'variables' are defined by their data-type ('_dtype') and dimensions ('_dims'),
141
142
  and optionally chunk sizes ('_chunks'), compression ('_compression'), variable length
142
143
  ('_vlen'). In addition, each variable can have as many attributes as you like,
@@ -0,0 +1,10 @@
1
+ h5yaml/conf_from_yaml.py,sha256=FT5oS4yqDFUYZqgria_OrmMK52ZcrTVoAPyPkLrHstc,982
2
+ h5yaml/yaml_h5.py,sha256=VNMyfcGaiWwqzAxy8M-l_nYHLbODIW8cxoppfZJc22k,10639
3
+ h5yaml/yaml_nc.py,sha256=9GqddTE5qmpumwoR5sJ0LZUDKW8RfnFi9LG98bm7tH8,9202
4
+ h5yaml/Data/h5_testing.yaml,sha256=zX0ipEZv3WILEpgniLlCDJz2zo2wTS6vAvTA2zZNQkY,2483
5
+ h5yaml/Data/nc_testing.yaml,sha256=v1jd2yJHS9qBJikZFmxp-RfNQZ1r6NmwPMhjeUmPOus,2295
6
+ h5yaml/lib/chunksizes.py,sha256=sAYiTTL8ecBivBDxw-XIJu2yMlt0zNHTr-KS7tBFp2o,1392
7
+ h5yaml-0.1.0.dist-info/METADATA,sha256=hjvtnjNMAJAYK0hoksSMnyecJzzxaMKKd1fvZQGr2Kc,7188
8
+ h5yaml-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
9
+ h5yaml-0.1.0.dist-info/licenses/LICENSE,sha256=MoOwtPnC77nFaIwRIAIE6fKhrzMd3G18mOXDPtAH8G0,1509
10
+ h5yaml-0.1.0.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- h5yaml/conf_from_yaml.py,sha256=FT5oS4yqDFUYZqgria_OrmMK52ZcrTVoAPyPkLrHstc,982
2
- h5yaml/yaml_h5py.py,sha256=MVPUqD5fNY3VYIi3ebaEY7uSR1sgYw-8DvIjrOWIaIk,11838
3
- h5yaml/yaml_nc.py,sha256=37NQ9FPuCrnOTN5R4otn0R-Sdwej1-cPwhODgY2L6pY,9202
4
- h5yaml/Data/h5_testing.yaml,sha256=_x3qBC8RNQ1h4c6B1JOH_y0L9DiDLsOEfyr60IcvpoI,2358
5
- h5yaml/lib/chunksizes.py,sha256=sAYiTTL8ecBivBDxw-XIJu2yMlt0zNHTr-KS7tBFp2o,1392
6
- h5yaml-0.0.4.dist-info/METADATA,sha256=Vvpv1h1t0cYvV5hBiXzdKe2CtU3TT2hWW0qwrIC8vLc,7160
7
- h5yaml-0.0.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
8
- h5yaml-0.0.4.dist-info/licenses/LICENSE,sha256=MoOwtPnC77nFaIwRIAIE6fKhrzMd3G18mOXDPtAH8G0,1509
9
- h5yaml-0.0.4.dist-info/RECORD,,
File without changes