SegmentTable: Basics#
Tip
For a more comprehensive guide including visualization, GravitySpy integration, and advanced operations, see the Table / Segment User Guide.
GWpy base classes and gwexpy extensions#
Segment analysis builds on GWpy types. Each row span is still represented by gwpy.segments.Segment, and payload columns can hold GWpy TimeSeries or FrequencySeries objects directly.
On top of that, gwexpy adds SegmentTable as an extension of gwpy.table.Table, plus lazy payload handling via SegmentCell, and table-oriented batch helpers such as apply(), map(), crop(), and asd(). In practice, you keep GWpy base classes for the actual data objects while gwexpy adds the workflow layer for processing many segments together.
import warnings
import warnings
with warnings.catch_warnings():
import numpy as np
np.random.seed(42)
from gwpy.segments import Segment
from gwexpy.table import SegmentTable
# 1. Create simple segments
segs = [Segment(0, 4), Segment(4, 8), Segment(8, 12)]
st = SegmentTable.from_segments(segs, label=["A", "B", "C"])
st
/home/runner/micromamba/envs/gwexpy/lib/python3.11/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
Delayed Loading with SegmentCell#
You can add payload columns that are only loaded when needed. This is useful for handling large datasets.
def my_loader():
# Simulate loading data
print("Loading series...")
from gwpy.timeseries import TimeSeries
return TimeSeries(np.random.randn(128), sample_rate=32)
# Add a payload column with a loader (sequence of callables)
st.add_series_column("raw", loader=[my_loader]*len(st), kind="timeseries")
st
| span | label | raw | |
|---|---|---|---|
| 0 | (0, 4) | A | <lazy: timeseries> |
| 1 | (4, 8) | B | <lazy: timeseries> |
| 2 | (8, 12) | C | <lazy: timeseries> |
Row-wise Processing#
SegmentTable provides an apply() method to process each row and collect results into new columns.
def process_row(row):
span = row["span"]
return {"duration": float(span[1] - span[0]), "valid": True}
st2 = st.apply(process_row)
st2.display()
| span | label | duration | valid | raw | |
|---|---|---|---|---|---|
| 0 | (0, 4) | A | 4.0 | True | <lazy: timeseries> |
| 1 | (4, 8) | B | 4.0 | True | <lazy: timeseries> |
| 2 | (8, 12) | C | 4.0 | True | <lazy: timeseries> |
Fetch and Conversion#
You can explicitly load lazy cells with fetch() or materialize(). Converting to pandas gives you a standard DataFrame for meta columns.
st2.fetch()
df = st2.to_pandas()
df.head()
Loading series...
Loading series...
Loading series...
| span | label | duration | valid | |
|---|---|---|---|---|
| 0 | (0, 4) | A | 4.0 | True |
| 1 | (4, 8) | B | 4.0 | True |
| 2 | (8, 12) | C | 4.0 | True |