from lxml import etree
from urllib.parse import urlparse
from celery import chain
from . import circulars
from . import detchar
from . import gcn
from . import gracedb
from . import ligo_fermi_skymaps
from . import lvalert
from . import raven
[docs]@gcn.handler(gcn.NoticeType.SNEWS,
queue='exttrig',
shared=False)
def handle_snews_gcn(payload):
"""Handles the payload from SNEWS alerts.
Prepares the alert to be sent to graceDB as 'E' events."""
root = etree.fromstring(payload)
# Get TrigID and Test Event Boolean
trig_id = root.find("./What/Param[@name='TrigID']").attrib['value']
test_event = root.find("./What/Group[@name='Trigger_ID']" +
"/Param[@name='Test']").attrib['value']
event_observatory = 'SNEWS'
query = 'group: External pipeline: {} grbevent.trigger_id = "{}"'.format(
event_observatory, trig_id)
events = gracedb.get_events(query=query)
if events:
assert len(events) == 1, 'Found more than one matching GraceDb entry'
event, = events
graceid = event['graceid']
gracedb.replace_event(graceid, payload)
return
elif test_event == 'true':
graceid = gracedb.create_event(filecontents=payload,
search='Supernova',
group='Test',
pipeline=event_observatory)
else:
graceid = gracedb.create_event(filecontents=payload,
search='Supernova',
group='External',
pipeline=event_observatory)
event = gracedb.get_event(graceid)
start, end = event['gpstime'], event['gpstime']
# Pre-start and post-end padding is applied by check_vectors
detchar.check_vectors(event, event['graceid'], start, end)
[docs]@gcn.handler(gcn.NoticeType.FERMI_GBM_ALERT,
gcn.NoticeType.FERMI_GBM_FLT_POS,
gcn.NoticeType.FERMI_GBM_GND_POS,
gcn.NoticeType.FERMI_GBM_FIN_POS,
gcn.NoticeType.SWIFT_BAT_GRB_ALERT,
gcn.NoticeType.SWIFT_BAT_GRB_LC,
gcn.NoticeType.FERMI_GBM_SUBTHRESH,
queue='exttrig',
shared=False)
def handle_grb_gcn(payload):
"""Handles the payload from Fermi and Swift alerts.
Prepares the alert to be sent to graceDB as 'E' events."""
root = etree.fromstring(payload)
u = urlparse(root.attrib['ivorn'])
stream_path = u.path
# Get TrigID
trig_id = root.find("./What/Param[@name='TrigID']").attrib['value']
stream_obsv_dict = {'/SWIFT': 'Swift',
'/Fermi': 'Fermi'}
event_observatory = stream_obsv_dict[stream_path]
query = 'group: External pipeline: {} grbevent.trigger_id = "{}"'.format(
event_observatory, trig_id)
events = gracedb.get_events(query=query)
if events:
assert len(events) == 1, 'Found more than one matching GraceDb entry'
event, = events
graceid = event['graceid']
gracedb.replace_event(graceid, payload)
else:
graceid = gracedb.create_event(filecontents=payload,
search='GRB',
group='External',
pipeline=event_observatory)
event = gracedb.get_event(graceid)
start = event['gpstime']
end = start + event['extra_attributes']['GRB']['trigger_duration']
detchar.check_vectors(event, event['graceid'], start, end)
[docs]@lvalert.handler('superevent',
'mdc_superevent',
'test_superevent',
'external_fermi',
'external_fermi_grb',
'external_grb',
'external_swift',
shared=False)
def handle_grb_lvalert(alert):
"""Parse an LVAlert message related to superevents/GRB external triggers
and dispatch it to other tasks.
Notes
-----
This LVAlert message handler is triggered by creating a new superevent or
GRB external trigger event, or applying the ``EM_COINC`` label to any
superevent:
* Any new event triggers a coincidence search with
:meth:`gwcelery.tasks.raven.coincidence_search`.
* The ``EM_COINC`` label triggers the creation of a combined GW-GRB sky map
using :meth:`gwcelery.tasks.ligo_fermi_skymaps.create_combined_skymap`.
"""
# Determine GraceDb ID
graceid = alert['uid']
if alert['alert_type'] == 'new' and \
alert['object'].get('group', '') == 'External':
raven.coincidence_search(graceid, alert['object'], group='CBC')
raven.coincidence_search(graceid, alert['object'],
group='Burst')
elif graceid.startswith('S'):
preferred_event_id = gracedb.get_superevent(graceid)['preferred_event']
group = gracedb.get_event(preferred_event_id)['group']
if alert['alert_type'] == 'new':
raven.coincidence_search(graceid, alert['object'],
group=group,
pipelines=['Fermi', 'Swift'])
elif alert['alert_type'] == 'label_added':
if alert['data']['name'] == 'EM_COINC':
ligo_fermi_skymaps.create_combined_skymap(graceid).delay()
raven.calculate_spacetime_coincidence_far(graceid,
group).delay()
[docs]@lvalert.handler('superevent',
'mdc_superevent',
'test_superevent',
'external_snews',
'external_snews_supernova',
shared=False)
def handle_snews_lvalert(alert):
"""Parse an LVAlert message related to superevents/SN external triggers and
dispatch it to other tasks.
Notes
-----
This LVAlert message handler is triggered by creating a new superevent or
SN external trigger event, or applying the ``EM_COINC`` label to any
superevent:
* Any new event triggers a coincidence search with
:meth:`gwcelery.tasks.raven.coincidence_search`.
"""
# Determine GraceDb ID
graceid = alert['uid']
if alert['object'].get('group', '') == 'Test':
pass
elif alert['alert_type'] == 'new' and \
alert['object'].get('group', '') == 'External':
raven.coincidence_search(graceid, alert['object'],
group='Burst', pipelines=['SNEWS']).delay()
elif graceid.startswith('S'):
preferred_event_id = gracedb.get_superevent(graceid)['preferred_event']
group = gracedb.get_event(preferred_event_id)['group']
if alert['alert_type'] == 'new' and group == 'Burst':
raven.coincidence_search(graceid, alert['object'],
group=group, pipelines=['SNEWS']).delay()
[docs]@lvalert.handler('superevent',
shared=False)
def handle_emcoinc_lvalert(alert):
"""Parse an LVAlert message related to EM_COINC label application and
upload circular. We need a separate handler to prevent doubles from
occurring by adding the task to both the handle_snews_lvalert and
handle_grb_lvalert handlers.
Notes
-----
This LVAlert message handler is triggered by applying the
``EM_COINC`` label to any superevent:
* Any EM_COINC label application triggers
:meth:`gwcelery.tasks.circulars.create_emcoinc_circular`.
"""
# Determine GraceDb ID
graceid = alert['uid']
if alert['alert_type'] == 'label_added':
if alert['data']['name'] == 'EM_COINC':
canvas = chain()
canvas |= (circulars.create_emcoinc_circular.si(graceid)
|
gracedb.upload.s(
'emcoinc-circular.txt',
graceid,
'Template for the em_coinc GCN Circular',
tags=['em_follow', 'ext_coinc']
))
canvas.apply_async()