Digital Event Generators
Overview
Milestone 4 adds three DigitalEventSeries generators to the DataSynthesizer registry. Each generator is a self-contained .cpp file under src/DataSynthesizer/Generators/DigitalEvent/ that self-registers at static initialization time via RegisterGenerator<Params>.
All generators produce an std::shared_ptr<DigitalEventSeries> wrapped in a DataTypeVariant. Events are stored as TimeFrameIndex values representing discrete time points. All stochastic generators are deterministic given the same seed.
Generators
PoissonEvents
Registration name: "PoissonEvents" · Category: Events
Generates events via a homogeneous Poisson process with constant rate lambda (events per sample). Inter-event intervals are drawn from an exponential distribution with rate parameter lambda. Continuous times are floored to integer TimeFrameIndex values and deduplicated.
| Parameter | Type | Required | Default | Constraint |
|---|---|---|---|---|
num_samples |
int |
✅ | 1000 | > 0 |
lambda |
float |
✅ | 0.05 | > 0 |
seed |
uint64_t |
☐ | 42 | — |
Expected event count: approximately num_samples × lambda (before deduplication).
Determinism guarantee: same (num_samples, lambda, seed) tuple always produces identical output within a single build.
RegularEvents
Registration name: "RegularEvents" · Category: Events
Generates evenly spaced events at positions 0, interval, 2×interval, ... within [0, num_samples). Optional Gaussian jitter displaces each event from its grid position. Jittered events are clamped to [0, num_samples-1] and deduplicated.
| Parameter | Type | Required | Default | Constraint |
|---|---|---|---|---|
num_samples |
int |
✅ | 1000 | > 0 |
interval |
int |
✅ | 20 | > 0 |
jitter_stddev |
float |
☐ | 0.0 | ≥ 0 |
seed |
uint64_t |
☐ | 42 | — |
Without jitter: produces exactly ⌈num_samples / interval⌉ events at deterministic grid positions.
With jitter: events are displaced by round(N(0, jitter_stddev)) samples, then clamped and deduplicated. The final count may differ from the grid count due to deduplication.
BurstEvents
Registration name: "BurstEvents" · Category: Events
Generates clustered burst event patterns. Burst onset times are drawn from a Poisson process at rate burst_rate. Within each burst, events are drawn from a second Poisson process at rate within_burst_rate for burst_duration samples.
| Parameter | Type | Required | Default | Constraint |
|---|---|---|---|---|
num_samples |
int |
✅ | 10000 | > 0 |
burst_rate |
float |
✅ | 0.005 | > 0 |
within_burst_rate |
float |
✅ | 0.5 | > 0 |
burst_duration |
int |
✅ | 20 | > 0 |
seed |
uint64_t |
☐ | 42 | — |
Expected burst count: approximately num_samples × burst_rate.
Expected events per burst: approximately burst_duration × within_burst_rate.
Events from all bursts are merged, sorted, and deduplicated.
InhomogeneousPoissonEvents
Registration name: "InhomogeneousPoissonEvents" · Category: Events
Generates events via an inhomogeneous Poisson process with time-varying rate λ(t) read from an existing AnalogTimeSeries in the DataManager. This is a contextual generator — it requires a GeneratorContext with a non-null DataManager pointer.
Uses the Lewis-Shedler thinning algorithm:
- Read λ(t) =
rate_scale×analog_values[t]from the rate signal. - Find λ_max = max(λ(t)).
- Generate candidate events from a homogeneous Poisson process with rate λ_max.
- Accept each candidate at time t with probability λ(t) / λ_max.
This ensures the local event density tracks the rate signal faithfully.
| Parameter | Type | Required | Default | Constraint |
|---|---|---|---|---|
rate_signal_key |
string |
✅ | — | Must exist in DataManager as AnalogTimeSeries |
rate_scale |
float |
☐ | 1.0 | > 0 |
seed |
uint64_t |
☐ | 42 | — |
Preconditions:
GeneratorContext::data_managermust not be null.rate_signal_keymust refer to an existingAnalogTimeSeries.- All rate values (after scaling) must be ≥ 0.
Zero-rate behavior: If the rate signal is zero everywhere, no events are produced (returns an empty DigitalEventSeries).
Determinism guarantee: same (rate_signal_key, rate_scale, seed) tuple with the same rate signal data always produces identical output within a single build.
Design note: This is the first generator that requires GeneratorContext, which was added to support generators needing DataManager access. Existing generators that don’t need context are unaffected — the RegisterGenerator template provides an overload that ignores the context automatically.