changeset 9348:a3f318347707

Show wq outliers within same thems with different symbol: not ready yet
author gernotbelger
date Tue, 31 Jul 2018 11:25:38 +0200
parents c08003a68478
children a8ef20ee60bd
files artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/Fitting.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixAnalysisCalculation.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixAnalysisResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixOutlierFacet.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixRealizingResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixReferenceEventsFacet.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/QWD.java artifacts/src/main/java/org/dive4elements/river/artifacts/services/QWSeriesCollection.java artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java artifacts/src/main/java/org/dive4elements/river/exports/process/FixWQProcessor.java
diffstat 11 files changed, 203 insertions(+), 224 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/Fitting.java	Mon Jul 30 16:43:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/Fitting.java	Tue Jul 31 11:25:38 2018 +0200
@@ -22,54 +22,33 @@
 import org.dive4elements.river.artifacts.math.GrubbsOutlier;
 import org.dive4elements.river.artifacts.math.fitting.Function;
 
-public class Fitting
-{
+public class Fitting {
     private static Logger log = Logger.getLogger(Fitting.class);
 
     /** Use instance of this factory to find meta infos for outliers. */
     public interface QWDFactory {
-
-        QWD create(double q, double w);
-
-    } // interface QWFactory
-
-    public static final QWDFactory QWD_FACTORY = new QWDFactory() {
-        @Override
-        public QWD create(double q, double w) {
-            return new QWD(q, w);
-        }
-    };
-
-    protected boolean        checkOutliers;
-    protected Function       function;
-    protected QWDFactory     qwdFactory;
-    protected double         chiSqr;
-    protected double []      parameters;
-    protected ArrayList<QWI> removed;
-    protected QWD []         referenced;
-    protected double         standardDeviation;
-
-
-    public Fitting() {
-        removed = new ArrayList<QWI>();
+        QWD create(double q, double w, boolean isOutlier);
     }
 
-    public Fitting(Function function) {
-        this(function, QWD_FACTORY);
-    }
-
-    public Fitting(Function function, QWDFactory qwdFactory) {
-        this(function, qwdFactory, false);
-    }
+    private final boolean checkOutliers;
+    
+    private final Function function;
+    
+    private final QWDFactory qwdFactory;
+    
+    private double chiSqr;
+    
+    private double[] parameters;
+    
+    private final List<QWD> removed = new ArrayList<>();
+    
+    private QWD[] referenced;
+    
+    private double standardDeviation;
 
-    public Fitting(
-        Function   function,
-        QWDFactory qwdFactory,
-        boolean    checkOutliers
-    ) {
-        this();
-        this.function      = function;
-        this.qwdFactory    = qwdFactory;
+    public Fitting(Function function, QWDFactory qwdFactory, boolean checkOutliers) {
+        this.function = function;
+        this.qwdFactory = qwdFactory;
         this.checkOutliers = checkOutliers;
     }
 
@@ -77,24 +56,16 @@
         return function;
     }
 
-    public void setFunction(Function function) {
-        this.function = function;
-    }
-
     public boolean getCheckOutliers() {
         return checkOutliers;
     }
 
-    public void setCheckOutliers(boolean checkOutliers) {
-        this.checkOutliers = checkOutliers;
-    }
-
     public double getChiSquare() {
         return chiSqr;
     }
 
     public void reset() {
-        chiSqr     = 0.0;
+        chiSqr = 0.0;
         parameters = null;
         removed.clear();
         referenced = null;
@@ -105,22 +76,18 @@
         return !removed.isEmpty();
     }
 
-    public List<QWI> getOutliers() {
-        return removed;
+    public QWD[] outliersToArray() {
+        return removed.toArray(new QWD[removed.size()]);
     }
 
-    public QWI [] outliersToArray() {
-        return removed.toArray(new QWI[removed.size()]);
-    }
-
-    public QWD [] referencedToArray() {
-        return referenced != null ? (QWD [])referenced.clone() : null;
+    public QWD[] referencedToArray() {
+        return referenced != null ? (QWD[]) referenced.clone() : null;
     }
 
     public double getMaxQ() {
         double maxQ = -Double.MAX_VALUE;
         if (referenced != null) {
-            for (QWI qw: referenced) {
+            for (QWI qw : referenced) {
                 double q = qw.getQ();
                 if (q > maxQ) {
                     maxQ = q;
@@ -130,7 +97,7 @@
         return maxQ;
     }
 
-    public double [] getParameters() {
+    public double[] getParameters() {
         return parameters;
     }
 
@@ -138,7 +105,7 @@
         return standardDeviation;
     }
 
-    public boolean fit(double [] qs, double [] ws) {
+    public boolean fit(double[] qs, double[] ws) {
 
         TDoubleArrayList xs = new TDoubleArrayList(qs.length);
         TDoubleArrayList ys = new TDoubleArrayList(ws.length);
@@ -188,10 +155,11 @@
             }
             if (parameters == null) {
                 /*
-                log.debug("Parameters is null");
-                for (int i = 0, N = xs.size(); i < N; ++i) {
-                    log.debug("DATA: " + xs.getQuick(i) + " " + ys.getQuick(i));
-                }*/
+                 * log.debug("Parameters is null");
+                 * for (int i = 0, N = xs.size(); i < N; ++i) {
+                 * log.debug("DATA: " + xs.getQuick(i) + " " + ys.getQuick(i));
+                 * }
+                 */
                 return false;
             }
 
@@ -219,9 +187,7 @@
             }
 
             int idx = outlier.intValue();
-            removed.add(
-                qwdFactory.create(
-                    xs.getQuick(idx), ys.getQuick(idx)));
+            removed.add(qwdFactory.create(xs.getQuick(idx), ys.getQuick(idx), true));
             xs.remove(idx);
             ys.remove(idx);
         }
@@ -230,14 +196,13 @@
 
         referenced = new QWD[xs.size()];
         for (int i = 0; i < referenced.length; ++i) {
-            QWD qwd = qwdFactory.create(xs.getQuick(i), ys.getQuick(i));
+            QWD qwd = qwdFactory.create(xs.getQuick(i), ys.getQuick(i), false);
 
             if (qwd == null) {
                 log.warn("QW creation failed!");
-            }
-            else {
+            } else {
                 referenced[i] = qwd;
-                double dw = (qwd.getW() - instance.value(qwd.getQ()))*100.0;
+                double dw = (qwd.getW() - instance.value(qwd.getQ())) * 100.0;
                 qwd.setDeltaW(dw);
                 stdDev.increment(dw);
             }
@@ -249,5 +214,4 @@
 
         return true;
     }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixAnalysisCalculation.java	Mon Jul 30 16:43:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixAnalysisCalculation.java	Tue Jul 31 11:25:38 2018 +0200
@@ -253,7 +253,8 @@
                             q, w,
                             description,
                             date, interpolated,
-                            dw, getIndex(col2index, column.getIndex()));
+                            dw, getIndex(col2index, column.getIndex()),
+                            false);
 
                         qwds.add(qwd);
 
@@ -279,7 +280,7 @@
 
                             QWD avgQWD = new QWD(
                                 avgQ, avgW, avgDescription,
-                                avgDate, true, avgDw, 0);
+                                avgDate, true, avgDw, 0, false);
 
                             qSectorAverages[qSector] = avgQWD;
                         }
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixAnalysisResult.java	Mon Jul 30 16:43:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixAnalysisResult.java	Tue Jul 31 11:25:38 2018 +0200
@@ -34,7 +34,7 @@
     public FixAnalysisResult(
         Parameters                 parameters,
         KMIndex<QWD []>            referenced,
-        KMIndex<QWI []>            outliers,
+        KMIndex<QWD []>            outliers,
         KMIndex<AnalysisPeriod []> analysisPeriods
     ) {
         super(parameters, referenced, outliers);
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixOutlierFacet.java	Mon Jul 30 16:43:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixOutlierFacet.java	Tue Jul 31 11:25:38 2018 +0200
@@ -71,8 +71,8 @@
             FixResult result = (FixResult) res.getData();
             double currentKm = getCurrentKm(context);
 
-            KMIndex<QWI []>       kmQWs    = result.getOutliers();
-            KMIndex.Entry<QWI []> qwsEntry = kmQWs.binarySearch(currentKm);
+            KMIndex<QWD []>       kmQWs    = result.getOutliers();
+            KMIndex.Entry<QWD []> qwsEntry = kmQWs.binarySearch(currentKm);
 
             QWI [] qws = null;
             if (qwsEntry != null) {
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixRealizingResult.java	Mon Jul 30 16:43:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixRealizingResult.java	Tue Jul 31 11:25:38 2018 +0200
@@ -28,7 +28,7 @@
     public FixRealizingResult(
         Parameters      parameters,
         KMIndex<QWD []> referenced,
-        KMIndex<QWI []> outliers,
+        KMIndex<QWD []> outliers,
         WQKms []        wqkms
     ) {
         super(parameters, referenced, outliers);
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixReferenceEventsFacet.java	Mon Jul 30 16:43:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixReferenceEventsFacet.java	Tue Jul 31 11:25:38 2018 +0200
@@ -9,7 +9,6 @@
 package org.dive4elements.river.artifacts.model.fixings;
 
 import org.apache.log4j.Logger;
-
 import org.dive4elements.artifacts.Artifact;
 import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.river.artifacts.D4EArtifact;
@@ -18,15 +17,12 @@
 import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
 import org.dive4elements.river.utils.KMIndex;
 
-
 /**
  * Facet to show W values for Q values at km for a date.
  *
  * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
  */
-public class FixReferenceEventsFacet
-extends      FixingsFacet
-implements   FacetTypes {
+public class FixReferenceEventsFacet extends FixingsFacet implements FacetTypes {
 
     /** House log. */
     private static Logger log = Logger.getLogger(FixReferenceEventsFacet.class);
@@ -35,30 +31,22 @@
     public FixReferenceEventsFacet() {
     }
 
-
-    /**
-     * @param name
-     */
-    public FixReferenceEventsFacet(int index, String name, String description) {
-        super(index,
-             name,
-             description,
-             ComputeType.ADVANCE,
-             null,
-             null);
+    public FixReferenceEventsFacet(final int index, final String name, final String description) {
+        super(index, name, description, ComputeType.ADVANCE, null, null);
     }
 
-
     /**
      * Returns the data this facet requires.
      *
-     * @param artifact the owner artifact.
-     * @param context  the CallContext (ignored).
+     * @param artifact
+     *            the owner artifact.
+     * @param context
+     *            the CallContext (ignored).
      *
      * @return the data.
      */
     @Override
-    public Object getData(Artifact artifact, CallContext context) {
+    public Object getData(final Artifact artifact, final CallContext context) {
         log.debug("FixReferenceEventsFacet.getData");
 
         if (!(artifact instanceof D4EArtifact)) {
@@ -66,43 +54,56 @@
             return null;
         }
 
-        D4EArtifact flys = (D4EArtifact)artifact;
+        final D4EArtifact flys = (D4EArtifact) artifact;
 
-        CalculationResult res =
-            (CalculationResult) flys.compute(context,
-                                             ComputeType.ADVANCE,
-                                             false);
+        final CalculationResult res = (CalculationResult) flys.compute(context, ComputeType.ADVANCE, false);
 
-        FixResult result = (FixResult) res.getData();
-        double currentKm = getCurrentKm(context);
+        final FixResult result = (FixResult) res.getData();
+        final double currentKm = getCurrentKm(context);
 
         if (log.isDebugEnabled()) {
             log.debug("current km in FRE: " + currentKm);
         }
 
-        KMIndex<QWD []> kmQWs = result.getReferenced();
-        KMIndex.Entry<QWD []> kmQWsEntry = kmQWs.binarySearch(currentKm);
-        if (kmQWsEntry != null) {
-            int ndx = index & 255;
-            for (QWD qwd: kmQWsEntry.getValue()) {
-                if (qwd.getIndex() == ndx) {
-                    return qwd;
-                }
-            }
-        }
+        /* first search in referenced */
+        final KMIndex<QWD[]> referenced = result.getReferenced();
+        final QWD foundReferenced = find(referenced, currentKm);
+        if (foundReferenced != null)
+            return foundReferenced;
+
+        // FIXME
+//        /* also search in outliers, should be mutually exclusive, because outliers got removed from referenced */
+//        final KMIndex<QWD[]> outliers = result.getOutliers();
+//        final QWD foundOutlier = find(outliers, currentKm);
+//        if (foundOutlier != null)
+//            return foundOutlier;
+
         return null;
     }
 
+    private QWD find(final KMIndex<QWD[]> kmQWs, final double currentKm) {
+
+        final KMIndex.Entry<QWD[]> kmQWsEntry = kmQWs.binarySearch(currentKm);
+        if (kmQWsEntry != null) {
+            final int ndx = this.index & 255;
+            for (final QWD qwd : kmQWsEntry.getValue()) {
+                if (qwd.getIndex() == ndx)
+                    return qwd;
+            }
+        }
+
+        return null;
+    }
 
     /**
      * Create a deep copy of this Facet.
+     *
      * @return a deep copy.
      */
     @Override
     public FixReferenceEventsFacet deepCopy() {
-        FixReferenceEventsFacet copy = new FixReferenceEventsFacet();
+        final FixReferenceEventsFacet copy = new FixReferenceEventsFacet();
         copy.set(this);
         return copy;
     }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixResult.java	Mon Jul 30 16:43:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixResult.java	Tue Jul 31 11:25:38 2018 +0200
@@ -16,6 +16,7 @@
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.Date;
+import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
 
@@ -27,7 +28,7 @@
 
     protected Parameters      parameters;
     protected KMIndex<QWD []> referenced;
-    protected KMIndex<QWI []> outliers;
+    protected KMIndex<QWD []> outliers;
 
     public FixResult() {
     }
@@ -35,7 +36,7 @@
     public FixResult(
         Parameters      parameters,
         KMIndex<QWD []> referenced,
-        KMIndex<QWI []> outliers
+        KMIndex<QWD []> outliers
     ) {
         this.parameters = parameters;
         this.referenced = referenced;
@@ -51,52 +52,76 @@
     }
 
     public void makeReferenceEventsDatesUnique() {
-        DateUniqueMaker dum = new DateUniqueMaker();
+        final DateUniqueMaker dum = new DateUniqueMaker();
+        
         for (KMIndex.Entry<QWD []> entry: referenced) {
-            for (QWD ref: entry.getValue()) {
+            for (QWD ref: entry.getValue())
                 dum.makeUnique(ref);
-            }
         }
+
+        // FIXME
+//        for (KMIndex.Entry<QWD []> entry: outliers) {
+//            for (QWD ref: entry.getValue())
+//                dum.makeUnique(ref);
+//        }
     }
 
-    public Collection<Integer> getReferenceEventsIndices() {
-        TreeMap<Date, Integer> dates = new TreeMap<Date, Integer>();
+    private Collection<Integer> getReferenceEventsIndices() {
+        final TreeMap<Date, Integer> dates = new TreeMap<>();
+        
         for (KMIndex.Entry<QWD []> entry: referenced) {
-            for (QWD value: entry.getValue()) {
+            for (QWD value: entry.getValue())
                 dates.put(value.date, value.index);
-            }
         }
+// FIXME
+//        for (KMIndex.Entry<QWD []> entry: outliers) {
+//            for (QWD value: entry.getValue())
+//                dates.put(value.date, value.index);
+//        }
+        
         return dates.values();
     }
 
     public void remapReferenceIndicesToRank() {
-        RankRemapper remapper = new RankRemapper();
-        for (Integer idx: getReferenceEventsIndices()) {
+        final RankRemapper remapper = new RankRemapper();
+        for (Integer idx: getReferenceEventsIndices())
             remapper.toMap(idx);
+        
+        for (KMIndex.Entry<QWD []> entry: referenced) {
+            for (QWD value: entry.getValue())
+                remapper.remap(value);
         }
-        for (KMIndex.Entry<QWD []> entry: referenced) {
-            for (QWD value: entry.getValue()) {
-                remapper.remap(value);
-            }
-        }
+// FIXME
+//        for (KMIndex.Entry<QWD []> entry: outliers) {
+//            for (QWD value: entry.getValue())
+//                remapper.remap(value);
+//        }
     }
 
     public Collection<Date> getReferenceEventsDates() {
-        TreeSet<Date> dates = new TreeSet<Date>();
-        for (KMIndex.Entry<QWD []> entry: referenced) {
-            for (QWD qwd: entry.getValue()) {
+        
+        final Set<Date> dates = new TreeSet<>();
+        
+        for (final KMIndex.Entry<QWD []> entry: referenced) {
+            for (final QWD qwd: entry.getValue())
                 dates.add(qwd.date);
-            }
         }
+        
+        // FIXME, but not always...
+//        for (final KMIndex.Entry<QWD []> entry: outliers) {
+//            for (final QWD qwd: entry.getValue())
+//                dates.add(qwd.date);
+//        }
+        
         return dates;
     }
 
 
-    public KMIndex<QWI []> getOutliers() {
+    public KMIndex<QWD []> getOutliers() {
         return outliers;
     }
 
-    public void setOutliers(KMIndex<QWI []> outliers) {
+    public void setOutliers(KMIndex<QWD []> outliers) {
         this.outliers = outliers;
     }
 
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/QWD.java	Mon Jul 30 16:43:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/QWD.java	Tue Jul 31 11:25:38 2018 +0200
@@ -10,37 +10,44 @@
 
 import java.util.Date;
 
-public class QWD
-extends      QWI
-{
+public class QWD extends QWI {
+
+    private static final long serialVersionUID = 1L;
+
     protected double deltaW;
 
+    private boolean isOutlier;
+
     public QWD() {
     }
 
-    public QWD(double q, double w) {
+    public QWD(final double q, final double w, final boolean isOutlier) {
         super(q, w);
+
+        this.isOutlier = isOutlier;
     }
 
-    public QWD(
-        double  q,
-        double  w,
-        String  description,
-        Date    date,
-        boolean interpolated,
-        double  deltaW,
-        int     index
-    ) {
+    public QWD(final double q, final double w, final String description, final Date date, final boolean interpolated, final double deltaW, final int index,
+            final boolean isOutlier) {
         super(q, w, description, date, interpolated, index);
+
+        this.deltaW = deltaW;
+        this.isOutlier = isOutlier;
+    }
+
+    public double getDeltaW() {
+        return this.deltaW;
+    }
+
+    public void setDeltaW(final double deltaW) {
         this.deltaW = deltaW;
     }
 
-    public double getDeltaW() {
-        return deltaW;
+    public boolean isOutlier() {
+        return this.isOutlier;
     }
 
-    public void setDeltaW(double deltaW) {
-        this.deltaW = deltaW;
+    public void setOutlier(final boolean isOutlier) {
+        this.isOutlier = isOutlier;
     }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/services/QWSeriesCollection.java	Mon Jul 30 16:43:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/services/QWSeriesCollection.java	Tue Jul 31 11:25:38 2018 +0200
@@ -9,8 +9,7 @@
 package org.dive4elements.river.artifacts.services;
 
 import org.dive4elements.river.artifacts.model.fixings.QWI;
-
-import org.dive4elements.river.java2d.ShapeUtils;
+import org.dive4elements.river.exports.fixings.FixWQCurveGenerator;
 
 import org.dive4elements.river.jfree.ShapeRenderer;
 
@@ -86,10 +85,10 @@
     protected LabelGenerator labelGenerator;
 
     protected Map<ShapeRenderer.Entry, Integer> knownShapes =
-        new HashMap<ShapeRenderer.Entry, Integer>();
+        new HashMap<>();
 
     public QWSeriesCollection() {
-        labels = new ArrayList<List<QWI>>();
+        labels = new ArrayList<>();
         labelGenerator = SIMPLE_GENERATOR;
     }
 
@@ -98,17 +97,14 @@
         this.labelGenerator = labelGenerator;
     }
 
-    protected static ShapeRenderer.Entry classify(QWI qw) {
-        boolean interpolated = qw.getInterpolated();
+    private static ShapeRenderer.Entry classify(QWI qw) {
 
-        Shape shape = interpolated
-            ? ShapeUtils.INTERPOLATED_SHAPE
-            : ShapeUtils.MEASURED_SHAPE;
+        final boolean interpolated = qw.getInterpolated();
 
-        boolean filled = !interpolated;
-        Color color = Color.blue;
+        final Shape shape = FixWQCurveGenerator.getWQDShape(qw);
 
-        return new ShapeRenderer.Entry(shape, color, filled);
+        final boolean filled = !interpolated;
+        return new ShapeRenderer.Entry(shape, Color.blue, filled);
     }
 
     public void add(QWI qw) {
--- a/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java	Mon Jul 30 16:43:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java	Tue Jul 31 11:25:38 2018 +0200
@@ -10,6 +10,7 @@
 
 import java.awt.BasicStroke;
 import java.awt.Color;
+import java.awt.Shape;
 import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.List;
@@ -324,32 +325,23 @@
 
         final ThemeDocument theme = configureThemeInterpolated(doc, qwd);
 
-        XYSeries series = new StyledXYSeries(
-            aaf.getFacetDescription(),
-            theme,
-            qwd.getInterpolated()
-                ? ShapeUtils.INTERPOLATED_SHAPE
-                : ShapeUtils.MEASURED_SHAPE);
-
+        final XYSeries series = new StyledXYSeries( aaf.getFacetDescription(), theme, getWQDShape(qwd));
         series.add(qwd.getQ(), w);
 
         addAxisSeries(series, atGauge ? YAXIS.WCm.idx : YAXIS.W.idx, visible);
 
         if (visible && theme.parseShowPointLabel()) {
 
-            List<XYTextAnnotation> textAnnos =
-                new ArrayList<XYTextAnnotation>();
+            List<XYTextAnnotation> textAnnos = new ArrayList<>();
 
-            DateFormat dateFormat = DateFormat.getDateInstance(
-                DateFormat.SHORT);
+            DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
             XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
                 dateFormat.format(qwd.getDate()),
                 qwd.getQ(),
                 w);
             textAnnos.add(anno);
 
-            RiverAnnotation flysAnno =
-                new RiverAnnotation(null, null, null, theme);
+            RiverAnnotation flysAnno = new RiverAnnotation(null, null, null, theme);
             flysAnno.setTextAnnotations(textAnnos);
             addAnnotations(flysAnno);
         }
@@ -375,10 +367,7 @@
 
         XYSeries series = new StyledXYSeries(
             aaf.getFacetDescription(),
-            false, true, theme,
-            qwd.getInterpolated()
-                ? ShapeUtils.INTERPOLATED_SHAPE
-                : ShapeUtils.MEASURED_SHAPE);
+            false, true, theme, getWQDShape(qwd));
 
         double gaugeDatum = getCurrentGaugeDatum();
 
@@ -398,8 +387,7 @@
                 qwd.getQ(),
                 w);
 
-            List<XYTextAnnotation> textAnnos =
-                new ArrayList<XYTextAnnotation>();
+            List<XYTextAnnotation> textAnnos = new ArrayList<>();
             textAnnos.add(anno);
             RiverAnnotation flysAnno =
                 new RiverAnnotation(null, null, null, theme);
@@ -410,18 +398,33 @@
         addAxisSeries(series, atGauge ? YAXIS.WCm.idx : YAXIS.W.idx, visible);
     }
 
+    public static Shape getWQDShape(final QWI qwd) {
+        final boolean isOutlier = qwd instanceof QWD ? ((QWD) qwd).isOutlier() : false;
+
+//        if( isOutlier)
+//            return ShapeUtils.DIGITIZED_SHAPE;
+        
+        if (qwd.getInterpolated())
+            return ShapeUtils.INTERPOLATED_SHAPE;
+
+        return ShapeUtils.MEASURED_SHAPE;
+    }
 
     public static final ThemeDocument configureThemeInterpolated(ThemeDocument theme, QWI qwd) {
         
+        // prevent potential side effects by copying original theme
+        final ThemeDocument newTheme = new ThemeDocument(theme);
+        
         // FIXME: it was like this before: points were always shown, flag had no effekt on this kind of theme, although the option is visible in the style editor
         final boolean showPoints = true;
 //        final boolean showPoints = theme.parseShowPoints();
         
         final boolean doFill = showPoints && !qwd.getInterpolated(); 
         final boolean doOutline = showPoints && qwd.getInterpolated(); 
-        
-        // prevent potential side effects by copying original theme
-        final ThemeDocument newTheme = new ThemeDocument(theme); 
+
+        final boolean isOutlier = qwd instanceof QWD ? ((QWD) qwd).isOutlier() : false;
+        if( isOutlier )
+            newTheme.setValue(ThemeDocument.POINT_COLOR, "255, 0, 0");
 
         newTheme.setValue(ThemeDocument.SHOW_POINTS, Boolean.toString(doFill));
         newTheme.setValue(ThemeDocument.SHOW_POINTS_OUTLINE, Boolean.toString(doOutline));
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/FixWQProcessor.java	Mon Jul 30 16:43:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/FixWQProcessor.java	Tue Jul 31 11:25:38 2018 +0200
@@ -31,7 +31,6 @@
 import org.dive4elements.river.exports.DiagramGenerator;
 import org.dive4elements.river.exports.StyledSeriesBuilder;
 import org.dive4elements.river.exports.fixings.FixWQCurveGenerator;
-import org.dive4elements.river.java2d.ShapeUtils;
 import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation;
 import org.dive4elements.river.jfree.JFreeUtil;
 import org.dive4elements.river.jfree.RiverAnnotation;
@@ -129,7 +128,7 @@
                     dateFormat.format(qwd.getDate()),
                     qwd.getQ(),
                     qwd.getW());
-            List<XYTextAnnotation> annos = new ArrayList<XYTextAnnotation>();
+            List<XYTextAnnotation> annos = new ArrayList<>();
             annos.add(anno);
             generator.addAxisSeries(series, axisName, visible);
 
@@ -165,21 +164,14 @@
         // prevent potential side effects
         final ThemeDocument themeInterpolated = FixWQCurveGenerator.configureThemeInterpolated(theme, qwd);
 
-        XYSeries series = new StyledXYSeries(
-            bundle.getFacetDescription(),
-            themeInterpolated,
-            qwd.getInterpolated()
-                ? ShapeUtils.INTERPOLATED_SHAPE
-                : ShapeUtils.MEASURED_SHAPE);
-
+        final XYSeries series = new StyledXYSeries( bundle.getFacetDescription(), themeInterpolated, FixWQCurveGenerator.getWQDShape(qwd));
         series.add(qwd.getQ(), qwd.getW());
 
         generator.addAxisSeries(series, axisName, visible);
 
         if (visible && themeInterpolated.parseShowPointLabel()) {
 
-            List<XYTextAnnotation> textAnnos =
-                new ArrayList<XYTextAnnotation>();
+            final List<XYTextAnnotation> textAnnos = new ArrayList<>();
 
             DateFormat dateFormat = DateFormat.getDateInstance(
                 DateFormat.SHORT);
@@ -189,8 +181,7 @@
                 qwd.getW());
             textAnnos.add(anno);
 
-            RiverAnnotation flysAnno =
-                new RiverAnnotation(null, null, null, themeInterpolated);
+            RiverAnnotation flysAnno = new RiverAnnotation(null, null, null, themeInterpolated);
             flysAnno.setTextAnnotations(textAnnos);
             generator.addAnnotations(flysAnno);
         }
@@ -213,13 +204,7 @@
 
         final ThemeDocument themeInterpolated = FixWQCurveGenerator.configureThemeInterpolated(theme, qwd);
 
-        XYSeries series = new StyledXYSeries(
-            bundle.getFacetDescription(),
-            false, true, themeInterpolated,
-            qwd.getInterpolated()
-                ? ShapeUtils.INTERPOLATED_SHAPE
-                : ShapeUtils.MEASURED_SHAPE);
-
+        final XYSeries series = new StyledXYSeries( bundle.getFacetDescription(), false, true, themeInterpolated, FixWQCurveGenerator.getWQDShape(qwd) );
         series.add(qwd.getQ(), qwd.getW(), false);
 
         if (visible && themeInterpolated.parseShowPointLabel()) {
@@ -231,11 +216,9 @@
                 qwd.getQ(),
                 qwd.getW());
 
-            List<XYTextAnnotation> textAnnos =
-                new ArrayList<XYTextAnnotation>();
+            List<XYTextAnnotation> textAnnos = new ArrayList<>();
             textAnnos.add(anno);
-            RiverAnnotation flysAnno =
-                new RiverAnnotation(null, null, null, themeInterpolated);
+            RiverAnnotation flysAnno = new RiverAnnotation(null, null, null, themeInterpolated);
             flysAnno.setTextAnnotations(textAnnos);
             generator.addAnnotations(flysAnno);
         }
@@ -295,7 +278,7 @@
             DateFormat dateFormat = DateFormat.getDateInstance(
                 DateFormat.SHORT);
 
-            List<XYTextAnnotation> annos = new ArrayList<XYTextAnnotation>();
+            List<XYTextAnnotation> annos = new ArrayList<>();
 
             for (QWI qw: qws) {
                 series.add(qw.getQ(), qw.getW(), false);
@@ -400,7 +383,7 @@
         boolean          visible
     ) {
         Object data = bundle.getData(generator.getContext());
-        List<StickyAxisAnnotation> xy = new ArrayList<StickyAxisAnnotation>();
+        List<StickyAxisAnnotation> xy = new ArrayList<>();
         if (data instanceof double[][]) {
             log.debug("Got double[][]");
             double [][] values = (double [][]) data;
@@ -458,7 +441,7 @@
             Double ckm = (Double) generator.getContext()
                 .getContextValue(CURRENT_KM);
 
-            if (wqkms == null || wqkms.getKms().length == 0 || ckm == null) {
+            if (wqkms.getKms().length == 0 || ckm == null) {
                 log.info("addPointFromWQKms: No event data to show.");
                 return;
             }
@@ -471,8 +454,7 @@
                     series.add(wqkms.getQ(i), wqkms.getW(i), false);
                     generator.addAxisSeries(series, axisName, visible);
                     if(visible && theme.parseShowPointLabel()) {
-                        List<XYTextAnnotation> textAnnos =
-                            new ArrayList<XYTextAnnotation>();
+                        List<XYTextAnnotation> textAnnos = new ArrayList<>();
                         XYTextAnnotation anno =
                             new CollisionFreeXYTextAnnotation(
                                 bundle.getFacetDescription(),

http://dive4elements.wald.intevation.org