shepherd-data 2025.6.3__py3-none-any.whl → 2025.8.1__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.
shepherd_data/__init__.py CHANGED
@@ -11,7 +11,7 @@ from shepherd_core import Writer
11
11
 
12
12
  from .reader import Reader
13
13
 
14
- __version__ = "2025.06.3"
14
+ __version__ = "2025.08.1"
15
15
 
16
16
  __all__ = [
17
17
  "Reader",
shepherd_data/cli.py CHANGED
@@ -5,16 +5,13 @@ import sys
5
5
  from contextlib import suppress
6
6
  from datetime import datetime
7
7
  from pathlib import Path
8
- from typing import Optional
9
8
 
10
9
  import click
11
- import pydantic
12
10
 
13
11
  from shepherd_core import get_verbose_level
14
12
  from shepherd_core import local_tz
15
13
  from shepherd_core.logger import set_log_verbose_level
16
14
 
17
- from . import __version__
18
15
  from .reader import Reader
19
16
 
20
17
  logger = logging.getLogger("SHPData.cli")
@@ -58,17 +55,22 @@ def cli(ctx: click.Context, *, verbose: bool) -> None:
58
55
  @cli.command(short_help="Print version-info (combine with -v for more)")
59
56
  def version() -> None:
60
57
  """Print version-info (combine with -v for more)."""
61
- logger.info("Shepherd-Data v%s", __version__)
58
+ from importlib import metadata # noqa: PLC0415
59
+
62
60
  logger.debug("Python v%s", sys.version)
63
- logger.debug("Click v%s", click.__version__)
64
- logger.debug("Pydantic v%s", pydantic.__version__)
61
+ logger.info("Shepherd-Data v%s", metadata.version("shepherd_data"))
62
+ logger.debug("Shepherd-Core v%s", metadata.version("shepherd_core"))
63
+ logger.debug("h5py v%s", metadata.version("h5py"))
64
+ logger.debug("numpy v%s", metadata.version("numpy"))
65
+ logger.debug("Click v%s", metadata.version("click"))
66
+ logger.debug("Pydantic v%s", metadata.version("pydantic"))
65
67
 
66
68
 
67
69
  @cli.command(short_help="Validates a file or directory containing shepherd-recordings")
68
70
  @click.argument("in_data", type=click.Path(exists=True, resolve_path=True))
69
71
  @click.option(
70
72
  "--recurse",
71
- "-a",
73
+ "-R",
72
74
  is_flag=True,
73
75
  help="Also consider files in sub-folders",
74
76
  )
@@ -129,14 +131,14 @@ def validate(in_data: Path, *, recurse: bool = False) -> None:
129
131
  )
130
132
  @click.option(
131
133
  "--recurse",
132
- "-a",
134
+ "-R",
133
135
  is_flag=True,
134
136
  help="Also consider files in sub-folders",
135
137
  )
136
138
  def extract(
137
139
  in_data: Path,
138
- start: Optional[float],
139
- end: Optional[float],
140
+ start: float | None,
141
+ end: float | None,
140
142
  ds_factor: float,
141
143
  separator: str,
142
144
  *,
@@ -173,7 +175,7 @@ def extract(
173
175
  )
174
176
  @click.option(
175
177
  "--recurse",
176
- "-a",
178
+ "-R",
177
179
  is_flag=True,
178
180
  help="Also consider files in sub-folders",
179
181
  )
@@ -211,7 +213,7 @@ def extract_meta(
211
213
  if not debug:
212
214
  continue
213
215
  csv_depr = ["sysutil", "timesync"]
214
- csv_meta = ["ptp", "phc2sys", "sys_util", "pru_util"]
216
+ csv_meta = ["ptp", "phc2sys", "sys_util", "pru_util", "power"]
215
217
  for element in csv_meta + csv_depr:
216
218
  if element in shpr.h5file:
217
219
  shpr.save_csv(shpr[element], separator)
@@ -223,7 +225,7 @@ def extract_meta(
223
225
  @click.argument("in_data", type=click.Path(exists=True, resolve_path=True))
224
226
  @click.option(
225
227
  "--recurse",
226
- "-a",
228
+ "-R",
227
229
  is_flag=True,
228
230
  help="Also consider files in sub-folders",
229
231
  )
@@ -248,7 +250,7 @@ def extract_uart(in_data: Path, *, recurse: bool = False) -> None:
248
250
  @click.argument("in_data", type=click.Path(exists=True, resolve_path=True))
249
251
  @click.option(
250
252
  "--recurse",
251
- "-a",
253
+ "-R",
252
254
  is_flag=True,
253
255
  help="Also consider files in sub-folders",
254
256
  )
@@ -294,7 +296,7 @@ def decode_uart(in_data: Path, *, recurse: bool = False) -> None:
294
296
  ) # TODO: also configure decimal point
295
297
  @click.option(
296
298
  "--recurse",
297
- "-a",
299
+ "-R",
298
300
  is_flag=True,
299
301
  help="Also consider files in sub-folders",
300
302
  )
@@ -347,16 +349,16 @@ def extract_gpio(in_data: Path, separator: str, *, recurse: bool = False) -> Non
347
349
  )
348
350
  @click.option(
349
351
  "--recurse",
350
- "-a",
352
+ "-R",
351
353
  is_flag=True,
352
354
  help="Also consider files in sub-folders",
353
355
  )
354
356
  def downsample(
355
357
  in_data: Path,
356
- ds_factor: Optional[float],
357
- sample_rate: Optional[int],
358
- start: Optional[float],
359
- end: Optional[float],
358
+ ds_factor: float | None,
359
+ sample_rate: int | None,
360
+ start: float | None,
361
+ end: float | None,
360
362
  *,
361
363
  recurse: bool = False,
362
364
  ) -> None:
@@ -425,14 +427,15 @@ def downsample(
425
427
  )
426
428
  @click.option(
427
429
  "--recurse",
428
- "-a",
430
+ "-R",
429
431
  is_flag=True,
430
432
  help="Also consider files in sub-folders",
431
433
  )
434
+ # TODO: allow SVG-output
432
435
  def plot(
433
436
  in_data: Path,
434
- start: Optional[float],
435
- end: Optional[float],
437
+ start: float | None,
438
+ end: float | None,
436
439
  width: int,
437
440
  height: int,
438
441
  *,
shepherd_data/ivonne.py CHANGED
@@ -16,7 +16,6 @@ import os
16
16
  import pickle
17
17
  from pathlib import Path
18
18
  from types import TracebackType
19
- from typing import Optional
20
19
 
21
20
  import numpy as np
22
21
  import pandas as pd
@@ -48,7 +47,7 @@ class Reader:
48
47
  def __init__(
49
48
  self,
50
49
  file_path: Path,
51
- samplerate_sps: Optional[int] = None,
50
+ samplerate_sps: int | None = None,
52
51
  *,
53
52
  verbose: bool = True,
54
53
  ) -> None:
@@ -66,7 +65,7 @@ class Reader:
66
65
  self.file_size: int = 0
67
66
  self.data_rate: float = 0
68
67
 
69
- self._df: Optional[pd.DataFrame] = None
68
+ self._df: pd.DataFrame | None = None
70
69
 
71
70
  def __enter__(self) -> Self:
72
71
  if not self.file_path.exists():
@@ -88,9 +87,9 @@ class Reader:
88
87
 
89
88
  def __exit__(
90
89
  self,
91
- typ: Optional[type[BaseException]] = None,
92
- exc: Optional[BaseException] = None,
93
- tb: Optional[TracebackType] = None,
90
+ typ: type[BaseException] | None = None,
91
+ exc: BaseException | None = None,
92
+ tb: TracebackType | None = None,
94
93
  extra_arg: int = 0,
95
94
  ) -> None:
96
95
  pass
@@ -107,7 +106,7 @@ class Reader:
107
106
  shp_output: Path,
108
107
  v_max: float = 5.0,
109
108
  pts_per_curve: int = 1000,
110
- duration_s: Optional[float] = None,
109
+ duration_s: float | None = None,
111
110
  ) -> None:
112
111
  """Transform recorded parameters to shepherd hdf database with IV curves.
113
112
 
@@ -170,8 +169,8 @@ class Reader:
170
169
  self,
171
170
  shp_output: Path,
172
171
  v_max: float = 5.0,
173
- duration_s: Optional[float] = None,
174
- tracker: Optional[MPPTracker] = None,
172
+ duration_s: float | None = None,
173
+ tracker: MPPTracker | None = None,
175
174
  ) -> None:
176
175
  """Transform shepherd IV surface / curves to shepherd IV trace / samples .
177
176
 
@@ -240,7 +239,7 @@ class Reader:
240
239
  self,
241
240
  shp_output: Path,
242
241
  v_max: float = 5.0,
243
- duration_s: Optional[float] = None,
242
+ duration_s: float | None = None,
244
243
  ) -> None:
245
244
  """Transform ivonne-parameters to up-sampled versions for shepherd.
246
245
 
shepherd_data/reader.py CHANGED
@@ -5,8 +5,6 @@ from collections.abc import Mapping
5
5
  from collections.abc import Sequence
6
6
  from datetime import datetime
7
7
  from pathlib import Path
8
- from typing import Optional
9
- from typing import Union
10
8
 
11
9
  import h5py
12
10
  import numpy as np
@@ -166,14 +164,14 @@ class Reader(CoreReader):
166
164
 
167
165
  def downsample(
168
166
  self,
169
- data_src: Union[h5py.Dataset, np.ndarray],
170
- data_dst: Union[None, h5py.Dataset, np.ndarray],
167
+ data_src: h5py.Dataset | np.ndarray,
168
+ data_dst: None | h5py.Dataset | np.ndarray,
171
169
  start_n: int = 0,
172
- end_n: Optional[int] = None,
170
+ end_n: int | None = None,
173
171
  ds_factor: float = 5,
174
172
  *,
175
173
  is_time: bool = False,
176
- ) -> Union[None, h5py.Dataset, np.ndarray]:
174
+ ) -> None | h5py.Dataset | np.ndarray:
177
175
  """Sample down iv-data.
178
176
 
179
177
  Warning: only valid for IV-Stream, not IV-Curves,
@@ -187,19 +185,23 @@ class Reader(CoreReader):
187
185
  :param is_time: time is not really down-sampled, but decimated
188
186
  :return: resampled h5-dataset or numpy-array
189
187
  """
190
- from scipy import signal # here due to massive delay
188
+ # import only when needed, due to massive delay
189
+ from scipy import signal # noqa: PLC0415
191
190
 
192
191
  if self.get_datatype() == EnergyDType.ivsurface:
193
192
  self._logger.warning("Downsampling-Function was not written for IVSurfaces")
194
193
  ds_factor = max(1, math.floor(ds_factor))
195
-
196
- if isinstance(end_n, (int, float)):
197
- _end_n = min(data_src.shape[0], round(end_n))
194
+ if not isinstance(start_n, int):
195
+ raise TypeError("start_n must be an integer")
196
+ if isinstance(end_n, int):
197
+ end_n = min(data_src.shape[0], end_n)
198
+ elif isinstance(end_n, float):
199
+ raise TypeError("end_n must be an integer")
198
200
  else:
199
- _end_n = data_src.shape[0]
201
+ end_n = data_src.shape[0]
200
202
 
201
- start_n = min(_end_n, round(start_n))
202
- data_len = _end_n - start_n # TODO: one-off to calculation below ?
203
+ start_n = min(end_n, start_n)
204
+ data_len = end_n - start_n # TODO: one-off to calculation below ?
203
205
  if data_len == 0:
204
206
  self._logger.warning("downsampling failed because of data_len = 0")
205
207
  return data_dst
@@ -258,8 +260,8 @@ class Reader(CoreReader):
258
260
 
259
261
  def cut_and_downsample_to_file(
260
262
  self,
261
- start_s: Optional[float],
262
- end_s: Optional[float],
263
+ start_s: float | None,
264
+ end_s: float | None,
263
265
  ds_factor: float,
264
266
  ) -> Path:
265
267
  """Cut source to given limits, downsample by factor and store result in separate file.
@@ -360,14 +362,14 @@ class Reader(CoreReader):
360
362
 
361
363
  def resample(
362
364
  self,
363
- data_src: Union[h5py.Dataset, np.ndarray],
364
- data_dst: Union[None, h5py.Dataset, np.ndarray],
365
+ data_src: h5py.Dataset | np.ndarray,
366
+ data_dst: None | h5py.Dataset | np.ndarray,
365
367
  start_n: int = 0,
366
- end_n: Optional[int] = None,
368
+ end_n: int | None = None,
367
369
  samplerate_dst: float = 1000,
368
370
  *,
369
371
  is_time: bool = False,
370
- ) -> Union[None, h5py.Dataset, np.ndarray]:
372
+ ) -> None | h5py.Dataset | np.ndarray:
371
373
  """Up- or down-sample the original trace-data.
372
374
 
373
375
  :param data_src: original iv-data
@@ -382,13 +384,17 @@ class Reader(CoreReader):
382
384
  if self.get_datatype() == EnergyDType.ivsurface:
383
385
  self._logger.warning("Resampling-Function was not written for IVSurfaces")
384
386
  return data_dst
385
- if isinstance(end_n, (int, float)):
386
- _end_n = min(data_src.shape[0], round(end_n))
387
+ if not isinstance(start_n, int):
388
+ raise TypeError("start_n must be an integer")
389
+ if isinstance(end_n, int):
390
+ end_n = min(data_src.shape[0], end_n)
391
+ elif isinstance(end_n, float):
392
+ raise TypeError("end_n must be an integer")
387
393
  else:
388
- _end_n = data_src.shape[0]
394
+ end_n = data_src.shape[0]
389
395
 
390
- start_n = min(_end_n, round(start_n))
391
- data_len = _end_n - start_n
396
+ start_n = min(end_n, start_n)
397
+ data_len = end_n - start_n
392
398
  if data_len == 0:
393
399
  self._logger.warning("resampling failed because of data_len = 0")
394
400
  return data_dst
@@ -463,11 +469,11 @@ class Reader(CoreReader):
463
469
 
464
470
  def generate_plot_data(
465
471
  self,
466
- start_s: Optional[float] = None,
467
- end_s: Optional[float] = None,
472
+ start_s: float | None = None,
473
+ end_s: float | None = None,
468
474
  *,
469
475
  relative_timestamp: bool = True,
470
- ) -> Optional[dict]:
476
+ ) -> dict | None:
471
477
  """Provide down-sampled iv-data that can be fed into plot_to_file().
472
478
 
473
479
  :param start_s: time in seconds, relative to start of recording
@@ -517,7 +523,7 @@ class Reader(CoreReader):
517
523
 
518
524
  @staticmethod
519
525
  def assemble_plot(
520
- data: Union[Mapping, Sequence], width: int = 20, height: int = 10, *, only_pwr: bool = False
526
+ data: Mapping | Sequence, width: int = 20, height: int = 10, *, only_pwr: bool = False
521
527
  ) -> plt.Figure:
522
528
  """Create the actual figure.
523
529
 
@@ -575,8 +581,8 @@ class Reader(CoreReader):
575
581
 
576
582
  def plot_to_file(
577
583
  self,
578
- start_s: Optional[float] = None,
579
- end_s: Optional[float] = None,
584
+ start_s: float | None = None,
585
+ end_s: float | None = None,
580
586
  width: int = 20,
581
587
  height: int = 10,
582
588
  *,
@@ -619,7 +625,7 @@ class Reader(CoreReader):
619
625
  height: int = 10,
620
626
  *,
621
627
  only_pwr: bool = False,
622
- ) -> Optional[Path]:
628
+ ) -> Path | None:
623
629
  """Create (down-sampled) IV-Multi-Plots (of more than one trace).
624
630
 
625
631
  :param data: plottable / down-sampled iv-data with some meta-data
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shepherd_data
3
- Version: 2025.6.3
3
+ Version: 2025.8.1
4
4
  Summary: Programming- and CLI-Interface for the h5-dataformat of the Shepherd-Testbed
5
5
  Author-email: Ingmar Splitt <ingmar.splitt@tu-dresden.de>
6
6
  Maintainer-email: Ingmar Splitt <ingmar.splitt@tu-dresden.de>
@@ -18,7 +18,6 @@ Classifier: Development Status :: 5 - Production/Stable
18
18
  Classifier: Intended Audience :: Developers
19
19
  Classifier: Intended Audience :: Information Technology
20
20
  Classifier: Intended Audience :: Science/Research
21
- Classifier: Programming Language :: Python :: 3.9
22
21
  Classifier: Programming Language :: Python :: 3.10
23
22
  Classifier: Programming Language :: Python :: 3.11
24
23
  Classifier: Programming Language :: Python :: 3.12
@@ -26,7 +25,7 @@ Classifier: Programming Language :: Python :: 3.13
26
25
  Classifier: License :: OSI Approved :: MIT License
27
26
  Classifier: Operating System :: OS Independent
28
27
  Classifier: Natural Language :: English
29
- Requires-Python: >=3.9
28
+ Requires-Python: >=3.10
30
29
  Description-Content-Type: text/markdown
31
30
  Requires-Dist: click
32
31
  Requires-Dist: h5py
@@ -35,7 +34,7 @@ Requires-Dist: numpy
35
34
  Requires-Dist: pandas>=2.0.0
36
35
  Requires-Dist: pyYAML
37
36
  Requires-Dist: scipy
38
- Requires-Dist: shepherd-core[inventory]>=2025.06.3
37
+ Requires-Dist: shepherd-core[inventory]>=2025.08.1
39
38
  Requires-Dist: tqdm
40
39
  Provides-Extra: elf
41
40
  Requires-Dist: shepherd-core[elf]; extra == "elf"
@@ -47,6 +46,8 @@ Requires-Dist: shepherd-core[test]; extra == "test"
47
46
  Requires-Dist: pytest; extra == "test"
48
47
  Requires-Dist: pytest-click; extra == "test"
49
48
  Requires-Dist: coverage; extra == "test"
49
+ Provides-Extra: all
50
+ Requires-Dist: shepherd-data[dev,elf,test]; extra == "all"
50
51
 
51
52
  # Shepherd-Data-Tool
52
53
 
@@ -0,0 +1,11 @@
1
+ shepherd_data/__init__.py,sha256=oEhjHkoauQ5UG6iosVocZ1DpmjIp_MfNtgAvVuj5L4c,353
2
+ shepherd_data/cli.py,sha256=CHlOIYMx1hcOukYUpK1LWrjj_7ESL0FKxJascVqnrqM,16118
3
+ shepherd_data/ivonne.py,sha256=vh0XyMoSjbanzy4sqpNfVo6DEnbWNJPRUgNKPfHP2Yc,11875
4
+ shepherd_data/mppt.py,sha256=y9gVIhMs-ZG3ScL9UQTc5n8T146B13Q5dA5sfqqfjg0,3999
5
+ shepherd_data/reader.py,sha256=jHDPmLCZ-wDiIAlpLkyjguMdcueJ-TbqL6Nq7AxzPu0,25997
6
+ shepherd_data-2025.8.1.dist-info/METADATA,sha256=BleD3ZIR6dUuFPPVPi9sgQkfZTyHT_gGj-6-ABuXhSw,3434
7
+ shepherd_data-2025.8.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
+ shepherd_data-2025.8.1.dist-info/entry_points.txt,sha256=6PBfY36A1xNOdzLiz-Qoukya_UzFZAwOapwmRNnPeZ8,56
9
+ shepherd_data-2025.8.1.dist-info/top_level.txt,sha256=7-SCTY-TG1mLY72OVKCaqte1hy-X8woxknIUAD3OIxs,14
10
+ shepherd_data-2025.8.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
11
+ shepherd_data-2025.8.1.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- shepherd_data/__init__.py,sha256=59AsLF1na1g6jQ1ZoFUCgaO_dMVJnrWpOKwW-jPAcwM,353
2
- shepherd_data/cli.py,sha256=8CShRsqJ5w6_nirNKInFEwYGv0gG5caXVLzExSeRGL4,15902
3
- shepherd_data/ivonne.py,sha256=sH7c2aj9i5ygkpw6xQbjRwrbl9wtU_Toj_ZFyJVywG8,11930
4
- shepherd_data/mppt.py,sha256=y9gVIhMs-ZG3ScL9UQTc5n8T146B13Q5dA5sfqqfjg0,3999
5
- shepherd_data/reader.py,sha256=NEIwXC5f5fkSiBEsyY85gIcgjhYHFS1tavNnA6ViE3k,25741
6
- shepherd_data-2025.6.3.dist-info/METADATA,sha256=YY0XjoqFMNNRHgg0a225ycvG7HYQH_-66Gxdo0UHnoI,3404
7
- shepherd_data-2025.6.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
- shepherd_data-2025.6.3.dist-info/entry_points.txt,sha256=6PBfY36A1xNOdzLiz-Qoukya_UzFZAwOapwmRNnPeZ8,56
9
- shepherd_data-2025.6.3.dist-info/top_level.txt,sha256=7-SCTY-TG1mLY72OVKCaqte1hy-X8woxknIUAD3OIxs,14
10
- shepherd_data-2025.6.3.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
11
- shepherd_data-2025.6.3.dist-info/RECORD,,