/ glassbrain_roi
glassbrain_roi
  1  #!/usr/bin/env python3
  2  # inspiration from https://github.com/nw-duncan/MRS-voxel-plot/
  3  # 20220324WF - init
  4  #  use nilearn glass brain to visualize slice position
  5  # colors from
  6  # https://matplotlib.org/3.5.1/tutorials/colors/colormaps.html
  7  # glass_brain
  8  # 'ortho', 'x', 'y', 'z', 'xz', 'yx', 'yz', 'l', 'r', 'lr', 'lzr', 'lyr', 'lzry', 'lyrz'.
  9  
 10  import sys
 11  import numpy as np
 12  import matplotlib.pyplot as plt
 13  import argparse
 14  import warnings
 15  warnings.simplefilter("ignore")
 16  import pandas as pd
 17  from nilearn import plotting, image
 18  
 19  
 20  def read_coords(fname='/Volumes/Hera/Projects/7TBrainMech/scripts/mri/MRSI_roi/roi_locations/labels_13MP20200207.txt'):
 21      labels = pd.read_csv(fname, sep="\t", header=None)
 22      # convert from LPI to "RAS+"
 23      centers = [[float(y) for y in x.split(" ")] for x in labels.iloc[:, 1]]
 24      # LPI to RAS+
 25      centers_ras = [(c[0], -1*c[1], c[2]) for c in centers]
 26      return centers_ras
 27  
 28  
 29  def roi_colors(n_roi=13):
 30      "here incase we want to change what roi gets what color"
 31      return plt.cm.get_cmap('tab20').colors[0:n_roi]
 32  
 33  
 34  def plot_rois(ax_roi, fname, roi_idxs=[1, 2, 7, 8, 9, 10], display_mode='xz'):
 35      centers_ras = read_coords(fname)
 36      colors = roi_colors(len(centers_ras))  # same colors despite subselect
 37      used_rois0 = [i-1 for i in roi_idxs]
 38      colors_used = [colors[i] for i in used_rois0]
 39      centers_used = [centers_ras[i] for i in used_rois0]
 40      # no lines between rois
 41      n_roi = len(centers_used)
 42      adjmat0 = np.zeros((n_roi, n_roi))
 43      plotting.plot_connectome(adjacency_matrix=adjmat0,
 44                               node_coords=centers_used,
 45                               annotate=False,
 46                               node_size=50, node_color=colors_used,
 47                               display_mode=display_mode, alpha=.5,
 48                               axes=ax_roi)
 49  
 50  def plot_nii(ax_roi, fname, display_mode='xz', digitize=True):
 51      """plot rois in nii. stat map needs its own function
 52      digitize takes eg roi mask/atlas with values 37,38 to 1,2"""
 53      # fname="/Volumes/Zeus/scratch/MNI_caez_ml_hpc37_38.nii.gz"
 54      #img = image.smooth_img(fname, 'fast')
 55      import nibabel as nib
 56      img = nib.load(fname)
 57      data = img.get_data()
 58  
 59      # if had nifti with roi vaules 7, 8 make them 1,2
 60      rois = np.unique(np.round(data))
 61      if digitize:
 62          dig = np.digitize(np.round(data), bins=rois)-1
 63          img = nib.Nifti1Image(dig, img.affine, img.header)
 64          rois = np.unique(dig)
 65  
 66      # TODO: what if we want 7 to always be the same color?
 67      # need to pass in maxroi?
 68      # TODO: tab20 not best choice? allow user to set
 69  
 70      plotting.plot_glass_brain(img,
 71                               cmap='tab20',
 72                               display_mode=display_mode, alpha=.5,
 73                               vmax=max(rois),
 74                               vmin=0,
 75                               axes=ax_roi)
 76  
 77  
 78  def main(args):
 79      "args display_mode save idx width height"
 80      # Plot the figure
 81      fig = plt.figure()
 82      fig.set_size_inches(args.width, args.height)
 83      ax_roi = plt.subplot(111)
 84      if args.roi_nii:
 85          plot_nii(ax_roi, args.roi_nii, args.display_mode)
 86      if not args.roi_txt in [None, "None", "", "NA"]:
 87          plot_rois(ax_roi, args.roi_txt, args.idx, args.display_mode)
 88      # display. save if not running interactively
 89      if hasattr(sys, 'ps1') or not args.save:
 90          plt.show()
 91      else:
 92          plt.savefig(args.save)
 93  
 94  
 95  if __name__ == "__main__":
 96      parser = argparse.ArgumentParser(description='')
 97      # USED_ROIS = [1, 2, 7, 8, 9, 10]
 98      parser.add_argument('idx', metavar='index', type=int, nargs='+',
 99                          help='1-based ROI indexes. probably want 1 2 7 8 9 10')
100      parser.add_argument('--save', metavar='save',
101                          help='save as', type=str, default=None)
102      parser.add_argument('--roi_txt', metavar='save',
103              help='ROI file with rows (LPI): "label:\tx y z"',
104              type=str, default=None)
105      parser.add_argument('--roi_nii', metavar='save',
106              help='ROI nifti file (unimplemented)',
107              type=str, default=None)
108      parser.add_argument('--width', type=float,
109                          dest='width',
110                          default=4,
111                          help="image width")
112      parser.add_argument('--height', type=float,
113                          dest='height',
114                          default=2,
115                          help="image height")
116      parser.add_argument('--display',  type=str,
117                          dest='display_mode',
118                          default='xz',
119                          help="'ortho', 'x', 'y', 'z', 'xz', 'yx', 'yz', 'l', 'r', 'lr', 'lzr', 'lyr', 'lzry', 'lyrz'.")
120  
121      args = parser.parse_args()
122      print(args)
123      main(args)
124  
125  # Local Variables:
126  # python-shell-interpreter: "ipython3"
127  # python-shell-interpreter-args: "-i --simple-prompt --InteractiveShell.display_page=True"
128  # End: