antspymm 1.3.9__py3-none-any.whl → 1.4.1__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 +1 -0
- antspymm/mm.py +555 -136
- {antspymm-1.3.9.dist-info → antspymm-1.4.1.dist-info}/METADATA +61 -7
- antspymm-1.4.1.dist-info/RECORD +7 -0
- {antspymm-1.3.9.dist-info → antspymm-1.4.1.dist-info}/WHEEL +1 -1
- antspymm-1.3.9.dist-info/RECORD +0 -7
- {antspymm-1.3.9.dist-info → antspymm-1.4.1.dist-info}/LICENSE +0 -0
- {antspymm-1.3.9.dist-info → antspymm-1.4.1.dist-info}/top_level.txt +0 -0
antspymm/mm.py
CHANGED
@@ -285,7 +285,7 @@ def get_antsimage_keys(dictionary):
|
|
285
285
|
:param dictionary: A dictionary to inspect
|
286
286
|
:return: A list of keys for which the values are ANTsImages
|
287
287
|
"""
|
288
|
-
return [key for key, value in dictionary.items() if isinstance(value, ants.ANTsImage)]
|
288
|
+
return [key for key, value in dictionary.items() if isinstance(value, ants.core.ants_image.ANTsImage)]
|
289
289
|
|
290
290
|
|
291
291
|
def dict_to_dataframe(data_dict, convert_lists=True, convert_arrays=True, convert_images=True, verbose=False):
|
@@ -328,7 +328,7 @@ def dict_to_dataframe(data_dict, convert_lists=True, convert_arrays=True, conver
|
|
328
328
|
print( " Key " + key + " is nparray with mean " + str(meanvalue) + " to " + newkey )
|
329
329
|
if newkey not in data_dict.keys():
|
330
330
|
processed_data[newkey] = meanvalue
|
331
|
-
elif isinstance(value, ants.ANTsImage) and convert_images:
|
331
|
+
elif isinstance(value, ants.core.ants_image.ANTsImage ) and convert_images:
|
332
332
|
meanvalue = value.mean()
|
333
333
|
newkey = key+"_mean"
|
334
334
|
if newkey not in data_dict.keys():
|
@@ -1106,40 +1106,83 @@ def study_dataframe_from_matched_dataframe( matched_dataframe, rootdir, outputdi
|
|
1106
1106
|
dt=get_first_item_as_string( csvrow, 'date' ) # str(csvrow['date'].iloc[0])
|
1107
1107
|
iid=get_first_item_as_string( csvrow, 'imageID' ) # str(csvrow['imageID'].iloc[0])
|
1108
1108
|
nrgt1fn=os.path.join( rootdir, pid, sid, dt, 'T1w', iid, str(csvrow['filename'].iloc[0]+iext) )
|
1109
|
+
if not exists( nrgt1fn ) and iid == '0':
|
1110
|
+
iid='000'
|
1111
|
+
nrgt1fn=os.path.join( rootdir, pid, sid, dt, 'T1w', iid, str(csvrow['filename'].iloc[0]+iext) )
|
1109
1112
|
if not exists( nrgt1fn ):
|
1110
1113
|
raise ValueError("T1 " + nrgt1fn + " does not exist in study_dataframe_from_qc_dataframe")
|
1111
1114
|
flList=[]
|
1112
1115
|
dtList=[]
|
1113
1116
|
rsfList=[]
|
1114
1117
|
nmList=[]
|
1118
|
+
perfList=[]
|
1115
1119
|
if 'flairfn' in csvrow.keys():
|
1116
1120
|
flid=get_first_item_as_string( csvrow, 'flairid' )
|
1117
1121
|
nrgt2fn=os.path.join( rootdir, pid, sid, dt, 'T2Flair', flid, str(csvrow['flairfn'].iloc[0]+iext) )
|
1122
|
+
if not exists( nrgt2fn ) and flid == '0':
|
1123
|
+
flid='000'
|
1124
|
+
nrgt2fn=os.path.join( rootdir, pid, sid, dt, 'T2Flair', flid, str(csvrow['flairfn'].iloc[0]+iext) )
|
1125
|
+
if verbose:
|
1126
|
+
print("Trying " + nrgt2fn )
|
1118
1127
|
if exists( nrgt2fn ):
|
1128
|
+
if verbose:
|
1129
|
+
print("success" )
|
1119
1130
|
flList.append( nrgt2fn )
|
1131
|
+
if 'perffn' in csvrow.keys():
|
1132
|
+
flid=get_first_item_as_string( csvrow, 'perfid' )
|
1133
|
+
nrgt2fn=os.path.join( rootdir, pid, sid, dt, 'perf', flid, str(csvrow['perffn'].iloc[0]+iext) )
|
1134
|
+
if not exists( nrgt2fn ) and flid == '0':
|
1135
|
+
flid='000'
|
1136
|
+
nrgt2fn=os.path.join( rootdir, pid, sid, dt, 'perf', flid, str(csvrow['perffn'].iloc[0]+iext) )
|
1137
|
+
if verbose:
|
1138
|
+
print("Trying " + nrgt2fn )
|
1139
|
+
if exists( nrgt2fn ):
|
1140
|
+
if verbose:
|
1141
|
+
print("success" )
|
1142
|
+
perfList.append( nrgt2fn )
|
1120
1143
|
if 'dtfn1' in csvrow.keys():
|
1121
1144
|
dtid=get_first_item_as_string( csvrow, 'dtid1' )
|
1122
|
-
dtfn1=glob.glob(os.path.join( rootdir, pid, sid, dt, 'DTI*', dtid, str(csvrow['dtfn1'].iloc[0]+iext) ))
|
1145
|
+
dtfn1=glob.glob(os.path.join( rootdir, pid, sid, dt, 'DTI*', dtid, str(csvrow['dtfn1'].iloc[0]+iext) ))
|
1146
|
+
if len( dtfn1) == 0 :
|
1147
|
+
dtid = '000'
|
1148
|
+
dtfn1=glob.glob(os.path.join( rootdir, pid, sid, dt, 'DTI*', dtid, str(csvrow['dtfn1'].iloc[0]+iext) ))
|
1149
|
+
dtfn1=dtfn1[0]
|
1123
1150
|
if exists( dtfn1 ):
|
1124
1151
|
dtList.append( dtfn1 )
|
1125
1152
|
if 'dtfn2' in csvrow.keys():
|
1126
1153
|
dtid=get_first_item_as_string( csvrow, 'dtid2' )
|
1127
|
-
dtfn2=glob.glob(os.path.join(rootdir, pid, sid, dt, 'DTI*', dtid, str(csvrow['dtfn2'].iloc[0]+iext) ))
|
1154
|
+
dtfn2=glob.glob(os.path.join(rootdir, pid, sid, dt, 'DTI*', dtid, str(csvrow['dtfn2'].iloc[0]+iext) ))
|
1155
|
+
if len( dtfn2) == 0 :
|
1156
|
+
dtid = '000'
|
1157
|
+
dtfn2=glob.glob(os.path.join( rootdir, pid, sid, dt, 'DTI*', dtid, str(csvrow['dtfn2'].iloc[0]+iext) ))
|
1158
|
+
dtfn2=dtfn2[0]
|
1128
1159
|
if exists( dtfn2 ):
|
1129
1160
|
dtList.append( dtfn2 )
|
1130
1161
|
if 'dtfn3' in csvrow.keys():
|
1131
1162
|
dtid=get_first_item_as_string( csvrow, 'dtid3' )
|
1132
|
-
dtfn3=glob.glob(os.path.join(rootdir, pid, sid, dt, 'DTI*', dtid, str(csvrow['dtfn3'].iloc[0]+iext) ))
|
1163
|
+
dtfn3=glob.glob(os.path.join(rootdir, pid, sid, dt, 'DTI*', dtid, str(csvrow['dtfn3'].iloc[0]+iext) ))
|
1164
|
+
if len( dtfn3) == 0 :
|
1165
|
+
dtid = '000'
|
1166
|
+
dtfn3=glob.glob(os.path.join( rootdir, pid, sid, dt, 'DTI*', dtid, str(csvrow['dtfn3'].iloc[0]+iext) ))
|
1167
|
+
dtfn3=dtfn3[0]
|
1133
1168
|
if exists( dtfn3 ):
|
1134
1169
|
dtList.append( dtfn3 )
|
1135
1170
|
if 'rsffn1' in csvrow.keys():
|
1136
1171
|
rsid=get_first_item_as_string( csvrow, 'rsfid1' )
|
1137
|
-
rsfn1=glob.glob(os.path.join( rootdir, pid, sid, dt, 'rsfMRI*', rsid, str(csvrow['rsffn1'].iloc[0]+iext) ))
|
1172
|
+
rsfn1=glob.glob(os.path.join( rootdir, pid, sid, dt, 'rsfMRI*', rsid, str(csvrow['rsffn1'].iloc[0]+iext) ))
|
1173
|
+
if len( rsfn1 ) == 0 :
|
1174
|
+
rsid = '000'
|
1175
|
+
rsfn1=glob.glob(os.path.join( rootdir, pid, sid, dt, 'rsfMRI*', rsid, str(csvrow['rsffn1'].iloc[0]+iext) ))
|
1176
|
+
rsfn1=rsfn1[0]
|
1138
1177
|
if exists( rsfn1 ):
|
1139
1178
|
rsfList.append( rsfn1 )
|
1140
1179
|
if 'rsffn2' in csvrow.keys():
|
1141
1180
|
rsid=get_first_item_as_string( csvrow, 'rsfid2' )
|
1142
1181
|
rsfn2=glob.glob(os.path.join( rootdir, pid, sid, dt, 'rsfMRI*', rsid, str(csvrow['rsffn2'].iloc[0]+iext) ))[0]
|
1182
|
+
if len( rsfn2 ) == 0 :
|
1183
|
+
rsid = '000'
|
1184
|
+
rsfn2=glob.glob(os.path.join( rootdir, pid, sid, dt, 'rsfMRI*', rsid, str(csvrow['rsffn2'].iloc[0]+iext) ))
|
1185
|
+
rsfn2=rsfn2[0]
|
1143
1186
|
if exists( rsfn2 ):
|
1144
1187
|
rsfList.append( rsfn2 )
|
1145
1188
|
for j in range(11):
|
@@ -1163,6 +1206,8 @@ def study_dataframe_from_matched_dataframe( matched_dataframe, rootdir, outputdi
|
|
1163
1206
|
print(dtList)
|
1164
1207
|
print("rsfMRI")
|
1165
1208
|
print(rsfList)
|
1209
|
+
print("perf")
|
1210
|
+
print(perfList)
|
1166
1211
|
studycsv = generate_mm_dataframe(
|
1167
1212
|
pid,
|
1168
1213
|
sid,
|
@@ -1175,7 +1220,8 @@ def study_dataframe_from_matched_dataframe( matched_dataframe, rootdir, outputdi
|
|
1175
1220
|
flair_filename=flList,
|
1176
1221
|
dti_filenames=dtList,
|
1177
1222
|
rsf_filenames=rsfList,
|
1178
|
-
nm_filenames=nmList
|
1223
|
+
nm_filenames=nmList,
|
1224
|
+
perf_filename=perfList)
|
1179
1225
|
return studycsv.dropna(axis=1)
|
1180
1226
|
|
1181
1227
|
def highest_quality_repeat(mxdfin, idvar, visitvar, qualityvar):
|
@@ -1233,13 +1279,14 @@ def highest_quality_repeat(mxdfin, idvar, visitvar, qualityvar):
|
|
1233
1279
|
return mxdfin[useit]
|
1234
1280
|
|
1235
1281
|
|
1236
|
-
def match_modalities( qc_dataframe, unique_identifier='filename', outlier_column='ol_loop',
|
1282
|
+
def match_modalities( qc_dataframe, unique_identifier='filename', outlier_column='ol_loop', mysep='-', verbose=False ):
|
1237
1283
|
"""
|
1238
1284
|
Find the best multiple modality dataset at each time point
|
1239
1285
|
|
1240
1286
|
:param qc_dataframe: quality control data frame with
|
1241
1287
|
:param unique_identifier : the unique NRG filename for each image
|
1242
1288
|
:param outlier_column: outlierness score used to identify the best image (pair) at a given date
|
1289
|
+
:param mysep (str, optional): the separator used in the image file names. Defaults to '-'.
|
1243
1290
|
:param verbose: boolean
|
1244
1291
|
:return: filtered matched modality data frame
|
1245
1292
|
"""
|
@@ -1507,8 +1554,8 @@ def mm_read_to_3d( x, slice=None, modality='' ):
|
|
1507
1554
|
read an image from a filename - and return as 3d or None if that is not possible
|
1508
1555
|
"""
|
1509
1556
|
img = ants.image_read( x, reorient=False )
|
1510
|
-
if img.dimension
|
1511
|
-
return
|
1557
|
+
if img.dimension <= 3:
|
1558
|
+
return img
|
1512
1559
|
elif img.dimension == 4:
|
1513
1560
|
nslices = img.shape[3]
|
1514
1561
|
if slice is None:
|
@@ -1518,7 +1565,7 @@ def mm_read_to_3d( x, slice=None, modality='' ):
|
|
1518
1565
|
if sl > nslices:
|
1519
1566
|
sl = nslices-1
|
1520
1567
|
return ants.slice_image( img, axis=3, idx=int(sl) )
|
1521
|
-
elif img.dimension
|
1568
|
+
elif img.dimension > 4:
|
1522
1569
|
return img
|
1523
1570
|
return None
|
1524
1571
|
|
@@ -2242,11 +2289,14 @@ def dti_reg(
|
|
2242
2289
|
print("remove_it " + str( remove_it ) )
|
2243
2290
|
|
2244
2291
|
if b0_idx is None:
|
2245
|
-
b0_idx = segment_timeseries_by_meanvalue( image )['highermeans']
|
2292
|
+
# b0_idx = segment_timeseries_by_meanvalue( image )['highermeans']
|
2293
|
+
b0_idx = segment_timeseries_by_bvalue( bvals )['lowbvals']
|
2294
|
+
|
2246
2295
|
# first get a local deformation from slice to local avg space
|
2247
2296
|
# then get a global deformation from avg to ref space
|
2248
2297
|
ab0, adw = get_average_dwi_b0( image )
|
2249
|
-
mask
|
2298
|
+
# mask is used to roughly locate middle of brain
|
2299
|
+
mask = ants.threshold_image( ants.iMath(adw,'Normalize'), 0.1, 1.0 )
|
2250
2300
|
motion_parameters = list()
|
2251
2301
|
motion_corrected = list()
|
2252
2302
|
centerOfMass = mask.get_center_of_mass()
|
@@ -2657,7 +2707,7 @@ def template_figure_with_overlay(scalar_label_df, prefix, outputfilename=None, t
|
|
2657
2707
|
toviz = temp['overlay']
|
2658
2708
|
return { "underlay": seggm, 'overlay': toviz, 'seg': tcrop }
|
2659
2709
|
|
2660
|
-
def get_data( name=None, force_download=False, version=
|
2710
|
+
def get_data( name=None, force_download=False, version=24, target_extension='.csv' ):
|
2661
2711
|
"""
|
2662
2712
|
Get ANTsPyMM data filename
|
2663
2713
|
|
@@ -2953,21 +3003,33 @@ def segment_timeseries_by_bvalue(bvals):
|
|
2953
3003
|
- bvals (numpy.ndarray): An array of b-values.
|
2954
3004
|
|
2955
3005
|
Returns:
|
2956
|
-
- dict: A dictionary with two keys, '
|
3006
|
+
- dict: A dictionary with two keys, 'largerbvals' and 'lowbvals', each containing
|
2957
3007
|
the indices of bvals where the b-values are above and at/below the threshold, respectively.
|
2958
3008
|
"""
|
2959
3009
|
# Define the threshold
|
2960
3010
|
threshold = 1e-12
|
2961
|
-
|
3011
|
+
def find_min_value(data):
|
3012
|
+
if isinstance(data, list):
|
3013
|
+
return min(data)
|
3014
|
+
elif isinstance(data, np.ndarray):
|
3015
|
+
return np.min(data)
|
3016
|
+
else:
|
3017
|
+
raise TypeError("Input must be either a list or a numpy array")
|
3018
|
+
|
2962
3019
|
# Get indices where b-values are greater than the threshold
|
2963
3020
|
lowermeans = list(np.where(bvals > threshold)[0])
|
2964
3021
|
|
2965
3022
|
# Get indices where b-values are less than or equal to the threshold
|
2966
3023
|
highermeans = list(np.where(bvals <= threshold)[0])
|
2967
3024
|
|
3025
|
+
if len(highermeans) == 0:
|
3026
|
+
minval = find_min_value( bvals )
|
3027
|
+
lowermeans = list(np.where(bvals > minval )[0])
|
3028
|
+
highermeans = list(np.where(bvals <= minval)[0])
|
3029
|
+
|
2968
3030
|
return {
|
2969
|
-
'
|
2970
|
-
'
|
3031
|
+
'largerbvals': lowermeans,
|
3032
|
+
'lowbvals': highermeans
|
2971
3033
|
}
|
2972
3034
|
|
2973
3035
|
def segment_timeseries_by_meanvalue( image, quantile = 0.995 ):
|
@@ -3404,6 +3466,7 @@ def dipy_dti_recon(
|
|
3404
3466
|
mask_closing = 5,
|
3405
3467
|
fit_method='WLS',
|
3406
3468
|
trim_the_mask=2.0,
|
3469
|
+
free_water=False,
|
3407
3470
|
verbose=False ):
|
3408
3471
|
"""
|
3409
3472
|
DiPy DTI reconstruction - building on the DiPy basic DTI example
|
@@ -3430,6 +3493,8 @@ def dipy_dti_recon(
|
|
3430
3493
|
|
3431
3494
|
trim_the_mask : float >=0 post-hoc method for trimming the mask
|
3432
3495
|
|
3496
|
+
free_water : boolean
|
3497
|
+
|
3433
3498
|
verbose : boolean
|
3434
3499
|
|
3435
3500
|
Returns
|
@@ -3445,6 +3510,9 @@ def dipy_dti_recon(
|
|
3445
3510
|
-------
|
3446
3511
|
>>> import antspymm
|
3447
3512
|
"""
|
3513
|
+
|
3514
|
+
import dipy.reconst.fwdti as fwdti
|
3515
|
+
|
3448
3516
|
if isinstance(bvecsfn, str):
|
3449
3517
|
bvals, bvecs = read_bvals_bvecs( bvalsfn , bvecsfn )
|
3450
3518
|
else: # assume we already read them
|
@@ -3454,16 +3522,22 @@ def dipy_dti_recon(
|
|
3454
3522
|
if bvals.max() < 1.0:
|
3455
3523
|
raise ValueError("DTI recon error: maximum bvalues are too small.")
|
3456
3524
|
|
3457
|
-
b0_idx = segment_timeseries_by_bvalue( bvals )['
|
3525
|
+
b0_idx = segment_timeseries_by_bvalue( bvals )['lowbvals']
|
3458
3526
|
|
3459
3527
|
b0 = ants.slice_image( image, axis=3, idx=b0_idx[0] )
|
3460
3528
|
bxtmod='bold'
|
3461
3529
|
bxtmod='t2'
|
3462
3530
|
constant_mask=False
|
3531
|
+
if verbose:
|
3532
|
+
print( np.unique( bvals ), flush=True )
|
3463
3533
|
if mask is not None:
|
3534
|
+
if verbose:
|
3535
|
+
print("use set bxt in dipy_dti_recon", flush=True)
|
3464
3536
|
constant_mask=True
|
3465
3537
|
mask = ants.resample_image_to_target( mask, b0, interp_type='nearestNeighbor')
|
3466
3538
|
else:
|
3539
|
+
if verbose:
|
3540
|
+
print("use deep learning bxt in dipy_dti_recon")
|
3467
3541
|
mask = antspynet.brain_extraction( b0, bxtmod ).threshold_image(0.5,1).iMath("GetLargestComponent").morphology("close",2).iMath("FillHoles")
|
3468
3542
|
if mask_closing > 0 and not constant_mask :
|
3469
3543
|
mask = ants.morphology( mask, "close", mask_closing ) # good
|
@@ -3472,7 +3546,7 @@ def dipy_dti_recon(
|
|
3472
3546
|
if verbose:
|
3473
3547
|
print("recon dti.TensorModel",flush=True)
|
3474
3548
|
|
3475
|
-
def justthefit( gtab, fit_method, imagein, maskin ):
|
3549
|
+
def justthefit( gtab, fit_method, imagein, maskin, free_water=False ):
|
3476
3550
|
if fit_method is None:
|
3477
3551
|
return None, None, None, None
|
3478
3552
|
maskedimage=[]
|
@@ -3481,7 +3555,10 @@ def dipy_dti_recon(
|
|
3481
3555
|
maskedimage.append( b0 * maskin )
|
3482
3556
|
maskedimage = ants.list_to_ndimage( imagein, maskedimage )
|
3483
3557
|
maskdata = maskedimage.numpy()
|
3484
|
-
|
3558
|
+
if free_water:
|
3559
|
+
tenmodel = fwdti.FreeWaterTensorModel(gtab)
|
3560
|
+
else:
|
3561
|
+
tenmodel = dti.TensorModel(gtab,fit_method=fit_method)
|
3485
3562
|
tenfit = tenmodel.fit(maskdata)
|
3486
3563
|
FA = fractional_anisotropy(tenfit.evals)
|
3487
3564
|
FA[np.isnan(FA)] = 1
|
@@ -3500,14 +3577,16 @@ def dipy_dti_recon(
|
|
3500
3577
|
|
3501
3578
|
bvecs = repair_bvecs( bvecs )
|
3502
3579
|
gtab = gradient_table(bvals, bvecs, atol=2.0 )
|
3503
|
-
|
3580
|
+
if free_water:
|
3581
|
+
free_water=len( np.unique( bvals ) ) >= 3
|
3582
|
+
tenfit, FA, MD1, RGB = justthefit( gtab, fit_method, image, maskdil, free_water=free_water )
|
3504
3583
|
if verbose:
|
3505
3584
|
print("recon dti.TensorModel done",flush=True)
|
3506
3585
|
|
3507
3586
|
# change the brain mask based on high FA values
|
3508
3587
|
if trim_the_mask > 0 and fit_method is not None:
|
3509
3588
|
mask = trim_dti_mask( FA, mask, trim_the_mask )
|
3510
|
-
tenfit, FA, MD1, RGB = justthefit( gtab, fit_method, image, mask )
|
3589
|
+
tenfit, FA, MD1, RGB = justthefit( gtab, fit_method, image, mask, free_water=free_water )
|
3511
3590
|
|
3512
3591
|
return {
|
3513
3592
|
'tensormodel' : tenfit,
|
@@ -3591,6 +3670,7 @@ def joint_dti_recon(
|
|
3591
3670
|
fit_method='WLS',
|
3592
3671
|
impute = False,
|
3593
3672
|
censor = True,
|
3673
|
+
free_water = False,
|
3594
3674
|
verbose = False ):
|
3595
3675
|
"""
|
3596
3676
|
1. pass in subject data and 1mm JHU atlas/labels
|
@@ -3645,6 +3725,8 @@ def joint_dti_recon(
|
|
3645
3725
|
|
3646
3726
|
censor : boolean
|
3647
3727
|
|
3728
|
+
free_water : boolean
|
3729
|
+
|
3648
3730
|
verbose : boolean
|
3649
3731
|
|
3650
3732
|
Returns
|
@@ -3754,11 +3836,12 @@ def joint_dti_recon(
|
|
3754
3836
|
if verbose:
|
3755
3837
|
print("final recon", flush=True)
|
3756
3838
|
print(img_LRdwp)
|
3839
|
+
|
3757
3840
|
recon_LR_dewarp = dipy_dti_recon(
|
3758
3841
|
img_LRdwp, bval_LR, bvec_LR,
|
3759
3842
|
mask = brain_mask,
|
3760
3843
|
fit_method=fit_method,
|
3761
|
-
mask_dilation=0, verbose=True )
|
3844
|
+
mask_dilation=0, free_water=free_water, verbose=True )
|
3762
3845
|
if verbose:
|
3763
3846
|
print("recon done", flush=True)
|
3764
3847
|
|
@@ -3822,6 +3905,7 @@ def joint_dti_recon(
|
|
3822
3905
|
'reg_RL':reg_RL,
|
3823
3906
|
'dtrecon_LR_dewarp':recon_LR_dewarp,
|
3824
3907
|
'dwi_LR_dewarped':img_LRdwp,
|
3908
|
+
'bval_unique_count': len(np.unique(bval_LR)),
|
3825
3909
|
'bval_LR':bval_LR,
|
3826
3910
|
'bvec_LR':bvec_LR,
|
3827
3911
|
'bval_RL':bval_RL,
|
@@ -5054,10 +5138,10 @@ def neuromelanin( list_nm_images, t1, t1_head, t1lab, brain_stem_dilation=8,
|
|
5054
5138
|
nmabovekthresh_mask3 = sn_mask * ants.threshold_image( simg, rrthresh, math.inf)
|
5055
5139
|
snvolabovethresh3 = vol_element * nmabovekthresh_mask3.sum()
|
5056
5140
|
|
5057
|
-
k =
|
5141
|
+
k = 1.0
|
5058
5142
|
rrthresh = (rravg + k * rrstd)
|
5059
|
-
|
5060
|
-
|
5143
|
+
nmabovekthresh_mask1 = sn_mask * ants.threshold_image( simg, rrthresh, math.inf)
|
5144
|
+
snvolabovethresh1 = vol_element * nmabovekthresh_mask1.sum()
|
5061
5145
|
|
5062
5146
|
if verbose:
|
5063
5147
|
print( "nm vol @2std above rrmean: " + str( snvolabovethresh ) )
|
@@ -5065,7 +5149,7 @@ def neuromelanin( list_nm_images, t1, t1_head, t1lab, brain_stem_dilation=8,
|
|
5065
5149
|
print( "nm intsum @2std above rrmean: " + str( snintsumabovethresh ) )
|
5066
5150
|
print( "nm done" )
|
5067
5151
|
|
5068
|
-
return{
|
5152
|
+
return convert_np_in_dict( {
|
5069
5153
|
'NM_avg' : nm_avg,
|
5070
5154
|
'NM_avg_cropped' : nm_avg_cropped,
|
5071
5155
|
'NM_labels': labels2nm,
|
@@ -5079,11 +5163,11 @@ def neuromelanin( list_nm_images, t1, t1_head, t1lab, brain_stem_dilation=8,
|
|
5079
5163
|
'NM_avg_substantianigra' : snavg,
|
5080
5164
|
'NM_std_substantianigra' : snstd,
|
5081
5165
|
'NM_volume_substantianigra' : snvol,
|
5166
|
+
'NM_volume_substantianigra_1std' : snvolabovethresh1,
|
5082
5167
|
'NM_volume_substantianigra_2std' : snvolabovethresh,
|
5083
5168
|
'NM_intmean_substantianigra_2std' : snintmeanabovethresh,
|
5084
5169
|
'NM_intsum_substantianigra_2std' : snintsumabovethresh,
|
5085
5170
|
'NM_volume_substantianigra_3std' : snvolabovethresh3,
|
5086
|
-
'NM_volume_substantianigra_4std' : snvolabovethresh4,
|
5087
5171
|
'NM_avg_refregion' : rravg,
|
5088
5172
|
'NM_std_refregion' : rrstd,
|
5089
5173
|
'NM_min' : nm_avg_cropped.min(),
|
@@ -5097,7 +5181,7 @@ def neuromelanin( list_nm_images, t1, t1_head, t1lab, brain_stem_dilation=8,
|
|
5097
5181
|
'NM_substantianigra_z_coordinate' : sn_z,
|
5098
5182
|
'NM_evr' : nm_evr,
|
5099
5183
|
'NM_count': len( list_nm_images )
|
5100
|
-
}
|
5184
|
+
} )
|
5101
5185
|
|
5102
5186
|
|
5103
5187
|
|
@@ -9328,7 +9412,9 @@ def quick_viz_mm_nrg(
|
|
9328
9412
|
dtid, # date
|
9329
9413
|
extract_brain=True,
|
9330
9414
|
slice_factor = 0.55,
|
9331
|
-
|
9415
|
+
post = False,
|
9416
|
+
original_sourcedir = None,
|
9417
|
+
filename = None, # output path
|
9332
9418
|
verbose = True
|
9333
9419
|
):
|
9334
9420
|
"""
|
@@ -9336,7 +9422,7 @@ def quick_viz_mm_nrg(
|
|
9336
9422
|
|
9337
9423
|
Args:
|
9338
9424
|
|
9339
|
-
sourcedir (str): Root folder
|
9425
|
+
sourcedir (str): Root folder for original data (if post=False) or processed data (post=True)
|
9340
9426
|
|
9341
9427
|
projectid (str): Project name.
|
9342
9428
|
|
@@ -9347,73 +9433,114 @@ def quick_viz_mm_nrg(
|
|
9347
9433
|
extract_brain (bool): If True, the function extracts the brain from the T1w image. Default is True.
|
9348
9434
|
|
9349
9435
|
slice_factor (float): The slice to be visualized is determined by multiplying the image size by this factor. Default is 0.55.
|
9436
|
+
|
9437
|
+
post ( bool ) : if True, will visualize example post-processing results.
|
9350
9438
|
|
9351
|
-
|
9439
|
+
original_sourcedir (str): Root folder for original data (used if post=True)
|
9440
|
+
|
9441
|
+
filename (str): Output path with extension (.png)
|
9352
9442
|
|
9353
9443
|
verbose (bool): If True, information will be printed while running the function. Default is True.
|
9354
9444
|
|
9355
9445
|
Returns:
|
9356
|
-
|
9446
|
+
None
|
9357
9447
|
|
9358
9448
|
"""
|
9359
9449
|
iid='*'
|
9360
9450
|
import glob as glob
|
9361
9451
|
from os.path import exists
|
9362
9452
|
import ants
|
9363
|
-
ex_path = os.path.expanduser( "~/.antspyt1w/" )
|
9364
|
-
ex_pathmm = os.path.expanduser( "~/.antspymm/" )
|
9365
|
-
templatefn = ex_path + 'CIT168_T1w_700um_pad_adni.nii.gz'
|
9366
|
-
if not exists( templatefn ):
|
9367
|
-
print( "**missing files** => call get_data from latest antspyt1w and antspymm." )
|
9368
|
-
antspyt1w.get_data( force_download=True )
|
9369
|
-
get_data( force_download=True )
|
9370
9453
|
temp = sourcedir.split( "/" )
|
9371
|
-
splitCount = len( temp )
|
9372
|
-
template = mm_read( templatefn ) # Read in template
|
9373
9454
|
subjectrootpath = os.path.join(sourcedir, projectid, sid, dtid)
|
9374
|
-
myimgsInput = glob.glob( subjectrootpath+"/*" )
|
9375
|
-
myimgsInput.sort( )
|
9376
9455
|
if verbose:
|
9377
|
-
print(
|
9456
|
+
print( 'subjectrootpath' )
|
9457
|
+
print( subjectrootpath )
|
9378
9458
|
t1_search_path = os.path.join(subjectrootpath, "T1w", "*", "*nii.gz")
|
9379
9459
|
if verbose:
|
9380
9460
|
print(f"t1 search path: {t1_search_path}")
|
9381
9461
|
t1fn = glob.glob(t1_search_path)
|
9382
|
-
t1fn.sort()
|
9383
9462
|
if len( t1fn ) < 1:
|
9384
9463
|
raise ValueError('quick_viz_mm_nrg cannot find the T1w @ ' + subjectrootpath )
|
9385
|
-
t1fn = t1fn[0]
|
9386
|
-
t1 = mm_read( t1fn )
|
9387
|
-
nimages = len(myimgsInput)
|
9388
9464
|
vizlist=[]
|
9389
|
-
|
9390
|
-
|
9391
|
-
|
9392
|
-
|
9465
|
+
undlist=[]
|
9466
|
+
nrg_modality_list = [ 'T1w', 'DTI', 'rsfMRI', 'perf', 'T2Flair', 'NM2DMT' ]
|
9467
|
+
if post:
|
9468
|
+
nrg_modality_list = [ 'T1wHierarchical', 'DTI', 'rsfMRI', 'perf', 'T2Flair', 'NM2DMT' ]
|
9393
9469
|
for nrgNum in [0,1,2,3,4,5]:
|
9470
|
+
underlay = None
|
9394
9471
|
overmodX = nrg_modality_list[nrgNum]
|
9395
|
-
if overmodX
|
9472
|
+
if 'T1w' in overmodX :
|
9396
9473
|
mod_search_path = os.path.join(subjectrootpath, overmodX, iid, "*nii.gz")
|
9474
|
+
if post:
|
9475
|
+
mod_search_path = os.path.join(subjectrootpath, overmodX, iid, "*brain_n4_dnz.nii.gz")
|
9476
|
+
mod_search_path_ol = os.path.join(subjectrootpath, overmodX, iid, "*thickness_image.nii.gz" )
|
9477
|
+
mod_search_path_ol = re.sub( "T1wHierarchical","T1w",mod_search_path_ol)
|
9478
|
+
myol = glob.glob(mod_search_path_ol)
|
9479
|
+
if len( myol ) > 0:
|
9480
|
+
temper = find_most_recent_file( myol )[0]
|
9481
|
+
underlay = ants.image_read( temper )
|
9482
|
+
if verbose:
|
9483
|
+
print("T1w overlay " + temper )
|
9484
|
+
underlay = underlay * ants.threshold_image( underlay, 0.2, math.inf )
|
9397
9485
|
myimgsr = glob.glob(mod_search_path)
|
9398
9486
|
if len( myimgsr ) == 0:
|
9399
9487
|
if verbose:
|
9400
9488
|
print("No t1 images: " + sid + dtid )
|
9401
9489
|
return None
|
9402
|
-
myimgsr
|
9403
|
-
myimgsr=myimgsr[0]
|
9490
|
+
myimgsr=find_most_recent_file( myimgsr )[0]
|
9404
9491
|
vimg=ants.image_read( myimgsr )
|
9405
|
-
elif overmodX
|
9492
|
+
elif 'T2Flair' in overmodX :
|
9493
|
+
if verbose:
|
9494
|
+
print("search flair")
|
9495
|
+
mod_search_path = os.path.join(subjectrootpath, overmodX, iid, "*nii.gz")
|
9496
|
+
if post and original_sourcedir is not None:
|
9497
|
+
if verbose:
|
9498
|
+
print("post in flair")
|
9499
|
+
mysubdir = os.path.join(original_sourcedir, projectid, sid, dtid)
|
9500
|
+
mod_search_path_under = os.path.join(mysubdir, overmodX, iid, "*T2Flair*.nii.gz")
|
9501
|
+
if verbose:
|
9502
|
+
print("post in flair mod_search_path_under " + mod_search_path_under)
|
9503
|
+
mod_search_path = os.path.join(subjectrootpath, overmodX, iid, "*wmh.nii.gz")
|
9504
|
+
if verbose:
|
9505
|
+
print("post in flair mod_search_path " + mod_search_path )
|
9506
|
+
myimgul = glob.glob(mod_search_path_under)
|
9507
|
+
if len( myimgul ) > 0:
|
9508
|
+
myimgul = find_most_recent_file( myimgul )[0]
|
9509
|
+
if verbose:
|
9510
|
+
print("Flair " + myimgul )
|
9511
|
+
vimg = ants.image_read( myimgul )
|
9512
|
+
myol = glob.glob(mod_search_path)
|
9513
|
+
if len( myol ) == 0:
|
9514
|
+
underlay = myimgsr * 0.0
|
9515
|
+
else:
|
9516
|
+
myol = find_most_recent_file( myol )[0]
|
9517
|
+
if verbose:
|
9518
|
+
print("Flair overlay " + myol )
|
9519
|
+
underlay=ants.image_read( myol )
|
9520
|
+
underlay=underlay*ants.threshold_image(underlay,0.05,math.inf)
|
9521
|
+
else:
|
9522
|
+
vimg = noizimg.clone()
|
9523
|
+
underlay = vimg * 0.0
|
9524
|
+
if original_sourcedir is None:
|
9525
|
+
myimgsr = glob.glob(mod_search_path)
|
9526
|
+
if len( myimgsr ) == 0:
|
9527
|
+
vimg = noizimg.clone()
|
9528
|
+
else:
|
9529
|
+
myimgsr=find_most_recent_file( myimgsr )[0]
|
9530
|
+
vimg=ants.image_read( myimgsr )
|
9531
|
+
elif overmodX == 'DTI':
|
9406
9532
|
mod_search_path = os.path.join(subjectrootpath, 'DTI*', "*", "*nii.gz")
|
9533
|
+
if post:
|
9534
|
+
mod_search_path = os.path.join(subjectrootpath, 'DTI*', "*", "*fa.nii.gz")
|
9407
9535
|
myimgsr = glob.glob(mod_search_path)
|
9408
9536
|
if len( myimgsr ) > 0:
|
9409
|
-
myimgsr
|
9410
|
-
myimgsr=myimgsr[0]
|
9537
|
+
myimgsr=find_most_recent_file( myimgsr )[0]
|
9411
9538
|
vimg=ants.image_read( myimgsr )
|
9412
9539
|
else:
|
9413
9540
|
if verbose:
|
9414
9541
|
print("No " + overmodX)
|
9415
|
-
vimg = noizimg
|
9416
|
-
elif overmodX == '
|
9542
|
+
vimg = noizimg.clone()
|
9543
|
+
elif overmodX == 'DTI2':
|
9417
9544
|
mod_search_path = os.path.join(subjectrootpath, 'DTI*', "*", "*nii.gz")
|
9418
9545
|
myimgsr = glob.glob(mod_search_path)
|
9419
9546
|
if len( myimgsr ) > 0:
|
@@ -9423,12 +9550,13 @@ def quick_viz_mm_nrg(
|
|
9423
9550
|
else:
|
9424
9551
|
if verbose:
|
9425
9552
|
print("No " + overmodX)
|
9426
|
-
vimg = noizimg
|
9553
|
+
vimg = noizimg.clone()
|
9427
9554
|
elif overmodX == 'NM2DMT':
|
9428
9555
|
mod_search_path = os.path.join(subjectrootpath, overmodX, "*", "*nii.gz")
|
9556
|
+
if post:
|
9557
|
+
mod_search_path = os.path.join(subjectrootpath, overmodX, "*", "*NM_avg.nii.gz" )
|
9429
9558
|
myimgsr = glob.glob(mod_search_path)
|
9430
9559
|
if len( myimgsr ) > 0:
|
9431
|
-
myimgsr.sort()
|
9432
9560
|
myimgsr0=myimgsr[0]
|
9433
9561
|
vimg=ants.image_read( myimgsr0 )
|
9434
9562
|
for k in range(1,len(myimgsr)):
|
@@ -9437,55 +9565,109 @@ def quick_viz_mm_nrg(
|
|
9437
9565
|
else:
|
9438
9566
|
if verbose:
|
9439
9567
|
print("No " + overmodX)
|
9440
|
-
vimg = noizimg
|
9568
|
+
vimg = noizimg.clone()
|
9441
9569
|
elif overmodX == 'rsfMRI':
|
9442
9570
|
mod_search_path = os.path.join(subjectrootpath, 'rsfMRI*', "*", "*nii.gz")
|
9571
|
+
if post:
|
9572
|
+
mod_search_path = os.path.join(subjectrootpath, 'rsfMRI*', "*", "*fcnxpro122_meanBold.nii.gz" )
|
9573
|
+
mod_search_path_ol = os.path.join(subjectrootpath, 'rsfMRI*', "*", "*fcnxpro122_DefaultMode.nii.gz" )
|
9574
|
+
myol = glob.glob(mod_search_path_ol)
|
9575
|
+
if len( myol ) > 0:
|
9576
|
+
myol = find_most_recent_file( myol )[0]
|
9577
|
+
underlay = ants.image_read( myol )
|
9578
|
+
if verbose:
|
9579
|
+
print("BOLD overlay " + myol )
|
9580
|
+
underlay = underlay * ants.threshold_image( underlay, 0.1, math.inf )
|
9443
9581
|
myimgsr = glob.glob(mod_search_path)
|
9444
9582
|
if len( myimgsr ) > 0:
|
9445
|
-
myimgsr
|
9446
|
-
myimgsr=myimgsr[0]
|
9583
|
+
myimgsr=find_most_recent_file( myimgsr )[0]
|
9447
9584
|
vimg=mm_read_to_3d( myimgsr )
|
9448
9585
|
else:
|
9449
9586
|
if verbose:
|
9450
9587
|
print("No " + overmodX)
|
9451
|
-
vimg = noizimg
|
9588
|
+
vimg = noizimg.clone()
|
9589
|
+
elif overmodX == 'perf':
|
9590
|
+
mod_search_path = os.path.join(subjectrootpath, 'perf*', "*", "*nii.gz")
|
9591
|
+
if post:
|
9592
|
+
mod_search_path = os.path.join(subjectrootpath, 'perf*', "*", "*cbf.nii.gz")
|
9593
|
+
myimgsr = glob.glob(mod_search_path)
|
9594
|
+
if len( myimgsr ) > 0:
|
9595
|
+
myimgsr=find_most_recent_file( myimgsr )[0]
|
9596
|
+
vimg=mm_read_to_3d( myimgsr )
|
9597
|
+
else:
|
9598
|
+
if verbose:
|
9599
|
+
print("No " + overmodX)
|
9600
|
+
vimg = noizimg.clone()
|
9452
9601
|
else :
|
9602
|
+
if verbose:
|
9603
|
+
print("Something else here")
|
9453
9604
|
mod_search_path = os.path.join(subjectrootpath, overmodX, "*", "*nii.gz")
|
9454
9605
|
myimgsr = glob.glob(mod_search_path)
|
9606
|
+
if post:
|
9607
|
+
myimgsr=[]
|
9455
9608
|
if len( myimgsr ) > 0:
|
9456
|
-
myimgsr
|
9457
|
-
myimgsr=myimgsr[0]
|
9609
|
+
myimgsr=find_most_recent_file( myimgsr )[0]
|
9458
9610
|
vimg=ants.image_read( myimgsr )
|
9459
9611
|
else:
|
9460
9612
|
if verbose:
|
9461
9613
|
print("No " + overmodX)
|
9462
9614
|
vimg = noizimg
|
9463
9615
|
if True:
|
9464
|
-
if extract_brain and overmodX == 'T1w':
|
9616
|
+
if extract_brain and overmodX == 'T1w' and post == False:
|
9465
9617
|
vimg = vimg * antspyt1w.brain_extraction(vimg)
|
9466
9618
|
if verbose:
|
9467
9619
|
print(f"modality search path: {myimgsr}" + " num: " + str(nrgNum))
|
9468
|
-
if
|
9620
|
+
if vimg.dimension == 4 and ( overmodX == "DTI2" ):
|
9469
9621
|
ttb0, ttdw=get_average_dwi_b0(vimg)
|
9470
9622
|
vimg = ttdw
|
9471
|
-
elif
|
9623
|
+
elif vimg.dimension == 4 and overmodX == "DTI":
|
9472
9624
|
ttb0, ttdw=get_average_dwi_b0(vimg)
|
9473
9625
|
vimg = ttb0
|
9474
|
-
elif
|
9626
|
+
elif vimg.dimension == 4 :
|
9475
9627
|
vimg=ants.get_average_of_timeseries(vimg)
|
9476
9628
|
msk=ants.get_mask(vimg)
|
9477
|
-
|
9478
|
-
|
9629
|
+
if overmodX == 'T2Flair':
|
9630
|
+
msk=vimg*0+1
|
9631
|
+
if underlay is not None:
|
9632
|
+
print( overmodX + " has underlay" )
|
9633
|
+
else:
|
9634
|
+
underlay = vimg * 0.0
|
9635
|
+
if nrgNum == 0:
|
9479
9636
|
refimg=ants.image_clone( vimg )
|
9480
9637
|
noizimg = ants.add_noise_to_image( refimg*0, 'additivegaussian', [100,1] )
|
9481
9638
|
vizlist.append( vimg )
|
9639
|
+
undlist.append( underlay )
|
9482
9640
|
else:
|
9483
|
-
vimg = ants.resample_image_to_target( vimg, refimg )
|
9484
9641
|
vimg = ants.iMath( vimg, 'TruncateIntensity',0.01,0.98)
|
9485
9642
|
vizlist.append( ants.iMath( vimg, 'Normalize' ) * 255 )
|
9643
|
+
undlist.append( underlay )
|
9644
|
+
|
9645
|
+
# mask & crop systematically ...
|
9646
|
+
msk = ants.get_mask( refimg )
|
9647
|
+
refimg = ants.crop_image( refimg, msk )
|
9648
|
+
|
9649
|
+
for jj in range(len(vizlist)):
|
9650
|
+
vizlist[jj]=ants.resample_image_to_target( vizlist[jj], refimg )
|
9651
|
+
undlist[jj]=ants.resample_image_to_target( undlist[jj], refimg )
|
9652
|
+
print( 'viz: ' + str( jj ) )
|
9653
|
+
print( vizlist[jj] )
|
9654
|
+
print( 'und: ' + str( jj ) )
|
9655
|
+
print( undlist[jj] )
|
9656
|
+
|
9657
|
+
|
9658
|
+
xyz = [None]*3
|
9659
|
+
for i in range(3):
|
9660
|
+
if xyz[i] is None:
|
9661
|
+
xyz[i] = int(refimg.shape[i] * slice_factor )
|
9662
|
+
|
9663
|
+
if verbose:
|
9664
|
+
print('slice positions')
|
9665
|
+
print( xyz )
|
9486
9666
|
|
9487
|
-
|
9488
|
-
|
9667
|
+
ants.plot_ortho_stack( vizlist, overlays=undlist, crop=False, reorient=False, filename=filename, xyz=xyz, orient_labels=False )
|
9668
|
+
return
|
9669
|
+
# listlen = len( vizlist )
|
9670
|
+
# vizlist = np.asarray( vizlist )
|
9489
9671
|
if show_it is not None:
|
9490
9672
|
filenameout=None
|
9491
9673
|
if verbose:
|
@@ -9497,7 +9679,7 @@ def quick_viz_mm_nrg(
|
|
9497
9679
|
filenameout=show_it+'_ax'+str(int(a))+'_sl'+str(n)+'.png'
|
9498
9680
|
if verbose:
|
9499
9681
|
print( filenameout )
|
9500
|
-
ants.plot_grid(vizlist.reshape(2,3), slices.reshape(2,3), title='MM Subject ' + sid + ' ' + dtid, rfacecolor='white', axes=a, filename=filenameout )
|
9682
|
+
# ants.plot_grid(vizlist.reshape(2,3), slices.reshape(2,3), title='MM Subject ' + sid + ' ' + dtid, rfacecolor='white', axes=a, filename=filenameout )
|
9501
9683
|
if verbose:
|
9502
9684
|
print("viz complete.")
|
9503
9685
|
return vizlist
|
@@ -9608,6 +9790,10 @@ def blind_image_assessment(
|
|
9608
9790
|
modality='unknown'
|
9609
9791
|
if "rsfMRI" in image_filename:
|
9610
9792
|
modality='rsfMRI'
|
9793
|
+
elif "perf" in image_filename:
|
9794
|
+
modality='perf'
|
9795
|
+
elif "DTI" in image_filename:
|
9796
|
+
modality='DTI'
|
9611
9797
|
elif "T1w" in image_filename:
|
9612
9798
|
modality='T1w'
|
9613
9799
|
elif "T2Flair" in image_filename:
|
@@ -10023,7 +10209,7 @@ def remove_volumes_from_timeseries(time_series, volumes_to_remove):
|
|
10023
10209
|
:param volumes_to_remove: List of volume indices to remove.
|
10024
10210
|
:return: ANTsImage with specified volumes removed.
|
10025
10211
|
"""
|
10026
|
-
if not isinstance(time_series, ants.ANTsImage):
|
10212
|
+
if not isinstance(time_series, ants.core.ants_image.ANTsImage):
|
10027
10213
|
raise ValueError("time_series must be an ANTsImage.")
|
10028
10214
|
|
10029
10215
|
if time_series.dimension != 4:
|
@@ -10033,7 +10219,7 @@ def remove_volumes_from_timeseries(time_series, volumes_to_remove):
|
|
10033
10219
|
volumes_to_keep = [i for i in range(time_series.shape[3]) if i not in volumes_to_remove]
|
10034
10220
|
|
10035
10221
|
# Select the volumes to keep
|
10036
|
-
filtered_time_series = ants.from_numpy( time_series[..., volumes_to_keep] )
|
10222
|
+
filtered_time_series = ants.from_numpy( time_series.numpy()[..., volumes_to_keep] )
|
10037
10223
|
|
10038
10224
|
return ants.copy_image_info( time_series, filtered_time_series )
|
10039
10225
|
|
@@ -10061,7 +10247,7 @@ def impute_timeseries(time_series, volumes_to_impute, method='linear', verbose=F
|
|
10061
10247
|
:param verbose: boolean
|
10062
10248
|
:return: ANTsImage with specified volumes imputed.
|
10063
10249
|
"""
|
10064
|
-
if not isinstance(time_series, ants.ANTsImage):
|
10250
|
+
if not isinstance(time_series, ants.core.ants_image.ANTsImage):
|
10065
10251
|
raise ValueError("time_series must be an ANTsImage.")
|
10066
10252
|
|
10067
10253
|
if time_series.dimension != 4:
|
@@ -10468,7 +10654,136 @@ def novelty_detection_quantile(df_train, df_test):
|
|
10468
10654
|
myqs[mykey] = abs( temp - 0.5 ) / 0.5
|
10469
10655
|
return myqs
|
10470
10656
|
|
10471
|
-
|
10657
|
+
|
10658
|
+
|
10659
|
+
def shorten_pymm_names(x):
|
10660
|
+
"""
|
10661
|
+
Shortens pmymm names by applying a series of regex substitutions.
|
10662
|
+
|
10663
|
+
Parameters:
|
10664
|
+
x (str): The input string to be shortened
|
10665
|
+
|
10666
|
+
Returns:
|
10667
|
+
str: The shortened string
|
10668
|
+
"""
|
10669
|
+
xx = x.lower()
|
10670
|
+
xx = re.sub("_", ".", xx) # Replace underscores with periods
|
10671
|
+
xx = re.sub("\.\.", ".", xx, flags=re.I) # Replace double dots with single dot
|
10672
|
+
# Apply the following regex substitutions in order
|
10673
|
+
xx = re.sub("sagittal.stratum.include.inferior.longitidinal.fasciculus.and.inferior.fronto.occipital.fasciculus.","ilf.and.ifo", xx, flags=re.I)
|
10674
|
+
xx = re.sub(r"sagittal.stratum.include.inferior.longitidinal.fasciculus.and.inferior.fronto.occipital.fasciculus.", "ilf.and.ifo", xx, flags=re.I)
|
10675
|
+
xx = re.sub(r".cres.stria.terminalis.can.not.be.resolved.with.current.resolution.", "",
|
10676
|
+
xx, flags=re.I)
|
10677
|
+
xx = re.sub("_", ".", xx) # Replace underscores with periods
|
10678
|
+
xx = re.sub(r"longitudinal.fasciculus", "l.fasc", xx, flags=re.I)
|
10679
|
+
xx = re.sub(r"corona.radiata", "cor.rad", xx, flags=re.I)
|
10680
|
+
xx = re.sub("central", "cent", xx, flags=re.I)
|
10681
|
+
xx = re.sub(r"deep.cit168", "dp.", xx, flags=re.I)
|
10682
|
+
xx = re.sub("cit168", "", xx, flags=re.I)
|
10683
|
+
xx = re.sub(".include", "", xx, flags=re.I)
|
10684
|
+
xx = re.sub("mtg.sn", "", xx, flags=re.I)
|
10685
|
+
xx = re.sub("brainstem", ".bst", xx, flags=re.I)
|
10686
|
+
xx = re.sub(r"rsfmri.", "rsf.", xx, flags=re.I)
|
10687
|
+
xx = re.sub(r"dti.mean.fa.", "dti.fa.", xx, flags=re.I)
|
10688
|
+
xx = re.sub("perf.cbf.mean.", "cbf.", xx, flags=re.I)
|
10689
|
+
xx = re.sub(".jhu.icbm.labels.1mm", "", xx, flags=re.I)
|
10690
|
+
xx = re.sub(".include.optic.radiation.", "", xx, flags=re.I)
|
10691
|
+
xx = re.sub("\.\.", ".", xx, flags=re.I) # Replace double dots with single dot
|
10692
|
+
xx = re.sub("\.\.", ".", xx, flags=re.I) # Replace double dots with single dot
|
10693
|
+
xx = re.sub("cerebellar.peduncle", "cereb.ped", xx, flags=re.I)
|
10694
|
+
xx = re.sub(r"anterior.limb.of.internal.capsule", "ant.int.cap", xx, flags=re.I)
|
10695
|
+
xx = re.sub(r"posterior.limb.of.internal.capsule", "post.int.cap", xx, flags=re.I)
|
10696
|
+
xx = re.sub("t1hier.", "t1.", xx, flags=re.I)
|
10697
|
+
xx = re.sub("anterior", "ant", xx, flags=re.I)
|
10698
|
+
xx = re.sub("posterior", "post", xx, flags=re.I)
|
10699
|
+
xx = re.sub("inferior", "inf", xx, flags=re.I)
|
10700
|
+
xx = re.sub("superior", "sup", xx, flags=re.I)
|
10701
|
+
xx = re.sub(r"dktcortex", ".ctx", xx, flags=re.I)
|
10702
|
+
xx = re.sub(".lravg", "", xx, flags=re.I)
|
10703
|
+
xx = re.sub("dti.mean.fa", "dti.fa", xx, flags=re.I)
|
10704
|
+
xx = re.sub(r"retrolenticular.part.of.internal", "rent.int.cap", xx, flags=re.I)
|
10705
|
+
xx = re.sub(r"iculus.could.be.a.part.of.ant.internal.capsule", "", xx, flags=re.I) # Twice
|
10706
|
+
xx = re.sub(".fronto.occipital.", ".frnt.occ.", xx, flags=re.I)
|
10707
|
+
xx = re.sub(r".longitidinal.fasciculus.", ".long.fasc.", xx, flags=re.I) # Twice
|
10708
|
+
xx = re.sub(".external.capsule", ".ext.cap", xx, flags=re.I)
|
10709
|
+
xx = re.sub("of.internal.capsule", ".int.cap", xx, flags=re.I)
|
10710
|
+
xx = re.sub("fornix.cres.stria.terminalis", "fornix.", xx, flags=re.I)
|
10711
|
+
xx = re.sub("capsule", "", xx, flags=re.I)
|
10712
|
+
xx = re.sub("and.inf.frnt.occ.fasciculus.", "", xx, flags=re.I)
|
10713
|
+
xx = re.sub("crossing.tract.a.part.of.mcp.", "", xx, flags=re.I)
|
10714
|
+
return xx[:40] # Truncate to first 40 characters
|
10715
|
+
|
10716
|
+
|
10717
|
+
def shorten_pymm_names2(x, verbose=False ):
|
10718
|
+
"""
|
10719
|
+
Shortens pmymm names by applying a series of regex substitutions.
|
10720
|
+
|
10721
|
+
Parameters:
|
10722
|
+
x (str): The input string to be shortened
|
10723
|
+
|
10724
|
+
verbose (bool): explain the patterns and replacements and their impact
|
10725
|
+
|
10726
|
+
Returns:
|
10727
|
+
str: The shortened string
|
10728
|
+
"""
|
10729
|
+
# Define substitution patterns as tuples
|
10730
|
+
substitutions = [
|
10731
|
+
("_", "."),
|
10732
|
+
("\.\.", "."),
|
10733
|
+
("sagittal.stratum.include.inferior.longitidinal.fasciculus.and.inferior.fronto.occipital.fasciculus.","ilf.and.ifo"),
|
10734
|
+
(r"sagittal.stratum.include.inferior.longitidinal.fasciculus.and.inferior.fronto.occipital.fasciculus.", "ilf.and.ifo"),
|
10735
|
+
(r".cres.stria.terminalis.can.not.be.resolved.with.current.resolution.", ""),
|
10736
|
+
("_", "."),
|
10737
|
+
(r"longitudinal.fasciculus", "l.fasc"),
|
10738
|
+
(r"corona.radiata", "cor.rad"),
|
10739
|
+
("central", "cent"),
|
10740
|
+
(r"deep.cit168", "dp."),
|
10741
|
+
("cit168", ""),
|
10742
|
+
(".include", ""),
|
10743
|
+
("mtg.sn", ""),
|
10744
|
+
("brainstem", ".bst"),
|
10745
|
+
(r"rsfmri.", "rsf."),
|
10746
|
+
(r"dti.mean.fa.", "dti.fa."),
|
10747
|
+
("perf.cbf.mean.", "cbf."),
|
10748
|
+
(".jhu.icbm.labels.1mm", ""),
|
10749
|
+
(".include.optic.radiation.", ""),
|
10750
|
+
("\.\.", "."), # Replace double dots with single dot
|
10751
|
+
("\.\.", "."), # Replace double dots with single dot
|
10752
|
+
("cerebellar.peduncle", "cereb.ped"),
|
10753
|
+
(r"anterior.limb.of.internal.capsule", "ant.int.cap"),
|
10754
|
+
(r"posterior.limb.of.internal.capsule", "post.int.cap"),
|
10755
|
+
("t1hier.", "t1."),
|
10756
|
+
("anterior", "ant"),
|
10757
|
+
("posterior", "post"),
|
10758
|
+
("inferior", "inf"),
|
10759
|
+
("superior", "sup"),
|
10760
|
+
(r"dktcortex", ".ctx"),
|
10761
|
+
(".lravg", ""),
|
10762
|
+
("dti.mean.fa", "dti.fa"),
|
10763
|
+
(r"retrolenticular.part.of.internal", "rent.int.cap"),
|
10764
|
+
(r"iculus.could.be.a.part.of.ant.internal.capsule", ""), # Twice
|
10765
|
+
(".fronto.occipital.", ".frnt.occ."),
|
10766
|
+
(r".longitidinal.fasciculus.", ".long.fasc."), # Twice
|
10767
|
+
(".external.capsule", ".ext.cap"),
|
10768
|
+
("of.internal.capsule", ".int.cap"),
|
10769
|
+
("fornix.cres.stria.terminalis", "fornix."),
|
10770
|
+
("capsule", ""),
|
10771
|
+
("and.inf.frnt.occ.fasciculus.", ""),
|
10772
|
+
("crossing.tract.a.part.of.mcp.", "")
|
10773
|
+
]
|
10774
|
+
|
10775
|
+
# Apply substitutions in order
|
10776
|
+
for pattern, replacement in substitutions:
|
10777
|
+
if verbose:
|
10778
|
+
print("Pre " + x + " pattern "+pattern + " repl " + replacement )
|
10779
|
+
x = re.sub(pattern, replacement, x.lower(), flags=re.IGNORECASE)
|
10780
|
+
if verbose:
|
10781
|
+
print("Post " + x)
|
10782
|
+
|
10783
|
+
return x[:40] # Truncate to first 40 characters
|
10784
|
+
|
10785
|
+
|
10786
|
+
def brainmap_figure(statistical_df, data_dictionary, output_prefix, brain_image, overlay_cmap='bwr', nslices=21, ncol=7, edge_image_dilation = 0, black_bg=True, axes = [0,1,2], fixed_overlay_range=None, crop=5, verbose=0 ):
|
10472
10787
|
"""
|
10473
10788
|
Create figures based on statistical data and an underlying brain image.
|
10474
10789
|
|
@@ -10480,7 +10795,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10480
10795
|
with respect to regions that are measured in antspymm. value will be
|
10481
10796
|
the value to be displayed. if two examples of a given region exist in
|
10482
10797
|
statistical_df, then the largest absolute value will be taken for display.
|
10483
|
-
-
|
10798
|
+
- data_dictionary (pandas dataframe): antspymm data dictionary.
|
10484
10799
|
- output_prefix (str): Prefix for the output figure filenames.
|
10485
10800
|
- brain_image (antsImage): the brain image on which results will overlay.
|
10486
10801
|
- overlay_cmap (str): see matplotlib
|
@@ -10498,12 +10813,18 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10498
10813
|
"""
|
10499
10814
|
import re
|
10500
10815
|
|
10816
|
+
def is_bst_region(filename):
|
10817
|
+
return filename[-4:] == '.bst'
|
10818
|
+
|
10501
10819
|
# Read the statistical file
|
10502
10820
|
zz = statistical_df
|
10503
10821
|
|
10504
10822
|
# Read the data dictionary from a CSV file
|
10505
|
-
mydict =
|
10823
|
+
mydict = data_dictionary
|
10506
10824
|
mydict = mydict[~mydict['Measurement'].str.contains("tractography-based connectivity", na=False)]
|
10825
|
+
mydict2=mydict.copy()
|
10826
|
+
mydict2['tidynames']=mydict2['tidynames'].str.replace(".left","")
|
10827
|
+
mydict2['tidynames']=mydict2['tidynames'].str.replace(".right","")
|
10507
10828
|
|
10508
10829
|
statistical_df['anat'] = statistical_df['anat'].str.replace("_", ".", regex=True)
|
10509
10830
|
|
@@ -10516,23 +10837,44 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10516
10837
|
postfix = ['bf', 'cit168lab', 'mtl', 'cerebellum', 'dkt_cortex','brainstem','JHU_wm','yeo']
|
10517
10838
|
atlas = ['BF', 'CIT168', 'MTL', 'TustisonCobra', 'desikan-killiany-tourville','brainstem','JHU_wm','yeo']
|
10518
10839
|
postdesc = ['nbm3CH13', 'CIT168_Reinf_Learn_v1_label_descriptions_pad', 'mtl_description', 'cerebellum', 'dkt','CIT168_T1w_700um_pad_adni_brainstem','FA_JHU_labels_edited','ppmi_template_500Parcels_Yeo2011_17Networks_2023_homotopic']
|
10519
|
-
statdf = pd.DataFrame({'img': postfix, 'atlas': atlas, 'csvdescript': postdesc})
|
10520
10840
|
templateprefix = '~/.antspymm/PPMI_template0_'
|
10521
10841
|
# Iterate through columns and create figures
|
10522
10842
|
col2viz = 'values'
|
10523
10843
|
if True:
|
10524
10844
|
anattoshow = zz['anat'].unique()
|
10525
|
-
if verbose:
|
10845
|
+
if verbose > 0:
|
10526
10846
|
print(col2viz)
|
10527
10847
|
print(anattoshow)
|
10528
10848
|
# Rest of your code for figure creation goes here...
|
10529
10849
|
addem = edgeimg * 0
|
10530
10850
|
for k in range(len(anattoshow)):
|
10531
|
-
if verbose:
|
10851
|
+
if verbose > 0 :
|
10532
10852
|
print(str(k) + " " + anattoshow[k] )
|
10533
10853
|
mysub = zz[zz['anat'].str.contains(anattoshow[k])]
|
10534
|
-
anatsear=
|
10854
|
+
anatsear=shorten_pymm_names( anattoshow[k] )
|
10855
|
+
anatsear=re.sub(r'[()]', '.', anatsear )
|
10856
|
+
anatsear=re.sub(r'\.\.', '.', anatsear )
|
10857
|
+
anatsear=re.sub("dti.mean.md.snc","md.snc",anatsear)
|
10858
|
+
anatsear=re.sub("dti.mean.fa.snc","fa.snc",anatsear)
|
10859
|
+
anatsear=re.sub("dti.mean.md.snr","md.snr",anatsear)
|
10860
|
+
anatsear=re.sub("dti.mean.fa.snr","fa.snr",anatsear)
|
10861
|
+
anatsear=re.sub("dti.mean.md.","",anatsear)
|
10862
|
+
anatsear=re.sub("dti.mean.fa.","",anatsear)
|
10863
|
+
anatsear=re.sub("dti.md.","",anatsear)
|
10864
|
+
anatsear=re.sub("dti.fa.","",anatsear)
|
10865
|
+
anatsear=re.sub("dti.md","",anatsear)
|
10866
|
+
anatsear=re.sub("dti.fa","",anatsear)
|
10535
10867
|
anatsear=re.sub("cbf.","",anatsear)
|
10868
|
+
anatsear=re.sub("rsfmri.fcnxpro122.","",anatsear)
|
10869
|
+
anatsear=re.sub("rsfmri.fcnxpro129.","",anatsear)
|
10870
|
+
anatsear=re.sub("rsfmri.fcnxpro134.","",anatsear)
|
10871
|
+
anatsear=re.sub("t1hier.vollravg","",anatsear)
|
10872
|
+
anatsear=re.sub("t1hier.volasym","",anatsear)
|
10873
|
+
anatsear=re.sub("t1hier.thkasym","",anatsear)
|
10874
|
+
anatsear=re.sub("t1hier.areaasym","",anatsear)
|
10875
|
+
anatsear=re.sub("t1hier.vol.","",anatsear)
|
10876
|
+
anatsear=re.sub("t1hier.thk.","",anatsear)
|
10877
|
+
anatsear=re.sub("t1hier.area.","",anatsear)
|
10536
10878
|
anatsear=re.sub("t1.volasym","",anatsear)
|
10537
10879
|
anatsear=re.sub("t1.thkasym","",anatsear)
|
10538
10880
|
anatsear=re.sub("t1.areaasym","",anatsear)
|
@@ -10541,30 +10883,68 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10541
10883
|
anatsear=re.sub("t1.area.","",anatsear)
|
10542
10884
|
anatsear=re.sub("asymdp.","",anatsear)
|
10543
10885
|
anatsear=re.sub("asym.","",anatsear)
|
10544
|
-
anatsear=re.sub("
|
10545
|
-
anatsear=re.sub("
|
10546
|
-
anatsear=re.sub("dti.md","",anatsear)
|
10547
|
-
anatsear=re.sub("dti.mean.md.","",anatsear)
|
10548
|
-
anatsear=re.sub("dti.mean.fa.","",anatsear)
|
10886
|
+
anatsear=re.sub("asym","",anatsear)
|
10887
|
+
anatsear=re.sub("lravg.","",anatsear)
|
10549
10888
|
anatsear=re.sub("lravg","",anatsear)
|
10889
|
+
anatsear=re.sub("dktcortex","",anatsear)
|
10890
|
+
anatsear=re.sub("dktregions","",anatsear)
|
10891
|
+
anatsear=re.sub("_",".",anatsear)
|
10892
|
+
anatsear=re.sub("superior","sup",anatsear)
|
10893
|
+
anatsear=re.sub("cerebellum","",anatsear)
|
10894
|
+
anatsear=re.sub("brainstem","",anatsear)
|
10895
|
+
anatsear=re.sub("t.limb.int","t.int",anatsear)
|
10896
|
+
anatsear=re.sub("paracentral","paracent",anatsear)
|
10897
|
+
anatsear=re.sub("precentral","precent",anatsear)
|
10898
|
+
anatsear=re.sub("postcentral","postcent",anatsear)
|
10899
|
+
anatsear=re.sub("sup.cerebellar.peduncle","sup.cereb.ped",anatsear)
|
10900
|
+
anatsear=re.sub("inferior.cerebellar.peduncle","inf.cereb.ped",anatsear)
|
10901
|
+
anatsear=re.sub(".crossing.tract.a.part.of.mcp.","",anatsear)
|
10902
|
+
anatsear=re.sub(".column.and.body.of.fornix.","",anatsear)
|
10903
|
+
anatsear=re.sub("fronto.occipital.fasciculus.could.be.a.part.of.ant.internal.capsule","frnt.occ",anatsear)
|
10904
|
+
anatsear=re.sub("inferior.fronto.occipital.fasciculus.could.be.a.part.of.anterior.internal.capsule","inf.frnt.occ",anatsear)
|
10905
|
+
anatsear=re.sub("fornix.cres.stria.terminalis.can.not.be.resolved.with.current.resolution","fornix.column.and.body.of.fornix",anatsear)
|
10906
|
+
anatsear=re.sub("external.capsule","ext.cap",anatsear)
|
10907
|
+
anatsear=re.sub(".jhu.icbm.labels.1mm","",anatsear)
|
10908
|
+
anatsear=re.sub("dp.",".",anatsear)
|
10909
|
+
anatsear=re.sub(".mtg.sn.snc.",".snc.",anatsear)
|
10910
|
+
anatsear=re.sub(".mtg.sn.snr.",".snr.",anatsear)
|
10911
|
+
anatsear=re.sub("mtg.sn.snc.",".snc.",anatsear)
|
10912
|
+
anatsear=re.sub("mtg.sn.snr.",".snr.",anatsear)
|
10913
|
+
anatsear=re.sub("mtg.sn.snc",".snc.",anatsear)
|
10914
|
+
anatsear=re.sub("mtg.sn.snr",".snr.",anatsear)
|
10915
|
+
anatsear=re.sub("anterior.","ant.",anatsear)
|
10916
|
+
anatsear=re.sub("rsf.","",anatsear)
|
10917
|
+
anatsear=re.sub("ant.corona.radiata","ant.cor.rad",anatsear)
|
10918
|
+
anatsear=re.sub("sup.corona.radiata","sup.cor.rad",anatsear)
|
10919
|
+
anatsear=re.sub("posterior.thalamic.radiation.include.optic.radiation","post.thalamic.radiation",anatsear)
|
10920
|
+
anatsear=re.sub("retrolenticular.part.of.internal.capsule","rent.int.cap",anatsear)
|
10921
|
+
anatsear=re.sub("post.limb.of.internal.capsule","post.int.cap",anatsear)
|
10922
|
+
anatsear=re.sub("ant.limb.of.internal.capsule","ant.int.cap",anatsear)
|
10923
|
+
anatsear=re.sub("sagittal.stratum.include.inferior.longitidinal.fasciculus.and.inferior.fronto.occipital.fasciculus","ilf.and.ifo",anatsear)
|
10550
10924
|
atlassearch = mydict['tidynames'].str.contains(anatsear)
|
10551
|
-
if
|
10925
|
+
if atlassearch.sum() == 0:
|
10926
|
+
atlassearch = mydict2['tidynames'].str.contains(anatsear)
|
10927
|
+
if verbose > 0 :
|
10552
10928
|
print( " anatsear " + anatsear + " atlassearch " )
|
10553
10929
|
if atlassearch.sum() > 0:
|
10554
10930
|
whichatlas = mydict[atlassearch]['Atlas'].iloc[0]
|
10555
10931
|
oglabelname = mydict[atlassearch]['Label'].iloc[0]
|
10932
|
+
oglabelname=re.sub("_",".",oglabelname)
|
10933
|
+
oglabelname=re.sub(r'\.\.','.',oglabelname)
|
10556
10934
|
else:
|
10557
10935
|
print(anatsear)
|
10558
10936
|
oglabelname='unknown'
|
10559
10937
|
whichatlas=None
|
10560
|
-
if verbose:
|
10938
|
+
if verbose > 0:
|
10561
10939
|
print("oglabelname " + oglabelname + " whichatlas " + str(whichatlas) )
|
10562
10940
|
vals2viz = mysub[col2viz].agg(['min', 'max'])
|
10563
10941
|
vals2viz = vals2viz[abs(vals2viz).idxmax()]
|
10564
10942
|
myext = None
|
10565
|
-
if
|
10943
|
+
if anatsear == 'cingulum.hippocampus':
|
10944
|
+
myext = 'JHU_wm'
|
10945
|
+
elif 'dktcortex' in anattoshow[k] or whichatlas == 'desikan-killiany-tourville' or 'dtkregions' in anattoshow[k] :
|
10566
10946
|
myext = 'dkt_cortex'
|
10567
|
-
elif 'cit168' in anattoshow[k] or whichatlas == 'CIT168':
|
10947
|
+
elif ('cit168' in anattoshow[k] or whichatlas == 'CIT168') and not 'brainstem' in anattoshow[k] and not is_bst_region(anatsear):
|
10568
10948
|
myext = 'cit168lab'
|
10569
10949
|
elif 'mtl' in anattoshow[k]:
|
10570
10950
|
myext = 'mtl'
|
@@ -10573,11 +10953,12 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10573
10953
|
myext = 'cerebellum'
|
10574
10954
|
oglabelname=re.sub('cerebellum', '',anatsear)
|
10575
10955
|
# oglabelname=oglabelname[2:]
|
10576
|
-
elif 'brainstem' in anattoshow[k]:
|
10956
|
+
elif 'brainstem' in anattoshow[k] or is_bst_region(anatsear):
|
10577
10957
|
myext = 'brainstem'
|
10578
10958
|
elif any(item in anattoshow[k] for item in ['nbm', 'bf']):
|
10579
10959
|
myext = 'bf'
|
10580
|
-
oglabelname=re.sub(
|
10960
|
+
oglabelname=re.sub('bf', '',oglabelname)
|
10961
|
+
# oglabelname=re.sub(r'\.', '_',anatsear)
|
10581
10962
|
elif whichatlas == 'johns hopkins white matter':
|
10582
10963
|
myext = 'JHU_wm'
|
10583
10964
|
elif whichatlas == 'desikan-killiany-tourville':
|
@@ -10589,14 +10970,14 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10589
10970
|
oglabelname=re.sub('bf', '',oglabelname)
|
10590
10971
|
elif whichatlas == 'yeo_homotopic':
|
10591
10972
|
myext = 'yeo'
|
10592
|
-
if myext is None and verbose:
|
10973
|
+
if myext is None and verbose > 0 :
|
10593
10974
|
if whichatlas is None:
|
10594
10975
|
whichatlas='None'
|
10595
10976
|
if anattoshow[k] is None:
|
10596
10977
|
anattoshow[k]='None'
|
10597
10978
|
print( "MYEXT " + anattoshow[k] + ' unfound ' + whichatlas )
|
10598
10979
|
else:
|
10599
|
-
if verbose:
|
10980
|
+
if verbose > 0 :
|
10600
10981
|
print( "MYEXT " + myext )
|
10601
10982
|
|
10602
10983
|
if myext == 'cit168lab':
|
@@ -10608,18 +10989,21 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10608
10989
|
if j == "deep_cit168lab":
|
10609
10990
|
j = 'deep_cit168'
|
10610
10991
|
anattoshow[k] = anattoshow[k].replace(j, "")
|
10611
|
-
if verbose:
|
10992
|
+
if verbose > 0:
|
10612
10993
|
print( anattoshow[k] + " " + str( vals2viz ) )
|
10613
|
-
myatlas = atlas[postfix.index(myext)]
|
10614
10994
|
correctdescript = postdesc[postfix.index(myext)]
|
10615
10995
|
locfilename = templateprefix + myext + '.nii.gz'
|
10616
|
-
if verbose:
|
10996
|
+
if verbose > 0:
|
10617
10997
|
print( locfilename )
|
10618
10998
|
if myext == 'yeo':
|
10619
10999
|
oglabelname=oglabelname.lower()
|
10620
11000
|
oglabelname=re.sub("rsfmri_fcnxpro122_","",oglabelname)
|
10621
11001
|
oglabelname=re.sub("rsfmri_fcnxpro129_","",oglabelname)
|
10622
11002
|
oglabelname=re.sub("rsfmri_fcnxpro134_","",oglabelname)
|
11003
|
+
oglabelname=re.sub("rsfmri.fcnxpro122.","",oglabelname)
|
11004
|
+
oglabelname=re.sub("rsfmri.fcnxpro129.","",oglabelname)
|
11005
|
+
oglabelname=re.sub("rsfmri.fcnxpro134.","",oglabelname)
|
11006
|
+
oglabelname=re.sub("_",".",oglabelname)
|
10623
11007
|
locfilename = "~/.antspymm/ppmi_template_500Parcels_Yeo2011_17Networks_2023_homotopic.nii.gz"
|
10624
11008
|
atlasDescript = pd.read_csv(f"~/.antspymm/{correctdescript}.csv")
|
10625
11009
|
atlasDescript.rename(columns={'SystemName': 'Description'}, inplace=True)
|
@@ -10636,15 +11020,25 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10636
11020
|
atlasDescript['Description'] = atlasDescript['Description'].str.replace("left_", "")
|
10637
11021
|
atlasDescript['Description'] = atlasDescript['Description'].str.replace("right_", "")
|
10638
11022
|
atlasDescript['Description'] = atlasDescript['Description'].str.replace("/",".")
|
11023
|
+
atlasDescript['Description'] = atlasDescript['Description'].str.replace("_",".")
|
11024
|
+
atlasDescript['Description'] = atlasDescript['Description'].str.replace(r'[()]', '', regex=True)
|
11025
|
+
atlasDescript['Description'] = atlasDescript['Description'].str.replace(r'\.\.', '.')
|
10639
11026
|
if myext == 'JHU_wm':
|
11027
|
+
atlasDescript['Description'] = atlasDescript['Description'].str.replace("-", ".")
|
11028
|
+
atlasDescript['Description'] = atlasDescript['Description'].str.replace("jhu.icbm.labels.1mm", "")
|
11029
|
+
atlasDescript['Description'] = atlasDescript['Description'].str.replace("fronto-occipital", "frnt.occ")
|
11030
|
+
atlasDescript['Description'] = atlasDescript['Description'].str.replace("superior", "sup")
|
10640
11031
|
atlasDescript['Description'] = atlasDescript['Description'].str.replace("fa-", "")
|
10641
11032
|
atlasDescript['Description'] = atlasDescript['Description'].str.replace("-left-", "")
|
10642
11033
|
atlasDescript['Description'] = atlasDescript['Description'].str.replace("-right-", "")
|
10643
11034
|
if myext == 'cerebellum':
|
10644
11035
|
atlasDescript['Description'] = atlasDescript['Description'].str.replace("l_", "")
|
10645
11036
|
atlasDescript['Description'] = atlasDescript['Description'].str.replace("r_", "")
|
11037
|
+
atlasDescript['Description'] = atlasDescript['Description'].str.replace("l.", "")
|
11038
|
+
atlasDescript['Description'] = atlasDescript['Description'].str.replace("r.", "")
|
11039
|
+
atlasDescript['Description'] = atlasDescript['Description'].str.replace("_",".")
|
10646
11040
|
|
10647
|
-
if verbose:
|
11041
|
+
if verbose > 0:
|
10648
11042
|
print( atlasDescript )
|
10649
11043
|
oglabelname = oglabelname.lower()
|
10650
11044
|
oglabelname = re.sub(" ", "_",oglabelname)
|
@@ -10657,15 +11051,31 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10657
11051
|
oglabelname = re.sub("t1hier_thk_", "",oglabelname)
|
10658
11052
|
oglabelname = re.sub("dktregions", "",oglabelname)
|
10659
11053
|
oglabelname = re.sub("dktcortex", "",oglabelname)
|
11054
|
+
|
11055
|
+
oglabelname = re.sub(" ", ".",oglabelname)
|
11056
|
+
oglabelname = re.sub(".left.", ".",oglabelname)
|
11057
|
+
oglabelname = re.sub(".right.", ".",oglabelname)
|
11058
|
+
oglabelname = re.sub(".left", "",oglabelname)
|
11059
|
+
oglabelname = re.sub(".right", "",oglabelname)
|
11060
|
+
oglabelname = re.sub("t1hier.vol.", "",oglabelname)
|
11061
|
+
oglabelname = re.sub("t1hier.area.", "",oglabelname)
|
11062
|
+
oglabelname = re.sub("t1hier.thk.", "",oglabelname)
|
11063
|
+
oglabelname = re.sub("dktregions", "",oglabelname)
|
11064
|
+
oglabelname = re.sub("dktcortex", "",oglabelname)
|
11065
|
+
oglabelname=re.sub("brainstem","",oglabelname)
|
10660
11066
|
if myext == 'JHU_wm':
|
10661
11067
|
oglabelname = re.sub("dti_mean_fa.", "",oglabelname)
|
10662
11068
|
oglabelname = re.sub("dti_mean_md.", "",oglabelname)
|
11069
|
+
oglabelname = re.sub("dti.mean.fa.", "",oglabelname)
|
11070
|
+
oglabelname = re.sub("dti.mean.md.", "",oglabelname)
|
10663
11071
|
oglabelname = re.sub(".left.", "",oglabelname)
|
10664
11072
|
oglabelname = re.sub(".right.", "",oglabelname)
|
10665
11073
|
oglabelname = re.sub(".lravg.", "",oglabelname)
|
10666
11074
|
oglabelname = re.sub(".asym.", "",oglabelname)
|
11075
|
+
oglabelname = re.sub(".jhu.icbm.labels.1mm", "",oglabelname)
|
11076
|
+
oglabelname = re.sub("superior", "sup",oglabelname)
|
10667
11077
|
|
10668
|
-
if verbose:
|
11078
|
+
if verbose > 0:
|
10669
11079
|
print("oglabelname " + oglabelname )
|
10670
11080
|
|
10671
11081
|
if myext == 'cerebellum':
|
@@ -10674,7 +11084,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10674
11084
|
atlasDescript['Description'] = atlasDescript['Description'].str.replace("r_", "")
|
10675
11085
|
oglabelname=re.sub("ravg","",oglabelname)
|
10676
11086
|
oglabelname=re.sub("lavg","",oglabelname)
|
10677
|
-
whichindex = atlasDescript.index[atlasDescript['Description'] == oglabelname].values
|
11087
|
+
whichindex = atlasDescript.index[atlasDescript['Description'] == oglabelname].values
|
10678
11088
|
else:
|
10679
11089
|
if atlasDescript.empty:
|
10680
11090
|
print("The DataFrame 'atlasDescript' is empty.")
|
@@ -10691,6 +11101,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10691
11101
|
if myext == 'yeo':
|
10692
11102
|
parts = re.findall(r'\D+', oglabelname)
|
10693
11103
|
oglabelname = [part.replace('_', '') for part in parts if part.replace('_', '')]
|
11104
|
+
oglabelname = [part.replace('.', '') for part in parts if part.replace('.', '')]
|
10694
11105
|
filtered_df = atlasDescript[atlasDescript['Description'].isin(oglabelname)]
|
10695
11106
|
labelnums = filtered_df['Label'].tolist()
|
10696
11107
|
|
@@ -10699,7 +11110,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10699
11110
|
addemiszero = ants.threshold_image(addem, 0, 0)
|
10700
11111
|
temp = ants.image_read(locfilename)
|
10701
11112
|
temp = ants.mask_image(temp, temp, level=labelnums, binarize=True)
|
10702
|
-
if verbose:
|
11113
|
+
if verbose > 0:
|
10703
11114
|
print("DEBUG")
|
10704
11115
|
print( temp.sum() )
|
10705
11116
|
print( labelnums )
|
@@ -10707,7 +11118,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10707
11118
|
temp[addemiszero == 0] = 0
|
10708
11119
|
addem = addem + temp
|
10709
11120
|
|
10710
|
-
if verbose:
|
11121
|
+
if verbose > 0:
|
10711
11122
|
print('Done Adding')
|
10712
11123
|
for axx in axes:
|
10713
11124
|
figfn=output_prefix+f"fig{col2viz}ax{axx}_py.jpg"
|
@@ -10726,7 +11137,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
|
|
10726
11137
|
ants.plot(edgeimgC, addemC, axis=axx, nslices=nslices, ncol=ncol,
|
10727
11138
|
overlay_cmap=overlay_cmap, resample=False, overlay_alpha=1.0,
|
10728
11139
|
filename=figfn, cbar=axx==axes[0], crop=True, black_bg=black_bg )
|
10729
|
-
if verbose:
|
11140
|
+
if verbose > 0:
|
10730
11141
|
print(f"{col2viz} done")
|
10731
11142
|
if verbose:
|
10732
11143
|
print("DONE brain map figures")
|
@@ -11421,7 +11832,7 @@ def renameit(df, old_col_name, new_col_name):
|
|
11421
11832
|
df.rename(columns={old_col_name: new_col_name}, inplace=True)
|
11422
11833
|
|
11423
11834
|
|
11424
|
-
def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
|
11835
|
+
def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, mysep='-', verbose=True ):
|
11425
11836
|
"""
|
11426
11837
|
Processes a quality control (QC) DataFrame to perform modality-specific matching and filtering based
|
11427
11838
|
on predefined criteria, optimizing for minimal outliers and noise, and maximal signal-to-noise ratio (SNR),
|
@@ -11436,6 +11847,7 @@ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
|
|
11436
11847
|
qc_dataframe : pandas.DataFrame
|
11437
11848
|
The DataFrame containing QC metrics for different modalities and imaging data.
|
11438
11849
|
fix_LRRL : bool, optional
|
11850
|
+
mysep : string, character such as - or _ the usual antspymm separator argument
|
11439
11851
|
|
11440
11852
|
verbose : bool, optional
|
11441
11853
|
If True, prints the progress and the shape of the DataFrame being processed in each step.
|
@@ -11453,17 +11865,19 @@ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
|
|
11453
11865
|
The matched and filtered DataFrame after applying all QC scoring and matching operations across specified modalities.
|
11454
11866
|
|
11455
11867
|
"""
|
11868
|
+
qc_dataframe=remove_unwanted_columns( qc_dataframe )
|
11456
11869
|
qc_dataframe['modality'] = qc_dataframe['modality'].replace(['DTIdwi', 'DTIb0'], 'DTI', regex=True)
|
11457
11870
|
qc_dataframe['filename']=qc_dataframe['filename'].astype(str)
|
11458
11871
|
qc_dataframe['ol_loop']=qc_dataframe['ol_loop'].astype(float)
|
11459
11872
|
qc_dataframe['ol_lof']=qc_dataframe['ol_lof'].astype(float)
|
11460
11873
|
qc_dataframe['ol_lof_decision']=qc_dataframe['ol_lof_decision'].astype(float)
|
11461
11874
|
outlier_column='ol_loop'
|
11462
|
-
mmdf0 = best_mmm( qc_dataframe, 'T1w', outlier_column=outlier_column )['filt']
|
11463
|
-
fldf = best_mmm( qc_dataframe, 'T2Flair', outlier_column=outlier_column )['filt']
|
11464
|
-
nmdf = best_mmm( qc_dataframe, 'NM2DMT', outlier_column=outlier_column )['filt']
|
11465
|
-
rsdf = best_mmm( qc_dataframe, 'rsfMRI', outlier_column=outlier_column )['filt']
|
11466
|
-
dtdf = best_mmm( qc_dataframe, 'DTI', outlier_column=outlier_column )['filt']
|
11875
|
+
mmdf0 = best_mmm( qc_dataframe, 'T1w', outlier_column=outlier_column, mysep=mysep )['filt']
|
11876
|
+
fldf = best_mmm( qc_dataframe, 'T2Flair', outlier_column=outlier_column, mysep=mysep )['filt']
|
11877
|
+
nmdf = best_mmm( qc_dataframe, 'NM2DMT', outlier_column=outlier_column, mysep=mysep )['filt']
|
11878
|
+
rsdf = best_mmm( qc_dataframe, 'rsfMRI', outlier_column=outlier_column, mysep=mysep )['filt']
|
11879
|
+
dtdf = best_mmm( qc_dataframe, 'DTI', outlier_column=outlier_column, mysep=mysep )['filt']
|
11880
|
+
pfdf = best_mmm( qc_dataframe, 'perf', outlier_column=outlier_column, mysep=mysep )['filt']
|
11467
11881
|
|
11468
11882
|
criteria = {'ol_loop': 'min', 'noise': 'min', 'snr': 'max', 'EVR': 'max', 'reflection_err':'min'}
|
11469
11883
|
xcl = [ 'mrimfg', 'mrimodel','mriMagneticFieldStrength', 'dti_failed', 'rsf_failed', 'subjectID', 'date', 'subjectIDdate','repeat']
|
@@ -11471,6 +11885,9 @@ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
|
|
11471
11885
|
mmdf, undffl = mm_match_by_qc_scoring(mmdf0, fldf, 'subjectIDdate', criteria,
|
11472
11886
|
prefix='T2Flair_', exclude_columns=xcl )
|
11473
11887
|
|
11888
|
+
mmdf, undfpf = mm_match_by_qc_scoring(mmdf, pfdf, 'subjectIDdate', criteria,
|
11889
|
+
prefix='perf_', exclude_columns=xcl )
|
11890
|
+
|
11474
11891
|
prefixes = ['NM1_', 'NM2_', 'NM3_', 'NM4_', 'NM5_', 'NM6_']
|
11475
11892
|
undfmod = nmdf # Initialize 'undfmod' with 'nmdf' for the first iteration
|
11476
11893
|
if undfmod is not None:
|
@@ -11489,27 +11906,29 @@ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
|
|
11489
11906
|
criteria = {'ol_loop': 'min', 'noise': 'min', 'dti_bvalueMax':'min', 'dimt':'max'}
|
11490
11907
|
prefixes = ['DTI1_', 'DTI2_', 'DTI3_'] # List of prefixes for each matching iteration
|
11491
11908
|
undfmod = dtdf
|
11492
|
-
if
|
11493
|
-
|
11494
|
-
|
11495
|
-
|
11496
|
-
|
11497
|
-
|
11498
|
-
|
11499
|
-
|
11500
|
-
|
11909
|
+
if undfmod is not None:
|
11910
|
+
if verbose:
|
11911
|
+
print('start DT')
|
11912
|
+
print( undfmod.shape )
|
11913
|
+
for prefix in prefixes:
|
11914
|
+
if undfmod.shape[0] > 50:
|
11915
|
+
mmdf, undfmod = mm_match_by_qc_scoring(mmdf, undfmod, 'subjectIDdate', criteria, prefix=prefix, exclude_columns=xcl)
|
11916
|
+
if verbose:
|
11917
|
+
print( prefix )
|
11918
|
+
print( undfmod.shape )
|
11501
11919
|
|
11502
11920
|
prefixes = ['rsf1_', 'rsf2_', 'rsf3_'] # List of prefixes for each matching iteration
|
11503
11921
|
undfmod = rsdf # Initialize 'undfmod' with 'nmdf' for the first iteration
|
11504
|
-
if
|
11505
|
-
|
11506
|
-
|
11507
|
-
|
11508
|
-
|
11509
|
-
|
11510
|
-
|
11511
|
-
|
11512
|
-
|
11922
|
+
if undfmod is not None:
|
11923
|
+
if verbose:
|
11924
|
+
print('start rsf')
|
11925
|
+
print( undfmod.shape )
|
11926
|
+
for prefix in prefixes:
|
11927
|
+
if undfmod.shape[0] > 50:
|
11928
|
+
mmdf, undfmod = mm_match_by_qc_scoring(mmdf, undfmod, 'subjectIDdate', criteria, prefix=prefix, exclude_columns=xcl)
|
11929
|
+
if verbose:
|
11930
|
+
print( prefix )
|
11931
|
+
print( undfmod.shape )
|
11513
11932
|
|
11514
11933
|
if fix_LRRL:
|
11515
11934
|
# mmdf=fix_LR_RL_stuff( mmdf, 'DTI1_filename', 'DTI2_filename', 'DTI1_dimt', 'DTI2_dimt')
|