docs: public OutlierResult run(Database database, Relation<O> relation) {
      StepProgress stepprog = LOG.isVerbose() ? new StepProgress(5) : null;
  
      Pair<KNNQuery<O>, KNNQuery<O>> pair = getKNNQueries(database, relation, stepprog);
      KNNQuery<O> knnComp = pair.getFirst();
      KNNQuery<O> knnReach = pair.getSecond();
  
      // Assert we got something
      if(knnComp == null) {
        throw new AbortException("No kNN queries supported by database for comparison distance function.");
      }
      if(knnReach == null) {
        throw new AbortException("No kNN queries supported by database for density estimation distance function.");
      }
  
      // FIXME: tie handling!
  
      // Probabilistic distances
      WritableDoubleDataStore pdists = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_DB);
      LOG.beginStep(stepprog, 3, "Computing pdists");
      computePDists(relation, knnReach, pdists);
      // Compute PLOF values.
      WritableDoubleDataStore plofs = DataStoreUtil.makeDoubleStorage(relation.getDBIDs(), DataStoreFactory.HINT_HOT | DataStoreFactory.HINT_TEMP);
      LOG.beginStep(stepprog, 4, "Computing PLOF");
      double nplof = computePLOFs(relation, knnComp, pdists, plofs);
  
      // Normalize the outlier scores.
      DoubleMinMax mm = new DoubleMinMax();
      {// compute LOOP_SCORE of each db object
        LOG.beginStep(stepprog, 5, "Computing LoOP scores");
  
        FiniteProgress progressLOOPs = LOG.isVerbose() ? new FiniteProgress("LoOP for objects", relation.size(), LOG) : null;
        final double norm = 1. / (nplof * MathUtil.SQRT2);
        for(DBIDIter iditer = relation.iterDBIDs(); iditer.valid(); iditer.advance()) {
          double loop = NormalDistribution.erf((plofs.doubleValue(iditer) - 1.) * norm);
          plofs.putDouble(iditer, loop);
          mm.put(loop);
          LOG.incrementProcessed(progressLOOPs);
        }
        LOG.ensureCompleted(progressLOOPs);
      }
  
      LOG.setCompleted(stepprog);
  
      // Build result representation.
      DoubleRelation scoreResult = new MaterializedDoubleRelation("Local Outlier Probabilities", "loop-outlier", plofs, relation.getDBIDs());
      OutlierScoreMeta scoreMeta = new ProbabilisticOutlierScore(mm.getMin(), mm.getMax(), 0.);
      return new OutlierResult(scoreMeta, scoreResult);
    }