Exemplo n.º 1
0
 def print_result(self):
     AdvPrint.set_cout_file(Info.files["output_result"], True)
     if self.cls_obs != -1:
         AdvPrint.cout("Test: Calculation of CLs(S, dS, B, dB, O) using profile likelihood")
     elif self.likelihood != -1:
         AdvPrint.cout("Test: Calculation of approximate (fast) likelihood given in results folder")
     elif self.r_obs != -1:
         AdvPrint.cout("Test: Calculation of r = signal/(95%CL limit on signal)")
     else:
         AdvPrint.cerr_exit("evaluator::printResult(): No result has been evaluated!")
         
     
     for w in self.warnings:
         AdvPrint.cout("\033[33mWarning: "+w+"\033[0m")
     result = "\033[31mExcluded\033[0m"
     if self.allowed():
         result = "\033[32mAllowed\033[0m"
     AdvPrint.cout("Result: "+result)
     if self.cls_obs != -1:
         AdvPrint.cout("Result for CLs: "+str(self.cls_obs))
     #if self.likelihood != -1:
     #    AdvPrint.cout("Result for likelihood: "+str(self.likelihood))
     elif self.r_obs != -1:
         AdvPrint.cout("Result for r: "+str(self.r_obs_cons))
     else:
         AdvPrint.cerr_exit("evaluator::printResult(): No result has been evaluated!")
     
     AdvPrint.cout("Analysis: "+self.resultCollector.analysis)
     AdvPrint.cout("SR: "+self.resultCollector.sr)
     AdvPrint.set_cout_file("#None")
Exemplo n.º 2
0
 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
Exemplo n.º 3
0
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'])
Exemplo n.º 4
0
    def print_result(self):
        AdvPrint.set_cout_file(Info.files["output_result"], True)
        if self.cls_obs != -1:
            AdvPrint.cout(
                "Test: Calculation of CLs(S, dS, B, dB, O) using profile likelihood"
            )
        elif self.likelihood != -1:
            AdvPrint.cout(
                "Test: Calculation of approximate (fast) likelihood given in results folder"
            )
        elif self.r_obs != -1:
            AdvPrint.cout(
                "Test: Calculation of r = signal/(95%CL limit on signal)")
        else:
            AdvPrint.cerr_exit(
                "evaluator::printResult(): No result has been evaluated!")

        for w in self.warnings:
            AdvPrint.cout("\033[33mWarning: " + w + "\033[0m")
        result = "\033[31mExcluded\033[0m"
        if self.allowed():
            result = "\033[32mAllowed\033[0m"
        AdvPrint.cout("Result: " + result)
        if self.cls_obs != -1:
            AdvPrint.cout("Result for CLs: " + str(self.cls_obs))
        #if self.likelihood != -1:
        #    AdvPrint.cout("Result for likelihood: "+str(self.likelihood))
        elif self.r_obs != -1:
            AdvPrint.cout("Result for r: " + str(self.r_obs_cons))
        else:
            AdvPrint.cerr_exit(
                "evaluator::printResult(): No result has been evaluated!")

        AdvPrint.cout("Analysis: " + self.resultCollector.analysis)
        AdvPrint.cout("SR: " + self.resultCollector.sr)
        AdvPrint.set_cout_file("#None")
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
    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
Exemplo n.º 8
0
    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)  
Exemplo n.º 9
0
    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
Exemplo n.º 10
0
    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