:py:mod:`tonic.transforms`
==========================

.. py:module:: tonic.transforms


Module Contents
---------------

Classes
~~~~~~~

.. autoapisummary::

   tonic.transforms.Compose
   tonic.transforms.CenterCrop
   tonic.transforms.CropTime
   tonic.transforms.Denoise
   tonic.transforms.Decimation
   tonic.transforms.DropEvent
   tonic.transforms.DropEventByTime
   tonic.transforms.DropEventByArea
   tonic.transforms.DropPixel
   tonic.transforms.Downsample
   tonic.transforms.EventDrop
   tonic.transforms.EventDownsampling
   tonic.transforms.MergePolarities
   tonic.transforms.RandomCrop
   tonic.transforms.RandomDropPixel
   tonic.transforms.RandomFlipPolarity
   tonic.transforms.RandomFlipLR
   tonic.transforms.RandomFlipUD
   tonic.transforms.RandomTimeReversal
   tonic.transforms.RefractoryPeriod
   tonic.transforms.SpatialJitter
   tonic.transforms.TimeAlignment
   tonic.transforms.TimeJitter
   tonic.transforms.TimeSkew
   tonic.transforms.UniformNoise
   tonic.transforms.NumpyAsType
   tonic.transforms.ToAveragedTimesurface
   tonic.transforms.ToFrame
   tonic.transforms.ToSparseTensor
   tonic.transforms.ToImage
   tonic.transforms.ToTimesurface
   tonic.transforms.ToVoxelGrid
   tonic.transforms.ToBinaRep
   tonic.transforms.Repeat
   tonic.transforms.ToOneHotEncoding




.. py:class:: Compose(transforms: Callable)


   Composes several transforms together. This a literal copy of torchvision.transforms.Compose
   function for convenience.

   :param transforms: list of transform(s) to compose.
                      Can combine Tonic, PyTorch Vision/Audio transforms.
   :type transforms: list of ``Transform`` objects

   .. rubric:: Example

   >>> transforms.Compose([
   >>>     transforms.Denoise(filter_time=10000),
   >>>     transforms.ToFrame(n_time_bins=3),
   >>> ])

   .. py:method:: __call__(events)


   .. py:method:: __repr__()

      Return repr(self).



.. py:class:: CenterCrop


   Crops events at the center to a specific output size. If output size is smaller than input
   sensor size along any dimension, padding will be used, which doesn't influence the number of
   events on that axis but just their spatial location after cropping. Make sure to use the
   cropped sensor size for any transform after CenterCrop.

   :param sensor_size: Size of the sensor that was used [W,H,P]
   :type sensor_size: tuple
   :param size: Desired output size of the crop. If size is an
                int instead of sequence like (h, w), a square crop (size, size) is made.
   :type size: sequence or int

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:attribute:: size
      :type: Union[int, Tuple[int, int]]

      

   .. py:method:: __call__(events: numpy.ndarray) -> numpy.ndarray



.. py:class:: CropTime


   Drops events with timestamps below min and above max.

   :param min: The minimum timestamp below which all events are dropped. Zero by default.
   :type min: int
   :param max: The maximum timestamp above which all events are dropped.
   :type max: int

   .. rubric:: Example

   >>> transform = tonic.transforms.CropTime(min=1000, max=20000)

   .. py:attribute:: min
      :type: int
      :value: 0

      

   .. py:attribute:: max
      :type: int

      

   .. py:method:: __call__(events)



.. py:class:: Denoise


   Drops events that are spatio-temporally not sufficiently close enough to other events in the
   sample. In practise that means that an event is dropped if no other event occured within a
   spatial neighbourhood of 1 pixel and a temporal neighbourhood of filter_time time units. Useful
   to filter noisy recordings where events occur isolated in time.

   :param filter_time: minimum temporal distance to next event, otherwise dropped.
                       Lower values will mean higher constraints, therefore less output events.
                       Use same unit of time as the events have.
   :type filter_time: float

   .. rubric:: Example

   >>> transform = tonic.transforms.Denoise(filter_time=10000)

   .. py:attribute:: filter_time
      :type: float

      

   .. py:method:: __call__(events)



.. py:class:: Decimation


   Deterministically drops every nth event for every spatial location x (and potentially y).

   :param n: The event stream for each x/y location is reduced to 1/n.
   :type n: int

   .. rubric:: Example

   >>> transform = tonic.transforms.Decimation(n=5)

   .. py:attribute:: n
      :type: int

      

   .. py:method:: __call__(events)



.. py:class:: DropEvent


   Randomly drops events with probability p. If random_p is selected, the drop probability is
   randomized between 0 and p.

   :param p: Probability of dropping events. Can be a tuple of floats (p_min, p_max), so that p is sampled from the range.
   :type p: float or tuple of floats

   .. rubric:: Example

   >>> transform1 = tonic.transforms.DropEvent(p=0.2)
   >>> transform2 = tonic.transforms.DropEvent(p=(0, 0.5))

   .. py:attribute:: p
      :type: Union[float, Tuple[float, float]]

      

   .. py:method:: get_params(p: Union[float, Tuple[float, float]])
      :staticmethod:


   .. py:method:: __call__(events)



.. py:class:: DropEventByTime


   Drops events in a certain time interval with a length proportional to a specified ratio of
   the original length.

   :param duration_ratio: the length of the dropped time interval, expressed in a ratio of the original sequence duration.
                          - If a float, the value is used to calculate the interval length
                          - If a tuple of 2 floats, the ratio is randomly chosen in [min, max)
                          Defaults to 0.2.
   :type duration_ratio: Union[float, Tuple[float]], optional

   .. rubric:: Example

   >>> transform = tonic.transforms.DropEventByTime(duration_ratio=(0.1, 0.8))

   .. py:attribute:: duration_ratio
      :type: Union[float, Tuple[float, float]]
      :value: 0.2

      

   .. py:method:: __call__(events)



.. py:class:: DropEventByArea


   Drops events located in a randomly chosen box area. The size of the box area is defined by a
   specified ratio of the sensor size.

   :param sensor_size: size of the sensor that was used [W,H,P]
   :type sensor_size: Tuple
   :param area_ratio: Ratio of the sensor resolution that determines the size of the box area where events are dropped.
                      - if a float, the value is used to calculate the size of the box area
                      - if a tuple of 2 floats, the ratio is randomly chosen in [min, max)
                      Defaults to 0.2.
   :type area_ratio: Union[float, Tuple[float]], optional

   .. rubric:: Example

   >>> transform = tonic.transforms.DropEventByArea(sensor_size=(128,128,2), area_ratio=(0.1, 0.8))

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:attribute:: area_ratio
      :type: Union[float, Tuple[float, float]]
      :value: 0.2

      

   .. py:method:: __call__(events)



.. py:class:: DropPixel


   Drops events for individual pixels. If the locations of pixels to be dropped is known, a
   list of x/y coordinates can be passed directly. Alternatively, a cutoff frequency for each
   pixel can be defined above which pixels will be deactivated completely. This prevents so-
   called *hot pixels* which fire at a high frequency even in the absence of any input signal
   (e.g. due to faulty hardware).

   :param coordinates: List of (x,y) coordinates for which all events will be deleted.
   :param hot_pixel_frequency: Drop pixels completely that fire higher than the given frequency.

   .. rubric:: Example

   >>> from tonic.transforms import DropPixel
   >>> transform1 = DropPixel(coordinates=[[10,10], [10,11], [11,10], [11,11]])
   >>> transform2 = DropPixel(hot_pixel_frequency=60) # Hertz

   .. py:attribute:: coordinates
      :type: Optional[List[Tuple[int, int]]]

      

   .. py:attribute:: hot_pixel_frequency
      :type: Optional[int]

      

   .. py:method:: __call__(events)



.. py:class:: Downsample


   Multiplies timestamps and spatial pixel coordinates with separate factors. Useful when the
   native temporal and/or spatial resolution of the original sensor is too high for downstream
   processing, notably when converting to dense representations of some sort. This transform does
   not drop any events.

   :param time_factor: value to multiply timestamps with. Default is 1.
   :type time_factor: float
   :param spatial_factor: values to multiply pixel coordinates with. Default is 1.
                          Note that when using subsequential transforms that require
                          sensor_size, you must change the spatial values for the later
                          transformation.
   :type spatial_factor: float or tuple of floats
   :param sensor_size: size of the sensor that was used [W,H,P]
   :type sensor_size: tuple
   :param target_size: size of the desired resolution [W,H]
   :type target_size: tuple

   .. rubric:: Example

   >>> from tonic.transforms import Downsample
   >>> transform1 = Downsample(time_factor=0.001) # change us to ms
   >>> transform2 = Downsample(spatial_factor=0.25) # reduce focal plane to 1/4.
   >>> transform3 = Downsample(sensor_size=(40, 20, 2), target_size=(10, 5)) # reduce focal plane to 1/4.

   .. py:attribute:: time_factor
      :type: float
      :value: 1

      

   .. py:attribute:: spatial_factor
      :type: Union[float, Tuple[float, float]]
      :value: 1

      

   .. py:attribute:: sensor_size
      :type: Optional[Tuple[int, int, int]]

      

   .. py:attribute:: target_size
      :type: Optional[Tuple[int, int]]

      

   .. py:method:: get_params(spatial_factor: Union[int, Tuple[int, int]])
      :staticmethod:


   .. py:method:: __call__(events)



.. py:class:: EventDrop


   Applies EventDrop transformation from the paper "EventDrop: Data Augmentation for Event-based Learning".
       Applies one of the 4 drops of event strategies between:
           1. Identity (do nothing)
           2. Drop events by time
           3. Drop events by area
           4. Drop events randomly

       For each strategy, the ratio of dropped events are determined in the paper.

   :param sensor_size: size of the sensor that was used [W,H,P]
   :type sensor_size: Tuple

   .. rubric:: Example

   >>> transform = tonic.transforms.EventDrop(sensor_size=(128,128,2))

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:method:: __call__(events)



.. py:class:: EventDownsampling


   Applies EventDownsampling from the paper "Insect-inspired Spatio-temporal Downsampling of Event-based Input."
       Allows:
           1. Integrator based method to perform spatio-temporal event-based downsampling
           2. Differentiator based method to perform spatio-temporal event-based downsampling

   :param sensor_size: size of the sensor that was used [W,H,P]
   :type sensor_size: Tuple
   :param target_size: size of the desired resolution [W,H]
   :type target_size: Tuple
   :param dt: temporal resolution of events in ms
   :type dt: float
   :param downsampling_method: string stating downsampling method. Choose from ['naive', 'integrator', 'differentiator']
   :type downsampling_method: str
   :param noise_threshold: set number of events in downsampled pixel required to emit spike. Zero by default.
   :type noise_threshold: int
   :param differentiator_time_bins: number of differentiator time bins within dt. Two by default.
   :type differentiator_time_bins: int

   .. rubric:: Example

   >>> transform1 = tonic.transforms.EventDownsampling(sensor_size=(640,480,2), target_size=(20,15), dt=0.5,
                                                      downsampling_method='integrator')
   >>> transform2 = tonic.transforms.EventDownsampling(sensor_size=(640,480,2), target_size=(20,15), dt=0.5,
                                                      downsampling_method='differentiator', noise_threshold=2,
                                                      differentiator_time_bins=3)

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:attribute:: target_size
      :type: Tuple[int, int]

      

   .. py:attribute:: downsampling_method
      :type: str

      

   .. py:attribute:: dt
      :type: Optional[float]

      

   .. py:attribute:: noise_threshold
      :type: Optional[int]

      

   .. py:attribute:: differentiator_time_bins
      :type: Optional[int]

      

   .. py:method:: __call__(events)



.. py:class:: MergePolarities


   Sets all polarities to zero. This transform does not have any parameters.

   .. rubric:: Example

   >>> transform = tonic.transforms.MergePolarities()

   .. py:method:: __call__(events)



.. py:class:: RandomCrop


   Crops the sensor size to a smaller size in a random location.

   x' = x - new_sensor_start_x

   y' = y - new_sensor_start_y

   :param sensor_size: a 3-tuple of x,y,p for sensor_size
   :param target_size: a tuple of x,y target sensor size

   .. rubric:: Example

   >>> transform = tonic.transforms.RandomCrop(sensor_size=(340, 240, 2), target_size=(50, 50))

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:attribute:: target_size
      :type: Tuple[int, int]

      

   .. py:method:: __call__(events)



.. py:class:: RandomDropPixel


   Drops all events for individual pixels with a given probability.

   :param p: Probability of pixel being dropped. Stochastic transform.
   :param sensor_size: a 3-tuple of x,y,p for sensor_size. Not necessary when RandomDropPixel is applied to rasters.

   .. rubric:: Example

   >>> from tonic.transforms import RandomDropPixel
   >>> transform = DropPixel(p=0.2)

   .. py:attribute:: p
      :type: float

      

   .. py:attribute:: sensor_size
      :type: Optional[Tuple[int, int, int]]

      

   .. py:method:: __call__(events)



.. py:class:: RandomFlipPolarity


   Flips polarity of individual events with p. Changes polarities 1 to 0 and polarities [-1, 0]
   to 1.

   :param p: probability of flipping individual event polarities
   :type p: float

   .. rubric:: Example

   >>> transform = tonic.transforms.RandomFlipPolarity(p=0.3)

   .. py:attribute:: p
      :type: float
      :value: 0.5

      

   .. py:method:: __post_init__()


   .. py:method:: __call__(events)



.. py:class:: RandomFlipLR


   Flips events in x with probability p. Pixels map as:

       x' = width - x

   :param sensor_size: a 3-tuple of x,y,p for sensor_size
   :param p: probability of performing the flip
   :type p: float

   .. rubric:: Example

   >>> transform = tonic.transforms.RandomFlipLR(p=0.3)

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:attribute:: p
      :type: float
      :value: 0.5

      

   .. py:method:: __post_init__()


   .. py:method:: __call__(events)



.. py:class:: RandomFlipUD


   Flips events in y with probability p. Pixels map as:

       y' = height - y

   :param sensor_size: a 3-tuple of x,y,p for sensor_size
   :param p: probability of performing the flip
   :type p: float

   .. rubric:: Example

   >>> transform = tonic.transforms.RandomFlipUD(p=0.3)

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:attribute:: p
      :type: float
      :value: 0.5

      

   .. py:method:: __post_init__()


   .. py:method:: __call__(events)



.. py:class:: RandomTimeReversal


   Reverses temporal order of events with probability p.

       .. math::
          t_i' = max(t) - t_i

   :param p: probability of performing the flip
   :type p: float
   :param flip_polarities: if the time is reversed, also flip the polarities. True by default.
   :type flip_polarities: bool

   .. rubric:: Example

   >>> transform = tonic.transforms.RandomTimeReversal(p=0.3)

   .. py:attribute:: p
      :type: float
      :value: 0.5

      

   .. py:attribute:: flip_polarities
      :type: bool
      :value: True

      

   .. py:method:: __post_init__()


   .. py:method:: __call__(events)



.. py:class:: RefractoryPeriod


   Sets a refractory period for each pixel, during which events will be ignored/discarded. We
   keep events if:

       .. math::
           t_n - t_{n-1} > t_{refrac}

   for each pixel.

   :param delta: Refractory period for each pixel. Use same time
                 unit as event timestamps. Can use a 2-tuple to
                 sample from a range.
   :type delta: int

   >>> transform1 = tonic.transforms.RefractoryPeriod(delta=1000)
   >>> transform2 = tonic.transforms.RefractoryPeriod(delta=[0, 1000])

   .. py:attribute:: delta
      :type: Union[int, Tuple[int, int]]

      

   .. py:method:: get_params(delta: Union[int, Tuple[int, int]])
      :staticmethod:


   .. py:method:: __call__(events)



.. py:class:: SpatialJitter


   Changes x/y coordinate for each event by adding samples from a multivariate Gaussian
   distribution. It with the following properties:

       .. math::
           mean = [x,y]

           \Sigma = [[var_x, sigma_{xy}],[sigma_{xy}, var_y]]

   Jittered events that lie outside the focal plane will be dropped if clip_outliers is True.

   :param sensor_size: a 3-tuple of x,y,p for sensor_size
   :param var_x: variance for the distribution in the x direction
   :type var_x: float
   :param var_y: variance for the distribution in the y direction
   :type var_y: float
   :param sigma_xy: changes skewness of distribution, only change if you want shifts along diagonal axis.
   :type sigma_xy: float
   :param clip_outliers: when True, events that have been jittered outside the sensor size will be dropped.
   :type clip_outliers: bool

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:attribute:: var_x
      :type: float
      :value: 1

      

   .. py:attribute:: var_y
      :type: float
      :value: 1

      

   .. py:attribute:: sigma_xy
      :type: float
      :value: 0

      

   .. py:attribute:: clip_outliers
      :type: bool
      :value: False

      

   .. py:method:: __call__(events)



.. py:class:: TimeAlignment


   Removes offset for timestamps, so that first event starts at time zero.

   .. py:method:: __call__(events)



.. py:class:: TimeJitter


   Changes timestamp for each event by adding samples from a Gaussian distribution.

   :param std: the standard deviation of the time jitter.
   :type std: sequence or float
   :param clip_negative: drops events that have negative timestamps.
   :type clip_negative: bool
   :param sort_timestamps: sort the events by timestamps after jitter.
   :type sort_timestamps: bool

   .. py:attribute:: std
      :type: float

      

   .. py:attribute:: clip_negative
      :type: bool
      :value: True

      

   .. py:attribute:: sort_timestamps
      :type: bool
      :value: False

      

   .. py:method:: __call__(events)



.. py:class:: TimeSkew


   Skew all event timestamps according to a linear transform.

   :param coefficient: a real-valued multiplier applied to the timestamps of the events.
                       E.g. a coefficient of 2.0 will double the effective delay between any
                       pair of events. Can provide a tuple for a range of values.
   :param offset: value by which the timestamps will be shifted after multiplication by
                  the coefficient. Negative offsets are permissible but may result in
                  in an exception if timestamps are shifted below 0. Tuple of values might
                  be provided as a range to sample from.

   .. rubric:: Example

   >>> transform1 = TimeSkew(coefficient=1.3, offset=100)
   >>> transform2 = TimeSkew(coefficient=[0.8, 1.2], offset=[0, 150])

   .. py:attribute:: coefficient
      :type: Union[float, Tuple[float, float]]

      

   .. py:attribute:: offset
      :type: Union[float, Tuple[float, float]]
      :value: 0

      

   .. py:method:: __call__(events)



.. py:class:: UniformNoise


   Adds a fixed number of n noise events that are uniformly distributed across sensor size
   dimensions such as x, y, t and p. Not applied if the input is empty.

   :param sensor_size: a 3-tuple of x,y,p for sensor_size
   :param n: Number of events that are added. Can be a tuple of integers,
             so that n is sampled from a range.

   .. rubric:: Example

   >>> transform = tonic.transforms.UniformNoise(sensor_size=(340, 240, 2), n=3000)

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:attribute:: n
      :type: Union[int, Tuple[int, int]]

      

   .. py:method:: get_params(n: Union[int, Tuple[int, int]])
      :staticmethod:


   .. py:method:: __call__(events)



.. py:class:: NumpyAsType


   Change dtype of numpy ndarray to custom dtype. This transform is necessary for example if
   you want to load raw events using a PyTorch dataloader. The original events coming from any
   dataset in Tonic are structured numpy arrays, so that they can be indexed as events["t"] or
   events["p"] etc. Pytorch's dataloader however does not support the conversion from structured
   numpy arrays to Tensors, that's why we need to employ at least NumpyAsType(int) to convert the
   structured array into an unstructured one before handing it to the dataloader.

   :param dtype: data type that the array should be cast to.

   .. rubric:: Example

   >>> # indexing the dataset directly provides structured numpy arrays
   >>> dataset = tonic.datasets.NMNIST(save_to='data')
   >>> events, targets = dataset[100]
   >>>
   >>> # this doesn't work
   >>> dataloader = torch.utils.data.DataLoader(dataset)
   >>> events, targets = next(iter(dataloader))
   >>>
   >>> # we need to convert to unstructured arrays
   >>> transform = tonic.transforms.NumpyAsType(int)
   >>> dataset = tonic.datasets.NMNIST(save_to='data', transform=transform)
   >>> dataloader = torch.utils.data.DataLoader(dataset)
   >>> events, targets = next(iter(dataloader))

   .. py:attribute:: dtype
      :type: numpy.dtype

      

   .. py:method:: __call__(events)



.. py:class:: ToAveragedTimesurface


   Create averaged timesurfaces for each event. Taken from the paper Sironi et al. 2018, HATS:
   Histograms of averaged time surfaces for robust event-based object classification https://opena
   ccess.thecvf.com/content_cvpr_2018/papers/Sironi_HATS_Histograms_of_CVPR_2018_paper.pdf.

   :param sensor_size: a 3-tuple of x,y,p for sensor_size
   :param cell_size: size of each square in the grid
   :type cell_size: int
   :param surface_size: has to be odd
   :type surface_size: int
   :param time_window: how far back to look for past events for the time averaging
   :type time_window: float
   :param tau: time constant to decay events around occuring event with.
   :type tau: float
   :param decay: can be either 'lin' or 'exp', corresponding to linear or exponential decay.
   :type decay: str

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:attribute:: surface_size
      :type: int
      :value: 5

      

   .. py:attribute:: cell_size
      :type: int
      :value: 10

      

   .. py:attribute:: time_window
      :type: float
      :value: 1000.0

      

   .. py:attribute:: tau
      :type: float
      :value: 100

      

   .. py:attribute:: decay
      :type: str
      :value: 'exp'

      

   .. py:method:: __call__(events)



.. py:class:: ToFrame


   Accumulate events to frames by slicing along constant time (time_window), constant number of
   events (event_count) or constant number of frames (n_time_bins / n_event_bins). All the events
   in one slice are added up in a frame for each polarity.  If you want binary frames, you can
   manually clamp them to 1 afterwards. You can set one of the first 4 parameters to choose the
   slicing method. Depending on which method you choose, overlap will be defined differently. As a
   rule of thumb, here are some considerations if you are unsure which slicing method to choose:

   * If your recordings are of roughly the same length, a safe option is to set time_window. Bare in mind
     that the number of events can vary greatly from slice to slice, but will give you some consistency when
     training RNNs or other algorithms that have time steps.

   * If your recordings have roughly the same amount of activity / number of events and you are more interested
     in the spatial composition, then setting event_count will give you frames that are visually more consistent.

   * The previous time_window and event_count methods will likely result in a different amount of frames for each
     recording. If your training method benefits from consistent number of frames across a dataset (for easier
     batching for example), or you want a parameter that is easier to set than the exact window length or number
     of events per slice, consider fixing the number of frames by setting n_time_bins or n_event_bins. The two
     methods slightly differ with respect to how the slices are distributed across the recording. You can define
     an overlap between 0 and 1 to provide some robustness.

   :param sensor_size: A 3-tuple of x,y,p for sensor_size. If omitted, the sensor size is calculated for that sample. However,
                       do use this feature sparingly as when not all pixels fire in a sample, this might cause issues with batching/
                       stacking tensors further down the line.
   :param time_window: Time window length for one frame. Use the same time unit as timestamps in the event recordings.
                       Good if you want temporal consistency in your training, bad if you need some visual consistency
                       for every frame if the recording's activity is not consistent.
   :type time_window: float
   :param event_count: Number of events per frame. Good for training CNNs which do not care about temporal consistency.
   :type event_count: int
   :param n_time_bins: Fixed number of frames, sliced along time axis. Good for generating a pre-determined number of
                       frames which might help with batching.
   :type n_time_bins: int
   :param n_event_bins: Fixed number of frames, sliced along number of events in the recording. Good for generating a
                        pre-determined number of frames which might help with batching.
   :type n_event_bins: int
   :param overlap: Overlap between frames. The definition of overlap depends on the slicing method.
                   For slicing by time_window, the overlap is defined in microseconds. For slicing by event_count,
                   the overlap is defined by number of events. For slicing by n_time_bins or n_event_bins, the
                   overlap is defined by the fraction of a bin between 0 and 1.
   :type overlap: float
   :param include_incomplete: If True, includes overhang slice when time_window or event_count is specified.
                              Not valid for bin_count methods.
   :type include_incomplete: bool
   :param start_time: Optional start time if some empty frames are expected in the beginning. If omitted, the
                      start time is the timestamp of the first event for that sample.
   :type start_time: float
   :param end_time: Optional end time if some empty frames are expected in the end. If omitted, the end time
                    is the timestamp of the last event for that sample.
   :type end_time: float

   .. rubric:: Example

   >>> from tonic.transforms import ToFrame
   >>> transform1 = ToFrame(time_window=10000, overlap=1000, include_incomplete=True)
   >>> transform2 = ToFrame(event_count=3000, overlap=100, include_incomplete=True)
   >>> transform3 = ToFrame(n_time_bins=100, overlap=0.1)

   .. py:attribute:: sensor_size
      :type: Optional[Tuple[int, int, int]]

      

   .. py:attribute:: time_window
      :type: Optional[float]

      

   .. py:attribute:: event_count
      :type: Optional[int]

      

   .. py:attribute:: n_time_bins
      :type: Optional[int]

      

   .. py:attribute:: n_event_bins
      :type: Optional[int]

      

   .. py:attribute:: overlap
      :type: float
      :value: 0

      

   .. py:attribute:: include_incomplete
      :type: bool
      :value: False

      

   .. py:attribute:: start_time
      :type: Optional[float]

      

   .. py:attribute:: end_time
      :type: Optional[float]

      

   .. py:method:: __call__(events)



.. py:class:: ToSparseTensor


   PyTorch sparse tensor drop-in replacement for ToFrame. See
   https://pytorch.org/docs/stable/sparse.html for details about sparse tensors. The dense shape
   of the tensor will be (TCWH) and can be inflated by calling to_dense(). You need to have
   PyTorch installed for this transformation. Under the hood this transform calls ToFrame() with
   the same parameters, converts to a pytorch tensor and calls to_sparse().

   :param sensor_size: a 3-tuple of x,y,p for sensor_size. If omitted, the sensor size is calculated for that sample. However,
                       do use this feature sparingly as when not all pixels fire in a sample, this might cause issues with batching/
                       stacking tensors further down the line.
   :param time_window: time window length for one frame. Use the same time unit as timestamps in the event recordings.
                       Good if you want temporal consistency in your training, bad if you need some visual consistency
                       for every frame if the recording's activity is not consistent.
   :type time_window: float
   :param event_count: number of events per frame. Good for training CNNs which do not care about temporal consistency.
   :type event_count: int
   :param n_time_bins: fixed number of frames, sliced along time axis. Good for generating a pre-determined number of
                       frames which might help with batching.
   :type n_time_bins: int
   :param n_event_bins: fixed number of frames, sliced along number of events in the recording. Good for generating a
                        pre-determined number of frames which might help with batching.
   :type n_event_bins: int
   :param overlap: overlap between frames defined either in time units, number of events or number of bins between 0 and 1.
   :type overlap: float
   :param include_incomplete: if True, includes overhang slice when time_window or event_count is specified.
                              Not valid for bin_count methods.
   :type include_incomplete: bool

   .. rubric:: Example

   >>> from tonic.transforms import ToSparseTensor
   >>> transform1 = ToSparseTensor(time_window=10000, overlap=300, include_incomplete=True)
   >>> transform2 = ToSparseTensor(event_count=3000, overlap=100, include_incomplete=True)
   >>> transform3 = ToSparseTensor(n_time_bins=100, overlap=0.1)

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:attribute:: time_window
      :type: Optional[float]

      

   .. py:attribute:: event_count
      :type: Optional[int]

      

   .. py:attribute:: n_time_bins
      :type: Optional[int]

      

   .. py:attribute:: n_event_bins
      :type: Optional[int]

      

   .. py:attribute:: overlap
      :type: float
      :value: 0

      

   .. py:attribute:: include_incomplete
      :type: bool
      :value: False

      

   .. py:method:: __call__(events)



.. py:class:: ToImage


   Counts up all events to a *single* image of size sensor_size.

   ToImage will typically be used in combination with SlicedDataset to cut a recording into
   smaller chunks that are then individually binned to frames.

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:method:: __call__(events)



.. py:class:: ToTimesurface


   Create global time surfaces at a specific time interval dt.

   :param sensor_size: A 3-tuple of x,y,p for sensor_size
   :param dt: The interval at which the time-surfaces are accumulated.
   :type dt: float
   :param tau: Time constant to decay events with.
   :type tau: float

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:attribute:: dt
      :type: float

      

   .. py:attribute:: tau
      :type: float

      

   .. py:method:: __call__(events)



.. py:class:: ToVoxelGrid


   Build a voxel grid with bilinear interpolation in the time domain from a set of events.
   Implements the event volume from Zhu et al. 2019, Unsupervised event-based learning of optical
   flow, depth, and egomotion.

   :param sensor_size: a 3-tuple of x,y,p for sensor_size
   :param n_time_bins: fixed number of time bins to slice the event sample into.
   :type n_time_bins: int

   .. py:attribute:: sensor_size
      :type: Tuple[int, int, int]

      

   .. py:attribute:: n_time_bins
      :type: int

      

   .. py:method:: __call__(events)



.. py:class:: ToBinaRep


   Takes T*B binary event frames to produce a sequence of T frames of N-bit numbers. To do so,
   N binary frames are interpreted as a single frame of N-bit representation. Taken from the paper
   Barchid et al. 2022, Bina-Rep Event Frames: a Simple and Effective Representation for Event-
   based cameras https://arxiv.org/pdf/2202.13662.pdf.

   :param n_frames: the number T of bina-rep frames.
   :type n_frames: int
   :param n_bits: the number N of bits used in the N-bit representation.
   :type n_bits: int

   .. rubric:: Example

   >>> n_time_bins = n_frames * n_bits
   >>>
   >>> transforms.Compose([
   >>>     transforms.ToFrame(
   >>>         sensor_size=sensor_size,
   >>>         n_time_bins=n_time_bins,
   >>>     ),
   >>>     transforms.ToBinaRep(
   >>>         n_frames=n_frames,
   >>>         n_bits=n_bits,
   >>>     ),
   >>> ])

   .. py:attribute:: n_frames
      :type: Optional[int]
      :value: 1

      

   .. py:attribute:: n_bits
      :type: Optional[int]
      :value: 8

      

   .. py:method:: __call__(event_frames)



.. py:class:: Repeat


   Copies target n times.

   Useful to transform sample labels into sequences.

   .. py:attribute:: n_repeat
      :type: int

      

   .. py:method:: __call__(target)



.. py:class:: ToOneHotEncoding


   Transforms one or more targets into a one hot encoding scheme.

   .. py:attribute:: n_classes
      :type: int

      

   .. py:method:: __call__(target)



