changeset 4392:0dace49f89a0

Merged
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Mon, 05 Nov 2012 09:18:59 +0100
parents 19ab9e23bc21 (current diff) 0f93da769082 (diff)
children 0b4926d93029
files flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.java flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.properties flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties
diffstat 41 files changed, 1905 insertions(+), 326 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Nov 02 15:13:49 2012 +0100
+++ b/.hgtags	Mon Nov 05 09:18:59 2012 +0100
@@ -16,3 +16,6 @@
 8a75cf0841b1e4a361cb547dd02616e7c1015a5b pre2.7-2012-03-16
 e1691b74f3aa888fe7b2cf78a4be3678abe6da45 flys-2.9.2
 ff74ff82f2d421c7ab1efc404828d1316d19adb7 flys-2.9.3
+651b93c10dc5aef887efef5026e87ddd5da67dee flys-2.9.4
+651b93c10dc5aef887efef5026e87ddd5da67dee flys-2.9.4
+10e277c2fe0f800f170e849c285574af6fe64ceb flys-2.9.4
--- a/flys-artifacts/doc/conf/artifacts/minfo.xml	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/doc/conf/artifacts/minfo.xml	Mon Nov 05 09:18:59 2012 +0100
@@ -187,6 +187,12 @@
                     <facets>
                         <facet name="bedheight_difference.height_year" description="A facet for absolute heights"/>
                         <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
+                        <facet name="fix_sector_average_ls_0" description="Datacage facet"/>
+                        <facet name="fix_sector_average_ls_1" description="Datacage facet"/>
+                        <facet name="fix_sector_average_ls_2" description="Datacage facet"/>
+                        <facet name="fix_sector_average_ls_3" description="Datacage facet"/>
+                        <facet name="fix_analysis_events_ls" description="Datacage facet"/>
+                        <facet name="fix_reference_events_ls" description="Datacage facet"/>
                     </facets>
                 </outputmode>
                 <outputmode name="bed_difference_year" description="output.difference_year" mime-type="img/png" type="chart">
@@ -196,6 +202,12 @@
                         <facet name="bedheight_difference.year.height1" description="A facet for raw heights."/>
                         <facet name="bedheight_difference.year.height2" description="A facet for raw heights."/>
                         <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
+                        <facet name="fix_sector_average_ls_0" description="Datacage facet"/>
+                        <facet name="fix_sector_average_ls_1" description="Datacage facet"/>
+                        <facet name="fix_sector_average_ls_2" description="Datacage facet"/>
+                        <facet name="fix_sector_average_ls_3" description="Datacage facet"/>
+                        <facet name="fix_analysis_events_ls" description="Datacage facet"/>
+                        <facet name="fix_reference_events_ls" description="Datacage facet"/>
                     </facets>
                 </outputmode>
                 <outputmode name="bed_difference_epoch" description="output.difference_epoch" mime-type="img/png" type="chart">
@@ -204,6 +216,12 @@
                         <facet name="bedheight_difference.epoch.height1" description="A facet for raw heights."/>
                         <facet name="bedheight_difference.epoch.height2" description="A facet for raw heights."/>
                         <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
+                        <facet name="fix_sector_average_ls_0" description="Datacage facet"/>
+                        <facet name="fix_sector_average_ls_1" description="Datacage facet"/>
+                        <facet name="fix_sector_average_ls_2" description="Datacage facet"/>
+                        <facet name="fix_sector_average_ls_3" description="Datacage facet"/>
+                        <facet name="fix_analysis_events_ls" description="Datacage facet"/>
+                        <facet name="fix_reference_events_ls" description="Datacage facet"/>
                     </facets>
                 </outputmode>
             </outputmodes>
@@ -355,8 +373,8 @@
         </transition>
 
         <state id="state.minfo.sediment.load.period" description="state.minfo.bed.period" state="de.intevation.flys.artifacts.states.minfo.SedimentLoadYearSelect">
-            <data name="start" type="Long"/>
-            <data name="end" type="Long"/>
+            <data name="start" type="Integer"/>
+            <data name="end" type="Integer"/>
         </state>
 
         <state id="state.minfo.sediment.load.epochs" description="state.minfo.bed.epochs" state="de.intevation.flys.artifacts.states.minfo.SedimentLoadEpochSelect">
@@ -393,8 +411,15 @@
 
         <state id="state.minfo.sediment.load.calculate" description="state.minfo.sediment.load.calculate" state="de.intevation.flys.artifacts.states.minfo.SedimentLoadCalculate">
             <outputmodes>
-                <outputmode name="dummy" description="output.dummy" mime-type="image/png" type="chart">
+                <outputmode name="sedimentload_ls" description="output.sedimentload.ls" mime-type="image/png" type="chart">
                     <facets>
+                        <facet name="sedimentload.coarse"/>
+                        <facet name="sedimentload.sand"/>
+                        <facet name="sedimentload.finemiddle"/>
+                        <facet name="sedimentload.susp_sand"/>
+                        <facet name="sedimentload.susp_sand_bed"/>
+                        <facet name="sedimentload.susp_sediment"/>
+                        <facet name="sedimentload.total"/>
                     </facets>
                 </outputmode>
             </outputmodes>
--- a/flys-artifacts/doc/conf/conf.xml	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/doc/conf/conf.xml	Mon Nov 05 09:18:59 2012 +0100
@@ -341,6 +341,8 @@
         <output-generator name="fix_waterlevel_export">de.intevation.flys.exports.WaterlevelExporter</output-generator>
         <output-generator name="fix_vollmer_wq_curve">de.intevation.flys.exports.fixings.FixWQCurveGenerator</output-generator>
         <output-generator name="fix_vollmer_wq_curve_chartinfo">de.intevation.flys.exports.fixings.FixWQCurveInfoGenerator</output-generator>
+        <output-generator name="sedimentload_ls">de.intevation.flys.exports.minfo.SedimentLoadLSGenerator</output-generator>
+        <output-generator name="sedimentload_ls_chartinfo">de.intevation.flys.exports.minfo.SedimentLoadLSInfoGenerator</output-generator>
         <!-- Error report generators. -->
         <output-generator name="discharge_longitudinal_section_report">de.intevation.flys.exports.ReportGenerator</output-generator>
         <output-generator name="waterlevel_report">de.intevation.flys.exports.ReportGenerator</output-generator>
--- a/flys-artifacts/doc/conf/meta-data.xml	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/doc/conf/meta-data.xml	Mon Nov 05 09:18:59 2012 +0100
@@ -1939,6 +1939,49 @@
           </floodmap>
         </dc:if>
 
+        <dc:comment>
+          MINFO bedheight difference
+        </dc:comment>
+
+        <dc:if test="dc:contains($artifact-outs, 'bed_difference_year') or dc:contains($artifact-outs, 'bed_difference_height_year')">
+          <fix_longitudinal_section_curve>
+            <dc:elements>
+                <dc:context>
+                  <dc:statement>
+                    SELECT m.id AS a_id, m.state AS a_state, m.gid AS a_gid, m.creation AS a_creation
+                    FROM   master_artifacts m
+                    WHERE  m.collection_id = ${collection_id} AND m.gid &lt;&gt; CAST(${artifact-id} AS uuid)
+                    AND EXISTS (
+                        SELECT id FROM artifact_data ad WHERE ad.artifact_id = m.id AND k = 'river' AND v = ${river})
+                  </dc:statement>
+                  <dc:elements>
+                      <dc:context>
+                        <dc:statement>
+                          SELECT a.gid as aid, f.id AS fid, f.name AS facet_name, f.num AS facet_num, f.description as facet_description
+                          FROM outs as o, facets as f, artifacts as a
+                          WHERE (f.name = 'fix_sector_average_ls_0' or f.name = 'fix_sector_average_ls_1' or f.name = 'fix_sector_average_ls_2'
+                                 or f.name = 'fix_sector_average_ls_3' or f.name = 'fix_analysis_events_ls' or f.name = 'fix_reference_events_ls')
+                                and f.out_id = o.id and o.artifact_id = ${a_id} and a.id = ${a_id}
+                        </dc:statement>
+                        <fix_longitudinal_section_curve>
+                            <dc:attribute name="description" value="${river} ${a_creation} ${collection_name}"/>
+                            <dc:elements>
+                            <dc:element name="${facet_name}">
+                                <dc:attribute name="description" value="${facet_description}"/>
+                                <dc:attribute name="factory"     value="fixanalysis"/>
+                                <dc:attribute name="artifact-id" value="${aid}"/>
+                                <dc:attribute name="ids"         value="${facet_num}"/>
+                                <dc:attribute name="out"         value="fix_longitudinal_section_curve"/>
+                            </dc:element>
+                            </dc:elements>
+                        </fix_longitudinal_section_curve>
+                        </dc:context>
+                    </dc:elements>
+                </dc:context>
+            </dc:elements>
+          </fix_longitudinal_section_curve>
+        </dc:if>
+
       </dc:context>
       </old_calculations>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/SedimentLoadAccess.java	Mon Nov 05 09:18:59 2012 +0100
@@ -0,0 +1,103 @@
+package de.intevation.flys.artifacts.access;
+
+import gnu.trove.TIntArrayList;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+
+public class SedimentLoadAccess
+extends RiverAccess
+{
+    private static final Logger logger = Logger.getLogger(BedHeightAccess.class);
+
+    private int[] singleIDs;
+    private int[] epochIDs;
+
+    private Double lowerKM;
+    private Double upperKM;
+
+    private String time;
+    private String unit;
+
+    public SedimentLoadAccess(FLYSArtifact artifact) {
+        super(artifact);
+    }
+
+    public Double getLowerKM() {
+        if (lowerKM == null) {
+            lowerKM = getDouble("ld_from");
+        }
+
+        return lowerKM;
+    }
+
+    public Double getUpperKM() {
+        if (upperKM == null) {
+            upperKM = getDouble("ld_to");
+        }
+
+        return upperKM;
+    }
+
+    public String getYearEpoch() {
+        if (time == null) {
+            time =  getString("ye_select");
+        }
+        return time;
+    }
+
+    public int[] getPeriod() {
+        if (getYearEpoch().equals("year") ) {
+            Integer start = getInteger("start");
+            Integer end = getInteger("end");
+            if (start == null || end == null) {
+                logger.warn("No 'start' or 'end' parameter specified!");
+                return null;
+            }
+
+            return new int[]{start.intValue(), end.intValue()};
+        }
+        return null;
+    }
+
+    public int[][] getEpochs() {
+        if (getYearEpoch().equals("epoch")) {
+            String data = getString("epochs");
+
+            if (data == null) {
+                logger.warn("No 'epochs' parameter specified!");
+                return null;
+            }
+
+            String[] parts = data.split(";");
+
+            int[][] list = new int[parts.length][];
+
+            for (int i = 0; i < parts.length; i++) {
+                String[] values = parts[i].split(",");
+                TIntArrayList ints = new TIntArrayList();
+                try {
+                    ints.add(Integer.parseInt(values[0]));
+                    ints.add(Integer.parseInt(values[1]));
+                    list[i] = ints.toNativeArray();
+                }
+                catch (NumberFormatException nfe) {
+                    logger.warn("Cannot parse int from string: '" + values + "'");
+                }
+            }
+            return list;
+        }
+
+        return null;
+    }
+
+    public String getUnit () {
+        if (unit == null) {
+            unit = getString("unit");
+        }
+        return unit;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java	Mon Nov 05 09:18:59 2012 +0100
@@ -251,6 +251,14 @@
     String BED_DIFFERENCE_EPOCH_HEIGHT1 = "bedheight_difference.epoch.height1";
     String BED_DIFFERENCE_EPOCH_HEIGHT2 = "bedheight_difference.epoch.height2";
 
+    String SEDIMENT_LOAD_COARSE        = "sedimentload.coarse";
+    String SEDIMENT_LOAD_SAND          = "sedimentload.sand";
+    String SEDIMENT_LOAD_FINEMIDDLE    = "sedimentload.finemiddle";
+    String SEDIMENT_LOAD_SUSP_SAND     = "sedimentload.susp_sand";
+    String SEDIMENT_LOAD_SUSP_SAND_BED = "sedimentload.susp_sand_bed";
+    String SEDIMENT_LOAD_SUSP_SEDIMENT = "sedimentload.susp_sediment";
+    String SEDIMENT_LOAD_TOTAL         = "sediemntload.total";
+
     String SQ_OVERVIEW       = "sq_overview";
 
     String SQ_A_CURVE       = "sq_a_curve";
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/StaticSedimentLoadCacheKey.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/StaticSedimentLoadCacheKey.java	Mon Nov 05 09:18:59 2012 +0100
@@ -1,7 +1,5 @@
 package de.intevation.flys.artifacts.model;
 
-import java.util.Date;
-
 import org.apache.commons.lang.builder.HashCodeBuilder;
 
 
@@ -12,29 +10,35 @@
     private String river;
     private double startKm;
     private double endKm;
-    private Date date;
+    private int sYear;
+    private int eYear;
 
     public StaticSedimentLoadCacheKey(
         String river,
         double startKm,
         double endKm,
-        Date date
+        int sYear,
+        int eYear
     ) {
         this.river = river;
         this.startKm = startKm;
         this.endKm = endKm;
-        this.date = date;
+        this.sYear = sYear;
+        this.eYear = eYear;
     }
 
+    @Override
     public int hashCode() {
         HashCodeBuilder builder = new HashCodeBuilder();
         builder.append(river);
         builder.append(startKm);
         builder.append(endKm);
-        builder.append(date);
+        builder.append(sYear);
+        builder.append(eYear);
         return builder.toHashCode();
     }
 
+    @Override
     public boolean equals(Object other) {
         if (!(other instanceof StaticBedHeightCacheKey)) {
             return false;
@@ -43,6 +47,7 @@
         return this.river == o.river &&
             this.startKm == o.startKm &&
             this.endKm == o.endKm &&
-            this.date == o.date;
+            this.sYear == o.sYear &&
+            this.eYear == o.eYear;
     }
 }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/extreme/ExtremeCalculation.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/extreme/ExtremeCalculation.java	Mon Nov 05 09:18:59 2012 +0100
@@ -12,7 +12,7 @@
 import de.intevation.flys.artifacts.access.ExtremeAccess;
 
 import de.intevation.flys.artifacts.math.Linear;
-import de.intevation.flys.artifacts.math.Utils;
+//import de.intevation.flys.artifacts.math.Utils;
 
 import de.intevation.flys.artifacts.math.fitting.Function;
 import de.intevation.flys.artifacts.math.fitting.FunctionFactory;
@@ -34,6 +34,8 @@
 
 import java.util.List;
 
+import java.awt.geom.Line2D;
+
 /** Calculate extrapolated W. */
 public class ExtremeCalculation
 extends      Calculation
@@ -185,46 +187,55 @@
         KMIndex<Curve> curves = new KMIndex<Curve>();
         WQKms [] wqkms = allocWQKms();
 
-        for (double km = from; km <= to; km += step) {
-            double currentKm = DoubleUtil.round(km);
+        boolean debug = log.isDebugEnabled();
 
-            if (range == null || !range.inside(currentKm)) {
+        from = DoubleUtil.round(from);
+        to = DoubleUtil.round(to);
+
+        for (double km = from; km <= to; km = DoubleUtil.round(km+step)) {
+
+            if (debug) {
+                log.debug("km: " + km);
+            }
+
+            if (range == null || !range.inside(km)) {
                 for (RangeWithValues r: ranges) {
-                    if (r.inside(currentKm)) {
+                    if (r.inside(km)) {
                         range = r;
                         break;
                     }
                 }
                 // TODO: i18n
-                addProblem(currentKm, "extreme.no.range.inner");
+                addProblem(km, "extreme.no.range.inner");
                 continue;
             }
 
-            double [][] wqs = wst.interpolateTabulated(currentKm);
+            double [][] wqs = wst.interpolateTabulated(km);
             if (wqs == null) {
                 // TODO: i18n
-                addProblem(currentKm, "extreme.no.raw.data");
+                addProblem(km, "extreme.no.raw.data");
                 continue;
             }
 
             // XXX: This should not be necessary for model data.
             if (!DoubleUtil.isValid(wqs)) {
                 // TODO: i18n
-                addProblem(currentKm, "extreme.invalid.data");
+                addProblem(km, "extreme.invalid.data");
                 continue;
             }
 
             double [][] fitWQs = extractPointsToFit(wqs);
             if (fitWQs == null) {
                 // TODO: i18n
-                addProblem(currentKm, "extreme.too.less.points");
+                addProblem(km, "extreme.too.less.points");
                 continue;
             }
 
-            double [] coeffs = doFitting(function, wqs, chiSqr);
+            double [] coeffs = doFitting(function, fitWQs, chiSqr);
             if (coeffs == null) {
                 // TODO: i18n
-                addProblem(currentKm, "extreme.fitting.failed");
+                addProblem(km, "extreme.fitting.failed");
+                continue;
             }
 
             Curve curve = new Curve(
@@ -233,7 +244,7 @@
                 coeffs,
                 chiSqr[0]);
 
-            curves.add(currentKm, curve);
+            curves.add(km, curve);
 
             double [] values = range.getValues();
 
@@ -243,10 +254,10 @@
                 double w = curve.value(q);
                 if (Double.isNaN(w)) {
                     // TODO: i18n
-                    addProblem(currentKm, "extreme.evaluate.failed", values[i]);
+                    addProblem(km, "extreme.evaluate.failed", values[i]);
                 }
                 else {
-                    wqkms[i].add(w, q, currentKm);
+                    wqkms[i].add(w, q, km);
                 }
             }
         }
@@ -275,7 +286,7 @@
 
             CurveFitter cf = new CurveFitter(lmo);
 
-            for (int i = ws.length-1; i >= 0; --i) {
+            for (int i = 0; i < ws.length; ++i) {
                 cf.addObservedPoint(qs[i], ws[i]);
             }
 
@@ -289,16 +300,13 @@
                 }
             }
         }
-        if (coeffs == null) {
-            return null;
+        if (coeffs != null) {
+            chiSqr[0] = lmo.getChiSquare();
         }
-        chiSqr[0] = lmo.getChiSquare();
         return coeffs;
     }
 
     protected double [][] extractPointsToFit(double [][] wqs) {
-        TDoubleArrayList ows = new TDoubleArrayList();
-        TDoubleArrayList oqs = new TDoubleArrayList();
 
         double [] ws = wqs[0];
         double [] qs = wqs[1];
@@ -315,48 +323,63 @@
         double q1 = qs[N-2];
         double w1 = ws[N-2];
 
+        boolean ascending = w2 > w1;
+
+        TDoubleArrayList ows = new TDoubleArrayList();
+        TDoubleArrayList oqs = new TDoubleArrayList();
+
         oqs.add(q2); oqs.add(q1);
         ows.add(w2); ows.add(w1);
 
-        int orientation = Utils.epsilonEquals(w1, w1)
-            ? 0
-            : w1 > w2
-                ? -1
-                : +1;
+        int lastDir = -2;
 
         for (int i = N-3; i >= 0; --i) {
-            double cq = qs[i];
-            double cw = qs[i];
-            int newOrientation = Utils.relativeCCW(
-                q2, w2,
-                q1, w1,
-                cq, cw);
+            double q = qs[i];
+            double w = ws[i];
 
-            if (newOrientation != 0 && newOrientation != orientation) {
+            if ((ascending && w > w1) || (!ascending && w < w1)) {
                 break;
             }
-            oqs.add(cq);
-            ows.add(cw);
 
-            if (newOrientation != 0) {
-                // rotate last out
-                q2 = q1;
-                w2 = w1;
+            int dir = Line2D.relativeCCW(q2, w2, q1, w1, q, w);
+            //int dir = Utils.relativeCCW(q2, w2, q1, w1, q, w);
+            if (lastDir == -2) {
+                lastDir = dir;
             }
-            q1 = cq;
-            w1 = cw;
+            else if (lastDir != dir) {
+                break;
+            }
+
+            oqs.add(q);
+            ows.add(w);
+            w2 = w1;
+            q2 = q1;
+            w1 = w;
+            q1 = q;
         }
 
         oqs.reverse();
         ows.reverse();
+
+        boolean debug = log.isDebugEnabled();
+        if (debug) {
+            log.debug("from table: " + N);
+            log.debug("after trim: " + oqs.size());
+        }
+
         cutPercent(ows, oqs);
 
+        if (debug) {
+            log.debug("after percent cut: " + oqs.size());
+        }
+
         return new double [][] {
             ows.toNativeArray(),
             oqs.toNativeArray()
         };
     }
 
+
     protected void cutPercent(TDoubleArrayList ws, TDoubleArrayList qs) {
         int N = qs.size();
         if (percent <= 0d || N == 0) {
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentLoad.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentLoad.java	Mon Nov 05 09:18:59 2012 +0100
@@ -1,8 +1,8 @@
 package de.intevation.flys.artifacts.model.minfo;
 
-import gnu.trove.TDoubleArrayList;
-
 import java.util.Date;
+import java.util.HashMap;
+import java.util.Set;
 
 import org.apache.log4j.Logger;
 
@@ -12,21 +12,15 @@
 public class SedimentLoad
 extends NamedObjectImpl
 {
-    private static Logger log = Logger.getLogger(BedHeight.class);
-
     protected String description;
     protected Date start;
     protected Date end;
     protected boolean isEpoch;
 
-    protected TDoubleArrayList sand_values;
-    protected TDoubleArrayList fine_middle_values;
-    protected TDoubleArrayList coarse_values;
-    protected TDoubleArrayList susp_sediment_values;
-    protected TDoubleArrayList susp_sand_bed_values;
-
+    protected HashMap<Double, SedimentLoadFraction> kms;
 
     public SedimentLoad() {
+        kms = new HashMap<Double, SedimentLoadFraction>();
     }
 
     public SedimentLoad(
@@ -35,6 +29,7 @@
         Date end,
         boolean isEpoch
     ) {
+        this();
         this.description = description;
         this.start = start;
         this.end = end;
@@ -73,63 +68,95 @@
         this.isEpoch = isEpoch;
     }
 
-    public void addSandValue(double value) {
-        this.sand_values.add(value);
-    }
-
-    public void addSandValues(TDoubleArrayList values) {
-        this.sand_values.add(values.toNativeArray());
-    }
-
-    public TDoubleArrayList getSandValues() {
-        return this.sand_values;
-    }
-
-    public void addFineMiddleValue(double value) {
-        this.fine_middle_values.add(value);
-    }
-
-    public void addFineMiddleValues(TDoubleArrayList values) {
-        this.fine_middle_values.add(values.toNativeArray());
-    }
-
-    public TDoubleArrayList getFineMiddleValues() {
-        return this.fine_middle_values;
-    }
-
-    public void addCoarseValue(double value) {
-        this.coarse_values.add(value);
+    public Set<Double> getKms() {
+        return kms.keySet();
     }
 
-    public void addCoarseValues(TDoubleArrayList values) {
-        this.coarse_values.add(values.toNativeArray());
-    }
-
-    public TDoubleArrayList getCoarseValues() {
-        return this.coarse_values;
-    }
-
-    public void addSuspSedimentValue(double value) {
-        this.susp_sediment_values.add(value);
-    }
-
-    public void addSuspSedimentValues(TDoubleArrayList values) {
-        this.susp_sediment_values.add(values.toNativeArray());
+    public void addKm(double km, SedimentLoadFraction fraction) {
+        kms.put(km, fraction);
     }
 
-   public TDoubleArrayList getSuspSedimentValues() {
-        return this.susp_sediment_values;
-    }
-
-    public void addSuspSandBedValue(double value) {
-        this.susp_sand_bed_values.add(value);
+    public SedimentLoadFraction getFraction(double km) {
+        if (kms.get(km) == null) {
+            return new SedimentLoadFraction();
+        }
+        return kms.get(km);
     }
 
-    public void addSuspSandBedValues(TDoubleArrayList values) {
-        this.susp_sand_bed_values.add(values.toNativeArray());
+    public void setCoarse(double km, double coarse) {
+        if (kms.containsKey(km)) {
+            kms.get(km).setCoarse(coarse);
+        }
+        else {
+            SedimentLoadFraction f = new SedimentLoadFraction();
+            f.setCoarse(coarse);
+            kms.put(km, f);
+        }
     }
 
-    public TDoubleArrayList getSuspSandBedValues() {
-        return this.susp_sand_bed_values;
+    public void setFineMiddle(double km, double fine_middle) {
+        if (kms.containsKey(km)) {
+            kms.get(km).setFine_middle(fine_middle);
+        }
+        else {
+            SedimentLoadFraction f = new SedimentLoadFraction();
+            f.setFine_middle(fine_middle);
+            kms.put(km, f);
+        }
+    }
+
+    public void setSand(double km, double sand) {
+        if (kms.containsKey(km)) {
+            kms.get(km).setSand(sand);
+        }
+        else {
+            SedimentLoadFraction f = new SedimentLoadFraction();
+            f.setSand(sand);
+            kms.put(km, f);
+        }
+    }
+
+    public void setSuspSand(double km, double susp_sand) {
+        if (kms.containsKey(km)) {
+            kms.get(km).setSusp_sand(susp_sand);
+        }
+        else {
+            SedimentLoadFraction f = new SedimentLoadFraction();
+            f.setSusp_sand(susp_sand);
+            kms.put(km, f);
+        }
+    }
+
+    public void setSuspSandBed(double km, double susp_sand_bed) {
+        if (kms.containsKey(km)) {
+            kms.get(km).setSusp_sand_bed(susp_sand_bed);
+        }
+        else {
+            SedimentLoadFraction f = new SedimentLoadFraction();
+            f.setSusp_sand_bed(susp_sand_bed);
+            kms.put(km, f);
+        }
+    }
+
+    public void setSuspSediment(double km, double susp_sediment) {
+        if (kms.containsKey(km)) {
+            kms.get(km).setSusp_sediment(susp_sediment);
+        }
+        else {
+            SedimentLoadFraction f = new SedimentLoadFraction();
+            f.setSusp_sediment(susp_sediment);
+            kms.put(km, f);
+        }
+    }
+
+    public void setTotal(double km, double total) {
+        if (kms.containsKey(km)) {
+            kms.get(km).setTotal(total);
+        }
+        else {
+            SedimentLoadFraction f = new SedimentLoadFraction();
+            f.setTotal(total);
+            kms.put(km, f);
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentLoadCalculation.java	Mon Nov 05 09:18:59 2012 +0100
@@ -0,0 +1,261 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import gnu.trove.TDoubleArrayList;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.jfree.util.Log;
+
+import de.intevation.flys.artifacts.access.SedimentLoadAccess;
+import de.intevation.flys.artifacts.model.Calculation;
+import de.intevation.flys.artifacts.model.CalculationResult;
+
+
+public class SedimentLoadCalculation
+extends Calculation
+{
+
+    private static final Logger logger = Logger
+        .getLogger(SedimentLoadCalculation.class);
+
+    protected String river;
+    protected String yearEpoch;
+    protected double kmUp;
+    protected double kmLow;
+    protected int[] period;
+    protected int[][] epoch;
+    protected String unit;
+
+    public SedimentLoadCalculation() {
+    }
+
+    public CalculationResult calculate(SedimentLoadAccess access) {
+        logger.info("SedimentLoadCalculation.calculate");
+
+        String river = access.getRiver();
+        String yearEpoch = access.getYearEpoch();
+        String unit = access.getUnit();
+        int[] period = null;
+        int[][] epoch = null;
+        double kmUp = access.getUpperKM();
+        double kmLow = access.getLowerKM();
+        if (yearEpoch.equals("year")) {
+            period = access.getPeriod();
+            epoch = null;
+        }
+        else if (yearEpoch.equals("epoch")) {
+            epoch = access.getEpochs();
+            period = null;
+        }
+        else {
+            addProblem("minfo.missing.year_epoch");
+        }
+
+        if (river == null) {
+            // TODO: i18n
+            addProblem("minfo.missing.river");
+        }
+
+        if (period == null && epoch == null) {
+            addProblem("minfo.missing.time");
+        }
+
+        if (!hasProblems()) {
+            this.river = river;
+            this.yearEpoch = yearEpoch;
+            this.unit = unit;
+            this.period = period;
+            this.epoch = epoch;
+            this.kmUp = kmUp;
+            this.kmLow = kmLow;
+            return internalCalculate();
+        }
+
+        return new CalculationResult();
+    }
+
+    private CalculationResult internalCalculate() {
+        logger.debug("internalCalulate; mode:" + yearEpoch);
+        if (yearEpoch.equals("year")) {
+            List<SedimentLoadResult> results =
+                new ArrayList<SedimentLoadResult>();
+            for (int i = period[0]; i <= period[1]; i++) {
+                logger.debug("calculating for year: " + i);
+                SedimentLoadResult res = calculateYear(i);
+                results.add(res);
+            }
+            return new CalculationResult(
+                results.toArray(new SedimentLoadResult[results.size()]), this);
+        }
+        else if (yearEpoch.equals("epoch")) {
+            List<SedimentLoadResult> results =
+                new ArrayList<SedimentLoadResult>();
+            for (int i = 0; i < epoch.length; i++) {
+                SedimentLoadResult res = calculateEpoch(i);
+                results.add(res);
+            }
+            return new CalculationResult(
+                results.toArray(new SedimentLoadResult[results.size()]), this);
+        }
+        else if (yearEpoch.equals("off_epoch")) {
+            List<SedimentLoadResult> results =
+                new ArrayList<SedimentLoadResult>();
+            for (int i = 0; i < epoch.length; i++) {
+                SedimentLoadResult res = calculateOffEpoch(i);
+                results.add(res);
+            }
+            return new CalculationResult(
+                results.toArray(new SedimentLoadResult[results.size()]), this);
+        }
+        return null;
+    }
+
+    private SedimentLoadResult calculateEpoch(int i) {
+        List<SedimentLoad> epochLoads = new ArrayList<SedimentLoad>();
+        for (int j = epoch[i][0]; j < epoch[i][1]; j++) {
+            epochLoads.add(SedimentLoadFactory.getLoadwithData(
+                this.river,
+                this.yearEpoch,
+                this.kmLow,
+                this.kmUp,
+                j,
+                j));
+        }
+
+        SedimentLoad resLoad = new SedimentLoad();
+        TDoubleArrayList kms = new TDoubleArrayList();
+
+        for (SedimentLoad load : epochLoads) {
+            for (double km : load.getKms()) {
+                if (!kms.contains(km)) {
+                    kms.add(km);
+                }
+            }
+        }
+
+        for (int j = 0; j < kms.size(); j++) {
+            int cSum = 0;
+            int fmSum = 0;
+            int sSum = 0;
+            int ssSum = 0;
+            int ssbSum = 0;
+            int sseSum = 0;
+            double km = kms.get(j);
+            for (SedimentLoad load : epochLoads) {
+                SedimentLoadFraction f = load.getFraction(km);
+                if (f.getCoarse() > 0d) {
+                    double c = resLoad.getFraction(km).getCoarse();
+                    resLoad.setCoarse(km, c + f.getCoarse());
+                    cSum++;
+                }
+                if (f.getFine_middle() > 0d) {
+                    double fm = resLoad.getFraction(km).getFine_middle();
+                    resLoad.setFineMiddle(km, fm + f.getFine_middle());
+                    fmSum++;
+                }
+                if (f.getSand() > 0d) {
+                    double s = resLoad.getFraction(km).getSand();
+                    resLoad.setSand(km, s + f.getSand());
+                    sSum++;
+                }
+                if (f.getSusp_sand() > 0d) {
+                    double s = resLoad.getFraction(km).getSand();
+                    resLoad.setSuspSand(km, s + f.getSusp_sand());
+                    ssSum++;
+                }
+                if (f.getSusp_sand_bed() > 0d) {
+                    double s = resLoad.getFraction(km).getSusp_sand_bed();
+                    resLoad.setSuspSandBed(km, s + f.getSusp_sand_bed());
+                    ssbSum++;
+                }
+                if (f.getSusp_sediment() > 0d) {
+                    double s = resLoad.getFraction(km).getSusp_sediment();
+                    resLoad.setSuspSediment(km, s + f.getSusp_sediment());
+                    sseSum++;
+                }
+            }
+            SedimentLoadFraction fr = resLoad.getFraction(km);
+            resLoad.setCoarse(km, fr.getCoarse()/cSum);
+            resLoad.setFineMiddle(km, fr.getFine_middle()/fmSum);
+            resLoad.setSand(km, fr.getSand()/sSum);
+            resLoad.setSuspSand(km, fr.getSusp_sand()/ssSum);
+            resLoad.setSuspSandBed(km, fr.getSusp_sand_bed()/ssbSum);
+            resLoad.setSuspSediment(km, fr.getSusp_sediment()/sseSum);
+        }
+        resLoad.setDescription("");
+        resLoad.setEpoch(true);
+
+        SedimentLoad sl = calculateTotalLoad(resLoad);
+        return new SedimentLoadResult(epoch[i][0], epoch[i][1], sl);
+    }
+
+    private SedimentLoadResult calculateOffEpoch(int i) {
+        return null;
+    }
+
+    private SedimentLoadResult calculateYear(int y) {
+        SedimentLoad load = SedimentLoadFactory.getLoadwithData(
+            this.river,
+            this.yearEpoch,
+            this.kmLow,
+            this.kmUp,
+            y,
+            y);
+
+        SedimentLoad sl = calculateTotalLoad(load);
+        if (unit.equals("m3_per_a")) {
+            SedimentLoad slu = calculateUnit(sl);
+        }
+
+        SedimentLoadResult result = new SedimentLoadResult(
+            y,
+            0,
+            sl);
+        return result;
+    }
+
+    private SedimentLoad validateData(SedimentLoad load) {
+        SedimentLoad clean = new SedimentLoad();
+        Set<Double> kms = load.getKms();
+        for (double km : kms) {
+            SedimentLoadFraction fraction = load.getFraction(km);
+            if (fraction.getCoarse() > 0 &&
+                fraction.getFine_middle() > 0 &&
+                fraction.getSand() > 0 &&
+                fraction.getSusp_sand() > 0&&
+                fraction.getSusp_sand_bed() > 0 &&
+                fraction.getSusp_sediment() > 0) {
+                clean.addKm(km, fraction);
+            }
+        }
+        return clean;
+    }
+
+    private SedimentLoad calculateTotalLoad(SedimentLoad load) {
+        Log.debug("calculateTotalLoad");
+        SedimentLoad clean = validateData(load);
+        if (clean.getKms().size() > 0) {
+            Iterator<Double> iter = clean.getKms().iterator();
+            while (iter.hasNext()) {
+                double km = iter.next();
+                SedimentLoadFraction f =clean.getFraction(km);
+                double total = f.getCoarse() +
+                    f.getFine_middle() +
+                    f.getSand() +
+                    f.getSusp_sand() +
+                    f.getSusp_sediment();
+                load.setTotal(km, total);
+            }
+        }
+        return load;
+    }
+
+    private SedimentLoad calculateUnit(SedimentLoad load) {
+        //TODO implement me!
+        return load;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentLoadFacet.java	Mon Nov 05 09:18:59 2012 +0100
@@ -0,0 +1,52 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+
+public class SedimentLoadFacet
+extends DataFacet
+{
+    private static Logger logger = Logger.getLogger(SedimentLoadFacet.class);
+
+    public SedimentLoadFacet() {
+    }
+
+    public SedimentLoadFacet(int idx, String name, String description,
+        ComputeType type, String stateId, String hash) {
+        super(idx, name, description, type, hash, stateId);
+    }
+
+    public Object getData(Artifact artifact, CallContext context) {
+        logger.debug("Get data for sediment load at index: " + index);
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(context, hash,
+            stateId, type, false);
+
+        Object[] data =
+            (SedimentLoadResult[]) res.getData(); // TODO CAST TO SPECIFIC CLASS
+
+        return data != null && data.length > index ? data[index] : null;
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        SedimentLoadFacet copy = new SedimentLoadFacet();
+        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 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentLoadFactory.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentLoadFactory.java	Mon Nov 05 09:18:59 2012 +0100
@@ -58,32 +58,34 @@
         "SELECT" +
         "       sy.description AS description, " +
         "       ti.start_time AS year, " +
-        "       syv.value AS load " +
+        "       syv.value AS load, " +
+        "       syv.station AS km " +
         "   FROM     sediment_yield sy " +
         "       JOIN rivers r ON sy.river_id = r.id " +
         "       JOIN time_intervals ti ON sy.time_interval_id = ti.id " +
-        "       JOIN sediment_yield_vales syv ON sy.id = syv.sediment_yield_id " +
+        "       JOIN sediment_yield_values syv ON sy.id = syv.sediment_yield_id " +
         "       JOIN grain_fraction gf ON sy.grain_fraction_id = gf.id " +
         "   WHERE   r.name = :name " +
         "       AND ti.start_time BETWEEN :begin AND :end " +
-        "       AND ti_stop_time IS NULL " +
+        "       AND ti.stop_time IS NULL " +
         "       AND gf.name = :grain " +
         "       AND syv.station BETWEEN :startKm AND :endKm";
 
     public static final String SQL_SELECT_EPOCHS_DATA =
         "SELECT" +
-        "       sy.description AS description," +
-        "       ti.start_time AS year," +
-        "       syv.value AS load" +
+        "       sy.description AS description, " +
+        "       ti.start_time AS year, " +
+        "       syv.value AS load, " +
+        "       syv.station AS km " +
         "   FROM     sediment_yield sy" +
         "       JOIN rivers r ON sy.river_id = r.id " +
         "       JOIN time_intervals ti ON sy.time_interval_id = ti.id" +
-        "       JOIN sediment_yield_vales syv ON sy.id = syv.sediment_yield_id" +
+        "       JOIN sediment_yield_values syv ON sy.id = syv.sediment_yield_id" +
         "       JOIN grain_fraction gf ON sy.grain_fraction_id = gf.id" +
         "   WHERE   r.name = :name" +
         "       AND ti.start_time BETWEEN :sbegin AND :send" +
-        "       AND ti_stop_time IS NOT NULL" +
-        "       AND ti_stop_time BETWEEN :ebegin AND :eend" +
+        "       AND ti.stop_time IS NOT NULL" +
+        "       AND ti.stop_time BETWEEN :ebegin AND :eend" +
         "       AND gf.name = :grain " +
         "       AND syv.station BETWEEN :startKm AND :endKm";
 
@@ -108,7 +110,7 @@
         }
 
         StaticSedimentLoadCacheKey key =
-            new StaticSedimentLoadCacheKey(river, startKm, endKm, null);
+            new StaticSedimentLoadCacheKey(river, startKm, endKm, 0, 0);
 
         Element element = cache.get(key);
 
@@ -121,7 +123,7 @@
             getSedimentLoadsUncached(river, type, startKm, endKm);
 
         if (values != null && key != null) {
-            log.debug("Store static sediment loads  values in cache.");
+            log.debug("Store static sediment load values in cache.");
             element = new Element(key, values);
             cache.put(element);
         }
@@ -133,8 +135,8 @@
         String type,
         double startKm,
         double endKm,
-        Date startDate,
-        Date endDate
+        int syear,
+        int eyear
     ) {
         log.debug("SedimentLoadFactory.getLoadWithData");
         Cache cache = CacheFactory.getCache(LOAD_DATA_CACHE_NAME);
@@ -146,12 +148,12 @@
                 type,
                 startKm,
                 endKm,
-                startDate,
-                endDate);
+                syear,
+                eyear);
         }
 
         StaticSedimentLoadCacheKey key =
-            new StaticSedimentLoadCacheKey(river, startKm, endKm, startDate);
+            new StaticSedimentLoadCacheKey(river, startKm, endKm, syear, eyear);
 
         Element element = cache.get(key);
 
@@ -160,8 +162,13 @@
             return (SedimentLoad)element.getValue();
         }
 
-        SedimentLoad values =
-            getSedimentLoadWithDataUncached(river, type, startKm, endKm, startDate, endDate);
+        SedimentLoad values = getSedimentLoadWithDataUncached(
+            river,
+            type,
+            startKm,
+            endKm,
+            syear,
+            eyear);
 
         if (values != null && key != null) {
             log.debug("Store static bed height values in cache.");
@@ -243,58 +250,52 @@
         String type,
         double startKm,
         double endKm,
-        Date sdate,
-        Date edate
+        int syear,
+        int eyear
     ) {
-        log.debug("SedimentLoadFactory.getBedHeightUncached");
+        log.debug("SedimentLoadFactory.getSedimentLoadWithDataUncached");
 
         Session session = SessionHolder.HOLDER.get();
         SQLQuery sqlQuery = null;
 
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(sdate);
-        int year = cal.get(Calendar.YEAR);
-        cal.set(year, 1, 1);
+        Calendar start = Calendar.getInstance();
+        start.set(syear, 1, 1);
         Calendar end = Calendar.getInstance();
-        end.set(year, 12, 31);
+        end.set(syear, 12, 31);
 
-        if (type.equals("single")) {
+        if (type.equals("year") || type.equals("epoch")) {
             sqlQuery = session.createSQLQuery(SQL_SELECT_SINGLES_DATA)
                 .addScalar("description", StandardBasicTypes.STRING)
                 .addScalar("year", StandardBasicTypes.DATE)
-                .addScalar("load", StandardBasicTypes.DOUBLE);
+                .addScalar("load", StandardBasicTypes.DOUBLE)
+                .addScalar("km", StandardBasicTypes.DOUBLE);
             sqlQuery.setString("name", river);
             sqlQuery.setDouble("startKm", startKm);
             sqlQuery.setDouble("endKm", endKm);
-            sqlQuery.setDate("begin", cal.getTime());
+            sqlQuery.setDate("begin", start.getTime());
             sqlQuery.setDate("end", end.getTime());
             sqlQuery.setString("grain", "total");
             List<Object []> results = sqlQuery.list();
             SedimentLoad load = new SedimentLoad();
-            if (results.size() != 1) {
-                // should not happen. throw some exception.
-                return new SedimentLoad();
-            }
             Object[] row = results.get(0);
             load = new SedimentLoad(
                     (String) row[0],
                     (Date) row[1],
                     null,
                     false);
-            load.addCoarseValues(getValues("coarse", sqlQuery));
-            load.addFineMiddleValues(getValues("fine_middle", sqlQuery));
-            load.addSandValues(getValues("sand", sqlQuery));
-            load.addSuspSandBedValues(getValues("suspended_sediment", sqlQuery));
-            load.addSuspSandBedValues(getValues("susp_sand_bed", sqlQuery));
+            getValues("coarse", sqlQuery, load);
+            getValues("fine_middle", sqlQuery, load);
+            getValues("sand", sqlQuery, load);
+            getValues("suspended_sediment", sqlQuery, load);
+            getValues("susp_sand_bed", sqlQuery, load);
+            getValues("susp_sand", sqlQuery, load);
             return load;
         }
-        else if (type.equals("epoch")) {
-            Calendar send = Calendar.getInstance();
-            send.setTime(edate);
-            int eyear = send.get(Calendar.YEAR);
-            send.set(year, 1, 1);
-            Calendar eend = Calendar.getInstance();
-            eend.set(eyear, 12, 31);
+        else if (type.equals("off_epoch")) {
+            Calendar toStart = Calendar.getInstance();
+            toStart.set(eyear, 1, 1);
+            Calendar toEnd = Calendar.getInstance();
+            toEnd.set(eyear, 12, 31);
 
             sqlQuery = session.createSQLQuery(SQL_SELECT_EPOCHS)
                 .addScalar("description", StandardBasicTypes.STRING)
@@ -304,30 +305,32 @@
             sqlQuery.setString("name", river);
             sqlQuery.setDouble("startKm", startKm);
             sqlQuery.setDouble("endKm", endKm);
-            sqlQuery.setDate("sbegin", cal.getTime());
+            sqlQuery.setDate("sbegin", start.getTime());
             sqlQuery.setDate("sbegin", end.getTime());
-            sqlQuery.setDate("ebegin",send.getTime());
-            sqlQuery.setDate("eend", eend.getTime());
+            sqlQuery.setDate("ebegin",toStart.getTime());
+            sqlQuery.setDate("eend", toEnd.getTime());
             sqlQuery.setString("grain", "total");
 
             List<Object []> results = sqlQuery.list();
 
             SedimentLoad load = new SedimentLoad();
-            if (results.size() != 1) {
-                // should not happen. throw some exception.
-                return new SedimentLoad();
-            }
             Object[] row = results.get(0);
             load = new SedimentLoad(
                     (String) row[0],
                     (Date) row[1],
                     null,
                     false);
-            load.addCoarseValues(getValues("coarse", sqlQuery));
-            load.addFineMiddleValues(getValues("fine_middle", sqlQuery));
-            load.addSandValues(getValues("sand", sqlQuery));
-            load.addSuspSandBedValues(getValues("suspended_sediment", sqlQuery));
-            load.addSuspSandBedValues(getValues("susp_sand_bed", sqlQuery));
+            TDoubleArrayList kms = new TDoubleArrayList();
+            for (int i = 0; i < results.size(); i++) {
+                row = results.get(i);
+                kms.add((Double)row[3]);
+            }
+            getValues("coarse", sqlQuery, load);
+            getValues("fine_middle", sqlQuery, load);
+            getValues("sand", sqlQuery, load);
+            getValues("suspended_sediment", sqlQuery, load);
+            getValues("susp_sand_bed", sqlQuery, load);
+            getValues("susp_sand", sqlQuery, load);
             return load;
         }
         return new SedimentLoad();
@@ -336,17 +339,38 @@
     /**
      * 
      */
-    protected static TDoubleArrayList getValues (
+    protected static void getValues (
         String fraction,
-        SQLQuery query
+        SQLQuery query,
+        SedimentLoad load
     ) {
         query.setString("grain", fraction);
         List<Object[]> results = query.list();
-        TDoubleArrayList values = new TDoubleArrayList();
         for (int i = 0; i < results.size(); i++) {
             Object[] row = results.get(i);
-            values.add(((Double)row[2]).doubleValue());
+            double km = (Double)row[3];
+            double v = -1;
+            if (row[2] != null) {
+                v = ((Double)row[2]).doubleValue();
+            }
+            if (fraction.equals("coarse")) {
+                load.setCoarse(km, v);
+            }
+            else if (fraction.equals("sand")) {
+                load.setSand(km, v);
+            }
+            else if (fraction.equals("fine_middle")) {
+                load.setFineMiddle(km, v);
+            }
+            else if (fraction.equals("suspended_sediment")) {
+                load.setSuspSediment(km, v);
+            }
+            else if (fraction.equals("sups_sand")) {
+                load.setSuspSand(km, v);
+            }
+            else if (fraction.equals("susp_sand_bed")) {
+                load.setSuspSandBed(km, v);
+            }
         }
-        return values;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentLoadFraction.java	Mon Nov 05 09:18:59 2012 +0100
@@ -0,0 +1,81 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import de.intevation.flys.artifacts.model.NamedObjectImpl;
+
+
+public class SedimentLoadFraction
+extends NamedObjectImpl
+{
+    double sand;
+    double fine_middle;
+    double coarse;
+    double susp_sand;
+    double susp_sand_bed;
+    double susp_sediment;
+    double total;
+
+    public SedimentLoadFraction() {
+        sand = 0d;
+        fine_middle = 0d;
+        coarse = 0d;
+        susp_sand = 0d;
+        susp_sand_bed = 0d;
+        susp_sediment = 0d;
+    }
+
+    public double getSand() {
+        return sand;
+    }
+
+    public void setSand(double sand) {
+        this.sand = sand;
+    }
+
+    public double getFine_middle() {
+        return fine_middle;
+    }
+
+    public void setFine_middle(double fine_middle) {
+        this.fine_middle = fine_middle;
+    }
+
+    public double getCoarse() {
+        return coarse;
+    }
+
+    public void setCoarse(double coarse) {
+        this.coarse = coarse;
+    }
+
+    public double getSusp_sand() {
+        return susp_sand;
+    }
+
+    public void setSusp_sand(double susp_sand) {
+        this.susp_sand = susp_sand;
+    }
+
+    public double getSusp_sand_bed() {
+        return susp_sand_bed;
+    }
+
+    public void setSusp_sand_bed(double susp_sand_bed) {
+        this.susp_sand_bed = susp_sand_bed;
+    }
+
+    public double getSusp_sediment() {
+        return susp_sediment;
+    }
+
+    public void setSusp_sediment(double susp_sediment) {
+        this.susp_sediment = susp_sediment;
+    }
+
+    public double getTotal() {
+        return total;
+    }
+
+    public void setTotal(double total) {
+        this.total = total;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentLoadResult.java	Mon Nov 05 09:18:59 2012 +0100
@@ -0,0 +1,183 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import gnu.trove.TDoubleArrayList;
+
+import java.io.Serializable;
+import java.util.Set;
+
+public class SedimentLoadResult
+implements Serializable
+{
+    protected int startYear;
+    protected int endYear;
+    protected SedimentLoad load;
+
+    public SedimentLoadResult() {
+    }
+
+    public SedimentLoadResult(
+        int startYear,
+        int endYear,
+        SedimentLoad load
+    ) {
+        this.startYear = startYear;
+        this.endYear = endYear;
+        this.load = load;
+    }
+
+    public int getStartYear() {
+        return this.startYear;
+    }
+
+    public void setStartYear(int year) {
+        this.startYear = year;
+    }
+
+    public int getEndYear() {
+        return this.endYear;
+    }
+
+    public void setEndYear(int year) {
+        this.endYear = year;
+    }
+
+    public double[][] getTotalData () {
+        Set<Double> kms = this.load.getKms();
+        TDoubleArrayList k = new TDoubleArrayList();
+        TDoubleArrayList total = new TDoubleArrayList();
+        for (double km : kms) {
+            if (load.getFraction(km).getTotal() > 0d) {
+                k.add(km);
+                total.add(load.getFraction(km).getTotal());
+            }
+        }
+        return new double [][] {
+            k.toNativeArray(),
+            total.toNativeArray()
+        };
+    }
+
+    public double[][] getSandData() {
+        Set<Double> kms = this.load.getKms();
+        TDoubleArrayList k = new TDoubleArrayList();
+        TDoubleArrayList sand = new TDoubleArrayList();
+        for(double km : kms) {
+            if (load.getFraction(km).getSand() > 0d) {
+                k.add(km);
+                sand.add(load.getFraction(km).getSand());
+            }
+        }
+        return new double [][] {
+            k.toNativeArray(),
+            sand.toNativeArray()
+        };
+    }
+
+    public double[][] getFineMiddleData() {
+        Set<Double> kms = this.load.getKms();
+        TDoubleArrayList k = new TDoubleArrayList();
+        TDoubleArrayList fm = new TDoubleArrayList();
+        for (double km : kms) {
+            if (load.getFraction(km).getFine_middle() > 0d) {
+                k.add(km);
+                fm.add(load.getFraction(km).getFine_middle());
+            }
+        }
+        return new double [][] {
+            k.toNativeArray(),
+            fm.toNativeArray()
+        };
+    }
+
+    public double[][] getCoarseData() {
+        Set<Double> kms = this.load.getKms();
+        TDoubleArrayList k = new TDoubleArrayList();
+        TDoubleArrayList coarse = new TDoubleArrayList();
+        for (double km : kms) {
+            if (load.getFraction(km).getCoarse() > 0d) {
+                k.add(km);
+                coarse.add(load.getFraction(km).getCoarse());
+            }
+        }
+        return new double [][] {
+            k.toNativeArray(),
+            coarse.toNativeArray()
+        };
+    }
+
+    public double[][] getSuspSandData() {
+        Set<Double> kms = this.load.getKms();
+        TDoubleArrayList k = new TDoubleArrayList();
+        TDoubleArrayList ss = new TDoubleArrayList();
+        for (double km : kms) {
+            if (load.getFraction(km).getSusp_sand() > 0d) {
+                k.add(km);
+                ss.add(load.getFraction(km).getSusp_sand());
+            }
+        }
+        return new double [][] {
+            k.toNativeArray(),
+            ss.toNativeArray()
+        };
+    }
+
+    public double[][] getSuspSandBedData() {
+        Set<Double> kms = this.load.getKms();
+        TDoubleArrayList k = new TDoubleArrayList();
+        TDoubleArrayList ss = new TDoubleArrayList();
+        for (double km : kms) {
+            if (load.getFraction(km).getSusp_sand_bed() > 0d) {
+                k.add(km);
+                ss.add(load.getFraction(km).getSusp_sand_bed());
+            }
+        }
+        return new double [][] {
+            k.toNativeArray(),
+            ss.toNativeArray()
+        };
+    }
+
+    public double[][] getSuspSedimentData() {
+        Set<Double> kms = this.load.getKms();
+        TDoubleArrayList k = new TDoubleArrayList();
+        TDoubleArrayList ss = new TDoubleArrayList();
+        for (double km : kms) {
+            if (load.getFraction(km).getSusp_sediment() > 0d) {
+                k.add(km);
+                ss.add(load.getFraction(km).getSusp_sediment());
+            }
+        }
+        return new double [][] {
+            k.toNativeArray(),
+            ss.toNativeArray()
+        };
+    }
+
+    public boolean hasCoarseData() {
+        return getCoarseData().length > 0;
+    }
+
+    public boolean hasFineMiddleData() {
+        return getFineMiddleData().length > 0;
+    }
+
+    public boolean hasSandData() {
+        return getSandData().length > 0;
+    }
+
+    public boolean hasSuspSandData() {
+        return getSuspSandData().length > 0;
+    }
+
+    public boolean hasSuspSandBedData() {
+        return getSuspSandBedData().length > 0;
+    }
+
+    public boolean hasSuspSedimentData() {
+        return getSuspSedimentData().length > 0;
+    }
+
+    public boolean hasTotalData() {
+        return getTotalData().length > 0;
+    }
+}
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MeasurementStationInfoService.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MeasurementStationInfoService.java	Mon Nov 05 09:18:59 2012 +0100
@@ -17,7 +17,6 @@
 import de.intevation.flys.model.MeasurementStation;
 import de.intevation.flys.model.Gauge;
 import de.intevation.flys.model.Range;
-import de.intevation.flys.model.River;
 import de.intevation.flys.model.TimeInterval;
 
 /**
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/extreme/ExtremeCompute.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/extreme/ExtremeCompute.java	Mon Nov 05 09:18:59 2012 +0100
@@ -21,8 +21,6 @@
 import de.intevation.flys.artifacts.resources.Resources;
 import de.intevation.flys.artifacts.states.DefaultState;
 
-import de.intevation.flys.utils.FLYSUtils;
-
 import java.util.List;
 
 import org.apache.log4j.Logger;
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/minfo/SedimentLoadCalculate.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/minfo/SedimentLoadCalculate.java	Mon Nov 05 09:18:59 2012 +0100
@@ -1,6 +1,22 @@
 package de.intevation.flys.artifacts.states.minfo;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.access.SedimentLoadAccess;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
 import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.minfo.SedimentLoadCalculation;
+import de.intevation.flys.artifacts.model.minfo.SedimentLoadFacet;
+import de.intevation.flys.artifacts.model.minfo.SedimentLoadResult;
+import de.intevation.flys.artifacts.resources.Resources;
 import de.intevation.flys.artifacts.states.DefaultState;
 
 
@@ -9,4 +25,378 @@
 implements FacetTypes 
 {
 
+    private static final long serialVersionUID = 1L;
+
+    private static final Logger logger = Logger
+        .getLogger(SedimentLoadCalculate.class);
+
+    public static final String I18N_FACET_SEDIMENTLOAD_COARSE = "facet.sedimentload.coarse";
+    public static final String I18N_FACET_SEDIMENTLOAD_SAND = "facet.sedimentload.sand";
+    public static final String I18N_FACET_SEDIMENTLOAD_FINE_MIDDLE = "facet.sedimentload.fine_middle";
+    public static final String I18N_FACET_SEDIMENTLOAD_SUSPSAND = "facet.sedimentload.susp_sand";
+    public static final String I18N_FACET_SEDIMENTLOAD_SUSPSANDBED = "facet.sediemntload.susp_sand_bed";
+    public static final String I18N_FACET_SEDIMENTLOAD_SUSPSEDIMENT = "facet.sedimentload.susp_sediment";
+    public static final String I18N_FACET_SEDIMENTLOAD_TOTAL = "facet.sedimentload.total";
+
+    @Override
+    public Object computeAdvance(FLYSArtifact artifact, String hash,
+        CallContext context, List<Facet> facets, Object old) {
+        logger.debug("SedimentLoadCalculate.computeAdvance");
+
+        List<Facet> newFacets = new ArrayList<Facet>();
+
+        SedimentLoadAccess access = new SedimentLoadAccess(artifact);
+
+        CalculationResult res = old instanceof CalculationResult ? (CalculationResult) old
+            : new SedimentLoadCalculation().calculate(access);
+
+        if (facets == null || res == null) {
+            return res;
+        }
+
+        SedimentLoadResult[] results = (SedimentLoadResult[]) res.getData();
+
+        if (results == null || results.length == 0) {
+            logger.warn("Calculation computed no results!");
+            return res;
+        }
+
+        String type = access.getYearEpoch();
+        if (type.equals("year")) {
+            generateYearFacets(context, newFacets, results, getID(), hash);
+        }
+        else if (type.equals("epoch")) {
+            generateEpochFacets(context, newFacets, results, getID(), hash);
+        }
+        else if (type.equals("off_epoch")) {
+            generateOffEpochFacets(context, newFacets, results, getID(), hash);
+        }
+        logger.debug("Created " + newFacets.size() + " new Facets.");
+
+        facets.addAll(newFacets);
+
+        return res;
+    }
+
+    protected void generateYearFacets(CallContext context, List<Facet> newFacets,
+        SedimentLoadResult[] results, String stateId, String hash) {
+        logger.debug("SedimentLoadCalculate.generateFacets");
+
+        CallMeta meta = context.getMeta();
+
+//      newFacets.add(new DataFacet(CSV, "CSV data", ComputeType.ADVANCE, hash, id));
+        for (int idx = 0; idx < results.length; idx++) {
+            SedimentLoadResult res = results[idx];
+            if (res.hasCoarseData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_COARSE,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_COARSE,
+                        I18N_FACET_SEDIMENTLOAD_COARSE) +
+                        " - " + res.getStartYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasSandData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_SAND,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_SAND,
+                        I18N_FACET_SEDIMENTLOAD_SAND) +
+                        " - " + res.getStartYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasFineMiddleData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_FINEMIDDLE,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_FINE_MIDDLE,
+                        I18N_FACET_SEDIMENTLOAD_FINE_MIDDLE) +
+                        " - " + res.getStartYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasSuspSandData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_SUSP_SAND,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSAND,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSAND)
+                        + " - " + res.getStartYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasSuspSandBedData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_SUSP_SAND_BED,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSANDBED,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSANDBED) +
+                        " - " + res.getStartYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasSuspSedimentData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_SUSP_SEDIMENT,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSEDIMENT,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSEDIMENT) +
+                        " - " + res.getStartYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+
+            }
+            if (res.hasTotalData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_TOTAL,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_TOTAL,
+                        I18N_FACET_SEDIMENTLOAD_TOTAL) +
+                        " - " + res.getStartYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+        }
+    }
+
+    protected void generateEpochFacets(
+        CallContext context,
+        List<Facet> newFacets,
+        SedimentLoadResult[] results,
+        String stateId,
+        String hash
+    ) {
+        logger.debug("SedimentLoadCalculate.generateEpochFacets");
+
+        CallMeta meta = context.getMeta();
+
+//      newFacets.add(new DataFacet(CSV, "CSV data", ComputeType.ADVANCE, hash, id));
+        for (int idx = 0; idx < results.length; idx++) {
+            SedimentLoadResult res = results[idx];
+            if (res.hasCoarseData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_COARSE,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_COARSE,
+                        I18N_FACET_SEDIMENTLOAD_COARSE) +
+                        " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasSandData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_SAND,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_SAND,
+                        I18N_FACET_SEDIMENTLOAD_SAND) +
+                        " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasFineMiddleData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_FINEMIDDLE,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_FINE_MIDDLE,
+                        I18N_FACET_SEDIMENTLOAD_FINE_MIDDLE) +
+                        " - " + res.getStartYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasSuspSandData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_SUSP_SAND,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSAND,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSAND)
+                        + " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasSuspSandBedData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_SUSP_SAND_BED,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSANDBED,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSANDBED) +
+                        " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasSuspSedimentData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_SUSP_SEDIMENT,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSEDIMENT,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSEDIMENT) +
+                        " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+
+            }
+            if (res.hasTotalData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_TOTAL,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_TOTAL,
+                        I18N_FACET_SEDIMENTLOAD_TOTAL) +
+                        " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+        }
+    }
+
+    protected void generateOffEpochFacets(
+        CallContext context,
+        List<Facet> newFacets,
+        SedimentLoadResult[] results,
+        String stateId,
+        String hash
+    ) {
+        logger.debug("SedimentLoadCalculate.generateOffEpochFacets");
+
+        CallMeta meta = context.getMeta();
+
+//      newFacets.add(new DataFacet(CSV, "CSV data", ComputeType.ADVANCE, hash, id));
+        for (int idx = 0; idx < results.length; idx++) {
+            SedimentLoadResult res = results[idx];
+            if (res.hasCoarseData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_COARSE,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_COARSE,
+                        I18N_FACET_SEDIMENTLOAD_COARSE) +
+                        " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasSandData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_SAND,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_SAND,
+                        I18N_FACET_SEDIMENTLOAD_SAND) +
+                        " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasFineMiddleData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_FINEMIDDLE,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_FINE_MIDDLE,
+                        I18N_FACET_SEDIMENTLOAD_FINE_MIDDLE) +
+                        " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasSuspSandData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_SUSP_SAND,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSAND,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSAND) +
+                        " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasSuspSandBedData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_SUSP_SAND_BED,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSANDBED,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSANDBED) +
+                        " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (res.hasSuspSedimentData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_SUSP_SEDIMENT,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSEDIMENT,
+                        I18N_FACET_SEDIMENTLOAD_SUSPSEDIMENT) +
+                        " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+
+            }
+            if (res.hasTotalData()) {
+                newFacets.add(new SedimentLoadFacet(
+                    idx,
+                    SEDIMENT_LOAD_TOTAL,
+                    Resources.getMsg(
+                        meta,
+                        I18N_FACET_SEDIMENTLOAD_TOTAL,
+                        I18N_FACET_SEDIMENTLOAD_TOTAL) +
+                        " - " + res.getStartYear() + "-" + res.getEndYear(),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+        }
+    }
 }
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java	Mon Nov 05 09:18:59 2012 +0100
@@ -1177,6 +1177,9 @@
         YAxisWalker walker = getYAxisWalker();
 
         AxisSection   as = chartSettings.getAxisSection(walker.getId(pos));
+        if (as == null) {
+            return DEFAULT_FONT_SIZE;
+        }
         Integer fontSize = as.getFontSize();
 
         return fontSize != null ? fontSize : DEFAULT_FONT_SIZE;
@@ -1250,6 +1253,11 @@
         }
 
         AxisSection as = chartSettings.getAxisSection(axisId);
+
+        if (as == null) {
+            return null;
+        }
+
         Boolean  fixed = as.isFixed();
 
         if (fixed != null && fixed) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/AbstractFixGenerator.java	Mon Nov 05 09:18:59 2012 +0100
@@ -0,0 +1,108 @@
+package de.intevation.flys.exports.fixings;
+
+import org.apache.log4j.Logger;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.flys.artifacts.model.fixings.AnalysisPeriod;
+import de.intevation.flys.artifacts.model.fixings.QWD;
+import de.intevation.flys.jfree.StyledXYSeries;
+import de.intevation.flys.utils.KMIndex;
+
+public abstract class AbstractFixGenerator extends FixChartGenerator {
+
+    public static final String I18N_DW_YAXIS_LABEL_DEFAULT  =
+            "delta W [cm]";
+
+    public static final String I18N_DW_YAXIS_LABEL =
+            "chart.fixings.longitudinalsection.yaxis.label";
+
+    private final static Logger logger =
+            Logger.getLogger(FixLongitudinalSectionGenerator.class);
+    
+    @SuppressWarnings("unchecked")
+    protected void doSectorAverageOut(ArtifactAndFacet aaf, Document doc, boolean visible, int idx) {
+        logger.debug("doSectorAverageOut" + aaf.getFacet().getIndex());
+    
+        int index = aaf.getFacet().getIndex();
+        int sectorNdx = index & 3;
+    
+        KMIndex<AnalysisPeriod> kms =
+                (KMIndex<AnalysisPeriod>)aaf.getData(context);
+    
+        if(kms == null) {
+            return;
+        }
+    
+        XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), doc);
+    
+        for (KMIndex.Entry<AnalysisPeriod> entry: kms) {
+            double km = entry.getKm();
+            AnalysisPeriod ap = entry.getValue();
+            QWD qwd = ap.getQSectorAverages()[sectorNdx];
+            if (qwd == null) {
+                continue;
+            }
+            double deltaW = qwd.getDeltaW();
+            series.add(km, deltaW);
+        }
+    
+        addAxisSeries(series, idx, visible);
+    
+    }
+
+    @SuppressWarnings("unchecked")
+    protected void doAnalysisEventsOut(ArtifactAndFacet aaf, Document doc, boolean visible, int idx) {
+        logger.debug("doAnalysisEventsOut");
+    
+        KMIndex<QWD> kms =
+                (KMIndex<QWD>)aaf.getData(context);
+    
+        if(kms == null) {
+            return;
+        }
+    
+        XYSeriesCollection col = new XYSeriesCollection();
+    
+        StyledXYSeries series = new StyledXYSeries(aaf.getFacetDescription(), false, doc);
+    
+        for (KMIndex.Entry<QWD> entry: kms) {
+            double km = entry.getKm();
+            QWD qwd = entry.getValue();
+    
+            series.add(km, qwd.getDeltaW());
+        }
+        col.addSeries(series);
+    
+        addAxisDataset(col, idx, visible);
+    }
+
+    @SuppressWarnings("unchecked")
+    protected void doReferenceEventsOut(ArtifactAndFacet aaf, Document doc, boolean visible, int idx) {
+        logger.debug("doReferenceEventOut");
+    
+        KMIndex<QWD> kms =
+                (KMIndex<QWD>)aaf.getData(context);
+    
+        if(kms == null) {
+            return;
+        }
+    
+        XYSeriesCollection col = new XYSeriesCollection();
+    
+        StyledXYSeries series = new StyledXYSeries(aaf.getFacetDescription(), false, doc);
+    
+        for (KMIndex.Entry<QWD> entry: kms) {
+            double km = entry.getKm();
+            QWD qwd = entry.getValue();
+    
+            series.add(km, qwd.getDeltaW());
+        }
+        col.addSeries(series);
+    
+        addAxisDataset(col, idx, visible);
+    }
+
+}
\ No newline at end of file
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixLongitudinalSectionGenerator.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixLongitudinalSectionGenerator.java	Mon Nov 05 09:18:59 2012 +0100
@@ -7,7 +7,6 @@
 import org.jfree.chart.plot.Marker;
 import org.jfree.chart.plot.ValueMarker;
 import org.jfree.data.xy.XYSeries;
-import org.jfree.data.xy.XYSeriesCollection;
 import org.w3c.dom.Document;
 
 import de.intevation.artifactdatabase.state.ArtifactAndFacet;
@@ -21,7 +20,7 @@
 import de.intevation.flys.utils.KMIndex;
 
 public class FixLongitudinalSectionGenerator
-extends FixChartGenerator
+extends AbstractFixGenerator
 implements FacetTypes
 {
     private static Logger logger =
@@ -36,17 +35,12 @@
     public static final String I18N_XAXIS_LABEL =
             "chart.fixings.longitudinalsection.xaxis.label";
 
-    public static final String I18N_YAXIS_LABEL =
-            "chart.fixings.longitudinalsection.yaxis.label";
-
     public static final String I18N_CHART_TITLE_DEFAULT  =
             "Fixierungsanalyse";
 
     public static final String I18N_XAXIS_LABEL_DEFAULT  =
             "[km]";
 
-    public static final String I18N_YAXIS_LABEL_DEFAULT  =
-            "delta W [cm]";
 
     public static enum YAXIS {
         dW(0);
@@ -65,13 +59,13 @@
             doSectorAverageDeviationOut(aaf, doc, visible);
         }
         else if (name.contains(FIX_SECTOR_AVERAGE_LS)) {
-            doSectorAverageOut(aaf, doc, visible);
+            doSectorAverageOut(aaf, doc, visible, YAXIS.dW.idx);
         }
         else if (name.equals(FIX_REFERENCE_EVENTS_LS)) {
-            doReferenceEventsOut(aaf, doc, visible);
+            doReferenceEventsOut(aaf, doc, visible, YAXIS.dW.idx);
         }
         else if (name.equals(FIX_ANALYSIS_EVENTS_LS)) {
-            doAnalysisEventsOut(aaf, doc, visible);
+            doAnalysisEventsOut(aaf, doc, visible, YAXIS.dW.idx);
         }
         else if (name.equals(FIX_DEVIATION_LS)) {
             doReferenceDeviationOut(aaf, doc, visible);
@@ -95,42 +89,6 @@
     }
 
     @SuppressWarnings("unchecked")
-    protected void doSectorAverageOut(
-            ArtifactAndFacet aaf,
-            Document doc,
-            boolean visible)
-    {
-        logger.debug("doSectorAverageOut" + aaf.getFacet().getIndex());
-
-        int index = aaf.getFacet().getIndex();
-        int sectorNdx = index & 3;
-
-        KMIndex<AnalysisPeriod> kms =
-                (KMIndex<AnalysisPeriod>)aaf.getData(context);
-
-        if(kms == null) {
-            return;
-        }
-
-        XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), doc);
-
-        for (KMIndex.Entry<AnalysisPeriod> entry: kms) {
-            double km = entry.getKm();
-            AnalysisPeriod ap = entry.getValue();
-            QWD qwd = ap.getQSectorAverages()[sectorNdx];
-            if (qwd == null) {
-                continue;
-            }
-            double deltaW = qwd.getDeltaW();
-            series.add(km, deltaW);
-        }
-
-        addAxisSeries(series, 0, visible);
-
-    }
-
-
-    @SuppressWarnings("unchecked")
     protected void doSectorAverageDeviationOut(
             ArtifactAndFacet aaf,
             Document doc,
@@ -220,67 +178,6 @@
         addAreaSeries(area, 0, visible);
     }
 
-    @SuppressWarnings("unchecked")
-    protected void doAnalysisEventsOut(
-            ArtifactAndFacet aaf,
-            Document doc,
-            boolean visible)
-    {
-        logger.debug("doAnalysisEventsOut");
-
-        KMIndex<QWD> kms =
-                (KMIndex<QWD>)aaf.getData(context);
-
-        if(kms == null) {
-            return;
-        }
-
-        XYSeriesCollection col = new XYSeriesCollection();
-
-        StyledXYSeries series = new StyledXYSeries(aaf.getFacetDescription(), false, doc);
-
-        for (KMIndex.Entry<QWD> entry: kms) {
-            double km = entry.getKm();
-            QWD qwd = entry.getValue();
-
-            series.add(km, qwd.getDeltaW());
-        }
-        col.addSeries(series);
-
-        addAxisDataset(col, 0, visible);
-    }
-
-    @SuppressWarnings("unchecked")
-    protected void doReferenceEventsOut(
-            ArtifactAndFacet aaf,
-            Document doc,
-            boolean visible)
-    {
-        logger.debug("doReferenceEventOut");
-
-        KMIndex<QWD> kms =
-                (KMIndex<QWD>)aaf.getData(context);
-
-        if(kms == null) {
-            return;
-        }
-
-        XYSeriesCollection col = new XYSeriesCollection();
-
-        StyledXYSeries series = new StyledXYSeries(aaf.getFacetDescription(), false, doc);
-
-        for (KMIndex.Entry<QWD> entry: kms) {
-            double km = entry.getKm();
-            QWD qwd = entry.getValue();
-
-            series.add(km, qwd.getDeltaW());
-        }
-        col.addSeries(series);
-
-        addAxisDataset(col, 0, visible);
-    }
-
-
     @Override
     protected String getDefaultChartTitle() {
         return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
@@ -293,7 +190,7 @@
 
     @Override
     protected String getDefaultYAxisLabel(int pos) {
-        return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
+        return msg(I18N_DW_YAXIS_LABEL, I18N_DW_YAXIS_LABEL_DEFAULT);
     }
 
     @Override
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixWQCurveGenerator.java	Mon Nov 05 09:18:59 2012 +0100
@@ -30,8 +30,6 @@
 import de.intevation.flys.artifacts.model.QWDDateRange;
 import de.intevation.flys.artifacts.model.WKms;
 import de.intevation.flys.artifacts.model.WQKms;
-import de.intevation.flys.artifacts.model.extreme.Curve;
-import de.intevation.flys.artifacts.model.extreme.ExtremeCurveFacet;
 import de.intevation.flys.artifacts.model.fixings.FixFunction;
 import de.intevation.flys.artifacts.model.fixings.FixWQCurveFacet;
 import de.intevation.flys.artifacts.model.fixings.QWD;
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffHeightYearGenerator.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffHeightYearGenerator.java	Mon Nov 05 09:18:59 2012 +0100
@@ -9,17 +9,17 @@
 import de.intevation.flys.artifacts.model.FacetTypes;
 import de.intevation.flys.artifacts.model.minfo.BedDiffYearResult;
 import de.intevation.flys.exports.StyledSeriesBuilder;
-import de.intevation.flys.exports.XYChartGenerator;
+import de.intevation.flys.exports.fixings.AbstractFixGenerator;
 import de.intevation.flys.jfree.FLYSAnnotation;
 import de.intevation.flys.jfree.StyledXYSeries;
 
 
 public class BedDiffHeightYearGenerator
-extends XYChartGenerator
+extends AbstractFixGenerator
 implements FacetTypes
 {
     public enum YAXIS {
-        D(0);
+        D(0), dW(1);
 
         protected int idx;
 
@@ -78,6 +78,15 @@
                 (BedDiffYearResult) bundle.getData(context),
                 bundle, attr, visible);
         }
+        else if (name.contains(FIX_SECTOR_AVERAGE_LS)) {
+            doSectorAverageOut( bundle, attr, visible, YAXIS.dW.idx);
+        }
+        else if (name.equals(FIX_REFERENCE_EVENTS_LS)) {
+            doReferenceEventsOut( bundle, attr, visible, YAXIS.dW.idx);
+        }
+        else if (name.equals(FIX_ANALYSIS_EVENTS_LS)) {
+            doAnalysisEventsOut( bundle, attr, visible, YAXIS.dW.idx);
+        }
         else if (name.equals(LONGITUDINAL_ANNOTATION)) {
             doAnnotations(
                 (FLYSAnnotation) bundle.getData(context),
@@ -99,7 +108,13 @@
 
     @Override
     protected String getDefaultYAxisLabel(int pos) {
-        return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
+        if (pos == YAXIS.D.idx) {
+            return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
+        }
+        else if (pos == YAXIS.dW.idx) {
+            return msg(I18N_DW_YAXIS_LABEL, I18N_DW_YAXIS_LABEL_DEFAULT);
+        }
+        return "default";
     }
 
     protected void doBedDifferenceYearOut(BedDiffYearResult data,
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDifferenceEpochGenerator.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDifferenceEpochGenerator.java	Mon Nov 05 09:18:59 2012 +0100
@@ -9,17 +9,17 @@
 import de.intevation.flys.artifacts.model.FacetTypes;
 import de.intevation.flys.artifacts.model.minfo.BedDiffEpochResult;
 import de.intevation.flys.exports.StyledSeriesBuilder;
-import de.intevation.flys.exports.XYChartGenerator;
+import de.intevation.flys.exports.fixings.AbstractFixGenerator;
 import de.intevation.flys.jfree.FLYSAnnotation;
 import de.intevation.flys.jfree.StyledXYSeries;
 
 
 public class BedDifferenceEpochGenerator
-extends XYChartGenerator
+extends AbstractFixGenerator
 implements FacetTypes
 {
     public enum YAXIS {
-        D(0), H(1);
+        D(0), H(1), dW(2);
 
         protected int idx;
 
@@ -88,6 +88,15 @@
             doBedDifferenceHeightsOut((BedDiffEpochResult)bundle.getData(context),
                 bundle, attr, visible, 1);
         }
+        else if (name.contains(FIX_SECTOR_AVERAGE_LS)) {
+            doSectorAverageOut( bundle, attr, visible, YAXIS.dW.idx);
+        }
+        else if (name.equals(FIX_REFERENCE_EVENTS_LS)) {
+            doReferenceEventsOut( bundle, attr, visible, YAXIS.dW.idx);
+        }
+        else if (name.equals(FIX_ANALYSIS_EVENTS_LS)) {
+            doAnalysisEventsOut( bundle, attr, visible, YAXIS.dW.idx);
+        }
         else if (name.equals(LONGITUDINAL_ANNOTATION)) {
             doAnnotations(
                 (FLYSAnnotation) bundle.getData(context),
@@ -116,6 +125,9 @@
         else if (pos == YAXIS.H.idx) {
             label = msg(I18N_SECOND_YAXIS_LABEL, I18N_SECOND_YAXIS_LABEL_DEFAULT);
         }
+        else if (pos == YAXIS.dW.idx) {
+            return msg(I18N_DW_YAXIS_LABEL, I18N_DW_YAXIS_LABEL_DEFAULT);
+        }
 
         return label;
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDifferenceYearGenerator.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDifferenceYearGenerator.java	Mon Nov 05 09:18:59 2012 +0100
@@ -9,17 +9,17 @@
 import de.intevation.flys.artifacts.model.FacetTypes;
 import de.intevation.flys.artifacts.model.minfo.BedDiffYearResult;
 import de.intevation.flys.exports.StyledSeriesBuilder;
-import de.intevation.flys.exports.XYChartGenerator;
+import de.intevation.flys.exports.fixings.AbstractFixGenerator;
 import de.intevation.flys.jfree.FLYSAnnotation;
 import de.intevation.flys.jfree.StyledXYSeries;
 
 
 public class BedDifferenceYearGenerator
-extends XYChartGenerator
+extends AbstractFixGenerator
 implements FacetTypes
 {
     public enum YAXIS {
-        D(0), M(1), H(2);
+        D(0), M(1), H(2),  dW(3);
 
         protected int idx;
 
@@ -96,6 +96,15 @@
             doBedDifferenceHeightsOut(
                 (BedDiffYearResult)bundle.getData(context),
                 bundle, attr, visible, 1);
+        } 
+        else if (name.contains(FIX_SECTOR_AVERAGE_LS)) {
+            doSectorAverageOut( bundle, attr, visible, YAXIS.dW.idx);
+        }
+        else if (name.equals(FIX_REFERENCE_EVENTS_LS)) {
+            doReferenceEventsOut( bundle, attr, visible, YAXIS.dW.idx);
+        }
+        else if (name.equals(FIX_ANALYSIS_EVENTS_LS)) {
+            doAnalysisEventsOut( bundle, attr, visible, YAXIS.dW.idx);
         }
         else if (name.equals(LONGITUDINAL_ANNOTATION)) {
             doAnnotations(
@@ -147,7 +156,9 @@
         else if (pos == YAXIS.H.idx) {
             label = msg(I18N_THIRD_YAXIS_LABEL, I18N_THIRD_YAXIS_LABEL_DEFAULT);
         }
-
+        else if (pos == YAXIS.dW.idx) {
+            label = msg(I18N_DW_YAXIS_LABEL, I18N_DW_YAXIS_LABEL_DEFAULT);
+        }
         return label;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/SedimentLoadLSGenerator.java	Mon Nov 05 09:18:59 2012 +0100
@@ -0,0 +1,215 @@
+package de.intevation.flys.exports.minfo;
+
+import org.apache.log4j.Logger;
+import org.jfree.data.xy.XYSeries;
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.minfo.SedimentLoadResult;
+import de.intevation.flys.exports.StyledSeriesBuilder;
+import de.intevation.flys.exports.XYChartGenerator;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StyledXYSeries;
+
+
+public class SedimentLoadLSGenerator
+extends XYChartGenerator
+implements FacetTypes
+{
+    public enum YAXIS {
+        L(0);
+
+        protected int idx;
+
+        private YAXIS(int c) {
+            idx = c;
+        }
+    }
+    /** The logger that is used in this generator. */
+    private static Logger logger = Logger.getLogger(BedQualityGenerator.class);
+
+    public static final String I18N_CHART_TITLE = "chart.sedimentload.ls.title";
+    public static final String I18N_XAXIS_LABEL = "chart.sedimentload.ls.xaxis.label";
+    public static final String I18N_YAXIS_LABEL = "chart.sedimentload.ls.yaxis.label.diff";
+
+    public static final String I18N_CHART_TITLE_DEFAULT = "Sedimentfracht";
+    public static final String I18N_XAXIS_LABEL_DEFAULT = "Fluss-Km";
+    public static final String I18N_YAXIS_LABEL_DEFAULT = "[t/a]";
+
+    @Override
+    protected YAxisWalker getYAxisWalker() {
+        return new YAxisWalker() {
+
+            @Override
+            public int length() {
+                return YAXIS.values().length;
+            }
+
+            @Override
+            public String getId(int idx) {
+                YAXIS[] yaxes = YAXIS.values();
+                return yaxes[idx].toString();
+            }
+        };
+    }
+
+    @Override
+    public void doOut(ArtifactAndFacet bundle, Document attr, boolean visible) {
+        String name = bundle.getFacetName();
+
+        logger.debug("doOut: " + name);
+
+        if (name == null) {
+            logger.error("No facet name for doOut(). No output generated!");
+            return;
+        }
+
+        Facet facet = bundle.getFacet();
+
+        if (facet == null) {
+            return;
+        }
+
+        if (name.equals(SEDIMENT_LOAD_COARSE)) {
+            doSedimentLoadCoarseOut(
+                (SedimentLoadResult) bundle.getData(context),
+                bundle,
+                attr,
+                visible);
+        }
+        else if (name.equals(SEDIMENT_LOAD_SAND)) {
+            doSedimentLoadSandOut(
+                (SedimentLoadResult) bundle.getData(context),
+                bundle,
+                attr,
+                visible);
+        }
+        else if (name.equals(SEDIMENT_LOAD_FINEMIDDLE)) {
+            doSedimentLoadFineMiddleOut(
+                (SedimentLoadResult) bundle.getData(context),
+                bundle,
+                attr,
+                visible);
+        }
+        else if (name.equals(SEDIMENT_LOAD_SUSP_SAND)) {
+            doSedimentLoadSandOut(
+                (SedimentLoadResult) bundle.getData(context),
+                bundle,
+                attr,
+                visible);
+        }
+        else if (name.equals(SEDIMENT_LOAD_SUSP_SAND_BED)) {
+            doSedimentLoadSuspSandBedOut(
+                (SedimentLoadResult) bundle.getData(context),
+                bundle,
+                attr,
+                visible);
+        }
+        else if (name.equals(SEDIMENT_LOAD_SUSP_SEDIMENT)) {
+            doSedimentLoadSuspSedimentOut(
+                (SedimentLoadResult) bundle.getData(context),
+                bundle,
+                attr,
+                visible);
+        }
+        else if (name.equals(SEDIMENT_LOAD_TOTAL)) {
+            doSedimentLoadTotalOut(
+                (SedimentLoadResult) bundle.getData(context),
+                bundle,
+                attr,
+                visible);
+        }
+        else if (name.equals(LONGITUDINAL_ANNOTATION)) {
+            doAnnotations(
+                (FLYSAnnotation) bundle.getData(context),
+                 bundle,
+                 attr,
+                 visible);
+        }
+    }
+
+    @Override
+    protected String getDefaultChartTitle() {
+        return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultXAxisLabel() {
+        return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultYAxisLabel(int pos) {
+        String label = "default";
+        if (pos == YAXIS.L.idx) {
+            label = msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
+        }
+        return label;
+    }
+
+    protected void doSedimentLoadCoarseOut(SedimentLoadResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getCoarseData(), true);
+
+        addAxisSeries(series, YAXIS.L.idx, visible);
+    }
+
+    protected void doSedimentLoadSandOut(SedimentLoadResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getSandData(), true);
+
+        addAxisSeries(series, YAXIS.L.idx, visible);
+    }
+
+    protected void doSedimentLoadFineMiddleOut(SedimentLoadResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getFineMiddleData(), true);
+
+        addAxisSeries(series, YAXIS.L.idx, visible);
+    }
+
+    protected void doSedimentLoadSuspSandOut(SedimentLoadResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getSuspSandData(), true);
+
+        addAxisSeries(series, YAXIS.L.idx, visible);
+    }
+
+    protected void doSedimentLoadSuspSandBedOut(SedimentLoadResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getSuspSandBedData(), true);
+
+        addAxisSeries(series, YAXIS.L.idx, visible);
+    }
+
+    protected void doSedimentLoadSuspSedimentOut(SedimentLoadResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getSuspSedimentData(), true);
+
+        addAxisSeries(series, YAXIS.L.idx, visible);
+    }
+
+    protected void doSedimentLoadTotalOut(SedimentLoadResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getTotalData(), true);
+
+        addAxisSeries(series, YAXIS.L.idx, visible);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/SedimentLoadLSInfoGenerator.java	Mon Nov 05 09:18:59 2012 +0100
@@ -0,0 +1,12 @@
+package de.intevation.flys.exports.minfo;
+
+import de.intevation.flys.exports.ChartInfoGenerator;
+
+
+public class SedimentLoadLSInfoGenerator
+extends ChartInfoGenerator
+{
+   public SedimentLoadLSInfoGenerator() {
+        super(new SedimentLoadLSGenerator());
+   }
+}
--- a/flys-artifacts/src/main/resources/messages.properties	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/resources/messages.properties	Mon Nov 05 09:18:59 2012 +0100
@@ -52,9 +52,19 @@
 state.minfo.bed.periods = Periods
 state.minfo.bed.char_diameter = Characteristic Diameter
 state.minfo.soundings = Choose Soundings
+state.minfo.sediment.load.location = Range
+state.minfo.sediment.load.year_epoch = Year/Epoch
+state.minfo.sediment.load.epochs = Epochs
+state.minfo.sediment.load.period = Years
+state.minfo.sediment.load.off_epochs = off. Epochs
+state.minfo.sediment.load.unit = Unit
+state.minfo.off_epoch = off. Epochs
+state.minfo.t_per_a = t/a
+state.minfo.m3_per_a = m\u00b3/a
 
 year=Year
 epoch=Epoch
+off_epoch = off. Epochs
 soundings = Soundings / Epochs
 
 historical.mode.w = Waterlevel Analyse
@@ -214,6 +224,17 @@
 facet.sq_relation.outlier.curve = Potenziell Durchgang {0}
 facet.sq_relation.outlier.measurement = Geschiebedaten Durchgang {0}
 
+chart.sedimentload.ls.title = Sediment load
+chart.sedimentload.ls.xaxis.label = km
+chart.sedimentload.ls.yaxis.label.diff = [t/a]
+facet.sedimentload.coarse = Coarse gravel
+facet.sedimentload.sand = Sand
+facet.sedimentload.fine_middle = Fine/Mid. gravel
+facet.sedimentload.susp_sand = Susp. Sand
+facet.sediemntload.susp_sand_bed = Bed. part Susp.Sand
+facet.sedimentload.susp_sediment = Sediement
+facet.sedimentload.total = Total
+
 facet.longitudinal_section.annotations = POIs
 facet.discharge_curves.mainvalues.q = Q (main values)
 facet.discharge_curves.mainvalues.w = W (main values)
--- a/flys-artifacts/src/main/resources/messages_de.properties	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/resources/messages_de.properties	Mon Nov 05 09:18:59 2012 +0100
@@ -52,9 +52,20 @@
 state.minfo.bed.periods = Zeitraum/Zeitr\u00e4ume
 state.minfo.bed.char_diameter = Charakteristischer Durchmesser
 state.minfo.soundings = Wahl der Peilungen
+state.minfo.sediment.load.location = Berechnungsstrecke
+state.minfo.sediment.load.year_epoch = Jahr/Zeitraum
+state.minfo.sediment.load.epochs = Epochen
+state.minfo.sediment.load.period = Jahre
+state.minfo.sediment.load.off_epochs = Amtl. Epochen
+state.minfo.off_epoch = Amtl. Epochen
+state.minfo.sediment.load.unit = Einheit
+state.minfo.t_per_a = t/a
+state.minfo.m3_per_a = m\u00b3/a
+
 
 year=Jahr
 epoch=Epoche
+off_epoch = Amtl. Epochen
 soundings = Peilungen / Epochen
 
 historical.mode.w = Wasserstandsanalyse
@@ -214,6 +225,17 @@
 facet.sq_relation.outlier.curve = Potenziell Durchgang {0}
 facet.sq_relation.outlier.measurement = Geschiebedaten Durchgang {0}
 
+chart.sedimentload.ls.title = Sedimentfracht
+chart.sedimentload.ls.xaxis.label = km
+chart.sedimentload.ls.yaxis.label.diff = [t/a]
+facet.sedimentload.coarse = Grober Kies
+facet.sedimentload.sand = Sand
+facet.sedimentload.fine_middle = Fein/Mittlerer Kies
+facet.sedimentload.susp_sand = Susp. Sand
+facet.sediemntload.susp_sand_bed = Bettbild. Anteil Susp.Sand
+facet.sedimentload.susp_sediment = Schwebstoff
+facet.sedimentload.total = Gesamt
+
 facet.longitudinal_section.annotations = Streckenfavoriten
 facet.discharge_curves.mainvalues.q = Q (Haupt- und Extremwerte)
 facet.discharge_curves.mainvalues.w = W (Haupt- und Extremwerte)
--- a/flys-artifacts/src/main/resources/messages_de_DE.properties	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/resources/messages_de_DE.properties	Mon Nov 05 09:18:59 2012 +0100
@@ -52,9 +52,19 @@
 state.minfo.bed.periods = Zeitraum/Zeitr\u00e4ume
 state.minfo.bed.char_diameter = Charakteristischer Durchmesser
 state.minfo.soundings = Wahl der Peilungen
+state.minfo.sediment.load.location = Berechnungsstrecke
+state.minfo.sediment.load.year_epoch = Jahr/Zeitraum
+state.minfo.sediment.load.epochs = Epochen
+state.minfo.sediment.load.period = Jahre
+state.minfo.sediment.load.off_epochs = Amtl. Epochen
+state.minfo.off_epoch = Amtl. Epochen
+state.minfo.sediment.load.unit = Einheit
+state.minfo.t_per_a = t/a
+state.minfo.m3_per_a = m\u00b3/a
 
 year=Jahr
 epoch=Epoche
+off_epoch = Amtl. Epoche
 soundings = Peilungen / Epochen
 
 historical.mode.w = Wasserstandsanalyse
@@ -212,6 +222,17 @@
 facet.sq_relation.outlier.curve = Potenziell Durchgang {0}
 facet.sq_relation.outlier.measurement = Geschiebedaten Durchgang {0}
 
+chart.sedimentload.ls.title = Sedimentfracht
+chart.sedimentload.ls.xaxis.label = km
+chart.sedimentload.ls.yaxis.label.diff = [t/a]
+facet.sedimentload.coarse = Grober Kies
+facet.sedimentload.sand = Sand
+facet.sedimentload.fine_middle = Fein/Mittlerer Kies
+facet.sedimentload.susp_sand = Susp. Sand
+facet.sediemntload.susp_sand_bed = Bettbild. Anteil Susp.Sand
+facet.sedimentload.susp_sediment = Schwebstoff
+facet.sedimentload.total = Gesamt
+
 facet.longitudinal_section.annotations = Streckenfavoriten
 facet.discharge_curves.mainvalues.q = Q (Haupt- und Extremwerte)
 facet.discharge_curves.mainvalues.w = W (Haupt- und Extremwerte)
--- a/flys-artifacts/src/main/resources/messages_en.properties	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-artifacts/src/main/resources/messages_en.properties	Mon Nov 05 09:18:59 2012 +0100
@@ -52,9 +52,19 @@
 state.minfo.bed.periods = Periods
 state.minfo.bed.char_diameter = Characteristic Diameter
 state.minfo.soundings = Choose Soundings
+state.minfo.sediment.load.location = Range
+state.minfo.sediment.load.year_epoch = Year/Epoch
+state.minfo.sediment.load.epochs = Epochs
+state.minfo.sediment.load.period = Years
+state.minfo.sediment.load.off_epochs = off. Epochs
+state.minfo.sediment.load.unit = Unit
+state.minfo.off_epoch = off. Epochs
+state.minfo.t_per_a = t/a
+state.minfo.m3_per_a = m\u00b3/a
 
 year=Year
 epoch=Epoch
+off_epoch = off. Epochs
 soundings = Soundings / Epochs
 
 historical.mode.w = Waterlevel Analyse
@@ -216,6 +226,17 @@
 facet.sq_relation.outlier.curve = Potenziell Durchgang {0}
 facet.sq_relation.outlier.measurement = Geschiebedaten Durchgang {0}
 
+chart.sedimentload.ls.title = Sediment load
+chart.sedimentload.ls.xaxis.label = km
+chart.sedimentload.ls.yaxis.label.diff = [t/a]
+facet.sedimentload.coarse = Coarse gravel
+facet.sedimentload.sand = Sand
+facet.sedimentload.fine_middle = Fine/Mid. gravel
+facet.sedimentload.susp_sand = Susp. Sand
+facet.sediemntload.susp_sand_bed = Bed. part Susp.Sand
+facet.sedimentload.susp_sediment = Sediement
+facet.sedimentload.total = Total
+
 facet.longitudinal_section.annotations = POIs
 facet.discharge_curves.mainvalues.q = Q (main values)
 facet.discharge_curves.mainvalues.w = W (main values)
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/SedimentYieldParser.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/SedimentYieldParser.java	Mon Nov 05 09:18:59 2012 +0100
@@ -45,6 +45,9 @@
         "_susp_Sand.csv";
 
     public static final String FRACTION_SUSP_SAND_BED =
+        "_bettbild_Anteil_susp_Sand.csv";
+
+    public static final String FRACTION_SUSP_SAND_BED_EPOCH =
         "_susp_Sand_bettbildAnteil.csv";
 
     public static final String FRACTION_SUSPENDED_SEDIMENT =
@@ -367,13 +370,16 @@
         else if (filename.endsWith(FRACTION_FINE_MIDDLE_STR)) {
             return GrainFraction.FINE_MIDDLE;
         }
-        else if (filename.endsWith(FRACTION_SAND)) {
+        else if (filename.endsWith(FRACTION_SAND) &&
+            !filename.endsWith(FRACTION_SUSP_SAND)) {
             return GrainFraction.SAND;
         }
-        else if (filename.endsWith(FRACTION_SUSP_SAND)) {
+        else if (filename.endsWith(FRACTION_SUSP_SAND) &&
+            !filename.endsWith(FRACTION_SUSP_SAND_BED)) {
             return GrainFraction.SUSP_SAND;
         }
-        else if (filename.endsWith(FRACTION_SUSP_SAND_BED)) {
+        else if (filename.endsWith(FRACTION_SUSP_SAND_BED) ||
+            filename.endsWith(FRACTION_SUSP_SAND_BED_EPOCH)) {
             return GrainFraction.SUSP_SAND_BED;
         }
         else if (filename.endsWith(FRACTION_SUSPENDED_SEDIMENT)) {
--- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.java	Mon Nov 05 09:18:59 2012 +0100
@@ -378,6 +378,8 @@
 
     String year();
 
+    String sedimentload_ls();
+
     // Gauges
 
     String gauge_mnq();
--- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.properties	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants.properties	Mon Nov 05 09:18:59 2012 +0100
@@ -85,6 +85,7 @@
 end_year = End
 period = Period
 year = Year
+sedimentload_ls = Sediment Load
 # Header images
 flysLogo = images/flys_logo.gif
 bfgLogo = images/bfg_logo.gif
--- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_de.properties	Mon Nov 05 09:18:59 2012 +0100
@@ -85,6 +85,8 @@
 end_year = Ende
 period = Zeitraum
 year = Jahr
+sedimentload_ls = Sediment Fracht
+
 # Header images
 flysLogo = images/flys_logo.gif
 bfgLogo = images/bfg_logo.gif
--- a/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/FLYSConstants_en.properties	Mon Nov 05 09:18:59 2012 +0100
@@ -85,6 +85,8 @@
 end_year = end
 period = Period
 year = Year
+sedimentload_ls = Sediment Load
+
 # Header images
 flysLogo = images/flys_logo.gif
 bfgLogo = images/bfg_logo.gif
--- a/flys-client/src/main/java/de/intevation/flys/client/client/services/SedimentLoadInfoService.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/services/SedimentLoadInfoService.java	Mon Nov 05 09:18:59 2012 +0100
@@ -4,7 +4,6 @@
 import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
 
 import de.intevation.flys.client.shared.exceptions.ServerException;
-import de.intevation.flys.client.shared.model.DischargeInfoObject;
 import de.intevation.flys.client.shared.model.SedimentLoadInfoObject;
 
 /**
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/DatacageWindow.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DatacageWindow.java	Mon Nov 05 09:18:59 2012 +0100
@@ -94,7 +94,7 @@
     public void toLoad(ToLoad toLoad) {
         destroy();
         List<Recommendation> recs = toLoad.toRecommendations();
-        loadArtifacts(recs.toArray(new Recommendation[recs.size()]));
+        loadArtifacts(recs);
     }
 
 
@@ -102,7 +102,7 @@
     public void onDoubleClick(ToLoad toLoad) {
         destroy();
         List<Recommendation> recs = toLoad.toRecommendations();
-        loadArtifacts(recs.toArray(new Recommendation[recs.size()]));
+        loadArtifacts(recs);
     }
 
 
@@ -157,14 +157,14 @@
     }
 
 
-    protected void loadArtifacts(Recommendation[] recommendations) {
+    protected void loadArtifacts(List<Recommendation> recommendations) {
         Config cfg = Config.getInstance();
 
         final Collection collection     = view.getCollection();
         final Artifact   masterArtifact = view.getArtifact();
         final String     locale         = cfg.getLocale();
 
-        this.inProgress = recommendations.length;
+        this.inProgress = recommendations.size();
 
         for (final Recommendation recommendation: recommendations) {
             // XXX: UGLY! If no reference artifact given use uuid of
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/MeasurementStationTree.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/MeasurementStationTree.java	Mon Nov 05 09:18:59 2012 +0100
@@ -2,9 +2,6 @@
 
 import java.util.Date;
 
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.i18n.client.DateTimeFormat;
 import com.google.gwt.i18n.client.NumberFormat;
 import com.google.gwt.user.client.ui.Anchor;
@@ -17,14 +14,10 @@
 import com.smartgwt.client.widgets.layout.HLayout;
 
 import de.intevation.flys.client.client.FLYS;
-import de.intevation.flys.client.shared.model.Data;
-import de.intevation.flys.client.shared.model.DataItem;
-import de.intevation.flys.client.shared.model.DataList;
 import de.intevation.flys.client.shared.model.MeasurementStation;
 import de.intevation.flys.client.shared.model.RiverInfo;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -179,8 +172,6 @@
             setStyleName("infopanel");
             Grid grid = new Grid(5, 2);
 
-            NumberFormat nf = NumberFormat.getDecimalFormat();
-
             String type = station.getMeasurementType();
             if (type != null) {
                 grid.setText(0, 0, MSG.measurement_station_type());
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/MousePositionPanel.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/MousePositionPanel.java	Mon Nov 05 09:18:59 2012 +0100
@@ -2,8 +2,6 @@
 
 import java.util.ArrayList;
 
-import com.google.gwt.i18n.client.NumberFormat;
-
 import com.smartgwt.client.widgets.Canvas;
 import com.smartgwt.client.widgets.Label;
 import com.smartgwt.client.widgets.layout.HLayout;
@@ -89,8 +87,6 @@
             addMember(xLayout);
         }
 
-        ArrayList<String> yCoordinates = new ArrayList<String>();
-        String xCoordinate = "";
         for (int i = 0; i < transformerCount; i++) {
             HLayout yLayout = null;
             // If no layout exists for this y axis, create one.
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/minfo/SedLoadDistancePanel.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/minfo/SedLoadDistancePanel.java	Mon Nov 05 09:18:59 2012 +0100
@@ -2,7 +2,6 @@
 
 import java.util.List;
 
-import com.google.gwt.core.client.GWT;
 import com.smartgwt.client.data.Record;
 import com.smartgwt.client.util.SC;
 import com.smartgwt.client.widgets.Canvas;
@@ -15,9 +14,6 @@
 import com.smartgwt.client.widgets.layout.VLayout;
 
 import de.intevation.flys.client.client.Config;
-import de.intevation.flys.client.client.event.FilterHandler;
-import de.intevation.flys.client.client.event.RangeFilterEvent;
-import de.intevation.flys.client.client.event.StringFilterEvent;
 import de.intevation.flys.client.client.ui.AbstractUIProvider;
 import de.intevation.flys.client.client.ui.DoubleRangeOnlyPanel;
 import de.intevation.flys.client.client.ui.DoubleRangePanel;
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/range/DischargeInfoDataSource.java	Fri Nov 02 15:13:49 2012 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/range/DischargeInfoDataSource.java	Mon Nov 05 09:18:59 2012 +0100
@@ -1,15 +1,11 @@
 package de.intevation.flys.client.client.ui.range;
 
-import java.util.Date;
-
 import com.google.gwt.core.client.GWT;
 
 import com.smartgwt.client.data.DataSource;
 import com.smartgwt.client.data.DataSourceField;
 import com.smartgwt.client.types.DSDataFormat;
 import com.smartgwt.client.types.FieldType;
-import com.smartgwt.client.util.DateDisplayFormatter;
-
 
 public class DischargeInfoDataSource extends DataSource {
 

http://dive4elements.wald.intevation.org