Skip to content

sgnl.transforms.strike

A transform element to assign likelihood and FAR to events

StrikeTransform dataclass

Bases: TransformElement

Compute LR and FAR

Source code in sgnl/transforms/strike.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
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
@dataclass
class StrikeTransform(TransformElement):
    """
    Compute LR and FAR
    """

    strike_object: StrikeObject = None
    update_interval: float = 14400

    def __post_init__(self):
        assert len(self.sink_pad_names) == 1
        assert self.strike_object is not None
        super().__post_init__()
        self.frame = None
        self.output_frame = None
        self.last_update = now()

    def pull(self, pad, frame):
        self.frame = frame

    def internal(self):
        """
        compute LR and FAR
        """
        frame = self.frame
        events = self.frame.events
        event_data = events["event"].data
        trigger_data = events["trigger"].data

        if event_data is not None:
            if now() - self.last_update >= self.update_interval:
                print("Updating lr and FAP/FAR assignment")
                # Update lr assignment
                self.strike_object.update_assign_lr()

                # Update FAP/FAR assignment
                self.strike_object.load_rank_stat_pdf()

                self.last_update = now()

            for e, t in zip(event_data, trigger_data):
                #
                # Assign likelihoods and FARs!
                #
                bankid = e["bankid"]
                if self.strike_object.ln_lr_from_triggers[bankid] is not None:
                    # update triggers
                    trigs = []
                    for i, ti in enumerate(t):
                        if ti is not None:
                            # FIXME the time conversion should happen in the
                            # ln_lr_from_triggers function?
                            # find a way to avoid making a copy
                            copytrig = {k: v for k, v in ti.items()}
                            copytrig["__trigger_id"] = i
                            copytrig["time"] /= 1e9
                            copytrig["epoch_start"] /= 1e9
                            copytrig["epoch_end"] /= 1e9
                            trigs.append(copytrig)

                    e["likelihood"] = float(
                        self.strike_object.ln_lr_from_triggers[bankid](
                            trigs, self.strike_object.offset_vectors
                        )
                    )

                    if self.strike_object.fapfar is not None:
                        # fapfar is updated every time we reload a rank stat pdf file in
                        # StrikeSink
                        # FIXME: reconcile far and combined_far
                        e["false_alarm_probability"] = (
                            self.strike_object.fapfar.fap_from_rank(e["likelihood"])
                        )
                        e["combined_far"] = (
                            self.strike_object.fapfar.far_from_rank(e["likelihood"])
                            * self.strike_object.FAR_trialsfactor
                        )
                        if (
                            len(trigs) == 1
                            and self.strike_object.cap_singles
                            and e["combined_far"]
                            < 1.0 / self.strike_object.fapfar.livetime
                        ):
                            # FIXME: do we still need this cap singles?
                            e["combined_far"] = 1.0 / self.strike_object.fapfar.livetime
                    else:
                        e["false_alarm_probability"] = None
                        e["combined_far"] = None

                    if self.strike_object.zerolag_rank_stat_pdfs is not None:
                        self.strike_object.zerolag_rank_stat_pdfs[
                            bankid
                        ].zero_lag_lr_lnpdf.count[
                            e["likelihood"],
                        ] += 1
                else:
                    e["likelihood"] = None
                    e["false_alarm_probability"] = None
                    e["combined_far"] = None

        self.output_frame = EventFrame(
            events=events,
            EOS=frame.EOS,
        )

    def new(self, pad):
        return self.output_frame

internal()

compute LR and FAR

Source code in sgnl/transforms/strike.py
 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
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
def internal(self):
    """
    compute LR and FAR
    """
    frame = self.frame
    events = self.frame.events
    event_data = events["event"].data
    trigger_data = events["trigger"].data

    if event_data is not None:
        if now() - self.last_update >= self.update_interval:
            print("Updating lr and FAP/FAR assignment")
            # Update lr assignment
            self.strike_object.update_assign_lr()

            # Update FAP/FAR assignment
            self.strike_object.load_rank_stat_pdf()

            self.last_update = now()

        for e, t in zip(event_data, trigger_data):
            #
            # Assign likelihoods and FARs!
            #
            bankid = e["bankid"]
            if self.strike_object.ln_lr_from_triggers[bankid] is not None:
                # update triggers
                trigs = []
                for i, ti in enumerate(t):
                    if ti is not None:
                        # FIXME the time conversion should happen in the
                        # ln_lr_from_triggers function?
                        # find a way to avoid making a copy
                        copytrig = {k: v for k, v in ti.items()}
                        copytrig["__trigger_id"] = i
                        copytrig["time"] /= 1e9
                        copytrig["epoch_start"] /= 1e9
                        copytrig["epoch_end"] /= 1e9
                        trigs.append(copytrig)

                e["likelihood"] = float(
                    self.strike_object.ln_lr_from_triggers[bankid](
                        trigs, self.strike_object.offset_vectors
                    )
                )

                if self.strike_object.fapfar is not None:
                    # fapfar is updated every time we reload a rank stat pdf file in
                    # StrikeSink
                    # FIXME: reconcile far and combined_far
                    e["false_alarm_probability"] = (
                        self.strike_object.fapfar.fap_from_rank(e["likelihood"])
                    )
                    e["combined_far"] = (
                        self.strike_object.fapfar.far_from_rank(e["likelihood"])
                        * self.strike_object.FAR_trialsfactor
                    )
                    if (
                        len(trigs) == 1
                        and self.strike_object.cap_singles
                        and e["combined_far"]
                        < 1.0 / self.strike_object.fapfar.livetime
                    ):
                        # FIXME: do we still need this cap singles?
                        e["combined_far"] = 1.0 / self.strike_object.fapfar.livetime
                else:
                    e["false_alarm_probability"] = None
                    e["combined_far"] = None

                if self.strike_object.zerolag_rank_stat_pdfs is not None:
                    self.strike_object.zerolag_rank_stat_pdfs[
                        bankid
                    ].zero_lag_lr_lnpdf.count[
                        e["likelihood"],
                    ] += 1
            else:
                e["likelihood"] = None
                e["false_alarm_probability"] = None
                e["combined_far"] = None

    self.output_frame = EventFrame(
        events=events,
        EOS=frame.EOS,
    )