Coverage for pesummary/gw/finish.py: 91.1%

56 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2026-01-15 17:49 +0000

1# Licensed under an MIT style license -- see LICENSE.md 

2 

3import subprocess 

4import os 

5import time 

6import numpy as np 

7 

8from pesummary.core.cli.parser import convert_dict_to_namespace 

9from pesummary.core.finish import FinishingTouches 

10from pesummary.utils.utils import logger 

11from pesummary.cli.summarymodify import _main, command_line 

12 

13__author__ = ["Charlie Hoy <charlie.hoy@ligo.org>"] 

14 

15 

16class GWFinishingTouches(FinishingTouches): 

17 """Class to handle the finishing touches 

18 

19 Parameters 

20 ---------- 

21 ligo_skymap_PID: dict 

22 dictionary containing the process ID for the ligo.skymap subprocess 

23 for each analysis 

24 """ 

25 def __init__(self, inputs, ligo_skymap_PID=None): 

26 super(GWFinishingTouches, self).__init__(inputs) 

27 self.ligo_skymap_PID = ligo_skymap_PID 

28 self.generate_ligo_skymap_statistics() 

29 

30 def generate_ligo_skymap_statistics(self): 

31 """Extract key statistics from the ligo.skymap fits file 

32 """ 

33 FAILURE = False 

34 if self.ligo_skymap_PID is None: 

35 return 

36 samples_dir = os.path.join(self.inputs.webdir, "samples") 

37 for label in self.inputs.labels: 

38 _path = os.path.join(samples_dir, "{}_skymap.fits".format(label)) 

39 while not os.path.isfile(_path): 

40 # fits file has not been created. Check if the process is still 

41 # running 

42 try: 

43 output = subprocess.check_output( 

44 ["ps -p {}".format(self.ligo_skymap_PID[label].pid)], 

45 shell=True 

46 ) 

47 cond1 = "summarypages" not in str(output) 

48 cond2 = "defunct" in str(output) 

49 if cond1 or cond2: 

50 if not os.path.isfile(_path): 

51 FAILURE = True 

52 break 

53 except (subprocess.CalledProcessError, KeyError): 

54 FAILURE = True 

55 break 

56 # wait for the process to finish 

57 time.sleep(60) 

58 if FAILURE: 

59 continue 

60 ess = subprocess.Popen( 

61 "ligo-skymap-stats {} -p 50 90 -o {}".format( 

62 os.path.join(samples_dir, "{}_skymap.fits".format(label)), 

63 os.path.join( 

64 samples_dir, "{}_skymap_stats.dat".format(label) 

65 ) 

66 ), shell=True 

67 ) 

68 ess.wait() 

69 self.save_skymap_stats_to_metafile( 

70 label, os.path.join(samples_dir, "{}_skymap_stats.dat".format(label)) 

71 ) 

72 self.save_skymap_data_to_metafile( 

73 label, os.path.join(samples_dir, "{}_skymap.fits".format(label)) 

74 ) 

75 

76 def save_skymap_stats_to_metafile(self, label, filename): 

77 """Save the skymap statistics to the PESummary metafile 

78 

79 Parameters 

80 ---------- 

81 label: str 

82 the label of the analysis that the skymap statistics corresponds to 

83 filename: str 

84 name of the file that contains the skymap statistics for label 

85 """ 

86 logger.info("Adding ligo.skymap statistics to the metafile") 

87 try: 

88 skymap_data = np.genfromtxt(filename, names=True, skip_header=True) 

89 except IndexError: 

90 logger.warning( 

91 "Failed to open '{}'. Unable to store skymap statistics in " 

92 "metafile".format(filename) 

93 ) 

94 return 

95 keys = skymap_data.dtype.names 

96 

97 _dict = { 

98 "webdir": self.inputs.webdir, 

99 "samples": [os.path.join(self.inputs.webdir, "samples", "posterior_samples.h5")], 

100 "kwargs": {label: ["{}:{}".format(key, float(skymap_data[key])) for key in keys]}, 

101 "overwrite": True 

102 } 

103 opts = convert_dict_to_namespace(_dict, add_defaults=command_line()) 

104 _main(opts) 

105 

106 def save_skymap_data_to_metafile(self, label, filename): 

107 """Save the skymap data to the PESummary metafile 

108 

109 Parameters 

110 ---------- 

111 label: str 

112 the label of the analysis that the skymap corresponds to 

113 filename: str 

114 name of the fits file that contains the skymap for label 

115 """ 

116 logger.info("Adding ligo.skymap data to the metafile") 

117 

118 _dict = { 

119 "webdir": self.inputs.webdir, 

120 "samples": [os.path.join(self.inputs.webdir, "samples", "posterior_samples.h5")], 

121 "overwrite": True, "store_skymap": {label: filename} 

122 } 

123 opts = convert_dict_to_namespace(_dict, add_defaults=command_line()) 

124 _main(opts)