A fast AEDAT4 decoder with an underlying Rust implementation
Project description
AEDAT
AEDAT is a fast AEDAT 4 python reader, with a Rust underlying implementation.
Run pip install aedat
to install it.
Documentation
The aedat
library provides a single class: Decoder
. A decoder object is created by passing a file name to Decoder
. The file name must be a path-like object.
Here's a short example:
import aedat
decoder = aedat.Decoder('/path/to/file.aedat')
print(decoder.id_to_stream())
for packet in decoder:
print(packet['stream_id'], end=': ')
if 'events' in packet:
print('{} polarity events'.format(len(packet['events'])))
elif 'frame' in packet:
print('{} x {} frame'.format(packet['frame']['width'], packet['frame']['height']))
elif 'imus' in packet:
print('{} IMU samples'.format(len(packet['imus'])))
elif 'triggers' in packet:
print('{} trigger events'.format(len(packet['triggers'])))
And the same example with detailed comments:
import aedat
decoder = aedat.Decoder('/path/to/file.aedat')
"""
decoder is a packet iterator with an additional method id_to_stream
id_to_stream returns a dictionary with the following structure:
{
<int>: {
'type': <str>,
}
}
type is one of 'events', 'frame', 'imus', 'triggers'
if type is 'events' or 'frame', its parent dictionary has the following structure:
{
'type': <str>,
'width': <int>,
'height': <int>,
}
"""
print(decoder.id_to_stream())
for packet in decoder:
"""
packet is a dictionary with the following structure:
{
'stream_id': <int>,
}
packet also has exactly one of the following fields:
'events', 'frame', 'imus', 'triggers'
"""
print(packet['stream_id'], end=': ')
if 'events' in packet:
"""
packet['events'] is a structured numpy array with the following dtype:
[
('t', '<u8'),
('x', '<u2'),
('y', '<u2'),
('on', '?'),
]
"""
print('{} polarity events'.format(len(packet['events'])))
elif 'frame' in packet:
"""
packet['frame'] is a dictionary with the following structure:
{
't': <int>,
'begin_t': <int>,
'end_t': <int>,
'exposure_begin_t': <int>,
'exposure_end_t': <int>,
'format': <str>,
'width': <int>,
'height': <int>,
'offset_x': <int>,
'offset_y': <int>,
'pixels': <numpy.array(shape=(height, width), dtype=uint8)>,
}
format is one of 'Gray', 'BGR', 'BGRA'
"""
print('{} x {} frame'.format(packet['frame']['width'], packet['frame']['height']))
elif 'imus' in packet:
"""
packet['imus'] is a structured numpy array with the following dtype:
[
('t', '<u8'),
('temperature', '<f4'),
('accelerometer_x', '<f4'),
('accelerometer_y', '<f4'),
('accelerometer_z', '<f4'),
('gyroscope_x', '<f4'),
('gyroscope_y', '<f4'),
('gyroscope_z', '<f4'),
('magnetometer_x', '<f4'),
('magnetometer_y', '<f4'),
('magnetometer_z', '<f4'),
]
"""
print('{} IMU samples'.format(len(packet['imus'])))
elif 'triggers' in packet:
"""
packet['triggers'] is a structured numpy array with the following dtype:
[
('t', '<u8'),
('source', 'u1'),
]
the source value has the following meaning:
0: timestamp reset
1: external signal rising edge
2: external signal falling edge
3: external signal pulse
4: external generator rising edge
5: external generator falling edge
6: frame begin
7: frame end
8: exposure begin
9: exposure end
"""
print('{} trigger events'.format(len(packet['triggers'])))
Because the lifetime of the file handle is managed by Rust, decoder objects are not compatible with the with statement. To ensure garbage collection, point the decoder variable to something else, for example None
, when you are done using it:
import aedat
decoder = aedat.Decoder('/path/to/file.aedat')
# do something with decoder
decoder = None
Install from source
This library requires Python 3.x, x >= 5, and NumPy. This guide assumes that they are installed on your machine.
Note for Windows users: this library requires the x86-64 version of Python. You can download it here: https://www.python.org/downloads/windows/ (the default installer contains the x86 version).
A Rust compiling toolchain is required during the installation (but can be removed afterwards).
Linux
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
git clone https://github.com/neuromorphicsystems/aedat.git
cd aedat
cargo build --release
cp target/release/libaedat.so aedat.so
You can import aedat
from python scripts in the same directory as aedat.so, which can be placed in any directory.
macOS
brew install rustup
rustup-init
git clone https://github.com/neuromorphicsystems/aedat.git
cd aedat
cargo build --release
cp target/release/libaedat.dylib aedat.so
You can import aedat
from python scripts in the same directory as aedat.so, which can be placed in any directory.
Windows
- install rustup (instructions availables at https://www.rust-lang.org/tools/install)
- clone or download this repository
- run in PowerShell from the aedat directory:
cargo build --release
copy .\target\release\aedat.dll .\aedat.pyd
You can import aedat
from python scripts in the same directory as aedat.pyd, which can be placed in any directory.
Contribute
After changing any of the files in framebuffers, one must run:
flatc --rust -o src/ flatbuffers/*.fbs
To format the code, run:
cargo fmt
You may need to install rustfmt first with:
rustup component add rustfmt
Publish
Requirements
- Build the Docker image for Linux builds
docker build manylinux -t manylinux
- Install all the Pythons for macOS
brew install pyenv
pyenv global 3.6.12 3.7.9 3.8.7 3.9.1
pip install maturin
pip install twine
- Download the base Vagrant box for Windows builds
vagrant box add gusztavvargadr/windows-10
Build and publish
rm -rf target
eval "$(pyenv init -)"
maturin publish
docker run --rm -v $(pwd):/io manylinux maturin build --release --strip
cd windows
vagrant up
vagrant destroy -f
cd ..
twine upload --skip-existing target/wheels/*
Note: The second maturin
call (i686 target) during the Windows build compiles the dependencies properly, but fails for the library itself (error: Unrecognized option: 'toolchain'
). The third maturin
call completes the compilation.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for aedat-1.1.0-cp39-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 27adef361f44f677d56cac16d7b17a60f8676953752c21f2faf2b1a39e861f62 |
|
MD5 | b31d5ec132131c39668ec26b3806b460 |
|
BLAKE2b-256 | ec4960838b1a2dbf22380376ac318ea49d9256185db9727362114bad29b7e649 |
Hashes for aedat-1.1.0-cp39-cp39-manylinux2010_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9fcd9b6a3937eb50dd779cbaf0cf370caed099d8f19d0da2b8bf2ae0f618f819 |
|
MD5 | ba656aac476213564d19ecda6b0d6fb6 |
|
BLAKE2b-256 | fce30ab352d627a2ff16eab4d7bfdade8793717b107d2fd6256bba92635eb00c |
Hashes for aedat-1.1.0-cp39-cp39-macosx_10_7_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8ef42b587f079c20a515e5a3e2a223e0c3f418eda724bdf5ce63cacfedf9b92e |
|
MD5 | 4d9265dd126d6f3ff9362a80ad0092f9 |
|
BLAKE2b-256 | 65b0b5ca48783c9df71f72c7ca4e952d2f2f6bdeaa23a559008e72a7e373c2c1 |
Hashes for aedat-1.1.0-cp38-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 113c340f988d146908b96d2805c47fa02f30bd373f5196ce66e44c94523a6d0c |
|
MD5 | 3b4142b0905456698a1147d486ad25d3 |
|
BLAKE2b-256 | e02825175d8bbec45f5daad535beeba2295ac0263b525e2fe2f6367bbfe5cae5 |
Hashes for aedat-1.1.0-cp38-cp38-manylinux2010_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 48526b25c56435421896e0ca521aeeb2e4aa6e3ca8bdef05c4df7d38ade17d2b |
|
MD5 | 4afca49814547895117ca47a4ecb10ce |
|
BLAKE2b-256 | 75e8c6a978b3c2912eb1890fff782aec33821b808f89508f0ddbfbf3a3e43f67 |
Hashes for aedat-1.1.0-cp38-cp38-macosx_10_7_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 743a32e81108419dfba5ba895a1ad480127b4c6c3d036b5aa978038e64120c89 |
|
MD5 | 2ca0a80588b6f048d0c25c457f893733 |
|
BLAKE2b-256 | ffce35ac551e072ca4f6e818228d9c0852446cd0e400ac80e50f95b5bd034c2f |
Hashes for aedat-1.1.0-cp37-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 66cd53b9d772c0fad9e7a12a51d9fc1d59add232c2b4186abead16678a4d8178 |
|
MD5 | 295c1bc1019dd7f8ae121af6079fd954 |
|
BLAKE2b-256 | 305cdc4f0f77d6eded4a00e2754ce1fcbf356557410c3ca61abec7ea89c46db6 |
Hashes for aedat-1.1.0-cp37-cp37m-manylinux2010_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 904535bed4cdfc7abd793ca6b51901499382e1141dc3cb0882a41b1644957483 |
|
MD5 | bf2c9655095037ee84386f471501b50a |
|
BLAKE2b-256 | bd8be81c6817fc9e6a9f680d81364e61cc447a3dbdb6f56645a4942cb5cf5636 |
Hashes for aedat-1.1.0-cp37-cp37m-macosx_10_7_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 48b9770c4a8f21ea9f00edc7f66add0ccb1e1b1c9a3f3aadeac02fb82c0b54f6 |
|
MD5 | 4e6bffe5212fc7a26c13e971194594a3 |
|
BLAKE2b-256 | f62f6499108cfb03962afc0a605ac4eacfb4fd181544394a7ef59a8e3509139d |
Hashes for aedat-1.1.0-cp36-none-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f54357c56a1e3e8f396d3f9dc8c2c107d0c281f3cf148269ebcd0c81f972e055 |
|
MD5 | fea215b8afad8b7123eb704c8ea62f8e |
|
BLAKE2b-256 | 72442ed4bdcd69c48a907ca3b6be4856fde1e2c23f4ccdfed025848002f33dfb |
Hashes for aedat-1.1.0-cp36-cp36m-manylinux2010_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b979a1e9e7944e7b4218adf66b3038a6895f7fe1659fdd5b7290f8a81558c6e1 |
|
MD5 | 45704cf9f7ce1b26ba82159486fc9df2 |
|
BLAKE2b-256 | 62ae136a99dfdcbf1075203010e5a68bfc0718cb6d2f1d5ffb91229dcf827d3e |
Hashes for aedat-1.1.0-cp36-cp36m-macosx_10_7_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | eee86ac843badf68b16712659c7e718233e39d81e16ca67b44a5bc2680a75b83 |
|
MD5 | b3b574f578dad359347523c04afcd40e |
|
BLAKE2b-256 | 9585163e842c1df89ab4f9d90e70e2434190fc46df9a4df8f53d8de9ef95e3ea |