AOT-biomaps 2.9.378__py3-none-any.whl → 2.9.379__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.
- AOT_biomaps/AOT_Acoustic/StructuredWave.py +122 -75
- AOT_biomaps/AOT_Acoustic/_mainAcoustic.py +2 -3
- AOT_biomaps/__init__.py +2 -1
- {aot_biomaps-2.9.378.dist-info → aot_biomaps-2.9.379.dist-info}/METADATA +1 -1
- {aot_biomaps-2.9.378.dist-info → aot_biomaps-2.9.379.dist-info}/RECORD +7 -7
- {aot_biomaps-2.9.378.dist-info → aot_biomaps-2.9.379.dist-info}/WHEEL +0 -0
- {aot_biomaps-2.9.378.dist-info → aot_biomaps-2.9.379.dist-info}/top_level.txt +0 -0
|
@@ -190,7 +190,7 @@ class StructuredWave(AcousticField):
|
|
|
190
190
|
"""
|
|
191
191
|
return f"{'1' if self.angle < 0 else '0'}{abs(self.angle):02d}"
|
|
192
192
|
|
|
193
|
-
def _apply_delay(self,dx=None):
|
|
193
|
+
def _apply_delay(self,dt=None,dx=None,c0=None):
|
|
194
194
|
"""
|
|
195
195
|
Apply a temporal delay to the signal for each transducer element.
|
|
196
196
|
|
|
@@ -198,9 +198,13 @@ class StructuredWave(AcousticField):
|
|
|
198
198
|
ndarray: Array of delayed signals.
|
|
199
199
|
"""
|
|
200
200
|
try:
|
|
201
|
+
print(f"dx in _apply_delay: {dx}")
|
|
201
202
|
is_positive = self.angle >= 0
|
|
202
203
|
if dx is None:
|
|
203
204
|
dx = self.params['dx']
|
|
205
|
+
if c0 is None:
|
|
206
|
+
c0 = self.params['c0']
|
|
207
|
+
actual_dt = dt if dt is not None else self.kgrid.dt
|
|
204
208
|
# Calculate the total number of grid points for all elements
|
|
205
209
|
total_grid_points = self.params['num_elements'] * int(round(self.params['element_width'] / dx))
|
|
206
210
|
|
|
@@ -212,10 +216,10 @@ class StructuredWave(AcousticField):
|
|
|
212
216
|
|
|
213
217
|
# Calculate delays based on physical positions
|
|
214
218
|
for i in range(total_grid_points):
|
|
215
|
-
delays[i] = (element_positions[i] * np.tan(np.deg2rad(abs(self.angle)))) /
|
|
219
|
+
delays[i] = (element_positions[i] * np.tan(np.deg2rad(abs(self.angle)))) / c0 # Delay in seconds
|
|
216
220
|
|
|
217
221
|
|
|
218
|
-
delay_samples = np.round(delays /
|
|
222
|
+
delay_samples = np.round(delays / actual_dt).astype(int)
|
|
219
223
|
max_delay = np.max(np.abs(delay_samples))
|
|
220
224
|
|
|
221
225
|
delayed_signals = np.zeros((total_grid_points, len(self.burst) + max_delay))
|
|
@@ -332,76 +336,119 @@ class StructuredWave(AcousticField):
|
|
|
332
336
|
f_hdr2.write(headerFieldGlob)
|
|
333
337
|
except Exception as e:
|
|
334
338
|
print(f"Error saving HDR/IMG files: {e}")
|
|
335
|
-
|
|
336
|
-
def _SetUpSource(self, source, Nx, dx, factorT):
|
|
337
|
-
"""
|
|
338
|
-
Set up source for both 2D and 3D structured waves.
|
|
339
|
-
"""
|
|
340
|
-
active_list = np.array([int(char) for char in ''.join(f"{int(self.pattern.activeList[i:i+2], 16):08b}" for i in range(0, len(self.pattern.activeList), 2))])
|
|
341
|
-
element_width_grid_points = int(round(self.params['element_width'] / dx))
|
|
342
|
-
|
|
343
|
-
if source.p_mask.ndim == 2:
|
|
344
|
-
element_width_grid_points = int(round(self.params['element_width'] / dx))
|
|
345
|
-
total_elements_width = self.params['num_elements'] * element_width_grid_points
|
|
346
|
-
|
|
347
|
-
# Vérifier que les éléments rentrent dans le grid
|
|
348
|
-
if total_elements_width > Nx:
|
|
349
|
-
raise ValueError(f"La largeur totale des éléments ({total_elements_width}) dépasse Nx ({Nx}).")
|
|
350
|
-
|
|
351
|
-
remaining_space = Nx - total_elements_width
|
|
352
|
-
if remaining_space < 0:
|
|
353
|
-
raise ValueError(f"Pas assez d'espace pour placer les éléments: total_elements_width ({total_elements_width}) > Nx ({Nx}).")
|
|
354
|
-
|
|
355
|
-
spacing = remaining_space // (self.params['num_elements'] + 1)
|
|
356
|
-
center_index = np.argmin(np.abs(np.linspace(self.params['Xrange'][0], self.params['Xrange'][1], Nx)))
|
|
357
|
-
|
|
358
|
-
activeListGrid = np.zeros(total_elements_width, dtype=int)
|
|
359
|
-
current_position = center_index - (total_elements_width + (self.params['num_elements'] - 1) * spacing) // 2
|
|
360
|
-
|
|
361
|
-
# Placement des éléments actifs
|
|
362
|
-
for i in range(self.params['num_elements']):
|
|
363
|
-
if active_list[i] == 1:
|
|
364
|
-
x_pos = max(0, current_position) # Éviter les indices négatifs
|
|
365
|
-
x_end = x_pos + element_width_grid_points
|
|
366
|
-
if x_end > Nx:
|
|
367
|
-
x_end = Nx # Limiter à Nx
|
|
368
|
-
source.p_mask[x_pos:x_end,0] = 1
|
|
369
|
-
|
|
370
|
-
start_idx = i * element_width_grid_points
|
|
371
|
-
end_idx = start_idx + element_width_grid_points
|
|
372
|
-
if end_idx > total_elements_width:
|
|
373
|
-
end_idx = total_elements_width
|
|
374
|
-
activeListGrid[start_idx:end_idx] = 1
|
|
375
|
-
|
|
376
|
-
current_position += element_width_grid_points + spacing
|
|
377
|
-
|
|
378
|
-
# Chargement des signaux retardés
|
|
379
|
-
if factorT != 1:
|
|
380
|
-
delayedSignal = self._apply_delay(dx=dx)
|
|
381
|
-
else:
|
|
382
|
-
delayedSignal = self.delayedSignal
|
|
383
|
-
|
|
384
|
-
# Vérification de la taille de delayedSignal
|
|
385
|
-
num_active_elements = np.sum(activeListGrid == 1)
|
|
386
|
-
if delayedSignal.shape[0] < num_active_elements:
|
|
387
|
-
raise ValueError(f"delayedSignal a une taille insuffisante: {delayedSignal.shape[0]} < {num_active_elements}.")
|
|
388
|
-
|
|
389
|
-
# Assigner source.p
|
|
390
|
-
source.p = float(self.params['voltage']) * float(self.params['sensitivity']) * delayedSignal[activeListGrid == 1, :]
|
|
391
|
-
|
|
392
339
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
340
|
+
def _SetUpSource(self, source, Nx, dt, dx, c0, factorT):
|
|
341
|
+
active_list = np.array([int(char) for char in ''.join(f"{int(self.pattern.activeList[i:i+2], 16):08b}" for i in range(0, len(self.pattern.activeList), 2))])
|
|
342
|
+
|
|
343
|
+
# Largeur d'un élément en pixels
|
|
344
|
+
el_width_px = int(round(self.params['element_width'] / dx))
|
|
345
|
+
# Largeur totale de la sonde en pixels
|
|
346
|
+
total_sonde_px = self.params['num_elements'] * el_width_px
|
|
347
|
+
|
|
348
|
+
# On récupère pva_nx depuis l'appel ou on le recalcule
|
|
349
|
+
pva_nx = int(np.round(self.params['width_phantom'] / dx))
|
|
350
|
+
air_margin = (Nx - pva_nx) // 2
|
|
351
|
+
|
|
352
|
+
# Position de départ pour que la sonde soit centrée sur le PHANTOM
|
|
353
|
+
# On commence à la fin de la marge d'air, et on centre la sonde dans le pva_nx
|
|
354
|
+
current_position = air_margin + (pva_nx - total_sonde_px) // 2
|
|
355
|
+
|
|
356
|
+
activeListGrid = np.zeros(total_sonde_px, dtype=int)
|
|
357
|
+
|
|
358
|
+
for i in range(self.params['num_elements']):
|
|
359
|
+
if active_list[i] == 1:
|
|
360
|
+
x_start = current_position
|
|
361
|
+
x_end = x_start + el_width_px
|
|
362
|
+
|
|
363
|
+
# On remplit le masque k-Wave (z=0)
|
|
364
|
+
source.p_mask[x_start:x_end, 0] = 1
|
|
365
|
+
|
|
366
|
+
# On marque les indices actifs pour injecter le signal delayed
|
|
367
|
+
idx_start = i * el_width_px
|
|
368
|
+
idx_end = idx_start + el_width_px
|
|
369
|
+
activeListGrid[idx_start:idx_end] = 1
|
|
370
|
+
|
|
371
|
+
current_position += el_width_px # Pas de "spacing" variable, les éléments sont collés
|
|
372
|
+
|
|
373
|
+
# Injection du signal
|
|
374
|
+
if factorT != 1:
|
|
375
|
+
delayedSignal = self._apply_delay(self, dt=dt, dx=dx, c0=c0)
|
|
376
|
+
else:
|
|
377
|
+
delayedSignal = self.delayedSignal
|
|
378
|
+
|
|
379
|
+
# On injecte uniquement là où p_mask == 1
|
|
380
|
+
source.p = float(self.params['voltage']) * float(self.params['sensitivity']) * delayedSignal[activeListGrid == 1, :]
|
|
381
|
+
return source
|
|
382
|
+
|
|
383
|
+
# def _SetUpSource(self, source, Nx, dx, factorT):
|
|
384
|
+
# """
|
|
385
|
+
# Set up source for both 2D and 3D structured waves.
|
|
386
|
+
# """
|
|
387
|
+
# active_list = np.array([int(char) for char in ''.join(f"{int(self.pattern.activeList[i:i+2], 16):08b}" for i in range(0, len(self.pattern.activeList), 2))])
|
|
388
|
+
# element_width_grid_points = int(round(self.params['element_width'] / dx))
|
|
389
|
+
|
|
390
|
+
# if source.p_mask.ndim == 2:
|
|
391
|
+
# element_width_grid_points = int(round(self.params['element_width'] / dx))
|
|
392
|
+
# total_elements_width = self.params['num_elements'] * element_width_grid_points
|
|
393
|
+
|
|
394
|
+
# # Vérifier que les éléments rentrent dans le grid
|
|
395
|
+
# if total_elements_width > Nx:
|
|
396
|
+
# raise ValueError(f"La largeur totale des éléments ({total_elements_width}) dépasse Nx ({Nx}).")
|
|
397
|
+
|
|
398
|
+
# remaining_space = Nx - total_elements_width
|
|
399
|
+
# if remaining_space < 0:
|
|
400
|
+
# raise ValueError(f"Pas assez d'espace pour placer les éléments: total_elements_width ({total_elements_width}) > Nx ({Nx}).")
|
|
401
|
+
|
|
402
|
+
# spacing = remaining_space // (self.params['num_elements'] + 1)
|
|
403
|
+
# center_index = np.argmin(np.abs(np.linspace(self.params['Xrange'][0], self.params['Xrange'][1], Nx)))
|
|
404
|
+
|
|
405
|
+
# activeListGrid = np.zeros(total_elements_width, dtype=int)
|
|
406
|
+
# current_position = center_index - (total_elements_width + (self.params['num_elements'] - 1) * spacing) // 2
|
|
407
|
+
|
|
408
|
+
# # Placement des éléments actifs
|
|
409
|
+
# for i in range(self.params['num_elements']):
|
|
410
|
+
# if active_list[i] == 1:
|
|
411
|
+
# x_pos = max(0, current_position) # Éviter les indices négatifs
|
|
412
|
+
# x_end = x_pos + element_width_grid_points
|
|
413
|
+
# if x_end > Nx:
|
|
414
|
+
# x_end = Nx # Limiter à Nx
|
|
415
|
+
# source.p_mask[x_pos:x_end,0] = 1
|
|
416
|
+
|
|
417
|
+
# start_idx = i * element_width_grid_points
|
|
418
|
+
# end_idx = start_idx + element_width_grid_points
|
|
419
|
+
# if end_idx > total_elements_width:
|
|
420
|
+
# end_idx = total_elements_width
|
|
421
|
+
# activeListGrid[start_idx:end_idx] = 1
|
|
422
|
+
|
|
423
|
+
# current_position += element_width_grid_points + spacing
|
|
424
|
+
|
|
425
|
+
# # Chargement des signaux retardés
|
|
426
|
+
# if factorT != 1:
|
|
427
|
+
# delayedSignal = self._apply_delay(dx=dx)
|
|
428
|
+
# else:
|
|
429
|
+
# delayedSignal = self.delayedSignal
|
|
430
|
+
|
|
431
|
+
# # Vérification de la taille de delayedSignal
|
|
432
|
+
# num_active_elements = np.sum(activeListGrid == 1)
|
|
433
|
+
# if delayedSignal.shape[0] < num_active_elements:
|
|
434
|
+
# raise ValueError(f"delayedSignal a une taille insuffisante: {delayedSignal.shape[0]} < {num_active_elements}.")
|
|
435
|
+
|
|
436
|
+
# # Assigner source.p
|
|
437
|
+
# source.p = float(self.params['voltage']) * float(self.params['sensitivity']) * delayedSignal[activeListGrid == 1, :]
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
# elif source.p_mask.ndim == 3:
|
|
441
|
+
# # --- 3D ---
|
|
442
|
+
# center_index_x = Nx // 2
|
|
443
|
+
# center_index_y = self.params['Ny'] // 2
|
|
444
|
+
# spacing = (Nx - self.params['num_elements'] * element_width_grid_points) // (self.params['num_elements'] + 1)
|
|
445
|
+
# current_position = center_index_x - (self.params['num_elements'] * element_width_grid_points + (self.params['num_elements'] - 1) * spacing) // 2
|
|
446
|
+
|
|
447
|
+
# for i in range(self.params['num_elements']):
|
|
448
|
+
# if active_list[i] == 1:
|
|
449
|
+
# x_pos = current_position
|
|
450
|
+
# source.p_mask[x_pos:x_pos + element_width_grid_points, center_index_y, 0] = 1
|
|
451
|
+
# current_position += element_width_grid_points + spacing
|
|
452
|
+
|
|
453
|
+
# delayed_signals = self._apply_delay()
|
|
454
|
+
# source.p = float(self.params['voltage']) * float(self.params['sensitivity']) * delayed_signals.T
|
|
@@ -569,7 +569,7 @@ class AcousticField(ABC):
|
|
|
569
569
|
source = kSource()
|
|
570
570
|
source.p_mask = np.zeros((Nx, Nz))
|
|
571
571
|
# Appel à la méthode spécialisée
|
|
572
|
-
self._SetUpSource(
|
|
572
|
+
source = self._SetUpSource(source, Nx, dt, dx, c_mean,factorT) # factorT=1 pour simplifier
|
|
573
573
|
|
|
574
574
|
# --- 4. Sensor setup ---
|
|
575
575
|
sensor = kSensor()
|
|
@@ -620,7 +620,6 @@ class AcousticField(ABC):
|
|
|
620
620
|
print(f"Error generating 2D acoustic field: {e}")
|
|
621
621
|
return None
|
|
622
622
|
|
|
623
|
-
|
|
624
623
|
def _generate_acoustic_field_KWAVE_3D(self, isGPU=True, show_log=True):
|
|
625
624
|
"""
|
|
626
625
|
Generate a 3D acoustic field using k-Wave.
|
|
@@ -700,7 +699,7 @@ class AcousticField(ABC):
|
|
|
700
699
|
return None
|
|
701
700
|
|
|
702
701
|
@abstractmethod
|
|
703
|
-
def _SetUpSource(self, source, Nx, dx, factorT):
|
|
702
|
+
def _SetUpSource(self, source, Nx, dt, dx, c0, factorT):
|
|
704
703
|
"""
|
|
705
704
|
Abstract method: each subclass must implement its own source setup.
|
|
706
705
|
"""
|
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.
|
|
88
|
+
__version__ = '2.9.379'
|
|
89
89
|
__process__ = config.get_process()
|
|
90
90
|
|
|
91
91
|
def initialize(process=None):
|
|
@@ -240,5 +240,6 @@ def initialize(process=None):
|
|
|
240
240
|
|
|
241
241
|
|
|
242
242
|
|
|
243
|
+
|
|
243
244
|
|
|
244
245
|
|
|
@@ -1,14 +1,14 @@
|
|
|
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=
|
|
3
|
+
AOT_biomaps/__init__.py,sha256=6qGbHw4T2-BgS21iC2JvKHMzIQZqodCkFuHn-CV56dM,4420
|
|
4
4
|
AOT_biomaps/AOT_Acoustic/AcousticEnums.py,sha256=s5kXa6jKzbS4btwbubrVcynLOr0yg5tth5vL_FGfbMk,1802
|
|
5
5
|
AOT_biomaps/AOT_Acoustic/AcousticTools.py,sha256=7kuWIIGyzZPQrzRI0zVvdwNUp7qKUE67yCYOMzSb0Ug,8283
|
|
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
|
-
AOT_biomaps/AOT_Acoustic/StructuredWave.py,sha256=
|
|
9
|
+
AOT_biomaps/AOT_Acoustic/StructuredWave.py,sha256=f7jI0hJ3VPjUlt3R9FYoI6At4JlQmyN3_J2OX3z13Is,21297
|
|
10
10
|
AOT_biomaps/AOT_Acoustic/__init__.py,sha256=t9M2rRqa_L9pk7W2FeELTkHEMuP4DBr4gBRldMqsQbg,491
|
|
11
|
-
AOT_biomaps/AOT_Acoustic/_mainAcoustic.py,sha256=
|
|
11
|
+
AOT_biomaps/AOT_Acoustic/_mainAcoustic.py,sha256=ZyGgf2nCENgOXNetxaTgFLNWGmn_MysVWCAVlsCINQs,47702
|
|
12
12
|
AOT_biomaps/AOT_Experiment/ExperimentTools.py,sha256=aFvJw6J_jfFVTDFnG7J3a61SHEgORdZKZS0UI82VMaY,2637
|
|
13
13
|
AOT_biomaps/AOT_Experiment/Focus.py,sha256=B2nBawmv-NG2AWJx9zgQ8GlN6aFB9FwTSqX-M-phKXg,3193
|
|
14
14
|
AOT_biomaps/AOT_Experiment/Tomography.py,sha256=9mJDwV9WVphoX8drL7MgN3WhS6fjYwS6HWQD3x1CrVs,37625
|
|
@@ -42,7 +42,7 @@ AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/__init__.py,sha256=RwrJdLOFbAFBFnRx
|
|
|
42
42
|
AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_CSR.py,sha256=RACc2P5oxmp0uPLAGnNj9mEtAxa_OlepNgCawKij3jI,12062
|
|
43
43
|
AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_SELL.py,sha256=ti3dZQsb_Uu62C7Bn65Z-yf-R5NKCFsmnBT5GlLd_HY,15138
|
|
44
44
|
AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/__init__.py,sha256=8nou-hqjQjuCTLhoL5qv4EM_lMPFviAZAZKSPhi84jE,67
|
|
45
|
-
aot_biomaps-2.9.
|
|
46
|
-
aot_biomaps-2.9.
|
|
47
|
-
aot_biomaps-2.9.
|
|
48
|
-
aot_biomaps-2.9.
|
|
45
|
+
aot_biomaps-2.9.379.dist-info/METADATA,sha256=_NqtecKRJ65mMrnnLL8Tub7dl5WcoUYL9nQEXqrYwDA,700
|
|
46
|
+
aot_biomaps-2.9.379.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
47
|
+
aot_biomaps-2.9.379.dist-info/top_level.txt,sha256=6STF-lT4kaAnBHJYCripmN5mZABoHjMuY689JdiDphk,12
|
|
48
|
+
aot_biomaps-2.9.379.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|