Coverage for pesummary/cli/summaryreview.py: 27.8%
360 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-12-09 22:34 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-12-09 22:34 +0000
1#! /usr/bin/env python
3# Licensed under an MIT style license -- see LICENSE.md
5from pesummary.core.cli.parser import ArgumentParser as _ArgumentParser
6from pesummary.gw.file.standard_names import standard_names, lalinference_map
7from pesummary.utils.samples_dict import SamplesDict
8from pesummary.io import read
9from pesummary.core.webpage.main import _WebpageGeneration
10from pesummary.utils.utils import logger
11import subprocess
12import numpy as np
13import sys
14import shutil
15import os
16from glob import glob
17from getpass import getuser
19__author__ = ["Charlie Hoy <charlie.hoy@ligo.org>"]
22REVIEW_TESTS = [
23 "all", "core_plots", "ligo.skymap", "spin_disk"
24]
27class ArgumentParser(_ArgumentParser):
28 def _pesummary_options(self):
29 options = super(ArgumentParser, self)._pesummary_options()
30 options.update(
31 {
32 "--samples": {
33 "short": "-s",
34 "help": "Posterior samples hdf5 file",
35 },
36 "--test": {
37 "short": "-t",
38 "help": "Review test that you wish to perform",
39 "choices": REVIEW_TESTS,
40 "default": "all"
41 }
42 }
43 )
44 return options
47def get_executable_path(executable):
48 """Return the path to the executable
50 Parameters
51 ----------
52 executable: str
53 name of the executable
54 """
55 try:
56 path = subprocess.check_output(["which", "%s" % (executable)])
57 path = path.decode("utf-8")
58 except Exception:
59 path = None
60 return path
63def make_cli(executable, default_arguments, add_symbol=False):
64 """Generate a command line
66 Parameters
67 ----------
68 executable: str
69 executable you wish to run
70 default_arguments: list
71 list of arguments you wish to pass to the executable
72 add_symbol: Bool, optional
73 if True, prepend the cli with a '$' symbol
74 """
75 executable_path = get_executable_path(executable)
76 if executable_path is None:
77 raise Exception(
78 "'{}' is not installed in your environment.".format(executable)
79 )
80 cli = executable + " " + " ".join(default_arguments)
81 if add_symbol:
82 cli = "$ {}".format(cli)
83 return cli
86def _launch_lalinference_cli(
87 webdir, path_to_results_file, trigger_file=None, add_symbol=False
88):
89 """Command line to launch the lalinference job
91 Parameters
92 ----------
93 webdir: str
94 path to the directory to store the output pages
95 path_to_results_file: str
96 path to the results file. Must be compatible with the LALInference
97 pipeline
98 trigger_file: str, optional
99 path to an xml trigger file.
100 add_symbol: Bool, optional
101 if True, prepend the cli with a '$' symbol
102 """
103 webdir += "/lalinference"
104 default_arguments = ["--skyres", "0.5", "--outpath", webdir,
105 path_to_results_file]
107 if trigger_file is not None:
108 default_arguments.append("--trig")
109 default_arguments.append(trigger_file)
111 cli = make_cli("cbcBayesPostProc", default_arguments, add_symbol=add_symbol)
112 return [cli]
115def launch_lalinference(webdir, path_to_results_file, trigger_file=None):
116 """Launch a subprocess to generate the lalinference pages
118 Parameters
119 ----------
120 webdir: str
121 path to the directory to store the output pages
122 path_to_results_file: str
123 path to the results file. Must be compatible with the LALInference
124 pipeline
125 trigger_file: str, optional
126 path to an xml trigger file.
127 """
128 cli = _launch_lalinference_cli(
129 webdir, path_to_results_file, trigger_file=trigger_file, add_symbol=False
130 )
131 logger.info("Running %s" % (cli))
132 ess = subprocess.Popen(
133 cli, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
134 ess.wait()
137def _launch_skymap_cli(
138 webdir, path_to_results_file, add_symbol=False, multi_process=1
139):
140 """Command lines to launch to the skymap job
142 Parameters
143 ----------
144 webdir: str
145 path to the directory to store the output pages
146 path_to_results_file: str
147 path to the results file. Must be compatible with the LALInference
148 pipeline
149 trigger_file: str, optional
150 path to an xml trigger file.
151 add_symbol: Bool, optional
152 if True, prepend each cli with a '$' symbol
153 multi_process: int, optional
154 number of cpus to run on
155 """
156 cli = []
157 default_arguments = [
158 path_to_results_file, "-j {}".format(multi_process), "--enable-multiresolution",
159 "--outdir", webdir
160 ]
161 cli.append(
162 make_cli("ligo-skymap-from-samples", default_arguments, add_symbol=add_symbol)
163 )
164 default_arguments = [
165 "{}/skymap.fits".format(webdir), "--annotate", "--contour 50 90",
166 "-o {}/skymap.png".format(webdir)
167 ]
168 cli.append(
169 make_cli("ligo-skymap-plot", default_arguments, add_symbol=add_symbol)
170 )
171 default_arguments = [
172 "{}/skymap.fits".format(webdir), "-p 50 90",
173 "-o {}/skymap.txt".format(webdir)
174 ]
175 cli.append(
176 make_cli("ligo-skymap-stats", default_arguments, add_symbol=add_symbol)
177 )
178 return cli
181def launch_skymap(webdir, path_to_results_file, multi_process=1):
182 """Generate a skymap with the `ligo.skymap` package.
184 Parameters
185 ----------
186 webdir: str
187 path to the directory to store the output pages
188 path_to_results_file: str
189 path to the results file. Must be compatible with the LALInference
190 pipeline
191 multi_process: int, optional
192 number of cpus to run on
193 """
194 webdir += "/ligo_skymap"
195 cli = _launch_skymap_cli(webdir, path_to_results_file, multi_process=multi_process)
196 for _cli in cli:
197 ess = subprocess.run(_cli, shell=True)
200def _launch_pesummary_cli(
201 webdir, path_to_results_file, trigger_file=None, add_symbol=False
202):
203 """Command lines to launch the pesummary job
205 Parameters
206 ----------
207 webdir: str
208 path to the directory to store the output pages
209 path_to_results_file: str
210 path to the results file. Must be compatible with the LALInference
211 pipeline
212 trigger_file: str, optional
213 path to an xml trigger file.
214 multi_process: int, optional
215 number of cpus to run on
216 """
217 executable = "summarypages"
218 executable_path = get_executable_path(executable)
220 if executable_path is None:
221 raise Exception(
222 "'summarypages' is not installed in your environment. failed "
223 "to generate PESummary pages")
225 webdir += "/pesummary"
226 default_arguments = ["--webdir", webdir, "--samples", path_to_results_file,
227 "--approximant", "IMRPhenomPv2", "--gw",
228 "--labels", "pesummary", "--cosmology", "planck15_lal",
229 "--multi_process 18"]
231 if trigger_file is not None:
232 default_arguments.append("--trig_file")
233 default_arguments.append(trigger_file)
235 cli = executable + " " + " ".join(default_arguments)
236 if add_symbol:
237 cli = "$ {}".format(cli)
238 return [cli]
241def launch_pesummary(
242 webdir, path_to_results_file, trigger_file=None, multi_process=1
243):
244 """Launch a subprocess to generate the PESummary pages
246 Parameters
247 ----------
248 webdir: str
249 path to the directory to store the output pages
250 path_to_results_file: str
251 path to the results file. Must be compatible with the LALInference
252 pipeline
253 trigger_file: str, optional
254 path to an xml trigger file.
255 multi_process: int, optional
256 number of cpus to run on
257 """
258 cli = _launch_pesummary_cli(
259 webdir, path_to_results_file, trigger_file=trigger_file
260 )[0]
261 executable = "summarypages"
262 executable_path = get_executable_path(executable)
264 if executable_path is None:
265 raise Exception(
266 "'summarypages' is not installed in your environment. failed "
267 "to generate PESummary pages")
269 webdir += "/pesummary"
270 default_arguments = ["--webdir", webdir, "--samples", path_to_results_file,
271 "--approximant", "IMRPhenomPv2", "--gw",
272 "--labels", "pesummary", "--cosmology", "planck15_lal",
273 "--multi_process {}".format(multi_process)]
275 if trigger_file is not None:
276 default_arguments.append("--trig_file")
277 default_arguments.append(trigger_file)
279 cli = executable + " " + " ".join(default_arguments)
280 logger.info("Running %s" % (cli))
281 ess = subprocess.run(cli, shell=True)
284def _launch_spin_disk_script():
285 """Script to run which generates a spin disk using pesummary and a spin
286 disk using the script used in GWTC1
287 """
288 script = """
289 import h5py
290 from pesummary.gw.fetch import fetch
291 from pesummary import cli
293 base = "https://ldas-jobs.ligo.caltech.edu/~charlie.hoy/projects/GWTC1/"
294 f = fetch(
295 base + "plot_spin_disks.py", read_file=False, delete_on_exit=True,
296 outdir=cli.__path__[0]
297 )
298 f = fetch(
299 base + "bounded_2d_kde.py", read_file=False, delete_on_exit=True,
300 outdir=cli.__path__[0]
301 )
302 from .plot_spin_disks import plot_spindisk_with_colorbar
303 path_to_pesummary_file = os.path.join(
304 webdir, "pesummary", "samples", "posterior_samples.h5"
305 )
306 try:
307 os.makedirs(os.path.join(webdir, "spin_disk"))
308 except FileExistsError:
309 pass
310 f = read(path_to_pesummary_file)
311 samples = f.samples_dict["pesummary"]
312 fig = samples.plot(type="spin_disk", colorbar=True, cmap="Blues")
313 fig.savefig("{}/spin_disk/pesummary.png".format(webdir))
314 fig.close()
315 f = h5py.File(path_to_results_file, 'r')
316 keys = list(f["lalinference"].keys())
317 samples = f["lalinference"][keys[0]]["posterior_samples"]
318 if "costilt1" in samples.dtype.names:
319 pass
320 else:
321 samples = SamplesDict({
322 "a1": samples["a1"], "a2": samples["a2"],
323 "costilt1": np.cos(samples["tilt1"]), "costilt2": np.cos(samples["tilt2"])
324 }).to_structured_array()
325 fig = plot_spindisk_with_colorbar(
326 samples, None, "Blues", plot_event_label=False, Na=25, Nt=25,
327 return_maxP_no_plot=False, threshold=True
328 )
329 fig.savefig("{}/spin_disk/GWTC1.png".format(webdir))
330 f.close()
331 """
332 return "\n".join([line[4:] for line in script.split("\n")])
335def launch_spin_disk(webdir, path_to_results_file):
336 """Generate a spin disk plot using both pesummary and code from GWTC1
337 """
338 exec(_launch_spin_disk_script())
341def get_list_of_plots(webdir, lalinference=False, pesummary=False):
342 """Get a list of plots generated by either lalinference or pesummary
344 Parameters
345 ----------
346 webdir: str
347 path to the directory to store the output pages
348 lalinference: Bool
349 if True, return the plots generated by LALInference. Default False
350 pesummary: Bool
351 if True, return the plots generated by PESummary. Default False
352 """
353 from glob import glob
355 if lalinference:
356 histogram_plots = sorted(
357 glob(webdir + "/lalinference/1Dpdf/*.png"))
358 params = [
359 i.split("/")[-1].split(".png")[0] for i in histogram_plots]
360 elif pesummary:
361 histogram_plots = sorted(
362 glob(webdir + "/pesummary/plots/*_1d_posterior*.png"))
363 params = [
364 i.split("/")[-1].split("_1d_posterior_")[1].split(".png")[0] for i
365 in histogram_plots]
366 return histogram_plots, params
369class WebpageGeneration(_WebpageGeneration):
370 """Class to handle webpage generation displaying the outcome from the review
372 Parameters
373 ----------
374 webdir: str
375 the web directory of the run
376 path_to_results_file: str
377 the path to the lalinference h5 file
378 *args: tuple
379 all args passed to the _WebpageGeneration class
380 **kwargs: dict
381 all kwargs passed to the _WebpageGeneration class
382 """
383 def __init__(self, webdir, path_to_results_file, *args, test="all", **kwargs):
384 self.path_to_results_file = os.path.abspath(path_to_results_file)
385 self.test = test
386 self.lalinference_path = os.path.abspath(os.path.join(
387 webdir, "lalinference", "posterior_samples.dat"
388 ))
389 self.pesummary_path = os.path.abspath(os.path.join(
390 webdir, "pesummary", "samples", "posterior_samples.h5"
391 ))
392 lalinference = np.genfromtxt(self.lalinference_path, names=True)
393 pesummary_dict = read(self.pesummary_path).samples_dict["pesummary"]
394 _lalinference_dict = {
395 param: lalinference[param] for param in lalinference.dtype.names
396 }
397 params = _lalinference_dict.keys()
398 lalinference_dict = {}
399 for param, data in _lalinference_dict.items():
400 if param in standard_names.keys():
401 lalinference_dict[standard_names[param]] = data
402 elif param in [
403 _param.lower() for _param in pesummary_dict.keys()
404 ]:
405 pp = [
406 _param for _param in pesummary_dict.keys() if param == _param.lower()
407 ][0]
408 lalinference_dict[pp] = data
409 else:
410 lalinference_dict[param] = data
411 samples = {
412 "lalinference": SamplesDict(lalinference_dict),
413 "pesummary": read(
414 os.path.join(webdir, "pesummary", "samples", "posterior_samples.h5")
415 ).samples_dict["pesummary"]
416 }
417 super(WebpageGeneration, self).__init__(
418 *args, webdir=webdir, labels=list(samples.keys()), samples=samples,
419 user=getuser(), **kwargs
420 )
421 self.abswebdir = os.path.abspath(self.webdir)
422 parameters = [list(self.samples[key].keys()) for key in self.samples.keys()]
423 params = list(set.intersection(*[set(l) for l in parameters]))
424 self.same_parameters = params
425 self.copy_css_and_js_scripts()
427 def copy_css_and_js_scripts(self):
428 """Copy css and js scripts from the package to the web directory
429 """
430 from pesummary import core
431 files_to_copy = []
432 path = core.__path__[0]
433 scripts = glob(os.path.join(path, "js", "*.js"))
434 for i in scripts:
435 files_to_copy.append(
436 [i, os.path.join(self.webdir, "js", os.path.basename(i))]
437 )
438 scripts = glob(os.path.join(path, "css", "*.css"))
439 for i in scripts:
440 files_to_copy.append(
441 [i, os.path.join(self.webdir, "css", os.path.basename(i))]
442 )
443 for _dir in ["js", "css"]:
444 try:
445 os.mkdir(os.path.join(self.webdir, _dir))
446 except FileExistsError:
447 pass
448 for ff in files_to_copy:
449 shutil.copy(ff[0], ff[1])
451 def generate_webpages(self):
452 """Generate all webpages for all result files passed
453 """
454 self.make_home_pages()
455 if self.test == "core_plots" or self.test == "all":
456 self.make_comparison_core_plots()
457 self.make_comparison_samples()
458 if self.test == "skymap" or self.test == "all":
459 self.make_comparison_skymap()
460 if self.test == "spin_disk" or self.test == "all":
461 self.make_comparison_spin_disk()
462 self.generate_specific_javascript()
464 def make_navbar_for_comparison_page(self):
465 """Make a navbar for the comparison homepage
466 """
467 links = ["home"]
468 comparison = ["Comparison"]
469 sub_comparison = []
470 if self.test == "core_plots" or self.test == "all":
471 sub_comparison.append("core_plots")
472 sub_comparison.append("samples")
473 if self.test == "skymap" or self.test == "all":
474 sub_comparison.append("skymap")
475 if self.test == "spin_disk" or self.test == "all":
476 sub_comparison.append("spin_disk")
477 comparison.append(sub_comparison)
478 links.append(comparison)
479 return links
481 def _make_home_pages(self, pages):
482 """Make the home pages
484 Parameters
485 ----------
486 pages: list
487 list of pages that you wish to create
488 """
489 from pesummary import __version__
491 html_file = self.setup_page(
492 "home", self.navbar["comparison"], title="Summary"
493 )
494 html_file.make_div(indent=2, _class='banner', _style="text-align: center")
495 html_file.add_content("Review completed with:")
496 html_file.end_div()
497 html_file.make_div(
498 indent=2, _class='banner', _style="text-align: center; color:red"
499 )
500 html_file.add_content("pesummary=={}".format(__version__))
501 html_file.end_div()
502 html_file.make_div(indent=2, _class='banner', _style="font-size: 14px")
503 html_file.add_content(
504 "This page compares the output between pesummary and lalinference/"
505 "ligo.skymap."
506 )
507 html_file.end_div()
508 html_file.make_banner(
509 approximant="On the command-line", key="command_line",
510 _style="font-size: 26px;", link=os.getcwd()
511 )
512 command = ""
513 for i in sys.argv:
514 command += " "
515 if i[0] == "-":
516 command += "\n"
517 command += "{}".format(i)
518 html_file.make_container()
519 styles = html_file.make_code_block(language="shell", contents=command)
520 with open('{0:s}/css/home.css'.format(self.webdir), 'w') as g:
521 g.write(styles)
522 html_file.end_container()
523 html_file.export(
524 "pesummary.sh", csv=False, json=False, shell=True,
525 margin_top="-4em"
526 )
527 html_file.end_div()
529 def make_comparison_spin_disk(self):
530 """Make a page which compares the spin disk produced using code in
531 pesummary and the spin disk produced using code from the GWTC1 catalog
532 """
533 pages = ["spin_disk"]
534 self.create_blank_html_pages(pages, stylesheets="spin_disk")
535 html_file = self.setup_page(
536 pages[0], self.navbar["comparison"], title="Spin disk comparison"
537 )
538 html_file.make_div(indent=2, _class='banner', _style=None)
539 html_file.add_content("Spin disk comparison")
540 html_file.end_div()
541 html_file.make_div(indent=2, _class='paragraph', _style="max-width:1400px")
542 html_file.add_content(
543 "Below we compare the spin disk plot produced using code within pesummary "
544 "to the spin disk produced using code from the GWTC1 catalog."
545 )
546 html_file.end_div()
547 html_file.make_container()
548 styles = html_file.make_code_block(
549 language="python", contents=_launch_spin_disk_script()
550 )
551 with open('{0:s}/css/spin_disk.css'.format(self.webdir), 'w') as g:
552 g.write(styles)
553 html_file.end_container()
554 contents = [[
555 "../spin_disk/pesummary.png", "../spin_disk/GWTC1.png"
556 ]]
557 html_file = self.make_modal_carousel(html_file, contents)
559 def make_comparison_core_plots(self):
560 """Make a page which compares the core 1d_histogram, autocorrelation
561 and sample trace plots in pesummary to the ones produced with
562 `cbcBayesPostProc`
563 """
564 pages = ["core_plots"]
565 self.create_blank_html_pages(pages)
566 html_file = self.setup_page(
567 pages[0], self.navbar["comparison"], title="Core plot comparison"
568 )
569 html_file.make_div(indent=2, _class='banner', _style=None)
570 html_file.add_content("Core plot comparison")
571 html_file.end_div()
572 html_file.make_div(indent=2, _class='paragraph', _style="max-width:1400px")
573 html_file.add_content(
574 "Below we compare the 1d histograms, autocorrelation and sample trace "
575 "plots produced by pesummary and `cbcBayesPostProc`."
576 )
577 html_file.end_div()
578 cli = "\n".join(
579 _launch_lalinference_cli(
580 self.abswebdir, self.path_to_results_file, add_symbol=True
581 )
582 )
583 cli += "\n"
584 cli += "\n".join(
585 _launch_pesummary_cli(
586 self.abswebdir, self.path_to_results_file, add_symbol=True
587 )
588 )
589 html_file.make_container()
590 styles = html_file.make_code_block(language="shell", contents=cli)
591 with open('{0:s}/css/Comparison_core_plots.css'.format(self.webdir), 'w') as g:
592 g.write(styles)
593 html_file.end_container()
594 _reverse_dict = {val: key for key, val in lalinference_map.items()}
595 _, lal_params = get_list_of_plots(self.webdir, lalinference=True)
596 not_included = []
597 _lalinf_base = "../lalinference"
598 _pes_base = "../pesummary"
599 for param in lal_params:
600 if param in standard_names.keys():
601 html_file.make_banner(
602 approximant=param, _style="font-size: 26px;"
603 )
604 contents = [[
605 "{}/1Dpdf/{}.png".format(_lalinf_base, param),
606 "{}/plots/pesummary_1d_posterior_{}.png".format(
607 _pes_base, standard_names[param]
608 )
609 ], [
610 "{}/1Dsamps/{}_acf.png".format(_lalinf_base, param),
611 "{}/plots/pesummary_autocorrelation_{}.png".format(
612 _pes_base, standard_names[param]
613 )
614 ], [
615 "{}/1Dsamps/{}_samps.png".format(_lalinf_base, param),
616 "{}/plots/pesummary_sample_evolution_{}.png".format(
617 _pes_base, standard_names[param]
618 )
619 ]]
620 html_file.make_table_of_images(contents=contents, autoscale=True)
621 try:
622 _lalinf_samples = self.samples["lalinference"][standard_names[param]]
623 _pes_samples = self.samples["pesummary"][standard_names[param]]
624 html_file.make_div(
625 _class="banner", _style="font-size:26px; color:red"
626 )
627 html_file.add_content(
628 "max difference in %s samples: %s" % (
629 standard_names[param], np.max(
630 np.abs(_lalinf_samples - _pes_samples)
631 )
632 )
633 )
634 html_file.end_div()
635 except Exception as e:
636 print(e)
637 else:
638 not_included.append(param)
639 html_file.make_div(
640 indent=2, _class='banner',
641 _style="font-size: 14px; max-width:1400px; margin-bottom: 2em"
642 )
643 html_file.add_content(
644 "parameters not included: {}".format(", ".join(not_included))
645 )
646 html_file.end_div()
647 html_file.make_footer()
649 def make_comparison_skymap(self):
650 """Make a page which compares the skymap produced with `ligo.skymap`
651 and pesummary.
652 """
653 pages = ["skymap"]
654 self.create_blank_html_pages(pages)
655 html_file = self.setup_page(
656 pages[0], self.navbar["comparison"], title="Skymap comparison",
657 )
658 html_file.make_div(indent=2, _class='banner', _style=None)
659 html_file.add_content("Skymap comparison")
660 html_file.end_div()
661 html_file.make_div(indent=2, _class='paragraph', _style="max-width:1400px")
662 html_file.add_content(
663 "Below we compare the skymap produced by ligo.skymap and the skymap "
664 "produced by pesummary (wrapper for ligo.skymap). We compare the "
665 "skymap plots and skymap stats."
666 )
667 html_file.end_div()
668 _webdir = self.abswebdir + "/ligo_skymap"
669 cli = "\n".join(
670 _launch_skymap_cli(_webdir, self.path_to_results_file, add_symbol=True)
671 )
672 cli += "\n\n"
673 cli += "\n".join(
674 _launch_pesummary_cli(_webdir, self.path_to_results_file, add_symbol=True)
675 )
676 html_file.make_container()
677 styles = html_file.make_code_block(language="shell", contents=cli)
678 with open('{0:s}/css/Comparison_skymap.css'.format(self.webdir), 'w') as g:
679 g.write(styles)
680 html_file.end_container()
681 lal_skymap = glob(
682 os.path.join(self.webdir, "ligo_skymap", "skymap.png")
683 )[0].replace(self.webdir, "")
684 pes_skymap = glob(
685 os.path.join(self.webdir, "pesummary", "plots", "pesummary_skymap.png")
686 )[0].replace(self.webdir, "")
687 contents = [
688 ["../{}".format(lal_skymap)], ["../{}".format(pes_skymap)]
689 ]
690 html_file = self.make_modal_carousel(html_file, contents)
691 html_file.make_div(indent=2, _class='banner', _style="font-size: 26px")
692 html_file.add_content("Stat comparison")
693 html_file.end_div()
694 lal_stats = np.genfromtxt(
695 os.path.join(self.webdir, "ligo_skymap", "skymap.txt"), names=True,
696 skip_header=True
697 )
698 pes_stats = np.genfromtxt(
699 os.path.join(
700 self.webdir, "pesummary", "samples", "pesummary_skymap_stats.dat"
701 ), names=True, skip_header=True
702 )
703 keys = lal_stats.dtype.names
704 headings = [" ", "ligo.skymap", "pesummary", "difference (%)"]
705 contents = []
706 for key in keys:
707 row = [key, lal_stats[key], pes_stats[key]]
708 row += [np.abs(lal_stats[key] - pes_stats[key]) * 100]
709 contents.append(row)
710 html_file.make_table(
711 headings=headings, contents=contents, heading_span=1,
712 accordian=False, format="table-hover header-fixed",
713 sticky_header=True
714 )
715 html_file.make_div(_style="margin-bottom: 2em")
716 html_file.end_div()
717 html_file.make_footer()
719 def make_comparison_samples(self):
720 """Make a page which compares the samples produced by `cbcBayesPostProc`
721 and pesummary.
722 """
723 pages = ["samples"]
724 self.create_blank_html_pages(pages)
725 html_file = self.setup_page(
726 pages[0], self.navbar["comparison"], title="Sample by sample comparison",
727 )
728 html_file.make_div(indent=2, _class='banner', _style=None)
729 html_file.add_content("Sample comparison")
730 html_file.end_div()
731 html_file.make_div(indent=2, _class='paragraph', _style="max-width:1400px")
732 html_file.add_content(
733 "Below we compare the samples stored in the lalinference "
734 "posterior_samples.dat (produced with `cbcBayesPostProc`) and the "
735 "samples stored in the `posterior_samples.h5` file (produced with "
736 "`pesummary`). We compare the medians, 90% confidence intervals."
737 )
738 html_file.end_div()
739 cli = "\n".join(
740 _launch_lalinference_cli(
741 self.abswebdir, self.path_to_results_file, add_symbol=True
742 )
743 )
744 cli += "\n"
745 cli += "\n".join(
746 _launch_pesummary_cli(
747 self.abswebdir, self.path_to_results_file, add_symbol=True
748 )
749 )
750 cli += "\n\n"
751 cli += "Files compared: \nlalinference: {}\npesummary: {}".format(
752 self.lalinference_path, self.pesummary_path
753 )
754 html_file.make_container()
755 styles = html_file.make_code_block(language="shell", contents=cli)
756 with open('{0:s}/css/Comparison_samples.css'.format(self.webdir), 'w') as g:
757 g.write(styles)
758 html_file.end_container()
759 headings = [" ", "lalinference", "pesummary", "difference (%)"]
760 contents = []
761 for _type in ["median", "5th percentile", "95th percentile"]:
762 if _type == "median":
763 func = np.median
764 elif _type == "5th percentile":
765 func = lambda array: np.percentile(array, 5)
766 elif _type == "95th percentile":
767 func = lambda array: np.percentile(array, 95)
768 for param in self.same_parameters:
769 row = []
770 lal = func(self.samples["lalinference"][param])
771 pes = func(self.samples["pesummary"][param])
772 row = [
773 param, lal, pes, np.abs(pes - lal) * 100
774 ]
775 contents.append(row)
776 html_file.make_div(
777 indent=2, _class='banner', _style="font-size: 26px; margin-top: 1em;"
778 )
779 html_file.add_content(_type)
780 html_file.end_div()
781 html_file.make_table(
782 headings=headings, contents=contents, heading_span=1,
783 accordian=False, format="table-hover header-fixed",
784 sticky_header=True
785 )
786 for analysis in ["lalinference", "pesummary"]:
787 html_file.make_div(
788 indent=2, _class='banner',
789 _style="font-size: 14px; max-width:1400px; margin-bottom: 2em"
790 )
791 html_file.add_content(
792 "{} parameters not included: {}".format(
793 analysis, ", ".join(
794 [
795 param for param in self.samples[analysis].keys()
796 if param not in self.same_parameters
797 ]
798 )
799 )
800 )
801 html_file.end_div()
802 html_file.make_footer()
805def main(args=None):
806 """Top level interface for `summaryreview`
807 """
808 parser = ArgumentParser(description=__doc__)
809 parser.add_known_options_to_parser(
810 ["--webdir", "--samples", "--test", "--multi_process"]
811 )
812 opts = parser.parse_args(args=args)
813 if opts.test == "core_plots" or opts.test == "all":
814 logger.info("Starting to generate plots using 'cbcBayesPostProc'")
815 launch_lalinference(opts.webdir, opts.samples)
816 logger.info("Starting to generate plots using 'summarypages'")
817 launch_pesummary(opts.webdir, opts.samples, multi_process=opts.multi_process)
818 if opts.test == "skymap" or opts.test == "all":
819 logger.info("Generating skymap with `ligo.skymap`")
820 launch_skymap(opts.webdir, opts.samples, multi_process=opts.multi_process)
821 if opts.test == "spin_disk" or opts.test == "all":
822 logger.info("Starting to make spin disk plots")
823 launch_spin_disk(opts.webdir, opts.samples)
824 logger.info("Making webpages to display tests")
825 try:
826 w = WebpageGeneration(opts.webdir, opts.samples, test=opts.test)
827 w.generate_webpages()
828 except Exception as e:
829 logger.warning("Unable to generate webpages because {}".format(e))
832if __name__ == "__main__":
833 main()