shepherd-data 2024.9.1__py3-none-any.whl → 2024.11.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 +1 -1
- shepherd_data/cli.py +82 -92
- shepherd_data/reader.py +126 -2
- {shepherd_data-2024.9.1.dist-info → shepherd_data-2024.11.1.dist-info}/METADATA +2 -2
- shepherd_data-2024.11.1.dist-info/RECORD +11 -0
- {shepherd_data-2024.9.1.dist-info → shepherd_data-2024.11.1.dist-info}/WHEEL +1 -1
- shepherd_data-2024.9.1.dist-info/RECORD +0 -11
- {shepherd_data-2024.9.1.dist-info → shepherd_data-2024.11.1.dist-info}/entry_points.txt +0 -0
- {shepherd_data-2024.9.1.dist-info → shepherd_data-2024.11.1.dist-info}/top_level.txt +0 -0
- {shepherd_data-2024.9.1.dist-info → shepherd_data-2024.11.1.dist-info}/zip-safe +0 -0
shepherd_data/__init__.py
CHANGED
shepherd_data/cli.py
CHANGED
|
@@ -10,13 +10,12 @@ from typing import List
|
|
|
10
10
|
from typing import Optional
|
|
11
11
|
|
|
12
12
|
import click
|
|
13
|
+
import pydantic
|
|
13
14
|
|
|
14
15
|
from shepherd_core import get_verbose_level
|
|
15
|
-
from shepherd_core import increase_verbose_level
|
|
16
16
|
from shepherd_core import local_tz
|
|
17
|
-
from shepherd_core.
|
|
17
|
+
from shepherd_core.logger import set_log_verbose_level
|
|
18
18
|
|
|
19
|
-
from . import Writer
|
|
20
19
|
from . import __version__
|
|
21
20
|
from .reader import Reader
|
|
22
21
|
|
|
@@ -50,26 +49,25 @@ def path_to_flist(data_path: Path) -> List[Path]:
|
|
|
50
49
|
"--verbose",
|
|
51
50
|
"-v",
|
|
52
51
|
is_flag=True,
|
|
53
|
-
help="
|
|
54
|
-
)
|
|
55
|
-
@click.option(
|
|
56
|
-
"--version",
|
|
57
|
-
is_flag=True,
|
|
58
|
-
help="Prints version-info at start (combinable with -v)",
|
|
52
|
+
help="Switch from info- to debug-level",
|
|
59
53
|
)
|
|
60
54
|
@click.pass_context # TODO: is the ctx-type correct?
|
|
61
|
-
def cli(ctx: click.Context, *, verbose: bool
|
|
55
|
+
def cli(ctx: click.Context, *, verbose: bool) -> None:
|
|
62
56
|
"""Shepherd: Synchronized Energy Harvesting Emulator and Recorder."""
|
|
63
|
-
if verbose
|
|
64
|
-
increase_verbose_level(3)
|
|
65
|
-
if version:
|
|
66
|
-
logger.info("Shepherd-Data v%s", __version__)
|
|
67
|
-
logger.debug("Python v%s", sys.version)
|
|
68
|
-
logger.debug("Click v%s", click.__version__)
|
|
57
|
+
set_log_verbose_level(logger, 3 if verbose else 2)
|
|
69
58
|
if not ctx.invoked_subcommand:
|
|
70
59
|
click.echo("Please specify a valid command")
|
|
71
60
|
|
|
72
61
|
|
|
62
|
+
@cli.command(short_help="Print version-info (combine with -v for more)")
|
|
63
|
+
def version() -> None:
|
|
64
|
+
"""Print version-info (combine with -v for more)."""
|
|
65
|
+
logger.info("Shepherd-Data v%s", __version__)
|
|
66
|
+
logger.debug("Python v%s", sys.version)
|
|
67
|
+
logger.debug("Click v%s", click.__version__)
|
|
68
|
+
logger.debug("Pydantic v%s", pydantic.__version__)
|
|
69
|
+
|
|
70
|
+
|
|
73
71
|
@cli.command(short_help="Validates a file or directory containing shepherd-recordings")
|
|
74
72
|
@click.argument("in_data", type=click.Path(exists=True, resolve_path=True))
|
|
75
73
|
def validate(in_data: Path) -> None:
|
|
@@ -94,6 +92,20 @@ def validate(in_data: Path) -> None:
|
|
|
94
92
|
|
|
95
93
|
@cli.command(short_help="Extracts recorded IVSamples and stores it to csv")
|
|
96
94
|
@click.argument("in_data", type=click.Path(exists=True, resolve_path=True))
|
|
95
|
+
@click.option(
|
|
96
|
+
"--start",
|
|
97
|
+
"-s",
|
|
98
|
+
default=None,
|
|
99
|
+
type=click.FLOAT,
|
|
100
|
+
help="Start-point in seconds, will be 0 if omitted",
|
|
101
|
+
)
|
|
102
|
+
@click.option(
|
|
103
|
+
"--end",
|
|
104
|
+
"-e",
|
|
105
|
+
default=None,
|
|
106
|
+
type=click.FLOAT,
|
|
107
|
+
help="End-point in seconds, will be max if omitted",
|
|
108
|
+
)
|
|
97
109
|
@click.option(
|
|
98
110
|
"--ds-factor",
|
|
99
111
|
"-f",
|
|
@@ -103,12 +115,25 @@ def validate(in_data: Path) -> None:
|
|
|
103
115
|
)
|
|
104
116
|
@click.option(
|
|
105
117
|
"--separator",
|
|
106
|
-
"-s",
|
|
107
118
|
default=";",
|
|
108
119
|
type=click.STRING,
|
|
109
120
|
help="Set an individual csv-separator",
|
|
110
121
|
)
|
|
111
|
-
|
|
122
|
+
@click.option(
|
|
123
|
+
"--raw",
|
|
124
|
+
"-r",
|
|
125
|
+
is_flag=True,
|
|
126
|
+
help="Plot only power instead of voltage, current & power",
|
|
127
|
+
)
|
|
128
|
+
def extract(
|
|
129
|
+
in_data: Path,
|
|
130
|
+
start: Optional[float],
|
|
131
|
+
end: Optional[float],
|
|
132
|
+
ds_factor: float,
|
|
133
|
+
separator: str,
|
|
134
|
+
*,
|
|
135
|
+
raw: bool = False,
|
|
136
|
+
) -> None:
|
|
112
137
|
"""Extract recorded IVSamples and store them to csv."""
|
|
113
138
|
files = path_to_flist(in_data)
|
|
114
139
|
verbose_level = get_verbose_level()
|
|
@@ -119,41 +144,10 @@ def extract(in_data: Path, ds_factor: float, separator: str) -> None:
|
|
|
119
144
|
logger.info("Extracting IV-Samples from '%s' ...", file.name)
|
|
120
145
|
try:
|
|
121
146
|
with Reader(file, verbose=verbose_level > 2) as shpr:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
"resulting sample-size is too small",
|
|
127
|
-
file.name,
|
|
128
|
-
)
|
|
129
|
-
continue
|
|
130
|
-
# will create a downsampled h5-file (if not existing) and then saving to csv
|
|
131
|
-
ds_file = file.with_suffix(f".downsampled_x{round(ds_factor)}.h5")
|
|
132
|
-
if not ds_file.exists():
|
|
133
|
-
logger.info("Downsampling '%s' by factor x%f ...", file.name, ds_factor)
|
|
134
|
-
with Writer(
|
|
135
|
-
ds_file,
|
|
136
|
-
mode=shpr.get_mode(),
|
|
137
|
-
datatype=shpr.get_datatype(),
|
|
138
|
-
window_samples=shpr.get_window_samples(),
|
|
139
|
-
cal_data=shpr.get_calibration_data(),
|
|
140
|
-
verbose=verbose_level > 2,
|
|
141
|
-
) as shpw:
|
|
142
|
-
shpw["ds_factor"] = ds_factor
|
|
143
|
-
shpw.store_hostname(shpr.get_hostname())
|
|
144
|
-
shpw.store_config(shpr.get_config())
|
|
145
|
-
shpr.downsample(
|
|
146
|
-
shpr.ds_time,
|
|
147
|
-
shpw.ds_time,
|
|
148
|
-
ds_factor=ds_factor,
|
|
149
|
-
is_time=True,
|
|
150
|
-
)
|
|
151
|
-
shpr.downsample(shpr.ds_voltage, shpw.ds_voltage, ds_factor=ds_factor)
|
|
152
|
-
shpr.downsample(shpr.ds_current, shpw.ds_current, ds_factor=ds_factor)
|
|
153
|
-
|
|
154
|
-
with Reader(ds_file, verbose=verbose_level > 2) as shpd:
|
|
155
|
-
shpd.save_csv(shpd["data"], separator)
|
|
156
|
-
except TypeError:
|
|
147
|
+
out_file = shpr.cut_and_downsample_to_file(start, end, ds_factor=ds_factor)
|
|
148
|
+
with Reader(out_file, verbose=verbose_level > 2) as shpd:
|
|
149
|
+
shpd.save_csv(shpd["data"], separator, raw=raw)
|
|
150
|
+
except (TypeError, ValueError):
|
|
157
151
|
logger.exception("ERROR: Will skip file. It caused an exception.")
|
|
158
152
|
|
|
159
153
|
|
|
@@ -256,11 +250,10 @@ def extract_gpio(in_data: Path, separator: str) -> None:
|
|
|
256
250
|
|
|
257
251
|
|
|
258
252
|
@cli.command(
|
|
259
|
-
short_help="Creates an array of
|
|
253
|
+
short_help="Creates an array of down-sampled files from "
|
|
260
254
|
"file or directory containing shepherd-recordings"
|
|
261
255
|
)
|
|
262
256
|
@click.argument("in_data", type=click.Path(exists=True, resolve_path=True))
|
|
263
|
-
# @click.option("--out_data", "-o", type=click.Path(resolve_path=True))
|
|
264
257
|
@click.option(
|
|
265
258
|
"--ds-factor",
|
|
266
259
|
"-f",
|
|
@@ -274,48 +267,45 @@ def extract_gpio(in_data: Path, separator: str) -> None:
|
|
|
274
267
|
type=click.INT,
|
|
275
268
|
help="Alternative Input to determine a downsample-factor (Choose One)",
|
|
276
269
|
)
|
|
277
|
-
|
|
270
|
+
@click.option(
|
|
271
|
+
"--start",
|
|
272
|
+
"-s",
|
|
273
|
+
default=None,
|
|
274
|
+
type=click.FLOAT,
|
|
275
|
+
help="Start-point in seconds, will be 0 if omitted",
|
|
276
|
+
)
|
|
277
|
+
@click.option(
|
|
278
|
+
"--end",
|
|
279
|
+
"-e",
|
|
280
|
+
default=None,
|
|
281
|
+
type=click.FLOAT,
|
|
282
|
+
help="End-point in seconds, will be max if omitted",
|
|
283
|
+
)
|
|
284
|
+
def downsample(
|
|
285
|
+
in_data: Path,
|
|
286
|
+
ds_factor: Optional[float],
|
|
287
|
+
sample_rate: Optional[int],
|
|
288
|
+
start: Optional[float],
|
|
289
|
+
end: Optional[float],
|
|
290
|
+
) -> None:
|
|
278
291
|
"""Create an array of down-sampled files from file or dir containing shepherd-recordings."""
|
|
279
|
-
if ds_factor is None and sample_rate is not None and sample_rate >= 1:
|
|
280
|
-
ds_factor = int(samplerate_sps_default / sample_rate)
|
|
281
|
-
# TODO: shouldn't current sps be based on file rather than default?
|
|
282
|
-
if isinstance(ds_factor, (float, int)) and ds_factor >= 1:
|
|
283
|
-
ds_list = [ds_factor]
|
|
284
|
-
else:
|
|
285
|
-
ds_list = [5, 25, 100, 500, 2_500, 10_000, 50_000, 250_000, 1_000_000]
|
|
286
|
-
|
|
287
292
|
files = path_to_flist(in_data)
|
|
288
293
|
verbose_level = get_verbose_level()
|
|
289
294
|
for file in files:
|
|
290
295
|
try:
|
|
291
296
|
with Reader(file, verbose=verbose_level > 2) as shpr:
|
|
297
|
+
if ds_factor is None and sample_rate is not None and sample_rate >= 1:
|
|
298
|
+
ds_factor = shpr.samplerate_sps / sample_rate
|
|
299
|
+
|
|
300
|
+
if isinstance(ds_factor, (float, int)) and ds_factor >= 1:
|
|
301
|
+
ds_list = [ds_factor]
|
|
302
|
+
else:
|
|
303
|
+
ds_list = [5, 25, 100, 500, 2_500, 10_000, 50_000, 250_000, 1_000_000]
|
|
304
|
+
|
|
292
305
|
for _factor in ds_list:
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
"resulting sample-size is too small",
|
|
297
|
-
file.name,
|
|
298
|
-
)
|
|
299
|
-
break
|
|
300
|
-
ds_file = file.with_suffix(f".downsampled_x{round(_factor)}.h5")
|
|
301
|
-
if ds_file.exists():
|
|
302
|
-
continue
|
|
303
|
-
logger.info("Downsampling '%s' by factor x%f ...", file.name, _factor)
|
|
304
|
-
with Writer(
|
|
305
|
-
ds_file,
|
|
306
|
-
mode=shpr.get_mode(),
|
|
307
|
-
datatype=shpr.get_datatype(),
|
|
308
|
-
window_samples=shpr.get_window_samples(),
|
|
309
|
-
cal_data=shpr.get_calibration_data(),
|
|
310
|
-
verbose=verbose_level > 2,
|
|
311
|
-
) as shpw:
|
|
312
|
-
shpw["ds_factor"] = _factor
|
|
313
|
-
shpw.store_hostname(shpr.get_hostname())
|
|
314
|
-
shpw.store_config(shpr.get_config())
|
|
315
|
-
shpr.downsample(shpr.ds_time, shpw.ds_time, ds_factor=_factor, is_time=True)
|
|
316
|
-
shpr.downsample(shpr.ds_voltage, shpw.ds_voltage, ds_factor=_factor)
|
|
317
|
-
shpr.downsample(shpr.ds_current, shpw.ds_current, ds_factor=_factor)
|
|
318
|
-
except TypeError:
|
|
306
|
+
path_file = shpr.cut_and_downsample_to_file(start, end, _factor)
|
|
307
|
+
logger.info("Created %s", path_file.name)
|
|
308
|
+
except (TypeError, ValueError): # noqa: PERF203
|
|
319
309
|
logger.exception("ERROR: Will skip file. It caused an exception.")
|
|
320
310
|
|
|
321
311
|
|
|
@@ -326,14 +316,14 @@ def downsample(in_data: Path, ds_factor: Optional[float], sample_rate: Optional[
|
|
|
326
316
|
"-s",
|
|
327
317
|
default=None,
|
|
328
318
|
type=click.FLOAT,
|
|
329
|
-
help="Start
|
|
319
|
+
help="Start-point in seconds, will be 0 if omitted",
|
|
330
320
|
)
|
|
331
321
|
@click.option(
|
|
332
322
|
"--end",
|
|
333
323
|
"-e",
|
|
334
324
|
default=None,
|
|
335
325
|
type=click.FLOAT,
|
|
336
|
-
help="End
|
|
326
|
+
help="End-point in seconds, will be max if omitted",
|
|
337
327
|
)
|
|
338
328
|
@click.option(
|
|
339
329
|
"--width",
|
shepherd_data/reader.py
CHANGED
|
@@ -13,7 +13,9 @@ from matplotlib import pyplot as plt
|
|
|
13
13
|
from tqdm import trange
|
|
14
14
|
|
|
15
15
|
from shepherd_core import Reader as CoreReader
|
|
16
|
+
from shepherd_core import Writer as CoreWriter
|
|
16
17
|
from shepherd_core import local_tz
|
|
18
|
+
from shepherd_core.logger import get_verbose_level
|
|
17
19
|
from shepherd_core.logger import logger
|
|
18
20
|
|
|
19
21
|
# import samplerate # noqa: ERA001, TODO: just a test-fn for now
|
|
@@ -37,11 +39,12 @@ class Reader(CoreReader):
|
|
|
37
39
|
) -> None:
|
|
38
40
|
super().__init__(file_path, verbose=verbose)
|
|
39
41
|
|
|
40
|
-
def save_csv(self, h5_group: h5py.Group, separator: str = ";") -> int:
|
|
42
|
+
def save_csv(self, h5_group: h5py.Group, separator: str = ";", *, raw: bool = False) -> int:
|
|
41
43
|
"""Extract numerical data from group and store it into csv.
|
|
42
44
|
|
|
43
45
|
:param h5_group: can be external and should probably be downsampled
|
|
44
46
|
:param separator: used between columns
|
|
47
|
+
:param raw: don't convert to si-units
|
|
45
48
|
:return: number of processed entries
|
|
46
49
|
"""
|
|
47
50
|
if ("time" not in h5_group) or (h5_group["time"].shape[0] < 1):
|
|
@@ -62,11 +65,21 @@ class Reader(CoreReader):
|
|
|
62
65
|
with csv_path.open("w", encoding="utf-8-sig") as csv_file:
|
|
63
66
|
self._logger.info("CSV-Generator will save '%s' to '%s'", h5_group.name, csv_path.name)
|
|
64
67
|
csv_file.write(header + "\n")
|
|
68
|
+
ts_gain = h5_group["time"].attrs.get("gain", 1e-9)
|
|
69
|
+
# for converting data to si - if raw=false
|
|
70
|
+
gains: dict[str, float] = {
|
|
71
|
+
key: h5_group[key].attrs.get("gain", 1.0) for key in datasets[1:]
|
|
72
|
+
}
|
|
73
|
+
offsets: dict[str, float] = {
|
|
74
|
+
key: h5_group[key].attrs.get("offset", 1.0) for key in datasets[1:]
|
|
75
|
+
}
|
|
65
76
|
for idx, time_ns in enumerate(h5_group["time"][:]):
|
|
66
|
-
timestamp = datetime.fromtimestamp(time_ns
|
|
77
|
+
timestamp = datetime.fromtimestamp(time_ns * ts_gain, tz=local_tz())
|
|
67
78
|
csv_file.write(timestamp.strftime("%Y-%m-%d %H:%M:%S.%f"))
|
|
68
79
|
for key in datasets[1:]:
|
|
69
80
|
values = h5_group[key][idx]
|
|
81
|
+
if not raw:
|
|
82
|
+
values = values * gains[key] + offsets[key]
|
|
70
83
|
if isinstance(values, np.ndarray):
|
|
71
84
|
values = separator.join([str(value) for value in values])
|
|
72
85
|
csv_file.write(f"{separator}{values}")
|
|
@@ -225,6 +238,115 @@ class Reader(CoreReader):
|
|
|
225
238
|
data_dst.resize((oblock_len * (iterations - 1) + slice_len,))
|
|
226
239
|
return data_dst
|
|
227
240
|
|
|
241
|
+
def cut_and_downsample_to_file(
|
|
242
|
+
self,
|
|
243
|
+
start_s: Optional[float],
|
|
244
|
+
end_s: Optional[float],
|
|
245
|
+
ds_factor: Optional[float],
|
|
246
|
+
) -> Path:
|
|
247
|
+
"""Cut source to given limits, downsample by factor and store result in separate file.
|
|
248
|
+
|
|
249
|
+
Resulting file-name is derived from input-name by adding
|
|
250
|
+
- ".cut_x_to_y" and
|
|
251
|
+
- ".downsample_x"
|
|
252
|
+
when applicable.
|
|
253
|
+
"""
|
|
254
|
+
# prepare cut
|
|
255
|
+
if not isinstance(start_s, (float, int)):
|
|
256
|
+
start_s = 0
|
|
257
|
+
if not isinstance(end_s, (float, int)):
|
|
258
|
+
end_s = self.runtime_s
|
|
259
|
+
start_s = max(0, start_s)
|
|
260
|
+
end_s = min(self.runtime_s, end_s)
|
|
261
|
+
|
|
262
|
+
start_sample = round(start_s * self.samplerate_sps)
|
|
263
|
+
end_sample = round(end_s * self.samplerate_sps)
|
|
264
|
+
|
|
265
|
+
# test input-parameters
|
|
266
|
+
if end_sample < start_sample:
|
|
267
|
+
raise ValueError(
|
|
268
|
+
"Cut & downsample for %s failed because "
|
|
269
|
+
"end-mark (%.3f) is before start-mark (%.3f).",
|
|
270
|
+
self.file_path.name,
|
|
271
|
+
end_s,
|
|
272
|
+
start_s,
|
|
273
|
+
)
|
|
274
|
+
if ds_factor < 1:
|
|
275
|
+
raise ValueError(
|
|
276
|
+
"Cut & downsample for %s failed because factor < 1",
|
|
277
|
+
self.file_path.name,
|
|
278
|
+
)
|
|
279
|
+
if ((end_sample - start_sample) / ds_factor) < 1000:
|
|
280
|
+
raise ValueError(
|
|
281
|
+
"Cut & downsample for %s failed because " "resulting sample-size is too small",
|
|
282
|
+
self.file_path.name,
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
# assemble file-name of output
|
|
286
|
+
if start_s != 0.0 or end_s != self.runtime_s:
|
|
287
|
+
start_str = f"{start_s:.3f}".replace(".", "s")
|
|
288
|
+
end_str = f"{end_s:.3f}".replace(".", "s")
|
|
289
|
+
cut_str = f".cut_{start_str}_to_{end_str}"
|
|
290
|
+
else:
|
|
291
|
+
cut_str = ""
|
|
292
|
+
|
|
293
|
+
if ds_factor > 1: # noqa: SIM108
|
|
294
|
+
ds_str = f".downsample_x{round(ds_factor)}"
|
|
295
|
+
else:
|
|
296
|
+
ds_str = ""
|
|
297
|
+
|
|
298
|
+
dst_file = self.file_path.resolve().with_suffix(cut_str + ds_str + ".h5")
|
|
299
|
+
if dst_file.exists():
|
|
300
|
+
logger.warning(
|
|
301
|
+
"Cut & Downsample skipped because output-file %s already exists.", dst_file.name
|
|
302
|
+
)
|
|
303
|
+
return dst_file
|
|
304
|
+
|
|
305
|
+
logger.debug(
|
|
306
|
+
"Cut & Downsample '%s' from %.3f s to %.3f s with factor = %.1f ...",
|
|
307
|
+
self.file_path.name,
|
|
308
|
+
start_s,
|
|
309
|
+
end_s,
|
|
310
|
+
ds_factor,
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
# convert data
|
|
314
|
+
with CoreWriter(
|
|
315
|
+
dst_file,
|
|
316
|
+
mode=self.get_mode(),
|
|
317
|
+
datatype=self.get_datatype(),
|
|
318
|
+
window_samples=self.get_window_samples(),
|
|
319
|
+
cal_data=self.get_calibration_data(),
|
|
320
|
+
verbose=get_verbose_level() > 2,
|
|
321
|
+
) as shpw:
|
|
322
|
+
shpw["ds_factor"] = ds_factor
|
|
323
|
+
shpw.store_hostname(self.get_hostname())
|
|
324
|
+
shpw.store_config(self.get_config())
|
|
325
|
+
self.downsample(
|
|
326
|
+
self.ds_time,
|
|
327
|
+
shpw.ds_time,
|
|
328
|
+
start_n=start_sample,
|
|
329
|
+
end_n=end_sample,
|
|
330
|
+
ds_factor=ds_factor,
|
|
331
|
+
is_time=True,
|
|
332
|
+
)
|
|
333
|
+
self.downsample(
|
|
334
|
+
self.ds_voltage,
|
|
335
|
+
shpw.ds_voltage,
|
|
336
|
+
start_n=start_sample,
|
|
337
|
+
end_n=end_sample,
|
|
338
|
+
ds_factor=ds_factor,
|
|
339
|
+
)
|
|
340
|
+
self.downsample(
|
|
341
|
+
self.ds_current,
|
|
342
|
+
shpw.ds_current,
|
|
343
|
+
start_n=start_sample,
|
|
344
|
+
end_n=end_sample,
|
|
345
|
+
ds_factor=ds_factor,
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
return dst_file
|
|
349
|
+
|
|
228
350
|
def resample(
|
|
229
351
|
self,
|
|
230
352
|
data_src: Union[h5py.Dataset, np.ndarray],
|
|
@@ -348,6 +470,8 @@ class Reader(CoreReader):
|
|
|
348
470
|
start_s = 0
|
|
349
471
|
if not isinstance(end_s, (float, int)):
|
|
350
472
|
end_s = self.runtime_s
|
|
473
|
+
start_s = max(0, start_s)
|
|
474
|
+
end_s = min(self.runtime_s, end_s)
|
|
351
475
|
start_sample = round(start_s * self.samplerate_sps)
|
|
352
476
|
end_sample = round(end_s * self.samplerate_sps)
|
|
353
477
|
if end_sample - start_sample < 5:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: shepherd_data
|
|
3
|
-
Version: 2024.
|
|
3
|
+
Version: 2024.11.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>
|
|
@@ -36,7 +36,7 @@ Requires-Dist: numpy
|
|
|
36
36
|
Requires-Dist: pandas >=2.0.0
|
|
37
37
|
Requires-Dist: pyYAML
|
|
38
38
|
Requires-Dist: scipy
|
|
39
|
-
Requires-Dist: shepherd-core[inventory] >=2024.
|
|
39
|
+
Requires-Dist: shepherd-core[inventory] >=2024.11.1
|
|
40
40
|
Requires-Dist: tqdm
|
|
41
41
|
Provides-Extra: dev
|
|
42
42
|
Requires-Dist: shepherd-core[dev] ; extra == 'dev'
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
shepherd_data/__init__.py,sha256=Bj7oLrhZ_tH1yjPc42MFFUP6uyTxS7cQtCQJFFiM4Rs,353
|
|
2
|
+
shepherd_data/cli.py,sha256=6ndpKTZxXYOIogOTxD0Eqha6TtRSLn7_Imd_T6wzidA,13670
|
|
3
|
+
shepherd_data/ivonne.py,sha256=IaHy7RizdaaLAo-cQS-S5xQW_TzHW3dcJjb9hkTLjjY,11900
|
|
4
|
+
shepherd_data/mppt.py,sha256=588KSrLuJfNRKKnnL6ewePLi3zrwaO_PAZypikACrks,3925
|
|
5
|
+
shepherd_data/reader.py,sha256=Fu5QziYNS8ffsWIc4S__Ln_0aF83v-endzpQ5s4seNE,24460
|
|
6
|
+
shepherd_data-2024.11.1.dist-info/METADATA,sha256=jC6j7wcIexQp1zRyLspS7SI8kSNBuUAKwNcBICo8z8M,3440
|
|
7
|
+
shepherd_data-2024.11.1.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
8
|
+
shepherd_data-2024.11.1.dist-info/entry_points.txt,sha256=6PBfY36A1xNOdzLiz-Qoukya_UzFZAwOapwmRNnPeZ8,56
|
|
9
|
+
shepherd_data-2024.11.1.dist-info/top_level.txt,sha256=7-SCTY-TG1mLY72OVKCaqte1hy-X8woxknIUAD3OIxs,14
|
|
10
|
+
shepherd_data-2024.11.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
11
|
+
shepherd_data-2024.11.1.dist-info/RECORD,,
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
shepherd_data/__init__.py,sha256=7qoBbrIem27hArbLNss7PYbdNcvRCzuLegXcJx4skHA,352
|
|
2
|
-
shepherd_data/cli.py,sha256=pv17ILFQCdPSyWgmw0rQIhdsYucqeiWFwJn8hft4ga0,15760
|
|
3
|
-
shepherd_data/ivonne.py,sha256=IaHy7RizdaaLAo-cQS-S5xQW_TzHW3dcJjb9hkTLjjY,11900
|
|
4
|
-
shepherd_data/mppt.py,sha256=588KSrLuJfNRKKnnL6ewePLi3zrwaO_PAZypikACrks,3925
|
|
5
|
-
shepherd_data/reader.py,sha256=eShdgACQLwoOtOYIyB3CjvUgJlUEbRDcUso_3m02C9U,20098
|
|
6
|
-
shepherd_data-2024.9.1.dist-info/METADATA,sha256=34fTRjrhjV1N_nyJtNCprz91K-IjafBywmdR_TBZZis,3438
|
|
7
|
-
shepherd_data-2024.9.1.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
|
8
|
-
shepherd_data-2024.9.1.dist-info/entry_points.txt,sha256=6PBfY36A1xNOdzLiz-Qoukya_UzFZAwOapwmRNnPeZ8,56
|
|
9
|
-
shepherd_data-2024.9.1.dist-info/top_level.txt,sha256=7-SCTY-TG1mLY72OVKCaqte1hy-X8woxknIUAD3OIxs,14
|
|
10
|
-
shepherd_data-2024.9.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
11
|
-
shepherd_data-2024.9.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|