Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# (c) Stefan Countryman 2016-2018
3"""
4Human-readable plotters for coincident skymaps showing overlapping events
5"""
7import os
8from subprocess import Popen, PIPE, check_output
9import logging
10from llama.serve.gui import gui_url
11from llama.filehandler import (
12 FileHandler,
13 GenerationError,
14)
15from llama.files.coinc_significance import CoincSignificanceI3Lvc
16from llama.files.healpix.plotters import (
17 JointSkymapScatter,
18)
19from llama.files.skymap_info import SkymapInfo
20from llama.files.ztf_trigger_list import ZtfTriggerList
21from llama.files.i3 import (
22 IceCubeNeutrinoList,
23 IceCubeNeutrinoListTex,
24)
25from llama.files.lvc_skymap import LvcSkymapHdf5
26from llama.files.slack import SlackReceiptIcecube, SlackReceiptLlama
27from llama.classes import ImmutableDict
29LOGGER = logging.getLogger(__name__)
31LATEX_SUMMARY = r"""\documentclass{{article}}
32\usepackage[utf8]{{inputenc}}
33\usepackage{{geometry}}
35\title{{Joint GW+Neutrino Analysis Summary for {skymap_info.graceid} \\ {warn}}}
36\author{{LLAMA Group}}
38\usepackage{{natbib}}
39\usepackage{{graphicx}}
41\usepackage{{hyperref}}
42\hypersetup{{
43 colorlinks=true,
44 linkcolor=blue,
45 filecolor=magenta,
46 urlcolor=cyan,
47}}
49\begin{{document}}
51\maketitle
54\begin{{figure}}[h!]
55\centering
56\includegraphics[width=\textwidth]{{{plot}}}
57\caption{{
58 Joint GW+High Energy Neutrino skymap. Used skymap \texttt{{{skymap_info.skymap_filename}}}.
59 Neutrino numbers on the skymap correspond to row numbers in the table
60 below.
61}}
62\label{{fig:coinc-scatterplot}}
63\end{{figure}}
65%\section{{Summary}}
66\begin{{table*}}
67\centering
68\small
69\begin{{tabular}}{{ l|l }}
70LLAMA P-value & {significance.combined_p_value} \\
71\hline
72GW FAR & {skymap_info.far} \\
73\hline
74GW Pipeline & {skymap_info.pipeline} \\
75\hline
76Alert Type & {skymap_info.alert_type} \\
77\hline
78GW Event Time (UTC) & {skymap_info.event_time_str} \\
79\hline
80GW Event Time (MJD) & {skymap_info.event_time_mjd} \\
81\hline
82GW Event Time (GPS) & {skymap_info.event_time_gps} \\
83\hline
84Notice Time (UTC) & {skymap_info.notice_time_str} \\
85\hline
86GraceID & {skymap_info.graceid} \\
87\hline
88GraceDB Page & \url{{{skymap_info.gracedb_url}}} \\
89\hline
90Skymap Filename & {skymap_info.skymap_filename} \\
91\hline
92Skymap Download URL & \url{{{skymap_info.human_url}}} \\
93\hline
94LLAMA EventID & {skymap_info.eventid} \\
95\hline
96LLAMA Event Page & \url{{{llamaurl}}} \\
97\end{{tabular}}
98\caption{{
99 The final p-value of the LLAMA analysis is noted at the top of the
100 table. GW event parameters are shown below.
101}}
102\label{{table:parameters}}
103\end{{table*}}
105%\section{{Neutrino Table}}
106{neutrino_table}
108%\section{{LLAMA Event Flags}}
109%\begin{{table*}}
110%\centering
111%\small
112%\begin{{tabular}}{{ l|l }}
113%Flag Name & Value \\
114%\hline
115%{{flags}}
116%\end{{tabular}}
117%\caption{{Internal flags used to control LLAMA pipeline execution.}}
118%\label{{table:flags}}
119%\end{{table*}}
121% \textbf{{Combined event p-value:}} {significance.combined_p_value: 11.8f}
122% \bibliographystyle{{plain}}
123% \bibliography{{references}}
124\end{{document}}
125"""
128class CoincScatterI3Lvc(JointSkymapScatter):
129 """
130 Abstract class for a human-viewable joint Neutrino/Gravitational Wave
131 skymap plot. Subclass this with an output file extension to make a working
132 FileHandler.
133 """
135 BACKGROUND_SKYMAP = LvcSkymapHdf5
136 POINT_SOURCES = ImmutableDict({
137 IceCubeNeutrinoList: ImmutableDict({
138 'color': 'green',
139 'marker': r"$\times$", # bullseye hides less GW density
140 }),
141 })
144class CoincScatterZtfLVC(JointSkymapScatter):
145 """
146 Abstract class for a human-viewable joint ZTF/Gravitational Wave skymap
147 plot. Subclass this with an output file extension to make a working
148 ``FileHandler``.
149 """
151 BACKGROUND_SKYMAP = LvcSkymapHdf5
152 POINT_SOURCES = ImmutableDict({
153 ZtfTriggerList: ImmutableDict({
154 'color': 'red',
155 'marker': r"$\times$", # x marks the ZTF trig
156 }),
157 })
160class CoincScatterZtfI3Lvc(JointSkymapScatter):
161 """
162 Abstract class for a human-viewable joint ZTF/Gravitational Wave/High
163 Energy Neutrino joint skymap plot. Subclass this with an output file
164 extension to make a working ``FileHandler``.
165 """
167 BACKGROUND_SKYMAP = LvcSkymapHdf5
168 POINT_SOURCES = ImmutableDict({
169 IceCubeNeutrinoList: ImmutableDict({
170 'color': 'green',
171 'marker': r"$\times$", # bullseye hides less GW density
172 }),
173 ZtfTriggerList: ImmutableDict({
174 'color': 'red',
175 'marker': r"$\times$", # x marks the ZTF trig
176 }),
177 })
180@SlackReceiptLlama.upload_this()
181@CoincScatterI3Lvc.set_class_attributes
182class CoincScatterI3LvcPdf(CoincScatterI3Lvc):
183 """
184 Human-readable joint Neutrino/Gravitational Wave skymap plot in PDF
185 format.
186 """
188 FILEEXT = 'pdf'
191@SlackReceiptLlama.upload_this()
192@CoincScatterI3Lvc.set_class_attributes
193class CoincScatterI3LvcPng(CoincScatterI3Lvc):
194 """
195 Human-readable joint Neutrino/Gravitational Wave skymap plot in PNG
196 format.
197 """
199 FILEEXT = 'png'
202@SlackReceiptLlama.upload_this()
203@CoincScatterZtfLVC.set_class_attributes
204class CoincScatterZtfLVCPdf(CoincScatterZtfLVC):
205 """
206 Human-readable joint ZTF/Gravitational Wave skymap plot in PDF
207 format.
208 """
210 FILEEXT = 'pdf'
213@SlackReceiptLlama.upload_this()
214@CoincScatterZtfLVC.set_class_attributes
215class CoincScatterZtfLVCPng(CoincScatterZtfLVC):
216 """
217 Human-readable joint ZTF/Gravitational Wave skymap plot in PNG
218 format.
219 """
221 FILEEXT = 'png'
224@SlackReceiptLlama.upload_this()
225@CoincScatterZtfI3Lvc.set_class_attributes
226class CoincScatterZtfI3LvcPdf(CoincScatterZtfI3Lvc):
227 """
228 Human-readable joint ZTF/Gravitational Wave/High Energy Neutrino skymap
229 plot in PDF format.
230 """
232 FILEEXT = 'pdf'
235@SlackReceiptLlama.upload_this()
236@CoincScatterZtfI3Lvc.set_class_attributes
237class CoincScatterZtfI3LvcPng(CoincScatterZtfI3Lvc):
238 """
239 Human-readable joint ZTF/Gravitational Wave/High Energy Neutrino skymap
240 plot in PNG format.
241 """
243 FILEEXT = 'png'
246@FileHandler.set_class_attributes
247class CoincSummaryI3LvcTex(FileHandler):
248 """
249 LaTeX file for a human-viewable joint Neutrino/Gravitational Wave skymap
250 plot complete with a list of neutrinos and their properties. Gets compiled
251 to a PDF file.
252 """
254 DEPENDENCIES = (
255 SkymapInfo,
256 CoincScatterI3LvcPdf,
257 CoincSignificanceI3Lvc,
258 IceCubeNeutrinoListTex,
259 IceCubeNeutrinoList,
260 )
262 FILENAME = 'summary_lvc-I3.tex'
264 def _generate(self):
265 # load the neutrino laTeX table
266 with IceCubeNeutrinoListTex(self).open() as infile:
267 table = infile.read()
268 if not IceCubeNeutrinoList(self).is_complete():
269 warn = r'\textbf{(PARTIAL RESULT: MORE ICECUBE EVENTS INCOMING)}'
270 else:
271 warn = r'(All IceCube Events Included in Search)'
272 calling_fh = self if (self.parent is None) else self.parent
273 latex_out = LATEX_SUMMARY.format(
274 skymap_info=SkymapInfo(self),
275 llamaurl=gui_url(calling_fh, linktype='event'),
276 flags='\n'.join(' & '.join(i)+r' \\' for i in self.flags.items()),
277 warn=warn,
278 plot=CoincScatterI3LvcPdf(self).FILENAME,
279 neutrino_table=table,
280 significance=CoincSignificanceI3Lvc(self),
281 )
282 # write the LaTeX output to file
283 with open(self.fullpath, 'w') as outfile:
284 outfile.write(latex_out)
287@SlackReceiptLlama.upload_this()
288@SlackReceiptIcecube.upload_this()
289@FileHandler.set_class_attributes
290class CoincSummaryI3LvcPdf(FileHandler):
291 """
292 Human-viewable joint Neutrino/Gravitational Wave skymap plot complete
293 with a list of neutrinos and their properties in PDF form. Useful for quick
294 human checks of the output of the pipeline on an event.
295 """
297 DEPENDENCIES = (
298 CoincSummaryI3LvcTex,
299 CoincScatterI3LvcPdf,
300 )
302 assert CoincSummaryI3LvcTex.FILENAME.endswith('.tex')
303 FILENAME = CoincSummaryI3LvcTex.FILENAME[:-3]+'pdf'
305 def _generate(self): # pylint: disable=arguments-differ
306 LOGGER.debug("Generation temp directory: %s",
307 check_output("pwd", cwd=self.eventdir).strip())
308 LOGGER.debug("Generation temp directory contents:\n%s",
309 check_output("ls", cwd=self.eventdir))
310 cmd = [
311 'pdflatex',
312 CoincSummaryI3LvcTex(self).FILENAME,
313 ]
314 proc = Popen(cmd, stdout=PIPE, stderr=PIPE, cwd=self.eventdir)
315 res, err = proc.communicate()
316 if proc.returncode:
317 raise GenerationError(("Could not make PDF from LaTeX.\nSTDOUT:"
318 "\n{}\nSTDERR:\n{}\n").format(res, err))
319 # clean up auxilliary files
320 for ext in ('aux', 'log'):
321 cruft_file = self.fullpath[:-3] + ext
322 if os.path.isfile(cruft_file):
323 os.remove(cruft_file)