class_docstr: Class for stateful representation of collections of streamlines
  Object designed to be identical no matter the file format
  (trk, tck, vtk, fib, dpy). Facilitate transformation between space and
  data manipulation for each streamline / point.
class_docstr_tok: ["Class","for","stateful","representation","of","collections","of","streamlines","Object","designed","to","be","identical","no","matter","the","file","format","(","trk",",","tck",",","vtk",",","fib",",","dpy",")",".","Facilitate","transformation","between","space","and","data","manipulation","for","each","streamline","\/","point","."]
docstr: Create a strict, state-aware, robust tractogram
  
  Parameters
  ----------
  streamlines : list or ArraySequence
      Streamlines of the tractogram
  reference : Nifti or Trk filename, Nifti1Image or TrkFile,
      Nifti1Header, trk.header (dict) or another Stateful Tractogram
      Reference that provides the spatial attributes.
      Typically a nifti-related object from the native diffusion used for
      streamlines generation
  space : Enum (dipy.io.stateful_tractogram.Space)
      Current space in which the streamlines are (vox, voxmm or rasmm)
      After tracking the space is VOX, after loading with nibabel
      the space is RASMM
  origin : Enum (dipy.io.stateful_tractogram.Origin), optional
      Current origin in which the streamlines are (center or corner)
      After loading with nibabel the origin is CENTER
  data_per_point : dict, optional
      Dictionary in which each key has X items, each items has Y_i items
      X being the number of streamlines
      Y_i being the number of points on streamlines #i
  data_per_streamline : dict, optional
      Dictionary in which each key has X items
      X being the number of streamlines
  
  Notes
  -----
  Very important to respect the convention, verify that streamlines
  match the reference and are effectively in the right space.
  
  Any change to the number of streamlines, data_per_point or
  data_per_streamline requires particular verification.
  
  In a case of manipulation not allowed by this object, use Nibabel
  directly and be careful.
docstr_tok: ["Create","a","strict",",","state-aware",",","robust","tractogram","Parameters","--","--","--","--","--","streamlines",":","list","or","ArraySequence","Streamlines","of","the","tractogram","reference",":","Nifti","or","Trk","filename",",","Nifti1Image","or","TrkFile",",","Nifti1Header",",","trk.header","(","dict",")","or","another","Stateful","Tractogram","Reference","that","provides","the","spatial","attributes",".","Typically","a","nifti-related","object","from","the","native","diffusion","used","for","streamlines","generation","space",":","Enum","(","dipy.io.stateful_tractogram.Space",")","Current","space","in","which","the","streamlines","are","(","vox",",","voxmm","or","rasmm",")","After","tracking","the","space","is","VOX",",","after","loading","with","nibabel","the","space","is","RASMM","origin",":","Enum","(","dipy.io.stateful_tractogram.Origin",")",",","optional","Current","origin","in","which","the","streamlines","are","(","center","or","corner",")","After","loading","with","nibabel","the","origin","is","CENTER","data_per_point",":","dict",",","optional","Dictionary","in","which","each","key","has","X","items",",","each","items","has","Y_i","items","X","being","the","number","of","streamlines","Y_i","being","the","number","of","points","on","streamlines","#","i","data_per_streamline",":","dict",",","optional","Dictionary","in","which","each","key","has","X","items","X","being","the","number","of","streamlines","Notes","--","--","-","Very","important","to","respect","the","convention",",","verify","that","streamlines","match","the","reference","and","are","effectively","in","the","right","space",".","Any","change","to","the","number","of","streamlines",",","data_per_point","or","data_per_streamline","requires","particular","verification",".","In","a","case","of","manipulation","not","allowed","by","this","object",",","use","Nibabel","directly","and","be","careful","."]
code: def __init__(
      self,
      streamlines,
      reference,
      space,
      origin=Origin.NIFTI,
      data_per_point=None,
      data_per_streamline=None,
  ):
      """Create a strict, state-aware, robust tractogram
  
      Parameters
      ----------
      streamlines : list or ArraySequence
          Streamlines of the tractogram
      reference : Nifti or Trk filename, Nifti1Image or TrkFile,
          Nifti1Header, trk.header (dict) or another Stateful Tractogram
          Reference that provides the spatial attributes.
          Typically a nifti-related object from the native diffusion used for
          streamlines generation
      space : Enum (dipy.io.stateful_tractogram.Space)
          Current space in which the streamlines are (vox, voxmm or rasmm)
          After tracking the space is VOX, after loading with nibabel
          the space is RASMM
      origin : Enum (dipy.io.stateful_tractogram.Origin), optional
          Current origin in which the streamlines are (center or corner)
          After loading with nibabel the origin is CENTER
      data_per_point : dict, optional
          Dictionary in which each key has X items, each items has Y_i items
          X being the number of streamlines
          Y_i being the number of points on streamlines #i
      data_per_streamline : dict, optional
          Dictionary in which each key has X items
          X being the number of streamlines
  
      Notes
      -----
      Very important to respect the convention, verify that streamlines
      match the reference and are effectively in the right space.
  
      Any change to the number of streamlines, data_per_point or
      data_per_streamline requires particular verification.
  
      In a case of manipulation not allowed by this object, use Nibabel
      directly and be careful.
      """
      if data_per_point is None:
          data_per_point = {}
  
      if data_per_streamline is None:
          data_per_streamline = {}
  
      if isinstance(streamlines, Streamlines):
          streamlines = streamlines.copy()
  
      self._tractogram = Tractogram(
          streamlines,
          data_per_point=data_per_point,
          data_per_streamline=data_per_streamline,
      )
  
      if isinstance(reference, type(self)):
          logger.warning(
              "Using a StatefulTractogram as reference, this "
              "will copy only the space_attributes, not "
              "the state. The variables space and origin "
              "must be specified separately."
          )
          logger.warning(
              "To copy the state from another StatefulTractogram "
              "you may want to use the function from_sft "
              "(static function of the StatefulTractogram)."
          )
  
      if isinstance(reference, tuple) and len(reference) == 4:
          if is_reference_info_valid(*reference):
              space_attributes = reference
          else:
              raise TypeError(
                  "The provided space attributes are not "
                  "considered valid, please correct before "
                  "using them with StatefulTractogram."
              )
      else:
          space_attributes = get_reference_info(reference)
          if space_attributes is None:
              raise TypeError(
                  "Reference MUST be one of the following:\n"
                  "Nifti or Trk filename, Nifti1Image or "
                  "TrkFile, Nifti1Header or trk.header (dict)."
              )
  
      (
          self._affine,
          self._dimensions,
          self._voxel_sizes,
          self._voxel_order,
      ) = space_attributes
      self._inv_affine = np.linalg.inv(self._affine).astype(np.float32)
  
      if space not in Space:
          raise ValueError(
              "Space MUST be from Space enum, e.g Space.VOX."
          )
      self._space = space
  
      if origin not in Origin:
          raise ValueError(
              "Origin MUST be from Origin enum, " "e.g Origin.NIFTI."
          )
      self._origin = origin
  
      logger.debug(self)
  
imports: from bisect import bisect
  from collections import OrderedDict
  from copy import deepcopy
  import enum
  from itertools import product
  import logging
  from nibabel.affines import apply_affine
  from nibabel.streamlines.tractogram import Tractogram, PerArraySequenceDict, PerArrayDict
  import numpy
  from dipy.io.dpy import Streamlines
  from dipy.io.utils import get_reference_info, is_reference_info_valid, is_header_compatible
label_desc: Use image node_id 1 to create a new StatefulTractogram object  with example: obj = StatefulTractogram(streamlines, reference, space, origin, data_per_point, data_per_streamline)