use std::ops::Range;
use cubecl::prelude::*;
use cubecl::server::Handle;
use dspk_ops::peaks::find_peak_candidates;
use super::spacing::SpikeSpacing;
use super::threshold::{SpikeEvent, SpikePolarity};
#[allow(clippy::too_many_arguments)]
pub fn execute_detect_spikes_in_vram(
client: &Client,
trace: &Handle,
heights: &Handle,
channels: usize,
samples: usize,
emit: Range<usize>,
global_offset: u64,
polarity: SpikePolarity,
spacing: SpikeSpacing,
) -> Vec<SpikeEvent> {
if channels == 0 || emit.is_empty() {
return Vec::new();
}
let d = spacing.distance();
let scan = emit.start.saturating_sub(d)..(emit.end + d).min(samples);
let candidates = find_peak_candidates::<f32>(client, trace, heights, channels, samples, scan, polarity.into());
let mut events = Vec::new();
for ch in 0..channels {
let (indices, values) = candidates.channel(ch);
let scored: Vec<(usize, f32, f32)> = indices.iter().zip(values).map(|(&t, &v)| (t as usize, v.abs(), v)).collect();
events.extend(spacing.select(scored).into_iter().filter(|(t, _, _)| emit.contains(t)).map(|(t, _, v)| SpikeEvent {
channel_id: ch,
sample_index: global_offset + t as u64,
peak_amplitude_uv: v,
}));
}
events.sort_by_key(|s| (s.sample_index, s.channel_id));
events
}