@@ -209,16 +209,29 @@ def _displacement_to_moment(stats, config):
209
209
return coeff
210
210
211
211
212
- def _smooth_spectrum (spec , npts = 5 ):
213
- """Smooth spectrum in a log_freq space."""
212
+ def _smooth_spectrum (spec , smooth_width_decades = 0.2 ):
213
+ """Smooth spectrum in a log10-freq space."""
214
+ # 1. Generate log10-spaced frequencies
214
215
freq = spec .get_freq ()
215
- f = interp1d (freq , spec .data , fill_value = 'extrapolate' )
216
- freq_log = np .logspace (np .log10 (freq [0 ]), np .log10 (freq [- 1 ]))
216
+ _log_freq = np .log10 (freq )
217
+ # frequencies in logarithmic spacing
218
+ freq_log = np .logspace (_log_freq [0 ], _log_freq [- 1 ], len (_log_freq ))
217
219
spec .freq_log = freq_log
218
- spec .data_log = f (freq_log )
219
- spec .data_log = smooth (spec .data_log , window_len = npts )
220
+ # 2. Reinterpolate data using log10 frequencies
221
+ # make sure that extrapolation does not create negative values
222
+ f = interp1d (freq , spec .data , fill_value = 'extrapolate' )
223
+ _data_log = f (freq_log )
224
+ _data_log [_data_log <= 0 ] = np .min (spec .data )
225
+ # 3. Smooth log10-spaced data points
226
+ log_df = np .log10 (freq_log [1 ]) - np .log10 (freq_log [0 ])
227
+ npts = max (1 , int (round (smooth_width_decades / log_df )))
228
+ spec .data_log = smooth (_data_log , window_len = npts )
229
+ # 4. Reinterpolate to linear frequencies
230
+ # make sure that extrapolation does not create negative values
220
231
f = interp1d (freq_log , spec .data_log , fill_value = 'extrapolate' )
221
- spec .data = f (freq )
232
+ _data = f (freq )
233
+ _data [_data <= 0 ] = np .min (spec .data )
234
+ spec .data = _data
222
235
223
236
224
237
def _build_spectrum (config , trace ):
@@ -246,11 +259,11 @@ def _build_spectrum(config, trace):
246
259
# for radiated_energy()
247
260
spec .coeff = coeff
248
261
# smooth
249
- _smooth_spectrum (spec , npts = 5 )
262
+ _smooth_spectrum (spec , config . spectral_smooth_width_decades )
250
263
return spec
251
264
252
265
253
- def _build_weight (spec , specnoise ):
266
+ def _build_weight (config , spec , specnoise ):
254
267
weight = spec .copy ()
255
268
if specnoise is not None :
256
269
weight .data /= specnoise .data
@@ -259,7 +272,8 @@ def _build_weight(spec, specnoise):
259
272
# The inversion is done in magnitude units,
260
273
# so let's take log10 of weight
261
274
weight .data = np .log10 (weight .data )
262
- _smooth_spectrum (weight , npts = 11 )
275
+ # Weight spectrum is smoothed once more
276
+ _smooth_spectrum (weight , config .spectral_smooth_width_decades )
263
277
weight .data /= np .max (weight .data )
264
278
# slightly taper weight at low frequencies, to avoid overestimating
265
279
# weight at low frequencies, in cases where noise is underestimated
@@ -277,7 +291,7 @@ def _build_weight(spec, specnoise):
277
291
return weight
278
292
279
293
280
- def _build_weight_st (spec_st , specnoise_st ):
294
+ def _build_weight_st (config , spec_st , specnoise_st ):
281
295
"""Build the weight spectrum."""
282
296
weight_st = Stream ()
283
297
spec_ids = set (sp .id [:- 1 ] for sp in spec_st if not sp .stats .ignore )
@@ -287,7 +301,7 @@ def _build_weight_st(spec_st, specnoise_st):
287
301
specnoise_h = _select_spectra (specnoise_st , specid + 'H' )[0 ]
288
302
except Exception :
289
303
continue
290
- weight = _build_weight (spec_h , specnoise_h )
304
+ weight = _build_weight (config , spec_h , specnoise_h )
291
305
weight_st .append (weight )
292
306
return weight_st
293
307
@@ -323,7 +337,7 @@ def _build_H(spec_st, specnoise_st=None, wave_type='S'):
323
337
324
338
325
339
def _check_spectral_sn_ratio (config , spec , specnoise ):
326
- weight = _build_weight (spec , specnoise )
340
+ weight = _build_weight (config , spec , specnoise )
327
341
if config .spectral_sn_freq_range is not None :
328
342
sn_fmin , sn_fmax = config .spectral_sn_freq_range
329
343
freqs = weight .get_freq ()
@@ -396,7 +410,7 @@ def build_spectra(config, st):
396
410
spec_st = station_correction (spec_st , config )
397
411
398
412
# build the weight spectrum
399
- weight_st = _build_weight_st (spec_st , specnoise_st )
413
+ weight_st = _build_weight_st (config , spec_st , specnoise_st )
400
414
401
415
logger .info ('Building spectra: done' )
402
416
if config .weighting == 'noise' :
0 commit comments