docstr: A streamline generator
docstr_tok: ["A","streamline","generator"]
code: def _generate_tractogram(self):
      """A streamline generator"""
  
      # Get inverse transform (lin/offset) for seeds
      inv_A = np.linalg.inv(self.affine)
      lin = inv_A[:3, :3]
      offset = inv_A[:3, 3]
  
      F = np.empty((self.max_length + 1, 3), dtype=float)
      B = F.copy()
      for i, s in enumerate(self.seeds):
          s = np.dot(lin, s) + offset
          # Set the random seed in numpy, random and fast_numpy (lic.stdlib)
          if self.random_seed is not None:
              s_random_seed = hash(
                  np.abs((np.sum(s)) + self.random_seed)
              ) % (np.iinfo(np.uint32).max - 1)
              random.seed(s_random_seed)
              np.random.seed(s_random_seed)
              fast_numpy.seed(s_random_seed)
  
          if self.initial_directions is None:
              directions = self.direction_getter.initial_direction(s)
          else:
              # normalize the initial directions.
              # initial directions with norm 0 are removed.
              d_ns = np.linalg.norm(
                  self.initial_directions[i, :, :], axis=1
              )
              directions = (
                  self.initial_directions[i, d_ns > 0, :]
                  / d_ns[d_ns > 0, np.newaxis]
              )
  
          if len(directions) == 0 and self.return_all:
              # only the seed position
              if self.save_seeds:
                  yield [s], s
              else:
                  yield [s]
  
          if self.randomize_forward_direction:
              directions = [
                  d * random.choice([1, -1]) for d in directions
              ]
  
          directions = directions[: self.max_cross]
  
          for first_step in directions:
              stepsF = stepsB = 1
              stepsF, stream_status = self._tracker(s, first_step, F)
              if not (
                  self.return_all
                  or stream_status
                  in (
                      StreamlineStatus.ENDPOINT,
                      StreamlineStatus.OUTSIDEIMAGE,
                  )
              ):
                  continue
  
              if not self.unidirectional:
                  first_step = -first_step
                  if stepsF > 1:
                      # Use the opposite of the first selected orientation for
                      # the backward tracking segment
                      opposite_step = F[0] - F[1]
                      opposite_step_norm = np.linalg.norm(opposite_step)
                      if opposite_step_norm > 0:
                          first_step = (
                              opposite_step / opposite_step_norm
                          )
                  stepsB, stream_status = self._tracker(
                      s, first_step, B
                  )
                  if not (
                      self.return_all
                      or stream_status
                      in (
                          StreamlineStatus.ENDPOINT,
                          StreamlineStatus.OUTSIDEIMAGE,
                      )
                  ):
                      continue
  
              if stepsB == 1:
                  streamline = F[:stepsF].copy()
              else:
                  parts = (B[stepsB - 1 : 0 : -1], F[:stepsF])
                  streamline = np.concatenate(parts, axis=0)
  
              # move to the next streamline if only the seed position
              # and not return all
              len_sl = len(streamline)
              if (
                  len_sl >= self.min_length
                  and len_sl <= self.max_length
                  or self.return_all
              ):
                  if self.save_seeds:
                      yield streamline, s
                  else:
                      yield streamline
  
file_path: dipy/dipy/tracking/local_tracking.py
imports: import random
  from collections.abc import Iterable
  from warnings import warn
  import numpy
  from dipy.tracking.localtrack import local_tracker, pft_tracker
  from dipy.tracking.stopping_criterion import AnatomicalStoppingCriterion, StreamlineStatus
  from dipy.tracking import utils
  from dipy.utils import fast_numpy
label_desc: Use image node_id 5 for calling the LocalTracking obj's underlying member method code with example usage: obj._generate_tractogram() without return types