Skip to content

Commit 587cd23

Browse files
committed
Reimplemented station_correction function without altering the frequency range of the original spectrum, neither in linear space nor in logarithmic space.
1 parent ce7ed54 commit 587cd23

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

sourcespec/ssp_correction.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def station_correction(spec_st, config):
5757
----------
5858
spec_st : SpectrumStream or list of Spectrum
5959
List of spectra to be corrected. Corrected spectra are appended
60-
to the list.
60+
to the list (component code of uncorrected spectra is renamed to 'h').
6161
config : Config
6262
Configuration object containing the residuals file path.
6363
"""
@@ -76,15 +76,20 @@ def station_correction(spec_st, config):
7676
corr = residual.select(id=spec.id)[0]
7777
except IndexError:
7878
continue
79-
# Define a common frequency range for the correction and the spectrum
79+
# Define common frequency range for the correction and the spectrum
8080
freq_min = max(spec.freq.min(), corr.freq.min())
8181
freq_max = min(spec.freq.max(), corr.freq.max())
82-
delta_f = spec.stats.delta
83-
freq = np.arange(freq_min, freq_max, delta_f)
84-
# Interpolate residual to the common frequency range
85-
corr_interp = _interpolate_spectrum_to_new_freq_range(corr, freq)
86-
# Interpolate original spectrum before correction
87-
spec_corr = _interpolate_spectrum_to_new_freq_range(spec, freq)
82+
# Note that frequency range of corrected spectrum must not change,
83+
# otherwise it will be out of sync with the noise spectrum
84+
# and with the weight used in the inversion
85+
# Instead, we use NaN values outside the common frequency range
86+
# Interpolate residual to frequency range of spectrum,
87+
# and set it to NaN outside the common frequency range
88+
corr_interp = _interpolate_spectrum_to_new_freq_range(corr, spec.freq)
89+
corr_interp.data_mag[corr_interp.freq < freq_min] = np.nan
90+
corr_interp.data_mag[corr_interp.freq > freq_max] = np.nan
91+
# Copy spectrum before correction
92+
spec_corr = spec.copy()
8893
# Uncorrected spectrum will have component name 'h',
8994
# while corrected spectrum will have component name 'H'
9095
spec.stats.channel = f'{spec.stats.channel[:-1]}h'
@@ -95,18 +100,18 @@ def station_correction(spec_st, config):
95100
logger.error(f'Cannot correct spectrum {spec.id}: {msg}')
96101
continue
97102
# Interpolate the corrected data_mag to logspaced frequencies
98-
# Note that spec_corr.freq_logspaced must not change, otherwise
99-
# it will be out of sync with the weight used in the inversion.
100-
# Instead, we set it to NaN outside the valid frequency range,
101-
# through the parameter bounds_error=False.
102-
f = interp1d(spec_corr.freq, spec_corr.data_mag, bounds_error=False)
103+
# We don't allow extrapolation, to make sure logspaced spectrum
104+
# is also NaN outside the common frequency range
105+
nan_idxs = np.isnan(spec_corr.data_mag)
106+
f = interp1d(spec_corr.freq[~nan_idxs], spec_corr.data_mag[~nan_idxs],
107+
bounds_error=False)
103108
spec_corr.data_mag_logspaced = f(spec_corr.freq_logspaced)
104109
# Convert mag to moment
105110
spec_corr.data = mag_to_moment(spec_corr.data_mag)
106111
spec_corr.data_logspaced = mag_to_moment(spec_corr.data_mag_logspaced)
107112
spec_st.append(spec_corr)
108-
fmin = freq.min()
109-
fmax = freq.max()
113+
fmin = spec_corr.freq[~nan_idxs].min()
114+
fmax = spec_corr.freq[~nan_idxs].max()
110115
logger.info(
111116
f'{spec_corr.id}: corrected, frequency range is: '
112117
f'{fmin:.2f} {fmax:.2f} Hz')

0 commit comments

Comments
 (0)