antspymm 1.3.8__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,
@@ -5046,8 +5130,18 @@ def neuromelanin( list_nm_images, t1, t1_head, t1lab, brain_stem_dilation=8,
5046
5130
  rrthresh = (rravg + k * rrstd)
5047
5131
  nmabovekthresh_mask = sn_mask * ants.threshold_image( simg, rrthresh, math.inf)
5048
5132
  snvolabovethresh = vol_element * nmabovekthresh_mask.sum()
5049
- snintmeanabovethresh = ( simg * nmabovekthresh_mask ).mean()
5050
- snintsumabovethresh = ( simg * nmabovekthresh_mask ).sum()
5133
+ snintmeanabovethresh = float( ( simg * nmabovekthresh_mask ).mean() )
5134
+ snintsumabovethresh = float( ( simg * nmabovekthresh_mask ).sum() )
5135
+
5136
+ k = 3.0
5137
+ rrthresh = (rravg + k * rrstd)
5138
+ nmabovekthresh_mask3 = sn_mask * ants.threshold_image( simg, rrthresh, math.inf)
5139
+ snvolabovethresh3 = vol_element * nmabovekthresh_mask3.sum()
5140
+
5141
+ k = 1.0
5142
+ rrthresh = (rravg + k * rrstd)
5143
+ nmabovekthresh_mask1 = sn_mask * ants.threshold_image( simg, rrthresh, math.inf)
5144
+ snvolabovethresh1 = vol_element * nmabovekthresh_mask1.sum()
5051
5145
 
5052
5146
  if verbose:
5053
5147
  print( "nm vol @2std above rrmean: " + str( snvolabovethresh ) )
@@ -5055,7 +5149,7 @@ def neuromelanin( list_nm_images, t1, t1_head, t1lab, brain_stem_dilation=8,
5055
5149
  print( "nm intsum @2std above rrmean: " + str( snintsumabovethresh ) )
5056
5150
  print( "nm done" )
5057
5151
 
5058
- return{
5152
+ return convert_np_in_dict( {
5059
5153
  'NM_avg' : nm_avg,
5060
5154
  'NM_avg_cropped' : nm_avg_cropped,
5061
5155
  'NM_labels': labels2nm,
@@ -5069,9 +5163,11 @@ def neuromelanin( list_nm_images, t1, t1_head, t1lab, brain_stem_dilation=8,
5069
5163
  'NM_avg_substantianigra' : snavg,
5070
5164
  'NM_std_substantianigra' : snstd,
5071
5165
  'NM_volume_substantianigra' : snvol,
5072
- 'NM_volume_substantianigra_above_k_thresh' : snvolabovethresh,
5073
- 'NM_intmean_substantianigra_above_k_thresh' : snintmeanabovethresh,
5074
- 'NM_intsum_substantianigra_above_k_thresh' : snintsumabovethresh,
5166
+ 'NM_volume_substantianigra_1std' : snvolabovethresh1,
5167
+ 'NM_volume_substantianigra_2std' : snvolabovethresh,
5168
+ 'NM_intmean_substantianigra_2std' : snintmeanabovethresh,
5169
+ 'NM_intsum_substantianigra_2std' : snintsumabovethresh,
5170
+ 'NM_volume_substantianigra_3std' : snvolabovethresh3,
5075
5171
  'NM_avg_refregion' : rravg,
5076
5172
  'NM_std_refregion' : rrstd,
5077
5173
  'NM_min' : nm_avg_cropped.min(),
@@ -5085,7 +5181,7 @@ def neuromelanin( list_nm_images, t1, t1_head, t1lab, brain_stem_dilation=8,
5085
5181
  'NM_substantianigra_z_coordinate' : sn_z,
5086
5182
  'NM_evr' : nm_evr,
5087
5183
  'NM_count': len( list_nm_images )
5088
- }
5184
+ } )
5089
5185
 
5090
5186
 
5091
5187
 
@@ -9316,7 +9412,9 @@ def quick_viz_mm_nrg(
9316
9412
  dtid, # date
9317
9413
  extract_brain=True,
9318
9414
  slice_factor = 0.55,
9319
- show_it = None, # output path
9415
+ post = False,
9416
+ original_sourcedir = None,
9417
+ filename = None, # output path
9320
9418
  verbose = True
9321
9419
  ):
9322
9420
  """
@@ -9324,7 +9422,7 @@ def quick_viz_mm_nrg(
9324
9422
 
9325
9423
  Args:
9326
9424
 
9327
- sourcedir (str): Root folder.
9425
+ sourcedir (str): Root folder for original data (if post=False) or processed data (post=True)
9328
9426
 
9329
9427
  projectid (str): Project name.
9330
9428
 
@@ -9335,73 +9433,114 @@ def quick_viz_mm_nrg(
9335
9433
  extract_brain (bool): If True, the function extracts the brain from the T1w image. Default is True.
9336
9434
 
9337
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.
9338
9438
 
9339
- 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)
9340
9442
 
9341
9443
  verbose (bool): If True, information will be printed while running the function. Default is True.
9342
9444
 
9343
9445
  Returns:
9344
- vizlist (list): List of image visualizations.
9446
+ None
9345
9447
 
9346
9448
  """
9347
9449
  iid='*'
9348
9450
  import glob as glob
9349
9451
  from os.path import exists
9350
9452
  import ants
9351
- ex_path = os.path.expanduser( "~/.antspyt1w/" )
9352
- ex_pathmm = os.path.expanduser( "~/.antspymm/" )
9353
- templatefn = ex_path + 'CIT168_T1w_700um_pad_adni.nii.gz'
9354
- if not exists( templatefn ):
9355
- print( "**missing files** => call get_data from latest antspyt1w and antspymm." )
9356
- antspyt1w.get_data( force_download=True )
9357
- get_data( force_download=True )
9358
9453
  temp = sourcedir.split( "/" )
9359
- splitCount = len( temp )
9360
- template = mm_read( templatefn ) # Read in template
9361
9454
  subjectrootpath = os.path.join(sourcedir, projectid, sid, dtid)
9362
- myimgsInput = glob.glob( subjectrootpath+"/*" )
9363
- myimgsInput.sort( )
9364
9455
  if verbose:
9365
- print( myimgsInput )
9456
+ print( 'subjectrootpath' )
9457
+ print( subjectrootpath )
9366
9458
  t1_search_path = os.path.join(subjectrootpath, "T1w", "*", "*nii.gz")
9367
9459
  if verbose:
9368
9460
  print(f"t1 search path: {t1_search_path}")
9369
9461
  t1fn = glob.glob(t1_search_path)
9370
- t1fn.sort()
9371
9462
  if len( t1fn ) < 1:
9372
9463
  raise ValueError('quick_viz_mm_nrg cannot find the T1w @ ' + subjectrootpath )
9373
- t1fn = t1fn[0]
9374
- t1 = mm_read( t1fn )
9375
- nimages = len(myimgsInput)
9376
9464
  vizlist=[]
9377
- if verbose:
9378
- print( " we have : " + str(nimages) + " modalities. will visualize T1 NM rsfMRI DTIB0 DTIDWI FLAIR")
9379
- # nrg_modality_list = ["T1w", "NM2DMT", "rsfMRI","rsfMRI_LR","rsfMRI_RL","DTI","DTI_LR", "T2Flair" ],
9380
- 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' ]
9381
9469
  for nrgNum in [0,1,2,3,4,5]:
9470
+ underlay = None
9382
9471
  overmodX = nrg_modality_list[nrgNum]
9383
- if overmodX == 'T1w':
9472
+ if 'T1w' in overmodX :
9384
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 )
9385
9485
  myimgsr = glob.glob(mod_search_path)
9386
9486
  if len( myimgsr ) == 0:
9387
9487
  if verbose:
9388
9488
  print("No t1 images: " + sid + dtid )
9389
9489
  return None
9390
- myimgsr.sort()
9391
- myimgsr=myimgsr[0]
9490
+ myimgsr=find_most_recent_file( myimgsr )[0]
9392
9491
  vimg=ants.image_read( myimgsr )
9393
- 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':
9394
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")
9395
9535
  myimgsr = glob.glob(mod_search_path)
9396
9536
  if len( myimgsr ) > 0:
9397
- myimgsr.sort()
9398
- myimgsr=myimgsr[0]
9537
+ myimgsr=find_most_recent_file( myimgsr )[0]
9399
9538
  vimg=ants.image_read( myimgsr )
9400
9539
  else:
9401
9540
  if verbose:
9402
9541
  print("No " + overmodX)
9403
- vimg = noizimg
9404
- elif overmodX == 'DWI2':
9542
+ vimg = noizimg.clone()
9543
+ elif overmodX == 'DTI2':
9405
9544
  mod_search_path = os.path.join(subjectrootpath, 'DTI*', "*", "*nii.gz")
9406
9545
  myimgsr = glob.glob(mod_search_path)
9407
9546
  if len( myimgsr ) > 0:
@@ -9411,12 +9550,13 @@ def quick_viz_mm_nrg(
9411
9550
  else:
9412
9551
  if verbose:
9413
9552
  print("No " + overmodX)
9414
- vimg = noizimg
9553
+ vimg = noizimg.clone()
9415
9554
  elif overmodX == 'NM2DMT':
9416
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" )
9417
9558
  myimgsr = glob.glob(mod_search_path)
9418
9559
  if len( myimgsr ) > 0:
9419
- myimgsr.sort()
9420
9560
  myimgsr0=myimgsr[0]
9421
9561
  vimg=ants.image_read( myimgsr0 )
9422
9562
  for k in range(1,len(myimgsr)):
@@ -9425,55 +9565,109 @@ def quick_viz_mm_nrg(
9425
9565
  else:
9426
9566
  if verbose:
9427
9567
  print("No " + overmodX)
9428
- vimg = noizimg
9568
+ vimg = noizimg.clone()
9429
9569
  elif overmodX == 'rsfMRI':
9430
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 )
9431
9581
  myimgsr = glob.glob(mod_search_path)
9432
9582
  if len( myimgsr ) > 0:
9433
- myimgsr.sort()
9434
- myimgsr=myimgsr[0]
9583
+ myimgsr=find_most_recent_file( myimgsr )[0]
9435
9584
  vimg=mm_read_to_3d( myimgsr )
9436
9585
  else:
9437
9586
  if verbose:
9438
9587
  print("No " + overmodX)
9439
- 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()
9440
9601
  else :
9602
+ if verbose:
9603
+ print("Something else here")
9441
9604
  mod_search_path = os.path.join(subjectrootpath, overmodX, "*", "*nii.gz")
9442
9605
  myimgsr = glob.glob(mod_search_path)
9606
+ if post:
9607
+ myimgsr=[]
9443
9608
  if len( myimgsr ) > 0:
9444
- myimgsr.sort()
9445
- myimgsr=myimgsr[0]
9609
+ myimgsr=find_most_recent_file( myimgsr )[0]
9446
9610
  vimg=ants.image_read( myimgsr )
9447
9611
  else:
9448
9612
  if verbose:
9449
9613
  print("No " + overmodX)
9450
9614
  vimg = noizimg
9451
9615
  if True:
9452
- if extract_brain and overmodX == 'T1w':
9616
+ if extract_brain and overmodX == 'T1w' and post == False:
9453
9617
  vimg = vimg * antspyt1w.brain_extraction(vimg)
9454
9618
  if verbose:
9455
9619
  print(f"modality search path: {myimgsr}" + " num: " + str(nrgNum))
9456
- if len( vimg.shape ) == 4 and ( overmodX == "DWI2" ):
9620
+ if vimg.dimension == 4 and ( overmodX == "DTI2" ):
9457
9621
  ttb0, ttdw=get_average_dwi_b0(vimg)
9458
9622
  vimg = ttdw
9459
- elif len( vimg.shape ) == 4 and overmodX == "DWI1":
9623
+ elif vimg.dimension == 4 and overmodX == "DTI":
9460
9624
  ttb0, ttdw=get_average_dwi_b0(vimg)
9461
9625
  vimg = ttb0
9462
- elif len( vimg.shape ) == 4 :
9626
+ elif vimg.dimension == 4 :
9463
9627
  vimg=ants.get_average_of_timeseries(vimg)
9464
9628
  msk=ants.get_mask(vimg)
9465
- vimg=ants.crop_image(vimg,msk)
9466
- 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:
9467
9636
  refimg=ants.image_clone( vimg )
9468
9637
  noizimg = ants.add_noise_to_image( refimg*0, 'additivegaussian', [100,1] )
9469
9638
  vizlist.append( vimg )
9639
+ undlist.append( underlay )
9470
9640
  else:
9471
- vimg = ants.resample_image_to_target( vimg, refimg )
9472
9641
  vimg = ants.iMath( vimg, 'TruncateIntensity',0.01,0.98)
9473
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 )
9474
9666
 
9475
- listlen = len( vizlist )
9476
- vizlist = np.asarray( vizlist )
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 )
9477
9671
  if show_it is not None:
9478
9672
  filenameout=None
9479
9673
  if verbose:
@@ -9485,7 +9679,7 @@ def quick_viz_mm_nrg(
9485
9679
  filenameout=show_it+'_ax'+str(int(a))+'_sl'+str(n)+'.png'
9486
9680
  if verbose:
9487
9681
  print( filenameout )
9488
- 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 )
9489
9683
  if verbose:
9490
9684
  print("viz complete.")
9491
9685
  return vizlist
@@ -9596,6 +9790,10 @@ def blind_image_assessment(
9596
9790
  modality='unknown'
9597
9791
  if "rsfMRI" in image_filename:
9598
9792
  modality='rsfMRI'
9793
+ elif "perf" in image_filename:
9794
+ modality='perf'
9795
+ elif "DTI" in image_filename:
9796
+ modality='DTI'
9599
9797
  elif "T1w" in image_filename:
9600
9798
  modality='T1w'
9601
9799
  elif "T2Flair" in image_filename:
@@ -10011,7 +10209,7 @@ def remove_volumes_from_timeseries(time_series, volumes_to_remove):
10011
10209
  :param volumes_to_remove: List of volume indices to remove.
10012
10210
  :return: ANTsImage with specified volumes removed.
10013
10211
  """
10014
- if not isinstance(time_series, ants.ANTsImage):
10212
+ if not isinstance(time_series, ants.core.ants_image.ANTsImage):
10015
10213
  raise ValueError("time_series must be an ANTsImage.")
10016
10214
 
10017
10215
  if time_series.dimension != 4:
@@ -10049,7 +10247,7 @@ def impute_timeseries(time_series, volumes_to_impute, method='linear', verbose=F
10049
10247
  :param verbose: boolean
10050
10248
  :return: ANTsImage with specified volumes imputed.
10051
10249
  """
10052
- if not isinstance(time_series, ants.ANTsImage):
10250
+ if not isinstance(time_series, ants.core.ants_image.ANTsImage):
10053
10251
  raise ValueError("time_series must be an ANTsImage.")
10054
10252
 
10055
10253
  if time_series.dimension != 4:
@@ -10456,7 +10654,7 @@ def novelty_detection_quantile(df_train, df_test):
10456
10654
  myqs[mykey] = abs( temp - 0.5 ) / 0.5
10457
10655
  return myqs
10458
10656
 
10459
- 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 ):
10460
10658
  """
10461
10659
  Create figures based on statistical data and an underlying brain image.
10462
10660
 
@@ -10492,6 +10690,9 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10492
10690
  # Read the data dictionary from a CSV file
10493
10691
  mydict = pd.read_csv(data_dictionary_path)
10494
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","")
10495
10696
 
10496
10697
  statistical_df['anat'] = statistical_df['anat'].str.replace("_", ".", regex=True)
10497
10698
 
@@ -10504,23 +10705,34 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10504
10705
  postfix = ['bf', 'cit168lab', 'mtl', 'cerebellum', 'dkt_cortex','brainstem','JHU_wm','yeo']
10505
10706
  atlas = ['BF', 'CIT168', 'MTL', 'TustisonCobra', 'desikan-killiany-tourville','brainstem','JHU_wm','yeo']
10506
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']
10507
- statdf = pd.DataFrame({'img': postfix, 'atlas': atlas, 'csvdescript': postdesc})
10508
10708
  templateprefix = '~/.antspymm/PPMI_template0_'
10509
10709
  # Iterate through columns and create figures
10510
10710
  col2viz = 'values'
10511
10711
  if True:
10512
10712
  anattoshow = zz['anat'].unique()
10513
- if verbose:
10713
+ if verbose > 0:
10514
10714
  print(col2viz)
10515
10715
  print(anattoshow)
10516
10716
  # Rest of your code for figure creation goes here...
10517
10717
  addem = edgeimg * 0
10518
10718
  for k in range(len(anattoshow)):
10519
- if verbose:
10719
+ if verbose > 0 :
10520
10720
  print(str(k) + " " + anattoshow[k] )
10521
10721
  mysub = zz[zz['anat'].str.contains(anattoshow[k])]
10522
- 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)
10523
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)
10524
10736
  anatsear=re.sub("t1.volasym","",anatsear)
10525
10737
  anatsear=re.sub("t1.thkasym","",anatsear)
10526
10738
  anatsear=re.sub("t1.areaasym","",anatsear)
@@ -10534,25 +10746,57 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10534
10746
  anatsear=re.sub("dti.md","",anatsear)
10535
10747
  anatsear=re.sub("dti.mean.md.","",anatsear)
10536
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)
10537
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)
10538
10776
  atlassearch = mydict['tidynames'].str.contains(anatsear)
10539
- if verbose:
10777
+ if atlassearch.sum() == 0:
10778
+ atlassearch = mydict2['tidynames'].str.contains(anatsear)
10779
+ if verbose > 0 :
10540
10780
  print( " anatsear " + anatsear + " atlassearch " )
10541
10781
  if atlassearch.sum() > 0:
10542
10782
  whichatlas = mydict[atlassearch]['Atlas'].iloc[0]
10543
10783
  oglabelname = mydict[atlassearch]['Label'].iloc[0]
10784
+ oglabelname=re.sub("_",".",oglabelname)
10785
+ oglabelname=re.sub(r'\.\.','.',oglabelname)
10544
10786
  else:
10545
10787
  print(anatsear)
10546
10788
  oglabelname='unknown'
10547
10789
  whichatlas=None
10548
- if verbose:
10790
+ if verbose > 0:
10549
10791
  print("oglabelname " + oglabelname + " whichatlas " + str(whichatlas) )
10550
10792
  vals2viz = mysub[col2viz].agg(['min', 'max'])
10551
10793
  vals2viz = vals2viz[abs(vals2viz).idxmax()]
10552
10794
  myext = None
10553
- 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] :
10554
10798
  myext = 'dkt_cortex'
10555
- elif 'cit168' in anattoshow[k] or whichatlas == 'CIT168':
10799
+ elif ('cit168' in anattoshow[k] or whichatlas == 'CIT168') and not 'brainstem' in anattoshow[k]:
10556
10800
  myext = 'cit168lab'
10557
10801
  elif 'mtl' in anattoshow[k]:
10558
10802
  myext = 'mtl'
@@ -10565,7 +10809,8 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10565
10809
  myext = 'brainstem'
10566
10810
  elif any(item in anattoshow[k] for item in ['nbm', 'bf']):
10567
10811
  myext = 'bf'
10568
- oglabelname=re.sub(r'\.', '_',anatsear)
10812
+ oglabelname=re.sub('bf', '',oglabelname)
10813
+ # oglabelname=re.sub(r'\.', '_',anatsear)
10569
10814
  elif whichatlas == 'johns hopkins white matter':
10570
10815
  myext = 'JHU_wm'
10571
10816
  elif whichatlas == 'desikan-killiany-tourville':
@@ -10577,14 +10822,14 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10577
10822
  oglabelname=re.sub('bf', '',oglabelname)
10578
10823
  elif whichatlas == 'yeo_homotopic':
10579
10824
  myext = 'yeo'
10580
- if myext is None and verbose:
10825
+ if myext is None and verbose > 0 :
10581
10826
  if whichatlas is None:
10582
10827
  whichatlas='None'
10583
10828
  if anattoshow[k] is None:
10584
10829
  anattoshow[k]='None'
10585
10830
  print( "MYEXT " + anattoshow[k] + ' unfound ' + whichatlas )
10586
10831
  else:
10587
- if verbose:
10832
+ if verbose > 0 :
10588
10833
  print( "MYEXT " + myext )
10589
10834
 
10590
10835
  if myext == 'cit168lab':
@@ -10596,18 +10841,21 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10596
10841
  if j == "deep_cit168lab":
10597
10842
  j = 'deep_cit168'
10598
10843
  anattoshow[k] = anattoshow[k].replace(j, "")
10599
- if verbose:
10844
+ if verbose > 0:
10600
10845
  print( anattoshow[k] + " " + str( vals2viz ) )
10601
- myatlas = atlas[postfix.index(myext)]
10602
10846
  correctdescript = postdesc[postfix.index(myext)]
10603
10847
  locfilename = templateprefix + myext + '.nii.gz'
10604
- if verbose:
10848
+ if verbose > 0:
10605
10849
  print( locfilename )
10606
10850
  if myext == 'yeo':
10607
10851
  oglabelname=oglabelname.lower()
10608
10852
  oglabelname=re.sub("rsfmri_fcnxpro122_","",oglabelname)
10609
10853
  oglabelname=re.sub("rsfmri_fcnxpro129_","",oglabelname)
10610
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)
10611
10859
  locfilename = "~/.antspymm/ppmi_template_500Parcels_Yeo2011_17Networks_2023_homotopic.nii.gz"
10612
10860
  atlasDescript = pd.read_csv(f"~/.antspymm/{correctdescript}.csv")
10613
10861
  atlasDescript.rename(columns={'SystemName': 'Description'}, inplace=True)
@@ -10624,15 +10872,25 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10624
10872
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("left_", "")
10625
10873
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("right_", "")
10626
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'\.\.', '.')
10627
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")
10628
10883
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("fa-", "")
10629
10884
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("-left-", "")
10630
10885
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("-right-", "")
10631
10886
  if myext == 'cerebellum':
10632
10887
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("l_", "")
10633
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("_",".")
10634
10892
 
10635
- if verbose:
10893
+ if verbose > 0:
10636
10894
  print( atlasDescript )
10637
10895
  oglabelname = oglabelname.lower()
10638
10896
  oglabelname = re.sub(" ", "_",oglabelname)
@@ -10645,15 +10903,31 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10645
10903
  oglabelname = re.sub("t1hier_thk_", "",oglabelname)
10646
10904
  oglabelname = re.sub("dktregions", "",oglabelname)
10647
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)
10648
10918
  if myext == 'JHU_wm':
10649
10919
  oglabelname = re.sub("dti_mean_fa.", "",oglabelname)
10650
10920
  oglabelname = re.sub("dti_mean_md.", "",oglabelname)
10921
+ oglabelname = re.sub("dti.mean.fa.", "",oglabelname)
10922
+ oglabelname = re.sub("dti.mean.md.", "",oglabelname)
10651
10923
  oglabelname = re.sub(".left.", "",oglabelname)
10652
10924
  oglabelname = re.sub(".right.", "",oglabelname)
10653
10925
  oglabelname = re.sub(".lravg.", "",oglabelname)
10654
10926
  oglabelname = re.sub(".asym.", "",oglabelname)
10927
+ oglabelname = re.sub(".jhu.icbm.labels.1mm", "",oglabelname)
10928
+ oglabelname = re.sub("superior", "sup",oglabelname)
10655
10929
 
10656
- if verbose:
10930
+ if verbose > 0:
10657
10931
  print("oglabelname " + oglabelname )
10658
10932
 
10659
10933
  if myext == 'cerebellum':
@@ -10662,7 +10936,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10662
10936
  atlasDescript['Description'] = atlasDescript['Description'].str.replace("r_", "")
10663
10937
  oglabelname=re.sub("ravg","",oglabelname)
10664
10938
  oglabelname=re.sub("lavg","",oglabelname)
10665
- whichindex = atlasDescript.index[atlasDescript['Description'] == oglabelname].values[0]
10939
+ whichindex = atlasDescript.index[atlasDescript['Description'] == oglabelname].values
10666
10940
  else:
10667
10941
  if atlasDescript.empty:
10668
10942
  print("The DataFrame 'atlasDescript' is empty.")
@@ -10679,6 +10953,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10679
10953
  if myext == 'yeo':
10680
10954
  parts = re.findall(r'\D+', oglabelname)
10681
10955
  oglabelname = [part.replace('_', '') for part in parts if part.replace('_', '')]
10956
+ oglabelname = [part.replace('.', '') for part in parts if part.replace('.', '')]
10682
10957
  filtered_df = atlasDescript[atlasDescript['Description'].isin(oglabelname)]
10683
10958
  labelnums = filtered_df['Label'].tolist()
10684
10959
 
@@ -10687,7 +10962,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10687
10962
  addemiszero = ants.threshold_image(addem, 0, 0)
10688
10963
  temp = ants.image_read(locfilename)
10689
10964
  temp = ants.mask_image(temp, temp, level=labelnums, binarize=True)
10690
- if verbose:
10965
+ if verbose > 0:
10691
10966
  print("DEBUG")
10692
10967
  print( temp.sum() )
10693
10968
  print( labelnums )
@@ -10695,7 +10970,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10695
10970
  temp[addemiszero == 0] = 0
10696
10971
  addem = addem + temp
10697
10972
 
10698
- if verbose:
10973
+ if verbose > 0:
10699
10974
  print('Done Adding')
10700
10975
  for axx in axes:
10701
10976
  figfn=output_prefix+f"fig{col2viz}ax{axx}_py.jpg"
@@ -10714,7 +10989,7 @@ def brainmap_figure(statistical_df, data_dictionary_path, output_prefix, brain_i
10714
10989
  ants.plot(edgeimgC, addemC, axis=axx, nslices=nslices, ncol=ncol,
10715
10990
  overlay_cmap=overlay_cmap, resample=False, overlay_alpha=1.0,
10716
10991
  filename=figfn, cbar=axx==axes[0], crop=True, black_bg=black_bg )
10717
- if verbose:
10992
+ if verbose > 0:
10718
10993
  print(f"{col2viz} done")
10719
10994
  if verbose:
10720
10995
  print("DONE brain map figures")
@@ -11409,7 +11684,7 @@ def renameit(df, old_col_name, new_col_name):
11409
11684
  df.rename(columns={old_col_name: new_col_name}, inplace=True)
11410
11685
 
11411
11686
 
11412
- 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 ):
11413
11688
  """
11414
11689
  Processes a quality control (QC) DataFrame to perform modality-specific matching and filtering based
11415
11690
  on predefined criteria, optimizing for minimal outliers and noise, and maximal signal-to-noise ratio (SNR),
@@ -11424,6 +11699,7 @@ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
11424
11699
  qc_dataframe : pandas.DataFrame
11425
11700
  The DataFrame containing QC metrics for different modalities and imaging data.
11426
11701
  fix_LRRL : bool, optional
11702
+ mysep : string, character such as - or _ the usual antspymm separator argument
11427
11703
 
11428
11704
  verbose : bool, optional
11429
11705
  If True, prints the progress and the shape of the DataFrame being processed in each step.
@@ -11441,17 +11717,19 @@ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
11441
11717
  The matched and filtered DataFrame after applying all QC scoring and matching operations across specified modalities.
11442
11718
 
11443
11719
  """
11720
+ qc_dataframe=remove_unwanted_columns( qc_dataframe )
11444
11721
  qc_dataframe['modality'] = qc_dataframe['modality'].replace(['DTIdwi', 'DTIb0'], 'DTI', regex=True)
11445
11722
  qc_dataframe['filename']=qc_dataframe['filename'].astype(str)
11446
11723
  qc_dataframe['ol_loop']=qc_dataframe['ol_loop'].astype(float)
11447
11724
  qc_dataframe['ol_lof']=qc_dataframe['ol_lof'].astype(float)
11448
11725
  qc_dataframe['ol_lof_decision']=qc_dataframe['ol_lof_decision'].astype(float)
11449
11726
  outlier_column='ol_loop'
11450
- mmdf0 = best_mmm( qc_dataframe, 'T1w', outlier_column=outlier_column )['filt']
11451
- fldf = best_mmm( qc_dataframe, 'T2Flair', outlier_column=outlier_column )['filt']
11452
- nmdf = best_mmm( qc_dataframe, 'NM2DMT', outlier_column=outlier_column )['filt']
11453
- rsdf = best_mmm( qc_dataframe, 'rsfMRI', outlier_column=outlier_column )['filt']
11454
- 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']
11455
11733
 
11456
11734
  criteria = {'ol_loop': 'min', 'noise': 'min', 'snr': 'max', 'EVR': 'max', 'reflection_err':'min'}
11457
11735
  xcl = [ 'mrimfg', 'mrimodel','mriMagneticFieldStrength', 'dti_failed', 'rsf_failed', 'subjectID', 'date', 'subjectIDdate','repeat']
@@ -11459,6 +11737,9 @@ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
11459
11737
  mmdf, undffl = mm_match_by_qc_scoring(mmdf0, fldf, 'subjectIDdate', criteria,
11460
11738
  prefix='T2Flair_', exclude_columns=xcl )
11461
11739
 
11740
+ mmdf, undfpf = mm_match_by_qc_scoring(mmdf, pfdf, 'subjectIDdate', criteria,
11741
+ prefix='perf_', exclude_columns=xcl )
11742
+
11462
11743
  prefixes = ['NM1_', 'NM2_', 'NM3_', 'NM4_', 'NM5_', 'NM6_']
11463
11744
  undfmod = nmdf # Initialize 'undfmod' with 'nmdf' for the first iteration
11464
11745
  if undfmod is not None:
@@ -11477,27 +11758,29 @@ def mm_match_by_qc_scoring_all( qc_dataframe, fix_LRRL=True, verbose=True ):
11477
11758
  criteria = {'ol_loop': 'min', 'noise': 'min', 'dti_bvalueMax':'min', 'dimt':'max'}
11478
11759
  prefixes = ['DTI1_', 'DTI2_', 'DTI3_'] # List of prefixes for each matching iteration
11479
11760
  undfmod = dtdf
11480
- if verbose:
11481
- print('start DT')
11482
- print( undfmod.shape )
11483
- for prefix in prefixes:
11484
- if undfmod.shape[0] > 50:
11485
- mmdf, undfmod = mm_match_by_qc_scoring(mmdf, undfmod, 'subjectIDdate', criteria, prefix=prefix, exclude_columns=xcl)
11486
- if verbose:
11487
- print( prefix )
11488
- 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 )
11489
11771
 
11490
11772
  prefixes = ['rsf1_', 'rsf2_', 'rsf3_'] # List of prefixes for each matching iteration
11491
11773
  undfmod = rsdf # Initialize 'undfmod' with 'nmdf' for the first iteration
11492
- if verbose:
11493
- print('start rsf')
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 )
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 )
11501
11784
 
11502
11785
  if fix_LRRL:
11503
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.8
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=72293DXAlbeKXj75j5d_SYeiH2uKK9-XnpZh6YLIpwY,480752
3
- antspymm-1.3.8.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
4
- antspymm-1.3.8.dist-info/METADATA,sha256=P1Q9RDLvhqAQalZfVewHpbbvTPzsYBo91cTpBtGrOSw,14866
5
- antspymm-1.3.8.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
- antspymm-1.3.8.dist-info/top_level.txt,sha256=iyD1sRhCKzfwKRJLq5ZUeV9xsv1cGQl8Ejp6QwXM1Zg,9
7
- antspymm-1.3.8.dist-info/RECORD,,