def getCleanedShape(self, sample): subtract = copy.copy(self.histograms.keys()) subtract.remove(sample) subtract.remove('data') hist = clean_control_region(self.histograms, data_label='data', subtract=subtract, fix_to_zero=True) return hist
def __qcd_from_data(self): ''' Replace Signal region mc qcd with data driven qcd N MC QCD in SR Data in CR * -------------- N MC QCD in CR Shape transfer factor from control to signal region ''' # Get the shape of the data driven qcd in the control region data_driven_qcd = clean_control_region( self.cr_histograms, subtract=['TTBar', 'V+Jets', 'SingleTop'] ) # print(hist_to_value_error_tuplelist(data_driven_qcd)) # Calculate transfer factor from signal to control region n_mc_sr = self.histograms['QCD'].Integral() n_mc_cr = 1 transfer_factor = 1 if self.cr_histograms_for_normalisation == {}: n_mc_cr = self.cr_histograms['QCD'].Integral() transfer_factor = n_mc_sr/n_mc_cr else : # Treatment for QCD systematic uncertainties # Use shape from the control region # and the normalisation derived from a different control region n_mc_cr = self.cr_histograms['QCD'].Integral() n_mc_cr_norm = self.cr_histograms_for_normalisation['QCD'].Integral() data_driven_qcd_normalisation = clean_control_region( self.cr_histograms_for_normalisation, subtract=['TTBar', 'V+Jets', 'SingleTop'] ) n_data_cr_norm = data_driven_qcd_normalisation.Integral() transfer_factor = n_mc_sr/ n_mc_cr_norm * n_data_cr_norm / data_driven_qcd.Integral() data_driven_qcd.Scale( transfer_factor ) # Replace QCD histogram with datadriven one self.histograms['QCD'] = data_driven_qcd self.t_factor = transfer_factor return
def __qcd_from_data(self): ''' Replace Signal region mc qcd with data driven qcd N MC QCD in SR Data in CR * -------------- N MC QCD in CR Shape transfer factor from control to signal region ''' # Get the shape of the data driven qcd in the control region data_driven_qcd = clean_control_region( self.cr_histograms, subtract=['TTBar', 'V+Jets', 'SingleTop']) # print(hist_to_value_error_tuplelist(data_driven_qcd)) # Calculate transfer factor from signal to control region n_mc_sr = self.histograms['QCD'].Integral() n_mc_cr = 1 transfer_factor = 1 if self.cr_histograms_for_normalisation == {}: n_mc_cr = self.cr_histograms['QCD'].Integral() transfer_factor = n_mc_sr / n_mc_cr else: # Treatment for QCD systematic uncertainties # Use shape from the control region # and the normalisation derived from a different control region n_mc_cr = self.cr_histograms['QCD'].Integral() n_mc_cr_norm = self.cr_histograms_for_normalisation[ 'QCD'].Integral() data_driven_qcd_normalisation = clean_control_region( self.cr_histograms_for_normalisation, subtract=['TTBar', 'V+Jets', 'SingleTop']) n_data_cr_norm = data_driven_qcd_normalisation.Integral() transfer_factor = n_mc_sr / n_mc_cr_norm * n_data_cr_norm / data_driven_qcd.Integral( ) data_driven_qcd.Scale(transfer_factor) # Replace QCD histogram with datadriven one self.histograms['QCD'] = data_driven_qcd self.t_factor = transfer_factor return
def __background_subtraction(self, histograms): ''' Subtracts the backgrounds from data to give amount of ttbar in data. Also adds all backgrounds to normalisation output ''' ttjet_hist = clean_control_region( histograms, subtract=['QCD', 'V+Jets', 'SingleTop'] ) self.normalisation['TTJet'] = hist_to_value_error_tuplelist(ttjet_hist) self.normalisation['data'] = hist_to_value_error_tuplelist(histograms['data']) self.normalisation['TTJet_MC'] = hist_to_value_error_tuplelist(histograms['TTBar']) self.normalisation['SingleTop'] = hist_to_value_error_tuplelist(histograms['SingleTop']) self.normalisation['V+Jets'] = hist_to_value_error_tuplelist(histograms['V+Jets']) self.normalisation['QCD'] = hist_to_value_error_tuplelist(histograms['QCD']) return
def __background_subtraction(self, histograms): ''' Subtracts the backgrounds from data to give amount of ttbar in data. Also adds all backgrounds to normalisation output ''' ttjet_hist = clean_control_region( histograms, subtract=['QCD', 'V+Jets', 'SingleTop']) self.normalisation['TTJet'] = hist_to_value_error_tuplelist(ttjet_hist) self.normalisation['data'] = hist_to_value_error_tuplelist( histograms['data']) self.normalisation['TTJet_MC'] = hist_to_value_error_tuplelist( histograms['TTBar']) self.normalisation['SingleTop'] = hist_to_value_error_tuplelist( histograms['SingleTop']) self.normalisation['V+Jets'] = hist_to_value_error_tuplelist( histograms['V+Jets']) self.normalisation['QCD'] = hist_to_value_error_tuplelist( histograms['QCD']) return
def plotHistograms( histogram_files, var_to_plot, output_folder): ''' ''' global measurement_config weightBranchSignalRegion = 'EventWeight * PUWeight * BJetWeight' weightBranchControlRegion = 'EventWeight' # Names of QCD regions to use qcd_data_region = '' qcd_data_region_electron = 'QCD non iso e+jets' qcd_data_region_muon = 'QCD non iso mu+jets 1p5to3' sr_e_tree = 'TTbar_plus_X_analysis/EPlusJets/Ref selection/AnalysisVariables' sr_mu_tree = 'TTbar_plus_X_analysis/MuPlusJets/Ref selection/AnalysisVariables' cr_e_tree = 'TTbar_plus_X_analysis/EPlusJets/{}/AnalysisVariables'.format(qcd_data_region_electron) cr_mu_tree = 'TTbar_plus_X_analysis/MuPlusJets/{}/AnalysisVariables'.format(qcd_data_region_muon) print "Trees : " print "\t {}".format(sr_e_tree) print "\t {}".format(sr_mu_tree) print "\t {}".format(cr_e_tree) print "\t {}".format(cr_mu_tree) histogram_files_electron = dict(histogram_files) histogram_files_electron['data'] = measurement_config.data_file_electron histogram_files_electron['QCD'] = measurement_config.electron_QCD_MC_trees histogram_files_muon = dict(histogram_files) histogram_files_muon['data'] = measurement_config.data_file_muon histogram_files_muon['QCD'] = measurement_config.muon_QCD_MC_trees signal_region_hists = {} control_region_hists = {} for var in var_to_plot: selectionSignalRegion = '{} >= 0'.format(var) # Print all the weights applied to this plot print "Variable : {}".format(var) print "Weight applied : {}".format(weightBranchSignalRegion) print "Selection applied : {}".format(selectionSignalRegion) histograms_electron = get_histograms_from_trees( trees = [sr_e_tree], branch = var, weightBranch = weightBranchSignalRegion + ' * ElectronEfficiencyCorrection', files = histogram_files_electron, nBins = 20, xMin = control_plots_bins[var][0], xMax = control_plots_bins[var][-1], selection = selectionSignalRegion ) histograms_muon = get_histograms_from_trees( trees = [sr_mu_tree], branch = var, weightBranch = weightBranchSignalRegion + ' * MuonEfficiencyCorrection', files = histogram_files_muon, nBins = 20, xMin = control_plots_bins[var][0], xMax = control_plots_bins[var][-1], selection = selectionSignalRegion ) histograms_electron_QCDControlRegion = get_histograms_from_trees( trees = [cr_e_tree], branch = var, weightBranch = weightBranchControlRegion, files = histogram_files_electron, nBins = 20, xMin = control_plots_bins[var][0], xMax = control_plots_bins[var][-1], selection = selectionSignalRegion ) histograms_muon_QCDControlRegion = get_histograms_from_trees( trees = [cr_mu_tree], branch = var, weightBranch = weightBranchControlRegion, files = histogram_files_muon, nBins = 20, xMin = control_plots_bins[var][0], xMax = control_plots_bins[var][-1], selection = selectionSignalRegion ) # Combine the electron and muon histograms for sample in histograms_electron: h_electron = histograms_electron[sample][sr_e_tree] h_muon = histograms_muon[sample][sr_mu_tree] h_qcd_electron = histograms_electron_QCDControlRegion[sample][cr_e_tree] h_qcd_muon = histograms_muon_QCDControlRegion[sample][cr_mu_tree] signal_region_hists[sample] = h_electron + h_muon control_region_hists[sample] = h_qcd_electron + h_qcd_muon # NORMALISE TO LUMI prepare_histograms( signal_region_hists, scale_factor = measurement_config.luminosity_scale ) prepare_histograms( control_region_hists, scale_factor = measurement_config.luminosity_scale ) # BACKGROUND SUBTRACTION FOR QCD qcd_from_data = None qcd_from_data = clean_control_region( control_region_hists, subtract = ['TTJet', 'V+Jets', 'SingleTop'] ) # DATA DRIVEN QCD nBins = signal_region_hists['QCD'].GetNbinsX() n, error = signal_region_hists['QCD'].integral(0,nBins+1,error=True) n_qcd_predicted_mc_signal = ufloat( n, error) n, error = control_region_hists['QCD'].integral(0,nBins+1,error=True) n_qcd_predicted_mc_control = ufloat( n, error) n, error = qcd_from_data.integral(0,nBins+1,error=True) n_qcd_control_region = ufloat( n, error) dataDrivenQCDScale = n_qcd_predicted_mc_signal / n_qcd_predicted_mc_control qcd_from_data.Scale( dataDrivenQCDScale.nominal_value ) signal_region_hists['QCD'] = qcd_from_data # PLOTTING histograms_to_draw = [] histogram_lables = [] histogram_colors = [] histograms_to_draw = [ # signal_region_hists['data'], # qcd_from_data, # signal_region_hists['V+Jets'], signal_region_hists['SingleTop'], signal_region_hists['ST_s'], signal_region_hists['ST_t'], signal_region_hists['ST_tW'], signal_region_hists['STbar_t'], signal_region_hists['STbar_tW'], # signal_region_hists['TTJet'], ] histogram_lables = [ 'data', # 'QCD', # 'V+Jets', # 'Single-Top', 'ST-s', 'ST-t', 'ST-tW', 'STbar-t', 'STbar-tW', # samples_latex['TTJet'], ] histogram_colors = [ colours['data'], # colours['QCD'], # colours['V+Jets'], # colours['Single-Top'], colours['ST_s'], colours['ST_t'], colours['ST_tW'], colours['STbar_t'], colours['STbar_tW'], # colours['TTJet'], ] # Find maximum y of samples maxData = max( list(signal_region_hists['SingleTop'].y()) ) y_limits = [0, maxData * 1.5] log_y = False if log_y: y_limits = [0.1, maxData * 100 ] # Lumi title of plots title_template = '%.1f fb$^{-1}$ (%d TeV)' title = title_template % ( measurement_config.new_luminosity/1000., measurement_config.centre_of_mass_energy ) x_axis_title = '$%s$ [GeV]' % variables_latex[var] y_axis_title = 'Events/(%i GeV)' % binWidth(control_plots_bins[var]) # More histogram settings to look semi decent histogram_properties = Histogram_properties() histogram_properties.name = var + '_with_ratio' histogram_properties.title = title histogram_properties.x_axis_title = x_axis_title histogram_properties.y_axis_title = y_axis_title histogram_properties.x_limits = control_plots_bins[var] histogram_properties.y_limits = y_limits histogram_properties.y_max_scale = 1.4 histogram_properties.xerr = None histogram_properties.emptybins = True histogram_properties.additional_text = channel_latex['combined'] histogram_properties.legend_location = ( 0.9, 0.73 ) histogram_properties.cms_logo_location = 'left' histogram_properties.preliminary = True histogram_properties.set_log_y = log_y histogram_properties.legend_color = False histogram_properties.ratio_y_limits = [0.1,1.9] if log_y: histogram_properties.name += '_logy' loc = histogram_properties.legend_location histogram_properties.legend_location = ( loc[0], loc[1] + 0.05 ) make_data_mc_comparison_plot( histograms_to_draw, histogram_lables, histogram_colors, histogram_properties, save_folder = output_folder, show_ratio = True, ) histogram_properties.name = var + '_ST_TTJet_Shape' if log_y: histogram_properties.name += '_logy' histogram_properties.y_axis_title = 'Normalised Distribution' histogram_properties.y_limits = [0,0.5] make_shape_comparison_plot( shapes = [ signal_region_hists['TTJet'], signal_region_hists['ST_t'], signal_region_hists['ST_tW'], signal_region_hists['ST_s'], signal_region_hists['STbar_t'], signal_region_hists['STbar_tW'], ], names = [ samples_latex['TTJet'], 'Single-Top t channel', 'Single-Top tW channel', 'Single-Top s channel', 'Single-AntiTop t channel', 'Single-AntiTop tW channel', ], colours = [ colours['TTJet'], colours['ST_t'], colours['ST_tW'], colours['ST_s'], colours['STbar_t'], colours['STbar_tW'], ], histogram_properties = histogram_properties, save_folder = output_folder, fill_area = False, add_error_bars = False, save_as = ['pdf'], make_ratio = True, alpha = 1, ) print_output(signal_region_hists, output_folder, var, 'combined') return
def plotHistograms(histogram_files, var_to_plot, output_folder): ''' ''' global measurement_config weightBranchSignalRegion = 'EventWeight * PUWeight * BJetWeight' weightBranchControlRegion = 'EventWeight' # Names of QCD regions to use qcd_data_region = '' qcd_data_region_electron = 'QCD non iso e+jets' qcd_data_region_muon = 'QCD non iso mu+jets 1p5to3' sr_e_tree = 'TTbar_plus_X_analysis/EPlusJets/Ref selection/AnalysisVariables' sr_mu_tree = 'TTbar_plus_X_analysis/MuPlusJets/Ref selection/AnalysisVariables' cr_e_tree = 'TTbar_plus_X_analysis/EPlusJets/{}/AnalysisVariables'.format( qcd_data_region_electron) cr_mu_tree = 'TTbar_plus_X_analysis/MuPlusJets/{}/AnalysisVariables'.format( qcd_data_region_muon) print "Trees : " print "\t {}".format(sr_e_tree) print "\t {}".format(sr_mu_tree) print "\t {}".format(cr_e_tree) print "\t {}".format(cr_mu_tree) histogram_files_electron = dict(histogram_files) histogram_files_electron['data'] = measurement_config.data_file_electron histogram_files_electron['QCD'] = measurement_config.electron_QCD_MC_trees histogram_files_muon = dict(histogram_files) histogram_files_muon['data'] = measurement_config.data_file_muon histogram_files_muon['QCD'] = measurement_config.muon_QCD_MC_trees signal_region_hists = {} control_region_hists = {} for var in var_to_plot: selectionSignalRegion = '{} >= 0'.format(var) # Print all the weights applied to this plot print "Variable : {}".format(var) print "Weight applied : {}".format(weightBranchSignalRegion) print "Selection applied : {}".format(selectionSignalRegion) histograms_electron = get_histograms_from_trees( trees=[sr_e_tree], branch=var, weightBranch=weightBranchSignalRegion + ' * ElectronEfficiencyCorrection', files=histogram_files_electron, nBins=20, xMin=control_plots_bins[var][0], xMax=control_plots_bins[var][-1], selection=selectionSignalRegion) histograms_muon = get_histograms_from_trees( trees=[sr_mu_tree], branch=var, weightBranch=weightBranchSignalRegion + ' * MuonEfficiencyCorrection', files=histogram_files_muon, nBins=20, xMin=control_plots_bins[var][0], xMax=control_plots_bins[var][-1], selection=selectionSignalRegion) histograms_electron_QCDControlRegion = get_histograms_from_trees( trees=[cr_e_tree], branch=var, weightBranch=weightBranchControlRegion, files=histogram_files_electron, nBins=20, xMin=control_plots_bins[var][0], xMax=control_plots_bins[var][-1], selection=selectionSignalRegion) histograms_muon_QCDControlRegion = get_histograms_from_trees( trees=[cr_mu_tree], branch=var, weightBranch=weightBranchControlRegion, files=histogram_files_muon, nBins=20, xMin=control_plots_bins[var][0], xMax=control_plots_bins[var][-1], selection=selectionSignalRegion) # Combine the electron and muon histograms for sample in histograms_electron: h_electron = histograms_electron[sample][sr_e_tree] h_muon = histograms_muon[sample][sr_mu_tree] h_qcd_electron = histograms_electron_QCDControlRegion[sample][ cr_e_tree] h_qcd_muon = histograms_muon_QCDControlRegion[sample][cr_mu_tree] signal_region_hists[sample] = h_electron + h_muon control_region_hists[sample] = h_qcd_electron + h_qcd_muon # NORMALISE TO LUMI prepare_histograms(signal_region_hists, scale_factor=measurement_config.luminosity_scale) prepare_histograms(control_region_hists, scale_factor=measurement_config.luminosity_scale) # BACKGROUND SUBTRACTION FOR QCD qcd_from_data = None qcd_from_data = clean_control_region( control_region_hists, subtract=['TTJet', 'V+Jets', 'SingleTop']) # DATA DRIVEN QCD nBins = signal_region_hists['QCD'].GetNbinsX() n, error = signal_region_hists['QCD'].integral(0, nBins + 1, error=True) n_qcd_predicted_mc_signal = ufloat(n, error) n, error = control_region_hists['QCD'].integral(0, nBins + 1, error=True) n_qcd_predicted_mc_control = ufloat(n, error) n, error = qcd_from_data.integral(0, nBins + 1, error=True) n_qcd_control_region = ufloat(n, error) dataDrivenQCDScale = n_qcd_predicted_mc_signal / n_qcd_predicted_mc_control qcd_from_data.Scale(dataDrivenQCDScale.nominal_value) signal_region_hists['QCD'] = qcd_from_data # PLOTTING histograms_to_draw = [] histogram_lables = [] histogram_colors = [] histograms_to_draw = [ # signal_region_hists['data'], # qcd_from_data, # signal_region_hists['V+Jets'], signal_region_hists['SingleTop'], signal_region_hists['ST_s'], signal_region_hists['ST_t'], signal_region_hists['ST_tW'], signal_region_hists['STbar_t'], signal_region_hists['STbar_tW'], # signal_region_hists['TTJet'], ] histogram_lables = [ 'data', # 'QCD', # 'V+Jets', # 'Single-Top', 'ST-s', 'ST-t', 'ST-tW', 'STbar-t', 'STbar-tW', # samples_latex['TTJet'], ] histogram_colors = [ colours['data'], # colours['QCD'], # colours['V+Jets'], # colours['Single-Top'], colours['ST_s'], colours['ST_t'], colours['ST_tW'], colours['STbar_t'], colours['STbar_tW'], # colours['TTJet'], ] # Find maximum y of samples maxData = max(list(signal_region_hists['SingleTop'].y())) y_limits = [0, maxData * 1.5] log_y = False if log_y: y_limits = [0.1, maxData * 100] # Lumi title of plots title_template = '%.1f fb$^{-1}$ (%d TeV)' title = title_template % (measurement_config.new_luminosity / 1000., measurement_config.centre_of_mass_energy) x_axis_title = '$%s$ [GeV]' % variables_latex[var] y_axis_title = 'Events/(%i GeV)' % binWidth(control_plots_bins[var]) # More histogram settings to look semi decent histogram_properties = Histogram_properties() histogram_properties.name = var + '_with_ratio' histogram_properties.title = title histogram_properties.x_axis_title = x_axis_title histogram_properties.y_axis_title = y_axis_title histogram_properties.x_limits = control_plots_bins[var] histogram_properties.y_limits = y_limits histogram_properties.y_max_scale = 1.4 histogram_properties.xerr = None histogram_properties.emptybins = True histogram_properties.additional_text = channel_latex['combined'] histogram_properties.legend_location = (0.9, 0.73) histogram_properties.cms_logo_location = 'left' histogram_properties.preliminary = True histogram_properties.set_log_y = log_y histogram_properties.legend_color = False histogram_properties.ratio_y_limits = [0.1, 1.9] if log_y: histogram_properties.name += '_logy' loc = histogram_properties.legend_location histogram_properties.legend_location = (loc[0], loc[1] + 0.05) make_data_mc_comparison_plot( histograms_to_draw, histogram_lables, histogram_colors, histogram_properties, save_folder=output_folder, show_ratio=True, ) histogram_properties.name = var + '_ST_TTJet_Shape' if log_y: histogram_properties.name += '_logy' histogram_properties.y_axis_title = 'Normalised Distribution' histogram_properties.y_limits = [0, 0.5] make_shape_comparison_plot( shapes=[ signal_region_hists['TTJet'], signal_region_hists['ST_t'], signal_region_hists['ST_tW'], signal_region_hists['ST_s'], signal_region_hists['STbar_t'], signal_region_hists['STbar_tW'], ], names=[ samples_latex['TTJet'], 'Single-Top t channel', 'Single-Top tW channel', 'Single-Top s channel', 'Single-AntiTop t channel', 'Single-AntiTop tW channel', ], colours=[ colours['TTJet'], colours['ST_t'], colours['ST_tW'], colours['ST_s'], colours['STbar_t'], colours['STbar_tW'], ], histogram_properties=histogram_properties, save_folder=output_folder, fill_area=False, add_error_bars=False, save_as=['pdf'], make_ratio=True, alpha=1, ) print_output(signal_region_hists, output_folder, var, 'combined') return
def compare_QCD_control_regions_to_MC(): config = XSectionConfig(13) ctrl_e1 = 'TTbar_plus_X_analysis/EPlusJets/QCDConversions/FitVariables' ctrl_e2 = 'TTbar_plus_X_analysis/EPlusJets/QCD non iso e+jets/FitVariables' mc_e = 'TTbar_plus_X_analysis/EPlusJets/Ref selection/FitVariables' data_file_e = config.data_file_electron_trees ttbar_file = config.ttbar_category_templates_trees['central'] vjets_file = config.VJets_category_templates_trees['central'] singleTop_file = config.SingleTop_category_templates_trees['central'] qcd_file_e = config.electron_QCD_MC_tree_file ctrl_mu1 = 'TTbar_plus_X_analysis/MuPlusJets/QCD iso > 0.3/FitVariables' ctrl_mu2 = 'TTbar_plus_X_analysis/MuPlusJets/QCD 0.12 < iso <= 0.3/FitVariables' mc_mu = 'TTbar_plus_X_analysis/MuPlusJets/Ref selection/FitVariables' data_file_mu = config.data_file_muon_trees qcd_file_mu = config.muon_QCD_MC_tree_file weight_branches_electron = [ "EventWeight", "PUWeight", "BJetWeight", "ElectronEfficiencyCorrection" ] weight_branches_mu = [ "EventWeight", "PUWeight", "BJetWeight", "MuonEfficiencyCorrection" ] variables = ['MET', 'HT', 'ST', 'NJets', 'lepton_pt', 'abs_lepton_eta', 'WPT'] # variables = ['abs_lepton_eta'] for variable in variables: branch = variable selection = '{0} >= 0'.format(branch) if variable == 'abs_lepton_eta': branch = 'abs(lepton_eta)' selection = 'lepton_eta >= -3' for channel in ['electron', 'muon']: data_file = data_file_e qcd_file = qcd_file_e ctrl1 = ctrl_e1 ctrl2 = ctrl_e2 mc = mc_e weight_branches = weight_branches_electron if channel == 'muon': data_file = data_file_mu qcd_file = qcd_file_mu ctrl1 = ctrl_mu1 ctrl2 = ctrl_mu2 mc = mc_mu weight_branches = weight_branches_mu inputs = { 'branch': branch, 'weight_branches': weight_branches, 'tree': ctrl1, 'bin_edges': bin_edges_vis[variable], 'selection': selection, } hs_ctrl1 = { 'data': get_histogram_from_tree(input_file=data_file, **inputs), 'TTJet': get_histogram_from_tree(input_file=ttbar_file, **inputs), 'VJets': get_histogram_from_tree(input_file=vjets_file, **inputs), 'SingleTop': get_histogram_from_tree(input_file=singleTop_file, **inputs), 'QCD': get_histogram_from_tree(input_file=qcd_file, **inputs), } inputs['tree'] = ctrl2 hs_ctrl2 = { 'data': get_histogram_from_tree(input_file=data_file, **inputs), 'TTJet': get_histogram_from_tree(input_file=ttbar_file, **inputs), 'VJets': get_histogram_from_tree(input_file=vjets_file, **inputs), 'SingleTop': get_histogram_from_tree(input_file=singleTop_file, **inputs), 'QCD': get_histogram_from_tree(input_file=qcd_file, **inputs), } inputs['tree'] = mc h_qcd = get_histogram_from_tree(input_file=qcd_file, **inputs) h_ctrl1 = clean_control_region( hs_ctrl1, data_label='data', subtract=['TTJet', 'VJets', 'SingleTop'], fix_to_zero=True) h_ctrl2 = clean_control_region( hs_ctrl2, data_label='data', subtract=['TTJet', 'VJets', 'SingleTop'], fix_to_zero=True) n_qcd_ctrl1 = hs_ctrl1['QCD'].integral() n_qcd_ctrl2 = hs_ctrl2['QCD'].integral() n_data1 = h_ctrl1.integral() n_data2 = h_ctrl2.integral() n_qcd_sg = h_qcd.integral() ratio_ctrl1 = n_data1 / n_qcd_ctrl1 ratio_ctrl2 = n_data2 / n_qcd_ctrl2 qcd_estimate_ctrl1 = n_qcd_sg * ratio_ctrl1 qcd_estimate_ctrl2 = n_qcd_sg * ratio_ctrl2 h_ctrl1.Scale(qcd_estimate_ctrl1 / n_data1) h_ctrl2.Scale(qcd_estimate_ctrl2 / n_data2) properties = Histogram_properties() properties.name = 'compare_qcd_control_regions_to_mc_{0}_{1}_channel'.format( variable, channel) properties.title = 'Comparison of QCD control regions ({0} channel)'.format( channel) properties.path = 'plots' properties.has_ratio = False properties.xerr = True properties.x_limits = ( bin_edges_vis[variable][0], bin_edges_vis[variable][-1]) properties.x_axis_title = variables_latex[variable] properties.y_axis_title = 'number of QCD events' histograms = {'control region 1': h_ctrl1, 'control region 2': h_ctrl2, 'MC prediction': h_qcd} diff = absolute(h_ctrl1 - h_ctrl2) lower = h_ctrl1 - diff upper = h_ctrl1 + diff err_e = ErrorBand('uncertainty', lower, upper) plot_e = Plot(histograms, properties) plot_e.draw_method = 'errorbar' plot_e.add_error_band(err_e) compare_histograms(plot_e)
for ch in channel: for variable in measurement_config.variables: print variable measurement_filepath = 'config/measurements/background_subtraction/13TeV/{channel}/{var}/VisiblePS/'.format(var=variable, channel=ch) # Get all config files in measurement_filepath central_file = measurement_filepath + 'central.json' other_qcd_control_file = measurement_filepath + 'QCD_other_control_region.json' central_control_histograms = getControlRegionHistogramsFromFile(central_file) other_control_histograms = getControlRegionHistogramsFromFile(other_qcd_control_file) # rebinHists( central_control_histograms ) # rebinHists( other_control_histograms ) qcd_from_data_in_central = clean_control_region( central_control_histograms, subtract=['TTBar', 'V+Jets', 'SingleTop'] ) qcd_mc_integral_in_central, u_central = central_control_histograms['QCD'].integral(overflow=True, error=True) qcd_mc_integral_in_central = ufloat( qcd_mc_integral_in_central, u_central ) qcd_from_data_in_other = clean_control_region( other_control_histograms, subtract=['TTBar', 'V+Jets', 'SingleTop'] ) qcd_mc_integral_in_other, u_other = other_control_histograms['QCD'].integral(overflow=True, error=True) qcd_mc_integral_in_other = ufloat( qcd_mc_integral_in_other, u_other) transfer_from_central_to_other = qcd_mc_integral_in_other / qcd_mc_integral_in_central
def background_subtraction(self, histograms): ttjet_hist = clean_control_region(histograms, subtract=['QCD', 'V+Jets', 'SingleTop']) self.normalisation[ 'TTJet'] = hist_to_value_error_tuplelist(ttjet_hist)
def make_plot( channel, x_axis_title, y_axis_title, signal_region_tree, control_region_tree, branchName, name_prefix, x_limits, nBins, use_qcd_data_region = False, compare_qcd_signal_with_data_control = False, y_limits = [], y_max_scale = 1.3, rebin = 1, legend_location = ( 0.98, 0.78 ), cms_logo_location = 'right', log_y = False, legend_color = False, ratio_y_limits = [0.3, 2.5], normalise = False, ): global output_folder, measurement_config, category, normalise_to_fit global preliminary, norm_variable, sum_bins, b_tag_bin, histogram_files controlToCompare = [] if 'electron' in channel : controlToCompare = ['QCDConversions', 'QCD non iso e+jets'] elif 'muon' in channel : controlToCompare = ['QCD iso > 0.3', 'QCD 0.12 < iso <= 0.3'] histogramsToCompare = {} for qcd_data_region in controlToCompare: print 'Doing ',qcd_data_region # Input files, normalisations, tree/region names title = title_template % ( measurement_config.new_luminosity, measurement_config.centre_of_mass_energy ) normalisation = None weightBranchSignalRegion = 'EventWeight' if 'electron' in channel: histogram_files['data'] = measurement_config.data_file_electron_trees histogram_files['QCD'] = measurement_config.electron_QCD_MC_category_templates_trees[category] if normalise_to_fit: normalisation = normalisations_electron[norm_variable] # if use_qcd_data_region: # qcd_data_region = 'QCDConversions' # # qcd_data_region = 'QCD non iso e+jets' if not 'QCD' in channel and not 'NPU' in branchName: weightBranchSignalRegion += ' * ElectronEfficiencyCorrection' if 'muon' in channel: histogram_files['data'] = measurement_config.data_file_muon_trees histogram_files['QCD'] = measurement_config.muon_QCD_MC_category_templates_trees[category] if normalise_to_fit: normalisation = normalisations_muon[norm_variable] # if use_qcd_data_region: # qcd_data_region = 'QCD iso > 0.3' if not 'QCD' in channel and not 'NPU' in branchName: weightBranchSignalRegion += ' * MuonEfficiencyCorrection' if not "_NPUNoWeight" in name_prefix: weightBranchSignalRegion += ' * PUWeight' if not "_NBJetsNoWeight" in name_prefix: weightBranchSignalRegion += ' * BJetWeight' selection = '1' if branchName == 'abs(lepton_eta)' : selection = 'lepton_eta > -10' else: selection = '%s >= 0' % branchName # if 'QCDConversions' in signal_region_tree: # selection += '&& isTightElectron' # print selection histograms = get_histograms_from_trees( trees = [signal_region_tree, control_region_tree], branch = branchName, weightBranch = weightBranchSignalRegion, files = histogram_files, nBins = nBins, xMin = x_limits[0], xMax = x_limits[-1], selection = selection ) histograms_QCDControlRegion = None if use_qcd_data_region: qcd_control_region = signal_region_tree.replace( 'Ref selection', qcd_data_region ) histograms_QCDControlRegion = get_histograms_from_trees( trees = [qcd_control_region], branch = branchName, weightBranch = 'EventWeight', files = histogram_files, nBins = nBins, xMin = x_limits[0], xMax = x_limits[-1], selection = selection ) # Split histograms up into signal/control (?) signal_region_hists = {} control_region_hists = {} for sample in histograms.keys(): signal_region_hists[sample] = histograms[sample][signal_region_tree] if compare_qcd_signal_with_data_control: if sample is 'data': signal_region_hists[sample] = histograms[sample][control_region_tree] elif sample is 'QCD' : signal_region_hists[sample] = histograms[sample][signal_region_tree] else: del signal_region_hists[sample] if use_qcd_data_region: control_region_hists[sample] = histograms_QCDControlRegion[sample][qcd_control_region] # Prepare histograms if normalise_to_fit: # only scale signal region to fit (results are invalid for control region) prepare_histograms( signal_region_hists, rebin = rebin, scale_factor = measurement_config.luminosity_scale, normalisation = normalisation ) elif normalise_to_data: totalMC = 0 for sample in signal_region_hists: if sample is 'data' : continue totalMC += signal_region_hists[sample].Integral() newScale = signal_region_hists['data'].Integral() / totalMC prepare_histograms( signal_region_hists, rebin = rebin, scale_factor = newScale, ) else: print measurement_config.luminosity_scale prepare_histograms( signal_region_hists, rebin = rebin, scale_factor = measurement_config.luminosity_scale ) prepare_histograms( control_region_hists, rebin = rebin, scale_factor = measurement_config.luminosity_scale ) # Use qcd from data control region or not qcd_from_data = None if use_qcd_data_region: qcd_from_data = clean_control_region( control_region_hists, subtract = ['TTJet', 'V+Jets', 'SingleTop'] ) # Normalise control region correctly nBins = signal_region_hists['QCD'].GetNbinsX() n, error = signal_region_hists['QCD'].integral(0,nBins+1,error=True) n_qcd_predicted_mc_signal = ufloat( n, error) n, error = control_region_hists['QCD'].integral(0,nBins+1,error=True) n_qcd_predicted_mc_control = ufloat( n, error) n, error = qcd_from_data.integral(0,nBins+1,error=True) n_qcd_control_region = ufloat( n, error) if not n_qcd_control_region == 0: dataDrivenQCDScale = n_qcd_predicted_mc_signal / n_qcd_predicted_mc_control print 'Overall scale : ',dataDrivenQCDScale qcd_from_data.Scale( dataDrivenQCDScale.nominal_value ) signalToControlScale = n_qcd_predicted_mc_signal / n_qcd_control_region dataToMCscale = n_qcd_control_region / n_qcd_predicted_mc_control print "Signal to control :",signalToControlScale print "QCD scale : ",dataToMCscale else: qcd_from_data = signal_region_hists['QCD'] # Which histograms to draw, and properties histograms_to_draw = [] histogram_lables = [] histogram_colors = [] if compare_qcd_signal_with_data_control : histograms_to_draw = [signal_region_hists['data'], qcd_from_data ] histogram_lables = ['data', 'QCD'] histogram_colors = ['black', 'yellow'] else : histograms_to_draw = [signal_region_hists['data'], qcd_from_data, signal_region_hists['V+Jets'], signal_region_hists['SingleTop'], signal_region_hists['TTJet']] histogram_lables = ['data', 'QCD', 'V+Jets', 'Single-Top', samples_latex['TTJet']] histogram_colors = [colours['data'], colours['QCD'], colours['V+Jets'], colours['Single-Top'], colours['TTJet'] ] print list(qcd_from_data.y()) histogramsToCompare[qcd_data_region] = qcd_from_data print histogramsToCompare histogram_properties = Histogram_properties() histogram_properties.name = 'QCD_control_region_comparison_' + channel + '_' + branchName histogram_properties.title = title histogram_properties.x_axis_title = x_axis_title histogram_properties.y_axis_title = y_axis_title histogram_properties.x_limits = x_limits histogram_properties.y_limits = y_limits histogram_properties.mc_error = 0.0 histogram_properties.legend_location = ( 0.98, 0.78 ) histogram_properties.ratio_y_limits = ratio_y_limits if 'electron' in channel: make_control_region_comparison(histogramsToCompare['QCDConversions'], histogramsToCompare['QCD non iso e+jets'], name_region_1='Conversions', name_region_2='Non Iso', histogram_properties=histogram_properties, save_folder=output_folder) elif 'muon' in channel: make_control_region_comparison(histogramsToCompare['QCD iso > 0.3'], histogramsToCompare['QCD 0.12 < iso <= 0.3'], name_region_1='QCD iso > 0.3', name_region_2='QCD 0.12 < iso <= 0.3', histogram_properties=histogram_properties, save_folder=output_folder)
def compare_qcd_control_regions(variable='MET', met_type='patType1CorrectedPFMet', title='Untitled', channel='electron'): ''' Compares the templates from the control regions in different bins of the current variable''' global fit_variable_properties, b_tag_bin, save_as, b_tag_bin_ctl variable_bins = variable_bins_ROOT[variable] histogram_template = get_histogram_template(variable) for fit_variable in electron_fit_variables: all_hists = {} inclusive_hist = None if '_bl' in fit_variable: b_tag_bin_ctl = '1orMoreBtag' else: b_tag_bin_ctl = '0orMoreBtag' save_path = 'plots/%dTeV/fit_variables/%s/%s/' % ( measurement_config.centre_of_mass_energy, variable, fit_variable) make_folder_if_not_exists(save_path + '/qcd/') max_bins = 3 for bin_range in variable_bins[0:max_bins]: params = { 'met_type': met_type, 'bin_range': bin_range, 'fit_variable': fit_variable, 'b_tag_bin': b_tag_bin, 'variable': variable } fit_variable_distribution = histogram_template % params qcd_fit_variable_distribution = fit_variable_distribution.replace( 'Ref selection', 'QCDConversions') qcd_fit_variable_distribution = qcd_fit_variable_distribution.replace( b_tag_bin, b_tag_bin_ctl) # format: histograms['data'][qcd_fit_variable_distribution] histograms = get_histograms_from_files( [qcd_fit_variable_distribution], histogram_files) prepare_histograms( histograms, rebin=fit_variable_properties[fit_variable]['rebin'], scale_factor=measurement_config.luminosity_scale) histograms_for_cleaning = { 'data': histograms['data'][qcd_fit_variable_distribution], 'V+Jets': histograms['V+Jets'][qcd_fit_variable_distribution], 'SingleTop': histograms['SingleTop'][qcd_fit_variable_distribution], 'TTJet': histograms['TTJet'][qcd_fit_variable_distribution] } qcd_from_data = clean_control_region( histograms_for_cleaning, subtract=['TTJet', 'V+Jets', 'SingleTop']) # clean all_hists[bin_range] = qcd_from_data # create the inclusive distributions inclusive_hist = deepcopy(all_hists[variable_bins[0]]) for bin_range in variable_bins[1:max_bins]: inclusive_hist += all_hists[bin_range] for bin_range in variable_bins[0:max_bins]: if not all_hists[bin_range].Integral() == 0: all_hists[bin_range].Scale(1 / all_hists[bin_range].Integral()) # normalise all histograms inclusive_hist.Scale(1 / inclusive_hist.Integral()) # now compare inclusive to all bins histogram_properties = Histogram_properties() histogram_properties.x_axis_title = fit_variable_properties[ fit_variable]['x-title'] histogram_properties.y_axis_title = fit_variable_properties[ fit_variable]['y-title'] histogram_properties.y_axis_title = histogram_properties.y_axis_title.replace( 'Events', 'a.u.') histogram_properties.x_limits = [ fit_variable_properties[fit_variable]['min'], fit_variable_properties[fit_variable]['max'] ] # histogram_properties.y_limits = [0, 0.5] histogram_properties.title = title histogram_properties.additional_text = channel_latex[ channel] + ', ' + b_tag_bins_latex[b_tag_bin_ctl] histogram_properties.name = variable + '_' + fit_variable + '_' + b_tag_bin_ctl + '_QCD_template_comparison' histogram_properties.y_max_scale = 1.5 measurements = { bin_range + ' GeV': histogram for bin_range, histogram in all_hists.iteritems() } measurements = OrderedDict(sorted(measurements.items())) compare_measurements(models={'inclusive': inclusive_hist}, measurements=measurements, show_measurement_errors=True, histogram_properties=histogram_properties, save_folder=save_path + '/qcd/', save_as=save_as)
def plot_fit_variable(histograms, fit_variable, variable, bin_range, fit_variable_distribution, qcd_fit_variable_distribution, title, save_path, channel='electron'): global fit_variable_properties, b_tag_bin, save_as, b_tag_bin_ctl histograms_ = deepcopy(histograms) mc_uncertainty = 0.10 prepare_histograms(histograms_, rebin=fit_variable_properties[fit_variable]['rebin'], scale_factor=measurement_config.luminosity_scale) ###################################### # plot the control regions as they are ###################################### histogram_properties = Histogram_properties() histogram_properties.x_axis_title = fit_variable_properties[fit_variable][ 'x-title'] histogram_properties.y_axis_title = fit_variable_properties[fit_variable][ 'y-title'] histogram_properties.x_limits = [ fit_variable_properties[fit_variable]['min'], fit_variable_properties[fit_variable]['max'] ] histogram_properties.y_max_scale = 2 histogram_lables = [ 'data', 'QCD', 'V+Jets', 'Single-Top', samples_latex['TTJet'] ] histogram_colors = ['black', 'yellow', 'green', 'magenta', 'red'] # qcd_from_data = histograms_['data'][qcd_fit_variable_distribution].Clone() # clean against other processes histograms_for_cleaning = { 'data': histograms_['data'][qcd_fit_variable_distribution], 'V+Jets': histograms_['V+Jets'][qcd_fit_variable_distribution], 'SingleTop': histograms_['SingleTop'][qcd_fit_variable_distribution], 'TTJet': histograms_['TTJet'][qcd_fit_variable_distribution] } qcd_from_data = clean_control_region( histograms_for_cleaning, subtract=['TTJet', 'V+Jets', 'SingleTop']) histograms_to_draw = [ histograms_['data'][qcd_fit_variable_distribution], histograms_['QCD'][qcd_fit_variable_distribution], histograms_['V+Jets'][qcd_fit_variable_distribution], histograms_['SingleTop'][qcd_fit_variable_distribution], histograms_['TTJet'][qcd_fit_variable_distribution] ] histogram_properties.title = title histogram_properties.additional_text = channel_latex[ channel] + ', ' + b_tag_bins_latex[b_tag_bin_ctl] histogram_properties.name = variable + '_' + bin_range + '_' + fit_variable + '_%s_QCDConversions' % b_tag_bin_ctl make_data_mc_comparison_plot( histograms_to_draw, histogram_lables, histogram_colors, histogram_properties, save_folder=save_path + '/qcd/', show_ratio=False, save_as=save_as, ) ###################################### # plot QCD against data control region with TTJet, SingleTop and V+Jets removed ###################################### histograms_to_draw = [ qcd_from_data, histograms_['QCD'][qcd_fit_variable_distribution], ] histogram_properties.y_max_scale = 1.5 histogram_properties.name = variable + '_' + bin_range + '_' + fit_variable + '_%s_QCDConversions_subtracted' % b_tag_bin_ctl make_data_mc_comparison_plot( histograms_to_draw, histogram_lables=['data', 'QCD'], histogram_colors=['black', 'yellow'], histogram_properties=histogram_properties, save_folder=save_path + '/qcd/', show_ratio=False, save_as=save_as, ) ###################################### # plot signal region ###################################### # scale QCD to predicted n_qcd_predicted_mc = histograms_['QCD'][ fit_variable_distribution].Integral() n_qcd_fit_variable_distribution = qcd_from_data.Integral() if not n_qcd_fit_variable_distribution == 0: qcd_from_data.Scale(1.0 / n_qcd_fit_variable_distribution * n_qcd_predicted_mc) histograms_to_draw = [ histograms_['data'][fit_variable_distribution], qcd_from_data, histograms_['V+Jets'][fit_variable_distribution], histograms_['SingleTop'][fit_variable_distribution], histograms_['TTJet'][fit_variable_distribution] ] histogram_properties.additional_text = channel_latex[ channel] + ', ' + b_tag_bins_latex[b_tag_bin] histogram_properties.name = variable + '_' + bin_range + '_' + fit_variable + '_' + b_tag_bin make_data_mc_comparison_plot( histograms_to_draw, histogram_lables, histogram_colors, histogram_properties, save_folder=save_path, show_ratio=False, save_as=save_as, ) ###################################### # plot templates ###################################### histogram_properties.mc_error = mc_uncertainty histogram_properties.mc_errors_label = '$\mathrm{t}\\bar{\mathrm{t}}$ uncertainty' histogram_properties.name = variable + '_' + bin_range + '_' + fit_variable + '_' + b_tag_bin + '_templates' histogram_properties.y_max_scale = 2 # change histogram order for better visibility histograms_to_draw = [ histograms_['TTJet'][fit_variable_distribution] + histograms_['SingleTop'][fit_variable_distribution], histograms_['TTJet'][fit_variable_distribution], histograms_['SingleTop'][fit_variable_distribution], histograms_['V+Jets'][fit_variable_distribution], qcd_from_data ] histogram_lables = [ 'QCD', 'V+Jets', 'Single-Top', samples_latex['TTJet'], samples_latex['TTJet'] + ' + ' + 'Single-Top' ] histogram_lables.reverse() # change QCD color to orange for better visibility histogram_colors = ['orange', 'green', 'magenta', 'red', 'black'] histogram_colors.reverse() # plot template make_shape_comparison_plot( shapes=histograms_to_draw, names=histogram_lables, colours=histogram_colors, histogram_properties=histogram_properties, fill_area=False, alpha=1, save_folder=save_path, save_as=save_as, )
def compare_qcd_control_regions( variable = 'MET', met_type = 'patType1CorrectedPFMet', title = 'Untitled', channel = 'electron' ): ''' Compares the templates from the control regions in different bins of the current variable''' global fit_variable_properties, b_tag_bin, save_as, b_tag_bin_ctl variable_bins = variable_bins_ROOT[variable] histogram_template = get_histogram_template( variable ) for fit_variable in electron_fit_variables: all_hists = {} inclusive_hist = None if '_bl' in fit_variable: b_tag_bin_ctl = '1orMoreBtag' else: b_tag_bin_ctl = '0orMoreBtag' save_path = 'plots/%dTeV/fit_variables/%s/%s/' % ( measurement_config.centre_of_mass_energy, variable, fit_variable ) make_folder_if_not_exists( save_path + '/qcd/' ) max_bins = 3 for bin_range in variable_bins[0:max_bins]: params = {'met_type': met_type, 'bin_range':bin_range, 'fit_variable':fit_variable, 'b_tag_bin':b_tag_bin, 'variable':variable} fit_variable_distribution = histogram_template % params qcd_fit_variable_distribution = fit_variable_distribution.replace( 'Ref selection', 'QCDConversions' ) qcd_fit_variable_distribution = qcd_fit_variable_distribution.replace( b_tag_bin, b_tag_bin_ctl ) # format: histograms['data'][qcd_fit_variable_distribution] histograms = get_histograms_from_files( [qcd_fit_variable_distribution], histogram_files ) prepare_histograms( histograms, rebin = fit_variable_properties[fit_variable]['rebin'], scale_factor = measurement_config.luminosity_scale ) histograms_for_cleaning = {'data':histograms['data'][qcd_fit_variable_distribution], 'V+Jets':histograms['V+Jets'][qcd_fit_variable_distribution], 'SingleTop':histograms['SingleTop'][qcd_fit_variable_distribution], 'TTJet':histograms['TTJet'][qcd_fit_variable_distribution]} qcd_from_data = clean_control_region( histograms_for_cleaning, subtract = ['TTJet', 'V+Jets', 'SingleTop'] ) # clean all_hists[bin_range] = qcd_from_data # create the inclusive distributions inclusive_hist = deepcopy( all_hists[variable_bins[0]] ) for bin_range in variable_bins[1:max_bins]: inclusive_hist += all_hists[bin_range] for bin_range in variable_bins[0:max_bins]: if not all_hists[bin_range].Integral() == 0: all_hists[bin_range].Scale( 1 / all_hists[bin_range].Integral() ) # normalise all histograms inclusive_hist.Scale( 1 / inclusive_hist.Integral() ) # now compare inclusive to all bins histogram_properties = Histogram_properties() histogram_properties.x_axis_title = fit_variable_properties[fit_variable]['x-title'] histogram_properties.y_axis_title = fit_variable_properties[fit_variable]['y-title'] histogram_properties.y_axis_title = histogram_properties.y_axis_title.replace( 'Events', 'a.u.' ) histogram_properties.x_limits = [fit_variable_properties[fit_variable]['min'], fit_variable_properties[fit_variable]['max']] # histogram_properties.y_limits = [0, 0.5] histogram_properties.title = title histogram_properties.additional_text = channel_latex[channel] + ', ' + b_tag_bins_latex[b_tag_bin_ctl] histogram_properties.name = variable + '_' + fit_variable + '_' + b_tag_bin_ctl + '_QCD_template_comparison' histogram_properties.y_max_scale = 1.5 measurements = {bin_range + ' GeV': histogram for bin_range, histogram in all_hists.iteritems()} measurements = OrderedDict( sorted( measurements.items() ) ) compare_measurements( models = {'inclusive' : inclusive_hist}, measurements = measurements, show_measurement_errors = True, histogram_properties = histogram_properties, save_folder = save_path + '/qcd/', save_as = save_as )
def plot_fit_variable( histograms, fit_variable, variable, bin_range, fit_variable_distribution, qcd_fit_variable_distribution, title, save_path, channel = 'electron' ): global fit_variable_properties, b_tag_bin, save_as, b_tag_bin_ctl histograms_ = deepcopy( histograms ) mc_uncertainty = 0.10 prepare_histograms( histograms_, rebin = fit_variable_properties[fit_variable]['rebin'], scale_factor = measurement_config.luminosity_scale ) ###################################### # plot the control regions as they are ###################################### histogram_properties = Histogram_properties() histogram_properties.x_axis_title = fit_variable_properties[fit_variable]['x-title'] histogram_properties.y_axis_title = fit_variable_properties[fit_variable]['y-title'] histogram_properties.x_limits = [fit_variable_properties[fit_variable]['min'], fit_variable_properties[fit_variable]['max']] histogram_properties.y_max_scale = 2 histogram_lables = ['data', 'QCD', 'V+Jets', 'Single-Top', samples_latex['TTJet']] histogram_colors = ['black', 'yellow', 'green', 'magenta', 'red'] # qcd_from_data = histograms_['data'][qcd_fit_variable_distribution].Clone() # clean against other processes histograms_for_cleaning = {'data':histograms_['data'][qcd_fit_variable_distribution], 'V+Jets':histograms_['V+Jets'][qcd_fit_variable_distribution], 'SingleTop':histograms_['SingleTop'][qcd_fit_variable_distribution], 'TTJet':histograms_['TTJet'][qcd_fit_variable_distribution]} qcd_from_data = clean_control_region( histograms_for_cleaning, subtract = ['TTJet', 'V+Jets', 'SingleTop'] ) histograms_to_draw = [histograms_['data'][qcd_fit_variable_distribution], histograms_['QCD'][qcd_fit_variable_distribution], histograms_['V+Jets'][qcd_fit_variable_distribution], histograms_['SingleTop'][qcd_fit_variable_distribution], histograms_['TTJet'][qcd_fit_variable_distribution]] histogram_properties.title = title histogram_properties.additional_text = channel_latex[channel] + ', ' + b_tag_bins_latex[b_tag_bin_ctl] histogram_properties.name = variable + '_' + bin_range + '_' + fit_variable + '_%s_QCDConversions' % b_tag_bin_ctl make_data_mc_comparison_plot( histograms_to_draw, histogram_lables, histogram_colors, histogram_properties, save_folder = save_path + '/qcd/', show_ratio = False, save_as = save_as, ) ###################################### # plot QCD against data control region with TTJet, SingleTop and V+Jets removed ###################################### histograms_to_draw = [qcd_from_data, histograms_['QCD'][qcd_fit_variable_distribution], ] histogram_properties.y_max_scale = 1.5 histogram_properties.name = variable + '_' + bin_range + '_' + fit_variable + '_%s_QCDConversions_subtracted' % b_tag_bin_ctl make_data_mc_comparison_plot( histograms_to_draw, histogram_lables = ['data', 'QCD'], histogram_colors = ['black', 'yellow'], histogram_properties = histogram_properties, save_folder = save_path + '/qcd/', show_ratio = False, save_as = save_as, ) ###################################### # plot signal region ###################################### # scale QCD to predicted n_qcd_predicted_mc = histograms_['QCD'][fit_variable_distribution].Integral() n_qcd_fit_variable_distribution = qcd_from_data.Integral() if not n_qcd_fit_variable_distribution == 0: qcd_from_data.Scale( 1.0 / n_qcd_fit_variable_distribution * n_qcd_predicted_mc ) histograms_to_draw = [histograms_['data'][fit_variable_distribution], qcd_from_data, histograms_['V+Jets'][fit_variable_distribution], histograms_['SingleTop'][fit_variable_distribution], histograms_['TTJet'][fit_variable_distribution]] histogram_properties.additional_text = channel_latex[channel] + ', ' + b_tag_bins_latex[b_tag_bin] histogram_properties.name = variable + '_' + bin_range + '_' + fit_variable + '_' + b_tag_bin make_data_mc_comparison_plot( histograms_to_draw, histogram_lables, histogram_colors, histogram_properties, save_folder = save_path, show_ratio = False, save_as = save_as, ) ###################################### # plot templates ###################################### histogram_properties.mc_error = mc_uncertainty histogram_properties.mc_errors_label = '$\mathrm{t}\\bar{\mathrm{t}}$ uncertainty' histogram_properties.name = variable + '_' + bin_range + '_' + fit_variable + '_' + b_tag_bin + '_templates' histogram_properties.y_max_scale = 2 # change histogram order for better visibility histograms_to_draw = [histograms_['TTJet'][fit_variable_distribution] + histograms_['SingleTop'][fit_variable_distribution], histograms_['TTJet'][fit_variable_distribution], histograms_['SingleTop'][fit_variable_distribution], histograms_['V+Jets'][fit_variable_distribution], qcd_from_data] histogram_lables = ['QCD', 'V+Jets', 'Single-Top', samples_latex['TTJet'], samples_latex['TTJet'] + ' + ' + 'Single-Top'] histogram_lables.reverse() # change QCD color to orange for better visibility histogram_colors = ['orange', 'green', 'magenta', 'red', 'black'] histogram_colors.reverse() # plot template make_shape_comparison_plot( shapes = histograms_to_draw, names = histogram_lables, colours = histogram_colors, histogram_properties = histogram_properties, fill_area = False, alpha = 1, save_folder = save_path, save_as = save_as, )
def background_subtraction(self, histograms): ttjet_hist = clean_control_region( histograms, subtract=['QCD', 'V+Jets', 'SingleTop']) self.normalisation['TTJet'] = hist_to_value_error_tuplelist(ttjet_hist)