Hide keyboard shortcuts

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 

3 

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""" 

8 

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 

22 

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. 

28 

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). 

33 

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: 

40 

41{{}} 

42""".format('\n'.join('- '+f for f in SKYMAP_FILENAMES)).strip() 

43 

44 

45def err(*args, **kwargs): 

46 """Print error message to stderr. Shortcut for print(... 

47 file=sys.stderr)""" 

48 print(*args, file=sys.stderr, **kwargs) 

49 

50 

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 

66 

67 

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) 

133 

134 

135def main(): 

136 """Create a new ``skymap_info.json`` file.""" 

137 run_on_args() 

138 

139 

140if __name__ == "__main__": 

141 main()