Skip to content
Snippets Groups Projects
Commit 0897d966 authored by Rebecca Ewing's avatar Rebecca Ewing
Browse files

gstlal_ll_inspiral_event_uploader: make sure min FAR event is always uploaded...

gstlal_ll_inspiral_event_uploader: make sure min FAR event is always uploaded above OPA; no wait time for first event below OPA
parent a6545a06
No related branches found
No related tags found
1 merge request!460gstlal_ll_inspiral_event_uploader: make sure min FAR event is always uploaded above OPA; no wait time for first event below OPA
Pipeline #517583 passed with warnings
......@@ -72,7 +72,7 @@ def parse_command_line():
parser.add_option("--upload-cadence-type", metavar = "string", default = "geometric", help = "Choose the method [geometric|linear] in which the cadence of subsequent uploads are done. Default = geometric.")
parser.add_option("--upload-cadence-factor", type = "float", default = 4, help = "Cadence factor T for sending out subsequent events for the same event window. For geometric cadence, first event gets sent T seconds later, second event gets sent T^2 seconds later, etc. For linear cadence, subsequent events get sent T seconds later. Default = 4.0.")
parser.add_option("--selection-criteria", type = "str", default = "MAXSNR", help = "Choose method for determining favored event. Select one of the following: " +
"1. MAXSNR - upload highest SNR candidate (default). " +
"1. MAXSNR - upload highest SNR candidate *below* public alert threshold (default). " +
"2. MINFAR - upload lowest FAR candidate. " +
"3. COMPOSITE - upload composite event by assigning the minimum FAR to the highest SNR candidate.")
parser.add_option("--far-threshold", type = "float", default = 3.84e-07, help = "FAR threshold considered for an event to be public, not including a trials factor. Default = 1 / month")
......@@ -287,9 +287,8 @@ class EventUploader(events.EventProcessor):
upload if a new favored event is found
"""
for key, event in sorted(self.events.items(), reverse=True):
if event['num_sent'] == 0 or (
event['candidates'] and utils.gps_now() >= self.next_event_upload(event)
):
if event['num_sent'] == 0 or event['candidates'] and ((utils.gps_now() >= self.next_event_upload(event)) or (
event['favored']['far'] > self.public_far_threshold and any([candidate['far'] <= self.public_far_threshold for candidate in event['candidates']]))):
self.process_event(event, key)
# clean out old events
......@@ -352,10 +351,8 @@ class EventUploader(events.EventProcessor):
returns event and whether the favored (maxsnr) event was updated
"""
if event['favored']:
event['candidates'].append(event['favored'])
updated, this_favored = self.favored_function(event['candidates'], event['favored'])
if updated:
event['favored'] = this_favored
......@@ -369,12 +366,22 @@ class EventUploader(events.EventProcessor):
Construct composite event. Replace far and likelihood
in maxsnr candidate with those in the minfar candidate.
"""
# add previous favored event to list so we can get
# the overall min FAR and max SNR instead of just
# over the new candidates
if favored:
candidates.append(favored)
maxsnr_candidate = max(candidates, key=self.rank_snr)
maxsnr = maxsnr_candidate['snr']
minfar_candidate = min(candidates, key=self.rank_far)
minfar = minfar_candidate['far']
# if neither the FAR nor SNR have improved compared to
# the previous favored, no update. Otherwise, make
# composite event and send an update
if favored and maxsnr <= favored['snr'] and minfar >= favored['far']:
return False, favored
else:
......@@ -408,18 +415,22 @@ class EventUploader(events.EventProcessor):
return True, maxsnr_candidate
def select_maxsnr_candidate(self, candidates, favored):
def select_maxsnr_candidate(self, candidates, favored = None):
"""
select the max snr candidate out of the candidates
select max snr candidate from candidates below
public alert threshold:
"""
maxsnr_candidate = max(candidates, key=self.rank_snr)
if favored and maxsnr_candidate['snr'] <= favored['snr']:
return False, maxsnr_candidate
# select the best candidate
new_favored = max(candidates, key=self.rank_candidate)
if not favored:
return True, new_favored
elif self.rank_candidate(new_favored) > self.rank_candidate(favored):
return True, new_favored
else:
return True, maxsnr_candidate
return False, favored
def select_minfar_candidate(self, candidates, favored):
def select_minfar_candidate(self, candidates, favored = None):
"""
select the min far candidate out of the candidates
"""
......@@ -430,12 +441,28 @@ class EventUploader(events.EventProcessor):
return True, minfar_candidate
def rank_snr(self, candidate):
def rank_candidate(self, candidate):
"""
rank a candidate based on the following criterion:
* FAR > public threshold, choose lowest FAR
* FAR <= public threshold, choose highest SNR
"""
if candidate['far'] <= self.public_far_threshold:
return True, candidate['snr'], 1. / candidate['far']
else:
return False, 1. / candidate['far'], candidate['snr']
@staticmethod
def rank_snr(candidate):
return candidate['snr']
def rank_far(self, candidate):
@staticmethod
def rank_far(candidate):
return candidate['far']
def send_favored_event(self, event, event_window):
"""
send a favored event via Kafka
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment