Skip to content
Snippets Groups Projects

Hazard service updates

Merged Powers, Peter M. requested to merge (removed):hazard-service-updates into master
1 file
+ 1
1
Compare changes
  • Side-by-side
  • Inline
package gov.usgs.earthquake.nshmp.www.services;
package gov.usgs.earthquake.nshmp.www.services;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Preconditions.checkState;
import static gov.usgs.earthquake.nshmp.calc.HazardExport.curvesBySource;
import static gov.usgs.earthquake.nshmp.calc.HazardExport.curvesBySource;
import java.util.ArrayList;
import java.util.ArrayList;
 
import java.util.Arrays;
import java.util.EnumMap;
import java.util.EnumMap;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import java.util.function.Function;
@@ -46,22 +45,10 @@ import io.micronaut.http.HttpResponse;
@@ -46,22 +45,10 @@ import io.micronaut.http.HttpResponse;
*/
*/
public final class HazardService {
public final class HazardService {
/*
* Developer notes:
*
* Calculations are designed to leverage all available processors by default,
* distributing work using the ServletUtil.CALC_EXECUTOR.
*/
private static final String NAME = "Hazard Service";
private static final String NAME = "Hazard Service";
/**
/** HazardController.doGetUsage() handler. */
* Handler for {@link HazardController#doGetUsage}. Returns the usage for the
public static HttpResponse<String> handleDoGetMetadata(UrlHelper urlHelper) {
* hazard service.
*
* @param urlHelper The URL helper
*/
public static HttpResponse<String> handleDoGetUsage(UrlHelper urlHelper) {
try {
try {
var usage = new RequestMetadata(ServletUtil.model());// SourceServices.ResponseData();
var usage = new RequestMetadata(ServletUtil.model());// SourceServices.ResponseData();
var response = new Response<>(Status.USAGE, NAME, urlHelper.url, usage, urlHelper);
var response = new Response<>(Status.USAGE, NAME, urlHelper.url, usage, urlHelper);
@@ -72,22 +59,17 @@ public final class HazardService {
@@ -72,22 +59,17 @@ public final class HazardService {
}
}
}
}
/**
/** HazardController.doGetHazard() handler. */
* Handler for {@link HazardController#doGetHazard}. Returns the usage or the
* hazard result.
*
* @param query The query
* @param urlHelper The URL helper
*/
public static HttpResponse<String> handleDoGetHazard(
public static HttpResponse<String> handleDoGetHazard(
QueryParameters query,
QueryParameters query,
UrlHelper urlHelper) {
UrlHelper urlHelper) {
try {
try {
if (query.isEmpty()) {
// TODO still need to validate
return handleDoGetUsage(urlHelper);
// if (query.isEmpty()) {
}
// return handleDoGetUsage(urlHelper);
query.checkParameters();
// }
 
// query.checkParameters();
var data = new RequestData(query);
var data = new RequestData(query);
var response = process(data, urlHelper);
var response = process(data, urlHelper);
var svcResponse = ServletUtil.GSON.toJson(response);
var svcResponse = ServletUtil.GSON.toJson(response);
@@ -142,35 +124,37 @@ public final class HazardService {
@@ -142,35 +124,37 @@ public final class HazardService {
public static class QueryParameters {
public static class QueryParameters {
Optional<Double> longitude;
final double longitude;
Optional<Double> latitude;
final double latitude;
Optional<Integer> vs30;
final int vs30;
 
final boolean truncate;
 
final boolean maxdir;
public QueryParameters(
public QueryParameters(
Optional<Double> longitude,
double longitude,
Optional<Double> latitude,
double latitude,
Optional<Integer> vs30) {
int vs30,
 
boolean truncate,
 
boolean maxdir) {
this.longitude = longitude;
this.longitude = longitude;
this.latitude = latitude;
this.latitude = latitude;
this.vs30 = vs30;
this.vs30 = vs30;
 
this.truncate = truncate;
 
this.maxdir = maxdir;
}
}
public boolean isEmpty() {
// void checkParameters() {
return longitude.isEmpty() && latitude.isEmpty() && vs30.isEmpty();
// checkParameter(longitude, "longitude");
}
// checkParameter(latitude, "latitude");
// checkParameter(vs30, "vs30");
public void checkParameters() {
// }
checkParameter(longitude, "longitude");
checkParameter(latitude, "latitude");
checkParameter(vs30, "vs30");
}
}
}
private static void checkParameter(Object param, String id) {
// private static void checkParameter(Object param, String id) {
checkNotNull(param, "Missing parameter: %s", id);
// checkNotNull(param, "Missing parameter: %s", id);
// TODO check range here
// // TODO check range here
}
// }
/* Service request and model metadata */
/* Service request and model metadata */
static class RequestMetadata {
static class RequestMetadata {
@@ -208,11 +192,15 @@ public final class HazardService {
@@ -208,11 +192,15 @@ public final class HazardService {
final double longitude;
final double longitude;
final double latitude;
final double latitude;
final double vs30;
final double vs30;
 
final boolean truncate;
 
final boolean maxdir;
RequestData(QueryParameters query) {
RequestData(QueryParameters query) {
this.longitude = query.longitude.orElseThrow();
this.longitude = query.longitude;
this.latitude = query.latitude.orElseThrow();
this.latitude = query.latitude;
this.vs30 = query.vs30.orElseThrow();
this.vs30 = query.vs30;
 
this.truncate = query.truncate;
 
this.maxdir = query.maxdir;
}
}
}
}
@@ -271,9 +259,7 @@ public final class HazardService {
@@ -271,9 +259,7 @@ public final class HazardService {
Curve(String component, XySequence values) {
Curve(String component, XySequence values) {
this.component = component;
this.component = component;
this.values = XySequence.create(
this.values = values;
values.xValues().map(Math::exp).toArray(),
values.yValues().toArray());
}
}
}
}
@@ -341,12 +327,16 @@ public final class HazardService {
@@ -341,12 +327,16 @@ public final class HazardService {
var curves = new ArrayList<Curve>();
var curves = new ArrayList<Curve>();
// total curve
// total curve
curves.add(new Curve(TOTAL_KEY, totalMap.get(imt)));
curves.add(new Curve(
 
TOTAL_KEY,
 
updateCurve(request, totalMap.get(imt), imt)));
// component curves
// component curves
var typeMap = componentMaps.get(imt);
var typeMap = componentMaps.get(imt);
for (SourceType type : typeMap.keySet()) {
for (SourceType type : typeMap.keySet()) {
curves.add(new Curve(type.toString(), typeMap.get(type)));
curves.add(new Curve(
 
type.toString(),
 
updateCurve(request, typeMap.get(type), imt)));
}
}
hazards.add(new HazardResponse(imt, List.copyOf(curves)));
hazards.add(new HazardResponse(imt, List.copyOf(curves)));
@@ -359,6 +349,44 @@ public final class HazardService {
@@ -359,6 +349,44 @@ public final class HazardService {
}
}
}
}
 
private static final double TRUNCATION_LIMIT = 1e-4;
 
 
/* Convert to linear and possibly truncate and scale to max-direction. */
 
private static XySequence updateCurve(
 
RequestData request,
 
XySequence curve,
 
Imt imt) {
 
 
/*
 
* If entire curve is <1e-4, this method will return a curve consisting of
 
* just the first point in the supplied curve.
 
*
 
* TODO We probably want to move the TRUNCATION_LIMIT out to a config.
 
*/
 
 
double[] yValues = curve.yValues().toArray();
 
int limit = request.truncate ? truncationLimit(yValues) : yValues.length;
 
yValues = Arrays.copyOf(yValues, limit);
 
 
double scale = request.maxdir ? MaxDirection.FACTORS.get(imt) : 1.0;
 
double[] xValues = curve.xValues()
 
.limit(yValues.length)
 
.map(Math::exp)
 
.map(x -> x * scale)
 
.toArray();
 
 
return XySequence.create(xValues, yValues);
 
}
 
 
private static int truncationLimit(double[] yValues) {
 
int limit = 1;
 
double y = yValues[0];
 
while (y > TRUNCATION_LIMIT && limit < yValues.length) {
 
y = yValues[limit++];
 
}
 
return limit;
 
}
 
@Deprecated
@Deprecated
public static class Query extends ServiceQueryData {
public static class Query extends ServiceQueryData {
Integer vs30;
Integer vs30;
Loading