diff --git a/src/test/java/gov/usgs/earthquake/nshmp/model/NshmTestsHawaii.java b/src/test/java/gov/usgs/earthquake/nshmp/model/NshmTestsHawaii.java new file mode 100644 index 0000000000000000000000000000000000000000..f98dd312b816b47a562e5a3ad17b5b575ff8cf39 --- /dev/null +++ b/src/test/java/gov/usgs/earthquake/nshmp/model/NshmTestsHawaii.java @@ -0,0 +1,243 @@ +package gov.usgs.earthquake.nshmp.model; + +import static gov.usgs.earthquake.nshmp.gmm.Imt.PGA; +import static gov.usgs.earthquake.nshmp.gmm.Imt.SA0P2; +import static gov.usgs.earthquake.nshmp.gmm.Imt.SA1P0; +import static gov.usgs.earthquake.nshmp.gmm.Imt.SA5P0; +import static gov.usgs.earthquake.nshmp.site.NshmpSite.HILO_HI; +import static gov.usgs.earthquake.nshmp.site.NshmpSite.HONOLULU_HI; +import static gov.usgs.earthquake.nshmp.site.NshmpSite.KAILUA_KONA_HI; +import static java.lang.Math.abs; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.BufferedReader; +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import gov.usgs.earthquake.nshmp.NamedLocation; +import gov.usgs.earthquake.nshmp.calc.CalcConfig; +import gov.usgs.earthquake.nshmp.calc.Hazard; +import gov.usgs.earthquake.nshmp.calc.HazardCalcs; +import gov.usgs.earthquake.nshmp.calc.Site; +import gov.usgs.earthquake.nshmp.data.XySequence; +import gov.usgs.earthquake.nshmp.geo.Location; +import gov.usgs.earthquake.nshmp.gmm.Imt; + +/** + * Class for end-to-end tests of hazard calculations. These tests require + * significant system resources to load source models, and source models are + * required to be in adjacent repositories. These tests should be run + * frequently, but not necessarily as part of continuous integration. Needs + * parameterization and additional regions. + * + * @author U.S. Geological Survey + */ +class NshmTestsHawaii { + + private static final double TOLERANCE = 1e-12; + + private static final List<NamedLocation> CONUS_SITES = List.of( + HILO_HI, + HONOLULU_HI, + KAILUA_KONA_HI); + + private static final Set<Imt> IMTS = EnumSet.of(PGA, SA0P2, SA1P0, SA5P0); + + private static final String MODEL_NAME = "nshm-hawaii"; + private static final int MODEL_YEAR = 2021; + private static final Path MODEL_PATH = Paths.get("../" + MODEL_NAME); + private static final Path DATA_PATH = Paths.get("src/test/resources/e2e"); + + private static final Gson GSON = new GsonBuilder() + .setPrettyPrinting() + .create(); + + private static ExecutorService exec; + private static HazardModel model; + static Map<Location, Map<String, XySequence>> expecteds; + + @BeforeAll + static void setUpBeforeClass() { + model = ModelLoader.load(MODEL_PATH); + int cores = Runtime.getRuntime().availableProcessors(); + exec = Executors.newFixedThreadPool(cores); + } + + @AfterAll + static void tearDownAfterClass() { + exec.shutdown(); + } + + @ParameterizedTest + @MethodSource("siteStream") + final void testLocation(NamedLocation site) { + compareCurves(site); + } + + private static Stream<NamedLocation> siteStream() { + return CONUS_SITES.stream(); + } + + private static void compareCurves(NamedLocation location) { + + // String actual = generateActual(model, location); + Map<String, XySequence> actual = generateActual(location); + // String expected = readExpected(modelName, year, location); + Map<String, XySequence> expected = readExpected(location); + // assertEquals(expected, actual); + + assertEquals(expected.keySet(), actual.keySet()); + for (String key : actual.keySet()) { + assertCurveEquals(expected.get(key), actual.get(key), TOLERANCE); + } + } + + private static void assertCurveEquals(XySequence expected, XySequence actual, double tol) { + + // IMLs close but not exact due to exp() transform + assertArrayEquals( + expected.xValues().toArray(), + actual.xValues().toArray()); + + double[] expectedYs = expected.yValues().toArray(); + double[] actualYs = actual.yValues().toArray(); + + // absolute y-value difference relative to tolerance + assertArrayEquals(expectedYs, actualYs, tol); + + // relative y-value difference relative to tolerance + for (int i = 0; i < expectedYs.length; i++) { + String message = String.format( + "arrays differ at [%s] expected:<[%s]> but was:<[%s]>", + i, expectedYs[i], actualYs[i]); + assertTrue(compare(expectedYs[i], actualYs[i], tol), message); + } + } + + private static boolean compare(double expected, double actual, double tolerance) { + return abs(actual - expected) / expected < tolerance || + Double.valueOf(expected).equals(Double.valueOf(actual)); + } + + private static Map<String, XySequence> generateActual(NamedLocation location) { + + Site site = Site.builder().location(location.location()).build(); + + CalcConfig config = CalcConfig.copyOf(model.config()) + .imts(IMTS) + .build(); + + Hazard hazard = HazardCalcs.hazard( + model, + config, + site, + exec); + + Map<String, XySequence> xyMap = hazard.curves().entrySet().stream() + .collect(Collectors.toMap( + e -> e.getKey().toString(), + Entry::getValue)); + + return xyMap; + } + + private static String resultFilename( + String modelName, + int year, + NamedLocation loc) { + + return modelName + "-" + year + "-" + loc.name() + ".json"; + } + + private static Map<String, XySequence> readExpected(NamedLocation loc) { + + String filename = resultFilename(MODEL_NAME, MODEL_YEAR, loc); + Path resultPath = DATA_PATH.resolve(filename); + + JsonObject obj = null; + try (BufferedReader br = Files.newBufferedReader(resultPath)) { + obj = JsonParser.parseReader(br).getAsJsonObject(); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + + Type curveDataType = new TypeToken<Map<String, Curve>>() {}.getType(); + Map<String, Curve> curveMap = GSON.fromJson(obj, curveDataType); + Map<String, XySequence> xyMap = curveMap.entrySet().stream() + .collect(Collectors.toMap( + Entry::getKey, + e -> XySequence.create(e.getValue().xs, e.getValue().ys))); + return xyMap; + } + + private static class Curve { + double[] xs; + double[] ys; + + @SuppressWarnings("unused") + Curve(double[] xs, double[] ys) { + this.xs = xs; + this.ys = ys; + } + } + + private static void writeExpecteds( + String modelName, + int year, + List<NamedLocation> locations) throws IOException { + + for (NamedLocation location : locations) { + // String json = generateActual(model, location); + Map<String, XySequence> xyMap = generateActual(location); + String json = GSON.toJson(xyMap); + writeExpected(modelName, year, location, json); + } + } + + private static void writeExpected( + String modelName, + int year, + NamedLocation loc, + String json) throws IOException { + + String filename = resultFilename(modelName, year, loc); + Path resultPath = DATA_PATH.resolve(filename); + Files.write(resultPath, json.getBytes()); + } + + public static void main(String[] args) throws IOException { + + /* Initialize and shut down executor to generate results. */ + setUpBeforeClass(); + + writeExpecteds("nshm-conus", 2018, CONUS_SITES); + + tearDownAfterClass(); + } + +} diff --git a/src/test/resources/e2e/nshm-conus-2018-HILO_HI.json b/src/test/resources/e2e/nshm-conus-2018-HILO_HI.json new file mode 100644 index 0000000000000000000000000000000000000000..8f0b4a16baad5790a668e4430dd7fe9ddf0ab15b --- /dev/null +++ b/src/test/resources/e2e/nshm-conus-2018-HILO_HI.json @@ -0,0 +1,186 @@ +{ + "1.00 Second Spectral Acceleration": { + "xs": [ + -5.991464547107982, + -5.585999438999818, + -5.181423615076537, + -4.775958506968373, + -4.374058465024705, + -3.9633162998156966, + -3.5613661338149765, + -3.1535563587475584, + -2.7488721956224653, + -2.3434070875143007, + -1.9379419794061366, + -1.5324768712979722, + -1.1270117631898076, + -0.7215466550816433, + -0.31608154697347896, + 0.08617769624105241, + 0.494696241836107, + 0.9001613499442714, + 1.3056264580524357, + 1.7119945007591924 + ], + "ys": [ + 1.139427959929886, + 0.9096459257402049, + 0.6810439562313703, + 0.48213438998284375, + 0.3270662494936988, + 0.2122733790095776, + 0.13579352589768767, + 0.08466990088453301, + 0.0514796672410259, + 0.0295922152331615, + 0.015605186053687877, + 0.007369438722986228, + 0.003079134500128523, + 0.001133816052813239, + 3.683841726832002E-4, + 1.077152977087167E-4, + 2.7590429340726252E-5, + 6.106383784135073E-6, + 9.141545957726994E-7, + 4.7166583187373387E-8 + ] + }, + "5.00 Second Spectral Acceleration": { + "xs": [ + -6.908755779315721, + -6.502290170873972, + -6.0968250627658085, + -5.692842534617867, + -5.286388795682763, + -4.882242079327857, + -4.474141923581687, + -4.0686768154735224, + -3.6651629274966204, + -3.259697819388456, + -2.8542327112802917, + -2.448767603172127, + -2.0402208285265546, + -1.6398971199188088, + -1.2310014767138553, + -0.8278220838865469, + -0.42159449003804794, + -0.016129381929883644, + 0.3920420877760237, + 0.7929925155296614 + ], + "ys": [ + 0.24225805041057027, + 0.1626494298061276, + 0.11286823232748021, + 0.08019936527365806, + 0.057001082377164766, + 0.03977231046422921, + 0.026270923994779784, + 0.0159300182060438, + 0.008586807484419113, + 0.0040091692633346795, + 0.0016237229130359049, + 5.831580842583807E-4, + 1.9354910833413707E-4, + 6.446411351755592E-5, + 2.0541404464536928E-5, + 5.89324452995356E-6, + 1.3026715401568408E-6, + 2.061368668443604E-7, + 2.2313612928494355E-8, + 3.427414499140028E-10 + ] + }, + "Peak Ground Acceleration": { + "xs": [ + -6.061887011404528, + -5.654992310486769, + -5.251433780649187, + -4.845968672541022, + -4.439655747510518, + -4.034190639402354, + -3.6306105459899607, + -3.223888366691745, + -2.8184232585835804, + -2.4123999590012524, + -2.0099154790312257, + -1.5994875815809322, + -1.1973282616072674, + -0.789658080940789, + -0.3856624808119846, + 0.01980262729617973, + 0.4252677354043441, + 0.8329091229351039, + 1.235471471385307, + 1.6428726885203377 + ], + "ys": [ + 1.367163786511996, + 1.2691006652906478, + 1.1637737587135957, + 1.0330746473392465, + 0.868541087272583, + 0.6793538859833672, + 0.4895776766820634, + 0.32305214036758084, + 0.19728774899189122, + 0.11230291486323442, + 0.059998792401783616, + 0.02903842762547559, + 0.012752442114810742, + 0.004825259624029285, + 0.0015856433122290357, + 4.467361996202859E-4, + 1.0815891326044897E-4, + 2.150197599508401E-5, + 3.0877820264321665E-6, + 2.0121735347546392E-7 + ] + }, + "0.20 Second Spectral Acceleration": { + "xs": [ + -5.704782974989785, + -5.30031936921871, + -4.8941864814530085, + -4.491841500681089, + -4.080441657053109, + -3.6769508832486624, + -3.2728041668937564, + -2.866459937849852, + -2.4615808244845034, + -2.05572501506252, + -1.6502599069543555, + -1.2447947988461912, + -0.8393296907380268, + -0.4338645826298623, + -0.028399474521698, + 0.37843643572024505, + 0.7839015438284094, + 1.1878434223960523, + 1.5933085305042167, + 1.998773638612381 + ], + "ys": [ + 1.4371068709113273, + 1.3442294606163505, + 1.2504550788598903, + 1.1451084785403978, + 1.0076845134906758, + 0.8393355383077514, + 0.6496537972367906, + 0.4625305796292689, + 0.3035348264320895, + 0.18409848770017576, + 0.10404729414822564, + 0.05492082710147257, + 0.026929508320917738, + 0.012117250742785222, + 0.0049122319794404614, + 0.0017509584506394302, + 5.433850247572385E-4, + 1.4341185451814312E-4, + 3.1018961899754435E-5, + 5.139667971021216E-6 + ] + } +} \ No newline at end of file diff --git a/src/test/resources/e2e/nshm-conus-2018-HONOLULU_HI.json b/src/test/resources/e2e/nshm-conus-2018-HONOLULU_HI.json new file mode 100644 index 0000000000000000000000000000000000000000..87cb4ce998380e2258647b5dd4efb789da1525a4 --- /dev/null +++ b/src/test/resources/e2e/nshm-conus-2018-HONOLULU_HI.json @@ -0,0 +1,186 @@ +{ + "1.00 Second Spectral Acceleration": { + "xs": [ + -5.991464547107982, + -5.585999438999818, + -5.181423615076537, + -4.775958506968373, + -4.374058465024705, + -3.9633162998156966, + -3.5613661338149765, + -3.1535563587475584, + -2.7488721956224653, + -2.3434070875143007, + -1.9379419794061366, + -1.5324768712979722, + -1.1270117631898076, + -0.7215466550816433, + -0.31608154697347896, + 0.08617769624105241, + 0.494696241836107, + 0.9001613499442714, + 1.3056264580524357, + 1.7119945007591924 + ], + "ys": [ + 0.1096176362431887, + 0.07712267985209978, + 0.05236216472551225, + 0.03410083982464373, + 0.02132788570031522, + 0.012597455865731777, + 0.007195466062794852, + 0.0039020156778838797, + 0.0020347763827356416, + 0.0010104978512827576, + 4.744665345271375E-4, + 2.0784677016393615E-4, + 8.354936782969439E-5, + 3.0262362405560818E-5, + 9.700628718654082E-6, + 2.73388661760168E-6, + 6.418080520161568E-7, + 1.2432205810419981E-7, + 1.6644800833465068E-8, + 8.894088492362763E-10 + ] + }, + "5.00 Second Spectral Acceleration": { + "xs": [ + -6.908755779315721, + -6.502290170873972, + -6.0968250627658085, + -5.692842534617867, + -5.286388795682763, + -4.882242079327857, + -4.474141923581687, + -4.0686768154735224, + -3.6651629274966204, + -3.259697819388456, + -2.8542327112802917, + -2.448767603172127, + -2.0402208285265546, + -1.6398971199188088, + -1.2310014767138553, + -0.8278220838865469, + -0.42159449003804794, + -0.016129381929883644, + 0.3920420877760237, + 0.7929925155296614 + ], + "ys": [ + 0.023279814179665247, + 0.015258454706800595, + 0.009636588671134795, + 0.0058636185962218715, + 0.0034303179683354557, + 0.0019508911864085043, + 0.0010720245656982627, + 5.727230032611106E-4, + 2.940392779991596E-4, + 1.4181349785670868E-4, + 6.333513533663933E-5, + 2.5779423268780836E-5, + 9.34540879758316E-6, + 3.0570885601346303E-6, + 8.448187381597024E-7, + 2.0283376419955368E-7, + 3.799045552673217E-8, + 5.257992980887434E-9, + 4.696318067912854E-10, + 8.040835683421514E-12 + ] + }, + "Peak Ground Acceleration": { + "xs": [ + -6.061887011404528, + -5.654992310486769, + -5.251433780649187, + -4.845968672541022, + -4.439655747510518, + -4.034190639402354, + -3.6306105459899607, + -3.223888366691745, + -2.8184232585835804, + -2.4123999590012524, + -2.0099154790312257, + -1.5994875815809322, + -1.1973282616072674, + -0.789658080940789, + -0.3856624808119846, + 0.01980262729617973, + 0.4252677354043441, + 0.8329091229351039, + 1.235471471385307, + 1.6428726885203377 + ], + "ys": [ + 0.16241112120908746, + 0.12117474522250349, + 0.08821017091766083, + 0.06247545594775962, + 0.04294114327512309, + 0.028525687803782396, + 0.018224455950293393, + 0.011059987400758737, + 0.006364262004183083, + 0.0034377054571609225, + 0.001738825379832288, + 7.965440914871203E-4, + 3.3531414903647464E-4, + 1.2359465951104756E-4, + 3.997349646564974E-5, + 1.1017452326436623E-5, + 2.556220564845531E-6, + 4.819237373193018E-7, + 6.872217721500788E-8, + 5.03174786246266E-9 + ] + }, + "0.20 Second Spectral Acceleration": { + "xs": [ + -5.704782974989785, + -5.30031936921871, + -4.8941864814530085, + -4.491841500681089, + -4.080441657053109, + -3.6769508832486624, + -3.2728041668937564, + -2.866459937849852, + -2.4615808244845034, + -2.05572501506252, + -1.6502599069543555, + -1.2447947988461912, + -0.8393296907380268, + -0.4338645826298623, + -0.028399474521698, + 0.37843643572024505, + 0.7839015438284094, + 1.1878434223960523, + 1.5933085305042167, + 1.998773638612381 + ], + "ys": [ + 0.20884911299107897, + 0.1614581046884402, + 0.11999074916434269, + 0.08664281640904029, + 0.06035281081025549, + 0.041136602866201834, + 0.027122373299762817, + 0.017158998663766196, + 0.010389832056442814, + 0.005966842420004628, + 0.003237425806138684, + 0.0016481130397465967, + 7.801989781232736E-4, + 3.388907756049955E-4, + 1.3261398028112855E-4, + 4.5544380625508945E-5, + 1.3505510623393688E-5, + 3.379046576023759E-6, + 6.851474870720804E-7, + 1.0763757443621396E-7 + ] + } +} \ No newline at end of file diff --git a/src/test/resources/e2e/nshm-conus-2018-KAILUA_KONA_HI.json b/src/test/resources/e2e/nshm-conus-2018-KAILUA_KONA_HI.json new file mode 100644 index 0000000000000000000000000000000000000000..e95d6d19d18ef0d69692ac9e1c3b74c4564750c8 --- /dev/null +++ b/src/test/resources/e2e/nshm-conus-2018-KAILUA_KONA_HI.json @@ -0,0 +1,186 @@ +{ + "1.00 Second Spectral Acceleration": { + "xs": [ + -5.991464547107982, + -5.585999438999818, + -5.181423615076537, + -4.775958506968373, + -4.374058465024705, + -3.9633162998156966, + -3.5613661338149765, + -3.1535563587475584, + -2.7488721956224653, + -2.3434070875143007, + -1.9379419794061366, + -1.5324768712979722, + -1.1270117631898076, + -0.7215466550816433, + -0.31608154697347896, + 0.08617769624105241, + 0.494696241836107, + 0.9001613499442714, + 1.3056264580524357, + 1.7119945007591924 + ], + "ys": [ + 0.9310649618626424, + 0.7152683525622628, + 0.5254960437436178, + 0.37057192881004797, + 0.25360306935928917, + 0.1673342748557868, + 0.10852163641624823, + 0.06764805605345484, + 0.040421250385918366, + 0.022759302561329985, + 0.012035453130050871, + 0.006001361401039622, + 0.002825403258669261, + 0.0012397199668725764, + 4.913127725890904E-4, + 1.6916652515186739E-4, + 4.6081848166959275E-5, + 9.142956045358946E-6, + 1.067682459238504E-6, + 4.4135240737735364E-8 + ] + }, + "5.00 Second Spectral Acceleration": { + "xs": [ + -6.908755779315721, + -6.502290170873972, + -6.0968250627658085, + -5.692842534617867, + -5.286388795682763, + -4.882242079327857, + -4.474141923581687, + -4.0686768154735224, + -3.6651629274966204, + -3.259697819388456, + -2.8542327112802917, + -2.448767603172127, + -2.0402208285265546, + -1.6398971199188088, + -1.2310014767138553, + -0.8278220838865469, + -0.42159449003804794, + -0.016129381929883644, + 0.3920420877760237, + 0.7929925155296614 + ], + "ys": [ + 0.191466520506286, + 0.13554779250681923, + 0.09647775115759329, + 0.06847614819048337, + 0.04772578379364717, + 0.03208679105889853, + 0.020129540279605, + 0.011639202185119844, + 0.0061951399190677625, + 0.003075883535659292, + 0.0014771509658122375, + 7.061929082246017E-4, + 3.3451441585971104E-4, + 1.5467986387544447E-4, + 6.363609376236911E-5, + 2.247131683032451E-5, + 6.219516642047414E-6, + 1.2615492254822047E-6, + 1.5297532779407637E-7, + 7.198489307670766E-9 + ] + }, + "Peak Ground Acceleration": { + "xs": [ + -6.061887011404528, + -5.654992310486769, + -5.251433780649187, + -4.845968672541022, + -4.439655747510518, + -4.034190639402354, + -3.6306105459899607, + -3.223888366691745, + -2.8184232585835804, + -2.4123999590012524, + -2.0099154790312257, + -1.5994875815809322, + -1.1973282616072674, + -0.789658080940789, + -0.3856624808119846, + 0.01980262729617973, + 0.4252677354043441, + 0.8329091229351039, + 1.235471471385307, + 1.6428726885203377 + ], + "ys": [ + 1.3099486083268739, + 1.199523417668875, + 1.0517265084684115, + 0.8707860874217463, + 0.6765138623146243, + 0.493401638622512, + 0.33992289432676787, + 0.22192803156480623, + 0.13847632521718928, + 0.08175333860325448, + 0.04511099205028913, + 0.022490754664834876, + 0.010374939794256521, + 0.004313773760782856, + 0.0016216028906538638, + 5.238693662990279E-4, + 1.3772717633153163E-4, + 2.676199733991637E-5, + 3.5045913382111145E-6, + 2.3097496341714198E-7 + ] + }, + "0.20 Second Spectral Acceleration": { + "xs": [ + -5.704782974989785, + -5.30031936921871, + -4.8941864814530085, + -4.491841500681089, + -4.080441657053109, + -3.6769508832486624, + -3.2728041668937564, + -2.866459937849852, + -2.4615808244845034, + -2.05572501506252, + -1.6502599069543555, + -1.2447947988461912, + -0.8393296907380268, + -0.4338645826298623, + -0.028399474521698, + 0.37843643572024505, + 0.7839015438284094, + 1.1878434223960523, + 1.5933085305042167, + 1.998773638612381 + ], + "ys": [ + 1.3761096429204573, + 1.292747489392661, + 1.178335057078432, + 1.0275173511479154, + 0.842703120792494, + 0.6513972997833428, + 0.4724290039202468, + 0.3221706088273527, + 0.20861884543377657, + 0.128355896587962, + 0.07482094551740774, + 0.040954079958872666, + 0.02092944382070038, + 0.009967533485864722, + 0.004400165256626161, + 0.0017609227596797569, + 6.180891817013114E-4, + 1.815463526788613E-4, + 4.1290331752591286E-5, + 6.280186508295586E-6 + ] + } +} \ No newline at end of file