Skip to content

Commit

Permalink
ui options
Browse files Browse the repository at this point in the history
  • Loading branch information
jordens committed Oct 9, 2023
1 parent 5cfabe3 commit 8944825
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 58 deletions.
140 changes: 96 additions & 44 deletions src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

use anyhow::Result;
use clap::Parser;
use eframe::egui;
use eframe::egui::plot::{Legend, Line, Plot, PlotPoints};
use eframe::egui::{self, ComboBox, Slider};
use std::sync::mpsc;
use std::time::Duration;

Expand All @@ -16,7 +16,7 @@ use stabilizer_streaming::{
enum Cmd {
Exit,
Reset,
Send,
Send(AcqOpts),
}

struct Trace {
Expand All @@ -29,6 +29,12 @@ pub struct Opts {
#[command(flatten)]
source: SourceOpts,

#[command(flatten)]
acq: AcqOpts,
}

#[derive(Parser, Debug, Copy, Clone)]
pub struct AcqOpts {
/// Exclude PSD stages with less than or equal this averaging level
#[arg(short, long, default_value_t = 1)]
min_avg: usize,
Expand All @@ -41,9 +47,14 @@ pub struct Opts {
#[arg(short, long, default_value_t = 1.0f32)]
fs: f32,

/// Exponential averaging, negative for constant time, positive for constant count accross stages
/// Exponential averaging
#[arg(short, long, default_value_t = 100000)]
max_avg: isize,
max_avg: usize,

/// Enable for constant time averaging across stages
/// Disable for constant count averaging across stages
#[arg(short, long)]
scale_avg: bool,

/// Integrate jitter (linear)
#[arg(short, long)]
Expand All @@ -52,16 +63,7 @@ pub struct Opts {

fn main() -> Result<()> {
env_logger::init();
let Opts {
source,
min_avg,
detrend,
fs,
max_avg,
integrate,
} = Opts::parse();

let logfs = fs.log10();
let Opts { source, mut acq } = Opts::parse();

let (cmd_send, cmd_recv) = mpsc::channel();
let (trace_send, trace_recv) = mpsc::sync_channel(1);
Expand All @@ -75,8 +77,8 @@ fn main() -> Result<()> {
dec.extend((0..4).map(|_| {
let mut c = PsdCascade::<{ 1 << 9 }>::default();
c.set_stage_depth(3);
c.set_detrend(detrend);
c.set_avg(max_avg);
c.set_detrend(acq.detrend);
c.set_avg(acq.scale_avg, acq.max_avg);
c
}));
}
Expand All @@ -94,12 +96,14 @@ fn main() -> Result<()> {
Err(mpsc::TryRecvError::Disconnected) | Ok(Cmd::Exit) => break,
Ok(Cmd::Reset) => dec.clear(),
Err(mpsc::TryRecvError::Empty) => {}
Ok(Cmd::Send) => {
Ok(Cmd::Send(opts)) => {
acq = opts;
let logfs = acq.fs.log10();
let trace = dec
.iter()
.map(|dec| {
let (p, b) = dec.psd(min_avg);
let f = Break::frequencies(&b, min_avg);
let (p, b) = dec.psd(acq.min_avg);
let f = Break::frequencies(&b, acq.min_avg);
let (mut p0, mut f0) = (0.0, 0.0);
Trace {
breaks: b,
Expand All @@ -109,12 +113,12 @@ fn main() -> Result<()> {
.rev()
.skip(1) // skip DC
.map(|(f, p)| {
let fsf = fs * f;
let fsf = acq.fs * f;
p0 += p * (fsf - f0);
f0 = fsf;
[
fsf.log10() as f64,
(if integrate {
(if acq.integrate {
p0
} else {
10.0 * (p.log10() - logfs)
Expand Down Expand Up @@ -144,15 +148,15 @@ fn main() -> Result<()> {
});

let options = eframe::NativeOptions {
initial_window_size: Some((1000.0, 700.0).into()),
initial_window_size: Some((1200.0, 700.0).into()),
..Default::default()
};
eframe::run_native(
"FLS",
options,
Box::new(|cc| {
Box::new(move |cc| {
cc.egui_ctx.set_visuals(egui::Visuals::light());
Box::new(FLS::new(trace_recv, cmd_send))
Box::new(FLS::new(trace_recv, cmd_send, acq))
}),
)
.unwrap();
Expand All @@ -166,14 +170,20 @@ pub struct FLS {
trace_recv: mpsc::Receiver<Vec<Trace>>,
cmd_send: mpsc::Sender<Cmd>,
current: Vec<Trace>,
acq: AcqOpts,
}

impl FLS {
fn new(trace_recv: mpsc::Receiver<Vec<Trace>>, cmd_send: mpsc::Sender<Cmd>) -> Self {
fn new(
trace_recv: mpsc::Receiver<Vec<Trace>>,
cmd_send: mpsc::Sender<Cmd>,
acq: AcqOpts,
) -> Self {
Self {
trace_recv,
cmd_send,
current: vec![],
acq,
}
}
}
Expand All @@ -194,31 +204,73 @@ impl eframe::App for FLS {
Err(mpsc::TryRecvError::Disconnected) => panic!("lost data processing thread"),
};

let plot: Plot = Plot::new("")
.height(ui.available_height() - 20.0)
// TODO proper log axis
// .x_grid_spacer(log_grid_spacer(10))
// .x_axis_formatter(log_axis_formatter())
.legend(Legend::default());
plot.show(ui, |plot_ui| {
// TODO trace names
for (trace, name) in self.current.iter().zip("ABCD".chars()) {
if trace.psd.first().is_some_and(|v| v[1].is_finite()) {
plot_ui.line(Line::new(PlotPoints::from(trace.psd.clone())).name(name));
}
}
ui.horizontal(|ui| {
ComboBox::from_label("Detrend")
.selected_text(format!("{:?}", self.acq.detrend))
.show_ui(ui, |ui| {
ui.selectable_value(&mut self.acq.detrend, Detrend::None, "None");
ui.selectable_value(&mut self.acq.detrend, Detrend::Mid, "Mid");
ui.selectable_value(&mut self.acq.detrend, Detrend::Span, "Span");
ui.selectable_value(&mut self.acq.detrend, Detrend::Mean, "Mean");
// ui.selectable_value(&mut self.acq.detrend, Detrend::Linear, "Linear");
})
.response
.on_hover_text("Segment detrending method");
ui.separator();
ui.add(
Slider::new(&mut self.acq.max_avg, 1..=1_000_000)
.text("Averages")
.logarithmic(true),
).on_hover_text("Averaging count: when below, the averaging is boxcar, when above it continues with exponential averaging");
ui.separator();
ui.checkbox(&mut self.acq.scale_avg, "Constant time avg").on_hover_text("Scale stage averaging count by stage dependent sample rate");
ui.separator();
ui.add(
Slider::new(&mut self.acq.min_avg, 0..=self.acq.max_avg)
.text("Min Count")
.logarithmic(true),
).on_hover_text("Minimum averaging count to show data from a stage");
});

ui.horizontal(|ui| {
if ui.button("Reset").clicked() {
self.cmd_send.send(Cmd::Reset).unwrap();
}
ui.add(
Slider::new(&mut self.acq.fs, 1e-3..=1e9)
.text("Sample rate")
.custom_formatter(|x, _| format!("{:.2e}", x))
.suffix(" Hz")
.logarithmic(true),
)
.on_hover_text("Input sample rate");
ui.separator();
ui.checkbox(&mut self.acq.integrate, "Integrate").on_hover_text("Integrate PSD into cumulative sum");
ui.separator();
self.current
.first()
.and_then(|t| t.breaks.first())
.map(|bi| ui.label(format!("{:.2e} top level averages", bi.count as f32)));
.map(|bi| ui.label(format!("{:.2e}", bi.count as f32)).on_hover_text("Top level average count"));
ui.separator();
if ui
.button("Reset")
.on_hover_text("Reset PSD stages and begin anew")
.clicked()
{
self.cmd_send.send(Cmd::Reset).unwrap();
}
});

Plot::new("plot")
// TODO proper log axis
// .x_grid_spacer(log_grid_spacer(10))
// .x_axis_formatter(log_axis_formatter())
.legend(Legend::default())
.show(ui, |plot_ui| {
// TODO trace names
for (trace, name) in self.current.iter().zip("ABCD".chars()) {
if trace.psd.first().is_some_and(|v| v[1].is_finite()) {
plot_ui.line(Line::new(PlotPoints::from(trace.psd.clone())).name(name));
}
}
});
});
self.cmd_send.send(Cmd::Send).unwrap();
self.cmd_send.send(Cmd::Send(self.acq)).unwrap();
}
}
20 changes: 6 additions & 14 deletions src/psd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ pub struct PsdCascade<const N: usize> {
stage_depth: usize,
detrend: Detrend,
win: Arc<Window<N>>,
avg: isize,
avg: (bool, usize),
}

impl<const N: usize> Default for PsdCascade<N> {
Expand All @@ -364,7 +364,7 @@ impl<const N: usize> Default for PsdCascade<N> {
stage_depth: 1,
detrend: Detrend::None,
win,
avg: isize::MAX,
avg: (false, usize::MAX),
}
}
}
Expand All @@ -382,14 +382,10 @@ impl<const N: usize> PsdCascade<N> {
}
}

pub fn set_avg(&mut self, avg: isize) {
self.avg = avg;
pub fn set_avg(&mut self, scale: bool, avg: usize) {
self.avg = (scale, avg);
for (i, stage) in self.stages.iter_mut().enumerate() {
stage.set_avg(if self.avg < 0 {
(-self.avg) >> (self.stage_depth * i)
} else {
self.avg
} as _);
stage.set_avg((self.avg.1 >> if self.avg.0 { self.stage_depth * i } else { 0 }) as _);
}
}

Expand All @@ -405,11 +401,7 @@ impl<const N: usize> PsdCascade<N> {
let mut stage = Psd::new(self.fft.clone(), self.win.clone());
stage.set_stage_depth(self.stage_depth);
stage.set_detrend(self.detrend);
stage.set_avg(if self.avg < 0 {
(-self.avg) >> (self.stage_depth * i)
} else {
self.avg
} as _);
stage.set_avg((self.avg.1 >> if self.avg.0 { self.stage_depth * i } else { 0 }) as _);
self.stages.push(stage);
}
&mut self.stages[i]
Expand Down

0 comments on commit 8944825

Please sign in to comment.