← ~/projects/

RBC Aggregation Analysis

GitHub →
RustBiophysics3D Analysis

RBC Aggregation Analysis

High-performance 3D analysis of red blood cell aggregation from confocal microscopy. Written in Rust.

Pipeline

┌────────────┐     ┌────────────┐     ┌────────────┐     ┌────────────┐
│   TIFF     │     │   ML       │     │   OBJ      │     │  SPATIAL   │
│   Stack    │────▶│   Segment  │────▶│   Meshes   │────▶│  Analysis  │
│            │     │  (ilastik) │     │            │     │            │
└────────────┘     └────────────┘     └────────────┘     └────────────┘
     │                                      │                   │
     ▼                                      ▼                   ▼
┌────────────┐                       ┌────────────┐     ┌────────────┐
│ Intensity  │                       │  Inertia   │     │   g(r)     │
│  Profile   │                       │  Tensor    │     │  Function  │
└────────────┘                       └────────────┘     └────────────┘

Shape Classification via Inertia Tensor

RBC morphology is encoded in the eigenvalues (λ₁ ≥ λ₂ ≥ λ₃) of the gyration tensor:

           ┌────────────────────────────────────────┐
           │           SHAPE SPACE                  │
           │                                        │
    λ₁/λ₂  │   Elliptocyte    ·                     │
      ▲    │        ·    ·         Stomatocyte      │
      │    │   ·              ·          ·          │
      │    │        Discocyte                       │
      │    │   ·    (healthy)   ·                   │
      │    │              ·                         │
      │    │                  Spherocyte            │
      │    │                     ·                  │
      └────┼─────────────────────────────────────▶  │
           │                               λ₂/λ₃    │
           └────────────────────────────────────────┘

Asphericity  = λ₁ - ½(λ₂ + λ₃)    → deviation from sphere
Acylindricity = λ₂ - λ₃           → deviation from cylinder

Pair Correlation Function

Quantifies aggregation by measuring spatial distribution:

         g(r)
          ▲
          │     ╭─╮
          │    ╱   ╲    Aggregation peak
          │   ╱     ╲   (cells cluster at this distance)
        1 │──╱───────╲──────────────────
          │ ╱         ╲
          │╱           ╲______________
          │
          └────────────────────────────▶ r
                 │
                 └── Contact distance (~8μm for RBCs)

For random distribution, g(r) = 1. Peaks indicate preferred separation distances.

Why Rust?

Concern Solution
Large meshes (100K+ vertices) Zero-copy parsing, stack allocation
Batch processing (1000s of cells) Rayon parallel iterators
Numerical stability nalgebra with proper epsilon handling
Memory safety Borrow checker prevents data races

Core Algorithm

// Pair correlation with interior particle handling
fn compute_g_r(&self, positions: &[[f64; 3]]) -> Vec<f64> {
    let interior = positions.par_iter()
        .filter(|p| self.is_interior(p))
        .collect::<Vec<_>>();

    interior.par_iter()
        .map(|ref_pos| self.histogram_distances(ref_pos, positions))
        .reduce(|| vec![0.0; n_bins], |a, b| add_vecs(a, b))
        .normalize_by_shell_volume()
}

GitHub