Skip to main content

ObservabilityReport

Struct ObservabilityReport 

Source
pub struct ObservabilityReport {
    pub n_unknowns: usize,
    pub rank: usize,
    pub structurally_unmeasured: Vec<Unknown>,
    pub unobservable: Vec<Unknown>,
    pub skipped_numerical: bool,
    pub de_energized: Vec<Unknown>,
    pub global_current_without_angle_reference: bool,
}
Expand description

What the measurements do and do not determine.

Fields§

§n_unknowns: usize§rank: usize

Rank of the gain matrix. Equal to n_unknowns exactly when the state is fully observable.

§structurally_unmeasured: Vec<Unknown>

Unknowns no measurement function mentions at all.

§unobservable: Vec<Unknown>

Unknowns left undetermined once linear dependence is accounted for.

A superset of structurally_unmeasured in effect — a zero column is also rank-deficient — though the specific variables reported can differ, since which member of a dependent group gets blamed depends on the pivot order. The count is what is meaningful; the names are representatives.

§skipped_numerical: bool

Set when the system was too large to analyze densely, in which case only the structural half of the report is filled in.

§de_energized: Vec<Unknown>

Unknowns belonging to buses that carry no voltage at all.

These are not a gap in the sensor plan and no sensor would close them. A de-energized bus is reported at exactly zero by every estimator path here — nr::estimate writes it, iterative::estimate skips its rows, linear_start starts it there — so its columns are determined by the network rather than by measurements, and they are zero columns of H by construction. Counting them against the rank would report every CGMES model containing one switched-out node as unobservable, which is the same mistake, in the same function, that ignoring constraint rows was.

They are excluded from structurally_unmeasured, unobservable and is_observable, and reported here instead.

§global_current_without_angle_reference: bool

A global-angle current sensor is present with nothing to measure its angle against.

Such a sensor reports I = i·e^{jθ} with θ absolute, which is only meaningful if something else fixes what that reference is. With no voltage angle in the set, StateLayout pins a reference bus instead — and that pin is then a false constraint, rotating the estimate away from the angle the sensor actually measured. The rank check will not catch it, because the system is perfectly determined; it is determined to the wrong thing.

power-grid-model refuses to run at all here, raising NotObservableError with “Global angle current sensors require at least one voltage angle measurement as a reference point”. gridoxide reports rather than refuses, on the grounds that this analysis is the place that says what is wrong and the estimator’s job is to answer the question it was asked.

Implementations§

Source§

impl ObservabilityReport

Source

pub fn is_observable(&self) -> bool

Whether every state variable is determined.

Deliberately does not fold in global_current_without_angle_reference: that state is fully determined, just to the wrong reference, and calling it unobservable would misname it.

Trait Implementations§

Source§

impl Clone for ObservabilityReport

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ObservabilityReport

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ByRef<T> for T

Source§

fn by_ref(&self) -> &T

Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DistributionExt for T
where T: ?Sized,

Source§

fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> T
where Self: Distribution<T>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V