ChannelEffects
DeepSpaceTelemetry.ChannelEffects — Module
ChannelEffectsDownlink channel models: stochastic packet loss (NoLoss, BernoulliLoss, two-state GilbertElliottLoss with its analytic stationary rate), scheduled disruption events (blackout, linear recovery ramp, elevated loss), and the composite LinkModel (visibility × disruption) gating both pipeline loops.
DeepSpaceTelemetry.ChannelEffects.LossModel — Type
LossModelAbstract supertype for stochastic downlink packet-loss models. Concrete models implement sample_loss!, which is drawn once per batch transfer attempt on the receiver side. All models carry their own seeded Xoshiro RNG so loss realizations are reproducible independently of the physics stream.
DeepSpaceTelemetry.ChannelEffects.NoLoss — Type
NoLoss()The trivial loss model: every transfer attempt succeeds. Used when [packet_loss] enabled = false.
DeepSpaceTelemetry.ChannelEffects.BernoulliLoss — Type
BernoulliLoss(p, rng)Memoryless i.i.d. packet loss: each batch transfer attempt fails independently with probability p ∈ [0, 1]. The RNG type is a struct parameter so the per-attempt draw dispatches statically.
DeepSpaceTelemetry.ChannelEffects.GilbertElliottLoss — Type
GilbertElliottLoss(p_good_to_bad, p_bad_to_good, p_loss_good, p_loss_bad, in_bad_state, rng)Two-state Markov (Gilbert–Elliott) bursty-channel model — the canonical model for correlated packet loss. The channel alternates between a GOOD state with loss probability p_loss_good and a BAD state with loss probability p_loss_bad; state transitions occur once per transfer attempt with probabilities p_good_to_bad / p_bad_to_good. All four parameters must lie in [0, 1]. The RNG type is a struct parameter so the per-attempt draws dispatch statically.
DeepSpaceTelemetry.ChannelEffects.sample_loss! — Function
sample_loss!(model::LossModel; multiplier::Float64=1.0) -> BoolDraws one loss realization for a single batch transfer attempt. Returns true if the transfer is lost. multiplier scales the instantaneous loss probability (clamped to [0, 1]) and is used to elevate loss rates during disruption events (see disruption_loss_multiplier). Mutates internal channel state for stateful models (Gilbert–Elliott).
DeepSpaceTelemetry.ChannelEffects.stationary_loss_rate — Function
stationary_loss_rate(model::LossModel) -> Float64Analytic long-run loss probability of the model (used for physics-style validation of the sampled stream). For Gilbert–Elliott this is π_bad·p_loss_bad + π_good·p_loss_good with the stationary state occupancies π_bad = p_good_to_bad / (p_good_to_bad + p_bad_to_good).
Examples
julia> ChannelEffects.stationary_loss_rate(ChannelEffects.BernoulliLoss(0.1, Xoshiro(1)))
0.1
julia> ge = ChannelEffects.GilbertElliottLoss(0.03, 0.25, 0.01, 0.5, false, Xoshiro(1));
julia> round(ChannelEffects.stationary_loss_rate(ge); digits = 4)
0.0625DeepSpaceTelemetry.ChannelEffects.DisruptionEvent — Type
DisruptionEventA scheduled link-degrading event (a solar flare, a spacecraft safe-mode entry, a ground-station outage, …). Between start_time and blackout_end the link capacity is multiplied by 1 - severity (severity = 1 is a full blackout); between blackout_end and recovery_end capacity ramps linearly back to nominal. Throughout the whole event (blackout + recovery) the stochastic loss probability is scaled by loss_multiplier. label is an optional free-text display name shown on the dashboard while the event is active.
DeepSpaceTelemetry.ChannelEffects.DisruptionTimeline — Type
DisruptionTimeline(events::Vector{DisruptionEvent})Chronologically sorted collection of DisruptionEvents. Overlapping events compose conservatively: the minimum capacity factor and the maximum loss multiplier apply. DisruptionTimeline() builds the empty timeline of a disruption-free link.
DeepSpaceTelemetry.ChannelEffects.disruption_factor — Function
disruption_factor(tl::DisruptionTimeline, t::DateTime) -> Float64Multiplicative link-capacity factor in [0, 1] at simulation time t: 1.0 outside all events, 1 - severity during a blackout, and a linear ramp from 1 - severity back to 1.0 during the recovery phase.
DeepSpaceTelemetry.ChannelEffects.disruption_loss_multiplier — Function
disruption_loss_multiplier(tl::DisruptionTimeline, t::DateTime) -> Float64Multiplier (≥ 1) applied to the stochastic loss probability at time t. Active from event start through the end of the recovery ramp.
Examples
julia> cfg = Dict{String,Any}(
"disruption" => Dict{String,Any}(
"events" => [Dict{String,Any}(
"start_day" => 2.0,
"duration_hours" => 12.0,
"recovery_hours" => 6.0,
"severity" => 1.0,
"loss_multiplier" => 4.0,
)],
),
);
julia> tl = ChannelEffects.build_disruption_timeline(cfg, DateTime(2035, 1, 1));
julia> ChannelEffects.disruption_loss_multiplier(tl, DateTime(2035, 1, 3, 6))
4.0
julia> ChannelEffects.disruption_loss_multiplier(tl, DateTime(2035, 1, 4))
1.0DeepSpaceTelemetry.ChannelEffects.active_disruption_label — Function
active_disruption_label(tl::DisruptionTimeline, t::DateTime) -> StringThe label of the earliest-starting disruption event active at time t that carries a non-empty label, or "" when no active event is labeled. Used by the dashboard status line to name the ongoing event.
DeepSpaceTelemetry.ChannelEffects.LinkModel — Type
LinkModel(visibility::TelemetryCore.VisibilityModel, disruptions::DisruptionTimeline)The complete downlink channel: daily DSN visibility windows composed with the disruption timeline. LinkModel(vis) builds a disruption-free link.
DeepSpaceTelemetry.ChannelEffects.effective_bandwidth — Function
effective_bandwidth(link::LinkModel, t::DateTime) -> Float64Effective link capacity in [0, 1] at simulation time t: the visibility bandwidth profile multiplied by the disruption capacity factor.
DeepSpaceTelemetry.ChannelEffects.is_transmittable — Function
is_transmittable(link::LinkModel, t::DateTime) -> BoolWhether the satellite can place batches on the downlink at time t: geometrically visible and not inside a full blackout.
DeepSpaceTelemetry.ChannelEffects.build_loss_model — Function
build_loss_model(cfg::AbstractDict, seed::Integer) -> LossModelConstructs the stochastic loss model declared in the [packet_loss] config section, with its own RNG seeded from seed. Returns NoLoss when the section is absent or enabled = false. Errors on an unknown model string or probabilities outside [0, 1] (validated upstream by TelemetryCore.validate_config, re-checked here defensively).
DeepSpaceTelemetry.ChannelEffects.build_disruption_timeline — Function
build_disruption_timeline(cfg::AbstractDict, start_sim::DateTime) -> DisruptionTimelineConstructs the link-disruption timeline from the validated TelemetryCore.disruption_event_settings (the pre-1.0 [[disaster.events]] section name is rejected); events with affects = "generation" belong to generation_gaps instead. Event start_day values are mission days relative to start_sim.
DeepSpaceTelemetry.ChannelEffects.generation_gaps — Function
generation_gaps(cfg::AbstractDict, start_sim::DateTime) -> Vector{Tuple{DateTime,DateTime}}The scheduled generation gaps — [[disruption.events]] with affects = "generation" — as (start, stop) intervals of duration_hours from start_day, sorted by start. The emitter produces no data inside them (Emitter.skip_generation_gaps!).
DeepSpaceTelemetry.ChannelEffects.build_link_model — Function
build_link_model(cfg::AbstractDict) -> LinkModelConstructs the full LinkModel from a parsed configuration: visibility from TelemetryCore.visibility_model, disruptions from [disruption] anchored at simulation.start_sim_time.
DeepSpaceTelemetry.ChannelEffects.loss_retry_limit — Function
loss_retry_limit(cfg::AbstractDict) -> IntResolves the retry policy from [packet_loss]: on_loss = "drop" maps to 0 retries (immediate loss), "retransmit" (default) to max_retries (default 3).