Initial commit

This commit is contained in:
redclawsystems
2026-03-04 00:08:42 +00:00
commit 4d88dc0584
4449 changed files with 1556714 additions and 0 deletions
@@ -0,0 +1,181 @@
//! Neuro service for state management.
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
use super::types::*;
/// Loaded recording with metadata
pub struct LoadedRecording {
pub handle: RecordingHandle,
pub data: Vec<Vec<f64>>,
pub sfreq: f64,
pub channel_names: Vec<String>,
pub channel_types: Vec<String>,
pub events: Vec<EventDto>,
}
/// Loaded BIDS dataset storage
pub struct LoadedBidsDataset {
pub handle: BidsDatasetHandle,
pub dataset: rtx_neuro::io::bids::BidsDataset,
}
/// Epochs data storage
pub struct EpochsData {
pub handle: EpochsHandle,
/// [n_epochs x n_channels x n_times]
pub data: Vec<Vec<Vec<f64>>>,
pub times: Vec<f64>,
pub channel_names: Vec<String>,
}
/// Forward model storage
pub struct ForwardModel {
pub handle: ForwardHandle,
/// Gain matrix [n_sensors x n_sources*3]
pub gain: Vec<Vec<f64>>,
/// Source positions [n_sources x 3]
pub source_positions: Vec<[f64; 3]>,
/// Sensor positions [n_sensors x 3]
pub sensor_positions: Vec<[f64; 3]>,
}
/// Inverse operator storage
pub struct InverseOperator {
pub handle: InverseHandle,
/// Inverse kernel [n_sources x n_channels]
pub kernel: Vec<Vec<f64>>,
/// Source positions
pub source_positions: Vec<[f64; 3]>,
}
/// SSP projector storage
pub struct SspProjectorData {
pub handle: SspHandle,
/// Projector vectors [n_projectors x n_channels]
pub vectors: Vec<Vec<f64>>,
/// Active flags
pub active: Vec<bool>,
}
/// ICA model storage
#[derive(Clone)]
pub struct IcaModelData {
pub handle: IcaHandle,
/// Unmixing matrix [n_components x n_channels]
pub unmixing: Vec<Vec<f64>>,
/// Mixing matrix [n_channels x n_components]
pub mixing: Vec<Vec<f64>>,
}
/// Loaded FreeSurfer subject storage
pub struct LoadedFreeSurferSubject {
pub handle: FreeSurferHandleDto,
pub subject: rtx_neuro_anatomy::FreeSurferSubject,
}
/// Handle to artifact detector
pub struct ArtifactDetectorHandle {
pub config: ArtifactDetectorConfigDto,
}
/// Holds GNN model and metadata
pub struct GnnModelHolder {
pub config: GnnModelConfigDto,
pub n_parameters: usize,
}
/// Neuro service managing recordings and processing
pub struct NeuroService {
pub(crate) recordings: HashMap<String, LoadedRecording>,
pub(crate) epochs: HashMap<String, EpochsData>,
pub(crate) forward_models: HashMap<String, ForwardModel>,
pub(crate) inverse_operators: HashMap<String, InverseOperator>,
pub(crate) ssp_projectors: HashMap<String, SspProjectorData>,
pub(crate) ica_models: HashMap<String, IcaModelData>,
pub(crate) bids_datasets: HashMap<String, LoadedBidsDataset>,
pub(crate) freesurfer_subjects: HashMap<String, LoadedFreeSurferSubject>,
pub(crate) active_recording: Option<String>,
pub(crate) counter: usize,
}
impl NeuroService {
/// Create a new neuro service
pub fn new() -> Self {
Self {
recordings: HashMap::new(),
epochs: HashMap::new(),
forward_models: HashMap::new(),
inverse_operators: HashMap::new(),
ssp_projectors: HashMap::new(),
ica_models: HashMap::new(),
bids_datasets: HashMap::new(),
freesurfer_subjects: HashMap::new(),
active_recording: None,
counter: 0,
}
}
/// Generate a unique ID
pub fn next_id(&mut self, prefix: &str) -> String {
self.counter += 1;
format!("{}_{}", prefix, self.counter)
}
/// Get service status
pub fn status(&self) -> NeuroStatus {
let memory_usage = self.recordings.values().map(|r| {
r.data.iter().map(|ch| ch.len() * std::mem::size_of::<f64>()).sum::<usize>()
}).sum::<usize>() + self.epochs.values().map(|e| {
e.data.iter().map(|ep| {
ep.iter().map(|ch| ch.len() * std::mem::size_of::<f64>()).sum::<usize>()
}).sum::<usize>()
}).sum::<usize>();
NeuroStatus {
n_recordings: self.recordings.len(),
active_recording: self.active_recording.clone(),
n_epochs_sets: self.epochs.len(),
memory_usage,
}
}
/// Reset the service, clearing all data
pub fn reset(&mut self) {
self.recordings.clear();
self.epochs.clear();
self.forward_models.clear();
self.inverse_operators.clear();
self.ssp_projectors.clear();
self.ica_models.clear();
self.bids_datasets.clear();
self.freesurfer_subjects.clear();
self.active_recording = None;
}
}
impl Default for NeuroService {
fn default() -> Self {
Self::new()
}
}
/// Type alias for the neuro state used by Tauri commands
pub type NeuroState = Arc<RwLock<NeuroService>>;
/// State for LSL service
pub type LslState = Arc<RwLock<rtx_neuro_lsl::LslService>>;
/// BCI pipeline state
pub type BciState = Arc<RwLock<Option<rtx_neuro_realtime::BciPipeline>>>;
/// State for artifact detector
pub type ArtifactDetectorState = Arc<RwLock<Option<ArtifactDetectorHandle>>>;
/// GNN state for managing models
pub type GnnModelState = Arc<RwLock<Option<GnnModelHolder>>>;
/// Separate state for the database to avoid async/sync conflicts
pub type DatabaseState = Arc<RwLock<Option<rtx_neuro_db::NeuroDatabase>>>;