Mercurial > dive4elements > river
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 : |