Example #1
0
        public Timeseries Apply(IUnaryAggregateOperator op, Timeseries ts)
        {
            if (ts == null || ! ts.Any()) return new Timeseries();

            var result = new Timeseries();

            // Default to monthly
            var t = ts.First().Time;
            do
            {
                var t0 = new DateTime(t.Year, t.Month, 1, 0, 0, 0);
                var t1 = new DateTime(t.Year, t.Month, DateTime.DaysInMonth(t.Year, t.Month), 23, 59, 59);
                result.Add(op.Apply(t0, t1, ts));
                t = t0.AddMonths(1);
            } while (t <= ts.Last().Time);

            return result;
        }
Example #2
0
        public Timeseries Apply(IUnaryAggregateOperator op, Timeseries ts)
        {
            if (ts == null || !ts.Any())
            {
                return(new Timeseries());
            }

            var result = new Timeseries();

            // Default to monthly
            var t = ts.First().Time;

            do
            {
                var t0 = new DateTime(t.Year, t.Month, 1, 0, 0, 0);
                var t1 = new DateTime(t.Year, t.Month, DateTime.DaysInMonth(t.Year, t.Month), 23, 59, 59);
                result.Add(op.Apply(t0, t1, ts));
                t = t0.AddMonths(1);
            } while (t <= ts.Last().Time);

            return(result);
        }
Example #3
0
        /// <summary>
        /// Periodizes a time series with relative consumption
        /// </summary>
        /// <param name="op"></param>
        /// <param name="ts">A time series with relative consumption, without roll over or meter change</param>
        /// <param name="interval"></param>
        /// <returns></returns>
        private Timeseries Periodize(IUnaryAggregateOperator op, Timeseries ts, Interval interval)
        {
            var result = new Timeseries();

            using (var enumerator = ts.GetEnumerator())
            {
                DateTime?intervalStart     = null;
                DateTime nextIntervalStart = DateTime.MinValue;
                var      areMoreValues     = enumerator.MoveNext();
                Tvq      currentTvq        = null;
                Tvq      previousTvq;
                Tvq      nextTvq      = enumerator.Current;
                var      doNeedToMove = true;
                double   sumForPeriod = 0;
                while (areMoreValues)
                {
                    // Setup previous, current and next if we need to
                    enumerator.MoveNext();
                    previousTvq = currentTvq;
                    currentTvq  = nextTvq;
                    nextTvq     = enumerator.Current;
                    Debug.Assert(currentTvq != null);

                    // Initialize interval
                    if (!intervalStart.HasValue)
                    {
                        intervalStart     = FirstSecond(currentTvq.Time, interval);
                        nextIntervalStart = FirstSecondOfNextInterval(intervalStart.Value, interval);
                        sumForPeriod      = 0;
                    }

                    Debug.Assert(currentTvq.Time >= intervalStart);
                    Debug.Assert(currentTvq.Time <= nextIntervalStart);

                    do  // next value may be many periods ahead
                    {
                        if (nextTvq == null)
                        {
                            if (previousTvq != null) // Prevent input with only one value from entering
                            {
                                sumForPeriod +=
                                    currentTvq.V
                                    / (currentTvq.Time - previousTvq.Time).TotalDays
                                    * (nextIntervalStart - previousTvq.Time).TotalDays; // Extrapolate consumption to end of interval
                            }

                            result.Add(new Tvq(intervalStart.Value, sumForPeriod, Quality.Interpolated));
                            sumForPeriod = 0;
                        }
                        else if (nextIntervalStart <= nextTvq.Time)
                        {
                            doNeedToMove = false;

                            sumForPeriod += currentTvq.V;

                            var remainingConsumptionBelongingToThisPeriod = nextTvq.V
                                                                            * (nextIntervalStart - currentTvq.Time).TotalDays
                                                                            / (nextTvq.Time - currentTvq.Time).TotalDays;

                            var consumptionInPeriod =
                                sumForPeriod
                                + remainingConsumptionBelongingToThisPeriod;
                            result.Add(new Tvq(intervalStart.Value, consumptionInPeriod, Quality.Interpolated));
                            sumForPeriod = -remainingConsumptionBelongingToThisPeriod - currentTvq.V; // This is how much of nextTvq.V that we already have added.

                            intervalStart     = nextIntervalStart;
                            nextIntervalStart = FirstSecondOfNextInterval(intervalStart.Value, interval);
                        }
                        else
                        {
                            sumForPeriod += currentTvq.V;
                            doNeedToMove  = true;
                        }
                    } while (!doNeedToMove);

                    areMoreValues = nextTvq != null;
                }
            }
            return(result);
        }