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
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-08 14:48 +0000
1#!/usr/bin/env python
3import datetime
4import logging
5import os
6import time
8import pymongo
10def wait_for_directory(directory, interval=5):
11 """
12 Wait for the directory to exist
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 !!!")
23def now():
24 """
25 Returns the current timestamp in seconds, relative to the Unix epoch.
27 :return: float
28 """
29 return datetime.datetime.timestamp(datetime.datetime.now())
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)]
44 keep_querying = True
45 query_idx = 0
46 visited_ids: Set[object] = set()
48 obs_id: Optional[int] = None
49 nb_duplicated_run_numbers = 0
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 )
70 try:
71 query_data = next(cursor)
72 finally:
73 # Close cursor explicitly for older pymongo versions
74 cursor.close()
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"])
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)
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 )
92 if query_idx == 0:
93 obs_id = camera_list[0]["run_number"]
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
102 query_idx += 1
104 if obs_id is None:
105 logging.error("DB query succeeded but no obs_id was extracted")
106 return -1
108 return int(obs_id + nb_duplicated_run_numbers)
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
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.
128 Ex: An observation launched at 04h00 (local time) will refer to the previous day.
130 :param today: datetime object
131 datetime object with current local time
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}"
143 return timestamp
146def Obtain_RA_DEC(runid):
147 try:
148 client = pymongo.MongoClient("lst101")
149 database = client["bridgesmonitoring"]
150 print(client)
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})
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]
184def today_to_directory(today):
185 return today[0:4]+"/"+today[4:6]+"/"+today[6:8]
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
199 Start_time = now()
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())
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)
208 RTA_ready = True
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 )
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 )
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")
396if __name__ == "__main__":
397 main()