AOT-biomaps 2.9.312__tar.gz → 2.9.319__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.

Potentially problematic release.


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

Files changed (52) hide show
  1. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Experiment/Tomography.py +124 -0
  2. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/MLEM.py +2 -1
  3. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/__init__.py +8 -1
  4. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps.egg-info/PKG-INFO +1 -1
  5. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/PKG-INFO +1 -1
  6. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/setup.py +8 -1
  7. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/AcousticEnums.py +0 -0
  8. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/AcousticTools.py +0 -0
  9. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/FocusedWave.py +0 -0
  10. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/IrregularWave.py +0 -0
  11. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/PlaneWave.py +0 -0
  12. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/StructuredWave.py +0 -0
  13. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/__init__.py +0 -0
  14. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/_mainAcoustic.py +0 -0
  15. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Experiment/Focus.py +0 -0
  16. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Experiment/__init__.py +0 -0
  17. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Experiment/_mainExperiment.py +0 -0
  18. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Optic/Absorber.py +0 -0
  19. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Optic/Laser.py +0 -0
  20. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Optic/OpticEnums.py +0 -0
  21. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Optic/__init__.py +0 -0
  22. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Optic/_mainOptic.py +0 -0
  23. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/DEPIERRO.py +0 -0
  24. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/LS.py +0 -0
  25. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/MAPEM.py +0 -0
  26. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/PDHG.py +0 -0
  27. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/__init__.py +0 -0
  28. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/Huber.py +0 -0
  29. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/Quadratic.py +0 -0
  30. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/RelativeDifferences.py +0 -0
  31. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/__init__.py +0 -0
  32. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_CSR.py +0 -0
  33. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_SELL.py +0 -0
  34. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/__init__.py +0 -0
  35. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_biomaps_kernels.cubin +0 -0
  36. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AlgebraicRecon.py +0 -0
  37. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AnalyticRecon.py +0 -0
  38. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/BayesianRecon.py +0 -0
  39. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/DeepLearningRecon.py +0 -0
  40. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/PrimalDualRecon.py +0 -0
  41. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/ReconEnums.py +0 -0
  42. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/ReconTools.py +0 -0
  43. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/__init__.py +0 -0
  44. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/_mainRecon.py +0 -0
  45. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/Config.py +0 -0
  46. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/Settings.py +0 -0
  47. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps.egg-info/SOURCES.txt +0 -0
  48. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps.egg-info/dependency_links.txt +0 -0
  49. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps.egg-info/requires.txt +0 -0
  50. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps.egg-info/top_level.txt +0 -0
  51. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/README.md +0 -0
  52. {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/setup.cfg +0 -0
@@ -287,6 +287,56 @@ class Tomography(Experiment):
287
287
  if not self._check_patterns(self.patterns):
288
288
  raise ValueError("Generated patterns failed validation.")
289
289
 
290
+ def selectAngles(self, angles):
291
+
292
+ if self.AOsignal_withTumor is None and self.AOsignal_withoutTumor is None:
293
+ raise ValueError("AO signals are not initialized. Please load or generate the AO signals first.")
294
+ if self.AcousticFields is None or len(self.AcousticFields) == 0:
295
+ raise ValueError("AcousticFields is not initialized. Please generate the system matrix first.")
296
+ newAcousticFields = []
297
+ index = []
298
+ for i,field in enumerate(self.AcousticFields):
299
+ if field.angle in angles:
300
+ newAcousticFields.append(field)
301
+ index.append(i)
302
+ if self.AOsignal_withTumor is not None:
303
+ self.AOsignal_withTumor = self.AOsignal_withTumor[:, index]
304
+ if self.AOsignal_withoutTumor is not None:
305
+ self.AOsignal_withoutTumor = self.AOsignal_withoutTumor[:, index]
306
+ self.AcousticFields = newAcousticFields
307
+
308
+ def selectPatterns(self, pattern_names):
309
+ if self.AOsignal_withTumor is None and self.AOsignal_withoutTumor is None:
310
+ raise ValueError("AO signals are not initialized. Please load or generate the AO signals first.")
311
+ if self.AcousticFields is None or len(self.AcousticFields) == 0:
312
+ raise ValueError("AcousticFields is not initialized. Please generate the system matrix first.")
313
+ newAcousticFields = []
314
+ index = []
315
+ for i,field in enumerate(self.AcousticFields):
316
+ if field.pattern.activeList in pattern_names:
317
+ newAcousticFields.append(field)
318
+ index.append(i)
319
+ if self.AOsignal_withTumor is not None:
320
+ self.AOsignal_withTumor = self.AOsignal_withTumor[:, index]
321
+ if self.AOsignal_withoutTumor is not None:
322
+ self.AOsignal_withoutTumor = self.AOsignal_withoutTumor[:, index]
323
+ self.AcousticFields = newAcousticFields
324
+
325
+ def selectRandom(self,N):
326
+ if self.AOsignal_withTumor is None and self.AOsignal_withoutTumor is None:
327
+ raise ValueError("AO signals are not initialized. Please load or generate the AO signals first.")
328
+ if self.AcousticFields is None or len(self.AcousticFields) == 0:
329
+ raise ValueError("AcousticFields is not initialized. Please generate the system matrix first.")
330
+ if N > len(self.AcousticFields):
331
+ raise ValueError("N is larger than the number of available AcousticFields.")
332
+ indices = np.random.choice(len(self.AcousticFields), size=N, replace=False)
333
+ newAcousticFields = [self.AcousticFields[i] for i in indices]
334
+ if self.AOsignal_withTumor is not None:
335
+ self.AOsignal_withTumor = self.AOsignal_withTumor[:, indices]
336
+ if self.AOsignal_withoutTumor is not None:
337
+ self.AOsignal_withoutTumor = self.AOsignal_withoutTumor[:, indices]
338
+ self.AcousticFields = newAcousticFields
339
+
290
340
  def _generate_patterns(self, N):
291
341
  def format_angle(a):
292
342
  return f"{'1' if a < 0 else '0'}{abs(a):02d}"
@@ -390,6 +440,80 @@ class Tomography(Experiment):
390
440
 
391
441
  return True
392
442
 
443
+ def applyApodisation(self, alpha=0.3, divergence_deg=0.5):
444
+ """
445
+ Applique une apodisation dynamique sur les champs acoustiques stockés dans l'objet.
446
+ L'apodisation suit l'angle d'émission et la divergence naturelle du faisceau pour
447
+ supprimer les lobes de diffraction (artefacts de bord) sans toucher au signal utile.
448
+ Args:
449
+ probe_width (float): Largeur physique active de la sonde (ex: 40e-3 pour 40mm).
450
+ alpha (float): Paramètre de Tukey (0.0=rectangle, 1.0=hann). 0.3 est un bon compromis.
451
+ divergence_deg (float): Angle d'ouverture du masque pour suivre l'élargissement du faisceau.
452
+ 0.0 = Droit, 0.5 = Légère ouverture (conseillé).
453
+ """
454
+ print(f"Applying apodization (Alpha={alpha}, Div={divergence_deg}°) on {len(self.AcousticFields)} fields...")
455
+
456
+ probe_width = self.params.acoustic['num_elements'] * self.params.acoustic['element_width']
457
+
458
+ for i in trange(len(self.AcousticFields), desc="Apodisation"):
459
+ # 1. Récupération des données et de l'angle
460
+ field = self.AcousticFields[i].field # Peut être (Z, X) ou (Time, Z, X)
461
+ angle = self.AcousticFields[i].angle # L'angle de l'onde plane
462
+
463
+ # 2. Récupération ou construction des axes physiques
464
+ nz, nx = field.shape[-2:]
465
+
466
+ if hasattr(self, 'x_axis') and self.x_axis is not None:
467
+ x_axis = self.x_axis
468
+ else:
469
+ # Génération par défaut centrée sur 0 (ex: -20mm à +20mm)
470
+ x_axis = np.linspace(-probe_width/2, probe_width/2, nx)
471
+
472
+ if hasattr(self, 'z_axis') and self.z_axis is not None:
473
+ z_axis = self.z_axis
474
+ else:
475
+ # Génération par défaut (ex: 0 à 40mm, basé sur un pitch standard ou arbitraire)
476
+ estimated_depth = 40e-3 # Valeur arbitraire si inconnue
477
+ z_axis = np.linspace(0, estimated_depth, nz)
478
+
479
+ # 3. Préparation des grilles pour le masque
480
+ Z, X = np.meshgrid(z_axis, x_axis, indexing='ij')
481
+
482
+ # 4. Calcul de la géométrie orientée (Steering)
483
+ angle_rad = np.deg2rad(angle)
484
+ X_aligned = X - Z * np.tan(angle_rad)
485
+
486
+ # 5. Calcul de la largeur dynamique du masque (Divergence)
487
+ div_rad = np.deg2rad(divergence_deg)
488
+ current_half_width = (probe_width / 2.0) + Z * np.tan(div_rad)
489
+
490
+ # 6. Normalisation et création du masque Tukey
491
+ X_norm = np.divide(X_aligned, current_half_width, out=np.zeros_like(X_aligned), where=current_half_width!=0)
492
+
493
+ mask = np.zeros_like(X_norm)
494
+ plateau_threshold = 1.0 * (1 - alpha)
495
+
496
+ # Zone centrale (plateau = 1)
497
+ mask[np.abs(X_norm) <= plateau_threshold] = 1.0
498
+
499
+ # Zone de transition (cosinus)
500
+ transition_indices = (np.abs(X_norm) > plateau_threshold) & (np.abs(X_norm) <= 1.0)
501
+ if np.any(transition_indices):
502
+ x_trans = np.abs(X_norm[transition_indices]) - plateau_threshold
503
+ width_trans = 1.0 * alpha
504
+ mask[transition_indices] = 0.5 * (1 + np.cos(np.pi * x_trans / width_trans))
505
+
506
+ # 7. Application du masque (Gestion 2D vs 3D)
507
+ if field.ndim == 3:
508
+ field_apodized = field * mask[np.newaxis, :, :]
509
+ else:
510
+ field_apodized = field * mask
511
+
512
+ # 8. Mise à jour de l'objet
513
+ self.AcousticFields[i].field = field_apodized
514
+
515
+ print("Apodisation done.")
516
+
393
517
  # PRIVATE METHODS
394
518
  def _generateAcousticFields_STRUCT_CPU(self, fieldDataPath=None, show_log=False, nameBlock=None):
395
519
  if self.patterns is None:
@@ -547,4 +547,5 @@ def MLEM_sparseSELL_pycuda(
547
547
  try:
548
548
  SMatrix.ctx.pop()
549
549
  except Exception:
550
- pass
550
+ pass
551
+
@@ -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.312'
88
+ __version__ = '2.9.319'
89
89
  __process__ = config.get_process()
90
90
 
91
91
  def initialize(process=None):
@@ -168,6 +168,13 @@ def initialize(process=None):
168
168
 
169
169
 
170
170
 
171
+
172
+
173
+
174
+
175
+
176
+
177
+
171
178
 
172
179
 
173
180
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AOT_biomaps
3
- Version: 2.9.312
3
+ Version: 2.9.319
4
4
  Summary: Acousto-Optic Tomography
5
5
  Home-page: https://github.com/LucasDuclos/AcoustoOpticTomography
6
6
  Author: Lucas Duclos
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AOT_biomaps
3
- Version: 2.9.312
3
+ Version: 2.9.319
4
4
  Summary: Acousto-Optic Tomography
5
5
  Home-page: https://github.com/LucasDuclos/AcoustoOpticTomography
6
6
  Author: Lucas Duclos
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='AOT_biomaps',
5
- version='2.9.312',
5
+ version='2.9.319',
6
6
  packages=find_packages(),
7
7
  include_package_data=True,
8
8
 
@@ -326,6 +326,13 @@ setup(
326
326
 
327
327
 
328
328
 
329
+
330
+
331
+
332
+
333
+
334
+
335
+
329
336
 
330
337
 
331
338
 
File without changes
File without changes