added timer and file processing

This commit is contained in:
Erik Frojdh
2026-06-02 15:24:01 +02:00
parent c10bcb8075
commit fc76f36413
6 changed files with 144 additions and 2 deletions
@@ -14,6 +14,7 @@
#include <mutex>
#include <thread>
#include <vector>
#include <filesystem>
namespace aare {
@@ -103,6 +104,10 @@ class PedestalTrackingPixelHistogram {
void fill_async(NDArray<FrameType, 2> image);
void fill_from_file(const std::filesystem::path &fname, ssize_t max_frames = -1, bool verbose = false);
void process_pedestal_file(const std::filesystem::path &fname, ssize_t max_frames = -1, bool verbose = false);
// Sigma multiplier for the pedestal-update gate in
// fill_async. Atomic; safe to read/write at any
// time (the new value takes effect on subsequent pixel evaluations).
+1
View File
@@ -84,6 +84,7 @@ void PixelHistogramImpl<T, StorageType>::fill(const NDView<T, 2> &frame) {
template <typename T, typename StorageType>
void PixelHistogramImpl<T, StorageType>::fill(int row, int col, T value) {
//TODO! add out of bounds check on row and col???
if (value < m_xmin || value >= m_xmax) {
return;
}
+1 -1
View File
@@ -33,7 +33,7 @@ from .CtbRawFile import CtbRawFile
from .RawFile import RawFile
from .ScanParameters import ScanParameters
from .utils import random_pixels, random_pixel, flat_list, add_colorbar
from .utils import random_pixels, random_pixel, flat_list, add_colorbar, Timer
#make functions available in the top level API
+16 -1
View File
@@ -2,6 +2,7 @@
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import time
def random_pixels(n_pixels, xmin=0, xmax=512, ymin=0, ymax=1024):
"""Return a list of random pixels.
@@ -34,4 +35,18 @@ def add_colorbar(ax, im, size="5%", pad=0.05):
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size=size, pad=pad)
plt.colorbar(im, cax=cax)
return ax, im, cax
return ax, im, cax
class Timer:
def __init__(self, label="Elapsed time:", verbose=True):
self.label = label
self.verbose = verbose
def __enter__(self):
self.start = time.perf_counter()
return self
def __exit__(self, exc_type, exc, tb):
self.elapsed = time.perf_counter() - self.start
if self.verbose:
print(f"{self.label} {self.elapsed:.3f}s")
@@ -142,6 +142,25 @@ void define_pedestal_tracking_pixel_histogram_bindings(py::module &m) {
)",
py::arg("image").noconvert())
.def("fill_from_file", &PedestalTrackingPixelHistogram::fill_from_file,
R"(
Fill the histogram from a file.
Args:
file_path: Path to the file to fill from
max_frames: Maximum number of frames to fill from the file (default: -1)
)",py::call_guard<py::gil_scoped_release>(),
py::arg("fname"), py::arg("max_frames") = -1, py::arg("verbose") = false)
.def("process_pedestal_file", &PedestalTrackingPixelHistogram::process_pedestal_file,
R"(
Process a pedestal file.
Args:
file_path: Path to the file to process
max_frames: Maximum number of frames to process from the file (default: -1)
)",py::call_guard<py::gil_scoped_release>(),
py::arg("fname"), py::arg("max_frames") = -1, py::arg("verbose") = false)
.def_property("n_sigma", &PedestalTrackingPixelHistogram::n_sigma,
&PedestalTrackingPixelHistogram::set_n_sigma,
R"(
+102
View File
@@ -1,12 +1,15 @@
#include "aare/PedestalTrackingPixelHistogram.hpp"
#include "aare/File.hpp"
#include <algorithm>
#include <chrono>
#include <cmath>
#include <cstring>
#include <stdexcept>
#include <utility>
#include <vector>
#include <fmt/format.h>
namespace aare {
PedestalTrackingPixelHistogram::PedestalTrackingPixelHistogram(
@@ -386,4 +389,103 @@ PedestalTrackingPixelHistogram::bin_edges() const {
return partial_hists_.front().bin_edges();
}
void PedestalTrackingPixelHistogram::fill_from_file(const std::filesystem::path &fname, ssize_t max_frames, bool verbose) {
constexpr std::size_t progress_interval = 66;
auto last = std::chrono::steady_clock::now();
File f(fname);
//check that row col matches constructor
if (f.rows() != rows_ || f.cols() != cols_) {
throw std::invalid_argument(
"PedestalTrackingPixelHistogram: Frame in file {} has shape ({}, {}) does not match "
"constructor shape");
}
const ssize_t total_frames = f.total_frames();
const ssize_t n_frames = max_frames == -1 ? total_frames : std::min(max_frames, total_frames);
for (ssize_t i = 0; i < n_frames; ++i) {
aare::NDArray<uint16_t> frame({rows_, cols_});
f.read_into(reinterpret_cast<std::byte *>(frame.data()));
fill_async(frame);
// print progress
if (verbose && ((i + 1) % progress_interval == 0 || (i + 1 == n_frames))) {
const auto now = std::chrono::steady_clock::now();
const double dt =
std::chrono::duration<double>(now - last).count();
const std::size_t done_in_interval =
(i + 1) % progress_interval == 0
? progress_interval
: (i + 1) % progress_interval;
const double fps =
dt > 0.0 ? static_cast<double>(done_in_interval) / dt
: 0.0;
// Carriage return (no newline) so the line is rewritten
// in place; flush since stdout is line-buffered.
fmt::print("\rProgress: {}/{} ({:.1f}%) {:.1f} FPS ",
i + 1, n_frames,
100.0 * static_cast<double>(i + 1) /
static_cast<double>(n_frames),
fps);
std::fflush(stdout);
last = now;
}
}
flush();
if (verbose) {
fmt::print("\n\n");
std::fflush(stdout);
}
}
void PedestalTrackingPixelHistogram::process_pedestal_file(const std::filesystem::path &fname, ssize_t max_frames, bool verbose) {
constexpr std::size_t progress_interval = 66;
auto last = std::chrono::steady_clock::now();
File f(fname);
//check that row col matches constructor
if (f.rows() != rows_ || f.cols() != cols_) {
throw std::invalid_argument(
"PedestalTrackingPixelHistogram: Frame in file {} has shape ({}, {}) does not match "
"constructor shape");
}
const ssize_t total_frames = f.total_frames();
const ssize_t n_frames = max_frames == -1 ? total_frames : std::min(max_frames, total_frames);
aare::NDArray<uint16_t> frame({rows_, cols_});
for (ssize_t i = 0; i < n_frames; ++i) {
f.read_into(reinterpret_cast<std::byte *>(frame.data()));
push_pedestal_no_update(frame.view());
if (verbose && ((i + 1) % progress_interval == 0 || (i + 1 == n_frames))) {
const auto now = std::chrono::steady_clock::now();
const double dt =
std::chrono::duration<double>(now - last).count();
const std::size_t done_in_interval =
(i + 1) % progress_interval == 0
? progress_interval
: (i + 1) % progress_interval;
const double fps =
dt > 0.0 ? static_cast<double>(done_in_interval) / dt
: 0.0;
fmt::print("\rProgress: {}/{} ({:.1f}%) {:.1f} FPS ",
i + 1, n_frames,
100.0 * static_cast<double>(i + 1) /
static_cast<double>(n_frames),
fps);
std::fflush(stdout);
last = now;
}
}
update_mean();
flush();
if (verbose) {
fmt::print("\n\n");
std::fflush(stdout);
}
}
} // namespace aare