shepherd-data 2025.4.2__tar.gz → 2025.5.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.
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/PKG-INFO +2 -2
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/pyproject.toml +1 -1
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data/__init__.py +1 -1
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data/cli.py +4 -4
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data/ivonne.py +7 -7
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data/mppt.py +3 -3
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data/reader.py +54 -34
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data.egg-info/PKG-INFO +2 -2
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data.egg-info/requires.txt +1 -1
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/tests/test_ivonne.py +3 -3
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/README.md +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/setup.cfg +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data.egg-info/SOURCES.txt +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data.egg-info/dependency_links.txt +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data.egg-info/entry_points.txt +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data.egg-info/top_level.txt +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data.egg-info/zip-safe +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/tests/test_cli.py +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/tests/test_cli_downsample.py +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/tests/test_cli_extract.py +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/tests/test_cli_extract_gpio.py +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/tests/test_cli_extract_meta.py +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/tests/test_cli_extract_uart.py +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/tests/test_cli_plot.py +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/tests/test_cli_validate.py +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/tests/test_cli_version.py +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/tests/test_examples.py +0 -0
- {shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/tests/test_reader.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shepherd_data
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.5.3
|
|
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>
|
|
@@ -35,7 +35,7 @@ Requires-Dist: numpy
|
|
|
35
35
|
Requires-Dist: pandas>=2.0.0
|
|
36
36
|
Requires-Dist: pyYAML
|
|
37
37
|
Requires-Dist: scipy
|
|
38
|
-
Requires-Dist: shepherd-core[inventory]>=2025.
|
|
38
|
+
Requires-Dist: shepherd-core[inventory]>=2025.05.3
|
|
39
39
|
Requires-Dist: tqdm
|
|
40
40
|
Provides-Extra: elf
|
|
41
41
|
Requires-Dist: shepherd-core[elf]; extra == "elf"
|
|
@@ -37,7 +37,7 @@ dependencies = [
|
|
|
37
37
|
"pandas>=2.0.0", # full-version, v2 is OK
|
|
38
38
|
"pyYAML",
|
|
39
39
|
"scipy", # full-version
|
|
40
|
-
"shepherd-core[inventory]>=2025.
|
|
40
|
+
"shepherd-core[inventory]>=2025.05.3", # libs are strongly coupled
|
|
41
41
|
"tqdm", # full-version
|
|
42
42
|
]
|
|
43
43
|
|
|
@@ -92,7 +92,7 @@ def validate(in_data: Path, *, recurse: bool = False) -> None:
|
|
|
92
92
|
sys.exit(int(not valid_dir))
|
|
93
93
|
|
|
94
94
|
|
|
95
|
-
@cli.command(short_help="Extracts recorded
|
|
95
|
+
@cli.command(short_help="Extracts recorded IVTrace and stores it to csv")
|
|
96
96
|
@click.argument("in_data", type=click.Path(exists=True, resolve_path=True))
|
|
97
97
|
@click.option(
|
|
98
98
|
"--start",
|
|
@@ -143,7 +143,7 @@ def extract(
|
|
|
143
143
|
raw: bool = False,
|
|
144
144
|
recurse: bool = False,
|
|
145
145
|
) -> None:
|
|
146
|
-
"""Extract recorded
|
|
146
|
+
"""Extract recorded IVTrace and store them to csv."""
|
|
147
147
|
files = path_to_flist(in_data, recurse=recurse)
|
|
148
148
|
verbose_level = get_verbose_level()
|
|
149
149
|
if not isinstance(ds_factor, (float, int)) or ds_factor < 1:
|
|
@@ -189,12 +189,12 @@ def extract_meta(in_data: Path, separator: str, *, recurse: bool = False) -> Non
|
|
|
189
189
|
with Reader(file, verbose=verbose_level > 2) as shpr:
|
|
190
190
|
shpr.save_metadata()
|
|
191
191
|
csvs_depr = ["sysutil", "timesync"]
|
|
192
|
-
csvs = ["ptp", "sys_util", "pru_util"]
|
|
192
|
+
csvs = ["ptp", "phc2sys", "sys_util", "pru_util"]
|
|
193
193
|
for element in csvs + csvs_depr:
|
|
194
194
|
if element in shpr.h5file:
|
|
195
195
|
shpr.save_csv(shpr[element], separator)
|
|
196
196
|
logs_depr = ["shepherd-log", "dmesg", "exceptions"]
|
|
197
|
-
logs = ["sheep", "kernel", "
|
|
197
|
+
logs = ["sheep", "kernel", "ntp", "uart"]
|
|
198
198
|
for element in logs + logs_depr:
|
|
199
199
|
if element in shpr.h5file:
|
|
200
200
|
shpr.save_log(shpr[element])
|
|
@@ -102,7 +102,7 @@ class Reader:
|
|
|
102
102
|
self.file_size = self.file_path.stat().st_size
|
|
103
103
|
self.data_rate = self.file_size / self.runtime_s if self.runtime_s > 0 else 0
|
|
104
104
|
|
|
105
|
-
def
|
|
105
|
+
def convert_2_ivsurface(
|
|
106
106
|
self,
|
|
107
107
|
shp_output: Path,
|
|
108
108
|
v_max: float = 5.0,
|
|
@@ -137,7 +137,9 @@ class Reader:
|
|
|
137
137
|
curve_interval_us = round(sfw.sample_interval_ns * pts_per_curve / 1000)
|
|
138
138
|
up_factor = self.sample_interval_ns // sfw.sample_interval_ns
|
|
139
139
|
max_elements = math.ceil(sfw.max_elements // up_factor)
|
|
140
|
-
job_iter = trange(
|
|
140
|
+
job_iter = trange(
|
|
141
|
+
0, df_elements_n, max_elements, desc="generate ivsurface", leave=False
|
|
142
|
+
)
|
|
141
143
|
|
|
142
144
|
for idx in job_iter:
|
|
143
145
|
idx_top = min(idx + max_elements, df_elements_n)
|
|
@@ -164,14 +166,14 @@ class Reader:
|
|
|
164
166
|
# - time can be generated and set as a whole
|
|
165
167
|
# - v_proto is repetitive, can also be set as a whole
|
|
166
168
|
|
|
167
|
-
def
|
|
169
|
+
def convert_2_ivtrace(
|
|
168
170
|
self,
|
|
169
171
|
shp_output: Path,
|
|
170
172
|
v_max: float = 5.0,
|
|
171
173
|
duration_s: Optional[float] = None,
|
|
172
174
|
tracker: Optional[MPPTracker] = None,
|
|
173
175
|
) -> None:
|
|
174
|
-
"""Transform shepherd IV curves to shepherd IV
|
|
176
|
+
"""Transform shepherd IV surface / curves to shepherd IV trace / samples .
|
|
175
177
|
|
|
176
178
|
For the 'buck' and 'buck-boost' modes, shepherd takes voltage and current traces.
|
|
177
179
|
These can be recorded with shepherd or generated from existing IV curves by, for
|
|
@@ -212,9 +214,7 @@ class Reader:
|
|
|
212
214
|
interval_us = round(sfw.sample_interval_ns / 1000)
|
|
213
215
|
up_factor = self.sample_interval_ns // sfw.sample_interval_ns
|
|
214
216
|
max_elements = math.ceil(sfw.max_elements // up_factor)
|
|
215
|
-
job_iter = trange(
|
|
216
|
-
0, df_elements_n, max_elements, desc="generate ivsamples", leave=False
|
|
217
|
-
)
|
|
217
|
+
job_iter = trange(0, df_elements_n, max_elements, desc="generate ivtrace", leave=False)
|
|
218
218
|
|
|
219
219
|
for idx in job_iter:
|
|
220
220
|
# select (max_elements + 1) elements, so upsampling is without gaps
|
|
@@ -56,7 +56,7 @@ class MPPTracker(ABC):
|
|
|
56
56
|
"""Apply harvesting model to input data.
|
|
57
57
|
|
|
58
58
|
:param coeffs: ivonne coefficients
|
|
59
|
-
:return:
|
|
59
|
+
:return: ivtrace-data
|
|
60
60
|
"""
|
|
61
61
|
|
|
62
62
|
|
|
@@ -76,7 +76,7 @@ class OpenCircuitTracker(MPPTracker):
|
|
|
76
76
|
"""Apply harvesting model to input data.
|
|
77
77
|
|
|
78
78
|
:param coeffs: ivonne coefficients
|
|
79
|
-
:return:
|
|
79
|
+
:return: ivtrace-data
|
|
80
80
|
"""
|
|
81
81
|
coeffs["icurve"] = coeffs.apply(lambda x: iv_model(self.v_proto, x), axis=1)
|
|
82
82
|
if "voc" not in coeffs.columns:
|
|
@@ -106,7 +106,7 @@ class OptimalTracker(MPPTracker):
|
|
|
106
106
|
"""Apply harvesting model to input data.
|
|
107
107
|
|
|
108
108
|
:param coeffs: ivonne coefficients
|
|
109
|
-
:return:
|
|
109
|
+
:return: ivtrace-data
|
|
110
110
|
"""
|
|
111
111
|
coeffs["icurve"] = coeffs.apply(lambda x: iv_model(self.v_proto, x), axis=1)
|
|
112
112
|
coeffs["pcurve"] = coeffs.apply(lambda x: self.v_proto * x["icurve"], axis=1)
|
|
@@ -16,6 +16,7 @@ from tqdm import trange
|
|
|
16
16
|
from shepherd_core import Reader as CoreReader
|
|
17
17
|
from shepherd_core import Writer as CoreWriter
|
|
18
18
|
from shepherd_core import local_tz
|
|
19
|
+
from shepherd_core.data_models import EnergyDType
|
|
19
20
|
from shepherd_core.logger import get_verbose_level
|
|
20
21
|
from shepherd_core.logger import logger
|
|
21
22
|
|
|
@@ -92,7 +93,7 @@ class Reader(CoreReader):
|
|
|
92
93
|
return h5_group["time"][:].shape[0]
|
|
93
94
|
|
|
94
95
|
def save_log(self, h5_group: h5py.Group, *, add_timestamp: bool = True) -> int:
|
|
95
|
-
"""Save dataset from
|
|
96
|
+
"""Save dataset from groups as log, optimal for logged kernel- and console-output.
|
|
96
97
|
|
|
97
98
|
:param h5_group: can be external
|
|
98
99
|
:param add_timestamp: can be external
|
|
@@ -175,7 +176,8 @@ class Reader(CoreReader):
|
|
|
175
176
|
) -> Union[None, h5py.Dataset, np.ndarray]:
|
|
176
177
|
"""Sample down iv-data.
|
|
177
178
|
|
|
178
|
-
Warning: only valid for IV-Stream, not IV-Curves
|
|
179
|
+
Warning: only valid for IV-Stream, not IV-Curves,
|
|
180
|
+
TODO: globally rename to IVTrace, IVSurface
|
|
179
181
|
|
|
180
182
|
:param data_src: a h5-dataset to digest, can be external
|
|
181
183
|
:param data_dst: can be a dataset, numpy-array or None (will be created internally then)
|
|
@@ -187,8 +189,8 @@ class Reader(CoreReader):
|
|
|
187
189
|
"""
|
|
188
190
|
from scipy import signal # here due to massive delay
|
|
189
191
|
|
|
190
|
-
if self.get_datatype() ==
|
|
191
|
-
self._logger.warning("Downsampling-Function was not written for
|
|
192
|
+
if self.get_datatype() == EnergyDType.ivsurface:
|
|
193
|
+
self._logger.warning("Downsampling-Function was not written for IVSurfaces")
|
|
192
194
|
ds_factor = max(1, math.floor(ds_factor))
|
|
193
195
|
|
|
194
196
|
if isinstance(end_n, (int, float)):
|
|
@@ -201,9 +203,9 @@ class Reader(CoreReader):
|
|
|
201
203
|
if data_len == 0:
|
|
202
204
|
self._logger.warning("downsampling failed because of data_len = 0")
|
|
203
205
|
return data_dst
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
iterations = math.ceil(data_len /
|
|
206
|
+
chunk_size_inp = min(self.max_elements, data_len)
|
|
207
|
+
chunk_size_out = round(chunk_size_inp / ds_factor)
|
|
208
|
+
iterations = math.ceil(data_len / chunk_size_inp)
|
|
207
209
|
dest_len = math.floor(data_len / ds_factor)
|
|
208
210
|
if data_dst is None:
|
|
209
211
|
data_dst = np.empty((dest_len,))
|
|
@@ -222,8 +224,13 @@ class Reader(CoreReader):
|
|
|
222
224
|
)
|
|
223
225
|
# filter state - needed for sliced calculation
|
|
224
226
|
f_state = np.zeros((filter_.shape[0], 2))
|
|
227
|
+
# prime the state to avoid starting from 0
|
|
228
|
+
if not is_time and ds_factor > 1:
|
|
229
|
+
slice_ds = data_src[start_n : start_n + self.CHUNK_SAMPLES_N]
|
|
230
|
+
slice_ds[:] = slice_ds[:].mean()
|
|
231
|
+
slice_ds, f_state = signal.sosfilt(filter_, slice_ds, zi=f_state)
|
|
225
232
|
|
|
226
|
-
|
|
233
|
+
output_pos = 0
|
|
227
234
|
for _iter in trange(
|
|
228
235
|
0,
|
|
229
236
|
iterations,
|
|
@@ -231,16 +238,22 @@ class Reader(CoreReader):
|
|
|
231
238
|
leave=False,
|
|
232
239
|
disable=iterations < 8,
|
|
233
240
|
):
|
|
234
|
-
slice_ds = data_src[
|
|
241
|
+
slice_ds = data_src[
|
|
242
|
+
start_n + _iter * chunk_size_inp : start_n + (_iter + 1) * chunk_size_inp
|
|
243
|
+
]
|
|
235
244
|
if not is_time and ds_factor > 1:
|
|
236
245
|
slice_ds, f_state = signal.sosfilt(filter_, slice_ds, zi=f_state)
|
|
237
246
|
slice_ds = slice_ds[::ds_factor]
|
|
238
|
-
slice_len = min(dest_len - _iter *
|
|
239
|
-
data_dst[
|
|
247
|
+
slice_len = min(dest_len - _iter * chunk_size_out, chunk_size_out, len(slice_ds))
|
|
248
|
+
data_dst[output_pos : output_pos + slice_len] = slice_ds[:slice_len]
|
|
249
|
+
# workaround to allow processing last slice (often smaller than expected),
|
|
250
|
+
# wanted: [_iter * chunk_size_out : (_iter + 1) * chunk_size_out]
|
|
251
|
+
# this prevents future parallel processing!
|
|
252
|
+
output_pos += slice_len
|
|
240
253
|
if isinstance(data_dst, np.ndarray):
|
|
241
|
-
data_dst.resize((
|
|
254
|
+
data_dst.resize((output_pos,), refcheck=False)
|
|
242
255
|
else:
|
|
243
|
-
data_dst.resize((
|
|
256
|
+
data_dst.resize((output_pos,))
|
|
244
257
|
return data_dst
|
|
245
258
|
|
|
246
259
|
def cut_and_downsample_to_file(
|
|
@@ -269,24 +282,20 @@ class Reader(CoreReader):
|
|
|
269
282
|
|
|
270
283
|
# test input-parameters
|
|
271
284
|
if end_sample < start_sample:
|
|
272
|
-
|
|
273
|
-
"Cut & downsample for
|
|
274
|
-
"end-mark (
|
|
275
|
-
self.file_path.name,
|
|
276
|
-
end_s,
|
|
277
|
-
start_s,
|
|
285
|
+
msg = (
|
|
286
|
+
f"Cut & downsample for {self.file_path.name} failed because "
|
|
287
|
+
f"end-mark ({end_s:.3f}) is before start-mark ({start_s:.3f})."
|
|
278
288
|
)
|
|
289
|
+
raise ValueError(msg)
|
|
279
290
|
if ds_factor < 1:
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
self.file_path.name,
|
|
283
|
-
)
|
|
291
|
+
msg = f"Cut & downsample for {self.file_path.name} failed because factor < 1"
|
|
292
|
+
raise ValueError(msg)
|
|
284
293
|
if ((end_sample - start_sample) / ds_factor) < 1000:
|
|
285
|
-
|
|
286
|
-
"Cut & downsample for
|
|
287
|
-
|
|
294
|
+
msg = (
|
|
295
|
+
f"Cut & downsample for {self.file_path.name} failed because "
|
|
296
|
+
f"resulting sample-size is too small",
|
|
288
297
|
)
|
|
289
|
-
|
|
298
|
+
raise ValueError(msg)
|
|
290
299
|
# assemble file-name of output
|
|
291
300
|
if start_s != 0.0 or end_s != self.runtime_s:
|
|
292
301
|
start_str = f"{start_s:.3f}".replace(".", "s")
|
|
@@ -370,8 +379,8 @@ class Reader(CoreReader):
|
|
|
370
379
|
:return: resampled iv-data
|
|
371
380
|
"""
|
|
372
381
|
self._logger.error("Resampling is still under construction - do not use for now!")
|
|
373
|
-
if self.get_datatype() ==
|
|
374
|
-
self._logger.warning("Resampling-Function was not written for
|
|
382
|
+
if self.get_datatype() == EnergyDType.ivsurface:
|
|
383
|
+
self._logger.warning("Resampling-Function was not written for IVSurfaces")
|
|
375
384
|
return data_dst
|
|
376
385
|
if isinstance(end_n, (int, float)):
|
|
377
386
|
_end_n = min(data_src.shape[0], round(end_n))
|
|
@@ -466,8 +475,8 @@ class Reader(CoreReader):
|
|
|
466
475
|
:param relative_timestamp: treat
|
|
467
476
|
:return: down-sampled size of ~ self.max_elements
|
|
468
477
|
"""
|
|
469
|
-
if self.get_datatype() ==
|
|
470
|
-
self._logger.warning("Plot-Function was not written for
|
|
478
|
+
if self.get_datatype() == EnergyDType.ivsurface:
|
|
479
|
+
self._logger.warning("Plot-Function was not written for IVSurfaces.")
|
|
471
480
|
if not isinstance(start_s, (float, int)):
|
|
472
481
|
start_s = 0
|
|
473
482
|
if not isinstance(end_s, (float, int)):
|
|
@@ -536,11 +545,20 @@ class Reader(CoreReader):
|
|
|
536
545
|
# last axis is set below
|
|
537
546
|
|
|
538
547
|
for date in data:
|
|
548
|
+
samples_n = min(len(date["time"]), len(date["voltage"]), len(date["current"]))
|
|
539
549
|
if not only_pwr:
|
|
540
|
-
axs[0].plot(
|
|
541
|
-
|
|
550
|
+
axs[0].plot(
|
|
551
|
+
date["time"][:samples_n], date["voltage"][:samples_n], label=date["name"]
|
|
552
|
+
)
|
|
553
|
+
axs[1].plot(
|
|
554
|
+
date["time"][:samples_n],
|
|
555
|
+
date["current"][:samples_n] * 10**3,
|
|
556
|
+
label=date["name"],
|
|
557
|
+
)
|
|
542
558
|
axs[-1].plot(
|
|
543
|
-
date["time"]
|
|
559
|
+
date["time"][:samples_n],
|
|
560
|
+
date["voltage"][:samples_n] * date["current"][:samples_n] * 10**3,
|
|
561
|
+
label=date["name"],
|
|
544
562
|
)
|
|
545
563
|
|
|
546
564
|
if len(data) > 1:
|
|
@@ -551,6 +569,8 @@ class Reader(CoreReader):
|
|
|
551
569
|
# deactivates offset-creation for ax-ticks
|
|
552
570
|
ax.get_yaxis().get_major_formatter().set_useOffset(False)
|
|
553
571
|
ax.get_xaxis().get_major_formatter().set_useOffset(False)
|
|
572
|
+
# add a thin and light gray grid, TODO: add option to switch off?
|
|
573
|
+
ax.grid(color="0.8", linewidth=0.5)
|
|
554
574
|
return fig
|
|
555
575
|
|
|
556
576
|
def plot_to_file(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shepherd_data
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.5.3
|
|
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>
|
|
@@ -35,7 +35,7 @@ Requires-Dist: numpy
|
|
|
35
35
|
Requires-Dist: pandas>=2.0.0
|
|
36
36
|
Requires-Dist: pyYAML
|
|
37
37
|
Requires-Dist: scipy
|
|
38
|
-
Requires-Dist: shepherd-core[inventory]>=2025.
|
|
38
|
+
Requires-Dist: shepherd-core[inventory]>=2025.05.3
|
|
39
39
|
Requires-Dist: tqdm
|
|
40
40
|
Provides-Extra: elf
|
|
41
41
|
Requires-Dist: shepherd-core[elf]; extra == "elf"
|
|
@@ -23,13 +23,13 @@ def test_convert_ivonne(tmp_path: Path, example_path: Path) -> None:
|
|
|
23
23
|
|
|
24
24
|
with ivonne.Reader(inp_path) as ifr:
|
|
25
25
|
ifr.upsample_2_isc_voc(isc_path, duration_s=20)
|
|
26
|
-
ifr.
|
|
26
|
+
ifr.convert_2_ivsurface(ivc_path, duration_s=20)
|
|
27
27
|
|
|
28
28
|
tr_voc = mppt.OpenCircuitTracker(ratio=0.76)
|
|
29
29
|
tr_opt = mppt.OptimalTracker()
|
|
30
30
|
|
|
31
|
-
ifr.
|
|
32
|
-
ifr.
|
|
31
|
+
ifr.convert_2_ivtrace(voc_path, tracker=tr_voc, duration_s=20)
|
|
32
|
+
ifr.convert_2_ivtrace(opt_path, tracker=tr_opt, duration_s=20)
|
|
33
33
|
|
|
34
34
|
energies = {}
|
|
35
35
|
for file_path in [isc_path, ivc_path, voc_path, opt_path]:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shepherd_data-2025.4.2 → shepherd_data-2025.5.3}/shepherd_data.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|