def _print_likelihood(evaluators): tot_likeli = 0. dict_likeli = {} for analysis, v in evaluators.iteritems(): ana_likeli =0. AdvPrint.set_cout_file(Info.files['output_evaluation_likelihood'][analysis], True) AdvPrint.mute() AdvPrint.cout("SR o b db s ds likeli") for sr, ev in v.iteritems(): AdvPrint.cout(sr+" " +str(float(ev.obs))+" " +str(float(ev.bkg))+" " +str(float(ev.bkg_err))+" " +str(ev.resultCollector.signal_normevents)+" " +str(ev.resultCollector.signal_err_tot)+" " +str(ev.likelihood)) ana_likeli += ev.likelihood AdvPrint.format_columnated_file(Info.files['output_evaluation_likelihood'][analysis]) AdvPrint.set_cout_file("#None") AdvPrint.unmute() dict_likeli[analysis] = ana_likeli tot_likeli += ana_likeli AdvPrint.set_cout_file(Info.files['likelihood'], True) AdvPrint.mute() AdvPrint.cout("Analysis -2lnL") for a in dict_likeli: AdvPrint.cout(a+" "+str(dict_likeli[a])) AdvPrint.cout("\nTotal: "+str(tot_likeli)) AdvPrint.format_columnated_file(Info.files['likelihood'])
def get_resultCollectors(self): """ Gathers results from all events""" # setup resultCollector object resultCollectors_pr = dict() for analysis in Info.analyses: resultCollectors_pr[analysis] = dict() signal_regions = Info.get_analysis_parameters(analysis)["signal_regions"] for sr in signal_regions: resultCollectors_pr[analysis][sr] = ResultCollector(self.name, analysis, sr) # loop over all associated events and average results in all resultCollectors for event in self.eventsList: resultCollectors_ev = event.get_resultCollectors() for analysis in resultCollectors_pr: for sr in resultCollectors_pr[analysis]: resultCollectors_pr[analysis][sr].add_and_average(resultCollectors_ev[analysis][sr]) # Write process file, if wanted if Info.parameters["ProcessResultFileColumns"] != []: AdvPrint.mute() AdvPrint.set_cout_file(self.result_output_file, True) for col in Info.parameters["ProcessResultFileColumns"]: AdvPrint.cout(col+" ", "nlb") AdvPrint.cout("") for a in sorted(resultCollectors_pr.keys()): for sr in sorted(resultCollectors_pr[a].keys()): AdvPrint.cout(resultCollectors_pr[a][sr].line_from_data(Info.parameters["ProcessResultFileColumns"])) AdvPrint.format_columnated_file(self.result_output_file) AdvPrint.set_cout_file("#None") AdvPrint.unmute() return resultCollectors_pr
def get_resultCollectors(self): """ Gathers results from all events""" # setup resultCollector object resultCollectors_pr = dict() for analysis in Info.analyses: resultCollectors_pr[analysis] = dict() signal_regions = Info.get_analysis_parameters( analysis)["signal_regions"] for sr in signal_regions: resultCollectors_pr[analysis][sr] = ResultCollector( self.name, analysis, sr) # loop over all associated events and average results in all resultCollectors for event in self.eventsList: resultCollectors_ev = event.get_resultCollectors() for analysis in resultCollectors_pr: for sr in resultCollectors_pr[analysis]: resultCollectors_pr[analysis][sr].add_and_average( resultCollectors_ev[analysis][sr]) # Write process file, if wanted if Info.parameters["ProcessResultFileColumns"] != []: AdvPrint.mute() AdvPrint.set_cout_file(self.result_output_file, True) for col in Info.parameters["ProcessResultFileColumns"]: AdvPrint.cout(col + " ", "nlb") AdvPrint.cout("") for a in sorted(resultCollectors_pr.keys()): for sr in sorted(resultCollectors_pr[a].keys()): AdvPrint.cout(resultCollectors_pr[a][sr].line_from_data( Info.parameters["ProcessResultFileColumns"])) AdvPrint.format_columnated_file(self.result_output_file) AdvPrint.set_cout_file("#None") AdvPrint.unmute() return resultCollectors_pr
def get_resultCollectors(self): resultCollectors = dict( ) # list of all collectors of all analyses and all signal regions resultCollector = ResultCollector( self.identifier, "", "") # base collector object which we will just edit and copy for analysis in Info.analyses: # check if results file exists if not os.path.isfile(self.analysis_signal_files[analysis]): AdvPrint.cerr_exit( "\t events::get_resultCollector() \n" "\t Required analysis result file does not exist: \n " "\t\t" + self.analysis_signal_files[analysis] + "\n" "\t It is very likely that something went wrong in the delphes and/or the analysis step. \n" "\t Please check \n " "\t \t " + Info.files['delphes_log'] + " \n " "\t \t " + Info.files['analysis_log'] + "* \n " "\t for error messages and, should you not be able to fix them yourself, contact the authors under \n" "\t \t [email protected]") # setup resultCollector object resultCollector.analysis = analysis resultCollectors[analysis] = dict() signal_regions = Info.get_analysis_parameters( analysis)["signal_regions"] # Read result file f = open(self.analysis_signal_files[analysis], "r") for line in f: # Ignore empty or commented lines line = line.rstrip() if line == "" or line[0] == "#": continue # Read file: line = AdvPrint.remove_extra_spaces(line) tokens = [t for t in line.split(" ") if t != ""] # First, read information on total events number if tokens[0] == "MCEvents:": resultCollector.total_mcevents = float(tokens[1]) elif tokens[0] == " SumOfWeights:": resultCollector.total_sumofweights = float(tokens[1]) elif tokens[0] == " SumOfWeights2:": resultCollector.total_sumofweights2 = float(tokens[1]) elif tokens[0] == " NormEvents:": resultCollector.total_normevents = float(tokens[1]) elif tokens[0] == "XSect:": xsect = float(tokens[1].split(" ")[0]) elif tokens[0] == " Error:": xsecterr = float(tokens[1].split(" ")[0]) else: # SR Sum_W Sum_W2 Acc N_Norm for sr in signal_regions: if tokens[0].startswith(sr): resultCollector.sr = sr # Read number of events resultCollector.signal_sumofweights = float( tokens[1]) resultCollector.signal_sumofweights2 = float( tokens[2]) resultCollector.signal_normevents = float( tokens[4]) # Calculate errors if resultCollector.signal_sumofweights > 0: resultCollector.signal_err_stat = resultCollector.signal_normevents * sqrt( resultCollector.signal_sumofweights2 ) / resultCollector.signal_sumofweights resultCollector.signal_err_sys = resultCollector.signal_normevents * xsecterr / xsect resultCollector.signal_err_tot = sqrt( resultCollector.signal_err_stat**2 + resultCollector.signal_err_sys**2) else: resultCollector.signal_err_stat = 0 resultCollector.signal_err_sys = 0 resultCollector.signal_err_tot = 0 # put copy of resultCollector in collector dict resultCollectors[analysis][sr] = deepcopy( resultCollector) f.close() # Write events file, if wanted if Info.parameters["EventResultFileColumns"] != []: AdvPrint.mute() AdvPrint.set_cout_file(self.result_output_file, True) for col in Info.parameters["EventResultFileColumns"]: AdvPrint.cout(col + " ", "nlb") AdvPrint.cout("") for a in sorted(resultCollectors.keys()): for sr in sorted(resultCollectors[a].keys()): AdvPrint.cout(resultCollectors[a][sr].line_from_data( Info.parameters["EventResultFileColumns"])) AdvPrint.format_columnated_file(self.result_output_file) AdvPrint.set_cout_file("#None") AdvPrint.unmute() return resultCollectors
def runFritz(self): self.prepareFritz() """ Runs Fritz """ from events import MG5Events for event in self.eventsList: if event.processed: continue fritz_command = Info.files["fritz_bin"]+" "+event.configFile result = subprocess.Popen(fritz_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) maxlen = 0 try: for line in iter(result.stdout.readline, b''): # Print to logfile. If it does not start with the Fritz::Global prefix, it comes from MG5 and should be redirected AdvPrint.mute() if not line.startswith("|~| ") and isinstance(event, MG5Events): AdvPrint.set_cout_file(os.path.join(Info.paths["output_mg5"], "mg5amcatnlo_"+event.identifier+".log")) elif "PYTHIA Rndm::dumpState" in line: AdvPrint.set_cout_file(os.path.join(Info.paths["output_pythia"], "pythia_"+event.identifier+".log")) else: line = line.replace("|~| ", "") AdvPrint.set_cout_file(os.path.join(Info.paths["output_fritz"], "fritz_"+event.identifier+".log")) AdvPrint.cout(line.rstrip()) AdvPrint.set_cout_file("#None") AdvPrint.unmute() # We should not exceed the terminal terminal_width: terminal_width = AdvPrint.get_terminal_width() print_line = " |-> "+str(line.strip()) print_line.replace("\t", " ") while "\r" in print_line: print_line = print_line[print_line.index("\r"):] len_of_print_line = len(print_line) maxlen = max(maxlen, len(print_line)) # As we print line by line in the same terminal row, we have to add spaces if the curr line is shorter than a line before fill_spaces = "" if len(print_line) < maxlen: fill_spaces = " "*(maxlen-len(print_line)) # if line is too long, make it shorter by appropriate amoung if len(print_line+fill_spaces) >= terminal_width and len(print_line) <= terminal_width: fill_spaces = " "*(terminal_width - len(print_line)-1) elif len(print_line) > terminal_width: fill_spaces = "" print_line = print_line[:terminal_width-4]+"..." AdvPrint.cout("\r"+print_line+fill_spaces+"\x1b[0m\r", "nlb") except KeyboardInterrupt: AdvPrint.cout("Caught Keyboard Signal. Aborting Fritz") result.send_signal(signal.SIGTERM) for line in iter(result.stderr.readline, b''): AdvPrint.unmute() AdvPrint.set_cout_file(Info.files['fritz_log']) # remove nasty ROOT6-CLING warnings from on-screen output if "cling::AutoloadingVisitor::InsertIntoAutoloadingState:" in line: AdvPrint.mute() elif "Missing FileEntry for ExRootAnalysis" in line: AdvPrint.mute() elif "requested to autoload type" in line: AdvPrint.mute() AdvPrint.cout(line.rstrip()+"") AdvPrint.set_cout_file("#None") AdvPrint.unmute() AdvPrint.cout("") # Abort if there was an error result.wait() if result.returncode != 0: AdvPrint.cerr_exit("Fritz returned with error. Check logfiles in result folder for more information!") # Remove all empty analysisstdout files for f in [x for x in os.listdir(Info.paths['output_analysis']) if x.startswith("analysisstdout")]: if os.stat(os.path.join(Info.paths['output_analysis'], f)).st_size == 0: os.remove(os.path.join(Info.paths['output_analysis'], f)) # Associate result files to event for a in Info.analyses: event.analysis_signal_files[a] = os.path.join(Info.paths['output_analysis'], event.identifier+'_'+a+'_signal.dat') if os.path.isfile(event.analysis_signal_files[a]): AdvPrint.format_columnated_file(event.analysis_signal_files[a]) event.analysis_cutflow_files[a] = os.path.join(Info.paths['output_analysis'], event.identifier+'_'+a+'_cutflow.dat') if os.path.isfile(event.analysis_cutflow_files[a]): AdvPrint.format_columnated_file(event.analysis_cutflow_files[a]) # finish event.processed = True
def evaluate(self): """ Performs statistical evaluation of the result """ AdvPrint.cout("Evaluating Results") resultCollectors = self.get_resultCollectors() # evaluate all results evaluators = dict() for analysis in resultCollectors: evaluators[analysis] = dict() # only process those results and those signal regions that are given in the reference file for analysis in Info.analyses: signal_regions = Info.get_analysis_parameters(analysis)["signal_regions"] for sr in signal_regions: evaluator = Evaluator(resultCollectors[analysis][sr]) # Calculate everything that should be calculated # TODO: Beware analyses with unknown background evaluator.calc_efficiencies() evaluator.calc_r_values() if Info.flags["likelihood"]: evaluator.calc_likelihood() if Info.flags["fullcls"]: evaluator.calc_cls_values() if Info.flags["zsig"]: evaluator.calc_zsig() evaluators[analysis][sr] = evaluator if Info.parameters["bestcls"] != 0: AdvPrint.cout("Calculating CLs for the "+str(Info.parameters["bestcls"])+" most sensitive signal regions!") best_evaluators = find_strongest_evaluators(evaluators, Info.parameters["bestcls"]) # if "bestcls" is 1, find_strongest_evaluators does not return a list but just the single best if Info.parameters["bestcls"] == 1: best_evaluators = [best_evaluators] for ev in best_evaluators: ev.calc_cls_values() # find best result best_evaluator_per_analysis = dict() for analysis in evaluators: # Find bes of all SRs in analysis best_evaluator_per_analysis[analysis] = find_strongest_evaluators(evaluators[analysis], 1) best_evaluator = find_strongest_evaluators(best_evaluator_per_analysis, 1) AdvPrint.set_cout_file(Info.files['output_totalresults'], True) AdvPrint.mute() for col in Info.parameters["TotalEvaluationFileColumns"]: AdvPrint.cout(col+" ", "nlb") AdvPrint.cout("") for a in sorted(evaluators.keys()): for sr in sorted(evaluators[a].keys()): AdvPrint.cout(evaluators[a][sr].line_from_data(Info.parameters["TotalEvaluationFileColumns"])) AdvPrint.format_columnated_file(Info.files['output_totalresults']) AdvPrint.set_cout_file(Info.files['output_bestsignalregions'], True) AdvPrint.mute() for col in Info.parameters["BestPerAnalysisEvaluationFileColumns"]: AdvPrint.cout(col+" ", "nlb") AdvPrint.cout("") # print analyses in alphabetic order for a in sorted(best_evaluator_per_analysis.keys()): AdvPrint.cout(best_evaluator_per_analysis[a].line_from_data(Info.parameters["BestPerAnalysisEvaluationFileColumns"])) AdvPrint.format_columnated_file(Info.files['output_bestsignalregions']) AdvPrint.set_cout_file("#None") AdvPrint.unmute() best_evaluator.check_warnings() best_evaluator.print_result() if Info.flags['zsig']: _print_zsig(evaluators) if Info.flags['likelihood']: _print_likelihood(evaluators)
def runFritz(self): self.prepareFritz() """ Runs Fritz """ from events import MG5Events for event in self.eventsList: if event.processed: continue fritz_command = Info.files["fritz_bin"] + " " + event.configFile result = subprocess.Popen(fritz_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) maxlen = 0 try: for line in iter(result.stdout.readline, b''): # Print to logfile. If it does not start with the Fritz::Global prefix, it comes from MG5 and should be redirected AdvPrint.mute() if not line.startswith("|~| ") and isinstance( event, MG5Events): AdvPrint.set_cout_file( os.path.join( Info.paths["output_mg5"], "mg5amcatnlo_" + event.identifier + ".log")) elif "PYTHIA Rndm::dumpState" in line: AdvPrint.set_cout_file( os.path.join(Info.paths["output_pythia"], "pythia_" + event.identifier + ".log")) else: line = line.replace("|~| ", "") AdvPrint.set_cout_file( os.path.join(Info.paths["output_fritz"], "fritz_" + event.identifier + ".log")) AdvPrint.cout(line.rstrip()) AdvPrint.set_cout_file("#None") AdvPrint.unmute() # We should not exceed the terminal terminal_width: terminal_width = AdvPrint.get_terminal_width() print_line = " |-> " + str(line.strip()) print_line.replace("\t", " ") while "\r" in print_line: print_line = print_line[print_line.index("\r"):] len_of_print_line = len(print_line) maxlen = max(maxlen, len(print_line)) # As we print line by line in the same terminal row, we have to add spaces if the curr line is shorter than a line before fill_spaces = "" if len(print_line) < maxlen: fill_spaces = " " * (maxlen - len(print_line)) # if line is too long, make it shorter by appropriate amoung if len(print_line + fill_spaces) >= terminal_width and len( print_line) <= terminal_width: fill_spaces = " " * (terminal_width - len(print_line) - 1) elif len(print_line) > terminal_width: fill_spaces = "" print_line = print_line[:terminal_width - 4] + "..." AdvPrint.cout( "\r" + print_line + fill_spaces + "\x1b[0m\r", "nlb") except KeyboardInterrupt: AdvPrint.cout("Caught Keyboard Signal. Aborting Fritz") result.send_signal(signal.SIGTERM) for line in iter(result.stderr.readline, b''): AdvPrint.unmute() AdvPrint.set_cout_file(Info.files['fritz_log']) # remove nasty ROOT6-CLING warnings from on-screen output if "cling::AutoloadingVisitor::InsertIntoAutoloadingState:" in line: AdvPrint.mute() elif "Missing FileEntry for ExRootAnalysis" in line: AdvPrint.mute() elif "requested to autoload type" in line: AdvPrint.mute() AdvPrint.cout(line.rstrip() + "") AdvPrint.set_cout_file("#None") AdvPrint.unmute() AdvPrint.cout("") # Abort if there was an error result.wait() if result.returncode != 0: AdvPrint.cerr_exit( "Fritz returned with error. Check logfiles in result folder for more information!" ) # Remove all empty analysisstdout files for f in [ x for x in os.listdir(Info.paths['output_analysis']) if x.startswith("analysisstdout") ]: if os.stat(os.path.join(Info.paths['output_analysis'], f)).st_size == 0: os.remove(os.path.join(Info.paths['output_analysis'], f)) # Associate result files to event for a in Info.analyses: event.analysis_signal_files[a] = os.path.join( Info.paths['output_analysis'], event.identifier + '_' + a + '_signal.dat') if os.path.isfile(event.analysis_signal_files[a]): AdvPrint.format_columnated_file( event.analysis_signal_files[a]) event.analysis_cutflow_files[a] = os.path.join( Info.paths['output_analysis'], event.identifier + '_' + a + '_cutflow.dat') if os.path.isfile(event.analysis_cutflow_files[a]): AdvPrint.format_columnated_file( event.analysis_cutflow_files[a]) # finish event.processed = True
def get_resultCollectors(self): resultCollectors = dict() # list of all collectors of all analyses and all signal regions resultCollector = ResultCollector(self.identifier, "", "") # base collector object which we will just edit and copy for analysis in Info.analyses: # check if results file exists if not os.path.isfile(self.analysis_signal_files[analysis]): AdvPrint.cerr_exit("\t events::get_resultCollector() \n" "\t Required analysis result file does not exist: \n " "\t\t"+self.analysis_signal_files[analysis]+"\n" "\t It is very likely that something went wrong in the delphes and/or the analysis step. \n" "\t Please check \n " "\t \t "+Info.files['delphes_log']+" \n " "\t \t "+Info.files['analysis_log']+"* \n " "\t for error messages and, should you not be able to fix them yourself, contact the authors under \n" "\t \t [email protected]") # setup resultCollector object resultCollector.analysis = analysis resultCollectors[analysis] = dict() signal_regions = Info.get_analysis_parameters(analysis)["signal_regions"] # Read result file f = open(self.analysis_signal_files[analysis], "r") for line in f: # Ignore empty or commented lines line = line.rstrip() if line == "" or line[0] == "#": continue # Read file: line = AdvPrint.remove_extra_spaces(line) tokens = [t for t in line.split(" ") if t != ""] # First, read information on total events number if tokens[0] == "MCEvents:": resultCollector.total_mcevents = float(tokens[1]) elif tokens[0] == " SumOfWeights:": resultCollector.total_sumofweights = float(tokens[1]) elif tokens[0] == " SumOfWeights2:": resultCollector.total_sumofweights2 = float(tokens[1]) elif tokens[0] == " NormEvents:": resultCollector.total_normevents = float(tokens[1]) elif tokens[0] == "XSect:": xsect = float(tokens[1].split(" ")[0]) elif tokens[0] == " Error:": xsecterr = float(tokens[1].split(" ")[0]) else: # SR Sum_W Sum_W2 Acc N_Norm for sr in signal_regions: if tokens[0].startswith(sr): resultCollector.sr = sr # Read number of events resultCollector.signal_sumofweights = float(tokens[1]) resultCollector.signal_sumofweights2 = float(tokens[2]) resultCollector.signal_normevents = float(tokens[4]) # Calculate errors if resultCollector.signal_sumofweights > 0: resultCollector.signal_err_stat = resultCollector.signal_normevents*sqrt(resultCollector.signal_sumofweights2)/resultCollector.signal_sumofweights resultCollector.signal_err_sys = resultCollector.signal_normevents*xsecterr/xsect resultCollector.signal_err_tot = sqrt(resultCollector.signal_err_stat**2+resultCollector.signal_err_sys**2) else: resultCollector.signal_err_stat = 0 resultCollector.signal_err_sys = 0 resultCollector.signal_err_tot = 0 # put copy of resultCollector in collector dict resultCollectors[analysis][sr] = deepcopy(resultCollector) f.close() # Write events file, if wanted if Info.parameters["EventResultFileColumns"] != []: AdvPrint.mute() AdvPrint.set_cout_file(self.result_output_file, True) for col in Info.parameters["EventResultFileColumns"]: AdvPrint.cout(col+" ", "nlb") AdvPrint.cout("") for a in sorted(resultCollectors.keys()): for sr in sorted(resultCollectors[a].keys()): AdvPrint.cout(resultCollectors[a][sr].line_from_data(Info.parameters["EventResultFileColumns"])) AdvPrint.format_columnated_file(self.result_output_file) AdvPrint.set_cout_file("#None") AdvPrint.unmute() return resultCollectors