antspymm 1.3.9__py3-none-any.whl → 1.4.0__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 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) ))[0]
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) ))[0]
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) ))[0]
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) ))[0]
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', verbose=False ):
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 < 3:
1511
- return None
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 == 3:
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 = ants.get_mask(adw)
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()
@@ -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, 'lowermeans' and 'highermeans', each containing
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
- 'lowermeans': lowermeans,
2970
- 'highermeans': highermeans
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 )['highermeans']
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
- tenmodel = dti.TensorModel(gtab,fit_method=fit_method)
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
- tenfit, FA, MD1, RGB = justthefit( gtab, fit_method, image, maskdil )
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 = 4.0
5141
+ k = 1.0
5058
5142
  rrthresh = (rravg + k * rrstd)
5059
- nmabovekthresh_mask4 = sn_mask * ants.threshold_image( simg, rrthresh, math.inf)
5060
- snvolabovethresh4 = vol_element * nmabovekthresh_mask4.sum()
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
- show_it = None, # output path
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
- show_it (str): Output path. If not None, the visualizations will be saved at this location. Default is None.
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
- vizlist (list): List of image visualizations.
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( myimgsInput )
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
- if verbose:
9390
- print( " we have : " + str(nimages) + " modalities. will visualize T1 NM rsfMRI DTIB0 DTIDWI FLAIR")
9391
- # nrg_modality_list = ["T1w", "NM2DMT", "rsfMRI","rsfMRI_LR","rsfMRI_RL","DTI","DTI_LR", "T2Flair" ],
9392
- nrg_modality_list = [ 'T1w', 'NM2DMT', 'rsfMRI', 'DWI1', 'DWI2', 'T2Flair' ]
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 == 'T1w':
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.sort()
9403
- myimgsr=myimgsr[0]
9490
+ myimgsr=find_most_recent_file( myimgsr )[0]
9404
9491
  vimg=ants.image_read( myimgsr )
9405
- elif overmodX == 'DWI1':
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.sort()
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 == 'DWI2':
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.sort()
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.sort()
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 len( vimg.shape ) == 4 and ( overmodX == "DWI2" ):
9620
+ if vimg.dimension == 4 and ( overmodX == "DTI2" ):
9469
9621
  ttb0, ttdw=get_average_dwi_b0(vimg)
9470
9622
  vimg = ttdw
9471
- elif len( vimg.shape ) == 4 and overmodX == "DWI1":
9623
+ elif vimg.dimension == 4 and overmodX == "DTI":
9472
9624
  ttb0, ttdw=get_average_dwi_b0(vimg)
9473
9625
  vimg = ttb0
9474
- elif len( vimg.shape ) == 4 :
9626
+ elif vimg.dimension == 4 :
9475
9627
  vimg=ants.get_average_of_timeseries(vimg)
9476
9628
  msk=ants.get_mask(vimg)
9477
- vimg=ants.crop_image(vimg,msk)
9478
- if overmodX == 'T1w':
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 )
9486
9644
 
9487
- listlen = len( vizlist )
9488
- vizlist = np.asarray( vizlist )
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 )
9666
+
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:
@@ -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,7 @@ 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
- def brainmap_figure(statistical_df, data_dictionary_path, 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=False ):
10657
+ def brainmap_figure(statistical_df, data_dictionary_path, 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
10658
  """
10473
10659
  Create figures based on statistical data and an underlying brain image.
10474
10660
 
@@ -10504,6 +10690,9 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10504
10690
  # Read the data dictionary from a CSV file
10505
10691
  mydict = pd.read_csv(data_dictionary_path)
10506
10692
  mydict = mydict[~mydict['Measurement'].str.contains("tractography-based connectivity", na=False)]
10693
+ mydict2=mydict.copy()
10694
+ mydict2['tidynames']=mydict2['tidynames'].str.replace(".left","")
10695
+ mydict2['tidynames']=mydict2['tidynames'].str.replace(".right","")
10507
10696
 
10508
10697
  statistical_df['anat'] = statistical_df['anat'].str.replace("_", ".", regex=True)
10509
10698
 
@@ -10516,23 +10705,34 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10516
10705
  postfix = ['bf', 'cit168lab', 'mtl', 'cerebellum', 'dkt_cortex','brainstem','JHU_wm','yeo']
10517
10706
  atlas = ['BF', 'CIT168', 'MTL', 'TustisonCobra', 'desikan-killiany-tourville','brainstem','JHU_wm','yeo']
10518
10707
  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
10708
  templateprefix = '~/.antspymm/PPMI_template0_'
10521
10709
  # Iterate through columns and create figures
10522
10710
  col2viz = 'values'
10523
10711
  if True:
10524
10712
  anattoshow = zz['anat'].unique()
10525
- if verbose:
10713
+ if verbose > 0:
10526
10714
  print(col2viz)
10527
10715
  print(anattoshow)
10528
10716
  # Rest of your code for figure creation goes here...
10529
10717
  addem = edgeimg * 0
10530
10718
  for k in range(len(anattoshow)):
10531
- if verbose:
10719
+ if verbose > 0 :
10532
10720
  print(str(k) + " " + anattoshow[k] )
10533
10721
  mysub = zz[zz['anat'].str.contains(anattoshow[k])]
10534
- anatsear=re.sub("dti.fa","",anattoshow[k])
10722
+ anatsear=re.sub(r'[()]', '.', anattoshow[k])
10723
+ anatsear=re.sub(r'\.\.', '.', anatsear)
10724
+ anatsear=re.sub("dti.fa","",anatsear)
10535
10725
  anatsear=re.sub("cbf.","",anatsear)
10726
+ anatsear=re.sub("rsfmri.fcnxpro122.","",anatsear)
10727
+ anatsear=re.sub("rsfmri.fcnxpro129.","",anatsear)
10728
+ anatsear=re.sub("rsfmri.fcnxpro134.","",anatsear)
10729
+ anatsear=re.sub("t1hier.vollravg","",anatsear)
10730
+ anatsear=re.sub("t1hier.volasym","",anatsear)
10731
+ anatsear=re.sub("t1hier.thkasym","",anatsear)
10732
+ anatsear=re.sub("t1hier.areaasym","",anatsear)
10733
+ anatsear=re.sub("t1hier.vol.","",anatsear)
10734
+ anatsear=re.sub("t1hier.thk.","",anatsear)
10735
+ anatsear=re.sub("t1hier.area.","",anatsear)
10536
10736
  anatsear=re.sub("t1.volasym","",anatsear)
10537
10737
  anatsear=re.sub("t1.thkasym","",anatsear)
10538
10738
  anatsear=re.sub("t1.areaasym","",anatsear)
@@ -10546,25 +10746,57 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10546
10746
  anatsear=re.sub("dti.md","",anatsear)
10547
10747
  anatsear=re.sub("dti.mean.md.","",anatsear)
10548
10748
  anatsear=re.sub("dti.mean.fa.","",anatsear)
10749
+ anatsear=re.sub("asym.","",anatsear)
10750
+ anatsear=re.sub("asym","",anatsear)
10751
+ anatsear=re.sub("lravg.","",anatsear)
10549
10752
  anatsear=re.sub("lravg","",anatsear)
10753
+ anatsear=re.sub("dktcortex","",anatsear)
10754
+ anatsear=re.sub("dktregions","",anatsear)
10755
+ anatsear=re.sub("_",".",anatsear)
10756
+ anatsear=re.sub("superior","sup",anatsear)
10757
+ anatsear=re.sub("cerebellum","",anatsear)
10758
+ anatsear=re.sub("brainstem","",anatsear)
10759
+ anatsear=re.sub("sup.cerebellar.peduncle","sup.cereb.ped",anatsear)
10760
+ anatsear=re.sub("inferior.cerebellar.peduncle","inf.cereb.ped",anatsear)
10761
+ anatsear=re.sub(".crossing.tract.a.part.of.mcp.","",anatsear)
10762
+ anatsear=re.sub(".column.and.body.of.fornix.","",anatsear)
10763
+ anatsear=re.sub("fronto.occipital.fasciculus.could.be.a.part.of.anterior.internal.capsule","frnt.occ",anatsear)
10764
+ anatsear=re.sub("inferior.fronto.occipital.fasciculus.could.be.a.part.of.anterior.internal.capsule","inf.frnt.occ",anatsear)
10765
+ anatsear=re.sub("fornix.cres.stria.terminalis.can.not.be.resolved.with.current.resolution","fornix.column.and.body.of.fornix",anatsear)
10766
+ anatsear=re.sub("external.capsule","ext.cap",anatsear)
10767
+ anatsear=re.sub(".jhu.icbm.labels.1mm","",anatsear)
10768
+ anatsear=re.sub("mtg.sn.snc.",".snc.",anatsear)
10769
+ anatsear=re.sub("mtg.sn.snr.",".snr.",anatsear)
10770
+ anatsear=re.sub("anterior.","ant.",anatsear)
10771
+ anatsear=re.sub("ant.corona.radiata","ant.cor.rad",anatsear)
10772
+ anatsear=re.sub("sup.corona.radiata","sup.cor.rad",anatsear)
10773
+ anatsear=re.sub("posterior.thalamic.radiation.include.optic.radiation","post.thalamic.radiation",anatsear)
10774
+ anatsear=re.sub("retrolenticular.part.of.internal.capsule","rent.int.cap",anatsear)
10775
+ anatsear=re.sub("sagittal.stratum.include.inferior.longitidinal.fasciculus.and.inferior.fronto.occipital.fasciculus","ilf.and.ifo",anatsear)
10550
10776
  atlassearch = mydict['tidynames'].str.contains(anatsear)
10551
- if verbose:
10777
+ if atlassearch.sum() == 0:
10778
+ atlassearch = mydict2['tidynames'].str.contains(anatsear)
10779
+ if verbose > 0 :
10552
10780
  print( " anatsear " + anatsear + " atlassearch " )
10553
10781
  if atlassearch.sum() > 0:
10554
10782
  whichatlas = mydict[atlassearch]['Atlas'].iloc[0]
10555
10783
  oglabelname = mydict[atlassearch]['Label'].iloc[0]
10784
+ oglabelname=re.sub("_",".",oglabelname)
10785
+ oglabelname=re.sub(r'\.\.','.',oglabelname)
10556
10786
  else:
10557
10787
  print(anatsear)
10558
10788
  oglabelname='unknown'
10559
10789
  whichatlas=None
10560
- if verbose:
10790
+ if verbose > 0:
10561
10791
  print("oglabelname " + oglabelname + " whichatlas " + str(whichatlas) )
10562
10792
  vals2viz = mysub[col2viz].agg(['min', 'max'])
10563
10793
  vals2viz = vals2viz[abs(vals2viz).idxmax()]
10564
10794
  myext = None
10565
- if 'dktcortex' in anattoshow[k] or whichatlas == 'desikan-killiany-tourville' or 'dtkregions' in anattoshow[k]:
10795
+ if anatsear == 'cingulum.hippocampus':
10796
+ myext = 'JHU_wm'
10797
+ elif 'dktcortex' in anattoshow[k] or whichatlas == 'desikan-killiany-tourville' or 'dtkregions' in anattoshow[k] :
10566
10798
  myext = 'dkt_cortex'
10567
- elif 'cit168' in anattoshow[k] or whichatlas == 'CIT168':
10799
+ elif ('cit168' in anattoshow[k] or whichatlas == 'CIT168') and not 'brainstem' in anattoshow[k]:
10568
10800
  myext = 'cit168lab'
10569
10801
  elif 'mtl' in anattoshow[k]:
10570
10802
  myext = 'mtl'
@@ -10577,7 +10809,8 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10577
10809
  myext = 'brainstem'
10578
10810
  elif any(item in anattoshow[k] for item in ['nbm', 'bf']):
10579
10811
  myext = 'bf'
10580
- oglabelname=re.sub(r'\.', '_',anatsear)
10812
+ oglabelname=re.sub('bf', '',oglabelname)
10813
+ # oglabelname=re.sub(r'\.', '_',anatsear)
10581
10814
  elif whichatlas == 'johns hopkins white matter':
10582
10815
  myext = 'JHU_wm'
10583
10816
  elif whichatlas == 'desikan-killiany-tourville':
@@ -10589,14 +10822,14 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10589
10822
  oglabelname=re.sub('bf', '',oglabelname)
10590
10823
  elif whichatlas == 'yeo_homotopic':
10591
10824
  myext = 'yeo'
10592
- if myext is None and verbose:
10825
+ if myext is None and verbose > 0 :
10593
10826
  if whichatlas is None:
10594
10827
  whichatlas='None'
10595
10828
  if anattoshow[k] is None:
10596
10829
  anattoshow[k]='None'
10597
10830
  print( "MYEXT " + anattoshow[k] + ' unfound ' + whichatlas )
10598
10831
  else:
10599
- if verbose:
10832
+ if verbose > 0 :
10600
10833
  print( "MYEXT " + myext )
10601
10834
 
10602
10835
  if myext == 'cit168lab':
@@ -10608,18 +10841,21 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10608
10841
  if j == "deep_cit168lab":
10609
10842
  j = 'deep_cit168'
10610
10843
  anattoshow[k] = anattoshow[k].replace(j, "")
10611
- if verbose:
10844
+ if verbose > 0:
10612
10845
  print( anattoshow[k] + " " + str( vals2viz ) )
10613
- myatlas = atlas[postfix.index(myext)]
10614
10846
  correctdescript = postdesc[postfix.index(myext)]
10615
10847
  locfilename = templateprefix + myext + '.nii.gz'
10616
- if verbose:
10848
+ if verbose > 0:
10617
10849
  print( locfilename )
10618
10850
  if myext == 'yeo':
10619
10851
  oglabelname=oglabelname.lower()
10620
10852
  oglabelname=re.sub("rsfmri_fcnxpro122_","",oglabelname)
10621
10853
  oglabelname=re.sub("rsfmri_fcnxpro129_","",oglabelname)
10622
10854
  oglabelname=re.sub("rsfmri_fcnxpro134_","",oglabelname)
10855
+ oglabelname=re.sub("rsfmri.fcnxpro122.","",oglabelname)
10856
+ oglabelname=re.sub("rsfmri.fcnxpro129.","",oglabelname)
10857
+ oglabelname=re.sub("rsfmri.fcnxpro134.","",oglabelname)
10858
+ oglabelname=re.sub("_",".",oglabelname)
10623
10859
  locfilename = "~/.antspymm/ppmi_template_500Parcels_Yeo2011_17Networks_2023_homotopic.nii.gz"
10624
10860
  atlasDescript = pd.read_csv(f"~/.antspymm/{correctdescript}.csv")
10625
10861
  atlasDescript.rename(columns={'SystemName': 'Description'}, inplace=True)
@@ -10636,15 +10872,25 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10636
10872
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("left_", "")
10637
10873
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("right_", "")
10638
10874
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("/",".")
10875
+ atlasDescript['Description'] = atlasDescript['Description'].str.replace("_",".")
10876
+ atlasDescript['Description'] = atlasDescript['Description'].str.replace(r'[()]', '', regex=True)
10877
+ atlasDescript['Description'] = atlasDescript['Description'].str.replace(r'\.\.', '.')
10639
10878
  if myext == 'JHU_wm':
10879
+ atlasDescript['Description'] = atlasDescript['Description'].str.replace("-", ".")
10880
+ atlasDescript['Description'] = atlasDescript['Description'].str.replace("jhu.icbm.labels.1mm", "")
10881
+ atlasDescript['Description'] = atlasDescript['Description'].str.replace("fronto-occipital", "frnt.occ")
10882
+ atlasDescript['Description'] = atlasDescript['Description'].str.replace("superior", "sup")
10640
10883
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("fa-", "")
10641
10884
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("-left-", "")
10642
10885
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("-right-", "")
10643
10886
  if myext == 'cerebellum':
10644
10887
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("l_", "")
10645
10888
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("r_", "")
10889
+ atlasDescript['Description'] = atlasDescript['Description'].str.replace("l.", "")
10890
+ atlasDescript['Description'] = atlasDescript['Description'].str.replace("r.", "")
10891
+ atlasDescript['Description'] = atlasDescript['Description'].str.replace("_",".")
10646
10892
 
10647
- if verbose:
10893
+ if verbose > 0:
10648
10894
  print( atlasDescript )
10649
10895
  oglabelname = oglabelname.lower()
10650
10896
  oglabelname = re.sub(" ", "_",oglabelname)
@@ -10657,15 +10903,31 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10657
10903
  oglabelname = re.sub("t1hier_thk_", "",oglabelname)
10658
10904
  oglabelname = re.sub("dktregions", "",oglabelname)
10659
10905
  oglabelname = re.sub("dktcortex", "",oglabelname)
10906
+
10907
+ oglabelname = re.sub(" ", ".",oglabelname)
10908
+ oglabelname = re.sub(".left.", ".",oglabelname)
10909
+ oglabelname = re.sub(".right.", ".",oglabelname)
10910
+ oglabelname = re.sub(".left", "",oglabelname)
10911
+ oglabelname = re.sub(".right", "",oglabelname)
10912
+ oglabelname = re.sub("t1hier.vol.", "",oglabelname)
10913
+ oglabelname = re.sub("t1hier.area.", "",oglabelname)
10914
+ oglabelname = re.sub("t1hier.thk.", "",oglabelname)
10915
+ oglabelname = re.sub("dktregions", "",oglabelname)
10916
+ oglabelname = re.sub("dktcortex", "",oglabelname)
10917
+ oglabelname=re.sub("brainstem","",oglabelname)
10660
10918
  if myext == 'JHU_wm':
10661
10919
  oglabelname = re.sub("dti_mean_fa.", "",oglabelname)
10662
10920
  oglabelname = re.sub("dti_mean_md.", "",oglabelname)
10921
+ oglabelname = re.sub("dti.mean.fa.", "",oglabelname)
10922
+ oglabelname = re.sub("dti.mean.md.", "",oglabelname)
10663
10923
  oglabelname = re.sub(".left.", "",oglabelname)
10664
10924
  oglabelname = re.sub(".right.", "",oglabelname)
10665
10925
  oglabelname = re.sub(".lravg.", "",oglabelname)
10666
10926
  oglabelname = re.sub(".asym.", "",oglabelname)
10927
+ oglabelname = re.sub(".jhu.icbm.labels.1mm", "",oglabelname)
10928
+ oglabelname = re.sub("superior", "sup",oglabelname)
10667
10929
 
10668
- if verbose:
10930
+ if verbose > 0:
10669
10931
  print("oglabelname " + oglabelname )
10670
10932
 
10671
10933
  if myext == 'cerebellum':
@@ -10674,7 +10936,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10674
10936
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("r_", "")
10675
10937
  oglabelname=re.sub("ravg","",oglabelname)
10676
10938
  oglabelname=re.sub("lavg","",oglabelname)
10677
- whichindex = atlasDescript.index[atlasDescript['Description'] == oglabelname].values[0]
10939
+ whichindex = atlasDescript.index[atlasDescript['Description'] == oglabelname].values
10678
10940
  else:
10679
10941
  if atlasDescript.empty:
10680
10942
  print("The DataFrame 'atlasDescript' is empty.")
@@ -10691,6 +10953,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10691
10953
  if myext == 'yeo':
10692
10954
  parts = re.findall(r'\D+', oglabelname)
10693
10955
  oglabelname = [part.replace('_', '') for part in parts if part.replace('_', '')]
10956
+ oglabelname = [part.replace('.', '') for part in parts if part.replace('.', '')]
10694
10957
  filtered_df = atlasDescript[atlasDescript['Description'].isin(oglabelname)]
10695
10958
  labelnums = filtered_df['Label'].tolist()
10696
10959
 
@@ -10699,7 +10962,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10699
10962
  addemiszero = ants.threshold_image(addem, 0, 0)
10700
10963
  temp = ants.image_read(locfilename)
10701
10964
  temp = ants.mask_image(temp, temp, level=labelnums, binarize=True)
10702
- if verbose:
10965
+ if verbose > 0:
10703
10966
  print("DEBUG")
10704
10967
  print( temp.sum() )
10705
10968
  print( labelnums )
@@ -10707,7 +10970,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10707
10970
  temp[addemiszero == 0] = 0
10708
10971
  addem = addem + temp
10709
10972
 
10710
- if verbose:
10973
+ if verbose > 0:
10711
10974
  print('Done Adding')
10712
10975
  for axx in axes:
10713
10976
  figfn=output_prefix+f"fig{col2viz}ax{axx}_py.jpg"
@@ -10726,7 +10989,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10726
10989
  ants.plot(edgeimgC, addemC, axis=axx, nslices=nslices, ncol=ncol,
10727
10990
  overlay_cmap=overlay_cmap, resample=False, overlay_alpha=1.0,
10728
10991
  filename=figfn, cbar=axx==axes[0], crop=True, black_bg=black_bg )
10729
- if verbose:
10992
+ if verbose > 0:
10730
10993
  print(f"{col2viz} done")
10731
10994
  if verbose:
10732
10995
  print("DONE brain map figures")
@@ -11421,7 +11684,7 @@ def renameit(df, old_col_name, new_col_name):
11421
11684
  df.rename(columns={old_col_name: new_col_name}, inplace=True)
11422
11685
 
11423
11686
 
11424
- def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
11687
+ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, mysep='-', verbose=True ):
11425
11688
  """
11426
11689
  Processes a quality control (QC) DataFrame to perform modality-specific matching and filtering based
11427
11690
  on predefined criteria, optimizing for minimal outliers and noise, and maximal signal-to-noise ratio (SNR),
@@ -11436,6 +11699,7 @@ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
11436
11699
  qc_dataframe : pandas.DataFrame
11437
11700
  The DataFrame containing QC metrics for different modalities and imaging data.
11438
11701
  fix_LRRL : bool, optional
11702
+ mysep : string, character such as - or _ the usual antspymm separator argument
11439
11703
 
11440
11704
  verbose : bool, optional
11441
11705
  If True, prints the progress and the shape of the DataFrame being processed in each step.
@@ -11453,17 +11717,19 @@ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
11453
11717
  The matched and filtered DataFrame after applying all QC scoring and matching operations across specified modalities.
11454
11718
 
11455
11719
  """
11720
+ qc_dataframe=remove_unwanted_columns( qc_dataframe )
11456
11721
  qc_dataframe['modality'] = qc_dataframe['modality'].replace(['DTIdwi', 'DTIb0'], 'DTI', regex=True)
11457
11722
  qc_dataframe['filename']=qc_dataframe['filename'].astype(str)
11458
11723
  qc_dataframe['ol_loop']=qc_dataframe['ol_loop'].astype(float)
11459
11724
  qc_dataframe['ol_lof']=qc_dataframe['ol_lof'].astype(float)
11460
11725
  qc_dataframe['ol_lof_decision']=qc_dataframe['ol_lof_decision'].astype(float)
11461
11726
  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']
11727
+ mmdf0 = best_mmm( qc_dataframe, 'T1w', outlier_column=outlier_column, mysep=mysep )['filt']
11728
+ fldf = best_mmm( qc_dataframe, 'T2Flair', outlier_column=outlier_column, mysep=mysep )['filt']
11729
+ nmdf = best_mmm( qc_dataframe, 'NM2DMT', outlier_column=outlier_column, mysep=mysep )['filt']
11730
+ rsdf = best_mmm( qc_dataframe, 'rsfMRI', outlier_column=outlier_column, mysep=mysep )['filt']
11731
+ dtdf = best_mmm( qc_dataframe, 'DTI', outlier_column=outlier_column, mysep=mysep )['filt']
11732
+ pfdf = best_mmm( qc_dataframe, 'perf', outlier_column=outlier_column, mysep=mysep )['filt']
11467
11733
 
11468
11734
  criteria = {'ol_loop': 'min', 'noise': 'min', 'snr': 'max', 'EVR': 'max', 'reflection_err':'min'}
11469
11735
  xcl = [ 'mrimfg', 'mrimodel','mriMagneticFieldStrength', 'dti_failed', 'rsf_failed', 'subjectID', 'date', 'subjectIDdate','repeat']
@@ -11471,6 +11737,9 @@ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
11471
11737
  mmdf, undffl = mm_match_by_qc_scoring(mmdf0, fldf, 'subjectIDdate', criteria,
11472
11738
  prefix='T2Flair_', exclude_columns=xcl )
11473
11739
 
11740
+ mmdf, undfpf = mm_match_by_qc_scoring(mmdf, pfdf, 'subjectIDdate', criteria,
11741
+ prefix='perf_', exclude_columns=xcl )
11742
+
11474
11743
  prefixes = ['NM1_', 'NM2_', 'NM3_', 'NM4_', 'NM5_', 'NM6_']
11475
11744
  undfmod = nmdf # Initialize 'undfmod' with 'nmdf' for the first iteration
11476
11745
  if undfmod is not None:
@@ -11489,27 +11758,29 @@ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
11489
11758
  criteria = {'ol_loop': 'min', 'noise': 'min', 'dti_bvalueMax':'min', 'dimt':'max'}
11490
11759
  prefixes = ['DTI1_', 'DTI2_', 'DTI3_'] # List of prefixes for each matching iteration
11491
11760
  undfmod = dtdf
11492
- if verbose:
11493
- print('start DT')
11494
- print( undfmod.shape )
11495
- for prefix in prefixes:
11496
- if undfmod.shape[0] > 50:
11497
- mmdf, undfmod = mm_match_by_qc_scoring(mmdf, undfmod, 'subjectIDdate', criteria, prefix=prefix, exclude_columns=xcl)
11498
- if verbose:
11499
- print( prefix )
11500
- print( undfmod.shape )
11761
+ if undfmod is not None:
11762
+ if verbose:
11763
+ print('start DT')
11764
+ print( undfmod.shape )
11765
+ for prefix in prefixes:
11766
+ if undfmod.shape[0] > 50:
11767
+ mmdf, undfmod = mm_match_by_qc_scoring(mmdf, undfmod, 'subjectIDdate', criteria, prefix=prefix, exclude_columns=xcl)
11768
+ if verbose:
11769
+ print( prefix )
11770
+ print( undfmod.shape )
11501
11771
 
11502
11772
  prefixes = ['rsf1_', 'rsf2_', 'rsf3_'] # List of prefixes for each matching iteration
11503
11773
  undfmod = rsdf # Initialize 'undfmod' with 'nmdf' for the first iteration
11504
- if verbose:
11505
- print('start rsf')
11506
- print( undfmod.shape )
11507
- for prefix in prefixes:
11508
- if undfmod.shape[0] > 50:
11509
- mmdf, undfmod = mm_match_by_qc_scoring(mmdf, undfmod, 'subjectIDdate', criteria, prefix=prefix, exclude_columns=xcl)
11510
- if verbose:
11511
- print( prefix )
11512
- print( undfmod.shape )
11774
+ if undfmod is not None:
11775
+ if verbose:
11776
+ print('start rsf')
11777
+ print( undfmod.shape )
11778
+ for prefix in prefixes:
11779
+ if undfmod.shape[0] > 50:
11780
+ mmdf, undfmod = mm_match_by_qc_scoring(mmdf, undfmod, 'subjectIDdate', criteria, prefix=prefix, exclude_columns=xcl)
11781
+ if verbose:
11782
+ print( prefix )
11783
+ print( undfmod.shape )
11513
11784
 
11514
11785
  if fix_LRRL:
11515
11786
  # mmdf=fix_LR_RL_stuff( mmdf, 'DTI1_filename', 'DTI2_filename', 'DTI1_dimt', 'DTI2_dimt')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: antspymm
3
- Version: 1.3.9
3
+ Version: 1.4.0
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,7 @@
1
+ antspymm/__init__.py,sha256=1fHqufHndrkJwz473av8qOf5-1xm5r-aKHuMAETGIiE,4462
2
+ antspymm/mm.py,sha256=mSizSFmJEisEuzVdBozOxKwg7GtxPPT299q6vOmOII0,495807
3
+ antspymm-1.4.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
4
+ antspymm-1.4.0.dist-info/METADATA,sha256=SXTcovYb7YSYn1K7xHKhwq9fE2QpJxGVfVv63VBFwk8,14866
5
+ antspymm-1.4.0.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
6
+ antspymm-1.4.0.dist-info/top_level.txt,sha256=iyD1sRhCKzfwKRJLq5ZUeV9xsv1cGQl8Ejp6QwXM1Zg,9
7
+ antspymm-1.4.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,7 +0,0 @@
1
- antspymm/__init__.py,sha256=1fHqufHndrkJwz473av8qOf5-1xm5r-aKHuMAETGIiE,4462
2
- antspymm/mm.py,sha256=m4l1VoltZnGqiKzLg1kOGRwx3INA87DkPZHJ4sU7cxE,481240
3
- antspymm-1.3.9.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
4
- antspymm-1.3.9.dist-info/METADATA,sha256=Ceg-uz1GUm1QPikt40iS9MkbF_7xJVgr4s-_1svpyr8,14866
5
- antspymm-1.3.9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
- antspymm-1.3.9.dist-info/top_level.txt,sha256=iyD1sRhCKzfwKRJLq5ZUeV9xsv1cGQl8Ejp6QwXM1Zg,9
7
- antspymm-1.3.9.dist-info/RECORD,,