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 (τ).
Namespace: Gemstone.PhasorProtocols.SelCWSAssembly: 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
)
Public Sub New (
sampleRateHz As Double,
outputRateHz As Double,
nominalFrequency As LineFrequency,
Optional referenceChannel As PhaseChannel = PhaseChannel.VA,
Optional targetCycles As Integer = 2,
Optional enableIntervalAveraging As Boolean = true,
Optional enablePublishEMA As Boolean = true,
Optional publishAnglesTauSeconds As Double = 0.35,
Optional publishMagnitudesTauSeconds As Double = 0.5,
Optional publishFrequencyTauSeconds As Double = 0.75,
Optional publishRocofTauSeconds As Double = 1.5,
Optional sampleFrequencyTauSeconds As Double = 0.15,
Optional sampleRocofTauSeconds As Double = 0.3,
Optional recalculationCycles As Integer = 10
)
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
)
Gemstone.PhasorProtocols.SelCWS.RollingPhaseEstimator = function(sampleRateHz, outputRateHz, nominalFrequency, referenceChannel, targetCycles, enableIntervalAveraging, enablePublishEMA, publishAnglesTauSeconds, publishMagnitudesTauSeconds, publishFrequencyTauSeconds, publishRocofTauSeconds, sampleFrequencyTauSeconds, sampleRocofTauSeconds, recalculationCycles);
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.
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):
- Interval averaging (boxcar) across the publish interval (anti-alias / jitter reduction).
- 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.
| ArgumentOutOfRangeException |
Thrown if any rate is non-positive, output rate exceeds input rate, targetCycles < 1, or any τ is negative.
|