Skip to content
Snippets Groups Projects
Commit 3b1b573f authored by Powers, Peter M.'s avatar Powers, Peter M.
Browse files

refactored cluster mfdTree reporting

parent 1fc75e96
No related branches found
No related tags found
1 merge request!432General edits and improvements
......@@ -8,12 +8,16 @@ import static java.util.stream.Collectors.toList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Predicate;
import gov.usgs.earthquake.nshmp.data.XySequence;
import gov.usgs.earthquake.nshmp.geo.Location;
import gov.usgs.earthquake.nshmp.geo.json.Feature;
import gov.usgs.earthquake.nshmp.mfd.Mfd;
import gov.usgs.earthquake.nshmp.tree.LogicGroup;
import gov.usgs.earthquake.nshmp.mfd.Mfd.Type;
import gov.usgs.earthquake.nshmp.tree.Branch;
import gov.usgs.earthquake.nshmp.tree.LogicTree;
/**
......@@ -36,13 +40,36 @@ import gov.usgs.earthquake.nshmp.tree.LogicTree;
*/
public class ClusterRuptureSet extends AbstractRuptureSet<ClusterSource> {
/*
* Developer notes:
*
* A ClusterRuptureSet is composed of two or more FaultRuptureSets (fault
* sections) that rupture together according to some rate or logic tree of
* rates. Each nested FaultRuptureSet itself contains a logic tree of SINGLE
* MFDs, usually labelled 'M1', 'M2', etc. The MFDs for each FaultRuptureSet
* are the same size and have identical weights. Technically, the M1 fault
* branches across each cluster should be considered together, the M2 fault
* branches together, etc. in the cluster hazard calculation. However, the
* magnitude branch exceedance curves are currently collapsed prior to doing
* the cluster calculation.
*
* For the purposes of reporting an MFD tree for a ClusterRuptureSet, we
* create MFDs for each magnitude branch spanning the individual sections in
* the cluster. In some cases there may be identical magnitudes in a cluster
* such that the cluster rate reflected in the MFD may be doubled or more.
*
*/
@Deprecated
final ModelData data; // holds cluster rate tree
private final List<ClusterSource> source;
private final LogicTree<Mfd> mfdTree;
private ClusterRuptureSet(Builder builder) {
super(builder);
this.data = builder.data;
this.source = List.of(builder.source);
this.mfdTree = builder.mfdTree;
}
@Override
......@@ -65,23 +92,7 @@ public class ClusterRuptureSet extends AbstractRuptureSet<ClusterSource> {
@Override
public LogicTree<Mfd> mfdTree() {
/*
* A ClusterSource is composed of multiple FaultRuptureSets that rupture
* together at some rate. For the purposes of reporting an MFD tree for the
* rupture set, we combine the SINGLE MFDs associated with each
* FaultRuptureSet and set the rate of each magnitude to its weight. We then
* build a logic group where the weight (scale) of each branch is set to the
* cluster rate.
*/
ClusterSource clusterSource = source.get(0);
double rate = clusterSource.rate();
LogicGroup.Builder<Mfd> builder = LogicGroup.builder();
for (RuptureSet<? extends Source> ruptureSet : clusterSource.ruptureSets()) {
Mfd mfd = ModelTrees.reduceMfdTree(ruptureSet.mfdTree());
builder.addBranch(ruptureSet.name(), mfd, rate);
}
return builder.build();
return mfdTree;
}
/*
......@@ -168,6 +179,7 @@ public class ClusterRuptureSet extends AbstractRuptureSet<ClusterSource> {
private ModelData data; // holds cluster rate-tree
private ClusterSource source;
private LogicTree<Mfd> mfdTree;
private Builder() {
super(SourceType.FAULT_CLUSTER);
......@@ -205,8 +217,37 @@ public class ClusterRuptureSet extends AbstractRuptureSet<ClusterSource> {
checkNotNull(source, "%s cluster source", label);
}
LogicTree<Mfd> createMfdTree() {
LogicTree.Builder<Mfd> builder = LogicTree.builder("cluster-mfd");
LogicTree<Mfd> model = source.ruptureSets().get(0).mfdTree();
/* loop magnitude branches */
for (int i = 0; i < model.size(); i++) {
/* collect cluster magnitudes and rate; all M have cluster rate */
Map<Double, Double> magMap = new TreeMap<>();
String magId = model.get(i).id();
double magWeight = model.get(i).weight();
for (RuptureSet<? extends Source> ruptureSet : source.ruptureSets()) {
Branch<Mfd> mfd = ruptureSet.mfdTree().get(i);
/* check magnitude branch IDs and weights match */
checkState(mfd.id().equals(magId));
checkState(mfd.value().properties().type() == Type.SINGLE);
magMap.merge(
mfd.value().data().x(0),
source.rate(),
(v1, v2) -> v1 + v2);
}
XySequence mfdXy = XySequence.create(
magMap.keySet(),
magMap.values());
Mfd clusterMfd = Mfd.create(mfdXy);
builder.addBranch(magId, clusterMfd, magWeight);
}
return builder.build();
}
ClusterRuptureSet build() {
validateAndInit("ClusterRuptureSet.Builder");
mfdTree = createMfdTree();
return new ClusterRuptureSet(this);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment