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 2016-2018, Rainer Corley 2016 

3""" 

4``FileHandler`` for making a nicely-formatted ascii table of IceCube neutrinos 

5including their reconstructed properties and their joint significance when 

6combined with a gravitational wave. Can also be used as a stand-alone 

7command-line script to generate a human-readable table with neutrinos for this 

8event from an input JSON file. Used for GCN circulars. 

9""" 

10 

11import sys 

12import json 

13from llama.utils import mjd2gps 

14from llama.files.i3.utils import zen_az2ra_dec 

15from llama.filehandler import FileHandler 

16from llama.files.i3.json import IceCubeNeutrinoList 

17from llama.files.skymap_info import SkymapInfo 

18from llama.files.coinc_significance import CoincSignificanceI3Lvc 

19from llama.files.gwastro import GWAstroReceipt 

20 

21 

22@GWAstroReceipt.upload_this() 

23@FileHandler.set_class_attributes 

24class IceCubeNeutrinoListTxt(FileHandler): 

25 """ 

26 A space-delimited, table-formatted list of neutrinos formatted for human 

27 consumption in GCN Circulars. 

28 """ 

29 

30 FILENAME = "icecube_neutrino_list.txt" 

31 DEPENDENCIES = (IceCubeNeutrinoList, SkymapInfo,) 

32 

33 def _generate(self): # pylint: disable=W0221 

34 infilename = IceCubeNeutrinoList(self).fullpath 

35 outfilename = self.fullpath 

36 gpstime = SkymapInfo(self).event_time_gps 

37 convert_json_neutrinos_to_txt(infilename, outfilename, gpstime=gpstime) 

38 

39 

40@FileHandler.set_class_attributes 

41class IceCubeNeutrinoListCoincTxt(FileHandler): 

42 """ 

43 A space-delimited, table-formatted list of neutrinos meant for human 

44 consumption in GCN Circulars. Contains coincidence significance measures in 

45 addition to the base neutrino properties. 

46 """ 

47 

48 FILENAME = 'icecube_neutrino_list_coinc.txt' 

49 DEPENDENCIES = (IceCubeNeutrinoList, SkymapInfo, 

50 CoincSignificanceI3Lvc) 

51 

52 def _generate(self): # pylint: disable=W0221 

53 infilename = IceCubeNeutrinoList(self).fullpath 

54 outfilename = self.fullpath 

55 gpstime = SkymapInfo(self).event_time_gps 

56 p_values = CoincSignificanceI3Lvc(self).p_values 

57 convert_json_neutrinos_to_txt(infilename, outfilename, gpstime=gpstime, 

58 p_values=p_values) 

59 

60 

61# pylint: disable=invalid-name 

62def convert_json_neutrinos_to_txt(infilename, outfilename, gpstime=None, 

63 p_values=None): 

64 """Take a json-formatted input filename and an output filename (both full 

65 paths) as arguments. Convert the neutrino list in the infile into a 

66 space-delimited, table-formatted list of neutrinos intended for human 

67 readability and saved to the path specified in outfilename. If an optional 

68 gpstime is given, then the time column will be given as the time difference 

69 in seconds between the neutrino's arrival and the GPS time provided, i.e. 

70 the neutrino detection time with t=0 defined as the GPS time.""" 

71 if gpstime is None: 

72 time_title = 'GPS' 

73 gpstime = 0 

74 else: 

75 time_title = 'dt[s]' 

76 column_titles = [time_title, 'RA[deg]', 'Dec[deg]', 'E[TeV]', 'Sigma[deg]'] 

77 with open(infilename, 'r') as infile: 

78 data = json.load(infile) 

79 # handle current and old neutrino list format 

80 if isinstance(data, dict): 

81 neutrinos = data['triggers'] 

82 else: 

83 neutrinos = data 

84 # if odds_ratios are provided, include a column for them 

85 if p_values is not None: 

86 column_titles += ["P Value"] 

87 with open(outfilename, 'w') as f: 

88 # write column titles 

89 f.write('#' + (' ' * 5)) # row number 

90 for column_title in column_titles: 

91 f.write('{0: >12}'.format(column_title)) 

92 f.write('\n') 

93 # write separator between header and data 

94 f.write(('-' * (6 + 12 * len(column_titles))) + '\n') 

95 # write rows 

96 for i, n in enumerate(neutrinos): 

97 # line num, 6 spaces long 

98 f.write(('{}.' + ' '*4).format(i+1)[:6]) 

99 f.write(' {:11.2f}'.format(mjd2gps(n['mjd']) - gpstime)) 

100 ra, dec = zen_az2ra_dec(n['mjd'], n['zenith'], n['azimuth']) 

101 f.write(' {:11.1f}'.format(ra)) 

102 f.write(' {:11.1f}'.format(dec)) 

103 # GeV->TeV 

104 f.write(' {:11.2f}'.format(n['energy'] / 1000.)) 

105 # rad->deg 

106 if isinstance(n['sigma'], float): 

107 f.write(' {:11.2f}'.format(n['sigma'])) 

108 else: 

109 # might be undefined, need to print the string 

110 f.write(' {:>11}'.format(n['sigma'])) 

111 if p_values is not None: 

112 f.write(' {:11.8f}'.format(p_values[i])) 

113 f.write('\n') 

114 

115 

116# we want parentheses after python2 print statements to maintain python3 

117# compatibility. 

118# pylint: disable=superfluous-parens 

119def main(): 

120 """Can also use this module as a command-line script to make this file 

121 conversion.""" 

122 infilename = sys.argv[1] 

123 outfilename = sys.argv[2] 

124 convert_json_neutrinos_to_txt(infilename, outfilename) 

125 

126 if len(sys.argv) == 1 or '-h' in sys.argv: 

127 print('USAGE: {} infile.json outfile.txt'.format(sys.argv[0])) 

128 print('Take a LLAMA JSON neutrino list as input and save a') 

129 print('space-delimited output text file with the following format:') 

130 print(' dt RA Dec Energy Sigma') 

131 print('Where dt is the time difference between the gravitational wave') 

132 print('arrival time and the timestamp for the neutrino, RA is the') 

133 print('right ascension, DEC is the declination, Energy is the energy,') 

134 print('and Sigma is the directional uncertainty in degrees.') 

135 exit(1) 

136 

137if __name__ == "__main__": 

138 main()