rrenkert@4373: package de.intevation.flys.artifacts.model.minfo; rrenkert@4373: rrenkert@4373: import gnu.trove.TDoubleArrayList; rrenkert@4373: rrenkert@4373: import java.util.ArrayList; rrenkert@4373: import java.util.List; rrenkert@4373: rrenkert@4373: import org.apache.log4j.Logger; rrenkert@4373: rrenkert@4373: import de.intevation.flys.artifacts.access.SedimentLoadAccess; rrenkert@4373: import de.intevation.flys.artifacts.model.Calculation; rrenkert@4373: import de.intevation.flys.artifacts.model.CalculationResult; rrenkert@4373: rrenkert@4373: felix@4483: /** Calculate sediment load. */ rrenkert@4373: public class SedimentLoadCalculation rrenkert@4373: extends Calculation rrenkert@4373: { rrenkert@4373: felix@4483: /** Private logger. */ rrenkert@4373: private static final Logger logger = Logger rrenkert@4373: .getLogger(SedimentLoadCalculation.class); rrenkert@4373: rrenkert@4373: protected String river; rrenkert@4373: protected String yearEpoch; rrenkert@4373: protected double kmUp; rrenkert@4373: protected double kmLow; rrenkert@4373: protected int[] period; rrenkert@4373: protected int[][] epoch; rrenkert@4373: protected String unit; rrenkert@4373: rrenkert@4373: public SedimentLoadCalculation() { rrenkert@4373: } rrenkert@4373: rrenkert@4373: public CalculationResult calculate(SedimentLoadAccess access) { rrenkert@4373: logger.info("SedimentLoadCalculation.calculate"); rrenkert@4373: rrenkert@4373: String river = access.getRiver(); rrenkert@4373: String yearEpoch = access.getYearEpoch(); rrenkert@4373: String unit = access.getUnit(); rrenkert@4373: int[] period = null; rrenkert@4373: int[][] epoch = null; rrenkert@4373: double kmUp = access.getUpperKM(); rrenkert@4373: double kmLow = access.getLowerKM(); rrenkert@4373: if (yearEpoch.equals("year")) { rrenkert@4373: period = access.getPeriod(); rrenkert@4373: epoch = null; rrenkert@4373: } rrenkert@4522: else if (yearEpoch.equals("epoch") || yearEpoch.equals("off_epoch")) { rrenkert@4373: epoch = access.getEpochs(); rrenkert@4373: period = null; rrenkert@4373: } rrenkert@4373: else { rrenkert@4373: addProblem("minfo.missing.year_epoch"); rrenkert@4373: } rrenkert@4373: rrenkert@4373: if (river == null) { rrenkert@4373: // TODO: i18n rrenkert@4373: addProblem("minfo.missing.river"); rrenkert@4373: } rrenkert@4373: rrenkert@4373: if (period == null && epoch == null) { rrenkert@4373: addProblem("minfo.missing.time"); rrenkert@4373: } rrenkert@4373: rrenkert@4373: if (!hasProblems()) { rrenkert@4373: this.river = river; rrenkert@4373: this.yearEpoch = yearEpoch; rrenkert@4373: this.unit = unit; rrenkert@4373: this.period = period; rrenkert@4373: this.epoch = epoch; rrenkert@4373: this.kmUp = kmUp; rrenkert@4373: this.kmLow = kmLow; rrenkert@4373: return internalCalculate(); rrenkert@4373: } rrenkert@4373: rrenkert@4373: return new CalculationResult(); rrenkert@4373: } rrenkert@4373: rrenkert@4373: private CalculationResult internalCalculate() { rrenkert@4373: logger.debug("internalCalulate; mode:" + yearEpoch); rrenkert@4373: if (yearEpoch.equals("year")) { rrenkert@4373: List results = rrenkert@4373: new ArrayList(); rrenkert@4373: for (int i = period[0]; i <= period[1]; i++) { rrenkert@4373: logger.debug("calculating for year: " + i); rrenkert@4373: SedimentLoadResult res = calculateYear(i); rrenkert@4373: results.add(res); rrenkert@4373: } rrenkert@4373: return new CalculationResult( rrenkert@4373: results.toArray(new SedimentLoadResult[results.size()]), this); rrenkert@4373: } rrenkert@4373: else if (yearEpoch.equals("epoch")) { rrenkert@4373: List results = rrenkert@4373: new ArrayList(); rrenkert@4373: for (int i = 0; i < epoch.length; i++) { rrenkert@4373: SedimentLoadResult res = calculateEpoch(i); rrenkert@4373: results.add(res); rrenkert@4373: } rrenkert@4373: return new CalculationResult( rrenkert@4373: results.toArray(new SedimentLoadResult[results.size()]), this); rrenkert@4373: } rrenkert@4373: else if (yearEpoch.equals("off_epoch")) { rrenkert@4373: List results = rrenkert@4373: new ArrayList(); rrenkert@4373: for (int i = 0; i < epoch.length; i++) { rrenkert@4373: SedimentLoadResult res = calculateOffEpoch(i); rrenkert@4373: results.add(res); rrenkert@4373: } rrenkert@4373: return new CalculationResult( rrenkert@4373: results.toArray(new SedimentLoadResult[results.size()]), this); rrenkert@4373: } rrenkert@4373: return null; rrenkert@4373: } rrenkert@4373: rrenkert@4373: private SedimentLoadResult calculateEpoch(int i) { rrenkert@4373: List epochLoads = new ArrayList(); rrenkert@4373: for (int j = epoch[i][0]; j < epoch[i][1]; j++) { rrenkert@4373: epochLoads.add(SedimentLoadFactory.getLoadwithData( rrenkert@4373: this.river, rrenkert@4373: this.yearEpoch, rrenkert@4373: this.kmLow, rrenkert@4373: this.kmUp, rrenkert@4373: j, rrenkert@4373: j)); rrenkert@4373: } rrenkert@4373: rrenkert@4373: SedimentLoad resLoad = new SedimentLoad(); rrenkert@4373: TDoubleArrayList kms = new TDoubleArrayList(); rrenkert@4373: rrenkert@4373: for (SedimentLoad load : epochLoads) { rrenkert@4373: for (double km : load.getKms()) { rrenkert@4373: if (!kms.contains(km)) { rrenkert@4373: kms.add(km); rrenkert@4373: } rrenkert@4373: } rrenkert@4373: } rrenkert@4373: rrenkert@4373: for (int j = 0; j < kms.size(); j++) { rrenkert@4373: int cSum = 0; rrenkert@4373: int fmSum = 0; rrenkert@4373: int sSum = 0; rrenkert@4373: int ssSum = 0; rrenkert@4373: int ssbSum = 0; rrenkert@4373: int sseSum = 0; rrenkert@4373: double km = kms.get(j); rrenkert@4373: for (SedimentLoad load : epochLoads) { rrenkert@4373: SedimentLoadFraction f = load.getFraction(km); rrenkert@4373: if (f.getCoarse() > 0d) { rrenkert@4373: double c = resLoad.getFraction(km).getCoarse(); rrenkert@4373: resLoad.setCoarse(km, c + f.getCoarse()); rrenkert@4373: cSum++; rrenkert@4373: } rrenkert@4373: if (f.getFine_middle() > 0d) { rrenkert@4373: double fm = resLoad.getFraction(km).getFine_middle(); rrenkert@4373: resLoad.setFineMiddle(km, fm + f.getFine_middle()); rrenkert@4373: fmSum++; rrenkert@4373: } rrenkert@4373: if (f.getSand() > 0d) { rrenkert@4373: double s = resLoad.getFraction(km).getSand(); rrenkert@4373: resLoad.setSand(km, s + f.getSand()); rrenkert@4373: sSum++; rrenkert@4373: } rrenkert@4373: if (f.getSusp_sand() > 0d) { rrenkert@4522: double s = resLoad.getFraction(km).getSusp_sand(); rrenkert@4373: resLoad.setSuspSand(km, s + f.getSusp_sand()); rrenkert@4373: ssSum++; rrenkert@4373: } rrenkert@4373: if (f.getSusp_sand_bed() > 0d) { rrenkert@4373: double s = resLoad.getFraction(km).getSusp_sand_bed(); rrenkert@4373: resLoad.setSuspSandBed(km, s + f.getSusp_sand_bed()); rrenkert@4373: ssbSum++; rrenkert@4373: } rrenkert@4373: if (f.getSusp_sediment() > 0d) { rrenkert@4373: double s = resLoad.getFraction(km).getSusp_sediment(); rrenkert@4373: resLoad.setSuspSediment(km, s + f.getSusp_sediment()); rrenkert@4373: sseSum++; rrenkert@4373: } rrenkert@4373: } rrenkert@4373: SedimentLoadFraction fr = resLoad.getFraction(km); rrenkert@4373: resLoad.setCoarse(km, fr.getCoarse()/cSum); rrenkert@4373: resLoad.setFineMiddle(km, fr.getFine_middle()/fmSum); rrenkert@4373: resLoad.setSand(km, fr.getSand()/sSum); rrenkert@4373: resLoad.setSuspSand(km, fr.getSusp_sand()/ssSum); rrenkert@4373: resLoad.setSuspSandBed(km, fr.getSusp_sand_bed()/ssbSum); rrenkert@4373: resLoad.setSuspSediment(km, fr.getSusp_sediment()/sseSum); rrenkert@4373: } rrenkert@4373: resLoad.setDescription(""); rrenkert@4373: resLoad.setEpoch(true); rrenkert@4373: rrenkert@4522: SedimentLoadResult result; rrenkert@4522: SedimentLoad sl = calculateTotalLoad(resLoad, this.epoch[i][0]); rrenkert@4522: if (this.unit.equals("m3_per_a")) { rrenkert@4522: SedimentLoad slu = calculateUnit(sl, this.epoch[i][0]); rrenkert@4522: result = new SedimentLoadResult( rrenkert@4522: this.epoch[i][0], rrenkert@4522: this.epoch[i][1], rrenkert@4522: slu); rrenkert@4522: } rrenkert@4522: else { rrenkert@4522: result = new SedimentLoadResult( rrenkert@4522: this.epoch[i][0], rrenkert@4522: this.epoch[i][1], rrenkert@4522: sl); rrenkert@4522: } rrenkert@4522: rrenkert@4522: return result; rrenkert@4373: } rrenkert@4373: rrenkert@4373: private SedimentLoadResult calculateOffEpoch(int i) { rrenkert@4522: SedimentLoad load = SedimentLoadFactory.getLoadwithData( rrenkert@4522: this.river, rrenkert@4522: this.yearEpoch, rrenkert@4522: kmLow, rrenkert@4522: kmUp, rrenkert@4522: this.epoch[i][0], rrenkert@4522: this.epoch[i][1]); rrenkert@4522: SedimentLoadResult result; rrenkert@4522: SedimentLoad sl = calculateTotalLoad(load, this.epoch[i][0]); rrenkert@4522: if (unit.equals("m3_per_a")) { rrenkert@4522: SedimentLoad slu = calculateUnit(sl, epoch[i][0]); rrenkert@4522: result = new SedimentLoadResult( rrenkert@4522: this.epoch[i][0], rrenkert@4522: this.epoch[i][1], rrenkert@4522: slu); rrenkert@4522: } rrenkert@4522: else { rrenkert@4522: result = new SedimentLoadResult( rrenkert@4522: this.epoch[i][0], rrenkert@4522: this.epoch[i][1], rrenkert@4522: sl); rrenkert@4522: } rrenkert@4522: rrenkert@4522: return result; rrenkert@4373: } rrenkert@4373: rrenkert@4373: private SedimentLoadResult calculateYear(int y) { rrenkert@4373: SedimentLoad load = SedimentLoadFactory.getLoadwithData( rrenkert@4373: this.river, rrenkert@4373: this.yearEpoch, rrenkert@4373: this.kmLow, rrenkert@4373: this.kmUp, rrenkert@4373: y, rrenkert@4373: y); rrenkert@4373: rrenkert@4522: SedimentLoadResult result; rrenkert@4522: SedimentLoad sl = calculateTotalLoad(load, y); rrenkert@4373: if (unit.equals("m3_per_a")) { rrenkert@4522: SedimentLoad slu = calculateUnit(sl, y); rrenkert@4522: result = new SedimentLoadResult(y, 0, slu); rrenkert@4373: } rrenkert@4522: else { rrenkert@4522: result = new SedimentLoadResult(y, 0, sl); rrenkert@4522: } rrenkert@4373: return result; rrenkert@4373: } rrenkert@4373: rrenkert@4522: private SedimentLoad calculateTotalLoad(SedimentLoad load, int year) { rrenkert@4522: logger.debug("calculateTotalLoad"); rrenkert@4522: if (!load.hasCoarse()) { rrenkert@4522: addProblem("missing.fraction.coarse" + " " + year); rrenkert@4373: } rrenkert@4522: if (!load.hasFineMiddle()) { rrenkert@4522: addProblem("missing.fraction.fine_middle" + " " + year); rrenkert@4522: } rrenkert@4522: if (!load.hasSand()) { rrenkert@4522: addProblem("missing.fraction.sand" + " " + year); rrenkert@4522: } rrenkert@4522: if (!load.hasSuspSand()) { rrenkert@4522: addProblem("missing.fraction.susp_sand" + " " + year); rrenkert@4522: } rrenkert@4522: if (!load.hasSuspSediment()) { rrenkert@4522: addProblem("missing.fraction.susp_sediment" + " " + year); rrenkert@4522: } rrenkert@4522: if (hasProblems()) { rrenkert@4522: return load; rrenkert@4522: } rrenkert@4522: for(double km : load.getKms()) { rrenkert@4522: logger.debug("total at km " + km); rrenkert@4522: SedimentLoadFraction fraction = load.getFraction(km); rrenkert@4522: double total = 0d; rrenkert@4522: if ((fraction.getCoarse() <= 0d && load.hasCoarse())){ rrenkert@4522: addProblem(km, "missing.data.coarse"); rrenkert@4522: continue; rrenkert@4373: } rrenkert@4522: if (fraction.getFine_middle() <= 0d && load.hasFineMiddle()) { rrenkert@4522: addProblem(km, "missing.data.fine_middle"); rrenkert@4522: continue; rrenkert@4522: } rrenkert@4522: if (fraction.getSand() <= 0d && load.hasSand()) { rrenkert@4522: addProblem(km, "missing data.sand"); rrenkert@4522: continue; rrenkert@4522: } rrenkert@4522: if (fraction.getSusp_sand() <= 0d && load.hasSuspSand()) { rrenkert@4522: addProblem(km, "missing.data.susp_sand"); rrenkert@4522: continue; rrenkert@4522: } rrenkert@4522: if (fraction.getSusp_sediment() <= 0d && load.hasSuspSediment()) { rrenkert@4522: addProblem(km, "missing.data.susp_sediment"); rrenkert@4522: continue; rrenkert@4522: } rrenkert@4522: total += fraction.getCoarse() + rrenkert@4522: fraction.getFine_middle() + rrenkert@4522: fraction.getSand() + rrenkert@4522: fraction.getSusp_sand() + rrenkert@4522: fraction.getSusp_sediment(); rrenkert@4522: load.setTotal(km, total); rrenkert@4373: } rrenkert@4373: return load; rrenkert@4373: } rrenkert@4373: rrenkert@4522: private SedimentLoad calculateUnit(SedimentLoad load, int year) { rrenkert@4522: SedimentDensity density = rrenkert@4522: SedimentDensityFactory.getSedimentDensity(river, kmLow, kmUp, year); rrenkert@4522: for (double km: load.getKms()) { rrenkert@4522: double dens = density.getDensity(km, year); rrenkert@4522: logger.debug("factor: " + dens); rrenkert@4522: SedimentLoadFraction fraction = load.getFraction(km); rrenkert@4522: double coarse = fraction.getCoarse(); rrenkert@4522: double fineMiddle = fraction.getFine_middle(); rrenkert@4522: double sand = fraction.getSand(); rrenkert@4522: double suspSand = fraction.getSusp_sand(); rrenkert@4522: double bedSand = fraction.getSusp_sand_bed(); rrenkert@4522: double sediment = fraction.getSusp_sediment(); rrenkert@4522: double total = fraction.getTotal(); rrenkert@4522: logger.debug("orig: " + coarse); rrenkert@4522: load.setCoarse(km, (coarse * dens)); rrenkert@4522: load.setFineMiddle(km, (fineMiddle * dens)); rrenkert@4522: load.setSand(km, (sand * dens)); rrenkert@4522: load.setSuspSand(km, (suspSand * dens)); rrenkert@4522: load.setSuspSandBed(km, (bedSand * dens)); rrenkert@4522: load.setSuspSediment(km, (sediment * dens)); rrenkert@4522: load.setTotal(km, (total * dens)); rrenkert@4522: logger.debug("m3/a: " + load.getFraction(km).getCoarse()); rrenkert@4522: } rrenkert@4373: return load; rrenkert@4373: } rrenkert@4373: } felix@4483: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :