Coverage for lst_auto_rta / High_Level_analysis.py: 0%

140 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 

31def get_current_run( 

32 db_hostname: str = "lst101", 

33 obs_target_query_timeout_s: int = 10, 

34) -> int: 

35 """ 

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

37 Robust to duplicated run_number entries. 

38 """ 

39 try: 

40 with pymongo.MongoClient(db_hostname) as client: 

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

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

43 

44 keep_querying = True 

45 query_idx = 0 

46 visited_ids: Set[object] = set() 

47 

48 obs_id: Optional[int] = None 

49 nb_duplicated_run_numbers = 0 

50 

51 while keep_querying: 

52 cursor = collection.find( 

53 { 

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

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

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

57 }, 

58 { 

59 "_id": True, 

60 "data.camera.run_number": True, 

61 "data.camera.tstart": True, 

62 "data.structure.tstart": True, 

63 }, 

64 sort=camera_data_index, 

65 max_time_ms=obs_target_query_timeout_s * 1000, 

66 skip=query_idx, 

67 limit=1, 

68 ) 

69 

70 try: 

71 query_data = next(cursor) 

72 finally: 

73 # Close cursor explicitly for older pymongo versions 

74 cursor.close() 

75 

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

77 if query_data["_id"] in visited_ids: 

78 query_idx += 1 

79 continue 

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

81 

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

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

84 

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

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

87 raise pymongo.errors.PyMongoError( 

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

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

90 ) 

91 

92 if query_idx == 0: 

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

94 

95 comparison_start_idx = 1 if query_idx == 0 else 0 

96 for field in camera_list[comparison_start_idx:]: 

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

98 keep_querying = False 

99 break 

100 nb_duplicated_run_numbers += 1 

101 

102 query_idx += 1 

103 

104 if obs_id is None: 

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

106 return -1 

107 

108 return int(obs_id + nb_duplicated_run_numbers) 

109 

110 except pymongo.errors.ExecutionTimeout: 

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

112 return -1 

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

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

115 return -1 

116 except pymongo.errors.PyMongoError as e: 

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

118 return -1 

119 except Exception as e: 

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

121 return -1 

122 

123def get_night_timestamp(today): 

124 """ 

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

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

127 

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

129 

130 :param today: datetime object 

131 datetime object with current local time 

132 

133 :return: 

134 timestamp: str 

135 """ 

136 # TODO check that today is a datetime object ? 

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

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

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

140 else: 

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

142 

143 return timestamp 

144 

145 

146def Obtain_RA_DEC(runid): 

147 try: 

148 client = pymongo.MongoClient("lst101") 

149 database = client["bridgesmonitoring"] 

150 print(client) 

151 

152 client = pymongo.MongoClient("lst101") 

153 database = client["lst1_obs_summary"] 

154 camera_collection = database["telescope"] 

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

156 

157 for summary in summaries: 

158 camera = summary["data"]["camera"] 

159 count = 0 

160 structure = summary["data"]["structure"] 

161 for c in camera: 

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

163 run_count = count 

164 count = count + 1 

165 run_parameters = structure[run_count] 

166 return ( 

167 run_parameters["target"]["ra"], 

168 run_parameters["target"]["dec"], 

169 run_parameters["target"]["source_ra"], 

170 run_parameters["target"]["source_dec"], 

171 ) 

172 except Exception as e: 

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

174 # database = client['lst1_obs_summary'] 

175 # camera_collection = database['camera'] 

176 # summaries = camera_collection.find({}) 

177 # for summary in summaries: 

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

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

180 # return [0,0,0,0] 

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

182 return [0, 0, 0, 0] 

183 

184def today_to_directory(today): 

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

186 

187def main(): 

188 """ 

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

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

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

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

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

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

195 """ 

196 current_run_is = -1 

197 quit = False 

198 

199 Start_time = now() 

200 

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

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

203 

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

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

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

207 

208 RTA_ready = True 

209 

210 loop_id = 0 

211 ra_dec = [0, 0, 0, 0] 

212 data_directory = "/fefs/onsite/pipeline/rta/data/" 

213 while quit == False and RTA_ready: 

214 time.sleep(10) 

215 # print(current_run_is+1) 

216 if current_run_is == -1: 

217 current_run_is = get_current_run() 

218 if current_run_is == -1: 

219 logging.info("None") 

220 current_run_is = -1 

221 continue 

222 if current_run_is != get_current_run(): 

223 time.sleep(1) 

224 current_run_is = get_current_run() 

225 if current_run_is != -1: 

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

227 time.sleep(2) 

228 ra_dec = Obtain_RA_DEC(current_run_is + 1) 

229 logging.info( 

230 # ~ "srun --reservation=rta_one_node ./Theta_square.py -da " 

231 "./Theta_square.py -da " 

232 + today_to_directory(today) 

233 + " -r " 

234 + str(current_run_is + 1) 

235 + " -RA " 

236 + str(ra_dec[2]) 

237 + " -DEC " 

238 + str(ra_dec[3]) 

239 ) 

240 os.system( 

241 # ~ "srun --reservation=rta_one_node ./Theta_square.py -da " 

242 "./Theta_square.py -da " 

243 + today_to_directory(today) 

244 + " -r " 

245 + str(current_run_is + 1) 

246 + " -RA " 

247 + str(ra_dec[2]) 

248 + " -DEC " 

249 + str(ra_dec[3]) 

250 ) 

251 logging.info( 

252 # ~ "srun --reservation=rta_one_node ./Spectra.py -da " 

253 "./Spectra.py -da " 

254 + today_to_directory(today) 

255 + " -r " 

256 + str(current_run_is + 1) 

257 + " -RA " 

258 + str(ra_dec[2]) 

259 + " -DEC " 

260 + str(ra_dec[3]) 

261 ) 

262 os.system( 

263 # ~ "srun --reservation=rta_one_node ./Spectra.py -da " 

264 "./Spectra.py -da " 

265 + today_to_directory(today) 

266 + " -r " 

267 + str(current_run_is + 1) 

268 + " -RA " 

269 + str(ra_dec[2]) 

270 + " -DEC " 

271 + str(ra_dec[3]) 

272 ) 

273 logging.info( 

274 # ~ "srun --reservation=rta_one_node ./rta_var.py --dl3_folder "  

275 "./rta_var.py --dl3_folder " 

276 + data_directory 

277 + today_to_directory(today) 

278 + "/" 

279 + str(current_run_is + 1) 

280 + "/DL3 -ra " 

281 + str(ra_dec[2]) 

282 + " -dec " 

283 + str(ra_dec[3]) 

284 + " --output_dir "+ data_directory 

285 + today_to_directory(today) 

286 + "/" 

287 + str(current_run_is + 1) 

288 + "/plots --date " 

289 + today 

290 ) 

291 os.system( 

292 # ~ "srun --reservation=rta_one_node ./rta_var.py --dl3_folder "  

293 "./rta_var.py --dl3_folder " 

294 + data_directory 

295 + today_to_directory(today) 

296 + "/" 

297 + str(current_run_is + 1) 

298 + "/DL3 -ra " 

299 + str(ra_dec[2]) 

300 + " -dec " 

301 + str(ra_dec[3]) 

302 + " --output_dir " + data_directory 

303 + today_to_directory(today) 

304 + "/" 

305 + str(current_run_is + 1) 

306 + "/plots --date " 

307 + today 

308 ) 

309 

310 if loop_id % 1 == 0: 

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

312 time.sleep(2) 

313 logging.info(datetime.datetime.now()) 

314 ra_dec = Obtain_RA_DEC(current_run_is + 1) 

315 logging.info( 

316 "./Theta_square.py -da " 

317 + today_to_directory(today) 

318 + " -r " 

319 + str(current_run_is + 1) 

320 + " -RA " 

321 + str(ra_dec[2]) 

322 + " -DEC " 

323 + str(ra_dec[3]) 

324 ) 

325 os.system( 

326 "./Theta_square.py -da " 

327 + today_to_directory(today) 

328 + " -r " 

329 + str(current_run_is + 1) 

330 + " -RA " 

331 + str(ra_dec[2]) 

332 + " -DEC " 

333 + str(ra_dec[3]) 

334 ) 

335 logging.info( 

336 "./Spectra.py -da " 

337 + today_to_directory(today) 

338 + " -r " 

339 + str(current_run_is + 1) 

340 + " -RA " 

341 + str(ra_dec[2]) 

342 + " -DEC " 

343 + str(ra_dec[3]) 

344 ) 

345 os.system( 

346 "./Spectra.py -da " 

347 + today_to_directory(today) 

348 + " -r " 

349 + str(current_run_is + 1) 

350 + " -RA " 

351 + str(ra_dec[2]) 

352 + " -DEC " 

353 + str(ra_dec[3]) 

354 ) 

355 logging.info( 

356 "./rta_var.py --dl3_folder "+ data_directory 

357 + today_to_directory(today) 

358 + "/" 

359 + str(current_run_is + 1) 

360 + "/DL3 -ra " 

361 + str(ra_dec[2]) 

362 + " -dec " 

363 + str(ra_dec[3]) 

364 + " --output_dir "+ data_directory 

365 + today_to_directory(today) 

366 + "/" 

367 + str(current_run_is + 1) 

368 + "/plots --date " 

369 + today 

370 ) 

371 os.system( 

372 "./rta_var.py --dl3_folder "+ data_directory 

373 + today_to_directory(today) 

374 + "/" 

375 + str(current_run_is + 1) 

376 + "/DL3 -ra " 

377 + str(ra_dec[2]) 

378 + " -dec " 

379 + str(ra_dec[3]) 

380 + " --output_dir "+ data_directory 

381 + today_to_directory(today) 

382 + "/" 

383 + str(current_run_is + 1) 

384 + "/plots --date " 

385 + today 

386 ) 

387 

388 loop_id = loop_id + 1 

389 if ( 

390 datetime.datetime.timestamp(datetime.datetime.now()) - Start_time 

391 ) > 14 * 3600: 

392 quit = True 

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

394 

395 

396if __name__ == "__main__": 

397 main()