view artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataCalculation.java @ 8049:d49846f05108

Sediment load: (incomplete) new sediment load calculation.
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 17 Jul 2014 16:51:18 +0200
parents
children 9e79e384aa8b
line wrap: on
line source
/* Copyright (C) 2014 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */
package org.dive4elements.river.artifacts.model.minfo;

import java.util.List;
import java.util.Set;

import org.dive4elements.river.artifacts.access.SedimentLoadAccess;
import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.apache.log4j.Logger;
import org.dive4elements.river.artifacts.model.minfo.SedimentLoadData;
import org.dive4elements.river.artifacts.model.minfo.SedimentLoadData.Value;
import org.dive4elements.river.artifacts.model.minfo.SedimentLoadData.Station;

public class SedimentLoadDataCalculation
extends      Calculation
{
    private static final Logger log = Logger
        .getLogger(SedimentLoadDataCalculation.class);

    public static final int [] TOTAL_LOAD_FLYS = {
        SedimentLoadData.GF_COARSE,
        SedimentLoadData.GF_FINE_MIDDLE,
        SedimentLoadData.GF_SAND,
        SedimentLoadData.GF_SUSP_SEDIMENT
    };

    public static final int [] BED_LOAD_FLYS = {
        SedimentLoadData.GF_COARSE,
        SedimentLoadData.GF_FINE_MIDDLE,
        SedimentLoadData.GF_SAND
    };

    public static final int [] BED_LOAD_SUSP_SAND_FLYS = {
        SedimentLoadData.GF_COARSE,
        SedimentLoadData.GF_FINE_MIDDLE,
        SedimentLoadData.GF_SAND,
        SedimentLoadData.GF_SUSP_SAND
    };

    public static final class Sum implements Value.Visitor {

        private int n;
        private double sum;
        private double scale;

        public Sum() {
        }

        public Sum(double scale) {
            this.scale = scale;
        }

        public double getSum() {
            return sum * scale;
        }

        public int getN() {
            return n;
        }

        public double getScale() {
            return scale;
        }

        public void reset() {
            n   = 0;
            sum = 0.0;
        }

        @Override
        public void visit(Value value) {
            sum += value.getValue();
            ++n;
        }
    } // class Aggregate


    public SedimentLoadDataCalculation() {
    }

    public CalculationResult calculate(SedimentLoadAccess access) {
        log.info("SedimentLoadDataCalculation.calculate");
        // TODO: Implement me!

        return null;
    }

    private static double sum(double [] values) {
        double sum = 0.0;
        for (double value: values) {
            sum += value;
        }
        return sum;
    }

    public double[][] sum(
        SedimentLoadData sld,
        double           from,
        double           to,
        int []           grainFractions,
        Value.Filter     filter,
        Sum              sum,
        boolean          isKMUp,
        Set<Integer>     missingFractions
    ) {
        List<Station> stations = sld.findStations(from, to);

        double [] values = new double[grainFractions.length];

        double [][] result = new double[2][stations.size()];

        for (int j = 0, S = stations.size(); j < S; ++j) {
            Station station = stations.get(j);
            for (int i = 0; i < grainFractions.length; ++i) {
                int gf = grainFractions[i];
                sum.reset();
                station.filterGrainFraction(gf, filter, sum);
                if (sum.getN() == 0) { // No values found
                    int msType = SedimentLoadData.measurementStationType(gf);
                    // Station of right fraction type already? No: take previous.
                    if (!station.isType(msType)) {
                        Station prev = station.prevByType(msType, isKMUp);
                        if (prev != null) {
                            prev.filterGrainFraction(gf, filter, sum);
                        }
                    }
                }

                if (sum.getN() == 0) {
                    missingFractions.add(gf);
                    values[i] = Double.NaN;
                } else {
                    values[i] = sum.getSum();
                }
            }
            result[0][j] = station.getStation();
            result[1][j] = sum(values);
        }

        // TODO: Handle 'virtual' measument stations 'from' and 'to'.

        return result;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org