Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
N
nshmp-haz
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ghsc
National Seismic Hazard Model Project
nshmp-haz
Commits
72d26d38
Commit
72d26d38
authored
5 years ago
by
Clayton, Brandon Scott
Browse files
Options
Downloads
Patches
Plain Diff
new handler for DeaggEpsilonController
parent
df64cbd7
No related branches found
Branches containing commit
No related tags found
Tags containing commit
1 merge request
!481
Deagg Epsilon
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/main/java/gov/usgs/earthquake/nshmp/www/services/DeaggEpsilonService.java
+299
-0
299 additions, 0 deletions
...gs/earthquake/nshmp/www/services/DeaggEpsilonService.java
with
299 additions
and
0 deletions
src/main/java/gov/usgs/earthquake/nshmp/www/services/DeaggEpsilonService.java
0 → 100644
+
299
−
0
View file @
72d26d38
package
gov.usgs.earthquake.nshmp.www.services
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkNotNull
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.net.URL
;
import
java.util.EnumMap
;
import
java.util.List
;
import
java.util.Properties
;
import
java.util.concurrent.ExecutionException
;
import
java.util.function.Function
;
import
java.util.logging.Logger
;
import
javax.servlet.ServletException
;
import
com.google.common.collect.ImmutableList
;
import
com.google.common.io.Resources
;
import
gov.usgs.earthquake.nshmp.calc.CalcConfig
;
import
gov.usgs.earthquake.nshmp.calc.Deaggregation
;
import
gov.usgs.earthquake.nshmp.calc.Site
;
import
gov.usgs.earthquake.nshmp.calc.Vs30
;
import
gov.usgs.earthquake.nshmp.geo.Location
;
import
gov.usgs.earthquake.nshmp.gmm.Imt
;
import
gov.usgs.earthquake.nshmp.internal.www.NshmpMicronautServlet.UrlHelper
;
import
gov.usgs.earthquake.nshmp.internal.www.Response
;
import
gov.usgs.earthquake.nshmp.internal.www.WsUtils
;
import
gov.usgs.earthquake.nshmp.internal.www.meta.Status
;
import
gov.usgs.earthquake.nshmp.www.BaseModel
;
import
gov.usgs.earthquake.nshmp.www.DeaggEpsilonController
;
import
gov.usgs.earthquake.nshmp.www.meta.Metadata
;
import
gov.usgs.earthquake.nshmp.www.services.ServicesUtil.Key
;
import
gov.usgs.earthquake.nshmp.www.services.ServletUtil.Timer
;
import
gov.usgs.earthquake.nshmp.www.services.SourceServices.SourceModel
;
import
io.micronaut.http.HttpRequest
;
import
io.micronaut.http.HttpResponse
;
/**
* Hazard deaggregation handler for {@link DeaggEpsilonController}.
*
* @author U.S. Geological Survey
*/
public
final
class
DeaggEpsilonService
{
/* Developer notes: See HazardService. */
private
static
final
String
NAME
=
"Epsilon Deaggregation"
;
private
static
final
Logger
LOGGER
=
Logger
.
getLogger
(
DeaggEpsilonService
.
class
.
getName
());
private
static
URL
basinUrl
;
public
static
void
init
()
throws
ServletException
{
try
(
InputStream
config
=
Resources
.
getResource
(
"config.properties"
).
openStream
())
{
checkNotNull
(
config
,
"Missing config.properties"
);
Properties
props
=
new
Properties
();
props
.
load
(
config
);
if
(
props
.
containsKey
(
"basin_host"
))
{
/*
* TODO Site builder tests if service is working, which may be
* inefficient for single call services.
*/
var
url
=
new
URL
(
props
.
getProperty
(
"basin_host"
)
+
"/nshmp/ws/data/basin"
);
basinUrl
=
url
;
}
}
catch
(
IOException
|
NullPointerException
e
)
{
throw
new
ServletException
(
e
);
}
}
/**
* Handler for {@link DeaggEpsilonController#doGetDeaggEpsilon}. Returns the
* usage or the deagg result.
*
* @param query The query
* @param urlHelper The URL helper
*/
public
static
HttpResponse
<
String
>
handleDoGetDeaggEpsilon
(
Query
query
,
UrlHelper
urlHelper
)
{
try
{
var
timer
=
ServletUtil
.
timer
();
LOGGER
.
info
(
NAME
+
" - Request:\n"
+
ServletUtil
.
GSON
.
toJson
(
query
));
if
(
query
.
isNull
())
{
return
HazardService
.
handleDoGetUsage
(
urlHelper
);
}
query
.
checkValues
();
var
data
=
new
RequestData
(
query
,
Vs30
.
fromValue
(
query
.
vs30
));
var
response
=
process
(
data
,
timer
,
urlHelper
);
var
svcResponse
=
ServletUtil
.
GSON
.
toJson
(
response
);
LOGGER
.
info
(
NAME
+
" - Response:\n"
+
svcResponse
);
return
HttpResponse
.
ok
(
svcResponse
);
}
catch
(
Exception
e
)
{
return
ServicesUtil
.
handleError
(
e
,
NAME
,
LOGGER
,
urlHelper
);
}
}
/* Create map of IMT to deagg IML. */
private
static
EnumMap
<
Imt
,
Double
>
readImtsFromQuery
(
HttpRequest
<?>
request
)
{
var
imtImls
=
new
EnumMap
<
Imt
,
Double
>(
Imt
.
class
);
for
(
var
param
:
request
.
getParameters
().
asMap
().
entrySet
())
{
if
(
isImtParam
(
param
.
getKey
()))
{
imtImls
.
put
(
Imt
.
valueOf
(
param
.
getKey
()),
Double
.
valueOf
(
param
.
getValue
().
get
(
0
)));
}
}
return
imtImls
;
}
private
static
boolean
isImtParam
(
String
key
)
{
return
key
.
equals
(
"PGA"
)
||
key
.
startsWith
(
"SA"
);
}
private
static
Response
<
RequestData
,
ResponseData
>
process
(
RequestData
data
,
Timer
timer
,
UrlHelper
urlHelper
)
throws
InterruptedException
,
ExecutionException
{
var
configFunction
=
new
ConfigFunction
();
var
siteFunction
=
new
SiteFunction
(
data
);
var
hazard
=
ServicesUtil
.
calcHazard
(
configFunction
,
siteFunction
);
var
deagg
=
Deaggregation
.
atImls
(
hazard
,
data
.
imtImls
,
ServletUtil
.
CALC_EXECUTOR
);
return
new
ResultBuilder
()
.
deagg
(
deagg
)
.
requestData
(
data
)
.
timer
(
timer
)
.
urlHelper
(
urlHelper
)
.
build
();
}
public
static
class
Query
extends
HazardService
.
Query
{
final
EnumMap
<
Imt
,
Double
>
imtImls
;
final
Boolean
basin
;
public
Query
(
HttpRequest
<?>
request
,
Double
longitude
,
Double
latitude
,
Integer
vs30
,
Boolean
basin
)
{
super
(
longitude
,
latitude
,
vs30
);
imtImls
=
readImtsFromQuery
(
request
);
this
.
basin
=
basin
==
null
?
false
:
basin
;
}
@Override
public
boolean
isNull
()
{
return
super
.
isNull
()
&&
vs30
==
null
;
}
@Override
public
void
checkValues
()
{
super
.
checkValues
();
WsUtils
.
checkValue
(
Key
.
BASIN
,
basin
);
}
}
static
class
ConfigFunction
implements
Function
<
BaseModel
,
CalcConfig
>
{
@Override
public
CalcConfig
apply
(
BaseModel
baseModel
)
{
var
hazardModel
=
ServletUtil
.
hazardModels
().
get
(
baseModel
);
var
configBuilder
=
CalcConfig
.
copyOf
(
hazardModel
.
config
());
configBuilder
.
imts
(
baseModel
.
imts
);
return
configBuilder
.
build
();
}
}
/*
* Developer notes:
*
* We're opting here to fetch basin terms ourselves. If we were to set the
* basin provider in the config, which requires additions to config, the URL
* is tested every time a site is created for a servlet request. While this
* worked for maps it's not good here.
*
* Site has logic for parsing the basin service response, which perhaps it
* shouldn't. TODO is it worth decomposing data objects and services
*/
static
class
SiteFunction
implements
Function
<
CalcConfig
,
Site
>
{
final
RequestData
data
;
private
SiteFunction
(
RequestData
data
)
{
this
.
data
=
data
;
}
@Override
public
Site
apply
(
CalcConfig
config
)
{
return
Site
.
builder
()
.
location
(
Location
.
create
(
data
.
latitude
,
data
.
longitude
))
.
basinDataProvider
(
data
.
basin
?
basinUrl
:
null
)
.
vs30
(
data
.
vs30
.
value
())
.
build
();
}
}
static
final
class
RequestData
extends
HazardService
.
RequestData
{
final
EnumMap
<
Imt
,
Double
>
imtImls
;
final
boolean
basin
;
RequestData
(
Query
query
,
Vs30
vs30
)
{
super
(
query
,
vs30
);
imtImls
=
query
.
imtImls
;
basin
=
query
.
basin
;
}
}
@SuppressWarnings
(
"unused"
)
private
static
final
class
ResponseMetadata
{
final
SourceModel
model
;
final
double
longitude
;
final
double
latitude
;
final
String
imt
;
final
double
iml
;
final
Vs30
vs30
;
final
String
rlabel
=
"Closest Distance, rRup (km)"
;
final
String
mlabel
=
"Magnitude (Mw)"
;
final
String
εlabel
=
"% Contribution to Hazard"
;
final
Object
εbins
;
ResponseMetadata
(
Deaggregation
deagg
,
RequestData
request
,
Imt
imt
)
{
this
.
model
=
request
.
model
;
this
.
longitude
=
request
.
longitude
;
this
.
latitude
=
request
.
latitude
;
this
.
imt
=
imt
.
toString
();
this
.
iml
=
imt
.
period
();
this
.
vs30
=
request
.
vs30
;
this
.
εbins
=
deagg
.
εBins
();
}
}
@SuppressWarnings
(
"unused"
)
private
static
final
class
ResponseData
{
final
Object
server
;
final
List
<
DeaggResponse
>
deaggs
;
ResponseData
(
Object
server
,
List
<
DeaggResponse
>
deaggs
)
{
this
.
server
=
server
;
this
.
deaggs
=
deaggs
;
}
}
@SuppressWarnings
(
"unused"
)
private
static
final
class
DeaggResponse
{
final
ResponseMetadata
metadata
;
final
Object
data
;
DeaggResponse
(
ResponseMetadata
metadata
,
Object
data
)
{
this
.
metadata
=
metadata
;
this
.
data
=
data
;
}
}
static
final
class
ResultBuilder
{
UrlHelper
urlHelper
;
Timer
timer
;
RequestData
request
;
Deaggregation
deagg
;
ResultBuilder
deagg
(
Deaggregation
deagg
)
{
this
.
deagg
=
deagg
;
return
this
;
}
ResultBuilder
urlHelper
(
UrlHelper
urlHelper
)
{
this
.
urlHelper
=
urlHelper
;
return
this
;
}
ResultBuilder
timer
(
Timer
timer
)
{
this
.
timer
=
timer
;
return
this
;
}
ResultBuilder
requestData
(
RequestData
request
)
{
this
.
request
=
request
;
return
this
;
}
Response
<
RequestData
,
ResponseData
>
build
()
{
ImmutableList
.
Builder
<
DeaggResponse
>
responseListBuilder
=
ImmutableList
.
builder
();
for
(
Imt
imt
:
request
.
imtImls
.
keySet
())
{
ResponseMetadata
responseData
=
new
ResponseMetadata
(
deagg
,
request
,
imt
);
Object
deaggs
=
deagg
.
toJsonCompact
(
imt
);
DeaggResponse
response
=
new
DeaggResponse
(
responseData
,
deaggs
);
responseListBuilder
.
add
(
response
);
}
List
<
DeaggResponse
>
responseList
=
responseListBuilder
.
build
();
Object
server
=
Metadata
.
serverData
(
ServletUtil
.
THREAD_COUNT
,
timer
);
var
response
=
new
ResponseData
(
server
,
responseList
);
return
new
Response
<>(
Status
.
SUCCESS
,
NAME
,
request
,
response
,
urlHelper
);
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment