def test_constraints(self):
     self.single_fit_collection.set_normalisation_constraints({
         'signal': 0.8,
         'bkg1': 0.5
     })
     self.roofitFitter = RooFitFit(self.single_fit_collection)
     #         self.roofitFitter.set_fit_constraints({'signal': 0.8, 'bkg1': 0.5})
     self.roofitFitter.fit()
     results = self.roofitFitter.readResults()
     self.assertAlmostEqual(N_signal_obs,
                            results['signal'][0],
                            delta=2 * results['signal'][1])
     self.assertAlmostEqual(N_bkg1_obs,
                            results['bkg1'][0],
                            delta=2 * results['bkg1'][1])
    def test_constraints(self):
        self.single_fit_collection.set_normalisation_constraints({'signal': 0.8, 'bkg1': 0.5})
        self.roofitFitter = RooFitFit(self.single_fit_collection)
#         self.roofitFitter.set_fit_constraints({'signal': 0.8, 'bkg1': 0.5})
        self.roofitFitter.fit()
        results = self.roofitFitter.readResults()
        self.assertAlmostEqual(N_signal_obs, results['signal'][0], delta=2 * results['signal'][1])
        self.assertAlmostEqual(N_bkg1_obs, results['bkg1'][0], delta=2 * results['bkg1'][1])
    def setUp(self):
        # create histograms
        h_bkg1_1 = Hist(100, 40, 200, title='Background')
        h_signal_1 = h_bkg1_1.Clone(title='Signal')
        h_data_1 = h_bkg1_1.Clone(title='Data')

        # fill the histograms with our distributions
        map(h_bkg1_1.Fill, x1)
        map(h_signal_1.Fill, x2)
        map(h_data_1.Fill, x1_obs)
        map(h_data_1.Fill, x2_obs)

        histograms_1 = {
            'signal': h_signal_1,
            'bkg1': h_bkg1_1,
            #                       'data': h_data_1
        }
        fit_data_1 = FitData(h_data_1, histograms_1, fit_boundaries=(40, 200))
        self.single_fit_collection = FitDataCollection()
        self.single_fit_collection.add(fit_data_1)

        #         self.roofitFitter = RooFitFit(histograms_1, dataLabel='data', fit_boundries=(40, 200))
        self.roofitFitter = RooFitFit(self.single_fit_collection)
class Test(unittest.TestCase):

    def setUp(self):
        # create histograms
        h_bkg1_1 = Hist(100, 40, 200, title='Background')
        h_signal_1 = h_bkg1_1.Clone(title='Signal')
        h_data_1 = h_bkg1_1.Clone(title='Data')
    
        # fill the histograms with our distributions
        map(h_bkg1_1.Fill, x1)
        map(h_signal_1.Fill, x2)
        map(h_data_1.Fill, x1_obs)
        map(h_data_1.Fill, x2_obs)
        
        histograms_1 = {'signal': h_signal_1,
                      'bkg1': h_bkg1_1,
#                       'data': h_data_1
                      }
        fit_data_1 = FitData(h_data_1, histograms_1, fit_boundaries=(40, 200))
        self.single_fit_collection = FitDataCollection()
        self.single_fit_collection.add( fit_data_1 )
        
#         self.roofitFitter = RooFitFit(histograms_1, dataLabel='data', fit_boundries=(40, 200))
        self.roofitFitter = RooFitFit(self.single_fit_collection)

    def tearDown(self):
        pass

    def test_normalisation(self):
        normalisation = self.roofitFitter.normalisation
        self.assertAlmostEqual(normalisation["data"], N_data, delta=sqrt(N_data))
        self.assertAlmostEqual(normalisation["bkg1"], N_bkg1, delta=sqrt(N_bkg1))
        self.assertAlmostEqual(normalisation["signal"], N_signal, delta=sqrt(N_signal))
        
    def test_signal_result(self):
        self.roofitFitter.fit()
        results = self.roofitFitter.readResults()
        self.assertAlmostEqual(N_signal_obs, results['signal'][0], delta=2 * results['signal'][1])
        self.assertAlmostEqual(N_bkg1_obs, results['bkg1'][0], delta=2 * results['bkg1'][1])
        
    def test_constraints(self):
        self.single_fit_collection.set_normalisation_constraints({'signal': 0.8, 'bkg1': 0.5})
        self.roofitFitter = RooFitFit(self.single_fit_collection)
#         self.roofitFitter.set_fit_constraints({'signal': 0.8, 'bkg1': 0.5})
        self.roofitFitter.fit()
        results = self.roofitFitter.readResults()
        self.assertAlmostEqual(N_signal_obs, results['signal'][0], delta=2 * results['signal'][1])
        self.assertAlmostEqual(N_bkg1_obs, results['bkg1'][0], delta=2 * results['bkg1'][1])
    def setUp(self):
        # create histograms
        h_bkg1_1 = Hist(100, 40, 200, title='Background')
        h_signal_1 = h_bkg1_1.Clone(title='Signal')
        h_data_1 = h_bkg1_1.Clone(title='Data')
    
        # fill the histograms with our distributions
        map(h_bkg1_1.Fill, x1)
        map(h_signal_1.Fill, x2)
        map(h_data_1.Fill, x1_obs)
        map(h_data_1.Fill, x2_obs)
        
        histograms_1 = {'signal': h_signal_1,
                      'bkg1': h_bkg1_1,
#                       'data': h_data_1
                      }
        fit_data_1 = FitData(h_data_1, histograms_1, fit_boundaries=(40, 200))
        self.single_fit_collection = FitDataCollection()
        self.single_fit_collection.add( fit_data_1 )
        
#         self.roofitFitter = RooFitFit(histograms_1, dataLabel='data', fit_boundries=(40, 200))
        self.roofitFitter = RooFitFit(self.single_fit_collection)
def get_fitted_normalisation_from_ROOT( channel, input_files, variable, met_systematic, met_type, b_tag_bin, treePrefix, weightBranch, scale_factors = None ):
    '''
    Retrieves the number of ttbar events from fits to one or more distribution
    (fit_variables) for each bin in the variable.
    ''' 
    global use_fitter, measurement_config, verbose, fit_variables, options
    # results and initial values are the same across different fit variables
    # templates are not
    results = {}
    initial_values = {}
    templates = {fit_variable: {} for fit_variable in fit_variables}

    for variable_bin in variable_bins_ROOT[variable]:
        fitter = None
        fit_data_collection = FitDataCollection()
        
        for fit_variable in fit_variables:
            
            histograms = get_histograms( channel,
                                        input_files,
                                        variable = variable,
                                        met_systematic = met_systematic,
                                        met_type = met_type,
                                        variable_bin = variable_bin,
                                        b_tag_bin = b_tag_bin,
                                        rebin = measurement_config.rebin[fit_variable],
                                        fit_variable = fit_variable,
                                        scale_factors = scale_factors,
                                        treePrefix = treePrefix,
                                        weightBranch = weightBranch,
                                        )
            # create data sets
            h_fit_variable_signal = None
            mc_histograms = None

            # if options.make_combined_signal:
            #     h_fit_variable_signal = histograms['TTJet'] + histograms['SingleTop']
            #     mc_histograms = {
            #                     'signal' : h_fit_variable_signal,
            #                     'V+Jets': histograms['V+Jets'],
            #                     'QCD': histograms['QCD'],
            #                 }
            # else:
            mc_histograms = {
                            'TTJet': histograms['TTJet'],
                            'SingleTop': histograms['SingleTop'],
                            'V+Jets': histograms['V+Jets'],
                            'QCD': histograms['QCD'],
                        }
            h_data = histograms['data']

            # if options.closure_test:
            #     ct_type = options.closure_test_type
            #     ct_norm = closure_tests[ct_type]
            #     h_data = histograms['TTJet'] * ct_norm['TTJet'] + histograms['SingleTop'] * ct_norm['SingleTop'] + histograms['V+Jets'] * ct_norm['V+Jets'] + histograms['QCD'] * ct_norm['QCD'] 
            fit_data = FitData( h_data,
                            mc_histograms,
                            fit_boundaries = measurement_config.fit_boundaries[fit_variable] )
            fit_data_collection.add( fit_data, name = fit_variable )
        # if options.enable_constraints:
        #     fit_data_collection.set_normalisation_constraints( {'QCD': 2.0, 'V+Jets': 0.5} )

        if use_fitter == 'RooFit':
            fitter = RooFitFit( fit_data_collection )
        elif use_fitter == 'Minuit':
            fitter = Minuit( fit_data_collection, verbose = verbose )
        else:  # not recognised
            sys.stderr.write( 'Do not recognise fitter "%s". Using default (Minuit).\n' % fitter )
            fitter = Minuit ( fit_data_collection )

        if verbose:
            print "FITTING: " + channel + '_' + variable + '_' + variable_bin + '_' + met_type + '_' + b_tag_bin

        fitter.fit()
        fit_results = fitter.readResults()
        
        normalisation = fit_data_collection.mc_normalisation( fit_variables[0] )
        normalisation_errors = fit_data_collection.mc_normalisation_errors( fit_variables[0] )

        # if options.make_combined_signal:
        #     N_ttbar_before_fit = histograms['TTJet'].Integral()
        #     N_SingleTop_before_fit = histograms['SingleTop'].Integral()
        #     N_ttbar_error_before_fit = sum(histograms['TTJet'].yerravg())
        #     N_SingleTop_error_before_fit = sum(histograms['SingleTop'].yerravg())
        #     N_Higgs_before_fit = 0
        #     N_Higgs_error_before_fit = 0
        #     if measurement_config.include_higgs:
        #         N_Higgs_before_fit = histograms['Higgs'].Integral()
        #         N_Higgs_error_before_fit = sum(histograms['Higgs'].yerravg())
     
        #     if (N_SingleTop_before_fit != 0):
        #         TTJet_SingleTop_ratio = (N_ttbar_before_fit + N_Higgs_before_fit) / N_SingleTop_before_fit
        #     else:
        #         print 'Bin ', variable_bin, ': ttbar/singleTop ratio undefined for %s channel! Setting to 0.' % channel
        #         TTJet_SingleTop_ratio = 0
     
        #     N_ttbar_all, N_SingleTop = decombine_result(fit_results['signal'], TTJet_SingleTop_ratio)
        #     if (N_Higgs_before_fit != 0):
        #         TTJet_Higgs_ratio = N_ttbar_before_fit/ N_Higgs_before_fit
        #     else:
        #         TTJet_Higgs_ratio = 0
     
            
        #     N_ttbar, N_Higgs = decombine_result(N_ttbar_all, TTJet_Higgs_ratio)
    
        #     fit_results['TTJet'] = N_ttbar
        #     fit_results['SingleTop'] = N_SingleTop
        #     fit_results['Higgs'] = N_Higgs
    
        #     normalisation['TTJet'] = N_ttbar_before_fit
        #     normalisation['SingleTop'] = N_SingleTop_before_fit
        #     normalisation['Higgs'] = N_Higgs_before_fit
        #     normalisation_errors['TTJet'] = N_ttbar_error_before_fit
        #     normalisation_errors['SingleTop'] = N_SingleTop_error_before_fit
        #     normalisation_errors['Higgs'] = N_Higgs_error_before_fit

        if results == {}:  # empty
            initial_values['data'] = [( normalisation['data'], normalisation_errors['data'] )]
            for fit_variable in fit_variables:
                templates[fit_variable]['data'] = [fit_data_collection.vectors( fit_variable )['data']]
            for sample in fit_results.keys():
                results[sample] = [fit_results[sample]]
                initial_values[sample] = [( normalisation[sample], normalisation_errors[sample] )]
                if sample in ['TTJet', 'SingleTop', 'Higgs'] and options.make_combined_signal:
                    continue
                for fit_variable in fit_variables:
                    templates[fit_variable][sample] = [fit_data_collection.vectors( fit_variable )[sample]]
        else:
            initial_values['data'].append( [normalisation['data'], normalisation_errors['data']] )
            for fit_variable in fit_variables:
                templates[fit_variable]['data'].append( fit_data_collection.vectors( fit_variable )['data'] )
            for sample in fit_results.keys():
                results[sample].append( fit_results[sample] )
                initial_values[sample].append( [normalisation[sample], normalisation_errors[sample]] )
                if sample in ['TTJet', 'SingleTop', 'Higgs'] and options.make_combined_signal:
                    continue
                for fit_variable in fit_variables:
                    templates[fit_variable][sample].append( fit_data_collection.vectors( fit_variable )[sample] )

    # print results
    # print "results = ", results
    # print 'templates = ',templates
    return results, initial_values, templates
class Test(unittest.TestCase):
    def setUp(self):
        # create histograms
        h_bkg1_1 = Hist(100, 40, 200, title='Background')
        h_signal_1 = h_bkg1_1.Clone(title='Signal')
        h_data_1 = h_bkg1_1.Clone(title='Data')

        # fill the histograms with our distributions
        map(h_bkg1_1.Fill, x1)
        map(h_signal_1.Fill, x2)
        map(h_data_1.Fill, x1_obs)
        map(h_data_1.Fill, x2_obs)

        histograms_1 = {
            'signal': h_signal_1,
            'bkg1': h_bkg1_1,
            #                       'data': h_data_1
        }
        fit_data_1 = FitData(h_data_1, histograms_1, fit_boundaries=(40, 200))
        self.single_fit_collection = FitDataCollection()
        self.single_fit_collection.add(fit_data_1)

        #         self.roofitFitter = RooFitFit(histograms_1, dataLabel='data', fit_boundries=(40, 200))
        self.roofitFitter = RooFitFit(self.single_fit_collection)

    def tearDown(self):
        pass

    def test_normalisation(self):
        normalisation = self.roofitFitter.normalisation
        self.assertAlmostEqual(normalisation["data"],
                               N_data,
                               delta=sqrt(N_data))
        self.assertAlmostEqual(normalisation["bkg1"],
                               N_bkg1,
                               delta=sqrt(N_bkg1))
        self.assertAlmostEqual(normalisation["signal"],
                               N_signal,
                               delta=sqrt(N_signal))

    def test_signal_result(self):
        self.roofitFitter.fit()
        results = self.roofitFitter.readResults()
        self.assertAlmostEqual(N_signal_obs,
                               results['signal'][0],
                               delta=2 * results['signal'][1])
        self.assertAlmostEqual(N_bkg1_obs,
                               results['bkg1'][0],
                               delta=2 * results['bkg1'][1])

    def test_constraints(self):
        self.single_fit_collection.set_normalisation_constraints({
            'signal': 0.8,
            'bkg1': 0.5
        })
        self.roofitFitter = RooFitFit(self.single_fit_collection)
        #         self.roofitFitter.set_fit_constraints({'signal': 0.8, 'bkg1': 0.5})
        self.roofitFitter.fit()
        results = self.roofitFitter.readResults()
        self.assertAlmostEqual(N_signal_obs,
                               results['signal'][0],
                               delta=2 * results['signal'][1])
        self.assertAlmostEqual(N_bkg1_obs,
                               results['bkg1'][0],
                               delta=2 * results['bkg1'][1])