|
| 1 | +<div align="center"> |
| 2 | + |
1 | 3 | # SPAD Detector |
2 | 4 |
|
3 | | -SPAD Detector is an integrated single-photon active-imaging simulation platform for UAV scenes, PF32 SPAD array data generation, backend photon simulation, and professional desktop 3D visualization. |
| 5 | +**A research-oriented single-photon active-imaging simulation platform for ball, propeller, and UAV scenes** |
| 6 | + |
| 7 | +[](https://github.com/hansamar/spad-detector/actions/workflows/verify.yml) |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | + |
| 12 | + |
| 13 | +</div> |
| 14 | + |
| 15 | +> **中文摘要**<br> |
| 16 | +> SPAD Detector 是面向单光子主动成像研究的仿真平台。平台支持网球类球体、螺旋桨叶片和四旋翼无人机目标,提供 PF32 SPAD 阵列参数联动、太阳辐照度驱动的场景杂散光子、暗计数、死时间、视场裁剪、轨迹记录、CPU/CUDA 后端以及 Electron 桌面端。仓库包含可复现的验证脚本和 GitHub Actions 工作流。 |
| 17 | +
|
| 18 | + |
4 | 19 |
|
5 | | -## Project Layout |
| 20 | +## Research Scope |
6 | 21 |
|
7 | | -- `src/`: Angular + Three.js frontend for professional UI, 3D scene rendering, UAV interaction, and result visualization. |
8 | | -- `backend/`: FastAPI service for capability checks, simulation jobs, summaries, and `.bin` downloads. |
9 | | -- `sim/`: Physics simulation core, including PF32 preset data, spectral response, background, imaging, geometry, atmospheric attenuation, and active SPAD count generation. |
10 | | -- `scripts/`: Frontend/backend smoke tests and physics consistency checks. |
11 | | -- `output/`: Local screenshots and backend job artifacts. |
| 22 | +SPAD Detector is designed for researchers exploring active optical detection and photon-limited imaging of nearby dynamic targets. It combines an interactive Angular and Three.js scene with a FastAPI simulation backend and a Python physics core. |
12 | 23 |
|
13 | | -## Common Commands |
| 24 | +The platform currently models: |
| 25 | + |
| 26 | +- spherical ball targets for tennis-ball-style motion studies; |
| 27 | +- elongated propeller or blade targets, including custom uploaded silhouettes; |
| 28 | +- quadrotor UAV targets with body geometry, four propellers, and DJI-based presets; |
| 29 | +- fixed, waypoint-based, and manually recorded UAV trajectories; |
| 30 | +- PF32 nominal detector settings and user-defined detector overrides; |
| 31 | +- signal photons, solar-irradiance-dependent scene stray photons, and detector dark counts; |
| 32 | +- frame-level and event-oriented SPAD output with CPU or CUDA Poisson sampling. |
| 33 | + |
| 34 | +This repository focuses on nearby dynamic-target detection. Its ambient-noise model is expressed as scene stray photons and detector noise rather than space-debris background terms. |
| 35 | + |
| 36 | +## Simulation Pipeline |
| 37 | + |
| 38 | +```mermaid |
| 39 | +flowchart LR |
| 40 | + A["Target and trajectory<br/>ball / blade / UAV"] --> B["Optical geometry<br/>range / attitude / FOV"] |
| 41 | + B --> C["Photon-rate model<br/>signal + scene stray + dark count"] |
| 42 | + C --> D["Detector response<br/>PF32 preset / custom SPAD"] |
| 43 | + D --> E["Sampling backend<br/>CPU or CUDA Poisson counts"] |
| 44 | + E --> F["Research outputs<br/>count cube / truth map / preview / binary artifact"] |
| 45 | + A --> G["Three.js scene"] |
| 46 | + F --> H["Angular diagnostics UI"] |
| 47 | + G --> H |
| 48 | +``` |
| 49 | + |
| 50 | +## Platform Preview |
| 51 | + |
| 52 | +The desktop interface exposes the selected compute backend, photon statistics, signal-to-noise ratio, dead-time loss, measured count map, truth trajectory, and incident-photon image in one workflow. The screenshot above was generated by the repository's browser smoke flow with the CUDA backend enabled. |
| 53 | + |
| 54 | +## Key Capabilities |
| 55 | + |
| 56 | +| Area | Current implementation | |
| 57 | +| --- | --- | |
| 58 | +| Target models | Spherical ball, blade strip, custom blade silhouette, quadrotor UAV | |
| 59 | +| UAV presets | DJI Mini 4 Pro, DJI Mavic 3 Pro, DJI Inspire 3, DJI Matrice 350 RTK | |
| 60 | +| Motion | Fixed pose, waypoint path, manual flight recording, attitude and propeller phase series | |
| 61 | +| Detector | PF32 nominal preset or custom SPAD settings | |
| 62 | +| Noise | Scene stray photons scaled by current solar irradiance, plus separate detector dark counts | |
| 63 | +| Optical effects | Range, aperture, FOV clipping, atmospheric attenuation, reflectivity, dead time, saturation | |
| 64 | +| Compute | CPU fallback and optional CUDA acceleration for batched photon-count sampling | |
| 65 | +| Outputs | Lightweight summaries, full responses, asynchronous jobs, `.bin` count-cube downloads | |
| 66 | +| Interfaces | Angular web UI, Three.js visualization, FastAPI backend, Electron desktop shell | |
| 67 | + |
| 68 | +## Quick Start |
| 69 | + |
| 70 | +### Prerequisites |
| 71 | + |
| 72 | +- Node.js 22 LTS |
| 73 | +- Python 3.12 or a compatible Python 3 environment |
| 74 | +- Windows for the packaged Electron desktop workflow |
| 75 | +- An NVIDIA GPU with a CUDA-enabled PyTorch environment for GPU acceleration |
| 76 | + |
| 77 | +### Install |
14 | 78 |
|
15 | 79 | ```powershell |
| 80 | +git clone https://github.com/hansamar/spad-detector.git |
| 81 | +cd spad-detector |
16 | 82 | npm install |
17 | 83 | python -m pip install -r requirements.txt |
18 | | -npm run dev |
| 84 | +``` |
| 85 | + |
| 86 | +### Run the web workflow |
| 87 | + |
| 88 | +Open two PowerShell terminals: |
| 89 | + |
| 90 | +```powershell |
| 91 | +# Terminal 1: FastAPI backend |
19 | 92 | npm run backend |
20 | | -npm run desktop |
| 93 | +``` |
| 94 | + |
| 95 | +```powershell |
| 96 | +# Terminal 2: Angular frontend |
| 97 | +npm run dev |
| 98 | +``` |
| 99 | + |
| 100 | +Then open `http://127.0.0.1:3000`. The backend listens on `http://127.0.0.1:8000`. |
| 101 | + |
| 102 | +### Run the desktop workflow |
| 103 | + |
| 104 | +```powershell |
21 | 105 | npm run desktop:dev |
22 | | -npm run desktop:pack |
23 | | -npm run desktop:dist |
24 | | -npm run verify:physics |
25 | | -npm run verify:backend |
26 | | -npm run verify:startup |
27 | | -npx tsc --noEmit --pretty false |
28 | | -npm run build |
29 | 106 | ``` |
30 | 107 |
|
31 | | -`npm run backend` probes available Python environments and starts the backend with |
32 | | -a CUDA-capable `torch` environment when available. By default it requires CUDA; |
33 | | -set `SPAD_REQUIRE_CUDA=0` only when an explicit CPU fallback is needed. |
| 108 | +The repository also provides Windows launchers: |
| 109 | + |
| 110 | +- `启动项目.bat` |
| 111 | +- `启动桌面仿真平台.bat` |
| 112 | + |
| 113 | +## CUDA Backend |
| 114 | + |
| 115 | +`npm run backend` probes available Python interpreters and prefers a CUDA-capable PyTorch environment. The desktop shell follows the same selection logic. On the original development workstation it first checks: |
34 | 116 |
|
35 | | -The backend listens on `http://127.0.0.1:8000`. The frontend connects to that backend under `/api`. |
| 117 | +```text |
| 118 | +~\.conda\envs\spad-detector\python.exe |
| 119 | +``` |
| 120 | + |
| 121 | +You can explicitly select another environment: |
| 122 | + |
| 123 | +```powershell |
| 124 | +$env:SPAD_PYTHON_EXE = "C:\path\to\cuda-enabled\python.exe" |
| 125 | +npm run backend |
| 126 | +``` |
36 | 127 |
|
37 | | -## Desktop Mode |
| 128 | +CPU fallback is available when explicitly requested: |
38 | 129 |
|
39 | | -The project includes an Electron desktop shell for professional local simulation use. |
| 130 | +```powershell |
| 131 | +$env:SPAD_REQUIRE_CUDA = "0" |
| 132 | +npm run backend |
| 133 | +``` |
40 | 134 |
|
41 | | -- `npm run desktop:dev`: starts the Angular dev server, launches the desktop window, and lets Electron start the FastAPI backend. |
42 | | -- `npm run desktop`: builds the Angular frontend and opens it as a local desktop app. |
43 | | -- `npm run desktop:pack`: creates an unpacked desktop app under `release/`. |
44 | | -- `npm run desktop:dist`: creates Windows installer/portable artifacts under `release/`. |
| 135 | +Probe the selected runtime with: |
45 | 136 |
|
46 | | -The desktop shell starts the backend with `SPAD_PYTHON_EXE` when that environment variable is set. Otherwise it tries the local Conda environment `~\.conda\envs\spad-detector\python.exe`, then falls back to `python` / `py`. |
| 137 | +```powershell |
| 138 | +node scripts/start-backend.cjs --probe |
| 139 | +``` |
47 | 140 |
|
48 | | -## Verification |
| 141 | +## Reproducibility Checks |
49 | 142 |
|
50 | | -Run the following checks before packaging: |
| 143 | +Run the local verification set before publishing results or packaging the desktop app: |
51 | 144 |
|
52 | 145 | ```powershell |
53 | 146 | npm run verify:backend |
54 | 147 | npm run verify:physics |
55 | 148 | npx tsc --noEmit --pretty false |
56 | 149 | npm run build |
57 | 150 | npm run verify:startup |
| 151 | +python -m compileall -q backend sim scripts |
| 152 | +``` |
| 153 | + |
| 154 | +`npm run verify:startup` is a local CUDA-environment check. GitHub Actions runs the portable CPU-compatible verification subset on every push and pull request. |
| 155 | + |
| 156 | +## Backend API |
| 157 | + |
| 158 | +| Endpoint | Purpose | |
| 159 | +| --- | --- | |
| 160 | +| `GET /api/capabilities` | Report Python, PyTorch, CUDA, GPU, and default worker information | |
| 161 | +| `POST /api/simulate` | Return a full simulation response | |
| 162 | +| `POST /api/simulate/summary` | Return a lightweight visualization summary | |
| 163 | +| `POST /api/simulate/jobs` | Start an asynchronous simulation job | |
| 164 | +| `GET /api/simulate/jobs/{job_id}` | Poll job state and summary | |
| 165 | +| `GET /api/simulate/jobs/{job_id}/download` | Download the completed `uint16` count cube | |
| 166 | + |
| 167 | +## Backend Limits |
| 168 | + |
| 169 | +The backend rejects requests that exceed its guarded compute envelope: |
| 170 | + |
| 171 | +| Limit | Value | |
| 172 | +| --- | ---: | |
| 173 | +| Frames per run | `200,000` | |
| 174 | +| ROI pixels | `16,384` | |
| 175 | +| Total frame-pixel samples | `204,800,000` | |
| 176 | +| Recorded trajectory points | `50,000` | |
| 177 | +| Custom-shape samples | `512` | |
| 178 | + |
| 179 | +The frontend budget estimator uses the same frame and sample limits so oversized jobs are blocked before submission. |
| 180 | + |
| 181 | +## Repository Layout |
| 182 | + |
| 183 | +```text |
| 184 | +src/ Angular UI, Three.js scene, frontend simulation services |
| 185 | +backend/ FastAPI routes, job management, capability reporting, serializers |
| 186 | +sim/ Python optical, detector, geometry, background, and sampling core |
| 187 | +desktop/ Electron shell and CUDA-capable Python selection |
| 188 | +scripts/ Physics, backend, CUDA-startup, and browser smoke checks |
| 189 | +docs/ Stable documentation assets |
| 190 | +``` |
| 191 | + |
| 192 | +Generated frontend output, local photon cubes, logs, caches, and Electron installers are excluded from source control. Rebuild Windows installer and portable artifacts locally with: |
| 193 | + |
| 194 | +```powershell |
| 195 | +npm run desktop:dist |
58 | 196 | ``` |
59 | 197 |
|
60 | | -`npm run verify:startup` confirms that the selected Python environment exposes a CUDA-enabled `torch` runtime. |
| 198 | +## Research Notes |
| 199 | + |
| 200 | +- The `pf32_nominal` detector preset combines public PF32 figures with documented engineering approximations for active-imaging studies. |
| 201 | +- Scene stray photons and dark counts remain separate terms throughout the simulation. |
| 202 | +- CUDA accelerates the sampling path; researchers should still record the selected backend, dependency versions, random seed, and commit SHA when reporting results. |
| 203 | +- Model assumptions and warnings are returned in backend simulation responses where applicable. |
| 204 | + |
| 205 | +## Citation |
| 206 | + |
| 207 | +Until a versioned release or DOI is published, cite the repository URL and the exact Git commit used for an experiment: |
| 208 | + |
| 209 | +```text |
| 210 | +SPAD Detector: single-photon active-imaging simulation platform. |
| 211 | +https://github.com/hansamar/spad-detector |
| 212 | +``` |
61 | 213 |
|
62 | | -## Release Artifacts |
| 214 | +## License |
63 | 215 |
|
64 | | -Generated frontend output, backend job artifacts, local caches, and Electron installers are intentionally excluded from the source repository. Run `npm run desktop:dist` to rebuild the Windows installer and portable executable under `release/`. |
| 216 | +This public repository does not currently include an open-source license. The source is publicly visible for research evaluation; reuse, modification, and redistribution permissions have not yet been granted. |
0 commit comments