Skip to content

Commit 5cdf523

Browse files
Merge pull request #461 from pmpowers-usgs/hawaii-decollement-uncertainty
Added limited uncertainty support to interface parser
2 parents ac25668 + 05a6e3f commit 5cdf523

1 file changed

Lines changed: 96 additions & 16 deletions

File tree

src/gov/usgs/earthquake/nshmp/eq/model/InterfaceParser.java

Lines changed: 96 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import static gov.usgs.earthquake.nshmp.internal.Parsing.readEnum;
77
import static gov.usgs.earthquake.nshmp.internal.Parsing.readInt;
88
import static gov.usgs.earthquake.nshmp.internal.Parsing.readString;
9+
import static gov.usgs.earthquake.nshmp.internal.Parsing.toMap;
910
import static gov.usgs.earthquake.nshmp.internal.SourceAttribute.DEPTH;
1011
import static gov.usgs.earthquake.nshmp.internal.SourceAttribute.DIP;
1112
import static gov.usgs.earthquake.nshmp.internal.SourceAttribute.ID;
@@ -21,6 +22,7 @@
2122
import java.io.InputStream;
2223
import java.util.ArrayList;
2324
import java.util.List;
25+
import java.util.Map;
2426
import java.util.logging.Logger;
2527

2628
import javax.xml.parsers.SAXParser;
@@ -31,6 +33,9 @@
3133
import org.xml.sax.SAXParseException;
3234
import org.xml.sax.helpers.DefaultHandler;
3335

36+
import com.google.common.collect.Lists;
37+
38+
import gov.usgs.earthquake.nshmp.eq.Earthquakes;
3439
import gov.usgs.earthquake.nshmp.eq.fault.surface.RuptureScaling;
3540
import gov.usgs.earthquake.nshmp.eq.model.MfdHelper.GR_Data;
3641
import gov.usgs.earthquake.nshmp.eq.model.MfdHelper.SingleData;
@@ -65,6 +70,11 @@ class InterfaceParser extends DefaultHandler {
6570

6671
private RuptureScaling rupScaling;
6772

73+
// Data applying to all sourceSet
74+
private MagUncertainty unc = null;
75+
private Map<String, String> epiAtts = null;
76+
private Map<String, String> aleaAtts = null;
77+
6878
// Default MFD data
6979
private boolean parsingDefaultMFDs = false;
7080
private MfdHelper.Builder mfdHelperBuilder;
@@ -83,10 +93,10 @@ static InterfaceParser create(SAXParser sax) {
8393
}
8494

8595
InterfaceSourceSet parse(
86-
InputStream in,
87-
GmmSet gmmSet,
96+
InputStream in,
97+
GmmSet gmmSet,
8898
ModelConfig config) throws SAXException, IOException {
89-
99+
90100
checkState(!used, "This parser has expired");
91101
this.gmmSet = gmmSet;
92102
this.config = config;
@@ -98,9 +108,9 @@ InterfaceSourceSet parse(
98108

99109
@Override
100110
public void startElement(
101-
String uri,
102-
String localName,
103-
String qName,
111+
String uri,
112+
String localName,
113+
String qName,
104114
Attributes atts) throws SAXException {
105115

106116
SourceElement e = null;
@@ -137,6 +147,14 @@ public void startElement(
137147
parsingDefaultMFDs = true;
138148
break;
139149

150+
case EPISTEMIC:
151+
epiAtts = toMap(atts);
152+
break;
153+
154+
case ALEATORY:
155+
aleaAtts = toMap(atts);
156+
break;
157+
140158
case SOURCE_PROPERTIES:
141159
rupScaling = readEnum(RUPTURE_SCALING, atts, RuptureScaling.class);
142160
log.fine("Rup scaling: " + rupScaling);
@@ -201,8 +219,8 @@ public void startElement(
201219

202220
@Override
203221
public void endElement(
204-
String uri,
205-
String localName,
222+
String uri,
223+
String localName,
206224
String qName) throws SAXException {
207225

208226
SourceElement e = null;
@@ -220,6 +238,15 @@ public void endElement(
220238
mfdHelper = mfdHelperBuilder.build();
221239
break;
222240

241+
case SETTINGS:
242+
// may not have mag uncertainty element so create the
243+
// uncertainty container upon leaving 'Settings'
244+
unc = MagUncertainty.create(epiAtts, aleaAtts);
245+
if (log.isLoggable(FINE)) {
246+
log.fine(unc.toString());
247+
}
248+
break;
249+
223250
case TRACE:
224251
readingTrace = false;
225252
sourceBuilder.trace(LocationList.fromString(traceBuilder.toString()));
@@ -282,24 +309,53 @@ private List<IncrementalMfd> buildMfds(Attributes atts) {
282309
private List<IncrementalMfd> buildGR(Attributes atts) {
283310
List<IncrementalMfd> mfdList = new ArrayList<>();
284311
for (GR_Data grData : mfdHelper.grData(atts)) {
285-
mfdList.add(buildGR(grData));
312+
mfdList.addAll(buildGR(grData));
286313
}
287314
return mfdList;
288315
}
289316

290-
private IncrementalMfd buildGR(GR_Data data) {
317+
private List<IncrementalMfd> buildGR(GR_Data data) {
291318

292319
int nMag = Mfds.magCount(data.mMin, data.mMax, data.dMag);
293320
checkState(nMag > 0, "GR MFD with no mags");
294321
double tmr = Mfds.totalMoRate(data.mMin, nMag, data.dMag, data.a, data.b);
322+
List<IncrementalMfd> mfds = Lists.newArrayList();
323+
324+
if (unc.hasEpistemic) {
325+
for (int i = 0; i < unc.epiCount; i++) {
326+
// update mMax and nMag
327+
double mMaxEpi = data.mMax + unc.epiDeltas[i];
328+
int nMagEpi = Mfds.magCount(data.mMin, mMaxEpi, data.dMag);
329+
if (nMagEpi > 0) {
330+
double weightEpi = data.weight * unc.epiWeights[i];
331+
332+
// epi branches preserve Mo between mMin and dMag(nMag-1),
333+
// not mMax to ensure that Mo is 'spent' on earthquakes
334+
// represented by the epi GR distribution with adj. mMax.
335+
336+
IncrementalMfd mfd = Mfds.newGutenbergRichterMoBalancedMFD(data.mMin,
337+
data.dMag, nMagEpi, data.b, tmr * weightEpi);
338+
mfds.add(mfd);
339+
log.finer(" MFD type: GR [+epi -alea] " + epiBranch(i));
340+
if (log.isLoggable(FINEST)) {
341+
log.finest(mfd.getMetadataString());
342+
}
343+
} else {
344+
log.warning(" GR MFD epi branch with no mags [" + sourceBuilder.name + "]");
295345

296-
IncrementalMfd mfd = Mfds.newGutenbergRichterMoBalancedMFD(data.mMin, data.dMag, nMag,
297-
data.b, tmr * data.weight);
298-
log.finer(" MFD type: GR");
299-
if (log.isLoggable(FINEST)) {
300-
log.finest(mfd.getMetadataString());
346+
}
347+
}
348+
349+
} else {
350+
IncrementalMfd mfd = Mfds.newGutenbergRichterMoBalancedMFD(data.mMin, data.dMag, nMag,
351+
data.b, tmr * data.weight);
352+
mfds.add(mfd);
353+
log.finer(" MFD type: GR");
354+
if (log.isLoggable(FINEST)) {
355+
log.finest(mfd.getMetadataString());
356+
}
301357
}
302-
return mfd;
358+
return mfds;
303359
}
304360

305361
/* Build SINGLE MFDs. */
@@ -311,7 +367,27 @@ private List<IncrementalMfd> buildSingle(Attributes atts) {
311367
return mfdList;
312368
}
313369

370+
// only aleatory supported
314371
private IncrementalMfd buildSingle(SingleData data) {
372+
373+
if (unc.hasAleatory) {
374+
double tmr = data.rate * Earthquakes.magToMoment(data.m);
375+
if (!unc.moBalance) {
376+
throw new RuntimeException("moBalance must be 'true'");
377+
}
378+
IncrementalMfd mfd = Mfds.newGaussianMoBalancedMFD(
379+
data.m,
380+
unc.aleaSigma,
381+
unc.aleaCount,
382+
data.weight * tmr,
383+
data.floats);
384+
log.finer(" MFD type: SINGLE [+alea]");
385+
if (log.isLoggable(FINEST)) {
386+
log.finest(mfd.getMetadataString());
387+
}
388+
return mfd;
389+
}
390+
315391
IncrementalMfd mfd = Mfds.newSingleMFD(data.m, data.weight * data.rate, data.floats);
316392
log.finer(" MFD type: SINGLE");
317393
if (log.isLoggable(FINEST)) {
@@ -320,4 +396,8 @@ private IncrementalMfd buildSingle(SingleData data) {
320396
return mfd;
321397
}
322398

399+
private static String epiBranch(int i) {
400+
return (i == 0) ? "(M-epi)" : (i == 2) ? "(M+epi)" : "(M)";
401+
}
402+
323403
}

0 commit comments

Comments
 (0)