antspymm 1.5.1__py3-none-any.whl → 1.5.3__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.
- antspymm/mm.py +28 -25
- {antspymm-1.5.1.dist-info → antspymm-1.5.3.dist-info}/METADATA +1 -1
- antspymm-1.5.3.dist-info/RECORD +7 -0
- antspymm-1.5.1.dist-info/RECORD +0 -7
- {antspymm-1.5.1.dist-info → antspymm-1.5.3.dist-info}/WHEEL +0 -0
- {antspymm-1.5.1.dist-info → antspymm-1.5.3.dist-info}/licenses/LICENSE +0 -0
- {antspymm-1.5.1.dist-info → antspymm-1.5.3.dist-info}/top_level.txt +0 -0
antspymm/mm.py
CHANGED
@@ -2198,9 +2198,10 @@ def dti_numpy_to_image( reference_image, tensorarray, upper_triangular=True):
|
|
2198
2198
|
def transform_and_reorient_dti( fixed, moving_dti, composite_transform, py_based=True, verbose=False, **kwargs):
|
2199
2199
|
"""
|
2200
2200
|
apply a transform to DTI in the style of ants.apply_transforms. this function
|
2201
|
-
expects a pre-computed composite transform which it will use to reorient
|
2202
|
-
the DTI using preservation of principle directions.
|
2203
|
-
|
2201
|
+
expects a pre-computed composite transform which it will use to reorient
|
2202
|
+
the DTI using preservation of principle directions. BUG fix by cookpa 2025
|
2203
|
+
06 18.
|
2204
|
+
|
2204
2205
|
fixed : antsImage reference space
|
2205
2206
|
|
2206
2207
|
moving_dti : antsImage DTI in upper triangular format
|
@@ -2224,34 +2225,36 @@ def transform_and_reorient_dti( fixed, moving_dti, composite_transform, py_based
|
|
2224
2225
|
dtiw = []
|
2225
2226
|
for k in range(len(dtsplit)):
|
2226
2227
|
dtiw.append( ants.apply_transforms( fixed, dtsplit[k], composite_transform ) )
|
2227
|
-
dtiw=ants.merge_channels(dtiw)
|
2228
|
+
dtiw=ants.merge_channels(dtiw) # resampled into fixed space but still based in moving index space
|
2228
2229
|
if verbose:
|
2229
2230
|
print("reorient tensors locally: compose and get reo image")
|
2230
|
-
locrot = ants.deformation_gradient( ants.image_read(composite_transform),
|
2231
|
+
locrot = ants.deformation_gradient( ants.image_read(composite_transform),
|
2231
2232
|
to_rotation = True, py_based=py_based ).numpy()
|
2232
|
-
|
2233
|
+
# rebases from moving index to fixed index space. Not quite what we need here
|
2234
|
+
# rebaser = np.dot( np.transpose( fixed.direction ), moving_dti.direction )
|
2233
2235
|
if verbose:
|
2234
2236
|
print("convert UT to full tensor")
|
2235
2237
|
dtiw2tensor = triangular_to_tensor( dtiw )
|
2236
2238
|
if verbose:
|
2237
|
-
print("rebase tensors to new space via iterator")
|
2239
|
+
print("rebase tensors to new space and apply reorientation via iterator")
|
2238
2240
|
it = np.ndindex( fixed.shape )
|
2239
2241
|
for i in it:
|
2240
|
-
# direction * dt * direction.transpose();
|
2241
2242
|
mmm = dtiw2tensor[i]
|
2242
|
-
#
|
2243
|
+
# Rebase mmm to physical space
|
2244
|
+
mmm = np.dot( mmm, np.transpose( moving_dti.direction ) )
|
2245
|
+
mmm = np.dot( moving_dti.direction, mmm )
|
2246
|
+
# Now apply local rotation
|
2243
2247
|
locrotx = np.reshape( locrot[i], [3,3] )
|
2244
2248
|
mmm = np.dot( mmm, np.transpose( locrotx ) )
|
2245
2249
|
mmm = np.dot( locrotx, mmm )
|
2246
|
-
#
|
2247
|
-
mmm = np.dot( mmm, np.transpose(
|
2248
|
-
mmm = np.dot(
|
2250
|
+
# Now rebase to fixed index space
|
2251
|
+
mmm = np.dot( mmm, np.transpose( fixed.direction ) )
|
2252
|
+
mmm = np.dot( fixed.direction, mmm )
|
2249
2253
|
dtiw2tensor[i] = mmm
|
2250
2254
|
if verbose:
|
2251
2255
|
print("done with rebasing")
|
2252
2256
|
return dti_numpy_to_image( fixed, dtiw2tensor )
|
2253
2257
|
|
2254
|
-
|
2255
2258
|
def dti_reg(
|
2256
2259
|
image,
|
2257
2260
|
avg_b0,
|
@@ -3655,8 +3658,8 @@ def efficient_tensor_fit( gtab, fit_method, imagein, maskin, diffusion_model='DT
|
|
3655
3658
|
|
3656
3659
|
|
3657
3660
|
def efficient_dwi_fit(gtab, diffusion_model, imagein, maskin,
|
3658
|
-
|
3659
|
-
|
3661
|
+
model_params=None, bvals_to_use=None,
|
3662
|
+
chunk_size=1024, num_threads=1, verbose=True):
|
3660
3663
|
"""
|
3661
3664
|
Efficient and optionally parallelized diffusion model reconstruction using DiPy.
|
3662
3665
|
|
@@ -3675,7 +3678,7 @@ def efficient_dwi_fit(gtab, diffusion_model, imagein, maskin,
|
|
3675
3678
|
bvals_to_use : list of int, optional
|
3676
3679
|
Subset of b-values to use for the fit (e.g., [0, 1000, 2000]).
|
3677
3680
|
chunk_size : int, optional
|
3678
|
-
|
3681
|
+
Maximum number of voxels per chunk (default 1024).
|
3679
3682
|
num_threads : int, optional
|
3680
3683
|
Number of parallel threads.
|
3681
3684
|
verbose : bool, optional
|
@@ -3707,23 +3710,25 @@ def efficient_dwi_fit(gtab, diffusion_model, imagein, maskin,
|
|
3707
3710
|
img_data = imagein.numpy()
|
3708
3711
|
mask = maskin.numpy().astype(bool)
|
3709
3712
|
X, Y, Z, N = img_data.shape
|
3713
|
+
inplane_size = X * Y
|
3714
|
+
|
3715
|
+
# Convert chunk_size from voxel count to number of slices
|
3716
|
+
slices_per_chunk = max(1, chunk_size // inplane_size)
|
3710
3717
|
|
3711
3718
|
if verbose:
|
3712
3719
|
print(f"[INFO] Image shape: {img_data.shape}")
|
3713
3720
|
print(f"[INFO] Using model: {diffusion_model}")
|
3714
|
-
print(f"[INFO]
|
3721
|
+
print(f"[INFO] Max voxels per chunk: {chunk_size} (→ {slices_per_chunk} slices) | Threads: {num_threads}")
|
3715
3722
|
|
3716
|
-
# Filter shells if specified
|
3717
3723
|
if bvals_to_use is not None:
|
3718
3724
|
bvals_to_use = set(bvals_to_use)
|
3719
3725
|
sel = np.isin(gtab.bvals, list(bvals_to_use))
|
3720
3726
|
img_data = img_data[..., sel]
|
3721
|
-
gtab = gradient_table(gtab.bvals[sel], gtab.bvecs[sel])
|
3727
|
+
gtab = gradient_table(gtab.bvals[sel], bvecs=gtab.bvecs[sel])
|
3722
3728
|
if verbose:
|
3723
3729
|
print(f"[INFO] Selected b-values: {sorted(bvals_to_use)}")
|
3724
3730
|
print(f"[INFO] Selected volumes: {sel.sum()} / {N}")
|
3725
3731
|
|
3726
|
-
# Choose model
|
3727
3732
|
def get_model(name, gtab, **params):
|
3728
3733
|
if name == 'DTI':
|
3729
3734
|
return dti.TensorModel(gtab, **params)
|
@@ -3736,14 +3741,13 @@ def efficient_dwi_fit(gtab, diffusion_model, imagein, maskin,
|
|
3736
3741
|
|
3737
3742
|
model = get_model(diffusion_model, gtab, **model_params)
|
3738
3743
|
|
3739
|
-
# Output volumes initialized to zero
|
3740
3744
|
FA_vol = np.zeros((X, Y, Z), dtype=np.float32)
|
3741
3745
|
MD_vol = np.zeros((X, Y, Z), dtype=np.float32)
|
3742
3746
|
RGB_vol = np.zeros((X, Y, Z, 3), dtype=np.float32)
|
3743
3747
|
has_tensor_metrics = diffusion_model in ['DTI', 'FreeWater']
|
3744
3748
|
|
3745
3749
|
def process_chunk(z_start):
|
3746
|
-
z_end = min(Z, z_start +
|
3750
|
+
z_end = min(Z, z_start + slices_per_chunk)
|
3747
3751
|
local_data = img_data[:, :, z_start:z_end, :]
|
3748
3752
|
local_mask = mask[:, :, z_start:z_end]
|
3749
3753
|
masked_data = local_data * local_mask[..., None]
|
@@ -3758,8 +3762,7 @@ def efficient_dwi_fit(gtab, diffusion_model, imagein, maskin,
|
|
3758
3762
|
return z_start, z_end, FA, MD, RGB
|
3759
3763
|
return z_start, z_end, None, None, None
|
3760
3764
|
|
3761
|
-
|
3762
|
-
chunks = range(0, Z, chunk_size)
|
3765
|
+
chunks = range(0, Z, slices_per_chunk)
|
3763
3766
|
if num_threads > 1:
|
3764
3767
|
with ThreadPoolExecutor(max_workers=num_threads) as executor:
|
3765
3768
|
futures = {executor.submit(process_chunk, z): z for z in chunks}
|
@@ -4455,7 +4458,7 @@ def dwi_deterministic_tracking(
|
|
4455
4458
|
gtab = gradient_table(bvals, bvecs=bvecs, atol=2.0 )
|
4456
4459
|
if mask is None:
|
4457
4460
|
mask = ants.threshold_image( fa, fa_thresh, 2.0 ).iMath("GetLargestComponent")
|
4458
|
-
dwi_data = dwi.numpy()
|
4461
|
+
dwi_data = dwi.numpy()
|
4459
4462
|
dwi_mask = mask.numpy() == 1
|
4460
4463
|
dti_model = dti.TensorModel(gtab,fit_method=fit_method)
|
4461
4464
|
if verbose:
|
@@ -0,0 +1,7 @@
|
|
1
|
+
antspymm/__init__.py,sha256=DnkidUfEu3Dl0tuWNTA-9VOUkBtH_cROKiPGNNXNagU,4637
|
2
|
+
antspymm/mm.py,sha256=8iZxrWenPeLhwc1dxDgvAhgNGZHOahTi1LegOhmHkL8,527319
|
3
|
+
antspymm-1.5.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
4
|
+
antspymm-1.5.3.dist-info/METADATA,sha256=pfNoP9vDefzKmOfRYk5z68qAJXXSmY2ELLLaRioiSHs,25939
|
5
|
+
antspymm-1.5.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
6
|
+
antspymm-1.5.3.dist-info/top_level.txt,sha256=iyD1sRhCKzfwKRJLq5ZUeV9xsv1cGQl8Ejp6QwXM1Zg,9
|
7
|
+
antspymm-1.5.3.dist-info/RECORD,,
|
antspymm-1.5.1.dist-info/RECORD
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
antspymm/__init__.py,sha256=DnkidUfEu3Dl0tuWNTA-9VOUkBtH_cROKiPGNNXNagU,4637
|
2
|
-
antspymm/mm.py,sha256=oPHhV70IhFXCKI26rP5HgKpkb2OjqCWkqoy4cSxJXqA,526866
|
3
|
-
antspymm-1.5.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
4
|
-
antspymm-1.5.1.dist-info/METADATA,sha256=_I4UmZGWLM6KkmTJc21wKW1DrjT2TY723C1jr7LA3Fw,25939
|
5
|
-
antspymm-1.5.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
6
|
-
antspymm-1.5.1.dist-info/top_level.txt,sha256=iyD1sRhCKzfwKRJLq5ZUeV9xsv1cGQl8Ejp6QwXM1Zg,9
|
7
|
-
antspymm-1.5.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|