Skip to content

Hamza-Anver/caerula-rs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Caerula Banner

Caerula Engine

Stochastic Monte Carlo Ray Tracing system for ocean optical sensor simulation built in Rust with Python bindings.

The writeup for this project is available at in the docs/caerula_writeup_capstone.pdf file. The presentation slides are also available at docs/caerula_presentation_slides.pdf.

Usage

Since this is a library for research purposes it does not have built wheels available for use just yet. So the process to use this library with its python bindings is a bit of an involved project. The process should be as follows:

Create a virtual environment (recommended)

python -m venv venv
source venv/bin/activate  # On Windows use `venv\Scripts\activate`

Then install maturin in that environment

pip install maturin

After that you can build and install the python bindings with

maturin develop --release

Note: the above command must be run where the pyproject.toml file is located which is caerula-py.

This creates an editable install of the python bindings in your virtual environment. You can then use the library in your python scripts or jupyter notebooks by importing caerula_py.

from caerula_py import CaerulaEngine

Some basic usage examples can be found in the jupyter_notebook folder. Note: the jupyter notebook requires plotly and pandas to be installed in the environment.

Example usage:

from caerula_py import CaerulaEngine
import pandas as pd

# Initialize the engine
# num_rays per batch
engine = CaerulaEngine(name="basic_scene", num_rays=500000, max_bounces=10, max_dist=100.0)

# Set medium properties
engine.set_medium(turbidity=10, chla=40)

# Add a sunlight source
# Position is relative, direction is normalized vector
engine.set_sunlight(
    name="sun",
    position=(0.0, 2.0, 0.0),
    direction=(0.0, -1.0, 0.0),
    intensity=1000.0,
    spread_angle=30 # degrees
)

# Add a sensor
engine.add_sensor(
    name="upward_sensor",
    position=(0.0, 0.0, 0.0),
    direction=(0.0, 1.0, 0.0), # Looking up
    dimensions=(0.5, 0.5, 0.5),
    half_angle=45.0, # degrees
    min_w=400.0,
    max_w=700.0,
    bin_size=5.0
)

# Callback for convergence
def on_step(i, err):
    if i % 5 == 0:
        print(f"Step {i}: Max Std Err = {err:.6f}")
    if err < 0.01 and i > 100: # Convergence threshold
        print(f"Converged at step {i} with error {err:.6f}")
        return True
    return False

# Run simulation
engine.run(max_iters=1000, callback=on_step)

# Collect results
results = []
for sensor_name, spectrum in engine.results.items():
    for wl, intensity in spectrum:
        results.append({"Wavelength (nm)": wl, "Intensity": intensity, "Sensor": sensor_name})

df = pd.DataFrame(results)
display(df)

Overview

Below is the current project structure, please note that this README is a work in progress and the project structure may change as development continues.

.
├── caerula-cli                 \\ Command line interface for testing and running scenes
│   ├── Cargo.toml
│   └── src
│       ├── config.rs
│       └── main.rs
├── caerula-engine              \\ Core ray tracing engine
│   ├── Cargo.toml
│   ├── engine.puml
│   └── src
│       ├── core                \\ Core engine components
│       │   ├── constants.rs
│       │   ├── mod.rs
│       │   ├── scene.rs
│       │   └── simrunner.rs
│       ├── elements            \\ Scene elements like sensors, media, sources
│       │   ├── medium.rs
│       │   ├── mod.rs
│       │   ├── sensor.rs
│       │   ├── source.rs
│       │   └── sunlight.rs
│       ├── geometry            \\ Geometric primitives and spatial structures
│       │   ├── mod.rs
│       │   ├── simbox.rs
│       │   ├── spectralray.rs
│       │   └── triangle.rs
│       └── lib.rs
├── caerula-py                  \\ Python bindings for the engine
│   ├── Cargo.toml
│   ├── pyproject.toml
│   ├── python
│   │   └── caerula_py
│   │       └── __init__.py
│   └── src
│       └── lib.rs
├── Cargo.toml
├── example.json
├── jupyter_notebook            \\ Jupyter notebook examples
│   ├── main.ipynb
│   └── test.py
└── README.md

The project is structured into three main components:

  1. caerula-engine: The core ray tracing engine implemented in Rust.
  2. caerula-cli: A command-line interface for testing and running scenes in Rust.
  3. caerula-py: Python bindings for the engine to allow easy integration and usage in Python environments.

How it works

The engine uses a Monte Carlo ray tracing approach to simulate light propagation in underwater environments. Naively this model traces from the source to the sensor, but this is very inefficient since most light does not reach the sensor. However, this approach is easier to conceptualize and easier to adapt existing mathematical models for underwater light propagation for.

The scattering can be depicted as in the figure below:

Scattering Diagram

Rays are traced from the light source through the medium, undergoing scattering and absorption events based on the medium properties. When rays intersect with sensors, their contributions are recorded to build up the sensor's received spectrum. A flow chart of the ray's path is shown below:

Ray Tracing Flowchart

Refer to the writeup PDF for more details on the implementation and algorithms used along with more detailed references.

Limitations / TODOs

  • No surface model yet (just medium)
  • No refraction / reflection at medium boundaries
  • CPU bound, not optimized for GPU
  • Not available as a package yet
  • No complex geometries yet (just boxes)
  • Naive implementation, lots of optimizations possible

The primary source used for the mathematical model of this project was https://www.oceanopticsbook.info/view/introduction/overview

About

Monte Carlo Ray Tracing system for marine optical sensor similation, built in Rust

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors