Skip to content

Commit 7f06339

Browse files
authored
Merge pull request #9099 from gem/cond_gmfs
Removed duplication in the ConditionedGmfComputer
2 parents 31f7e8d + b9a89e6 commit 7f06339

File tree

2 files changed

+60
-96
lines changed

2 files changed

+60
-96
lines changed

openquake/hazardlib/calc/conditioned_gmfs.py

Lines changed: 3 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,12 @@ def compute_all(self, dstore, sig_eps=None, max_iml=None,
228228
"""
229229
:returns: (dict with fields eid, sid, gmv_X, ...), dt
230230
"""
231-
min_iml = self.cmaker.min_iml
232231
rlzs_by_gsim = self.cmaker.gsims
233232
rlzs = numpy.concatenate(list(rlzs_by_gsim.values()))
234233
eid_, rlz_ = get_eid_rlz(vars(self.ebrupture), rlzs, scenario=True)
235-
mag = self.ebrupture.rupture.mag
236234
data = AccumDict(accum=[])
237235
rng = numpy.random.default_rng(self.seed)
238236
# NB: ms is a dictionary gsim -> [imt -> array]
239-
sids = dstore['conditioned/sids'][:]
240237
for g, (gsim, rlzs) in enumerate(rlzs_by_gsim.items()):
241238
with mon1:
242239
mea = dstore['conditioned/gsim_%d/mea' % g][:]
@@ -245,51 +242,9 @@ def compute_all(self, dstore, sig_eps=None, max_iml=None,
245242
with mon2:
246243
array, sig, eps = self.compute(
247244
gsim, self.num_events, mea, tau, phi, rng)
248-
M, N, E = array.shape # sig and eps have shapes (M, E) instead
249-
assert len(sids) == N, (len(sids), N)
250-
251-
# manage max_iml
252-
if max_iml is not None:
253-
for m, im in enumerate(self.cmaker.imtls):
254-
if (array[m] > max_iml[m]).any():
255-
for n in range(N):
256-
bad = array[m, n] > max_iml[m] # shape E
257-
mean = mea[m] # shape (N, 1)
258-
array[m, n, bad] = exp(mean[n, 0], im)
259-
260-
# manage min_iml
261-
for n in range(N):
262-
for e in range(E):
263-
if (array[:, n, e] < min_iml).all():
264-
array[:, n, e] = 0
265-
array = array.transpose(1, 0, 2) # from M, N, E to N, M, E
266-
n = 0
267-
for rlz in rlzs:
268-
eids = eid_[rlz_ == rlz]
269-
for ei, eid in enumerate(eids):
270-
gmfa = array[:, :, n + ei] # shape (N, M)
271-
if sig_eps is not None:
272-
tup = tuple([eid, rlz] + list(sig[:, n + ei]) +
273-
list(eps[:, n + ei]))
274-
sig_eps.append(tup)
275-
items = []
276-
for sp in self.sec_perils:
277-
o = sp.compute(mag, zip(self.imts, gmfa.T), self.ctx)
278-
for outkey, outarr in zip(sp.outputs, o):
279-
items.append((outkey, outarr))
280-
for i, gmv in enumerate(gmfa):
281-
if gmv.sum() == 0:
282-
continue
283-
data["sid"].append(sids[i])
284-
data["eid"].append(eid)
285-
data["rlz"].append(rlz) # used in compute_gmfs_curves
286-
for m in range(M):
287-
data[f"gmv_{m}"].append(gmv[m])
288-
for outkey, outarr in items:
289-
data[outkey].append(outarr[i])
290-
# gmv can be zero due to the minimum_intensity, coming
291-
# from the job.ini or from the vulnerability functions
292-
n += len(eids)
245+
self.update(data, array, sig, eps, eid_, rlz_, rlzs,
246+
[mea, tau+phi, tau, phi], sig_eps, max_iml)
247+
293248
return pandas.DataFrame(data)
294249

295250
def compute(self, gsim, num_events, mea, tau, phi, rng):

openquake/hazardlib/calc/gmf.py

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def exp(vals, imt):
5858
return numpy.exp(vals)
5959

6060

61+
6162
class GmfComputer(object):
6263
"""
6364
Given an earthquake rupture, the ground motion field computer computes
@@ -132,16 +133,66 @@ def __init__(self, rupture, sitecol, cmaker, correlation_model=None,
132133
self.cross_correl = cross_correl or NoCrossCorrelation(
133134
cmaker.truncation_level)
134135

136+
def update(self, data, array, sig, eps, eid_, rlz_, rlzs,
137+
mean_stds, sig_eps, max_iml):
138+
sids = self.ctx.sids
139+
min_iml = self.cmaker.min_iml
140+
mag = self.ebrupture.rupture.mag
141+
M, N, E = array.shape # sig and eps have shapes (M, E) instead
142+
143+
# manage max_iml
144+
if max_iml is not None:
145+
for m, im in enumerate(self.cmaker.imtls):
146+
if (array[m] > max_iml[m]).any():
147+
for n in range(N):
148+
bad = array[m, n] > max_iml[m] # shape E
149+
mean = mean_stds[0][m, n]
150+
if len(mean.shape) == 2: # conditioned GMFs
151+
mean = mean[:, 0] # shape (N, 1)
152+
array[m, n, bad] = exp(mean, im)
153+
154+
# manage min_iml
155+
for n in range(N):
156+
for e in range(E):
157+
if (array[:, n, e] < min_iml).all():
158+
array[:, n, e] = 0
159+
160+
array = array.transpose(1, 0, 2) # from M, N, E to N, M, E
161+
n = 0
162+
for rlz in rlzs:
163+
eids = eid_[rlz_ == rlz]
164+
for ei, eid in enumerate(eids):
165+
gmfa = array[:, :, n + ei] # shape (N, M)
166+
if sig_eps is not None:
167+
tup = tuple([eid, rlz] + list(sig[:, n + ei]) +
168+
list(eps[:, n + ei]))
169+
sig_eps.append(tup)
170+
items = []
171+
for sp in self.sec_perils:
172+
o = sp.compute(mag, zip(self.imts, gmfa.T), self.ctx)
173+
for outkey, outarr in zip(sp.outputs, o):
174+
items.append((outkey, outarr))
175+
for i, gmv in enumerate(gmfa):
176+
if gmv.sum() == 0:
177+
continue
178+
data['sid'].append(sids[i])
179+
data['eid'].append(eid)
180+
data['rlz'].append(rlz) # used in compute_gmfs_curves
181+
for m in range(M):
182+
data[f'gmv_{m}'].append(gmv[m])
183+
for outkey, outarr in items:
184+
data[outkey].append(outarr[i])
185+
# gmv can be zero due to the minimum_intensity, coming
186+
# from the job.ini or from the vulnerability functions
187+
n += len(eids)
188+
135189
def compute_all(self, scenario, sig_eps=None, max_iml=None, mon=Monitor()):
136190
"""
137191
:returns: DataFrame with fields eid, rlz, sid, gmv_X, ...
138192
"""
139-
min_iml = self.cmaker.min_iml
140193
rlzs_by_gsim = self.cmaker.gsims
141-
sids = self.ctx.sids
142194
rlzs = numpy.concatenate(list(rlzs_by_gsim.values()))
143195
eid_, rlz_ = get_eid_rlz(vars(self.ebrupture), rlzs, scenario)
144-
mag = self.ebrupture.rupture.mag
145196
data = AccumDict(accum=[])
146197
mean_stds = self.cmaker.get_mean_stds([self.ctx]) # (4, G, M, N)
147198
rng = numpy.random.default_rng(self.seed)
@@ -155,51 +206,9 @@ def compute_all(self, scenario, sig_eps=None, max_iml=None, mon=Monitor()):
155206
with mon:
156207
array, sig, eps = self.compute(
157208
gs, num_events, mean_stds[:, g], rng)
158-
M, N, E = array.shape # sig and eps have shapes (M, E) instead
159-
160-
# manage max_iml
161-
if max_iml is not None:
162-
for m, im in enumerate(self.cmaker.imtls):
163-
if (array[m] > max_iml[m]).any():
164-
for n in range(N):
165-
bad = array[m, n] > max_iml[m] # shape E
166-
array[m, n, bad] = exp(
167-
mean_stds[0, g, m, n], im)
168-
169-
# manage min_iml
170-
for n in range(N):
171-
for e in range(E):
172-
if (array[:, n, e] < min_iml).all():
173-
array[:, n, e] = 0
174-
175-
array = array.transpose(1, 0, 2) # from M, N, E to N, M, E
176-
n = 0
177-
for rlz in rlzs:
178-
eids = eid_[rlz_ == rlz]
179-
for ei, eid in enumerate(eids):
180-
gmfa = array[:, :, n + ei] # shape (N, M)
181-
if sig_eps is not None:
182-
tup = tuple([eid, rlz] + list(sig[:, n + ei]) +
183-
list(eps[:, n + ei]))
184-
sig_eps.append(tup)
185-
items = []
186-
for sp in self.sec_perils:
187-
o = sp.compute(mag, zip(self.imts, gmfa.T), self.ctx)
188-
for outkey, outarr in zip(sp.outputs, o):
189-
items.append((outkey, outarr))
190-
for i, gmv in enumerate(gmfa):
191-
if gmv.sum() == 0:
192-
continue
193-
data['sid'].append(sids[i])
194-
data['eid'].append(eid)
195-
data['rlz'].append(rlz) # used in compute_gmfs_curves
196-
for m in range(M):
197-
data[f'gmv_{m}'].append(gmv[m])
198-
for outkey, outarr in items:
199-
data[outkey].append(outarr[i])
200-
# gmv can be zero due to the minimum_intensity, coming
201-
# from the job.ini or from the vulnerability functions
202-
n += len(eids)
209+
self.update(data, array, sig, eps, eid_, rlz_, rlzs,
210+
mean_stds[:, g], sig_eps, max_iml)
211+
203212
for key, val in sorted(data.items()):
204213
if key in 'eid sid rlz':
205214
data[key] = U32(data[key])

0 commit comments

Comments
 (0)