How the-devil-8/q-diamond works
1. What this repository is
- Q-Diamond is a desktop measurement suite for NV-centre experiments.
- It combines confocal scanning, ODMR, pulsed measurements, time traces, and optimization into one application.
- The same codebase runs either against simulated instruments or real NI-DAQ / microwave hardware.
2. Top-level application shape
- main.py is the entry point.
- The app is organized around a GUI front end in gui_env, a control/experiment layer in logic, a hardware abstraction layer in interface, and concrete device backends in drivers.
- core provides shared infrastructure used across the app: configuration, logging, module lifecycle, and event routing.
3. Presentation layer
- gui_env/main_window.py is the main container window.
- Feature-specific panels live beside it: confocal_widget.py, odmr_widget.py, pulsed_widget.py, time_trace_widget.py, and log_widget.py.
- These widgets are the user-facing controls and displays; they do not appear to own hardware logic directly.
4. Experiment/control layer
- The logic package contains the measurement workflows and analysis flows.
- Key modules include scan_logic.py, odmr_logic.py, pulsed_logic.py, time_trace_logic.py, zscan_logic.py, and optimizer_logic.py.
- Supporting logic such as sequence_generator.py, fit_logic.py, and data_manager.py handle waveform/sequence creation, fitting/analysis, and persistence of acquired data.
5. Hardware abstraction boundary
- The interface package defines the contracts for the physical subsystems:
- scanner_interface.py
- counter_interface.py
- mw_interface.py
- pulse_interface.py
- These interfaces form the boundary between experiment logic and device-specific implementations, so the logic layer can stay independent of whether hardware is real or simulated.
6. Device backends
- drivers/dummy_scanner.py provides simulation behavior for running without hardware.
- drivers/ni_scanner.py is the real scanner backend for NI-based acquisition.
- drivers/mw_smiq.py connects to the microwave source.
- The README’s “one line” switch in config/hardware.yaml indicates that backend selection is configuration-driven, not code-driven.
7. Shared application infrastructure
- core/base_module.py and core/modular_manager.py suggest a plugin-like module lifecycle and registration model.
- core/signal_bus.py is the central event channel for decoupled communication between GUI, logic, and possibly hardware-facing components.
- core/config_loader.py reads configuration from the YAML files under config/.
- core/logger.py provides centralized logging, likely feeding both console/file output and the GUI log widget.
8. Data flow
- User actions start in a GUI widget.
- The widget triggers a logic module through the shared app infrastructure.
- Logic modules call hardware interfaces, which route to either dummy or real drivers.
- Measurements and status updates propagate back through signals/bus events to the widgets and log panel.
- Analysis and data saving are handled by the logic layer, not the widgets.
9. Measurement pipelines
- Confocal and scan-oriented workflows likely flow through the scanner/counter interfaces and scan_logic / zscan_logic.
- ODMR and pulsed experiments involve the microwave and pulse interfaces, with sequence_generator.py defining timing/control sequences.
- time_trace_logic.py handles single-point fluorescence monitoring, and optimizer_logic.py likely adjusts scan position or experimental settings based on measured signal quality.
10. Configuration and runtime mode
- config/hardware.yaml controls whether dummy or real hardware is used.
- config/scan_config.yaml appears to define scan-related defaults and acquisition parameters.
- This makes the runtime environment declarative: hardware selection and key acquisition parameters are externalized from code.
11. Outputs and analysis
- Data is not just displayed; it is also processed by fit_logic.py and managed by data_manager.py.
- The architecture implies a clear separation between raw acquisition, derived analysis, and presentation.
- That separation matters for the diagram because analysis is part of the experiment pipeline, not a GUI-only concern.
12. External dependencies that matter architecturally
- The presence of NI scanner and SMIQ microwave drivers means the app integrates with lab hardware.
- The project is explicitly designed to tolerate missing hardware by swapping in dummy implementations.
- No external network or cloud services are indicated; the main integration boundary is instrument control.
13. Good diagram boundaries
- Draw four main zones: GUI, logic/analysis, hardware interfaces, and device drivers.
- Show core as shared infrastructure spanning all zones.
- Show configuration files feeding core/config_loader.py, and logging/events flowing through core/logger.py and core/signal_bus.py.
Main entry points: main_window.py Main window · scan_logic.py Scan logic · data_manager.py Data manager · odmr_logic.py ODMR logic
Components 30
GUI
User-facing windows and measurement panels
- Main window · Top-level application container
gui_env/main_window.py - Confocal · Confocal scan controls and display
gui_env/confocal_widget.py - ODMR · ODMR experiment controls and display
gui_env/odmr_widget.py - Pulsed · Pulsed measurement controls and display
gui_env/pulsed_widget.py - Time trace · Time trace monitoring panel
gui_env/time_trace_widget.py - Log panel · UI log viewer
gui_env/log_widget.py
Logic
Measurement workflows, analysis, and persistence
- Scan logic · Confocal and scan acquisition flow
logic/scan_logic.py - Z scan · Axial scan workflow
logic/zscan_logic.py - ODMR logic · Frequency sweep and resonance acquisition
logic/odmr_logic.py - Pulsed logic · Pulse-based measurement workflow
logic/pulsed_logic.py - Time trace logic · Single-point fluorescence monitoring
logic/time_trace_logic.py - Optimizer · Adaptive tuning and positioning
logic/optimizer_logic.py - Sequences · Pulse and timing sequence construction
logic/sequence_generator.py - Fitting · Curve fitting and derived analysis
logic/fit_logic.py - Data manager · Acquisition storage and data handling
logic/data_manager.py
Core
Shared runtime infrastructure
- Base module · Common module lifecycle base
core/base_module.py - Module manager · Registers and coordinates modules
core/modular_manager.py - Signal bus · Decoupled app-wide event routing
core/signal_bus.py - Config loader · Loads runtime configuration
core/config_loader.py - Logger · Centralized application logging
core/logger.py
Interfaces
Hardware abstraction contracts
- Scanner API · Scanner abstraction boundary
interface/scanner_interface.py - Counter API · Photon counter abstraction boundary
interface/counter_interface.py - MW API · Microwave source abstraction boundary
interface/mw_interface.py - Pulse API · Pulse control abstraction boundary
interface/pulse_interface.py
Drivers
Concrete simulated and real instrument backends
- Dummy scanner · Simulated scanner implementation
drivers/dummy_scanner.py - NI scanner · NI-based scanner implementation
drivers/ni_scanner.py - SMIQ driver · Microwave source driver
drivers/mw_smiq.py
Config
Runtime configuration files
- hardware.yaml · Hardware backend selection
config/hardware.yaml - scan_config.yaml · Scan defaults and acquisition parameters
config/scan_config.yaml
Other components
- main.py · Application startup and wiring
main.py
Connections 42
- main.py → Main window: starts · Launches the GUI application
- main.py → Config loader: loads · Initial runtime configuration
- main.py → Module manager: initializes · Sets up module lifecycle coordination
- Main window → Confocal: hosts · Contains measurement panels
- Main window → ODMR: hosts · Contains measurement panels
- Main window → Pulsed: hosts · Contains measurement panels
- Main window → Time trace: hosts · Contains measurement panels
- Main window → Log panel: hosts · Contains log display
- Confocal → Scan logic: drives · Triggers scan workflows
- Confocal → Z scan: drives · Triggers axial scan workflows
- ODMR → ODMR logic: drives · Triggers ODMR workflows
- Pulsed → Pulsed logic: drives · Triggers pulsed workflows
- Time trace → Time trace logic: drives · Triggers monitoring workflows
- Log panel → Signal bus: subscribes · Displays application events and logs
- Scan logic → Scanner API: uses · Reads position-controlled acquisition data
- Scan logic → Counter API: uses · Reads count data during scans
- Z scan → Scanner API: uses · Controls axial scanner motion
- ODMR logic → MW API: uses · Sweeps microwave source
- Pulsed logic → Pulse API: uses · Programs pulse timing and control
- Pulsed logic → Sequences: builds · Generates pulse sequences
- Time trace logic → Counter API: uses · Monitors fluorescence counts
- Optimizer → Scan logic: adapts · Uses scan feedback for optimization
- Fitting → Data manager: writes · Stores processed results and fits
- Scan logic → Data manager: writes · Persists acquired scan data
- ODMR logic → Data manager: writes · Persists ODMR results
- Pulsed logic → Data manager: writes · Persists pulsed measurement data
- Time trace logic → Data manager: writes · Persists trace data
- Scan logic → Fitting: analyzes · Uses fitting for derived metrics
- ODMR logic → Fitting: analyzes · Uses fitting for resonance analysis
- Module manager → Base module: manages · Coordinates module lifecycle
- Module manager → Signal bus: routes · Dispatches decoupled events
- Config loader → hardware.yaml: reads · Loads hardware mode and backend choice
- Config loader → scan_config.yaml: reads · Loads scan defaults and parameters
- Config loader → Logger: configures · Initializes application logging
- Logger → Log panel: feeds · Supplies log messages to UI
- hardware.yaml → Dummy scanner: selects · Chooses simulated scanner backend
- hardware.yaml → NI scanner: selects · Chooses real scanner backend
- hardware.yaml → SMIQ driver: selects · Chooses microwave backend
- Scanner API → Dummy scanner: implemented by · Simulation backend implementation
- Scanner API → NI scanner: implemented by · Real scanner backend implementation
- MW API → SMIQ driver: implemented by · Microwave backend implementation
- Base module → Signal bus: emits · Modules publish state changes and results