From dbe77a4c57bfa050c326916205e57f526a5c9502 Mon Sep 17 00:00:00 2001
From: Peter Powers <pmpowers@usgs.gov>
Date: Mon, 21 Mar 2016 16:45:08 -0600
Subject: [PATCH] updated examples to be consistent with config changes

---
 .gitignore                                    |  2 +-
 etc/examples/1-hazard-curve/README.md         |  4 +-
 etc/examples/2-custom-config/README.md        | 11 ++----
 etc/examples/3-sites-file/README.md           |  6 +--
 etc/examples/4-hazard-map/README.md           |  6 +--
 etc/examples/5-complex-model/README.md        | 18 +++++----
 etc/examples/5-complex-model/config-map.json  |  4 ++
 .../5-complex-model/config-sites.json         |  4 ++
 etc/examples/5-complex-model/config.json      |  3 --
 etc/examples/6-enhanced-output/README.md      |  4 +-
 src/org/opensha2/calc/CalcConfig.java         | 39 ++++++++++++++++++-
 src/org/opensha2/calc/Results.java            |  3 +-
 src/org/opensha2/programs/HazardCalc.java     |  9 ++---
 13 files changed, 75 insertions(+), 38 deletions(-)
 create mode 100644 etc/examples/5-complex-model/config-map.json
 create mode 100644 etc/examples/5-complex-model/config-sites.json
 delete mode 100644 etc/examples/5-complex-model/config.json

diff --git a/.gitignore b/.gitignore
index d1038274c..d27f7d99d 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 daf1961bd..3647eee34 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 47de1dc34..cff4d28ec 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 0b614226c..4e3ee65d1 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 68c0742ee..4a300ff98 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 4605796fd..3acaf6517 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 000000000..741d91296
--- /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 000000000..6093b2603
--- /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 e972ec090..000000000
--- 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 84c92898b..778aeec93 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 624540982..a702f4b6a 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 bdcd4e05f..8ab56900f 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 7fd55c44f..5fff8c191 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);
 
-- 
GitLab