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
« 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())
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)]
45 keep_querying = True
46 query_idx = 0
47 visited_ids: Set[object] = set()
49 obs_id: Optional[int] = None
50 nb_duplicated_run_numbers = 0
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 )
71 try:
72 query_data = next(cursor)
73 finally:
74 # Close cursor explicitly for older pymongo versions
75 cursor.close()
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"])
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)
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 )
93 if query_idx == 0:
94 obs_id = camera_list[0]["run_number"]
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
103 query_idx += 1
105 if obs_id is None:
106 logging.error("DB query succeeded but no obs_id was extracted")
107 return -1
109 return int(obs_id + nb_duplicated_run_numbers)
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
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.
130 Ex: An observation launched at 04h00 (local time) will refer to the previous day.
132 :param today: datetime object
133 datetime object with current local time
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}"
145 return timestamp
148def Obtain_RA_DEC(runid):
149 try:
150 client = pymongo.MongoClient("lst101")
151 database = client["bridgesmonitoring"]
152 print(client)
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})
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]
186def today_to_directory(today):
187 return today[0:4]+"/"+today[4:6]+"/"+today[6:8]
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
201 Start_time = now()
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)
209 RTA_ready = True
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 )
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 )
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")
287if __name__ == "__main__":
288 main()