view artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/BedDiffCalculation.java @ 7261:a56fe3bc6700

Refactoring: Let RiverAccess.getRiver return an River. Renamed getRiver in getRiverName. Update Callers.
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Tue, 08 Oct 2013 14:50:58 +0200
parents d4108d6c4000
children 4eccd72595ee
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */
package org.dive4elements.river.artifacts.model.minfo;

import gnu.trove.TDoubleArrayList;

import java.util.Date;

import org.apache.log4j.Logger;

import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.access.BedDifferencesAccess;
import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.artifacts.model.CalculationResult;

/**
 * Perform calculation of differences of bed height (german Sohlhoehe).
 * The input are either single year data or epochs.
 */
public class BedDiffCalculation
extends Calculation
{
    private static final Logger logger =
        Logger.getLogger(BedDiffCalculation.class);

    protected String   river;
    protected String   yearEpoch;
    protected int [][] heightIds;

    public BedDiffCalculation() {
    }

    public CalculationResult calculate(BedDifferencesAccess access, CallContext context) {
        logger.info("BedDiffCalculation.calculate");

        String river       = access.getRiverName();
        String yearEpoch   = access.getYearEpoch();
        int [][] heightIds = access.extractHeightIds(context);

        if (river == null) {
            // TODO: i18n
            addProblem("minfo.missing.river");
        }

        if (yearEpoch == null) {
            addProblem("minfo.missing.year_epoch");
        }

        if (!hasProblems()) {
            this.river     = river;
            this.yearEpoch = yearEpoch;
            this.heightIds = heightIds;
            return internalCalculate();
        }

        return new CalculationResult();
    }

    private CalculationResult internalCalculate() {

        BedDiffYearResult [] results = new BedDiffYearResult[heightIds.length];

        for (int i = 0; i < heightIds.length; i++) {
            BedHeight [] pair = getHeightPair(heightIds[i], "single");
            results[i] = calculateYearDifference(pair);
        }
        return new CalculationResult(results, this);
        // Currently epochs are handled like single years. To handle epochs
        // uncomment the follwing code and use an if-clause in the code above.
/*
        if (yearEpoch.equals("epoch")) {
            BedDiffEpochResult [] results = new BedDiffEpochResult[heightIds.length];

            for (int i = 0; i < heightIds.length; i++) {
                BedHeight[] pair = getHeightPair(heightIds[i], "epoch");
                results[i] = calculateEpochDifference(pair);
            }
            return new CalculationResult(results, this);
        }

       return new CalculationResult();
       */
    }

    /** Get two BedHeights from factory. */
    private static BedHeight [] getHeightPair(int [] ids, String type) {
        return new BedHeight [] {
            BedHeightFactory.getHeight(type, ids[0], 0),
            BedHeightFactory.getHeight(type, ids[1], 0)
        };
    }

    private BedDiffEpochResult calculateEpochDifference(BedHeight[] pair) {

        BedHeight bh1 = pair[0];
        BedHeight bh2 = pair[1];

        TDoubleArrayList stations = bh1.getStations();
        int size = stations.size();

        TDoubleArrayList diffRes  = new TDoubleArrayList(size);
        TDoubleArrayList kms      = new TDoubleArrayList(size);
        TDoubleArrayList heights1 = new TDoubleArrayList(size);
        TDoubleArrayList heights2 = new TDoubleArrayList(size);

        for (int i = 0; i < size; i++) {
            double station = stations.getQuick(i);
            double h1      = bh1.getHeight(station);
            double h2      = bh2.getHeight(station);
            double hDiff   = h1 - h2;
            if (!Double.isNaN(hDiff)) {
                diffRes.add(hDiff);
                kms.add(station);
                heights1.add(h1);
                heights2.add(h2);
            }
        }
        Date start = ((BedHeightEpoch)bh1).getStart();
        Date end   = ((BedHeightEpoch)bh2).getEnd();
        return new BedDiffEpochResult(kms, diffRes, heights1, heights2, start, end);
    }

    private BedDiffYearResult calculateYearDifference(BedHeight[] pair) {

        BedHeightSingle s1 = (BedHeightSingle)pair[0];
        BedHeightSingle s2 = (BedHeightSingle)pair[1];

        TDoubleArrayList stations = s1.getStations();
        int size = stations.size();

        TDoubleArrayList diffRes  = new TDoubleArrayList(size);
        TDoubleArrayList kms      = new TDoubleArrayList(size);
        TDoubleArrayList morphs   = new TDoubleArrayList(size);
        TDoubleArrayList absolute = new TDoubleArrayList(size);
        TDoubleArrayList gap      = new TDoubleArrayList(size);
        TDoubleArrayList heights1 = new TDoubleArrayList(size);
        TDoubleArrayList heights2 = new TDoubleArrayList(size);

        int range = Math.abs(s1.getYear() - s2.getYear());

        for (int i = 0; i < size; i++) {
            double station = stations.getQuick(i);
            double h1      = s1.getHeight(station);
            double h2      = s2.getHeight(station);
            double hDiff   = h1 - h2;

            if (!Double.isNaN(hDiff)) {
                diffRes.add(hDiff);
                kms.add(station);

                morphs.add(Math.max(
                    s1.getMorphWidth(station),
                    s2.getMorphWidth(station)));

                gap.add(Math.max(
                    s1.getDataGap(station),
                    s2.getDataGap(station)));

                absolute.add((hDiff / range) * 100d);
                heights1.add(h1);
                heights2.add(h2);
            }
        }
        return new BedDiffYearResult(
            kms,
            diffRes,
            heights1,
            heights2,
            morphs,
            absolute,
            gap,
            s1.getYear(),
            s2.getYear(),
            s1.getName(),
            s2.getName());
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org