Coverage for lst_auto_rta / High_Level_analysis_Maps.py: 0%

132 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-08 14:48 +0000

1#!/usr/bin/env python 

2 

3import datetime 

4import logging 

5import os 

6import time 

7 

8import pymongo 

9 

10def wait_for_directory(directory, interval=5): 

11 """ 

12 Wait for the directory to exist 

13 

14 :param directory: directory path 

15 :param interval: Time interval between verification 

16 """ 

17 while not os.path.exists(directory): 

18 print(f"{directory} does not exist yet. let's wait {interval} seconds...") 

19 time.sleep(interval) 

20 print(f"The directory {directory} finally exist !!!") 

21 

22 

23def now(): 

24 """ 

25 Returns the current timestamp in seconds, relative to the Unix epoch. 

26 

27 :return: float 

28 """ 

29 return datetime.datetime.timestamp(datetime.datetime.now()) 

30 

31 

32def get_current_run( 

33 db_hostname: str = "lst101", 

34 obs_target_query_timeout_s: int = 10, 

35) -> int: 

36 """ 

37 Standalone retrieval of the current run number from the lst1_obs_summary DB. 

38 Robust to duplicated run_number entries. 

39 """ 

40 try: 

41 with pymongo.MongoClient(db_hostname) as client: 

42 collection = client.get_database("lst1_obs_summary").get_collection("telescope") 

43 camera_data_index = [("data.camera.tstart", pymongo.DESCENDING)] 

44 

45 keep_querying = True 

46 query_idx = 0 

47 visited_ids: Set[object] = set() 

48 

49 obs_id: Optional[int] = None 

50 nb_duplicated_run_numbers = 0 

51 

52 while keep_querying: 

53 cursor = collection.find( 

54 { 

55 "data.camera.run_number": {"$exists": True}, 

56 "data.camera.tstart": {"$exists": True}, 

57 "data.structure.tstart": {"$exists": True}, 

58 }, 

59 { 

60 "_id": True, 

61 "data.camera.run_number": True, 

62 "data.camera.tstart": True, 

63 "data.structure.tstart": True, 

64 }, 

65 sort=camera_data_index, 

66 max_time_ms=obs_target_query_timeout_s * 1000, 

67 skip=query_idx, 

68 limit=1, 

69 ) 

70 

71 try: 

72 query_data = next(cursor) 

73 finally: 

74 # Close cursor explicitly for older pymongo versions 

75 cursor.close() 

76 

77 # If the DB changes while iterating, we may get the same _id again: ignore it 

78 if query_data["_id"] in visited_ids: 

79 query_idx += 1 

80 continue 

81 visited_ids.add(query_data["_id"]) 

82 

83 camera_list = sorted(query_data["data"]["camera"], key=lambda x: x["tstart"], reverse=True) 

84 structure_list = sorted(query_data["data"]["structure"], key=lambda x: x["tstart"], reverse=True) 

85 

86 # If the DB is incoherent for the latest run: raise error. 

87 if (len(structure_list) != len(camera_list)) and (query_idx == 0): 

88 raise pymongo.errors.PyMongoError( 

89 "TCU DB query returned inconsistent data.structure (length {}) " 

90 "and data.camera (length {})".format(len(structure_list), len(camera_list)) 

91 ) 

92 

93 if query_idx == 0: 

94 obs_id = camera_list[0]["run_number"] 

95 

96 comparison_start_idx = 1 if query_idx == 0 else 0 

97 for field in camera_list[comparison_start_idx:]: 

98 if field["run_number"] != obs_id: 

99 keep_querying = False 

100 break 

101 nb_duplicated_run_numbers += 1 

102 

103 query_idx += 1 

104 

105 if obs_id is None: 

106 logging.error("DB query succeeded but no obs_id was extracted") 

107 return -1 

108 

109 return int(obs_id + nb_duplicated_run_numbers) 

110 

111 except pymongo.errors.ExecutionTimeout: 

112 logging.error("DB query timeout (max_time_ms exceeded) while retrieving current run number") 

113 return -1 

114 except (StopIteration, KeyError, TypeError) as e: 

115 logging.error(f"DB returned unexpected/empty data while retrieving current run number: {e}") 

116 return -1 

117 except pymongo.errors.PyMongoError as e: 

118 logging.error(f"MongoDB error while retrieving current run number: {e}") 

119 return -1 

120 except Exception as e: 

121 logging.error(f"Unexpected error while retrieving current run number: {e}") 

122 return -1 

123 

124 

125def get_night_timestamp(today): 

126 """ 

127 Get current timestamp (YYYYMMDD) with respect to the night. 

128 It will consider a same night everything run between 08h00 until 07h59 of the next day. 

129 

130 Ex: An observation launched at 04h00 (local time) will refer to the previous day. 

131 

132 :param today: datetime object 

133 datetime object with current local time 

134 

135 :return: 

136 timestamp: str 

137 """ 

138 # TODO check that today is a datetime object ? 

139 if today.hour < 8: # script launched between 

140 yesterday = today - datetime.timedelta(days=1) 

141 timestamp = f"{yesterday.year:04d}{yesterday.month:02d}{yesterday.day:02d}" 

142 else: 

143 timestamp = f"{today.year:04d}{today.month:02d}{today.day:02d}" 

144 

145 return timestamp 

146 

147 

148def Obtain_RA_DEC(runid): 

149 try: 

150 client = pymongo.MongoClient("lst101") 

151 database = client["bridgesmonitoring"] 

152 print(client) 

153 

154 client = pymongo.MongoClient("lst101") 

155 database = client["lst1_obs_summary"] 

156 camera_collection = database["telescope"] 

157 summaries = camera_collection.find({"data.camera.run_number": runid}) 

158 

159 for summary in summaries: 

160 camera = summary["data"]["camera"] 

161 count = 0 

162 structure = summary["data"]["structure"] 

163 for c in camera: 

164 if c["run_number"] == runid: 

165 run_count = count 

166 count = count + 1 

167 run_parameters = structure[run_count] 

168 return ( 

169 run_parameters["target"]["ra"], 

170 run_parameters["target"]["dec"], 

171 run_parameters["target"]["source_ra"], 

172 run_parameters["target"]["source_dec"], 

173 ) 

174 except Exception as e: 

175 # client = pymongo.MongoClient('lst101') 

176 # database = client['lst1_obs_summary'] 

177 # camera_collection = database['camera'] 

178 # summaries = camera_collection.find({}) 

179 # for summary in summaries: 

180 # if (summary['tstart'] > datetime.datetime.timestamp(datetime.datetime.now())-3600*24*100): 

181 # if (summary['run_number']==runid and summary["kind"] != "data_taking"): 

182 # return [0,0,0,0] 

183 logging.error("Error DB !!!!!") 

184 return [0, 0, 0, 0] 

185 

186def today_to_directory(today): 

187 return today[0:4]+"/"+today[4:6]+"/"+today[6:8] 

188 

189def main(): 

190 """ 

191 Initialize current_run_is and quit variables and get the current timestamp with Start_time = now() 

192 Initialize the logging system by setting the log file name and logging level 

193 Change the current working directory to /fefs/onsite/pipeline/rta/data 

194 Find the current reservations for nodes using the scontrol command and parse the output to find the individual node names 

195 Modify a configuration file with sed commands, replacing placeholders with the node names found in step 4 

196 Check if the ib0 network interface is in connected mode for each of the nodes and log the results 

197 """ 

198 current_run_is = -1 

199 quit = False 

200 

201 Start_time = now() 

202 

203 # today = str(datetime.datetime.now().year) + str(datetime.datetime.now().month) + str(datetime.datetime.now().day) 

204 today = get_night_timestamp(datetime.datetime.now()) 

205 wait_for_directory("/fefs/onsite/pipeline/rta/data/"+today_to_directory(today)) 

206 logging.basicConfig(filename="/fefs/onsite/pipeline/rta/data/"+today_to_directory(today)+"/log_High_Level_Maps_" + today + ".txt", level=logging.INFO) 

207 logging.info("Start RTA High Level for the day " + today) 

208 

209 RTA_ready = True 

210 

211 loop_id = 0 

212 ra_dec = [0, 0, 0, 0] 

213 data_directory = "'/fefs/onsite/pipeline/rta/data/" 

214 while quit == False and RTA_ready: 

215 time.sleep(10) 

216 # print(current_run_is+1) 

217 if current_run_is == -1: 

218 current_run_is = get_current_run() 

219 if current_run_is == -1: 

220 logging.info("None") 

221 current_run_is = -1 

222 continue 

223 if current_run_is != get_current_run(): 

224 time.sleep(1) 

225 current_run_is = get_current_run() 

226 if current_run_is != -1: 

227 logging.info("Start RTA check for run " + str(current_run_is)) 

228 time.sleep(2) 

229 ra_dec = Obtain_RA_DEC(current_run_is + 1) 

230 logging.info( 

231 # ~ "srun --reservation=rta_one_node ./Ring_Background_Maps.py -da " 

232 "./Ring_Background_Maps.py -da " 

233 + today_to_directory(today) 

234 + " -r " 

235 + str(current_run_is + 1) 

236 + " -RA " 

237 + str(ra_dec[2]) 

238 + " -DEC " 

239 + str(ra_dec[3]) 

240 ) 

241 os.system( 

242 # ~ "srun --reservation=rta_one_node ./Ring_Background_Maps.py -da " 

243 "./Ring_Background_Maps.py -da " 

244 + today_to_directory(today) 

245 + " -r " 

246 + str(current_run_is + 1) 

247 + " -RA " 

248 + str(ra_dec[2]) 

249 + " -DEC " 

250 + str(ra_dec[3]) 

251 ) 

252 

253 if loop_id % 1 == 0: 

254 logging.info("Start RTA check for run " + str(current_run_is)) 

255 time.sleep(2) 

256 logging.info(datetime.datetime.now()) 

257 ra_dec = Obtain_RA_DEC(current_run_is + 1) 

258 logging.info( 

259 # ~ "srun --reservation=rta_one_node ./Ring_Background_Maps.py -da " 

260 "./Ring_Background_Maps.py -da " 

261 + today_to_directory(today) 

262 + " -r " 

263 + str(current_run_is + 1) 

264 + " -RA " 

265 + str(ra_dec[2]) 

266 + " -DEC " 

267 + str(ra_dec[3]) 

268 ) 

269 os.system( 

270 # ~ "srun --reservation=rta_one_node ./Ring_Background_Maps.py -da " 

271 "./Ring_Background_Maps.py -da " 

272 + today_to_directory(today) 

273 + " -r " 

274 + str(current_run_is + 1) 

275 + " -RA " 

276 + str(ra_dec[2]) 

277 + " -DEC " 

278 + str(ra_dec[3]) 

279 ) 

280 

281 loop_id = loop_id + 1 

282 if (datetime.datetime.timestamp(datetime.datetime.now()) - Start_time) > 14 * 3600: 

283 quit = True 

284 logging.info("End of the night, Stop the RTA check") 

285 

286 

287if __name__ == "__main__": 

288 main()