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; }
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; }
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; }
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; }
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); }
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; }
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; }
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); }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
/// <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); }
/// <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); }
/// <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); }
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; }
/// <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)); }
public override void UpdateBoundingValues(TimeSlice bucket, AggregateState state) { }
/// <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; }
/// <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); }
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; } } }
/// <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); }
public abstract DataValue Compute(IAggregationContext context, TimeSlice bucket, AggregateState state);
/// <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; }
protected override StatusCode ComputeStatus(IAggregationContext context, int numGood, int numBad, TimeSlice bucket) { return(numBad + numGood == 0 ? StatusCodes.BadNoData : base.ComputeStatus(context, numGood, numBad, bucket)); }
/// <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); }
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); }
public abstract void UpdateBoundingValues(TimeSlice bucket, AggregateState state);
/// <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); }
public abstract bool WaitForMoreData(TimeSlice bucket, AggregateState state);
/// <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); }
/// <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); } }
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; } } }
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; }
/// <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]; } }
/// <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; }
/// <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; }
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); } }
/// <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); }
/// <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; }
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); }
/// <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; }
/// <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); }
/// <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; }
/// <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); }
public override void UpdateBoundingValues(TimeSlice bucket, AggregateState state) { base.UpdateBoundingValues(bucket, state); UpdatePriorPoint(bucket.EarlyBound, state); }