teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5863: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5863: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.artifacts.model.minfo; raimund@3887: raimund@3887: import gnu.trove.TDoubleArrayList; raimund@3887: raimund@3898: import java.util.Date; raimund@3887: import java.util.LinkedList; raimund@3887: import java.util.List; raimund@3887: raimund@3887: import org.apache.log4j.Logger; raimund@3887: teichmann@5867: import org.dive4elements.river.artifacts.D4EArtifact; teichmann@5831: import org.dive4elements.river.artifacts.access.BedDifferencesAccess; teichmann@5831: import org.dive4elements.river.artifacts.model.Calculation; teichmann@5831: import org.dive4elements.river.artifacts.model.CalculationResult; raimund@3887: raimund@3887: raimund@3887: public class BedDiffCalculation raimund@3887: extends Calculation raimund@3887: { raimund@3887: raimund@3887: private static final Logger logger = Logger raimund@3898: .getLogger(BedDiffCalculation.class); raimund@3887: raimund@3887: protected String river; raimund@3887: protected String yearEpoch; teichmann@5867: protected D4EArtifact[][] artifacts; raimund@3887: raimund@3887: public BedDiffCalculation() { raimund@3887: } raimund@3887: raimund@3887: public CalculationResult calculate(BedDifferencesAccess access) { raimund@3898: logger.info("BedDiffCalculation.calculate"); raimund@3887: raimund@3887: String river = access.getRiver(); raimund@3887: String yearEpoch = access.getYearEpoch(); teichmann@5867: D4EArtifact[][] artifacts = access.getDifferenceArtifacts(); raimund@3887: raimund@3898: logger.debug("got artifacts: " + artifacts.length + "; " + artifacts[0].length); raimund@3887: if (river == null) { raimund@3887: // TODO: i18n raimund@3887: addProblem("minfo.missing.river"); raimund@3887: } raimund@3887: raimund@3887: if (yearEpoch == null) { raimund@3887: addProblem("minfo.missing.year_epoch"); raimund@3887: } raimund@3887: raimund@3887: if (artifacts == null) { raimund@3887: addProblem("minfo.missing.differences"); raimund@3887: } raimund@3887: raimund@3887: if (!hasProblems()) { raimund@3887: this.river = river; raimund@3887: this.yearEpoch = yearEpoch; raimund@3887: this.artifacts = artifacts; raimund@3887: return internalCalculate(); raimund@3887: } raimund@3887: raimund@3887: return new CalculationResult(); raimund@3887: } raimund@3887: raimund@3887: private CalculationResult internalCalculate() { raimund@3887: raimund@3887: if (yearEpoch.equals("year")) { raimund@3898: List results = raimund@3898: new LinkedList(); raimund@3898: raimund@3887: for (int i = 0; i < artifacts.length; i++) { raimund@3887: BedHeight[] pair = raimund@3887: getHeightPair(artifacts[i][0], artifacts[i][1], "single"); raimund@3898: BedDiffYearResult res = calculateYearDifference(pair); raimund@3887: results.add(res); raimund@3887: } raimund@3898: return new CalculationResult( raimund@3898: results.toArray(new BedDiffYearResult[results.size()]), this); raimund@3887: } raimund@3887: if (yearEpoch.equals("epoch")) { raimund@3898: List results = raimund@3898: new LinkedList(); raimund@3887: for (int i = 0; i < artifacts.length; i++) { raimund@3887: BedHeight[] pair = raimund@3887: getHeightPair(artifacts[i][0], artifacts[i][1], "epoch"); raimund@3898: BedDiffEpochResult res = calculateEpochDifference(pair); raimund@3887: results.add(res); raimund@3887: } raimund@3898: return new CalculationResult( raimund@3898: results.toArray(new BedDiffEpochResult[results.size()]), this); raimund@3887: } raimund@3887: raimund@3898: return new CalculationResult(); raimund@3887: } raimund@3887: raimund@3887: private BedHeight[] getHeightPair( teichmann@5867: D4EArtifact art1, teichmann@5867: D4EArtifact art2, raimund@3887: String type raimund@3887: ) { raimund@3887: int id1 = BedDifferencesAccess.getHeightId(art1); raimund@3887: int id2 = BedDifferencesAccess.getHeightId(art2); raimund@3887: raimund@3887: BedHeight[] heights = new BedHeight[2]; raimund@3887: heights[0] = BedHeightFactory.getHeight(type, id1, 0); raimund@3887: heights[1] = BedHeightFactory.getHeight(type, id2, 0); raimund@3887: return heights; raimund@3887: } raimund@3887: raimund@3887: private BedDiffEpochResult calculateEpochDifference(BedHeight[] pair) { raimund@3887: raimund@3887: TDoubleArrayList stations = pair[0].getStations(); raimund@3887: TDoubleArrayList diffRes = new TDoubleArrayList(); raimund@3887: TDoubleArrayList kms = new TDoubleArrayList(); raimund@3898: TDoubleArrayList heights1 = new TDoubleArrayList(); raimund@3898: TDoubleArrayList heights2 = new TDoubleArrayList(); raimund@3898: raimund@3887: for (int i = 0; i < stations.size(); i++) { raimund@3887: if (!Double.isNaN(pair[0].getHeight(stations.get(i))) && raimund@3887: !Double.isNaN(pair[1].getHeight(stations.get(i)))) { raimund@3887: double hDiff = raimund@3887: pair[0].getHeight(stations.get(i)) - raimund@3887: pair[1].getHeight(stations.get(i)); raimund@3887: diffRes.add(hDiff); raimund@3887: kms.add(stations.get(i)); raimund@3898: heights1.add(pair[0].getHeight(stations.get(i))); raimund@3898: heights2.add(pair[1].getHeight(stations.get(i))); raimund@3887: } raimund@3887: } raimund@3898: Date start = ((BedHeightEpoch)pair[0]).getStart(); raimund@3898: Date end = ((BedHeightEpoch)pair[1]).getEnd(); raimund@3898: return new BedDiffEpochResult(kms, diffRes, heights1, heights2, start, end); raimund@3887: } raimund@3887: raimund@3887: private BedDiffYearResult calculateYearDifference(BedHeight[] pair) { raimund@3887: raimund@3887: TDoubleArrayList stations = pair[0].getStations(); raimund@3887: TDoubleArrayList diffRes = new TDoubleArrayList(); raimund@3887: TDoubleArrayList kms = new TDoubleArrayList(); raimund@3887: TDoubleArrayList morphs = new TDoubleArrayList(); raimund@3898: TDoubleArrayList absolute = new TDoubleArrayList(); raimund@3887: TDoubleArrayList gap = new TDoubleArrayList(); raimund@3898: TDoubleArrayList heights1 = new TDoubleArrayList(); raimund@3898: TDoubleArrayList heights2 = new TDoubleArrayList(); raimund@3898: raimund@3887: BedHeightSingle s1 = (BedHeightSingle)pair[0]; raimund@3887: BedHeightSingle s2 = (BedHeightSingle)pair[1]; raimund@3887: int range = s1.getYear() - s2.getYear(); raimund@3887: if (range < 0) { raimund@3887: range = range * -1; raimund@3887: } raimund@3887: for (int i = 0; i < stations.size(); i++) { raimund@3898: if (!Double.isNaN(s1.getHeight(stations.get(i))) && raimund@3898: !Double.isNaN(s2.getHeight(stations.get(i)))) { raimund@3887: double hDiff = raimund@3898: s1.getHeight(stations.get(i)) - raimund@3898: s2.getHeight(stations.get(i)); raimund@3887: diffRes.add(hDiff); raimund@3898: double km = stations.get(i); raimund@3898: kms.add(km); raimund@3898: if (s1.getMorphWidth(km) > raimund@3898: s2.getMorphWidth(km)) { raimund@3898: morphs.add(s1.getMorphWidth(km)); raimund@3887: } raimund@3887: else { raimund@3898: morphs.add(s2.getMorphWidth(km)); raimund@3887: } raimund@3898: if (s1.getDataGap(km) > s2.getDataGap(km)) { raimund@3898: gap.add(s1.getDataGap(km)); raimund@3887: } raimund@3887: else { raimund@3898: gap.add(s2.getDataGap(km)); raimund@3887: } raimund@3898: absolute.add((hDiff / range) * 100); raimund@3898: heights1.add(s1.getHeight(km)); raimund@3898: heights2.add(s2.getHeight(km)); raimund@3887: } raimund@3887: } raimund@3898: return new BedDiffYearResult( raimund@3898: kms, raimund@3898: diffRes, raimund@3898: heights1, raimund@3898: heights2, raimund@3898: morphs, raimund@3898: absolute, raimund@3898: gap, raimund@3898: s1.getYear(), raimund@3898: s2.getYear()); raimund@3887: } raimund@3887: }