diff --git a/.gitignore b/.gitignore index d1038274ce481b044d9904724d0ebbe2b2509e71..d27f7d99d45160c9b66026752342ef4329cd57cf 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,6 @@ /dist /docs /tmp -curves/ +curves*/ Scratch*.java /src/META-INF diff --git a/etc/examples/1-hazard-curve/README.md b/etc/examples/1-hazard-curve/README.md index daf1961bd28419306e37d3becbc9b3404b0e811a..3647eee34edc11d1f9d6745df5a7ffff9dbbc4a4 100644 --- a/etc/examples/1-hazard-curve/README.md +++ b/etc/examples/1-hazard-curve/README.md @@ -15,6 +15,8 @@ The result of this calculation should be available as a single comma-delimited f Note that not all [calculation configuration](https://github.com/usgs/nshmp-haz/wiki/Configuration) parameters need be supplied; see the [configuration file](../../peer/models/Set1-Case1/config.json) for this example model. -Also note that all output is written to the current working directory. In the next example, we'll override the model supplied configuration with a custom file. +Also note that all output is written to the current working directory, but the ouput destination can be specified via the [`outputDir`](https://github.com/usgs/nshmp-haz/wiki/Configuration) parameter. + +In the next example, we'll override the model supplied configuration with a custom file. #### Next: [Example 2 – A custom configuration](../2-custom-config) diff --git a/etc/examples/2-custom-config/README.md b/etc/examples/2-custom-config/README.md index 47de1dc343393797b348482a2c8979723eb9e867..cff4d28ec672344d90e7133b6eaee6d1f0e45cb7 100644 --- a/etc/examples/2-custom-config/README.md +++ b/etc/examples/2-custom-config/README.md @@ -1,23 +1,20 @@ Example 2: A custom configuration ------------------------------- -__Working directory:__ `/path/to/nshmp-haz/etc/examples` +__Working directory:__ `/path/to/nshmp-haz/etc/examples/2-custom-config` -Navigate up one level to the `examples/` directory and execute the following: +Navigate to the directory above and execute the following: ```Shell -hazard ../peer/models/Set1-Case1 "San Francisco,-122.40,37.75" 2-custom-config/config.json +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 calculated for 3 `imts` ([intensity measure types](http://usgs.github.io/nshmp-haz/javadoc/index.html?org/opensha2/gmm/Imt.html), or spectral periods) and written to the directory containing the config file. +* 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`. -* And two different sites have been specified. See the [configuration specification](https://github.com/usgs/nshmp-haz/wiki/Configuration) for details on default values and supported options and formats. -**A note on output:** Because we supplied a specific configuration file, all program output is written to the directory where the config resides, thus keeping a record of calculation settings along with any results. - #### Next: [Example 3 – Using a custom sites file](../3-sites-file) diff --git a/etc/examples/3-sites-file/README.md b/etc/examples/3-sites-file/README.md index 0b614226cdbe21b7bc4852c513a50fe97038681f..4e3ee65d15b7c24fa1133f9a5bb7c320c6c51877 100644 --- a/etc/examples/3-sites-file/README.md +++ b/etc/examples/3-sites-file/README.md @@ -1,18 +1,18 @@ Example 3: Using a custom sites file ------------------------------------ -__Working directory:__ `/path/to/nshmp-haz/etc/examples` +__Working directory:__ `/path/to/nshmp-haz/etc/examples/3-sites-file` To compute hazard at more than one site, one may supply a comma-delimited (\*.csv) or [GeoJSON](http://geojson.org) (\*.geojson) formatted site data file instead: ```Shell -hazard ../peer/models/Set1-Case1 3-sites-file/sites.csv 3-sites-file/config.json +hazard ../../peer/models/Set1-Case1 sites.csv config.json ``` or ```Shell -hazard ../peer/models/Set1-Case1 3-sites-file/sites.geojson 3-sites-file/config.json +hazard ../../peer/models/Set1-Case1 sites.geojson config.json ``` The [site specification](https://github.com/usgs/nshmp-haz/wiki/Sites) wiki page provides details on the two file formats. Note that with either format, if the name of a site is supplied, it will be included in the first column of any output curve files. diff --git a/etc/examples/4-hazard-map/README.md b/etc/examples/4-hazard-map/README.md index 68c0742eee667f997170c5b1040b1c13d8742d2b..4a300ff98f1405753ac37761bb6582f667948102 100644 --- a/etc/examples/4-hazard-map/README.md +++ b/etc/examples/4-hazard-map/README.md @@ -1,12 +1,12 @@ Example 4: A simple hazard map ------------------------------ -__Working directory:__ `/path/to/nshmp-haz/etc/examples` +__Working directory:__ `/path/to/nshmp-haz/etc/examples/4-hazard-map` -A hazard map is just a lot of hazard curves. To compute curves at reqularly spaced intervals in latitude and longitude over a region, a [GeoJSON site file](https://github.com/usgs/nshmp-haz/wiki/Sites) may instead specify a polygon and a site spacing. +A hazard map is just a collection of values plucked from a lot of hazard curves. To compute curves at reqularly spaced intervals in latitude and longitude over a region, a [GeoJSON site file](https://github.com/usgs/nshmp-haz/wiki/Sites) may instead specify a polygon and a site spacing. ```Shell -hazard ../peer/models/Set1-Case1 4-hazard-map/map.geojson 4-hazard-map/config.json +hazard ../../peer/models/Set1-Case1 map.geojson config.json ``` #### Next: [Example 5 – A more complex model](../5-complex-model) diff --git a/etc/examples/5-complex-model/README.md b/etc/examples/5-complex-model/README.md index 4605796fd81b04223ebfcee9460816f37f2527a0..3acaf6517a5b1e189e5c9840b640a119d48b8704 100644 --- a/etc/examples/5-complex-model/README.md +++ b/etc/examples/5-complex-model/README.md @@ -1,28 +1,30 @@ Example 5: A more complex model ------------------------------- -__Working directory:__ `/path/to/nshmp-haz/etc/examples` +__Working directory:__ `/path/to/nshmp-haz/etc/examples/5-complex-model` Most PSHAs involve the use of more complex source models, the components of which might use different ground motion models. For this and ensuing examples, we'll use the 2008 USGS National Seismic Hazard Model (NSHM) for the western U.S. -First, clone the 2008 USGS NSHM. Assuming `examples/` is the current working directory, the following will create a copy of the model adjacent to nshmp-haz: +First, clone the 2008 USGS NSHM. Assuming you are in the current working directory (above), the following will create a copy of the model adjacent to nshmp-haz: ```Shell -git clone https://github.com/usgs/nshmp-model-cous-2008.git ../../../nshmp-model-cous-2008 +git clone https://github.com/usgs/nshmp-model-cous-2008.git ../../../../nshmp-model-cous-2008 ``` -The 2008 NSHM repository contains two source models: one for the western U.S. and a one for the central and eastern U.S. To compute hazard for a few sites in the Western U.S., execute: +The 2008 NSHM repository contains two source models: one for the western U.S. and a one for the central and eastern U.S. To compute hazard for a few sites in the Western U.S. at 1.0s and 2.0s spectral periods, execute: ```Shell -hazard ../../../nshmp-model-cous-2008/Western\ US 5-complex-model/sites.geojson 5-complex-model/config.json +hazard ../../../../nshmp-model-cous-2008/Western\ US sites.geojson config-sites.json ``` -Note that more complex models take longer to initialize, although this only occurs once per calculation, and make for longer, per-site calculations. However, `HazardCalc` will automatically use all cores available and therefore performs better on multi-core systems. To compute a small, low-resolution map for the central San Francisco bay area, execute: +Note that more complex models take longer to initialize, although this only occurs once per calculation, and make for longer, per-site calculations. However, `HazardCalc` will automatically use all cores available by default and therefore performs better on multi-core systems. + +To compute a small, low-resolution map for the central San Francisco bay area, execute: ```Shell -hazard ../../../nshmp-model-cous-2008/Western\ US 5-complex-model/map.geojson 5-complex-model/config.json +hazard ../../../../nshmp-model-cous-2008/Western\ US map.geojson config-map.json ``` -This computes 121 curves over a 2° by 2° area and will give you a sense of how long a larger map might take. These results overwrite those of the prior site-specific calculation. For this example we only compute curves at 1.0 and 2.0 second spectral periods. +This computes 121 curves over a 2° by 2° area and will give you a sense of how long a larger map might take. Note that in the above two examples we specified different output directories for each calculation. #### Next: [Example 6 – Enhanced output](../6-enhanced-output) diff --git a/etc/examples/5-complex-model/config-map.json b/etc/examples/5-complex-model/config-map.json new file mode 100644 index 0000000000000000000000000000000000000000..741d912969225b993424e110036f7d8205aba5b4 --- /dev/null +++ b/etc/examples/5-complex-model/config-map.json @@ -0,0 +1,4 @@ +{ + "imts": ["SA1P0", "SA2P0"], + "outputDir": "curves-map" +} diff --git a/etc/examples/5-complex-model/config-sites.json b/etc/examples/5-complex-model/config-sites.json new file mode 100644 index 0000000000000000000000000000000000000000..6093b260372efb3866702f4afd8d56117c0594a4 --- /dev/null +++ b/etc/examples/5-complex-model/config-sites.json @@ -0,0 +1,4 @@ +{ + "imts": ["SA1P0", "SA2P0"], + "outputDir": "curves-sites" +} diff --git a/etc/examples/5-complex-model/config.json b/etc/examples/5-complex-model/config.json deleted file mode 100644 index e972ec0907d6934182d9f6bf02e8df874a242bfc..0000000000000000000000000000000000000000 --- a/etc/examples/5-complex-model/config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "imts": ["SA1P0", "SA2P0"] -} diff --git a/etc/examples/6-enhanced-output/README.md b/etc/examples/6-enhanced-output/README.md index 84c92898bdcd6b255250429f45ab116fdfe32f70..778aeec93e52c900c17fb57ac9a8b7c01c84a602 100644 --- a/etc/examples/6-enhanced-output/README.md +++ b/etc/examples/6-enhanced-output/README.md @@ -1,12 +1,12 @@ Example 6: Enhanced output -------------------------- -__Working directory:__ `/path/to/nshmp-haz/etc/examples` +__Working directory:__ `/path/to/nshmp-haz/etc/examples/6-enhanced-output` While mean hazard is of broad interest, it can be useful to preserve individual components of a total curve, particularly with more complex models. Execute the following to write curves for each source type and ground motion model (GMM) used in the 2008 NSHM: ```Shell -hazard ../../../nshmp-model-cous-2008/Western\ US 6-enhanced-output/sites.geojson 6-enhanced-output/config.json +hazard ../../../../nshmp-model-cous-2008/Western\ US sites.geojson config.json ``` Note that the output curves directory now contains additional directories of curves by source type and GMM. diff --git a/src/org/opensha2/calc/CalcConfig.java b/src/org/opensha2/calc/CalcConfig.java index 62454098203d9ec0b33bc1b9db24318fec3fc0b4..a702f4b6ab572d52a77b66be83fb3a2a91f5ccfd 100644 --- a/src/org/opensha2/calc/CalcConfig.java +++ b/src/org/opensha2/calc/CalcConfig.java @@ -12,6 +12,7 @@ import static org.opensha2.util.TextUtils.wrap; import java.io.IOException; import java.io.Reader; +import java.lang.reflect.Type; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -33,6 +34,10 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; /** * Calculation configuration. @@ -261,7 +266,17 @@ public final class CalcConfig { } } - private static final Gson GSON = new GsonBuilder().create(); + private static final Gson GSON = new GsonBuilder() + .registerTypeAdapter(Path.class, new JsonDeserializer<Path>() { + @Override + public Path deserialize( + JsonElement json, + Type type, + JsonDeserializationContext context) throws JsonParseException { + return Paths.get(json.getAsString()); + } + }) + .create(); /** * Create a new calculation configuration builder from the resource at the @@ -281,6 +296,14 @@ public final class CalcConfig { return configBuilder; } + public static void main(String[] args) throws IOException { + CalcConfig cc = builder() + .withDefaults() + .extend(builder(Paths.get("etc/examples/5-complex-model/config-sites.json"))) + .build(); + System.out.println(cc); + } + /** * Create a new empty calculation configuration builder. */ @@ -346,7 +369,7 @@ public final class CalcConfig { this.systemPartition = 1000; this.gmmUncertainty = false; this.hazardFormat = HazardFormat.TOTAL; - this.outputDir = Paths.get("."); + this.outputDir = Paths.get("curves"); this.outputBatchSize = 20; this.deagg = new DeaggData(); return this; @@ -450,4 +473,16 @@ public final class CalcConfig { } } + // static final class PathDeserializer implements JsonDeserializer<Path> { + // + // @Override + // public Path deserialize( + // JsonElement json, + // Type type, + // JsonDeserializationContext context) { + // + // + // } + // } + } diff --git a/src/org/opensha2/calc/Results.java b/src/org/opensha2/calc/Results.java index bdcd4e05f247eda47a872cce8aebf7b5db308ab3..8ab56900fd49e3c3b20c0662e3de9da1c7ae4d1d 100644 --- a/src/org/opensha2/calc/Results.java +++ b/src/org/opensha2/calc/Results.java @@ -42,7 +42,6 @@ public class Results { private static final String CURVE_FILE_SUFFIX = ".csv"; private static final String RATE_FMT = "%.8e"; - private static final String CURVE_DIR = "curves"; /** * Hazard output format. @@ -258,7 +257,7 @@ public class Results { for (Entry<Imt, List<String>> totalEntry : totalLineMap.entrySet()) { Imt imt = totalEntry.getKey(); - Path imtDir = dir.resolve(CURVE_DIR).resolve(imt.name()); + Path imtDir = dir.resolve(imt.name()); Files.createDirectories(imtDir); Path totalFile = imtDir.resolve("total" + CURVE_FILE_SUFFIX); Files.write(totalFile, totalEntry.getValue(), US_ASCII, options); diff --git a/src/org/opensha2/programs/HazardCalc.java b/src/org/opensha2/programs/HazardCalc.java index 7fd55c44f6991f489a7620609dbf225cf9977a92..5fff8c1919e2ba31e867c9c4bf69c078a981d0a2 100644 --- a/src/org/opensha2/programs/HazardCalc.java +++ b/src/org/opensha2/programs/HazardCalc.java @@ -94,14 +94,12 @@ public class HazardCalc { HazardModel model = HazardModel.load(modelPath); CalcConfig config = model.config(); - Path out = Paths.get(StandardSystemProperty.USER_DIR.value()); if (argCount == 3) { Path userConfigPath = Paths.get(args[2]); config = CalcConfig.builder() .copy(model.config()) .extend(CalcConfig.builder(userConfigPath)) .build(); - out = userConfigPath.getParent(); } log.info(config.toString()); @@ -109,7 +107,7 @@ public class HazardCalc { log.info(""); log.info("Sites: " + sites); - calc(model, config, sites, out, log); + calc(model, config, sites, log); log.info(PROGRAM + ": finished"); return Optional.absent(); @@ -151,7 +149,6 @@ public class HazardCalc { HazardModel model, CalcConfig config, Iterable<Site> sites, - Path out, Logger log) throws IOException { ExecutorService execSvc = createExecutor(); @@ -173,7 +170,7 @@ public class HazardCalc { if (results.size() == config.outputBatchSize) { OpenOption[] opts = firstBatch ? WRITE_OPTIONS : APPEND_OPTIONS; firstBatch = false; - Results.writeResults(out, results, opts); + Results.writeResults(config.outputDir, results, opts); log.info(" batch: " + (count + 1) + " " + batchWatch + " total: " + totalWatch); results.clear(); @@ -184,7 +181,7 @@ public class HazardCalc { // write final batch if (!results.isEmpty()) { OpenOption[] opts = firstBatch ? WRITE_OPTIONS : APPEND_OPTIONS; - Results.writeResults(out, results, opts); + Results.writeResults(config.outputDir, results, opts); } log.info(PROGRAM + ": " + count + " complete " + totalWatch);