PPSD spectrogram time restrictions

Dear all,

I have a big .npz file including previous PPSD calculations. I want to restrict the days to a specific time range and plot the spectrogram with PPSD.plot_spectrogram().

For instance:

from obspy.signal import PPSD
from obspy.core import UTCDateTime

start = UTCDateTime("2022-04-01")
end = UTCDateTime("2022-04-05")

ppsd = PPSD.load_npz("data.npz")
ppsd.calculate_histogram(starttime=start, endtime=end)
ppsd.plot_spectrogram()

This does not plot the spectrogram within the set time range. There is no temporal restrictions option within the plot_spectrogram() like the plot_temporal().

Could you please help me to find a solution?

Thank you,

Korhan

I can think about the following options…

1. short term / quick fix

After loading in your npz, you can modify the data yourself, i.e. get rid of unwanted portions. You would want to modify ppsd._binned_psds and ppsd._times_processed. Both are just plain lists, so you need to make sure to modify them in the exact same way, or your data timestamping will be wrong when plotted.
From a quick look at the code, you should be able to use ppsd._stack_selection() for this purpose to create a yes/no mask.

from obspy import UTCDateTime
from obspy.signal.tests.test_spectral_estimation import _get_ppsd
ppsd = _get_ppsd()
starttime = UTCDateTime("2011-03-31T00:10:00")
endtime = UTCDateTime("2011-03-31T01:20:00")
mask = ppsd._stack_selection(starttime=starttime, endtime=endtime)
ppsd._times_processed = [t for i, t in enumerate(ppsd._times_processed) if mask[i]]
ppsd._binned_psds = [t for i, t in enumerate(ppsd._binned_psds) if mask[i]]
ppsd.plot_spectrogram()

If you want to avoid loading the npz over and over for different stacks, you could make backups of those two variables before cropping them.

Just be aware that private methods (starting with an underscore) are not guaranteed to stay as is and might get changed without notice.

2. mid term

You could subclass PPSD and add the above programmatically into plot_spectrogram, just overwriting that one routine, similar to how it is done in plot_temporal.

from obspy import PPSD

class MyPPSD(PPSD):
    def plot_spectrogram(...., **temporal_restrictions):
        ...
        if temporal_restrictions:
            ...
        else:
            ...
        ...

3. long term

You could add this change to obspy code and make a pull request :wink:

Just tried the quick fix and it works like a charm. Thank you @megies for the solution and further ideas. :smile:

1 Like