822d6df0 by Nathan Lighthart

Add ability to separate regionalization parameters to separate file

- Add dataFileReg to the ages parameters
- Set parameters from dataFileReg to the ages context
- Import CSProperties and DataIO routines from OMS
1 parent 286e4e93
...@@ -33,7 +33,9 @@ import groundwater.ProcessGroundwaterAdapter; ...@@ -33,7 +33,9 @@ import groundwater.ProcessGroundwaterAdapter;
33 import interception.ProcessInterceptionAdapter; 33 import interception.ProcessInterceptionAdapter;
34 import io.ArrayGrabberAdapter; 34 import io.ArrayGrabberAdapter;
35 import io.CO2ClimateReader; 35 import io.CO2ClimateReader;
36 import io.CSProperties;
36 import io.ClimateReader; 37 import io.ClimateReader;
38 import io.DataIO;
37 import io.EntityIDFilter; 39 import io.EntityIDFilter;
38 import io.EntityReader; 40 import io.EntityReader;
39 import io.ManagementParameterReader; 41 import io.ManagementParameterReader;
...@@ -419,6 +421,7 @@ public class AgESModel { ...@@ -419,6 +421,7 @@ public class AgESModel {
419 agesContext.put("basinArea", basinArea); 421 agesContext.put("basinArea", basinArea);
420 422
421 addClimateStations(agesContext); 423 addClimateStations(agesContext);
424 addRegionalizationParameters();
422 } 425 }
423 426
424 private void addClimateStations(Context context) { 427 private void addClimateStations(Context context) {
...@@ -452,6 +455,50 @@ public class AgESModel { ...@@ -452,6 +455,50 @@ public class AgESModel {
452 context.put("elevation" + type, elevation); 455 context.put("elevation" + type, elevation);
453 } 456 }
454 457
458 private void addRegionalizationParameters() {
459 if (parameters.dataFileReg == null) {
460 return;
461 }
462
463 CSProperties regionalizationProperties;
464 try {
465 regionalizationProperties = DataIO.properties(
466 parameters.dataFileReg.toFile(), null);
467 } catch (IOException ex) {
468 throw new RuntimeException("Error reading regionalization parameter file: "
469 + parameters.dataFileReg, ex);
470 }
471
472 // Grab main parameters
473 addRegionalizationParameter(regionalizationProperties, "projection");
474 addRegionalizationParameter(regionalizationProperties, "regThres");
475 addRegionalizationParameter(regionalizationProperties, "equalWeights");
476
477 // Grab climate specific parameters
478 String[] climateTypes = new String[]{"Tmin", "Tmax", "Tmean", "Hum", "Precip", "Wind", "Sol"};
479 for (String climateType : climateTypes) {
480 addRegionalizationParameter(regionalizationProperties, "nidw" + climateType);
481 addRegionalizationParameter(regionalizationProperties, "pidw" + climateType);
482 addRegionalizationParameter(regionalizationProperties, "rsqThreshold" + climateType);
483 addRegionalizationParameter(regionalizationProperties, "elevationCorrection" + climateType);
484 }
485
486 // Grab rainfall correction parameters
487 addRegionalizationParameter(regionalizationProperties, "windNIDW");
488 addRegionalizationParameter(regionalizationProperties, "precipCorrectMethod");
489 addRegionalizationParameter(regionalizationProperties, "tempNIDW");
490 addRegionalizationParameter(regionalizationProperties, "pIDW");
491 }
492
493 private void addRegionalizationParameter(Map<String, Object> dataMap, String name) {
494 if (dataMap.containsKey(name)) {
495 Object value = dataMap.get(name);
496 agesContext.put(name, value);
497 } else {
498 throw new RuntimeException("Missing regionalization parameter: " + name);
499 }
500 }
501
455 private void initializeTemporalContext() { 502 private void initializeTemporalContext() {
456 temporalContext = new MapContext(); 503 temporalContext = new MapContext();
457 504
......
...@@ -79,6 +79,9 @@ public class AgESParameters { ...@@ -79,6 +79,9 @@ public class AgESParameters {
79 @Description("HRU parameter override file path") 79 @Description("HRU parameter override file path")
80 public final Path hruOverrideFilePath; 80 public final Path hruOverrideFilePath;
81 81
82 @Description("HRU parameter override file path")
83 public final Path dataFileReg;
84
82 @Description("Surface program file path") 85 @Description("Surface program file path")
83 public final Path surfaceProgramFilePath; 86 public final Path surfaceProgramFilePath;
84 87
...@@ -693,6 +696,7 @@ public class AgESParameters { ...@@ -693,6 +696,7 @@ public class AgESParameters {
693 dataFileWind = builder.dataFileWind; 696 dataFileWind = builder.dataFileWind;
694 dataFileCO2 = builder.dataFileCO2; 697 dataFileCO2 = builder.dataFileCO2;
695 hruOverrideFilePath = builder.hruOverrideFilePath; 698 hruOverrideFilePath = builder.hruOverrideFilePath;
699 dataFileReg = builder.dataFileReg;
696 700
697 surfaceProgramFilePath = builder.surfaceProgramFilePath; 701 surfaceProgramFilePath = builder.surfaceProgramFilePath;
698 subSurfaceProgramFilePath = builder.subSurfaceProgramFilePath; 702 subSurfaceProgramFilePath = builder.subSurfaceProgramFilePath;
...@@ -923,6 +927,7 @@ public class AgESParameters { ...@@ -923,6 +927,7 @@ public class AgESParameters {
923 private Path dataFileWind; 927 private Path dataFileWind;
924 private Path dataFileCO2; 928 private Path dataFileCO2;
925 private Path hruOverrideFilePath; 929 private Path hruOverrideFilePath;
930 private Path dataFileReg;
926 931
927 private Path surfaceProgramFilePath; 932 private Path surfaceProgramFilePath;
928 private Path subSurfaceProgramFilePath; 933 private Path subSurfaceProgramFilePath;
...@@ -1310,6 +1315,11 @@ public class AgESParameters { ...@@ -1310,6 +1315,11 @@ public class AgESParameters {
1310 return this; 1315 return this;
1311 } 1316 }
1312 1317
1318 public Builder dataFileReg(Path regionalizationFilePath) {
1319 this.dataFileReg = regionalizationFilePath;
1320 return this;
1321 }
1322
1313 public Builder surfaceProgramFilePath(Path surfaceProgramFilePath) { 1323 public Builder surfaceProgramFilePath(Path surfaceProgramFilePath) {
1314 this.surfaceProgramFilePath = surfaceProgramFilePath; 1324 this.surfaceProgramFilePath = surfaceProgramFilePath;
1315 return this; 1325 return this;
......
1 /*
2 * $Id$
3 *
4 * This file is part of the Object Modeling System (OMS),
5 * 2007-2012, Olaf David and others, Colorado State University.
6 *
7 * OMS is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, version 2.1.
10 *
11 * OMS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with OMS. If not, see <http://www.gnu.org/licenses/lgpl.txt>.
18 */
19 package io;
20
21 import java.util.Map;
22
23 /** Comma separated properties
24 *
25 * @author od
26 */
27 public interface CSProperties extends Map<String, Object> {
28
29 /** Get the name of the propertyset
30 *
31 * @return the name
32 */
33 String getName();
34
35 /**
36 * Set the name
37 * @param name
38 */
39 void setName(String name);
40
41 /** Get the annotations for the propertyset.
42 *
43 * @return the info for the propertyset.
44 */
45 Map<String, String> getInfo();
46
47 /** Get the info for a property.
48 *
49 * @param propertyName
50 * @return the annotations for this property.
51 */
52 Map<String, String> getInfo(String propertyName);
53
54 void setInfo(String propertyname, Map<String, String> info);
55
56 public void putAll(CSProperties p);
57 }
...@@ -31,6 +31,8 @@ import java.util.HashMap; ...@@ -31,6 +31,8 @@ import java.util.HashMap;
31 import java.util.LinkedHashMap; 31 import java.util.LinkedHashMap;
32 import java.util.List; 32 import java.util.List;
33 import java.util.Map; 33 import java.util.Map;
34 import java.util.Properties;
35 import java.util.regex.Matcher;
34 import java.util.regex.Pattern; 36 import java.util.regex.Pattern;
35 37
36 /** 38 /**
...@@ -120,6 +122,82 @@ public class DataIO { ...@@ -120,6 +122,82 @@ public class DataIO {
120 } 122 }
121 123
122 /** 124 /**
125 * Parse properties from a reader
126 *
127 * @param r the Reader
128 * @param name the name of the properties
129 * @return properties from a file.
130 * @throws java.io.IOException
131 */
132 public static CSProperties properties(Reader r, String name) throws IOException {
133 return new CSVProperties(r, name);
134 }
135
136 public static CSProperties properties(File r, String name) throws IOException {
137 return new CSVProperties(new FileReader(r), name);
138 }
139
140 /**
141 * Create a CSProperty from an array of reader.
142 *
143 * @param r
144 * @param name
145 * @return merged properties.
146 * @throws java.io.IOException
147 */
148 public static CSProperties properties(Reader[] r, String name) throws IOException {
149 CSVProperties p = new CSVProperties(r[0], name);
150 for (int i = 1; i < r.length; i++) {
151 CSVParser csv = new CSVParser(r[i], CSVStrategy.DEFAULT_STRATEGY);
152 locate(csv, name, PROPERTIES, PROPERTIES1);
153 p.readProps(csv);
154 r[i].close();
155 }
156 return p;
157 }
158
159 /**
160 * Convert CSProperties into Properties
161 *
162 * @param p
163 * @return the Properties.
164 */
165 public static Properties properties(CSProperties p) {
166 Properties pr = new Properties();
167 pr.putAll(p);
168 return pr;
169 }
170
171 /**
172 * Convert Properties to CSProperties.
173 *
174 * @param p the Properties
175 * @return CSProperties
176 */
177 public static CSProperties properties(Properties p) {
178 return new BasicCSProperties(p);
179 }
180
181 /**
182 * Convert from a Map to properties.
183 *
184 * @param p the source map
185 * @return CSProperties
186 */
187 public static CSProperties properties(Map<String, Object> p) {
188 return new BasicCSProperties(p);
189 }
190
191 /**
192 * Create Empty properties
193 *
194 * @return get some empty properties.
195 */
196 public static CSProperties properties() {
197 return new BasicCSProperties();
198 }
199
200 /**
123 * Parse the first table from a file 201 * Parse the first table from a file
124 * 202 *
125 * @param file the file to parse 203 * @param file the file to parse
...@@ -181,6 +259,169 @@ public class DataIO { ...@@ -181,6 +259,169 @@ public class DataIO {
181 throw new IllegalArgumentException("Not found : " + Arrays.toString(type) + ", " + name); 259 throw new IllegalArgumentException("Not found : " + Arrays.toString(type) + ", " + name);
182 } 260 }
183 261
262 // @SuppressWarnings("serial")
263 private static class BasicCSProperties extends LinkedHashMap<String, Object> implements CSProperties {
264
265 private static final long serialVersionUID = 1L;
266
267 String name = "";
268 Map<String, Map<String, String>> info = new HashMap<String, Map<String, String>>();
269
270 BasicCSProperties(Properties p) {
271 this();
272 for (Object key : p.keySet()) {
273 put(key.toString(), p.getProperty(key.toString()));
274 }
275 }
276
277 BasicCSProperties(Map<String, Object> p) {
278 this();
279 for (String key : p.keySet()) {
280 put(key, p.get(key));
281 }
282 }
283
284 BasicCSProperties() {
285 info.put(ROOT_ANN, new LinkedHashMap<String, String>());
286 }
287
288 @Override
289 public void putAll(CSProperties p) {
290 for (String key : p.keySet()) {
291 if (containsKey(key)) {
292 throw new IllegalArgumentException("Duplicate key in parameter sets: " + key);
293 }
294 }
295 super.putAll(p);
296 for (String s : p.keySet()) {
297 Map<String, String> m = p.getInfo(s);
298 setInfo(s, m);
299 }
300 getInfo().putAll(p.getInfo());
301 }
302
303 @Override
304 public String getName() {
305 return name;
306 }
307
308 @Override
309 public void setName(String name) {
310 this.name = name;
311 }
312
313 @Override
314 public synchronized Map<String, String> getInfo(String property) {
315 Map<String, String> im = info.get(property);
316 // return (im == null) ? NOINFO : im;
317 if (im == null) {
318 im = new HashMap<String, String>();
319 info.put(property, im);
320 }
321 return im;
322 }
323
324 @Override
325 public Map<String, String> getInfo() {
326 return getInfo(ROOT_ANN);
327 }
328
329 @Override
330 public void setInfo(String propertyname, Map<String, String> inf) {
331 info.put(propertyname, inf);
332 }
333
334 // @Override
335 // public String get(Object key) {
336 // Object val = super.get(key.toString());
337 // return val.toString();
338 //// return resolve(val != null ? val.toString() : null);
339 // }
340 //
341 @Override
342 public Object get(Object key) {
343 Object val = super.get(key);
344 if (val != null && val.getClass() == String.class) {
345 return resolve((String) val);
346 }
347 return val;
348 }
349
350 /**
351 * Resolve variable substitution.
352 *
353 * @P, dir, "/tmp/input"
354 * @P, file, "${dir}/test.txt"
355 *
356 * - The referenced key has to be in the same properties set. - there
357 * could be a chain of references, however, no recursion testing is
358 * implemented.
359 *
360 * @param str
361 * @return
362 */
363 private String resolve(String str) {
364 if (str != null && str.contains("${")) {
365 Matcher ma = null;
366 while ((ma = varPattern.matcher(str)).find()) {
367 String key = ma.group(1);
368 String val = (String) get(key);
369 if (val == null) {
370 throw new IllegalArgumentException("value substitution failed for " + key);
371 }
372 Pattern repl = Pattern.compile("\\$\\{" + key + "\\}");
373 str = repl.matcher(str).replaceAll(val);
374 }
375 }
376 return str;
377 }
378 }
379
380 /**
381 * Note: to keep the order of properties, it is sub-classed from
382 * LinkedHashMap
383 */
384 @SuppressWarnings("serial")
385 private static class CSVProperties extends BasicCSProperties implements CSProperties {
386
387 CSVProperties(Reader reader, String name) throws IOException {
388 super();
389 CSVParser csv = new CSVParser(reader, CSVStrategy.DEFAULT_STRATEGY);
390 this.name = locate(csv, name, PROPERTIES, PROPERTIES1);
391 readProps(csv);
392 reader.close();
393 }
394
395 private void readProps(CSVParser csv) throws IOException {
396 Map<String, String> propInfo = null;
397 String[] line = null;
398 String propKey = ROOT_ANN;
399 while ((line = csv.getLine()) != null
400 && !line[0].equalsIgnoreCase(PROPERTIES)
401 && !line[0].equalsIgnoreCase(PROPERTIES1)
402 && !line[0].equalsIgnoreCase(TABLE)
403 && !line[0].equalsIgnoreCase(TABLE1)) {
404 if (line[0].startsWith(COMMENT) || line[0].isEmpty()) {
405 continue;
406 }
407 if (line[0].equalsIgnoreCase(PROPERTY) || line[0].equalsIgnoreCase(PROPERTY1)) {
408 if (line.length < 2) {
409 throw new IOException("Expected property name in line " + csv.getLineNumber());
410 }
411 propKey = line[1];
412 // maybe there is no value for the property, so we add null
413 put(propKey, (line.length > 2) ? line[2] : null);
414 propInfo = null;
415 } else {
416 if (propInfo == null) {
417 info.put(propKey, propInfo = new HashMap<String, String>());
418 }
419 propInfo.put(line[0], (line.length > 1) ? line[1] : null);
420 }
421 }
422 }
423 }
424
184 /** 425 /**
185 * CSVTable implementation 426 * CSVTable implementation
186 */ 427 */
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!