public static double calcInterpolatedPointValue(TimeAlignedPoint point1, TimeAlignedPoint point2, DateTimeOffset theX)
        {
            double y1 = double.NaN;
            double y2 = double.NaN;

            if (goodValuePoint(point1))
            {
                y1 = point1.NumericValue1.Value;
            }
            if (goodValuePoint(point2))
            {
                y2 = point2.NumericValue1.Value;
            }

            return(calcInterpolatedValue(point1.Timestamp, y1, point2.Timestamp, y2, theX));
        }
        public static TimeAlignedPoint[] GetInstMinMaxPoints(List <TimeAlignedPoint> inputPoints,
                                                             bool extrema, DateTimeOffset theStartTime, DateTimeOffset[] binEnds)
        {
            bool MIN = true;
            bool MAX = false;

            TimeAlignedPoint[] pointsOfExtrema = new TimeAlignedPoint[binEnds.Length];
            for (int i = 0; i < binEnds.Length; i++)
            {
                pointsOfExtrema[i] = new TimeAlignedPoint();
            }

            if (inputPoints.Count == 0)
            {
                return(pointsOfExtrema);
            }

            int    j            = 0;
            double leftBinValue = double.NaN;

            while ((j < inputPoints.Count) && inputPoints[j].Timestamp < theStartTime)
            {
                j++;
            }

            if (j >= inputPoints.Count)
            {
                return(pointsOfExtrema);
            }

            if ((inputPoints[j].Timestamp >= theStartTime) && (j > 0))
            {
                leftBinValue = calcInterpolatedPointValue(inputPoints[j - 1], inputPoints[j], theStartTime);
            }

            for (int i = 0; i < binEnds.Length; i++)
            {
                DateTimeOffset currentTime = (i > 0) ? binEnds[i - 1] : theStartTime;
                double         currentVal  = leftBinValue;

                Log.DebugFormat("i = {0}, j = {1}, leftBinValue = {2}, time = {3}", i, j, leftBinValue, currentTime);

                for (; j < inputPoints.Count; j++)
                {
                    TimeAlignedPoint inputPoint = inputPoints[j];

                    if (inputPoint.Timestamp > binEnds[i])
                    {
                        break;
                    }

                    if ((inputPoint.NumericValue1.HasValue) &&
                        (double.IsNaN(currentVal) ||
                         ((extrema == MIN) && (inputPoint.NumericValue1.Value < currentVal)) ||
                         ((extrema == MAX) && (inputPoint.NumericValue1.Value > currentVal))))
                    {
                        currentTime = inputPoint.Timestamp;
                        currentVal  = inputPoint.NumericValue1.Value;
                    }
                }

                double rightBinValue = double.NaN;

                if ((j > 0) && (j < inputPoints.Count) && (inputPoints[j].Timestamp > binEnds[i]))
                {
                    DateTimeOffset binEnd = binEnds[i];
                    rightBinValue = calcInterpolatedPointValue(inputPoints[j - 1], inputPoints[j], binEnd);
                    Log.DebugFormat("checking boundary extrema i = {0}, j = {1}, binEnd = {2}, rightBinValue = {3}", i, j, binEnd, rightBinValue);
                    if (!double.IsNaN(rightBinValue) &&
                        (double.IsNaN(currentVal) ||
                         ((extrema == MIN) && (rightBinValue < currentVal)) ||
                         ((extrema == MAX) && (rightBinValue > currentVal))))
                    {
                        currentTime = binEnd;
                        currentVal  = rightBinValue;
                        Log.DebugFormat("checking boundary extrema i = {0}, j = {1}, currentTime = {2}, currentVal = {3}", i, j, currentTime, currentVal);
                    }
                }

                if (!double.IsNaN(currentVal))
                {
                    pointsOfExtrema[i].Timestamp     = currentTime;
                    pointsOfExtrema[i].NumericValue1 = currentVal;
                    Log.DebugFormat("setting extrema i = {0}, j = {1}, currentTime = {2}, currentVal = {3}", i, j, currentTime, currentVal);
                }

                leftBinValue = rightBinValue;
            }

            return(pointsOfExtrema);
        }
 public static bool goodValuePoint(TimeAlignedPoint point)
 {
     return(point.NumericValue1.HasValue); // possible enhancement to check grade code
 }