docstr: Workflow of bundle analytics.
  
  Applies bundle shape similarity analysis on bundles of subjects and
  saves the results in a directory specified by ``out_dir``.
  
  Parameters
  ----------
  
  subject_folder : string
      Path to the input subject folder. This path may contain
      wildcards to process multiple inputs at once.
  
  clust_thr : variable float, optional
      list of bundle clustering thresholds used in QuickBundlesX.
  
  threshold : float, optional
      Bundle shape similarity threshold.
  
  out_dir : string, optional
      Output directory. (default current directory)
  
  References
  ----------
  .. [Chandio2020] Chandio, B.Q., Risacher, S.L., Pestilli, F.,
  Bullock, D., Yeh, FC., Koudoro, S., Rokem, A., Harezlak, J., and
  Garyfallidis, E. Bundle analytics, a computational framework for
  investigating the shapes and profiles of brain pathways across
  populations. Sci Rep 10, 17149 (2020)
docstr_tok: ["Workflow","of","bundle","analytics",".","Applies","bundle","shape","similarity","analysis","on","bundles","of","subjects","and","saves","the","results","in","a","directory","specified","by","``","out_dir","``",".","Parameters","--","--","--","--","--","subject_folder",":","string","Path","to","the","input","subject","folder",".","This","path","may","contain","wildcards","to","process","multiple","inputs","at","once",".","clust_thr",":","variable","float",",","optional","list","of","bundle","clustering","thresholds","used","in","QuickBundlesX",".","threshold",":","float",",","optional","Bundle","shape","similarity","threshold",".","out_dir",":","string",",","optional","Output","directory",".","(","default","current","directory",")","References","--","--","--","--","--","..","[","Chandio2020","]","Chandio",",","B.Q.",",","Risacher",",","S.L.",",","Pestilli",",","F.",",","Bullock",",","D.",",","Yeh",",","FC.",",","Koudoro",",","S.",",","Rokem",",","A.",",","Harezlak",",","J.",",","and","Garyfallidis",",","E.","Bundle","analytics",",","a","computational","framework","for","investigating","the","shapes","and","profiles","of","brain","pathways","across","populations",".","Sci","Rep","10",",","17149","(","2020",")"]
code: def run(
      self,
      subject_folder,
      clust_thr=(5, 3, 1.5),
      threshold=6,
      out_dir="",
  ):
      """Workflow of bundle analytics.
  
      Applies bundle shape similarity analysis on bundles of subjects and
      saves the results in a directory specified by ``out_dir``.
  
      Parameters
      ----------
  
      subject_folder : string
          Path to the input subject folder. This path may contain
          wildcards to process multiple inputs at once.
  
      clust_thr : variable float, optional
          list of bundle clustering thresholds used in QuickBundlesX.
  
      threshold : float, optional
          Bundle shape similarity threshold.
  
      out_dir : string, optional
          Output directory. (default current directory)
  
      References
      ----------
      .. [Chandio2020] Chandio, B.Q., Risacher, S.L., Pestilli, F.,
      Bullock, D., Yeh, FC., Koudoro, S., Rokem, A., Harezlak, J., and
      Garyfallidis, E. Bundle analytics, a computational framework for
      investigating the shapes and profiles of brain pathways across
      populations. Sci Rep 10, 17149 (2020)
  
      """
      rng = np.random.default_rng()
      all_subjects = []
      if os.path.isdir(subject_folder):
          groups = os.listdir(subject_folder)
          groups.sort()
      else:
          raise ValueError("Not a directory")
  
      for group in groups:
          if os.path.isdir(os.path.join(subject_folder, group)):
              subjects = os.listdir(os.path.join(subject_folder, group))
              subjects.sort()
              logging.info(
                  "first "
                  + str(len(subjects))
                  + " subjects in matrix belong to "
                  + group
                  + " group"
              )
  
              for sub in subjects:
                  dpath = os.path.join(subject_folder, group, sub)
                  if os.path.isdir(dpath):
                      all_subjects.append(dpath)
  
      N = len(all_subjects)
  
      bundles = os.listdir(os.path.join(all_subjects[0], "rec_bundles"))
      for bun in bundles:
          # bundle shape similarity matrix
          ba_matrix = np.zeros((N, N))
          i = 0
          logging.info(bun)
          for sub in all_subjects:
              j = 0
  
              bundle1 = load_tractogram(
                  os.path.join(sub, "rec_bundles", bun),
                  reference="same",
                  bbox_valid_check=False,
              ).streamlines
  
              for subi in all_subjects:
                  logging.info(subi)
  
                  bundle2 = load_tractogram(
                      os.path.join(subi, "rec_bundles", bun),
                      reference="same",
                      bbox_valid_check=False,
                  ).streamlines
  
                  ba_value = bundle_shape_similarity(
                      bundle1, bundle2, rng, clust_thr, threshold
                  )
  
                  ba_matrix[i][j] = ba_value
  
                  j += 1
              i += 1
          logging.info("saving BA score matrix")
          np.save(os.path.join(out_dir, bun[:-4] + ".npy"), ba_matrix)
  
          cmap = matplt.colormaps["Blues"]
          plt.title(bun[:-4])
          plt.imshow(ba_matrix, cmap=cmap)
          plt.colorbar()
          plt.clim(0, 1)
          plt.savefig(os.path.join(out_dir, "SM_" + bun[:-4]))
          plt.clf()
  
imports: import logging
  import numpy
  import os
  import json
  import warnings
  from time import time
  from scipy.ndimage import binary_dilation
  from dipy.utils.optpkg import optional_package
  from dipy.io import read_bvals_bvecs
  from dipy.io.image import load_nifti, save_nifti
  from dipy.core.gradients import gradient_table
  from dipy.reconst.dti import TensorModel
  from dipy.io.peaks import load_peaks
  from dipy.io.streamline import load_tractogram
  from dipy.segment.mask import segment_from_cfa
  from dipy.segment.mask import bounding_box
  from dipy.tracking.streamline import transform_streamlines
  from glob import glob
  from dipy.workflows.workflow import Workflow
  from dipy.segment.bundles import bundle_shape_similarity
  from dipy.stats.analysis import assignment_map
  from dipy.stats.analysis import anatomical_measures
  from dipy.stats.analysis import peak_values
label_desc: Use image node_id 2 for calling the BundleShapeAnalysis obj's underlying member method code with example usage: obj.run(subject_folder, clust_thr, threshold, out_dir) without return types