antspymm 1.5.6__py3-none-any.whl → 1.5.7__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/__init__.py CHANGED
@@ -140,5 +140,7 @@ from .mm import pet3d_summary
140
140
  from .mm import deformation_gradient_optimized
141
141
  from .mm import efficient_dwi_fit_voxelwise
142
142
  from .mm import generate_voxelwise_bvecs
143
+ from .mm import distortion_correct_bvecs
144
+
143
145
 
144
146
 
antspymm/mm.py CHANGED
@@ -2138,6 +2138,40 @@ def bvec_reorientation( motion_parameters, bvecs, rebase=None ):
2138
2138
  bvecs[myidx,:] = np.dot( rebase, bvecs[myidx,:] )
2139
2139
  return bvecs
2140
2140
 
2141
+
2142
+ def distortion_correct_bvecs(bvecs, def_grad, A_img, A_ref):
2143
+ """
2144
+ Vectorized computation of voxel-wise distortion corrected b-vectors.
2145
+
2146
+ Parameters
2147
+ ----------
2148
+ bvecs : ndarray (N, 3)
2149
+ def_grad : ndarray (X, Y, Z, 3, 3) containing rotations derived from the deformation gradient
2150
+ A_img : ndarray (3, 3) direction matrix of the fixed image (target undistorted space)
2151
+ A_ref : ndarray (3, 3) direction matrix of the moving image (being corrected)
2152
+
2153
+ Returns
2154
+ -------
2155
+ bvecs_5d : ndarray (X, Y, Z, N, 3)
2156
+ """
2157
+ X, Y, Z = def_grad.shape[:3]
2158
+ N = bvecs.shape[0]
2159
+ # Combined rotation: R_voxel = A_ref.T @ A_img @ def_grad
2160
+ A = A_ref.T @ A_img
2161
+ R_voxel = np.einsum('ij,xyzjk->xyzik', A, def_grad) # (X, Y, Z, 3, 3)
2162
+ # Apply R_voxel.T @ bvecs
2163
+ # First, reshape R_voxel: (X*Y*Z, 3, 3)
2164
+ R_voxel_reshaped = R_voxel.reshape(-1, 3, 3)
2165
+ # Rotate all bvecs for each voxel
2166
+ # Output: (X*Y*Z, N, 3)
2167
+ rotated = np.einsum('vij,nj->vni', R_voxel_reshaped, bvecs)
2168
+ # Normalize
2169
+ norms = np.linalg.norm(rotated, axis=2, keepdims=True)
2170
+ rotated /= np.clip(norms, 1e-8, None)
2171
+ # Reshape back to (X, Y, Z, N, 3)
2172
+ bvecs_5d = rotated.reshape(X, Y, Z, N, 3)
2173
+ return bvecs_5d
2174
+
2141
2175
  def get_dti( reference_image, tensormodel, upper_triangular=True, return_image=False ):
2142
2176
  """
2143
2177
  extract DTI data from a dipy tensormodel
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: antspymm
3
- Version: 1.5.6
3
+ Version: 1.5.7
4
4
  Summary: multi-channel/time-series medical image processing with antspyx
5
5
  Author-email: "Avants, Gosselin, Tustison, Reardon" <stnava@gmail.com>
6
6
  License: Apache-2.0
@@ -0,0 +1,6 @@
1
+ antspymm/__init__.py,sha256=cTcqtGO0J5T2I0Chxe-Sy25QDlnHLDEQK8QEnJkkFRs,4900
2
+ antspymm/mm.py,sha256=eqMcRxQt03AbC3qRrubYBxGsbkKNfrS0dd9VgqXavCE,544991
3
+ antspymm-1.5.7.dist-info/METADATA,sha256=c-2SVYUIR2RGZ_XJXE8M1nxG94CpF9-fYBiRERaCHhQ,26007
4
+ antspymm-1.5.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
+ antspymm-1.5.7.dist-info/top_level.txt,sha256=iyD1sRhCKzfwKRJLq5ZUeV9xsv1cGQl8Ejp6QwXM1Zg,9
6
+ antspymm-1.5.7.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- antspymm/__init__.py,sha256=50wAFf04ZlF7wYg1h07dFLKebGOGFwKCJfAcdyHhSXw,4858
2
- antspymm/mm.py,sha256=mtkFJi0ZwLFw32vCrBdZcGa4ITgIOSn_Vfwq1SXLdqE,543752
3
- antspymm-1.5.6.dist-info/METADATA,sha256=0H4Olfd04VZNR56ErUfVd0hEo8DppIsDrWWbks0JgHs,26007
4
- antspymm-1.5.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
- antspymm-1.5.6.dist-info/top_level.txt,sha256=iyD1sRhCKzfwKRJLq5ZUeV9xsv1cGQl8Ejp6QwXM1Zg,9
6
- antspymm-1.5.6.dist-info/RECORD,,