zea 0.0.4__py3-none-any.whl → 0.0.5__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.
- zea/__init__.py +8 -7
- zea/__main__.py +8 -26
- zea/data/__main__.py +6 -3
- zea/data/file.py +19 -74
- zea/display.py +1 -5
- zea/doppler.py +75 -0
- zea/internal/_generate_keras_ops.py +125 -0
- zea/internal/core.py +10 -3
- zea/internal/device.py +33 -16
- zea/internal/notebooks.py +39 -0
- zea/internal/operators.py +10 -0
- zea/internal/parameters.py +75 -19
- zea/internal/viewer.py +24 -24
- zea/io_lib.py +60 -62
- zea/keras_ops.py +1989 -0
- zea/models/__init__.py +6 -3
- zea/models/deeplabv3.py +131 -0
- zea/models/diffusion.py +4 -4
- zea/models/echonetlvh.py +290 -0
- zea/models/presets.py +14 -0
- zea/ops.py +28 -45
- zea/scan.py +10 -3
- zea/tensor_ops.py +150 -0
- zea/tools/fit_scan_cone.py +2 -2
- zea/tools/selection_tool.py +28 -9
- {zea-0.0.4.dist-info → zea-0.0.5.dist-info}/METADATA +5 -2
- {zea-0.0.4.dist-info → zea-0.0.5.dist-info}/RECORD +30 -25
- zea/internal/convert.py +0 -150
- {zea-0.0.4.dist-info → zea-0.0.5.dist-info}/LICENSE +0 -0
- {zea-0.0.4.dist-info → zea-0.0.5.dist-info}/WHEEL +0 -0
- {zea-0.0.4.dist-info → zea-0.0.5.dist-info}/entry_points.txt +0 -0
zea/tensor_ops.py
CHANGED
|
@@ -1270,6 +1270,14 @@ def L2(x):
|
|
|
1270
1270
|
return ops.sqrt(ops.sum(x**2))
|
|
1271
1271
|
|
|
1272
1272
|
|
|
1273
|
+
def L1(x):
|
|
1274
|
+
"""L1 norm of a tensor.
|
|
1275
|
+
|
|
1276
|
+
Implementation of L1 norm: https://mathworld.wolfram.com/L1-Norm.html
|
|
1277
|
+
"""
|
|
1278
|
+
return ops.sum(ops.abs(x))
|
|
1279
|
+
|
|
1280
|
+
|
|
1273
1281
|
def linear_sum_assignment(cost):
|
|
1274
1282
|
"""Greedy linear sum assignment.
|
|
1275
1283
|
|
|
@@ -1325,3 +1333,145 @@ else:
|
|
|
1325
1333
|
def safe_vectorize(pyfunc, excluded=None, signature=None):
|
|
1326
1334
|
"""Just a wrapper around ops.vectorize."""
|
|
1327
1335
|
return ops.vectorize(pyfunc, excluded=excluded, signature=signature)
|
|
1336
|
+
|
|
1337
|
+
|
|
1338
|
+
def apply_along_axis(func1d, axis, arr, *args, **kwargs):
|
|
1339
|
+
"""Apply a function to 1D array slices along an axis.
|
|
1340
|
+
|
|
1341
|
+
Keras implementation of numpy.apply_along_axis using keras.ops.vectorized_map.
|
|
1342
|
+
|
|
1343
|
+
Args:
|
|
1344
|
+
func1d: A callable function with signature ``func1d(arr, /, *args, **kwargs)``
|
|
1345
|
+
where ``*args`` and ``**kwargs`` are the additional positional and keyword
|
|
1346
|
+
arguments passed to apply_along_axis.
|
|
1347
|
+
axis: Integer axis along which to apply the function.
|
|
1348
|
+
arr: The array over which to apply the function.
|
|
1349
|
+
*args: Additional positional arguments passed through to func1d.
|
|
1350
|
+
**kwargs: Additional keyword arguments passed through to func1d.
|
|
1351
|
+
|
|
1352
|
+
Returns:
|
|
1353
|
+
The result of func1d applied along the specified axis.
|
|
1354
|
+
"""
|
|
1355
|
+
# Convert to keras tensor
|
|
1356
|
+
arr = ops.convert_to_tensor(arr)
|
|
1357
|
+
|
|
1358
|
+
# Get array dimensions
|
|
1359
|
+
num_dims = len(arr.shape)
|
|
1360
|
+
|
|
1361
|
+
# Canonicalize axis (handle negative indices)
|
|
1362
|
+
if axis < 0:
|
|
1363
|
+
axis = num_dims + axis
|
|
1364
|
+
|
|
1365
|
+
if axis < 0 or axis >= num_dims:
|
|
1366
|
+
raise ValueError(f"axis {axis} is out of bounds for array of dimension {num_dims}")
|
|
1367
|
+
|
|
1368
|
+
# Create a wrapper function that applies func1d with the additional arguments
|
|
1369
|
+
def func(slice_arr):
|
|
1370
|
+
return func1d(slice_arr, *args, **kwargs)
|
|
1371
|
+
|
|
1372
|
+
# Recursively build up vectorized maps following the JAX pattern
|
|
1373
|
+
# For dimensions after the target axis (right side)
|
|
1374
|
+
for i in range(1, num_dims - axis):
|
|
1375
|
+
prev_func = func
|
|
1376
|
+
|
|
1377
|
+
def make_func(f, dim_offset):
|
|
1378
|
+
def vectorized_func(x):
|
|
1379
|
+
# Move the dimension we want to map over to the front
|
|
1380
|
+
perm = list(range(len(x.shape)))
|
|
1381
|
+
perm[0], perm[dim_offset] = perm[dim_offset], perm[0]
|
|
1382
|
+
x_moved = ops.transpose(x, perm)
|
|
1383
|
+
result = ops.vectorized_map(f, x_moved)
|
|
1384
|
+
# Move the result dimension back if needed
|
|
1385
|
+
if len(result.shape) > 0:
|
|
1386
|
+
result_perm = list(range(len(result.shape)))
|
|
1387
|
+
if len(result_perm) > dim_offset:
|
|
1388
|
+
result_perm[0], result_perm[dim_offset] = (
|
|
1389
|
+
result_perm[dim_offset],
|
|
1390
|
+
result_perm[0],
|
|
1391
|
+
)
|
|
1392
|
+
result = ops.transpose(result, result_perm)
|
|
1393
|
+
return result
|
|
1394
|
+
|
|
1395
|
+
return vectorized_func
|
|
1396
|
+
|
|
1397
|
+
func = make_func(prev_func, i)
|
|
1398
|
+
|
|
1399
|
+
# For dimensions before the target axis (left side)
|
|
1400
|
+
for i in range(axis):
|
|
1401
|
+
prev_func = func
|
|
1402
|
+
|
|
1403
|
+
def make_func(f):
|
|
1404
|
+
return lambda x: ops.vectorized_map(f, x)
|
|
1405
|
+
|
|
1406
|
+
func = make_func(prev_func)
|
|
1407
|
+
|
|
1408
|
+
return func(arr)
|
|
1409
|
+
|
|
1410
|
+
|
|
1411
|
+
def correlate(x, y, mode="full"):
|
|
1412
|
+
"""
|
|
1413
|
+
Complex correlation via splitting real and imaginary parts.
|
|
1414
|
+
Equivalent to np.correlate(x, y, mode).
|
|
1415
|
+
|
|
1416
|
+
NOTE: this function exists because tensorflow does not support complex correlation.
|
|
1417
|
+
NOTE: tensorflow also handles padding differently than numpy, so we manually pad the input.
|
|
1418
|
+
|
|
1419
|
+
Args:
|
|
1420
|
+
x: np.ndarray (complex or real)
|
|
1421
|
+
y: np.ndarray (complex or real)
|
|
1422
|
+
mode: "full", "valid", or "same"
|
|
1423
|
+
"""
|
|
1424
|
+
x = ops.convert_to_tensor(x)
|
|
1425
|
+
y = ops.convert_to_tensor(y)
|
|
1426
|
+
|
|
1427
|
+
is_complex = "complex" in ops.dtype(x) or "complex" in ops.dtype(y)
|
|
1428
|
+
|
|
1429
|
+
# Split into real and imaginary
|
|
1430
|
+
xr, xi = ops.real(x), ops.imag(x)
|
|
1431
|
+
yr, yi = ops.real(y), ops.imag(y)
|
|
1432
|
+
|
|
1433
|
+
# Pad to do full correlation
|
|
1434
|
+
pad_left = ops.shape(y)[0] - 1
|
|
1435
|
+
pad_right = ops.shape(y)[0] - 1
|
|
1436
|
+
xr = ops.pad(xr, [[pad_left, pad_right]])
|
|
1437
|
+
xi = ops.pad(xi, [[pad_left, pad_right]])
|
|
1438
|
+
|
|
1439
|
+
# Correlation: sum over x[n] * conj(y[n+k])
|
|
1440
|
+
rr = ops.correlate(xr, yr, mode="valid")
|
|
1441
|
+
ii = ops.correlate(xi, yi, mode="valid")
|
|
1442
|
+
ri = ops.correlate(xr, yi, mode="valid")
|
|
1443
|
+
ir = ops.correlate(xi, yr, mode="valid")
|
|
1444
|
+
|
|
1445
|
+
real_part = rr + ii
|
|
1446
|
+
imag_part = ir - ri
|
|
1447
|
+
|
|
1448
|
+
real_part = ops.cast(real_part, "complex64")
|
|
1449
|
+
imag_part = ops.cast(imag_part, "complex64")
|
|
1450
|
+
|
|
1451
|
+
complex_tensor = real_part + 1j * imag_part
|
|
1452
|
+
|
|
1453
|
+
# Extract relevant part based on mode
|
|
1454
|
+
full_length = ops.shape(real_part)[0]
|
|
1455
|
+
x_len = ops.shape(x)[0]
|
|
1456
|
+
y_len = ops.shape(y)[0]
|
|
1457
|
+
|
|
1458
|
+
if mode == "same":
|
|
1459
|
+
# Return output of length max(M, N)
|
|
1460
|
+
target_len = ops.maximum(x_len, y_len)
|
|
1461
|
+
start = ops.floor((full_length - target_len) / 2)
|
|
1462
|
+
start = ops.cast(start, "int32")
|
|
1463
|
+
end = start + target_len
|
|
1464
|
+
complex_tensor = complex_tensor[start:end]
|
|
1465
|
+
elif mode == "valid":
|
|
1466
|
+
# Return output of length max(M, N) - min(M, N) + 1
|
|
1467
|
+
target_len = ops.maximum(x_len, y_len) - ops.minimum(x_len, y_len) + 1
|
|
1468
|
+
start = ops.ceil((full_length - target_len) / 2)
|
|
1469
|
+
start = ops.cast(start, "int32")
|
|
1470
|
+
end = start + target_len
|
|
1471
|
+
complex_tensor = complex_tensor[start:end]
|
|
1472
|
+
# For "full" mode, use the entire result (no slicing needed)
|
|
1473
|
+
|
|
1474
|
+
if is_complex:
|
|
1475
|
+
return complex_tensor
|
|
1476
|
+
else:
|
|
1477
|
+
return ops.real(complex_tensor)
|
zea/tools/fit_scan_cone.py
CHANGED
|
@@ -83,8 +83,7 @@ def filter_edge_points_by_boundary(edge_points, is_left=True, min_cone_half_angl
|
|
|
83
83
|
|
|
84
84
|
|
|
85
85
|
def detect_cone_parameters(image, min_cone_half_angle_deg=20, threshold=15):
|
|
86
|
-
"""
|
|
87
|
-
Detect the ultrasound cone parameters from a grayscale image.
|
|
86
|
+
"""Detect the ultrasound cone parameters from a grayscale image.
|
|
88
87
|
|
|
89
88
|
This function performs the following steps:
|
|
90
89
|
1. Thresholds the image to create a binary mask
|
|
@@ -209,6 +208,7 @@ def detect_cone_parameters(image, min_cone_half_angle_deg=20, threshold=15):
|
|
|
209
208
|
apex_x = left_a + left_b * apex_y
|
|
210
209
|
|
|
211
210
|
# Calculate cone height
|
|
211
|
+
max_y = ops.cast(max_y, apex_y.dtype)
|
|
212
212
|
cone_height = max_y - apex_y
|
|
213
213
|
|
|
214
214
|
# Calculate opening angle from the line slopes
|
zea/tools/selection_tool.py
CHANGED
|
@@ -250,10 +250,13 @@ def add_shape_from_mask(ax, mask, **kwargs):
|
|
|
250
250
|
Returns:
|
|
251
251
|
plt.ax: matplotlib axis with shape added
|
|
252
252
|
"""
|
|
253
|
-
#
|
|
254
|
-
|
|
253
|
+
# Pad mask to ensure edge contours are found
|
|
254
|
+
padded_mask = np.pad(mask, pad_width=1, mode="constant", constant_values=0)
|
|
255
|
+
contours = measure.find_contours(padded_mask, 0.5)
|
|
255
256
|
patches = []
|
|
256
257
|
for contour in contours:
|
|
258
|
+
# Remove padding offset
|
|
259
|
+
contour -= 1
|
|
257
260
|
path = pltPath(contour[:, ::-1])
|
|
258
261
|
patch = PathPatch(path, **kwargs)
|
|
259
262
|
patches.append(ax.add_patch(patch))
|
|
@@ -593,10 +596,11 @@ def interpolate_masks(
|
|
|
593
596
|
assert all(mask.shape == mask_shape for mask in masks), "All masks must have the same shape."
|
|
594
597
|
|
|
595
598
|
# distribute number of frames over number of masks
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
599
|
+
base_frames = num_frames // (number_of_masks - 1)
|
|
600
|
+
remainder = num_frames % (number_of_masks - 1)
|
|
601
|
+
num_frames_per_segment = [base_frames] * (number_of_masks - 1)
|
|
602
|
+
for i in range(remainder):
|
|
603
|
+
num_frames_per_segment[i] += 1
|
|
600
604
|
|
|
601
605
|
if rectangle:
|
|
602
606
|
# get the rectangles
|
|
@@ -615,7 +619,6 @@ def interpolate_masks(
|
|
|
615
619
|
for _rectangle in rectangles:
|
|
616
620
|
interpolated_masks.append(reconstruct_mask_from_rectangle(_rectangle, mask_shape))
|
|
617
621
|
return interpolated_masks
|
|
618
|
-
|
|
619
622
|
# get the contours
|
|
620
623
|
polygons = []
|
|
621
624
|
for mask in masks:
|
|
@@ -726,6 +729,17 @@ def update_imshow_with_mask(
|
|
|
726
729
|
return imshow_obj, mask_obj
|
|
727
730
|
|
|
728
731
|
|
|
732
|
+
def ask_for_title():
|
|
733
|
+
print("What are you selecting?")
|
|
734
|
+
title = input("Enter a title for the selection: ")
|
|
735
|
+
if not title:
|
|
736
|
+
raise ValueError("Title cannot be empty.")
|
|
737
|
+
# Convert title to snake_case
|
|
738
|
+
title = title.strip().replace(" ", "_").lower()
|
|
739
|
+
print(f"Title set to: {title}")
|
|
740
|
+
return title
|
|
741
|
+
|
|
742
|
+
|
|
729
743
|
def main():
|
|
730
744
|
"""Main function for interactive selector on multiple images."""
|
|
731
745
|
print(
|
|
@@ -751,6 +765,7 @@ def main():
|
|
|
751
765
|
raise e
|
|
752
766
|
print("No more images selected. Continuing...")
|
|
753
767
|
|
|
768
|
+
title = ask_for_title()
|
|
754
769
|
selector = ask_for_selection_tool()
|
|
755
770
|
|
|
756
771
|
if same_images is True:
|
|
@@ -829,6 +844,10 @@ def main():
|
|
|
829
844
|
else:
|
|
830
845
|
add_shape_from_mask(axs, interpolated_masks[0], alpha=0.5)
|
|
831
846
|
|
|
847
|
+
filestem = Path(file.parent / f"{file.stem}_{title}_annotations.gif")
|
|
848
|
+
np.save(filestem.with_suffix(".npy"), interpolated_masks)
|
|
849
|
+
print(f"Succesfully saved interpolated masks to {log.yellow(filestem.with_suffix('.npy'))}")
|
|
850
|
+
|
|
832
851
|
fps = ask_save_animation_with_fps()
|
|
833
852
|
|
|
834
853
|
ani = FuncAnimation(
|
|
@@ -838,9 +857,9 @@ def main():
|
|
|
838
857
|
fargs=(axs, imshow_obj, images, interpolated_masks, selector),
|
|
839
858
|
interval=1000 / fps,
|
|
840
859
|
)
|
|
841
|
-
filename =
|
|
860
|
+
filename = filestem.with_suffix(".gif")
|
|
842
861
|
ani.save(filename, writer="pillow")
|
|
843
|
-
print(f"Succesfully saved animation as {filename}")
|
|
862
|
+
print(f"Succesfully saved animation as {log.yellow(filename)}")
|
|
844
863
|
|
|
845
864
|
|
|
846
865
|
if __name__ == "__main__":
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: zea
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.5
|
|
4
4
|
Summary: A Toolbox for Cognitive Ultrasound Imaging. Provides a set of tools for processing of ultrasound data, all built in your favorite machine learning framework.
|
|
5
5
|
Keywords: ultrasound,machine learning,beamforming
|
|
6
6
|
Author: Tristan Stevens
|
|
@@ -33,13 +33,14 @@ Requires-Dist: furo ; extra == "dev"
|
|
|
33
33
|
Requires-Dist: furo ; extra == "docs"
|
|
34
34
|
Requires-Dist: h5py (>=3.11)
|
|
35
35
|
Requires-Dist: huggingface_hub (>=0.26)
|
|
36
|
+
Requires-Dist: imageio[ffmpeg] (>=2.0)
|
|
36
37
|
Requires-Dist: ipykernel (>=6.29.5) ; extra == "dev"
|
|
37
38
|
Requires-Dist: ipykernel (>=6.29.5) ; extra == "tests"
|
|
38
39
|
Requires-Dist: ipywidgets ; extra == "dev"
|
|
39
40
|
Requires-Dist: ipywidgets ; extra == "tests"
|
|
40
41
|
Requires-Dist: jax ; extra == "backends"
|
|
41
42
|
Requires-Dist: jax[cuda12-pip] (>=0.4.26) ; extra == "jax"
|
|
42
|
-
Requires-Dist: keras (>=3.
|
|
43
|
+
Requires-Dist: keras (>=3.11)
|
|
43
44
|
Requires-Dist: matplotlib (>=3.8)
|
|
44
45
|
Requires-Dist: mock ; extra == "dev"
|
|
45
46
|
Requires-Dist: mock ; extra == "docs"
|
|
@@ -69,6 +70,8 @@ Requires-Dist: scikit-learn (>=1.4)
|
|
|
69
70
|
Requires-Dist: scipy (>=1.13)
|
|
70
71
|
Requires-Dist: sphinx ; extra == "dev"
|
|
71
72
|
Requires-Dist: sphinx ; extra == "docs"
|
|
73
|
+
Requires-Dist: sphinx-argparse ; extra == "dev"
|
|
74
|
+
Requires-Dist: sphinx-argparse ; extra == "docs"
|
|
72
75
|
Requires-Dist: sphinx-autobuild ; extra == "dev"
|
|
73
76
|
Requires-Dist: sphinx-autobuild ; extra == "docs"
|
|
74
77
|
Requires-Dist: sphinx-autodoc-typehints ; extra == "dev"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
zea/__init__.py,sha256
|
|
2
|
-
zea/__main__.py,sha256=
|
|
1
|
+
zea/__init__.py,sha256=Fur5gTy71o142eTY924plqQwlsghVLeHea2-kae9SaA,2345
|
|
2
|
+
zea/__main__.py,sha256=4OCFujuZ5ooIDMF7xxE4Esin9dfFlgX9PdOi9uB64y8,1569
|
|
3
3
|
zea/agent/__init__.py,sha256=uJjMiPvvCXmUxC2mkSkh1Q9Ege0Vf7WazKX1_Ul80GY,924
|
|
4
4
|
zea/agent/gumbel.py,sha256=WbvSrM8meXtZmDLkyXDGUyRzjB4dWZmNO_qzloRxB_s,3770
|
|
5
5
|
zea/agent/masks.py,sha256=qdSGbTs9449hUxcX6gAl_s47mrs1FKI6U_T2KjS-iz8,6581
|
|
@@ -32,7 +32,7 @@ zea/beamform/phantoms.py,sha256=zow6j4mPXOJjSl31dLQbuDW8rH_qEV2dsfcy-TqkhkI,1108
|
|
|
32
32
|
zea/beamform/pixelgrid.py,sha256=XONJqgWC9XUkEL7iaphy0YBr6xLAyXz-yaTdPQju1r0,5432
|
|
33
33
|
zea/config.py,sha256=mhmTxD1ylyc6zl7yq834-BUiBpcqJ-sNVnJd38yinCs,19509
|
|
34
34
|
zea/data/__init__.py,sha256=h2wKll096dKxTRrEKHnFmgURqp9lDHlqJM884HzmhSY,1757
|
|
35
|
-
zea/data/__main__.py,sha256=
|
|
35
|
+
zea/data/__main__.py,sha256=xEXj3m3gJ6MoV1f9WbDl3QVPMbDXedTj1J9WeT83NrI,909
|
|
36
36
|
zea/data/augmentations.py,sha256=R09_dVkhOFGHiiVFaTjP9pYcHCMtwri9Nz8wsM5mRPY,12686
|
|
37
37
|
zea/data/convert/__init__.py,sha256=xuPIB-Dd8voTTRoQr-Mb5KTbPpWzk46alCgKQ_EZqzY,244
|
|
38
38
|
zea/data/convert/camus.py,sha256=PgFN6b0AgHZRS0JjcsiOGOzoagG-sHvlmhDuNR6iNKo,9555
|
|
@@ -46,60 +46,65 @@ zea/data/convert/picmus.py,sha256=1TK1vDWzfHmnFErtt0ad36TInIiy4fm3nMmfx83G5nw,62
|
|
|
46
46
|
zea/data/data_format.py,sha256=n4OTQKl1newgvTamlPprAsRubAVt3bPeNYHJXNc89G0,25684
|
|
47
47
|
zea/data/dataloader.py,sha256=ZAlWbZB6F43EtLvRcUzfeHVtMhYViJTvyaRb9CmpEFc,14865
|
|
48
48
|
zea/data/datasets.py,sha256=XcNlJVmkfNo7TXp80y4Si_by75Ix2ULIU_iEiNEhl6Q,24492
|
|
49
|
-
zea/data/file.py,sha256=
|
|
49
|
+
zea/data/file.py,sha256=DJHqYlVDNZtQWj0VvytrdGeZEnpDJqc2zZPWz3rF_7k,27152
|
|
50
50
|
zea/data/layers.py,sha256=Tv_dEIX6DZPTVjVMYSPomz1wtkEMrAcX9u9gQkJPRrY,6737
|
|
51
51
|
zea/data/preset_utils.py,sha256=mJ7YC7W9X91__V6Wk2xenORIqZ0reZQerbX3zgapBJM,4408
|
|
52
52
|
zea/data/utils.py,sha256=Y8eO7DznJFiq89SUQmDdiYetQ3aHjf72sC8ih9ooht4,2687
|
|
53
53
|
zea/datapaths.py,sha256=SzsgW4KuZ72aieUbKTUPBmErEPPNcthgI01ixrKX0RQ,20239
|
|
54
|
-
zea/display.py,sha256=
|
|
54
|
+
zea/display.py,sha256=tIrPY2wcQFhdsijgydeNkZviZHkVZDtpz4lFAyPzRv0,24250
|
|
55
|
+
zea/doppler.py,sha256=PG8-GhgTxo2eUjFQ2D6Ag74HD2SkJa6b5LUQjXCS8a8,2994
|
|
55
56
|
zea/interface.py,sha256=2xa3wSNwVlESBa3hWqsJIypjnemioPUGJxEgwl4mDXY,18176
|
|
57
|
+
zea/internal/_generate_keras_ops.py,sha256=0K64fBSDBirTGiwP_qPPT4gdrGwVvKLzPylbHzT-qus,3853
|
|
56
58
|
zea/internal/cache.py,sha256=JHbWJ2vXz_NnXWHXrfSKAhcvi1_JMMeQnBzQIrSlYBo,10559
|
|
57
59
|
zea/internal/checks.py,sha256=Dj8kMY0BY5M170V7NmM9TENyiI7tb6wT9tG6jdrxy-0,10809
|
|
58
60
|
zea/internal/config/create.py,sha256=f8dy6YcAUZbROxwCvORI26ACMRO4Q7EL188KyTL8Bpk,5447
|
|
59
61
|
zea/internal/config/parameters.py,sha256=3YE8aBeiosxTuIT0RAEEMkJPmkykSyZZ7hbmmyGnsuc,6602
|
|
60
62
|
zea/internal/config/validation.py,sha256=vPGFWC-UVtNh8jqfQ4V8HTUIjfnOtsJrqcG2R2ae5hg,6522
|
|
61
|
-
zea/internal/
|
|
62
|
-
zea/internal/
|
|
63
|
-
zea/internal/device.py,sha256=pcgKHWudolflxe6umQh5DVNDz8QtQBZ8tDiWDNwTays,15175
|
|
63
|
+
zea/internal/core.py,sha256=wJHqp3h_MCCkugTPpvmsxNIOOQ6_VAF7-skNUY-bvmc,9587
|
|
64
|
+
zea/internal/device.py,sha256=YM-yuB2wu8hmILP84LfIjxmcLq9mI6FMI_iS8Lr04i0,15841
|
|
64
65
|
zea/internal/git_info.py,sha256=vEeN7cdppNIJPRkC69pUQqtAfTdwCN-tpfo702xpGzY,1040
|
|
65
|
-
zea/internal/
|
|
66
|
-
zea/internal/
|
|
66
|
+
zea/internal/notebooks.py,sha256=57qBEJMzLIfWndZslQ6NphJgU4Wlu_jL_XgDWft_xkY,1136
|
|
67
|
+
zea/internal/operators.py,sha256=F4J5R6L_VBfq5JbYKtqXuMQqk1q-L-n3JaOakcX_fDg,2005
|
|
68
|
+
zea/internal/parameters.py,sha256=kyHbEg0otKN-_kPFPIg4iaHSNBJ-TitFmhahR5DRhlk,19871
|
|
67
69
|
zea/internal/registry.py,sha256=lQsJbYUz1S2eKzE-7shRYWUBulX2TjHTRN37evrYIGA,7884
|
|
68
70
|
zea/internal/setup_zea.py,sha256=P8dmHk_0hwfukaf-DfPxeDofOH4Kj1s5YvUs8yeFqAQ,7800
|
|
69
|
-
zea/internal/viewer.py,sha256=
|
|
70
|
-
zea/io_lib.py,sha256=
|
|
71
|
+
zea/internal/viewer.py,sha256=nXTJwaWM9x8_R3X8YB9B5bNkZwwfVGKUu8pIr2HMweQ,15840
|
|
72
|
+
zea/io_lib.py,sha256=9yjiYQmoyaJ6IYo4SuNZ5ofX8DB67mbypvmKxd8iZqk,12506
|
|
73
|
+
zea/keras_ops.py,sha256=QUN8sX3tNvyxXPcabiE2V41EJNFDIDBdOrwDscPL1aE,65461
|
|
71
74
|
zea/log.py,sha256=UJIL91lHUgWc-vrlJWOn1PX60fX3TFQ5slIs-b5EWEQ,10540
|
|
72
75
|
zea/metrics.py,sha256=22BonPRPs6sfpDqtSEQGC1icNhsSywBak4iaf_1cook,4894
|
|
73
|
-
zea/models/__init__.py,sha256=
|
|
76
|
+
zea/models/__init__.py,sha256=xeyo23kLfXCEy92eev4qLVVA2oSVWsN1XXEMsuwrlBU,4325
|
|
74
77
|
zea/models/base.py,sha256=_l1RlXIYS2V5py-en5llJpX1oU0IXK_hzLhfCYybzHg,7121
|
|
75
78
|
zea/models/carotid_segmenter.py,sha256=qxv4xSSbwLQ3AWeP8xoVCFhpPLOqsN-4dNq1ECkG3FM,5401
|
|
79
|
+
zea/models/deeplabv3.py,sha256=Ew-JIaQgekumVZN--pIQ5XQR5xTj1qMbfLm_xQH9qYo,4967
|
|
76
80
|
zea/models/dense.py,sha256=EwrSawfSTi9oWE55Grr7jtwLXC9MNqEOO3su4oYHqfg,4067
|
|
77
|
-
zea/models/diffusion.py,sha256=
|
|
81
|
+
zea/models/diffusion.py,sha256=Itt6Os7LTtIXBosvqwy9nc2EoClkmIstFgKjALa5DQI,31908
|
|
78
82
|
zea/models/echonet.py,sha256=toLw6QjpdROvGrm6VEuqHuxxKkiAWtX-__5YzrE-LJA,6346
|
|
83
|
+
zea/models/echonetlvh.py,sha256=HlfgzIBg9v6-whTLV-j3g1mopFj4gP7H1AkB9uSI8Ow,10951
|
|
79
84
|
zea/models/generative.py,sha256=iujicyFDuCD7NEk_cZ8thlZ2Rl3Qa8LfkwPsZdWYpR0,2625
|
|
80
85
|
zea/models/gmm.py,sha256=6YYoiizsD7BtISOToEXkki6Cc8iXMkgmPH_rMFQKs3E,8324
|
|
81
86
|
zea/models/layers.py,sha256=hhtBLQgt6ZMKj60FXBNIpThI7gZZeEqkzBMsub_TNFM,1920
|
|
82
87
|
zea/models/lpips.py,sha256=ryJSg2_XIZyOyPP-fcEQKsz3JzlDl9ik4TZPipVbomw,6126
|
|
83
88
|
zea/models/preset_utils.py,sha256=OEs13M92W3NH_lB5_dCvJSNqdW0-QQwKw87QMZg06O4,15396
|
|
84
|
-
zea/models/presets.py,sha256=
|
|
89
|
+
zea/models/presets.py,sha256=cwua5PBC2zT2J_uExcNzjuc_LT_uEhaOjA29e16M_Yw,3012
|
|
85
90
|
zea/models/taesd.py,sha256=Vab5jywo4uxXPXMQ-8VdpOMhVwQsEc_PNztctDzFZfk,8403
|
|
86
91
|
zea/models/unet.py,sha256=B_600WLn3jj_BuhDdRrj5I1XQIHylaQQN8ISq-vt7zM,6392
|
|
87
92
|
zea/models/utils.py,sha256=My6VY27S4udOn7xatIM22Qgn8jED1FmnA2yZw1mcuVw,2015
|
|
88
|
-
zea/ops.py,sha256=
|
|
93
|
+
zea/ops.py,sha256=Pe2H8yQ8T8MrASxfaEPmKux5Eiv6-w7a3SkoJhEyDh0,109511
|
|
89
94
|
zea/probes.py,sha256=991X4ilpMablekNxAHwBU6DoBIZHrmzoJgs2C6zfU0U,7632
|
|
90
|
-
zea/scan.py,sha256=
|
|
95
|
+
zea/scan.py,sha256=vtF60IgP6V2I5wfvT__ZngfFmhqtEGl5LlbCqSEATw0,27339
|
|
91
96
|
zea/simulator.py,sha256=KziYNRNAwIyKNE4nzVp2cbNyLATaaUkF-Ity6O1fx20,11279
|
|
92
|
-
zea/tensor_ops.py,sha256=
|
|
97
|
+
zea/tensor_ops.py,sha256=5cphTpARxlpeAfvY-zcdm5KZec1QuzlpwVMqRwZLNdE,53434
|
|
93
98
|
zea/tools/__init__.py,sha256=QunH0W09HdOLYq2rNyNJCajfZgarLjX-ymiHVwjR9Kg,259
|
|
94
|
-
zea/tools/fit_scan_cone.py,sha256=
|
|
99
|
+
zea/tools/fit_scan_cone.py,sha256=0T6PSmMVb8DmU9yLAc-nqZFd5lhTRMxYCvmDmF3Klx8,24672
|
|
95
100
|
zea/tools/hf.py,sha256=ibuTGaLitK1vOlQdZJuVmDBoUkYRrEfCctj3kiiOQGs,5477
|
|
96
|
-
zea/tools/selection_tool.py,sha256=
|
|
101
|
+
zea/tools/selection_tool.py,sha256=nEALcrHGLb4NzRRcN_bxYCwzVyHKNN6Y21Q9jsuPFI8,30514
|
|
97
102
|
zea/tools/wndb.py,sha256=8XY056arnDKpVV7k-B5PrMa-RANur3ldPSR4GW3jgS4,666
|
|
98
103
|
zea/utils.py,sha256=8gxZaojsC0D2S63gs6lN0ulcSJ1jry3AzOMFvBdl4H4,23351
|
|
99
104
|
zea/visualize.py,sha256=4-bEHRYG3hUukmBkx7x4VBoa3oAJffO3HnnnzTfduDE,23905
|
|
100
105
|
zea/zea_darkmode.mplstyle,sha256=wHTXkgy00tLEbRmr8GZULb5zIzU0MTMn9xC0Z3WT7Bo,42141
|
|
101
|
-
zea-0.0.
|
|
102
|
-
zea-0.0.
|
|
103
|
-
zea-0.0.
|
|
104
|
-
zea-0.0.
|
|
105
|
-
zea-0.0.
|
|
106
|
+
zea-0.0.5.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
107
|
+
zea-0.0.5.dist-info/METADATA,sha256=Usg0MvMgewPYLPS0Illkx1WI6uNy1g_Pn0Vc7wUnA2Q,6626
|
|
108
|
+
zea-0.0.5.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
109
|
+
zea-0.0.5.dist-info/entry_points.txt,sha256=hQcQYCHdMu2LRM1PGZuaGU5EwAjTGErC-QakgwZKZeo,41
|
|
110
|
+
zea-0.0.5.dist-info/RECORD,,
|
zea/internal/convert.py
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
"""This module contains functionality for converting between hdf5, mat and
|
|
2
|
-
dictionary.
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import argparse
|
|
7
|
-
from pathlib import Path
|
|
8
|
-
|
|
9
|
-
import h5py
|
|
10
|
-
import numpy as np
|
|
11
|
-
import scipy.io as sio
|
|
12
|
-
|
|
13
|
-
from zea.data.file import recursively_load_dict_contents_from_group
|
|
14
|
-
from zea.internal.viewer import filename_from_window_dialog
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def load_mat(filename):
|
|
18
|
-
"""
|
|
19
|
-
This function should be called instead of direct scipy.io.loadmat
|
|
20
|
-
as it cures the problem of not properly recovering python dictionaries
|
|
21
|
-
from mat files. It calls the function check keys to cure all entries
|
|
22
|
-
which are still mat-objects
|
|
23
|
-
"""
|
|
24
|
-
|
|
25
|
-
def _check_vars(d):
|
|
26
|
-
"""
|
|
27
|
-
Checks if entries in dictionary are mat-objects. If yes
|
|
28
|
-
todict is called to change them to nested dictionaries
|
|
29
|
-
"""
|
|
30
|
-
for key in d:
|
|
31
|
-
if isinstance(d[key], sio.matlab.mio5_params.mat_struct):
|
|
32
|
-
d[key] = _todict(d[key])
|
|
33
|
-
elif isinstance(d[key], np.ndarray):
|
|
34
|
-
d[key] = _toarray(d[key])
|
|
35
|
-
return d
|
|
36
|
-
|
|
37
|
-
def _todict(matobj):
|
|
38
|
-
"""
|
|
39
|
-
A recursive function which constructs from matobjects nested dictionaries
|
|
40
|
-
"""
|
|
41
|
-
d = {}
|
|
42
|
-
for strg in matobj._fieldnames:
|
|
43
|
-
elem = matobj.__dict__[strg]
|
|
44
|
-
if isinstance(elem, sio.matlab.mio5_params.mat_struct):
|
|
45
|
-
d[strg] = _todict(elem)
|
|
46
|
-
elif isinstance(elem, np.ndarray):
|
|
47
|
-
d[strg] = _toarray(elem)
|
|
48
|
-
else:
|
|
49
|
-
d[strg] = elem
|
|
50
|
-
return d
|
|
51
|
-
|
|
52
|
-
def _toarray(ndarray):
|
|
53
|
-
"""
|
|
54
|
-
A recursive function which constructs ndarray from cellarrays
|
|
55
|
-
(which are loaded as numpy ndarrays), recursing into the elements
|
|
56
|
-
if they contain matobjects.
|
|
57
|
-
"""
|
|
58
|
-
if ndarray.dtype != "float64":
|
|
59
|
-
elem_list = []
|
|
60
|
-
for sub_elem in ndarray:
|
|
61
|
-
if isinstance(sub_elem, sio.matlab.mio5_params.mat_struct):
|
|
62
|
-
elem_list.append(_todict(sub_elem))
|
|
63
|
-
elif isinstance(sub_elem, np.ndarray):
|
|
64
|
-
elem_list.append(_toarray(sub_elem))
|
|
65
|
-
else:
|
|
66
|
-
elem_list.append(sub_elem)
|
|
67
|
-
return np.array(elem_list)
|
|
68
|
-
else:
|
|
69
|
-
return ndarray
|
|
70
|
-
|
|
71
|
-
data = sio.loadmat(filename, struct_as_record=False, squeeze_me=True)
|
|
72
|
-
return _check_vars(data)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def save_dict_to_file(filename, dic):
|
|
76
|
-
"""Save dict to .mat or .hdf5"""
|
|
77
|
-
|
|
78
|
-
filetype = Path(filename).suffix
|
|
79
|
-
assert filetype in [".mat", ".hdf5"]
|
|
80
|
-
|
|
81
|
-
if filetype == ".hdf5":
|
|
82
|
-
with h5py.File(filename, "w") as h5file:
|
|
83
|
-
recursively_save_dict_contents_to_group(h5file, "/", dic)
|
|
84
|
-
elif filetype == ".mat":
|
|
85
|
-
sio.savemat(filename, dic)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def recursively_save_dict_contents_to_group(h5file, path, dic):
|
|
89
|
-
"""Save dict contents to group"""
|
|
90
|
-
for key, item in dic.items():
|
|
91
|
-
if isinstance(item, dict):
|
|
92
|
-
recursively_save_dict_contents_to_group(h5file, path + key + "/", item)
|
|
93
|
-
else:
|
|
94
|
-
h5file[path + key] = item
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def load_dict_from_file(filename, squeeze=True):
|
|
98
|
-
"""dict from file"""
|
|
99
|
-
filetype = Path(filename).suffix
|
|
100
|
-
assert filetype in [".mat", ".hdf5"]
|
|
101
|
-
|
|
102
|
-
v_7_3 = False
|
|
103
|
-
if filetype == ".mat":
|
|
104
|
-
try:
|
|
105
|
-
return load_mat(filename)
|
|
106
|
-
except Exception:
|
|
107
|
-
v_7_3 = True
|
|
108
|
-
|
|
109
|
-
if (filetype == ".hdf5") or (v_7_3 is True):
|
|
110
|
-
with h5py.File(filename, "r", locking=False) as h5file:
|
|
111
|
-
return recursively_load_dict_contents_from_group(h5file, "/", squeeze)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
def strip_matfile_keys(dic):
|
|
115
|
-
"""Strip some unecessary .mat keys"""
|
|
116
|
-
new_dic = {}
|
|
117
|
-
for key, val in dic.items():
|
|
118
|
-
if key not in ["__globals__", "__header__", "__version__"]:
|
|
119
|
-
new_dic[key] = np.squeeze(val)
|
|
120
|
-
return new_dic
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def get_args():
|
|
124
|
-
"""Command line argument parser"""
|
|
125
|
-
parser = argparse.ArgumentParser()
|
|
126
|
-
parser.add_argument("--file", default=None, help="hdf5 file or mat file")
|
|
127
|
-
args = parser.parse_args()
|
|
128
|
-
return args
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if __name__ == "__main__":
|
|
132
|
-
args = get_args()
|
|
133
|
-
data = {}
|
|
134
|
-
if args.file is None:
|
|
135
|
-
file = filename_from_window_dialog(
|
|
136
|
-
"Choose .mat or .hdf5 file",
|
|
137
|
-
filetypes=(("mat or hdf5", "*.mat *.hdf5 *.h5"),),
|
|
138
|
-
)
|
|
139
|
-
else:
|
|
140
|
-
file = Path(args.file)
|
|
141
|
-
|
|
142
|
-
dic = load_dict_from_file(file)
|
|
143
|
-
if file.suffix == ".mat":
|
|
144
|
-
dic = strip_matfile_keys(dic)
|
|
145
|
-
save_dict_to_file(file.with_suffix(".hdf5"), dic)
|
|
146
|
-
|
|
147
|
-
elif file.suffix in [".h5", ".hdf5"]:
|
|
148
|
-
save_dict_to_file(file.with_suffix(".mat"), dic)
|
|
149
|
-
|
|
150
|
-
print(f"Succesfully converted {file}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|