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;
import interception.ProcessInterceptionAdapter;
import io.ArrayGrabberAdapter;
import io.CO2ClimateReader;
import io.CSProperties;
import io.ClimateReader;
import io.DataIO;
import io.EntityIDFilter;
import io.EntityReader;
import io.ManagementParameterReader;
......@@ -419,6 +421,7 @@ public class AgESModel {
agesContext.put("basinArea", basinArea);
addClimateStations(agesContext);
addRegionalizationParameters();
}
private void addClimateStations(Context context) {
......@@ -452,6 +455,50 @@ public class AgESModel {
context.put("elevation" + type, elevation);
}
private void addRegionalizationParameters() {
if (parameters.dataFileReg == null) {
return;
}
CSProperties regionalizationProperties;
try {
regionalizationProperties = DataIO.properties(
parameters.dataFileReg.toFile(), null);
} catch (IOException ex) {
throw new RuntimeException("Error reading regionalization parameter file: "
+ parameters.dataFileReg, ex);
}
// Grab main parameters
addRegionalizationParameter(regionalizationProperties, "projection");
addRegionalizationParameter(regionalizationProperties, "regThres");
addRegionalizationParameter(regionalizationProperties, "equalWeights");
// Grab climate specific parameters
String[] climateTypes = new String[]{"Tmin", "Tmax", "Tmean", "Hum", "Precip", "Wind", "Sol"};
for (String climateType : climateTypes) {
addRegionalizationParameter(regionalizationProperties, "nidw" + climateType);
addRegionalizationParameter(regionalizationProperties, "pidw" + climateType);
addRegionalizationParameter(regionalizationProperties, "rsqThreshold" + climateType);
addRegionalizationParameter(regionalizationProperties, "elevationCorrection" + climateType);
}
// Grab rainfall correction parameters
addRegionalizationParameter(regionalizationProperties, "windNIDW");
addRegionalizationParameter(regionalizationProperties, "precipCorrectMethod");
addRegionalizationParameter(regionalizationProperties, "tempNIDW");
addRegionalizationParameter(regionalizationProperties, "pIDW");
}
private void addRegionalizationParameter(Map<String, Object> dataMap, String name) {
if (dataMap.containsKey(name)) {
Object value = dataMap.get(name);
agesContext.put(name, value);
} else {
throw new RuntimeException("Missing regionalization parameter: " + name);
}
}
private void initializeTemporalContext() {
temporalContext = new MapContext();
......
......@@ -79,6 +79,9 @@ public class AgESParameters {
@Description("HRU parameter override file path")
public final Path hruOverrideFilePath;
@Description("HRU parameter override file path")
public final Path dataFileReg;
@Description("Surface program file path")
public final Path surfaceProgramFilePath;
......@@ -693,6 +696,7 @@ public class AgESParameters {
dataFileWind = builder.dataFileWind;
dataFileCO2 = builder.dataFileCO2;
hruOverrideFilePath = builder.hruOverrideFilePath;
dataFileReg = builder.dataFileReg;
surfaceProgramFilePath = builder.surfaceProgramFilePath;
subSurfaceProgramFilePath = builder.subSurfaceProgramFilePath;
......@@ -923,6 +927,7 @@ public class AgESParameters {
private Path dataFileWind;
private Path dataFileCO2;
private Path hruOverrideFilePath;
private Path dataFileReg;
private Path surfaceProgramFilePath;
private Path subSurfaceProgramFilePath;
......@@ -1310,6 +1315,11 @@ public class AgESParameters {
return this;
}
public Builder dataFileReg(Path regionalizationFilePath) {
this.dataFileReg = regionalizationFilePath;
return this;
}
public Builder surfaceProgramFilePath(Path surfaceProgramFilePath) {
this.surfaceProgramFilePath = surfaceProgramFilePath;
return this;
......
/*
* $Id$
*
* This file is part of the Object Modeling System (OMS),
* 2007-2012, Olaf David and others, Colorado State University.
*
* OMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 2.1.
*
* OMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OMS. If not, see <http://www.gnu.org/licenses/lgpl.txt>.
*/
package io;
import java.util.Map;
/** Comma separated properties
*
* @author od
*/
public interface CSProperties extends Map<String, Object> {
/** Get the name of the propertyset
*
* @return the name
*/
String getName();
/**
* Set the name
* @param name
*/
void setName(String name);
/** Get the annotations for the propertyset.
*
* @return the info for the propertyset.
*/
Map<String, String> getInfo();
/** Get the info for a property.
*
* @param propertyName
* @return the annotations for this property.
*/
Map<String, String> getInfo(String propertyName);
void setInfo(String propertyname, Map<String, String> info);
public void putAll(CSProperties p);
}
......@@ -31,6 +31,8 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
......@@ -120,6 +122,82 @@ public class DataIO {
}
/**
* Parse properties from a reader
*
* @param r the Reader
* @param name the name of the properties
* @return properties from a file.
* @throws java.io.IOException
*/
public static CSProperties properties(Reader r, String name) throws IOException {
return new CSVProperties(r, name);
}
public static CSProperties properties(File r, String name) throws IOException {
return new CSVProperties(new FileReader(r), name);
}
/**
* Create a CSProperty from an array of reader.
*
* @param r
* @param name
* @return merged properties.
* @throws java.io.IOException
*/
public static CSProperties properties(Reader[] r, String name) throws IOException {
CSVProperties p = new CSVProperties(r[0], name);
for (int i = 1; i < r.length; i++) {
CSVParser csv = new CSVParser(r[i], CSVStrategy.DEFAULT_STRATEGY);
locate(csv, name, PROPERTIES, PROPERTIES1);
p.readProps(csv);
r[i].close();
}
return p;
}
/**
* Convert CSProperties into Properties
*
* @param p
* @return the Properties.
*/
public static Properties properties(CSProperties p) {
Properties pr = new Properties();
pr.putAll(p);
return pr;
}
/**
* Convert Properties to CSProperties.
*
* @param p the Properties
* @return CSProperties
*/
public static CSProperties properties(Properties p) {
return new BasicCSProperties(p);
}
/**
* Convert from a Map to properties.
*
* @param p the source map
* @return CSProperties
*/
public static CSProperties properties(Map<String, Object> p) {
return new BasicCSProperties(p);
}
/**
* Create Empty properties
*
* @return get some empty properties.
*/
public static CSProperties properties() {
return new BasicCSProperties();
}
/**
* Parse the first table from a file
*
* @param file the file to parse
......@@ -181,6 +259,169 @@ public class DataIO {
throw new IllegalArgumentException("Not found : " + Arrays.toString(type) + ", " + name);
}
// @SuppressWarnings("serial")
private static class BasicCSProperties extends LinkedHashMap<String, Object> implements CSProperties {
private static final long serialVersionUID = 1L;
String name = "";
Map<String, Map<String, String>> info = new HashMap<String, Map<String, String>>();
BasicCSProperties(Properties p) {
this();
for (Object key : p.keySet()) {
put(key.toString(), p.getProperty(key.toString()));
}
}
BasicCSProperties(Map<String, Object> p) {
this();
for (String key : p.keySet()) {
put(key, p.get(key));
}
}
BasicCSProperties() {
info.put(ROOT_ANN, new LinkedHashMap<String, String>());
}
@Override
public void putAll(CSProperties p) {
for (String key : p.keySet()) {
if (containsKey(key)) {
throw new IllegalArgumentException("Duplicate key in parameter sets: " + key);
}
}
super.putAll(p);
for (String s : p.keySet()) {
Map<String, String> m = p.getInfo(s);
setInfo(s, m);
}
getInfo().putAll(p.getInfo());
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public synchronized Map<String, String> getInfo(String property) {
Map<String, String> im = info.get(property);
// return (im == null) ? NOINFO : im;
if (im == null) {
im = new HashMap<String, String>();
info.put(property, im);
}
return im;
}
@Override
public Map<String, String> getInfo() {
return getInfo(ROOT_ANN);
}
@Override
public void setInfo(String propertyname, Map<String, String> inf) {
info.put(propertyname, inf);
}
// @Override
// public String get(Object key) {
// Object val = super.get(key.toString());
// return val.toString();
//// return resolve(val != null ? val.toString() : null);
// }
//
@Override
public Object get(Object key) {
Object val = super.get(key);
if (val != null && val.getClass() == String.class) {
return resolve((String) val);
}
return val;
}
/**
* Resolve variable substitution.
*
* @P, dir, "/tmp/input"
* @P, file, "${dir}/test.txt"
*
* - The referenced key has to be in the same properties set. - there
* could be a chain of references, however, no recursion testing is
* implemented.
*
* @param str
* @return
*/
private String resolve(String str) {
if (str != null && str.contains("${")) {
Matcher ma = null;
while ((ma = varPattern.matcher(str)).find()) {
String key = ma.group(1);
String val = (String) get(key);
if (val == null) {
throw new IllegalArgumentException("value substitution failed for " + key);
}
Pattern repl = Pattern.compile("\\$\\{" + key + "\\}");
str = repl.matcher(str).replaceAll(val);
}
}
return str;
}
}
/**
* Note: to keep the order of properties, it is sub-classed from
* LinkedHashMap
*/
@SuppressWarnings("serial")
private static class CSVProperties extends BasicCSProperties implements CSProperties {
CSVProperties(Reader reader, String name) throws IOException {
super();
CSVParser csv = new CSVParser(reader, CSVStrategy.DEFAULT_STRATEGY);
this.name = locate(csv, name, PROPERTIES, PROPERTIES1);
readProps(csv);
reader.close();
}
private void readProps(CSVParser csv) throws IOException {
Map<String, String> propInfo = null;
String[] line = null;
String propKey = ROOT_ANN;
while ((line = csv.getLine()) != null
&& !line[0].equalsIgnoreCase(PROPERTIES)
&& !line[0].equalsIgnoreCase(PROPERTIES1)
&& !line[0].equalsIgnoreCase(TABLE)
&& !line[0].equalsIgnoreCase(TABLE1)) {
if (line[0].startsWith(COMMENT) || line[0].isEmpty()) {
continue;
}
if (line[0].equalsIgnoreCase(PROPERTY) || line[0].equalsIgnoreCase(PROPERTY1)) {
if (line.length < 2) {
throw new IOException("Expected property name in line " + csv.getLineNumber());
}
propKey = line[1];
// maybe there is no value for the property, so we add null
put(propKey, (line.length > 2) ? line[2] : null);
propInfo = null;
} else {
if (propInfo == null) {
info.put(propKey, propInfo = new HashMap<String, String>());
}
propInfo.put(line[0], (line.length > 1) ? line[1] : null);
}
}
}
}
/**
* CSVTable implementation
*/
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!