changeset 9361:2aec052d4088

Refactoring on SalixLineCalculationResult etc., calculation using MQ etc., scenario (regional+supra) csv columns and meta data added
author mschaefer
date Wed, 01 Aug 2018 18:01:11 +0200
parents ddcd52d239cd
children 392745cccede
files artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/common/UInfoResultType.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationHistoricalResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationNoScenarioResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationRegionalResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResults.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationSupraRegionalResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineExporter.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineState.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixScenario.java artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java artifacts/src/main/resources/messages.properties artifacts/src/main/resources/messages_de.properties
diffstat 16 files changed, 357 insertions(+), 477 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/common/UInfoResultType.java	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/common/UInfoResultType.java	Wed Aug 01 18:01:11 2018 +0200
@@ -40,7 +40,7 @@
         return null;
     }
 
-    public static final UInfoResultType customMultiRowColSalixRegionalValue_Dwspl = new UInfoResultType(null, "uinfo.export.salix_line.csv.header.scenario") {
+    public static final UInfoResultType customMultiRowColSalixScenarios = new UInfoResultType(null, "uinfo.export.salix_line.csv.header.scenario") {
         private static final long serialVersionUID = 1L;
 
         @Override
@@ -54,39 +54,7 @@
         }
     };
 
-    public static final UInfoResultType salix_line_scenario = new UInfoResultType(null, "uinfo.export.salix_line.csv.header.scenario") {
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        public String exportValue(final CallContext context, final Object value) {
-            final double doubleValue = asDouble(value);
-            return exportDoubleValue(context, doubleValue);
-        }
-
-        @Override
-        protected NumberFormat createFormatter(final CallContext context) {
-            // REMARK: other modules use Formatter.getWaterlevelW(context) instead, but that format with a variable number of
-            // digits.
-            return Formatter.getSalixLine(context);
-        }
-    };
-
-    public static final UInfoResultType salix_line_scenario_dwspl = new UInfoResultType(null, "uinfo.export.salix_line.csv.header.scenario_dwspl") {
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        public String exportValue(final CallContext context, final Object value) {
-            final String valueStr = ((int) value == 0) ? "" : String.valueOf(value);
-            return exportStringValue(valueStr);
-        }
-
-        @Override
-        protected NumberFormat createFormatter(final CallContext context) {
-
-            return Formatter.getIntegerFormatter(context);
-        }
-    };
-    public static final UInfoResultType salix_delta_mw = new UInfoResultType(null, "uinfo.export.salix_line.csv.header.delta_mw") {
+    public static final UInfoResultType salix_mw_mnw = new UInfoResultType(null, "uinfo.export.salix_line.csv.header.mw_mnw") {
         private static final long serialVersionUID = 1L;
 
         @Override
@@ -120,23 +88,6 @@
         }
     };
 
-    public static final UInfoResultType salixlinehist = new UInfoResultType(null, "uinfo.export.salix_line.csv.header.hist") {
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        public String exportValue(final CallContext context, final Object value) {
-            final double doubleValue = asDouble(value);
-            return exportDoubleValue(context, doubleValue);
-        }
-
-        @Override
-        protected NumberFormat createFormatter(final CallContext context) {
-            // REMARK: other modules use Formatter.getWaterlevelW(context) instead, but that format with a variable number of
-            // digits.
-            return Formatter.getSalixLine(context);
-        }
-    };
-
     public static final UInfoResultType vegname = new UInfoResultType(null, "uinfo.export.csv.meta.header.veg.name") {
         private static final long serialVersionUID = 1L;
 
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java	Wed Aug 01 18:01:11 2018 +0200
@@ -17,6 +17,7 @@
 import org.apache.commons.lang.math.DoubleRange;
 import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.river.artifacts.access.RangeAccess;
+import org.dive4elements.river.artifacts.common.GeneralResultType;
 import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.CalculationResult;
 import org.dive4elements.river.artifacts.resources.Resources;
@@ -61,87 +62,14 @@
         final SalixLineCalculator calculator = new SalixLineCalculator(riverInfoProvider);
         final NavigableMap<Double, List<Double>> rangeScenarios = buildRangeScenarios(accessSalix);
 
-        calculator.execute(problems, uinfo, rangeScenarios, scenarioType, buildScenarioLabels(accessSalix), results);
+        calculator.execute(problems, uinfo, rangeScenarios, scenarioType, buildScenarioLabels(accessSalix), buildPartialRangeString(accessSalix),
+                buildAdditionalString(accessSalix), results);
 
-        // final Collection<ResultRow> rows = new ArrayList<>();
-        // SalixLineCalculationNoScenarioResult result = null; // verzweigung etwas ungünstig. möglicherweise auch die
-        // Abstraktion. ist erstmal nur ne idee
-        // final ResultRow row1 = ResultRow.create(). //
-        // putValue(BunduResultType.station, 100).//
-        // putValue(UInfoResultType.salixline, 28).//
-        // putValue(UInfoResultType.salix_delta_mw, 2);
-        //
-        // if (!useScenario) {
-        //
-        // rows.add(row1);
-        // result = new SalixLineCalculationNoScenarioResult("Ergebnis 1", null, rows);
-        // } else {
-        //
-        // if (scenario.equals("scenarioType.option1")) { // REGIONAL
-        //
-        // final int[] scenarios = accessSalix.getRegionalScenarioIntegers();
-        // final List<SalixScenario> list = new ArrayList<>();
-        // for (final int scen_val : scenarios) {
-        // list.add(new SalixScenario(scen_val, 666.));// TODO: replace 666 by real calculated value
-        // }
-        // row1.putValue(UInfoResultType.customMultiRowColSalixRegionalValue_Dwspl, list);//
-        // rows.add(row1);
-        // result = new SalixLineCalculationRegionalResult("Ergebnis 1 regional test", null, rows, scenarios);
-        //
-        // } else if (scenario.equals("scenarioType.option2")) { // SUPRA-REGIONAL
-        //
-        // final String supraRegional = accessSalix.getSupraRegionalString();
-        // final List<SalixZone> list = SalixZone.parse(supraRegional);
-        //
-        // final Map<DoubleRange, SalixScenario> rangeScenarioMap = new HashMap<>();
-        // // make double range
-        // for (int i = 0; i < list.size(); i++) {
-        // final SalixZone zone = list.get(i);
-        // final double upper = i < list.size() - 1 ? (zone.getUpperFromTo() - 0.0001) : zone.getUpperFromTo() + 0.0001;//
-        // "halboffenes Intervall
-        //
-        // final DoubleRange zonerange = new DoubleRange((double) zone.getLowerFromTo(), upper);
-        // final double salixValue = 666.;// TODO: calculate the salix value
-        // final SalixScenario salixscen = new SalixScenario(zone.getDwsplValue(), salixValue);
-        //
-        // rangeScenarioMap.put(zonerange, salixscen);
-        // }
-        //
-        // // make calculation
-        // double currentKm = range.getMinimumDouble();
-        // final double step = 0.1; // TODO: get from global setting?
-        // while (currentKm < range.getMaximumDouble()) {
-        // final ResultRow rowSupraRegional = ResultRow.create(). //
-        // putValue(BunduResultType.station, currentKm).//
-        // putValue(UInfoResultType.salixline, 28).//
-        // putValue(UInfoResultType.salix_delta_mw, 2);
-        //
-        // final SalixScenario scenarioCurrentKm = findScenarioByKm(currentKm, rangeScenarioMap);
-        //
-        // if (scenarioCurrentKm != null) { // should not happen, scenarioCurrentKm == null -> BUG
-        // rowSupraRegional.putValue(UInfoResultType.salix_line_scenario, scenarioCurrentKm.getSalixValue());
-        // rowSupraRegional.putValue(UInfoResultType.salix_line_scenario_dwspl, scenarioCurrentKm.getDwspl());
-        // }
-        // rows.add(rowSupraRegional);
-        //
-        // currentKm = currentKm + step;
-        // }
-        //
-        // result = new SalixLineCalculationSupraRegionalResult("Ergebnis 1 supra regional test", null, rows);
-        //
-        // } else if (scenario.equals("scenarioType.option3")) { // HISTORICAL
-        // row1.putValue(UInfoResultType.salixlinehist, 66).//
-        // putValue(UInfoResultType.salix_line_scenario_dwspl, 88);
-        // rows.add(row1);
-        // result = new SalixLineCalculationHistoricalResult("Ergebnis 1 historical test", null, rows);
-        // }
-        // }
-        // results.addResult(result, problems);
         return new CalculationResult(results, problems);
     }
 
     /**
-     * Build a map of delta-Ws by km-range for the selected scenario
+     * Build a map of delta-Ws by from-km for the selected scenario
      */
     private NavigableMap<Double, List<Double>> buildRangeScenarios(final SalixLineAccess access) {
         final NavigableMap<Double, List<Double>> rangeScenarios = new TreeMap<>();
@@ -207,6 +135,68 @@
                 if (deltaws[i] != 0)
                     labels.add(Integer.toString(deltaws[i]) + " cm");
         }
+        else if (access.getScenario() == ScenarioType.SUPRAREGIONAL)
+            labels.add(Resources.getMsg(this.context.getMeta(), "uinfo_salix_scenario_supraregional"));
+        else if (access.getScenario() == ScenarioType.HISTORICAL)
+            labels.add(Resources.getMsg(this.context.getMeta(), "uinfo_salix_scenario_historical"));
         return labels.toArray(new String[labels.size()]);
     }
+
+    /**
+     * Build the km range string for the scenario type
+     */
+    private String buildPartialRangeString(final SalixLineAccess access) {
+        if ((access.getScenario() == ScenarioType.REGIONAL) || (access.getScenario() == ScenarioType.HISTORICAL)) {
+            return String.format("%s - %s", GeneralResultType.station.exportValue(this.context, access.getFromPart().doubleValue()),
+                    GeneralResultType.station.exportValue(this.context, access.getToPart().doubleValue()));
+        }
+        if (access.getScenario() == ScenarioType.SUPRAREGIONAL) {
+            String ranges = "";
+            String sep = "";
+            final List<SalixZone> parts = SalixZone.parse(access.getSupraRegionalString());
+            for (final SalixZone part : parts) {
+                if (part.getDwsplValue() != 0) {
+                    ranges = ranges + sep + String.format("%s - %s", GeneralResultType.station.exportValue(this.context, part.getFromKm().doubleValue()),
+                            GeneralResultType.station.exportValue(this.context, part.getToKm().doubleValue()));
+                    sep = ", ";
+                }
+            }
+            return ranges;
+        }
+        return "";
+    }
+
+    /**
+     * Build the delta w or time string for the scenario type
+     */
+    private String buildAdditionalString(final SalixLineAccess access) {
+        if (access.getScenario() == ScenarioType.REGIONAL) {
+            String deltas = "";
+            String sep = "";
+            for (final int d : access.getRegionalScenarioIntegers()) {
+                deltas = deltas + sep + Integer.toString(d);
+                sep = ", ";
+            }
+            return deltas;
+        }
+        if (access.getScenario() == ScenarioType.HISTORICAL) {
+            if (access.getYear() != null)
+                return access.getYear().toString();
+            else
+                return access.getEpoch().toString();
+        }
+        if (access.getScenario() == ScenarioType.SUPRAREGIONAL) {
+            String deltas = "";
+            String sep = "";
+            final List<SalixZone> parts = SalixZone.parse(access.getSupraRegionalString());
+            for (final SalixZone part : parts) {
+                if (part.getDwsplValue() != 0) {
+                    deltas = deltas + sep + Integer.toString(part.getDwsplValue());
+                    sep = ", ";
+                }
+            }
+            return deltas;
+        }
+        return "";
+    }
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationHistoricalResult.java	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationHistoricalResult.java	Wed Aug 01 18:01:11 2018 +0200
@@ -12,32 +12,24 @@
 import java.util.Collection;
 
 import org.dive4elements.river.artifacts.common.ExportContextCSV;
-import org.dive4elements.river.artifacts.common.IExportContext;
 import org.dive4elements.river.artifacts.common.ResultRow;
-import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
-import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType;
 
 /**
  * @author Domenico Nardi Tironi
  */
-final class SalixLineCalculationHistoricalResult extends SalixLineCalculationNoScenarioResult {
+final class SalixLineCalculationHistoricalResult extends SalixLineCalculationResult {
 
     private static final long serialVersionUID = 1L;
 
-    public SalixLineCalculationHistoricalResult(final String label, final Collection<ResultRow> rows) {
-        super(label, rows);
+    private final String timeString;
+
+    public SalixLineCalculationHistoricalResult(final String label, final String[] scenarioLabels, final String partialRangeString, final String timeString,
+            final Collection<ResultRow> rows) {
+
+        super(label, scenarioLabels, partialRangeString, "", rows);
+        this.timeString = timeString;
     }
 
-    @Override
-    public void writeCSVHeader(final ExportContextCSV exportContextCSV, final RiverInfo river) {
-
-        final Collection<String> header = super.writeNoScenarioHeader(exportContextCSV);
-
-        header.add(exportContextCSV.formatCsvHeader(UInfoResultType.salixlinehist));
-        header.add(exportContextCSV.formatCsvHeader(UInfoResultType.salix_line_scenario_dwspl));
-
-        exportContextCSV.writeCSVLine(header.toArray(new String[header.size()]));
-    }
 
     @Override
     protected void writeCSVResultMetadata(final ExportContextCSV exportContextCSV) {
@@ -45,29 +37,20 @@
         exportContextCSV.writeBlankLine();
     }
 
-    @Override
-    protected String[] formatRow(final IExportContext context, final ResultRow row) {
-
-        final Collection<String> lines = super.getNoScenarioFormat(row, context);
-
-        if (context instanceof ExportContextCSV) { // enum gespart - pdf-export hat ja nur die drei spalten
-            lines.add(context.formatRowValue(row, UInfoResultType.salixlinehist));
-            lines.add(context.formatRowValue(row, UInfoResultType.salix_line_scenario_dwspl));
+    private void writeHistoricalViewCSVMetadata(final ExportContextCSV exportContextCSV) {
 
-        }
-        return lines.toArray(new String[lines.size()]);
-    }
+        final String main = "uinfo.export.csv.meta.header.salix";
+        final String mainSub = "uinfo.export.csv.meta.header.salix.historical";
 
-    private void writeHistoricalViewCSVMetadata(final ExportContextCSV exportContextCSV) {
-        final String main = "uinfo.export.csv.meta.header.salix.historical";
         // "##Historische Betrachtung"
-        exportContextCSV.writeCSVMetaEntry(main);
+        exportContextCSV.writeCSVMetaEntry(mainSub);
 
-        final String mainSub = "uinfo.export.csv.meta.header.salix";
         // "# Teilabschnitt: "
-        exportContextCSV.writeCSVMetaEntry(mainSub + ".teilabschnitt");
+        exportContextCSV.writeCSVMetaEntry(main + ".teilabschnitt", this.getPartialRangeString());
 
         // "# Historischer Zeitpunkt: "
-        exportContextCSV.writeCSVMetaEntry(main + ".zeitpunkt");
+        exportContextCSV.writeCSVMetaEntry(mainSub + ".zeitpunkt", this.timeString);
+
+        exportContextCSV.writeBlankLine();
     }
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationNoScenarioResult.java	Wed Aug 01 17:13:52 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
- * Software engineering by
- *  Björnsen Beratende Ingenieure GmbH
- *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-package org.dive4elements.river.artifacts.uinfo.salix;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.dive4elements.river.artifacts.common.AbstractCalculationExportableResult;
-import org.dive4elements.river.artifacts.common.ExportContextCSV;
-import org.dive4elements.river.artifacts.common.ExportContextPDF;
-import org.dive4elements.river.artifacts.common.GeneralResultType;
-import org.dive4elements.river.artifacts.common.IExportContext;
-import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource;
-import org.dive4elements.river.artifacts.common.ResultRow;
-import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
-import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType;
-
-/**
- * @author Domenico Nardi Tironi
- */
-class SalixLineCalculationNoScenarioResult extends AbstractCalculationExportableResult {
-
-    private static final long serialVersionUID = 1L;
-    private static final String JASPER_FILE = "/jasper/templates/uinfo.salixline.jrxml";
-
-    public SalixLineCalculationNoScenarioResult(final String label, final Collection<ResultRow> rows) {
-        super(label, rows);
-    }
-
-    @Override
-    public void writeCSVHeader(final ExportContextCSV exportContextCSV, final RiverInfo river) {
-        final Collection<String> header = writeNoScenarioHeader(exportContextCSV);
-        exportContextCSV.writeCSVLine(header.toArray(new String[header.size()]));
-    }
-
-    protected final Collection<String> writeNoScenarioHeader(final ExportContextCSV exportContextCSV) {
-        final Collection<String> header = new ArrayList<>();
-        header.add(exportContextCSV.formatCsvHeader(GeneralResultType.station));
-        header.add(exportContextCSV.formatCsvHeader(UInfoResultType.salixline));
-        header.add(exportContextCSV.formatCsvHeader(UInfoResultType.salix_delta_mw));
-        return header;
-    }
-
-    @Override
-    protected String[] formatCSVRow(final ExportContextCSV exportContextCSV, final ResultRow row) {
-        return formatRow(exportContextCSV, row);
-    }
-
-    @Override
-    protected String[] formatPDFRow(final ExportContextPDF exportContextPDF, final ResultRow row) {
-        return formatRow(exportContextPDF, row);
-    }
-
-    @Override
-    protected String getJasperFile() {
-        return JASPER_FILE;
-    }
-
-    @Override
-    protected void addJRTableHeader(final ExportContextPDF exportContextPDF, final MetaAndTableJRDataSource source) {
-
-        /* additional column headings */
-        exportContextPDF.addJRMetadata(source, "station_header", GeneralResultType.station);
-        exportContextPDF.addJRMetadata(source, "salix_line", UInfoResultType.salixline);
-        exportContextPDF.addJRMetadata(source, "salix_delta_mw", UInfoResultType.salix_delta_mw);
-    }
-
-    protected String[] formatRow(final IExportContext context, final ResultRow row) {
-        final Collection<String> lines = getNoScenarioFormat(row, context);
-        return lines.toArray(new String[lines.size()]);
-    }
-
-    protected final Collection<String> getNoScenarioFormat(final ResultRow row, final IExportContext context) {
-
-        final Collection<String> lines = new ArrayList<>();
-        lines.add(context.formatRowValue(row, GeneralResultType.station));
-        lines.add(context.formatRowValue(row, UInfoResultType.salixline));
-        lines.add(context.formatRowValue(row, UInfoResultType.salix_delta_mw));
-
-        return lines;
-    }
-
-    protected final void writeRegionalCommonCSVMeta(final ExportContextCSV exportContextCSV) {
-        final String main = "uinfo.export.csv.meta.header.salix";
-        // "# Teilabschnitt: "
-        exportContextCSV.writeCSVMetaEntry(main + ".teilabschnitt");
-        // "# Mittelwasserspiegellagenänderung: "
-        exportContextCSV.writeCSVMetaEntry(main + ".mwspiegellaenderung");
-    }
-
-    @Override
-    protected void writeCSVResultMetadata(final ExportContextCSV exportContextCSV) {
-        // do nothing. subclass may override
-    }
-}
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationRegionalResult.java	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationRegionalResult.java	Wed Aug 01 18:01:11 2018 +0200
@@ -9,116 +9,39 @@
  */
 package org.dive4elements.river.artifacts.uinfo.salix;
 
-import java.text.NumberFormat;
 import java.util.Collection;
-import java.util.List;
 
-import org.apache.commons.lang.StringUtils;
 import org.dive4elements.river.artifacts.common.ExportContextCSV;
-import org.dive4elements.river.artifacts.common.GeneralResultType;
-import org.dive4elements.river.artifacts.common.IExportContext;
 import org.dive4elements.river.artifacts.common.ResultRow;
-import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
-import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType;
-
-import gnu.trove.TDoubleArrayList;
 
 /**
  * @author Domenico Nardi Tironi
  */
-final class SalixLineCalculationRegionalResult extends SalixLineCalculationNoScenarioResult {
+final class SalixLineCalculationRegionalResult extends SalixLineCalculationResult {
 
     private static final long serialVersionUID = 1L;
 
-    private final String[] scenarioLabels;
-
-    public SalixLineCalculationRegionalResult(final String label, final String[] scenarioLabels, final Collection<ResultRow> rows) {
-        super(label, rows);
-        this.scenarioLabels = scenarioLabels;
-    }
-
-    public final int getScenarioCount() {
-        return (this.scenarioLabels != null) ? this.scenarioLabels.length : 0;
-    }
+    public SalixLineCalculationRegionalResult(final String label, final String[] scenarioLabels, final String partialRangeString, final String deltaWString,
+            final Collection<ResultRow> rows) {
 
-    public String getScenarioLabel(final int i) {
-        if ((this.scenarioLabels != null) && (i < this.scenarioLabels.length))
-            return this.scenarioLabels[i];
-
-        return "";
-    }
-
-    @Override
-    public void writeCSVHeader(final ExportContextCSV exportContextCSV, final RiverInfo river) {
-
-        final Collection<String> header = super.writeNoScenarioHeader(exportContextCSV);
-
-        for (int i = 1; i <= getScenarioCount(); i++) {
-            header.add(exportContextCSV.msg(SalixScenario.getScenarioValueHeader()));
-            header.add(exportContextCSV.msg(SalixScenario.getDwsplHeader()));
-        }
-        exportContextCSV.writeCSVLine(header.toArray(new String[header.size()]));
+        super(label, scenarioLabels, partialRangeString, deltaWString, rows);
     }
 
     @Override
     protected void writeCSVResultMetadata(final ExportContextCSV exportContextCSV) {
-        writeRegionalEffectsCSVMetadata(exportContextCSV);
+
+        final String main = "uinfo.export.csv.meta.header.salix";
+        final String mainSub = "uinfo.export.csv.meta.header.salix.regional";
+
+        // "##Regional wirkende Eingriffe"
+        exportContextCSV.writeCSVMetaEntry(mainSub);
+
+        // "# Teilabschnitte: "
+        exportContextCSV.writeCSVMetaEntry(main + ".teilabschnitt", this.getPartialRangeString());
+
+        // "# Mittelwasserspiegellagenänderung: "
+        exportContextCSV.writeCSVMetaEntry(main + ".mwspiegelaenderung", this.getDeltaWString());
+
         exportContextCSV.writeBlankLine();
     }
-
-    @Override
-    protected String[] formatRow(final IExportContext context, final ResultRow row) {
-
-        final Collection<String> lines = super.getNoScenarioFormat(row, context);
-
-        if (context instanceof ExportContextCSV) { // enum gespart - pdf-export hat ja nur die drei spalten
-            final NumberFormat formatter = ((ExportContextCSV) context).getSalixScenFormatter();
-            final List<SalixScenario> scenList = (List<SalixScenario>) row.getValue(UInfoResultType.customMultiRowColSalixRegionalValue_Dwspl);
-
-            for (final SalixScenario scenario : scenList) {
-                // scenario unused; index wurde ja verworfen, stattdessen 2 spalten
-                if (scenario == null) {
-                    lines.add(StringUtils.EMPTY);
-                    lines.add(StringUtils.EMPTY);
-                } else {
-                    lines.add(scenario.getSalixValueFormatted(formatter));
-                    lines.add(scenario.getDwsplFormatted());
-                }
-            }
-        }
-        return lines.toArray(new String[lines.size()]);
-    }
-
-    private void writeRegionalEffectsCSVMetadata(final ExportContextCSV exportContextCSV) {
-        final String main = "uinfo.export.csv.meta.header.salix.regional";
-        // "##Regional wirkende Eingriffe"
-        exportContextCSV.writeCSVMetaEntry(main);
-        writeRegionalCommonCSVMeta(exportContextCSV);
-    }
-
-    /**
-     * Gets a longitudinal section of W, Q, or flood duration of one of the waterlevels
-     */
-    public final double[][] getScenarioPoints(final int dataIndex) {
-
-        final Collection<ResultRow> rows = getRows();
-
-        final TDoubleArrayList xPoints = new TDoubleArrayList(rows.size());
-        final TDoubleArrayList yPoints = new TDoubleArrayList(rows.size());
-
-        for (final ResultRow row : rows) {
-
-            final double station = row.getDoubleValue(GeneralResultType.station);
-
-            final List<SalixScenario> scenarios = (List<SalixScenario>) row.getValue(UInfoResultType.customMultiRowColSalixRegionalValue_Dwspl);
-            final SalixScenario salixScenario = scenarios.get(dataIndex);
-            if (salixScenario != null) {
-                final double value = salixScenario.getSalixValue();
-                xPoints.add(station);
-                yPoints.add(value);
-            }
-        }
-
-        return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() };
-    }
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResult.java	Wed Aug 01 18:01:11 2018 +0200
@@ -0,0 +1,174 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.uinfo.salix;
+
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.dive4elements.river.artifacts.common.AbstractCalculationExportableResult;
+import org.dive4elements.river.artifacts.common.ExportContextCSV;
+import org.dive4elements.river.artifacts.common.ExportContextPDF;
+import org.dive4elements.river.artifacts.common.GeneralResultType;
+import org.dive4elements.river.artifacts.common.IExportContext;
+import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource;
+import org.dive4elements.river.artifacts.common.ResultRow;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType;
+
+import gnu.trove.TDoubleArrayList;
+
+/**
+ * @author Domenico Nardi Tironi
+ */
+class SalixLineCalculationResult extends AbstractCalculationExportableResult {
+
+    private static final long serialVersionUID = 1L;
+    private static final String JASPER_FILE = "/jasper/templates/uinfo.salixline.jrxml";
+
+    private final String[] scenarioLabels;
+
+    private final String partialRangeString;
+
+    private final String deltaWString;
+
+    public SalixLineCalculationResult(final String label, final Collection<ResultRow> rows) {
+        this(label, new String[] {}, "", "", rows);
+    }
+
+    public SalixLineCalculationResult(final String label, final String[] scenarioLabels, final String partialRangeString, final String deltaWString,
+            final Collection<ResultRow> rows) {
+        super(label, rows);
+        this.scenarioLabels = scenarioLabels;
+        this.partialRangeString = partialRangeString;
+        this.deltaWString = deltaWString;
+    }
+
+    public final int getScenarioCount() {
+        return (this.scenarioLabels != null) ? this.scenarioLabels.length : 0;
+    }
+
+    public String getScenarioLabel(final int i) {
+        if ((this.scenarioLabels != null) && (i < this.scenarioLabels.length))
+            return this.scenarioLabels[i];
+
+        return "";
+    }
+
+    public String getPartialRangeString() {
+        return this.partialRangeString;
+    }
+
+    public String getDeltaWString() {
+        return this.deltaWString;
+    }
+
+    @Override
+    public void writeCSVHeader(final ExportContextCSV exportContextCSV, final RiverInfo river) {
+
+        final Collection<String> header = new ArrayList<>();
+
+        header.add(exportContextCSV.formatCsvHeader(GeneralResultType.station));
+        header.add(exportContextCSV.formatCsvHeader(UInfoResultType.salixline));
+        header.add(exportContextCSV.formatCsvHeader(UInfoResultType.salix_mw_mnw));
+
+        for (int i = 1; i <= getScenarioCount(); i++) {
+            header.add(exportContextCSV.msg(SalixScenario.getDeltaWHeader()));
+            header.add(exportContextCSV.msg(SalixScenario.getScenarioValueHeader()));
+        }
+        exportContextCSV.writeCSVLine(header.toArray(new String[header.size()]));
+    }
+
+    @Override
+    protected String[] formatCSVRow(final ExportContextCSV exportContextCSV, final ResultRow row) {
+        return formatRow(exportContextCSV, row);
+    }
+
+    @Override
+    protected String[] formatPDFRow(final ExportContextPDF exportContextPDF, final ResultRow row) {
+        return formatRow(exportContextPDF, row);
+    }
+
+    @Override
+    protected String getJasperFile() {
+        return JASPER_FILE;
+    }
+
+    @Override
+    protected void addJRTableHeader(final ExportContextPDF exportContextPDF, final MetaAndTableJRDataSource source) {
+
+        /* additional column headings */
+        exportContextPDF.addJRMetadata(source, "station_header", GeneralResultType.station);
+        exportContextPDF.addJRMetadata(source, "salix_line", UInfoResultType.salixline);
+        exportContextPDF.addJRMetadata(source, "salix_delta_mw", UInfoResultType.salix_mw_mnw);
+
+        for (int i = 1; i <= this.getScenarioCount(); i++) {
+            // TODO Spaltenueberschriften der Scenarios
+        }
+    }
+
+    private String[] formatRow(final IExportContext context, final ResultRow row) {
+
+        final Collection<String> lines = new ArrayList<>();
+        lines.add(context.formatRowValue(row, GeneralResultType.station));
+        lines.add(context.formatRowValue(row, UInfoResultType.salixline));
+        lines.add(context.formatRowValue(row, UInfoResultType.salix_mw_mnw));
+
+        final NumberFormat formatter = ((ExportContextCSV) context).getSalixScenFormatter();
+        final List<SalixScenario> scenarios = (List<SalixScenario>) row.getValue(UInfoResultType.customMultiRowColSalixScenarios);
+        for (int i = 1; i <= this.getScenarioCount(); i++) {
+            if (i > scenarios.size())
+                break;
+            if (scenarios.get(i - 1) != null) {
+                lines.add(scenarios.get(i - 1).getDeltaWFormatted());
+                lines.add(scenarios.get(i - 1).getSalixValueFormatted(formatter));
+            }
+            else {
+                lines.add("");
+                lines.add("");
+            }
+        }
+        return lines.toArray(new String[lines.size()]);
+    }
+
+    @Override
+    protected void writeCSVResultMetadata(final ExportContextCSV exportContextCSV) {
+        // do nothing. subclass may override
+    }
+
+    /**
+     * Gets a longitudinal section of the salix value of a scenario
+     */
+    public final double[][] getScenarioPoints(final int dataIndex) {
+
+        final Collection<ResultRow> rows = getRows();
+
+        final TDoubleArrayList xPoints = new TDoubleArrayList(rows.size());
+        final TDoubleArrayList yPoints = new TDoubleArrayList(rows.size());
+
+        for (final ResultRow row : rows) {
+
+            final double station = row.getDoubleValue(GeneralResultType.station);
+
+            final List<SalixScenario> scenarios = (List<SalixScenario>) row.getValue(UInfoResultType.customMultiRowColSalixScenarios);
+            if (dataIndex <= scenarios.size() - 1) {
+                final SalixScenario salixScenario = scenarios.get(dataIndex);
+                if (salixScenario != null) {
+                    final double value = salixScenario.getSalixValue();
+                    xPoints.add(station);
+                    yPoints.add(value);
+                }
+            }
+        }
+
+        return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() };
+    }
+}
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResults.java	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResults.java	Wed Aug 01 18:01:11 2018 +0200
@@ -17,7 +17,7 @@
  * @author Domenico Nardi Tironi
  *
  */
-final class SalixLineCalculationResults extends AbstractCalculationResults<SalixLineCalculationNoScenarioResult> {
+final class SalixLineCalculationResults extends AbstractCalculationResults<SalixLineCalculationResult> {
 
     private static final long serialVersionUID = 1L;
 
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationSupraRegionalResult.java	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationSupraRegionalResult.java	Wed Aug 01 18:01:11 2018 +0200
@@ -12,31 +12,19 @@
 import java.util.Collection;
 
 import org.dive4elements.river.artifacts.common.ExportContextCSV;
-import org.dive4elements.river.artifacts.common.IExportContext;
 import org.dive4elements.river.artifacts.common.ResultRow;
-import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
-import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType;
 
 /**
  * @author Domenico Nardi Tironi
  */
-final class SalixLineCalculationSupraRegionalResult extends SalixLineCalculationNoScenarioResult {
+final class SalixLineCalculationSupraRegionalResult extends SalixLineCalculationResult {
 
     private static final long serialVersionUID = 1L;
 
-    public SalixLineCalculationSupraRegionalResult(final String label, final Collection<ResultRow> rows) {
-        super(label, rows);
-    }
+    public SalixLineCalculationSupraRegionalResult(final String label, final String[] scenarioLabels, final String partialRangeString,
+            final String deltaWString, final Collection<ResultRow> rows) {
 
-    @Override
-    public void writeCSVHeader(final ExportContextCSV exportContextCSV, final RiverInfo river) {
-
-        final Collection<String> header = super.writeNoScenarioHeader(exportContextCSV);
-
-        header.add(exportContextCSV.formatCsvHeader(UInfoResultType.salix_line_scenario));
-        header.add(exportContextCSV.formatCsvHeader(UInfoResultType.salix_line_scenario_dwspl));
-
-        exportContextCSV.writeCSVLine(header.toArray(new String[header.size()]));
+        super(label, scenarioLabels, partialRangeString, deltaWString, rows);
     }
 
     @Override
@@ -46,24 +34,20 @@
 
     }
 
-    @Override
-    protected String[] formatRow(final IExportContext context, final ResultRow row) {
-
-        final Collection<String> lines = super.getNoScenarioFormat(row, context);
-
-        if (context instanceof ExportContextCSV) { // enum gespart - pdf-export hat ja nur die drei spalten
-            lines.add(context.formatRowValue(row, UInfoResultType.salix_line_scenario));
-            lines.add(context.formatRowValue(row, UInfoResultType.salix_line_scenario_dwspl));
+    private void writeExtendedRegionalEffectsCSVMetadata(final ExportContextCSV exportContextCSV) {
 
-        }
-        return lines.toArray(new String[lines.size()]);
-    }
+        final String main = "uinfo.export.csv.meta.header.salix";
+        final String mainSub = "uinfo.export.csv.meta.header.salix.supraregional";
 
-    private void writeExtendedRegionalEffectsCSVMetadata(final ExportContextCSV exportContextCSV) {
-        final String main = "uinfo.export.csv.meta.header.salix.regionalextended";
         // "##Überregional wirkende Eingriffe"
-        exportContextCSV.writeCSVMetaEntry(main);
+        exportContextCSV.writeCSVMetaEntry(mainSub);
 
-        writeRegionalCommonCSVMeta(exportContextCSV);
+        // "# Teilabschnitte: "
+        exportContextCSV.writeCSVMetaEntry(mainSub + ".teilabschnitt", this.getPartialRangeString());
+
+        // "# Mittelwasserspiegellagenänderung: "
+        exportContextCSV.writeCSVMetaEntry(main + ".mwspiegelaenderung", this.getDeltaWString());
+
+        exportContextCSV.writeBlankLine();
     }
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java	Wed Aug 01 18:01:11 2018 +0200
@@ -24,7 +24,6 @@
 import org.dive4elements.river.artifacts.model.WstValueTable;
 import org.dive4elements.river.artifacts.model.WstValueTable.QPosition;
 import org.dive4elements.river.artifacts.model.WstValueTableFactory;
-import org.dive4elements.river.artifacts.sinfo.common.GaugeDischargeValuesFinder;
 import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper;
@@ -34,6 +33,7 @@
 import org.dive4elements.river.model.Gauge;
 import org.dive4elements.river.model.MainValue;
 import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
+import org.dive4elements.river.utils.Formatter;
 
 /**
  * Calculation of the result rows of the u-info salix line calc mode
@@ -65,7 +65,8 @@
      * Calculate the salix line result rows
      */
     public void execute(final Calculation problems, final UINFOArtifact uinfo, final NavigableMap<Double, List<Double>> rangeScenarios,
-            final ScenarioType scenarioType, final String[] scenarioLabels, final SalixLineCalculationResults results) {
+            final ScenarioType scenarioType, final String[] scenarioLabels, final String rangeString, final String additionalString,
+            final SalixLineCalculationResults results) {
 
         this.problems = problems;
         this.wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver());
@@ -79,17 +80,17 @@
             this.rows.add(createRow(station, rangeScenarios));
         }
         if (scenarioType == ScenarioType.REGIONAL)
-            results.addResult(new SalixLineCalculationRegionalResult("Salix", scenarioLabels, this.rows), problems);
+            results.addResult(new SalixLineCalculationRegionalResult("Salix-regional", scenarioLabels, rangeString, additionalString, this.rows), problems);
         else if (scenarioType == ScenarioType.SUPRAREGIONAL)
-            results.addResult(new SalixLineCalculationSupraRegionalResult("Salix", this.rows), problems);
+            results.addResult(new SalixLineCalculationSupraRegionalResult("Salix-supra", scenarioLabels, rangeString, additionalString, this.rows), problems);
         else if (scenarioType == ScenarioType.HISTORICAL)
-            results.addResult(new SalixLineCalculationHistoricalResult("Salix", this.rows), problems);
+            results.addResult(new SalixLineCalculationHistoricalResult("Salix-hist", scenarioLabels, rangeString, additionalString, this.rows), problems);
         else
-            results.addResult(new SalixLineCalculationNoScenarioResult("Salix", this.rows), problems);
+            results.addResult(new SalixLineCalculationResult("Salix-simple", this.rows), problems);
     }
 
     /**
-     * Fetch MW, MNW and MHW of all gauges and determine the wst QPosition for each one
+     * Fetch MQ, MNQ and MHQ of all gauges and determine the wst QPosition for each one
      */
     private void fetchGaugeMainValuePositions() {
         this.gaugeMwPos.clear();
@@ -99,17 +100,14 @@
             this.gaugeMwPos.put(gauge, null);
             this.gaugeMnwPos.put(gauge, null);
             this.gaugeMhwPos.put(gauge, null);
-            final GaugeDischargeValuesFinder finder = GaugeDischargeValuesFinder.loadValues(gauge, this.problems);
-            if (finder == null)
-                continue;
             final double gaugeKm = gauge.getStation().doubleValue();
-            for (final MainValue mv : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.W)) {
-                if (mv.getMainValue().getName().equalsIgnoreCase("mw"))
-                    this.gaugeMwPos.put(gauge, this.wst.getQPosition(gaugeKm, finder.getDischarge(mv.getValue().doubleValue())));
-                else if (mv.getMainValue().getName().equalsIgnoreCase("mnw"))
-                    this.gaugeMnwPos.put(gauge, this.wst.getQPosition(gaugeKm, finder.getDischarge(mv.getValue().doubleValue())));
-                else if (mv.getMainValue().getName().equalsIgnoreCase("mhw"))
-                    this.gaugeMhwPos.put(gauge, this.wst.getQPosition(gaugeKm, finder.getDischarge(mv.getValue().doubleValue())));
+            for (final MainValue mv : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.Q)) {
+                if (mv.getMainValue().getName().equalsIgnoreCase("mq"))
+                    this.gaugeMwPos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue()));
+                else if (mv.getMainValue().getName().equalsIgnoreCase("mnq"))
+                    this.gaugeMnwPos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue()));
+                else if (mv.getMainValue().getName().equalsIgnoreCase("mhq"))
+                    this.gaugeMhwPos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue()));
             }
         }
     }
@@ -134,24 +132,20 @@
         row.putValue(SInfoResultType.waterlevel2, mhw);
         // Calc salix-line and mw-mnw
         row.putValue(UInfoResultType.salixline, calcSalix(mhw, mw));
-        row.putValue(UInfoResultType.salix_delta_mw, calcMwmnw(mw, mnw));
+        row.putValue(UInfoResultType.salix_mw_mnw, calcMwmnw(mw, mnw));
         // Calc scenario values (always all scenario types set, Result variant extracts the fields needed)
         final List<SalixScenario> scenarios = new ArrayList<>();
         final double[] deltaws = getDeltaWs(station, rangeScenarios);
         for (int i = 0; i <= deltaws.length - 1; i++) {
-            if (Math.abs(deltaws[i]) < 0.0001) {
-                row.putValue(UInfoResultType.salix_line_scenario, Double.NaN);
-                row.putValue(UInfoResultType.salix_line_scenario_dwspl, 0); // TODO NaN when changed from int to double
-                /* always need to add a member, so the exporter will produce empty columns */
-                scenarios.add(null);
-            } else {
+            if (Math.abs(deltaws[i]) > 0.0001) {
                 final double salix = calcSalix(mhw, mw + deltaws[i]);
-                row.putValue(UInfoResultType.salix_line_scenario, salix);
-                row.putValue(UInfoResultType.salix_line_scenario_dwspl, (int) (deltaws[i] * 100));
                 scenarios.add(new SalixScenario((int) (deltaws[i] * 100), salix));
             }
+            else {
+                scenarios.add(null);
+            }
         }
-        row.putValue(UInfoResultType.customMultiRowColSalixRegionalValue_Dwspl, scenarios);
+        row.putValue(UInfoResultType.customMultiRowColSalixScenarios, scenarios);
         return row;
     }
 
@@ -169,14 +163,14 @@
      * Calculates the salix value
      */
     private double calcSalix(final double mhw, final double mw) {
-        return mhw - 2.31 - mw;
+        return Formatter.roundW(mhw) - 2.31 - Formatter.roundW(mw);
     }
 
     /**
      * Calculates the inverse MW-MNW difference
      */
     private double calcMwmnw(final double mw, final double mnw) {
-        return mnw - mw;
+        return Formatter.roundW(mnw) - Formatter.roundW(mw);
     }
 
     /**
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineExporter.java	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineExporter.java	Wed Aug 01 18:01:11 2018 +0200
@@ -17,7 +17,7 @@
 /**
  * @author Domenico Nardi Tironi
  */
-public class SalixLineExporter extends AbstractCommonExporter<SalixLineCalculationNoScenarioResult, SalixLineCalculationResults> {
+public class SalixLineExporter extends AbstractCommonExporter<SalixLineCalculationResult, SalixLineCalculationResults> {
 
     @Override
     protected void writeCSVGlobalMetadata(final ExportContextCSV exportContextCSV, final SalixLineCalculationResults results) {
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineProcessor.java	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineProcessor.java	Wed Aug 01 18:01:11 2018 +0200
@@ -79,31 +79,20 @@
 
         // log.debug("Processing facet: " + bundle.getFacetName());
         final CallContext context = generator.getContext();
-        final Object data = bundle.getData(context);
+        final SalixLineCalculationResult data = (SalixLineCalculationResult) bundle.getData(context);
 
         if (bundle.getFacetName().equals(FACET_SALIX_LINE)) {
             return buildSeriesForType(generator, bundle, theme, visible, UInfoResultType.salixline, GAP_DISTANCE);
         }
 
         if (bundle.getFacetName().equals(FACET_SALIX_MNWMW)) {
-            return buildSeriesForType(generator, bundle, theme, visible, UInfoResultType.salix_delta_mw, GAP_DISTANCE);
+            return buildSeriesForType(generator, bundle, theme, visible, UInfoResultType.salix_mw_mnw, GAP_DISTANCE);
         }
 
         if (bundle.getFacetName().equals(FACET_SALIX_SCENARIO)) {
-            // TODO Differenzieren, Scenario 1 bis max. 5 bei Regional
-
-            // FIXME: warum so unterscheiden? bei den anderen beiden szenarien einfach nur ein szenario-ergebnis in die liste
-            // packen!
-
-            if (data instanceof SalixLineCalculationRegionalResult) {
-
-                final int dataIndex = ((SalixScenarioResultFacet) bundle.getFacet()).getDataIndex();
-
-                final double[][] scenarioPoints = ((SalixLineCalculationRegionalResult) data).getScenarioPoints(dataIndex);
-                return buildSeriesForPoints(scenarioPoints, generator, bundle, theme, visible, GAP_DISTANCE);
-
-            } else
-                return buildSeriesForType(generator, bundle, theme, visible, UInfoResultType.salix_line_scenario, GAP_DISTANCE);
+            final int dataIndex = ((SalixScenarioResultFacet) bundle.getFacet()).getDataIndex();
+            final double[][] scenarioPoints = data.getScenarioPoints(dataIndex);
+            return buildSeriesForPoints(scenarioPoints, generator, bundle, theme, visible, GAP_DISTANCE);
         }
 
         throw new UnsupportedOperationException();
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineState.java	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineState.java	Wed Aug 01 18:01:11 2018 +0200
@@ -75,7 +75,7 @@
 
         final SalixLineCalculationResults results = (SalixLineCalculationResults) res.getData();
 
-        final List<SalixLineCalculationNoScenarioResult> resultList = results.getResults();
+        final List<SalixLineCalculationResult> resultList = results.getResults();
 
         int facetIndex = 0;
 
@@ -83,25 +83,14 @@
             facets.add(SalixLineProcessor.createSalixLineFacet(context, hash, this.id, facetIndex++, 0));
             facets.add(SalixLineProcessor.createSalixMnwMwFacet(context, hash, this.id, facetIndex++, 0));
 
-            if (resultList.get(0) instanceof SalixLineCalculationRegionalResult) {
-
-                final SalixLineCalculationRegionalResult result = (SalixLineCalculationRegionalResult) resultList.get(0);
+            final SalixLineCalculationResult result = resultList.get(0);
 
-                for (int i = 0; i <= result.getScenarioCount() - 1; i++) {
-                    final String sublabel = Resources.getMsg(context.getMeta(), "uinfo_salix_scenario_deltaw", "uinfo_salix_scenario_deltaw",
-                            result.getScenarioLabel(i));
-                    // REMARK: using data index as facetIndex, as we know there is only one result of this type. Else we should just
-                    // increment
-                    facets.add(SalixLineProcessor.createSalixScenarioFacet(context, hash, this.id, i, 0, facetIndex++, sublabel));
-                }
-            } else if (resultList.get(0) instanceof SalixLineCalculationSupraRegionalResult) {
-                final String sublabel = Resources.getMsg(context.getMeta(), "uinfo_salix_scenario_supraregional");
-                facets.add(SalixLineProcessor.createSalixScenarioFacet(context, hash, this.id, 0, 0, facetIndex++, sublabel));
-            }
-
-            else if (resultList.get(0) instanceof SalixLineCalculationHistoricalResult) {
-                final String sublabel = Resources.getMsg(context.getMeta(), "uinfo_salix_scenario_historical");
-                facets.add(SalixLineProcessor.createSalixScenarioFacet(context, hash, this.id, 0, 0, facetIndex++, sublabel));
+            for (int i = 0; i <= result.getScenarioCount() - 1; i++) {
+                final String sublabel = Resources.getMsg(context.getMeta(), "uinfo_salix_scenario_deltaw", "uinfo_salix_scenario_deltaw",
+                        result.getScenarioLabel(i));
+                // REMARK: using data index as facetIndex, as we know there is only one result of this type. Else we should just
+                // increment
+                facets.add(SalixLineProcessor.createSalixScenarioFacet(context, hash, this.id, i, 0, facetIndex++, sublabel));
             }
 
             final Facet csv = new DataFacet(FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, this.id);
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixScenario.java	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixScenario.java	Wed Aug 01 18:01:11 2018 +0200
@@ -23,10 +23,10 @@
     private static final long serialVersionUID = 1L;
 
     private final double salix_value;
-    private final int dwspl;
+    private final int deltaW;
 
-    public SalixScenario(final int scen_val, final double salix_value) {
-        this.dwspl = scen_val;
+    public SalixScenario(final int deltaW, final double salix_value) {
+        this.deltaW = deltaW;
         this.salix_value = salix_value;
     }
 
@@ -34,15 +34,15 @@
         return this.salix_value;
     }
 
-    public int getDwspl() {
-        return this.dwspl;
+    public int getDeltaW() {
+        return this.deltaW;
     }
 
-    public String getDwsplFormatted() {
-        if (Double.isNaN(this.dwspl))
+    public String getDeltaWFormatted() {
+        if (Double.isNaN(this.deltaW))
             return StringUtils.EMPTY;
 
-        return String.valueOf(this.dwspl);
+        return String.valueOf(this.deltaW);
     }
 
     public String getSalixValueFormatted(final NumberFormat formatter) {
@@ -56,7 +56,7 @@
         return "uinfo.export.salix_line.csv.header.scenario";
     }
 
-    public static final String getDwsplHeader() {
-        return "uinfo.export.salix_line.csv.header.scenario_dwspl";
+    public static final String getDeltaWHeader() {
+        return "uinfo.export.salix_line.csv.header.scenario_deltaw";
     }
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java	Wed Aug 01 18:01:11 2018 +0200
@@ -96,6 +96,7 @@
     // OTHER
     public static final int CSV_DIAGRAM_DATA_MAX_DIGITS = 3;
     public static final int CSV_DIAGRAM_DATA_MIN_DIGITS = 3;
+    private static final double W_ROUND_MULT = 100.0;
 
     // S-INFO
     public static final int FLOWDEPTH_MAX_DIGITS = 2;
@@ -392,6 +393,10 @@
         return Formatter.getFormatter(context, 2, 2);
     }
 
+    public static double roundW(final double value) {
+        return Math.round(value * W_ROUND_MULT) / W_ROUND_MULT;
+    }
+
     /**
      * Another waterlevel formatter with fixed digits (always 2)
      */
--- a/artifacts/src/main/resources/messages.properties	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/resources/messages.properties	Wed Aug 01 18:01:11 2018 +0200
@@ -1119,17 +1119,17 @@
 
 uinfo.salix.sounding= Peilung
 uinfo.salix.soundings= Soundings
-uinfo.export.salix_line.csv.header.scenario_dwspl = \u0394MW [cm]
+uinfo.export.salix_line.csv.header.scenario_deltaw = \u0394MW [cm]
 uinfo.export.salix_line.csv.header.scenario = Salix-Linie_Szenario [m]
 uinfo.export.salix_line.csv.header.salix_line = Salix-Linie [m]
-uinfo.export.salix_line.csv.header.delta_mw =  (MW-MNW)x(-1) [m] 
-uinfo.export.salix_line.csv.header.hist =  Salix-Linie [m] historisch
+uinfo.export.salix_line.csv.header.mw_mnw =  (MW-MNW)x(-1) [m] 
 uinfo.export.csv.meta.header.salix.regional = ##Regional wirkende Eingriffe 
-uinfo.export.csv.meta.header.salix.regionalextended = ##\u00dcberregional wirkende Eingriffe
-uinfo.export.csv.meta.header.salix.teilabschnitt = # Teilabschnitt
-uinfo.export.csv.meta.header.salix.mwspiegellaenderung = # MittelwasserSpiegellagen\u00e4nderung
+uinfo.export.csv.meta.header.salix.supraregional = ##\u00dcberregional wirkende Eingriffe
+uinfo.export.csv.meta.header.salix.teilabschnitt = # Teilabschnitt: {0}
+uinfo.export.csv.meta.header.salix.supraregional.teilabschnitt = # Teilabschnitte: {0}
+uinfo.export.csv.meta.header.salix.mwspiegelaenderung = # MittelwasserSpiegellagen\u00e4nderung: {0}
 uinfo.export.csv.meta.header.salix.historical = ##Historische Betrachtung
-uinfo.export.csv.meta.header.salix.historical.zeitpunkt = # Historischer Zeitpunkt
+uinfo.export.csv.meta.header.salix.historical.zeitpunkt = # Historischer Zeitpunkt: {0}
 uinfo.export.csv.meta.header.veg.name = Vegetationszonen
 uinfo.export.csv.meta.header.veg.dauervon = \u00dcberflutungsdauer von [d/a]
 uinfo.export.csv.meta.header.veg.dauerbis = \u00dcberflutungsdauer bis [d/a]
--- a/artifacts/src/main/resources/messages_de.properties	Wed Aug 01 17:13:52 2018 +0200
+++ b/artifacts/src/main/resources/messages_de.properties	Wed Aug 01 18:01:11 2018 +0200
@@ -1119,17 +1119,17 @@
 state.uinfo.salix.historical.km_range_part = Ausgewertete Strecke
 uinfo.salix.sounding= Peilung
 uinfo.salix.soundings= Peilungen
-uinfo.export.salix_line.csv.header.scenario_dwspl = \u0394MW [cm]
+uinfo.export.salix_line.csv.header.scenario_deltaw = \u0394MW [cm]
 uinfo.export.salix_line.csv.header.scenario = Salix-Linie_Szenario [m]
 uinfo.export.salix_line.csv.header.salix_line = Salix-Linie [m]
-uinfo.export.salix_line.csv.header.delta_mw =  (MW-MNW)x(-1) [m] 
-uinfo.export.salix_line.csv.header.hist =  Salix-Linie [m] historisch
+uinfo.export.salix_line.csv.header.mw_mnw =  (MW-MNW)x(-1) [m] 
 uinfo.export.csv.meta.header.salix.regional = ##Regional wirkende Eingriffe 
-uinfo.export.csv.meta.header.salix.regionalextended = ##\u00dcberregional wirkende Eingriffe
-uinfo.export.csv.meta.header.salix.teilabschnitt = # Teilabschnitt
-uinfo.export.csv.meta.header.salix.mwspiegellaenderung = # MittelwasserSpiegellagen\u00e4nderung
+uinfo.export.csv.meta.header.salix.supraregional = ##\u00dcberregional wirkende Eingriffe
+uinfo.export.csv.meta.header.salix.teilabschnitt = # Teilabschnitt: {0}
+uinfo.export.csv.meta.header.salix.supraregional.teilabschnitt = # Teilabschnitte: {0}
+uinfo.export.csv.meta.header.salix.mwspiegelaenderung = # MittelwasserSpiegellagen\u00e4nderung: {0}
 uinfo.export.csv.meta.header.salix.historical = ##Historische Betrachtung
-uinfo.export.csv.meta.header.salix.historical.zeitpunkt = # Historischer Zeitpunkt
+uinfo.export.csv.meta.header.salix.historical.zeitpunkt = # Historischer Zeitpunkt: {0}
 uinfo.export.csv.meta.header.veg.name = Vegetationszonen
 uinfo.export.csv.meta.header.veg.dauervon = \u00dcberflutungsdauer von [d/a]
 uinfo.export.csv.meta.header.veg.dauerbis = \u00dcberflutungsdauer bis [d/a]

http://dive4elements.wald.intevation.org