Note
このページは Jupyter Notebook から生成されました。 ノートブックをダウンロード (.ipynb)
GWExPy TimeSeries 相互運用性 (Interop) チュートリアル
このノートブックでは、gwexpy の TimeSeries クラスに追加された新しい相互運用機能 (Interoperability Features) を紹介します。 gwexpy は、Pandas, Xarray, PyTorch, Astropy などの一般的なデータサイエンス・ライブラリとの間で、シームレスにデータを変換することができます。
目次
汎用データ形式・データ基盤
1.1. NumPy [Original GWpy]
1.2. Pandas との連携 [Original GWpy]
1.3. Polars [GWExPy New]
1.4. Xarray との連携 [Original GWpy]
1.5. Dask との連携 [GWExPy New]
1.6. JSON / Python Dict (to_json) (to_json) [GWExPy New]
データベース・ストレージ層
2.1. HDF5 [Original GWpy]
2.2. SQLite [GWExPy New]
2.3. Zarr [GWExPy New]
2.4. netCDF4 [GWExPy New]
情報科学・機械学習・加速計算
3.1. PyTorch との連携 [GWExPy New]
3.2. CuPy (CUDA 加速) [GWExPy New]
3.3. TensorFlow との連携 [GWExPy New]
3.4. JAX との連携 [GWExPy New]
天文学・重力波物理学
4.1. PyCBC / LAL [Original GWpy]
4.2. Astropy との連携 [Original GWpy]
4.3. Specutils との連携 [GWExPy New]
4.4. Pyspeckit との連携 [GWExPy New]
素粒子物理学・高エネルギー物理
5.1. CERN ROOT との連携 [GWExPy New]
5.2. ROOT オブジェクトからの復元 (
from_root)
地球物理学・地震学・電磁気学
6.1. ObsPy [Original GWpy]
6.2. SimPEG との連携 [GWExPy New]
6.3. MTH5 / MTpy [GWExPy New]
音響・音声解析
7.1. Librosa / Pydub [GWExPy New]
医学・生体信号解析
8.1. MNE-Python [GWExPy New]
8.2. Elephant / quantities との連携 [GWExPy New]
8.3. Neo [GWExPy New]
まとめ
[1]:
import os
os.environ.setdefault("TF_CPP_MIN_LOG_LEVEL", "3")
[1]:
'3'
[2]:
import logging
import warnings
import matplotlib.pyplot as plt
import numpy as np
from astropy import units as u
from gwpy.time import LIGOTimeGPS
from gwexpy.timeseries import TimeSeries
warnings.filterwarnings("ignore", "Wswiglal-redir-stdio")
warnings.filterwarnings("ignore", category=UserWarning)
# Suppress MTH5 redundant warnings
logging.getLogger("mth5.groups.base").setLevel(logging.ERROR)
logging.getLogger("mth5").setLevel(logging.ERROR)
/home/washimi/work/gwexpy/.venv-docs-exec/lib/python3.12/site-packages/gwpy/time/_ligotimegps.py:42: UserWarning: Wswiglal-redir-stdio:
SWIGLAL standard output/error redirection is enabled in IPython.
This may lead to performance penalties. To disable locally, use:
with lal.no_swig_redirect_standard_output_error():
...
To disable globally, use:
lal.swig_redirect_standard_output_error(False)
Note however that this will likely lead to error messages from
LAL functions being either misdirected or lost when called from
Jupyter notebooks.
To suppress this warning, use:
import warnings
warnings.filterwarnings("ignore", "Wswiglal-redir-stdio")
import lal
from lal import LIGOTimeGPS
[3]:
# SampleData Create
# 10seconds 、100Hz Sine waveData Generate
rate = 100 * u.Hz
dt = 1 / rate
t0 = LIGOTimeGPS(1234567890, 0)
duration = 10 * u.s
size = int(rate * duration)
times = np.arange(size) * dt.value
data = np.sin(2 * np.pi * 1.0 * times) # 1Hz sine wave
ts = TimeSeries(data, t0=t0, dt=dt, unit="V", name="demo_signal")
print("Original TimeSeries:")
print(ts)
ts.plot(title="Original TimeSeries");
Original TimeSeries:
TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: V,
t0: 1234567890.0 1 / Hz,
dt: 0.01 1 / Hz,
name: demo_signal,
channel: None)
1. 汎用データ形式・データ基盤
1.1. NumPy [Original GWpy]
NumPy: NumPy は Python の数値計算の基盤となるライブラリで、多次元配列と高速な数学演算を提供します。 📚 NumPy Documentation
TimeSeries.value や np.asarray(ts) で NumPy 配列を取得できます。
1.2. Pandas との連携 [Original GWpy]
Pandas: Pandas はデータ分析・操作のための強力なライブラリで、DataFrame と Series による柔軟なデータ構造を提供します。 📚 Pandas Documentation
to_pandas() メソッドを使うと、TimeSeries を pandas.Series に変換できます。 インデックスは datetime (UTC), gps, seconds (Unix timestamp) から選択可能です。
[4]:
try:
# Pandas Series Transform ( datetime index)
s_pd = ts.to_pandas(index="datetime")
print("\n--- Converted to Pandas Series ---")
display(s_pd)
s_pd.plot(title="Pandas Series")
plt.show()
plt.close()
# Pandas Series from TimeSeries
ts_restored = TimeSeries.from_pandas(s_pd, unit="V")
print("\n--- Restored TimeSeries from Pandas ---")
print(ts_restored)
del s_pd, ts_restored
except ImportError:
print("Pandas is not installed.")
--- Converted to Pandas Series ---
time_utc
2019-02-18 23:31:49+00:00 0.000000
2019-02-18 23:31:49.010000+00:00 0.062791
2019-02-18 23:31:49.020000+00:00 0.125333
2019-02-18 23:31:49.030000+00:00 0.187381
2019-02-18 23:31:49.040000+00:00 0.248690
...
2019-02-18 23:31:58.949991+00:00 -0.309017
2019-02-18 23:31:58.959991+00:00 -0.248690
2019-02-18 23:31:58.969990+00:00 -0.187381
2019-02-18 23:31:58.979990+00:00 -0.125333
2019-02-18 23:31:58.989990+00:00 -0.062791
Name: demo_signal, Length: 1000, dtype: float64
--- Restored TimeSeries from Pandas ---
TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: V,
t0: 1234567927.0 s,
dt: 0.009999990463256836 s,
name: demo_signal,
channel: None)
1.3. Polars [GWExPy New]
Polars: Polars は Rust で実装された高速な DataFrame ライブラリで、大規模データの高速処理に優れています。 📚 Polars Documentation
to_polars() で Polars DataFrame/Series に変換できます。
[5]:
try:
import polars as pl
_ = pl
# TimeSeries -> Polars DataFrame
df_pl = ts.to_polars()
print("--- Polars DataFrame ---")
print(df_pl.head())
# Plot using Polars/Matplotlib
plt.figure()
data_col = [c for c in df_pl.columns if c != "time"][0]
plt.plot(df_pl["time"], df_pl[data_col])
plt.title("Polars Data Plot")
plt.show()
# Recover to TimeSeries
from gwexpy.timeseries import TimeSeries
ts_recovered = TimeSeries.from_polars(df_pl)
print("Recovered from Polars:", ts_recovered)
del df_pl, ts_recovered
except ImportError:
print("Polars not installed.")
--- Polars DataFrame ---
shape: (5, 2)
┌────────────────────────────┬─────────────┐
│ time ┆ demo_signal │
│ --- ┆ --- │
│ object ┆ f64 │
╞════════════════════════════╪═════════════╡
│ 2019-02-18 23:31:12 ┆ 0.0 │
│ 2019-02-18 23:31:12.010000 ┆ 0.062791 │
│ 2019-02-18 23:31:12.020000 ┆ 0.125333 │
│ 2019-02-18 23:31:12.030000 ┆ 0.187381 │
│ 2019-02-18 23:31:12.040000 ┆ 0.24869 │
└────────────────────────────┴─────────────┘
Recovered from Polars: TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: dimensionless,
t0: 1234567890.0 s,
dt: None,
name: demo_signal,
channel: None)
1.4. Xarray との連携 [Original GWpy]
xarray: xarray は多次元ラベル付き配列のためのライブラリで、NetCDF データの操作や気象・地球科学データの解析に広く使用されます。 📚 xarray Documentation
xarray は多次元のラベル付き配列を扱う強力なライブラリです。to_xarray() でメタデータを保持したまま変換できます。
[6]:
try:
# Xarray DataArray Transform
da = ts.to_xarray()
print("\n--- Converted to Xarray DataArray ---")
print(da)
# Data (attrs) Verify
print("Attributes:", da.attrs)
da.plot()
plt.title("Xarray DataArray")
plt.show()
plt.close()
#
ts_x = TimeSeries.from_xarray(da)
print("\n--- Restored TimeSeries from Xarray ---")
print(ts_x)
del da, ts_x
except ImportError:
print("Xarray is not installed.")
--- Converted to Xarray DataArray ---
<xarray.DataArray 'demo_signal' (time: 1000)> Size: 8kB
array([ 0. , 0.06279052, 0.12533323, ..., -0.18738131,
-0.12533323, -0.06279052], shape=(1000,))
Coordinates:
* time (time) datetime64[us] 8kB 2019-02-18T23:31:49 ... 2019-02-18T23:...
Attributes:
unit: V
name: demo_signal
channel: None
epoch: 1234567890.0
time_coord: datetime
Attributes: {'unit': 'V', 'name': 'demo_signal', 'channel': 'None', 'epoch': 1234567890.0, 'time_coord': 'datetime'}
--- Restored TimeSeries from Xarray ---
TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: V,
t0: 1234567927.0 s,
dt: 0.009999990463256836 s,
name: demo_signal,
channel: None)
1.5. Dask との連携 [GWExPy New]
Dask: Dask は並列計算のためのライブラリで、NumPy/Pandas を超える大規模データの処理を可能にします。 📚 Dask Documentation
[7]:
try:
import dask.array as da
_ = da
# Dask Array Transform
dask_arr = ts.to_dask(chunks="auto")
print("\n--- Converted to Dask Array ---")
print(dask_arr)
# (compute=True )
ts_from_dask = TimeSeries.from_dask(dask_arr, t0=ts.t0, dt=ts.dt, unit=ts.unit)
print("Recovered from Dask:", ts_from_dask)
del dask_arr, ts_from_dask
except ImportError:
print("Dask not installed.")
--- Converted to Dask Array ---
dask.array<array, shape=(1000,), dtype=float64, chunksize=(1000,), chunktype=numpy.ndarray>
Recovered from Dask: TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: V,
t0: 1234567890.0 1 / Hz,
dt: 0.01 1 / Hz,
name: None,
channel: None)
1.6. JSON / Python Dict (to_json) [GWExPy New]
JSON: JSON (JavaScript Object Notation) は軽量なデータ交換フォーマットで、Python 標準ライブラリでサポートされています。 📚 JSON Documentation
to_json() や to_dict() で JSON 互換の辞書形式を出力できます。
[8]:
import json
# TimeSeries -> JSON string
ts_json = ts.to_json()
print("--- JSON Representation (Partial) ---")
print(ts_json[:500] + "...")
# Plot data by loading back from JSON
ts_dict_temp = json.loads(ts_json)
plt.figure()
plt.plot(ts_dict_temp["data"])
plt.title("Plot from JSON Data")
plt.show()
# Recover from JSON
from gwexpy.timeseries import TimeSeries
ts_recovered = TimeSeries.from_json(ts_json)
print("Recovered from JSON:", ts_recovered)
del ts_json, ts_dict_temp, ts_recovered
--- JSON Representation (Partial) ---
{
"t0": 1234567890.0,
"dt": 0.01,
"unit": "V",
"name": "demo_signal",
"data": [
0.0,
0.06279051952931337,
0.12533323356430426,
0.1873813145857246,
0.2486898871648548,
0.3090169943749474,
0.3681245526846779,
0.4257792915650727,
0.4817536741017153,
0.5358267949789967,
0.5877852522924731,
0.6374239897486896,
0.6845471059286886,
0.7289686274214116,
0.7705132427757893,
0.8090169943749475,
0.8443279255020151,
0.876306680...
Recovered from JSON: TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: V,
t0: 1234567890.0 s,
dt: 0.01 s,
name: demo_signal,
channel: None)
2. データベース・ストレージ層
2.1. HDF5 [Original GWpy]
HDF5: HDF5 は大規模な科学データを効率的に保存・管理するための階層型データフォーマットです。h5py ライブラリで Python から利用できます。 📚 HDF5 Documentation
to_hdf5_dataset() で HDF5 への保存をサポート。
[9]:
try:
import tempfile
import h5py
with tempfile.NamedTemporaryFile(suffix=".h5") as tmp:
# TimeSeries -> HDF5
with h5py.File(tmp.name, "w") as f:
ts.to_hdf5_dataset(f, "dataset_01")
# Read back and display
with h5py.File(tmp.name, "r") as f:
ds = f["dataset_01"]
print("--- HDF5 Dataset Info ---")
print(f"Shape: {ds.shape}, Dtype: {ds.dtype}")
print("Attributes:", dict(ds.attrs))
# Recover
from gwexpy.timeseries import TimeSeries
ts_recovered = TimeSeries.from_hdf5_dataset(f, "dataset_01")
print("Recovered from HDF5:", ts_recovered)
ts_recovered.plot()
plt.title("Recovered from HDF5")
plt.show()
del ds, ts_recovered
except ImportError:
print("h5py not installed.")
--- HDF5 Dataset Info ---
Shape: (1000,), Dtype: float64
Attributes: {'dt': np.float64(0.01), 'name': 'demo_signal', 't0': np.float64(1234567890.0), 'unit': 'V'}
Recovered from HDF5: TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: V,
t0: 1234567890.0 s,
dt: 0.01 s,
name: demo_signal,
channel: None)
2.2. SQLite [GWExPy New]
SQLite: SQLite は軽量な組み込み型 SQL データベースエンジンで、Python 標準ライブラリに含まれています。 📚 SQLite Documentation
to_sqlite() で DB 永続化をサポート。
[10]:
import sqlite3
conn = sqlite3.connect(":memory:")
# TimeSeries -> SQLite
series_id = ts.to_sqlite(conn, series_id="test_series")
print(f"Saved to SQLite with ID: {series_id}")
# Verify data in SQL
cursor = conn.cursor()
row = cursor.execute("SELECT * FROM series WHERE series_id=?", (series_id,)).fetchone()
print("Metadata from SQL:", row)
# Recover
from gwexpy.timeseries import TimeSeries
ts_recovered = TimeSeries.from_sqlite(conn, series_id)
print("Recovered from SQLite:", ts_recovered)
ts_recovered.plot()
plt.title("Recovered from SQLite")
plt.show()
del series_id, conn, cursor, ts_recovered
Saved to SQLite with ID: test_series
Metadata from SQL: ('test_series', '', 'V', 1234567890.0, 0.01, 1000, '{"name": "demo_signal"}')
Recovered from SQLite: TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: V,
t0: 1234567890.0 s,
dt: 0.01 s,
name: test_series,
channel: None)
2.3. Zarr [GWExPy New]
Zarr: Zarr はチャンク化・圧縮された多次元配列のためのストレージフォーマットで、クラウドストレージとの連携に優れています。 📚 Zarr Documentation
to_zarr() でクラウドストレージ向き形式に対応。
[11]:
try:
import os
import tempfile
import zarr
with tempfile.TemporaryDirectory() as tmpdir:
store_path = os.path.join(tmpdir, "test.zarr")
# TimeSeries -> Zarr
ts.to_zarr(store_path, path="timeseries")
# Read back
z = zarr.open(store_path, mode="r")
ds = z["timeseries"]
print("--- Zarr Array Info ---")
print(ds.info)
# Recover
from gwexpy.timeseries import TimeSeries
ts_recovered = TimeSeries.from_zarr(store_path, "timeseries")
print("Recovered from Zarr:", ts_recovered)
ts_recovered.plot()
plt.title("Recovered from Zarr")
plt.show()
del z, ds, ts_recovered
except ImportError:
print("zarr not installed.")
--- Zarr Array Info ---
Type : Array
Zarr format : 3
Data type : Float64(endianness='little')
Fill value : 0.0
Shape : (1000,)
Chunk shape : (1000,)
Order : C
Read-only : True
Store type : LocalStore
Filters : ()
Serializer : BytesCodec(endian=<Endian.little: 'little'>)
Compressors : (ZstdCodec(level=0, checksum=False),)
No. bytes : 8000 (7.8K)
Recovered from Zarr: TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: V,
t0: 1234567890.0 s,
dt: 0.01 s,
name: demo_signal,
channel: None)
2.4. netCDF4 [GWExPy New]
netCDF4: netCDF4 は気象・海洋・地球科学データの標準フォーマットで、自己記述的なデータ構造を持ちます。 📚 netCDF4 Documentation
to_netcdf4() で気象・海洋データの標準に対応。
[12]:
try:
import tempfile
from pathlib import Path
import netCDF4
with tempfile.TemporaryDirectory() as tmpdir:
path = Path(tmpdir) / "gwexpy_timeseries.nc"
# TimeSeries -> netCDF4
with netCDF4.Dataset(path, "w", format="NETCDF3_CLASSIC") as ds:
ts.to_netcdf4(ds, "my_signal")
# Read back
with netCDF4.Dataset(path, "r") as ds:
v = ds.variables["my_signal"]
print("--- netCDF4 Variable Info ---")
print(v)
# Recover
from gwexpy.timeseries import TimeSeries
ts_recovered = TimeSeries.from_netcdf4(ds, "my_signal")
print("Recovered from netCDF4:", ts_recovered)
ts_recovered.plot()
plt.title("Recovered from netCDF4")
plt.show()
del v, ts_recovered
except ImportError:
print("netCDF4 not installed.")
--- netCDF4 Variable Info ---
<class 'netCDF4.Variable'>
float64 my_signal(time)
t0: 1234567890.0
dt: 0.01
units: V
long_name: demo_signal
unlimited dimensions:
current shape = (1000,)
filling on, default _FillValue of 9.969209968386869e+36 used
Recovered from netCDF4: TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: V,
t0: 1234567890.0 s,
dt: 0.01 s,
name: demo_signal,
channel: None)
3. 情報科学・機械学習・加速計算
3.1. PyTorch との連携 [GWExPy New]
PyTorch: PyTorch は深層学習フレームワークで、動的計算グラフと GPU 加速をサポートします。 📚 PyTorch Documentation
ディープラーニングの前処理として、TimeSeries を直接 torch.Tensor に変換できます。GPU転送も可能です。
[13]:
import os
os.environ.setdefault("TF_CPP_MIN_LOG_LEVEL", "3")
try:
import torch
# PyTorch Tensor Transform
tensor = ts.to_torch(dtype=torch.float32)
print("\n--- Converted to PyTorch Tensor ---")
print(f"Tensor shape: {tensor.shape}, dtype: {tensor.dtype}")
# Tensor from (t0, dt )
ts_torch = TimeSeries.from_torch(tensor, t0=ts.t0, dt=ts.dt, unit="V")
print("\n--- Restored from Torch ---")
print(ts_torch)
del tensor, ts_torch
except ImportError:
print("PyTorch is not installed.")
--- Converted to PyTorch Tensor ---
Tensor shape: torch.Size([1000]), dtype: torch.float32
--- Restored from Torch ---
TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: V,
t0: 1234567890.0 1 / Hz,
dt: 0.01 1 / Hz,
name: None,
channel: None)
3.2. CuPy (CUDA 加速) [GWExPy New]
CuPy: CuPy は NumPy 互換の GPU 配列ライブラリで、NVIDIA CUDA を使用した高速計算を可能にします。 📚 CuPy Documentation
GPU 上での計算を可能にする CuPy 配列へ変換できます。
[14]:
from gwexpy.interop import is_cupy_available
if is_cupy_available():
import cupy as cp
# TimeSeries -> CuPy
y_gpu = ts.to_cupy()
print("--- CuPy Array (on GPU) ---")
print(y_gpu)
# Simple processing on GPU
y_gpu_filt = y_gpu * 2.0
# Plot (must move to CPU for plotting)
plt.figure()
plt.plot(cp.asnumpy(y_gpu_filt))
plt.title("CuPy Data (Moved to CPU for plot)")
plt.show()
# Recover
from gwexpy.timeseries import TimeSeries
ts_recovered = TimeSeries.from_cupy(y_gpu_filt, t0=ts.t0, dt=ts.dt)
print("Recovered from CuPy:", ts_recovered)
del y_gpu, y_gpu_filt, ts_recovered
else:
print("CuPy or CUDA driver not available.")
CuPy or CUDA driver not available.
3.3. TensorFlow との連携 [GWExPy New]
TensorFlow: TensorFlow は Google が開発した機械学習プラットフォームで、大規模な本番環境での利用に優れています。 📚 TensorFlow Documentation
[15]:
try:
import os
import warnings
os.environ.setdefault("TF_CPP_MIN_LOG_LEVEL", "3")
warnings.filterwarnings(
"ignore", category=UserWarning, module=r"google\.protobuf\..*"
)
warnings.filterwarnings(
"ignore", category=UserWarning, message=r"Protobuf gencode version.*"
)
import tensorflow as tf
_ = tf
# TensorFlow Tensor Transform
tf_tensor = ts.to_tensorflow()
print("\n--- Converted to TensorFlow Tensor ---")
print(f"Tensor shape: {tf_tensor.shape}")
print(f"Tensor dtype: {tf_tensor.dtype}")
#
ts_from_tensorflow = TimeSeries.from_tensorflow(
tf_tensor, t0=ts.t0, dt=ts.dt, unit=ts.unit
)
print("Recovered from TF:", ts_from_tensorflow)
del tf_tensor, ts_from_tensorflow
except ImportError:
pass
3.4. JAX との連携 [GWExPy New]
JAX: JAX は Google が開発した高性能数値計算ライブラリで、自動微分と XLA コンパイルによる高速化が特徴です。 📚 JAX Documentation
[16]:
try:
import os
os.environ["XLA_PYTHON_CLIENT_PREALLOCATE"] = "false"
import jax
_ = jax
import jax.numpy as jnp
_ = jnp
# JAX Array Transform
jax_arr = ts.to_jax()
print("\n--- Converted to JAX Array ---")
print(f"Array shape: {jax_arr.shape}")
#
ts_from_jax = TimeSeries.from_jax(jax_arr, t0=ts.t0, dt=ts.dt, unit=ts.unit)
print("Recovered from JAX:", ts_from_jax)
del jax_arr, ts_from_jax
except ImportError:
print("JAX not installed.")
--- Converted to JAX Array ---
Array shape: (1000,)
Recovered from JAX: TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: V,
t0: 1234567890.0 1 / Hz,
dt: 0.01 1 / Hz,
name: None,
channel: None)
4. 天文学・重力波物理学
4.1. PyCBC / LAL [Original GWpy]
LAL: LAL (LIGO Algorithm Library) は LIGO/Virgo の公式解析ライブラリで、重力波解析の基盤を提供します。 📚 LAL Documentation
PyCBC: PyCBC は重力波データ解析のためのライブラリで、信号探索やパラメータ推定に使用されます。 📚 PyCBC Documentation
重力波解析の標準ツールとの互換性を備えています。
4.2. Astropy との連携 [Original GWpy]
Astropy: Astropy は天文学のための Python ライブラリで、座標変換、時間系変換、単位系などをサポートします。 📚 Astropy Documentation
天文学分野で標準的な astropy.timeseries.TimeSeries との相互変換もサポートしています。
[17]:
try:
# Astropy TimeSeries Transform
ap_ts = ts.to_astropy_timeseries()
print("\n--- Converted to Astropy TimeSeries ---")
print(ap_ts[:5])
fig, ax = plt.subplots()
ax.plot(ap_ts.time.jd, ap_ts["value"])
plt.title("Astropy TimeSeries")
plt.show()
plt.close()
#
ts_astro = TimeSeries.from_astropy_timeseries(ap_ts)
print("\n--- Restored from Astropy ---")
print(ts_astro)
del ap_ts, ts_astro
except ImportError:
print("Astropy is not installed.")
--- Converted to Astropy TimeSeries ---
time value
------------- -------------------
1234567890.0 0.0
1234567890.01 0.06279051952931337
1234567890.02 0.12533323356430426
1234567890.03 0.1873813145857246
1234567890.04 0.2486898871648548
--- Restored from Astropy ---
TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: dimensionless,
t0: 1234567890.0 s,
dt: 0.009999990463256836 s,
name: None,
channel: None)
4.3. Specutils との連携 [GWExPy New]
specutils: specutils は天文スペクトルデータの操作・解析のための Astropy 関連パッケージです。 📚 specutils Documentation
FrequencySeries は、Astropy エコシステムのスペクトル解析ライブラリ specutils の Spectrum1D オブジェクトと相互変換可能です。 単位 (Units) や周波数軸が適切に保持されます。
[18]:
try:
import specutils
_ = specutils
from gwexpy.frequencyseries import FrequencySeries
# FrequencySeries -> specutils.Spectrum1D
fs = FrequencySeries(
np.random.random(100), frequencies=np.linspace(10, 100, 100), unit="Jy"
)
spec = fs.to_specutils()
print("specutils Spectrum1D:", spec)
print("Spectral axis unit:", spec.spectral_axis.unit)
# specutils.Spectrum1D -> FrequencySeries
fs_rec = FrequencySeries.from_specutils(spec)
print("Restored FrequencySeries unit:", fs_rec.unit)
del fs, spec, fs_rec
except ImportError:
print("specutils library not found. Skipping example.")
specutils Spectrum1D: Spectrum (length=100)
Flux=[0.56858854 0.72891221 0.66168921 ... 0.74864585 0.83726098
0.50917497] Jy, mean=0.48529 Jy
Spectral Axis=[ 10. 10.90909091 11.81818182 ...
98.18181818 99.09090909 100. ] Hz, mean=55.00000 Hz
Spectral axis unit: Hz
Restored FrequencySeries unit: Jy
4.4. Pyspeckit との連携 [GWExPy New]
PySpecKit: PySpecKit は電波天文学のスペクトル解析ツールキットで、スペクトル線のフィッティングなどをサポートします。 📚 PySpecKit Documentation
FrequencySeries は、汎用的なスペクトル解析ツールキット pyspeckit の Spectrum オブジェクトとも連携可能です。
[19]:
try:
import pyspeckit
_ = pyspeckit
from gwexpy.frequencyseries import FrequencySeries
# FrequencySeries -> pyspeckit.Spectrum
fs = FrequencySeries(np.random.random(100), frequencies=np.linspace(10, 100, 100))
spec = fs.to_pyspeckit()
print("pyspeckit Spectrum length:", len(spec.data))
# pyspeckit.Spectrum -> FrequencySeries
fs_rec = FrequencySeries.from_pyspeckit(spec)
print("Restored FrequencySeries length:", len(fs_rec))
del fs, spec, fs_rec
except ImportError:
print("pyspeckit library not found. Skipping example.")
pyspeckit Spectrum length: 100
Restored FrequencySeries length: 100
WARNING: No header given. Creating an empty one.
5. 素粒子物理学・高エネルギー物理
5.1. CERN ROOT との連携 [GWExPy New]
ROOT: ROOT は CERN が開発した高エネルギー物理学向けのデータ解析フレームワークです。 📚 ROOT Documentation
高エネルギー物理学で標準的なツールである ROOT との相互運用が強化されました。 gwexpy の Series オブジェクトを ROOT の TGraph や TH1D, TH2D に高速に変換したり、ROOT ファイルを作成することができます。 逆に、ROOT オブジェクトから TimeSeries などを復元することも可能です。
Note: この機能を使用するには ROOT (PyROOT) がインストールされている必要があります。
[20]:
try:
import numpy as np
import ROOT
from gwexpy.timeseries import TimeSeries
# Data
t = np.linspace(0, 10, 1000)
data = np.sin(2 * np.pi * 1.0 * t) + np.random.normal(0, 0.5, size=len(t))
ts = TimeSeries(data, dt=t[1] - t[0], name="signal")
# --- 1. TGraph Transform ---
# Vector done Transform
graph = ts.to_tgraph()
# ROOT Plot
c1 = ROOT.TCanvas("c1", "TGraph Example", 800, 600)
graph.SetTitle("ROOT TGraph;GPS Time [s];Amplitude")
graph.Draw("AL")
c1.Draw()
# c1.SaveAs("signal_graph.png") # Savedo
print(f"Created TGraph: {graph.GetName()} with {graph.GetN()} points")
# --- 2. TH1D ( ) Transform ---
# Transform ( )
hist = ts.to_th1d()
c2 = ROOT.TCanvas("c2", "TH1D Example", 800, 600)
hist.SetTitle("ROOT TH1D;GPS Time [s];Amplitude")
hist.SetLineColor(ROOT.kRed)
hist.Draw()
c2.Draw()
print(f"Created TH1D: {hist.GetName()} with {hist.GetNbinsX()} bins")
del t, data, graph, hist, c1, c2
except ImportError:
pass
except Exception as e:
print(f"An error occurred: {e}")
5.2. ROOT オブジェクトからの復元 (from_root)
ROOT: ROOT は CERN が開発した高エネルギー物理学向けのデータ解析フレームワークです。 📚 ROOT Documentation
既存の ROOT ファイルにあるヒストグラムやグラフを読み込んで、解析しやすい gwexpy オブジェクトに戻すことができます。
[21]:
try:
if "hist" in locals() and hist:
# ROOT TH1D -> TimeSeries
# Data
ts_restored = from_root(TimeSeries, hist)
print(f"Restored TimeSeries: {ts_restored.name}")
print(ts_restored)
# TGraph from
ts_from_graph = from_root(TimeSeries, graph)
print(f"Restored from TGraph: {len(ts_from_graph)} samples")
del ts_restored, ts_from_graph
except NameError:
pass # hist graph Create
except ImportError:
pass
6. 地球物理学・地震学・電磁気学
6.1. ObsPy [Original GWpy]
ObsPy: ObsPy は地震学データの取得・処理・解析のための Python ライブラリで、MiniSEED 形式などをサポートします。 📚 ObsPy Documentation
地震学で標準的な ObsPy との相互運用をサポート。
[22]:
try:
import obspy
_ = obspy
# TimeSeries -> ObsPy Trace
tr = ts.to_obspy()
print("--- ObsPy Trace ---")
print(tr)
# Plot using ObsPy
tr.plot()
# Recover to TimeSeries
from gwexpy.timeseries import TimeSeries
ts_recovered = TimeSeries.from_obspy(tr)
print("Recovered from ObsPy:", ts_recovered)
del tr, ts_recovered
except ImportError:
print("ObsPy not installed.")
--- ObsPy Trace ---
.demo_signal.. | 2019-02-18T23:31:12.000000Z - 2019-02-18T23:31:21.990000Z | 100.0 Hz, 1000 samples
Recovered from ObsPy: TimeSeries([ 0. , 0.06279052, 0.12533323, ...,
-0.18738131, -0.12533323, -0.06279052],
unit: dimensionless,
t0: 1234567890.0 s,
dt: 0.01 s,
name: .demo_signal..,
channel: None)
[23]:
try:
import obspy
_ = obspy
tr = ts.to_obspy()
print("ObsPy Trace:", tr)
del tr
except ImportError:
print("ObsPy not installed.")
ObsPy Trace: .demo_signal.. | 2019-02-18T23:31:12.000000Z - 2019-02-18T23:31:21.990000Z | 100.0 Hz, 1000 samples
6.2. SimPEG との連携 [GWExPy New]
SimPEG: SimPEG は地球物理学的逆問題のシミュレーション・推定フレームワークです。 📚 SimPEG Documentation
gwexpy は、地球物理学のフォワード計算・反転モデリングライブラリである SimPEG との連携をサポートしています。 TimeSeries (TDEM) および FrequencySeries (FDEM) を simpeg.data.Data オブジェクトに変換したり、その逆を行ったりできます。
[24]:
try:
import numpy as np
import simpeg
_ = simpeg
from simpeg import maps
_ = maps
from gwexpy.frequencyseries import FrequencySeries
from gwexpy.timeseries import TimeSeries
# --- TimeSeries -> SimPEG (TDEM ) ---
ts = TimeSeries(np.random.normal(size=100), dt=0.01, unit="A/m^2")
simpeg_data_td = ts.to_simpeg(location=np.array([0, 0, 0]))
print("SimPEG TDEM data shape:", simpeg_data_td.dobs.shape)
# --- FrequencySeries -> SimPEG (FDEM ) ---
fs = FrequencySeries(
np.random.normal(size=10) + 1j * 0.1, frequencies=np.logspace(0, 3, 10)
)
simpeg_data_fd = fs.to_simpeg(location=np.array([0, 0, 0]), orientation="z")
print("SimPEG FDEM data shape:", simpeg_data_fd.dobs.shape)
del simpeg_data_td, simpeg_data_fd, fs
except ImportError:
print("SimPEG library not found. Skipping example.")
SimPEG TDEM data shape: (100,)
SimPEG FDEM data shape: (10,)
6.3. MTH5 / MTpy [GWExPy New]
MTH5: MTH5 は磁気地電流 (MT) データのための HDF5 ベースのデータフォーマットです。 📚 MTH5 Documentation
地磁気地電流法データの MTH5 保存に対応。
[25]:
try:
import logging
import tempfile
logging.getLogger("mth5").setLevel(logging.ERROR)
logging.getLogger("mt_metadata").setLevel(logging.ERROR)
import mth5
_ = mth5
with tempfile.NamedTemporaryFile(suffix=".h5") as tmp:
from gwexpy.interop.mt_ import from_mth5, to_mth5
# TimeSeries -> MTH5
# We need to provide station and run names for MTH5 structure
to_mth5(ts, tmp.name, station="SITE01", run="RUN01")
print(f"Saved to MTH5 file: {tmp.name}")
# Display structure info if needed, or just recover
# Recover
ts_recovered = from_mth5(tmp.name, "SITE01", "RUN01", ts.name or "Ex")
print("Recovered from MTH5:", ts_recovered)
ts_recovered.plot()
plt.title("Recovered from MTH5")
plt.show()
del ts_recovered
except ImportError:
print("mth5 not installed.")
2026-02-26T21:29:43.956469+0900 | INFO | mth5.mth5 | _initialize_file | line: 900 | Initialized MTH5 0.2.0 file /tmp/tmpdsp7sqir.h5 in mode a
2026-02-26T21:29:44.676931+0900 | INFO | mth5.mth5 | close_mth5 | line: 1035 | Flushing and closing /tmp/tmpdsp7sqir.h5
Saved to MTH5 file: /tmp/tmpdsp7sqir.h5
2026-02-26T21:29:44.928276+0900 | INFO | mth5.mth5 | close_mth5 | line: 1035 | Flushing and closing /tmp/tmpdsp7sqir.h5
Recovered from MTH5: TimeSeries([-8.73335907e-01, 3.85949249e-01, 8.85888075e-01,
1.39610703e+00, 1.49989585e-01, 1.76490380e+00,
1.24027260e+00, 6.58447327e-01, 4.31816064e-01,
1.17772790e+00, 6.11637843e-01, -7.35290494e-01,
2.98021226e-01, -1.87190636e+00, 1.61121487e-01,
-5.19264179e-01, -1.30494955e+00, 1.45324386e+00,
-1.78471000e+00, 1.53364445e+00, 1.78404622e+00,
-6.74255701e-01, -6.92431778e-01, -1.51452991e+00,
1.21489537e+00, 5.89466115e-01, 5.41344620e-01,
1.04817235e-01, 1.73195466e+00, 8.25285400e-01,
-4.91798858e-01, 3.51232954e-01, 4.85615311e-02,
-1.65352774e+00, 3.74342162e-01, -3.97723500e-01,
-3.93479059e-01, 3.33212678e-01, -3.89125154e-01,
-2.50238129e+00, 3.34017139e-01, 5.75843355e-01,
-3.14261773e-01, -2.01519270e+00, 3.60155714e-01,
5.25460247e-04, -1.07171036e-01, -1.44728906e+00,
-9.19469431e-03, -1.51589952e-01, 2.01853273e+00,
2.19025934e+00, 1.32224015e+00, 3.62743748e-01,
-7.14810345e-01, -4.57020570e-01, -1.80294149e+00,
-9.80396589e-01, 1.13176630e+00, 6.72165613e-01,
7.02938765e-01, 1.01464677e+00, 1.20320223e+00,
-5.03063591e-01, -4.89665667e-01, -9.35268618e-02,
1.38139817e+00, 5.78775715e-01, -1.38719274e+00,
3.54361097e+00, -6.82621751e-01, 6.69578954e-02,
8.35296900e-02, -5.02967569e-01, -6.28434939e-01,
4.37316516e-01, -1.40544782e+00, 1.05039486e-01,
3.23349363e+00, -5.83719923e-01, -4.94099296e-01,
2.94506963e-01, -4.93193986e-01, 6.76695583e-01,
8.00295327e-01, 3.17634649e-01, 1.42497870e+00,
6.81093567e-01, 3.52391969e-01, -1.13684759e+00,
1.02603709e+00, 6.81708562e-01, -5.87602452e-01,
5.40923479e-01, -3.41832176e-01, 2.39464162e-01,
1.01233200e+00, -4.14889369e-01, -4.04418706e-01,
-2.19174773e+00],
unit: dimensionless,
t0: 0.0 s,
dt: 1.0 s,
name: Ex,
channel: None)
7. 音響・音声解析
7.1. Librosa / Pydub [GWExPy New]
pydub: pydub はオーディオファイルの操作(編集・変換・エフェクト)のためのシンプルなライブラリです。 📚 pydub Documentation
librosa: librosa は音声・音楽解析のためのライブラリで、スペクトル解析やビート検出などの機能を提供します。 📚 librosa Documentation
音声処理ライブラリ Librosa や Pydub との連携をサポート。
[26]:
try:
import librosa
_ = librosa
import matplotlib.pyplot as plt
# TimeSeries -> Librosa (y, sr)
y, sr = ts.to_librosa()
print(f"--- Librosa Data ---\nSignal shape: {y.shape}, Sample rate: {sr}")
# Plot using librosa style (matplotlib)
plt.figure()
plt.plot(y[:1000]) # Plot first 1000 samples
plt.title("Librosa Audio Signal (Zoom)")
plt.show()
# Recover to TimeSeries
from gwexpy.timeseries import TimeSeries
ts_recovered = TimeSeries(y, dt=1.0 / sr)
print("Recovered from Librosa:", ts_recovered)
del y, sr
except ImportError:
print("Librosa not installed.")
--- Librosa Data ---
Signal shape: (100,), Sample rate: 100
Recovered from Librosa: TimeSeries([-8.73335898e-01, 3.85949254e-01, 8.85888100e-01,
1.39610708e+00, 1.49989590e-01, 1.76490378e+00,
1.24027264e+00, 6.58447325e-01, 4.31816071e-01,
1.17772794e+00, 6.11637831e-01, -7.35290468e-01,
2.98021227e-01, -1.87190640e+00, 1.61121488e-01,
-5.19264162e-01, -1.30494952e+00, 1.45324385e+00,
-1.78471005e+00, 1.53364444e+00, 1.78404617e+00,
-6.74255729e-01, -6.92431808e-01, -1.51452994e+00,
1.21489537e+00, 5.89466095e-01, 5.41344643e-01,
1.04817234e-01, 1.73195469e+00, 8.25285375e-01,
-4.91798848e-01, 3.51232946e-01, 4.85615321e-02,
-1.65352774e+00, 3.74342173e-01, -3.97723496e-01,
-3.93479049e-01, 3.33212674e-01, -3.89125168e-01,
-2.50238132e+00, 3.34017128e-01, 5.75843334e-01,
-3.14261764e-01, -2.01519275e+00, 3.60155702e-01,
5.25460229e-04, -1.07171036e-01, -1.44728911e+00,
-9.19469446e-03, -1.51589945e-01, 2.01853275e+00,
2.19025922e+00, 1.32224011e+00, 3.62743735e-01,
-7.14810371e-01, -4.57020581e-01, -1.80294144e+00,
-9.80396569e-01, 1.13176632e+00, 6.72165632e-01,
7.02938735e-01, 1.01464677e+00, 1.20320225e+00,
-5.03063619e-01, -4.89665657e-01, -9.35268626e-02,
1.38139820e+00, 5.78775704e-01, -1.38719273e+00,
3.54361105e+00, -6.82621777e-01, 6.69578984e-02,
8.35296884e-02, -5.02967596e-01, -6.28434956e-01,
4.37316507e-01, -1.40544784e+00, 1.05039485e-01,
3.23349357e+00, -5.83719909e-01, -4.94099289e-01,
2.94506967e-01, -4.93193984e-01, 6.76695585e-01,
8.00295353e-01, 3.17634642e-01, 1.42497873e+00,
6.81093574e-01, 3.52391958e-01, -1.13684762e+00,
1.02603710e+00, 6.81708574e-01, -5.87602437e-01,
5.40923476e-01, -3.41832161e-01, 2.39464164e-01,
1.01233196e+00, -4.14889365e-01, -4.04418707e-01,
-2.19174767e+00],
unit: dimensionless,
t0: 0.0 s,
dt: 0.01 s,
name: None,
channel: None)
8. 医学・生体信号解析
8.1. MNE-Python [GWExPy New]
MNE: MNE-Python は脳波 (EEG)・脳磁図 (MEG) データの解析ライブラリで、神経科学研究に広く使用されています。 📚 MNE Documentation
脳電図 (EEG/MEG) 解析パッケージ MNE との連携。
[27]:
try:
import mne
_ = mne
# TimeSeries -> MNE Raw
raw = ts.to_mne()
print("--- MNE Raw ---")
print(raw)
# Display info
print(raw.info)
# Recover to TimeSeries
from gwexpy.timeseries import TimeSeries
ts_recovered = TimeSeries.from_mne(raw, channel=ts.name or "ch0")
print("Recovered from MNE:", ts_recovered)
del raw, ts_recovered
except ImportError:
print("MNE not installed.")
Creating RawArray with float64 data, n_channels=1, n_times=100
Range : 0 ... 99 = 0.000 ... 0.990 secs
Ready.
--- MNE Raw ---
<RawArray | 1 x 100 (1.0 s), ~6 KiB, data loaded>
<Info | 7 non-empty values
bads: []
ch_names: ch0
chs: 1 misc
custom_ref_applied: False
highpass: 0.0 Hz
lowpass: 50.0 Hz
meas_date: unspecified
nchan: 1
projs: []
sfreq: 100.0 Hz
>
Recovered from MNE: TimeSeries([-8.73335907e-01, 3.85949249e-01, 8.85888075e-01,
1.39610703e+00, 1.49989585e-01, 1.76490380e+00,
1.24027260e+00, 6.58447327e-01, 4.31816064e-01,
1.17772790e+00, 6.11637843e-01, -7.35290494e-01,
2.98021226e-01, -1.87190636e+00, 1.61121487e-01,
-5.19264179e-01, -1.30494955e+00, 1.45324386e+00,
-1.78471000e+00, 1.53364445e+00, 1.78404622e+00,
-6.74255701e-01, -6.92431778e-01, -1.51452991e+00,
1.21489537e+00, 5.89466115e-01, 5.41344620e-01,
1.04817235e-01, 1.73195466e+00, 8.25285400e-01,
-4.91798858e-01, 3.51232954e-01, 4.85615311e-02,
-1.65352774e+00, 3.74342162e-01, -3.97723500e-01,
-3.93479059e-01, 3.33212678e-01, -3.89125154e-01,
-2.50238129e+00, 3.34017139e-01, 5.75843355e-01,
-3.14261773e-01, -2.01519270e+00, 3.60155714e-01,
5.25460247e-04, -1.07171036e-01, -1.44728906e+00,
-9.19469431e-03, -1.51589952e-01, 2.01853273e+00,
2.19025934e+00, 1.32224015e+00, 3.62743748e-01,
-7.14810345e-01, -4.57020570e-01, -1.80294149e+00,
-9.80396589e-01, 1.13176630e+00, 6.72165613e-01,
7.02938765e-01, 1.01464677e+00, 1.20320223e+00,
-5.03063591e-01, -4.89665667e-01, -9.35268618e-02,
1.38139817e+00, 5.78775715e-01, -1.38719274e+00,
3.54361097e+00, -6.82621751e-01, 6.69578954e-02,
8.35296900e-02, -5.02967569e-01, -6.28434939e-01,
4.37316516e-01, -1.40544782e+00, 1.05039486e-01,
3.23349363e+00, -5.83719923e-01, -4.94099296e-01,
2.94506963e-01, -4.93193986e-01, 6.76695583e-01,
8.00295327e-01, 3.17634649e-01, 1.42497870e+00,
6.81093567e-01, 3.52391969e-01, -1.13684759e+00,
1.02603709e+00, 6.81708562e-01, -5.87602452e-01,
5.40923479e-01, -3.41832176e-01, 2.39464162e-01,
1.01233200e+00, -4.14889369e-01, -4.04418706e-01,
-2.19174773e+00],
unit: dimensionless,
t0: 0.0 s,
dt: 0.01 s,
name: ch0,
channel: None)
[28]:
try:
import mne
_ = mne
raw = ts.to_mne()
print("MNE Raw:", raw)
del raw
except ImportError:
print("MNE not installed.")
Creating RawArray with float64 data, n_channels=1, n_times=100
Range : 0 ... 99 = 0.000 ... 0.990 secs
Ready.
MNE Raw: <RawArray | 1 x 100 (1.0 s), ~6 KiB, data loaded>
8.2. Elephant / quantities との連携 [GWExPy New]
gwexpy の FrequencySeries や Spectrogram は、quantities.Quantity オブジェクトと相互変換可能です。 これは Elephant や Neo との連携に役立ちます。
※ 事前に pip install quantities が必要です。
[29]:
try:
import numpy as np
import quantities as pq
_ = pq
from gwexpy.frequencyseries import FrequencySeries
# FrequencySeries Create
freqs = np.linspace(0, 100, 101)
data_fs = np.random.random(101)
fs = FrequencySeries(data_fs, frequencies=freqs, unit="V")
# to_quantities
q_obj = fs.to_quantities(units="mV")
print("Quantities object:", q_obj)
# from_quantities
fs_new = FrequencySeries.from_quantities(q_obj, frequencies=freqs)
print("Restored FrequencySeries unit:", fs_new.unit)
del freqs, data_fs, fs, q_obj, fs_new
except ImportError:
print("quantities library not found. Skipping example.")
Quantities object: [446.47934766 976.58211045 483.82846336 309.13238065
80.96763002 275.93041711 687.36761228 956.30850228
390.21681506 348.96786911 276.12198709 924.42735562
48.81888359 756.25690461 100.43413213 582.4365419
812.56365677 83.04497486 663.92096973 250.95177872
29.68751243 601.13368803 565.54115638 620.34075667
561.78864735 247.69043435 919.15709605 827.19146124
343.1205898 946.44522192 968.05695394 896.80744969
59.17336443 260.4171364 641.9224496 776.99894477
955.16752026 10.59449568 333.49133559 520.40717454
833.8527583 761.45033157 422.51304835 390.75623398
891.06283648 525.6142011 521.70328993 873.5914692
703.72332651 769.64058303 319.44785504 366.27737261
302.56080707 23.20769337 700.00929609 790.53310967
391.73512546 669.42318508 336.30244728 751.5849929
641.05834985 937.47156091 275.87240127 89.17417305
487.83270967 748.67938932 148.00223691 534.07922524
880.90763254 425.32065413 609.15442427 897.18686266
599.74719555 955.28473519 514.9303788 733.04032637
17.47705579 166.56380532 182.45452859 720.91826186
215.03551974 143.6409298 904.62718142 2.95042478
181.42024699 99.93232509 327.95011449 27.79535712
472.53208021 768.49916521 842.68203826 799.22797826
109.11810132 263.79611209 353.18693843 432.73359655
364.07504598 361.33647855 711.17340215 970.62885478
469.85830082] mV
Restored FrequencySeries unit: mV
8.3. Neo [GWExPy New]
Neo: Neo は電気生理学データ(神経科学)のためのデータ構造ライブラリで、様々なフォーマットへの入出力をサポートします。 📚 Neo Documentation
電気生理データの共通規格 Neo への変換をサポート。
[30]:
try:
import neo
_ = neo
# TimeSeries -> Neo AnalogSignal
# to_neo is available in gwexpy.interop
# Note: TimeseriesMatrix is preferred for multi-channel Neo conversion,
# but we can convert single TimeSeries by wrapping it.
from gwexpy.interop import from_neo, to_neo
_ = from_neo
_ = to_neo
# For single TimeSeries, we might need a Matrix wrapper or direct helper.
# Assuming helper exists or using Matrix:
from gwexpy.timeseries import TimeSeriesMatrix
tm = TimeSeriesMatrix(
ts.value[None, None, :], t0=ts.t0, dt=ts.dt, channel_names=[ts.name]
)
sig = tm.to_neo()
print("--- Neo AnalogSignal ---")
print(sig)
# Display/Plot
plt.figure()
plt.plot(sig.times, sig)
plt.title("Neo AnalogSignal Plot")
plt.show()
# Recover
tm_recovered = TimeSeriesMatrix.from_neo(sig)
ts_recovered = tm_recovered[0]
print("Recovered from Neo:", ts_recovered)
del tm, tm_recovered, sig, ts_recovered
except ImportError:
print("neo not installed.")
--- Neo AnalogSignal ---
[[-8.73335907e-01]
[ 3.85949249e-01]
[ 8.85888075e-01]
[ 1.39610703e+00]
[ 1.49989585e-01]
[ 1.76490380e+00]
[ 1.24027260e+00]
[ 6.58447327e-01]
[ 4.31816064e-01]
[ 1.17772790e+00]
[ 6.11637843e-01]
[-7.35290494e-01]
[ 2.98021226e-01]
[-1.87190636e+00]
[ 1.61121487e-01]
[-5.19264179e-01]
[-1.30494955e+00]
[ 1.45324386e+00]
[-1.78471000e+00]
[ 1.53364445e+00]
[ 1.78404622e+00]
[-6.74255701e-01]
[-6.92431778e-01]
[-1.51452991e+00]
[ 1.21489537e+00]
[ 5.89466115e-01]
[ 5.41344620e-01]
[ 1.04817235e-01]
[ 1.73195466e+00]
[ 8.25285400e-01]
[-4.91798858e-01]
[ 3.51232954e-01]
[ 4.85615311e-02]
[-1.65352774e+00]
[ 3.74342162e-01]
[-3.97723500e-01]
[-3.93479059e-01]
[ 3.33212678e-01]
[-3.89125154e-01]
[-2.50238129e+00]
[ 3.34017139e-01]
[ 5.75843355e-01]
[-3.14261773e-01]
[-2.01519270e+00]
[ 3.60155714e-01]
[ 5.25460247e-04]
[-1.07171036e-01]
[-1.44728906e+00]
[-9.19469431e-03]
[-1.51589952e-01]
[ 2.01853273e+00]
[ 2.19025934e+00]
[ 1.32224015e+00]
[ 3.62743748e-01]
[-7.14810345e-01]
[-4.57020570e-01]
[-1.80294149e+00]
[-9.80396589e-01]
[ 1.13176630e+00]
[ 6.72165613e-01]
[ 7.02938765e-01]
[ 1.01464677e+00]
[ 1.20320223e+00]
[-5.03063591e-01]
[-4.89665667e-01]
[-9.35268618e-02]
[ 1.38139817e+00]
[ 5.78775715e-01]
[-1.38719274e+00]
[ 3.54361097e+00]
[-6.82621751e-01]
[ 6.69578954e-02]
[ 8.35296900e-02]
[-5.02967569e-01]
[-6.28434939e-01]
[ 4.37316516e-01]
[-1.40544782e+00]
[ 1.05039486e-01]
[ 3.23349363e+00]
[-5.83719923e-01]
[-4.94099296e-01]
[ 2.94506963e-01]
[-4.93193986e-01]
[ 6.76695583e-01]
[ 8.00295327e-01]
[ 3.17634649e-01]
[ 1.42497870e+00]
[ 6.81093567e-01]
[ 3.52391969e-01]
[-1.13684759e+00]
[ 1.02603709e+00]
[ 6.81708562e-01]
[-5.87602452e-01]
[ 5.40923479e-01]
[-3.41832176e-01]
[ 2.39464162e-01]
[ 1.01233200e+00]
[-4.14889369e-01]
[-4.04418706e-01]
[-2.19174773e+00]] dimensionless
Recovered from Neo: SeriesMatrix(shape=(1, 1, 100), name='')
epoch : 0.0
x0 : 0.0 s
dx : 0.01 s
xunit : s
samples : 100
[ Row metadata ]
name channel unit
key
row0
[ Column metadata ]
name channel unit
key
col0
[ Elements metadata ]
unit name channel row col
0 None None 0 0
9. 音響・電磁シミュレーション連携(追加ライブラリ)
以下のセクションでは、室内音響シミュレーション・電磁場シミュレーション・非構造格子メッシュデータ・マルチテーパースペクトル推定の4つの追加連携モジュールを扱います。
9.1. Pyroomacoustics — 室内インパルス応答(RIR)
pyroomacoustics は室内音響シミュレーションライブラリです。
room.rirはrir[マイクインデックス][音源インデックス](外側=マイク)という規約に従います。
[ ]:
try:
from unittest.mock import MagicMock
import numpy as np
from gwexpy.interop.pyroomacoustics_ import from_pyroomacoustics_rir
# モックルーム: 2マイク x 2音源 — 実際のレイアウト: rir[mic][source]
room = MagicMock()
room.fs = 16000
rir_data = [
[np.array([1.0, 0.5, 0.2, 0.0]), np.array([0.8, 0.4, 0.1, 0.0])], # マイク0
[np.array([0.9, 0.3, 0.1, 0.0]), np.array([0.7, 0.2, 0.05, 0.0])], # マイク1
]
room.rir = rir_data
# source=0, mic=0 -> rir[mic=0][source=0] を返す
print("rir[mic=0][source=0] =", rir_data[0][0])
print("ヒント: room.rir の規約は rir[マイクインデックス][音源インデックス]")
except Exception as e:
print(f"スキップ(pyroomacoustics 未インストールまたはモックエラー): {e}")
9.2. OpenEMS — HDF5 電磁場ダンプ
openEMS は電磁場データを HDF5 に書き出します。 TD データセットに
"Time"属性(秒)、FD データセットに"frequency"属性(Hz)がある場合、axis0 に物理値が使われます。属性がない場合は整数インデックスにフォールバックします。
[ ]:
try:
import h5py
import numpy as np
import tempfile, os
from gwexpy.fields import VectorField
from gwexpy.interop.openems_ import from_openems_hdf5
# Time 属性付きの最小 openEMS スタイル HDF5 を作成
with tempfile.NamedTemporaryFile(suffix=".h5", delete=False) as tmp:
tmp_path = tmp.name
with h5py.File(tmp_path, "w") as h5:
mesh = h5.create_group("Mesh")
mesh.create_dataset("x", data=np.linspace(0, 1, 4))
mesh.create_dataset("y", data=np.linspace(0, 1, 4))
mesh.create_dataset("z", data=np.linspace(0, 1, 4))
td = h5.create_group("FieldData/TD")
for i, t in enumerate([1e-9, 2e-9, 3e-9]):
ds = td.create_dataset(f"step_{i}", data=np.ones((4, 4, 4, 3)))
ds.attrs["Time"] = t # 物理時間(秒)
vf = from_openems_hdf5(VectorField, tmp_path, dump_type=0)
print(f"VectorField の形状: {vf['x'].shape}, axis0={list(vf['x']._axis0_index)}")
print("axis0 には物理時間値(1e-9, 2e-9, 3e-9 秒)が含まれています")
os.unlink(tmp_path)
except Exception as e:
print(f"スキップ: {e}")
9.3. Meshio — 非構造格子メッシュ → ScalarField
meshio は VTK・XDMF・Gmsh など40以上のメッシュフォーマットを読み込めます。 補間には
point_dataのみ対応しています。cell_dataのみの場合はValueErrorが発生します(事前にpoint_dataに変換してください)。
[ ]:
try:
from unittest.mock import MagicMock
import numpy as np
from gwexpy.fields import ScalarField
from gwexpy.interop.meshio_ import from_meshio
# スカラー温度フィールドを持つ 2D 三角形メッシュ
nx, ny = 15, 15
x = np.linspace(0, 1, nx)
y = np.linspace(0, 1, ny)
xx, yy = np.meshgrid(x, y)
pts = np.column_stack([xx.ravel(), yy.ravel(), np.zeros(nx * ny)])
mesh = MagicMock()
mesh.points = pts
mesh.point_data = {"temperature": pts[:, 0] ** 2 + pts[:, 1] ** 2}
mesh.cell_data = {}
mesh.cells = []
sf = from_meshio(ScalarField, mesh, grid_resolution=0.1)
print(f"ScalarField の形状: {sf.shape} (axis0, nx, ny, 1)")
print(f"中心の値 ≈ {float(np.asarray(sf.value)[0, sf.shape[1]//2, sf.shape[2]//2, 0]):.3f}")
except Exception as e:
print(f"スキップ: {e}")
9.4. マルチテーパースペクトル推定
multitaper(Prieto)は
from_mtspecで、mtspec(Krischer)はfrom_mtspec_arrayで対応します。cls=FrequencySeriesを渡すと常にプレーンなスペクトルが返ります。cls=FrequencySeriesDictを渡すと、信頼区間が利用可能な場合にその dict が返ります。
[ ]:
try:
from unittest.mock import MagicMock
import numpy as np
# モックレジストリ(FrequencySeries / FrequencySeriesDict の代替)
class _FS(list):
def __init__(self, data, *, frequencies, name="", unit=None):
super().__init__(data)
self.frequencies = frequencies
self.name = name
class _FSD(dict):
pass
from gwexpy.interop._registry import ConverterRegistry
ConverterRegistry.register_constructor("FrequencySeries", _FS)
ConverterRegistry.register_constructor("FrequencySeriesDict", _FSD)
from gwexpy.interop.multitaper_ import from_mtspec
# 信頼区間付き MTSpec モック
n = 100
freq = np.linspace(0, 50, n)
mt = MagicMock()
mt.freq = freq
mt.spec = np.abs(np.random.default_rng(0).standard_normal(n)) + 0.1
mt.spec_ci = np.column_stack([mt.spec * 0.8, mt.spec * 1.2])
# cls=_FS -> 常に FrequencySeries(CI は破棄)
result_fs = from_mtspec(_FS, mt, include_ci=True)
print(f"cls=FrequencySeries -> 型: {type(result_fs).__name__}")
# cls=_FSD -> CI 付き FrequencySeriesDict
result_fsd = from_mtspec(_FSD, mt, include_ci=True)
print(f"cls=FrequencySeriesDict -> 型: {type(result_fsd).__name__}, キー: {list(result_fsd.keys())}")
except Exception as e:
print(f"スキップ: {e}")
10. まとめ
gwexpy は多種多様な bilimti 向けライブラリとの相互運用を提供し、既存のエコシステムとのシームレスな統合を可能にします。