IndividualsDetector implements Detector { @Override public DetectorResult detect(MetricData metricData) { notNull(metricData, "metricData can't be null"); val params = getParams(); val trusted = isTrusted(); val observed = metricData.getValue(); val stdDev = sqrt(this.variance); val strongDelta = params.getStrongSigmas() * stdDev; val currentRange = Math.abs(prevValue - observed); val thresholds = new AnomalyThresholds( this.mean + strongDelta, this.mean + strongDelta, this.mean - strongDelta, this.mean - strongDelta); AnomalyLevel level; if (totalDataPoints > params.getWarmUpPeriod()) { level = NORMAL; if (currentRange > upperControlLimit_R) { level = STRONG; } else { if (observed > upperControlLimit_X || observed < lowerControlLimit_X) { level = WEAK; } } } else { level = MODEL_WARMUP; } if (level == NORMAL || level == MODEL_WARMUP) { this.movingRangeSum += abs(currentRange); this.mean = getRunningMean(observed); this.totalDataPoints++; } if (((totalDataPoints - params.getWarmUpPeriod()) % RECOMPUTE_LIMITS_PERIOD) == 0) { double averageMovingRange = getAverageMovingRange(); double multiplier = params.getStrongSigmas() / R_CONTROL_CHART_CONSTANT_D2; this.target = this.mean; upperControlLimit_R = R_CONTROL_CHART_CONSTANT_D4 * averageMovingRange; upperControlLimit_X = this.target + multiplier * averageMovingRange; lowerControlLimit_X = this.target - multiplier * averageMovingRange; } this.prevValue = observed; final OutlierDetectorResult result = new OutlierDetectorResult(level); result.setPredicted(this.mean); result.setThresholds(thresholds); result.setTrusted(trusted); return result; } IndividualsDetector(UUID uuid, IndividualsDetectorParams params, boolean trusted, String name); @Override DetectorResult detect(MetricData metricData); @Override String getName();  }
@Test public void testEvaluate() { val testRows = data.listIterator(); val testRow0 = testRows.next(); val observed0 = testRow0.getObserved(); val params = buildParams(observed0); val detector = buildDetector(params); assertEquals(detectorUuid, detector.getUuid()); assertEquals(trusted, detector.isTrusted()); assertSame(params, detector.getParams()); int noOfDataPoints = 1; while (testRows.hasNext()) { val testRow = testRows.next(); val observed = testRow.getObserved(); val metricData = new MetricData(metricDef, observed, epochSecond); val result = (OutlierDetectorResult) detector.detect(metricData); val level = result.getAnomalyLevel(); if (noOfDataPoints < WARMUP_PERIOD) { TestCase.assertEquals(AnomalyLevel.MODEL_WARMUP, level); } else { assertEquals(testRow.getUpperControlLimit_R(), detector.getUpperControlLimit_R(), TOLERANCE); assertEquals(testRow.getLowerControlLimit_X(), detector.getLowerControlLimit_X(), TOLERANCE); assertEquals(testRow.getUpperControlLimit_X(), detector.getUpperControlLimit_X(), TOLERANCE); assertEquals(AnomalyLevel.valueOf(testRow.getAnomalyLevel()), level); } noOfDataPoints += 1; } }