@@ -58,6 +58,7 @@ def exp(vals, imt):
5858 return numpy .exp (vals )
5959
6060
61+
6162class 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