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

Files changed (29) hide show
  1. AOT_biomaps/AOT_Acoustic/StructuredWave.py +2 -2
  2. AOT_biomaps/AOT_Acoustic/_mainAcoustic.py +14 -7
  3. AOT_biomaps/AOT_Experiment/Tomography.py +74 -4
  4. AOT_biomaps/AOT_Experiment/_mainExperiment.py +95 -55
  5. AOT_biomaps/AOT_Recon/AOT_Optimizers/DEPIERRO.py +48 -13
  6. AOT_biomaps/AOT_Recon/AOT_Optimizers/LS.py +9 -6
  7. AOT_biomaps/AOT_Recon/AOT_Optimizers/MAPEM.py +118 -38
  8. AOT_biomaps/AOT_Recon/AOT_Optimizers/MLEM.py +305 -102
  9. AOT_biomaps/AOT_Recon/AOT_Optimizers/PDHG.py +1 -1
  10. AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/RelativeDifferences.py +10 -14
  11. AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_CSR.py +281 -0
  12. AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_SELL.py +295 -0
  13. AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/__init__.py +2 -0
  14. AOT_biomaps/AOT_Recon/AOT_biomaps_kernels.cubin +0 -0
  15. AOT_biomaps/AOT_Recon/AlgebraicRecon.py +262 -149
  16. AOT_biomaps/AOT_Recon/AnalyticRecon.py +27 -42
  17. AOT_biomaps/AOT_Recon/BayesianRecon.py +84 -151
  18. AOT_biomaps/AOT_Recon/DeepLearningRecon.py +1 -1
  19. AOT_biomaps/AOT_Recon/PrimalDualRecon.py +69 -62
  20. AOT_biomaps/AOT_Recon/ReconEnums.py +27 -2
  21. AOT_biomaps/AOT_Recon/ReconTools.py +120 -12
  22. AOT_biomaps/AOT_Recon/__init__.py +1 -0
  23. AOT_biomaps/AOT_Recon/_mainRecon.py +73 -59
  24. AOT_biomaps/__init__.py +4 -74
  25. {aot_biomaps-2.9.167.dist-info → aot_biomaps-2.9.270.dist-info}/METADATA +2 -1
  26. aot_biomaps-2.9.270.dist-info/RECORD +47 -0
  27. aot_biomaps-2.9.167.dist-info/RECORD +0 -43
  28. {aot_biomaps-2.9.167.dist-info → aot_biomaps-2.9.270.dist-info}/WHEEL +0 -0
  29. {aot_biomaps-2.9.167.dist-info → aot_biomaps-2.9.270.dist-info}/top_level.txt +0 -0
@@ -354,8 +354,33 @@ class NoiseType(Enum):
354
354
  - None: No noise is applied.
355
355
  """
356
356
  POISSON = 'poisson'
357
- """Poisson noise, typically used for emission data."""
357
+ """Poisson noise."""
358
358
  GAUSSIAN = 'gaussian'
359
- """Gaussian noise, typically used for transmission data."""
359
+ """Gaussian noise."""
360
360
  None_ = 'none'
361
361
  """No noise is applied."""
362
+
363
+ class SMatrixType(Enum):
364
+ """
365
+ Enum for different sparsing methods used in reconstructions.
366
+
367
+ Selection of sparsing methods:
368
+ - Thresholding: Sparsing based on a threshold value.
369
+ - TopK: Sparsing by retaining the top K values.
370
+ - None: No sparsing is applied.
371
+ """
372
+ DENSE = 'DENSE'
373
+ """No sparsing is applied."""
374
+ CSR = 'CSR'
375
+ """Sparsing based on a threshold value."""
376
+ COO = 'COO'
377
+ """Sparsing by retaining the top K values."""
378
+ SELL = 'SELL'
379
+ """Sparsing using sell C sigma method.
380
+ Optimized variant of ELLPACK, dividing the matrix into fixed-size "chunks" of `C` rows.
381
+ Non-zero elements are sorted by column within each chunk to improve memory coalescing on GPUs.
382
+ Rows are padded with zeros to align their length to the longest row in the chunk.
383
+ ** Ref : Kreutzer, M., Hager, G., Wellein, G., Fehske, H., & Bishop, A. R. (2014).
384
+ "A Unified Sparse Matrix Data Format for Efficient General Sparse Matrix-Vector Multiply on Modern Processors".
385
+ ACM Transactions on Mathematical Software, 41(2), 1–24. DOI: 10.1145/2592376.
386
+ """
@@ -1,9 +1,10 @@
1
1
  import os
2
+ from AOT_biomaps.AOT_Recon.AOT_SparseSMatrix import SparseSMatrix_CSR, SparseSMatrix_SELL
2
3
  import torch
3
4
  import numpy as np
4
5
  from numba import njit, prange
5
6
  from torch_sparse import coalesce
6
- import torch.nn.functional as F
7
+ import cupyx.scipy.sparse as cpsparse
7
8
 
8
9
  def load_recon(hdr_path):
9
10
  """
@@ -78,7 +79,7 @@ def load_recon(hdr_path):
78
79
  rescale_offset = float(header.get('data rescale offset', 0))
79
80
  image = image * rescale_slope + rescale_offset
80
81
 
81
- return image.T
82
+ return image
82
83
 
83
84
  def mse(y_true, y_pred):
84
85
  """
@@ -150,20 +151,82 @@ def ssim(img1, img2, win_size=7, k1=0.01, k2=0.03, L=1.0):
150
151
  return np.mean(ssim_map)
151
152
 
152
153
  def calculate_memory_requirement(SMatrix, y):
153
- """Calculate the memory requirement for the given matrices in GB."""
154
- num_elements_SMatrix = SMatrix.size
155
- num_elements_y = y.size
156
- num_elements_theta = SMatrix.shape[1] * SMatrix.shape[2] # Assuming theta has shape (Z, X)
154
+ """
155
+ Calcule la mémoire requise (en Go) pour :
156
+ - SMatrix : Matrice (np.ndarray, CuPy CSR, SparseSMatrix_CSR ou SparseSMatrix_SELL)
157
+ - y : vecteur (NumPy ou CuPy, float32)
158
+
159
+ Args:
160
+ SMatrix: Matrix object (np.ndarray, cpsparse.csr_matrix, SparseSMatrix_CSR, or SparseSMatrix_SELL)
161
+ y: Vector (float32)
162
+ """
163
+ total_bytes = 0
164
+
165
+ # --- 1. Memory for SMatrix ---
166
+
167
+ # 1.1. Custom Sparse Matrix (SELL/CSR)
168
+ if isinstance(SMatrix, (SparseSMatrix_SELL, SparseSMatrix_CSR)):
169
+ # We rely on the getMatrixSize method, which we fixed to track all host/GPU bytes.
170
+ # This is the most reliable way to estimate memory for custom GPU-backed structures.
171
+ try:
172
+ matrix_size_gb = SMatrix.getMatrixSize()
173
+ if isinstance(matrix_size_gb, dict) and 'error' in matrix_size_gb:
174
+ raise ValueError(f"SMatrix allocation error: {matrix_size_gb['error']}")
175
+
176
+ # Convert GB back to bytes (1 GB = 1024^3 bytes)
177
+ size_SMatrix = matrix_size_gb * (1024 ** 3)
178
+ total_bytes += size_SMatrix
179
+ print(f"SMatrix (Custom Sparse) size: {matrix_size_gb:.3f} GB")
180
+
181
+ except AttributeError:
182
+ raise AttributeError("Custom Sparse Matrix must implement the getMatrixSize() method.")
183
+
184
+ # 1.2. NumPy Dense Array (Standard)
185
+ elif isinstance(SMatrix, np.ndarray):
186
+ # Dense NumPy array (float32)
187
+ size_SMatrix = SMatrix.nbytes
188
+ total_bytes += size_SMatrix
189
+ print(f"SMatrix (NumPy Dense) size: {size_SMatrix / (1024 ** 3):.3f} GB")
190
+
191
+ # 1.3. CuPy CSR Matrix (Standard Sparse CuPy)
192
+ # Note: Requires CuPy to be imported, which is usually done outside this function.
193
+ # Assuming 'cpsparse.csr_matrix' is available in the environment if this path is taken.
194
+ elif 'cupy.sparse' in str(type(SMatrix)): # Using string check for type safety outside CuPy context
195
+ # CuPy CSR matrix structure: data (float32), indices (int32), indptr (int32)
196
+ nnz = SMatrix.nnz
197
+ num_rows = SMatrix.shape[0]
198
+ size_data = nnz * 4 # float32 = 4 bytes
199
+ size_indices = nnz * 4 # int32 = 4 bytes
200
+ size_indptr = (num_rows + 1) * 4 # int32 = 4 bytes
201
+ size_SMatrix = size_data + size_indices + size_indptr
202
+ total_bytes += size_SMatrix
203
+ print(f"SMatrix (CuPy CSR) size: {size_SMatrix / (1024 ** 3):.3f} GB")
204
+
205
+ else:
206
+ raise ValueError("SMatrix must be a np.ndarray, cpsparse.csr_matrix, or a custom SparseSMatrix object (CSR/SELL).")
207
+
208
+ # --- 2. Memory for Vector y ---
209
+
210
+ # Check if y is a CuPy array or NumPy array (assuming float32 based on docstring)
211
+ if hasattr(y, 'nbytes'):
212
+ size_y = y.nbytes
213
+ total_bytes += size_y
214
+ print(f"Vector y size: {size_y / (1024 ** 3):.3f} GB")
215
+ else:
216
+ # Fallback if object doesn't expose nbytes (e.g., custom buffer), but usually array objects do.
217
+ raise ValueError("Vector y must be an array type exposing the .nbytes attribute.")
157
218
 
158
- # Calculate total memory requirement in GB
159
- total_memory = (num_elements_SMatrix + num_elements_y + num_elements_theta) * 32 / 8 / 1024**3
160
- return total_memory
161
219
 
162
- def check_gpu_memory(device_index, required_memory):
220
+ # --- 3. Final Result ---
221
+ return total_bytes / (1024 ** 3)
222
+
223
+
224
+ def check_gpu_memory(device_index, required_memory, show_logs=True):
163
225
  """Check if enough memory is available on the specified GPU."""
164
- free_memory, total_memory = torch.cuda.mem_get_info(f"cuda:{device_index}")
226
+ free_memory, _ = torch.cuda.mem_get_info(f"cuda:{device_index}")
165
227
  free_memory_gb = free_memory / 1024**3
166
- print(f"Free memory on GPU {device_index}: {free_memory_gb:.2f} GB, Required memory: {required_memory:.2f} GB")
228
+ if show_logs:
229
+ print(f"Free memory on GPU {device_index}: {free_memory_gb:.2f} GB, Required memory: {required_memory:.2f} GB")
167
230
  return free_memory_gb >= required_memory
168
231
 
169
232
  @njit(parallel=True)
@@ -270,3 +333,48 @@ def prox_F_star(y, sigma, a):
270
333
  def prox_G(x, tau, K):
271
334
  return torch.clamp(x - tau * K, min=0)
272
335
 
336
+ def filter_radon(f, N, filter_type, Fc):
337
+ """
338
+ Implémente les filtres pour la rétroprojection filtrée (iRadon).
339
+ Inspirée de la fonction MATLAB FilterRadon de Mamouna Bocoum.
340
+
341
+ Paramètres :
342
+ ------------
343
+ f : np.ndarray
344
+ Vecteur des fréquences (ex: f_t ou f_z).
345
+ N : int
346
+ Taille du filtre (longueur de f).
347
+ filter_type : str
348
+ Type de filtre : 'ram-lak', 'shepp-logan', 'cosine', 'hamming', 'hann'.
349
+ Fc : float
350
+ Fréquence de coupure.
351
+
352
+ Retourne :
353
+ -----------
354
+ FILTER : np.ndarray
355
+ Filtre appliqué aux fréquences.
356
+ """
357
+ FILTER = np.abs(f)
358
+
359
+ if filter_type == 'ram-lak':
360
+ pass # FILTER = |f| (déjà calculé)
361
+ elif filter_type == 'shepp-logan':
362
+ # Évite la division par zéro
363
+ with np.errstate(divide='ignore', invalid='ignore'):
364
+ FILTER = FILTER * (np.sinc(2 * f / (2 * Fc))) # sin(2πf/(2Fc))/(2πf/(4Fc)) = sinc(2f/(2Fc))
365
+ FILTER[np.isnan(FILTER)] = 1.0 # Pour f=0
366
+ elif filter_type == 'cosine':
367
+ FILTER = FILTER * np.cos(2 * np.pi * f / (4 * Fc))
368
+ elif filter_type == 'hamming':
369
+ FILTER = FILTER * (0.54 + 0.46 * np.cos(2 * np.pi * f / Fc))
370
+ elif filter_type == 'hann':
371
+ FILTER = FILTER * (1 + np.cos(2 * np.pi * f / (4 * Fc))) / 2
372
+ else:
373
+ raise ValueError(f"Type de filtre inconnu : {filter_type}")
374
+
375
+ # Coupure des fréquences au-delà de Fc
376
+ FILTER[np.abs(f) > Fc] = 0
377
+ # Atténuation exponentielle (optionnelle, comme dans le code MATLAB)
378
+ FILTER = FILTER * np.exp(-2 * (np.abs(f) / Fc)**10)
379
+
380
+ return FILTER
@@ -9,3 +9,4 @@ from .ReconTools import *
9
9
 
10
10
 
11
11
 
12
+
@@ -10,7 +10,7 @@ from abc import ABC, abstractmethod
10
10
 
11
11
 
12
12
  class Recon(ABC):
13
- def __init__(self, experiment, saveDir = None, isGPU = config.get_process() == 'gpu', isMultiGPU = True if config.numGPUs > 1 else False, isMultiCPU = True):
13
+ def __init__(self, experiment, saveDir = None, isGPU = config.get_process() == 'gpu', isMultiCPU = True):
14
14
  self.reconPhantom = None
15
15
  self.reconLaser = None
16
16
  self.experiment = experiment
@@ -21,7 +21,6 @@ class Recon(ABC):
21
21
  self.CRC = None
22
22
 
23
23
  self.isGPU = isGPU
24
- self.isMultiGPU = isMultiGPU
25
24
  self.isMultiCPU = isMultiCPU
26
25
 
27
26
  if str(type(self.experiment)) != str(Tomography):
@@ -31,7 +30,7 @@ class Recon(ABC):
31
30
  def run(self,withTumor = True):
32
31
  pass
33
32
 
34
- def save(self, withTumor=True, overwrite=False):
33
+ def save(self, withTumor=True, overwrite=False, date=None, show_logs=True):
35
34
  """
36
35
  Save the reconstruction results (reconPhantom is with tumor, reconLaser is without tumor) and indices of the saved recon results, in numpy format.
37
36
 
@@ -42,23 +41,31 @@ class Recon(ABC):
42
41
  Warnings:
43
42
  reconPhantom and reconLaser are lists of 2D numpy arrays, each array corresponding to one iteration.
44
43
  """
45
- should_save, filepath = self.checkExistingFile(withTumor, overwrite)
46
- if not should_save:
44
+ isExisting, filepath = self.checkExistingFile(date=date)
45
+ if isExisting and not overwrite:
47
46
  return
47
+
48
+ filename = 'reconPhantom.npy' if withTumor else 'reconLaser.npy'
49
+ filepathRecon = os.path.join(filepath, filename)
48
50
 
49
51
  if withTumor:
50
52
  if not self.reconPhantom or len(self.reconPhantom) == 0:
51
53
  raise ValueError("Reconstructed phantom is empty. Run reconstruction first.")
52
- np.save(filepath, np.array(self.reconPhantom))
54
+ np.save(filepathRecon, np.array(self.reconPhantom))
53
55
  else:
54
56
  if not self.reconLaser or len(self.reconLaser) == 0:
55
57
  raise ValueError("Reconstructed laser is empty. Run reconstruction first.")
56
- np.save(filepath, np.array(self.reconLaser))
58
+ np.save(filepathRecon, np.array(self.reconLaser))
57
59
 
58
- print(f"Reconstruction results saved to {os.path.dirname(filepath)}")
60
+ if self.indices is not None and len(self.indices) > 0:
61
+ filepathIndices = os.path.join(filepath, "indices.npy")
62
+ np.save(filepathIndices, np.array(self.indices))
63
+
64
+ if show_logs:
65
+ print(f"Reconstruction results saved to {os.path.dirname(filepath)}")
59
66
 
60
67
  @abstractmethod
61
- def checkExistingFile(self, withTumor=True, overwrite=False):
68
+ def checkExistingFile(self, date = None):
62
69
  pass
63
70
 
64
71
  def calculateCRC(self, use_ROI=True):
@@ -132,7 +139,7 @@ class Recon(ABC):
132
139
  if self.reconType in (ReconType.Analytic, ReconType.DeepLearning):
133
140
  self.MSE = mse(self.experiment.OpticImage.phantom, self.reconPhantom)
134
141
 
135
- elif self.reconType in (ReconType.Algebraic, ReconType.Bayesian):
142
+ elif self.reconType in (ReconType.Algebraic, ReconType.Bayesian, ReconType.Convex):
136
143
  self.MSE = []
137
144
  for theta in self.reconPhantom:
138
145
  self.MSE.append(mse(self.experiment.OpticImage.phantom, theta))
@@ -158,10 +165,9 @@ class Recon(ABC):
158
165
  data_range = theta.max() - theta.min()
159
166
  ssim_value = ssim(self.experiment.OpticImage.phantom, theta, data_range=data_range)
160
167
  self.SSIM.append(ssim_value)
161
-
162
- def show(self, withTumor=True, savePath=None):
163
- fig, axs = plt.subplots(1, 2, figsize=(20, 10))
168
+
164
169
 
170
+ def show(self, withTumor=True, savePath=None):
165
171
  if withTumor:
166
172
  if self.reconPhantom is None or self.reconPhantom == []:
167
173
  raise ValueError("Reconstructed phantom with tumor is empty. Run reconstruction first.")
@@ -169,9 +175,31 @@ class Recon(ABC):
169
175
  image = self.reconPhantom[-1]
170
176
  else:
171
177
  image = self.reconPhantom
172
- # Phantom original
178
+ if self.experiment.OpticImage is None:
179
+ fig, axs = plt.subplots(1, 1, figsize=(10, 10))
180
+ else:
181
+ fig, axs = plt.subplots(1, 2, figsize=(20, 10))
182
+ # Phantom original
183
+ im1 = axs[1].imshow(
184
+ self.experiment.OpticImage.phantom,
185
+ cmap='hot',
186
+ vmin=0,
187
+ vmax=1,
188
+ extent=(
189
+ self.experiment.params.general['Xrange'][0],
190
+ self.experiment.params.general['Xrange'][1],
191
+ self.experiment.params.general['Zrange'][1],
192
+ self.experiment.params.general['Zrange'][0]
193
+ ),
194
+ aspect='equal'
195
+ )
196
+ axs[1].set_title("Phantom with tumor")
197
+ axs[1].set_xlabel("x (mm)", fontsize=12)
198
+ axs[1].set_ylabel("z (mm)", fontsize=12)
199
+ axs[1].tick_params(axis='both', which='major', labelsize=8)
200
+ # Phantom reconstruit
173
201
  im0 = axs[0].imshow(
174
- self.experiment.OpticImage.phantom,
202
+ image,
175
203
  cmap='hot',
176
204
  vmin=0,
177
205
  vmax=1,
@@ -183,29 +211,11 @@ class Recon(ABC):
183
211
  ),
184
212
  aspect='equal'
185
213
  )
186
- axs[0].set_title("Phantom with tumor")
214
+ axs[0].set_title("Reconstructed phantom with tumor")
187
215
  axs[0].set_xlabel("x (mm)", fontsize=12)
188
216
  axs[0].set_ylabel("z (mm)", fontsize=12)
189
217
  axs[0].tick_params(axis='both', which='major', labelsize=8)
190
- # Phantom reconstruit
191
- im1 = axs[1].imshow(
192
- image,
193
- cmap='hot',
194
- vmin=0,
195
- vmax=1,
196
- extent=(
197
- self.experiment.params.general['Xrange'][0],
198
- self.experiment.params.general['Xrange'][1],
199
- self.experiment.params.general['Zrange'][1],
200
- self.experiment.params.general['Zrange'][0]
201
- ),
202
- aspect='equal'
203
- )
204
- axs[1].set_title("Reconstructed phantom with tumor")
205
- axs[1].set_xlabel("x (mm)", fontsize=12)
206
- axs[1].set_ylabel("z (mm)", fontsize=12)
207
- axs[1].tick_params(axis='both', which='major', labelsize=8)
208
- axs[1].tick_params(axis='y', which='both', left=False, right=False, labelleft=False)
218
+ axs[0].tick_params(axis='y', which='both', left=False, right=False, labelleft=False)
209
219
  else:
210
220
  if self.reconLaser is None or self.reconLaser == []:
211
221
  raise ValueError("Reconstructed laser without tumor is empty. Run reconstruction first.")
@@ -213,9 +223,31 @@ class Recon(ABC):
213
223
  image = self.reconLaser[-1]
214
224
  else:
215
225
  image = self.reconLaser
216
- # Laser original
226
+ if self.experiment.OpticImage is None:
227
+ fig, axs = plt.subplots(1, 1, figsize=(10, 10))
228
+ else:
229
+ fig, axs = plt.subplots(1, 2, figsize=(20, 10))
230
+ # Laser original
231
+ im1 = axs[1].imshow(
232
+ self.experiment.OpticImage.laser.intensity,
233
+ cmap='hot',
234
+ vmin=0,
235
+ vmax=np.max(self.experiment.OpticImage.laser.intensity),
236
+ extent=(
237
+ self.experiment.params.general['Xrange'][0],
238
+ self.experiment.params.general['Xrange'][1],
239
+ self.experiment.params.general['Zrange'][1],
240
+ self.experiment.params.general['Zrange'][0]
241
+ ),
242
+ aspect='equal'
243
+ )
244
+ axs[1].set_title("Laser without tumor")
245
+ axs[1].set_xlabel("x (mm)", fontsize=12)
246
+ axs[1].set_ylabel("z (mm)", fontsize=12)
247
+ axs[1].tick_params(axis='both', which='major', labelsize=8)
248
+ # Laser reconstruit
217
249
  im0 = axs[0].imshow(
218
- self.experiment.OpticImage.laser.intensity,
250
+ image,
219
251
  cmap='hot',
220
252
  vmin=0,
221
253
  vmax=np.max(self.experiment.OpticImage.laser.intensity),
@@ -225,36 +257,18 @@ class Recon(ABC):
225
257
  self.experiment.params.general['Zrange'][1],
226
258
  self.experiment.params.general['Zrange'][0]
227
259
  ),
228
- aspect='equal'
260
+ aspect='equal'
229
261
  )
230
- axs[0].set_title("Laser without tumor")
262
+ axs[0].set_title("Reconstructed laser without tumor")
231
263
  axs[0].set_xlabel("x (mm)", fontsize=12)
232
264
  axs[0].set_ylabel("z (mm)", fontsize=12)
233
265
  axs[0].tick_params(axis='both', which='major', labelsize=8)
234
- # Laser reconstruit
235
- im1 = axs[1].imshow(
236
- image,
237
- cmap='hot',
238
- vmin=0,
239
- vmax=np.max(self.experiment.OpticImage.laser.intensity),
240
- extent=(
241
- self.experiment.params.general['Xrange'][0],
242
- self.experiment.params.general['Xrange'][1],
243
- self.experiment.params.general['Zrange'][1],
244
- self.experiment.params.general['Zrange'][0]
245
- ),
246
- aspect='equal'
247
- )
248
- axs[1].set_title("Reconstructed laser without tumor")
249
- axs[1].set_xlabel("x (mm)", fontsize=12)
250
- axs[1].set_ylabel("z (mm)", fontsize=12)
251
- axs[1].tick_params(axis='both', which='major', labelsize=8)
252
- axs[1].tick_params(axis='y', which='both', left=False, right=False, labelleft=False)
266
+ axs[0].tick_params(axis='y', which='both', left=False, right=False, labelleft=False)
253
267
 
254
268
  # Colorbar commune
255
269
  fig.subplots_adjust(bottom=0.2)
256
270
  cbar_ax = fig.add_axes([0.25, 0.08, 0.5, 0.03])
257
- cbar = fig.colorbar(im1, cax=cbar_ax, orientation='horizontal')
271
+ cbar = fig.colorbar(im0, cax=cbar_ax, orientation='horizontal')
258
272
  cbar.set_label('Normalized Intensity', fontsize=12)
259
273
  cbar.ax.tick_params(labelsize=8)
260
274
 
AOT_biomaps/__init__.py CHANGED
@@ -74,6 +74,9 @@ from .AOT_Recon.AOT_Optimizers.DEPIERRO import *
74
74
  from .AOT_Recon.AOT_Optimizers.MAPEM import *
75
75
  from .AOT_Recon.AOT_Optimizers.MLEM import *
76
76
  from .AOT_Recon.AOT_Optimizers.PDHG import *
77
+ # SPARSE S-MATRIX
78
+ from .AOT_Recon.AOT_SparseSMatrix.SparseSMatrix_CSR import *
79
+ from .AOT_Recon.AOT_SparseSMatrix.SparseSMatrix_SELL import *
77
80
  # POTENTIAL FUNCTIONS
78
81
  from .AOT_Recon.AOT_PotentialFunctions.Huber import *
79
82
  from .AOT_Recon.AOT_PotentialFunctions.Quadratic import *
@@ -82,7 +85,7 @@ from .AOT_Recon.AOT_PotentialFunctions.RelativeDifferences import *
82
85
  from .Config import config
83
86
  from .Settings import *
84
87
 
85
- __version__ = '2.9.167'
88
+ __version__ = '2.9.270'
86
89
  __process__ = config.get_process()
87
90
 
88
91
  def initialize(process=None):
@@ -131,76 +134,3 @@ def initialize(process=None):
131
134
 
132
135
 
133
136
 
134
-
135
-
136
-
137
-
138
-
139
-
140
-
141
-
142
-
143
-
144
-
145
-
146
-
147
-
148
-
149
-
150
-
151
-
152
-
153
-
154
-
155
-
156
-
157
-
158
-
159
-
160
-
161
-
162
-
163
-
164
-
165
-
166
-
167
-
168
-
169
-
170
-
171
-
172
-
173
-
174
-
175
-
176
-
177
-
178
-
179
-
180
-
181
-
182
-
183
-
184
-
185
-
186
-
187
-
188
-
189
-
190
-
191
-
192
-
193
-
194
-
195
-
196
-
197
-
198
-
199
-
200
-
201
-
202
-
203
-
204
-
205
-
206
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: AOT_biomaps
3
- Version: 2.9.167
3
+ Version: 2.9.270
4
4
  Summary: Acousto-Optic Tomography
5
5
  Home-page: https://github.com/LucasDuclos/AcoustoOpticTomography
6
6
  Author: Lucas Duclos
@@ -15,6 +15,7 @@ Requires-Dist: nvidia-ml-py3==7.352.0
15
15
  Requires-Dist: numpy==1.26.4
16
16
  Requires-Dist: torch==2.7.0
17
17
  Requires-Dist: scipy==1.13.1
18
+ Requires-Dist: cupy-cuda12x==13.6.0
18
19
  Dynamic: author
19
20
  Dynamic: author-email
20
21
  Dynamic: home-page
@@ -0,0 +1,47 @@
1
+ AOT_biomaps/Config.py,sha256=ghEOP1n8aO1pR-su13wMeAZAxZRfry5hH67NbtZ8SqI,3614
2
+ AOT_biomaps/Settings.py,sha256=v8fPhnvvcfBJP29m1RLOTEr3jndGLGwbUiORXmsj2Bo,2853
3
+ AOT_biomaps/__init__.py,sha256=iEepgwL2rWJA8lbRj13CVqHYGC2VHsTf6zp7mQFm480,4202
4
+ AOT_biomaps/AOT_Acoustic/AcousticEnums.py,sha256=s5kXa6jKzbS4btwbubrVcynLOr0yg5tth5vL_FGfbMk,1802
5
+ AOT_biomaps/AOT_Acoustic/AcousticTools.py,sha256=al7xXKMY5e-qQQ7nrQVPVAmqYiB320OluNlY6ti8iKc,7539
6
+ AOT_biomaps/AOT_Acoustic/FocusedWave.py,sha256=3kGKKDx_3Msy5COYqIwzROPORGWvNjw8UsDanBfkMXE,11037
7
+ AOT_biomaps/AOT_Acoustic/IrregularWave.py,sha256=yZhtxkR6zlciRcEpdTR0BAhvgQl40XHKFaF8f4VXarE,3035
8
+ AOT_biomaps/AOT_Acoustic/PlaneWave.py,sha256=xza-rj5AUWDecLkGDxRcULrwZVWeBvGnEP2d51TyR04,1447
9
+ AOT_biomaps/AOT_Acoustic/StructuredWave.py,sha256=jTLVlOhYLWJb5MxZPxhq3OFVlz2McoyMPBmfLvnekDU,18209
10
+ AOT_biomaps/AOT_Acoustic/__init__.py,sha256=t9M2rRqa_L9pk7W2FeELTkHEMuP4DBr4gBRldMqsQbg,491
11
+ AOT_biomaps/AOT_Acoustic/_mainAcoustic.py,sha256=RdmhRF1i0KAlpsP7_wnZ7F4J27br3eUc4XR91Qq7C64,44158
12
+ AOT_biomaps/AOT_Experiment/Focus.py,sha256=B2nBawmv-NG2AWJx9zgQ8GlN6aFB9FwTSqX-M-phKXg,3193
13
+ AOT_biomaps/AOT_Experiment/Tomography.py,sha256=Ri83b4GMrxJO60qWsK9JInS9a7HU2Q8uqpjD3Xkl9OY,24488
14
+ AOT_biomaps/AOT_Experiment/__init__.py,sha256=H9zMLeBLA6uhbaHohAa-2u5mDDxqJi8oE5c6tShdQp8,308
15
+ AOT_biomaps/AOT_Experiment/_mainExperiment.py,sha256=zSfuNrsz7nhiKrGIdK6CAXjlI2T6qYC5-JXHFgPNzhc,24674
16
+ AOT_biomaps/AOT_Optic/Absorber.py,sha256=jEodzRy7gkEH-wbazVasRQiri0dU16BfapmR-qnTSvM,867
17
+ AOT_biomaps/AOT_Optic/Laser.py,sha256=uzQwxswjU0kZWix3CmZLoWmhsBa3VhN27STprNv-xB8,2986
18
+ AOT_biomaps/AOT_Optic/OpticEnums.py,sha256=b349_JyjHqQohmjK4Wke-A_HLGaqb3_BKbyUqFC4jxY,499
19
+ AOT_biomaps/AOT_Optic/__init__.py,sha256=HSUVhfz0NzwHHZZ9KP9Xyfu33IgP_rYJX86J-gEROlo,321
20
+ AOT_biomaps/AOT_Optic/_mainOptic.py,sha256=Wk63CcgWbU-ygMfjNK80islaUbGGJpTXgZY3_C2KQNY,8179
21
+ AOT_biomaps/AOT_Recon/AOT_biomaps_kernels.cubin,sha256=_pYCvzNSnoJgBo_d0IRrkyka41XgZ4axzqCFMfnGRRI,61544
22
+ AOT_biomaps/AOT_Recon/AlgebraicRecon.py,sha256=DG9mLMYXRX6cMYjbRRoXAAuGxQQIQKq3lat6rYn5XWM,46099
23
+ AOT_biomaps/AOT_Recon/AnalyticRecon.py,sha256=RaQ5AJ1HUmSct0BgjZ0GWSJg7SALCn3Q0laqj1yyhAE,7123
24
+ AOT_biomaps/AOT_Recon/BayesianRecon.py,sha256=RnnPa-tTcvirwiNPnCRZnSM4NWeEEltYET-piBbp34g,12671
25
+ AOT_biomaps/AOT_Recon/DeepLearningRecon.py,sha256=RfVcEsi4GeGqJn0_SPxwQPQx6IQjin79WKh2UarMRLI,1383
26
+ AOT_biomaps/AOT_Recon/PrimalDualRecon.py,sha256=-7dqUxKXbHt7yR1I1kGcu1TOXn05ik6QoDDsuM0QvNU,10310
27
+ AOT_biomaps/AOT_Recon/ReconEnums.py,sha256=KAf55RqHAr2ilt6pxFrUBGQOn-7HA8NP6TyL-1FNiXo,19714
28
+ AOT_biomaps/AOT_Recon/ReconTools.py,sha256=1iHAjtlV3BX3iHxkOwyb7z5DkmBmO7VspwqsDYB-B2U,15138
29
+ AOT_biomaps/AOT_Recon/__init__.py,sha256=xs_argJqXKFl76xP7-jiUc1ynOEEtY7XZ0gDxD5uVZc,246
30
+ AOT_biomaps/AOT_Recon/_mainRecon.py,sha256=exoa2UBMfMHjemxAU9dW0mhEfsP6Oe1qjSfrTrgbIcY,13125
31
+ AOT_biomaps/AOT_Recon/AOT_Optimizers/DEPIERRO.py,sha256=qA1n722GLQJH3V8HcLr5q_GxEwBS_NRlIT3E6JZk-Ag,9479
32
+ AOT_biomaps/AOT_Recon/AOT_Optimizers/LS.py,sha256=N7v1xN9I-adIe3c20LN9Drc4-fBSLc9SEmJS8B3Zmag,4343
33
+ AOT_biomaps/AOT_Recon/AOT_Optimizers/MAPEM.py,sha256=vQLCB0L4FSXJKn2_6kdIdWrI6WZ82KuqUh7CSqBGVuo,25766
34
+ AOT_biomaps/AOT_Recon/AOT_Optimizers/MLEM.py,sha256=di5ZpC4ID6CgkFdfaENTjtnnsvf2c331NHyPJqukyUM,21181
35
+ AOT_biomaps/AOT_Recon/AOT_Optimizers/PDHG.py,sha256=5w4klYKAct9_gnlyocIiJfDrQUdz_VhXQVSpfjrjvNU,7927
36
+ AOT_biomaps/AOT_Recon/AOT_Optimizers/__init__.py,sha256=tNGVulINaqQZzcs5cvCMAT5ypGdoFWRnxtl9y7ePECk,106
37
+ AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/Huber.py,sha256=dRd1t5OBag_gVmfji3L0QrA1GJ_702LcCkLH32Bot0M,3285
38
+ AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/Quadratic.py,sha256=wTbzcXxMdEl9ReEXrL43DOJQecokBwJYU_s2kQUASZY,2545
39
+ AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/RelativeDifferences.py,sha256=ZlWaKsNPCMfy4fWxYFT2pSoKMbysQkJH4N1WbbWncq4,2493
40
+ AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/__init__.py,sha256=RwrJdLOFbAFBFnRxo5xdlOyeZgtQRDaRWDN9-uCGUiY,84
41
+ AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_CSR.py,sha256=rZigEUe0d1reCBU-IT4LexbO5uUyps-ZkzhdH3j0PLc,12408
42
+ AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_SELL.py,sha256=jSwtfQvhZi9R0tG7tDsWwyXoftgbq4FQi9Yxoahuzhw,12866
43
+ AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/__init__.py,sha256=8nou-hqjQjuCTLhoL5qv4EM_lMPFviAZAZKSPhi84jE,67
44
+ aot_biomaps-2.9.270.dist-info/METADATA,sha256=TUjwBnJTI1xN-RlfNNphbzWZrgH1rtwmLNxwZm6m6GA,700
45
+ aot_biomaps-2.9.270.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
46
+ aot_biomaps-2.9.270.dist-info/top_level.txt,sha256=6STF-lT4kaAnBHJYCripmN5mZABoHjMuY689JdiDphk,12
47
+ aot_biomaps-2.9.270.dist-info/RECORD,,
@@ -1,43 +0,0 @@
1
- AOT_biomaps/Config.py,sha256=ghEOP1n8aO1pR-su13wMeAZAxZRfry5hH67NbtZ8SqI,3614
2
- AOT_biomaps/Settings.py,sha256=v8fPhnvvcfBJP29m1RLOTEr3jndGLGwbUiORXmsj2Bo,2853
3
- AOT_biomaps/__init__.py,sha256=Ku39fDD9dr1QTQqsoJmPKJ3h7Gg8ggXKCDWrj5dZSOo,4204
4
- AOT_biomaps/AOT_Acoustic/AcousticEnums.py,sha256=s5kXa6jKzbS4btwbubrVcynLOr0yg5tth5vL_FGfbMk,1802
5
- AOT_biomaps/AOT_Acoustic/AcousticTools.py,sha256=al7xXKMY5e-qQQ7nrQVPVAmqYiB320OluNlY6ti8iKc,7539
6
- AOT_biomaps/AOT_Acoustic/FocusedWave.py,sha256=3kGKKDx_3Msy5COYqIwzROPORGWvNjw8UsDanBfkMXE,11037
7
- AOT_biomaps/AOT_Acoustic/IrregularWave.py,sha256=yZhtxkR6zlciRcEpdTR0BAhvgQl40XHKFaF8f4VXarE,3035
8
- AOT_biomaps/AOT_Acoustic/PlaneWave.py,sha256=xza-rj5AUWDecLkGDxRcULrwZVWeBvGnEP2d51TyR04,1447
9
- AOT_biomaps/AOT_Acoustic/StructuredWave.py,sha256=LlHBxGYmTsM1gQVaJXlUxIOsqg6zTIPBAZK46v3UUiE,18205
10
- AOT_biomaps/AOT_Acoustic/__init__.py,sha256=t9M2rRqa_L9pk7W2FeELTkHEMuP4DBr4gBRldMqsQbg,491
11
- AOT_biomaps/AOT_Acoustic/_mainAcoustic.py,sha256=lA5ZbX-fuqlSNphdpzWUdLuM5BHqPLPu2Q7i9OwbSIs,43624
12
- AOT_biomaps/AOT_Experiment/Focus.py,sha256=B2nBawmv-NG2AWJx9zgQ8GlN6aFB9FwTSqX-M-phKXg,3193
13
- AOT_biomaps/AOT_Experiment/Tomography.py,sha256=H3DZKSzoGZlV9gEpRyCgIW7KPn-qZn3V2RTmf6DUrmE,20901
14
- AOT_biomaps/AOT_Experiment/__init__.py,sha256=H9zMLeBLA6uhbaHohAa-2u5mDDxqJi8oE5c6tShdQp8,308
15
- AOT_biomaps/AOT_Experiment/_mainExperiment.py,sha256=SbDmSNQoNS5G0-QwpV94KeV6XtdN5xzfFCnQPQWrH1Y,21891
16
- AOT_biomaps/AOT_Optic/Absorber.py,sha256=jEodzRy7gkEH-wbazVasRQiri0dU16BfapmR-qnTSvM,867
17
- AOT_biomaps/AOT_Optic/Laser.py,sha256=uzQwxswjU0kZWix3CmZLoWmhsBa3VhN27STprNv-xB8,2986
18
- AOT_biomaps/AOT_Optic/OpticEnums.py,sha256=b349_JyjHqQohmjK4Wke-A_HLGaqb3_BKbyUqFC4jxY,499
19
- AOT_biomaps/AOT_Optic/__init__.py,sha256=HSUVhfz0NzwHHZZ9KP9Xyfu33IgP_rYJX86J-gEROlo,321
20
- AOT_biomaps/AOT_Optic/_mainOptic.py,sha256=Wk63CcgWbU-ygMfjNK80islaUbGGJpTXgZY3_C2KQNY,8179
21
- AOT_biomaps/AOT_Recon/AlgebraicRecon.py,sha256=rBkhrrC17XT5UUiTy3SSvo0lk_sYDRq62hvucxDwTDA,38877
22
- AOT_biomaps/AOT_Recon/AnalyticRecon.py,sha256=U4mMCDkhJ5f3v1LUCy5mVDfrMZGX3GV4Xuxgnyqx2QI,7616
23
- AOT_biomaps/AOT_Recon/BayesianRecon.py,sha256=SD53o887b48XJstau-N_sGds2cS-X1hUEmrHYoCr5T8,17006
24
- AOT_biomaps/AOT_Recon/DeepLearningRecon.py,sha256=jtVbfDw6HgVw3vGaEcwJ4g2j43j749pvldTATOfUHmQ,1403
25
- AOT_biomaps/AOT_Recon/PrimalDualRecon.py,sha256=n3XN4SBOOo4sMhT_gAjg527LYFMB096DnH1i9wFyjU4,9622
26
- AOT_biomaps/AOT_Recon/ReconEnums.py,sha256=oyT9qIfEpE_ChPQihM8-6b0UOtNmuE4weUpO8lJCB38,18641
27
- AOT_biomaps/AOT_Recon/ReconTools.py,sha256=dz0ZmyT5ggJEaBXJJS7WbsWpj0fTa2rZqym_qdQ2hbk,10610
28
- AOT_biomaps/AOT_Recon/__init__.py,sha256=LDbNpsjS8_TJrXMKzkpzSAj5trVuCW57AWQaJBrzd0I,244
29
- AOT_biomaps/AOT_Recon/_mainRecon.py,sha256=pRs_ep0TKeRpyJ1EToNerZCMPGO8YdNMO90Pn2CIHS4,12323
30
- AOT_biomaps/AOT_Recon/AOT_Optimizers/DEPIERRO.py,sha256=Oc5Z_G2EGctN4y1NNmZMBF6kzPnaaCjjLr32ecHTVoo,8012
31
- AOT_biomaps/AOT_Recon/AOT_Optimizers/LS.py,sha256=DOaNHmyQNXBG2JbYpprKtoX9bnRT0DL_faKQqH1LNrs,4020
32
- AOT_biomaps/AOT_Recon/AOT_Optimizers/MAPEM.py,sha256=suH4bNq_DN7pZYOyV2kESAaFKA6guyxv1NoRQJbdkMc,22818
33
- AOT_biomaps/AOT_Recon/AOT_Optimizers/MLEM.py,sha256=QIowCEeTetIkxMeB-fe32vbamTXHNT2ycvVofgdun6U,11805
34
- AOT_biomaps/AOT_Recon/AOT_Optimizers/PDHG.py,sha256=TGN_QLYr4k47ZGRMvcWsLbqjRqFOWm2y97-hFhvmv6k,7930
35
- AOT_biomaps/AOT_Recon/AOT_Optimizers/__init__.py,sha256=tNGVulINaqQZzcs5cvCMAT5ypGdoFWRnxtl9y7ePECk,106
36
- AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/Huber.py,sha256=dRd1t5OBag_gVmfji3L0QrA1GJ_702LcCkLH32Bot0M,3285
37
- AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/Quadratic.py,sha256=wTbzcXxMdEl9ReEXrL43DOJQecokBwJYU_s2kQUASZY,2545
38
- AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/RelativeDifferences.py,sha256=dgB3Vt40S5D1VerHr-h-YnzB5xNCt6amE19-C0zyIpU,2253
39
- AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/__init__.py,sha256=RwrJdLOFbAFBFnRxo5xdlOyeZgtQRDaRWDN9-uCGUiY,84
40
- aot_biomaps-2.9.167.dist-info/METADATA,sha256=irRCNfqcGArp-fdSAb-KLaOz6T1RbGicEbFpba64Su8,663
41
- aot_biomaps-2.9.167.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
42
- aot_biomaps-2.9.167.dist-info/top_level.txt,sha256=6STF-lT4kaAnBHJYCripmN5mZABoHjMuY689JdiDphk,12
43
- aot_biomaps-2.9.167.dist-info/RECORD,,