<h1 align="center">sgn-gwframe</h1>

<p align="center">Gravitational wave frame file I/O elements for <a href="https://git.ligo.org/greg/sgn-ts">sgn-ts</a></p>

<p align="center">
  <a href="https://git.ligo.org/greg/sgn-gwframe/-/pipelines/latest">
    <img alt="ci" src="https://git.ligo.org/greg/sgn-gwframe/badges/main/pipeline.svg" />
  </a>
  <a href="https://git.ligo.org/greg/sgn-gwframe/-/pipelines/latest">
    <img alt="coverage" src="https://git.ligo.org/greg/sgn-gwframe/badges/main/coverage.svg" />
  </a>
  <a href="https://docs.ligo.org/greg/sgn-gwframe">
    <img alt="documentation" src="https://img.shields.io/badge/docs-mkdocs%20material-blue.svg?style=flat" />
  </a>
  <a href="https://pypi.org/project/sgn-gwframe/">
    <img alt="pypi version" src="https://img.shields.io/pypi/v/sgn-gwframe.svg" />
  </a>
</p>

---

## Resources

* [Documentation](https://docs.ligo.org/greg/sgn-gwframe)
* [Source Code](https://git.ligo.org/greg/sgn-gwframe)
* [Issue Tracker](https://git.ligo.org/greg/sgn-gwframe/-/issues)

## Installation

```
pip install sgn-gwframe
```

## Features

* Read timeseries data from `.gwf` frame files, frame caches, or lists of frame files
* Watch directories for new frame files in real-time with automatic gap detection
* Write timeseries data to `.gwf` files with compression, multi-frame support, and retention policies
* Integrates as source and sink elements for [SGN](https://git.ligo.org/greg/sgn) pipelines

## Quickstart

### Read from frame files

``` python
from sgn_gwframe.sources import GWFrameSource
from sgn.apps import Pipeline

src = GWFrameSource(
    name="gwosc",
    channels=["L1:GWOSC-16KHZ_R1_STRAIN"],
    frames="frames.cache",
    start=1187008882,
    end=1187008896,
)

pipeline = Pipeline()
pipeline.insert(src, ...)
pipeline.run()
```

### Watch a directory for live frame data

``` python
from sgn_gwframe.sources import GWFrameWatchSource
from sgn.apps import Pipeline

src = GWFrameWatchSource(
    name="L1_live",
    channels=["L1:GDS-CALIB_STRAIN"],
    watch_dir="/data/frames/L1",
)

pipeline = Pipeline()
pipeline.insert(src, ...)
pipeline.run()
```

### Write frame files

``` python
from sgn_gwframe.sinks import GWFrameSink
from sgn.apps import Pipeline

sink = GWFrameSink(
    name="writer",
    channels=["H1:GDS-CALIB_STRAIN"],
    duration=1,
    path="output/{instruments}-{description}-{gps_start_time}-{duration}.gwf",
    description="FILTERED",
    max_files=100,
)

pipeline = Pipeline()
pipeline.insert(..., sink)
pipeline.run()
```
