@@ -91,6 +91,22 @@ def human(ts_ms):
9191 return datetime .fromtimestamp (ts_ms / 1000 , tz = timezone .utc ).strftime ("%Y-%m-%d %H:%M:%S UTC" )
9292
9393
94+ def print_log (severity , message , file ):
95+ print (f"[getCCDBTimeMachineTimestamp] [{ severity } ] { message } " , file = file )
96+
97+
98+ def print_info (message , file = sys .stderr ):
99+ print_log ("Info" , message , file )
100+
101+
102+ def print_warning (message , file = sys .stderr ):
103+ print_log ("Warning" , message , file )
104+
105+
106+ def print_error (message , file = sys .stderr ):
107+ print_log ("Error" , message , file )
108+
109+
94110def get_ccdb_objects (url , timeout = 15 ):
95111 req = urllib .request .Request (url , headers = {"Accept" : "application/json" })
96112 try :
@@ -120,15 +136,29 @@ def ccdb_cross_check(run, path, not_after, timeout=15):
120136
121137 objects = get_ccdb_objects (url )
122138 if not objects :
123- return { ** result , "error" : "no CCDB object covers this instant" }
139+ result . update ({ "error" : "no CCDB object covers this instant" })
124140
125141 as_of = [o for o in objects if o .get ("Created" , 0 ) <= not_after ]
126142 newest = max (objects , key = lambda o : o .get ("Created" , 0 ))
127143 result .update ({"newest" : newest , "as_of" : None , "outdated" : False })
128144 if as_of :
129145 result ["as_of" ] = max (as_of , key = lambda o : o .get ("Created" , 0 ))
130146 result ["outdated" ] = newest ["Created" ] > result ["as_of" ]["Created" ]
131- return result
147+
148+ check_timestamp = f"/{ result ['timestamp' ]} " if result else ""
149+ if result is None or "error" in result :
150+ reason = result ["error" ] if result else "unknown error"
151+ print_warning (f"CCDB cross-check on { path } { check_timestamp } skipped: { reason } " )
152+ elif result ["as_of" ] is None :
153+ print_info (f"CCDB cross-check on { path } { check_timestamp } : no object existed "
154+ f"yet at the recommended timestamp (newest is { describe_object (result ['newest' ])} )" )
155+ else :
156+ print_info (f"CCDB cross-check on { path } { check_timestamp } : as-of object is "
157+ f"{ describe_object (result ['as_of' ])} " )
158+ if result ["outdated" ]:
159+ print_info (f"CCDB's current object for this window is newer "
160+ f"({ describe_object (result ['newest' ])} ) - it postdates this pass's processing and "
161+ f"was not what this run actually saw." )
132162
133163
134164def describe_object (o ):
@@ -157,51 +187,36 @@ def get_NotAfter(year, period, run, passname, samples=9, ccdb_check_path="TPC/Ca
157187 int: CCDBTimeMachineTS NotAfter timestamp
158188 """
159189 pass_dir = f"/alice/data/{ year } /{ period } /{ run } /{ passname } /"
160- print (f"[getCCDBTimeMachineTimestamp] Looking for TF output under { pass_dir } " , file = sys . stderr )
190+ print_info (f"Looking for TF output under { pass_dir } " )
161191
162192 matches = find_tf_output_files (pass_dir , run )
163193 if not matches :
164- sys .exit (f"[getCCDBTimeMachineTimestamp] No o2_ctf_run{ int (run ):08d} _orbit* output found "
165- f"under { pass_dir } . Check year/period/run/pass, or this run+pass may not use this "
166- f"catalog layout. Refusing to guess a timestamp." )
194+ print_error (f"No o2_ctf_run{ int (run ):08d} _orbit* output found under { pass_dir } . "
195+ f"Check year/period/run/pass, or this run+pass may not use this "
196+ f"catalog layout. Refusing to guess a timestamp. Exiting..." )
197+ sys .exit (1 )
167198
168199 sampled = sample_evenly (matches , samples )
169200 ctimes = []
170201 for lfn in sampled :
171202 ctime = stat_ctime (lfn )
172203 if ctime is not None :
173204 ctimes .append (ctime )
174- print (f"[getCCDBTimeMachineTimestamp] { human (ctime )} { lfn } " , file = sys . stderr )
205+ print_info (f"{ human (ctime )} { lfn } " )
175206
176207 if len (ctimes ) < 2 :
177- sys .exit (f"[getCCDBTimeMachineTimestamp] Only got { len (ctimes )} usable timestamp(s) out of "
178- f"{ len (sampled )} sampled files ({ len (matches )} found in total); refusing to guess." )
208+ print_error (f"Only got { len (ctimes )} usable timestamp(s) out of { len (sampled )} "
209+ f"sampled files ({ len (matches )} found in total); refusing to guess. Exiting..." )
210+ sys .exit (1 )
179211
180212 not_after = int (statistics .median (ctimes ))
181213 spread_h = (max (ctimes ) - min (ctimes )) / 3.6e6
182- print (f"[getCCDBTimeMachineTimestamp] { len (ctimes )} samples out of { len (matches )} TF outputs found; "
183- f"span { human (min (ctimes ))} .. { human (max (ctimes ))} ({ spread_h :.1f} h)" , file = sys .stderr )
184- print (f"[getCCDBTimeMachineTimestamp] Recommended NotAfter: { not_after } ({ human (not_after )} )" ,
185- file = sys .stderr )
214+ print_info (f"{ len (ctimes )} samples out of { len (matches )} TF outputs found; "
215+ f"span { human (min (ctimes ))} .. { human (max (ctimes ))} ({ spread_h :.1f} h)" )
216+ print_info (f"Recommended NotAfter: { not_after } ({ human (not_after )} )" )
186217
187218 if ccdb_check :
188- check = ccdb_cross_check (run , ccdb_check_path , not_after )
189- check_timestamp = f"/{ check ['timestamp' ]} " if check else ""
190- if check is None or "error" in check :
191- reason = check ["error" ] if check else "unknown error"
192- print (f"[getCCDBTimeMachineTimestamp] CCDB cross-check on { ccdb_check_path } { check_timestamp } skipped: { reason } " ,
193- file = sys .stderr )
194- elif check ["as_of" ] is None :
195- print (f"[getCCDBTimeMachineTimestamp] CCDB cross-check on { ccdb_check_path } { check_timestamp } : no object "
196- f"existed yet at the recommended timestamp (earliest is { describe_object (check ['newest' ])} )" ,
197- file = sys .stderr )
198- else :
199- print (f"[getCCDBTimeMachineTimestamp] CCDB cross-check on { ccdb_check_path } { check_timestamp } : as-of object is "
200- f"{ describe_object (check ['as_of' ])} " , file = sys .stderr )
201- if check ["outdated" ]:
202- print (f"[getCCDBTimeMachineTimestamp] note: CCDB's current object for this window is newer "
203- f"({ describe_object (check ['newest' ])} ) - it postdates this pass's processing and was "
204- f"not what this run actually saw." , file = sys .stderr )
219+ ccdb_cross_check (run , ccdb_check_path , not_after )
205220
206221 return not_after
207222
@@ -221,7 +236,7 @@ def query_CCDBTimeMachineTS(base_url, user, period, passname):
221236 user_path = 'Users/' + user [0 ] + '/' + user
222237 url = f"{ base_url } /browse/{ user_path } /CCDBTimeMachineTS/{ query } "
223238
224- print (f"[getCCDBTimeMachineTimestamp] Checking if CCDBTimeMachineTS already exists: { url } " , file = sys . stderr )
239+ print_info (f"Checking if CCDBTimeMachineTS already exists: { url } " )
225240
226241 response = requests .get (url , cert = (cert_path , key_path ), verify = False )
227242 if response .status_code == 200 :
@@ -232,9 +247,9 @@ def filter_known_fields(cls, data: dict) -> dict:
232247 return {k : v for k , v in data .items () if k in valid_keys }
233248
234249 clean_meta = filter_known_fields (CCDBTimeMachineTS , meta [0 ])
235- print (f"[getCCDBTimeMachineTimestamp] Found object for { clean_meta ['Period' ]} , Pass: { clean_meta ['Pass' ]} , "
236- f"NotAfter: { clean_meta ['NotAfter' ]} ({ human (clean_meta ['NotAfter' ])} ), uploaded by LPMProductionTag { clean_meta [ 'LPMProductionTag' ] } " ,
237- file = sys . stderr )
250+ print_info (f"Found object for { clean_meta ['Period' ]} , Pass: { clean_meta ['Pass' ]} , "
251+ f"NotAfter: { clean_meta ['NotAfter' ]} ({ human (clean_meta ['NotAfter' ])} ), "
252+ f"uploaded by LPMProductionTag { clean_meta [ 'LPMProductionTag' ] } " )
238253 return clean_meta ['NotAfter' ], True
239254
240255 return None , False
@@ -262,7 +277,7 @@ def upload_CCDBTimeMachineTS(base_url, user, keys):
262277 stop = start + 1
263278 url = f"{ base_url } /{ user_path } /CCDBTimeMachineTS/{ start } /{ stop } /{ query } "
264279
265- print (f"[getCCDBTimeMachineTimestamp] Uploading CCDBTimeMachineTS: { url } " , file = sys . stderr )
280+ print_info (f"Uploading CCDBTimeMachineTS: { url } " )
266281
267282 # Prepare request
268283 with open (empty_file , 'rb' ) as f :
@@ -272,7 +287,7 @@ def upload_CCDBTimeMachineTS(base_url, user, keys):
272287 os .remove (empty_file )
273288
274289 if response .status_code != 201 :
275- print (f"[getCCDBTimeMachineTimestamp] Upload failed, response: { response .status_code } " , file = sys . stderr )
290+ print_warning (f"Upload failed, response: { response .status_code } " )
276291
277292
278293def get_CCDBTimeMachineTS (production_tag , year , period , run , passname ,
@@ -293,22 +308,20 @@ def get_CCDBTimeMachineTS(production_tag, year, period, run, passname,
293308 not_after , found = query_CCDBTimeMachineTS (ccdb_url , username , period , passname )
294309
295310 if not found or force_overwrite :
296- print ( "[getCCDBTimeMachineTimestamp] Estimating CCDBTimeMachineTS for "
297- f"LPMProductionTag: { production_tag } , Period: { period } , Pass: { passname } " , file = sys . stderr )
311+ print_info ( " Estimating CCDBTimeMachineTS for "
312+ f"LPMProductionTag: { production_tag } , Period: { period } , Pass: { passname } " )
298313 not_after = get_NotAfter (year , period , run , passname , samples , ccdb_check_path , ccdb_check )
299314
300315 if publish_to_ccdb :
301316 if skip_ccdb_query :
302- print ("[getCCDBTimeMachineTimestamp] CCDB query was skipped, a newer object may be "
303- "uploaded on top of an existing one" , file = sys .stderr )
317+ print_info ("CCDB query was skipped, a newer object may be uploaded on top of an existing one" )
304318 elif not found :
305319 # check again in case another subjob uploaded an object in the meantime
306320 not_after_q , found = query_CCDBTimeMachineTS (ccdb_url , username , period , passname )
307321
308322 if found :
309323 if force_overwrite :
310- print ("[getCCDBTimeMachineTimestamp] Forcing upload of a newer object "
311- "on top of the existing one" , file = sys .stderr )
324+ print_info ("Forcing upload of a newer object on top of the existing one" )
312325 else :
313326 return not_after_q
314327
0 commit comments