1313import multiprocessing
1414from itertools import islice
1515import os
16+ import sys
17+ try :
18+ import tqdm
19+ except ImportError as e :
20+ print ("Module tqdm is not imported. Progress bar will not be available (you can install tqdm for the progress bar)" )
21+ from ROOT import TFile
1622
1723# Global running flags
1824verbose_mode = False
@@ -43,6 +49,11 @@ def msg(*args, color=bcolors.BOKBLUE):
4349 print (color , * args , bcolors .ENDC )
4450
4551
52+ def fatal_msg (* args ):
53+ msg ("[FATAL]" , * args , color = bcolors .BFAIL )
54+ raise RuntimeError ("Fatal Error!" )
55+
56+
4657def set_o2_analysis (o2_analyses = ["o2-analysis-hf-task-d0 --pipeline qa-tracking-kine:4,qa-tracking-resolution:4" ],
4758 o2_arguments = "--shm-segment-size 16000000000 --readers 4 --configuration json://$PWD/dpl-config_std.json" ,
4859 input_file = "listfiles.txt" ,
@@ -121,16 +132,16 @@ def run_command(cmd):
121132
122133
123134def run_o2_analysis (tmp_script_name , remove_tmp_script = False ):
124- msg ("> starting run with" , tmp_script_name )
135+ verbose_msg ("> starting run with" , tmp_script_name )
125136 cmd = f"bash { tmp_script_name } "
126137 run_command (cmd )
127138 if remove_tmp_script :
128139 os .remove (tmp_script_name )
129- msg ( "> end run with" , tmp_script_name )
140+ verbose_msg ( "< end run with" , tmp_script_name )
130141
131142
132- analyses = {"TrackQA" : ["o2-analysis-qa-simple " ,
133- "o2-analysis-qa-efficiency --make-eff 1 --eta-min -0.8 --eta-max 0.8" ,
143+ analyses = {"TrackQA" : ["o2-analysis-qa-track-event " ,
144+ "o2-analysis-qa-efficiency --make-eff 1 --eff-pi 1 --eff-el 1 --eff-ka 1 --eff-pr 1 -- eta-min -0.8 --eta-max 0.8" ,
134145 "o2-analysis-trackextension" ,
135146 "o2-analysis-alice3-trackselection" ],
136147 "TOF" : ["o2-analysis-spectra-tof" ,
@@ -195,6 +206,20 @@ def main(mode,
195206 input_file_list = []
196207
197208 def build_list_of_files (file_list ):
209+ if len (file_list ) != len (set (file_list )): # Check that runlist does not have duplicates
210+ fatal_msg ("Runlist has duplicated entries, fix runlist!" )
211+ not_readable = []
212+ for i in file_list : # Check that input files can be open
213+ f = TFile (i .strip (), "READ" )
214+ if not f .IsOpen ():
215+ verbose_msg ("Cannot open AOD file:" , i , color = bcolors .WARNING )
216+ not_readable .append (i )
217+ if len (not_readable ) > 0 :
218+ msg (len (not_readable ), "files cannot be read and will be skipped" ,
219+ color = bcolors .BWARNING )
220+ for i in not_readable :
221+ file_list .remove (i )
222+
198223 files_per_batch = []
199224 iter_file_list = iter (file_list )
200225 for i in range (0 , len (file_list )):
@@ -213,17 +238,19 @@ def build_list_of_files(file_list):
213238 with open (run_list [- 1 ], "w" ) as f :
214239 for j in lines :
215240 f .write (j .strip () + "\n " )
241+ msg ("Number or runs:" , len (run_list ))
216242 return run_list
217243
218244 if type (input_file ) is list :
219245 if batch_size == 1 :
220246 input_file_list = os .path .join (os .getcwd (), input_file )
221247 else :
222248 input_file_list = build_list_of_files (input_file )
223-
224249 elif not input_file .endswith (".root" ):
225250 with open (input_file , "r" ) as f :
226251 lines = f .readlines ()
252+ msg ("Building input list from" , len (lines ),
253+ "inputs, limiting to" , n_max_files )
227254 if len (lines ) > n_max_files :
228255 lines = lines [0 :n_max_files ]
229256 input_file_list = build_list_of_files (lines )
@@ -243,10 +270,16 @@ def build_list_of_files(file_list):
243270 dpl_configuration_file = dpl_configuration_file ))
244271 if not merge_only :
245272 with multiprocessing .Pool (processes = njobs ) as pool :
246- pool .map (run_o2_analysis , run_list )
273+ msg ("Running analysis" )
274+ if "tqdm" not in sys .modules :
275+ for i in enumerate (pool .imap (run_o2_analysis , run_list )):
276+ msg (f"Done: { i [0 ]+ 1 } ," , len (run_list )- i [0 ]- 1 , "to go" )
277+ else :
278+ r = list (tqdm .tqdm (pool .imap (run_o2_analysis , run_list ),
279+ total = len (run_list ),
280+ bar_format = '{l_bar}{bar:10}{r_bar}{bar:-10b}' ))
247281
248282 if merge_output or merge_only :
249- msg ("Merging results" , color = bcolors .BOKBLUE )
250283 files_to_merge = []
251284 for i in input_file_list :
252285 p = os .path .dirname (os .path .abspath (i ))
@@ -257,20 +290,23 @@ def build_list_of_files(file_list):
257290 msg ("Warning: Did not find any file to merge for tag" ,
258291 tag , color = bcolors .BWARNING )
259292 return
293+ msg ("Merging" , len (files_to_merge ), "results" , color = bcolors .BOKBLUE )
260294 files_per_type = {}
261295 for i in files_to_merge :
262296 fn = os .path .basename (i )
263297 files_per_type .setdefault (fn , [])
264298 files_per_type [fn ].append (i )
299+ merged_files = []
265300 for i in files_per_type :
266301 merged_file = os .path .join (out_path , i )
267302 if os .path .isfile (merged_file ):
268303 msg ("Warning: file" , merged_file ,
269304 "is already found, remove it before merging, you can use the --mergeonly flag to avoid running the analysis again" ,
270305 color = bcolors .BWARNING )
271306 continue
307+ merged_files .append (merged_file )
272308 run_command (f"hadd { merged_file } " + " " .join (files_per_type [i ]))
273- msg ("Merging completed" , color = bcolors .BOKGREEN )
309+ msg ("Merging completed, merged:" , * merged_files , color = bcolors .BOKGREEN )
274310
275311
276312if __name__ == "__main__" :
0 commit comments