diff --git a/.gitignore b/.gitignore
index bf6b8259ce8dbba01c88cdc4c9961c13b4ff702e..d2c7a6fd9cab187d5148a022d243f9e3c3773de1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,8 @@
 /dist
 /docs
 /tmp
+/results
 Scratch*.java
 /src/META-INF
 /etc/examples/model
+/etc/examples/results
diff --git a/LICENSE b/LICENSE
index aa3bdde9bee35734c352d6e00e80a89643d962de..6a7379e4a9ff9e2866feac16bc2bfe4ebaa615d1 100644
--- a/LICENSE
+++ b/LICENSE
@@ -3,7 +3,6 @@ contains materials that originally came from the United States Geological
 Survey, an agency of the United States Department of Interior. For more
 information, see the official USGS copyright policy at:
 
-
 http://www.usgs.gov/visual-id/credit_usgs.html#copyright
 
 This software and content is distributed on an "AS IS" BASIS, WITHOUT
diff --git a/build.xml b/build.xml
index f9f66bae490c28e5326d4c173b86a7f4cba0d181..db819e81b53dab992c749da5401e9c8c0c4f86d6 100644
--- a/build.xml
+++ b/build.xml
@@ -44,7 +44,9 @@
 		       source="1.7"
 		       target="1.7"
 		       encoding="UTF-8"
-		       debug="true" />
+		       debug="true"
+		       includeantruntime="false"
+		       createMissingPackageInfoClass="false" />
 
 		<!-- Copy any non-Java resources -->
 		<copy todir="${classes.dir}" includeEmptyDirs="false">
diff --git a/etc/README.md b/etc/README.md
index d0ce4223736ea55ba836bcfc1e81c8b5ec769100..edc17f87f0a2b9d9613a5be612c8b533ada26db9 100644
--- a/etc/README.md
+++ b/etc/README.md
@@ -1,4 +1,6 @@
 Examples
 
-Output files are created in the directory from which a program is run.
+Output files are always placed in a 'results' directory within the directory from which a program was run.
+
+Navigate to 
 
diff --git a/etc/examples/README.md b/etc/examples/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..f0fafc5b7dd6255b2c0ba594d1830c40b1e6cacc
--- /dev/null
+++ b/etc/examples/README.md
@@ -0,0 +1,32 @@
+#### Tutorial
+
+##### Hazard Curves
+The simplest way to run the HazardCurve program via the command-line is to supply it with a source model; all model initialization and calculation configuration data will be read from the model itself. Navigate to the examples directory and run:
+```
+java -cp ../../dist/nshmp-haz.jar org.opensha2.programs.HazardCurve model
+```
+By way of example, the [configuration file](https://github.com/usgs/nshmp-haz/blob/master/etc/examples/model/config.json) in the model above omits any site data and a default Los Angeles site is used. Remember that calculation [configuration parameters](https://github.com/usgs/nshmp-haz/wiki/Configuration) need not be supplied. The result of this calculation should be available as a single file containing one hazard curve for PGA in a newly created 'results' directory.
+
+One can override calculation configuration parameters by supplying an alternate configuration file. For example:
+```
+java -cp ../../dist/nshmp-haz.jar org.opensha2.programs.HazardCurve model config-sites.json
+```
+In this case:
+* the `truncationLevel` has been increased to `3.0`.
+* the list of `imts` (intensity measure types, or periods) for which curves will be calculated has been expanded to 3.
+* the `imls` (the intensity measure levels or x-values) of the resultant curves, have been explicitely defined.
+* two sites have been specified
+The 'results' directory should now include 3 files, one for each intensity measure type.
+
+One can also supply a comma-delimited site data file, which may be easier to work with in some applications.
+```
+java -cp ../../dist/nshmp-haz.jar org.opensha2.programs.HazardCurve model config-sites.json sites-wus.csv
+```
+See the site file itself for details on the expected file structure. Under all use cases, if the name of a site is supplied, it will be included in the first column of any result files.
+
+##### Hazard Maps
+Hazard maps are generated from numerous uniformely spaced hazard curves. To compute such a curve set, the same program is used, but sites are instead specified as a region.
+```
+java -cp ../../dist/nshmp-haz.jar org.opensha2.programs.HazardCurve model config-region.json
+```
+
diff --git a/etc/examples/config-region.json b/etc/examples/config-region.json
index 0176ee6771853cf07d3811bc7543d626e90a3df3..5a17e7155657b96446ff4cfe568936446d1414ff 100644
--- a/etc/examples/config-region.json
+++ b/etc/examples/config-region.json
@@ -1,52 +1,18 @@
 {
-  "exceedanceModel": "TRUNCATION_UPPER_ONLY",
-  "truncationLevel": 2.0,
-  "defaultImls": [
-    0.002,
-    0.004,
-    0.007,
-    0.011,
-    0.017,
-    0.025,
-    0.040,
-    0.060,
-    0.085,
-    0.13,
-    0.19,
-    0.29,
-    0.43,
-    0.65,
-    0.97,
-    1.5,
-    2.2,
-    3.3,
-    5.0,
-    7.4
-  ],
+  "truncationLevel": 3.0,
+  "imts": ["PGA", "SA0P2", "SA1P0"],
   "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],
     "SA1P0": [0.0025, 0.00375, 0.00563, 0.00844, 0.0127, 0.0190, 0.0285, 0.0427, 0.0641, 0.0961, 0.144, 0.216, 0.324, 0.487, 0.730, 1.09, 1.64, 2.46, 3.69, 5.54]
   },
-  "deagg": {
-    "rMin": 0.0,
-    "rMax": 100.0,
-    "Δr": 10.0,
-    "mMin": 5.0,
-    "mMax": 7.0,
-    "Δm": 0.1,
-    "εMin": -3.0,
-    "εMax": 3.0,
-    "Δε": 0.5
-  },
   "sites": {  
     "region": {
-      "name": "Test Map",
+      "name": "Downtown Los Angeles",
       "spacing": 0.1,
       "border": [  
-        [-111, 40],
-        [-110, 41],
-        [-109, 40]
+        [-118.5, 33.8],
+        [-118.0, 34.3]
       ],
       "vs30": 459,
       "vsInf": true,
diff --git a/etc/examples/config-sites.json b/etc/examples/config-sites.json
index 0b18220ef8b67b321e33d11db35b7f7bae93f7de..6a7c5178d080602f61006b38c83818ddcdc6f973 100644
--- a/etc/examples/config-sites.json
+++ b/etc/examples/config-sites.json
@@ -1,54 +1,21 @@
 {
-  "exceedanceModel": "TRUNCATION_UPPER_ONLY",
-  "truncationLevel": 2.0,
-  "defaultImls": [
-    0.002,
-    0.004,
-    0.007,
-    0.011,
-    0.017,
-    0.025,
-    0.040,
-    0.060,
-    0.085,
-    0.13,
-    0.19,
-    0.29,
-    0.43,
-    0.65,
-    0.97,
-    1.5,
-    2.2,
-    3.3,
-    5.0,
-    7.4
-  ],
+  "truncationLevel": 3.0,
+  "imts": ["PGA", "SA0P2", "SA1P0"],
   "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],
     "SA1P0": [0.0025, 0.00375, 0.00563, 0.00844, 0.0127, 0.0190, 0.0285, 0.0427, 0.0641, 0.0961, 0.144, 0.216, 0.324, 0.487, 0.730, 1.09, 1.64, 2.46, 3.69, 5.54]
   },
-  "deagg": {
-    "rMin": 0.0,
-    "rMax": 100.0,
-    "Δr": 10.0,
-    "mMin": 5.0,
-    "mMax": 7.0,
-    "Δm": 0.1,
-    "εMin": -3.0,
-    "εMax": 3.0,
-    "Δε": 0.5
-  },
   "sites": [
     {
-    "name": "Test Site 1",
-    "location": [-111.9, 40.75],
+    "name": "Los Angeles",
+    "location": [-118.25, 34.05],
     "vs30": 760,
     "vsInf": true
     },
     {
-    "name": "Test Site 2",
-    "location": [-111.9, 40.75],
+    "name": "San Francisco",
+    "location": [-122.40, 37.75],
     "vs30": 760,
     "vsInf": true
     }
diff --git a/src/org/opensha2/calc/CalcConfig.java b/src/org/opensha2/calc/CalcConfig.java
index 9b5b60c4832258dcf2b1db67dd9e886677d62a5f..ff153fcc3f4b90b03f20b443ad1942605018b4b9 100644
--- a/src/org/opensha2/calc/CalcConfig.java
+++ b/src/org/opensha2/calc/CalcConfig.java
@@ -4,10 +4,7 @@ import static com.google.common.base.CaseFormat.LOWER_CAMEL;
 import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.base.Strings.padStart;
 import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.opensha2.util.TextUtils.ALIGN_COL;
-import static org.opensha2.util.TextUtils.NEWLINE;
 import static org.opensha2.util.TextUtils.format;
 
 import java.io.IOException;
@@ -15,6 +12,7 @@ import java.io.Reader;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Arrays;
+import java.util.EnumSet;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -37,19 +35,19 @@ import com.google.gson.GsonBuilder;
  */
 public final class CalcConfig {
 
-	// TODO revisit privatization
-	
+	// TODO revisit privatization, comments, and immutability
+
 	static final String FILE_NAME = "config.json";
 
 	final Path resource;
-	
+
 	final ExceedanceModel exceedanceModel;
 	final double truncationLevel;
-	final Set<Imt> imts;
-	final double[] defaultImls;
-	final Map<Imt, double[]> customImls;
-	final Deagg deagg;
-	final SiteSet sites;
+	private final Set<Imt> imts;
+	private final double[] defaultImls;
+	private final Map<Imt, double[]> customImls;
+	private final DeaggData deagg;
+	private final SiteSet sites;
 
 	private static final Gson GSON = new GsonBuilder()
 		.registerTypeAdapter(Site.class, new Site.Deserializer())
@@ -63,7 +61,7 @@ public final class CalcConfig {
 			Set<Imt> imts,
 			double[] defaultImls,
 			Map<Imt, double[]> customImls,
-			Deagg deagg,
+			DeaggData deagg,
 			SiteSet sites) {
 
 		this.resource = resource;
@@ -172,7 +170,15 @@ public final class CalcConfig {
 	}
 
 	/**
-	 * Returns an unmodifiable iterator over the {@code Site}s specified by this
+	 * Return the {@code Set} of {@code Imt}s for which calculations will be
+	 * performed.
+	 */
+	public Set<Imt> imts() {
+		return imts;
+	}
+	
+	/**
+	 * Return an unmodifiable iterator over the {@code Site}s specified by this
 	 * configuration.
 	 * 
 	 * @see Iterables#unmodifiableIterable(Iterable)
@@ -180,8 +186,15 @@ public final class CalcConfig {
 	public Iterable<Site> sites() {
 		return Iterables.unmodifiableIterable(sites);
 	}
+	
+	/**
+	 * Return the deaggregation data model spcified by this configuration.
+	 */
+	public DeaggData deagg() {
+		return deagg;
+	}
 
-	public static final class Deagg {
+	public static final class DeaggData {
 
 		public final double rMin;
 		public final double rMax;
@@ -195,7 +208,7 @@ public final class CalcConfig {
 		public final double εMax;
 		public final double Δε;
 
-		Deagg() {
+		DeaggData() {
 			rMin = 0.0;
 			rMax = 100.0;
 			Δr = 10.0;
@@ -247,7 +260,7 @@ public final class CalcConfig {
 		Set<Imt> imts;
 		double[] defaultImls;
 		Map<Imt, double[]> customImls;
-		Deagg deagg;
+		DeaggData deagg;
 		SiteSet sites;
 
 		public Builder copy(CalcConfig config) {
@@ -266,13 +279,13 @@ public final class CalcConfig {
 		public Builder withDefaults() {
 			this.exceedanceModel = ExceedanceModel.TRUNCATION_UPPER_ONLY;
 			this.truncationLevel = 3.0;
-			this.imts = Sets.immutableEnumSet(Imt.PGA, Imt.SA0P2, Imt.SA1P0);
+			this.imts = EnumSet.of(Imt.PGA, Imt.SA0P2, Imt.SA1P0);
 			// Slightly modified version of NSHM 5Hz curve, size = 20
 			this.defaultImls = new double[] { 0.0025, 0.0045, 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 };
 			this.customImls = Maps.newHashMap();
-			this.deagg = new Deagg();
+			this.deagg = new DeaggData();
 			this.sites = new SiteSet(Lists.newArrayList(Site.builder().build()));
 			return this;
 		}
@@ -311,8 +324,9 @@ public final class CalcConfig {
 
 		public CalcConfig build() {
 			validateState(ID);
+			Set<Imt> finalImts = Sets.immutableEnumSet(imts);
 			return new CalcConfig(
-				resource, exceedanceModel, truncationLevel, imts,
+				resource, exceedanceModel, truncationLevel, finalImts,
 				defaultImls, customImls, deagg, sites);
 		}
 	}
diff --git a/src/org/opensha2/calc/Calcs.java b/src/org/opensha2/calc/Calcs.java
index e29467365db26f4dae57871cd7e83f23f891431b..8ac1558ad908ce5398f60243b16808fc9c13b08a 100644
--- a/src/org/opensha2/calc/Calcs.java
+++ b/src/org/opensha2/calc/Calcs.java
@@ -63,7 +63,7 @@ public class Calcs {
 				if (inputs.isEmpty()) continue; // all sources out of range
 
 				AsyncList<ClusterGroundMotions> groundMotions = toClusterGroundMotions(inputs,
-					clusterSourceSet, config.imts, executor);
+					clusterSourceSet, config.imts(), executor);
 
 				AsyncList<ClusterCurves> clusterCurves = toClusterCurves(groundMotions,
 					modelCurves, config.exceedanceModel, config.truncationLevel, executor);
@@ -79,7 +79,7 @@ public class Calcs {
 				if (inputs.isEmpty()) continue; // all sources out of range
 
 				AsyncList<HazardGroundMotions> groundMotions = toGroundMotions(inputs, sourceSet,
-					config.imts, executor);
+					config.imts(), executor);
 
 				AsyncList<HazardCurves> hazardCurves = toHazardCurves(groundMotions, modelCurves,
 					config.exceedanceModel, config.truncationLevel, executor);
diff --git a/src/org/opensha2/calc/Deagg.java b/src/org/opensha2/calc/Deagg.java
index 979e5b255afa7515ed42351c311bfda69abe2989..d12076cb31cacc53b3850847c421b435d40f24e1 100644
--- a/src/org/opensha2/calc/Deagg.java
+++ b/src/org/opensha2/calc/Deagg.java
@@ -10,6 +10,7 @@ import java.util.Properties;
 import java.util.Queue;
 import java.util.Set;
 
+import org.opensha2.calc.CalcConfig.DeaggData;
 import org.opensha2.data.DataUtils;
 import org.opensha2.eq.Magnitudes;
 import org.opensha2.eq.model.GmmSet;
@@ -316,8 +317,8 @@ class Deagg {
 		 * @param c {@code CalcConfig} to process
 		 */
 		public static Model fromConfig(CalcConfig c) {
-			return create(c.deagg.mMin, c.deagg.mMax, c.deagg.Δm, c.deagg.rMin, c.deagg.rMax,
-				c.deagg.Δr, c.deagg.εMin, c.deagg.εMax, c.deagg.Δε);
+			DeaggData d = c.deagg();
+			return create(d.mMin, d.mMax, d.Δm, d.rMin, d.rMax, d.Δr, d.εMin, d.εMax, d.Δε);
 		}
 
 		private static class Builder {
diff --git a/src/org/opensha2/calc/Results.java b/src/org/opensha2/calc/Results.java
index 112c2f74da02028a108844be9f59fb700a00ee2b..b91bc34185bb70ed5605a6a98f0d5bf275adda4a 100644
--- a/src/org/opensha2/calc/Results.java
+++ b/src/org/opensha2/calc/Results.java
@@ -1,7 +1,6 @@
 package org.opensha2.calc;
 
 import static java.nio.charset.StandardCharsets.US_ASCII;
-import static java.nio.file.StandardOpenOption.APPEND;
 import static org.opensha2.data.ArrayXY_Sequence.copyOf;
 
 import java.io.IOException;
@@ -9,9 +8,7 @@ import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.OpenOption;
 import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.EnumMap;
 import java.util.List;
 import java.util.Map;
@@ -21,16 +18,18 @@ import java.util.Set;
 import org.opensha2.data.ArrayXY_Sequence;
 import org.opensha2.data.XY_Sequence;
 import org.opensha2.eq.model.SourceType;
+import org.opensha2.geo.Location;
 import org.opensha2.gmm.Imt;
 import org.opensha2.util.Parsing;
 import org.opensha2.util.Parsing.Delimiter;
 
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
 
 /**
  * Factory class for reducing and exporting various result types.
@@ -40,7 +39,8 @@ import com.google.common.collect.Sets;
 public class Results {
 
 	private static final String CURVE_FILE_SUFFIX = "-curves.csv";
-
+	private static final String RATE_FMT = "%8e";
+	
 	/**
 	 * Write a {@code batch} of {@code HazardResult}s to files in the specified
 	 * directory, one for each {@link Imt} in the {@code batch}. See
@@ -48,7 +48,8 @@ public class Results {
 	 * for details on {@code options}. If no {@code options} are specified, the
 	 * default behavior is to (over)write a new file. In this case a header row
 	 * will be written as well. Files are encoded as
-	 * {@link StandardCharsets#US_ASCII}.
+	 * {@link StandardCharsets#US_ASCII}, lat and lon values are formatted to 2
+	 * decimal places, and curve values are formatted to 8 significant figures.
 	 * 
 	 * @param dir to write to
 	 * @param batch of results to write
@@ -58,7 +59,10 @@ public class Results {
 	 */
 	public static void writeResults(Path dir, List<HazardResult> batch, OpenOption... options)
 			throws IOException {
-		
+
+		Function<Double, String> locFmtFunc = Parsing.formatDoubleFunction(Location.FORMAT);
+		Function<Double, String> rateFmtFunc = Parsing.formatDoubleFunction(RATE_FMT);
+
 		HazardResult demo = batch.get(0);
 		boolean newFile = options.length == 0;
 		boolean namedSites = demo.site.name != Site.NO_NAME;
@@ -81,14 +85,18 @@ public class Results {
 		}
 
 		for (HazardResult result : batch) {
-			List<Double> locData = Lists.newArrayList(
-				result.site.location.lon(),
-				result.site.location.lat());
+			Iterable<String> locData = Iterables.transform(
+				Lists.newArrayList(
+					result.site.location.lon(),
+					result.site.location.lat()),
+				locFmtFunc);
 			String name = result.site.name;
 			for (Entry<Imt, ? extends XY_Sequence> entry : result.totalCurves.entrySet()) {
-				Iterable<Double> lineData = Iterables.concat(
+				Iterable<String> lineData = Iterables.concat(
 					locData,
-					entry.getValue().yValues());
+					Iterables.transform(
+						entry.getValue().yValues(),
+						rateFmtFunc));
 				String line = Parsing.join(lineData, Delimiter.COMMA);
 				if (namedSites) line = name + "," + line;
 				lineMap.get(entry.getKey()).add(line);
@@ -129,5 +137,5 @@ public class Results {
 
 		return imtMapBuilder.build();
 	}
-	
+
 }
diff --git a/src/org/opensha2/calc/Site.java b/src/org/opensha2/calc/Site.java
index 5785334fd5678228f780c00edb3c140eb2e5996b..226448e8393d464fab96b87ed97e27b093b29e37 100644
--- a/src/org/opensha2/calc/Site.java
+++ b/src/org/opensha2/calc/Site.java
@@ -82,7 +82,7 @@ public class Site implements Named {
 	/**
 	 * The location.
 	 * 
-	 * <p>Default: lat=40.75, lon=-111.90 (Salt Lake City, UT)</p>
+	 * <p>Default: lat=34.05, lon=-118.25 (Los Angeles, CA)</p>
 	 */
 	public final Location location;
 
@@ -163,7 +163,7 @@ public class Site implements Named {
 	public static class Builder {
 
 		private String name = NO_NAME;
-		private Location location = NehrpTestCity.SALT_LAKE_CITY.location();
+		private Location location = NehrpTestCity.LOS_ANGELES.location();
 		private double vs30 = DEFAULT_VS_30;
 		private boolean vsInferred = true;
 		private double z1p0 = Double.NaN;
diff --git a/src/org/opensha2/calc/SiteSet.java b/src/org/opensha2/calc/SiteSet.java
index 625be6d8b4bfc52bbab58e7d4918c52e8e77c1c6..3c9853361c5c670e60625966e5ce42c84159a3c2 100644
--- a/src/org/opensha2/calc/SiteSet.java
+++ b/src/org/opensha2/calc/SiteSet.java
@@ -15,6 +15,7 @@ import static org.opensha2.util.TextUtils.ALIGN_COL;
 
 import java.io.IOException;
 import java.lang.reflect.Type;
+import java.math.BigDecimal;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -55,7 +56,7 @@ final class SiteSet implements Iterable<Site> {
 	final private GriddedRegion region;
 	final private Builder builder;
 	final private List<Site> sites;
-
+	
 	SiteSet(List<Site> sites) {
 		this.sites = checkNotNull(sites);
 		this.region = null;
@@ -72,6 +73,12 @@ final class SiteSet implements Iterable<Site> {
 		return (region == null) ? sites.size() : region.size();
 	}
 
+	private static int computeLocationPrecision(GriddedRegion region) {
+		return Math.max(
+			new BigDecimal(region.latSpacing()).scale(),
+			new BigDecimal(region.lonSpacing()).scale());
+	}
+
 	@Override public Iterator<Site> iterator() {
 		return (region == null) ? sites.iterator() : new RegionIterator();
 	}
diff --git a/src/org/opensha2/programs/HazardCurve.java b/src/org/opensha2/programs/HazardCurve.java
index 3fa22c7ff0f845804c0a6830f4071cfb34022a7a..ebc1a95aa6857bb26549a34ad2d8c609cf449dc4 100644
--- a/src/org/opensha2/programs/HazardCurve.java
+++ b/src/org/opensha2/programs/HazardCurve.java
@@ -7,6 +7,7 @@ import static org.opensha2.util.TextUtils.NEWLINE;
 import static org.opensha2.util.TextUtils.format;
 
 import java.io.IOException;
+import java.nio.file.Files;
 import java.nio.file.OpenOption;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -71,6 +72,9 @@ public class HazardCurve {
 	 * @param args
 	 * @see <a href="https://github.com/usgs/nshmp-haz/wiki/Building-&-Running">
 	 *      nshmp-haz wiki</a>
+	 * @see <a
+	 *      href="https://github.com/usgs/nshmp-haz/tree/master/etc/examples">
+	 *      example calculations</a>
 	 */
 	public static void main(String[] args) {
 		String status = run(args);
@@ -157,8 +161,9 @@ public class HazardCurve {
 
 		List<HazardResult> results = new ArrayList<>();
 		boolean firstBatch = true;
-		Path dir = Paths.get(StandardSystemProperty.USER_DIR.value());
-
+		Path dir = Paths.get(StandardSystemProperty.USER_DIR.value(), "results");
+		Files.createDirectories(dir);
+		
 		for (Site site : sites) {
 			HazardResult result = calc(model, config, site, executor);
 			results.add(result);
@@ -167,7 +172,8 @@ public class HazardCurve {
 				OpenOption[] opts = firstBatch ? WRITE_OPTIONS : APPEND_OPTIONS;
 				firstBatch = false;
 				Results.writeResults(dir, results, opts);
-				log.info("   " + count + "  batch: " + batchWatch + "  total: " + totalWatch);
+				log.info("       batch: " + (count + 1) + "  " + batchWatch + "  total: " +
+					totalWatch);
 				results.clear();
 				batchWatch.reset();
 			}
diff --git a/src/org/opensha2/util/Logging.java b/src/org/opensha2/util/Logging.java
index 0c72d849ea04c2ceb41c114c5959e4635b7a9bb0..1b09aede6d91f3599d4415f4d8b67238222d268f 100644
--- a/src/org/opensha2/util/Logging.java
+++ b/src/org/opensha2/util/Logging.java
@@ -28,15 +28,19 @@ public class Logging {
 	 */
 	public static void init() {
 		try {
-//			InputStream is = Logging.class.getResourceAsStream("/logging.properties");
-//			if (is == null) is = new FileInputStream("lib/logging.properties");
-			InputStream is = new FileInputStream("lib/logging.properties");
+			/*
+			 * When running from a jar, logging.properties will have been moved
+			 * to the root of the source directory, otherwise it can be found in
+			 * lib.
+			 */
+			InputStream is = Logging.class.getResourceAsStream("/logging.properties");
+			if (is == null) is = new FileInputStream("lib/logging.properties");
 			LogManager.getLogManager().readConfiguration(is);
 		} catch (IOException ioe) {
 			ioe.printStackTrace();
 		}
 	}
-	
+
 	/**
 	 * Log a resource loading error and exit.
 	 * 
@@ -51,15 +55,14 @@ public class Logging {
 		log.log(SEVERE, sb.toString(), e);
 		System.exit(1);
 	}
-	
+
 	/**
 	 * Custom console formatter.
 	 * @author Peter Powers
 	 */
 	public final static class ConsoleFormatter extends Formatter {
 
-		@Override
-		public String format(LogRecord record) {
+		@Override public String format(LogRecord record) {
 			// @formatter:off
 			StringBuilder b = new StringBuilder();
 			Level l = record.getLevel();
@@ -91,7 +94,7 @@ public class Logging {
 			return b.toString();
 			// @formatter:on
 		}
-		
+
 	}
 
 }