Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions openquake/hazardlib/calc/gmf.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,35 +267,38 @@ def compute_all(self, max_iml=None,
rng = numpy.random.default_rng(self.seed)
data = AccumDict(accum=[])
for g, (gs, rlzs) in enumerate(self.cmaker.gsims.items()):
idxs, = numpy.where(numpy.isin(self.rlz, rlzs))
E = len(idxs)
if E == 0: # crucial for performance
continue
with cmon:
array = self.compute(gs, rlzs, mean_stds[:, g], rng) # NME
array = self.compute(gs, idxs, mean_stds[:, g], rng) # NME
with umon:
self.update(data, array, rlzs, mean_stds[:, g], max_iml)
with umon:
return self.strip_zeros(data)

def compute(self, gsim, rlzs, mean_stds, rng):
def compute(self, gsim, idxs, mean_stds, rng):
"""
:param gsim: GSIM used to compute mean_stds
:param rlzs: realizations associated to the gsim
:param idxs: affected indices
:param mean_stds: array of shape (4, M, N)
:param rng: random number generator for the rupture
:returns: a 32 bit array of shape (N, M, E)
"""
# sets self.eps
M = len(self.imts)
mask = numpy.isin(self.rlz, rlzs)
E = mask.sum()
E = len(idxs)
result = numpy.zeros(
(len(self.imts), len(self.ctx.sids), E), F32)
ccdist = self.cross_correl.distribution
# build arrays of random numbers of shape (M, N, E) and (M, E)
intra_eps = [ccdist.rvs((self.N, E), rng) for _ in range(M)]
self.eps[mask] = self.cross_correl.get_inter_eps(self.imts, E, rng).T
self.eps[idxs] = self.cross_correl.get_inter_eps(self.imts, E, rng).T
for m, imt in enumerate(self.imts):
try:
result[m] = self._compute(
mean_stds[:, m], m, imt, gsim, intra_eps[m], mask)
mean_stds[:, m], m, imt, gsim, intra_eps[m], idxs)
except Exception as exc:
raise RuntimeError(
'(%s, %s, source_id=%r) %s: %s' %
Expand All @@ -307,7 +310,7 @@ def compute(self, gsim, rlzs, mean_stds, rng):
self.ctx.ampcode, result, self.imts, self.seed)
return result.transpose(1, 0, 2)

def _compute(self, mean_stds, m, imt, gsim, intra_eps, mask):
def _compute(self, mean_stds, m, imt, gsim, intra_eps, idxs):
# sets self.sig
im = imt.string
if self.cmaker.truncation_level <= 1E-9:
Expand All @@ -329,7 +332,7 @@ def _compute(self, mean_stds, m, imt, gsim, intra_eps, mask):

mean, sig, _, _ = mean_stds
gmf = exp(mean[:, None] + sig[:, None] * intra_eps, im!='MMI')
self.sig[mask, m] = numpy.nan
self.sig[idxs, m] = numpy.nan
else:
mean, sig, tau, phi = mean_stds
# the [:, None] is used to implement multiplication by row;
Expand All @@ -344,10 +347,10 @@ def _compute(self, mean_stds, m, imt, gsim, intra_eps, mask):
if len(intra_res.shape) == 1: # a vector
intra_res = intra_res[:, None]

inter_res = tau[:, None] * self.eps[mask, m]
inter_res = tau[:, None] * self.eps[idxs, m]
# shape (N, 1) * E => (N, E)
gmf = exp(mean[:, None] + intra_res + inter_res, im!='MMI')
self.sig[mask, m] = tau.max() # from shape (N, 1) => scalar
self.sig[idxs, m] = tau.max() # from shape (N, 1) => scalar
return gmf # shapes (N, E)


Expand Down