[PATCH 1 of 3] (issue1755) Generalise BedQuality result handling

Wald Commits scm-commit at wald.intevation.org
Wed Mar 18 18:48:32 CET 2015


# HG changeset patch
# User Andre Heinecke <andre.heinecke at intevation.de>
# Date 1426700528 -3600
# Node ID 07c9ac22f61194cef4457163b018c3b862527a81
# Parent  19fde13e2db46b9b15790625fb5ab7866a8f76b4
(issue1755) Generalise BedQuality result handling

The bedquality calculation now produces a result for each time period
which has BedQualityResultValues for each specific result type.
Formally this was split up in density, porosity and diameter classes
with some bedload diameter classes mixed in for extra fun.

The intent of this commit is to allow more shared code and generic
access patterns to the BedQuality results.

diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/doc/conf/artifacts/minfo.xml
--- a/artifacts/doc/conf/artifacts/minfo.xml	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/doc/conf/artifacts/minfo.xml	Wed Mar 18 18:42:08 2015 +0100
@@ -152,9 +152,9 @@
                         <facet name="flow_velocity.measurement" description="A facet for measured flow velocities"/>
                         <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
                         <facet name="flow_velocity.manualpoints"/>
-                        <facet name="bed_longitudinal_section.bed_diameter_toplayer"/>
-                        <facet name="bed_longitudinal_section.bed_diameter_sublayer"/>
-                        <facet name="bed_longitudinal_section.bedload_diameter"/>
+                        <facet name="bed_longitudinal_section.diameter.toplayer"/>
+                        <facet name="bed_longitudinal_section.diameter.sublayer"/>
+                        <facet name="bed_longitudinal_section.diameter.bedload"/>
                     </facets>
                 </outputmode>
                 <outputmode name="flow_velocity_export" description="output.flow_velocity_export" mime-type="text/plain" type="export">
@@ -463,17 +463,17 @@
             <outputmodes>
                 <outputmode name="bed_longitudinal_section" description="output.bed_longitudinal_section" mime-type="image/png" type="chart">
                     <facets>
-                        <facet name="bed_longitudinal_section.porosity_toplayer"/>
-                        <facet name="bed_longitudinal_section.porosity_sublayer"/>
-                        <facet name="bed_longitudinal_section.sediment_density_toplayer"/>
-                        <facet name="bed_longitudinal_section.sediment_density_sublayer"/>
-                        <facet name="bed_longitudinal_section.bed_diameter_toplayer"/>
-                        <facet name="bed_longitudinal_section.bed_diameter_sublayer"/>
-                        <facet name="bed_longitudinal_section.bed_diameter_data_top"/>
-                        <facet name="bed_longitudinal_section.bed_diameter_data_sub"/>
-                        <facet name="bed_longitudinal_section.bedload_diameter_data"/>
+                        <facet name="bed_longitudinal_section.porosity.toplayer"/>
+                        <facet name="bed_longitudinal_section.porosity.toplayer"/>
+                        <facet name="bed_longitudinal_section.density.toplayer"/>
+                        <facet name="bed_longitudinal_section.density.sublayer"/>
+                        <facet name="bed_longitudinal_section.diameter.toplayer"/>
+                        <facet name="bed_longitudinal_section.diameter.sublayer"/>
+                        <facet name="bed_longitudinal_section.diameter.toplayer.data"/>
+                        <facet name="bed_longitudinal_section.diameter.sublayer.data"/>
+                        <facet name="bed_longitudinal_section.diameter.bedload.data"/>
                         <facet name="bed_longitudinal_section.manualpoints" />
-                        <facet name="bed_longitudinal_section.bedload_diameter"/>
+                        <facet name="bed_longitudinal_section.diameter.bedload"/>
                         <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
                         <facet name="porosity" description="facet.porosity"/>
                     </facets>
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/doc/conf/meta-data.xml
--- a/artifacts/doc/conf/meta-data.xml	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/doc/conf/meta-data.xml	Wed Mar 18 18:42:08 2015 +0100
@@ -830,13 +830,13 @@
 
     <dc:macro name="bedquality">
       <dc:filter expr="$out_name = 'bed_longitudinal_section' and
-        ($facet_name = 'bed_longitudinal_section.bed_diameter_toplayer' or
-        $facet_name = 'bed_longitudinal_section.bed_diameter_sublayer' or
-        $facet_name = 'bed_longitudinal_section.bedload_diameter' or
-        $facet_name = 'bed_longitudinal_section.sediment_density_toplayer' or
-        $facet_name = 'bed_longitudinal_section.sediment_density_sublayer' or
-        $facet_name = 'bed_longitudinal_section.porosity_toplayer' or
-        $facet_name = 'bed_longitudinal_section.porosity_sublayer')">
+        ($facet_name = 'bed_longitudinal_section.diameter.toplayer' or
+        $facet_name = 'bed_longitudinal_section.diameter.sublayer' or
+        $facet_name = 'bed_longitudinal_section.diameter.bedload' or
+        $facet_name = 'bed_longitudinal_section.density.toplayer' or
+        $facet_name = 'bed_longitudinal_section.density.sublayer' or
+        $facet_name = 'bed_longitudinal_section.porosity.toplayer' or
+        $facet_name = 'bed_longitudinal_section.porosity.toplayer')">
         <dc:if test="dc:has-result()">
           <bed_quality>
             <dc:call-macro name="collection-group">
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/doc/conf/themes.xml
--- a/artifacts/doc/conf/themes.xml	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/doc/conf/themes.xml	Wed Mar 18 18:42:08 2015 +0100
@@ -213,16 +213,16 @@
         <mapping from="flow_velocity.measurement" to="FlowVelocityDischarge" />
         <mapping from="bedheight_middle.single" to="MiddleBedHeightSingle" />
         <mapping from="bedheight_middle.manualpoints" to="ManualPoints" />
-        <mapping from="bed_longitudinal_section.porosity_toplayer" to="PorosityTopLayer" />
-        <mapping from="bed_longitudinal_section.porosity_sublayer" to="PorositySubLayer" />
-        <mapping from="bed_longitudinal_section.sediment_density_toplayer" to="DensityTopLayer" />
-        <mapping from="bed_longitudinal_section.sediment_density_sublayer" to="DensitySublayer" />
-        <mapping from="bed_longitudinal_section.bed_diameter_toplayer" to="BedDiameterTopLayer" />
-        <mapping from="bed_longitudinal_section.bed_diameter_sublayer" to="BedDiameterSubLayer" />
-        <mapping from="bed_longitudinal_section.bedload_diameter" to="BedLoadDiameter" />
-        <mapping from="bed_longitudinal_section.bed_diameter_data_top" to="BedDiameterDataTop"/>
-        <mapping from="bed_longitudinal_section.bed_diameter_data_sub" to="BedDiameterDataSub"/>
-        <mapping from="bed_longitudinal_section.bedload_diameter_data" to="BedloadDiameterData"/>
+        <mapping from="bed_longitudinal_section.porosity.toplayer" to="PorosityTopLayer" />
+        <mapping from="bed_longitudinal_section.porosity.toplayer" to="PorositySubLayer" />
+        <mapping from="bed_longitudinal_section.density.toplayer" to="DensityTopLayer" />
+        <mapping from="bed_longitudinal_section.density.sublayer" to="DensitySublayer" />
+        <mapping from="bed_longitudinal_section.diameter.toplayer" to="BedDiameterTopLayer" />
+        <mapping from="bed_longitudinal_section.diameter.sublayer" to="BedDiameterSubLayer" />
+        <mapping from="bed_longitudinal_section.diameter.bedload" to="BedLoadDiameter" />
+        <mapping from="bed_longitudinal_section.diameter.toplayer.data" to="BedDiameterDataTop"/>
+        <mapping from="bed_longitudinal_section.diameter.sublayer.data" to="BedDiameterDataSub"/>
+        <mapping from="bed_longitudinal_section.diameter.bedload.data" to="BedloadDiameterData"/>
         <mapping from="bedheight_difference.year" to="BedheightDiffYear"/>
         <mapping from="bedheight_difference.year.filtered" to="BedheightDiffYear"/>
         <mapping from="bedheight_difference.morph_width" to="BedheightDiffMorphWidth"/>
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/FacetTypes.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/FacetTypes.java	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/FacetTypes.java	Wed Mar 18 18:42:08 2015 +0100
@@ -308,16 +308,17 @@
     String MIDDLE_BED_HEIGHT_SINGLE     = "bedheight_middle.single";
     String MIDDLE_BED_HEIGHT_ANNOTATION = "bedheight_middle.annotation";
 
-    String BED_QUALITY_POROSITY_TOPLAYER         = "bed_longitudinal_section.porosity_toplayer";
-    String BED_QUALITY_POROSITY_SUBLAYER         = "bed_longitudinal_section.porosity_sublayer";
-    String BED_QUALITY_BED_DIAMETER_TOPLAYER     = "bed_longitudinal_section.bed_diameter_toplayer";
-    String BED_QUALITY_BED_DIAMETER_SUBLAYER     = "bed_longitudinal_section.bed_diameter_sublayer";
-    String BED_QUALITY_SEDIMENT_DENSITY_TOPLAYER = "bed_longitudinal_section.sediment_density_toplayer";
-    String BED_QUALITY_SEDIMENT_DENSITY_SUBLAYER = "bed_longitudinal_section.sediment_density_sublayer";
-    String BED_QUALITY_BEDLOAD_DIAMETER          = "bed_longitudinal_section.bedload_diameter";
-    String BED_DIAMETER_DATA_TOP                 = "bed_longitudinal_section.bed_diameter_data_top";
-    String BED_DIAMETER_DATA_SUB                 = "bed_longitudinal_section.bed_diameter_data_sub";
-    String BEDLOAD_DIAMETER_DATA                 = "bed_longitudinal_section.bedload_diameter_data";
+    String BED_QUALITY_DATA_FACET                = "bed_longitudinal_section";
+    String BED_QUALITY_POROSITY_TOPLAYER         =  BED_QUALITY_DATA_FACET + ".porosity.toplayer";
+    String BED_QUALITY_POROSITY_SUBLAYER         =  BED_QUALITY_DATA_FACET + ".porosity.sublayer";
+    String BED_QUALITY_BED_DIAMETER_TOPLAYER     =  BED_QUALITY_DATA_FACET + ".diameter.toplayer";
+    String BED_QUALITY_BED_DIAMETER_SUBLAYER     =  BED_QUALITY_DATA_FACET + ".diameter.sublayer";
+    String BED_QUALITY_SEDIMENT_DENSITY_TOPLAYER =  BED_QUALITY_DATA_FACET + ".density.toplayer";
+    String BED_QUALITY_SEDIMENT_DENSITY_SUBLAYER =  BED_QUALITY_DATA_FACET + ".density.sublayer";
+    String BED_QUALITY_BEDLOAD_DIAMETER          =  BED_QUALITY_DATA_FACET + ".diameter.bedload";
+    String BED_DIAMETER_DATA_TOP                 =  BED_QUALITY_DATA_FACET + ".diameter.toplayer.data";
+    String BED_DIAMETER_DATA_SUB                 =  BED_QUALITY_DATA_FACET + ".diameter.sublayer.data";
+    String BEDLOAD_DIAMETER_DATA                 =  BED_QUALITY_DATA_FACET + ".diameter.bedload.data";
     String POROSITY                              = "porosity";
 
     String BED_DIFFERENCE_YEAR                   = "bedheight_difference.year";
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedDensitySubFacet.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedDensitySubFacet.java	Tue Mar 17 18:52:00 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.artifacts.model.minfo;
-
-import org.apache.log4j.Logger;
-
-import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
-import org.dive4elements.river.artifacts.D4EArtifact;
-import org.dive4elements.river.artifacts.model.CalculationResult;
-import org.dive4elements.river.artifacts.model.DataFacet;
-import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
-
-
-/**
- * Facet for serving bed density data.
- *
- * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
- */
-public class BedDensitySubFacet extends DataFacet {
-
-    private static final long serialVersionUID = 1L;
-
-    private static Logger log = Logger.getLogger(BedDensitySubFacet.class);
-
-    public BedDensitySubFacet() {
-    }
-
-    public BedDensitySubFacet(int idx, String name, String description,
-        ComputeType type, String stateId, String hash) {
-        super(idx, name, description, type, hash, stateId);
-        this.metaData.put("X", "chart.longitudinal.section.xaxis.label");
-        this.metaData.put("Y", "chart.bedquality.yaxis.label.density");
-    }
-
-    public Object getData(Artifact artifact, CallContext context) {
-        log.debug("Get data for bed density at index: " + index);
-
-        D4EArtifact flys = (D4EArtifact) artifact;
-
-        CalculationResult res = (CalculationResult) flys.compute(context, hash,
-            stateId, type, false);
-
-        int ndx = index >> 8;
-        BedParametersResult[] data =
-            ((BedQualityResult[]) res.getData())[ndx].getParameters(); // TODO CAST TO SPECIFIC CLASS
-
-        int ndy = index & 255;
-        if (data != null && data.length > ndy) {
-            BedParametersResult result = data[ndy];
-            return result.getDensitySubData();
-        }
-        return null;
-    }
-
-    /** Copy deeply. */
-    @Override
-    public Facet deepCopy() {
-        BedDensitySubFacet copy = new BedDensitySubFacet();
-        copy.set(this);
-        copy.type = type;
-        copy.hash = hash;
-        copy.stateId = stateId;
-        return copy;
-    }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedDensityTopFacet.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedDensityTopFacet.java	Tue Mar 17 18:52:00 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.artifacts.model.minfo;
-
-import org.apache.log4j.Logger;
-
-import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
-import org.dive4elements.river.artifacts.D4EArtifact;
-import org.dive4elements.river.artifacts.model.CalculationResult;
-import org.dive4elements.river.artifacts.model.DataFacet;
-import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
-
-
-/**
- * Facet for serving bed density data.
- *
- * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
- */
-public class BedDensityTopFacet extends DataFacet {
-
-    private static final long serialVersionUID = 1L;
-
-    private static Logger log = Logger.getLogger(BedDensityTopFacet.class);
-
-    public BedDensityTopFacet() {
-    }
-
-    public BedDensityTopFacet(int idx, String name, String description,
-        ComputeType type, String stateId, String hash) {
-        super(idx, name, description, type, hash, stateId);
-        this.metaData.put("X", "chart.longitudinal.section.xaxis.label");
-        this.metaData.put("Y", "chart.bedquality.yaxis.label.density");
-    }
-
-    public Object getData(Artifact artifact, CallContext context) {
-        log.debug("Get data for bed density at index: " + index);
-
-        D4EArtifact flys = (D4EArtifact) artifact;
-
-        CalculationResult res = (CalculationResult) flys.compute(context, hash,
-            stateId, type, false);
-
-        int ndx = index >> 8;
-        BedParametersResult[] data =
-            ((BedQualityResult[]) res.getData())[ndx].getParameters(); // TODO CAST TO SPECIFIC CLASS
-
-        int ndy = index & 255;
-        if (data != null && data.length > ndy) {
-            BedParametersResult result = data[ndy];
-            return result.getDensityCapData();
-        }
-        return null;
-    }
-
-    /** Copy deeply. */
-    @Override
-    public Facet deepCopy() {
-        BedDensityTopFacet copy = new BedDensityTopFacet();
-        copy.set(this);
-        copy.type = type;
-        copy.hash = hash;
-        copy.stateId = stateId;
-        return copy;
-    }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedDiameterResult.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedDiameterResult.java	Tue Mar 17 18:52:00 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.artifacts.model.minfo;
-
-import org.dive4elements.river.utils.DoubleUtil;
-
-import gnu.trove.TDoubleArrayList;
-
-import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
-
-import org.apache.commons.math.ArgumentOutsideDomainException;
-
-public class BedDiameterResult
-extends BedQualityDiameterResult
-{
-    protected TDoubleArrayList diameterCap;
-    protected TDoubleArrayList diameterSub;
-
-    protected PolynomialSplineFunction interpolSub;
-    protected PolynomialSplineFunction interpolCap;
-    protected boolean nonInterpolSub;
-    protected boolean nonInterpolCap;
-
-    public BedDiameterResult (
-        String type,
-        TDoubleArrayList diameterCap,
-        TDoubleArrayList diameterSub,
-        TDoubleArrayList km
-    ) {
-        super(type, km);
-        this.diameterCap = diameterCap;
-        this.diameterSub = diameterSub;
-        interpolSub = null;
-        nonInterpolSub = false;
-        interpolCap = null;
-        nonInterpolCap = false;
-    }
-
-    public double getDiameterCap(int ndx) {
-        if (diameterCap != null) {
-            return this.diameterCap.get(ndx);
-        }
-        return Double.NaN;
-    }
-
-    public double getDiameterSub(int ndx) {
-        if (diameterSub != null) {
-            return this.diameterSub.get(ndx);
-        }
-        return Double.NaN;
-    }
-
-    public double getDiameterCap(double km) {
-        if (kms.indexOf(km) >= 0) {
-            return diameterCap.get(kms.indexOf(km));
-        }
-        return Double.NaN;
-    }
-
-    public double getDiameterCapInterpol(double km) {
-        if (nonInterpolCap) {
-            return Double.NaN;
-        }
-        if (interpolCap == null) {
-            interpolCap = DoubleUtil.getLinearInterpolator(kms, diameterCap);
-            if (interpolCap == null) {
-                nonInterpolCap = true;
-                return Double.NaN;
-            }
-        }
-        try {
-            return interpolCap.value(km);
-        } catch (ArgumentOutsideDomainException e) {
-            /* This is expected for many results. */
-            return Double.NaN;
-        }
-    }
-
-    public double getDiameterSub(double km) {
-        if (kms.indexOf(km) >= 0) {
-            return diameterSub.get(kms.indexOf(km));
-        }
-        return Double.NaN;
-    }
-
-    public double getDiameterSubInterpol(double km) {
-        if (nonInterpolSub) {
-            return Double.NaN;
-        }
-        if (interpolSub == null) {
-            interpolSub = DoubleUtil.getLinearInterpolator(kms, diameterSub);
-            if (interpolSub == null) {
-                nonInterpolSub = true;
-                return Double.NaN;
-            }
-        }
-        try {
-            return interpolSub.value(km);
-        } catch (ArgumentOutsideDomainException e) {
-            /* This is expected for many results. */
-            return Double.NaN;
-        }
-    }
-
-    public double[][] getDiameterCapData() {
-        return new double[][] {
-            kms.toNativeArray(),
-            diameterCap.toNativeArray()
-        };
-    }
-
-    public double[][] getDiameterSubData() {
-        return new double[][] {
-            kms.toNativeArray(),
-            diameterSub.toNativeArray()
-        };
-    }
-}
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedDiameterSubFacet.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedDiameterSubFacet.java	Tue Mar 17 18:52:00 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.artifacts.model.minfo;
-
-import org.apache.log4j.Logger;
-
-import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
-import org.dive4elements.river.artifacts.D4EArtifact;
-import org.dive4elements.river.artifacts.model.CalculationResult;
-import org.dive4elements.river.artifacts.model.DataFacet;
-import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
-
-
-/**
- * Facet for serving bed diameter data.
- *
- * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
- */
-public class BedDiameterSubFacet extends DataFacet {
-
-    private static final long serialVersionUID = 1L;
-
-    private static Logger log = Logger.getLogger(BedDiameterSubFacet.class);
-
-    public BedDiameterSubFacet() {
-    }
-
-    public BedDiameterSubFacet(int idx, String name, String description,
-        ComputeType type, String stateId, String hash) {
-        super(idx, name, description, type, hash, stateId);
-        this.metaData.put("X", "chart.longitudinal.section.xaxis.label");
-        this.metaData.put("Y", "chart.bedquality.yaxis.label.diameter");
-    }
-
-    public Object getData(Artifact artifact, CallContext context) {
-        log.debug("Get data for bed diameter at index: " + index);
-
-        D4EArtifact flys = (D4EArtifact) artifact;
-
-        CalculationResult res = (CalculationResult) flys.compute(context, hash,
-            stateId, type, false);
-
-        int ndx = index >> 8;
-        Object[] raw =
-            ((BedQualityResult[]) res.getData())[ndx].getBedResults();
-
-        int ndy = index & 255;
-        if (raw != null && raw.length > ndy) {
-            BedDiameterResult data = (BedDiameterResult)raw[ndy];
-            return data.getDiameterSubData();
-        }
-        return null;
-    }
-
-    /** Copy deeply. */
-    @Override
-    public Facet deepCopy() {
-        BedDiameterSubFacet copy = new BedDiameterSubFacet();
-        copy.set(this);
-        copy.type = type;
-        copy.hash = hash;
-        copy.stateId = stateId;
-        return copy;
-    }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedDiameterTopFacet.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedDiameterTopFacet.java	Tue Mar 17 18:52:00 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.artifacts.model.minfo;
-
-import org.apache.log4j.Logger;
-
-import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
-import org.dive4elements.river.artifacts.D4EArtifact;
-import org.dive4elements.river.artifacts.model.CalculationResult;
-import org.dive4elements.river.artifacts.model.DataFacet;
-import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
-
-
-/**
- * Facet for serving bed diameter data.
- *
- * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
- */
-public class BedDiameterTopFacet extends DataFacet {
-
-    private static final long serialVersionUID = 1L;
-
-    private static Logger log = Logger.getLogger(BedDiameterTopFacet.class);
-
-    public BedDiameterTopFacet() {
-    }
-
-    public BedDiameterTopFacet(int idx, String name, String description,
-        ComputeType type, String stateId, String hash) {
-        super(idx, name, description, type, hash, stateId);
-        this.metaData.put("X", "chart.longitudinal.section.xaxis.label");
-        this.metaData.put("Y", "chart.bedquality.yaxis.label.diameter");
-    }
-
-    public Object getData(Artifact artifact, CallContext context) {
-        log.debug("Get data for bed diameter at index: " + index);
-
-        D4EArtifact flys = (D4EArtifact) artifact;
-
-        CalculationResult res = (CalculationResult) flys.compute(context, hash,
-            stateId, type, false);
-
-        int ndx = index >> 8;
-        Object[] raw = ((BedQualityResult[]) res.getData())[ndx].getBedResults(); // TODO CAST TO SPECIFIC CLASS
-
-        int ndy = index & 255;
-        if (raw != null && raw.length > ndy) {
-            BedDiameterResult data = (BedDiameterResult)raw[ndy];
-            return data.getDiameterCapData();
-        }
-        return null;
-    }
-
-    /** Copy deeply. */
-    @Override
-    public Facet deepCopy() {
-        BedDiameterTopFacet copy = new BedDiameterTopFacet();
-        copy.set(this);
-        copy.type = type;
-        copy.hash = hash;
-        copy.stateId = stateId;
-        return copy;
-    }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedPorositySubFacet.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedPorositySubFacet.java	Tue Mar 17 18:52:00 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.artifacts.model.minfo;
-
-import org.apache.log4j.Logger;
-
-import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
-import org.dive4elements.river.artifacts.D4EArtifact;
-import org.dive4elements.river.artifacts.model.CalculationResult;
-import org.dive4elements.river.artifacts.model.DataFacet;
-import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
-
-
-/**
- * Facet for serving bed porosity data.
- *
- * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
- */
-public class BedPorositySubFacet extends DataFacet {
-
-    private static final long serialVersionUID = 1L;
-
-    private static Logger log = Logger.getLogger(BedPorositySubFacet.class);
-
-    public BedPorositySubFacet() {
-    }
-
-    public BedPorositySubFacet(int idx, String name, String description,
-        ComputeType type, String stateId, String hash) {
-        super(idx, name, description, type, hash, stateId);
-        this.metaData.put("X", "chart.longitudinal.section.xaxis.label");
-        this.metaData.put("Y", "chart.bedquality.yaxis.label.porosity");
-    }
-
-    public Object getData(Artifact artifact, CallContext context) {
-        log.debug("Get data for bed porosity at index: " + index);
-
-        D4EArtifact flys = (D4EArtifact) artifact;
-
-        CalculationResult res = (CalculationResult) flys.compute(context, hash,
-            stateId, type, false);
-
-        int ndx = index >> 8;
-        Object[] raw = ((BedQualityResult[]) res.getData())[ndx].getParameters(); // TODO CAST TO SPECIFIC CLASS
-
-        int ndy = index & 255;
-        if (raw != null && raw.length > ndy) {
-            BedParametersResult data = (BedParametersResult)raw[ndy];
-            return data.getPorositySubData();
-        }
-        return null;
-    }
-
-    /** Copy deeply. */
-    @Override
-    public Facet deepCopy() {
-        BedPorositySubFacet copy = new BedPorositySubFacet();
-        copy.set(this);
-        copy.type = type;
-        copy.hash = hash;
-        copy.stateId = stateId;
-        return copy;
-    }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedPorosityTopFacet.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedPorosityTopFacet.java	Tue Mar 17 18:52:00 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.artifacts.model.minfo;
-
-import org.apache.log4j.Logger;
-
-import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
-import org.dive4elements.river.artifacts.D4EArtifact;
-import org.dive4elements.river.artifacts.model.CalculationResult;
-import org.dive4elements.river.artifacts.model.DataFacet;
-import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
-
-
-/**
- * Facet for serving bed porosity data.
- *
- * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
- */
-public class BedPorosityTopFacet extends DataFacet {
-
-    private static final long serialVersionUID = 1L;
-
-    private static Logger log = Logger.getLogger(BedPorosityTopFacet.class);
-
-    public BedPorosityTopFacet() {
-    }
-
-    public BedPorosityTopFacet(int idx, String name, String description,
-        ComputeType type, String stateId, String hash) {
-        super(idx, name, description, type, hash, stateId);
-        this.metaData.put("X", "chart.longitudinal.section.xaxis.label");
-        this.metaData.put("Y", "chart.bedquality.yaxis.label.porosity");
-    }
-
-    public Object getData(Artifact artifact, CallContext context) {
-        log.debug("Get data for bed porosity at index: " + index);
-
-        D4EArtifact flys = (D4EArtifact) artifact;
-
-        CalculationResult res = (CalculationResult) flys.compute(context, hash,
-            stateId, type, false);
-
-        int ndx = index >> 8;
-        Object[] raw = ((BedQualityResult[]) res.getData())[ndx].getParameters(); // TODO CAST TO SPECIFIC CLASS
-
-        int ndy = index & 255;
-        if (raw != null && raw.length > ndy) {
-            BedParametersResult data = (BedParametersResult)raw[ndy];
-            return data.getPorosityCapData();
-        }
-        return null;
-    }
-
-    /** Copy deeply. */
-    @Override
-    public Facet deepCopy() {
-        BedPorosityTopFacet copy = new BedPorosityTopFacet();
-        copy.set(this);
-        copy.type = type;
-        copy.hash = hash;
-        copy.stateId = stateId;
-        return copy;
-    }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedQualityCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedQualityCalculation.java	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedQualityCalculation.java	Wed Mar 18 18:42:08 2015 +0100
@@ -110,22 +110,14 @@
             BedQualityResult result = new BedQualityResult();
             result.setDateRange(dr);
             if (bedDiameter != null) {
-                result.add(calculateBedParameter(bedMeasurements, dr));
+                result.add(calculateBedParameter(bedMeasurements));
                 for (String bd : bedDiameter) {
-                    BedDiameterResult bedResult =
-                        calculateBed(bedMeasurements, bd, dr);
-
-                    // Avoid adding empty result sets.
-                    if (!bedResult.isEmpty()) {
-                        result.add(bedResult);
-                    }
+                    result.add (calculateBed(bedMeasurements, bd));
                 }
             }
             if (bedloadDiameter != null) {
                 for (String bld : bedloadDiameter) {
-                    BedloadDiameterResult loadResult =
-                        calculateBedload(loadMeasurements, bld, dr);
-                    result.add(loadResult);
+                    result.add(calculateBedload(loadMeasurements, bld));
                 }
             }
             results.add(result);
@@ -135,14 +127,13 @@
             results.toArray(new BedQualityResult[results.size()]), this);
     }
 
-    private BedParametersResult calculateBedParameter(
-        QualityMeasurements qm,
-        DateRange dr
+    private BedQualityResultValue[] calculateBedParameter(
+        QualityMeasurements qm
     ) {
         List<Double> kms = qm.getKms();
+        TDoubleArrayList location = new TDoubleArrayList();
         QualityMeasurements capFiltered = filterCapMeasurements(qm);
         QualityMeasurements subFiltered = filterSubMeasurements(qm);
-        TDoubleArrayList location = new TDoubleArrayList();
         TDoubleArrayList porosityCap = new TDoubleArrayList();
         TDoubleArrayList porositySub = new TDoubleArrayList();
         TDoubleArrayList densityCap = new TDoubleArrayList();
@@ -173,19 +164,24 @@
             densitySub.add((dSubRes / dSub.length) / 1000);
 
         }
-
-        return new BedParametersResult(
-            location,
-            porosityCap,
-            porositySub,
-            densityCap,
-            densitySub);
+        return new BedQualityResultValue[] {
+                new BedQualityResultValue("porosity",
+                        new double[][] {location.toNativeArray(), porositySub.toNativeArray()},
+                        "sublayer"),
+                new BedQualityResultValue("porosity",
+                        new double[][] {location.toNativeArray(), porosityCap.toNativeArray()},
+                        "toplayer"),
+                new BedQualityResultValue("density",
+                        new double[][] {location.toNativeArray(), densitySub.toNativeArray()},
+                        "sublayer"),
+                new BedQualityResultValue("density",
+                        new double[][] {location.toNativeArray(), densityCap.toNativeArray()},
+                        "toplayer")};
     }
 
-    protected BedDiameterResult calculateBed(
+    protected BedQualityResultValue[] calculateBed(
         QualityMeasurements qm,
-        String diameter,
-        DateRange range
+        String diameter
     ) {
         List<Double> kms = qm.getKms();
         TDoubleArrayList location = new TDoubleArrayList();
@@ -205,11 +201,13 @@
             avDiameterCap.add(avCap * 1000);// bring to mm.
             avDiameterSub.add(avSub * 1000);
         }
-        return new BedDiameterResult(
-            diameter,
-            avDiameterCap,
-            avDiameterSub,
-            location);
+        return new BedQualityResultValue[] {
+                new BedQualityResultValue(diameter,
+                        new double[][] {location.toNativeArray(), avDiameterSub.toNativeArray()},
+                        "sublayer"),
+                new BedQualityResultValue(diameter,
+                        new double[][] {location.toNativeArray(), avDiameterCap.toNativeArray()},
+                        "toplayer")};
     }
 
     private double[] calculateDensity(
@@ -241,10 +239,9 @@
         return results;
     }
 
-    protected BedloadDiameterResult calculateBedload(
+    protected BedQualityResultValue calculateBedload(
         QualityMeasurements qm,
-        String diameter,
-        DateRange range
+        String diameter
     ) {
         List<Double> kms = qm.getKms();
         TDoubleArrayList location = new TDoubleArrayList();
@@ -255,11 +252,9 @@
             location.add(km);
             avDiameter.add(mid * 1000);
         }
-        return new BedloadDiameterResult(
-            diameter,
-            avDiameter,
-            location,
-            range);
+        return new BedQualityResultValue(diameter,
+                new double[][] {location.toNativeArray(), avDiameter.toNativeArray()},
+                "bedload");
     }
 
     protected double calculateAverage(
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedQualityDataFacet.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedQualityDataFacet.java	Wed Mar 18 18:42:08 2015 +0100
@@ -0,0 +1,79 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.model.minfo;
+
+import org.apache.log4j.Logger;
+
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.DataFacet;
+import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
+
+
+/**
+ * Facet for serving BedQualityResults
+ */
+public class BedQualityDataFacet extends DataFacet {
+
+    private static final long serialVersionUID = 1L;
+
+    private static Logger log = Logger.getLogger(BedQualityDataFacet.class);
+
+    private String valueName; /* Name of the ResultValue underlying this facet */
+    private String valueType; /* Type of the ResultValue underlying this facet */
+
+    public BedQualityDataFacet() {
+        // required for clone operation deepCopy()
+    }
+
+    public BedQualityDataFacet(int idx, String name, String description,
+        ComputeType type, String stateId, String hash, String valueName, String valueType) {
+        super(idx, name, description, type, hash, stateId);
+        this.valueName = valueName;
+        this.valueType = valueType;
+        this.metaData.put("X", "chart.longitudinal.section.xaxis.label");
+        this.metaData.put("Y", ""); /* check if those <^ be removed? */
+    }
+
+    @Override
+    public Object getData(Artifact artifact, CallContext context) {
+        log.debug("Get bedquality data: " + valueName + " - " + valueType);
+
+        D4EArtifact flys = (D4EArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(context, hash,
+            stateId, type, false);
+
+        int ndx = index >> 8;
+        BedQualityResultValue value =
+            ((BedQualityResult[]) res.getData())[ndx].getValue(valueName, valueType);
+
+        if (value == null) {
+            /* Other facets check this so we do too */
+            return null;
+        }
+        return value.getData();
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        BedQualityDataFacet copy = new BedQualityDataFacet();
+        copy.set(this);
+        copy.type = type;
+        copy.hash = hash;
+        copy.stateId = stateId;
+        copy.valueName = valueName;
+        copy.valueType = valueType;
+        return copy;
+    }
+}
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedQualityResult.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedQualityResult.java	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedQualityResult.java	Wed Mar 18 18:42:08 2015 +0100
@@ -18,53 +18,44 @@
 implements Serializable
 {
 
-    protected List<BedDiameterResult> bedResults;
-    protected List<BedloadDiameterResult> bedloadResults;
-    protected List<BedParametersResult> bedParameters;
+    protected LinkedList<BedQualityResultValue> values;
     protected DateRange dateRange;
 
     public BedQualityResult () {
-        bedResults = new LinkedList<BedDiameterResult>();
-        bedloadResults = new LinkedList<BedloadDiameterResult>();
-        bedParameters = new LinkedList<BedParametersResult>();
+        values = new LinkedList<BedQualityResultValue>();
     };
 
     public BedQualityResult (
-        List<BedDiameterResult> bedResults,
-        List<BedloadDiameterResult> bedloadResults,
-        List<BedParametersResult> bedParameters,
+        LinkedList<BedQualityResultValue> values,
         DateRange range
     ) {
         this.dateRange = range;
-        this.bedResults = bedResults;
-        this.bedloadResults = bedloadResults;
-        this.bedParameters = bedParameters;
+        this.values = values;
     }
 
-    public BedParametersResult[] getParameters() {
-        return bedParameters.toArray(
-            new BedParametersResult[bedParameters.size()]);
+    public void add(BedQualityResultValue[] values) {
+        for (BedQualityResultValue value: values) {
+            add(value);
+        }
     }
 
-    public BedDiameterResult[] getBedResults() {
-        return bedResults.toArray(new BedDiameterResult[bedResults.size()]);
+    public void add(BedQualityResultValue value) {
+        /* Add first is here to mimic the result sorting before
+         * a refactorization.*/
+        values.addFirst(value);
     }
 
-    public BedloadDiameterResult[] getBedloadResults() {
-        return bedloadResults.toArray(
-            new BedloadDiameterResult[bedloadResults.size()]);
+    public List<BedQualityResultValue> getValues() {
+        return values;
     }
 
-    public void add(BedloadDiameterResult result) {
-        bedloadResults.add(result);
-    }
-
-    public void add(BedDiameterResult result) {
-        bedResults.add(result);
-    }
-
-    public void add(BedParametersResult result) {
-        bedParameters.add(result);
+    public BedQualityResultValue getValue(String name, String type) {
+        for (BedQualityResultValue value: values) {
+            if (name.equals(value.getName()) && type.equals(value.getType())) {
+                return value;
+            }
+        }
+        return null;
     }
 
     public DateRange getDateRange() {
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedQualityResultValue.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedQualityResultValue.java	Wed Mar 18 18:42:08 2015 +0100
@@ -0,0 +1,126 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.model.minfo;
+
+import org.dive4elements.river.utils.DoubleUtil;
+
+import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
+import org.apache.commons.math.ArgumentOutsideDomainException;
+
+import java.util.Arrays;
+import java.util.Set;
+import java.util.HashSet;
+
+import java.io.Serializable;
+
+/** Holder of a specific result from the bed quality calculation.
+ *
+ * Data is always a map of km to value. The type "bedload"
+ * translates to german "Geschiebe" other results are either
+ * specific to the top or the sublayer of the riverbed.
+ *
+ * The name can be the diameter of this result for bed and bedload
+ * data.
+ **/
+public class BedQualityResultValue implements Serializable {
+    public static final String[] DIAMETER_NAMES = new String[] {
+        "D90",
+        "D84",
+        "D80",
+        "D75",
+        "D70",
+        "D60",
+        "D50",
+        "D40",
+        "D30",
+        "D25",
+        "D20",
+        "D16",
+        "D10",
+        "DM",
+        "DMIN",
+        "DMAX"
+    };
+
+    /* For ease of access */
+    public static final Set<String> DIAMETER_NAME_SET = new HashSet<String>(
+            Arrays.asList(DIAMETER_NAMES));
+
+    private String      name;
+    private String      type;
+    private double [][] data;
+    private transient PolynomialSplineFunction interpolFunc;
+
+    public BedQualityResultValue() {
+    }
+
+    public BedQualityResultValue(String name, double [][] data, String type) {
+        this.name = name;
+        setData(data);
+        this.type = type;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public double [][] getData() {
+        return data;
+    }
+
+    public double getData(double x) {
+        int idx = Arrays.binarySearch(data[0], x);
+        if (idx < 0) {
+            return Double.NaN;
+        } else {
+            return data[1][idx];
+        }
+    }
+
+    public double getDataInterpolated(double x) {
+        if (interpolFunc == null) {
+            interpolFunc = DoubleUtil.getLinearInterpolator(data[0], data[1]);
+        }
+        try {
+            return interpolFunc.value(x);
+        } catch (ArgumentOutsideDomainException e) {
+            return getData(x);
+        }
+    }
+
+    public double [][] getDataInterpolated(double[] x) {
+        double y[] = new double[x.length];
+        int i = 0;
+        for (double point: x) {
+            y[i++] = getDataInterpolated(point);
+        }
+        return new double[][] {x, y};
+    }
+
+    public void setData(double [][] data) {
+        this.data = data;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    /** Checks wether or not the name matches that of a diameter */
+    public boolean isDiameterResult() {
+        return DIAMETER_NAME_SET.contains(name.toUpperCase());
+    }
+}
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedloadDiameterFacet.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedloadDiameterFacet.java	Tue Mar 17 18:52:00 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.artifacts.model.minfo;
-
-import org.apache.log4j.Logger;
-
-import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
-import org.dive4elements.river.artifacts.D4EArtifact;
-import org.dive4elements.river.artifacts.model.CalculationResult;
-import org.dive4elements.river.artifacts.model.DataFacet;
-import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
-
-
-/**
- * Facet for serving bedload diameter data.
- *
- * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
- */
-public class BedloadDiameterFacet extends DataFacet {
-
-    private static final long serialVersionUID = 1L;
-
-    private static Logger log = Logger.getLogger(BedloadDiameterFacet.class);
-
-    public BedloadDiameterFacet() {
-        // required for clone operation deepCopy()
-    }
-
-    public BedloadDiameterFacet(int idx, String name, String description,
-        ComputeType type, String stateId, String hash) {
-        super(idx, name, description, type, hash, stateId);
-        this.metaData.put("X", "chart.longitudinal.section.xaxis.label");
-        this.metaData.put("Y", "chart.bedquality.yaxis.label.diameter");
-    }
-
-    public Object getData(Artifact artifact, CallContext context) {
-        log.debug("Get data for bedload diameter at index: " + index);
-
-        D4EArtifact flys = (D4EArtifact) artifact;
-
-        CalculationResult res = (CalculationResult) flys.compute(context, hash,
-            stateId, type, false);
-
-        int ndx = index >> 8;
-        Object[] raw =
-            ((BedQualityResult[]) res.getData())[ndx].getBedloadResults(); // TODO CAST TO SPECIFIC CLASS
-
-        int ndy = index & 255;
-        if (raw != null && raw.length > ndy) {
-            BedloadDiameterResult data = (BedloadDiameterResult)raw[ndy];
-            return data.getDiameterData();
-        }
-        return null;
-    }
-
-    /** Copy deeply. */
-    @Override
-    public Facet deepCopy() {
-        BedloadDiameterFacet copy = new BedloadDiameterFacet();
-        copy.set(this);
-        copy.type = type;
-        copy.hash = hash;
-        copy.stateId = stateId;
-        return copy;
-    }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedloadDiameterResult.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedloadDiameterResult.java	Tue Mar 17 18:52:00 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.artifacts.model.minfo;
-
-import org.dive4elements.river.artifacts.model.DateRange;
-import org.dive4elements.river.utils.DoubleUtil;
-
-import gnu.trove.TDoubleArrayList;
-
-import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
-
-import org.apache.commons.math.ArgumentOutsideDomainException;
-
-public class BedloadDiameterResult
-extends BedQualityDiameterResult
-{
-    protected TDoubleArrayList diameter;
-    protected PolynomialSplineFunction interpol;
-
-    /** Set to true if this result can't be interpolated.*/
-    protected boolean nonInterpolResult;
-
-    public BedloadDiameterResult(
-        String type,
-        TDoubleArrayList diameter,
-        TDoubleArrayList km,
-        DateRange range
-    ) {
-        super (type, km);
-        this.diameter = diameter;
-        interpol = null;
-        nonInterpolResult = false;
-    }
-
-    public double getDiameter(int ndx) {
-        if (diameter != null) {
-            return this.diameter.get(ndx);
-        }
-        return Double.NaN;
-    }
-
-    public double getDiameter(double km) {
-        if (kms.indexOf(km) >= 0) {
-            return diameter.get(kms.indexOf(km));
-        }
-        return Double.NaN;
-    }
-
-    public double getDiameterInterpol(double km) {
-        if (nonInterpolResult) {
-            return Double.NaN;
-        }
-        if (interpol == null) {
-            interpol = DoubleUtil.getLinearInterpolator(kms, diameter);
-            if (interpol == null) {
-                nonInterpolResult = true;
-                return Double.NaN;
-            }
-        }
-        try {
-            return interpol.value(km);
-        } catch (ArgumentOutsideDomainException e) {
-            /* This is expected for many results. */
-            return Double.NaN;
-        }
-    }
-
-    public double[][] getDiameterData() {
-        return new double[][] {
-            kms.toNativeArray(),
-            diameter.toNativeArray()
-        };
-    }
-}
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/artifacts/states/minfo/BedQualityState.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/states/minfo/BedQualityState.java	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/states/minfo/BedQualityState.java	Wed Mar 18 18:42:08 2015 +0100
@@ -25,24 +25,17 @@
 import org.dive4elements.river.artifacts.model.DataFacet;
 import org.dive4elements.river.artifacts.model.DateRange;
 import org.dive4elements.river.artifacts.model.FacetTypes;
-import org.dive4elements.river.artifacts.model.minfo.BedDensityTopFacet;
-import org.dive4elements.river.artifacts.model.minfo.BedDensitySubFacet;
-import org.dive4elements.river.artifacts.model.minfo.BedDiameterTopFacet;
+import org.dive4elements.river.artifacts.model.minfo.BedQualityDataFacet;
 import org.dive4elements.river.artifacts.model.minfo.BedDiameterDataFacet;
-import org.dive4elements.river.artifacts.model.minfo.BedDiameterResult;
-import org.dive4elements.river.artifacts.model.minfo.BedDiameterSubFacet;
-import org.dive4elements.river.artifacts.model.minfo.BedParametersResult;
-import org.dive4elements.river.artifacts.model.minfo.BedPorositySubFacet;
-import org.dive4elements.river.artifacts.model.minfo.BedPorosityTopFacet;
+import org.dive4elements.river.artifacts.model.minfo.BedloadDiameterDataFacet;
 import org.dive4elements.river.artifacts.model.minfo.BedQualityCalculation;
-import org.dive4elements.river.artifacts.model.minfo.BedQualityDiameterResult;
 import org.dive4elements.river.artifacts.model.minfo.BedQualityResult;
-import org.dive4elements.river.artifacts.model.minfo.BedloadDiameterDataFacet;
-import org.dive4elements.river.artifacts.model.minfo.BedloadDiameterFacet;
-import org.dive4elements.river.artifacts.model.minfo.BedloadDiameterResult;
+import org.dive4elements.river.artifacts.model.minfo.BedQualityResultValue;
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.states.DefaultState;
 
+/* TODO: Change data facets to live in the generalized data scheme and
+ * obsolute the obfuscated index magic. */
 
 public class BedQualityState extends DefaultState implements FacetTypes {
 
@@ -51,23 +44,19 @@
     private static final Logger log = Logger
         .getLogger(BedQualityState.class);
 
+    /* The suffix to append to interpol facets. */
+    public static final String I18N_INTERPOL_SUFFIX = "facet.bedquality.interpol.suffix";
+
+    /* I18n is in the pattern base.<name>.<type> with the optional suffix .data */
+    public static final String I18N_FACET_BED_BASE = "facet.bedquality.bed";
+
+    /* Data Layers */
+    public static final String I18N_FACET_BEDLOAD_DIAMETER_DATA = "facet.bedquality.bed.diameter.bedload.data";
+    public static final String I18N_FACET_BED_DIAMETER_DATA_TOPLAYER = "facet.bedquality.bed.diameter.toplayer.data";
+    public static final String I18N_FACET_BED_DIAMETER_DATA_SUBLAYER = "facet.bedquality.bed.diameter.sublayer.data";
     public static final String I18N_TOPLAYER = "bedquality.toplayer";
     public static final String I18N_SUBLAYER = "bedquality.sublayer";
 
-    /* Calculated layers */
-    public static final String I18N_FACET_BED_POROSITY_TOPLAYER = "facet.bedquality.bed.porosity.toplayer";
-    public static final String I18N_FACET_BED_POROSITY_SUBLAYER = "facet.bedquality.bed.porosity.sublayer";
-    public static final String I18N_FACET_BED_DENSITY_TOPLAYER = "facet.bedquality.bed.density.toplayer";
-    public static final String I18N_FACET_BED_DENSITY_SUBLAYER = "facet.bedquality.bed.density.sublayer";
-    public static final String I18N_FACET_BED_DIAMETER_TOPLAYER = "facet.bedquality.bed.diameter.toplayer";
-    public static final String I18N_FACET_BED_DIAMETER_SUBLAYER = "facet.bedquality.bed.diameter.sublayer";
-    public static final String I18N_FACET_BEDLOAD_DIAMETER = "facet.bedquality.bedload.diameter";
-
-    /* Data Layers */
-    public static final String I18N_FACET_BEDLOAD_DIAMETER_DATA = "facet.bedquality.bedload.diameter.data";
-    public static final String I18N_FACET_BED_DIAMETER_DATA_TOPLAYER = "facet.bedquality.bed.diameter.data.toplayer";
-    public static final String I18N_FACET_BED_DIAMETER_DATA_SUBLAYER = "facet.bedquality.bed.diameter.data.sublayer";
-
     static {
         // Active/deactivate facets.
         FacetActivity.Registry.getInstance().register(
@@ -123,85 +112,13 @@
         }
 
         generateFacets(context, newFacets, results, getID(), hash);
+        generateDataFacets(context, newFacets, access, getID(), hash);
         log.debug("Created " + newFacets.size() + " new Facets.");
-        generateDataFacets(context, newFacets, access, getID(), hash);
         facets.addAll(newFacets);
 
         return res;
     }
 
-    private void generateDataFacets(
-        CallContext context,
-        List<Facet> newFacets,
-        BedQualityAccess access,
-        String stateId,
-        String hash) {
-        List<String> diameters = access.getBedDiameter();
-        List<String> loadDiameters = access.getBedloadDiameter();
-        List<DateRange> ranges = access.getDateRanges();
-        for (int i = 0, R = ranges.size(); i < R; i++) {
-            DateRange range = ranges.get(i);
-            for (String diameter: diameters) {
-                int ndxTop = generateIndex(diameter);
-                int ndxSub = ndxTop; // TODO: Is this correct?
-                ndxTop += 1;
-                ndxTop = ndxTop << 3;
-                ndxSub = ndxSub << 3;
-                ndxTop += i;
-                ndxSub += i;
-                String toplayer =
-                    Resources.getMsg(
-                        context.getMeta(), I18N_TOPLAYER, I18N_TOPLAYER);
-                String sublayer =
-                    Resources.getMsg(
-                        context.getMeta(), I18N_SUBLAYER, I18N_SUBLAYER);
-                //toplayer
-                newFacets.add(new BedDiameterDataFacet(
-                    ndxTop,
-                    BED_DIAMETER_DATA_TOP,
-                    Resources.getMsg(
-                        context.getMeta(),
-                        I18N_FACET_BED_DIAMETER_DATA_TOPLAYER,
-                        I18N_FACET_BED_DIAMETER_DATA_TOPLAYER,
-                        new Object[] { diameter.toUpperCase(),
-                            range.getFrom(), range.getTo(), toplayer}),
-                    ComputeType.ADVANCE,
-                    stateId,
-                    hash));
-                //sublayer
-                newFacets.add(new BedDiameterDataFacet(
-                    ndxSub,
-                    BED_DIAMETER_DATA_SUB,
-                    Resources.getMsg(
-                        context.getMeta(),
-                        I18N_FACET_BED_DIAMETER_DATA_TOPLAYER,
-                        I18N_FACET_BED_DIAMETER_DATA_TOPLAYER,
-                        new Object[] { diameter.toUpperCase(),
-                            range.getFrom(), range.getTo(), sublayer}),
-                    ComputeType.ADVANCE,
-                    stateId,
-                    hash));
-            }
-            for (String loadDiameter: loadDiameters) {
-                int ndx = generateIndex(loadDiameter);
-                ndx = ndx << 3;
-                ndx += i;
-                newFacets.add(new BedloadDiameterDataFacet(
-                    ndx,
-                    BEDLOAD_DIAMETER_DATA,
-                    Resources.getMsg(
-                        context.getMeta(),
-                        I18N_FACET_BEDLOAD_DIAMETER_DATA,
-                        I18N_FACET_BEDLOAD_DIAMETER_DATA,
-                        new Object[] { loadDiameter.toUpperCase(),
-                            range.getFrom(), range.getTo()}),
-                    ComputeType.ADVANCE,
-                    stateId,
-                    hash));
-            }
-        }
-    }
-
     private int generateIndex(String diameter) {
         int d = 0;
         if(diameter.equals("d10")) {
@@ -256,6 +173,86 @@
         return ndx;
     }
 
+    private void generateDataFacets(
+        CallContext context,
+        List<Facet> newFacets,
+        BedQualityAccess access,
+        String stateId,
+        String hash) {
+        List<String> diameters = access.getBedDiameter();
+        List<String> loadDiameters = access.getBedloadDiameter();
+        List<DateRange> ranges = access.getDateRanges();
+        for (int i = 0, R = ranges.size(); i < R; i++) {
+            DateRange range = ranges.get(i);
+            for (String diameter: diameters) {
+                int ndxTop = generateIndex(diameter);
+                int ndxSub = ndxTop;
+                ndxTop += 1;
+                ndxTop = ndxTop << 3;
+                ndxSub = ndxSub << 3;
+                ndxTop += i;
+                ndxSub += i;
+                String toplayer =
+                    Resources.getMsg(
+                        context.getMeta(), I18N_TOPLAYER, I18N_TOPLAYER);
+                String sublayer =
+                    Resources.getMsg(
+                        context.getMeta(), I18N_SUBLAYER, I18N_SUBLAYER);
+                //toplayer
+                newFacets.add(new BedDiameterDataFacet(
+                    ndxTop,
+                    BED_DIAMETER_DATA_TOP,
+                    Resources.getMsg(
+                        context.getMeta(),
+                        I18N_FACET_BED_DIAMETER_DATA_TOPLAYER,
+                        I18N_FACET_BED_DIAMETER_DATA_TOPLAYER,
+                        new Object[] { diameter.toUpperCase(),
+                            range.getFrom(), range.getTo(), toplayer}),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                //sublayer
+                newFacets.add(new BedDiameterDataFacet(
+                    ndxSub,
+                    BED_DIAMETER_DATA_SUB,
+                    Resources.getMsg(
+                        context.getMeta(),
+                        I18N_FACET_BED_DIAMETER_DATA_TOPLAYER,
+                        I18N_FACET_BED_DIAMETER_DATA_TOPLAYER,
+                        new Object[] { diameter.toUpperCase(),
+                            range.getFrom(), range.getTo(), sublayer}),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            for (String loadDiameter: loadDiameters) {
+                int ndx = generateIndex(loadDiameter);
+                ndx = ndx << 3;
+                ndx += i;
+                newFacets.add(new BedloadDiameterDataFacet(
+                    ndx,
+                    BEDLOAD_DIAMETER_DATA,
+                    Resources.getMsg(
+                        context.getMeta(),
+                        I18N_FACET_BEDLOAD_DIAMETER_DATA,
+                        I18N_FACET_BEDLOAD_DIAMETER_DATA,
+                        new Object[] { loadDiameter.toUpperCase(),
+                            range.getFrom(), range.getTo()}),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+        }
+    }
+
+
+    protected String getFacetName(BedQualityResultValue value) {
+        /* basename + name or "diameter" + .type */
+        return BED_QUALITY_DATA_FACET + "." +
+            (value.isDiameterResult() ? "diameter" : value.getName()) + "." +
+            value.getType();
+    }
+
     protected void generateFacets(CallContext context, List<Facet> newFacets,
         BedQualityResult[] results, String stateId, String hash) {
         log.debug("BedQualityState.generateFacets");
@@ -266,111 +263,37 @@
         for (int idx = 0; idx < results.length; idx++) {
             BedQualityResult result = results[idx];
             DateRange range = result.getDateRange();
-            BedDiameterResult[] bedDiameter = result.getBedResults();
-            for (int j = 0; j < bedDiameter.length; j++) {
-                newFacets.add(new BedDiameterTopFacet((idx << 8) + j,
-                    BED_QUALITY_BED_DIAMETER_TOPLAYER,
-                    getLayerDescription(
-                        meta,
-                        bedDiameter[j],
-                        range,
-                        I18N_FACET_BED_DIAMETER_TOPLAYER,
-                        true),
-                    ComputeType.ADVANCE, stateId, hash));
-
-                newFacets.add(new BedDiameterSubFacet((idx << 8) +j,
-                    BED_QUALITY_BED_DIAMETER_SUBLAYER,
-                    getLayerDescription(
-                        meta,
-                        bedDiameter[j],
-                        range,
-                        I18N_FACET_BED_DIAMETER_SUBLAYER,
-                        false),
-                    ComputeType.ADVANCE, stateId, hash));
-            }
-            BedloadDiameterResult[] bedloadDiameter = result.getBedloadResults();
-            for (int j = 0;  j < bedloadDiameter.length; j++) {
-                newFacets.add(new BedloadDiameterFacet(
-                    (idx << 8) + j,
-                    BED_QUALITY_BEDLOAD_DIAMETER,
-                    createDiameterDescription(
-                        meta, bedloadDiameter[j]),
+            int i = 0;
+            for (BedQualityResultValue value: result.getValues()) {
+                newFacets.add(new BedQualityDataFacet((idx << 8) + i++,
+                    getFacetName(value),
+                    getFacetDescription(meta, range, value),
                     ComputeType.ADVANCE,
-                    stateId,
-                    hash));
-
-            }
-            if (bedDiameter.length > 0) {
-                BedParametersResult[] bedParameters = result.getParameters();
-                for (int j = 0; j < bedParameters.length; j++) {
-                    newFacets.add(new BedPorosityTopFacet((idx << 8) + j,
-                        BED_QUALITY_POROSITY_TOPLAYER,
-                        getLayerDescription(
-                            meta,
-                            bedParameters[j],
-                            range,
-                            I18N_FACET_BED_POROSITY_TOPLAYER,
-                            true),
-                        ComputeType.ADVANCE, stateId, hash));
-
-                    newFacets.add(new BedPorositySubFacet((idx << 8) + j,
-                        BED_QUALITY_POROSITY_SUBLAYER,
-                        getLayerDescription(
-                            meta,
-                            bedParameters[j],
-                            range,
-                            I18N_FACET_BED_POROSITY_SUBLAYER,
-                            false),
-                        ComputeType.ADVANCE, stateId, hash));
-
-                    newFacets.add(new BedDensityTopFacet((idx << 8) + j,
-                        BED_QUALITY_SEDIMENT_DENSITY_TOPLAYER,
-                        getLayerDescription(
-                            meta,
-                            bedParameters[j],
-                            range,
-                            I18N_FACET_BED_DENSITY_TOPLAYER,
-                            true),
-                        ComputeType.ADVANCE, stateId, hash));
-
-                    newFacets.add(new BedDensitySubFacet((idx << 8) + j,
-                        BED_QUALITY_SEDIMENT_DENSITY_SUBLAYER,
-                        getLayerDescription(
-                            meta,
-                            bedParameters[j],
-                            range,
-                            I18N_FACET_BED_DENSITY_SUBLAYER,
-                            false),
-                        ComputeType.ADVANCE, stateId, hash));
-                }
+                    stateId, hash, value.getName(), value.getType()));
             }
         }
     }
 
-    protected String getLayerDescription(CallMeta meta,
-        Object result, DateRange range, String i18n, boolean topLayer) {
+    protected String getFacetDescription(CallMeta meta,
+                                         DateRange range,
+                                         BedQualityResultValue value) {
         Date from = range != null ? range.getFrom() : new Date();
         Date to = range != null ? range.getTo() : new Date();
 
-        String layer;
-        /* Maybe just a check if i18n ends with .sublayer? */
-        if (topLayer) {
-            layer = Resources.getMsg(meta, I18N_TOPLAYER, I18N_TOPLAYER);
+        final String layerSuffix =
+            Resources.getMsg(meta, "bedquality." + value.getType(), "");
+
+        /* This could probably be unified with the facet name */
+        final String i18n = I18N_FACET_BED_BASE + "." +
+            (value.isDiameterResult() ? "diameter" : value.getName()) + "." +
+            value.getType();
+
+        if (value.isDiameterResult()) {
+            /* Include the diameter in the description */
+            return Resources.getMsg(meta, i18n, i18n, new Object[] {
+                value.getName().toUpperCase(), from, to, layerSuffix });
         } else {
-            layer = Resources.getMsg(meta, I18N_SUBLAYER, I18N_SUBLAYER);
-        }
-        if (result instanceof BedDiameterResult) {
-            return Resources.getMsg(meta, i18n, i18n, new Object[] { ((BedDiameterResult)result).getType(),
-                from, to, layer });
-        } else {
-            return Resources.getMsg(meta, i18n, i18n, new Object[] { from, to, layer });
+            return Resources.getMsg(meta, i18n, i18n, new Object[] { from, to, layerSuffix });
         }
     }
-
-    protected String createDiameterDescription(CallMeta meta,
-        BedQualityDiameterResult result) {
-        return Resources.getMsg(meta, I18N_FACET_BEDLOAD_DIAMETER,
-            I18N_FACET_BEDLOAD_DIAMETER, new Object[] { result.getType() });
-    }
 }
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedQualityExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedQualityExporter.java	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedQualityExporter.java	Wed Mar 18 18:42:08 2015 +0100
@@ -22,10 +22,8 @@
 
 import au.com.bytecode.opencsv.CSVWriter;
 import org.dive4elements.river.artifacts.model.CalculationResult;
-import org.dive4elements.river.artifacts.model.minfo.BedDiameterResult;
-import org.dive4elements.river.artifacts.model.minfo.BedParametersResult;
 import org.dive4elements.river.artifacts.model.minfo.BedQualityResult;
-import org.dive4elements.river.artifacts.model.minfo.BedloadDiameterResult;
+import org.dive4elements.river.artifacts.model.minfo.BedQualityResultValue;
 import org.dive4elements.river.exports.AbstractExporter;
 import org.dive4elements.river.utils.Formatter;
 
@@ -41,20 +39,8 @@
 
     private static final String CSV_HEADER_KM =
         "export.minfo.bedquality.km";
-    private static final String CSV_HEADER_DENSITY_CAP =
-        "export.minfo.bedquality.density_cap";
-    private static final String CSV_HEADER_DENSITY_SUB =
-        "export.minfo.bedquality.density_sub";
-    private static final String CSV_HEADER_POROSITY_CAP =
-        "export.minfo.bedquality.porosity_cap";
-    private static final String CSV_HEADER_POROSITY_SUB =
-        "export.minfo.bedquality.porosity_sub";
-    private static final String CSV_HEADER_BEDLOAD =
-        "export.minfo.bedquality.bedload";
-    private static final String CSV_HEADER_BED_CAP =
-        "export.minfo.bedquality.bed_cap";
-    private static final String CSV_HEADER_BED_SUB =
-        "export.minfo.bedquality.bed_sub";
+    private static final String CSV_HEADER_BASE =
+        "export.minfo.bedquality";
 
     private BedQualityResult[] results;
 
@@ -68,53 +54,18 @@
         double[] kms = new RangeAccess((D4EArtifact) master).getKmSteps();
 
         int cols = 1;
-        for (BedQualityResult result : results) {
-            BedDiameterResult[]     beds  = result.getBedResults();
-            BedloadDiameterResult[] loads = result.getBedloadResults();
-
-            cols += beds.length * 2;
-            if (beds.length > 0) {
-                cols += 4;
-            }
-            cols += loads.length;
+        for (BedQualityResult result: results) {
+            cols += result.getValues().size();
         }
 
         List<double[]> rows = new ArrayList<double[]>(kms.length);
         for (double km: kms) {
             double[] row = new double[cols];
             row[0] = km;
-            for (int j = 0; j < results.length; j++) {
-
-                BedloadDiameterResult[] loads = results[j].getBedloadResults();
-
-                for(int k = 0; k < loads.length; k++) {
-                    // k + 1: shift km column.
-                    // j* loads.length: shift periods.
-                    row[(k + 1) + (j * loads.length)] =
-                        loads[k].getDiameterInterpol(km);
-                }
-
-                BedDiameterResult[] beds = results[j].getBedResults();
-                if (beds.length == 0) {
-                    continue;
-                }
-                for (int k = 0; k < beds.length; k++) {
-                    // k * 2 + 1: shift km column.
-                    // j * beds.length * 2: shift periods.
-                    // loads.length * results.length: shift bed load columns.
-                    int ndx = (k * 2 + 1) + (j * beds.length * 2) + (loads.length * results.length);
-                    row[ndx] = beds[k].getDiameterCapInterpol(km);
-                    row[ndx + 1] = beds[k].getDiameterSubInterpol(km);
-                }
-
-                BedParametersResult[] params = results[j].getParameters();
-                for(int k = 0; k < params.length; k++) {
-                    // loads.length + (beds.lenght * 2) * (j + 1): shift bed and bedload columns.
-                    int ndx = 1 + (loads.length + (beds.length * 2) * (j + 1));
-                    row[ndx] = params[k].getDensityCapInterpol(km);
-                    row[ndx + 1] = params[k].getDensitySubInterpol(km);
-                    row[ndx + 2] = params[k].getPorosityCapInterpol(km);
-                    row[ndx + 3] = params[k].getPorositySubInterpol(km);
+            for (BedQualityResult result: results) {
+                int i = 1;
+                for (BedQualityResultValue value: result.getValues()) {
+                    row[i++] = value.getDataInterpolated(km);
                 }
             }
             rows.add(row);
@@ -170,48 +121,25 @@
         log.debug("writeCSVHeader()");
 
         List<String> header = new ArrayList<String>();
-        if (results != null)  {
-            header.add(msg(CSV_HEADER_KM, "km"));
-            for (int i = 0; i < results.length; i++) {
-                DateFormat df = Formatter.getDateFormatter(context.getMeta(), "dd.MM.yyyy");
-                String d1 = df.format(results[i].getDateRange().getFrom());
-                String d2 = df.format(results[i].getDateRange().getTo());
-                BedloadDiameterResult[] loads = results[i].getBedloadResults();
-                BedDiameterResult[] beds = results[i].getBedResults();
-                BedParametersResult[] params = results[i].getParameters();
-                for (int j = 0; j < loads.length; j++) {
-                    header.add(msg(CSV_HEADER_BEDLOAD, CSV_HEADER_BEDLOAD) +
-                        " - " +
-                        msg(loads[j].getType().toString(),
-                            loads[j].getType().toString()) + " - " +
-                        d1 + "-" + d2);
-                }
-                for (int j = 0; j < beds.length; j++) {
-                    header.add(msg(CSV_HEADER_BED_CAP, CSV_HEADER_BED_CAP) + " - " +
-                        msg(beds[j].getType().toString(),
-                            beds[j].getType().toString()) + " - " +
-                        d1 + "-" + d2);
-                    header.add(msg(CSV_HEADER_BED_SUB, CSV_HEADER_BED_SUB) + " - " +
-                        msg(beds[j].getType().toString(),
-                            beds[j].getType().toString()) + " - " +
-                        d1 + "-" + d2);
-                }
-                if (beds.length == 0) {
-                    continue;
-                }
-                if (params.length > 0) {
-                    header.add(
-                        msg(CSV_HEADER_DENSITY_CAP, CSV_HEADER_DENSITY_CAP) +
-                        " - " + d1 + "-" + d2);
-                    header.add(
-                        msg(CSV_HEADER_DENSITY_SUB, CSV_HEADER_DENSITY_SUB) +
-                        " - " + d1 + "-" + d2);
-                    header.add(
-                        msg(CSV_HEADER_POROSITY_CAP, CSV_HEADER_POROSITY_CAP) +
-                        " - " + d1 + "-" + d2);
-                    header.add(
-                        msg(CSV_HEADER_POROSITY_SUB, CSV_HEADER_POROSITY_SUB) +
-                        " - " + d1 + "-" + d2);
+        if (results == null)  {
+            writer.writeNext(header.toArray(new String[header.size()]));
+            return;
+        }
+
+        header.add(msg(CSV_HEADER_KM, "km"));
+        DateFormat df = Formatter.getDateFormatter(context.getMeta(), "dd.MM.yyyy");
+        for (BedQualityResult result: results) {
+            String d1 = df.format(result.getDateRange().getFrom());
+            String d2 = df.format(result.getDateRange().getTo());
+            for (BedQualityResultValue value: result.getValues()) {
+                String i18n;
+                if (value.isDiameterResult()) {
+                    i18n = CSV_HEADER_BASE + ".diameter." + value.getType();
+                    header.add(msg(i18n, i18n) +
+                        " - " + value.getName() + " - " + d1 + "-" + d2);
+                } else {
+                    i18n = CSV_HEADER_BASE + "." + value.getName() + "." + value.getType();
+                    header.add(msg(i18n, i18n) + " - " + d1 + "-" + d2);
                 }
             }
         }
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/java/org/dive4elements/river/utils/DoubleUtil.java
--- a/artifacts/src/main/java/org/dive4elements/river/utils/DoubleUtil.java	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/utils/DoubleUtil.java	Wed Mar 18 18:42:08 2015 +0100
@@ -316,10 +316,10 @@
     /** Convieniance function for results to get an interpolator.
      * This is basically a static wrapper to for LinearInterpolator.interpolate
      * with error handling. Returns null on error.*/
-    public static PolynomialSplineFunction getLinearInterpolator(TDoubleArrayList x, TDoubleArrayList y) {
+    public static PolynomialSplineFunction getLinearInterpolator(double[] x, double[] y) {
         LinearInterpolator lpol = new LinearInterpolator();
         try {
-            return lpol.interpolate(x.toNativeArray(), y.toNativeArray());
+            return lpol.interpolate(x, y);
         } catch (DimensionMismatchException e) {
             log.error("KMs and Result values have different sizes. Failed to interpolate: " +
                     e.getMessage());
@@ -330,5 +330,9 @@
         }
         return null;
     }
+
+    public static PolynomialSplineFunction getLinearInterpolator(TDoubleArrayList x, TDoubleArrayList y) {
+        return getLinearInterpolator(x.toNativeArray(), y.toNativeArray());
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/resources/messages.properties
--- a/artifacts/src/main/resources/messages.properties	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/src/main/resources/messages.properties	Wed Mar 18 18:42:08 2015 +0100
@@ -321,10 +321,11 @@
 facet.bedquality.bed.density.sublayer = Density ({0,date} - {1,date}) ({2})
 facet.bedquality.bed.diameter.toplayer = {0}_Bed ({1,date} - {2,date}) ({3})
 facet.bedquality.bed.diameter.sublayer = {0}_Bed ({1,date} - {2,date}) ({3})
-facet.bedquality.bed.diameter.data.toplayer = {0} Bed ({1,date} - {2,date}) ({3}) - measurements
-facet.bedquality.bed.diameter.data.sublayer = {0} Bed ({1,date} - {2,date}) ({3}) - measurements
-facet.bedquality.bedload.diameter.data = {0} Bedload - measurements
-facet.bedquality.bedload.diameter = {0}_Bedload
+facet.bedquality.bed.diameter.toplayer.data = {0} Bed ({1,date} - {2,date}) ({3}) - measurements
+facet.bedquality.bed.diameter.sublayer.data = {0} Bed ({1,date} - {2,date}) ({3}) - measurements
+facet.bedquality.bed.diameter.bedload.data = {0} Bedload - measurements
+facet.bedquality.bed.diameter.bedload = {0}_Bedload
+facet.bedquality.interpol.suffix = " - interpolated"
 bedquality.toplayer = 0.0m - 0.3m
 bedquality.sublayer = 0.1m - 0.5m
 facet.bedheight.diff.year = Bedheight Difference {0}
@@ -482,13 +483,13 @@
 export.sqrelation.measurements.pdf.file = /jasper/sqmeasurements_en.jasper
 export.sqrelation.pdf.mode = Load Discharge Relation
 export.minfo.bedquality.km = km
-export.minfo.bedquality.density_cap = Density Toplayer
-export.minfo.bedquality.density_sub = Density Sublayer
-export.minfo.bedquality.porosity_cap = Porosity Toplayer
-export.minfo.bedquality.porosity_sub = Porosity Sublayer
-export.minfo.bedquality.bedload = Bedload Diameter
-export.minfo.bedquality.bed_cap = Bed Diameter Toplayer
-export.minfo.bedquality.bed_sub = Bed Diameter Sublayer
+export.minfo.bedquality.density.toplayer = Density Toplayer
+export.minfo.bedquality.density.sublayer = Density Sublayer
+export.minfo.bedquality.porosity.toplayer = Porosity Toplayer
+export.minfo.bedquality.porosity.sublayer = Porosity Sublayer
+export.minfo.bedquality.diameter.bedload = Bedload Diameter
+export.minfo.bedquality.diameter.toplayer = Bed Diameter Toplayer
+export.minfo.bedquality.diameter.sublayer = Bed Diameter Sublayer
 export.minfo.beddifference.km = km
 export.minfo.beddifference.diff = Bedheight Difference [cm]
 export.minfo.beddifference.diff.pair = Difference pair
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/resources/messages_de.properties
--- a/artifacts/src/main/resources/messages_de.properties	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/src/main/resources/messages_de.properties	Wed Mar 18 18:42:08 2015 +0100
@@ -322,10 +322,11 @@
 facet.bedquality.bed.density.sublayer = Dichte ({0,date} - {1,date}) ({2})
 facet.bedquality.bed.diameter.toplayer = {0}_Sohle ({1,date} - {2,date}) ({3})
 facet.bedquality.bed.diameter.sublayer = {0}_Sohle ({1,date} - {2,date}) ({3})
-facet.bedquality.bed.diameter.data.toplayer = {0} Sohle ({1,date} - {2,date}) ({3}) - Messungen
-facet.bedquality.bed.diameter.data.sublayer = {0} Sohle ({1,date} - {2,date}) ({3}) - Messungen
-facet.bedquality.bedload.diameter.data = {0} Geschiebe - Messungen
-facet.bedquality.bedload.diameter = {0}_Geschiebe
+facet.bedquality.bed.diameter.toplayer.data = {0} Sohle ({1,date} - {2,date}) ({3}) - Messungen
+facet.bedquality.bed.diameter.sublayer.data = {0} Sohle ({1,date} - {2,date}) ({3}) - Messungen
+facet.bedquality.bed.diameter.bedload.data = {0} Geschiebe - Messungen
+facet.bedquality.bed.diameter.bedload = {0}_Geschiebe
+facet.bedquality.interpol.suffix = " - interpoliert"
 bedquality.toplayer = 0,0m - 0,3m
 bedquality.sublayer = 0,1m - 0,5m
 facet.bedheight.diff.year = Sohlh\u00f6hendifferenz {0}
@@ -484,13 +485,13 @@
 export.sqrelation.measurements.pdf.file = /jasper/sqmeasurements.jasper
 export.sqrelation.pdf.mode = Transport-Abfluss Beziehung
 export.minfo.bedquality.km = km
-export.minfo.bedquality.density_cap = Sedimentdichte Deckschicht [t/m\u00b3]
-export.minfo.bedquality.density_sub = Sedimentdichte Unterschicht [t/m\u00b3]
-export.minfo.bedquality.porosity_cap = Porosit\u00e4t Deckschicht [%]
-export.minfo.bedquality.porosity_sub = Porosit\u00e4t Unterschicht [%]
-export.minfo.bedquality.bedload = Geschiebedurchmesser [mm]
-export.minfo.bedquality.bed_cap = Sohldurchmesser Deckschicht [mm]
-export.minfo.bedquality.bed_sub = Sohldurchmesser Unterschicht [mm]
+export.minfo.bedquality.density.toplayer = Sedimentdichte Deckschicht [t/m\u00b3]
+export.minfo.bedquality.density.sublayer = Sedimentdichte Unterschicht [t/m\u00b3]
+export.minfo.bedquality.porosity.toplayer = Porosit\u00e4t Deckschicht [%]
+export.minfo.bedquality.porosity.sublayer = Porosit\u00e4t Unterschicht [%]
+export.minfo.bedquality.diameter.bedload = Geschiebedurchmesser [mm]
+export.minfo.bedquality.diameter.toplayer = Sohldurchmesser Deckschicht [mm]
+export.minfo.bedquality.diameter.sublayer = Sohldurchmesser Unterschicht [mm]
 export.minfo.beddifference.km = Fluss-km
 export.minfo.beddifference.diff = Sohlh\u00f6hendifferenz [cm]
 export.minfo.beddifference.diff.pair = Differenzenpaar
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/resources/messages_de_DE.properties
--- a/artifacts/src/main/resources/messages_de_DE.properties	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/src/main/resources/messages_de_DE.properties	Wed Mar 18 18:42:08 2015 +0100
@@ -319,10 +319,11 @@
 facet.bedquality.bed.density.sublayer = Dichte ({0,date} - {1,date}) ({2})
 facet.bedquality.bed.diameter.toplayer = {0}_Sohle ({1,date} - {2,date}) ({3})
 facet.bedquality.bed.diameter.sublayer = {0}_Sohle ({1,date} - {2,date}) ({3})
-facet.bedquality.bed.diameter.data.toplayer = {0} Sohle ({1,date} - {2,date}) ({3}) - Messungen
-facet.bedquality.bed.diameter.data.sublayer = {0} Sohle ({1,date} - {2,date}) ({3}) - Messungen
-facet.bedquality.bedload.diameter.data = {0} Geschiebe - Messungen
-facet.bedquality.bedload.diameter = {0}_Geschiebe
+facet.bedquality.bed.diameter.toplayer.data = {0} Sohle ({1,date} - {2,date}) ({3}) - Messungen
+facet.bedquality.bed.diameter.sublayer.data = {0} Sohle ({1,date} - {2,date}) ({3}) - Messungen
+facet.bedquality.bed.diameter.bedload.data = {0} Geschiebe - Messungen
+facet.bedquality.bed.diameter.bedload = {0}_Geschiebe
+facet.bedquality.interpol.suffix = " - interpoliert"
 bedquality.toplayer = 0,0m - 0,3m
 bedquality.sublayer = 0,1m - 0,5m
 facet.bedheight.diff.year = Sohlh\u00f6hendifferenz {0}
@@ -480,13 +481,13 @@
 export.sqrelation.measurements.pdf.file = /jasper/sqmeasurements.jasper
 export.sqrelation.pdf.mode = Transport-Abfluss Beziehung
 export.minfo.bedquality.km = km
-export.minfo.bedquality.density_cap = Sedimentdichte Deckschicht [t/m\u00b3]
-export.minfo.bedquality.density_sub = Sedimentdichte Unterschicht [t/m\u00b3]
-export.minfo.bedquality.porosity_cap = Porosit\u00e4t Deckschicht [%]
-export.minfo.bedquality.porosity_sub = Porosit\u00e4t Unterschicht [%]
-export.minfo.bedquality.bedload = Geschiebedurchmesser [mm]
-export.minfo.bedquality.bed_cap = Sohldurchmesser Deckschicht [mm]
-export.minfo.bedquality.bed_sub = Sohldurchmesser Unterschicht [mm]
+export.minfo.bedquality.density.toplayer = Sedimentdichte Deckschicht [t/m\u00b3]
+export.minfo.bedquality.density.sublayer = Sedimentdichte Unterschicht [t/m\u00b3]
+export.minfo.bedquality.porosity.toplayer = Porosit\u00e4t Deckschicht [%]
+export.minfo.bedquality.porosity.sublayer = Porosit\u00e4t Unterschicht [%]
+export.minfo.bedquality.diameter.bedload = Geschiebedurchmesser [mm]
+export.minfo.bedquality.diameter.toplayer = Sohldurchmesser Deckschicht [mm]
+export.minfo.bedquality.diameter.sublayer = Sohldurchmesser Unterschicht [mm]
 export.minfo.beddifference.km = Fluss-km
 export.minfo.beddifference.diff = Sohlh\u00f6hendifferenz [cm]
 export.minfo.beddifference.diff.pair = Differenzenpaar
diff -r 19fde13e2db4 -r 07c9ac22f611 artifacts/src/main/resources/messages_en.properties
--- a/artifacts/src/main/resources/messages_en.properties	Tue Mar 17 18:52:00 2015 +0100
+++ b/artifacts/src/main/resources/messages_en.properties	Wed Mar 18 18:42:08 2015 +0100
@@ -323,10 +323,11 @@
 facet.bedquality.bed.density.sublayer = Density ({0,date} - {1,date}) ({2})
 facet.bedquality.bed.diameter.toplayer = {0}_Bed ({1,date} - {2,date}) ({3})
 facet.bedquality.bed.diameter.sublayer = {0}_Bed ({1,date} - {2,date}) ({3})
-facet.bedquality.bed.diameter.data.toplayer = {0} Bed ({1,date} - {2,date}) ({3}) - measurements
-facet.bedquality.bed.diameter.data.sublayer = {0} Bed ({1,date} - {2,date}) ({3}) - measurements
-facet.bedquality.bedload.diameter.data = {0} Bedload - measurements
-facet.bedquality.bedload.diameter = {0}_Bedload
+facet.bedquality.bed.diameter.toplayer.data = {0} Bed ({1,date} - {2,date}) ({3}) - measurements
+facet.bedquality.bed.diameter.sublayer.data = {0} Bed ({1,date} - {2,date}) ({3}) - measurements
+facet.bedquality.bed.diameter.bedload.data = {0} Bedload - measurements
+facet.bedquality.bed.diameter.bedload = {0}_Bedload
+facet.bedquality.interpol.suffix = " - interpolated"
 bedquality.toplayer = 0.0m - 0.3m
 bedquality.sublayer = 0.1m - 0.5m
 facet.bedheight.diff.year = Bedheight Difference {0}
@@ -484,13 +485,13 @@
 export.sqrelation.measurements.pdf.file = /jasper/sqmeasurements_en.jasper
 export.sqrelation.pdf.mode = Load Discharge Relation
 export.minfo.bedquality.km = km
-export.minfo.bedquality.density_cap = Density Toplayer [t/m\u00b3]
-export.minfo.bedquality.density_sub = Density Sublayer [t/m\u00b3]
-export.minfo.bedquality.porosity_cap = Porosity Toplayer [%]
-export.minfo.bedquality.porosity_sub = Porosity Sublayer [%]
-export.minfo.bedquality.bedload = Bedload Diameter [mm]
-export.minfo.bedquality.bed_cap = Bed Diameter Toplayer [mm]
-export.minfo.bedquality.bed_sub = Bed Diameter Sublayer [mm]
+export.minfo.bedquality.density.toplayer = Density Toplayer [t/m\u00b3]
+export.minfo.bedquality.density.sublayer = Density Sublayer [t/m\u00b3]
+export.minfo.bedquality.porosity.toplayer = Porosity Toplayer [%]
+export.minfo.bedquality.porosity.sublayer = Porosity Sublayer [%]
+export.minfo.bedquality.diameter.bedload = Bedload Diameter [mm]
+export.minfo.bedquality.diameter.toplayer = Bed Diameter Toplayer [mm]
+export.minfo.bedquality.diameter.sublayer = Bed Diameter Sublayer [mm]
 export.minfo.beddifference.km = km
 export.minfo.beddifference.diff = Bedheight Difference [cm]
 export.minfo.beddifference.diff.pair = Difference pair


More information about the Dive4Elements-commits mailing list