C++ API¶
The public phepex:: kernels, grouped by header. Include everything via the umbrella header
<phepex/phepex.hpp>, or a single header for one kernel. Each function’s description below is
rendered from its own header documentation.
Deconvolution & upsampling¶
Declared in <phepex/deconvolve.hpp>.
-
void phepex::deconvolve_upsample(const float *waveforms, int n_ch, int n_pix, int n_samples, int upsampling, const float *pole_zero, const float *baseline, const float *scale, float *out)¶
Pole-zero deconvolution + upsampling of PMT/SiPM waveforms.
Applies, independently to every (channel, pixel) waveform: upsampling by
upsampling, baseline subtraction and scaling, a single-pole-decay (pole-zero) correction, and twoupsampling-wide moving-average smoothings (a forward+backward boxcar pass, so the smoothing introduces no net time shift).pole_zero,baselineandscaleare per-(channel, pixel) arrays ofn_ch*n_pixfloats, indexed row-major likewaveforms. Each may be null, in which case a constant default is used for every pixel: pole_zero = 0 (no pole-zero correction), baseline = 0, scale = 1.The smoothing produces 2*(upsampling-1) invalid samples at each end of every output waveform; where pole_zero != 0, the first 3*upsampling-2 samples are invalid (see deconvolve_valid_range() below).
- Parameters:
waveforms – input, row-major (n_ch, n_pix, n_samples), float32
pole_zero – per-(channel, pixel) pole-zero factors, or null for 0 (no correction)
baseline – per-(channel, pixel) baselines subtracted before scaling, or null for 0
scale – per-(channel, pixel) scale factors, or null for 1
out – caller-allocated output of n_ch*n_pix*n_samples*upsampling floats, row-major (n_ch, n_pix, n_samples*upsampling)
-
struct SampleRange¶
Half-open sample range [lo, hi).
-
SampleRange phepex::deconvolve_valid_range(int upsampling, int n_samples, double pole_zero)¶
Trustworthy (non-edge) output-sample range of deconvolve_upsample(): the upsample+filtfilt boxcar contaminates 2*(upsampling-1) samples at each end, and a non-zero pole_zero adds
upsamplingmore invalid samples at the start.Returns the range into the length upsampling*n_samples deconvolution output.
Waveform preprocessing¶
Declared in <phepex/preprocess.hpp>. Single-waveform upsampling + pole-zero deconvolution
with optional Deriche (1992) Gaussian smoothing, plus its DVR-convention valid range.
-
struct SmoothingCoefficients¶
Coefficients for the delay-compensated second-order IIR (Deriche 1992) Gaussian-like smoothing applied by preprocess_waveform().
-
SmoothingCoefficients phepex::calculate_smoothing_coefficients(double smoothing_fwhm)¶
Compute the smoothing coefficients for a given impulse-response FWHM (in samples).
-
void phepex::preprocess_waveform(const std::uint16_t *src, int n_samples, int upsampling, float pole_zero, const SmoothingCoefficients *smoothing, float offset, float scale, float *out, float *scratch = nullptr)¶
Upsampling + pole-zero deconvolution of a single waveform, with optional Gaussian smoothing.
Repeats each of the
n_samplesinputsupsamplingtimes, subtractsoffsetand appliesscale, corrects a single-pole decaypole_zero, and smooths with twoupsampling-wide moving averages; whensmoothing != nullptran additional Deriche IIR pass is applied.upsampling == 1degenerates to scale*(src - offset).Writes
n_samples*upsamplingfloats toout(caller-allocated). All arithmetic is float32;offset/scale/pole_zeroare float on purpose (bit-exactness).- Parameters:
src – input waveform of
n_samplessamplessmoothing – optional Deriche coefficients; nullptr disables smoothing
out – caller-allocated output of n_samples*upsampling floats
scratch – optional caller-provided workspace of at least n_samples*upsampling floats, used only when
smoothing != nullptr; if null a buffer is allocated internally for the duration of the call
-
void phepex::preprocess_waveform(const float *src, int n_samples, int upsampling, float pole_zero, const SmoothingCoefficients *smoothing, float offset, float scale, float *out, float *scratch = nullptr)¶
-
SampleRange phepex::preprocess_valid_range(int upsampling, float pole_zero, const SmoothingCoefficients *smoothing, int num_samples)¶
Trustworthy (non-edge) sample range of preprocess_waveform(): the boxcar smoothing contaminates 2*(upsampling-1) samples at each end, a non-zero pole_zero adds
upsamplingmore invalid samples at the start, and smoothing widens both margins by floor(fwhm).The upper bound follows the DVR convention
num_samples - right(using the RAW, pre-upsamplenum_samples) — this differs from deconvolve_valid_range(). Returns {0, 0} if the margins exceednum_samples.
Clipping¶
Declared in <phepex/clip.hpp>.
-
void phepex::pos_soft_clip(const float *waveforms, int n_ch, int n_pix, int n_up, float scale, int sample_lo, int sample_hi, float *out)¶
Positive soft clip: max(y/(1+|y|), 0) with y = x/scale, applied over samples [sample_lo, sample_hi) of each (channel, pixel) waveform; samples outside that range are set to 0.
Passing sample_lo == sample_hi == 0 means the full trace. The soft clip already bounds the result to (-1,1), so only negatives are clamped (to 0).
- Parameters:
waveforms – input (n_ch, n_pix, n_up) float32
out – caller-allocated n_ch*n_pix*n_up floats (fully written; 0 outside range)
Neighbour peak finding¶
Declared in <phepex/neighbor.hpp>.
-
void phepex::neighbor_peak_indices(const float *waveforms, int n_ch, int n_pix, int n_up, const std::int32_t *indptr, const std::int32_t *indices, int local_weight, const bool *broken_pixels, int sample_lo, int sample_hi, std::int64_t *peak_out, std::int32_t *neighbor_count = nullptr, float *scratch = nullptr)¶
Per-pixel peak index (over samples in [sample_lo, sample_hi)) of the neighbour-summed waveform: average = waveforms[pixel]*local_weight + sum over non-broken neighbours.
First-max tie-break, float32 accumulation, no normalisation. Passing sample_lo == sample_hi == 0 means the full trace.
Neighbours are given as a CSR adjacency (compressed sparse row: row pointers + column indices): pixel p’s neighbours are indices[indptr[p] .. indptr[p+1]).
- Parameters:
waveforms – input (n_ch, n_pix, n_up) float32
indptr – CSR row pointers, length n_pix+1
indices – CSR column indices (neighbour pixel ids), length indptr[n_pix]
broken_pixels – (n_ch, n_pix) bool; broken neighbours are skipped
peak_out – caller-allocated n_ch*n_pix int64 (argmax sample index per pixel)
neighbor_count – optional n_ch*n_pix int32 (caller-allocated); if non-null, gets the number of non-broken neighbours summed per pixel
scratch – optional caller-provided workspace of at least n_up floats; if null, a buffer is allocated internally for the duration of the call
Charge & timing extraction¶
Declared in <phepex/extract.hpp>.
-
void phepex::extract_around_peak(const float *waveforms, int n_ch, int n_pix, int n_up, const std::int64_t *peak_index, int width, int shift, double sampling_rate_ghz, float *charge, float *peak_time)¶
Window integration + amplitude-weighted peak time, per (channel, pixel).
Sums the waveform over [peak-shift, peak-shift+width) (clamped to the trace) and computes the amplitude-weighted centroid over strictly-positive samples, in ns (divided by sampling_rate_ghz). float64 accumulation; float32 outputs.
- Parameters:
waveforms – input (n_ch, n_pix, n_up) float32
peak_index – (n_ch, n_pix) int64 peak sample index per pixel
charge – caller-allocated n_ch*n_pix float32 (integrated charge)
peak_time – caller-allocated n_ch*n_pix float32 (peak time, ns)
-
void phepex::adaptive_centroid(const float *waveforms, int n_ch, int n_pix, int n_up, const std::int64_t *peak_index, double rel_descend_limit, float *centroids)¶
Leading-edge weighted centroid (in sample units), per (channel, pixel): walks left then right from peak while samples exceed rel_descend_limit*peak_amplitude, accumulating an amplitude-weighted index centroid.
float64 accumulation; float32 output.
- Parameters:
waveforms – input (n_ch, n_pix, n_up) float32
peak_index – (n_ch, n_pix) int64 peak sample index per pixel
centroids – caller-allocated n_ch*n_pix float32 (centroid, sample units)
Waveform generation¶
Declared in <phepex/generate.hpp>.
-
void phepex::generate_waveforms(const double *charge, const double *time_ns, int n_events, int n_pix, const double *reference_pulse, int n_ref, double ref_sample_width_ns, double sample_width_ns, int n_samples, int upsampling, double nsb_rate_ghz, std::uint64_t seed, float *out)¶
Synthesize sampled waveforms from per-pixel (charge, peak_time): for the signal component, each pixel’s charge is deposited at its sub-sample peak time and convolved with the reference pulse shape; a temporally-distributed Poisson night-sky-background (NSB) process at nsb_rate_ghz is added on top.
Intended as a fast generator for testing/benchmarking extractors.
- Parameters:
charge – (n_events, n_pix) float64 photo-electron charge per pixel
time_ns – (n_events, n_pix) float64 pulse peak time (ns) per pixel
reference_pulse – (n_ref) float64 single-channel reference pulse shape
ref_sample_width_ns – sample width of the reference pulse (ns)
sample_width_ns – readout sample width (ns) = 1 / sampling_rate
upsampling – internal upsampling used to place sub-sample deposits (e.g. 10)
nsb_rate_ghz – NSB rate in GHz (0 disables NSB)
seed – RNG seed (per-event deterministic)
out – caller-allocated n_events*n_pix*n_samples float32, row-major (n_events, n_pix, n_samples)