/// /// Copyright (c) 2013-2022 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; namespace Config.Entities { public class MeasurementCorrection : Common.IMeasurementCorrection, IComparable { public virtual int Id { get; protected set; } public virtual int RangeIx { get; set; } /// 0..5 public virtual double Measurement { get; set; } public virtual double Correction { get; set; } public MeasurementCorrection() { RangeIx = 0; } public MeasurementCorrection(int rangeIx) { RangeIx = rangeIx; } public virtual int CompareTo(MeasurementCorrection other) { return (Measurement > other.Measurement) ? 1 : ((Measurement == other.Measurement) ? 0 : -1); } /// /// Calculates corrected value from a list of corrections by interpolation. /// It is assumed that values in the list 'corrections' are sorted. /// /// Raw uncorrected value /// Sorted (value, correction) pairs /// Corrected value public static double CorrectedValue(double rawValue, IList corrections) { return rawValue + GetCorrection(rawValue, corrections); } /// /// Get a correction from a list of corrections by interpolation. /// It is assumed that values in the list 'corrections' are sorted. /// /// Raw uncorrected value /// Sorted (value, correction) pairs /// Corrected value public static double GetCorrection(double rawValue, IList corrections) { if ((corrections == null) || (corrections.Count == 0)) return 0; /// No correction if (rawValue < corrections[0].Measurement) { /// rawValue is below the lowest value in the correction table return corrections[0].Correction; } for (int i = 1; i < corrections.Count; i++) { if (rawValue < corrections[i].Measurement) { double d1 = rawValue - corrections[i - 1].Measurement; double d2 = corrections[i].Measurement - rawValue; if (d1 + d2 <= float.Epsilon) { /// Neigboring values in the corection table are close to each other -> calculate the average return (corrections[i - 1].Correction + corrections[i].Correction) / 2.0; } else { /// Interpolate the correction from neigboring values in the corection table return (corrections[i - 1].Correction * d2 + corrections[i].Correction * d1) / (d1 + d2); } } } /// rawValue is above the highest value in the correction table return corrections[corrections.Count - 1].Correction; } public override string ToString() { return string.Format("{0} {1} ({2})", Measurement, Correction, RangeIx); } } }