From 879e09b67289271c76c263c7d2e7b04b74d9d070 Mon Sep 17 00:00:00 2001 From: Peter Powers <pmpowers@usgs.gov> Date: Thu, 24 Mar 2016 15:08:49 -0600 Subject: [PATCH] hazard Results now handles annRate vs poissProb output from config --- etc/examples/2-custom-config/README.md | 1 + etc/examples/2-custom-config/config.json | 1 + src/org/opensha2/calc/Results.java | 111 +++++++---------------- 3 files changed, 33 insertions(+), 80 deletions(-) diff --git a/etc/examples/2-custom-config/README.md b/etc/examples/2-custom-config/README.md index cff4d28ec..10b3a22ac 100644 --- a/etc/examples/2-custom-config/README.md +++ b/etc/examples/2-custom-config/README.md @@ -12,6 +12,7 @@ hazard ../../peer/models/Set1-Case1 "San Francisco,-122.40,37.75" config.json In this example we've overridden the configuration supplied by the model. Specifically: * The upper end of each hazard curve has been truncated at 3 standard deviations. +* Hazard curves have been saved as poisson probability instead of annual rate. * Hazard curves have been calculated for 3 `imts` ([intensity measures](http://usgs.github.io/nshmp-haz/javadoc/index.html?org/opensha2/gmm/Imt.html), or spectral periods). * The `imls` (intensity measure levels or x-values) of the resultant curves have been explicitely defined for each `imt`. diff --git a/etc/examples/2-custom-config/config.json b/etc/examples/2-custom-config/config.json index 36b538061..81bf35969 100644 --- a/etc/examples/2-custom-config/config.json +++ b/etc/examples/2-custom-config/config.json @@ -3,6 +3,7 @@ "exceedanceModel": "TRUNCATION_UPPER_ONLY", "truncationLevel": 3.0, "imts": ["PGA", "SA0P2", "SA1P0"], + "valueType": "POISSON_PROBABILITY", "customImls": { "PGA": [0.0050, 0.0070, 0.0098, 0.0137, 0.0192, 0.0269, 0.0376, 0.0527, 0.0738, 0.103, 0.145, 0.203, 0.284, 0.397, 0.556, 0.778, 1.09, 1.52, 2.2, 3.3], "SA0P2": [0.0050, 0.0075, 0.0113, 0.0169, 0.0253, 0.0380, 0.0570, 0.0854, 0.128, 0.192, 0.288, 0.432, 0.649, 0.973, 1.46, 2.19, 3.28, 4.92, 7.38], diff --git a/src/org/opensha2/calc/Results.java b/src/org/opensha2/calc/Results.java index 13e0e9901..782f62aae 100644 --- a/src/org/opensha2/calc/Results.java +++ b/src/org/opensha2/calc/Results.java @@ -19,13 +19,14 @@ import org.opensha2.data.XySequence; import org.opensha2.eq.model.Source; import org.opensha2.eq.model.SourceSet; import org.opensha2.eq.model.SourceType; -import org.opensha2.geo.Location; import org.opensha2.gmm.Gmm; import org.opensha2.gmm.Imt; +import org.opensha2.mfd.Mfds; import org.opensha2.util.Parsing; import org.opensha2.util.Parsing.Delimiter; import com.google.common.base.Function; +import com.google.common.base.Functions; import com.google.common.collect.FluentIterable; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @@ -43,6 +44,28 @@ public class Results { private static final String CURVE_FILE_SUFFIX = ".csv"; private static final String RATE_FMT = "%.8e"; + /* + * Individual Hazard results only contain data relevant to the site of + * interest (e.g. for the NSHM WUS models, hazard in San Fancisco is + * influenced by slab sources whereas hazard in Los Angeles is not because + * it is too far away). For consistency when outputting batches of results, + * files are written for all source types and ground motion models supported + * by the HazardModel being used. This yields curve sets that are consistent + * across all locations in a batch, however, some of the curves may be + * empty. Depending on the extents of a map or list of sites, some curve + * sets may consist exclusively of zero-valued curves. + */ + + /* + * TODO There is no good reason for this class to be public. It would be + * better as a ResultsWriter, an instance of which would be obtained and + * configured on a per-calculation basis to receive batches of results. + * Although problems are unlikely, we're repeating a number of configuration + * steps below and relying on the same config file coming with the first + * result in each batch (below). We also wouldn't have to pass around + * OpenOptions which are mildly confusing. + */ + /** * Write a {@code batch} of {@code HazardResult}s to files in the specified * directory, one for each {@link Imt} in the {@code batch}. See @@ -59,96 +82,24 @@ public class Results { * @throws IOException if a problem is encountered * @see Files#write(Path, Iterable, java.nio.charset.Charset, OpenOption...) */ - @Deprecated - public static void writeResultsOLD(Path dir, List<Hazard> batch, OpenOption... options) - throws IOException { - - Function<Double, String> locFmtFunc = Parsing.formatDoubleFunction("%.5f"); - Function<Double, String> rateFmtFunc = Parsing.formatDoubleFunction(RATE_FMT); - - Hazard demo = batch.get(0); - boolean newFile = options.length == 0; - boolean namedSites = demo.site.name != Site.NO_NAME; - - Map<Imt, List<String>> lineMap = new EnumMap<>(Imt.class); - for (Imt imt : demo.totalCurves.keySet()) { - List<String> lineList = new ArrayList<>(); - // write header - if (newFile) { - List<String> headings = new ArrayList<>(); - if (namedSites) headings.add("name"); - headings.add("lon"); - headings.add("lat"); - Iterable<?> header = Iterables.concat( - headings, - demo.config.curve.modelCurves().get(imt).xValues()); - lineList.add(Parsing.join(header, Delimiter.COMMA)); - } - lineMap.put(imt, lineList); - } - - for (Hazard result : batch) { - Iterable<String> locData = Iterables.transform( - Lists.newArrayList( - result.site.location.lon(), - result.site.location.lat()), - locFmtFunc); - String name = result.site.name; - for (Entry<Imt, XySequence> entry : result.totalCurves.entrySet()) { - - // enable to output poisson probability - used when running - // PEER test cases - TODO should be configurable - // Function<Double, String> valueFunction = Functions.compose( - // rateFmtFunc, - // Mfds.rateToProbConverter()); - - // enable to output annual rate - Function<Double, String> valueFunction = rateFmtFunc; - - Iterable<String> lineData = Iterables.concat( - locData, - Iterables.transform( - entry.getValue().yValues(), - valueFunction)); - - String line = Parsing.join(lineData, Delimiter.COMMA); - if (namedSites) line = name + "," + line; - lineMap.get(entry.getKey()).add(line); - } - } - - for (Entry<Imt, List<String>> entry : lineMap.entrySet()) { - String filename = entry.getKey().name() + CURVE_FILE_SUFFIX; - Path file = dir.resolve(filename); - Files.write(file, entry.getValue(), US_ASCII, options); - } - } - - /* - * Individual Hazard results only contain data relevant to the site of - * interest (e.g. for the NSHM WUS models, hazard in San Fancisco is - * influenced by slab sources whereas hazard in Los Angeles is not because - * it is too far away). For consistency when outputting batches of results, - * files are written for all source types and ground motion models supported - * by the HazardModel being used. This yields curve sets that are consistent - * across all locations in a batch, however, some of the curves may be - * empty. Depending on the extents of a map or list of sites, some curve - * sets may consist exclusively of zero-valued curves. - */ - public static void writeResults( Path dir, List<Hazard> batch, OpenOption... options) throws IOException { - Function<Double, String> formatter = Parsing.formatDoubleFunction(RATE_FMT); - Hazard demo = batch.get(0); boolean newFile = options.length == 0; boolean namedSites = demo.site.name != Site.NO_NAME; boolean gmmCurves = demo.config.output.curveTypes.contains(CurveType.GMM); boolean sourceCurves = demo.config.output.curveTypes.contains(CurveType.SOURCE); + Function<Double, String> formatter = Parsing.formatDoubleFunction(RATE_FMT); + if (demo.config.curve.valueType == CurveValue.POISSON_PROBABILITY) { + formatter = Functions.compose( + formatter, + Mfds.annualRateToProbabilityConverter()); + } + Map<Imt, List<String>> totalLineMap = Maps.newEnumMap(Imt.class); Map<Imt, Map<SourceType, List<String>>> sourceLineMap = Maps.newEnumMap(Imt.class); Map<Imt, Map<Gmm, List<String>>> gmmLineMap = Maps.newEnumMap(Imt.class); -- GitLab