goldpan.cuts

Cuts: pulses in, one boolean per pulse out (True = keep).

Every function takes an array shaped (..., n_samples) and returns a boolean array of shape (...,). Cuts are plain functions of the quantities in goldpan.quantities – combine them with ordinary &/|/~ rather than a special combinator API.

randoms and real_triggers are the exception: they take an array of trigger-type labels (see goldpan.io.trigger_types), not pulses, since that is per-event metadata.

Percentile-based cuts (quiet_baseline, excursion_below_percentile) compute the percentile from the batch passed in, i.e. “quiet relative to this population” – pass the same batch you’re about to select from, not some other reference set, unless that’s actually what you want.

Functions

active(pulses, config)

~dead_channel, as its own name for readability at call sites.

dead_channel(pulses, config)

True where the pretrigger std is exactly zero -- channel not read out for this pulse, not merely a quiet channel.

excursion_band(pulses, config[, low, high, ...])

True where log_excursion_ratio is in [low, high) -- default [0.5, 0.7), the "tight" Branch 2 cut from 07221203_2025_dump1_noise.ipynb (cleanest slice found there, though even it keeps 13 of its 192 traces that look like real pulses -- see excursion_band_AI).

excursion_band_AI(pulses, config[, low, ...])

excursion_band_loose(pulses, config[, log_ratio])

excursion_band widened to [0.5, 1.0) -- the "loose" Branch 2 cut from 07221203_2025_dump1_noise.ipynb (more traces retained, somewhat more contamination than the tight [0.5, 0.7) default).

excursion_below_percentile(pulses, config[, ...])

looks_like_pulse(pulses, config[, ...])

quiet_baseline(pulses, config[, percentile, ...])

True where pretrigger_std is below its own percentile-th value across the active pulses in this batch.

randoms(trigger_types[, label])

ratio_band(pulses, config[, low, high, ratio])

True where excursion_ratio (linear, not log) is in [low, high) (either bound optional).

real_triggers(trigger_types[, label])

goldpan.cuts.dead_channel(pulses, config)[source]

True where the pretrigger std is exactly zero – channel not read out for this pulse, not merely a quiet channel. See the Detector 0/Channel 2 finding in 07221203_2025_dump1_noise.ipynb (100% dead in that dump).

Parameters:

config (PulseConfig)

goldpan.cuts.active(pulses, config)[source]

~dead_channel, as its own name for readability at call sites.

Parameters:

config (PulseConfig)

goldpan.cuts.quiet_baseline(pulses, config, percentile=75, bstd=None)[source]

True where pretrigger_std is below its own percentile-th value across the active pulses in this batch. Dead channels are always excluded (never True).

Pass a precomputed bstd (e.g. goldpan.quantities.pretrigger_std(pulses, config)) to avoid recomputing it when combining with other cuts on the same batch.

Parameters:
goldpan.cuts.ratio_band(pulses, config, low=None, high=None, ratio=None)[source]

True where excursion_ratio (linear, not log) is in [low, high) (either bound optional). The generic band-threshold utility – see excursion_band for the specific log10(ratio) cut used by the Branch 2 exploration.

Pass a precomputed ratio (e.g. goldpan.quantities.excursion_ratio(pulses, config)) to avoid recomputing it when combining with other cuts on the same batch.

Parameters:

config (PulseConfig)

goldpan.cuts.excursion_band(pulses, config, low=0.5, high=0.7, log_ratio=None)[source]

True where log_excursion_ratio is in [low, high) – default [0.5, 0.7), the “tight” Branch 2 cut from 07221203_2025_dump1_noise.ipynb (cleanest slice found there, though even it keeps 13 of its 192 traces that look like real pulses – see excursion_band_AI). Pass a config with the pretrigger window you want (Branch 2 used 500 samples, which is what the Run 76 readout has now; until 2026-10-28 it was 1000).

Pass a precomputed log_ratio (e.g. goldpan.quantities.log_excursion_ratio(pulses, config)) to avoid recomputing it when combining with other cuts on the same batch.

Parameters:

config (PulseConfig)

goldpan.cuts.excursion_band_loose(pulses, config, log_ratio=None)[source]

excursion_band widened to [0.5, 1.0) – the “loose” Branch 2 cut from 07221203_2025_dump1_noise.ipynb (more traces retained, somewhat more contamination than the tight [0.5, 0.7) default).

Parameters:

config (PulseConfig)

goldpan.cuts.excursion_below_percentile(pulses, config, percentile=25, ratio=None)[source]

Warning

Under development: matches the original dump1_noise ‘good noise’ cut, which the same notebook’s widened-Cut-A investigation found is biased toward contaminated-baseline traces rather than quiet ones when used alone – combine with quiet_baseline (already the notebook’s practice) rather than relying on this in isolation

True where excursion_ratio is below its own percentile-th value across the active pulses in this batch. Convenience wrapper matching the original dump1_noise notebook’s “good noise” ratio cut – see its module docstring for why a low ratio is not automatically “quieter.

Parameters:
goldpan.cuts.looks_like_pulse(pulses, config, min_duration=50, duration=None)[source]

Warning

Under development: ‘looks like a pulse’ is a judgment call, not a validated physical criterion. Flags traces whose excursion stays near its own peak for a long consecutive run (excursion_duration >= min_duration), which a real detector pulse’s rise-then-decay does and ordinary noise usually doesn’t. default min_duration=50 was picked by eye from a real gap in the data (07221203_2025_F0001, Detector0/Channel0, 500-sample window): within the tight excursion_band, 179/192 traces had duration <= 25 and the other 13 had duration >= 168 – nothing in between – and those 13 are visually unambiguous real pulses/drifts, the other 179 visually flat noise. Devised for excursion_band_AI – treat as a first guess to be checked against the traces it flags on any new dataset, not ground truth.

True where excursion_duration is at or above min_duration samples.

Parameters:
goldpan.cuts.excursion_band_AI(pulses, config, low=0.5, high=0.7, log_ratio=None, min_duration=50, duration=None)[source]

Warning

Under development: excursion_band ([0.5, 0.7) by default) with looks_like_pulse traces removed – i.e. ‘whatever Claude judged to be a real pulse, taken out.’ Both the band and the pulse-shape veto are judgment calls; treat this as an exploratory variant of excursion_band, not an independently validated cut, and check what it removes before trusting it on a new dataset.

excursion_band(low, high) with looks_like_pulse traces removed.

Parameters:
goldpan.cuts.randoms(trigger_types, label='Physics')[source]

Warning

Under development: assumes the dump’s trigger_type labels are swapped relative to their names: events recorded as ‘Physics’ are taken to be randoms (fixed-count random triggers) and ‘Unknown’ to be real triggers. That mapping is a working assumption from 07221203_2025_F0001 (see Note 2a), not confirmed against the DAQ configuration or the nsdf library

True where the recorded trigger type equals label (default "Physics"), taken to be random triggers. Takes the trigger-type array from goldpan.io.trigger_types rather than pulses.

Parameters:

label (str)

goldpan.cuts.real_triggers(trigger_types, label='Unknown')[source]

Warning

Under development: the other half of the randoms assumption: events recorded as ‘Unknown’ are taken to be real (pulse-triggered) events. Not confirmed; see randoms

True where the recorded trigger type equals label (default "Unknown"), taken to be real triggers. Takes the trigger-type array from goldpan.io.trigger_types rather than pulses.

Parameters:

label (str)