コード例 #1
0
 public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
 {
     DataValue dv = base.Compute(context, bucket, state);
     double duration = Convert.ToDouble(dv.Value) / Math.Abs((bucket.To - bucket.From).TotalMilliseconds) * 100;
     dv.Value = duration;
     return dv;
 }
コード例 #2
0
ファイル: CountAggregate.cs プロジェクト: yuriik83/UA-.NET
 protected override StatusCode ComputeStatus(IAggregationContext context, int numGood, int numBad, TimeSlice bucket)
 {
     StatusCode code = base.ComputeStatus(context, numGood, numBad, bucket);
     if (code.CodeBits == StatusCodes.GoodNoData)    // can be removed if GoodNoData is used.
         code = StatusCodes.Good;
     return code;
 }
コード例 #3
0
 public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
 {
     DataValue initValue = bucket.EarlyBound.Value, finalValue = bucket.LateBound.Value;
     IEnumerator<DataValue> enumerator = bucket.Values.GetEnumerator();
     if (initValue == null && enumerator.MoveNext()) // first element
     {
         initValue = enumerator.Current;
         bucket.Incomplete = true;
     }
     if (finalValue == null)
     {
         while (enumerator.MoveNext())
         {
             finalValue = enumerator.Current;
         }
         bucket.Incomplete = true;
     }
     DataValue retVal = base.Compute(context, bucket, state);
     if (retVal.StatusCode.CodeBits == StatusCodes.BadNoData)
         retVal.Value = null;
     else
         retVal.Value = Convert.ToDouble(retVal.Value) / 
             Math.Abs((finalValue.SourceTimestamp - initValue.SourceTimestamp).TotalMilliseconds); // revisit
     return retVal;
 }
コード例 #4
0
ファイル: EndAggregate.cs プロジェクト: yuriik83/UA-.NET
        public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
        {
            List<DataValue> l = new List<DataValue>(bucket.Values);
            DataValue dv = l.Count > 0 ? GetDataValue(l) : null;
            if (SteppedVariable && dv == null)
                dv = bucket.LateBound.Value;

            DataValue retval = new DataValue();
            StatusCode code = StatusCodes.BadNoData;
            if (dv != null)
            {
                code = StatusCode.IsNotGood(dv.StatusCode)
                    ? StatusCodes.UncertainDataSubNormal
                    : StatusCodes.Good;
                retval.SourceTimestamp = dv.SourceTimestamp;
                retval.Value = dv.Value;
                code.AggregateBits = AggregateBits.Raw;
                if (bucket.Incomplete) code.AggregateBits |= AggregateBits.Partial;
            }
            else
            {
                retval.SourceTimestamp = bucket.From;
            }
            retval.StatusCode = code;
            return retval;
        }
コード例 #5
0
 protected override StatusCode ComputeStatus(IAggregationContext context, int numGood, int numBad, TimeSlice bucket)
 {
     StatusCode code = base.ComputeStatus(context, numGood, numBad, bucket);
     if (bucket.EarlyBound.Value == null || StatusCode.IsNotGood(bucket.EarlyBound.Value.StatusCode))
         code = StatusCodes.Uncertain;
     return code;
 }
        /// <summary>
        /// Computes the value for the timeslice.
        /// </summary>
        protected override DataValue ComputeValue(TimeSlice slice)
        {
            uint? id = AggregateId.Identifier as uint?;

            if (id != null)
            {
                switch (id.Value)
                {
                    case Objects.AggregateFunction_StandardDeviationPopulation:
                    {
                        return ComputeStdDev(slice, false, 1);
                    }

                    case Objects.AggregateFunction_StandardDeviationSample:
                    {
                        return ComputeStdDev(slice, false, 2);
                    }

                    case Objects.AggregateFunction_VariancePopulation:
                    {
                        return ComputeStdDev(slice, true, 1);
                    }

                    case Objects.AggregateFunction_VarianceSample:
                    {
                        return ComputeStdDev(slice, true, 2);
                    }
                }
            }

            return base.ComputeValue(slice);
        }
コード例 #7
0
ファイル: TotalAggregate.cs プロジェクト: yuriik83/UA-.NET
 public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
 {
     int numGood = 0;
     int numBad = 0;
     double total = 0.0;
     foreach (DataValue v in bucket.Values)
     {
         if (state.RawValueIsGood(v))
         {
             numGood += 1;
             total += Convert.ToDouble(v.Value, CultureInfo.InvariantCulture);
         }
         else
         {
             numBad += 1;
         }
     }
     DataValue retval = new DataValue { SourceTimestamp = bucket.From };
     StatusCode code = ComputeStatus(context, numGood, numBad, bucket).Code;
     code.AggregateBits = AggregateBits.Calculated;
     if (bucket.Incomplete) code.AggregateBits |= AggregateBits.Partial;
     if (StatusCode.IsNotBad(code))
         retval.Value = total;
     retval.StatusCode = code;
     GoodDataCount = numGood;
     return retval;
 }
コード例 #8
0
        public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
        {
            int numGood = 0;
            int numBad = 0;
            DataValue previous = RightState(bucket.EarlyBound.Value) ? bucket.EarlyBound.Value : null;
            double total = 0.0;

            DataValue retval = new DataValue { SourceTimestamp = bucket.From };
            StatusCode code = StatusCodes.BadNoData;

            foreach (DataValue v in bucket.Values)
            {
                if (state.RawValueIsGood(v))
                {
                    numGood += 1;
                    if (previous != null)
                        total += (v.SourceTimestamp - previous.SourceTimestamp).TotalMilliseconds;
                    previous = RightState(v) ? v : null;
                }
                else
                {
                    numBad += 1;
                }
            }
            if (previous != null)
                total += (bucket.LateBound.Value.SourceTimestamp - previous.SourceTimestamp).TotalMilliseconds;
            retval.Value = total;
            code = ComputeStatus(context, numGood, numBad, bucket).Code;
            code.AggregateBits = AggregateBits.Calculated;
            if (bucket.Incomplete) code.AggregateBits |= AggregateBits.Partial;
            retval.StatusCode = code;
            return retval;
        }
コード例 #9
0
ファイル: TotalAggregate.cs プロジェクト: yuriik83/UA-.NET
 protected override StatusCode ComputeStatus(IAggregationContext context, int numGood, int numBad, TimeSlice bucket)
 {
     if (numGood + numBad == 0)
         return StatusCodes.GoodNoData;
     if (numGood == 0 && numBad > 0)
         return StatusCodes.Bad;
     return base.ComputeStatus(context, numGood, numBad, bucket);
 }
コード例 #10
0
ファイル: MinimumAggregate.cs プロジェクト: yuriik83/UA-.NET
 public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
 {
     DataValue dv = base.Compute(context, bucket, state);
     if (dv.SourceTimestamp != bucket.From)
     {
         dv.SourceTimestamp = bucket.From;
         StatusCode code = dv.StatusCode;
         code.AggregateBits |= AggregateBits.Calculated;
         dv.StatusCode = code;
     }
     return dv;
 }
コード例 #11
0
ファイル: DeltaAggregate.cs プロジェクト: yuriik83/UA-.NET
        public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
        {
            int numGood = 0;
            int numBad = 0;
            DataValue firstGoodDv = null;
            DataValue lastGoodDv = null;
            DataValue lastDv = null;
            bool uncertainDataSubNormal = false;
            double delta = double.NaN;
            
            foreach (DataValue dv in bucket.Values)
            {
                if (state.RawValueIsGood(dv))
                {
                    if (firstGoodDv == null)
                    {
                        firstGoodDv = dv;
                    }
                    lastGoodDv = dv;                   
                    numGood++;
                }
                else
                {
                    // check for non-good value occuring before first good value
                    if (firstGoodDv == null)
                        uncertainDataSubNormal = true;
                    numBad++;
                }
                lastDv = dv;
            }
            if (firstGoodDv != null)
            {
                double fv = Convert.ToDouble(firstGoodDv.Value);
                double lv = Convert.ToDouble(lastGoodDv.Value);
                delta = lv - fv;
            }
            
            // check for non-good value occuring after latest good value
            if (!uncertainDataSubNormal && lastGoodDv != null && lastGoodDv.SourceTimestamp < lastDv.SourceTimestamp)
                uncertainDataSubNormal = true;

            StatusCode code = (uncertainDataSubNormal)
                ? StatusCodes.UncertainDataSubNormal
                : (numGood > 0) ? StatusCodes.Good : StatusCodes.BadNoData;
            DataValue retval = new DataValue { SourceTimestamp = bucket.From };
            if (!double.IsNaN(delta))
                retval.Value = delta;
            code.AggregateBits = AggregateBits.Calculated;
            if (bucket.Incomplete) code.AggregateBits |= AggregateBits.Partial;
            retval.StatusCode = code;
            return retval;
        }
コード例 #12
0
        protected abstract bool Comparison(DataValue value1, DataValue value2); // true if keep value1.

        public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
        {
            int numGood = 0;
            int numBad = 0;
            DataValue valueToKeep = new DataValue() { SourceTimestamp = bucket.From, StatusCode = StatusCodes.BadNoData };
            bool moreData = false;
            bool hasGoodData = false;
            foreach (DataValue dv in bucket.Values)
            {
                if (state.RawValueIsGood(dv))
                {
                    hasGoodData = true;
                    if (valueToKeep.StatusCode == StatusCodes.BadNoData)
                    {
                        valueToKeep = dv;
                    }
                    else
                    {
                        moreData = valueToKeep == dv;
                        if (Comparison(dv, valueToKeep))
                        {
                            valueToKeep = dv;
                        }
                    }
                    numGood++;
                }
                else
                {
                    numBad++;
                    if (!hasGoodData)
                        valueToKeep = dv;
                }
            }
            DataValue retval = valueToKeep.StatusCode == StatusCodes.BadNoData ? valueToKeep : (DataValue)valueToKeep.Clone();
            if (hasGoodData)
            {
                StatusCode code = StatusCodes.Good;
                code = ComputeStatus(context, numGood, numBad, bucket).Code;
                code.AggregateBits = moreData ? AggregateBits.ExtraData : AggregateBits.Raw;
                if (bucket.Incomplete) code.AggregateBits |= AggregateBits.Partial;
                retval.StatusCode = code;
            } // numGood = 0, hasGoodData = false beyond this point, i.e., no good data
            else if(numBad > 0)
            {
                retval.Value = null;
                retval.StatusCode = StatusCodes.Bad;
                retval.StatusCode = retval.StatusCode.SetAggregateBits(AggregateBits.Raw);
            }
            return retval;
        }
コード例 #13
0
 public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
 {
     DataValue retval = new DataValue { SourceTimestamp = bucket.From };
     StatusCode code = StatusCodes.BadNoData;
     DataValue boundValue = context.IsReverseAggregation ? bucket.LateBound.Value : bucket.EarlyBound.Value;
     if (boundValue != null)
     {
         code = bucket.EarlyBound.Value.StatusCode.Code;
         code.AggregateBits = bucket.EarlyBound.Value.StatusCode.AggregateBits;
         retval.Value = Convert.ToDouble(bucket.EarlyBound.Value.Value, CultureInfo.InvariantCulture);
     }
     if (bucket.Incomplete) code.AggregateBits |= AggregateBits.Partial;
     retval.StatusCode = code;
     return retval;
 }
コード例 #14
0
ファイル: AverageAggregate.cs プロジェクト: yuriik83/UA-.NET
 public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
 {
     DataValue initValue = bucket.EarlyBound.Value;
     IEnumerator<DataValue> enumerator = bucket.Values.GetEnumerator();
     if (enumerator.MoveNext()) // first element
     {
         if(initValue == null && bucket.From != enumerator.Current.SourceTimestamp)
             bucket.Incomplete = true;
     }
     DataValue retVal = base.Compute(context, bucket, state);
     if (GoodDataCount > 0)
         retVal.Value = Convert.ToDouble(retVal.Value) / GoodDataCount;
     else
         retVal.Value = null;
     return retVal;
 }
コード例 #15
0
ファイル: RangeAggregate.cs プロジェクト: yuriik83/UA-.NET
        public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
        {
            int numGood = 0;
            int numBad = 0;
            double minV = double.MaxValue;
            double maxV = double.MinValue;
            bool uncertainDataSubNormal = false;
            double range = double.NaN;

            foreach (DataValue dv in bucket.Values)
            {
                if (state.RawValueIsGood(dv))
                {
                    double v = Convert.ToDouble(dv.Value);
                    if (minV > v)
                    {
                        minV = v;
                    }
                    if (maxV < v)
                    {
                        maxV = v;
                    }
                    numGood++;
                }
                else
                {
                    uncertainDataSubNormal = true;
                    numBad++;
                }
            }
            if (minV != double.MaxValue && maxV != double.MinValue)
            {
                range = Math.Abs(maxV - minV);
            }

            StatusCode code = (uncertainDataSubNormal)
                ? StatusCodes.UncertainDataSubNormal
                : StatusCodes.Good;
            if (numGood + numBad == 0) code = StatusCodes.BadNoData;
            DataValue retval = new DataValue { SourceTimestamp = bucket.From };
            if (!double.IsNaN(range))
                retval.Value = range;
            code.AggregateBits = AggregateBits.Calculated;
            if (bucket.Incomplete) code.AggregateBits |= AggregateBits.Partial;
            retval.StatusCode = code;
            return retval;
        }
コード例 #16
0
 public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
 {
     StatusCode returnCode = StatusCodes.BadNoData;
     foreach(DataValue dv in bucket.Values)
     {
         if (returnCode == StatusCodes.BadNoData)
         {
             returnCode = dv.StatusCode;
         }
         else
         {
             // StatusCodes.Bad = 0x80000000
             // StatusCodes.Uncertain = 0x40000000
             // StatusCodes.Good = 0x00000000
             uint code = dv.StatusCode.Code >> 28;   // 7 Hexadecimal digits = 28 binary digits.
             switch (code)
             {
                 case 8: // 8 is maximum
                     returnCode = StatusCodes.Bad;
                     break;
                 case 4:
                     if(StatusCode.IsNotBad(returnCode))
                         returnCode = StatusCodes.Uncertain;
                     break;
                 case 0: // 0 is minimum 
                     break;
                 default:
                     Debug.Assert(true, "should not touch this line");
                     throw new Exception(String.Format("Unknown error in WorstQuality aggregate calculation, code = {0}", dv.StatusCode));
             }
         }
     }
     DataValue retVal = new DataValue() { SourceTimestamp = bucket.From };
     if (returnCode != StatusCodes.BadNoData)
     {
         retVal.Value = returnCode;
         StatusCode status = StatusCodes.Good;
         status.AggregateBits |= AggregateBits.Calculated;
         if (bucket.Incomplete) status.AggregateBits |= AggregateBits.Partial;
         retVal.StatusCode = status;
     }
     else
     {
         retVal.StatusCode = returnCode;
     }
     return retVal;
 }
        /// <summary>
        /// Computes the value for the timeslice.
        /// </summary>
        protected override DataValue ComputeValue(TimeSlice slice)
        {
            uint? id = AggregateId.Identifier as uint?;

            if (id != null)
            {
                switch (id.Value)
                {
                    case Objects.AggregateFunction_DurationGood:
                    {
                        return ComputeDurationGoodBad(slice, false, false);
                    }

                    case Objects.AggregateFunction_DurationBad:
                    {
                        return ComputeDurationGoodBad(slice, true, false);
                    }

                    case Objects.AggregateFunction_PercentGood:
                    {
                        return ComputeDurationGoodBad(slice, false, true);
                    }

                    case Objects.AggregateFunction_PercentBad:
                    {
                        return ComputeDurationGoodBad(slice, true, true);
                    }

                    case Objects.AggregateFunction_WorstQuality:
                    {
                        return ComputeWorstQuality(slice, false);
                    }

                    case Objects.AggregateFunction_WorstQuality2:
                    {
                        return ComputeWorstQuality(slice, true);
                    }
                }
            }

            return base.ComputeValue(slice);
        }
コード例 #18
0
        /// <summary>
        /// Computes the value for the timeslice.
        /// </summary>
        protected override DataValue ComputeValue(TimeSlice slice)
        {
            uint? id = AggregateId.Identifier as uint?;

            if (id != null)
            {
                switch (id.Value)
                {
                    case Objects.AggregateFunction_Start:
                    {
                        return ComputeStartEnd(slice, false);
                    }

                    case Objects.AggregateFunction_End:
                    {
                        return ComputeStartEnd(slice, true);
                    }

                    case Objects.AggregateFunction_Delta:
                    {
                        return ComputeDelta(slice);
                    }

                    case Objects.AggregateFunction_StartBound:
                    {
                        return ComputeStartEnd2(slice, false);
                    }

                    case Objects.AggregateFunction_EndBound:
                    {
                        return ComputeStartEnd2(slice, true);
                    }

                    case Objects.AggregateFunction_DeltaBounds:
                    {
                        return ComputeDelta2(slice);
                    }
                }
            }

            return base.ComputeValue(slice);
        }
コード例 #19
0
        /// <summary>
        /// Computes the value for the timeslice.
        /// </summary>
        protected override DataValue ComputeValue(TimeSlice slice)
        {
            uint? id = AggregateId.Identifier as uint?;

            if (id != null)
            {
                switch (id.Value)
                {
                    case Objects.AggregateFunction_Average:
                    {
                        return ComputeAverage(slice);
                    }

                    case Objects.AggregateFunction_TimeAverage:
                    {
                        return ComputeTimeAverage(slice, false, 1);
                    }

                    case Objects.AggregateFunction_Total:
                    {
                        return ComputeTimeAverage(slice, false, 2);
                    }

                    case Objects.AggregateFunction_TimeAverage2:
                    {
                        return ComputeTimeAverage(slice, true, 1);
                    }

                    case Objects.AggregateFunction_Total2:
                    {
                        return ComputeTimeAverage(slice, true, 2);
                    }
                }
            }

            return base.ComputeValue(slice);
        }
コード例 #20
0
        /// <summary>
        /// Computes the value for the timeslice.
        /// </summary>
        protected override DataValue ComputeValue(TimeSlice slice)
        {
            uint? id = AggregateId.Identifier as uint?;

            if (id != null)
            {
                switch (id.Value)
                {
                    case Objects.AggregateFunction_Count:
                    {
                        return ComputeCount(slice);
                    }

                    case Objects.AggregateFunction_AnnotationCount:
                    {
                        return ComputeAnnotationCount(slice);
                    }

                    case Objects.AggregateFunction_DurationInStateZero:
                    {
                        return ComputeDurationInState(slice, false);
                    }

                    case Objects.AggregateFunction_DurationInStateNonZero:
                    {
                        return ComputeDurationInState(slice, true);
                    }

                    case Objects.AggregateFunction_NumberOfTransitions:
                    {
                        return ComputeNumberOfTransitions(slice);
                    }
                }
            }

            return base.ComputeValue(slice);
        }
コード例 #21
0
ファイル: CountAggregate.cs プロジェクト: yuriik83/UA-.NET
 public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
 {
     int numGood = 0;
     int numBad = 0;
     foreach (DataValue v in bucket.Values)
     {
         if (state.RawValueIsGood(v))
         {
             numGood += 1;
         }
         else
         {
             numBad += 1;
         }
     }
     StatusCode code = StatusCodes.Good;
     DataValue retval = new DataValue { SourceTimestamp = bucket.From };
     retval.Value = numGood;
     code = ComputeStatus(context, numGood, numBad, bucket).Code;
     code.AggregateBits = AggregateBits.Calculated;
     if (bucket.Incomplete) code.AggregateBits |= AggregateBits.Partial;
     retval.StatusCode = code;
     return retval;
 }
コード例 #22
0
        /// <summary>
        /// Computes the value for the timeslice.
        /// </summary>
        protected override DataValue ComputeValue(TimeSlice slice)
        {
            uint?id = AggregateId.Identifier as uint?;

            if (id != null)
            {
                switch (id.Value)
                {
                case Objects.AggregateFunction_Minimum:
                {
                    return(ComputeMinMax(slice, 1, false));
                }

                case Objects.AggregateFunction_MinimumActualTime:
                {
                    return(ComputeMinMax(slice, 1, true));
                }

                case Objects.AggregateFunction_Maximum:
                {
                    return(ComputeMinMax(slice, 2, false));
                }

                case Objects.AggregateFunction_MaximumActualTime:
                {
                    return(ComputeMinMax(slice, 2, true));
                }

                case Objects.AggregateFunction_Range:
                {
                    return(ComputeMinMax(slice, 3, false));
                }

                case Objects.AggregateFunction_Minimum2:
                {
                    return(ComputeMinMax2(slice, 1, false));
                }

                case Objects.AggregateFunction_MinimumActualTime2:
                {
                    return(ComputeMinMax2(slice, 1, true));
                }

                case Objects.AggregateFunction_Maximum2:
                {
                    return(ComputeMinMax2(slice, 2, false));
                }

                case Objects.AggregateFunction_MaximumActualTime2:
                {
                    return(ComputeMinMax2(slice, 2, true));
                }

                case Objects.AggregateFunction_Range2:
                {
                    return(ComputeMinMax2(slice, 3, false));
                }
                }
            }

            return(base.ComputeValue(slice));
        }
コード例 #23
0
 public override void UpdateBoundingValues(TimeSlice bucket, AggregateState state)
 {
 }
コード例 #24
0
        /// <summary>
        /// Calculates the Count aggregate for the timeslice.
        /// </summary>
        protected DataValue ComputeNumberOfTransitions(TimeSlice slice)
        {
            // get the values in the slice.
            List<DataValue> values = GetValues(slice);

            // check for empty slice.
            if (values == null)
            {
                return GetNoDataValue(slice);
            }

            // determine whether a transition occurs at the StartTime
            double lastValue = Double.NaN;

            if (slice.EarlyBound != null)
            {
                if (StatusCode.IsGood(slice.EarlyBound.Value.StatusCode))
                {
                    try
                    {
                        lastValue = CastToDouble(slice.EarlyBound.Value);
                    }
                    catch (Exception)
                    {
                        lastValue = Double.NaN;
                    }
                }
            }

            // count the transitions.
            int count = 0;

            for (int ii = 0; ii < values.Count; ii++)
            {
                if (!IsGood(values[ii]))
                {
                    continue;
                }

                double nextValue = 0;

                try
                {
                    nextValue = CastToDouble(values[ii]);
                }
                catch (Exception)
                {
                    continue;
                }

                if (!Double.IsNaN(lastValue))
                {
                    if (lastValue != nextValue)
                    {
                        count++;
                    }
                }

                lastValue = nextValue;
            }

            // set the timestamp and status.
            DataValue value = new DataValue();
            value.WrappedValue = new Variant(count, TypeInfo.Scalars.Int32);
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);
            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);
            value.StatusCode = GetValueBasedStatusCode(slice, values, value.StatusCode);

            // return result.
            return value;
        }
コード例 #25
0
        /// <summary>
        /// Calculates the Delta2 aggregate for the timeslice.
        /// </summary>
        protected DataValue ComputeDelta2(TimeSlice slice)
        {
            // get the values in the slice.
            List <DataValue> values = GetValuesWithSimpleBounds(slice);

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return(GetNoDataValue(slice));
            }

            DataValue start = values[0];
            DataValue end   = values[values.Count - 1];

            // check for bad bounds.
            if (StatusCode.IsBad(start.StatusCode) || StatusCode.IsBad(end.StatusCode))
            {
                return(GetNoDataValue(slice));
            }

            // convert to doubles.
            double   startValue   = 0;
            TypeInfo originalType = null;

            try {
                startValue   = CastToDouble(start);
                originalType = start.WrappedValue.TypeInfo;
            } catch (Exception) {
                startValue = Double.NaN;
            }

            double endValue = 0;

            try {
                endValue = CastToDouble(end);
            } catch (Exception) {
                endValue = Double.NaN;
            }

            // check for bad bounds.
            if (Double.IsNaN(startValue) || Double.IsNaN(endValue))
            {
                return(GetNoDataValue(slice));
            }

            DataValue value = new DataValue();

            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);

            if (StatusCode.IsNotGood(start.StatusCode) || StatusCode.IsNotGood(end.StatusCode))
            {
                value.StatusCode = StatusCodes.UncertainDataSubNormal;
            }

            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);

            // calculate delta.
            double delta = endValue - startValue;

            if (originalType != null && originalType.BuiltInType != BuiltInType.Double)
            {
                object delta2 = TypeInfo.Cast(delta, TypeInfo.Scalars.Double, originalType.BuiltInType);
                value.WrappedValue = new Variant(delta2, originalType);
            }
            else
            {
                value.WrappedValue = new Variant(delta, TypeInfo.Scalars.Double);
            }

            // return result.
            return(value);
        }
コード例 #26
0
        public void UpdateProcessedData(DataValue rawValue, AggregateState state)
        {
            // step 1: compute new TimeSlice instances to enqueue, until we reach the one the
            // rawValue belongs in or we've reached the one that goes to the EndTime. Ensure
            // that the raw value is added to the last one created.
            TimeSlice tmpTS = null;

            if (m_pending == null)
            {
                m_pending = new Queue <TimeSlice>();
            }
            if (m_latest == null)
            {
                tmpTS = TimeSlice.CreateInitial(StartTime, EndTime, ProcessingInterval);
                if (tmpTS != null)
                {
                    m_pending.Enqueue(tmpTS);
                    m_latest = tmpTS;
                }
            }
            else
            {
                tmpTS = m_latest;
            }
            DateTime latestTime = (StartTime > EndTime) ? StartTime : EndTime;

            while ((tmpTS != null) && (state.HasTerminated || !tmpTS.AcceptValue(rawValue)))
            {
                tmpTS = TimeSlice.CreateNext(latestTime, ProcessingInterval, tmpTS);
                if (tmpTS != null)
                {
                    m_pending.Enqueue(tmpTS);
                    m_latest = tmpTS;
                }
            }

            // step 2: apply the aggregator to the head of the queue to see if we can convert
            // it into a processed point. If so, dequeue it and add the processed value to the
            // m_released list. Keep doing it until one of the TimeSlices returns null or we
            // run out of enqueued TimeSlices (should only happen on termination).
            if (m_released == null)
            {
                m_released = new List <DataValue>();
            }
            foreach (TimeSlice b in m_pending)
            {
                UpdateBoundingValues(b, state);
            }
            bool active = true;

            while ((m_pending.Count > 0) && active)
            {
                TimeSlice top      = m_pending.Peek();
                DataValue computed = null;
                if (!WaitForMoreData(top, state))
                {
                    computed = Compute(this, top, state);
                }
                if (computed != null)
                {
                    m_released.Add(computed);
                    m_pending.Dequeue();
                }
                else
                {
                    active = false;
                }
            }
        }
コード例 #27
0
        /// <summary>
        /// Calculates the AnnotationCount aggregate for the timeslice.
        /// </summary>
        protected DataValue ComputeAnnotationCount(TimeSlice slice)
        {
            // get the values in the slice.
            List<DataValue> values = GetValues(slice);

            // check for empty slice.
            if (values == null)
            {
                return GetNoDataValue(slice);
            }

            // count the values.
            int count = 0;

            for (int ii = 0; ii < values.Count; ii++)
            {
                count++;
            }

            // set the timestamp and status.
            DataValue value = new DataValue();
            value.WrappedValue = new Variant(count, TypeInfo.Scalars.Int32);
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);
            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);

            // return result.
            return value;
        }
        /// <summary>
        /// Calculates the StdDev, Variance, StdDev2 and Variance2 aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeStdDev(TimeSlice slice, bool includeBounds, int valueType)
        {
            // get the values in the slice.
            List <DataValue> values = null;

            if (includeBounds)
            {
                values = GetValuesWithSimpleBounds(slice);
            }
            else
            {
                values = GetValues(slice);
            }

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return(GetNoDataValue(slice));
            }

            // get the regions.
            List <SubRegion> regions = GetRegionsInValueSet(values, false, true);

            List <double> xData             = new List <double>();
            double        average           = 0;
            bool          nonGoodDataExists = false;

            for (int ii = 0; ii < regions.Count; ii++)
            {
                if (StatusCode.IsGood(regions[ii].StatusCode))
                {
                    xData.Add(regions[ii].StartValue);
                    average += regions[ii].StartValue;
                }
                else
                {
                    nonGoodDataExists = true;
                }
            }

            // check if no good data.
            if (xData.Count == 0)
            {
                return(GetNoDataValue(slice));
            }

            average /= xData.Count;

            // calculate variance.
            double variance = 0;

            for (int ii = 0; ii < xData.Count; ii++)
            {
                double error = xData[ii] - average;
                variance += error * error;
            }

            // use the sample variance if bounds are included.
            if (includeBounds)
            {
                variance /= (xData.Count + 1);
            }

            // use the population variance if bounds are not included.
            else
            {
                variance /= xData.Count;
            }

            // select the result.
            double result = 0;

            switch (valueType)
            {
            case 1: { result = Math.Sqrt(variance); break; }

            case 2: { result = variance; break; }
            }

            // set the timestamp and status.
            DataValue value = new DataValue();

            value.WrappedValue    = new Variant(result, TypeInfo.Scalars.Double);
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);

            if (nonGoodDataExists)
            {
                value.StatusCode = StatusCodes.UncertainDataSubNormal;
            }

            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);

            // return result.
            return(value);
        }
コード例 #29
0
 public abstract DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state);
コード例 #30
0
        /// <summary>
        /// Calculates the StdDev, Variance, StdDev2 and Variance2 aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeTimeAverage(TimeSlice slice, bool useSimpleBounds, int valueType)
        {
            // get the values in the slice.
            List<DataValue> values = null;

            if (useSimpleBounds)
            {
                values = GetValuesWithSimpleBounds(slice);
            }
            else
            {
                values = GetValuesWithInterpolatedBounds(slice);
            }

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return GetNoDataValue(slice);
            }

            // get the regions.
            List<SubRegion> regions = GetRegionsInValueSet(values, !useSimpleBounds, Stepped);

            double total = 0;
            double totalDuration = 0;
            bool nonGoodRegionsExists = false;

            for (int ii = 0; ii < regions.Count; ii++)
            {
                double duration = regions[ii].Duration/1000.0;

                if (StatusCode.IsNotBad(regions[ii].StatusCode))
                {
                    total += (regions[ii].StartValue + regions[ii].EndValue) * duration / 2;
                    totalDuration += duration;
                }

                if (StatusCode.IsNotGood(regions[ii].StatusCode))
                {
                    nonGoodRegionsExists = true;
                }
            }

            // check if no good data.
            if (totalDuration == 0)
            {
                return GetNoDataValue(slice);
            }

            // select the result.
            double result = 0;

            switch (valueType)
            {
                case 1: { result = total/totalDuration; break; }
                case 2: { result = total; break; }
            }

            // set the timestamp and status.
            DataValue value = new DataValue();
            value.WrappedValue = new Variant(result, TypeInfo.Scalars.Double);
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);

            if (useSimpleBounds)
            {
                value.StatusCode = GetTimeBasedStatusCode(regions, value.StatusCode);
            }
            else
            {
                value.StatusCode = StatusCodes.Good;

                if (nonGoodRegionsExists)
                {
                    value.StatusCode = StatusCodes.UncertainDataSubNormal;
                }
            }

            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);

            // return result.
            return value;
        }
コード例 #31
0
 protected override StatusCode ComputeStatus(IAggregationContext context, int numGood, int numBad, TimeSlice bucket)
 {
     StatusCode code = base.ComputeStatus(context, numGood, numBad, bucket);
     if (bucket.EarlyBound.Value == null || StatusCode.IsNotGood(bucket.EarlyBound.Value.StatusCode))
         code = StatusCodes.Uncertain;
     return code;
 }
コード例 #32
0
 protected override StatusCode ComputeStatus(IAggregationContext context, int numGood, int numBad, TimeSlice bucket)
 {
     return(numBad + numGood == 0 ? StatusCodes.BadNoData : base.ComputeStatus(context, numGood, numBad, bucket));
 }
コード例 #33
0
        /// <summary>
        /// Calculates the Delta aggregate for the timeslice.
        /// </summary>
        protected DataValue ComputeDelta(TimeSlice slice)
        {
            // get the values in the slice.
            List <DataValue> values = GetValues(slice);

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return(GetNoDataValue(slice));
            }

            // find start value.
            DataValue start          = null;
            double    startValue     = 0;
            TypeInfo  originalType   = null;
            bool      badDataSkipped = false;

            for (int ii = 0; ii < values.Count; ii++)
            {
                start = values[ii];

                if (StatusCode.IsGood(start.StatusCode))
                {
                    try {
                        startValue   = CastToDouble(start);
                        originalType = start.WrappedValue.TypeInfo;
                        break;
                    } catch (Exception) {
                        startValue = Double.NaN;
                    }
                }

                start          = null;
                badDataSkipped = true;
            }

            // find end value.
            DataValue end      = null;
            double    endValue = 0;

            for (int ii = values.Count - 1; ii >= 0; ii--)
            {
                end = values[ii];

                if (StatusCode.IsGood(end.StatusCode))
                {
                    try {
                        endValue = CastToDouble(end);
                        break;
                    } catch (Exception) {
                        endValue = Double.NaN;
                    }

                    break;
                }

                end            = null;
                badDataSkipped = true;
            }

            // check if no good data.
            if (Double.IsNaN(startValue) || Double.IsNaN(endValue))
            {
                return(GetNoDataValue(slice));
            }

            DataValue value = new DataValue();

            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);

            // set status code.
            if (badDataSkipped)
            {
                value.StatusCode = StatusCodes.UncertainDataSubNormal;
            }

            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);

            // calculate delta.
            double delta = endValue - startValue;

            if (originalType != null && originalType.BuiltInType != BuiltInType.Double)
            {
                object delta2 = TypeInfo.Cast(delta, TypeInfo.Scalars.Double, originalType.BuiltInType);
                value.WrappedValue = new Variant(delta2, originalType);
            }
            else
            {
                value.WrappedValue = new Variant(delta, TypeInfo.Scalars.Double);
            }

            // return result.
            return(value);
        }
コード例 #34
0
ファイル: CountAggregate.cs プロジェクト: neobox3000/UA-.NET
        protected override StatusCode ComputeStatus(IAggregationContext context, int numGood, int numBad, TimeSlice bucket)
        {
            StatusCode code = base.ComputeStatus(context, numGood, numBad, bucket);

            if (code.CodeBits == StatusCodes.GoodNoData)    // can be removed if GoodNoData is used.
            {
                code = StatusCodes.Good;
            }
            return(code);
        }
コード例 #35
0
 public abstract void UpdateBoundingValues(TimeSlice bucket, AggregateState state);
コード例 #36
0
        /// <summary>
        /// Calculates the Count aggregate for the timeslice.
        /// </summary>
        protected DataValue ComputeNumberOfTransitions(TimeSlice slice)
        {
            // get the values in the slice.
            List <DataValue> values = GetValues(slice);

            // check for empty slice.
            if (values == null)
            {
                return(GetNoDataValue(slice));
            }

            // determine whether a transition occurs at the StartTime
            double lastValue = Double.NaN;

            if (slice.EarlyBound != null)
            {
                if (StatusCode.IsGood(slice.EarlyBound.Value.StatusCode))
                {
                    try
                    {
                        lastValue = CastToDouble(slice.EarlyBound.Value);
                    }
                    catch (Exception)
                    {
                        lastValue = Double.NaN;
                    }
                }
            }

            // count the transitions.
            int count = 0;

            for (int ii = 0; ii < values.Count; ii++)
            {
                if (!IsGood(values[ii]))
                {
                    continue;
                }

                double nextValue = 0;

                try
                {
                    nextValue = CastToDouble(values[ii]);
                }
                catch (Exception)
                {
                    continue;
                }

                if (!Double.IsNaN(lastValue))
                {
                    if (lastValue != nextValue)
                    {
                        count++;
                    }
                }

                lastValue = nextValue;
            }

            // set the timestamp and status.
            DataValue value = new DataValue();

            value.WrappedValue    = new Variant(count, TypeInfo.Scalars.Int32);
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);
            value.StatusCode      = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);
            value.StatusCode      = GetValueBasedStatusCode(slice, values, value.StatusCode);

            // return result.
            return(value);
        }
コード例 #37
0
 public abstract bool WaitForMoreData(TimeSlice bucket, AggregateState state);
コード例 #38
0
        /// <summary>
        /// Calculates the DurationGood and DurationBad aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeWorstQuality(TimeSlice slice, bool includeBounds)
        {
            // get the values in the slice.
            List <DataValue> values = null;

            if (!includeBounds)
            {
                values = GetValues(slice);
            }
            else
            {
                values = GetValuesWithSimpleBounds(slice);
            }

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return(GetNoDataValue(slice));
            }

            // get the regions.
            List <SubRegion> regions = GetRegionsInValueSet(values, false, true);

            StatusCode worstQuality          = StatusCodes.Good;
            int        badQualityCount       = 0;
            int        uncertainQualityCount = 0;

            for (int ii = 0; ii < values.Count; ii++)
            {
                StatusCode quality = values[ii].StatusCode;

                if (StatusCode.IsBad(quality))
                {
                    badQualityCount++;

                    if (StatusCode.IsNotBad(worstQuality))
                    {
                        worstQuality = quality.CodeBits;
                    }

                    continue;
                }

                if (StatusCode.IsUncertain(quality))
                {
                    uncertainQualityCount++;

                    if (StatusCode.IsGood(worstQuality))
                    {
                        worstQuality = quality.CodeBits;
                    }

                    continue;
                }
            }

            // set the timestamp and status.
            DataValue value = new DataValue();

            value.WrappedValue    = new Variant(worstQuality, TypeInfo.Scalars.StatusCode);
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);
            value.StatusCode      = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);

            if ((StatusCode.IsBad(worstQuality) && badQualityCount > 1) || (StatusCode.IsUncertain(worstQuality) && uncertainQualityCount > 1))
            {
                value.StatusCode = value.StatusCode.SetAggregateBits(value.StatusCode.AggregateBits | AggregateBits.MultipleValues);
            }

            // return result.
            return(value);
        }
コード例 #39
0
        /// <summary>
        /// Computes the status code for the processing interval using the percent good/bad
        /// information in the context.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="numGood"></param>
        /// <param name="numBad"></param>
        /// <returns></returns>
        protected virtual StatusCode ComputeStatus(IAggregationContext context, int numGood, int numBad, TimeSlice bucket)
        {
            int total = numGood + numBad;

            if (total > 0)
            {
                double pbad = (numBad * 100) / total;
                if (pbad > context.PercentDataBad)
                {
                    return(StatusCodes.Bad);
                }
                double pgood = (numGood * 100) / total;
                if (pgood >= context.PercentDataGood)
                {
                    return(StatusCodes.Good);
                }
                return(StatusCodes.Uncertain);
                // return StatusCodes.UncertainDataSubNormal;
            }
            else
            {
                return(StatusCodes.GoodNoData);
            }
        }
コード例 #40
0
        public override void UpdateBoundingValues(TimeSlice bucket, AggregateState state)
        {
            BoundingValue EarlyBound = bucket.EarlyBound;
            BoundingValue LateBound  = bucket.LateBound;

            if (bucket.ExactMatch(state.LatestTimestamp))
            {
                EarlyBound.RawPoint       = state.LatePoint == null ? state.EarlyPoint : state.LatePoint;
                EarlyBound.DerivationType = BoundingValueType.QualityRaw;
            }
            else
            {
                if (EarlyBound.DerivationType != BoundingValueType.QualityRaw)
                {
                    if (EarlyBound.EarlyPoint == null)
                    {
                        if ((state.EarlyPoint != null) && (state.EarlyPoint.SourceTimestamp < bucket.From))
                        {
                            EarlyBound.EarlyPoint = state.EarlyPoint;
                        }
                    }
                    if (EarlyBound.LatePoint == null)
                    {
                        if ((state.LatePoint != null) && (state.LatePoint.SourceTimestamp >= bucket.From))
                        {
                            EarlyBound.CurrentBadPoints = new List <DataValue>();
                            foreach (DataValue dv in state.CurrentBadPoints)
                            {
                                if (dv.SourceTimestamp < EarlyBound.Timestamp)
                                {
                                    EarlyBound.CurrentBadPoints.Add(dv);
                                }
                            }
                            EarlyBound.DerivationType = BoundingValueType.QualityInterpolation;
                        }
                    }
                }
                if (state.HasTerminated && (state.LatePoint == null))
                {
                    EarlyBound.CurrentBadPoints = new List <DataValue>();
                    foreach (DataValue dv in state.CurrentBadPoints)
                    {
                        if (dv.SourceTimestamp < EarlyBound.Timestamp)
                        {
                            EarlyBound.CurrentBadPoints.Add(dv);
                        }
                    }
                    EarlyBound.DerivationType = BoundingValueType.QualityExtrapolation;
                }
            }

            if (bucket.EndMatch(state.LatestTimestamp))
            {
                LateBound.RawPoint       = state.LatePoint == null ? state.EarlyPoint : state.LatePoint;
                LateBound.DerivationType = BoundingValueType.QualityRaw;
            }
            else
            {
                if (LateBound.DerivationType != BoundingValueType.QualityRaw)
                {
                    if ((state.EarlyPoint != null) && (state.EarlyPoint.SourceTimestamp < bucket.To))
                    {
                        LateBound.EarlyPoint = state.EarlyPoint;
                    }
                    if (LateBound.LatePoint == null)
                    {
                        if ((state.LatePoint != null) && (state.LatePoint.SourceTimestamp >= bucket.To))
                        {
                            LateBound.CurrentBadPoints = new List <DataValue>();
                            foreach (DataValue dv in state.CurrentBadPoints)
                            {
                                if (dv.SourceTimestamp < LateBound.Timestamp)
                                {
                                    LateBound.CurrentBadPoints.Add(dv);
                                }
                            }
                            LateBound.DerivationType = BoundingValueType.QualityInterpolation;
                        }
                    }
                }
                if (state.HasTerminated && (state.LatePoint == null))
                {
                    LateBound.CurrentBadPoints = new List <DataValue>();
                    foreach (DataValue dv in state.CurrentBadPoints)
                    {
                        if (dv.SourceTimestamp < LateBound.Timestamp)
                        {
                            LateBound.CurrentBadPoints.Add(dv);
                        }
                    }
                    LateBound.DerivationType = BoundingValueType.QualityExtrapolation;
                }
            }
        }
コード例 #41
0
        public override DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state)
        {
            int numGood = 0;
            int numBad = 0;
            int nTransitions = 0;
            long stateCode = -1;
            IEnumerator<DataValue> enumerator = bucket.Values.GetEnumerator();
            bool bucketValueNotEmpty = enumerator.MoveNext();
            if (bucketValueNotEmpty && enumerator.Current != null)
            {
                if (bucket.EarlyBound != null)
                {
                    if (enumerator.Current.SourceTimestamp == bucket.EarlyBound.Timestamp && bucket.EarlyBound.PriorPoint != null)
                    {
                        stateCode = Convert.ToInt32(Convert.ToBoolean(bucket.EarlyBound.PriorPoint.Value));
                    }
                    else if (bucket.EarlyBound.Value != null)
                    {
                        stateCode = Convert.ToInt32(Convert.ToBoolean(bucket.EarlyBound.Value.Value));
                    }
                }
            }

            // viz. UA MultiStateNodeState & TwoStateNodeState, 
            // assume DataValue.Value is either an EnumValueType or a bool
            if (bucketValueNotEmpty)
            {
                do
                {
                    DataValue dv = enumerator.Current;
                    if (state.RawValueIsGood(dv))
                    {
                        EnumValueType ev = dv.Value as EnumValueType;
                        if (ev == null)
                        {
                            bool b;
                            if (bool.TryParse(dv.Value.ToString(), out b))
                            {
                                if (stateCode < 0)
                                    stateCode = b ? 1 : 0;
                                else if (b.CompareTo(Convert.ToBoolean(stateCode)) != 0)
                                {
                                    nTransitions++;
                                    stateCode = b ? 1 : 0;
                                }
                            }
                            else
                                continue;
                        }
                        else
                        {
                            long s = ev.Value;
                            if (stateCode < 0)
                                stateCode = s;
                            else if (!s.Equals(stateCode))
                            {
                                nTransitions++;
                                stateCode = s;
                            }
                        }
                        numGood++;
                    }
                    else
                    {
                        numBad++;
                    }
                } while (enumerator.MoveNext());
            }

            StatusCode code = ComputeStatus(context, numGood, numBad, bucket).Code;
            DataValue retval = new DataValue { SourceTimestamp = bucket.From, Value = nTransitions };
            code.AggregateBits = AggregateBits.Calculated;
            if (bucket.Incomplete) code.AggregateBits |= AggregateBits.Partial;
            retval.StatusCode = code;
            return retval;
        }
コード例 #42
0
        /// <summary>
        /// Calculate the Start and End aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeStartEnd(TimeSlice slice, bool returnEnd)
        {
            // get the values in the slice.
            List<DataValue> values = GetValues(slice);

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return GetNoDataValue(slice);
            }

            // return start value.
            if (!returnEnd)
            {
                return values[0];
            }

            // return end value.
            else
            {
                return values[values.Count - 1];
            }
        }
コード例 #43
0
        /// <summary>
        /// Calculates the DurationInStateZero and DurationInStateNonZero aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeDurationInState(TimeSlice slice, bool isNonZero)
        {
            // get the values in the slice.
            List<DataValue> values = GetValuesWithSimpleBounds(slice);

            // check for empty slice.
            if (values == null)
            {
                return GetNoDataValue(slice);
            }

            // get the regions.
            List<SubRegion> regions = GetRegionsInValueSet(values, false, true);

            double duration = 0;

            for (int ii = 0; ii < regions.Count; ii++)
            {
                if (StatusCode.IsNotGood(regions[ii].StatusCode))
                {
                    continue;
                }

                if (isNonZero)
                {
                    if (regions[ii].StartValue != 0)
                    {
                        duration += regions[ii].Duration;
                    }
                }
                else
                {
                    if (regions[ii].StartValue == 0)
                    {
                        duration += regions[ii].Duration;
                    }
                }
            }

            // set the timestamp and status.
            DataValue value = new DataValue();
            value.WrappedValue = new Variant(duration, TypeInfo.Scalars.Double);
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);
            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);
            value.StatusCode = GetTimeBasedStatusCode(regions, value.StatusCode);

            // return result.
            return value;
        }
コード例 #44
0
        /// <summary>
        /// Calculate the Start2 and End2 aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeStartEnd2(TimeSlice slice, bool returnEnd)
        {
            // get the values in the slice.
            List<DataValue> values = GetValuesWithSimpleBounds(slice);

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return GetNoDataValue(slice);
            }

            DataValue value = null;

            // return start bound.
            if ((!returnEnd && !TimeFlowsBackward) || (returnEnd && TimeFlowsBackward))
            {
                value = values[0];
            }

            // return end bound.
            else
            {
                value = values[values.Count - 1];
            }

            if (returnEnd)
            {
                value.SourceTimestamp = GetTimestamp(slice);
                value.ServerTimestamp = GetTimestamp(slice);

                if (StatusCode.IsNotBad(value.StatusCode))
                {
                    value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);
                }
            }

            return value;
        }
コード例 #45
0
        public override void UpdateBoundingValues(TimeSlice bucket, AggregateState state)
        {
            BoundingValue EarlyBound = bucket.EarlyBound;
            BoundingValue LateBound  = bucket.LateBound;

            if (bucket.ExactMatch(state.LatestTimestamp) && StatusCode.IsGood(state.LatestStatus))
            {
                EarlyBound.RawPoint       = state.LatePoint == null ? state.EarlyPoint : state.LatePoint;
                EarlyBound.DerivationType = BoundingValueType.Raw;
            }
            else
            {
                if (EarlyBound.DerivationType != BoundingValueType.Raw)
                {
                    if (EarlyBound.EarlyPoint == null)
                    {
                        if ((state.EarlyPoint != null) && (state.EarlyPoint.SourceTimestamp < bucket.From))
                        {
                            EarlyBound.EarlyPoint = state.EarlyPoint;
                        }
                    }
                    if (EarlyBound.LatePoint == null)
                    {
                        if ((state.LatePoint != null) && (state.LatePoint.SourceTimestamp >= bucket.From))
                        {
                            EarlyBound.LatePoint = state.LatePoint;
                            if (SteppedVariable)
                            {
                                EarlyBound.CurrentBadPoints = new List <DataValue>();
                                foreach (DataValue dv in state.CurrentBadPoints)
                                {
                                    if (dv.SourceTimestamp < EarlyBound.Timestamp)
                                    {
                                        EarlyBound.CurrentBadPoints.Add(dv);
                                    }
                                }
                            }
                            else
                            {
                                EarlyBound.CurrentBadPoints = state.CurrentBadPoints;
                            }
                            EarlyBound.DerivationType = SteppedVariable ? BoundingValueType.SteppedInterpolation : BoundingValueType.SlopedInterpolation;
                        }
                    }
                }
                if (state.HasTerminated && (state.LatePoint == null))
                {
                    if (SteppedVariable)
                    {
                        EarlyBound.CurrentBadPoints = new List <DataValue>();
                        foreach (DataValue dv in state.CurrentBadPoints)
                        {
                            if (dv.SourceTimestamp < EarlyBound.Timestamp)
                            {
                                EarlyBound.CurrentBadPoints.Add(dv);
                            }
                        }
                    }
                    else
                    {
                        EarlyBound.CurrentBadPoints = state.CurrentBadPoints;
                    }
                }
            }

            if (bucket.EndMatch(state.LatestTimestamp) && StatusCode.IsGood(state.LatestStatus))
            {
                LateBound.RawPoint       = state.LatePoint == null ? state.EarlyPoint : state.LatePoint;
                LateBound.DerivationType = BoundingValueType.Raw;
            }
            else
            {
                if (LateBound.DerivationType != BoundingValueType.Raw)
                {
                    if ((state.EarlyPoint != null) && (state.EarlyPoint.SourceTimestamp < bucket.To))
                    {
                        LateBound.EarlyPoint = state.EarlyPoint;
                    }
                    if (LateBound.LatePoint == null)
                    {
                        if ((state.LatePoint != null) && (state.LatePoint.SourceTimestamp >= bucket.To))
                        {
                            LateBound.LatePoint = state.LatePoint;
                            if (SteppedVariable)
                            {
                                LateBound.CurrentBadPoints = new List <DataValue>();
                                foreach (DataValue dv in state.CurrentBadPoints)
                                {
                                    if (dv.SourceTimestamp < LateBound.Timestamp)
                                    {
                                        LateBound.CurrentBadPoints.Add(dv);
                                    }
                                }
                            }
                            else
                            {
                                LateBound.CurrentBadPoints = state.CurrentBadPoints;
                            }
                            LateBound.DerivationType = SteppedVariable ? BoundingValueType.SteppedInterpolation : BoundingValueType.SlopedInterpolation;
                        }
                    }
                }
                if (state.HasTerminated && (state.LatePoint == null))
                {
                    if (SteppedVariable)
                    {
                        LateBound.CurrentBadPoints = new List <DataValue>();
                        foreach (DataValue dv in state.CurrentBadPoints)
                        {
                            if (dv.SourceTimestamp < LateBound.Timestamp)
                            {
                                LateBound.CurrentBadPoints.Add(dv);
                            }
                        }
                    }
                    else
                    {
                        LateBound.CurrentBadPoints = state.CurrentBadPoints;
                    }
                }
                UpdatePriorPoint(LateBound, state);
            }
        }
コード例 #46
0
        /// <summary>
        /// Calculate the Minimum, Maximum, MinimumActualTime and MaximumActualTime aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeMinMax(TimeSlice slice, int valueType, bool returnActualTime)
        {
            // get the values in the slice.
            List <DataValue> values = GetValues(slice);

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return(GetNoDataValue(slice));
            }

            double minimumGoodValue      = Double.MaxValue;
            double minimumUncertainValue = Double.MaxValue;
            double maximumGoodValue      = Double.MinValue;
            double maximumUncertainValue = Double.MinValue;

            DateTime minimumGoodTimestamp = DateTime.MinValue;
            DateTime maximumGoodTimestamp = DateTime.MinValue;

            TypeInfo minimumOriginalType = null;
            TypeInfo maximumOriginalType = null;

            bool badValuesExist          = false;
            bool duplicatesMinimumsExist = false;
            bool duplicatesMaximumsExist = false;
            bool goodValueExists         = false;

            for (int ii = 0; ii < values.Count; ii++)
            {
                double     currentValue  = 0;
                DateTime   currentTime   = values[ii].SourceTimestamp;
                StatusCode currentStatus = values[ii].StatusCode;

                // ignore bad values.
                if (!IsGood(values[ii]))
                {
                    badValuesExist = true;
                    continue;
                }

                // convert to double.
                try
                {
                    currentValue = CastToDouble(values[ii]);
                }
                catch (Exception)
                {
                    badValuesExist = true;
                    continue;
                }

                // check for uncertain.
                if (StatusCode.IsUncertain(currentStatus))
                {
                    if (minimumUncertainValue > currentValue)
                    {
                        minimumUncertainValue = currentValue;
                    }

                    if (maximumUncertainValue < currentValue)
                    {
                        maximumUncertainValue = currentValue;
                    }

                    continue;
                }

                // check for new minimum.
                if (minimumGoodValue > currentValue)
                {
                    minimumGoodValue        = currentValue;
                    minimumGoodTimestamp    = currentTime;
                    minimumOriginalType     = values[ii].WrappedValue.TypeInfo;
                    duplicatesMinimumsExist = false;
                    goodValueExists         = true;
                }

                // check for duplicate minimums.
                else if (minimumGoodValue == currentValue)
                {
                    duplicatesMinimumsExist = true;
                }

                // check for new maximum.
                if (maximumGoodValue < currentValue)
                {
                    maximumGoodValue        = currentValue;
                    maximumGoodTimestamp    = currentTime;
                    maximumOriginalType     = values[ii].WrappedValue.TypeInfo;
                    duplicatesMaximumsExist = false;
                    goodValueExists         = true;
                }

                // check for duplicate maximums.
                else if (maximumGoodValue == currentValue)
                {
                    duplicatesMaximumsExist = true;
                }
            }

            // check if at least on good value exists.
            if (!goodValueExists)
            {
                return(GetNoDataValue(slice));
            }

            // set the status code.
            StatusCode statusCode = StatusCodes.Good;

            // uncertain if any bad values exist.
            if (badValuesExist)
            {
                statusCode = StatusCodes.UncertainDataSubNormal;
            }

            // determine the calculated value to return.
            object   processedValue       = null;
            TypeInfo processedType        = null;
            DateTime processedTimestamp   = DateTime.MinValue;
            bool     uncertainValueExists = false;
            bool     duplicatesExist      = false;

            if (valueType == 1)
            {
                processedValue       = minimumGoodValue;
                processedTimestamp   = minimumGoodTimestamp;
                processedType        = minimumOriginalType;
                uncertainValueExists = minimumGoodValue > minimumUncertainValue;
                duplicatesExist      = duplicatesMinimumsExist;
            }

            else if (valueType == 2)
            {
                processedValue       = maximumGoodValue;
                processedTimestamp   = maximumGoodTimestamp;
                processedType        = maximumOriginalType;
                uncertainValueExists = maximumGoodValue < maximumUncertainValue;
                duplicatesExist      = duplicatesMaximumsExist;
            }

            else if (valueType == 3)
            {
                processedValue       = Math.Abs(maximumGoodValue - minimumGoodValue);
                processedType        = TypeInfo.Scalars.Double;
                uncertainValueExists = maximumGoodValue <maximumUncertainValue || minimumGoodValue> minimumUncertainValue;
            }

            // set calculated if not returning actual time and value is not at the start time.
            if (!returnActualTime && processedTimestamp != slice.StartTime)
            {
                statusCode = statusCode.SetAggregateBits(AggregateBits.Calculated);
            }

            // set the multiple values flags.
            if (duplicatesExist)
            {
                statusCode = statusCode.SetAggregateBits(statusCode.AggregateBits | AggregateBits.MultipleValues);
            }

            // convert back to original datatype.
            if (processedType != null && processedType.BuiltInType != BuiltInType.Double)
            {
                processedValue = TypeInfo.Cast(processedValue, TypeInfo.Scalars.Double, processedType.BuiltInType);
            }
            else
            {
                processedType = TypeInfo.Scalars.Double;
            }

            // create processed value.
            DataValue value = new DataValue();

            value.WrappedValue = new Variant(processedValue, processedType);
            value.StatusCode   = statusCode;

            if (returnActualTime)
            {
                value.SourceTimestamp = processedTimestamp;
                value.ServerTimestamp = processedTimestamp;
            }
            else
            {
                value.SourceTimestamp = GetTimestamp(slice);
                value.ServerTimestamp = GetTimestamp(slice);
            }

            return(value);
        }
コード例 #47
0
        /// <summary>
        /// Calculates the Delta aggregate for the timeslice.
        /// </summary>
        protected DataValue ComputeDelta(TimeSlice slice)
        {
            // get the values in the slice.
            List<DataValue> values = GetValues(slice);

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return GetNoDataValue(slice);
            }

            // find start value.
            DataValue start = null;
            double startValue = 0;
            TypeInfo originalType = null;
            bool badDataSkipped = false;

            for (int ii = 0; ii < values.Count; ii++)
            {
                start = values[ii];

                if (StatusCode.IsGood(start.StatusCode))
                {
                    try
                    {
                        startValue = CastToDouble(start);
                        originalType = start.WrappedValue.TypeInfo;
                        break;
                    }
                    catch (Exception)
                    {
                        startValue = Double.NaN;
                    }
                }

                start = null;
                badDataSkipped = true;
            }

            // find end value.
            DataValue end = null;
            double endValue = 0;

            for (int ii = values.Count - 1; ii >= 0; ii--)
            {
                end = values[ii];

                if (StatusCode.IsGood(end.StatusCode))
                {
                    try
                    {
                        endValue = CastToDouble(end);
                        break;
                    }
                    catch (Exception)
                    {
                        endValue = Double.NaN;
                    }

                    break;
                }

                end = null;
                badDataSkipped = true;
            }

            // check if no good data.
            if (Double.IsNaN(startValue) || Double.IsNaN(endValue))
            {
                return GetNoDataValue(slice);
            }
            
            DataValue value = new DataValue();
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);

            // set status code.
            if (badDataSkipped)
            {
                value.StatusCode = StatusCodes.UncertainDataSubNormal;
            }
            
            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);
            
            // calculate delta.
            double delta = endValue - startValue;

            if (originalType != null && originalType.BuiltInType != BuiltInType.Double)
            {
                object delta2 = TypeInfo.Cast(delta, TypeInfo.Scalars.Double, originalType.BuiltInType);
                value.WrappedValue = new Variant(delta2, originalType);
            }
            else
            {
                value.WrappedValue = new Variant(delta, TypeInfo.Scalars.Double);
            }

            // return result.
            return value;
        }
コード例 #48
0
        protected override StatusCode ComputeStatus(IAggregationContext context, int numGood, int numBad, TimeSlice bucket)
        {
            StatusCode code = (bucket.EarlyBound.Value == null && numGood + numBad == 0) ? // no inital bound, do not extrapolate
                              StatusCodes.BadNoData : base.ComputeStatus(context, numGood, numBad, bucket);

            return(code);
        }
コード例 #49
0
        /// <summary>
        /// Calculates the Delta2 aggregate for the timeslice.
        /// </summary>
        protected DataValue ComputeDelta2(TimeSlice slice)
        {
            // get the values in the slice.
            List<DataValue> values = GetValuesWithSimpleBounds(slice);

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return GetNoDataValue(slice);
            }

            DataValue start = values[0];
            DataValue end = values[values.Count-1];

            // check for bad bounds.
            if (StatusCode.IsBad(start.StatusCode) || StatusCode.IsBad(end.StatusCode))
            {
                return GetNoDataValue(slice);
            }

            // convert to doubles.
            double startValue = 0;
            TypeInfo originalType = null;

            try
            {
                startValue = CastToDouble(start);
                originalType = start.WrappedValue.TypeInfo;
            }
            catch (Exception)
            {
                startValue = Double.NaN;
            }

            double endValue = 0;

            try
            {
                endValue = CastToDouble(end);
            }
            catch (Exception)
            {
                endValue = Double.NaN;
            }

            // check for bad bounds.
            if (Double.IsNaN(startValue) || Double.IsNaN(endValue))
            {
                return GetNoDataValue(slice);
            }

            DataValue value = new DataValue();
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);

            if (StatusCode.IsNotGood(start.StatusCode) || StatusCode.IsNotGood(end.StatusCode))
            {
                value.StatusCode = StatusCodes.UncertainDataSubNormal;
            }

            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);

            // calculate delta.
            double delta = endValue - startValue;

            if (originalType != null && originalType.BuiltInType != BuiltInType.Double)
            {
                object delta2 = TypeInfo.Cast(delta, TypeInfo.Scalars.Double, originalType.BuiltInType);
                value.WrappedValue = new Variant(delta2, originalType);
            }
            else
            {
                value.WrappedValue = new Variant(delta, TypeInfo.Scalars.Double);
            }

            // return result.
            return value;
        }
コード例 #50
0
        /// <summary>
        /// Calculate the Minimum2, Maximum2, MinimumActualTime2, MaximumActualTime2 and Range2 aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeMinMax2(TimeSlice slice, int valueType, bool returnActualTime)
        {
            // get the values in the slice.
            List <DataValue> values = GetValuesWithSimpleBounds(slice);

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return(GetNoDataValue(slice));
            }

            double minimumGoodValue = Double.MaxValue;
            double maximumGoodValue = Double.MinValue;

            DateTime minimumGoodTimestamp = DateTime.MinValue;
            DateTime maximumGoodTimestamp = DateTime.MinValue;

            StatusCode minimumGoodStatusCode = StatusCodes.Good;
            StatusCode maximumGoodStatusCode = StatusCodes.Good;

            TypeInfo minimumOriginalType = null;
            TypeInfo maximumOriginalType = null;

            bool duplicatesMinimumsExist = false;
            bool duplicatesMaximumsExist = false;
            bool goodValueExists         = false;

            for (int ii = 0; ii < values.Count; ii++)
            {
                double     currentValue  = 0;
                DateTime   currentTime   = values[ii].SourceTimestamp;
                StatusCode currentStatus = values[ii].StatusCode;

                // ignore bad values (as determined by the TreatUncertainAsBad parameter).
                if (!IsGood(values[ii]))
                {
                    continue;
                }

                // convert to double.
                try
                {
                    currentValue = CastToDouble(values[ii]);
                }
                catch (Exception)
                {
                    continue;
                }

                // skip endpoint if stepped.
                if (currentTime == slice.EndTime)
                {
                    if (Stepped)
                    {
                        break;
                    }
                }

                // check for new minimum.
                if (minimumGoodValue > currentValue)
                {
                    minimumGoodValue        = currentValue;
                    minimumGoodTimestamp    = currentTime;
                    minimumGoodStatusCode   = currentStatus;
                    minimumOriginalType     = values[ii].WrappedValue.TypeInfo;
                    duplicatesMinimumsExist = false;
                    goodValueExists         = true;
                }

                // check for duplicate minimums.
                else if (minimumGoodValue == currentValue)
                {
                    duplicatesMinimumsExist = true;
                }

                // check for new maximum.
                if (maximumGoodValue < currentValue)
                {
                    maximumGoodValue        = currentValue;
                    maximumGoodTimestamp    = currentTime;
                    maximumGoodStatusCode   = currentStatus;
                    maximumOriginalType     = values[ii].WrappedValue.TypeInfo;
                    duplicatesMaximumsExist = false;
                    goodValueExists         = true;
                }

                // check for duplicate maximums.
                else if (maximumGoodValue == currentValue)
                {
                    duplicatesMaximumsExist = true;
                }
            }

            // check if at least on good value exists.
            if (!goodValueExists)
            {
                return(GetNoDataValue(slice));
            }

            // determine the calculated value to return.
            object     processedValue      = null;
            TypeInfo   processedType       = null;
            DateTime   processedTimestamp  = DateTime.MinValue;
            StatusCode processedStatusCode = StatusCodes.Good;
            bool       duplicatesExist     = false;

            if (valueType == 1)
            {
                processedValue      = minimumGoodValue;
                processedTimestamp  = minimumGoodTimestamp;
                processedStatusCode = minimumGoodStatusCode;
                processedType       = minimumOriginalType;
                duplicatesExist     = duplicatesMinimumsExist;
            }

            else if (valueType == 2)
            {
                processedValue      = maximumGoodValue;
                processedTimestamp  = maximumGoodTimestamp;
                processedStatusCode = maximumGoodStatusCode;
                processedType       = maximumOriginalType;
                duplicatesExist     = duplicatesMaximumsExist;
            }

            else if (valueType == 3)
            {
                processedValue = Math.Abs(maximumGoodValue - minimumGoodValue);
                processedType  = TypeInfo.Scalars.Double;
            }

            // set the status code.
            StatusCode statusCode = processedStatusCode;

            // set calculated if not returning actual time and value is not at the start time.
            if (!returnActualTime && processedTimestamp != slice.StartTime && (statusCode.AggregateBits & AggregateBits.Interpolated) == 0)
            {
                statusCode = statusCode.SetAggregateBits(statusCode.AggregateBits | AggregateBits.Calculated);
            }

            // set the multiple values flags.
            if (duplicatesExist)
            {
                statusCode = statusCode.SetAggregateBits(statusCode.AggregateBits | AggregateBits.MultipleValues);
            }

            // convert back to original datatype.
            if (processedType != null && processedType.BuiltInType != BuiltInType.Double)
            {
                processedValue = TypeInfo.Cast(processedValue, TypeInfo.Scalars.Double, processedType.BuiltInType);
            }
            else
            {
                processedType = TypeInfo.Scalars.Double;
            }

            // create processed value.
            DataValue value = new DataValue();

            value.WrappedValue = new Variant(processedValue, processedType);
            value.StatusCode   = GetTimeBasedStatusCode(slice, values, statusCode);

            // zero value if status is bad.
            if (StatusCode.IsBad(value.StatusCode))
            {
                value.WrappedValue = Variant.Null;
            }

            if (returnActualTime)
            {
                // calculate effective time if end bound is used.
                if (TimeFlowsBackward)
                {
                    if (processedTimestamp == slice.StartTime)
                    {
                        processedTimestamp = processedTimestamp.AddMilliseconds(+1);
                        value.StatusCode   = value.StatusCode.SetAggregateBits(value.StatusCode.AggregateBits | AggregateBits.Interpolated);
                    }
                }
                else
                {
                    if (processedTimestamp == slice.EndTime)
                    {
                        processedTimestamp = processedTimestamp.AddMilliseconds(-1);
                        value.StatusCode   = value.StatusCode.SetAggregateBits(value.StatusCode.AggregateBits | AggregateBits.Interpolated);
                    }
                }

                value.SourceTimestamp = processedTimestamp;
                value.ServerTimestamp = processedTimestamp;
            }
            else
            {
                value.SourceTimestamp = GetTimestamp(slice);
                value.ServerTimestamp = GetTimestamp(slice);
            }

            return(value);
        }
コード例 #51
0
        /// <summary>
        /// Calculates the RegSlope, RegConst and RegStdDev aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeAverage(TimeSlice slice)
        {
            // get the values in the slice.
            List<DataValue> values = GetValues(slice);

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return GetNoDataValue(slice);
            }

            // calculate total and count.
            int count = 0;
            double total = 0;

            for (int ii = 0; ii < values.Count; ii++)
            {
                if (StatusCode.IsGood(values[ii].StatusCode))
                {
                    try
                    {
                        double sample = CastToDouble(values[ii]);
                        total += sample;
                        count++;
                    }
                    catch
                    {
                        // ignore conversion errors.
                    }
                }
            }

            // check for empty slice.
            if (count == 0)
            {
                return GetNoDataValue(slice);
            }

            // select the result.
            double result = total/count;

            // set the timestamp and status.
            DataValue value = new DataValue();
            value.WrappedValue = new Variant(result, TypeInfo.Scalars.Double);
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);
            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);
            value.StatusCode = GetValueBasedStatusCode(slice, values, value.StatusCode);

            // return result.
            return value;
        }
コード例 #52
0
        /// <summary>
        /// Calculates the StdDev, Variance, StdDev2 and Variance2 aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeTimeAverage(TimeSlice slice, bool useSimpleBounds, int valueType)
        {
            // get the values in the slice.
            List <DataValue> values = null;

            if (useSimpleBounds)
            {
                values = GetValuesWithSimpleBounds(slice);
            }
            else
            {
                values = GetValuesWithInterpolatedBounds(slice);
            }

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return(GetNoDataValue(slice));
            }

            // get the regions.
            List <SubRegion> regions = GetRegionsInValueSet(values, !useSimpleBounds, Stepped);

            double total                = 0;
            double totalDuration        = 0;
            bool   nonGoodRegionsExists = false;

            for (int ii = 0; ii < regions.Count; ii++)
            {
                double duration = regions[ii].Duration / 1000.0;

                if (StatusCode.IsNotBad(regions[ii].StatusCode))
                {
                    total         += (regions[ii].StartValue + regions[ii].EndValue) * duration / 2;
                    totalDuration += duration;
                }

                if (StatusCode.IsNotGood(regions[ii].StatusCode))
                {
                    nonGoodRegionsExists = true;
                }
            }

            // check if no good data.
            if (totalDuration == 0)
            {
                return(GetNoDataValue(slice));
            }

            // select the result.
            double result = 0;

            switch (valueType)
            {
            case 1: { result = total / totalDuration; break; }

            case 2: { result = total; break; }
            }

            // set the timestamp and status.
            DataValue value = new DataValue();

            value.WrappedValue    = new Variant(result, TypeInfo.Scalars.Double);
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);

            if (useSimpleBounds)
            {
                value.StatusCode = GetTimeBasedStatusCode(regions, value.StatusCode);
            }
            else
            {
                value.StatusCode = StatusCodes.Good;

                if (nonGoodRegionsExists)
                {
                    value.StatusCode = StatusCodes.UncertainDataSubNormal;
                }
            }

            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);

            // return result.
            return(value);
        }
        /// <summary>
        /// Calculates the RegSlope, RegConst and RegStdDev aggregates for the timeslice.
        /// </summary>
        protected DataValue ComputeRegression(TimeSlice slice, int valueType)
        {
            // get the values in the slice.
            List <DataValue> values = GetValuesWithSimpleBounds(slice);

            // check for empty slice.
            if (values == null || values.Count == 0)
            {
                return(GetNoDataValue(slice));
            }

            // get the regions.
            List <SubRegion> regions = GetRegionsInValueSet(values, false, true);

            List <double> xData = new List <double>();
            List <double> yData = new List <double>();

            double duration          = 0;
            bool   nonGoodDataExists = false;

            for (int ii = 0; ii < regions.Count; ii++)
            {
                if (StatusCode.IsGood(regions[ii].StatusCode))
                {
                    xData.Add(regions[ii].StartValue);
                    yData.Add(duration);
                }
                else
                {
                    nonGoodDataExists = true;
                }

                // normalize to seconds.
                duration += regions[ii].Duration / 1000.0;
            }

            // check if no good data.
            if (xData.Count == 0)
            {
                return(GetNoDataValue(slice));
            }

            // compute the regression parameters.
            double regSlope  = 0;
            double regConst  = 0;
            double regStdDev = 0;

            if (xData.Count > 1)
            {
                double xAvg  = 0;
                double yAvg  = 0;
                double xxAgv = 0;
                double xyAvg = 0;

                for (int ii = 0; ii < xData.Count; ii++)
                {
                    xAvg  += xData[ii];
                    yAvg  += yData[ii];
                    xxAgv += xData[ii] * xData[ii];
                    xyAvg += xData[ii] * yData[ii];
                }

                xAvg  /= xData.Count;
                yAvg  /= xData.Count;
                xxAgv /= xData.Count;
                xyAvg /= xData.Count;

                regSlope = (xyAvg - xAvg * yAvg) / (xxAgv - xAvg * xAvg);
                regConst = yAvg - regSlope * xAvg;

                List <double> errors = new List <double>();

                double eAvg = 0;

                for (int ii = 0; ii < xData.Count; ii++)
                {
                    double error = yData[ii] - regConst - regSlope * xData[ii];
                    errors.Add(error);
                    eAvg += error;
                }

                eAvg /= errors.Count;

                double variance = 0;

                for (int ii = 0; ii < errors.Count; ii++)
                {
                    double error = errors[ii] - eAvg;
                    variance += error * error;
                }

                variance /= errors.Count;
                regStdDev = Math.Sqrt(variance);
            }

            // select the result.
            double result = 0;

            switch (valueType)
            {
            case 1: { result = regSlope;  break; }

            case 2: { result = regConst;  break; }

            case 3: { result = regStdDev; break; }
            }

            // set the timestamp and status.
            DataValue value = new DataValue();

            value.WrappedValue    = new Variant(result, TypeInfo.Scalars.Double);
            value.SourceTimestamp = GetTimestamp(slice);
            value.ServerTimestamp = GetTimestamp(slice);

            if (nonGoodDataExists)
            {
                value.StatusCode = StatusCodes.UncertainDataSubNormal;
            }

            value.StatusCode = value.StatusCode.SetAggregateBits(AggregateBits.Calculated);

            // return result.
            return(value);
        }
コード例 #54
0
 public override void UpdateBoundingValues(TimeSlice bucket, AggregateState state)
 {
     base.UpdateBoundingValues(bucket, state);
     UpdatePriorPoint(bucket.EarlyBound, state);
 }