diff --git a/gracedb/superevents/urls.py b/gracedb/superevents/urls.py index 026b27cd8ad55c0793124fb14e6bd39d7f1303fd..0dea4db315fc54355601cc16cf2719f2bf246f90 100644 --- a/gracedb/superevents/urls.py +++ b/gracedb/superevents/urls.py @@ -34,10 +34,6 @@ urlpatterns = legacy_urlpatterns + [ url(r'^(?P<superevent_id>{regex})/'.format(regex=Superevent.ID_REGEX), include(suburlpatterns)), - # table of all public events + # View of all candidates url(r'^public/$', views.SupereventPublic.as_view(), name="public-alerts"), - - # Tanner customizations (now, both links go to same view) - url(r'^public2/$', views.SupereventPublic.as_view(), name="public-alerts2"), - ] diff --git a/gracedb/superevents/views.py b/gracedb/superevents/views.py index 19bbe38a3c2f04c3a6b5e2b98b1a010c6d2ff32c..b033c75b239cae8fec0de4092ea9549e843d9368 100644 --- a/gracedb/superevents/views.py +++ b/gracedb/superevents/views.py @@ -120,20 +120,20 @@ class SupereventFileList(SupereventDetailView): # handled through the API. Links on the file list page point to the # API file download page. + class SupereventPublic(DisplayFarMixin, ListView): model = Superevent - template_name = 'superevents/public.html' + template_name = 'superevents/public_alerts.html' filter_permissions = ['superevents.view_superevent'] log_view_permission = 'superevents.view_log' noticeurl_template = 'https://gcn.gsfc.nasa.gov/notices_l/{s_id}.lvc' gcnurl_template = 'https://gcn.gsfc.nasa.gov/other/GW{sd_id}.gcn3' skymap_filename = 'bayestar.png' + pe_results_tagname = 'pe_results' - def get_queryset(self, **kwargs): - # -- Query only for public events - # Comment from Tanner: Use the category directly from the superevent - # model rather than hard-coding + # Query only for public events + # NOTE: may want to fix this to only O3 events at some point qs = Superevent.objects.filter(is_exposed=True, category=Superevent.SUPEREVENT_CATEGORY_PRODUCTION) \ .prefetch_related('voevent_set', 'log_set') @@ -141,73 +141,70 @@ class SupereventPublic(DisplayFarMixin, ListView): def get_context_data(self, **kwargs): # Get base context - # Comment from Tanner: use super() here; it's equivalent in this case - # to directly calling ListView.get_context_data, but super() is - # typically better practice context = super(SupereventPublic, self).get_context_data(**kwargs) #-- For each superevent, get list of log messages and construct pastro string candidates = 0 for se in self.object_list: - # Comment from Tanner: use reverse() for internal URLs - se.maplocal = reverse('legacy_apiweb:default:superevents:superevent-file-detail', - args=[se.default_superevent_id, self.skymap_filename]) + # Get skymap image (if a public one exists) + se.skymap_image = None + if se.log_set.filter(tags__name='public', + filename=self.skymap_filename).exists(): + se.skymap_image = reverse( + 'legacy_apiweb:default:superevents:superevent-file-detail', + args=[se.default_superevent_id, self.skymap_filename]) - #-- GCN links - # Comment from Tanner: define link templates outside of function - # so they are loaded at "compile-time" rather than each time the - # function is called + # External links to GCN notice and circular se.noticeurl = self.noticeurl_template.format(s_id= se.default_superevent_id) se.gcnurl = self.gcnurl_template.format(sd_id= se.default_superevent_id[1:]) - + se.t0_iso = gpstime.gps_to_utc(se.t_0).isoformat(' ').split('.')[0] se.t0_utc = se.t0_iso.split()[1] # Get display FARs for preferred_event - se.far_hz, se.far_hr, se.far_limit = self.get_display_far(obj=se.preferred_event) - - - - #-- Get list of voevents - # Comment from Tanner: do as much work as you can in the database. - # Also, use VOEvent types from the model rather than hard-coding - # -- Filter out retractions - # Comment from Tanner: looks like we only ever use the - # non-retraction VOEvent with the highest N, so let's just get - # it in one query. + se.far_hz, se.far_hr, se.far_limit = self.get_display_far( + obj=se.preferred_event) + + # Get list of voevents, filtering out retractions voe = se.voevent_set.exclude(voevent_type= VOEvent.VOEVENT_TYPE_RETRACTION).order_by('-N').first() - # -- Was this candidate retracted? + + # Was the candidate retracted? se.retract = se.voevent_set.filter(voevent_type= VOEvent.VOEVENT_TYPE_RETRACTION).exists() candidates += int(not se.retract) # Get list of viewable logs for user which are tagged with # 'analyst_comments' - viewable_logs = get_objects_for_user(self.request.user, - self.log_view_permission, - klass=se.log_set.filter(tags__name='analyst_comments')) + #viewable_logs = get_objects_for_user(self.request.user, + # self.log_view_permission, + # klass=se.log_set.filter(tags__name='analyst_comments')) + viewable_logs = se.log_set.filter(tags__name='public').filter(tags__name='analyst_comments') # Compile comments from these logs se.comments = ' ** '.join(list(viewable_logs.values_list( 'comment', flat=True))) - if se.retract: se.comments += "RETRACTED" + if se.retract: + if se.comments: + se.comments += " " + se.comments += "RETRACTED" - # -- Get list of PE results + # Get list of PE results pe_results = get_objects_for_user(self.request.user, self.log_view_permission, - klass=se.log_set.filter(tags__name='pe_result')) + klass=se.log_set.filter(tags__name=self.pe_results_tagname)) # Compile comments from these logs se.pe = ' ** '.join(list(pe_results.values_list( 'comment', flat=True))) - - # -- Read out probabilities - pastro_values = [ ("BNS",voe.prob_bns), ("NSBH",voe.prob_nsbh), - ("BBH", voe.prob_bbh), ("Terrestrial", voe.prob_terrestrial), - ("MassGap", voe.prob_mass_gap) ] + # Get p_astro probabilities + pastro_values = [("BNS", voe.prob_bns), + ("NSBH", voe.prob_nsbh), + ("BBH", voe.prob_bbh), + ("Terrestrial", voe.prob_terrestrial), + ("MassGap", voe.prob_mass_gap)] pastro_values.sort(reverse=True, key=lambda (a,b):b) sourcelist = [] for key, value in pastro_values: @@ -222,7 +219,4 @@ class SupereventPublic(DisplayFarMixin, ListView): # Number of non-retracted candidate events context['candidates'] = candidates - #-- Is this user outside the LVC? - context['user_is_external'] = is_external(self.request.user) - return context diff --git a/gracedb/templates/base.html b/gracedb/templates/base.html index 754a5ae644242b78fae1ba61ce076eb608074179..8ac97c1be36ddc115d9ca4d421bab0049e0f68b2 100644 --- a/gracedb/templates/base.html +++ b/gracedb/templates/base.html @@ -7,7 +7,9 @@ {# remove requests for favicon #} <link rel="icon" href="data:,"> - {% block csslink %}<link rel="stylesheet" href="{% static "css/style.css" %}" /> {% endblock %} + {% block csslink %} + <link rel="stylesheet" href="{% static "css/style.css" %}" /> + {% endblock %} <title>GraceDb | {% block title %}{% endblock %}</title> <!-- START TESTING --> <script type="text/javascript"> diff --git a/gracedb/templates/navbar_min.html b/gracedb/templates/navbar_min.html deleted file mode 100644 index 1e430f46168930d8e1b871188c876badb42b7fe7..0000000000000000000000000000000000000000 --- a/gracedb/templates/navbar_min.html +++ /dev/null @@ -1,26 +0,0 @@ -<div style="padding-bottom: 30px;"> -<ul id="nav"> - <li id="nav-home"><a href="{% url "home" %}">Home</a></li> - {% if user.is_authenticated %} - <li id="nav-logout"><a href="{% url "logout" %}">Logout</a></li> - <li id="nav-user">Authenticated as: - {% if user.first_name %} - {{ user.get_full_name }} - {% else %} - {{ user.username }} - {% endif %} - </li> - {% else %} - <li id="nav-login"><a href="{% url "login" %}">Login</a></li> - {% endif %} -</ul> - -{% if 'lvem_view' in request.path %} -<div id="lvem_view_message"> -<b>IMPORTANT:</b> You are viewing this page as a member of the LV-EM Observers group. -At the end of your session, please remove the 'lvem_view/' string from the URL to -return to the regular GraceDB site. This will ensure that your group memberships -are correct the next time you log in. -</div> -{% endif %} -</div> diff --git a/gracedb/templates/superevents/public.html b/gracedb/templates/superevents/public.html deleted file mode 100644 index b190eccb620d002ebcdeb6eac95e38dcb5425377..0000000000000000000000000000000000000000 --- a/gracedb/templates/superevents/public.html +++ /dev/null @@ -1,103 +0,0 @@ -{% extends "base.html" %} -{% load sanitize_html %} -{% load logtags %} -{% load static %} - - -{% block csslink %} -<link rel="stylesheet" href="{% static "css/style.css" %}" /> -<link rel="stylesheet" href="{% static "css/public.css" %}" /> -<meta name="viewport" content="width=device-width, initial-scale=1"> -{% endblock %} - -{% block heading %}{% endblock %} - -{% block jscript %} -<link rel="stylesheet" type="text/css" href="{% static "tablesaw/dist/tablesaw.css" %}" /> -<script language="javascript" type="text/javascript" src="{% static "tablesaw/dist/tablesaw.js" %}"></script> -<script language="javascript" type="text/javascript" src="{% static "tablesaw/dist/tablesaw-init.js" %}"></script> -{% endblock %} - -{% block nav %} -<!-- This nav bar only has links for HOME and LOGIN to fit on mobile --> -{% include "navbar_min.html" %} -{% endblock %} - -{% block content %} -<br/> -<h1>LIGO/Virgo Public Alerts</h1> - -<h3>Detection candidates: {{ candidates }}</h3> -<br/><br/> - -<div style="overflow-x: auto"> -<table class="tablesaw" data-tablesaw-sortable data-tablesaw-sortable-switch data-tablesaw-mode="columntoggle"> - <thead><tr> - <th scope="col" data-tablesaw-sortable-col data-tablesaw-priority="persist">Event ID</th> - <th scope="col" data-tablesaw-sortable-col data-tablesaw-priority="1">Possible Source (Probability)</th> - <th scope="col" data-tablesaw-sortable-col data-tablesaw-priority="2">UTC</th> - <th scope="col" data-tablesaw-col data-tablesaw-priority="3">GCN</th> - <th scope="col" data-tablesaw-col data-tablesaw-priority="4">Location</th> - <th scope="col" data-tablesaw-sortable-col data-tablesaw-priority="5">FAR</th> - <th scope="col" data-tablesaw-sortable-col data-tablesaw-priority="6">Comments</th> - <th scope="col" data-tablesaw-sortable-col data-tablesaw-priority="0">GPS</th> - - {% if not user_is_external %} - <th scope="col" data-tablesaw-col data-tablesaw-priority="6">Ω Scan</th> - <th scope="col" data-tablesaw-col data-tablesaw-priority="6">PE</th> - {% endif %} - - </tr> - </thead> - <tbody> - - -{% for event in object_list %} -<tr{% if event.retract %} style='background-color:#EDD' {% endif %}> - - <td style='min-width:100px;'><a href=/superevents/{{ event.superevent_id }}>{{ event.default_superevent_id }}</a></td> - - <td style='min-width:100px;'>{{ event.sourcetypes }} </td> - - <td style='min-width:140px'> - <span style='font-size:0px;'>{{ event.t0_iso }}</span>{{ event.t_0_date }}<br/> - {{ event.t0_utc }} UTC - </td> - - <td style='min-width:110px;'> - <a href={{ event.gcnurl }}>GCN Circulars</a><br/> - <a href={{ event.noticeurl }}>Notices</a> | - <a href='/api/superevents/{{ event.default_superevent_id }}/voevents/'>VOE</a> - </td> - - <td> <a href='{{ event.maplocal }}'> <img src='{{ event.maplocal }}' width='120px'/> </a> </td> - - - <td style='min-width:120px;'><span style='font-size:0px'>{{ event.far_hz|floatformat:10 }}</span>{{ event.far_hr }}</td> - <td style='min-width:80px;'>{{ event.comments |safe}} </td> - <td>{{ event.t_0|floatformat:2 }} </td> - - {% if not user_is_external %} - <td style='min-width:70px'> - <a href='https://ldas-jobs.ligo-la.caltech.edu/~detchar/dqr/events/{{ event.superevent_id }}/L1deepomegascan/'>Ω L1</a><br/> - <a href='https://ldas-jobs.ligo-wa.caltech.edu/~detchar/dqr/events/{{ event.superevent_id }}/H1deepomegascan/'>Ω H1</a> - </td> - <td>{{ event.pe |safe}}</td> - {% endif %} - -</tr> - -{% endfor %} -</tbody></table> -</div> - -<hr/> -<ul style="list-style-type:square"> - <li> Retractions are marked in red</li> - <li> Details in the <a href='https://emfollow.docs.ligo.org/userguide/'>LIGO/Virgo Alerts User Guide</a> -</ul> - -<br/><br/><br/> - -{% endblock %} - diff --git a/gracedb/templates/superevents/public_alerts.html b/gracedb/templates/superevents/public_alerts.html new file mode 100644 index 0000000000000000000000000000000000000000..f97ee8f953387b773d7af5e63c49d7a2e01dca3f --- /dev/null +++ b/gracedb/templates/superevents/public_alerts.html @@ -0,0 +1,104 @@ +{% extends "base.html" %} +{% load sanitize_html %} +{% load logtags %} +{% load static %} + + +{% block csslink %} +{{ block.super }} +<link rel="stylesheet" href="{% static "css/public.css" %}" /> +<meta name="viewport" content="width=device-width, initial-scale=1"> +{% endblock %} + +{% block heading %}{% endblock %} + +{% block jscript %} +<link rel="stylesheet" type="text/css" href="{% static "tablesaw/dist/tablesaw.css" %}" /> +<script language="javascript" type="text/javascript" src="{% static "tablesaw/dist/tablesaw.js" %}"></script> +<script language="javascript" type="text/javascript" src="{% static "tablesaw/dist/tablesaw-init.js" %}"></script> +{% endblock %} + +{% block content %} +<br /> +<h1>LIGO/Virgo Public Alerts</h1> + +<h3>Detection candidates: {{ candidates }}</h3> +<br /><br /> + +<div style="overflow-x: auto"> +<table class="tablesaw" data-tablesaw-sortable data-tablesaw-sortable-switch data-tablesaw-mode="columntoggle"> + <thead><tr> + <th scope="col" data-tablesaw-sortable-col data-tablesaw-priority="persist">Event ID</th> + <th scope="col" data-tablesaw-sortable-col data-tablesaw-priority="1">Possible Source (Probability)</th> + <th scope="col" data-tablesaw-sortable-col data-tablesaw-sortable-string data-tablesaw-priority="2">UTC</th> + <th scope="col" data-tablesaw-col data-tablesaw-priority="3">GCN</th> + <th scope="col" data-tablesaw-col data-tablesaw-priority="4">Location</th> + <th scope="col" data-tablesaw-sortable-col data-tablesaw-priority="5">FAR</th> + <th scope="col" data-tablesaw-col data-tablesaw-priority="6">Comments</th> + <th scope="col" data-tablesaw-sortable-col data-tablesaw-priority="0">GPS</th> + + {% if user_is_internal %} + <th scope="col" data-tablesaw-col data-tablesaw-priority="6">Ω Scan</th> + <th scope="col" data-tablesaw-col data-tablesaw-priority="6">PE</th> + {% endif %} + + </tr> + </thead> + <tbody> + + +{% for event in object_list %} +<tr{% if event.retract %} style="background-color: #EDD;" {% endif %}> + + <td style="min-width: 100px;"> + <a href="{% url "superevents:view" event.superevent_id %}">{{ event.default_superevent_id }}</a> + </td> + <td style="min-width: 100px;">{{ event.sourcetypes }}</td> + <td style="min-width: 140px;"> + <span style="font-size: 0px;">{{ event.t_0|floatformat:2 }}</span>{{ event.t_0_date }}<br/> + {{ event.t0_utc }} UTC + </td> + <td style="min-width: 110px;"> + <a href={{ event.gcnurl }}>GCN Circulars</a><br/> + <a href={{ event.noticeurl }}>Notices</a> | <a href="{% url "legacy_apiweb:default:superevents:superevent-voevent-list" event.default_superevent_id %}">VOE</a> + </td> + <td> + {% if event.skymap_image %} + <a href="{{ event.skymap_image }}"> + <img src="{{ event.skymap_image }}" width="120px" /> + </a> + {% else %} + No public skymap image found. + {% endif %} + </td> + <td style="min-width: 120px;"> + <!-- Hidden float FAR value for table sorting --> + <span style="font-size: 0px;">{{ event.far_hz|floatformat:20 }}</span>{{ event.far_hr }} + </td> + <td style="min-width: 80px;">{{ event.comments|safe }} </td> + <td>{{ event.t_0|floatformat:2 }} </td> + + {% if user_is_internal %} + <!-- Add Omega scans and PE results for LVC users --> + <td style="min-width: 70px;"> + <a href="https://ldas-jobs.ligo-la.caltech.edu/~detchar/dqr/events/{{ event.superevent_id }}/L1deepomegascan/">Ω L1</a><br/> + <a href="https://ldas-jobs.ligo-wa.caltech.edu/~detchar/dqr/events/{{ event.superevent_id }}/H1deepomegascan/">Ω H1</a> + </td> + <td>{{ event.pe|safe }}</td> + {% endif %} + +</tr> +{% endfor %} +</tbody></table> +</div> + +<hr /> +<ul style="list-style-type: square;"> + <li>Retractions are marked in red.</li> + <li>More details about public alerts are provided in the <a href="https://emfollow.docs.ligo.org/userguide/">LIGO/Virgo Alerts User Guide</a>.</li> +</ul> + +<br /><br /><br /> + +{% endblock %} +