VirtualInstrument
DeepSpaceTelemetry.VirtualInstrument — Module
VirtualInstrumentScience-payload data source: amplitude-calibrated synthetic LISA strain via windowed overlap-add FFT synthesis against the sky-averaged LISA sensitivity of Robson, Cornish & Liu (2019), or gapless segmented ingestion of an external CSV time series.
DeepSpaceTelemetry.VirtualInstrument.InstrumentState — Type
InstrumentStateMaintains the state of the satellite's scientific payload. Can generate synthetic LISA strain noise (instrument sensitivity plus the galactic-confusion foreground, lisa_noise_psd) or ingest an externally provided continuous 1D time-series CSV array.
Synthetic strain is generated by a windowed overlap-add (WOLA) scheme: amplitude-calibrated colored-noise blocks of 2N samples (N = samples per segment) are shaped with a periodic sqrt-Hann window and summed at 50% overlap. The squared window tiles to exactly 1, so the emitted stream is stationary, continuous across segment boundaries, and reproduces the sky-averaged LISA sensitivity with the correct absolute amplitude (spectral content below 1/(2·segment_duration_sec) Hz is not representable at this block length — increase segment_duration_sec for low-frequency fidelity). The constructor keywords confusion_observation_years (0.5, 1.0, 2.0, or 4.0) select the confusion fit and noise_f_min_hz the lower edge of the synthesized band: bins below it, the DC bin included, carry no power, so the model is never evaluated outside its domain.
The amplitude spectrum is stored in Float64: raw LISA PSD values (~1e-40) underflow into Float32 subnormals.
All stochastic draws (noise phases) come from the instrument's own rng (any Random.AbstractRNG; default Xoshiro(0)), seeded via the constructor keyword — the stream is fully reproducible from simulation.rng_seed and independent of the global RNG and of other simulation components.
The struct is deliberately named differently from its parent module: an exported struct sharing the module's name shadows the module binding in downstream using scopes, breaking qualified access (VirtualInstrument.next_segment!).
DeepSpaceTelemetry.VirtualInstrument.lisa_noise_psd — Function
lisa_noise_psd(f; observation_years = 1.0) -> Float64Sky-averaged LISA sensitivity [Hz⁻¹] at frequency f [Hz]: the instrument term lisa_instrument_psd plus the galactic-confusion foreground lisa_confusion_psd of the fit for observation_years. It is the noise PSD divided by the sky- and polarization-averaged response (Robson, Cornish & Liu 2019, Eqs. 1 and 14), the quantity the downstream classifier whitens against, and the synthesis reproduces it at the correct absolute level. Returns Inf for f ≤ 0; the synthesis zeroes the DC bin and every bin below noise_f_min_hz, so no floor value can enter a stream.
DeepSpaceTelemetry.VirtualInstrument.welch_psd — Function
welch_psd(x::AbstractVector{<:Real}, fs::Real; nperseg = 0) -> (Vector{Float64}, Vector{Float64})One-sided power spectral density of x sampled at fs [Hz], by Welch's method: Hann windows of nperseg samples (default: the largest power of two giving at least eight segments, floored at 256) overlapping by half, each segment mean-removed, the periodograms averaged and normalized so the estimate integrates to the variance of the series. Returns the frequency grid and the density in units of x²/Hz.
The measurement counterpart of lisa_noise_psd: a stream synthesized from S(f) returns it over the band its synthesis block resolves, which is what the payload-spectrum figure shows. Below 1/(2·segment_duration_sec) the estimate carries spectral leakage, not content — no power was synthesized there.
Returns empty vectors when x is shorter than one window.
DeepSpaceTelemetry.VirtualInstrument.lisa_instrument_psd — Function
lisa_instrument_psd(f) -> Float64Sky- and polarization-averaged LISA instrument sensitivity S_n(f) [Hz⁻¹] at frequency f [Hz], Robson, Cornish & Liu (2019) Eq. 1:
S_n(f) = 10 / (3 L²) · [P_OMS(f) + 2 (1 + cos²(f/f*)) P_acc(f) / (2π f)⁴] · [1 + 0.6 (f/f*)²]with P_OMS = (1.5 × 10⁻¹¹)² (1 + (2 mHz / f)⁴) m² Hz⁻¹, P_acc = (3 × 10⁻¹⁵)² (1 + (0.4 mHz / f)²) (1 + (f / 8 mHz)⁴) m² s⁻⁴ Hz⁻¹ (the constants OMS_NOISE_AMPLITUDE, OMS_NOISE_KNEE_HZ, ACCELERATION_NOISE_AMPLITUDE, ACCELERATION_NOISE_LOW_KNEE_HZ, ACCELERATION_NOISE_HIGH_KNEE_HZ, and RESPONSE_CORRECTION_COEFFICIENT), L = 2.5 × 10⁹ m, and f* = c / (2π L). This is the noise PSD divided by the sky-averaged response, the quantity a strain stream is whitened against. Returns Inf for f ≤ 0.
DeepSpaceTelemetry.VirtualInstrument.lisa_confusion_psd — Function
lisa_confusion_psd(f, observation_years = 1.0) -> Float64Unresolved galactic-binary confusion foreground S_c(f) [Hz⁻¹] at frequency f [Hz], Robson, Cornish & Liu (2019) Eq. 14:
S_c(f) = A f^(-7/3) exp(-f^α + β f sin(κ f)) [1 + tanh(γ (f_k − f))]with A = CONFUSION_AMPLITUDE and (α, β, κ, γ, f_k) from CONFUSION_FITS for observation_years (one of 0.5, 1.0, 2.0, 4.0; ArgumentError otherwise). Returns Inf for f ≤ 0.
The product is evaluated in log space with log(1 + tanh(x)) = log 2 − softplus(−2x): far above the knee f_k the cutoff factor underflows to zero while exp(β f sin(κ f)) can overflow, and the direct product would give NaN where the foreground is zero.
DeepSpaceTelemetry.VirtualInstrument.CONFUSION_FITS — Constant
CONFUSION_FITSGalactic-confusion fit parameters (α, β, κ, γ, f_k) of Robson, Cornish & Liu (2019), Table 1, keyed by the observation time in years (0.5, 1.0, 2.0, 4.0); f_k in Hz.
DeepSpaceTelemetry.VirtualInstrument.CONFUSION_AMPLITUDE — Constant
CONFUSION_AMPLITUDEAmplitude A = 9 × 10⁻⁴⁵ Hz⁻¹ of the galactic-confusion fit (Robson, Cornish & Liu 2019, Eq. 14).
DeepSpaceTelemetry.VirtualInstrument.OMS_NOISE_AMPLITUDE — Constant
OMS_NOISE_AMPLITUDEAmplitude 1.5 × 10⁻¹¹ m Hz⁻¹ᐟ² of the optical-metrology-system displacement noise P_OMS(f) in Robson, Cornish & Liu (2019), Eq. 1.
DeepSpaceTelemetry.VirtualInstrument.OMS_NOISE_KNEE_HZ — Constant
OMS_NOISE_KNEE_HZKnee frequency 2 mHz of the low-frequency rise (1 + (f_knee / f)⁴) of P_OMS(f) [Hz].
DeepSpaceTelemetry.VirtualInstrument.ACCELERATION_NOISE_AMPLITUDE — Constant
ACCELERATION_NOISE_AMPLITUDEAmplitude 3 × 10⁻¹⁵ m s⁻² Hz⁻¹ᐟ² of the test-mass acceleration noise P_acc(f) in Robson, Cornish & Liu (2019), Eq. 1.
DeepSpaceTelemetry.VirtualInstrument.ACCELERATION_NOISE_LOW_KNEE_HZ — Constant
ACCELERATION_NOISE_LOW_KNEE_HZKnee frequency 0.4 mHz of the low-frequency rise (1 + (f_knee / f)²) of P_acc(f) [Hz].
DeepSpaceTelemetry.VirtualInstrument.ACCELERATION_NOISE_HIGH_KNEE_HZ — Constant
ACCELERATION_NOISE_HIGH_KNEE_HZKnee frequency 8 mHz of the high-frequency rise (1 + (f / f_knee)⁴) of P_acc(f) [Hz].
DeepSpaceTelemetry.VirtualInstrument.RESPONSE_CORRECTION_COEFFICIENT — Constant
RESPONSE_CORRECTION_COEFFICIENTDimensionless coefficient 0.6 of the high-frequency correction 1 + 0.6 (f / f*)² to the sky-averaged response in Robson, Cornish & Liu (2019), Eq. 1.
DeepSpaceTelemetry.VirtualInstrument.synth_windowed_block — Function
synth_windowed_block(rng::AbstractRNG, noise_amp::Vector{Float64}, window::Vector{Float64})Synthesizes one sqrt-Hann-windowed block of amplitude-calibrated colored noise of length(window) samples from the scaled amplitude spectrum noise_amp (see InstrumentState), drawing phases from rng. The DC bin is zeroed and the Nyquist bin is forced real, as required for a real-valued signal. Allocating convenience form of synth_windowed_block!.
DeepSpaceTelemetry.VirtualInstrument.synth_windowed_block! — Function
synth_windowed_block!(block, z, irfft_plan, rng, noise_amp, window)In-place core of synth_windowed_block: draws the spectral realization into z, applies the cached irfft_plan, and writes the windowed block into block. Allocation-free apart from the transform's internal workspace; the RNG draw order is identical to the allocating form, so seeded streams are unchanged.
DeepSpaceTelemetry.VirtualInstrument.next_segment! — Function
next_segment!(vi::InstrumentState)Produces the next temporal segment of science data, either sliced from the external array or synthesized as calibrated noise. Synthetic segments are phase-continuous across calls: each segment is the sum of the previous block's overlap-add tail and the head of a freshly synthesized windowed block (see InstrumentState).