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/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)
@@ -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
@@ -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
- # Create a Path patch
254
- contours = measure.find_contours(mask, 0.5)
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
- num_frames_per_segment = [num_frames // (number_of_masks - 1)] * (number_of_masks - 1)
597
- if num_frames % num_frames_per_segment[0] != 0:
598
- # make sure that number of frames per mask adds up to total number of frames
599
- num_frames_per_segment[-1] += num_frames - sum(num_frames_per_segment)
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 = Path(file.parent.stem + "_" + f"{file.stem}_interpolated_masks.gif")
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.4
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.9)
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=-et4Iz8oJRRaQahurztVr7Rvz9Do7WkXfq5D5CuhX7w,2274
2
- zea/__main__.py,sha256=QQaxECJxTUo99q43OobV1Tc9m4POtmjRbeKqpkCZ4Lo,2020
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=3KKsj-8ZL1k8vWE7mZkGJyn5xfzVTSK_MaplUgXIUCo,857
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=dG6if-hofBzfOTr_39_X_OFlTx7t8s7ggrYR7XwyhI8,29387
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=nvtef82SiOVZJxm8FgykueIsR7yv8pfGIWOLW4XB_lE,24419
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/convert.py,sha256=EDg6vY73vQht-AwwrYUJ2XrE2L64qL3JBXxnft7Xw70,4596
62
- zea/internal/core.py,sha256=QAiN1yFgIm8PGTn8RyE3LyZd5YWpbxuSGwbjfbEYJzU,9387
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/operators.py,sha256=0CMv4s0k8MIlD0uMKcxiHq4YryIfacklBFnCqf7RO0A,1837
66
- zea/internal/parameters.py,sha256=MbYYQQuESQtzXA1b7S3psESdfTbntzQCgljkV_zTlLw,17857
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=VsDehOQgqvVp7gkw0kz2Y2v_My8P8FshJEOCM4E0RIk,15745
70
- zea/io_lib.py,sha256=z65zGUDaRsxeYnddgy9LtEkbHfKhW3O3wPumqozjZvg,12527
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=gBW1pXrD01beK10dlV6GeY6H17Ym_6wrzMDXrbUs1dk,4183
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=DJhrV_NGgRFK8p3kIBelM-0mqvmuDbdxRyWugaftv-0,31841
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=drTQF2XCAxMFSqZtu_6m-kpPtcG6io4DrXsBcdFss-4,2623
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=wgm_p1rbQFFQ5856u2SIYGGTv3dFaJR1ogdMkiteChc,109464
93
+ zea/ops.py,sha256=Pe2H8yQ8T8MrASxfaEPmKux5Eiv6-w7a3SkoJhEyDh0,109511
89
94
  zea/probes.py,sha256=991X4ilpMablekNxAHwBU6DoBIZHrmzoJgs2C6zfU0U,7632
90
- zea/scan.py,sha256=dp-PiQZWk4HnRROeu6cwrGcM8FNjezDzkF05ZJcacVI,26935
95
+ zea/scan.py,sha256=vtF60IgP6V2I5wfvT__ZngfFmhqtEGl5LlbCqSEATw0,27339
91
96
  zea/simulator.py,sha256=KziYNRNAwIyKNE4nzVp2cbNyLATaaUkF-Ity6O1fx20,11279
92
- zea/tensor_ops.py,sha256=TA8N9o8fg6sf-d8JFbMDZAeNzyOBOMbLY--guf2HCjE,48284
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=Pw1kiXUAXenCVIO1nfqWVne2i0eWWXHFmoAQ7l_Qzro,24635
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=dNksdVw_sNcelAyszbrseOTQRDxJpwlapabdh7feNoQ,29848
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.4.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
102
- zea-0.0.4.dist-info/METADATA,sha256=VL_XaEx_hcxAPQTU2EcGEaz1RfYxbZ5p_5XRfmqOA6Q,6489
103
- zea-0.0.4.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
104
- zea-0.0.4.dist-info/entry_points.txt,sha256=hQcQYCHdMu2LRM1PGZuaGU5EwAjTGErC-QakgwZKZeo,41
105
- zea-0.0.4.dist-info/RECORD,,
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