Browser-based tool for loading, filtering, measuring, and stitching OCT volumes (Optical Coherence Tomography). A Python/FastAPI backend handles all heavy computation; a React/Three.js frontend renders 3-D point clouds and 2-D slice views entirely in the browser.
Set up your configuration via a .env file, then start. Do it this way — a .env
next to docker-compose.yml is read automatically by Docker Compose and works
identically on Windows, macOS, and Linux (no inline shell variables, which only
work in bash).
1. Create your .env from the template:
cp .env.example .env # Windows: copy .env.example .env2. Edit .env and set LUMINA_DATA_DIR to the absolute path of the folder that
holds your source .h5 files:
# macOS / Linux
LUMINA_DATA_DIR=/Users/you/oct-data
# Windows
LUMINA_DATA_DIR=C:\Users\you\oct-data(Leave it as the default ./data to just use the repo's local data/ folder.)
The OCT datasets are not part of this repository — they are several GB, so
challenge/data/is git-ignored. PointLUMINA_DATA_DIRat wherever you keep the.h5files; nothing else needs to change. Files are expected as(512, 250, 250)under the dataset nameOCT, which is what the challenge data uses.
3. Start:
docker compose up --build| URL | Description |
|---|---|
| http://localhost:5173 | Frontend |
| http://localhost:8000 | Backend API |
| http://localhost:8000/docs | Swagger / OpenAPI |
The directory in LUMINA_DATA_DIR is bind-mounted read-only at /data inside
the backend container, so your originals are never modified. Once running, use
Load H5 → From server… in the toolbar (or From Server in the Stitch panel)
to pick those files with no upload — the backend registers each by symlink
(zero-copy, instant) and serves it pre-normalised. The classic browser file picker
still works regardless of this setting.
# Backend (Python 3.11, uv package manager)
cd backend
uv sync # CPU-only (default)
uv sync --extra elastix # + itk-elastix B-spline stitcher (optional)
uv run uvicorn main:app --reload --port 8000
# Frontend (Node 20)
cd frontend
npm install
npm run dev # dev server on port 5173
npm run build # TypeScript check + Vite production build# Backend
cd backend
uv run pytest # test suite
uv run ruff check src/ --fix # lint + auto-fix
uv run mypy src/ # type check
# Frontend
cd frontend
npm run lint # ESLint
npm run format # Prettier
npm run build # tsc --noEmit + Vite build
# Both (formatting)
make formatThe backend reads settings from environment variables (or a .env file). See
backend/src/config.py.
| Variable | Default | Purpose |
|---|---|---|
DATA_DIR |
data |
Root of registerable source .h5 files (/data in Docker). |
LUMINA_DATA_DIR |
./data |
Host path bind-mounted to /data; set it in .env (see .env.example). Docker Compose only. |
CORS_ORIGINS |
http://localhost:5173 |
Allowed browser origins (comma-separated). |
VITE_API_URL |
http://localhost:8000 |
Backend base URL the frontend calls. |
| Property | Value |
|---|---|
| Dataset name | "OCT" (fixed) |
| Standard shape | (512, 250, 250) — nSlices × height × width |
| Accepted dtypes | float32/64, int16/32, uint8/16/32 (auto-converted) |
Merged (stitched) volumes may be larger along height/width; sliders and slice indices adapt automatically.
| Layer | Technology |
|---|---|
| Backend | Python 3.11 · FastAPI · NumPy · SciPy · h5py · scikit-image · SimpleITK |
| Backend (optional) | itk-elastix |
| Frontend | React 18 · TypeScript · Three.js · MUI v6 · Zustand · Vite |
| Infra | Docker Compose · uv · Node 20 |
Detailed documentation lives in docs/ — one file per domain,
each explaining the features, the functions behind them, and every formula in
plain language with worked examples.
| Document | Covers |
|---|---|
| Architecture Overview | System design, tech stack, the packed-binary data format, end-to-end data flow. |
| Volume Ingestion & Storage | Upload, register-by-path, HDF5 format, in-browser reading, memory management. |
| Normalization, Rendering & Shaders | Backend/frontend normalization, radix sort, GPU shaders, colormaps, tone mapping. |
| Preprocessing Filters | Gaussian, median, mean, normalize, edge — math and filter chains. |
| Slice Viewer & Measurements | 2-D panels, coordinate transforms, distance/area tools, volumetric measurements. |
| Cropping & Object Analysis | Sub-volume crops (rect/cylinder/sphere), 3-D connected-component counting. |
| Annotation | Non-destructive brush/eraser painting and label storage. |
| Stitching & Registration | Phase correlation, global offsets (BFS), max-blend merging, quality metrics. |
| Jobs, Sessions & Lifecycle | Background execution, polling, and the memory-management strategy. |
| STL Viewer & Overlay | 3-D mesh viewing and STL-on-volume registration. |
| Frontend Shell, State & Theming | App layout, Zustand store, tabs, eviction, MUI theme. |
| API Reference | Every endpoint, request/response, status codes, headers. |
Lumina/
├── LICENSE
├── docker-compose.yml
├── .github/workflows/ci.yml # lint · typecheck · test on push and PR
├── docs/ # detailed documentation (see above)
├── backend/ # Python 3.11 · FastAPI · uv
│ ├── main.py # app, CORS, routers
│ └── src/ # config, routers/, processing/, schemas/
└── frontend/ # React · TypeScript · Vite
└── src/ # App.tsx, app/store/, features/, shared/
Released under the MIT License — free to use, modify and distribute, including commercially, as long as the copyright notice is kept. Third-party dependencies remain under their own (all permissive) licenses.