package org.opensha2.gmm;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.nio.charset.StandardCharsets.UTF_8;
import org.opensha2.internal.Parsing;
import org.opensha2.internal.Parsing.Delimiter;
import com.google.common.collect.ArrayTable;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import com.google.common.io.Resources;
import com.google.common.primitives.Doubles;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Class loads and manages {@code GroundMotionModel} coefficients.
*
* <p>Coefficients are loaded from CSV files. When such files are updated, it
* may be necessary to edit certain {@code Imt} designations that are commonly
* coded as integers (e.g. -1 = PGV, usually) or coefficient IDs that contain
* illegal characters (e.g those with units labels in parentheses).
*
* @author Peter Powers
*/
final class CoefficientContainer {
private static final String C_DIR = "coeffs/";
private Table<Imt, String, Double> table;
/**
* Create a new coefficent container from a comma-delimited coefficient
* resource.
*
* @param resource coefficent csv text resource
*/
CoefficientContainer(String resource) {
try {
table = ImmutableTable.copyOf(load(resource));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Return the value of the coefficient for the supplied name and intensity
* measure type.
*
* @param imt intensity measure type
* @param name of the coefficient to look up
*/
double get(Imt imt, String name) {
return table.get(imt, name);
}
/**
* Return a {@code Map} of all coefficient for the supplied intensity measure
* type.
*
* @param imt intensity measure type
*/
Map<String, Double> get(Imt imt) {
return table.row(imt);
}
/**
* Returns the {@code Set} of intensity measure types (IMTs) for which
* coefficients are supplied.
* @return the {@code Set} of supported IMTs
*/
Set<Imt> imts() {
return Sets.immutableEnumSet(table.rowKeySet());
}
private static Table<Imt, String, Double> load(String resource) throws IOException {
URL url = Resources.getResource(CoefficientContainer.class, C_DIR + resource);
List<String> lines = Resources.readLines(url, UTF_8);
// build coeff name list
Iterable<String> names = FluentIterable
.from(Parsing.split(lines.get(0), Delimiter.COMMA))
.skip(1);
// build Imt-value map
Map<Imt, Double[]> valueMap = Maps.newHashMap();
for (String line : Iterables.skip(lines, 1)) {
Iterable<String> entries = Parsing.split(line, Delimiter.COMMA);
String imtStr = Iterables.get(entries, 0);
Imt imt = Imt.parseImt(imtStr);
checkNotNull(imt, "Unparseable Imt: " + imtStr);
Iterable<String> valStrs = Iterables.skip(entries, 1);
Iterable<Double> values = Iterables.transform(valStrs, Doubles.stringConverter());
valueMap.put(imt, Iterables.toArray(values, Double.class));
}
// create and load table
Table<Imt, String, Double> table = ArrayTable.create(valueMap.keySet(), names);
for (Imt imt : valueMap.keySet()) {
Double[] values = valueMap.get(imt);
int i = 0;
for (String name : names) {
table.put(imt, name, values[i++]);
}
}
return table;
}
}