A transform element to assign likelihood and FAR to events
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
|
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,
)
|