Skip to content

Commit

Permalink
modified: src/histoer/histo2d/histogram2d.rs
Browse files Browse the repository at this point in the history
	modified:   src/histoer/histogrammer.rs
	modified:   src/histogram_scripter/custom_scripts.rs
  • Loading branch information
alconley committed Feb 7, 2025
1 parent a566ccd commit a528d50
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 61 deletions.
43 changes: 18 additions & 25 deletions src/histoer/histo2d/histogram2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,36 +104,29 @@ impl Histogram2D {
Some(bin_index)
}

// Convert histogram data to a ColorImage in parallel using Rayon
fn data_2_image(&self) -> egui::ColorImage {
let width = ((self.range.x.max - self.range.x.min) / self.bins.x_width) as usize;
let height = ((self.range.y.max - self.range.y.min) / self.bins.y_width) as usize;

let colormap_options = self.plot_settings.colormap_options;

// Parallelize over rows, and for each row, compute pixel colors for all columns
let pixels: Vec<_> = (0..height)
.into_par_iter()
.map(|y| {
(0..width)
.map(|x| {
let count = self
.bins
.counts
.get(&(x, height - y - 1))
.cloned()
.unwrap_or(0);
self.plot_settings.colormap.color(
count,
self.bins.min_count,
self.bins.max_count,
colormap_options,
)
})
.collect::<Vec<_>>() // Collect each row as a `Vec<Color32>`
})
.flatten() // Flatten the rows into a single Vec<Color32> for pixels
.collect();
// Preallocate a flat buffer for the pixel data.
let total_pixels = width * height;
let mut pixels = vec![egui::Color32::default(); total_pixels];

// Fill the pixel buffer in parallel.
pixels.par_iter_mut().enumerate().for_each(|(i, pixel)| {
// Compute the 2D coordinate.
// (x, y) where we reverse the y coordinate so that y=0 is at the bottom.
let x = i % width;
let y = height - 1 - (i / width);
let count = self.bins.counts.get(&(x, y)).cloned().unwrap_or(0);
*pixel = self.plot_settings.colormap.color(
count,
self.bins.min_count,
self.bins.max_count,
colormap_options,
);
});

egui::ColorImage {
size: [width, height],
Expand Down
111 changes: 87 additions & 24 deletions src/histoer/histogrammer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,47 +329,110 @@ impl Histogrammer {
if let Ok(df) = batch_lf.collect() {
let height = df.height();

// Fill 1D histograms in parallel
// // Fill 1D histograms in parallel
// hist1d_map.par_iter().for_each(|(hist, meta)| {
// if let Ok(column) = df.column(&meta.column_name).and_then(|c| c.f64()) {
// let mut hist = hist.lock().unwrap();
// column.into_no_null_iter().enumerate().for_each(
// |(index, value)| {
// if value != -1e6 && meta.cuts.valid(&df, index) {
// hist.fill(value);
// }
// if index == height || index == 0 {
// hist.plot_settings.egui_settings.reset_axis = true;
// }
// },
// );
// }
// });

// // Fill 2D histograms in parallel
// hist2d_map.par_iter().for_each(|(hist, meta)| {
// if let (Ok(x_col), Ok(y_col)) = (
// df.column(&meta.x_column_name).and_then(|c| c.f64()),
// df.column(&meta.y_column_name).and_then(|c| c.f64()),
// ) {
// let mut hist = hist.lock().unwrap();
// x_col
// .into_no_null_iter()
// .zip(y_col.into_no_null_iter())
// .enumerate()
// .for_each(|(index, (x, y))| {
// if x != -1e6 && y != -1e6 && meta.cuts.valid(&df, index) {
// hist.fill(x, y);
// }
// if index == height {
// hist.plot_settings.recalculate_image = true;
// hist.plot_settings.egui_settings.reset_axis = true;
// hist.plot_settings.x_column =
// meta.x_column_name.clone();
// hist.plot_settings.y_column =
// meta.y_column_name.clone();
// }
// });
// }
// });

// --- Process 1D histograms ---
hist1d_map.par_iter().for_each(|(hist, meta)| {
if let Ok(column) = df.column(&meta.column_name).and_then(|c| c.f64()) {
let mut hist = hist.lock().unwrap();
column.into_no_null_iter().enumerate().for_each(
|(index, value)| {
// Buffer valid updates outside the lock:
let valid_values: Vec<f64> = column
.into_no_null_iter()
.enumerate()
.filter_map(|(index, value)| {
if value != -1e6 && meta.cuts.valid(&df, index) {
hist.fill(value);
Some(value)
} else {
None
}
if index == height || index == 0 {
hist.plot_settings.egui_settings.reset_axis = true;
}
},
);
})
.collect();

// Lock only once to update the histogram:
{
let mut hist_guard = hist.lock().unwrap();
for value in valid_values {
hist_guard.fill(value);
}
// Update the plot settings once after processing the batch.
hist_guard.plot_settings.egui_settings.reset_axis = true;
}
}
});

// Fill 2D histograms in parallel
// --- Process 2D histograms ---
hist2d_map.par_iter().for_each(|(hist, meta)| {
if let (Ok(x_col), Ok(y_col)) = (
df.column(&meta.x_column_name).and_then(|c| c.f64()),
df.column(&meta.y_column_name).and_then(|c| c.f64()),
) {
let mut hist = hist.lock().unwrap();
x_col
// Buffer valid (x, y) pairs outside the lock:
let valid_pairs: Vec<(f64, f64)> = x_col
.into_no_null_iter()
.zip(y_col.into_no_null_iter())
.enumerate()
.for_each(|(index, (x, y))| {
.filter_map(|(index, (x, y))| {
if x != -1e6 && y != -1e6 && meta.cuts.valid(&df, index) {
hist.fill(x, y);
}
if index == height {
hist.plot_settings.recalculate_image = true;
hist.plot_settings.egui_settings.reset_axis = true;
hist.plot_settings.x_column =
meta.x_column_name.clone();
hist.plot_settings.y_column =
meta.y_column_name.clone();
Some((x, y))
} else {
None
}
});
})
.collect();

// Lock once to update the 2D histogram:
{
let mut hist_guard = hist.lock().unwrap();
for (x, y) in valid_pairs {
hist_guard.fill(x, y);
}
// Update plot settings after processing the batch.
hist_guard.plot_settings.recalculate_image = true;
hist_guard.plot_settings.egui_settings.reset_axis = true;
hist_guard.plot_settings.x_column = meta.x_column_name.clone();
hist_guard.plot_settings.y_column = meta.y_column_name.clone();
}
}
});

Expand Down
14 changes: 2 additions & 12 deletions src/histogram_scripter/custom_scripts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ impl Default for CeBrAConfig {
Self {
active: false,
// 9 detectors
detectors: (0..9).map(|i| Cebr3::new(i)).collect(),
detectors: (0..9).map(Cebr3::new).collect(),
}
}
}
Expand Down Expand Up @@ -1230,23 +1230,13 @@ impl ICESPICEConfig {
}

/*************************** SE-SPS Custom Struct ***************************/
#[derive(Clone, serde::Deserialize, serde::Serialize)]
#[derive(Default, Clone, serde::Deserialize, serde::Serialize)]
pub struct SPSConfig {
active: bool,
xavg: Calibration,
cuts: Cuts,
}

impl Default for SPSConfig {
fn default() -> Self {
Self {
active: false,
xavg: Calibration::default(),
cuts: Cuts::default(),
}
}
}

impl SPSConfig {
pub fn new() -> Self {
Self::default()
Expand Down

0 comments on commit a528d50

Please sign in to comment.