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.
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Experiment/Tomography.py +124 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/MLEM.py +2 -1
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/__init__.py +8 -1
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps.egg-info/PKG-INFO +1 -1
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/PKG-INFO +1 -1
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/setup.py +8 -1
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/AcousticEnums.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/AcousticTools.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/FocusedWave.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/IrregularWave.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/PlaneWave.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/StructuredWave.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/__init__.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Acoustic/_mainAcoustic.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Experiment/Focus.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Experiment/__init__.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Experiment/_mainExperiment.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Optic/Absorber.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Optic/Laser.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Optic/OpticEnums.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Optic/__init__.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Optic/_mainOptic.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/DEPIERRO.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/LS.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/MAPEM.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/PDHG.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/__init__.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/Huber.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/Quadratic.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/RelativeDifferences.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/__init__.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_CSR.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_SELL.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/__init__.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_biomaps_kernels.cubin +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AlgebraicRecon.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AnalyticRecon.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/BayesianRecon.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/DeepLearningRecon.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/PrimalDualRecon.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/ReconEnums.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/ReconTools.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/__init__.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/_mainRecon.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/Config.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/Settings.py +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps.egg-info/SOURCES.txt +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps.egg-info/dependency_links.txt +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps.egg-info/requires.txt +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps.egg-info/top_level.txt +0 -0
- {aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/README.md +0 -0
- {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:
|
|
@@ -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.
|
|
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
|
|
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name='AOT_biomaps',
|
|
5
|
-
version='2.9.
|
|
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
|
|
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
|
{aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/DEPIERRO.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_Optimizers/__init__.py
RENAMED
|
File without changes
|
{aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/Huber.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aot_biomaps-2.9.312 → aot_biomaps-2.9.319}/AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/__init__.py
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|