comparison flys-artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixATWriter.java @ 5831:bd047b71ab37

Repaired internal references
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 12:06:39 +0200
parents flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java@8bbb9e173297
children
comparison
equal deleted inserted replaced
5830:160f53ee0870 5831:bd047b71ab37
1 package org.dive4elements.river.exports.fixings;
2
3 import org.dive4elements.artifacts.CallMeta;
4
5 import org.dive4elements.river.artifacts.math.fitting.Function;
6
7 import org.dive4elements.river.artifacts.model.Parameters;
8
9 import org.dive4elements.river.artifacts.resources.Resources;
10
11 import org.dive4elements.river.exports.ATWriter;
12
13 import java.io.IOException;
14 import java.io.PrintWriter;
15 import java.io.Writer;
16
17 import java.util.Locale;
18
19 import org.apache.log4j.Logger;
20
21 /** Export Fixation Analysis Results to AT. */
22 public class FixATWriter
23 {
24 /** Private logger. */
25 private static Logger log = Logger.getLogger(FixATWriter.class);
26
27 public static final String I18N_HEADER_KEY =
28 "fix.export.at.header";
29
30 public static final String I18N_HEADER_DEFAULT =
31 "Exported fixings discharge curve for {0} {0}-km: {1}";
32
33 public static final String [] Q_MAX_COLUMN = new String [] { "max_q" };
34
35 private static final int MAX_ITERATIONS = 10000;
36 private static final double EPSILON = 1e-8;
37 private static final double MIN_Q = 1e-4;
38
39 protected Function function;
40 protected Parameters parameters;
41
42 public FixATWriter() {
43 }
44
45 public FixATWriter(Function function, Parameters parameters) {
46 this.function = function;
47 this.parameters = parameters;
48 }
49
50 public void write(
51 Writer writer,
52 CallMeta meta,
53 String river,
54 double km
55 )
56 throws IOException {
57 PrintWriter out = new PrintWriter(writer);
58 printHeader(out, meta, river, km);
59
60 double [] coeffs = parameters.interpolate(
61 "km", km, function.getParameterNames());
62
63 double [] qMax = parameters.interpolate(
64 "km", km, Q_MAX_COLUMN);
65
66 if (coeffs == null || qMax == null) {
67 log.debug("No data found at km " + km + ".");
68 return;
69 }
70
71 org.dive4elements.river.artifacts.math.Function funcInst =
72 function.instantiate(coeffs);
73
74 // Increase Q max about 5%.
75 qMax[0] += Math.abs(qMax[0])*0.05;
76
77 double wMax = funcInst.value(qMax[0]);
78
79 if (Double.isNaN(wMax) || wMax < 0d) {
80 log.debug("function '" + function.getName() +
81 "' eval failed at " + wMax);
82 return;
83 }
84
85 Function inverse = function.getInverse();
86
87 org.dive4elements.river.artifacts.math.Function invInst =
88 inverse.instantiate(coeffs);
89
90 double wMin = minW(invInst, wMax, qMax[0]);
91
92 double wMinCM = wMin * 100d;
93 double wMaxCM = wMax * 100d;
94
95 int wRow = ((int)wMinCM / 10) * 10;
96
97 if ((wMinCM - (int)wMinCM) > 0d) {
98 wMinCM = (int)wMinCM + 1d;
99 }
100
101 double w = wMinCM / 100.0;
102
103 int wcm = ((int)wMinCM) % 10;
104
105 if (log.isDebugEnabled()) {
106 log.debug("wMinCM: " + wMinCM);
107 log.debug("wMaxCM: " + wMaxCM);
108 log.debug("wcm: " + wcm);
109 }
110
111 out.printf(Locale.US, "%8d", wRow);
112
113 if (wcm > 0) {
114 int rest = 10 - wcm;
115 while (rest-- > 0) {
116 out.print(ATWriter.EMPTY);
117 }
118 }
119
120 for (;;) {
121 while (wcm++ < 10) {
122 if (w > wMax) {
123 break;
124 }
125 double q = invInst.value(w);
126 if (Double.isNaN(w)) {
127 out.print(ATWriter.EMPTY);
128 }
129 else {
130 ATWriter.printQ(out, q);
131 }
132 w += 0.01d;
133 }
134 out.println();
135 if (w > wMax) {
136 break;
137 }
138 out.printf(Locale.US, "%8d", wRow += 10);
139 wcm = 0;
140 }
141
142 out.flush();
143 }
144
145 protected void printHeader(
146 PrintWriter out,
147 CallMeta meta,
148 String river,
149 double km
150 ) {
151 out.println(Resources.format(
152 meta,
153 I18N_HEADER_KEY,
154 I18N_HEADER_DEFAULT,
155 river, km));
156 }
157
158 private static double minW(
159 org.dive4elements.river.artifacts.math.Function function,
160 double maxW,
161 double maxQ
162 ) {
163 double stepWidth = 10d;
164
165 double lastW = maxW;
166 double lastQ = maxQ;
167
168 for (int i = 0; i < MAX_ITERATIONS; ++i) {
169 double w = lastW - stepWidth;
170 double q = function.value(w);
171
172 if (Double.isNaN(q) || q > lastQ || q < MIN_Q) {
173 if (stepWidth < EPSILON) {
174 break;
175 }
176 stepWidth *= 0.5d;
177 continue;
178 }
179
180 lastW = w;
181 lastQ = q;
182 }
183
184 return lastW;
185 }
186 }
187 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org