evlib


Nameevlib JSON
Version 0.2.3 PyPI version JSON
download
home_pagehttps://github.com/tallamjr/evlib
SummaryPython bindings for event camera utilities
upload_time2025-07-18 17:51:49
maintainerNone
docs_urlNone
authorTarek Allam <t.allam.jr@gmail.com>
requires_python>=3.10
licenseMIT
keywords event-camera vision rust python pyo3
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <table align="center">
  <tr>
    <td>
      <img src="./docs/evlogo.png" width="70" alt="evlib logo" />
    </td>
    <td>
      <h1 style="margin: 0;">
        <code>evlib</code>: Event Camera Data Processing Library
      </h1>
    </td>
  </tr>
</table>

<div style="text-align: center;" align="center">

[![PyPI Version](https://img.shields.io/pypi/v/evlib.svg)](https://pypi.org/project/evlib/)
[![Python Versions](https://img.shields.io/pypi/pyversions/evlib.svg)](https://pypi.org/project/evlib/)
[![Documentation](https://readthedocs.org/projects/evlib/badge/?version=latest)](https://evlib.readthedocs.io/en/latest/?badge=latest)
[![Python](https://github.com/tallamjr/evlib/actions/workflows/pytest.yml/badge.svg)](https://github.com/tallamjr/evlib/actions/workflows/pytest.yml)
[![Rust](https://github.com/tallamjr/evlib/actions/workflows/rust.yml/badge.svg)](https://github.com/tallamjr/evlib/actions/workflows/rust.yml)
[![License](https://img.shields.io/github/license/tallamjr/evlib)](https://github.com/tallamjr/evlib/blob/master/LICENSE.md)

</div>

A robust event camera processing library with Rust backend and Python bindings, designed for reliable data processing with real-world event camera datasets.

## Current Status (v0.2.3)

**Fully Working Features:**
- Universal format support (H5, AEDAT, EVT2/3, AER, text)
- Automatic format detection
- Polars DataFrame integration (up to 97x speedup)
- High-performance event filtering
- Event representations (stacked histograms, voxel grids)
- Neural network model loading (E2VID)
- Large file support (tested with 200M+ events)

**In Development:**
- Advanced neural network processing (Rust backend temporarily disabled)
- Real-time visualization (Rust backend temporarily disabled)

**Note**: The core functionality is stable and production-ready. The Rust backend currently focuses on data loading and processing, with Python modules providing advanced features like filtering and representations.

## Core Features

- **Universal Format Support**: Load data from H5, AEDAT, EVT2/3, AER, and text formats
- **Automatic Format Detection**: No need to specify format types manually
- **Polars DataFrame Integration**: High-performance DataFrame operations with up to 97x speedup
- **Event Filtering**: Comprehensive filtering with temporal, spatial, and polarity options
- **Event Representations**: Stacked histograms, voxel grids, and mixed density stacks
- **Neural Network Models**: E2VID model loading and inference
- **Real-time Data Processing**: Handle large datasets (550MB+ files) efficiently
- **Polarity Encoding**: Automatic conversion between 0/1 and -1/1 polarities
- **Rust Performance**: Memory-safe, high-performance backend with Python bindings

## Quick Start

### Basic Usage
```python
import evlib

# Load events from any supported format (automatic detection)
df = evlib.load_events("path/to/your/data.h5").collect()

# Or load as LazyFrame for memory-efficient processing
lf = evlib.load_events("path/to/your/data.h5")

# Basic event information
print(f"Loaded {len(df)} events")
print(f"Resolution: {df['x'].max()} x {df['y'].max()}")
print(f"Duration: {df['timestamp'].max() - df['timestamp'].min()}")

# Convert to NumPy arrays for compatibility
x_coords = df['x'].to_numpy()
y_coords = df['y'].to_numpy()
timestamps = df['timestamp'].to_numpy()
polarities = df['polarity'].to_numpy()
```

### Advanced Filtering
```python
import evlib.filtering as evf

# High-level preprocessing pipeline
processed = evf.preprocess_events(
    "path/to/your/data.h5",
    t_start=0.1, t_end=0.5,
    roi=(100, 500, 100, 400),
    polarity=1,
    remove_hot_pixels=True,
    remove_noise=True,
    hot_pixel_threshold=99.9,
    refractory_period_us=1000
)

# Individual filters (work with LazyFrames)
events = evlib.load_events("path/to/your/data.h5")
time_filtered = evf.filter_by_time(events, t_start=0.1, t_end=0.5)
spatial_filtered = evf.filter_by_roi(time_filtered, x_min=100, x_max=500, y_min=100, y_max=400)
clean_events = evf.filter_hot_pixels(spatial_filtered, threshold_percentile=99.9)
denoised = evf.filter_noise(clean_events, method="refractory", refractory_period_us=1000)
```

### Event Representations
```python
import evlib.representations as evr

# Create stacked histogram (replaces RVT preprocessing)
hist = evr.create_stacked_histogram(
    "path/to/your/data.h5",
    height=480, width=640,
    nbins=10, window_duration_ms=50.0,
    count_cutoff=10
)

# Create mixed density stack representation
density = evr.create_mixed_density_stack(
    "path/to/your/data.h5",
    height=480, width=640,
    nbins=10, window_duration_ms=50.0
)

# Create voxel grid representation
voxel = evr.create_voxel_grid(
    "path/to/your/data.h5",
    height=480, width=640,
    nbins=5
)

# High-level preprocessing for neural networks
data = evr.preprocess_for_detection(
    "path/to/your/data.h5",
    representation="stacked_histogram",
    height=480, width=640,
    nbins=10, window_duration_ms=50
)

# Performance benchmarking against RVT
results = evr.benchmark_vs_rvt("path/to/your/data.h5", height=480, width=640)
```

## Installation

### Basic Installation
```bash
pip install evlib

# For Polars DataFrame support (recommended)
pip install evlib[polars]
```

### Development Installation
```bash
# Clone the repository
git clone https://github.com/tallamjr/evlib.git
cd evlib

# Create virtual environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install in development mode with all features
pip install -e ".[dev,polars]"

# Build the Rust extensions
maturin develop
```

### System Dependencies
```bash
# Ubuntu/Debian
sudo apt install libhdf5-dev pkg-config

# macOS
brew install hdf5 pkg-config
```

### Performance-Optimized Installation

For optimal performance, ensure you have the recommended system configuration:

**System Requirements:**
- **RAM**: 8GB+ recommended for files >100M events
- **Python**: 3.10+ (3.12 recommended for best performance)
- **Polars**: Latest version for advanced DataFrame operations

**Installation for Performance:**
```bash
# Install with Polars support (recommended)
pip install "evlib[polars]"

# For development with all performance features
pip install "evlib[dev,polars]"

# Verify installation with benchmark
python -c "import evlib; print('evlib installed successfully')"
python benchmark_memory.py  # Test memory efficiency
```

**Optional Performance Dependencies:**
```bash
# For advanced memory monitoring
pip install psutil

# For parallel processing (already included in dev)
pip install multiprocessing-logging
```

## Polars DataFrame Integration

evlib provides comprehensive Polars DataFrame support for high-performance event data processing:

### Key Benefits
- **Performance**: Up to 97x faster filtering compared to NumPy arrays
- **Memory Efficiency**: Optimized data structures reduce memory usage
- **Expressive Queries**: SQL-like operations for complex data analysis
- **Lazy Evaluation**: Query optimization for better performance
- **Ecosystem Integration**: Seamless integration with data science tools

### API Overview

#### Loading Data
```python
# Load as LazyFrame (recommended)
events = evlib.load_events("data.h5")
df = events.collect()  # Collect to DataFrame when needed

# Automatic format detection and optimization
events = evlib.load_events("data.evt2")  # EVT2 format automatically detected
print(f"Format: {evlib.detect_format('data.evt2')}")
print(f"Description: {evlib.get_format_description('EVT2')}")

# Direct Rust access (returns NumPy arrays)
x, y, t, p = evlib.formats.load_events("data.h5")
```

#### Advanced Features
```python
import polars as pl

# Chain operations with LazyFrames for optimal performance
events = evlib.load_events("data.h5")
result = events.filter(pl.col("polarity") == 1).with_columns([
    pl.col("timestamp").dt.total_microseconds().alias("time_us"),
    (pl.col("x") + pl.col("y")).alias("diagonal_pos")
]).collect()

# Memory-efficient temporal analysis
temporal_stats = events.group_by_dynamic(
    "timestamp",
    every="1s"
).agg([
    pl.len().alias("event_count"),
    pl.col("polarity").mean().alias("avg_polarity")
]).collect()

# Combine with filtering module for complex operations
import evlib.filtering as evf
filtered = evf.filter_by_time(events, t_start=0.1, t_end=0.5)
analysis = filtered.with_columns([
    pl.col("timestamp").dt.total_microseconds().alias("time_us")
]).collect()
```

#### Utility Functions
```python
import polars as pl
import evlib.filtering as evf

# Built-in format detection
format_info = evlib.detect_format("data.h5")
print(f"Detected format: {format_info}")

# Spatial filtering using dedicated filtering functions (preferred)
events = evlib.load_events("data.h5")
spatial_filtered = evf.filter_by_roi(events, x_min=100, x_max=200, y_min=50, y_max=150)

# Or using direct Polars operations
manual_filtered = events.filter(
    (pl.col("x") >= 100) & (pl.col("x") <= 200) &
    (pl.col("y") >= 50) & (pl.col("y") <= 150)
)

# Temporal analysis with Polars operations
rates = events.group_by_dynamic("timestamp", every="10ms").agg([
    pl.len().alias("event_rate"),
    pl.col("polarity").mean().alias("avg_polarity")
]).collect()

# Save processed data
processed = evf.preprocess_events("data.h5", t_start=0.1, t_end=0.5)
x, y, t, p = processed.select(["x", "y", "timestamp", "polarity"]).collect().to_numpy().T
evlib.save_events_to_hdf5(x, y, t, p, "output.h5")
```

## Performance Optimizations

### Memory Efficiency
- **Direct Polars Integration**: Zero-copy architecture with single-pass construction
- **Memory Usage**: ~110 bytes/event including overhead (previously ~200+ bytes/event)
- **Automatic Streaming**: Files >5M events automatically use chunked processing
- **Memory-Efficient Types**: Optimized data types (Int16 for x/y, Int8 for polarity)
- **Scalability**: Support for files up to 1B+ events without memory exhaustion

### Processing Speed
- **Load Speed**: 600k+ events/s for typical files (measured on real datasets)
- **Filter Speed**: 400M+ events/s using LazyFrame operations
- **Streaming Performance**: 1M+ events/s for large files (>100M events)
- **Format Support**: All formats (EVT2, HDF5, Text) optimized with format-specific encoding

### Scalability Features
- **LazyFrame Processing**: Memory-efficient operations without full materialization
- **Direct Polars Integration**: Zero-copy construction for optimal memory usage
- **Large File Support**: Tested with files up to 1.6GB (200M+ events)
- **Error Recovery**: Graceful handling of memory constraints and large files

### Benchmarking and Monitoring

Run performance benchmarks to verify optimizations:

```bash
# Verify README performance claims
python benches/benchmark_performance_readme.py

# Memory efficiency benchmark
python benches/benchmark_memory.py

# Test with your own data
python -c "
import evlib
import time
start = time.time()
events = evlib.load_events('your_file.h5')
df = events.collect()
print(f'Loaded {len(df):,} events in {time.time()-start:.2f}s')
print(f'Format: {evlib.detect_format("your_file.h5")}')
print(f'Memory per event: {df.estimated_size() / len(df):.1f} bytes')
"
```

### Performance Examples

#### Optimal Loading for Different File Sizes
```python
import evlib
import evlib.filtering as evf
import polars as pl

# Small files (<5M events) - Direct loading
events_small = evlib.load_events("small_file.h5")
df_small = events_small.collect()

# Large files (>5M events) - Automatic streaming
events_large = evlib.load_events("large_file.h5")
# Same API, but uses streaming internally for memory efficiency

# Memory-efficient filtering on large datasets using filtering module
filtered = evf.filter_by_time(events_large, t_start=1.0, t_end=2.0)
positive_events = evf.filter_by_polarity(filtered, polarity=1)

# Or using direct Polars operations
manual_filtered = events_large.filter(
    (pl.col("timestamp").dt.total_microseconds() / 1_000_000 > 1.0) &
    (pl.col("polarity") == 1)
).collect()
```

#### Memory Monitoring
```python
import evlib
import psutil
import os

def monitor_memory():
    process = psutil.Process(os.getpid())
    return process.memory_info().rss / 1024 / 1024  # MB

# Monitor memory usage during loading
initial_mem = monitor_memory()
events = evlib.load_events("data.h5")
df = events.collect()
peak_mem = monitor_memory()

print(f"Memory used: {peak_mem - initial_mem:.1f} MB")
print(f"Memory per event: {(peak_mem - initial_mem) * 1024 * 1024 / len(df):.1f} bytes")
print(f"Polars DataFrame size: {df.estimated_size() / 1024 / 1024:.1f} MB")
```

### Troubleshooting Large Files

#### Memory Constraints
- **Automatic Streaming**: Files >5M events use streaming by default (when implemented)
- **LazyFrame Operations**: Memory-efficient processing without full materialization
- **Memory Monitoring**: Use `benchmark_memory.py` to track usage
- **System Requirements**: Recommend 8GB+ RAM for files >100M events

#### Performance Tuning
- **Optimal Chunk Size**: System automatically calculates based on available memory
- **LazyFrame Operations**: Use `.lazy()` for complex filtering chains
- **Memory-Efficient Formats**: HDF5 generally most efficient, followed by EVT2
- **Progress Reporting**: Large files show progress during loading

#### Common Issues and Solutions

**Issue**: Out of memory errors
```python
# Solution: Use filtering before collecting and verify streaming is enabled
events = evlib.load_events("large_file.h5")
# Streaming activates automatically for files >5M events

# Apply filtering before collecting to reduce memory usage
import evlib.filtering as evf
filtered = evf.filter_by_time(events, t_start=0.1, t_end=0.5)
df = filtered.collect()  # Only collect when needed

# Or stream to disk using Polars
filtered.sink_parquet("filtered_events.parquet")
```

**Issue**: Slow loading performance
```python
# Solution: Use LazyFrame for complex operations and filtering module
events = evlib.load_events("file.h5")

# Use filtering module for optimized operations
import evlib.filtering as evf
result = evf.filter_by_roi(events, x_min=0, x_max=640, y_min=0, y_max=480)
df = result.collect()

# Or chain Polars operations
result = events.filter(pl.col("polarity") == 1).select(["x", "y", "timestamp"]).collect()
```

**Issue**: Memory usage higher than expected
```python
# Solution: Monitor and verify optimization
import evlib
events = evlib.load_events("file.h5")
df = events.collect()
print(f"Memory efficiency: {df.estimated_size() / len(df)} bytes/event")
print(f"DataFrame schema: {df.schema}")
print(f"Number of events: {len(df):,}")

# Check format detection
format_info = evlib.detect_format("file.h5")
print(f"Format: {format_info}")
```

### Performance Metrics Summary

| Metric | Previous | Optimized | Improvement |
|--------|----------|-----------|-------------|
| Memory per event | ~200+ bytes | ~35 bytes | 80%+ reduction |
| Loading speed | ~300k events/s | 2.2M+ events/s | 7x+ improvement |
| Filter speed | ~50M events/s | 467M+ events/s | 9x+ improvement |
| Max file size | ~50M events | 200M+ events tested | 4x+ improvement |
| Memory efficiency | Variable | Consistent ~35 bytes/event | Predictable |

*Performance measured on Apple M1 with 16GB RAM using real-world datasets*

**Verified Performance Claims:**
- Loading speed: 2.2M events/s (exceeds 600k target)
- Filter speed: 467M events/s (exceeds 400M target)
- Memory efficiency: 35 bytes/event (well under 110 target)
- Large file support: Successfully tested with 200M+ events

## Available Python Modules

evlib provides several Python modules for different aspects of event processing:

### Core Modules
- **`evlib.formats`**: Direct Rust access for format loading and detection
- **`evlib.filtering`**: High-performance event filtering with Polars
- **`evlib.representations`**: Event representations (stacked histograms, voxel grids)
- **`evlib.models`**: Neural network model loading and inference

### Module Overview
```python
# Core event loading (returns Polars LazyFrame)
import evlib
events = evlib.load_events("data.h5")

# Format detection and description
format_info = evlib.detect_format("data.h5")
description = evlib.get_format_description("HDF5")

# Advanced filtering
import evlib.filtering as evf
filtered = evf.preprocess_events("data.h5", t_start=0.1, t_end=0.5)
time_filtered = evf.filter_by_time(events, t_start=0.1, t_end=0.5)

# Event representations
import evlib.representations as evr
hist = evr.create_stacked_histogram("data.h5", height=480, width=640, nbins=10)
voxel = evr.create_voxel_grid("data.h5", height=480, width=640, nbins=5)

# Neural network models (limited functionality)
from evlib.models import ModelConfig  # If available

# Data saving
evlib.save_events_to_hdf5(x, y, t, p, "output.h5")
evlib.save_events_to_text(x, y, t, p, "output.txt")
```

## Examples

The `examples/` directory contains comprehensive notebooks demonstrating:

### Core Examples
- **H5 Data Processing**: Loading and processing HDF5 event data
- **eTram Dataset**: Working with sparse event distributions
- **Gen4 Data**: Processing modern event camera formats
- **Event Filtering**: Comprehensive filtering examples
- **Event Representations**: Creating stacked histograms and voxel grids
- **Performance Benchmarks**: Performance comparison with other tools

Run examples:
```bash
# Test all notebooks
pytest --nbmake examples/

# Run specific examples
python examples/simple_example.py
python examples/filtering_demo.py
python examples/stacked_histogram_demo.py
```

## Development

### Testing

evlib includes comprehensive testing for both code and documentation:

#### Core Testing
```bash
# Run all tests (Python and Rust)
pytest
cargo test

# Test specific modules
pytest tests/test_filtering.py
pytest tests/test_representations.py
pytest tests/test_evlib_exact_match.py

# Test notebooks (including examples)
pytest --nbmake examples/

# Test with coverage
pytest --cov=evlib
```

#### Documentation Testing
All code examples in the documentation are automatically tested to ensure they work correctly:

```bash
# Test all documentation examples
pytest --markdown-docs docs/

# Test specific documentation file
pytest --markdown-docs docs/getting-started/quickstart.md

# Use the convenient test script
python scripts/test_docs.py --list    # List testable files
python scripts/test_docs.py --report  # Generate report

# Test specific documentation section
pytest --markdown-docs docs/user-guide/
pytest --markdown-docs docs/getting-started/
```

**Documentation Testing Features:**
- **266 code examples** across 27 documentation files are automatically tested
- **Mock evlib module** allows testing even when full library isn't built
- **CI/CD integration** runs tests on every push and pull request
- **Comprehensive reporting** shows which examples work and which need attention

#### Code Quality
```bash
# Format code
black python/ tests/ examples/
cargo fmt

# Run linting
ruff check python/ tests/
cargo clippy

# Check types
mypy python/evlib/
```

### Building
```bash
# Development build
maturin develop

# Build with features
maturin develop --features polars
maturin develop --features pytorch

# Release build
maturin build --release
```

### Build Requirements
- **Rust**: Stable toolchain (see `rust-toolchain.toml`)
- **Python**: ≥3.10 (3.12 recommended)
- **Maturin**: For building Python extensions

## Community & Support

- **GitHub**: [tallamjr/evlib](https://github.com/tallamjr/evlib)
- **Issues**: Report bugs and request features
- **Discussions**: Community Q&A and ideas

## License

MIT License - see [LICENSE.md](LICENSE.md) for details.


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/tallamjr/evlib",
    "name": "evlib",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "event-camera, vision, rust, python, pyo3",
    "author": "Tarek Allam <t.allam.jr@gmail.com>",
    "author_email": "Tarek Allam <t.allam.jr@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/33/04/82020a5cc2705a854c92f271c6cb00758e11aa8a0012beeca15aafd8228e/evlib-0.2.3.tar.gz",
    "platform": null,
    "description": "<table align=\"center\">\n  <tr>\n    <td>\n      <img src=\"./docs/evlogo.png\" width=\"70\" alt=\"evlib logo\" />\n    </td>\n    <td>\n      <h1 style=\"margin: 0;\">\n        <code>evlib</code>: Event Camera Data Processing Library\n      </h1>\n    </td>\n  </tr>\n</table>\n\n<div style=\"text-align: center;\" align=\"center\">\n\n[![PyPI Version](https://img.shields.io/pypi/v/evlib.svg)](https://pypi.org/project/evlib/)\n[![Python Versions](https://img.shields.io/pypi/pyversions/evlib.svg)](https://pypi.org/project/evlib/)\n[![Documentation](https://readthedocs.org/projects/evlib/badge/?version=latest)](https://evlib.readthedocs.io/en/latest/?badge=latest)\n[![Python](https://github.com/tallamjr/evlib/actions/workflows/pytest.yml/badge.svg)](https://github.com/tallamjr/evlib/actions/workflows/pytest.yml)\n[![Rust](https://github.com/tallamjr/evlib/actions/workflows/rust.yml/badge.svg)](https://github.com/tallamjr/evlib/actions/workflows/rust.yml)\n[![License](https://img.shields.io/github/license/tallamjr/evlib)](https://github.com/tallamjr/evlib/blob/master/LICENSE.md)\n\n</div>\n\nA robust event camera processing library with Rust backend and Python bindings, designed for reliable data processing with real-world event camera datasets.\n\n## Current Status (v0.2.3)\n\n**Fully Working Features:**\n- Universal format support (H5, AEDAT, EVT2/3, AER, text)\n- Automatic format detection\n- Polars DataFrame integration (up to 97x speedup)\n- High-performance event filtering\n- Event representations (stacked histograms, voxel grids)\n- Neural network model loading (E2VID)\n- Large file support (tested with 200M+ events)\n\n**In Development:**\n- Advanced neural network processing (Rust backend temporarily disabled)\n- Real-time visualization (Rust backend temporarily disabled)\n\n**Note**: The core functionality is stable and production-ready. The Rust backend currently focuses on data loading and processing, with Python modules providing advanced features like filtering and representations.\n\n## Core Features\n\n- **Universal Format Support**: Load data from H5, AEDAT, EVT2/3, AER, and text formats\n- **Automatic Format Detection**: No need to specify format types manually\n- **Polars DataFrame Integration**: High-performance DataFrame operations with up to 97x speedup\n- **Event Filtering**: Comprehensive filtering with temporal, spatial, and polarity options\n- **Event Representations**: Stacked histograms, voxel grids, and mixed density stacks\n- **Neural Network Models**: E2VID model loading and inference\n- **Real-time Data Processing**: Handle large datasets (550MB+ files) efficiently\n- **Polarity Encoding**: Automatic conversion between 0/1 and -1/1 polarities\n- **Rust Performance**: Memory-safe, high-performance backend with Python bindings\n\n## Quick Start\n\n### Basic Usage\n```python\nimport evlib\n\n# Load events from any supported format (automatic detection)\ndf = evlib.load_events(\"path/to/your/data.h5\").collect()\n\n# Or load as LazyFrame for memory-efficient processing\nlf = evlib.load_events(\"path/to/your/data.h5\")\n\n# Basic event information\nprint(f\"Loaded {len(df)} events\")\nprint(f\"Resolution: {df['x'].max()} x {df['y'].max()}\")\nprint(f\"Duration: {df['timestamp'].max() - df['timestamp'].min()}\")\n\n# Convert to NumPy arrays for compatibility\nx_coords = df['x'].to_numpy()\ny_coords = df['y'].to_numpy()\ntimestamps = df['timestamp'].to_numpy()\npolarities = df['polarity'].to_numpy()\n```\n\n### Advanced Filtering\n```python\nimport evlib.filtering as evf\n\n# High-level preprocessing pipeline\nprocessed = evf.preprocess_events(\n    \"path/to/your/data.h5\",\n    t_start=0.1, t_end=0.5,\n    roi=(100, 500, 100, 400),\n    polarity=1,\n    remove_hot_pixels=True,\n    remove_noise=True,\n    hot_pixel_threshold=99.9,\n    refractory_period_us=1000\n)\n\n# Individual filters (work with LazyFrames)\nevents = evlib.load_events(\"path/to/your/data.h5\")\ntime_filtered = evf.filter_by_time(events, t_start=0.1, t_end=0.5)\nspatial_filtered = evf.filter_by_roi(time_filtered, x_min=100, x_max=500, y_min=100, y_max=400)\nclean_events = evf.filter_hot_pixels(spatial_filtered, threshold_percentile=99.9)\ndenoised = evf.filter_noise(clean_events, method=\"refractory\", refractory_period_us=1000)\n```\n\n### Event Representations\n```python\nimport evlib.representations as evr\n\n# Create stacked histogram (replaces RVT preprocessing)\nhist = evr.create_stacked_histogram(\n    \"path/to/your/data.h5\",\n    height=480, width=640,\n    nbins=10, window_duration_ms=50.0,\n    count_cutoff=10\n)\n\n# Create mixed density stack representation\ndensity = evr.create_mixed_density_stack(\n    \"path/to/your/data.h5\",\n    height=480, width=640,\n    nbins=10, window_duration_ms=50.0\n)\n\n# Create voxel grid representation\nvoxel = evr.create_voxel_grid(\n    \"path/to/your/data.h5\",\n    height=480, width=640,\n    nbins=5\n)\n\n# High-level preprocessing for neural networks\ndata = evr.preprocess_for_detection(\n    \"path/to/your/data.h5\",\n    representation=\"stacked_histogram\",\n    height=480, width=640,\n    nbins=10, window_duration_ms=50\n)\n\n# Performance benchmarking against RVT\nresults = evr.benchmark_vs_rvt(\"path/to/your/data.h5\", height=480, width=640)\n```\n\n## Installation\n\n### Basic Installation\n```bash\npip install evlib\n\n# For Polars DataFrame support (recommended)\npip install evlib[polars]\n```\n\n### Development Installation\n```bash\n# Clone the repository\ngit clone https://github.com/tallamjr/evlib.git\ncd evlib\n\n# Create virtual environment\npython -m venv .venv\nsource .venv/bin/activate  # On Windows: .venv\\Scripts\\activate\n\n# Install in development mode with all features\npip install -e \".[dev,polars]\"\n\n# Build the Rust extensions\nmaturin develop\n```\n\n### System Dependencies\n```bash\n# Ubuntu/Debian\nsudo apt install libhdf5-dev pkg-config\n\n# macOS\nbrew install hdf5 pkg-config\n```\n\n### Performance-Optimized Installation\n\nFor optimal performance, ensure you have the recommended system configuration:\n\n**System Requirements:**\n- **RAM**: 8GB+ recommended for files >100M events\n- **Python**: 3.10+ (3.12 recommended for best performance)\n- **Polars**: Latest version for advanced DataFrame operations\n\n**Installation for Performance:**\n```bash\n# Install with Polars support (recommended)\npip install \"evlib[polars]\"\n\n# For development with all performance features\npip install \"evlib[dev,polars]\"\n\n# Verify installation with benchmark\npython -c \"import evlib; print('evlib installed successfully')\"\npython benchmark_memory.py  # Test memory efficiency\n```\n\n**Optional Performance Dependencies:**\n```bash\n# For advanced memory monitoring\npip install psutil\n\n# For parallel processing (already included in dev)\npip install multiprocessing-logging\n```\n\n## Polars DataFrame Integration\n\nevlib provides comprehensive Polars DataFrame support for high-performance event data processing:\n\n### Key Benefits\n- **Performance**: Up to 97x faster filtering compared to NumPy arrays\n- **Memory Efficiency**: Optimized data structures reduce memory usage\n- **Expressive Queries**: SQL-like operations for complex data analysis\n- **Lazy Evaluation**: Query optimization for better performance\n- **Ecosystem Integration**: Seamless integration with data science tools\n\n### API Overview\n\n#### Loading Data\n```python\n# Load as LazyFrame (recommended)\nevents = evlib.load_events(\"data.h5\")\ndf = events.collect()  # Collect to DataFrame when needed\n\n# Automatic format detection and optimization\nevents = evlib.load_events(\"data.evt2\")  # EVT2 format automatically detected\nprint(f\"Format: {evlib.detect_format('data.evt2')}\")\nprint(f\"Description: {evlib.get_format_description('EVT2')}\")\n\n# Direct Rust access (returns NumPy arrays)\nx, y, t, p = evlib.formats.load_events(\"data.h5\")\n```\n\n#### Advanced Features\n```python\nimport polars as pl\n\n# Chain operations with LazyFrames for optimal performance\nevents = evlib.load_events(\"data.h5\")\nresult = events.filter(pl.col(\"polarity\") == 1).with_columns([\n    pl.col(\"timestamp\").dt.total_microseconds().alias(\"time_us\"),\n    (pl.col(\"x\") + pl.col(\"y\")).alias(\"diagonal_pos\")\n]).collect()\n\n# Memory-efficient temporal analysis\ntemporal_stats = events.group_by_dynamic(\n    \"timestamp\",\n    every=\"1s\"\n).agg([\n    pl.len().alias(\"event_count\"),\n    pl.col(\"polarity\").mean().alias(\"avg_polarity\")\n]).collect()\n\n# Combine with filtering module for complex operations\nimport evlib.filtering as evf\nfiltered = evf.filter_by_time(events, t_start=0.1, t_end=0.5)\nanalysis = filtered.with_columns([\n    pl.col(\"timestamp\").dt.total_microseconds().alias(\"time_us\")\n]).collect()\n```\n\n#### Utility Functions\n```python\nimport polars as pl\nimport evlib.filtering as evf\n\n# Built-in format detection\nformat_info = evlib.detect_format(\"data.h5\")\nprint(f\"Detected format: {format_info}\")\n\n# Spatial filtering using dedicated filtering functions (preferred)\nevents = evlib.load_events(\"data.h5\")\nspatial_filtered = evf.filter_by_roi(events, x_min=100, x_max=200, y_min=50, y_max=150)\n\n# Or using direct Polars operations\nmanual_filtered = events.filter(\n    (pl.col(\"x\") >= 100) & (pl.col(\"x\") <= 200) &\n    (pl.col(\"y\") >= 50) & (pl.col(\"y\") <= 150)\n)\n\n# Temporal analysis with Polars operations\nrates = events.group_by_dynamic(\"timestamp\", every=\"10ms\").agg([\n    pl.len().alias(\"event_rate\"),\n    pl.col(\"polarity\").mean().alias(\"avg_polarity\")\n]).collect()\n\n# Save processed data\nprocessed = evf.preprocess_events(\"data.h5\", t_start=0.1, t_end=0.5)\nx, y, t, p = processed.select([\"x\", \"y\", \"timestamp\", \"polarity\"]).collect().to_numpy().T\nevlib.save_events_to_hdf5(x, y, t, p, \"output.h5\")\n```\n\n## Performance Optimizations\n\n### Memory Efficiency\n- **Direct Polars Integration**: Zero-copy architecture with single-pass construction\n- **Memory Usage**: ~110 bytes/event including overhead (previously ~200+ bytes/event)\n- **Automatic Streaming**: Files >5M events automatically use chunked processing\n- **Memory-Efficient Types**: Optimized data types (Int16 for x/y, Int8 for polarity)\n- **Scalability**: Support for files up to 1B+ events without memory exhaustion\n\n### Processing Speed\n- **Load Speed**: 600k+ events/s for typical files (measured on real datasets)\n- **Filter Speed**: 400M+ events/s using LazyFrame operations\n- **Streaming Performance**: 1M+ events/s for large files (>100M events)\n- **Format Support**: All formats (EVT2, HDF5, Text) optimized with format-specific encoding\n\n### Scalability Features\n- **LazyFrame Processing**: Memory-efficient operations without full materialization\n- **Direct Polars Integration**: Zero-copy construction for optimal memory usage\n- **Large File Support**: Tested with files up to 1.6GB (200M+ events)\n- **Error Recovery**: Graceful handling of memory constraints and large files\n\n### Benchmarking and Monitoring\n\nRun performance benchmarks to verify optimizations:\n\n```bash\n# Verify README performance claims\npython benches/benchmark_performance_readme.py\n\n# Memory efficiency benchmark\npython benches/benchmark_memory.py\n\n# Test with your own data\npython -c \"\nimport evlib\nimport time\nstart = time.time()\nevents = evlib.load_events('your_file.h5')\ndf = events.collect()\nprint(f'Loaded {len(df):,} events in {time.time()-start:.2f}s')\nprint(f'Format: {evlib.detect_format(\"your_file.h5\")}')\nprint(f'Memory per event: {df.estimated_size() / len(df):.1f} bytes')\n\"\n```\n\n### Performance Examples\n\n#### Optimal Loading for Different File Sizes\n```python\nimport evlib\nimport evlib.filtering as evf\nimport polars as pl\n\n# Small files (<5M events) - Direct loading\nevents_small = evlib.load_events(\"small_file.h5\")\ndf_small = events_small.collect()\n\n# Large files (>5M events) - Automatic streaming\nevents_large = evlib.load_events(\"large_file.h5\")\n# Same API, but uses streaming internally for memory efficiency\n\n# Memory-efficient filtering on large datasets using filtering module\nfiltered = evf.filter_by_time(events_large, t_start=1.0, t_end=2.0)\npositive_events = evf.filter_by_polarity(filtered, polarity=1)\n\n# Or using direct Polars operations\nmanual_filtered = events_large.filter(\n    (pl.col(\"timestamp\").dt.total_microseconds() / 1_000_000 > 1.0) &\n    (pl.col(\"polarity\") == 1)\n).collect()\n```\n\n#### Memory Monitoring\n```python\nimport evlib\nimport psutil\nimport os\n\ndef monitor_memory():\n    process = psutil.Process(os.getpid())\n    return process.memory_info().rss / 1024 / 1024  # MB\n\n# Monitor memory usage during loading\ninitial_mem = monitor_memory()\nevents = evlib.load_events(\"data.h5\")\ndf = events.collect()\npeak_mem = monitor_memory()\n\nprint(f\"Memory used: {peak_mem - initial_mem:.1f} MB\")\nprint(f\"Memory per event: {(peak_mem - initial_mem) * 1024 * 1024 / len(df):.1f} bytes\")\nprint(f\"Polars DataFrame size: {df.estimated_size() / 1024 / 1024:.1f} MB\")\n```\n\n### Troubleshooting Large Files\n\n#### Memory Constraints\n- **Automatic Streaming**: Files >5M events use streaming by default (when implemented)\n- **LazyFrame Operations**: Memory-efficient processing without full materialization\n- **Memory Monitoring**: Use `benchmark_memory.py` to track usage\n- **System Requirements**: Recommend 8GB+ RAM for files >100M events\n\n#### Performance Tuning\n- **Optimal Chunk Size**: System automatically calculates based on available memory\n- **LazyFrame Operations**: Use `.lazy()` for complex filtering chains\n- **Memory-Efficient Formats**: HDF5 generally most efficient, followed by EVT2\n- **Progress Reporting**: Large files show progress during loading\n\n#### Common Issues and Solutions\n\n**Issue**: Out of memory errors\n```python\n# Solution: Use filtering before collecting and verify streaming is enabled\nevents = evlib.load_events(\"large_file.h5\")\n# Streaming activates automatically for files >5M events\n\n# Apply filtering before collecting to reduce memory usage\nimport evlib.filtering as evf\nfiltered = evf.filter_by_time(events, t_start=0.1, t_end=0.5)\ndf = filtered.collect()  # Only collect when needed\n\n# Or stream to disk using Polars\nfiltered.sink_parquet(\"filtered_events.parquet\")\n```\n\n**Issue**: Slow loading performance\n```python\n# Solution: Use LazyFrame for complex operations and filtering module\nevents = evlib.load_events(\"file.h5\")\n\n# Use filtering module for optimized operations\nimport evlib.filtering as evf\nresult = evf.filter_by_roi(events, x_min=0, x_max=640, y_min=0, y_max=480)\ndf = result.collect()\n\n# Or chain Polars operations\nresult = events.filter(pl.col(\"polarity\") == 1).select([\"x\", \"y\", \"timestamp\"]).collect()\n```\n\n**Issue**: Memory usage higher than expected\n```python\n# Solution: Monitor and verify optimization\nimport evlib\nevents = evlib.load_events(\"file.h5\")\ndf = events.collect()\nprint(f\"Memory efficiency: {df.estimated_size() / len(df)} bytes/event\")\nprint(f\"DataFrame schema: {df.schema}\")\nprint(f\"Number of events: {len(df):,}\")\n\n# Check format detection\nformat_info = evlib.detect_format(\"file.h5\")\nprint(f\"Format: {format_info}\")\n```\n\n### Performance Metrics Summary\n\n| Metric | Previous | Optimized | Improvement |\n|--------|----------|-----------|-------------|\n| Memory per event | ~200+ bytes | ~35 bytes | 80%+ reduction |\n| Loading speed | ~300k events/s | 2.2M+ events/s | 7x+ improvement |\n| Filter speed | ~50M events/s | 467M+ events/s | 9x+ improvement |\n| Max file size | ~50M events | 200M+ events tested | 4x+ improvement |\n| Memory efficiency | Variable | Consistent ~35 bytes/event | Predictable |\n\n*Performance measured on Apple M1 with 16GB RAM using real-world datasets*\n\n**Verified Performance Claims:**\n- Loading speed: 2.2M events/s (exceeds 600k target)\n- Filter speed: 467M events/s (exceeds 400M target)\n- Memory efficiency: 35 bytes/event (well under 110 target)\n- Large file support: Successfully tested with 200M+ events\n\n## Available Python Modules\n\nevlib provides several Python modules for different aspects of event processing:\n\n### Core Modules\n- **`evlib.formats`**: Direct Rust access for format loading and detection\n- **`evlib.filtering`**: High-performance event filtering with Polars\n- **`evlib.representations`**: Event representations (stacked histograms, voxel grids)\n- **`evlib.models`**: Neural network model loading and inference\n\n### Module Overview\n```python\n# Core event loading (returns Polars LazyFrame)\nimport evlib\nevents = evlib.load_events(\"data.h5\")\n\n# Format detection and description\nformat_info = evlib.detect_format(\"data.h5\")\ndescription = evlib.get_format_description(\"HDF5\")\n\n# Advanced filtering\nimport evlib.filtering as evf\nfiltered = evf.preprocess_events(\"data.h5\", t_start=0.1, t_end=0.5)\ntime_filtered = evf.filter_by_time(events, t_start=0.1, t_end=0.5)\n\n# Event representations\nimport evlib.representations as evr\nhist = evr.create_stacked_histogram(\"data.h5\", height=480, width=640, nbins=10)\nvoxel = evr.create_voxel_grid(\"data.h5\", height=480, width=640, nbins=5)\n\n# Neural network models (limited functionality)\nfrom evlib.models import ModelConfig  # If available\n\n# Data saving\nevlib.save_events_to_hdf5(x, y, t, p, \"output.h5\")\nevlib.save_events_to_text(x, y, t, p, \"output.txt\")\n```\n\n## Examples\n\nThe `examples/` directory contains comprehensive notebooks demonstrating:\n\n### Core Examples\n- **H5 Data Processing**: Loading and processing HDF5 event data\n- **eTram Dataset**: Working with sparse event distributions\n- **Gen4 Data**: Processing modern event camera formats\n- **Event Filtering**: Comprehensive filtering examples\n- **Event Representations**: Creating stacked histograms and voxel grids\n- **Performance Benchmarks**: Performance comparison with other tools\n\nRun examples:\n```bash\n# Test all notebooks\npytest --nbmake examples/\n\n# Run specific examples\npython examples/simple_example.py\npython examples/filtering_demo.py\npython examples/stacked_histogram_demo.py\n```\n\n## Development\n\n### Testing\n\nevlib includes comprehensive testing for both code and documentation:\n\n#### Core Testing\n```bash\n# Run all tests (Python and Rust)\npytest\ncargo test\n\n# Test specific modules\npytest tests/test_filtering.py\npytest tests/test_representations.py\npytest tests/test_evlib_exact_match.py\n\n# Test notebooks (including examples)\npytest --nbmake examples/\n\n# Test with coverage\npytest --cov=evlib\n```\n\n#### Documentation Testing\nAll code examples in the documentation are automatically tested to ensure they work correctly:\n\n```bash\n# Test all documentation examples\npytest --markdown-docs docs/\n\n# Test specific documentation file\npytest --markdown-docs docs/getting-started/quickstart.md\n\n# Use the convenient test script\npython scripts/test_docs.py --list    # List testable files\npython scripts/test_docs.py --report  # Generate report\n\n# Test specific documentation section\npytest --markdown-docs docs/user-guide/\npytest --markdown-docs docs/getting-started/\n```\n\n**Documentation Testing Features:**\n- **266 code examples** across 27 documentation files are automatically tested\n- **Mock evlib module** allows testing even when full library isn't built\n- **CI/CD integration** runs tests on every push and pull request\n- **Comprehensive reporting** shows which examples work and which need attention\n\n#### Code Quality\n```bash\n# Format code\nblack python/ tests/ examples/\ncargo fmt\n\n# Run linting\nruff check python/ tests/\ncargo clippy\n\n# Check types\nmypy python/evlib/\n```\n\n### Building\n```bash\n# Development build\nmaturin develop\n\n# Build with features\nmaturin develop --features polars\nmaturin develop --features pytorch\n\n# Release build\nmaturin build --release\n```\n\n### Build Requirements\n- **Rust**: Stable toolchain (see `rust-toolchain.toml`)\n- **Python**: \u22653.10 (3.12 recommended)\n- **Maturin**: For building Python extensions\n\n## Community & Support\n\n- **GitHub**: [tallamjr/evlib](https://github.com/tallamjr/evlib)\n- **Issues**: Report bugs and request features\n- **Discussions**: Community Q&A and ideas\n\n## License\n\nMIT License - see [LICENSE.md](LICENSE.md) for details.\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python bindings for event camera utilities",
    "version": "0.2.3",
    "project_urls": {
        "Homepage": "https://github.com/tallamjr/evlib",
        "Source Code": "https://github.com/tallamjr/evlib"
    },
    "split_keywords": [
        "event-camera",
        " vision",
        " rust",
        " python",
        " pyo3"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "49a6ea3b62dbc42fb75d19c771a67adf7f3ef8046c2522e823098eab09b61586",
                "md5": "bdd327a1a0a64b242529871830a6af83",
                "sha256": "db2e54134eba0fa8e1db0ebec693f4e9b834f7e65206deabddf975e372822d12"
            },
            "downloads": -1,
            "filename": "evlib-0.2.3-cp310-cp310-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "bdd327a1a0a64b242529871830a6af83",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.10",
            "size": 6260883,
            "upload_time": "2025-07-18T17:51:47",
            "upload_time_iso_8601": "2025-07-18T17:51:47.495466Z",
            "url": "https://files.pythonhosted.org/packages/49/a6/ea3b62dbc42fb75d19c771a67adf7f3ef8046c2522e823098eab09b61586/evlib-0.2.3-cp310-cp310-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "330482020a5cc2705a854c92f271c6cb00758e11aa8a0012beeca15aafd8228e",
                "md5": "6a7b24a410c68b8d43c17c0987dacf5d",
                "sha256": "67f58f766cfbbab156667895c2660eb02927f522094a5847862514b21983a660"
            },
            "downloads": -1,
            "filename": "evlib-0.2.3.tar.gz",
            "has_sig": false,
            "md5_digest": "6a7b24a410c68b8d43c17c0987dacf5d",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 453832,
            "upload_time": "2025-07-18T17:51:49",
            "upload_time_iso_8601": "2025-07-18T17:51:49.807116Z",
            "url": "https://files.pythonhosted.org/packages/33/04/82020a5cc2705a854c92f271c6cb00758e11aa8a0012beeca15aafd8228e/evlib-0.2.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-18 17:51:49",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "tallamjr",
    "github_project": "evlib",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "evlib"
}
        
Elapsed time: 0.56892s