RollingPhaseEstimator Constructor

Initializes a new instance of the RollingPhaseEstimator class with independent input sample rate and output publish rate, plus smoothing expressed as time constants (τ).

Definition

Namespace: Gemstone.PhasorProtocols.SelCWS
Assembly: Gemstone.PhasorProtocols (in Gemstone.PhasorProtocols.dll) Version: 1.0.166 -- Release Build+4f9601ce2fc7721cafe5edaeacb540e40faa3f58
public RollingPhaseEstimator(
	double sampleRateHz,
	double outputRateHz,
	LineFrequency nominalFrequency,
	PhaseChannel referenceChannel = PhaseChannel.VA,
	int targetCycles = 2,
	bool enableIntervalAveraging = true,
	bool enablePublishEMA = true,
	double publishAnglesTauSeconds = 0.35,
	double publishMagnitudesTauSeconds = 0.5,
	double publishFrequencyTauSeconds = 0.75,
	double publishRocofTauSeconds = 1.5,
	double sampleFrequencyTauSeconds = 0.15,
	double sampleRocofTauSeconds = 0.3,
	int recalculationCycles = 10
)

Parameters

sampleRateHz  Double
Input sample rate in Hz (PoW samples per second). Must be > 0. This is the rate at which Step(Double, Double, Double, Double, Double, Double, Int64, PhaseEstimateHandler) is called with new samples.
outputRateHz  Double
Output publish rate in Hz (estimates per second). Must be > 0 and <= sampleRateHz. Common synchrophasor-friendly values: 30, 60 or 120Hz. Defaults chosen for "calm" 60Hz publish rates; τ-to-α mapping adapts automatically to other publish rates.
Behavioral note: Step(Double, Double, Double, Double, Double, Double, Int64, PhaseEstimateHandler) may return false even after the estimator is ready, if the current sample does not land on a publish boundary (i.e., it is not yet time to produce the next output).
nominalFrequency  LineFrequency
Nominal line frequency (typically 50Hz or 60Hz). This determines the nominal-cycle length used for the DFT window and the expected reference-phase progression.
referenceChannel  PhaseChannel  (Optional)
Reference channel for frequency tracking. Default: VA.
targetCycles  Int32  (Optional)
Number of nominal cycles contained in the sliding DFT analysis window (default: 2). Larger values generally reduce noise/jitter (more averaging) but increase latency and reduce step response.
enableIntervalAveraging  Boolean  (Optional)
Enables interval averaging (boxcar averaging) across each publish interval when down-sampling (outputRateHz < sampleRateHz).
Why this exists: Down-sampling without an anti-alias / low-pass step will preserve high-rate jitter and can alias higher-frequency content into the published stream. Interval averaging acts as a simple, cheap low-pass filter that reduces jitter and improves published stability.
Consequences:
- Improves calmness and reduces aliasing artifacts.
- Adds a small amount of additional latency (effectively ~½ publish interval group delay).
Recommended: true (default).
enablePublishEMA  Boolean  (Optional)
Enables an additional exponential moving average (EMA) applied to the published stream (after interval averaging).
Why this exists:
Interval averaging removes high-rate noise; publish-EMA further reduces remaining jitter and produces a "calm" display or control signal. This is usually the most intuitive "knob" for operators/consumers because it acts on the actual output cadence.
Consequences:
- Larger time constants (τ) produce smoother outputs but slower response to real changes.
- Smaller τ tracks faster but appears noisier.
Default: true.
publishAnglesTauSeconds  Double  (Optional)
EMA time constant τ (seconds) for published phase angles. Default: 0.35s.
Important:
Angles are circular quantities; this implementation performs wrap-safe smoothing by operating on unit vectors (cos/sin) rather than naïvely averaging radians. This avoids discontinuities at ±π.
publishMagnitudesTauSeconds  Double  (Optional)
EMA time constant τ (seconds) for published RMS magnitudes. Default: 0.50s.
publishFrequencyTauSeconds  Double  (Optional)
EMA time constant τ (seconds) for published frequency. Default: 0.75s.
publishRocofTauSeconds  Double  (Optional)
EMA time constant τ (seconds) for published ROCOF (dF/dt). Default: 1.50s.
Note:
ROCOF is effectively a derivative signal and is typically much noisier than frequency; it generally benefits from heavier smoothing (larger τ) than frequency.
sampleFrequencyTauSeconds  Double  (Optional)
EMA time constant τ (seconds) for the internal per-sample frequency smoothing that occurs inside the estimator before any down-sampling/publish filtering. Default: 0.15s.
Guidance:
When interval averaging + publish EMA are enabled, this can be relatively light. If you disable publish smoothing, you may want to increase this τ.
sampleRocofTauSeconds  Double  (Optional)
EMA time constant τ (seconds) for the internal per-sample ROCOF smoothing (computed from the internally smoothed frequency). Default: 0.30s.
recalculationCycles  Int32  (Optional)
Number of nominal cycles between full DFT recalculations for numerical stability (default: 10). Sliding DFT updates are O(1) per sample but can accumulate numerical drift; periodic full recomputation re-anchors the phasor sums.

Remarks

Time constant (τ) vs "alpha" (α):
Internally, EMAs use α constrained from 0 to 1. This API exposes τ because it is easier to reason about. For update period Δt (seconds), α is derived as: α = 1 - exp(-Δt / τ) Interpretation: after a step change, an EMA will move about 63% toward the new value after ~τ seconds.

Two-stage smoothing (when outputRate < inputRate):

  1. Interval averaging (boxcar) across the publish interval (anti-alias / jitter reduction).
  2. Publish EMA applied to the down-sampled stream (additional "calmness").
This combination yields stable outputs at 60Hz without producing thousands of nearly-identical jittery estimates per second.

Knob-tweaking guidance:

  • Increase targetCycles to reduce noise/jitter, at the cost of more latency.
  • Increase publish τ values to make outputs calmer, at the cost of slower response.
  • If you disable interval averaging, consider increasing publish τ values to compensate.
  • Keep ROCOF τ larger than frequency τ; ROCOF is inherently noisier.

Exceptions

ArgumentOutOfRangeException Thrown if any rate is non-positive, output rate exceeds input rate, targetCycles < 1, or any τ is negative.

See Also