changeset 6780:b8f94e865875

S/Q relation: Part I of 'faking' fitting linear data. S/Qs can now be subclassed and processed through views. TODO: Add knob to setup a linear data path.
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 08 Aug 2013 12:17:03 +0200
parents 8e5adc56385c
children dbaa31354b58
files artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Fitting.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/MeasurementFactory.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Measurements.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/SQ.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/SQRelationCalculation.java
diffstat 5 files changed, 59 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Fitting.java	Thu Aug 08 12:06:54 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Fitting.java	Thu Aug 08 12:17:03 2013 +0200
@@ -52,13 +52,15 @@
 
     protected Callback callback;
 
+    protected SQ.View sqView;
+
     public Fitting() {
     }
 
-    public Fitting(Function function, double stdDevFactor) {
-        this();
+    public Fitting(Function function, double stdDevFactor, SQ.View sqView) {
         this.function     = function;
         this.stdDevFactor = stdDevFactor;
+        this.sqView       = sqView;
     }
 
     public Function getFunction() {
@@ -151,8 +153,8 @@
 
     @Override
     public double eval(SQ sq) {
-        double s = instance.value(sq.q);
-        return sq.s - s;
+        double s = instance.value(sqView.getQ(sq));
+        return sqView.getS(sq) - s;
     }
 
     @Override
@@ -177,28 +179,15 @@
             chiSqr);
     }
 
-    protected static final List<SQ> onlyValid(List<SQ> sqs) {
-
-        List<SQ> good = new ArrayList<SQ>(sqs.size());
-
-        for (SQ sq: sqs) {
-            if (sq.isValid()) {
-                good.add(sq);
-            }
-        }
-
-        return good;
-    }
-
-    public boolean fit(List<SQ> sqs, String method, Callback callback) {
-
-        sqs = onlyValid(sqs);
+    public boolean fit(List<SQ> sqs, String   method, Callback callback) {
 
         if (sqs.size() < 2) {
             log.warn("Too less points for fitting.");
             return false;
         }
 
+        sqs = new ArrayList<SQ>(sqs);
+
         this.callback = callback;
 
         try {
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/MeasurementFactory.java	Thu Aug 08 12:06:54 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/MeasurementFactory.java	Thu Aug 08 12:17:03 2013 +0200
@@ -190,9 +190,10 @@
     }
 
     public static Measurements getMeasurements(
-        String    river,
-        double    location,
-        DateRange dateRange
+        String     river,
+        double     location,
+        DateRange  dateRange,
+        SQ.Factory sqFactory
     ) {
         Session session = SedDBSessionHolder.HOLDER.get();
         try {
@@ -202,7 +203,7 @@
             List<Measurement> accumulated = loadFractions(
                 session, river, location, dateRange);
 
-            return new Measurements(totals, accumulated);
+            return new Measurements(totals, accumulated, sqFactory);
         }
         finally {
             session.close();
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Measurements.java	Thu Aug 08 12:06:54 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/Measurements.java	Thu Aug 08 12:17:03 2013 +0200
@@ -66,13 +66,17 @@
     protected List<Measurement> measuments;
     protected List<Measurement> accumulated;
 
+    protected SQ.Factory sqFactory;
+
     public Measurements() {
     }
 
     public Measurements(
         List<Measurement> measuments,
-        List<Measurement> accumulated
+        List<Measurement> accumulated,
+        SQ.Factory        sqFactory
     ) {
+        this.sqFactory = sqFactory;
         if (log.isDebugEnabled()) {
             log.debug("number of measuments: " + measuments.size());
             log.debug("number of accumulated: " + accumulated.size());
@@ -81,14 +85,14 @@
         this.accumulated = accumulated;
     }
 
-    public static List<SQ> extractSQ(
+    public List<SQ> extractSQ(
         List<Measurement> measuments,
         SExtractor extractor
     ) {
         List<SQ> result = new ArrayList<SQ>(measuments.size());
         int invalid = 0;
         for (Measurement measument: measuments) {
-            SQ sq = new SQ(extractor.getS(measument), measument.Q());
+            SQ sq = sqFactory.createSQ(extractor.getS(measument), measument.Q());
             if (sq.isValid()) {
                 result.add(sq);
             }
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/SQ.java	Thu Aug 08 12:06:54 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/SQ.java	Thu Aug 08 12:17:03 2013 +0200
@@ -11,8 +11,37 @@
 import java.io.Serializable;
 
 
+/** Represents S/Q pairs. They are immutable! */
 public class SQ implements Serializable {
 
+    public interface Factory {
+        SQ createSQ(double s, double q);
+    }
+
+    public static final Factory SQ_FACTORY = new Factory() {
+        @Override
+        public SQ createSQ(double s, double q) {
+            return new SQ(s, q);
+        }
+    };
+
+    public interface View {
+        double getS(SQ sq);
+        double getQ(SQ sq);
+    }
+
+    public static final View SQ_VIEW = new View() {
+        @Override
+        public double getS(SQ sq) {
+            return sq.getS();
+        }
+
+        @Override
+        public double getQ(SQ sq) {
+            return sq.getQ();
+        }
+    };
+
     protected double s;
     protected double q;
 
@@ -29,19 +58,10 @@
         return s;
     }
 
-    public void setS(double s) {
-        this.s = s;
-    }
-
-
     public double getQ() {
         return q;
     }
 
-    public void setQ(double q) {
-        this.q = q;
-    }
-
     public boolean isValid() {
         return !Double.isNaN(s) && !Double.isNaN(q);
     }
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/SQRelationCalculation.java	Thu Aug 08 12:06:54 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/sq/SQRelationCalculation.java	Thu Aug 08 12:17:03 2013 +0200
@@ -114,8 +114,12 @@
             addProblem("sq.missing.sq.function");
         }
 
+        SQ.View    sqView    = SQ.SQ_VIEW;
+        SQ.Factory sqFactory = SQ.SQ_FACTORY;
+
         Measurements measurements =
-            MeasurementFactory.getMeasurements(river, location, period);
+            MeasurementFactory.getMeasurements(
+                river, location, period, sqFactory);
 
         SQFractionResult [] fractionResults =
             new SQFractionResult[SQResult.NUMBER_FRACTIONS];
@@ -126,7 +130,7 @@
             SQFractionResult fractionResult;
 
             List<SQFractionResult.Iteration> iterations =
-                doFitting(function, sqs);
+                doFitting(function, sqs, sqView);
 
             if (iterations == null) {
                 // TODO: i18n
@@ -149,12 +153,13 @@
 
     protected List<SQFractionResult.Iteration> doFitting(
         final Function function,
-        List<SQ> sqs
+        List<SQ>       sqs,
+        SQ.View        sqView
     ) {
         final List<SQFractionResult.Iteration> iterations =
             new ArrayList<SQFractionResult.Iteration>();
 
-        boolean success = new Fitting(function, outliers).fit(
+        boolean success = new Fitting(function, outliers, sqView).fit(
             sqs,
             method,
             new Fitting.Callback() {

http://dive4elements.wald.intevation.org