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#!/usr/bin/env python
2# (c) Stefan Countryman, 2019
4"""
5Manually create a ``skymap_info.json`` file (necessary to start a LLAMA
6analysis for a GW event) using various types of initialization data.
7"""
9import os
10import sys
11import tempfile
12from shutil import copy
13from argparse import RawDescriptionHelpFormatter
14from llama.utils import DEFAULT_RUN_DIR, GenerationError
15from llama.event import Event
16from llama.files.lvc_skymap.utils import SKYMAP_FILENAMES
17from llama.files.advok import Advok
18from llama.files.skymap_info import SkymapInfo, is_super
19from llama.cli import Parsers, CliParser
20from llama.flags.cli import Parsers as FlagParsers
21from llama.files.skymap_info.cli import Parsers as SkyParsers
23EPILOG = f"""
24By default, save this event in the default run directory
25({DEFAULT_RUN_DIR}) using this
26event's GraceID as the eventid, so that the output file will be in the
27{DEFAULT_RUN_DIR}/GRACEID directory.
29If no ``--outfile`` is provided, the default filename ({SkymapInfo.FILENAME})
30will be used and all metadata and flags will be copied to ``--outdir``.
31Otherwise, only the skymap information will be copied to the destination path
32(with the requested filename).
34If ``--graceid`` is provided, the event will be constructed by querying GraceDB
35for this event. Can be a superevent or a regular event. Only one of
36``--graceid`` or ``--voevent`` can be specified (since they both serve to
37create a new ``skymap_info`` event). If no ``--skymap`` filename is specified,
38the latest skymap added to GraceDB with one of the following names will be
39used:
41{{}}
42""".format('\n'.join('- '+f for f in SKYMAP_FILENAMES)).strip()
45def err(*args, **kwargs):
46 """Print error message to stderr. Shortcut for print(...
47 file=sys.stderr)"""
48 print(*args, file=sys.stderr, **kwargs)
51def get_parser():
52 """Parse command line arguments for the command-line functionality of this
53 module (or, alternatively, provide your own argument list)."""
54 parser = CliParser(description=__doc__, epilog=EPILOG,
55 prog="llama files skymap_info",
56 formatter_class=RawDescriptionHelpFormatter,
57 parents=(Parsers.outdir, Parsers.outfile,
58 Parsers.clobber, FlagParsers.flags,
59 SkyParsers.graceid, SkyParsers.skymap))
60 parser.add_argument('-v', '--voevent', help="""
61 If provided, the event will be constructed by reading from this VOEvent
62 file. Only one of ``--graceid`` or ``--voevent`` can be specified. If
63 no ``--skymap`` filename is specified, then the skymap specified in the
64 VOEvent will be used.""")
65 return parser
68def run_on_args(cliargs=None, error_on_failure=False):
69 """Run this script on the given command line arguments. If
70 ``error_on_failure`` is ``True``, raise a ``Run"""
71 parser = get_parser()
72 if cliargs is not None:
73 args = parser.parse_args(cliargs)
74 else:
75 args = parser.parse_args()
76 if ((args.voevent is not None and args.graceid is not None) or
77 (args.voevent is None and args.graceid is None)):
78 msg = "Provide exactly one of --graceid or --voevent."
79 if error_on_failure:
80 raise RuntimeError(msg)
81 parser.error(msg)
82 try:
83 with tempfile.TemporaryDirectory() as tempdir:
84 event = Event.fromdir(tempdir)
85 event.init()
86 # necessary check since an empty ``args.flags`` list will not
87 # lead to an update
88 if args.flags:
89 event.flags.update(args.flags)
90 else:
91 event.flags.update(event.flags.DEFAULT_FLAGS)
92 skyinfo = event.files.SkymapInfo
93 if args.voevent:
94 tmpvoe = event.files.LvcGcnXml
95 copy(args.voevent, tmpvoe.fullpath)
96 skyinfo.generate_from_lvc_gcn_xml(tmpvoe)
97 # mark as ADVOK if this is an Initial or Update event
98 if tmpvoe.get_alert_type() in ('Initial', 'Update'):
99 adv = Advok(tmpvoe)
100 adv.generate('gcn', tmpvoe.notice_time_str)
101 tmpvoe.delete()
102 elif args.graceid:
103 if is_super(args.graceid):
104 skyinfo.generate_from_gracedb_superevent(args.graceid,
105 args.skymap)
106 else:
107 skyinfo.generate_from_gracedb(args.graceid, args.skymap)
108 graceid = skyinfo.graceid
109 if not args.outdir:
110 args.outdir = Event(graceid).eventdir
111 if not os.path.isdir(args.outdir):
112 os.mkdir(args.outdir)
113 if args.outfile:
114 outpath = os.path.join(args.outdir, args.outfile)
115 copy(skyinfo.fullpath, outpath)
116 print(f"New SkymapInfo at {outpath}")
117 else:
118 for fname in os.listdir(event.eventdir):
119 src = os.path.join(event.eventdir, fname)
120 if not os.path.isdir(src):
121 copy(src, os.path.join(args.outdir, fname))
122 out = Event.fromdir(args.outdir)
123 out.init()
124 out.flags.update(args.flags)
125 out.git.commit_changes("Manually generated SkymapInfo from "
126 "CLI.")
127 print(f"New SkymapInfo at {out.files.SkymapInfo.fullpath}")
128 except GenerationError as exc:
129 msg = f"Error generating skymap: {exc}"
130 if error_on_failure:
131 raise RuntimeError(msg)
132 parser.error(msg)
135def main():
136 """Create a new ``skymap_info.json`` file."""
137 run_on_args()
140if __name__ == "__main__":
141 main()