Skip to content

sgnl.transforms.horizon

An element to track horizon distance for incoming PSDs.

HorizonDistanceTracker dataclass

Bases: TSTransform

Compute horizon distance for an incoming PSD and a given waveform model

Source code in sgnl/transforms/horizon.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
@dataclass
class HorizonDistanceTracker(TSTransform):
    """
    Compute horizon distance for an incoming PSD and a given waveform model
    """

    horizon_distance_funcs: Callable | dict[str, Callable] = None
    ifo: str = None
    range: bool = False

    def __post_init__(self):
        super().__post_init__()

    def new(self, pad):
        """
        compute horizon distance
        """
        # incoming frame handling
        frame = self.preparedframes[self.sink_pads[0]]
        EOS = frame.EOS
        shape = frame.shape
        offset = frame.offset
        metadata = frame.metadata

        ts = Offset.tons(offset)
        te = Offset.tons(offset + Offset.fromsamples(shape[-1], frame.sample_rate))

        # get spectrum from metadata
        # FIXME: this is a hack since the PSD is a frequency series.
        psd = metadata["psd"]
        if psd is not None:
            assert isinstance(psd, lal.REAL8FrequencySeries)

            if isinstance(self.horizon_distance_funcs, dict):
                dist = {
                    bankid: func(psd, 8)[0]
                    for bankid, func in self.horizon_distance_funcs.items()
                }
            else:
                dist = self.horizon_distance_funcs(psd, 8)[0]

            data = {}
            if self.range is True:
                data["range_history"] = {
                    "time": [float(ts / 1e9)],
                    "data": [float(dist / 2.25)],
                }
            else:
                data["horizon"] = dist
                data["time"] = ts
                data["ifo"] = self.ifo
                data["navg"] = metadata["navg"]
                data["n_samples"] = metadata["n_samples"]
                data["epoch"] = metadata["epoch"]
        else:
            data = {}
            data["horizon"] = None
            data["time"] = ts
            data["ifo"] = self.ifo
            data["navg"] = None
            data["n_samples"] = None
            data["epoch"] = metadata["epoch"]

        if self.range is True:
            events = {"kafka": EventBuffer(ts, te, data)}
        else:
            events = {"data": EventBuffer(ts, te, data)}

        return EventFrame(
            events=events,
            EOS=EOS,
        )

new(pad)

compute horizon distance

Source code in sgnl/transforms/horizon.py
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
def new(self, pad):
    """
    compute horizon distance
    """
    # incoming frame handling
    frame = self.preparedframes[self.sink_pads[0]]
    EOS = frame.EOS
    shape = frame.shape
    offset = frame.offset
    metadata = frame.metadata

    ts = Offset.tons(offset)
    te = Offset.tons(offset + Offset.fromsamples(shape[-1], frame.sample_rate))

    # get spectrum from metadata
    # FIXME: this is a hack since the PSD is a frequency series.
    psd = metadata["psd"]
    if psd is not None:
        assert isinstance(psd, lal.REAL8FrequencySeries)

        if isinstance(self.horizon_distance_funcs, dict):
            dist = {
                bankid: func(psd, 8)[0]
                for bankid, func in self.horizon_distance_funcs.items()
            }
        else:
            dist = self.horizon_distance_funcs(psd, 8)[0]

        data = {}
        if self.range is True:
            data["range_history"] = {
                "time": [float(ts / 1e9)],
                "data": [float(dist / 2.25)],
            }
        else:
            data["horizon"] = dist
            data["time"] = ts
            data["ifo"] = self.ifo
            data["navg"] = metadata["navg"]
            data["n_samples"] = metadata["n_samples"]
            data["epoch"] = metadata["epoch"]
    else:
        data = {}
        data["horizon"] = None
        data["time"] = ts
        data["ifo"] = self.ifo
        data["navg"] = None
        data["n_samples"] = None
        data["epoch"] = metadata["epoch"]

    if self.range is True:
        events = {"kafka": EventBuffer(ts, te, data)}
    else:
        events = {"data": EventBuffer(ts, te, data)}

    return EventFrame(
        events=events,
        EOS=EOS,
    )