An open API service indexing awesome lists of open source software.

https://github.com/sctg-development/rust-photoacoustic


https://github.com/sctg-development/rust-photoacoustic

Last synced: 3 months ago
JSON representation

Awesome Lists containing this project

README

          

![Code](https://tokeisrv.sctg.eu.org/b1/github.com/sctg-development/rust-photoacoustic?type=Rust,TypeScript,TSX,C&category=code)
![Comments](https://tokeisrv.sctg.eu.org/b1/github.com/sctg-development/rust-photoacoustic?type=TSX,Rust,TypeScript&category=comments&color=abdbe3)
![Documentation](https://tokeisrv.sctg.eu.org/b1/github.com/sctg-development/rust-photoacoustic?type=Markdown&label=doc&color=e28743)
[![codecov](https://codecov.io/github/sctg-development/rust-photoacoustic/branch/main/graph/badge.svg)](https://codecov.io/github/sctg-development/rust-photoacoustic)
![Rust](https://img.shields.io/badge/Rust-1.75+-orange.svg)
![React](https://img.shields.io/badge/React-19.x-blue.svg)
![License](https://img.shields.io/badge/License-SCTG--NC--1.0-green.svg)

# πŸ”¬ Rust-Photoacoustic

**Flexible Gas Analyzer using Laser Photoacoustic Spectroscopy**

A comprehensive software and hardware platform for high-precision gas concentration measurement using differential Helmholtz resonator photoacoustic spectroscopy.

---

## πŸ“‹ Table of Contents

- [Overview](#-overview)
- [Key Features](#-key-features)
- [Architecture](#-architecture)
- [Quick Start](#-quick-start)
- [Project Structure](#-project-structure)
- [Configuration](#-configuration)
- [Physical Principles](#-physical-principles)
- [Signal Processing Pipeline](#-signal-processing-pipeline)
- [Technology Stack](#-technology-stack)
- [API Reference](#-api-reference)
- [Hardware Interface](#-hardware-interface)
- [Development](#-development)
- [Documentation](#-documentation)
- [License](#-license)

---

## 🌟 Overview

Rust-Photoacoustic is a complete platform for laser photoacoustic spectroscopy (LPAS), designed for real-time gas concentration measurement with laboratory-grade precision. The system provides:

- **ppb-level sensitivity** (parts per billion) for trace gas detection
- **Real-time processing** with <10ms latency
- **Multi-platform support** (Linux, macOS, Windows)
- **Industrial integration** via Modbus TCP and REST API
- **Modern web interface** for visualization and control

### Development Philosophy

This project follows a transparent continuous integration approach where development happens openly in the main branch. Tests are designed and implemented in real-time, ensuring code functionality aligns with project objectives.

> ⚠️ **Status**: Active development - APIs may change between commits.

---

## ✨ Key Features

```mermaid
mindmap
root((Rust-Photoacoustic))
Signal Processing
Real-time FFT
Butterworth filters
Differential subtraction
Lock-in detection
Python integration
Hardware Control
USB-HID interface
I2C/SPI protocols
Thermal regulation
DDS modulation
Web Interface
Real-time streaming
OAuth2/JWT security
6 languages + RTL
Interactive graphs
Industrial
Modbus TCP server
Redis Pub/Sub
Kafka streaming
REST API
```

### Performance Metrics

| Metric | Value | Notes |
|--------|-------|-------|
| **Sampling Rate** | 48 kHz | Stereo, 16-bit |
| **FFT Resolution** | 4096 points | Configurable 256-8192 |
| **Processing Latency** | < 10 ms | Real-time streaming |
| **Web Streaming** | 60 fps | SSE with compression |
| **ADC Resolution** | 16-bit | Β±7.8 Β΅V @ PGA=16 |
| **DDS Resolution** | 0.004 Hz | 28-bit frequency register |
| **Temperature Control** | Β±0.1Β°C | PID regulation |

---

## πŸ—οΈ Architecture

```mermaid
flowchart TB
subgraph Hardware["πŸ”§ Hardware Layer"]
MIC["Microphones A/B"]
LASER["QCL/DFB Laser"]
TEC["TEC Controllers"]
NTC["NTC Thermistors"]
end

subgraph LaserSmart["⚑ Laser+Smart Interface"]
USB["USB-HID"]
ADC["4Γ— ADS1115
16-bit ADC"]
DAC["LTC2641
12-bit DAC"]
DDS["AD9833
DDS Modulator"]
end

subgraph Backend["πŸ¦€ Rust Backend"]
ACQ["Acquisition
Daemon"]
PROC["Processing
Graph Engine"]
THERM["Thermal
Regulation"]
API["REST API
+ SSE"]
MODBUS["Modbus
Server"]
end

subgraph Frontend["βš›οΈ React Frontend"]
DASH["Dashboard"]
AUDIO["Audio
Analyzer"]
GRAPH["Processing
Graph Editor"]
THERMAL["Thermal
Monitor"]
end

subgraph External["🌐 External Systems"]
SCADA["SCADA/PLC"]
REDIS["Redis"]
KAFKA["Kafka"]
end

MIC --> ADC
LASER --> DAC
TEC --> DAC
NTC --> ADC

ADC --> USB
DAC --> USB
DDS --> USB
USB --> ACQ

ACQ --> PROC
PROC --> API
PROC --> MODBUS
THERM --> API

API --> DASH
API --> AUDIO
API --> GRAPH
API --> THERMAL

MODBUS --> SCADA
PROC --> REDIS
PROC --> KAFKA
```

---

## πŸš€ Quick Start

### Prerequisites

- **Rust** 1.75 or later
- **Node.js** 20+ (for frontend)
- **Python** 3.10+ (optional, for Python drivers)

### Installation

```bash
# Clone the repository
git clone https://github.com/sctg-development/rust-photoacoustic.git
cd rust-photoacoustic

# Build the backend
cd rust
cargo build --release

# Install frontend dependencies
cd ../web
npm install

# Start the application
cd ../rust
cargo run --release -- --server
```

### Quick Test

```bash
# Run with a test audio file
cargo run -- --input-file examples/test_signal.wav --frequency 2000

# Start server on custom port
cargo run -- --server --web-port 9000

# Enable verbose logging
cargo run -- --server -v
```

---

## πŸ“ Project Structure

```plaintext
rust-photoacoustic/
β”œβ”€β”€ rust/ # πŸ¦€ Rust Backend
β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”œβ”€β”€ main.rs # Application entry point
β”‚ β”‚ β”œβ”€β”€ lib.rs # Library exports
β”‚ β”‚ β”œβ”€β”€ acquisition/ # Audio signal acquisition (CPAL)
β”‚ β”‚ β”œβ”€β”€ preprocessing/ # Digital filters, differential
β”‚ β”‚ β”œβ”€β”€ spectral/ # FFT, spectral analysis
β”‚ β”‚ β”œβ”€β”€ processing/ # Processing graph engine (~3000 lines)
β”‚ β”‚ β”œβ”€β”€ visualization/ # Web server, API, OAuth2
β”‚ β”‚ β”œβ”€β”€ thermal_regulation/ # PID controllers
β”‚ β”‚ β”œβ”€β”€ modbus/ # Modbus TCP server
β”‚ β”‚ β”œβ”€β”€ daemon/ # Acquisition daemon
β”‚ β”‚ β”œβ”€β”€ config/ # Configuration management
β”‚ β”‚ β”œβ”€β”€ photoacoustic/ # Core domain logic
β”‚ β”‚ └── utility/ # Helpers, certificate generation
β”‚ β”œβ”€β”€ auth-macros/ # Procedural macros for auth
β”‚ β”œβ”€β”€ examples/ # Usage examples
β”‚ β”œβ”€β”€ tests/ # Integration tests
β”‚ └── Cargo.toml
β”‚
β”œβ”€β”€ web/ # βš›οΈ React Frontend
β”‚ β”œβ”€β”€ src/
β”‚ β”‚ β”œβ”€β”€ pages/ # Route pages
β”‚ β”‚ β”‚ β”œβ”€β”€ index.tsx # Dashboard
β”‚ β”‚ β”‚ β”œβ”€β”€ audio.tsx # Audio analyzer
β”‚ β”‚ β”‚ β”œβ”€β”€ thermal.tsx # Thermal monitor
β”‚ β”‚ β”‚ └── graph.tsx # Processing graph editor
β”‚ β”‚ β”œβ”€β”€ components/ # Reusable UI components
β”‚ β”‚ β”œβ”€β”€ hooks/ # Custom React hooks
β”‚ β”‚ β”‚ β”œβ”€β”€ useAudioStream.ts # Audio streaming (~2000 lines)
β”‚ β”‚ β”‚ └── useProcessingGraph.ts
β”‚ β”‚ β”œβ”€β”€ authentication/ # Auth0/OIDC integration
β”‚ β”‚ β”œβ”€β”€ locales/ # i18n translations (6 languages)
β”‚ β”‚ └── contexts/ # React contexts
β”‚ └── package.json
β”‚
β”œβ”€β”€ hardware/ # ⚑ Hardware Designs
β”‚ └── 6C47543F-DEE8-4421-881E-CF5E1C8FF55D/ # Laser+Smart
β”‚ β”œβ”€β”€ *.SchDoc # Altium schematics
β”‚ β”œβ”€β”€ components/ # JLCPCB component library
β”‚ └── doc/ # Hardware documentation
β”‚
β”œβ”€β”€ docs/ # πŸ“š Documentation
β”‚ β”œβ”€β”€ COMPLETE_TECHNICAL_DOCUMENTATION.md
β”‚ β”œβ”€β”€ acquisition_daemon_guide_en.md
β”‚ β”œβ”€β”€ jwt_tokens.md
β”‚ └── ...
β”‚
└── .github/ # πŸ”„ CI/CD
└── workflows/
β”œβ”€β”€ ci.yml
β”œβ”€β”€ code-quality.yml
└── release-multiarch.yml
```

---

## βš™οΈ Configuration

### Configuration File

The application uses YAML configuration. Create `config.yaml`:

```yaml
# Audio acquisition settings
acquisition:
sample_rate: 48000 # Hz
buffer_size: 4096 # samples
channels: 2 # stereo (A/B microphones)

# Signal processing settings
processing:
excitation_frequency: 2000.0 # Hz (laser modulation)
filter_bandwidth: 100.0 # Hz (bandpass filter)
fft_size: 4096 # FFT window size
window_function: hann # hann, blackman_harris, hamming
averaging_count: 10 # spectra to average

# Web server settings
visualization:
port: 8080
address: "127.0.0.1"
name: "LaserSmartApiServer/0.1.0"
hmac_secret: "your-secure-jwt-secret-key"
# Optional: Base64-encoded SSL certificates
# cert: "LS0tLS1CRUdJTi..."
# key: "LS0tLS1CRUdJTi..."

# Modbus TCP server (industrial integration)
modbus:
enabled: true
address: "0.0.0.0"
port: 5020

# Thermal regulation (PID control)
thermal_regulation:
enabled: true
setpoint: 25.0 # Β°C
kp: 1.0 # Proportional gain
ki: 0.1 # Integral gain
kd: 0.05 # Derivative gain

# Processing graph (hot-reloadable)
processing_graph:
nodes:
- id: "audio_input"
type: "AudioSource"
config:
device: "default"
- id: "bandpass"
type: "ButterworthFilter"
config:
filter_type: "bandpass"
low_cutoff: 1900.0
high_cutoff: 2100.0
order: 4
- id: "fft"
type: "FFTAnalyzer"
config:
size: 4096
```

### Command Line Options

```bash
# Core options
--config # Configuration file path (default: config.yaml)
--server # Start in server mode
--input-device # Audio input device (e.g., hw:0,0)
--input-file # Analyze WAV file instead of live audio

# Processing parameters
--frequency # Excitation frequency (default: 2000)
--bandwidth # Filter bandwidth (default: 100)
--window-size # FFT size (default: 4096)
--averages # Spectra to average (default: 10)

# Server options
--web-port, -p # Web server port (default: 8080)
--web-address # Bind address (default: 127.0.0.1)
--hmac-secret # JWT signing secret

# Modbus options
--modbus-enabled # Enable Modbus server
--modbus-address # Modbus bind address
--modbus-port # Modbus port (default: 5020)

# Logging
--verbose, -v # Debug logging
--quiet, -q # Suppress all output
--show-config-schema # Print JSON schema and exit
```

### SSL Certificates

Certificates are auto-generated during build for development. For production:

1. Place certificates in `resources/` directory
2. Or specify base64-encoded in config:

```yaml
visualization:
cert: |
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...
key: |
LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0t...
```

---

## πŸ”¬ Physical Principles

### Photoacoustic Spectroscopy

```mermaid
sequenceDiagram
participant L as Modulated Laser
participant G as Gas Sample
participant M as Microphone
participant S as Signal Processing

L->>G: Pulsed IR radiation (f = 2 kHz)
Note over G: Molecular absorption
Hβ‚‚O, COβ‚‚, CHβ‚„...
G->>G: Thermal expansion
(photoacoustic effect)
G->>M: Acoustic wave
M->>S: Electrical signal
S->>S: FFT at excitation frequency
Note over S: Amplitude ∝ concentration
```

**Key equations:**

- Photoacoustic signal: $S_{PA} = \alpha \cdot P_L \cdot C \cdot Q$
- $\alpha$: absorption coefficient (cm⁻¹)
- $P_L$: laser power (W)
- $C$: gas concentration
- $Q$: cell quality factor

- Helmholtz resonance: $f_0 = \frac{c}{2\pi}\sqrt{\frac{A}{V \cdot L}}$
- $c$: speed of sound
- $A$: neck cross-section
- $V$: cavity volume
- $L$: effective neck length

### Differential Detection

Two microphones (A and B) enable common-mode noise rejection:

$$S_{diff} = S_A - S_B$$

This cancels:
- Ambient acoustic noise
- Electronic interference
- Temperature fluctuations

---

## πŸ”„ Signal Processing Pipeline

```mermaid
graph LR
subgraph Acquisition
A1[Mic A] --> |48kHz/16-bit| B1[Buffer A]
A2[Mic B] --> |48kHz/16-bit| B2[Buffer B]
end

subgraph Preprocessing
B1 --> C1[Bandpass
Filter]
B2 --> C2[Bandpass
Filter]
C1 --> D[Differential
A - B]
C2 --> D
end

subgraph Analysis
D --> E[Windowing
Hann/Blackman]
E --> F[FFT
4096 pts]
F --> G[Peak
Detection]
end

subgraph Output
G --> H1[REST API]
G --> H2[Modbus]
G --> H3[SSE Stream]
end
```

### Processing Nodes Available

| Node Type | Description | Parameters |
|-----------|-------------|------------|
| `AudioSource` | Audio input acquisition | device, sample_rate |
| `WavFileSource` | WAV file reader | path, loop |
| `ButterworthFilter` | IIR bandpass/lowpass/highpass | order, cutoff frequencies |
| `Differential` | Channel subtraction | - |
| `FFTAnalyzer` | Spectral analysis | size, window, overlap |
| `PeakDetector` | Frequency/amplitude extraction | threshold, range |
| `Averager` | Temporal averaging | count |
| `PythonNode` | Custom Python processing | script_path |

---

## πŸ› οΈ Technology Stack

### Backend (Rust)

| Category | Technology | Version |
|----------|------------|---------|
| Web Framework | Rocket | 0.5.1 |
| Async Runtime | Tokio | 1.45 |
| Audio | CPAL | 0.17 |
| FFT | RustFFT | 6.4 |
| Auth | jsonwebtoken + oxide-auth | 10.2 |
| Modbus | tokio-modbus | 0.17 |
| Python | PyO3 | 0.27 |
| Serialization | Serde | 1.0 |

### Frontend (TypeScript/React)

| Category | Technology | Version |
|----------|------------|---------|
| Framework | React | 19.2 |
| Build Tool | Vite | 7.3 |
| UI Library | HeroUI | 2.x |
| Charts | Chart.js | 4.5 |
| Flow Editor | ReactFlow | 11.x |
| Audio Viz | AudioMotion | 4.5 |
| i18n | i18next | 25.x |
| Auth | Auth0 / OIDC | 2.x |

### Hardware (Laser+Smart)

| Component | Part Number | Function |
|-----------|-------------|----------|
| MCU | ATmega32U4 | USB-HID controller |
| ADC | ADS1115 Γ—4 | 16-bit, IΒ²C, 860 SPS |
| DAC | LTC2641 | 12-bit, SPI |
| DDS | AD9833 | Frequency synthesis |
| GPIO | MCP23017 | IΒ²C expander |
| Reference | REF5040 | 4.096V precision |

---

## πŸ“‘ API Reference

### Authentication

The API supports OAuth2 with PKCE and JWT bearer tokens:

```bash
# Get OAuth2 authorization
GET /oauth/authorize?client_id=&redirect_uri=&response_type=code&code_challenge=

# Exchange code for token
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=&code_verifier=

# Access protected endpoints
GET /api/v1/spectrum
Authorization: Bearer
```

### REST Endpoints

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/v1/status` | System status |
| GET | `/api/v1/spectrum` | Current spectrum data |
| GET | `/api/v1/spectrum/stream` | SSE spectrum stream |
| GET | `/api/v1/config` | Current configuration |
| PUT | `/api/v1/config` | Update configuration |
| GET | `/api/v1/graph` | Processing graph state |
| PUT | `/api/v1/graph` | Update processing graph |
| GET | `/api/v1/thermal` | Thermal sensor readings |
| PUT | `/api/v1/thermal/setpoint` | Set temperature target |

### Modbus Registers

| Address | Type | Description |
|---------|------|-------------|
| 0-1 | Float32 | Excitation frequency (Hz) |
| 2-3 | Float32 | Signal amplitude |
| 4-5 | Float32 | Phase (degrees) |
| 6-7 | Float32 | Temperature (Β°C) |
| 100+ | Float32[] | Spectrum data |

### OpenAPI Documentation

Interactive API documentation available at:
- **RapiDoc**: `https://localhost:8080/rapidoc`
- **Swagger**: `https://localhost:8080/swagger`

---

## ⚑ Hardware Interface

### Laser+Smart Board

The Laser+Smart interface board provides:

- **4Γ— 16-bit ADC channels** (ADS1115) for microphone and sensor inputs
- **12-bit DAC** (LTC2641) for laser power control
- **DDS synthesizer** (AD9833) for laser modulation (0.004 Hz resolution)
- **16 GPIO** (MCP23017) for auxiliary control
- **USB-HID** interface (no drivers required)

### Connection Diagram

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Laser+Smart Board β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ ADC0-1 β”‚ DAC β”‚ DDS β”‚
β”‚ Mic A/B β”‚ Laser PWR β”‚ Modulation β”‚
β”‚ Β±2.048V β”‚ 0-4.096V β”‚ 100Hz-14kHz β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ ADC2-3 β”‚ GPIO β”‚ USB β”‚
β”‚ NTC Sensors β”‚ TEC Control β”‚ HID to Host β”‚
β”‚ Β±2.048V β”‚ 8 outputs β”‚ Full Speed β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

---

## πŸ’» Development

### Building from Source

```bash
# Development build
cargo build

# Release build with optimizations
cargo build --release

# With Python driver support
cargo build --features python-driver

# Static build (musl)
cargo build --release --features static --target x86_64-unknown-linux-musl
```

### Running Tests

```bash
# Unit tests
cargo test

# Integration tests
cargo test --test '*'

# With coverage
cargo tarpaulin --out Html

# Frontend tests
cd web && npm test
```

### Development Server

```bash
# Backend with hot-reload (requires cargo-watch)
cargo watch -x 'run -- --server -v'

# Frontend dev server
cd web && npm run dev

# Full stack with proxy
cd web && npm run dev:env
```

---

## πŸ“š Documentation

- **[Complete Technical Documentation](COMPLETE_TECHNICAL_DOCUMENTATION.md)** - Comprehensive guide for all audiences
- **[Acquisition Daemon Guide](acquisition_daemon_guide_en.md)** - Audio acquisition system
- **[JWT Tokens](jwt_tokens.md)** - Authentication details
- **[Hardware Analysis](../hardware/doc/driver-analysis-doc.md)** - Laser+Smart interface

---

## πŸ“œ License

This project is licensed under the **SCTG Non-Commercial License 1.0**.

- βœ… Free for research and education
- βœ… Open source contributions welcome
- ❌ Commercial use requires separate license

See [LICENSE](../LICENSE) for details.

---

## 🀝 Contributing

Contributions are welcome! Please read our contributing guidelines before submitting pull requests.

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

---

## πŸ“§ Contact

- **Author**: Ronan Le Meillat
- **Organization**: SCTG Development
- **Repository**: [github.com/sctg-development/rust-photoacoustic](https://github.com/sctg-development/rust-photoacoustic)