AOT-biomaps 2.9.177__py3-none-any.whl → 2.9.261__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.
- AOT_biomaps/AOT_Acoustic/StructuredWave.py +2 -2
- AOT_biomaps/AOT_Acoustic/_mainAcoustic.py +11 -6
- AOT_biomaps/AOT_Experiment/Tomography.py +74 -4
- AOT_biomaps/AOT_Experiment/_mainExperiment.py +95 -55
- AOT_biomaps/AOT_Recon/AOT_Optimizers/DEPIERRO.py +48 -13
- AOT_biomaps/AOT_Recon/AOT_Optimizers/LS.py +9 -6
- AOT_biomaps/AOT_Recon/AOT_Optimizers/MAPEM.py +118 -38
- AOT_biomaps/AOT_Recon/AOT_Optimizers/MLEM.py +268 -102
- AOT_biomaps/AOT_Recon/AOT_Optimizers/PDHG.py +1 -1
- AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/RelativeDifferences.py +10 -14
- AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_CSR.py +252 -0
- AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_SELL.py +322 -0
- AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/__init__.py +2 -0
- AOT_biomaps/AOT_Recon/AlgebraicRecon.py +248 -141
- AOT_biomaps/AOT_Recon/AnalyticRecon.py +27 -42
- AOT_biomaps/AOT_Recon/BayesianRecon.py +84 -151
- AOT_biomaps/AOT_Recon/DeepLearningRecon.py +1 -1
- AOT_biomaps/AOT_Recon/PrimalDualRecon.py +69 -62
- AOT_biomaps/AOT_Recon/ReconEnums.py +27 -2
- AOT_biomaps/AOT_Recon/ReconTools.py +84 -13
- AOT_biomaps/AOT_Recon/__init__.py +1 -0
- AOT_biomaps/AOT_Recon/_mainRecon.py +72 -58
- AOT_biomaps/__init__.py +4 -93
- {aot_biomaps-2.9.177.dist-info → aot_biomaps-2.9.261.dist-info}/METADATA +2 -1
- aot_biomaps-2.9.261.dist-info/RECORD +46 -0
- aot_biomaps-2.9.177.dist-info/RECORD +0 -43
- {aot_biomaps-2.9.177.dist-info → aot_biomaps-2.9.261.dist-info}/WHEEL +0 -0
- {aot_biomaps-2.9.177.dist-info → aot_biomaps-2.9.261.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
|
|
357
|
+
"""Poisson noise."""
|
|
358
358
|
GAUSSIAN = 'gaussian'
|
|
359
|
-
"""Gaussian noise
|
|
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
|
+
"""
|
|
@@ -3,7 +3,7 @@ import torch
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
from numba import njit, prange
|
|
5
5
|
from torch_sparse import coalesce
|
|
6
|
-
import
|
|
6
|
+
import cupyx.scipy.sparse as cpsparse
|
|
7
7
|
|
|
8
8
|
def load_recon(hdr_path):
|
|
9
9
|
"""
|
|
@@ -78,7 +78,7 @@ def load_recon(hdr_path):
|
|
|
78
78
|
rescale_offset = float(header.get('data rescale offset', 0))
|
|
79
79
|
image = image * rescale_slope + rescale_offset
|
|
80
80
|
|
|
81
|
-
return image
|
|
81
|
+
return image
|
|
82
82
|
|
|
83
83
|
def mse(y_true, y_pred):
|
|
84
84
|
"""
|
|
@@ -150,20 +150,46 @@ def ssim(img1, img2, win_size=7, k1=0.01, k2=0.03, L=1.0):
|
|
|
150
150
|
return np.mean(ssim_map)
|
|
151
151
|
|
|
152
152
|
def calculate_memory_requirement(SMatrix, y):
|
|
153
|
-
"""
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
|
153
|
+
"""
|
|
154
|
+
Calcule la mémoire requise (en Go) pour :
|
|
155
|
+
- SMatrix : np.ndarray (dense) ou cpsparse.csr_matrix (sparse)
|
|
156
|
+
- y : vecteur (NumPy ou CuPy, float32)
|
|
161
157
|
|
|
162
|
-
|
|
158
|
+
Args:
|
|
159
|
+
SMatrix: np.ndarray ou cpsparse.csr_matrix
|
|
160
|
+
y: vecteur (float32)
|
|
161
|
+
"""
|
|
162
|
+
# 1. Mémoire pour SMatrix
|
|
163
|
+
if isinstance(SMatrix, cpsparse.csr_matrix):
|
|
164
|
+
# Matrice CSR CuPy
|
|
165
|
+
nnz = SMatrix.nnz
|
|
166
|
+
num_cols = SMatrix.shape[1]
|
|
167
|
+
size_SMatrix = nnz * (4 + 4) + (num_cols + 1) * 4 # data (float32) + indices (int32) + indptr (int32)
|
|
168
|
+
elif isinstance(SMatrix, np.ndarray):
|
|
169
|
+
# Tableau NumPy dense (float32)
|
|
170
|
+
size_SMatrix = SMatrix.nbytes
|
|
171
|
+
else:
|
|
172
|
+
raise ValueError("SMatrix doit être un np.ndarray ou une matrice CSR CuPy.")
|
|
173
|
+
|
|
174
|
+
# 2. Mémoire pour y (float32)
|
|
175
|
+
if hasattr(y, 'nbytes'):
|
|
176
|
+
size_y = y.nbytes
|
|
177
|
+
else:
|
|
178
|
+
size_y = np.prod(y.shape) * 4 # float32
|
|
179
|
+
|
|
180
|
+
# Total en Go
|
|
181
|
+
total_bytes = size_SMatrix + size_y
|
|
182
|
+
total_GB = total_bytes / 1024**3
|
|
183
|
+
|
|
184
|
+
return total_GB
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def check_gpu_memory(device_index, required_memory, show_logs=True):
|
|
163
188
|
"""Check if enough memory is available on the specified GPU."""
|
|
164
|
-
free_memory,
|
|
189
|
+
free_memory, _ = torch.cuda.mem_get_info(f"cuda:{device_index}")
|
|
165
190
|
free_memory_gb = free_memory / 1024**3
|
|
166
|
-
|
|
191
|
+
if show_logs:
|
|
192
|
+
print(f"Free memory on GPU {device_index}: {free_memory_gb:.2f} GB, Required memory: {required_memory:.2f} GB")
|
|
167
193
|
return free_memory_gb >= required_memory
|
|
168
194
|
|
|
169
195
|
@njit(parallel=True)
|
|
@@ -270,3 +296,48 @@ def prox_F_star(y, sigma, a):
|
|
|
270
296
|
def prox_G(x, tau, K):
|
|
271
297
|
return torch.clamp(x - tau * K, min=0)
|
|
272
298
|
|
|
299
|
+
def filter_radon(f, N, filter_type, Fc):
|
|
300
|
+
"""
|
|
301
|
+
Implémente les filtres pour la rétroprojection filtrée (iRadon).
|
|
302
|
+
Inspirée de la fonction MATLAB FilterRadon de Mamouna Bocoum.
|
|
303
|
+
|
|
304
|
+
Paramètres :
|
|
305
|
+
------------
|
|
306
|
+
f : np.ndarray
|
|
307
|
+
Vecteur des fréquences (ex: f_t ou f_z).
|
|
308
|
+
N : int
|
|
309
|
+
Taille du filtre (longueur de f).
|
|
310
|
+
filter_type : str
|
|
311
|
+
Type de filtre : 'ram-lak', 'shepp-logan', 'cosine', 'hamming', 'hann'.
|
|
312
|
+
Fc : float
|
|
313
|
+
Fréquence de coupure.
|
|
314
|
+
|
|
315
|
+
Retourne :
|
|
316
|
+
-----------
|
|
317
|
+
FILTER : np.ndarray
|
|
318
|
+
Filtre appliqué aux fréquences.
|
|
319
|
+
"""
|
|
320
|
+
FILTER = np.abs(f)
|
|
321
|
+
|
|
322
|
+
if filter_type == 'ram-lak':
|
|
323
|
+
pass # FILTER = |f| (déjà calculé)
|
|
324
|
+
elif filter_type == 'shepp-logan':
|
|
325
|
+
# Évite la division par zéro
|
|
326
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
|
327
|
+
FILTER = FILTER * (np.sinc(2 * f / (2 * Fc))) # sin(2πf/(2Fc))/(2πf/(4Fc)) = sinc(2f/(2Fc))
|
|
328
|
+
FILTER[np.isnan(FILTER)] = 1.0 # Pour f=0
|
|
329
|
+
elif filter_type == 'cosine':
|
|
330
|
+
FILTER = FILTER * np.cos(2 * np.pi * f / (4 * Fc))
|
|
331
|
+
elif filter_type == 'hamming':
|
|
332
|
+
FILTER = FILTER * (0.54 + 0.46 * np.cos(2 * np.pi * f / Fc))
|
|
333
|
+
elif filter_type == 'hann':
|
|
334
|
+
FILTER = FILTER * (1 + np.cos(2 * np.pi * f / (4 * Fc))) / 2
|
|
335
|
+
else:
|
|
336
|
+
raise ValueError(f"Type de filtre inconnu : {filter_type}")
|
|
337
|
+
|
|
338
|
+
# Coupure des fréquences au-delà de Fc
|
|
339
|
+
FILTER[np.abs(f) > Fc] = 0
|
|
340
|
+
# Atténuation exponentielle (optionnelle, comme dans le code MATLAB)
|
|
341
|
+
FILTER = FILTER * np.exp(-2 * (np.abs(f) / Fc)**10)
|
|
342
|
+
|
|
343
|
+
return FILTER
|
|
@@ -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',
|
|
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, date=None):
|
|
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
|
-
isExisting, filepath = self.checkExistingFile(
|
|
44
|
+
isExisting, filepath = self.checkExistingFile(date=date)
|
|
46
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(
|
|
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(
|
|
58
|
+
np.save(filepathRecon, np.array(self.reconLaser))
|
|
57
59
|
|
|
58
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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("
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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("
|
|
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
|
-
|
|
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(
|
|
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.
|
|
88
|
+
__version__ = '2.9.261'
|
|
86
89
|
__process__ = config.get_process()
|
|
87
90
|
|
|
88
91
|
def initialize(process=None):
|
|
@@ -122,95 +125,3 @@ def initialize(process=None):
|
|
|
122
125
|
|
|
123
126
|
|
|
124
127
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: AOT_biomaps
|
|
3
|
-
Version: 2.9.
|
|
3
|
+
Version: 2.9.261
|
|
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,46 @@
|
|
|
1
|
+
AOT_biomaps/Config.py,sha256=ghEOP1n8aO1pR-su13wMeAZAxZRfry5hH67NbtZ8SqI,3614
|
|
2
|
+
AOT_biomaps/Settings.py,sha256=v8fPhnvvcfBJP29m1RLOTEr3jndGLGwbUiORXmsj2Bo,2853
|
|
3
|
+
AOT_biomaps/__init__.py,sha256=EAyX3lRoiynQtskCWC5xS9exXzUs8hl6NuOWBYnaHfQ,4184
|
|
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/AlgebraicRecon.py,sha256=DG9mLMYXRX6cMYjbRRoXAAuGxQQIQKq3lat6rYn5XWM,46099
|
|
22
|
+
AOT_biomaps/AOT_Recon/AnalyticRecon.py,sha256=RaQ5AJ1HUmSct0BgjZ0GWSJg7SALCn3Q0laqj1yyhAE,7123
|
|
23
|
+
AOT_biomaps/AOT_Recon/BayesianRecon.py,sha256=RnnPa-tTcvirwiNPnCRZnSM4NWeEEltYET-piBbp34g,12671
|
|
24
|
+
AOT_biomaps/AOT_Recon/DeepLearningRecon.py,sha256=RfVcEsi4GeGqJn0_SPxwQPQx6IQjin79WKh2UarMRLI,1383
|
|
25
|
+
AOT_biomaps/AOT_Recon/PrimalDualRecon.py,sha256=-7dqUxKXbHt7yR1I1kGcu1TOXn05ik6QoDDsuM0QvNU,10310
|
|
26
|
+
AOT_biomaps/AOT_Recon/ReconEnums.py,sha256=KAf55RqHAr2ilt6pxFrUBGQOn-7HA8NP6TyL-1FNiXo,19714
|
|
27
|
+
AOT_biomaps/AOT_Recon/ReconTools.py,sha256=NRTr13hEohXIyAw6p56CEsVFR4O0bDM-ijcPOs-cpxw,12936
|
|
28
|
+
AOT_biomaps/AOT_Recon/__init__.py,sha256=xs_argJqXKFl76xP7-jiUc1ynOEEtY7XZ0gDxD5uVZc,246
|
|
29
|
+
AOT_biomaps/AOT_Recon/_mainRecon.py,sha256=exoa2UBMfMHjemxAU9dW0mhEfsP6Oe1qjSfrTrgbIcY,13125
|
|
30
|
+
AOT_biomaps/AOT_Recon/AOT_Optimizers/DEPIERRO.py,sha256=qA1n722GLQJH3V8HcLr5q_GxEwBS_NRlIT3E6JZk-Ag,9479
|
|
31
|
+
AOT_biomaps/AOT_Recon/AOT_Optimizers/LS.py,sha256=N7v1xN9I-adIe3c20LN9Drc4-fBSLc9SEmJS8B3Zmag,4343
|
|
32
|
+
AOT_biomaps/AOT_Recon/AOT_Optimizers/MAPEM.py,sha256=vQLCB0L4FSXJKn2_6kdIdWrI6WZ82KuqUh7CSqBGVuo,25766
|
|
33
|
+
AOT_biomaps/AOT_Recon/AOT_Optimizers/MLEM.py,sha256=PoizVH4ifMyfJ7QSLsHP1gwKuUh9LLGPs_OaaZavpiM,19597
|
|
34
|
+
AOT_biomaps/AOT_Recon/AOT_Optimizers/PDHG.py,sha256=5w4klYKAct9_gnlyocIiJfDrQUdz_VhXQVSpfjrjvNU,7927
|
|
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=ZlWaKsNPCMfy4fWxYFT2pSoKMbysQkJH4N1WbbWncq4,2493
|
|
39
|
+
AOT_biomaps/AOT_Recon/AOT_PotentialFunctions/__init__.py,sha256=RwrJdLOFbAFBFnRxo5xdlOyeZgtQRDaRWDN9-uCGUiY,84
|
|
40
|
+
AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_CSR.py,sha256=tk8eZHyTpey4TNDmoFL9w88LjerviQmI5YeV8M2Iuq4,10689
|
|
41
|
+
AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/SparseSMatrix_SELL.py,sha256=nH9gBea7p_V5LaewFAG-Bkfp_YepMTExoaQcbRf4_Mk,14426
|
|
42
|
+
AOT_biomaps/AOT_Recon/AOT_SparseSMatrix/__init__.py,sha256=8nou-hqjQjuCTLhoL5qv4EM_lMPFviAZAZKSPhi84jE,67
|
|
43
|
+
aot_biomaps-2.9.261.dist-info/METADATA,sha256=7mJL-l-m4N7m-ScwYoV1Hey0n6dO6hHESAjzGHXgqm8,700
|
|
44
|
+
aot_biomaps-2.9.261.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
45
|
+
aot_biomaps-2.9.261.dist-info/top_level.txt,sha256=6STF-lT4kaAnBHJYCripmN5mZABoHjMuY689JdiDphk,12
|
|
46
|
+
aot_biomaps-2.9.261.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=V-O4OmNdkLfz7KbVUZ9g4X2N8WLKUy1_QXx-P9UhbuU,4224
|
|
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=YZK5KnG60CyHlQaxYg-J4tGVY3SzJPB4t8uvNwU1HMI,43934
|
|
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=7UmzTHvZ71DTGnoZeU83LN0jS33Haw_CvlPFsa-uQ54,39387
|
|
22
|
-
AOT_biomaps/AOT_Recon/AnalyticRecon.py,sha256=K413dIU1i_ERT7hL_GfDVgeyPxy8ZUZOHu48xS4bwsQ,7600
|
|
23
|
-
AOT_biomaps/AOT_Recon/BayesianRecon.py,sha256=HsGbKgjTfvQrzT4ebTV4g8fZnr35meHqobtswpkf5JM,16996
|
|
24
|
-
AOT_biomaps/AOT_Recon/DeepLearningRecon.py,sha256=_-2B0jAFPoqHaa7cuDvJPkUv9r_henollyMAWIF_4yY,1387
|
|
25
|
-
AOT_biomaps/AOT_Recon/PrimalDualRecon.py,sha256=Tl3zvM10ycJhHXEjL6kHtWOhN-z8oh2HrKZVKISX5EI,9610
|
|
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=EXfjw_hekHn9kJ5n-GnbnTtyQVp8r3H04mC4aLqEeuA,12340
|
|
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.177.dist-info/METADATA,sha256=wpM-7sI-rxHpsYBuhiG5GPUEVBPzKXBaiGE8eaNEuBw,663
|
|
41
|
-
aot_biomaps-2.9.177.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
42
|
-
aot_biomaps-2.9.177.dist-info/top_level.txt,sha256=6STF-lT4kaAnBHJYCripmN5mZABoHjMuY689JdiDphk,12
|
|
43
|
-
aot_biomaps-2.9.177.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|