Note

このページは Jupyter Notebook から生成されました。 ノートブックをダウンロード (.ipynb)

SpectrogramList と SpectrogramDict のチュートリアル

Open In Colab

このノートブックでは、gwexpy で新しく導入された SpectrogramList および SpectrogramDict クラスの使い方を紹介します。

これらのクラスは、複数のスペクトログラムデータ(gwpy.spectrogram.Spectrogram)をまとめて管理し、一括して処理(クロップ、再ビン化、プロットなど)を行うためのコンテナです。 時系列データを扱う TimeSeriesList / TimeSeriesDict と似たインターフェースを持っていますが、2次元データ(時間 × 周波数)を扱う点が特徴です。

[1]:
import matplotlib.pyplot as plt

from gwexpy.noise.wave import gaussian, sine
from gwexpy.spectrogram import SpectrogramDict, SpectrogramList

1. データの準備

まずはデモ用のスペクトログラムデータを作成します。 ここでは、異なる周波数のサイン波を含む時系列データを生成し、それを spectrogram() メソッドで変換して使用します。

[2]:
# SampleData Create
duration = 20 # seconds
sample_rate = 128 # Hz

# 10Hz, 30Hz, 50Hz (+Noise) Create
noise_amp = 0.1


def make_signal(freq, name):
    s = sine(duration=duration, sample_rate=sample_rate, frequency=freq, amplitude=1.0)
    n = gaussian(duration=duration, sample_rate=sample_rate, std=noise_amp)
    ts = s + n
    ts.name = name
    ts.override_unit("strain")
    return ts


ts1 = make_signal(10, "Signal 10Hz")
ts2 = make_signal(30, "Signal 30Hz")
ts3 = make_signal(50, "Signal 50Hz")

# Calculate (stride=2s, fftlength=1s)
# nproc=1 Runby
spec1 = ts1.spectrogram(2, fftlength=1, overlap=0.5, nproc=1)
spec2 = ts2.spectrogram(2, fftlength=1, overlap=0.5, nproc=1)
spec3 = ts3.spectrogram(2, fftlength=1, overlap=0.5, nproc=1)

print("Spectrogram shape:", spec1.shape)
print("Time range:", spec1.xspan)
print("Freq range:", spec1.yspan)
Spectrogram shape: (10, 65)
Time range: [0.0 ... 20.0)
Freq range: [0.0 ... 65.0)

2. SpectrogramList の基本操作

SpectrogramList はリストのように振る舞いますが、格納できるのは Spectrogram オブジェクトのみです。 初期化時にリストを渡すか、append() メソッドで追加します。

[3]:
# List Create
spec_list = SpectrogramList([spec1, spec2])

#
spec_list.append(spec3)

print(f"List length: {len(spec_list)}")
print(f"Items: {[s.name for s in spec_list]}")
List length: 3
Items: ['Signal 10Hz', 'Signal 30Hz', 'Signal 50Hz']

バッチ処理: 時間軸の切り出し (crop)

リスト内のすべてのスペクトログラムに対して、一括で時間軸の切り出しを行います。 注意: スペクトログラムはデータ量が大きいため、クロップなどの操作は元のデータを変更せず、新しいオブジェクト(コピー)を返すことがあります。

[4]:
# 5seconds〜15seconds Range
cropped_list = spec_list.crop(5, 15)

print("Original range:", spec_list[0].xspan)
print("Cropped range:", cropped_list[0].xspan)
Original range: [0.0 ... 20.0)
Cropped range: [4.0 ... 14.0)

バッチ処理: 周波数軸の切り出し (crop_frequencies)

gwpyの Spectrogram に互換性のあるメソッドがあればそれを使用し、なければ周波数軸を指定してフィルタリングを行います。

[5]:
# 0Hz 〜 40Hz Range
freq_cropped = spec_list.crop_frequencies(0, 40)

print("Original yspan:", spec_list[0].yspan)
print("Cropped yspan:", freq_cropped[0].yspan)
# 50Hz Signal 3 Range minutes
Original yspan: [0.0 ... 65.0)
Cropped yspan: [0.0 ... 40.0)

3. SpectrogramDict の利用

名前(キー)付きで管理したい場合は SpectrogramDict が便利です。

[6]:
spec_dict = SpectrogramDict({"low_freq": spec1, "mid_freq": spec2, "high_freq": spec3})

print("Keys:", list(spec_dict.keys()))
Keys: ['low_freq', 'mid_freq', 'high_freq']

4. 可視化 (plot)

リストや辞書の .plot() メソッドを呼ぶと、含まれるすべてのスペクトログラムをまとめてプロットできます。 内部では gwpy.plot.Plot を使用しています。

[7]:
# BatchPlot
# sharex=True, sharey=True do Axis Ratiocomparison
plot = spec_dict.plot(figsize=(12, 8), sharex=True, sharey=True)
plt.show()
../../../../_images/web_ja_user_guide_tutorials_intro_spectrogram_13_0.png

5. マトリックス形式への変換とDeep Learning連携

to_matrix() を使用すると、各スペクトログラムを積み重ねた 3次元配列 (Channels, Time, Frequency) を持つ SpectrogramMatrix オブジェクトを作成できます。

これは機械学習モデル(PyTorch, TensorFlowなど)への入力を作成する際に非常に便利です。

[8]:
matrix = spec_list.to_matrix()

print("Matrix Type:", type(matrix))
print("Matrix Shape:", matrix.shape)
print(" (N_channels, N_time_steps, N_freq_bins)")

#
print("Time axis shape:", matrix.times.shape)
print("Freq axis shape:", matrix.frequencies.shape)
Matrix Type: <class 'gwexpy.spectrogram.matrix.SpectrogramMatrix'>
Matrix Shape: (3, 10, 65)
 (N_channels, N_time_steps, N_freq_bins)
Time axis shape: (10,)
Freq axis shape: (65,)

PyTorchやCuPyがインストールされていれば、そのままTensor等に変換可能です。

# PyTorch Tensorへの変換
# tensor = matrix.to_torch()

まとめ

これで SpectrogramListSpectrogramDict の基本的な使い方の紹介を終わります。 大量のスペクトログラムデータを一括で前処理したり、比較プロットを行う際にぜひ活用してください。