AOT-biomaps 2.9.318__py3-none-any.whl → 2.9.321__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.

Potentially problematic release.


This version of AOT-biomaps might be problematic. Click here for more details.

@@ -157,8 +157,6 @@ def calculate_envelope_squared(field):
157
157
  print(f"Erreur dans calculate_envelope_squared: {e}")
158
158
  raise
159
159
 
160
-
161
-
162
160
  def getPattern(pathFile):
163
161
  """
164
162
  Get the pattern from a file path.
@@ -0,0 +1,60 @@
1
+ import numpy as np
2
+
3
+ def calc_mat_os(xm, fx, dx, bool_active_list, signal_type):
4
+ num_els = len(xm)
5
+
6
+ # Cas limite : Fréquence nulle (Décimation 0)
7
+ if fx == 0:
8
+ if signal_type == 'cos':
9
+ # cos(0) = 1 -> Tout est actif
10
+ mask = np.ones(num_els, dtype=bool)
11
+ else:
12
+ # sin(0) = 0 -> Tout est inactif
13
+ mask = np.zeros(num_els, dtype=bool)
14
+ else:
15
+ # Calcul normal pour fx > 0
16
+ half_period_elements = round(1 / (2 * fx * dx))
17
+
18
+ # Sécurité : si fx est tellement grand que half_period < 1
19
+ half_period_elements = max(1, half_period_elements)
20
+
21
+ indices = np.arange(num_els)
22
+ if signal_type == 'cos':
23
+ mask = ((indices // half_period_elements) % 2 == 0)
24
+ else:
25
+ # Déphasage de 90° pour le sinus : on décale d'une demi-demi-période
26
+ shift = half_period_elements // 2
27
+ mask = (((indices + shift) // half_period_elements) % 2 == 0)
28
+
29
+ return np.tile(mask[:, np.newaxis], (1, bool_active_list.shape[1]))
30
+
31
+ def convert_to_hex_list(matrix):
32
+ """
33
+ Convertit une matrice binaire en liste de strings hexa (paquets de 4 bits).
34
+ Chaque colonne devient une chaîne de caractères.
35
+ """
36
+ n_els, n_scans = matrix.shape
37
+
38
+ # 1. Padding pour s'assurer que n_els est multiple de 4
39
+ remainder = n_els % 4
40
+ if remainder != 0:
41
+ padding = np.zeros((4 - remainder, n_scans))
42
+ matrix = np.vstack([matrix, padding])
43
+
44
+ # 2. Reshape pour isoler des blocs de 4 bits (nibbles)
45
+ # Shape résultante : (Nombre de blocs, 4 bits, Nombre de scans)
46
+ blocks = matrix.reshape(-1, 4, n_scans)
47
+
48
+ # 3. Calcul de la valeur décimale de chaque bloc (0 à 15)
49
+ # On considère le premier élément comme le bit de poids faible (LSB)
50
+ weights = np.array([1, 2, 4, 8]).reshape(1, 4, 1)
51
+ dec_values = np.sum(blocks * weights, axis=1).astype(int)
52
+
53
+ # 4. Conversion en caractères Hexadécimaux
54
+ # On définit la table de conversion pour la rapidité
55
+ hex_table = np.array(list("0123456789abcdef"))
56
+ hex_matrix = hex_table[dec_values]
57
+
58
+ # 5. Assemblage des chaînes (de l'élément N vers 0 pour l'ordre Shift Register standard)
59
+ return ["".join(hex_matrix[::-1, col]) for col in range(n_scans)]
60
+
@@ -2,6 +2,7 @@ from ._mainExperiment import Experiment
2
2
  from AOT_biomaps.AOT_Acoustic.AcousticEnums import WaveType
3
3
  from AOT_biomaps.AOT_Acoustic.StructuredWave import StructuredWave
4
4
  from AOT_biomaps.Config import config
5
+ from AOT_biomaps.AOT_Experiment.ExperimentTools import calc_mat_os, convert_to_hex_list
5
6
  import os
6
7
  import psutil
7
8
  import numpy as np
@@ -273,7 +274,7 @@ class Tomography(Experiment):
273
274
  line = f"({coords}, {angles})\n"
274
275
  file.write(line)
275
276
 
276
- def generateActiveList(self, N):
277
+ def generateActiveList(self, N, decimations = None, angles = None):
277
278
  """
278
279
  Génère une liste de patterns d'activation équilibrés et réguliers.
279
280
  Args:
@@ -281,11 +282,15 @@ class Tomography(Experiment):
281
282
  Returns:
282
283
  list: Liste de strings au format "hex_angle".
283
284
  """
285
+ if decimations is not None and angles is not None:
286
+ self._genereate_patterns_from_decimations(decimations, angles)
284
287
  if N < 1:
285
288
  raise ValueError("N must be a positive integer.")
286
289
  self.patterns = self._generate_patterns(N)
287
290
  if not self._check_patterns(self.patterns):
288
291
  raise ValueError("Generated patterns failed validation.")
292
+
293
+
289
294
 
290
295
  def selectAngles(self, angles):
291
296
 
@@ -337,7 +342,76 @@ class Tomography(Experiment):
337
342
  self.AOsignal_withoutTumor = self.AOsignal_withoutTumor[:, indices]
338
343
  self.AcousticFields = newAcousticFields
339
344
 
340
- def _generate_patterns(self, N):
345
+ def _genereate_patterns_from_decimations(self, decimations, angles):
346
+ if isinstance(decimations, list): decimations = np.array(decimations)
347
+ if isinstance(angles, list): angles = np.array(angles)
348
+
349
+ angles = np.sort(angles)
350
+ decimations = np.sort(decimations)
351
+
352
+ num_elements = self.params.acoustic['num_elements']
353
+ dx_mm = self.params.general['dx'] * 1e3
354
+
355
+ # --- Calcul du nombre de Scans ---
356
+ if 0 in decimations:
357
+ Nscans = 4 * angles.shape[0] * (decimations.shape[0] - 1) + angles.shape[0]
358
+ offSet = angles.shape[0]
359
+ else:
360
+ Nscans = 4 * angles.shape[0] * decimations.shape[0]
361
+ offSet = 0
362
+
363
+ ActiveLIST = np.ones((num_elements, Nscans))
364
+ Xm = np.arange(1, num_elements + 1) * dx_mm
365
+ dFx = 1 / (num_elements * dx_mm)
366
+
367
+ # On traite séparément les décimations non nulles pour la boucle
368
+ active_decimations = decimations[decimations != 0]
369
+
370
+ for i_dec in range(len(active_decimations)):
371
+ idx_base = (np.arange(len(angles))) + (i_dec * 4 * len(angles)) + offSet
372
+
373
+ Icos = idx_base
374
+ Incos = idx_base + len(angles)
375
+ Isin = idx_base + 2 * len(angles)
376
+ Insin = idx_base + 3 * len(angles)
377
+
378
+ fx = dFx * active_decimations[i_dec]
379
+
380
+ # Remplissage des 4 phases
381
+ valid_icos = Icos[Icos < Nscans]
382
+ if valid_icos.size > 0:
383
+ ActiveLIST[:, valid_icos] = calc_mat_os(Xm, fx, dx_mm, ActiveLIST[:, valid_icos], 'cos')
384
+ if (Incos < Nscans).any():
385
+ ActiveLIST[:, Incos[Incos < Nscans]] = 1 - ActiveLIST[:, valid_icos]
386
+
387
+ valid_isin = Isin[Isin < Nscans]
388
+ if valid_isin.size > 0:
389
+ ActiveLIST[:, valid_isin] = calc_mat_os(Xm, fx, dx_mm, ActiveLIST[:, valid_isin], 'sin')
390
+ if (Insin < Nscans).any():
391
+ ActiveLIST[:, Insin[Insin < Nscans]] = 1 - ActiveLIST[:, valid_isin]
392
+
393
+ # --- Conversion au format attendu ---
394
+ # 1. On convertit toute la matrice en liste de strings Hexa
395
+ hexa_list = convert_to_hex_list(ActiveLIST)
396
+
397
+ # 2. Fonction interne de formatage d'angle (pour coller à votre ancien code)
398
+ def format_angle(a):
399
+ return f"{'1' if a < 0 else '0'}{abs(a):02d}"
400
+
401
+ # 3. Construction de la liste de dictionnaires
402
+ patterns = []
403
+ for i in range(Nscans):
404
+ # On retrouve l'angle correspondant à l'index i
405
+ # La logique est cyclique sur la taille de 'angles'
406
+ angle_val = angles[i % len(angles)]
407
+
408
+ hex_pattern = hexa_list[i]
409
+ pair = f"{hex_pattern}_{format_angle(angle_val)}"
410
+ patterns.append({"fileName": pair})
411
+
412
+ return patterns
413
+
414
+ def _generate_patterns(self, N,angles = None):
341
415
  def format_angle(a):
342
416
  return f"{'1' if a < 0 else '0'}{abs(a):02d}"
343
417
 
@@ -348,7 +422,13 @@ class Tomography(Experiment):
348
422
  return hex_string
349
423
 
350
424
  num_elements = self.params.acoustic['num_elements']
351
- angle_choices = list(range(-20, 21))
425
+ if angles is None:
426
+ angle_choices = list(range(-20, 21))
427
+ else:
428
+ # convert np.array to list if necessary
429
+ if isinstance(angles, np.ndarray):
430
+ angles = angles.tolist()
431
+ angle_choices = angles
352
432
 
353
433
  # 1. Trouver TOUS les diviseurs PAIRS de num_elements (y compris num_elements)
354
434
  divs = [d for d in range(2, num_elements + 1) if num_elements % d == 0 and d % 2 == 0]
@@ -451,7 +531,7 @@ class Tomography(Experiment):
451
531
  divergence_deg (float): Angle d'ouverture du masque pour suivre l'élargissement du faisceau.
452
532
  0.0 = Droit, 0.5 = Légère ouverture (conseillé).
453
533
  """
454
- print(f"Application de l'apodisation (Alpha={alpha}, Div={divergence_deg}°) sur {len(self.AcousticFields)} champs...")
534
+ print(f"Applying apodization (Alpha={alpha}, Div={divergence_deg}°) on {len(self.AcousticFields)} fields...")
455
535
 
456
536
  probe_width = self.params.acoustic['num_elements'] * self.params.acoustic['element_width']
457
537
 
@@ -512,7 +592,7 @@ class Tomography(Experiment):
512
592
  # 8. Mise à jour de l'objet
513
593
  self.AcousticFields[i].field = field_apodized
514
594
 
515
- print("Apodisation terminée.")
595
+ print("Apodisation done.")
516
596
 
517
597
  # PRIVATE METHODS
518
598
  def _generateAcousticFields_STRUCT_CPU(self, fieldDataPath=None, show_log=False, nameBlock=None):
@@ -221,7 +221,6 @@ def calculate_memory_requirement(SMatrix, y):
221
221
  # --- 3. Final Result ---
222
222
  return total_bytes / (1024 ** 3)
223
223
 
224
-
225
224
  def check_gpu_memory(device_index, required_memory, show_logs=True):
226
225
  """Check if enough memory is available on the specified GPU."""
227
226
  free_memory, _ = torch.cuda.mem_get_info(f"cuda:{device_index}")
@@ -252,7 +251,6 @@ def _backward_projection(SMatrix, e_p, c_p):
252
251
  total += SMatrix[_t, _z, _x, _n] * e_p[_t, _n]
253
252
  c_p[_z, _x] = total
254
253
 
255
-
256
254
  def _build_adjacency_sparse(Z, X, device, corner=(0.5 - np.sqrt(2) / 4) / np.sqrt(2), face=0.5 - np.sqrt(2) / 4,dtype=torch.float32):
257
255
  rows, cols, weights = [], [], []
258
256
  for z in range(Z):
@@ -273,7 +271,6 @@ def _build_adjacency_sparse(Z, X, device, corner=(0.5 - np.sqrt(2) / 4) / np.sqr
273
271
  index, values = coalesce(index, values, m=Z*X, n=Z*X)
274
272
  return index, values
275
273
 
276
-
277
274
  def power_method(P, PT, data, Z, X, n_it=10):
278
275
  x = torch.randn(Z * X, device=data.device)
279
276
  x = x / torch.norm(x)
AOT_biomaps/__init__.py CHANGED
@@ -85,7 +85,7 @@ from .AOT_Recon.AOT_PotentialFunctions.RelativeDifferences import *
85
85
  from .Config import config
86
86
  from .Settings import *
87
87
 
88
- __version__ = '2.9.318'
88
+ __version__ = '2.9.321'
89
89
  __process__ = config.get_process()
90
90
 
91
91
  def initialize(process=None):
@@ -178,6 +178,9 @@ def initialize(process=None):
178
178
 
179
179
 
180
180
 
181
+
182
+
183
+
181
184
 
182
185
 
183
186
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AOT_biomaps
3
- Version: 2.9.318
3
+ Version: 2.9.321
4
4
  Summary: Acousto-Optic Tomography
5
5
  Home-page: https://github.com/LucasDuclos/AcoustoOpticTomography
6
6
  Author: Lucas Duclos
@@ -1,16 +1,17 @@
1
1
  AOT_biomaps/Config.py,sha256=ghEOP1n8aO1pR-su13wMeAZAxZRfry5hH67NbtZ8SqI,3614
2
2
  AOT_biomaps/Settings.py,sha256=v8fPhnvvcfBJP29m1RLOTEr3jndGLGwbUiORXmsj2Bo,2853
3
- AOT_biomaps/__init__.py,sha256=JzWlV3kQ0eqvYRCkDaPawjpBhG0lagMhcLDnBLaY5Fs,4298
3
+ AOT_biomaps/__init__.py,sha256=6TSP5wI6TYb3icQQXws5eVgqxv0-F2F9HDYXj9uot6A,4304
4
4
  AOT_biomaps/AOT_Acoustic/AcousticEnums.py,sha256=s5kXa6jKzbS4btwbubrVcynLOr0yg5tth5vL_FGfbMk,1802
5
- AOT_biomaps/AOT_Acoustic/AcousticTools.py,sha256=al7xXKMY5e-qQQ7nrQVPVAmqYiB320OluNlY6ti8iKc,7539
5
+ AOT_biomaps/AOT_Acoustic/AcousticTools.py,sha256=h2sCtGVcDtyLtEF1q7sLZmuWivWmesVGUBPnW-ndQqc,7535
6
6
  AOT_biomaps/AOT_Acoustic/FocusedWave.py,sha256=3kGKKDx_3Msy5COYqIwzROPORGWvNjw8UsDanBfkMXE,11037
7
7
  AOT_biomaps/AOT_Acoustic/IrregularWave.py,sha256=yZhtxkR6zlciRcEpdTR0BAhvgQl40XHKFaF8f4VXarE,3035
8
8
  AOT_biomaps/AOT_Acoustic/PlaneWave.py,sha256=xza-rj5AUWDecLkGDxRcULrwZVWeBvGnEP2d51TyR04,1447
9
9
  AOT_biomaps/AOT_Acoustic/StructuredWave.py,sha256=jTLVlOhYLWJb5MxZPxhq3OFVlz2McoyMPBmfLvnekDU,18209
10
10
  AOT_biomaps/AOT_Acoustic/__init__.py,sha256=t9M2rRqa_L9pk7W2FeELTkHEMuP4DBr4gBRldMqsQbg,491
11
11
  AOT_biomaps/AOT_Acoustic/_mainAcoustic.py,sha256=RdmhRF1i0KAlpsP7_wnZ7F4J27br3eUc4XR91Qq7C64,44158
12
+ AOT_biomaps/AOT_Experiment/ExperimentTools.py,sha256=BkHSX_foyyj5UrHZWQH5F9DGeV8o2fkp3euEbcvE4vA,2399
12
13
  AOT_biomaps/AOT_Experiment/Focus.py,sha256=B2nBawmv-NG2AWJx9zgQ8GlN6aFB9FwTSqX-M-phKXg,3193
13
- AOT_biomaps/AOT_Experiment/Tomography.py,sha256=JO-yLOSnCd8Da2HC9uJ1uI0GD-_Ca1PX9URzAk_EAiQ,31149
14
+ AOT_biomaps/AOT_Experiment/Tomography.py,sha256=qH7QlAPp5Er1AhMbWDpbOT6VRJHgrYUdUxazuEMAc_A,34569
14
15
  AOT_biomaps/AOT_Experiment/__init__.py,sha256=H9zMLeBLA6uhbaHohAa-2u5mDDxqJi8oE5c6tShdQp8,308
15
16
  AOT_biomaps/AOT_Experiment/_mainExperiment.py,sha256=zSfuNrsz7nhiKrGIdK6CAXjlI2T6qYC5-JXHFgPNzhc,24674
16
17
  AOT_biomaps/AOT_Optic/Absorber.py,sha256=jEodzRy7gkEH-wbazVasRQiri0dU16BfapmR-qnTSvM,867
@@ -25,7 +26,7 @@ AOT_biomaps/AOT_Recon/BayesianRecon.py,sha256=RnnPa-tTcvirwiNPnCRZnSM4NWeEEltYET
25
26
  AOT_biomaps/AOT_Recon/DeepLearningRecon.py,sha256=RfVcEsi4GeGqJn0_SPxwQPQx6IQjin79WKh2UarMRLI,1383
26
27
  AOT_biomaps/AOT_Recon/PrimalDualRecon.py,sha256=JbFhxiyUoSTnlJgHbOWIfUUwhwfZoi39RJMnfkagegY,16504
27
28
  AOT_biomaps/AOT_Recon/ReconEnums.py,sha256=KAf55RqHAr2ilt6pxFrUBGQOn-7HA8NP6TyL-1FNiXo,19714
28
- AOT_biomaps/AOT_Recon/ReconTools.py,sha256=A4IQV7IETu9MgYr7hjLNPTImzjf8CEU4cZ2e0EgJNWA,19878
29
+ AOT_biomaps/AOT_Recon/ReconTools.py,sha256=py1zKVEa0j7EfmcNZS2lpVQwzlkY6rRWsDQ8izWlme4,19872
29
30
  AOT_biomaps/AOT_Recon/__init__.py,sha256=xs_argJqXKFl76xP7-jiUc1ynOEEtY7XZ0gDxD5uVZc,246
30
31
  AOT_biomaps/AOT_Recon/_mainRecon.py,sha256=exoa2UBMfMHjemxAU9dW0mhEfsP6Oe1qjSfrTrgbIcY,13125
31
32
  AOT_biomaps/AOT_Recon/AOT_Optimizers/DEPIERRO.py,sha256=qA1n722GLQJH3V8HcLr5q_GxEwBS_NRlIT3E6JZk-Ag,9479
@@ -41,7 +42,7 @@ AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/__init__.py,sha256=RwrJdLOFbAFBFnRx
41
42
  AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_CSR.py,sha256=RACc2P5oxmp0uPLAGnNj9mEtAxa_OlepNgCawKij3jI,12062
42
43
  AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_SELL.py,sha256=ti3dZQsb_Uu62C7Bn65Z-yf-R5NKCFsmnBT5GlLd_HY,15138
43
44
  AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/__init__.py,sha256=8nou-hqjQjuCTLhoL5qv4EM_lMPFviAZAZKSPhi84jE,67
44
- aot_biomaps-2.9.318.dist-info/METADATA,sha256=ynPqtHAnkFQBks7GrB91EadzCQxdCC7PFc0kHG3H-Zo,700
45
- aot_biomaps-2.9.318.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
46
- aot_biomaps-2.9.318.dist-info/top_level.txt,sha256=6STF-lT4kaAnBHJYCripmN5mZABoHjMuY689JdiDphk,12
47
- aot_biomaps-2.9.318.dist-info/RECORD,,
45
+ aot_biomaps-2.9.321.dist-info/METADATA,sha256=DMnk4rlTFW95pX0welgBZD3GdTkjeFbn3vwXNyUxSHs,700
46
+ aot_biomaps-2.9.321.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
47
+ aot_biomaps-2.9.321.dist-info/top_level.txt,sha256=6STF-lT4kaAnBHJYCripmN5mZABoHjMuY689JdiDphk,12
48
+ aot_biomaps-2.9.321.dist-info/RECORD,,