class_docstr: Synchronize features to beats.
  
  First, divide a beat interval into `beat_subdivision` divisions. Then
  summarise all features that fall into one subdivision. If no feature value
  for a subdivision is found, it is set to 0.
  
  Parameters
  ----------
  beat_subdivisions : int
      Number of subdivisions a beat is divided into.
  fps : float
      Frames per second.
class_docstr_tok: ["Synchronize","features","to","beats",".","First",",","divide","a","beat","interval","into","`","beat_subdivision","`","divisions",".","Then","summarise","all","features","that","fall","into","one","subdivision",".","If","no","feature","value","for","a","subdivision","is","found",",","it","is","set","to","0",".","Parameters","--","--","--","--","--","beat_subdivisions",":","int","Number","of","subdivisions","a","beat","is","divided","into",".","fps",":","float","Frames","per","second","."]
docstr: Synchronize features to beats.
  
  Average all feature values that fall into a window of beat duration /
  beat subdivisions, centered on the beat positions or interpolated
  subdivisions, starting with the first beat.
  
  Parameters
  ----------
  data : tuple (features, beats)
      Tuple of two numpy arrays, the first containing features to be
      synchronized and second the beat times.
  
  Returns
  -------
  numpy array (num beats - 1, beat subdivisions, features dim.)
      Beat synchronous features.
code: def process(self, data, **kwargs):
      """
      Synchronize features to beats.
  
      Average all feature values that fall into a window of beat duration /
      beat subdivisions, centered on the beat positions or interpolated
      subdivisions, starting with the first beat.
  
      Parameters
      ----------
      data : tuple (features, beats)
          Tuple of two numpy arrays, the first containing features to be
          synchronized and second the beat times.
  
      Returns
      -------
      numpy array (num beats - 1, beat subdivisions, features dim.)
          Beat synchronous features.
  
      """
      features, beats = data
      # no beats, return immediately
      if beats.size == 0:
          return np.array([]), np.array([])
      # beats can be 1D (only beat times) or 2D (times, position inside bar)
      if beats.ndim > 1:
          beats = beats[:, 0]
      # trim beat sequence
      while (float(len(features)) / self.fps) < beats[-1]:
          beats = beats[:-1]
          warnings.warn("Beat sequence too long compared to features.")
      # number of beats
      num_beats = len(beats)
      # feature dimension (make sure features are 2D)
      features = np.array(features.T, copy=False, ndmin=2).T
      feat_dim = features.shape[-1]
      # init a 3D feature aggregation array
      beat_features = np.zeros(
          (num_beats - 1, self.beat_subdivisions, feat_dim)
      )
      # start first beat 20ms before actual annotation
      beat_start = int(max(0, np.floor((beats[0] - 0.02) * self.fps)))
      # TODO: speed this up, could probably be done without a loop
      for i in range(num_beats - 1):
          # aggregate all feature values that fall into a window of
          # length = beat_duration / beat_subdivisions, centered on the beat
          # annotations or interpolated subdivisions
          beat_duration = beats[i + 1] - beats[i]
          offset = 0.5 * beat_duration / self.beat_subdivisions
          # offset should be < 50 ms
          offset = np.min([offset, 0.05])
          # last frame of beat
          beat_end = int(np.floor((beats[i + 1] - offset) * self.fps))
          # we need to put each feature frame into its corresponding
          # beat subdivison; linearly align the subdivisions up to the
          # length of the beat
          subdiv = np.floor(
              np.linspace(
                  0,
                  self.beat_subdivisions,
                  beat_end - beat_start,
                  endpoint=False,
              )
          )
          beat = features[beat_start:beat_end]
          # group features by beat subdivisions and aggregate them
          subdiv_features = [
              beat[subdiv == div]
              for div in range(self.beat_subdivisions)
          ]
          beat_features[i, :, :] = np.array(
              [np.mean(x, axis=0) for x in subdiv_features]
          )
          # progress to next beat
          beat_start = beat_end
      # return beats and beat-synchronous features
      return beat_features
  
imports: from __future__ import absolute_import, division, print_function
  import sys
  import warnings
  import numpy
  from .beats import threshold_activations
  from .beats_hmm import BarStateSpace, BarTransitionModel, GMMPatternTrackingObservationModel, MultiPatternStateSpace, MultiPatternTransitionModel, RNNBeatTrackingObservationModel, RNNDownBeatTrackingObservationModel
  from ..ml.hmm import HiddenMarkovModel
  from ..processors import ParallelProcessor, Processor, SequentialProcessor
  from ..utils import string_types
label_desc: Use image node_id 2 for calling the SyncronizeFeaturesProcessor obj's underlying member method code with example usage: obj.process(data) and returns: beat_features, np,  np