teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5994: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5994: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.artifacts.model; sascha@726: teichmann@5831: import org.dive4elements.river.utils.DoubleUtil; teichmann@4821: teichmann@4821: import gnu.trove.TDoubleArrayList; teichmann@4821: aheinecke@6302: import java.math.BigDecimal; aheinecke@6302: ingo@2087: import java.util.regex.Matcher; ingo@2087: import java.util.regex.Pattern; ingo@2087: sascha@1033: import org.apache.log4j.Logger; sascha@1033: sascha@726: public class WQ sascha@2182: extends W sascha@726: { ingo@2087: public static final Pattern NUMBERS_PATTERN = ingo@2087: Pattern.compile("\\D*(\\d++.\\d*)\\D*"); ingo@2087: sascha@2182: private static Logger log = Logger.getLogger(WQ.class); sascha@1033: sascha@2182: protected TDoubleArrayList qs; sascha@726: sascha@726: public WQ() { sascha@726: this(""); sascha@726: } sascha@726: sascha@726: public WQ(String name) { sascha@2182: super(name); sascha@2182: qs = new TDoubleArrayList(); sascha@726: } sascha@726: sascha@726: public WQ(int capacity) { sascha@726: this(capacity, ""); sascha@726: } sascha@726: sascha@726: sascha@726: public WQ(int capacity, String name) { sascha@2182: super(capacity, name); sascha@2182: qs = new TDoubleArrayList(capacity); sascha@726: } sascha@726: sascha@726: public WQ(double [] qs, double [] ws) { sascha@726: this(qs, ws, ""); sascha@726: } sascha@726: sascha@726: public WQ(double [] qs, double [] ws, String name) { sascha@726: super(name); sascha@2182: this.ws = new TDoubleArrayList(ws); sascha@2182: this.qs = new TDoubleArrayList(qs); sascha@726: } sascha@726: felix@7648: public WQ(TDoubleArrayList qs, TDoubleArrayList ws, String name) { felix@7648: super(name); felix@7648: this.ws = ws; felix@7648: this.qs = qs; felix@7648: } felix@7648: ingo@2087: ingo@2087: public Double getRawValue() { ingo@2087: if (name == null || name.length() == 0) { ingo@2087: // this should never happen ingo@2087: return null; ingo@2087: } ingo@2087: ingo@2087: Matcher m = NUMBERS_PATTERN.matcher(name); ingo@2087: ingo@2087: if (m.matches()) { ingo@2087: String raw = m.group(1); ingo@2087: ingo@2087: try { ingo@2087: return Double.valueOf(raw); ingo@2087: } ingo@2087: catch (NumberFormatException nfe) { ingo@2087: // do nothing ingo@2087: } ingo@2087: } ingo@2087: ingo@2087: return null; ingo@2087: } ingo@2087: sascha@726: public void add(double w, double q) { sascha@2182: ws.add(w); sascha@2182: qs.add(q); sascha@726: } sascha@726: sascha@726: public double getQ(int idx) { sascha@2182: return qs.getQuick(idx); sascha@726: } sascha@726: sascha@2182: @Override sascha@726: public double [] get(int idx) { sascha@726: return get(idx, new double [2]); sascha@726: } sascha@726: sascha@2182: @Override sascha@726: public double [] get(int idx, double [] dst) { sascha@2182: dst[0] = ws.getQuick(idx); sascha@2182: dst[1] = qs.getQuick(idx); sascha@726: return dst; sascha@726: } sascha@726: sascha@726: public double [] getQs() { sascha@2182: return qs.toNativeArray(); sascha@744: } sascha@744: sascha@2182: @Override sascha@2182: public void removeNaNs() { teichmann@4821: DoubleUtil.removeNaNs(new TDoubleArrayList [] { ws, qs }); sascha@1033: } aheinecke@6302: aheinecke@6302: /** Returns either a modified copy or the same Object with fixed W values. aheinecke@6302: * If a conversion takes place converted is set to true aheinecke@6302: */ aheinecke@6302: public static WQ getFixedWQforExportAtGauge(WQ wq, BigDecimal datum) { teichmann@7930: if (wq.getReferenceSystem() == W.CENTIMETER_AT_GAUGE) { aheinecke@6302: // Do nothing aheinecke@6302: return wq; aheinecke@6302: } aheinecke@6302: // If we convert we work on a copy to avoid side effects. aheinecke@6302: WQ ret = new WQ(wq.size(), wq.getName()); teichmann@7930: ret.setReferenceSystem(W.CENTIMETER_AT_GAUGE); aheinecke@6302: aheinecke@6302: // When we convert and have a datum we have a calculated aheinecke@6302: // result at a gauge so we must subtract the datum. aheinecke@6302: double subtractDatum = datum == null ? 0 : datum.doubleValue(); teichmann@7254: double [] data = new double[8]; teichmann@7254: for (int i = 0, WQ = wq.size(); i < WQ; i++) { teichmann@7254: wq.get(i, data); teichmann@7254: ret.add((data[0] - subtractDatum)*100d, data[1]); aheinecke@6302: } aheinecke@6302: log.debug("Converted W values to centimeter and substracted: " + subtractDatum); aheinecke@6302: return ret; aheinecke@6302: } sascha@726: } sascha@726: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :