Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • emfollow/gwcelery
  • leo-singer/gwcelery
  • deep.chatterjee/gwcelery
  • michael-coughlin/gwcelery
  • brandon.piotrzkowski/gwcelery
  • geoffrey.mo/gwcelery
  • vinaya.valsan/gwcelery
  • patrick.godwin/gwcelery
  • john-veitch/gwcelery
  • roberto.depietri/gwcelery
  • veronica.villa/gwcelery
  • teresa.slaven-blair/gwcelery
  • cody.messick/gwcelery
  • sarah.antier/gwcelery
  • shreya.anand/gwcelery
  • ron.tapia/gwcelery
  • andrew.toivonen/gwcelery
  • adam-zadrozny/gwcelery
  • duncanmmacleod/gwcelery
  • sushant.sharma-chaudhary/gwcelery
  • manleong.chan/gwcelery
  • satyanarayan.raypitambarmohapatra/gwcelery
  • yu-kuang.chu/gwcelery
  • jacob.golomb/gwcelery
  • daniele.monteleone/gwcelery
  • albertcheng.zhang/gwcelery
  • colm.talbot/gwcelery
  • gaurav.waratkar/gwcelery
  • yun-jing.huang/gwcelery
29 results
Show changes
Commits on Source (22)
Showing
with 263 additions and 91 deletions
......@@ -6,6 +6,9 @@ if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# Create log directories.
mkdir -p $HOME/.local/state/log
# Add user site directory to the PATH. On Linux, this is usuall ~/.local/bin.
export PATH="$(python3.11 -m site --user-base)/bin${PATH+:${PATH}}"
......
"~/.local/state/log/*.log" {
compress
dateext
missingok
rotate 4
weekly
}
......@@ -23,7 +23,6 @@ htmlcov
appendonly.aof
celerybeat-schedule
*.pid
*.log
*.rdb
*.sock
......
Changelog
=========
2.5.2 (unreleased)
2.6.0 (unreleased)
------------------
- Update bilby_pipe to v1.4.2.
- Enabled SSM triggers and HasSSM source property
- Rework determining the preferred external event using a keyfunc method
......@@ -44,6 +42,38 @@ Changelog
- Fix coincidence search so SubGRB events can only be found in coincidence
with CBC-like events (group is CBC or from CWB BBH search).
- Don't download p-astro file for SSM alert canvas, since they are not required
by policy.
- Automatically rotate and compress log files to avoid running out of disk
space. Logs are rotated and compressed once per week and deleted after one
month.
- Logs are now stored in the directory ``~/.local/state/log``, which is the
per-user equivalent of ``/var/log`` (at least according to the conventions
of `systemd <https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Specifiers>`_).
- Rename the certificate renewal script from ``renew-cert.sh`` to ``cron.sh``
to reflect the fact that it is now responsible for additional maintenance
tasks including log rotation.
- Fixed the broken link at the combined sky map png which was pointing to a
wrong URL.
- Plot external sky maps with contour lines and annotate with contained
areas; remove central RA/dec position.
2.5.2 "Cactus cat" (2024-11-18)
-------------------------------
- Update ``bilby_pipe`` to v1.4.2, ``GWSkyNet`` to v2.5.1, and
``ligo.skymap`` to v2.1.2.
- Roll back ``ligo-followup-advocate`` to 1.2.9 until SSM triggers are
planned in production.
- Change all external ingestion handlers and functions to concurrency of 1.
2.5.1 "Cactus cat" (2024-08-20)
-------------------------------
......@@ -55,7 +85,7 @@ Changelog
2.5.0 "Cactus cat" (2024-08-08)
-------------------------------
- Update ``ligo-rrt-chat``` to v0.1.5, ``ligo-followup-advocate`` to v1.2.10, and
- Update ``ligo-rrt-chat`` to v0.1.5, ``ligo-followup-advocate`` to v1.2.10, and
``ligo.skymap`` to v2.0.1.
- Change functions calls to prepare for NumPy 2.0 release.
......
#!/usr/bin/bash
# Renew the robot certificate from the Kerberos keytab.
# Perform hourly maintenance activities.
# Stop on error.
set -e
# This script is designed to be run by cron.
......@@ -11,6 +13,7 @@ kinit_keytab() {
kinit "${principal}" -k -t "$1"
}
# Renew GraceDB credentials.
X509_USER_CERT="$HOME/.globus/usercert.pem"
X509_USER_KEY="$HOME/.globus/userkey.pem"
kinit_keytab "${HOME}/.globus/krb5.keytab"
......@@ -19,5 +22,9 @@ GRID_PROXY_PATH="$(ecp-cert-info -path)"
cp "${GRID_PROXY_PATH}" "${X509_USER_CERT}"
cp "${GRID_PROXY_PATH}" "${X509_USER_KEY}"
# Renew CVMFS credentials.
kinit_keytab "${HOME}/read-cvmfs.keytab"
chronic htgettoken -v -a vault.ligo.org -i igwn -r read-cvmfs-${USER} --scopes=read:/virgo --credkey=read-cvmfs-${USER}/robot/${USER}.ligo.caltech.edu --nooidc
# Rotate log files.
logrotate --state ~/.local/state/logrotate.status ~/.config/logrotate.conf
......@@ -114,3 +114,16 @@ systems)::
If you have to make any changes to your Redis configuration, be sure to restart
the Redis daemon.
Cron
----
For deployments of GWCelery at
`LIGO Data Grid computing sites <https://computing.docs.ligo.org/guide/computing-centres/ldg/>`_,
it is recommended that you configure :manpage:`cron <cron(8)>` to call the
script ``cron.sh`` once per hour by adding the following to your
:manpage:`crontab <crontab(1)>`::
@hourly $HOME/cron.sh
This script automatically renews credentials and rotates log files.
......@@ -3,7 +3,7 @@ accounting_group_user = cody.messick
universe = local
getenv = true
executable = /usr/bin/env
log = gwcelery-condor.log
log = .local/state/log/gwcelery-condor.log
on_exit_remove = false
request_disk = 7GB
JobBatchName = gwcelery
......@@ -12,46 +12,46 @@ JobBatchName = gwcelery
job_max_vacate_time = 20
kill_sig = SIGKILL
arguments = "gwcelery beat -f gwcelery-beat.log"
arguments = "gwcelery beat -f .local/state/log/gwcelery-beat.log"
description = gwcelery-beat
queue
arguments = "gwcelery flask -l info -f gwcelery-flask.log run --with-threads --host 127.0.0.1"
arguments = "gwcelery flask -l info -f .local/state/log/gwcelery-flask.log run --with-threads --host 127.0.0.1"
description = gwcelery-flask
queue
arguments = "gwcelery flower --address=127.0.0.1 --log-file-prefix=gwcelery-flower.log"
arguments = "gwcelery flower --address=127.0.0.1 --log-file-prefix=.local/state/log/gwcelery-flower.log"
description = gwcelery-flower
queue
# FIXME: The GraceDB tasks are not very computationally intensive, but take a
# very long time to execute. Manually bump up the concurrency well past the
# number of hardware threads until the GraceDB API throughput is improved.
arguments = "gwcelery worker -l info -n gwcelery-worker@%h -f %n.log -Q celery --igwn-alert --email --concurrency 32 --max-memory-per-child 2097152"
arguments = "gwcelery worker -l info -n gwcelery-worker@%h -f .local/state/log/%n.log -Q celery --igwn-alert --email --concurrency 32 --max-memory-per-child 2097152"
description = gwcelery-worker
queue
arguments = "gwcelery worker -l info -n gwcelery-exttrig-worker@%h -f %n.log -Q exttrig -c 1 --prefetch-multiplier 1"
arguments = "gwcelery worker -l info -n gwcelery-exttrig-worker@%h -f .local/state/log/%n.log -Q exttrig -c 1 --prefetch-multiplier 1"
description = gwcelery-exttrig-worker
queue
arguments = "gwcelery worker -l info -n gwcelery-superevent-worker@%h -f %n.log -Q superevent -c 1 --prefetch-multiplier 1"
arguments = "gwcelery worker -l info -n gwcelery-superevent-worker@%h -f .local/state/log/%n.log -Q superevent -c 1 --prefetch-multiplier 1"
description = gwcelery-superevent-worker
queue
arguments = "gwcelery worker -l info -n gwcelery-voevent-worker@%h -f %n.log -Q voevent -P solo"
arguments = "gwcelery worker -l info -n gwcelery-voevent-worker@%h -f .local/state/log/%n.log -Q voevent -P solo"
description = gwcelery-voevent-worker
queue
arguments = "gwcelery worker -l info -n gwcelery-kafka-worker@%h -f %n.log -Q kafka -P solo"
arguments = "gwcelery worker -l info -n gwcelery-kafka-worker@%h -f .local/state/log/%n.log -Q kafka -P solo"
description = gwcelery-kafka-worker
queue
arguments = "gwcelery worker -l info -n gwcelery-em-bright-worker@%h -f %n.log -Q em-bright -c 2 --prefetch-multiplier 1"
arguments = "gwcelery worker -l info -n gwcelery-em-bright-worker@%h -f .local/state/log/%n.log -Q em-bright -c 2 --prefetch-multiplier 1"
description = gwcelery-em-bright-worker
queue
arguments = "gwcelery worker -l info -n gwcelery-highmem-worker@%h -f %n.log -Q highmem -c 2 --prefetch-multiplier 1"
arguments = "gwcelery worker -l info -n gwcelery-highmem-worker@%h -f .local/state/log/%n.log -Q highmem -c 2 --prefetch-multiplier 1"
description = gwcelery-highmem-worker
queue
......@@ -65,10 +65,10 @@ universe = vanilla
executable = /bin/env
arguments = "gwcelery-condor-submit-helper gwcelery worker -l info -n gwcelery-multiprocessing-worker@%h -f %n.log -Q multiprocessing -c 1 --prefetch-multiplier 1"
arguments = "gwcelery-condor-submit-helper gwcelery worker -l info -n gwcelery-multiprocessing-worker@%h -f .local/state/log/%n.log -Q multiprocessing -c 1 --prefetch-multiplier 1"
description = gwcelery-multiprocessing-worker
queue
arguments = "--unset OMP_NUM_THREADS gwcelery-condor-submit-helper gwcelery worker -l info -n gwcelery-openmp-worker-$(Process)@%h -f %n.log -Q openmp -c 1 --prefetch-multiplier 1"
arguments = "--unset OMP_NUM_THREADS gwcelery-condor-submit-helper gwcelery worker -l info -n gwcelery-openmp-worker-$(Process)@%h -f .local/state/log/%n.log -Q openmp -c 1 --prefetch-multiplier 1"
description = gwcelery-openmp-worker-$(Process)
queue 15
......@@ -23,6 +23,7 @@ from ligo.skymap.moc import bayestar_adaptive_grid
from ligo.skymap.plot.bayes_factor import plot_bayes_factor
from .. import _version, app
from ..util import closing_figures
from ..util.cmdline import handling_system_exit
from ..util.tempfile import NamedTemporaryFile
from . import gracedb, skymaps
......@@ -449,8 +450,6 @@ def read_upload_skymap_from_base64(event, skymap_str):
"""
graceid = event['graceid']
ra = event['extra_attributes']['GRB']['ra']
dec = event['extra_attributes']['GRB']['dec']
# Decode base64 encoded string to bytes string
skymap_data = b64decode(skymap_str)
......@@ -475,7 +474,7 @@ def read_upload_skymap_from_base64(event, skymap_str):
event['pipeline']),
['sky_loc']),
skymaps.plot_allsky.si(skymap_data, ra=ra, dec=dec)
skymaps.plot_allsky.si(skymap_data)
|
gracedb.upload.s(event['pipeline'].lower() + '_skymap.png',
graceid,
......@@ -775,7 +774,7 @@ def create_upload_external_skymap(event, notice_type, notice_date):
extra_sentence),
['sky_loc'])
|
skymaps.plot_allsky.si(skymap_data, ra=ra, dec=dec)
skymaps.plot_allsky.si(skymap_data)
|
gracedb.upload.s(event['pipeline'].lower() + '_skymap.png',
graceid,
......@@ -787,6 +786,7 @@ def create_upload_external_skymap(event, notice_type, notice_date):
@app.task(shared=False)
@closing_figures()
def plot_overlap_integral(coinc_far_dict, superevent, ext_event,
var_label=r"\mathcal{I}_{\Omega}"):
"""Plot and upload visualization of the sky map overlap integral computed
......
......@@ -97,6 +97,29 @@ def create_label(label, graceid):
raise
@task(ignore_result=True, shared=False)
@catch_retryable_http_errors
def create_label_with_log(log_message, label, tags, superevent_id):
"""Create a label with a log for a superevent in GraceDB."""
try:
client.superevents[superevent_id].logs.create(
comment=log_message,
label=label,
tags=tags
)
except HTTPError as e:
# If we got a 400 error because no change was made, then ignore
# the exception and return successfully to preserve idempotency.
messages = {
b'"The \'ADVREQ\' label cannot be applied to request a signoff '
b'because a related signoff already exists."',
b'"The fields superevent, name must make a unique set."'
}
if e.response.content not in messages:
raise
@task(ignore_result=True, shared=False)
@catch_retryable_http_errors
def remove_label(label, graceid):
......
......@@ -792,7 +792,8 @@ def earlywarning_preliminary_alert(event, alert, alert_type='preliminary',
em_bright_filename = 'em_bright.json'
elif alert_group == 'cbc':
skymap_filename = 'bayestar.multiorder.fits'
p_astro_filename = alert_pipeline + '.p_astro.json'
p_astro_filename = alert_pipeline + '.p_astro.json' \
if alert_search != 'ssm' else None
em_bright_filename = 'em_bright.json'
elif alert_group == 'burst':
skymap_filename = event['pipeline'].lower() + '.multiorder.fits'
......@@ -1067,6 +1068,7 @@ def earlywarning_preliminary_initial_update_alert(
"""
labels = superevent['labels']
superevent_id = superevent['superevent_id']
search = superevent['preferred_event_data']['search'].lower()
if 'INJ' in labels:
return
......@@ -1082,7 +1084,7 @@ def earlywarning_preliminary_initial_update_alert(
combined_skymap_needed = False
skymap_needed = (skymap_filename is None)
em_bright_needed = (em_bright_filename is None)
p_astro_needed = (p_astro_filename is None)
p_astro_needed = False if search == 'ssm' else (p_astro_filename is None)
raven_coinc = ('RAVEN_ALERT' in labels and bool(superevent['em_type']))
if raven_coinc:
ext_labels = gracedb.get_labels(superevent['em_type'])
......@@ -1142,7 +1144,7 @@ def earlywarning_preliminary_initial_update_alert(
message = 'Combined LVK-external sky map copied from {0}'.format(
ext_id)
message_png = (
'Mollweide projection of <a href="/api/events/{se_id}/files/'
'Mollweide projection of <a href="/api/superevents/{se_id}/files/'
'{filename}">{filename}</a>, copied from {ext_id}').format(
se_id=superevent_id,
ext_id=ext_id,
......@@ -1277,9 +1279,15 @@ def earlywarning_preliminary_initial_update_alert(
download_andor_expose_group = [
gracedb.download.si(em_bright_filename, superevent_id) if
em_bright_filename is not None else identity.s(None),
gracedb.download.si(p_astro_filename, superevent_id) if
p_astro_filename is not None else identity.s(None),
]
if search != 'ssm':
download_andor_expose_group += [
gracedb.download.si(p_astro_filename, superevent_id) if
p_astro_filename is not None else identity.s(None)
]
else:
# for SSM events skip downloading p-astro file
download_andor_expose_group += [identity.s(None)]
high_profile_canvas = identity.si()
voevent_canvas = _create_voevent.s(
......
......@@ -30,14 +30,29 @@ def check_high_profile(skymap, em_bright,
if far_list_sorted[0]["group"] == "Burst" and \
far_list_sorted[0]["search"] != "BBH":
gracedb.create_label.si(
'HIGH_PROFILE', superevent_id).delay()
return "Event with the lowest FAR is a Burst event. Applying label"
gracedb.create_label_with_log(
log_message='Superevent labeled '
'<font color="red">HIGH_PROFILE</font> '
'since event with lowest FAR is a Burst event.',
label='HIGH_PROFILE',
tags=['em_follow'],
superevent_id=superevent_id)
return
# annotation number condition
preferred_event = superevent['preferred_event_data']
if preferred_event["search"] == "SSM":
gracedb.create_label_with_log(
log_message='Superevent labeled '
'<font color="red">HIGH_PROFILE</font> '
'since preferred event is from SSM search.',
label='HIGH_PROFILE',
tags=['em_follow'],
superevent_id=superevent_id)
return
if preferred_event["group"] == "CBC":
em_bright_dict = json.loads(em_bright)
has_remnant = em_bright_dict['HasRemnant']
pastro_dict = json.loads(p_astro)
......@@ -50,10 +65,41 @@ def check_high_profile(skymap, em_bright,
cl = 90
result = crossmatch(gw_skymap, contours=[cl / 100])
sky_area = result.contour_areas[0]
# This is commented out while we figure out the distance cutoff
# is_far_away = not (gw_skymap.meta.get('distmean', np.nan) < 2000)
if p_terr < 0.5:
if (p_bns > 0.1 or p_nsbh > 0.1 or has_remnant > 0.1 or sky_area < 100): # noqa: E501
gracedb.create_label.si(
'HIGH_PROFILE', superevent_id).delay()
return "Annotations condition satisfied. Applying label"
if p_bns > 0.1:
gracedb.create_label_with_log(
log_message='Superevent labeled '
'<font color="red">HIGH_PROFILE</font> since p_BNS >10%.',
label='HIGH_PROFILE',
tags=['em_follow'],
superevent_id=superevent_id)
return
elif p_nsbh > 0.1:
gracedb.create_label_with_log(
log_message='Superevent labeled '
'<font color="red">HIGH_PROFILE</font> since p_NSBH >10%.',
label='HIGH_PROFILE',
tags=['em_follow'],
superevent_id=superevent_id)
return
elif has_remnant > 0.1:
gracedb.create_label_with_log(
log_message='Superevent labeled '
'<font color="red">HIGH_PROFILE</font> since '
'p_HasRemnant > 10%.',
label='HIGH_PROFILE',
tags=['em_follow'],
superevent_id=superevent_id)
return
elif sky_area < 100:
gracedb.create_label_with_log(
log_message='Superevent labeled '
'<font color="red">HIGH_PROFILE</font> since area of '
'90% confidence level in the skymap is < 100 sq.deg.',
label='HIGH_PROFILE',
tags=['em_follow'],
superevent_id=superevent_id)
return
return "No conditions satisfied. Skipping"
......@@ -115,7 +115,7 @@ def fits_header(filecontents, filename):
@app.task(shared=False)
@closing_figures()
def plot_allsky(filecontents, ra=None, dec=None):
def plot_allsky(filecontents):
"""Plot a Mollweide projection of a sky map using the command-line tool
:doc:`ligo-skymap-plot <ligo.skymap:tool/ligo_skymap_plot>`.
"""
......@@ -125,12 +125,8 @@ def plot_allsky(filecontents, ra=None, dec=None):
with NamedTemporaryFile(mode='rb', suffix='.png') as pngfile, \
NamedTemporaryFile(content=filecontents) as fitsfile, \
handling_system_exit():
if ra is not None and dec is not None:
ligo_skymap_plot.main([fitsfile.name, '-o', pngfile.name,
'--annotate', '--radec', str(ra), str(dec)])
else:
ligo_skymap_plot.main([fitsfile.name, '-o', pngfile.name,
'--annotate', '--contour', '50', '90'])
ligo_skymap_plot.main([fitsfile.name, '-o', pngfile.name,
'--annotate', '--contour', '50', '90'])
return pngfile.read()
......
......@@ -48,9 +48,10 @@
</div>
</div>
<div class="form-group col-md">
<label for=gracedb-host>LVAlert Host</label>
<label for=gracedb-host>igwn-alert [options]</label>
<div class="input-group">
<input id=gracedb-host class=form-control readonly value="{{ conf.lvalert_host }}">
<input id=gracedb-host class=form-control readonly
value="-s {{ conf.igwn_alert_server }} -g {{ conf.igwn_alert_group }}">
</div>
</div>
<div class="form-group col-md">
......
No preview for this file type
......@@ -48,6 +48,15 @@ def test_create_label(mock_gracedb):
'label')
@patch('gwcelery.tasks.gracedb.client')
def test_create_label_with_log(mock_gracedb):
gracedb.create_label_with_log('log_message', 'label', ['tag'], 'graceid')
mock_gracedb.superevents['graceid'].logs.create.assert_called_once_with(
comment='log_message',
label='label',
tags=['tag'])
@patch('gwcelery.tasks.gracedb.client')
def test_remove_label(mock_gracedb):
gracedb.remove_label('label', 'graceid')
......
......@@ -826,11 +826,14 @@ def _mock_get_log(se_id):
@pytest.mark.parametrize( # noqa: F811
'labels,superevent_id,ext_id',
[[[], 'S1234', 'E1'],
[['EM_COINC', 'RAVEN_ALERT'], 'S1234', 'E2'],
[['EM_COINC', 'RAVEN_ALERT', 'COMBINEDSKYMAP_READY'], 'S1234', 'E3'],
[['EM_COINC', 'RAVEN_ALERT', 'COMBINEDSKYMAP_READY'], 'S2468', 'E3']])
'labels,superevent_id,ext_id,search',
[[[], 'S1234', 'E1', 'AllSky'],
[[], 'S1234', 'E1', 'SSM'],
[['EM_COINC', 'RAVEN_ALERT'], 'S1234', 'E2', 'AllSky'],
[['EM_COINC', 'RAVEN_ALERT', 'COMBINEDSKYMAP_READY'], 'S1234',
'E3', 'AllSky'],
[['EM_COINC', 'RAVEN_ALERT', 'COMBINEDSKYMAP_READY'], 'S2468',
'E3', 'AllSky']])
@patch('gwcelery.tasks.gracedb.expose._orig_run', return_value=None)
@patch('gwcelery.tasks.gracedb.get_log',
side_effect=_mock_get_log)
......@@ -853,7 +856,7 @@ def test_handle_superevent_initial_alert(mock_create_initial_circular,
mock_create_voevent,
mock_create_tag, mock_get_log,
mock_expose, labels,
superevent_id, ext_id):
superevent_id, ext_id, search):
"""Test that the ``ADVOK`` label triggers an initial alert.
This test varies the labels in the superevent and external event in order
to test the non-RAVEN alerts, RAVEN alerts without a combined sky map, and
......@@ -867,6 +870,7 @@ def test_handle_superevent_initial_alert(mock_create_initial_circular,
'category': 'Production',
'superevent_id': superevent_id,
'em_type': ext_id if labels else '',
'preferred_event_data': dict(search=search),
'category': 'Production'}
}
combined_skymap_needed = ('COMBINEDSKYMAP_READY' in labels)
......@@ -883,19 +887,45 @@ def test_handle_superevent_initial_alert(mock_create_initial_circular,
# Run function under test
orchestrator.handle_superevent(alert)
mock_create_voevent.assert_called_once_with(
superevent_id, 'initial', BBH=0.02, BNS=0.94, NSBH=0.03, ProbHasNS=0.0,
ProbHasRemnant=0.0, Terrestrial=0.01, internal=False, open_alert=True,
voevent_kwargs = dict(
ProbHasRemnant=0.0, ProbHasNS=0.0, internal=False, open_alert=True,
skymap_filename='foobar.multiorder.fits,0', skymap_type='foobar',
raven_coinc='RAVEN_ALERT' in labels, HasMassGap=0.0,
Significant=1, # this field is true for initial alerts
combined_skymap_filename=(combined_skymap_filename if
combined_skymap_needed else None))
combined_skymap_needed else None)
)
download_calls = (
superevent_initial_alert_download(
'foobar.multiorder.fits,0',
superevent_id
),
superevent_initial_alert_download('em_bright.json,0', superevent_id)
)
public_tag_calls = [
call('foobar.multiorder.fits,0', 'public', superevent_id),
call('em_bright.json,0', 'public', superevent_id),
call('S1234-Initial-1.xml', 'public', superevent_id)
]
if search != "SSM":
# For SSM alerts there is no p-astro information
voevent_kwargs.update(
dict(BBH=0.02, BNS=0.94, NSBH=0.03, Terrestrial=0.01)
)
download_calls += (
superevent_initial_alert_download(
'p_astro.json,0',
superevent_id
),
)
public_tag_calls.append(
call('p_astro.json,0', 'public', superevent_id),
)
mock_create_voevent.assert_called_once()
assert mock_create_voevent.call_args.args == (superevent_id, 'initial')
assert set(voevent_kwargs) == set(mock_create_voevent.call_args.kwargs)
mock_alerts_send.assert_called_once_with(
(superevent_initial_alert_download('foobar.multiorder.fits,0',
superevent_id),
superevent_initial_alert_download('em_bright.json,0', superevent_id),
superevent_initial_alert_download('p_astro.json,0', superevent_id)) +
download_calls +
((6 if combined_skymap_needed else 4) * (None,)),
alert['object'], 'initial', raven_coinc='RAVEN_ALERT' in labels,
combined_skymap_filename=combined_skymap_filename)
......@@ -904,12 +934,7 @@ def test_handle_superevent_initial_alert(mock_create_initial_circular,
mock_create_emcoinc_circular.assert_called_once_with(superevent_id)
else:
mock_create_initial_circular.assert_called_once_with(superevent_id)
mock_create_tag.assert_has_calls(
[call('foobar.multiorder.fits,0', 'public', superevent_id),
call('em_bright.json,0', 'public', superevent_id),
call('p_astro.json,0', 'public', superevent_id),
call('S1234-Initial-1.xml', 'public', superevent_id)],
any_order=True)
mock_create_tag.assert_has_calls(public_tag_calls, any_order=True)
mock_expose.assert_called_once_with(superevent_id)
......
......@@ -16,11 +16,12 @@ skymap_large = read_binary(data, 'MS220722v_bayestar.multiorder.fits')
# 3. p_BNS check ---> True
# 4. p_NSBH check ---> True
# 5. skymap check ---> True
# 6. Simple BBH ---> False
# 7. Burst but low far ---> False
# 8. High p-terrestrial ---> False
# 9. Burst BBH low far ---> False
# 10. HIGH_PROFILE_applied-> False
# 6. SSM preferred ---> True
# 7. Simple BBH ---> False
# 8. Burst but low far ---> False
# 9. High p-terrestrial ---> False
# 10. Burst BBH low far ---> False
# 11. HIGH_PROFILE_applied-> False
def get_event(graceid):
......@@ -60,6 +61,15 @@ def get_event(graceid):
'far': 1e-10,
'gpstime': 1234,
}
elif graceid == 'G468':
event = {
'group': 'CBC',
'pipeline': 'gstlal',
'search': 'SSM',
'graceid': graceid,
'far': 1e-10,
'gpstime': 1234,
}
return event
......@@ -85,6 +95,10 @@ def get_event(graceid):
{'HasNS': 0.0, 'HasRemnant': 0.0, 'HasMassGap': 0.0},
{"BNS": 0.0, "NSBH": 0.0, "BBH": 0.9, "Terrestrial": 0.1},
skymap_small, True],
[{'labels': [], 'gw_events': ['G123', 'G468']},
{'HasNS': 0.0, 'HasSSM': 1.0, 'HasMassGap': 0.0},
{"BNS": 0.0, "NSBH": 0.0, "BBH": 0.9, "Terrestrial": 0.1},
skymap_large, True],
[{'labels': [], 'gw_events': ['G123']},
{'HasNS': 0.0, 'HasRemnant': 0.0, 'HasMassGap': 0.0},
{"BNS": 0.0, "NSBH": 0.0, "BBH": 1.0, "Terrestrial": 0.0},
......@@ -110,18 +124,20 @@ def test_high_profile(monkeypatch, superevent, embright,
pastro, skymap, result):
embright = json.dumps(embright)
pastro = json.dumps(pastro)
superevent.update({'superevent_id': 'S123',
'preferred_event_data': get_event('G123')})
mock_create_label = Mock()
monkeypatch.setattr('gwcelery.tasks.gracedb.create_label.run',
mock_create_label)
if 'G468' in superevent['gw_events']:
superevent.update({'superevent_id': 'S123',
'preferred_event_data': get_event('G468')})
else:
superevent.update({'superevent_id': 'S123',
'preferred_event_data': get_event('G123')})
mock_create_label_with_log = Mock()
monkeypatch.setattr('gwcelery.tasks.gracedb.create_label_with_log.run',
mock_create_label_with_log)
monkeypatch.setattr('gwcelery.tasks.gracedb.get_event.run',
get_event)
rrt_utils.check_high_profile(skymap, embright,
pastro, superevent)
if result is True:
mock_create_label.assert_called_once_with(
"HIGH_PROFILE", "S123"
)
mock_create_label_with_log.assert_called_once()
elif result is False:
mock_create_label.assert_not_called()
mock_create_label_with_log.assert_not_called()
......@@ -89,18 +89,6 @@ def test_plot_allsky(mock_plot):
assert cmdline[2].endswith('.png')
@patch('ligo.skymap.tool.ligo_skymap_plot.main')
def test_plot_allsky_swift(mock_plot):
# Run function under test
skymaps.plot_allsky('', ra=0, dec=0)
# Check that the script would have been run once
# with the correct arguments
mock_plot.assert_called_once()
cmdline, = mock_plot.call_args[0]
assert cmdline[2].endswith('.png')
def test_is_3d_fits_file(toy_fits_filecontents, toy_3d_fits_filecontents):
# This is not a 3D FITS file.
assert not skymaps.is_3d_fits_file(toy_fits_filecontents)
......