Skip to content
Snippets Groups Projects
Commit 5e90d979 authored by Brandon Piotrzkowski's avatar Brandon Piotrzkowski
Browse files

Listen to GCN Fermi GBM_ALERT channel for earlier warning; fixes #396

parent b172cf1f
No related branches found
No related tags found
1 merge request!863Listen to GCN Fermi GBM_ALERT channel for earlier warning of Fermi GRBs; fixes #396
......@@ -24,6 +24,8 @@ Changelog
- Move functions in handle_grb_gcn to asynchronous group to prevent detchar
errors from interupting sky map generation.
- Prevent sub-threhsold GRBs from overwriting high-threshold GRBs.
- Listen to initial GBM alerts for earlier warning. Prevent these events
from triggering alerts unless later updated.
1.0.1 (2022-05-09)
------------------
......
......@@ -69,7 +69,8 @@ def handle_snews_gcn(payload):
detchar.check_vectors(event, event['graceid'], start, end)
@gcn.handler(gcn.NoticeType.FERMI_GBM_FLT_POS,
@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_POS_ACK,
......@@ -87,6 +88,13 @@ def handle_grb_gcn(payload):
Filters out candidates likely to be noise. Creates external events
from the notice if new notice, otherwise updates existing event. Then
creates and/or grabs external sky map to be uploaded to the external event.
More info for these notices can be found at:
Fermi-GBM: https://gcn.gsfc.nasa.gov/fermi_grbs.html
Fermi-GBM sub: https://gcn.gsfc.nasa.gov/fermi_gbm_subthresh_archive.html
Swift: https://gcn.gsfc.nasa.gov/swift.html
INTEGRAL: https://gcn.gsfc.nasa.gov/integral.html
AGILE-MCAL: https://gcn.gsfc.nasa.gov/agile_mcal.html
"""
root = etree.fromstring(payload)
u = urlparse(root.attrib['ivorn'])
......@@ -99,6 +107,9 @@ def handle_grb_gcn(payload):
trig_id = root.find("./What/Param[@name='Trans_Num']").attrib['value']
ext_group = 'Test' if root.attrib['role'] == 'test' else 'External'
notice_type = \
int(root.find("./What/Param[@name='Packet_Type']").attrib['value'])
stream_obsv_dict = {'/SWIFT': 'Swift',
'/Fermi': 'Fermi',
'/INTEGRAL': 'INTEGRAL',
......@@ -114,19 +125,27 @@ def handle_grb_gcn(payload):
# If not at least 50% chance of GRB we will not consider it for RAVEN
likely_source = root.find("./What/Param[@name='Most_Likely_Index']")
likely_prob = root.find("./What/Param[@name='Most_Likely_Prob']")
if likely_source is not None and \
not_likely_grb = likely_source is not None and \
(likely_source.attrib['value'] != FERMI_GRB_CLASS_VALUE
or likely_prob.attrib['value'] < FERMI_GRB_CLASS_THRESH):
labels = ['NOT_GRB']
else:
labels = None
or likely_prob.attrib['value'] < FERMI_GRB_CLASS_THRESH)
# Check if initial Fermi alert. These are generally unreliable and should
# never trigger a RAVEN alert, but will give us earlier warning of a
# possible coincidence. Later notices could change this.
initial_gbm_alert = notice_type == gcn.NoticeType.FERMI_GBM_ALERT
# Check if Swift has lost lock. If so then veto
lost_lock = \
root.find("./What/Group[@name='Solution_Status']" +
"/Param[@name='StarTrack_Lost_Lock']")
if lost_lock is not None and lost_lock.attrib['value'] == 'true':
swift_veto = lost_lock is not None and lost_lock.attrib['value'] == 'true'
# Only send alerts if likely a GRB, is not a low-confidence early Fermi
# alert, and if not a Swift veto
if not_likely_grb or initial_gbm_alert or swift_veto:
labels = ['NOT_GRB']
else:
labels = None
ivorn = root.attrib['ivorn']
if 'subthresh' in ivorn.lower():
......@@ -165,8 +184,6 @@ def handle_grb_gcn(payload):
group_canvas += _launch_external_detchar.s(),
if search in {'GRB', 'MDC'}:
notice_type = \
int(root.find("./What/Param[@name='Packet_Type']").attrib['value'])
notice_date = root.find("./Who/Date").text
group_canvas += external_skymaps.create_upload_external_skymap.s(
notice_type, notice_date),
......@@ -279,23 +296,23 @@ def handle_grb_igwn_alert(alert):
if _skymaps_are_ready(alert['object'], alert['data']['name'],
'compare'):
# if both sky maps present and a coincidence, compare sky maps
se_id, ext_ids = _get_superevent_ext_ids(graceid, alert['object'],
'compare')
superevent = gracedb.get_superevent(se_id)
superevent_id, ext_ids = _get_superevent_ext_ids(
graceid, alert['object'], 'compare')
superevent = gracedb.get_superevent(superevent_id)
preferred_event_id = superevent['preferred_event']
gw_group = gracedb.get_group(preferred_event_id)
tl, th = raven._time_window(graceid, gw_group,
[alert['object']['pipeline']],
[alert['object']['search']])
raven.raven_pipeline([alert['object']], se_id, superevent,
raven.raven_pipeline([alert['object']], superevent_id, superevent,
tl, th, gw_group)
if _skymaps_are_ready(alert['object'], alert['data']['name'],
'combine'):
# if both sky maps present and a raven alert, create combined
# skymap
se_id, ext_id = _get_superevent_ext_ids(graceid, alert['object'],
'combine')
external_skymaps.create_combined_skymap(se_id, ext_id)
superevent_id, ext_id = _get_superevent_ext_ids(
graceid, alert['object'], 'combine')
external_skymaps.create_combined_skymap(superevent_id, ext_id)
elif 'EM_COINC' in alert['object']['labels']:
# if not complete, check if GW sky map; apply label to external
# event if GW sky map
......@@ -310,6 +327,19 @@ def handle_grb_igwn_alert(alert):
gracedb.create_label.si('SKYMAP_READY', ext_id)
for ext_id in alert['object']['em_events']
).delay()
elif alert['alert_type'] == 'label_removed' and \
alert['object'].get('group') == 'External':
if alert['data']['name'] == 'NOT_GRB':
# if NOT_GRB is removed, re-check publishing conditions
superevent_id = alert['object']['superevent']
superevent = gracedb.get_superevent(superevent_id)
gw_group = superevent['preferred_event_data']['group']
coinc_far_dict = {
'temporal_coinc_far': superevent['time_coinc_far'],
'spatiotemporal_coinc_far': superevent['space_coinc_far']
}
raven.trigger_raven_alert(coinc_far_dict, superevent, graceid,
alert['object'], gw_group)
@igwn_alert.handler('superevent',
......
<?xml version = '1.0' encoding = 'UTF-8'?>
<voe:VOEvent
ivorn="ivo://nasa.gsfc.gcn/Fermi#GBM_ALERT2018-05-24T09:58:26.31_548848711_0-566"
role="observation" version="2.0"
xmlns:voe="http://www.ivoa.net/xml/VOEvent/v2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ivoa.net/xml/VOEvent/v2.0 http://www.ivoa.net/xml/VOEvent/VOEvent-v2.0.xsd" >
<Who>
<AuthorIVORN>ivo://nasa.gsfc.tan/gcn</AuthorIVORN>
<Author>
<shortName>Fermi (via VO-GCN)</shortName>
<contactName>Julie McEnery</contactName>
<contactPhone>+1-301-286-1632</contactPhone>
<contactEmail>Julie.E.McEnery@nasa.gov</contactEmail>
</Author>
<Date>2018-05-24T18:35:45</Date>
<Description>This VOEvent message was created with GCN VOE version: 1.25 07feb18</Description>
</Who>
<What>
<Param name="Packet_Type" value="110" />
<Param name="Pkt_Ser_Num" value="15" />
<Param name="TrigID" value="548841234" ucd="meta.id" />
<Param name="Sequence_Num" value="0" ucd="meta.id.part" />
<Param name="Burst_TJD" value="18262" unit="days" ucd="time" />
<Param name="Burst_SOD" value="35906.31" unit="sec" ucd="time" />
<Param name="Burst_Inten" value="0" unit="cts" ucd="phot.count" />
<Param name="Data_Integ" value="0.000" unit="sec" ucd="time.interval" />
<Param name="Burst_Signif" value="0.00" unit="sigma" ucd="stat.snr" />
<Param name="Phi" value="262.01" unit="deg" ucd="pos.az.azi" />
<Param name="Theta" value="64.10" unit="deg" ucd="pos.az.zd" />
<Param name="Algorithm" value="415" unit="dn" />
<Param name="Lo_Energy" value="50000" unit="keV" />
<Param name="Hi_Energy" value="300000" unit="keV" />
<Param name="Trigger_ID" value="0x0" />
<Param name="Misc_flags" value="0x40000001" />
<Group name="Trigger_ID" >
<Param name="Def_NOT_a_GRB" value="false" />
<Param name="Target_in_Blk_Catalog" value="false" />
<Param name="Human_generated" value="false" />
<Param name="Robo_generated" value="true" />
<Param name="Spatial_Prox_Match" value="false" />
<Param name="Temporal_Prox_Match" value="false" />
<Param name="Test_Submission" value="false" />
</Group>
<Group name="Misc_Flags" >
<Param name="Values_Out_of_Range" value="false" />
<Param name="Flt_Generated" value="false" />
<Param name="Gnd_Generated" value="true" />
<Param name="CRC_Error" value="false" />
</Group>
<Param name="LightCurve_URL" value="http://heasarc.gsfc.nasa.gov/FTP/fermi/data/gbm/triggers/2018/bn180524416/quicklook/glg_lc_medres34_bn180524416.gif" ucd="meta.ref.url" />
<Param name="LocationMap_URL" value="http://heasarc.gsfc.nasa.gov/FTP/fermi/data/gbm/triggers/2018/bn180524416/quicklook/glg_locplot_all_bn180524416.png" ucd="meta.ref.url" />
<Param name="Coords_Type" value="1" unit="dn" />
<Param name="Coords_String" value="source_object" />
<Group name="Obs_Support_Info" >
<Description>The Sun and Moon values are valid at the time the VOEvent XML message was created.</Description>
<Param name="Sun_RA" value="61.53" unit="deg" ucd="pos.eq.ra" />
<Param name="Sun_Dec" value="20.86" unit="deg" ucd="pos.eq.dec" />
<Param name="Sun_Distance" value="94.75" unit="deg" ucd="pos.angDistance" />
<Param name="Sun_Hr_Angle" value="-5.25" unit="hr" />
<Param name="Moon_RA" value="187.65" unit="deg" ucd="pos.eq.ra" />
<Param name="Moon_Dec" value="1.42" unit="deg" ucd="pos.eq.dec" />
<Param name="MOON_Distance" value="59.39" unit="deg" ucd="pos.angDistance" />
<Param name="Moon_Illum" value="77.31" unit="%" ucd="arith.ratio" />
<Param name="Galactic_Long" value="264.32" unit="deg" ucd="pos.galactic.lon" />
<Param name="Galactic_Lat" value="7.50" unit="deg" ucd="pos.galactic.lat" />
<Param name="Ecliptic_Long" value="160.83" unit="deg" ucd="pos.ecliptic.lon" />
<Param name="Ecliptic_Lat" value="-50.93" unit="deg" ucd="pos.ecliptic.lat" />
</Group>
<Description>The Fermi-GBM location of a transient.</Description>
</What>
<WhereWhen>
<ObsDataLocation>
<ObservatoryLocation id="GEOLUN" />
<ObservationLocation>
<AstroCoordSystem id="UTC-FK5-GEO" />
<AstroCoords coord_system_id="UTC-FK5-GEO">
<Time unit="s">
<TimeInstant>
<ISOTime>2018-05-24T09:58:26.31</ISOTime>
</TimeInstant>
</Time>
<Position2D unit="deg">
<Name1>RA</Name1>
<Name2>Dec</Name2>
<Value2>
<C1>0.0</C1>
<C2>0.0</C2>
</Value2>
<Error2Radius>0.000</Error2Radius>
</Position2D>
</AstroCoords>
</ObservationLocation>
</ObsDataLocation>
<Description>The RA,Dec coordinates are of the type: source_object.</Description>
</WhereWhen>
<How>
<Description>Fermi Satellite, GBM Instrument</Description>
<Reference uri="http://gcn.gsfc.nasa.gov/fermi.html" type="url" />
</How>
<Why importance="0.95">
<Inference probability="1.0">
<Concept>process.variation.burst;em.gamma</Concept>
</Inference>
</Why>
<Description>
</Description>
</voe:VOEvent>
......@@ -155,6 +155,38 @@ def test_handle_noise_fermi_event(mock_check_vectors,
mock_get_upload_external_skymap.assert_called_once()
@patch('gwcelery.tasks.external_skymaps.create_external_skymap')
@patch('gwcelery.tasks.external_skymaps.get_upload_external_skymap.run')
@patch('gwcelery.tasks.gracedb.get_events', return_value=[])
@patch('gwcelery.tasks.gracedb.create_event.run', return_value={
'graceid': 'E1', 'gpstime': 1, 'instruments': '', 'pipeline': 'Fermi',
'search': 'GRB',
'extra_attributes': {'GRB': {'trigger_duration': 1, 'trigger_id': 123,
'ra': 0., 'dec': 0., 'error_radius': 0.}},
'links': {'self': 'https://gracedb.ligo.org/events/E356793/'}})
@patch('gwcelery.tasks.detchar.check_vectors.run')
def test_handle_initial_fermi_event(mock_check_vectors,
mock_create_event,
mock_get_events,
mock_get_upload_external_skymap,
mock_create_external_skymap):
text = read_binary(data, 'fermi_initial_grb_gcn.xml')
external_triggers.handle_grb_gcn(payload=text)
mock_get_events.assert_called_once_with(query=(
'group: External pipeline: '
'Fermi grbevent.trigger_id '
'= "548841234"'))
# Note that this is the exact ID in the .xml file
mock_create_event.assert_called_once_with(filecontents=text,
search='GRB',
pipeline='Fermi',
group='External',
labels=['NOT_GRB'])
mock_check_vectors.assert_called_once()
mock_get_upload_external_skymap.assert_called_once()
mock_create_external_skymap.assert_not_called()
@pytest.mark.parametrize('filename',
['fermi_grb_gcn.xml',
'fermi_noise_gcn.xml',
......@@ -261,6 +293,45 @@ def test_handle_skymap_comparison(mock_get_event, mock_get_superevent,
-5, 1, 'CBC')
@patch('gwcelery.tasks.raven.trigger_raven_alert')
@patch('gwcelery.tasks.gracedb.get_superevent',
return_value={'superevent_id': 'S1234',
'preferred_event': 'G1234',
'preferred_event_data': {
'group': 'CBC'},
'time_coinc_far': 1e-9,
'space_coinc_far': 1e-10})
def test_handle_label_removed(mock_get_superevent,
mock_trigger_raven_alert):
alert = {"uid": "E1212",
"alert_type": "label_removed",
"data": {"name": "NOT_GRB"},
"object": {
"graceid": "E1212",
"group": "External",
"labels": ["EM_COINC", "EXT_SKYMAP_READY", "SKYMAP_READY"],
"superevent": "S1234",
"pipeline": "Fermi",
"search": "GRB"
}
}
superevent = {'superevent_id': 'S1234',
'preferred_event': 'G1234',
'preferred_event_data': {
'group': 'CBC'},
'time_coinc_far': 1e-9,
'space_coinc_far': 1e-10}
coinc_far_dict = {
'temporal_coinc_far': 1e-9,
'spatiotemporal_coinc_far': 1e-10
}
external_triggers.handle_grb_igwn_alert(alert)
mock_trigger_raven_alert.assert_called_once_with(
coinc_far_dict, superevent, alert['uid'],
alert['object'], 'CBC'
)
@patch('gwcelery.tasks.external_skymaps.create_combined_skymap')
def test_handle_skymap_combine(mock_create_combined_skymap):
alert = {"uid": "E1212",
......
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