shepherd-data 2025.8.1__py3-none-any.whl → 2026.2.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.08.1"
14
+ __version__ = "2026.02.1"
15
15
 
16
16
  __all__ = [
17
17
  "Reader",
shepherd_data/cli.py CHANGED
@@ -7,10 +7,10 @@ from datetime import datetime
7
7
  from pathlib import Path
8
8
 
9
9
  import click
10
+ from shepherd_core.logger import set_log_verbose_level
10
11
 
11
12
  from shepherd_core import get_verbose_level
12
13
  from shepherd_core import local_tz
13
- from shepherd_core.logger import set_log_verbose_level
14
14
 
15
15
  from .reader import Reader
16
16
 
@@ -58,12 +58,9 @@ def version() -> None:
58
58
  from importlib import metadata # noqa: PLC0415
59
59
 
60
60
  logger.debug("Python v%s", sys.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"))
61
+ logger.info("shepherd-data v%s", metadata.version("shepherd_data"))
62
+ for package in ["shepherd_core", "h5py", "numpy", "click", "pydantic"]:
63
+ logger.debug("%s v%s", package, metadata.version(package))
67
64
 
68
65
 
69
66
  @cli.command(short_help="Validates a file or directory containing shepherd-recordings")
@@ -108,7 +105,7 @@ def validate(in_data: Path, *, recurse: bool = False) -> None:
108
105
  "-e",
109
106
  default=None,
110
107
  type=click.FLOAT,
111
- help="End-point in seconds, will be max if omitted",
108
+ help="End-point in seconds, will be maximum if omitted",
112
109
  )
113
110
  @click.option(
114
111
  "--ds-factor",
@@ -345,7 +342,7 @@ def extract_gpio(in_data: Path, separator: str, *, recurse: bool = False) -> Non
345
342
  "-e",
346
343
  default=None,
347
344
  type=click.FLOAT,
348
- help="End-point in seconds, will be max if omitted",
345
+ help="End-point in seconds, will be maximum if omitted",
349
346
  )
350
347
  @click.option(
351
348
  "--recurse",
@@ -376,8 +373,8 @@ def downsample(
376
373
  else:
377
374
  ds_list = [5, 25, 100, 500, 2_500, 10_000, 50_000, 250_000, 1_000_000]
378
375
 
379
- for _factor in ds_list:
380
- path_file = shpr.cut_and_downsample_to_file(start, end, _factor)
376
+ for factor_ in ds_list:
377
+ path_file = shpr.cut_and_downsample_to_file(start, end, factor_)
381
378
  logger.info("Created %s", path_file.name)
382
379
  except (TypeError, ValueError): # noqa: PERF203
383
380
  logger.exception("ERROR: Will skip file. It caused an exception.")
@@ -397,7 +394,7 @@ def downsample(
397
394
  "-e",
398
395
  default=None,
399
396
  type=click.FLOAT,
400
- help="End-point in seconds, will be max if omitted",
397
+ help="End-point in seconds, will be maximum if omitted",
401
398
  )
402
399
  @click.option(
403
400
  "--width",
shepherd_data/ivonne.py CHANGED
@@ -19,11 +19,10 @@ from types import TracebackType
19
19
 
20
20
  import numpy as np
21
21
  import pandas as pd
22
+ from shepherd_core.writer import Writer as CoreWriter
22
23
  from tqdm import trange
23
24
  from typing_extensions import Self
24
25
 
25
- from shepherd_core.writer import Writer as CoreWriter
26
-
27
26
  from .mppt import MPPTracker
28
27
  from .mppt import OptimalTracker
29
28
  from .mppt import iv_model
shepherd_data/mppt.py CHANGED
@@ -15,9 +15,12 @@ from shepherd_core import Calc_t
15
15
  def iv_model(voltages: Calc_t, coeffs: pd.Series) -> Calc_t:
16
16
  """Calculate simple diode based model (equivalent circuit diagram) of a solar panel IV curve.
17
17
 
18
- :param voltages: Load voltage of the solar panel
19
- :param coeffs: three generic coefficients
20
- :return: Solar current at given load voltage
18
+ Args:
19
+ voltages: Load voltage of the solar panel
20
+ coeffs: three generic coefficients
21
+
22
+ Returns:
23
+ Solar current at given load voltage
21
24
  """
22
25
  currents = float(coeffs["a"]) - float(coeffs["b"]) * (
23
26
  np.exp(float(coeffs["c"]) * voltages) - 1.0
@@ -75,8 +78,11 @@ class OpenCircuitTracker(MPPTracker):
75
78
  def process(self, coeffs: pd.DataFrame) -> pd.DataFrame:
76
79
  """Apply harvesting model to input data.
77
80
 
78
- :param coeffs: ivonne coefficients
79
- :return: ivtrace-data
81
+ Args:
82
+ coeffs: ivonne coefficients
83
+
84
+ Returns:
85
+ ivtrace-data
80
86
  """
81
87
  coeffs["icurve"] = coeffs.apply(lambda x: iv_model(self.v_proto, x), axis=1)
82
88
  if "voc" not in coeffs.columns:
shepherd_data/reader.py CHANGED
@@ -9,14 +9,14 @@ from pathlib import Path
9
9
  import h5py
10
10
  import numpy as np
11
11
  from matplotlib import pyplot as plt
12
+ from shepherd_core.data_models import EnergyDType
13
+ from shepherd_core.logger import get_verbose_level
14
+ from shepherd_core.logger import log
12
15
  from tqdm import trange
13
16
 
14
17
  from shepherd_core import Reader as CoreReader
15
18
  from shepherd_core import Writer as CoreWriter
16
19
  from shepherd_core import local_tz
17
- from shepherd_core.data_models import EnergyDType
18
- from shepherd_core.logger import get_verbose_level
19
- from shepherd_core.logger import log
20
20
 
21
21
  # import samplerate # noqa: ERA001, TODO: just a test-fn for now
22
22
 
@@ -133,45 +133,45 @@ class Reader(CoreReader):
133
133
  show: bool = True,
134
134
  ) -> int:
135
135
  """Print warning messages from log in data-group."""
136
- _count = self.count_errors_in_log(group_name, min_level)
137
- if (_count < 1) or ("level" not in self.h5file[group_name]):
136
+ count = self.count_errors_in_log(group_name, min_level)
137
+ if (count < 1) or ("level" not in self.h5file[group_name]):
138
138
  return 0
139
139
  if not show:
140
- return _count
140
+ return count
141
141
  self._logger.warning(
142
142
  "%s caught %d messages with level>=%d -> first %d are:",
143
143
  self.get_hostname(),
144
- _count,
144
+ count,
145
145
  min_level,
146
146
  limit,
147
147
  )
148
148
  for idx, time_ns in enumerate(self.h5file[group_name]["time"][:]):
149
- _level = self.h5file[group_name]["level"][idx]
150
- if _level < min_level:
149
+ level_ = self.h5file[group_name]["level"][idx]
150
+ if level_ < min_level:
151
151
  continue
152
- _msg = self.h5file[group_name]["message"][idx]
153
- _timestamp = datetime.fromtimestamp(time_ns / 1e9, local_tz())
154
- if _level < 30:
155
- self._logger.info(" %s: %s", _timestamp, _msg)
156
- elif _level < 40:
157
- self._logger.warning(" %s: %s", _timestamp, _msg)
152
+ msg_ = self.h5file[group_name]["message"][idx]
153
+ timestamp_ = datetime.fromtimestamp(time_ns / 1e9, local_tz())
154
+ if level_ < 30:
155
+ self._logger.info(" %s: %s", timestamp_, msg_)
156
+ elif level_ < 40:
157
+ self._logger.warning(" %s: %s", timestamp_, msg_)
158
158
  else:
159
- self._logger.error(" %s: %s", _timestamp, _msg)
159
+ self._logger.error(" %s: %s", timestamp_, msg_)
160
160
  limit -= 1
161
161
  if limit < 1:
162
162
  break
163
- return _count
163
+ return count
164
164
 
165
165
  def downsample(
166
166
  self,
167
167
  data_src: h5py.Dataset | np.ndarray,
168
- data_dst: None | h5py.Dataset | np.ndarray,
168
+ data_dst: h5py.Dataset | np.ndarray | None,
169
169
  start_n: int = 0,
170
170
  end_n: int | None = None,
171
171
  ds_factor: float = 5,
172
172
  *,
173
173
  is_time: bool = False,
174
- ) -> None | h5py.Dataset | np.ndarray:
174
+ ) -> h5py.Dataset | np.ndarray | None:
175
175
  """Sample down iv-data.
176
176
 
177
177
  Warning: only valid for IV-Stream, not IV-Curves,
@@ -233,7 +233,7 @@ class Reader(CoreReader):
233
233
  slice_ds, f_state = signal.sosfilt(filter_, slice_ds, zi=f_state)
234
234
 
235
235
  output_pos = 0
236
- for _iter in trange(
236
+ for iter_ in trange(
237
237
  0,
238
238
  iterations,
239
239
  desc=f"downsampling {data_src.name if isinstance(data_src, h5py.Dataset) else ''}",
@@ -241,12 +241,12 @@ class Reader(CoreReader):
241
241
  disable=iterations < 8,
242
242
  ):
243
243
  slice_ds = data_src[
244
- start_n + _iter * chunk_size_inp : start_n + (_iter + 1) * chunk_size_inp
244
+ start_n + iter_ * chunk_size_inp : start_n + (iter_ + 1) * chunk_size_inp
245
245
  ]
246
246
  if not is_time and ds_factor > 1:
247
247
  slice_ds, f_state = signal.sosfilt(filter_, slice_ds, zi=f_state)
248
248
  slice_ds = slice_ds[::ds_factor]
249
- slice_len = min(dest_len - _iter * chunk_size_out, chunk_size_out, len(slice_ds))
249
+ slice_len = min(dest_len - iter_ * chunk_size_out, chunk_size_out, len(slice_ds))
250
250
  data_dst[output_pos : output_pos + slice_len] = slice_ds[:slice_len]
251
251
  # workaround to allow processing last slice (often smaller than expected),
252
252
  # wanted: [_iter * chunk_size_out : (_iter + 1) * chunk_size_out]
@@ -363,13 +363,13 @@ class Reader(CoreReader):
363
363
  def resample(
364
364
  self,
365
365
  data_src: h5py.Dataset | np.ndarray,
366
- data_dst: None | h5py.Dataset | np.ndarray,
366
+ data_dst: h5py.Dataset | np.ndarray | None,
367
367
  start_n: int = 0,
368
368
  end_n: int | None = None,
369
369
  samplerate_dst: float = 1000,
370
370
  *,
371
371
  is_time: bool = False,
372
- ) -> None | h5py.Dataset | np.ndarray:
372
+ ) -> h5py.Dataset | np.ndarray | None:
373
373
  """Up- or down-sample the original trace-data.
374
374
 
375
375
  :param data_src: original iv-data
@@ -518,7 +518,7 @@ class Reader(CoreReader):
518
518
  "end_s": end_s,
519
519
  }
520
520
  if relative_timestamp:
521
- data["time"] = data["time"] - self._cal.time.raw_to_si(self.ds_time[0])
521
+ data["time"] -= self._cal.time.raw_to_si(self.ds_time[0])
522
522
  return data
523
523
 
524
524
  @staticmethod
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.4
2
- Name: shepherd_data
3
- Version: 2025.8.1
2
+ Name: shepherd-data
3
+ Version: 2026.2.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>
7
+ License-Expression: MIT
7
8
  Project-URL: Documentation, https://github.com/nes-lab/shepherd-tools/blob/main/README.md
8
9
  Project-URL: Issues, https://pypi.org/project/shepherd-data/issues
9
10
  Project-URL: Source, https://pypi.org/project/shepherd-data/
@@ -22,11 +23,12 @@ Classifier: Programming Language :: Python :: 3.10
22
23
  Classifier: Programming Language :: Python :: 3.11
23
24
  Classifier: Programming Language :: Python :: 3.12
24
25
  Classifier: Programming Language :: Python :: 3.13
25
- Classifier: License :: OSI Approved :: MIT License
26
+ Classifier: Programming Language :: Python :: 3.14
26
27
  Classifier: Operating System :: OS Independent
27
28
  Classifier: Natural Language :: English
28
29
  Requires-Python: >=3.10
29
30
  Description-Content-Type: text/markdown
31
+ License-File: LICENSE
30
32
  Requires-Dist: click
31
33
  Requires-Dist: h5py
32
34
  Requires-Dist: matplotlib
@@ -34,7 +36,7 @@ Requires-Dist: numpy
34
36
  Requires-Dist: pandas>=2.0.0
35
37
  Requires-Dist: pyYAML
36
38
  Requires-Dist: scipy
37
- Requires-Dist: shepherd-core[inventory]>=2025.08.1
39
+ Requires-Dist: shepherd-core[inventory]==2026.02.1
38
40
  Requires-Dist: tqdm
39
41
  Provides-Extra: elf
40
42
  Requires-Dist: shepherd-core[elf]; extra == "elf"
@@ -48,6 +50,7 @@ Requires-Dist: pytest-click; extra == "test"
48
50
  Requires-Dist: coverage; extra == "test"
49
51
  Provides-Extra: all
50
52
  Requires-Dist: shepherd-data[dev,elf,test]; extra == "all"
53
+ Dynamic: license-file
51
54
 
52
55
  # Shepherd-Data-Tool
53
56
 
@@ -0,0 +1,12 @@
1
+ shepherd_data/__init__.py,sha256=Pla3NFvQsQauHMxK_lnH7SfuiUsfPODFdVcN8AFcysQ,353
2
+ shepherd_data/cli.py,sha256=VYZh88QjjYkYfLSItgAzWPVLLO83nKz6nikmRAkJUnw,15968
3
+ shepherd_data/ivonne.py,sha256=sGiSRUd8bH8EG5M-aD4FFKJ4RqbkIOYQRYGh5VWpAl0,11874
4
+ shepherd_data/mppt.py,sha256=bTCODVXoWevsL4uji38kdSkvvOAk2YuDH3a-wdwsmPk,4037
5
+ shepherd_data/reader.py,sha256=cvZNw0vRzjwguAY9amTUTYW22pJgbXXZe8v_lIuR1DI,25978
6
+ shepherd_data-2026.2.1.dist-info/licenses/LICENSE,sha256=89rkXaau2wFxiFxOi9wKow7KoZEaDQm33QdKIqZvWHU,1120
7
+ shepherd_data-2026.2.1.dist-info/METADATA,sha256=yEnsVl3tyVmdkeO992c98AJcCn7Ash36shNrdCJJlNQ,3502
8
+ shepherd_data-2026.2.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
9
+ shepherd_data-2026.2.1.dist-info/entry_points.txt,sha256=6PBfY36A1xNOdzLiz-Qoukya_UzFZAwOapwmRNnPeZ8,56
10
+ shepherd_data-2026.2.1.dist-info/top_level.txt,sha256=7-SCTY-TG1mLY72OVKCaqte1hy-X8woxknIUAD3OIxs,14
11
+ shepherd_data-2026.2.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
12
+ shepherd_data-2026.2.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022-2025, Networked Embedded Systems Lab, TU Dresden, Ingmar Splitt
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,11 +0,0 @@
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,,