### Tonic Quickstart Example Source: https://github.com/neuromorphs/tonic/blob/develop/README.md A minimal example demonstrating how to load the NMNIST dataset with transformations and create a DataLoader. This snippet is useful for quickly getting started with Tonic. ```python import tonic import tonic.transforms as transforms sensor_size = tonic.datasets.NMNIST.sensor_size transform = transforms.Compose( [ transforms.Denoise(filter_time=10000), transforms.ToFrame(sensor_size=sensor_size, time_window=3000), ] ) testset = tonic.datasets.NMNIST(save_to="./data", train=False, transform=transform) from torch.utils.data import DataLoader testloader = DataLoader( testset, batch_size=10, collate_fn=tonic.collation.PadTensors(batch_first=True), ) frames, targets = next(iter(testloader)) ``` -------------------------------- ### Setup development environment with uv Source: https://github.com/neuromorphs/tonic/blob/develop/README.md Set up the development environment for Tonic using uv, including installing dependencies and the package in editable mode. This is recommended for developers contributing to the project. ```bash # Install uv curl -LsSf https://astral.sh/uv/install.sh | sh # Clone the repository git clone https://github.com/neuromorphs/tonic.git cd tonic # Install dependencies and tonic in editable mode uv sync --extra dev # Run tests uv run pytest test/ ``` -------------------------------- ### Install and Use Pre-commit Hook Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_involved/contribute.rst Install the pre-commit package and set up the hook to automatically format code with Black before committing. This ensures consistent code style across the project. ```bash pip install pre-commit pre-commit install ``` -------------------------------- ### Install Tonic using conda Source: https://github.com/neuromorphs/tonic/blob/develop/README.md Install the Tonic library using conda, recommended for users who prefer the conda package manager. ```bash conda install -c conda-forge tonic ``` -------------------------------- ### Install Latest Pre-release Tonic Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_started/install.rst Install the latest pre-release version of Tonic, which corresponds to the latest code on the develop branch that has passed tests. ```bash pip install tonic --pre ``` -------------------------------- ### Install Latest Stable Tonic Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_started/install.rst Use this command to install the latest stable release of the Tonic library via pip. ```bash pip install tonic ``` -------------------------------- ### PyTorch DataLoader Iteration Shortcut Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/fast_dataloading.ipynb A concise lambda function to get the next batch from the PyTorch DataLoader, simplifying the iteration process for timing purposes. ```python load_sample_pytorch = lambda: next(iter(dataloader)) ``` -------------------------------- ### Get Dataset Size Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Retrieves the total number of recordings in the dataset. This is a basic operation before slicing. ```python len(dataset) ``` -------------------------------- ### BibTeX Citation for Tonic Package Source: https://github.com/neuromorphs/tonic/blob/develop/README.md Use this BibTeX entry to cite the Tonic package in your academic work. Ensure you have the 'bibtexparser' library installed if you plan to programmatically parse this citation. ```BibTex @software{lenz_gregor_2021_5079802, author = {Lenz, Gregor and Chaney, Kenneth and Shrestha, Sumit Bam and Oubari, Omar and Picaud, Serge and Zarrella, Guido}, title = {Tonic: event-based datasets and transformations.}, month = jul, year = 2021, note = {{Documentation available under https://tonic.readthedocs.io}}, publisher = {Zenodo}, version = {0.4.0}, doi = {10.5281/zenodo.5079802}, url = {https://doi.org/10.5281/zenodo.5079802} } ``` -------------------------------- ### Build Documentation Locally Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_involved/contribute.rst Navigate to the docs directory and build the HTML documentation locally. This allows you to preview changes before deploying them. ```bash cd docs/ make html firefox _build/html/index.html ``` -------------------------------- ### Instantiate Dataset and DataLoader Source: https://github.com/neuromorphs/tonic/blob/develop/docs/how-tos/wrapping_own_data.ipynb Demonstrates how to create an instance of the custom dataset and use it with PyTorch's DataLoader for batching and shuffling. ```python dataset = MyRecordings(train=True, transform=transforms.NumpyAsType(int)) events = dataset[5] import torch dataloader = torch.utils.data.DataLoader(dataset, shuffle=True) events = next(iter(dataloader)) ``` -------------------------------- ### Load and Display Sample Audio Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/audio_transforms_tutorial.ipynb Loads a sample audio file using torchaudio and displays it. This is a prerequisite for applying audio transformations. ```python import warnings warnings.filterwarnings("ignore") import IPython import matplotlib.pyplot as plt import numpy as np import torchaudio from torchaudio.utils import download_asset SAMPLE_WAV = download_asset( "tutorial-assets/Lab41-SRI-VOiCES-src-sp0307-ch127535-sg0042.wav" ) sample_audio, sample_rate = torchaudio.load(SAMPLE_WAV) sample_audio = sample_audio.numpy() original_sample_length = int(np.ceil(np.shape(sample_audio)[1] / sample_rate)) IPython.display.display(IPython.display.Audio(sample_audio, rate=sample_rate)) ``` -------------------------------- ### Get Batch Shape Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/batching.ipynb Retrieves and displays the shape of the batched frames tensor. This helps verify the padding and batching process. ```python frames.shape ``` -------------------------------- ### Create Dummy Event Recording Files Source: https://github.com/neuromorphs/tonic/blob/develop/docs/how-tos/wrapping_own_data.ipynb Generates random event data and saves it as numpy files. This is useful for testing custom dataset implementations. ```python import numpy as np from tonic import Dataset, transforms sensor_size = (200, 100, 2) n_recordings = 10 def create_random_input( sensor_size=sensor_size, n_events=10000, dtype=np.dtype([("x", int), ("y", int), ("t", int), ("p", int)]), ): events = np.zeros(n_events, dtype=dtype) events["x"] = np.random.rand(n_events) * sensor_size[0] events["y"] = np.random.rand(n_events) * sensor_size[1] events["p"] = np.random.rand(n_events) * sensor_size[2] events["t"] = np.sort(np.random.rand(n_events) * 1e6) return events [ np.save(f"../tutorials/data/recording{i}.npy", create_random_input()) for i in range(n_recordings) ]; ``` -------------------------------- ### Run All Tests Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_involved/contribute.rst Execute all functional tests for the Tonic project from the root directory. This command verifies the correctness of existing and new code. ```bash python -m pytest ``` -------------------------------- ### Measure Loading Time Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/fast_dataloading.ipynb Measures the execution time of the `load_sample_simple` function using IPython's %timeit magic command. ```python %timeit -o load_sample_simple() ``` -------------------------------- ### Initialize DataLoader with Batching and Padding (batch_first=False) Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/batching.ipynb Reconfigures the DataLoader to use padding where the time dimension comes first, aligning with PyTorch RNN conventions. This is achieved by setting `batch_first=False` in the `PadTensors` collate function. ```python dataloader_batched = DataLoader( dataset, shuffle=True, batch_size=10, collate_fn=tonic.collation.PadTensors(batch_first=False), ) frames, targets = next(iter(dataloader_batched)) ``` -------------------------------- ### Initialize DataLoader with Batching and Padding Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/batching.ipynb Sets up a DataLoader for the NMNIST dataset with batching and padding enabled. The `collate_fn=tonic.collation.PadTensors(batch_first=True)` ensures that all tensors in a batch are padded to the same shape, with the batch dimension coming first. ```python import torch from torch.utils.data import DataLoader import tonic import tonic.transforms as transforms torch.manual_seed(1234) sensor_size = tonic.datasets.NMNIST.sensor_size frame_transform = transforms.ToFrame(sensor_size=sensor_size, time_window=10000) dataset = tonic.datasets.NMNIST( save_to="./data", train=False, transform=frame_transform ) dataloader_batched = DataLoader( dataset, shuffle=True, batch_size=10, collate_fn=tonic.collation.PadTensors(batch_first=True), ) frames, targets = next(iter(dataloader_batched)) ``` -------------------------------- ### Instantiate SlicedDataset from Metadata Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Re-instantiates a SlicedDataset by loading slicing metadata from a specified path. This is significantly faster than the initial creation. ```python %%time sliced_dataset = SlicedDataset( dataset, slicer=slicer, transform=custom_transform, metadata_path="./metadata/large_datasets", ) ``` -------------------------------- ### Plotting Event Grids for Audio Datasets Source: https://github.com/neuromorphs/tonic/blob/develop/docs/how-tos/visualizing-data.ipynb This snippet demonstrates plotting event grids for audio datasets like SHD. The `axis_array` parameter is ignored for audio datasets with (txp) ordering. ```python shd = tonic.datasets.SHD("../tutorials/data", train=False) audio_events, label = shd[10] tonic.utils.plot_event_grid(audio_events) ``` -------------------------------- ### Importing PyTorch DataLoader Source: https://github.com/neuromorphs/tonic/blob/develop/docs/about/release_notes.rst Previously, tonic.datasets.DataLoader was an alias for the PyTorch DataLoader. Now, you must import it directly from PyTorch. ```python import torch dataloader = torch.utils.data.DataLoader(dataset) ``` -------------------------------- ### Simple Function to Load Samples Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/fast_dataloading.ipynb A basic Python function to iterate through the first 100 samples of a dataset. This is used for initial performance measurement. ```python def load_sample_simple(): for i in range(100): events, target = dataset[i] ``` -------------------------------- ### Initialize Aug_DiskCachedDataset with Transforms Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/Aug_DiskCachDataset.ipynb This snippet demonstrates how to initialize Aug_DiskCachedDataset by defining pre-augmentation, augmentation, and post-augmentation transforms. It ensures that the number of copies corresponds to the number of augmentation parameters. ```python from tonic.audio_augmentations import RandomPitchShift from tonic.audio_transforms import AmplitudeScale, FixLength from tonic.cached_dataset import Aug_DiskCachedDataset, load_from_disk_cache all_transforms = {} all_transforms["pre_aug"] = [AmplitudeScale(max_amplitude=0.150)] all_transforms["augmentations"] = [RandomPitchShift(samplerate=16000, caching=True)] all_transforms["post_aug"] = [FixLength(16000)] # number of copies is set to number of augmentation params (factors) n = len(RandomPitchShift(samplerate=16000, caching=True).factors) Aug_cach = Aug_DiskCachedDataset( dataset=mini_dataset(), cache_path="cache/", all_transforms=all_transforms, num_copies=n, ) ``` -------------------------------- ### Calculate Total Loading Time Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/fast_dataloading.ipynb Calculates and prints the estimated total loading time for a large number of samples and epochs based on the measured average time. ```python print( f"Loading time for 60k samples and 200 epochs: ~{int(_.average * 600 * 200 / 3600)} minutes." ) ``` -------------------------------- ### Calculate Total Loading Time with Cache Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/fast_dataloading.ipynb Calculates and prints the estimated total loading time for a large dataset and multiple epochs when using the `DiskCachedDataset`, highlighting the performance gains. ```python print( f"Loading time for 60k samples and 200 epochs with cache: ~{int(_.average * 600 * 200 / 3600)} minutes." ) ``` -------------------------------- ### Instantiate SlicedDataset Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Creates a SlicedDataset from an existing dataset, applying a custom transform and specifying a path for metadata storage. This operation can be time-consuming for large datasets. ```python %%time sliced_dataset = SlicedDataset( dataset, slicer=slicer, transform=custom_transform, metadata_path="./metadata/large_datasets", ) ``` -------------------------------- ### Disk-Cached Dataset for Faster Epochs Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/fast_dataloading.ipynb Implements dataset caching using Tonic's `DiskCachedDataset`. This wraps an existing dataset, saves processed samples to disk, and reads from the cache in subsequent epochs for significant speedup. ```python from tonic import DiskCachedDataset cached_dataset = DiskCachedDataset(dataset, cache_path="./cache/fast_dataloading") cached_dataloader = DataLoader(cached_dataset, num_workers=2) def load_sample_cached(): for i, (events, target) in enumerate(iter(cached_dataloader)): if i > 99: break ``` -------------------------------- ### Load DAVIS Dataset Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/davis_data.ipynb Loads a sample DAVIS dataset containing events, IMU recordings, and images. The data is saved to the specified directory. ```python import tonic dataset = tonic.datasets.DAVISDATA(save_to="data", recording="shapes_6dof") data, targets = dataset[0] events, imu, images = data ``` -------------------------------- ### Apply Transforms to NMNIST Samples Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/fast_dataloading.ipynb This snippet demonstrates how to apply a sequence of transforms (Denoise and ToFrame) to NMNIST dataset samples using Tonic. It sets up the dataset with a specified transform. ```python import tonic import tonic.transforms as transforms sensor_size = tonic.datasets.NMNIST.sensor_size transform = transforms.Compose( [ transforms.Denoise(filter_time=10000), transforms.ToFrame(sensor_size=sensor_size, n_time_bins=3), ] ) dataset = tonic.datasets.NMNIST(save_to="./data", train=False, transform=transform) ``` -------------------------------- ### Import Tonic and NumPy Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Imports the necessary libraries for working with Tonic datasets and numerical operations. ```python import numpy as np import tonic ``` -------------------------------- ### Initialize SlicedDataset with Custom Slicer Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Wraps the dataset with SlicedDataset, using the custom MultiDataSlicer to define how recordings are chunked. A ToFrame transform is also specified to process each slice. ```python import tonic.transforms as transforms from tonic import SlicedDataset # the time length of one slice of recording slicing_time_window = 200000 slicer = MultiDataSlicer(time_window=slicing_time_window) ``` -------------------------------- ### Slice N-MNIST Dataset by Time Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/slicing.ipynb Demonstrates how to slice the N-MNIST dataset into smaller chunks of a specified time window using SliceByTime. Ensure the dataset and metadata paths are correctly set. ```python import tonic from tonic import SlicedDataset from tonic.slicers import SliceByTime dataset = tonic.datasets.NMNIST(save_to="./data", train=False) slicing_time_window = 50000 # microseconds slicer = SliceByTime(time_window=slicing_time_window) sliced_dataset = SlicedDataset( dataset, slicer=slicer, metadata_path="./metadata/nmnist" ) ``` -------------------------------- ### Applying Room Impulse Response (RIR) Augmentation Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/audio_transforms_tutorial.ipynb Applies RIR augmentation to a sample audio using a specified RIR audio file. Requires numpy, matplotlib, and IPython.display. Ensure the RIR audio file is accessible. ```python import numpy as np from tonic.audio_augmentations import RIR plt.figure(figsize=(10, 5)) plt.subplot(121) plt.plot(sample_audio[0]) plt.grid(True) plt.title("original sample") plt.ylim([-1, 1]) rir_audio_path = "tutorial-assets/Lab41-SRI-VOiCES-rm1-impulse-mc01-stu-clo-8000hz.wav" aug = RIR(samplerate=sample_rate, rir_audio=rir_audio_path) rir = aug(sample_audio) plt.subplot(122) plt.plot(rir[0]) plt.grid(True) plt.title("augmented with room impulse response") plt.ylim([-1, 1]) IPython.display.display( IPython.display.Audio(sample_audio, rate=sample_rate, normalize=True) ) # the original IPython.display.display( IPython.display.Audio(rir[0], rate=sample_rate, normalize=True) ) # ``` -------------------------------- ### Apply ToFrame Transform Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_started/nmnist.ipynb Converts event data into frames using a specified sensor size and number of time bins. Requires importing tonic.transforms. ```python import tonic.transforms as transforms sensor_size = tonic.datasets.NMNIST.sensor_size frame_transform = transforms.ToFrame(sensor_size=sensor_size, n_time_bins=3) frames = frame_transform(events) ``` -------------------------------- ### Define a Mini Dataset Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/Aug_DiskCachDataset.ipynb This code defines a simple PyTorch Dataset class named 'mini_dataset' that generates random data samples. It includes basic structure for transformations and target transformations. ```python # %%writefile mini_dataset.py import warnings warnings.filterwarnings("ignore") import numpy as np from torch.utils.data import Dataset class mini_dataset(Dataset): def __init__(self) -> None: super().__init__() np.random.seed(0) self.data = np.random.rand(10, 16000) self.transform = None self.target_transform = None def __getitem__(self, index): sample = self.data[index] label = 1 if sample.ndim == 1: sample = sample[None, ...] if self.transform is not None: sample = self.transform(sample) if self.target_transform is not None: label = self.target_transform(label) return sample, label ``` -------------------------------- ### Print Sliced Dataset Size Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/slicing.ipynb Prints the number of samples in the original dataset and the newly created sliced dataset to show the effect of slicing. ```python print( f"Went from {len(dataset)} samples in the original dataset to {len(sliced_dataset)} in the sliced version." ) ``` -------------------------------- ### Display Batch Targets Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/batching.ipynb Shows the target labels for the batched event frames. ```python targets ``` -------------------------------- ### Instantiate CachedDataset Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Wraps a SlicedDataset with CachedDataset to enable caching of individual slices to disk. This speeds up subsequent access to the same slices. ```python from tonic import CachedDataset, SlicedDataset cached_dataset = CachedDataset(sliced_dataset, cache_path="./cache/large_datasets") ``` -------------------------------- ### Custom Tonic Dataset Class Source: https://github.com/neuromorphs/tonic/blob/develop/docs/how-tos/wrapping_own_data.ipynb Defines a custom dataset class 'MyRecordings' that inherits from Tonic's Dataset. It loads event data from numpy files and applies transformations. ```python class MyRecordings(Dataset): sensor_size = ( 200, 100, 2, ) # the sensor size of the event camera or the number of channels of the silicon cochlear that was used ordering = ( "xytp" # the order in which your event channels are provided in your recordings ) def __init__( self, train=True, transform=None, target_transform=None, ): super(MyRecordings, self).__init__( save_to="./", transform=transform, target_transform=target_transform ) self.train = train # replace the strings with your training/testing file locations or pass as an argument if train: self.filenames = [ f"../tutorials/data/recording{i}.npy" for i in range(n_recordings) ] else: raise NotImplementedError def __getitem__(self, index): events = np.load(self.filenames[index]) if self.transform is not None: events = self.transform(events) return events def __len__(self): return len(self.filenames) ``` -------------------------------- ### Inspect N-MNIST Sample Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_started/nmnist.ipynb Access individual samples from the N-MNIST dataset. Returns events and the target class. ```python events, target = dataset[1000] events ``` -------------------------------- ### Download DAVIS Dataset Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Downloads the DAVIS dataset, specifying the save location and the desired recordings (shapes_6dof, shapes_rotation). ```python dataset = tonic.datasets.DAVISDATA( save_to="./data", recording=["shapes_6dof", "shapes_rotation"] ) ``` -------------------------------- ### Verify Cached Copies Against Generated Samples Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/Aug_DiskCachDataset.ipynb This snippet verifies that the data loaded from the disk cache matches the data generated directly from the dataset with the same augmentation parameters. It iterates through all generated copies and compares them. ```python from torchvision.transforms import Compose for i in range(n): transform = Compose( [ AmplitudeScale(max_amplitude=0.150), RandomPitchShift(samplerate=16000, caching=True, aug_index=i), FixLength(16000), ] ) ds = mini_dataset() ds.transform = transform sample = ds[sample_index][0] data, targets = load_from_disk_cache("cache/" + "0_" + str(i) + ".hdf5") print((sample == data).all()) ``` -------------------------------- ### Creating Event Animations Source: https://github.com/neuromorphs/tonic/blob/develop/docs/how-tos/visualizing-data.ipynb Generate matplotlib animations from event data using `tonic.utils.plot_animation`. This requires transforming the events into frames first using `tonic.transforms.ToFrame`. ```python transform = tonic.transforms.ToFrame( sensor_size=nmnist.sensor_size, time_window=20000, ) frames = transform(events) animation = tonic.utils.plot_animation(frames=frames) ``` -------------------------------- ### PyTorch DataLoader with Multithreading Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/fast_dataloading.ipynb This snippet demonstrates using PyTorch's DataLoader with `num_workers` to enable multithreaded data loading, improving performance. It iterates through the first 100 samples. ```python from torch.utils.data import DataLoader dataloader = DataLoader(dataset, num_workers=2, shuffle=True) def load_sample_pytorch(): for i, (events, target) in enumerate(iter(dataloader)): if i > 99: break ``` -------------------------------- ### Check Disk Footprint of Cached Slice Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Calculates and prints the disk space occupied by a single slice in the cache directory. Demonstrates the space savings achieved through caching and compression. ```python from pathlib import Path print( f"Last slice takes {sum(p.stat().st_size for p in Path('./cache/large_datasets').rglob('*')) / 1e6} MB on disk." ) ``` -------------------------------- ### Convert Events to Voxel Grid Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_started/nmnist.ipynb Transforms denoised event data into a voxel grid representation. Requires sensor size and time bins. ```python volume = transforms.ToVoxelGrid(sensor_size=sensor_size, n_time_bins=3)(events_denoised) fig, axes = plt.subplots(1, len(volume)) for axis, slice in zip(axes, volume, strict=False): axis.imshow(slice[0]) axis.axis("off") plt.tight_layout() ``` -------------------------------- ### Access Slice for the First Time Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Accesses a specific slice from the CachedDataset for the first time. This triggers loading the full recording, slicing, applying transforms, and caching the data. ```python %%time # first time access (event_frames, imu, images), targets = cached_dataset[1] ``` -------------------------------- ### Load Dataset with Custom Transform Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/davis_data.ipynb Loads the DAVIS dataset again, this time applying the previously defined custom data transformation function. ```python dataset = tonic.datasets.DAVISDATA( save_to="./data", recording="slider_depth", transform=data_transform ) data, targets = dataset[0] frames_cropped, imu, images_cropped = data ``` -------------------------------- ### Load Data with PyTorch DataLoader Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_started/nmnist.ipynb Uses a PyTorch DataLoader to efficiently load transformed N-MNIST data with shuffling. Sets a manual seed for reproducibility. ```python import torch torch.manual_seed(1234) dataloader = torch.utils.data.DataLoader(dataset, shuffle=True) frames, target = next(iter(dataloader)) plot_frames(frames.squeeze()) ``` -------------------------------- ### Print Sliced Dataset Information Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Prints the original dataset size and the number of slices created. Useful for verifying the slicing operation. ```python print(f"Cut a dataset of {len(dataset)} recording into {len(sliced_dataset)} slices.") ``` -------------------------------- ### Load N-MNIST Dataset Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_started/nmnist.ipynb Loads the N-MNIST dataset. Specify the save location and whether to load training or testing data. ```python import tonic dataset = tonic.datasets.NMNIST(save_to="../tutorials/data", train=False) ``` -------------------------------- ### Custom Multi-Data Slicer Implementation Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Implements a custom slicer for handling multiple data types (events, IMU, images) within a recording. It defines how to extract slices based on time windows and how to process each slice. ```python from dataclasses import dataclass from typing import Any @dataclass class MultiDataSlicer: time_window: float overlap: float = 0.0 include_incomplete: bool = False # this method receives all the data for one recording/sample. # Based on the timestamps in there, we'll work out the boundaries # of slices, in this case according to a time window. This method # is called once per sample. def get_slice_metadata(self, data, targets): events, imu, images = data min_ts = min(min(events["t"])), min(imu["ts"])), min(images["ts"])) max_ts = max(max(events["t"])), max(imu["ts"])), max(images["ts"])) stride = self.time_window - self.overlap if self.include_incomplete: n_slices = int(np.ceil(((max_ts - min_ts) - self.time_window) / stride) + 1) else: n_slices = int( np.floor(((max_ts - min_ts) - self.time_window) / stride) + 1 ) window_start_times = np.arange(n_slices) * stride + min_ts window_end_times = window_start_times + self.time_window return list(zip(window_start_times, window_end_times, strict=False)) # Even if we are only interested in a single slice, the data is still stored in a file for the # whole recording. To access that slice, we thus need to load the whole recording and then pick # the part of it that we are interested in. This method receives the whole data recording and # metadata about where a slice starts and stops. This can be timestamps, indices or other things. # In this example we just copy the targets for each new slice by passing them along. @staticmethod def slice_with_metadata( data: tuple[Any], targets: tuple[Any], metadata: list[tuple[int, int]] ): events, imu, images = data # this is data for a whole recording start, stop = metadata[0][0], metadata[0][1] event_slice = events[np.logical_and(events["t"] >= start, events["t"] < stop)] imu_slice = {} imu_slice["ts"] = imu["ts"][ np.logical_and(imu["ts"] >= start, imu["ts"] < stop) ] imu_slice["rotQ"] = imu["rotQ"][ np.logical_and(imu["ts"] >= start, imu["ts"] < stop) ] imu_slice["angV"] = imu["angV"][ np.logical_and(imu["ts"] >= start, imu["ts"] < stop) ] imu_slice["acc"] = imu["acc"][ np.logical_and(imu["ts"] >= start, imu["ts"] < stop) ] imu_slice["mag"] = imu["mag"][ np.logical_and(imu["ts"] >= start, imu["ts"] < stop) ] image_slice = {} image_slice["ts"] = images["ts"][ np.logical_and(images["ts"] >= start, images["ts"] < stop) ] image_slice["frames"] = images["frames"][ np.logical_and(images["ts"] >= start, images["ts"] < stop) ] return (event_slice, imu_slice, image_slice), targets ``` -------------------------------- ### Print Loaded Events Source: https://github.com/neuromorphs/tonic/blob/develop/docs/how-tos/wrapping_own_data.ipynb Prints the loaded events from the dataset or dataloader. This is useful for inspecting the data after loading and transformation. ```python print(events) ``` -------------------------------- ### Generate All Copies of a Data Sample Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/Aug_DiskCachDataset.ipynb This code generates all augmented copies for a specific data sample (index 0) using the initialized Aug_DiskCachedDataset. This is useful for pre-computing and caching augmented versions of your data. ```python sample_index = 0 Aug_cach.generate_all(sample_index) ``` -------------------------------- ### Plotting Event Grids for NMNIST Source: https://github.com/neuromorphs/tonic/blob/develop/docs/how-tos/visualizing-data.ipynb Use `tonic.utils.plot_event_grid` to visualize event data from datasets like NMNIST. The `axis_array` parameter can be used to specify the dimensions for plotting. ```python import tonic nmnist = tonic.datasets.NMNIST("../tutorials/data", train=False) events, label = nmnist[10] tonic.utils.plot_event_grid(events, axis_array=(1, 5)) ``` -------------------------------- ### Run Specific Tests with Filter Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_involved/contribute.rst Run a subset of tests by filtering based on a test name. This is useful for focusing on specific functionalities during development. ```bash python -m pytest -k my_test_name ``` -------------------------------- ### Compose and Apply Transforms to Dataset Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_started/nmnist.ipynb Chains multiple transforms (Denoise, ToFrame) and applies them to the N-MNIST dataset. Transforms are automatically applied on sample loading. ```python transform = transforms.Compose([denoise_transform, frame_transform]) dataset = tonic.datasets.NMNIST( save_to="../tutorials/data", train=False, transform=transform ) ``` -------------------------------- ### Convert Events to Time Surface Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_started/nmnist.ipynb Generates time surfaces from denoised event data. Requires sensor size, time delta (dt), and tau. ```python surfaces = transforms.ToTimesurface(sensor_size=sensor_size, dt=99000, tau=100000)( events_denoised ) n_events = events_denoised.shape[0] n_events_per_slice = n_events // 3 fig, axes = plt.subplots(1, 3) for i, axis in enumerate(axes): surf = surfaces[i] axis.imshow(surf[0] - surf[1]) axis.axis("off") plt.tight_layout() ``` -------------------------------- ### Display Rotated Frames Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/slicing.ipynb Uses matplotlib to display the first frame of the retrieved, rotated data. Requires the matplotlib and %matplotlib inline magic command to be set up. ```python %matplotlib inline import matplotlib.pyplot as plt plt.imshow(rotated_frames[0]); ``` -------------------------------- ### Verify Event Count After Transform Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/slicing.ipynb Confirms that the total number of spikes (sum of events in frames) matches the original number of events before the transform was applied. ```python print("Number of spikes: " + str(frames.sum())) assert frames.sum() == len(events) ``` -------------------------------- ### Load Raw Events with PyTorch DataLoader Source: https://github.com/neuromorphs/tonic/blob/develop/docs/how-tos/loading-raw-events.ipynb Use `tonic.transforms.NumpyAsType` to convert structured NumPy arrays to unstructured ones, enabling PyTorch's DataLoader to process raw events efficiently with multiprocessing. Note that batching operations are not supported for raw events due to variable sample lengths. ```python import tonic # converts structured numpy arrays to unstructured ones transform = tonic.transforms.NumpyAsType(int) nmnist = tonic.datasets.NMNIST("../tutorials/data", train=False, transform=transform) from torch.utils.data import DataLoader dataloader = DataLoader(nmnist, shuffle=True, num_workers=2) events, label = next(iter(dataloader)) print(events) ``` -------------------------------- ### Measure Augmented Disk-Cached Dataset Performance Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/fast_dataloading.ipynb Measures the execution time of loading augmented samples from the `DiskCachedDataset`. This tests the performance of applying both cached transforms and on-the-fly augmentations. ```python %timeit -r 20 load_sample_augmented() ``` -------------------------------- ### Plot Frames Source: https://github.com/neuromorphs/tonic/blob/develop/docs/getting_started/nmnist.ipynb Helper function to plot frames, useful for visualizing event camera data. Requires matplotlib. ```python %matplotlib inline import matplotlib.pyplot as plt def plot_frames(frames): fig, axes = plt.subplots(1, len(frames)) for axis, frame in zip(axes, frames, strict=False): axis.imshow(frame[1] - frame[0]) axis.axis("off") plt.tight_layout() plot_frames(frames) ``` -------------------------------- ### Access Event Timestamps Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/davis_data.ipynb Retrieves the timestamps for the events from the loaded dataset. ```python events["t"] ``` -------------------------------- ### Access Image Timestamps Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/davis_data.ipynb Retrieves the timestamps for the images from the loaded dataset. ```python images["ts"] ``` -------------------------------- ### Access Slice for the Second Time Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Accesses the same slice from the CachedDataset again. This time, the data is loaded directly from the cache, resulting in faster access. ```python %%time # second time access (event_frames, imu, images), targets = cached_dataset[1] ``` -------------------------------- ### Apply Transform Post-Slicing Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/slicing.ipynb Creates a new SlicedDataset instance with a transform (ToImage) applied to each slice after it's loaded. This is useful for converting event data into image frames. ```python frame_transform = tonic.transforms.ToImage( sensor_size=tonic.datasets.NMNIST.sensor_size ) sliced_dataset = SlicedDataset( dataset, slicer=slicer, transform=frame_transform, metadata_path="./metadata/nmnist" ) ``` -------------------------------- ### Measure PyTorch DataLoader Performance Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/fast_dataloading.ipynb Measures the execution time of loading a single sample using the PyTorch DataLoader with multithreading enabled. ```python %timeit load_sample_pytorch() ``` -------------------------------- ### Cache Sliced Dataset with Augmentation Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/slicing.ipynb Wraps a SlicedDataset in MemoryCachedDataset to store slices in memory for faster retrieval. Includes a Compose transform for applying multiple augmentations, such as random rotation. ```python import torch import torchvision from tonic import MemoryCachedDataset torch.manual_seed(1234) augmentation = tonic.transforms.Compose( [torch.tensor, torchvision.transforms.RandomRotation([-45, 45])] ) augmented_dataset = MemoryCachedDataset(sliced_dataset, transform=augmentation) ``` -------------------------------- ### Plot Processed Event Frame and Image Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/davis_data.ipynb Visualizes a processed event frame and a corresponding grey-level image side-by-side using matplotlib. Requires matplotlib and inline plotting to be enabled. ```python %matplotlib inline import matplotlib as mpl import matplotlib.pyplot as plt fig, (ax1, ax2) = plt.subplots(1, 2) event_frame = frames_cropped[10] ax1.imshow(event_frame[0] - event_frame[1]) ax1.set_title("event frame") ax2.imshow(images_cropped[10], cmap=mpl.cm.gray) ax2.set_title("grey level image"); ``` -------------------------------- ### Add White Noise to Audio Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/audio_transforms_tutorial.ipynb Adds white noise to an audio sample. This augmentation can be used to introduce background noise. ```python from tonic.audio_augmentations import AddWhiteNoise plt.figure(figsize=(10, 5)) plt.subplot(121) plt.plot(sample_audio[0]) plt.grid(True) plt.title("original sample") aug = AddWhiteNoise(samplerate=sample_rate) noisy = aug(sample_audio) plt.subplot(122) plt.plot(noisy[0]) plt.grid(True) plt.title("augmented with white noise") IPython.display.display( IPython.display.Audio(sample_audio, rate=sample_rate, normalize=True) # the original ) IPython.display.display( IPython.display.Audio(noisy[0], rate=sample_rate, normalize=True) # ) ``` -------------------------------- ### Verify Slice Data Source: https://github.com/neuromorphs/tonic/blob/develop/docs/tutorials/large_datasets.ipynb Prints the shapes and time ranges of event frames, images, and IMU data for a given slice. Used to verify the integrity of the loaded data. ```python print( f"Event frames have a shape of {event_frames.shape},\nimages for this slice have a shape of {images['frames'].shape} and go from {images['ts'][0]} to {images['ts'][-1]} microseconds\nand imu time stamps range from {imu['ts'][0]} to {imu['ts'][-1]} microseconds." ) ```