class Test(unittest.TestCase):


    def setUp(self):
        

        # create histograms
        h1 = Hist(100, 40, 200, title='Background')
        h2 = h1.Clone(title='Signal')
        h3 = h1.Clone(title='Data')
        h3.markersize=1.2
    
        # fill the histograms with our distributions
        map(h1.Fill, x1)
        map(h2.Fill, x2)
        map(h3.Fill, x1_obs)
        map(h3.Fill, x2_obs)
        
        histograms = {'signal': h2,
                      'bkg1': h1,
                      'data': h3}
        self.minuitFitter = TMinuitFit(histograms, dataLabel='data')
        self.minuitFitter.fit()


    def tearDown(self):
        pass

    def testTemplateKeys(self):
        templateKeys = sorted(self.minuitFitter.templates.keys())
        self.assertEqual(templateKeys, sorted(['signal', 'bkg1', 'data']))

    def testNormalisation(self):
        normalisation = self.minuitFitter.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 testSignalResult(self):
        results = self.minuitFitter.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
        h1 = Hist(100, 40, 200, title='Background')
        h2 = h1.Clone(title='Signal')
        h3 = h1.Clone(title='Data')
        h3.markersize=1.2
    
        # fill the histograms with our distributions
        map(h1.Fill, x1)
        map(h2.Fill, x2)
        map(h3.Fill, x1_obs)
        map(h3.Fill, x2_obs)
        
        histograms = {'signal': h2,
                      'bkg1': h1,
                      'data': h3}
        self.minuitFitter = TMinuitFit(histograms, dataLabel='data')
        self.minuitFitter.fit()
def get_fitted_normalisation_from_ROOT(channel, input_files, variable, met_type, b_tag_bin):
    results = {}
    initial_values = {}
    templates = {}

    for variable_bin in variable_bins_ROOT[variable]:
        histograms = get_histograms(channel,
                                    input_files,
                                    variable=variable,
                                    met_type=met_type,
                                    variable_bin=variable_bin,
                                    b_tag_bin=b_tag_bin,
                                    rebin=measurement_config.rebin
                                    )
        # prepare histograms
        # normalise histograms
        
        # create signal histograms
        h_eta_signal = histograms['TTJet'] + histograms['SingleTop']
        fitter = TMinuitFit(histograms={
                                      'data':histograms['data'],
                                      'signal':h_eta_signal,
#                                      'background':histograms['V+Jets']+histograms['QCD']
                                      'V+Jets':histograms['V+Jets'],
                                      'QCD':histograms['QCD']
                                      })
        
        fitter.set_fit_constraints({'QCD': 2.0, 'V+Jets': 0.5})
        fitter.fit()
        fit_results = fitter.readResults()
        normalisation = fitter.normalisation
        normalisation_errors = fitter.normalisation_errors
        
        N_ttbar_before_fit = histograms['TTJet'].Integral()
        N_SingleTop_before_fit = histograms['SingleTop'].Integral()
        N_ttbar_error_before_fit = sum(histograms['TTJet'].errors())
        N_SingleTop_error_before_fit = sum(histograms['SingleTop'].errors())

        if (N_SingleTop_before_fit != 0):
            TTJet_SingleTop_ratio = N_ttbar_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, N_SingleTop = decombine_result(fit_results['signal'], TTJet_SingleTop_ratio)
        
        
        fit_results['TTJet'] = N_ttbar
        fit_results['SingleTop'] = N_SingleTop
        normalisation['TTJet'] = N_ttbar_before_fit
        normalisation['SingleTop'] = N_SingleTop_before_fit
        normalisation_errors['TTJet'] = N_ttbar_error_before_fit
        normalisation_errors['SingleTop'] = N_SingleTop_error_before_fit
        
        if results == {}:  # empty
            initial_values['data'] = [(normalisation['data'], normalisation_errors['data'])]
            templates['data'] = [fitter.vectors['data']]
            for sample in fit_results.keys():
                results[sample] = [fit_results[sample]]
                initial_values[sample] = [(normalisation[sample], normalisation_errors[sample])]
                if not sample == 'TTJet' and not sample == 'SingleTop':
                    templates[sample] = [fitter.vectors[sample]]
        else:
            initial_values['data'].append([normalisation['data'], normalisation_errors['data']])
            templates['data'].append(fitter.vectors['data'])
            for sample in fit_results.keys():
                results[sample].append(fit_results[sample])
                initial_values[sample].append([normalisation[sample], normalisation_errors[sample]])
                if not sample == 'TTJet' and not sample == 'SingleTop':
                    templates[sample].append(fitter.vectors[sample])
        
    return results, initial_values, templates
def get_fitted_normalisation_from_ROOT(input_files, met_type, b_tag_bin):
    global met_bins_ROOT
    electron_results = {}
    electron_initial_values = {}
    muon_results = {}
    muon_initial_values = {}
    for met_bin in met_bins_ROOT:
        electron_histograms, muon_histograms = get_histograms(input_files={
                                  'TTJet': TTJet_file,
                                  'SingleTop': SingleTop_file,
                                  'V+Jets':VJets_file,
                                  'data_electron': data_file_electron,
                                  'data_muon': data_file_muon
                                  },
                   met_type=met_type,
                   met_bin=met_bin,
                   b_tag_bin=b_tag_bin,
                   rebin=20
                   )
        # prepare histograms
        # normalise histograms
        # TODO
        
        # store pre-fit information
        
        # create signal histograms
        h_electron_eta_signal = electron_histograms['TTJet'] + electron_histograms['SingleTop']
        h_muon_eta_signal = muon_histograms['TTJet'] + muon_histograms['SingleTop']
        fitter_electron = TMinuitFit(histograms={
                                      'data':electron_histograms['data_electron'],
                                      'signal':h_electron_eta_signal,
                                      'V+Jets':electron_histograms['V+Jets'],
                                      'QCD':electron_histograms['QCD']
                                      })
        fitter_muon = TMinuitFit(histograms={
                                      'data':muon_histograms['data_muon'],
                                      'signal':h_muon_eta_signal,
                                      'V+Jets':muon_histograms['V+Jets'],
                                      'QCD':muon_histograms['QCD']
                                      })
        
        fitter_electron.fit()
        fit_results_electron = fitter_electron.readResults()
        normalisation_electron = fitter_electron.normalisation
        
        N_ttbar_before_fit_electron = electron_histograms['TTJet'].Integral()
        N_SingleTop_before_fit_electron = electron_histograms['SingleTop'].Integral()
        
        TTJet_SingleTop_ratio_electron = N_ttbar_before_fit_electron / N_SingleTop_before_fit_electron
        N_ttbar_electron, N_SingleTop_electron = decombine_result(fit_results_electron['signal'], TTJet_SingleTop_ratio_electron)
        
        
        fit_results_electron['TTJet'] = N_ttbar_electron
        fit_results_electron['SingleTop'] = N_SingleTop_electron
        normalisation_electron['TTJet'] = N_ttbar_before_fit_electron
        normalisation_electron['SingleTop'] = N_SingleTop_before_fit_electron
        # this needs to
        if electron_results == {}:  # empty
            for sample in fit_results_electron.keys():
                electron_results[sample] = [fit_results_electron[sample]]
                electron_initial_values[sample] = [normalisation_electron[sample]]
        else:
            for sample in fit_results_electron.keys():
                electron_results[sample].append(fit_results_electron[sample])
                electron_initial_values[sample].append(normalisation_electron[sample])
        
        fitter_muon.fit()
        fit_results_muon = fitter_muon.readResults()
        normalisation_muon = fitter_muon.normalisation
        
        N_ttbar_before_fit_muon = muon_histograms['TTJet'].Integral()
        N_SingleTop_before_fit_muon = muon_histograms['SingleTop'].Integral()
        TTJet_SingleTop_ratio_muon = N_ttbar_before_fit_muon / N_SingleTop_before_fit_muon
        N_ttbar_muon, N_SingleTop_muon = decombine_result(fit_results_muon['signal'], TTJet_SingleTop_ratio_muon)
        
        fit_results_muon['TTJet'] = N_ttbar_muon
        fit_results_muon['SingleTop'] = N_SingleTop_muon
        normalisation_muon['TTJet'] = N_ttbar_before_fit_muon
        normalisation_muon['SingleTop'] = N_SingleTop_before_fit_muon
        
        if muon_results == {}:  # empty
            for sample in fit_results_muon.keys():
                muon_results[sample] = [fit_results_muon[sample]]
                muon_initial_values[sample] = [normalisation_muon[sample]]
        else:
            for sample in fit_results_muon.keys():
                muon_results[sample].append(fit_results_muon[sample])
                muon_initial_values[sample].append(normalisation_muon[sample])
        
    return electron_results, muon_results, electron_initial_values, muon_initial_values