def run(self, plotData=None): super(EstimateWjets, self).run(plotData) for wjets_from_mc, wjets_shape_nick, wjets_data_control_nick, wjets_data_substract_nicks, wjets_mc_signal_nick, wjets_mc_control_nick in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): if not wjets_from_mc: yield_data_control = tools.PoissonYield( plotData.plotdict["root_objects"] [wjets_data_control_nick])() for nick in wjets_data_substract_nicks: yield_bkg_control = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() if nick in plotData.metadata: yield_bkg_control = uncertainties.ufloat( plotData.metadata[nick].get( "yield", yield_bkg_control.nominal_value), plotData.metadata[nick].get( "yield_unc", yield_bkg_control.std_dev)) yield_data_control -= yield_bkg_control yield_data_control = max(0.0, yield_data_control) yield_mc_signal = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_mc_signal_nick])() yield_mc_control = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_mc_control_nick])() assert (yield_data_control * yield_mc_signal == 0.0) or (yield_mc_control != 0.0) final_yield = yield_data_control * yield_mc_signal if final_yield != 0.0: final_yield /= yield_mc_control log.debug( "Relative statistical uncertainty of the yield for process W+jets (nick \"{nick}\") is {unc}." .format(nick=wjets_shape_nick, unc=final_yield.std_dev / final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0)) plotData.metadata[wjets_shape_nick] = { "yield": final_yield.nominal_value, "yield_unc": final_yield.std_dev, "yield_unc_rel": abs(final_yield.std_dev / final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0), } integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_shape_nick])() if integral_shape != 0.0: scale_factor = final_yield / integral_shape log.debug( "Scale factor for process W+jets (nick \"{nick}\") is {scale_factor}." .format(nick=wjets_shape_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][wjets_shape_nick].Scale( scale_factor.nominal_value)
def run(self, plotData=None): super(EstimateTtbar, self).run(plotData) for ttbar_shape_nick, ttbar_data_control_nick, ttbar_data_subtract_nicks, ttbar_mc_signal_nick, ttbar_mc_control_nick in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): yield_data_control = tools.PoissonYield( plotData.plotdict["root_objects"][ttbar_data_control_nick])() #print "data_control_yield from nick " + ttbar_data_control_nick + " : " + str(yield_data_control) for nick in ttbar_data_subtract_nicks: yield_bkg_control = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() #print "\t minus " + nick + " : " + str(yield_bkg_control) if nick in plotData.metadata: yield_bkg_control = uncertainties.ufloat( plotData.metadata[nick].get( "yield", yield_bkg_control.nominal_value), plotData.metadata[nick].get("yield_unc", yield_bkg_control.std_dev)) yield_data_control -= yield_bkg_control #print "data_control_yield final " + str(yield_data_control) yield_data_control = max(0.0, yield_data_control) yield_mc_signal = tools.PoissonYield( plotData.plotdict["root_objects"][ttbar_mc_signal_nick])() yield_mc_control = tools.PoissonYield( plotData.plotdict["root_objects"][ttbar_mc_control_nick])() #print "data_mc_signal " + str(yield_mc_signal) #print "data_mc_control " + str(yield_mc_control) integral_shape = plotData.plotdict["root_objects"][ ttbar_shape_nick].Integral() final_yield = yield_mc_control / yield_data_control * integral_shape log.debug( "Relative statistical uncertainty of the yield for process ttbar+jets (nick \"{nick}\") is {unc}." .format(nick=ttbar_shape_nick, unc=final_yield.std_dev / final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0)) plotData.metadata[ttbar_shape_nick] = { "yield": final_yield.nominal_value, "yield_unc": final_yield.std_dev, "yield_unc_rel": abs(final_yield.std_dev / final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0), } if integral_shape != 0.0: scale_factor = integral_shape / final_yield #print "scale factor: " + str(scale_factor) log.debug( "Scale factor for process ttbar+jets (nick \"{nick}\") is {scale_factor}." .format(nick=ttbar_shape_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][ttbar_shape_nick].Scale( scale_factor.nominal_value)
def run(self, plotData=None): super(EstimateQcdTauHadTauHad, self).run(plotData) for qcd_data_shape_nick, qcd_data_signal_control_nick, qcd_data_relaxed_control_nick, qcd_data_subtract_nicks, qcd_control_signal_subtract_nicks, qcd_control_relaxed_subtract_nicks in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): for nick in qcd_data_subtract_nicks: plotData.plotdict["root_objects"][qcd_data_shape_nick].Add( plotData.plotdict["root_objects"][nick], -1.0) yield_control_signal = tools.PoissonYield( plotData.plotdict["root_objects"] [qcd_data_signal_control_nick])() for nick in qcd_control_signal_subtract_nicks: yield_bgk_control = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() yield_control_signal -= yield_bgk_control yield_control_signal = max(0.0, yield_control_signal) yield_control_relaxed = tools.PoissonYield( plotData.plotdict["root_objects"] [qcd_data_relaxed_control_nick])() for nick in qcd_control_relaxed_subtract_nicks: yield_bgk_control = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() yield_control_relaxed -= yield_bgk_control yield_control_relaxed = max(0.0, yield_control_relaxed) scale_factor = yield_control_signal if yield_control_relaxed != 0.0: scale_factor /= yield_control_relaxed log.debug( "Scale factor for process QCD (nick \"{nick}\") is {scale_factor}." .format(nick=qcd_data_shape_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][qcd_data_shape_nick].Scale( scale_factor.nominal_value) final_yield = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_data_shape_nick])() log.debug( "Relative statistical uncertainty of the yield for process QCD (nick \"{nick}\") is {unc}." .format(nick=qcd_data_shape_nick, unc=final_yield.std_dev / final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0)) plotData.metadata[qcd_data_shape_nick] = { "yield": final_yield.nominal_value, "yield_unc": final_yield.std_dev, "yield_unc_rel": abs(final_yield.std_dev / final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0), }
def prepare_args(self, parser, plotData): super(CalculateWJetsOSSSFactor, self).prepare_args(parser, plotData) self._plotdict_keys = [ "wjets_from_mc_os_nicks", "wjets_from_mc_ss_nicks" ] self.prepare_list_args(plotData, self._plotdict_keys) def run(self, plotData=None): super(CalculateWJetsOSSSFactor, self).run(plotData) # make sure that all necessary histograms are available for nicks in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): for nick in nicks: if isinstance(nick, basestring): assert isinstance( plotData.plotdict["root_objects"].get(nick), ROOT.TH1) elif not isinstance(nick, bool): for subnick in nick: assert isinstance( plotData.plotdict["root_objects"].get(subnick), ROOT.TH1) for wjets_from_mc_os_nicks, wjets_from_mc_ss_nicks in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): yield_wj_mc_os = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_from_mc_os_nicks])() yield_wj_mc_ss = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_from_mc_ss_nicks])() # make sure we don't have negative yields yield_wj_mc_os = uncertainties.ufloat( max(0.0, yield_wj_mc_os.nominal_value), yield_wj_mc_os.std_dev) yield_wj_mc_ss = uncertainties.ufloat( max(0.0, yield_wj_mc_ss.nominal_value), yield_wj_mc_ss.std_dev) print(yield_wj_mc_os, yield_wj_mc_ss) assert (yield_wj_mc_os != 0.0) or (yield_wj_mc_ss != 0.0) # the final yield in the signal region is N_data, WJ^{SR} = N_data, WJ^{CR} * N_MC,WJ^{SR} / N_MC,WJ^{CR} os_ss_factor = yield_wj_mc_os / yield_wj_mc_ss plotData.metadata[wjets_from_mc_os_nicks] = { "os_ss_factor": os_ss_factor.nominal_value, "os_ss_factor_unc": os_ss_factor.std_dev, "yield_unc_rel": abs(os_ss_factor.std_dev / os_ss_factor.nominal_value if os_ss_factor.nominal_value != 0.0 else 0.0), } plotData.metadata print(plotData.metadata)
def run(self, plotData=None): super(EstimateQcd, self).run(plotData) for qcd_shape_nick, qcd_yield_nick, qcd_yield_subtract_nicks, qcd_shape_subtract_nicks, qcd_extrapolation_factor_ss_os in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): yield_qcd = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_yield_nick])() # estimate the QCD yield # print "yield qcd total: " + str(yield_qcd) for nick in qcd_yield_subtract_nicks: yield_bkg = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() #print "minus " + nick + " " + str(yield_bkg) yield_qcd -= yield_bkg yield_qcd = max(0.0, yield_qcd) if (yield_qcd == 0.0): log.warning("QCD yield is 0!") # QCD shape #print "shape total: " + str(tools.PoissonYield(plotData.plotdict["root_objects"][qcd_shape_nick])()) for nick in qcd_shape_subtract_nicks: #print "\t minus " + nick + " " + str(tools.PoissonYield(plotData.plotdict["root_objects"][nick])()) plotData.plotdict["root_objects"][qcd_shape_nick].Add( plotData.plotdict["root_objects"][nick], -1.0 / plotData.plotdict["qcd_scale_factor"]) shape_yield = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_shape_nick])() if shape_yield != 0.0: scale_factor = yield_qcd / shape_yield * qcd_extrapolation_factor_ss_os final_yield_qcd = yield_qcd * qcd_extrapolation_factor_ss_os #log.debug("Relative statistical uncertainty of the yield for process QCD (nick \"{nick}\") is {unc}.".format(nick=qcd_data_shape_nick, unc=final_yield.std_dev/final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0)) plotData.plotdict["root_objects"][qcd_shape_nick].Scale( scale_factor.nominal_value) #print "QCD em estimation summary" #print "scale factor : " + str(scale_factor) #print "shape_yield :" + str(shape_yield) #print "yield_qcd :" + str(yield_qcd) # save to be picked up plotData.metadata[qcd_shape_nick] = { "yield": final_yield_qcd.nominal_value, "yield_unc": final_yield_qcd.std_dev, "yield_unc_rel": abs(final_yield_qcd.std_dev / final_yield_qcd.nominal_value if final_yield_qcd.nominal_value != 0.0 else 0.0), }
def run(self, plotData=None): super(EstimateFF, self).run(plotData) for (ff_data_nick, ff_mc_subtract_nicks, ff_norm_data_nick, ff_norm_mc_subtract_nicks) in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): for nick in ff_mc_subtract_nicks: plotData.plotdict["root_objects"][ff_data_nick].Add( plotData.plotdict["root_objects"][nick], -1.0) for nick in ff_norm_mc_subtract_nicks: plotData.plotdict["root_objects"][ff_norm_data_nick].Add( plotData.plotdict["root_objects"][nick], -1.0) ff_yield = tools.PoissonYield( plotData.plotdict["root_objects"][ff_data_nick])() ff_norm_yield = tools.PoissonYield( plotData.plotdict["root_objects"][ff_norm_data_nick])() if ff_yield != 0.0: scale_factor = ff_norm_yield / ff_yield plotData.plotdict["root_objects"][ff_data_nick].Scale( scale_factor.nominal_value)
def run(self, plotData=None): super(EstimateFF, self).run(plotData) # make sure that all necessary histograms are available for nicks in zip(*[plotData.plotdict[key] for key in self._plotdict_keys]): for nick in nicks: if isinstance(nick, basestring): assert isinstance(plotData.plotdict["root_objects"].get(nick), ROOT.TH1) elif (not isinstance(nick, float) and not isinstance(nick, bool)): for subnick in nick: assert isinstance(plotData.plotdict["root_objects"].get(subnick), ROOT.TH1) for (ff_data_nick, ff_mc_subtract_nicks, ff_norm_data_nick, ff_norm_mc_subtract_nicks) in zip(*[plotData.plotdict[key] for key in self._plotdict_keys]): for nick in ff_mc_subtract_nicks: plotData.plotdict["root_objects"][ff_data_nick].Add(plotData.plotdict["root_objects"][nick], -1.0) for nick in ff_norm_mc_subtract_nicks: plotData.plotdict["root_objects"][ff_norm_data_nick].Add(plotData.plotdict["root_objects"][nick], -1.0) ff_yield = tools.PoissonYield(plotData.plotdict["root_objects"][ff_data_nick])() ff_norm_yield = tools.PoissonYield(plotData.plotdict["root_objects"][ff_norm_data_nick])() if ff_yield != 0.0: scale_factor = ff_norm_yield/ff_yield plotData.plotdict["root_objects"][ff_data_nick].Scale(scale_factor.nominal_value)
def run(self, plotData=None): super(EstimateQcdTauHadTauHad, self).run(plotData) # make sure that all necessary histograms are available for nicks in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): for nick in nicks: if isinstance(nick, basestring): assert isinstance( plotData.plotdict["root_objects"].get(nick), ROOT.TH1) elif (not isinstance(nick, float) and not isinstance(nick, bool)): for subnick in nick: assert isinstance( plotData.plotdict["root_objects"].get(subnick), ROOT.TH1) for qcd_data_shape_nick, qcd_data_signal_control_nick, qcd_data_relaxed_control_nick, qcd_data_subtract_nicks, qcd_control_signal_subtract_nicks, qcd_control_relaxed_subtract_nicks in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): for nick in qcd_data_subtract_nicks: plotData.plotdict["root_objects"][qcd_data_shape_nick].Add( plotData.plotdict["root_objects"][nick], -1.0) yield_control_signal = tools.PoissonYield( plotData.plotdict["root_objects"] [qcd_data_signal_control_nick])() for nick in qcd_control_signal_subtract_nicks: yield_bgk_control = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() yield_control_signal -= yield_bgk_control yield_control_signal = uncertainties.ufloat( max(0.0, yield_control_signal.nominal_value), yield_control_signal.std_dev) yield_control_relaxed = tools.PoissonYield( plotData.plotdict["root_objects"] [qcd_data_relaxed_control_nick])() for nick in qcd_control_relaxed_subtract_nicks: yield_bgk_control = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() yield_control_relaxed -= yield_bgk_control yield_control_relaxed = uncertainties.ufloat( max(0.0, yield_control_relaxed.nominal_value), yield_control_relaxed.std_dev) scale_factor = yield_control_signal if yield_control_relaxed != 0.0: scale_factor /= yield_control_relaxed log.debug( "Scale factor for process QCD (nick \"{nick}\") is {scale_factor}." .format(nick=qcd_data_shape_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][qcd_data_shape_nick].Scale( scale_factor.nominal_value) final_yield = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_data_shape_nick])() log.debug( "Relative statistical uncertainty of the yield for process QCD (nick \"{nick}\") is {unc}." .format(nick=qcd_data_shape_nick, unc=final_yield.std_dev / final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0)) plotData.metadata[qcd_data_shape_nick] = { "yield": final_yield.nominal_value, "yield_unc": final_yield.std_dev, "yield_unc_rel": abs(final_yield.std_dev / final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0), }
def run(self, plotData=None): super(EstimateQcdPrefit, self).run(plotData) # make sure that all necessary histograms are available for nicks in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): for nick in nicks: if isinstance(nick, basestring): assert isinstance( plotData.plotdict["root_objects"].get(nick), ROOT.TH1) elif (not isinstance(nick, float) and not isinstance(nick, bool)): for subnick in nick: assert isinstance( plotData.plotdict["root_objects"].get(subnick), ROOT.TH1) for qcd_shape_nick, qcd_yield_nick, qcd_yield_subtract_nicks, qcd_shape_subtract_nicks, qcd_extrapolation_factor_ss_os in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): ###################### # ------- Step 1 ----- # 1. Get Yield in Control region and subtract all backgrounds. yield_qcd = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_yield_nick])() # estimate the QCD yield for nick in qcd_yield_subtract_nicks: yield_bkg = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() yield_qcd -= yield_bkg yield_qcd = uncertainties.ufloat(max(0.0, yield_qcd.nominal_value), yield_qcd.std_dev) if (yield_qcd.nominal_value == 0.0): log.warning("QCD yield is 0!") ###################### # ------- Step 2 ----- # QCD shape # 1. Subtract the shapes of all backgrounds from data in the control region. # 2. Scale the qcd by the qcd_os_ss_extrapolation_factor to get the prefit estimate. # Sidemark: In this script the factor is supposed to be 1.0 because we want to determine the # factor with this first estimate. for nick in qcd_shape_subtract_nicks: plotData.plotdict["root_objects"][qcd_shape_nick].Add( plotData.plotdict["root_objects"][nick], -1.0 / plotData.plotdict["qcd_scale_factor"]) shape_yield = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_shape_nick])() if shape_yield != 0.0: qcd_extrapolation_factor_ss_os = 1.0 scale_factor = yield_qcd / shape_yield * qcd_extrapolation_factor_ss_os plotData.plotdict["root_objects"][qcd_shape_nick].Scale( scale_factor.nominal_value) #log.debug("Relative statistical uncertainty of the yield for process QCD (nick \"{nick}\") is {unc}.".format(nick=qcd_data_shape_nick, unc=final_yield.std_dev/final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0)) final_yield_qcd = yield_qcd * qcd_extrapolation_factor_ss_os # save to be picked up plotData.metadata[qcd_shape_nick] = { "yield": final_yield_qcd.nominal_value, "yield_unc": final_yield_qcd.std_dev, "yield_unc_rel": abs(final_yield_qcd.std_dev / final_yield_qcd.nominal_value if final_yield_qcd.nominal_value != 0.0 else 0.0), }
def run(self, plotData=None): super(EstimateWjetsAndQCD, self).run(plotData) for qcd_extrapolation_factor_ss_os, qcd_shape_nick, qcd_ss_lowmt_nick, qcd_ss_highmt_shape_nick, qcd_os_highmt_nick, qcd_shape_highmt_substract_nick, qcd_yield_nick, qcd_shape_substract_nick, qcd_yield_substract_nick, wjets_os_highmt_mc_nick, wjets_ss_highmt_mc_nick, wjets_ss_substract_nick, wjets_ss_data_nick, wjets_os_substract_nick, wjets_os_data_nick, wjets_shape_nick, wjets_relaxed_os_highmt_nick, wjets_relaxed_os_lowmt_nick, wjets_scale_factor_shift, wjets_final_selection in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): ######################################## # estimate QCD for the highmT region # get qcd ss high mt shape for nick in qcd_shape_highmt_substract_nick + [ wjets_ss_highmt_mc_nick ]: plotData.plotdict["root_objects"][ qcd_ss_highmt_shape_nick].Add( plotData.plotdict["root_objects"][nick], -1) # get qcd yield in ss high mt region yield_qcd_ss_highmt = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_ss_data_nick])() for nick in wjets_ss_substract_nick + [wjets_ss_highmt_mc_nick]: yield_qcd_ss_highmt -= tools.PoissonYield( plotData.plotdict["root_objects"][nick])() yield_qcd_ss_highmt = max( uncertainties.ufloat(0.0, yield_qcd_ss_highmt.std_dev), yield_qcd_ss_highmt) # scale qcd ss high mt shape by qcd yield found in data integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_ss_highmt_shape_nick])() if integral_shape != 0.0: scale_factor = yield_qcd_ss_highmt / integral_shape plotData.plotdict["root_objects"][ qcd_ss_highmt_shape_nick].Scale(scale_factor.nominal_value) # scale qcd os high mt shape by qcd yield found in ss data and ss->os extrapolation factor integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_os_highmt_nick])() if integral_shape != 0.0: scale_factor = yield_qcd_ss_highmt * qcd_extrapolation_factor_ss_os / integral_shape plotData.plotdict["root_objects"][qcd_os_highmt_nick].Scale( scale_factor.nominal_value) ######################################## # estimate W+jets # get w+jets yield in os high mt region yield_wjets_os_highmt = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_os_data_nick])() for nick in wjets_os_substract_nick: yield_wjets_os_highmt -= tools.PoissonYield( plotData.plotdict["root_objects"][nick])() yield_wjets_os_highmt -= qcd_extrapolation_factor_ss_os * yield_qcd_ss_highmt yield_wjets_os_highmt = max( uncertainties.ufloat(0.0, yield_wjets_os_highmt.std_dev), yield_wjets_os_highmt) if yield_wjets_os_highmt.nominal_value == 0.0: log.warning( "W+jets & QCD estimation: data yield in high mT region after background subtraction is 0!" ) # get high mt -> low mt extrapolation factor from MC if tools.PoissonYield(plotData.plotdict["root_objects"] [wjets_relaxed_os_highmt_nick])() != 0.0: wjets_extrapolation_factor_mt = tools.PoissonYield( plotData.plotdict["root_objects"] [wjets_relaxed_os_lowmt_nick])() / tools.PoissonYield( plotData.plotdict["root_objects"] [wjets_relaxed_os_highmt_nick])() else: log.warning( "W+jets & QCD estimation: W+jets high mT region in MC has no entries. High->low mT extrapolation factor is set to 1.0!" ) wjets_extrapolation_factor_mt = 1.0 # get w+jets yield in low mt region wjets_yield = yield_wjets_os_highmt * wjets_extrapolation_factor_mt # extrapolate to final selection if wjets_final_selection != None: wjets_yield = wjets_yield * tools.PoissonYield( plotData.plotdict["root_objects"][wjets_final_selection])( ) / tools.PoissonYield(plotData.plotdict["root_objects"] [wjets_relaxed_os_lowmt_nick])() # scale signal region histograms integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_shape_nick])() if integral_shape != 0.0: scale_factor = wjets_yield / integral_shape log.debug( "Scale factor for process W+jets (nick \"{nick}\") is {scale_factor}." .format(nick=wjets_shape_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][wjets_shape_nick].Scale( scale_factor.nominal_value) plotData.metadata[wjets_shape_nick] = { "yield": wjets_yield.nominal_value, "yield_unc": wjets_yield.std_dev, "yield_unc_rel": abs(wjets_yield.std_dev / wjets_yield.nominal_value if wjets_yield.nominal_value != 0.0 else 0.0), } ######################################## # estimate QCD for the lowmT # define w+jets scale factor for qcd estimation if tools.PoissonYield(plotData.plotdict["root_objects"] [wjets_os_highmt_mc_nick])() != 0.0: wjets_scale_factor = yield_wjets_os_highmt / tools.PoissonYield( plotData.plotdict["root_objects"] [wjets_os_highmt_mc_nick])() else: log.warning( "W+jets & QCD estimation: W+jets high mT region in MC has no entries. Scale factor for W+jets in QCD estimation is set to 1.0!" ) wjets_scale_factor = uncertainties.ufloat(1.0, 0.0) for nick in qcd_shape_substract_nick: if "wj" in nick: scale_factor = wjets_scale_factor * wjets_scale_factor_shift plotData.plotdict["root_objects"][nick].Scale( scale_factor.nominal_value) plotData.plotdict["root_objects"][qcd_shape_nick].Add( plotData.plotdict["root_objects"][nick], -1) yield_qcd_ss_lowmt = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_yield_nick])() for nick in qcd_yield_substract_nick: if "wj" in nick and tools.PoissonYield( plotData.plotdict["root_objects"][nick])() != 0.0: scale_factor = wjets_scale_factor * wjets_scale_factor_shift plotData.plotdict["root_objects"][nick].Scale( scale_factor.nominal_value) yield_qcd_ss_lowmt -= tools.PoissonYield( plotData.plotdict["root_objects"][nick])() yield_qcd_ss_lowmt = max( uncertainties.ufloat(0.0, yield_qcd_ss_lowmt.std_dev), yield_qcd_ss_lowmt) if yield_qcd_ss_lowmt.nominal_value == 0.0: log.warning( "W+jets & QCD estimation: data yield in low mT SS region after background subtraction is 0!" ) # get qcd yield in low mt region qcd_yield = yield_qcd_ss_lowmt * qcd_extrapolation_factor_ss_os integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_shape_nick])() if integral_shape != 0.0: scale_factor = qcd_yield / integral_shape plotData.plotdict["root_objects"][qcd_shape_nick].Scale( scale_factor.nominal_value) integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_ss_lowmt_nick])() if integral_shape != 0.0: scale_factor = yield_qcd_ss_lowmt / integral_shape plotData.plotdict["root_objects"][qcd_ss_lowmt_nick].Scale( scale_factor.nominal_value) # write relative uncertainties to metadata to pick them up with combine plotData.metadata[qcd_shape_nick] = { "yield": qcd_yield.nominal_value, "yield_unc": qcd_yield.std_dev, "yield_unc_rel": abs(qcd_yield.std_dev / qcd_yield.nominal_value if qcd_yield.nominal_value != 0.0 else 0.0), }
def run(self, plotData=None): super(EstimateWjetsAndQCD, self).run(plotData) for qcd_extrapolation_factor_ss_os, qcd_shape_nick, qcd_ss_lowmt_nick, qcd_ss_highmt_shape_nick, qcd_os_highmt_nick, qcd_shape_highmt_substract_nick, qcd_yield_nick, qcd_shape_substract_nick, qcd_yield_substract_nick, wjets_ss_mc_nick, wjets_os_mc_nick, wjets_os_highmt_mc_nick, wjets_os_lowmt_mc_nick, wjets_ss_highmt_mc_nick, wjets_ss_substract_nick, wjets_ss_data_nick, wjets_os_substract_nick, wjets_os_data_nick, wjets_shape_nick, wjets_final_selection in zip(*[plotData.plotdict[key] for key in self._plotdict_keys]): # estimate QCD for the lowmT for nick in qcd_shape_substract_nick: plotData.plotdict["root_objects"][qcd_shape_nick].Add(plotData.plotdict["root_objects"][nick], -1) yield_qcd_control = tools.PoissonYield(plotData.plotdict["root_objects"][qcd_yield_nick])() for nick in qcd_yield_substract_nick: yield_bkg_control = tools.PoissonYield(plotData.plotdict["root_objects"][nick])() if nick in plotData.metadata: yield_bkg_control = uncertainties.ufloat( plotData.metadata[nick].get("yield", yield_bkg_control.nominal_value), plotData.metadata[nick].get("yield_unc", yield_bkg_control.std_dev) ) yield_qcd_control -= yield_bkg_control yield_qcd_control = max(0.0, yield_qcd_control) integral_shape = tools.PoissonYield(plotData.plotdict["root_objects"][qcd_shape_nick])() if integral_shape != 0.0: scale_factor = yield_qcd_control * qcd_extrapolation_factor_ss_os / integral_shape final_qcd_yield = yield_qcd_control * qcd_extrapolation_factor_ss_os plotData.plotdict["root_objects"][qcd_shape_nick].Scale(scale_factor.nominal_value) integral_shape = tools.PoissonYield(plotData.plotdict["root_objects"][qcd_ss_lowmt_nick])() if integral_shape != 0.0: scale_factor = yield_qcd_control / integral_shape plotData.plotdict["root_objects"][qcd_ss_lowmt_nick].Scale(scale_factor.nominal_value) # write relative uncertainties to metadata to pick them up with combine plotData.metadata[qcd_shape_nick] = { "yield" : final_qcd_yield.nominal_value, "yield_unc" : final_qcd_yield.std_dev, "yield_unc_rel" : abs(final_qcd_yield.std_dev/final_qcd_yield.nominal_value if final_qcd_yield.nominal_value != 0.0 else 0.0), } # estimate W+jets yield_ss_control = tools.PoissonYield(plotData.plotdict["root_objects"][wjets_ss_data_nick])() for nick in wjets_ss_substract_nick: yield_bkg_control = tools.PoissonYield(plotData.plotdict["root_objects"][nick])() yield_ss_control -= yield_bkg_control yield_os_control = tools.PoissonYield(plotData.plotdict["root_objects"][wjets_os_data_nick])() for nick in wjets_os_substract_nick: yield_bkg_control = tools.PoissonYield(plotData.plotdict["root_objects"][nick])() yield_os_control -= yield_bkg_control wjets_extrapolation_factor_ss_os = tools.PoissonYield(plotData.plotdict["root_objects"][wjets_os_mc_nick])()/tools.PoissonYield(plotData.plotdict["root_objects"][wjets_ss_mc_nick])() wjets_extrapolation_factor_mt = tools.PoissonYield(plotData.plotdict["root_objects"][wjets_os_lowmt_mc_nick])()/tools.PoissonYield(plotData.plotdict["root_objects"][wjets_os_highmt_mc_nick])() wjets_yield = (yield_os_control-qcd_extrapolation_factor_ss_os*yield_ss_control)*wjets_extrapolation_factor_ss_os/(wjets_extrapolation_factor_ss_os-qcd_extrapolation_factor_ss_os)*wjets_extrapolation_factor_mt # extrapolate to final selection if wjets_final_selection != None: wjets_yield = wjets_yield * tools.PoissonYield(plotData.plotdict["root_objects"][wjets_final_selection])() / tools.PoissonYield(plotData.plotdict["root_objects"][wjets_os_lowmt_mc_nick])() #print "scale factor inclusive to categorized" #print str(tools.PoissonYield(plotData.plotdict["root_objects"][wjets_final_selection])() / tools.PoissonYield(plotData.plotdict["root_objects"][wjets_os_lowmt_mc_nick])()) #print "final selection " + str(tools.PoissonYield(plotData.plotdict["root_objects"][wjets_final_selection])()) #print "inclusive " + str(tools.PoissonYield(plotData.plotdict["root_objects"][wjets_os_lowmt_mc_nick])()) # scale signal region histograms integral_shape = tools.PoissonYield(plotData.plotdict["root_objects"][wjets_shape_nick])() #print "QCD/WJets estimation summary" #print "Extrapolation factors" #print "\t QCD OS/SS: " + str(qcd_extrapolation_factor_ss_os) #print "\t WJets OS/SS: " + str(wjets_extrapolation_factor_ss_os) #print "\t WJets high-low mT: " + str(wjets_extrapolation_factor_mt) #print "WJets yield" #print "\t before: " + str(integral_shape) #print "\t after: " + str(wjets_yield) #print "Scale factor: " + str(wjets_yield / integral_shape) if integral_shape != 0.0: scale_factor = wjets_yield / integral_shape log.debug("Scale factor for process W+jets (nick \"{nick}\") is {scale_factor}.".format(nick=wjets_shape_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][wjets_shape_nick].Scale(scale_factor.nominal_value) integral_shape = tools.PoissonYield(plotData.plotdict["root_objects"][wjets_os_highmt_mc_nick])() if integral_shape != 0.0: scale_factor = wjets_yield / (integral_shape * wjets_extrapolation_factor_mt) log.debug("Scale factor for process W+jets (nick \"{nick}\") is {scale_factor}.".format(nick=wjets_os_highmt_mc_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][wjets_os_highmt_mc_nick].Scale(scale_factor.nominal_value) integral_shape = tools.PoissonYield(plotData.plotdict["root_objects"][wjets_ss_highmt_mc_nick])() if integral_shape != 0.0: scale_factor = wjets_yield / (integral_shape * wjets_extrapolation_factor_mt * wjets_extrapolation_factor_ss_os) log.debug("Scale factor for process W+jets (nick \"{nick}\") is {scale_factor}.".format(nick=wjets_ss_highmt_mc_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][wjets_ss_highmt_mc_nick].Scale(scale_factor.nominal_value) # estimate QCD for the highmT region for nick in qcd_shape_highmt_substract_nick+[wjets_ss_highmt_mc_nick]: plotData.plotdict["root_objects"][qcd_ss_highmt_shape_nick].Add(plotData.plotdict["root_objects"][nick], -1) yield_qcd_ss_highmt = yield_ss_control - tools.PoissonYield(plotData.plotdict["root_objects"][wjets_ss_highmt_mc_nick])() yield_qcd_ss_highmt = max(0.0, yield_qcd_ss_highmt) integral_shape = tools.PoissonYield(plotData.plotdict["root_objects"][qcd_ss_highmt_shape_nick])() if integral_shape != 0.0: scale_factor = yield_qcd_ss_highmt / integral_shape plotData.plotdict["root_objects"][qcd_ss_highmt_shape_nick].Scale(scale_factor.nominal_value) integral_shape = tools.PoissonYield(plotData.plotdict["root_objects"][qcd_os_highmt_nick])() if integral_shape != 0.0: scale_factor = yield_qcd_ss_highmt * qcd_extrapolation_factor_ss_os / integral_shape plotData.plotdict["root_objects"][qcd_os_highmt_nick].Scale(scale_factor.nominal_value) plotData.metadata[wjets_shape_nick] = { "yield" : wjets_yield.nominal_value, "yield_unc" : wjets_yield.std_dev, "yield_unc_rel" : abs(wjets_yield.std_dev/wjets_yield.nominal_value if wjets_yield.nominal_value != 0.0 else 0.0), }
def run(self, plotData=None): super(NormalizeForPolarisation, self).run(plotData) for ztt_pos_pol_gen_nick, ztt_neg_pol_gen_nick, ztt_pos_pol_reco_nick, ztt_neg_pol_reco_nick, ztt_forced_gen_polarisation, ztt_pos_pol_reco_result_nick, ztt_neg_pol_reco_result_nick in zip( *[ plotData.plotdict[key] for key in [ "ztt_pos_pol_gen_nicks", "ztt_neg_pol_gen_nicks", "ztt_pos_pol_reco_nicks", "ztt_neg_pol_reco_nicks", "ztt_forced_gen_polarisations", "ztt_pos_pol_reco_result_nicks", "ztt_neg_pol_reco_result_nicks" ] ]): if ztt_pos_pol_reco_result_nick != ztt_pos_pol_reco_nick: new_name = "zttpospol_" + hashlib.md5( ztt_pos_pol_gen_nick + ztt_pos_pol_reco_nick + ztt_pos_pol_reco_result_nick).hexdigest() new_histogram = plotData.plotdict["root_objects"][ ztt_pos_pol_reco_nick].Clone(new_name) plotData.plotdict["root_objects"][ ztt_pos_pol_reco_result_nick] = new_histogram if ztt_neg_pol_reco_result_nick != ztt_neg_pol_reco_nick: new_name = "zttnegpol_" + hashlib.md5( ztt_neg_pol_gen_nick + ztt_neg_pol_reco_nick + ztt_neg_pol_reco_result_nick).hexdigest() new_histogram = plotData.plotdict["root_objects"][ ztt_neg_pol_reco_nick].Clone(new_name) plotData.plotdict["root_objects"][ ztt_neg_pol_reco_result_nick] = new_histogram pos_reco_norm = tools.PoissonYield( plotData.plotdict["root_objects"][ztt_pos_pol_reco_nick])() neg_reco_norm = tools.PoissonYield( plotData.plotdict["root_objects"][ztt_neg_pol_reco_nick])() pos_gen_norm = tools.PoissonYield( plotData.plotdict["root_objects"][ztt_pos_pol_gen_nick])() neg_gen_norm = tools.PoissonYield( plotData.plotdict["root_objects"][ztt_neg_pol_gen_nick])() scale_factors = polarisationsignalscaling.PolarisationScaleFactors( pos_reco_norm, neg_reco_norm, pos_gen_norm, neg_gen_norm, forced_gen_polarisation=ztt_forced_gen_polarisation) log.debug("Gen. level polarisation = {polarisation}".format( polarisation=scale_factors.get_gen_polarisation())) log.debug("Reco. level polarisation = {polarisation}".format( polarisation=scale_factors.get_reco_polarisation())) pos_reco_scale_factor = scale_factors.get_bias_removal_factor_pospol( ) if plotData.plotdict[ "ztt_remove_bias_instead_unpolarisation"] else scale_factors.get_scale_factor_pospol( ) plotData.plotdict["root_objects"][ ztt_pos_pol_reco_result_nick].Scale( pos_reco_scale_factor.nominal_value) log.debug( "Scaled histogram \"{nick}\" by a factor of {factor}".format( nick=ztt_pos_pol_reco_result_nick, factor=pos_reco_scale_factor)) neg_reco_scale_factor = scale_factors.get_bias_removal_factor_neg_pol( ) if plotData.plotdict[ "ztt_remove_bias_instead_unpolarisation"] else scale_factors.get_scale_factor_negpol( ) plotData.plotdict["root_objects"][ ztt_neg_pol_reco_result_nick].Scale( neg_reco_scale_factor.nominal_value) log.debug( "Scaled histogram \"{nick}\" by a factor of {factor}".format( nick=ztt_neg_pol_reco_result_nick, factor=neg_reco_scale_factor)) if log.isEnabledFor(logging.DEBUG): reco_polarisation_before_scaling = ( pos_reco_norm - neg_reco_norm) / (pos_reco_norm + neg_reco_norm) reco_polarisation_after_scaling = ( pos_reco_norm * pos_reco_scale_factor - neg_reco_norm * neg_reco_scale_factor) / ( pos_reco_norm * pos_reco_scale_factor + neg_reco_norm * neg_reco_scale_factor) log.debug("Tau polarisation changed from {before} to {after}.". format(before=reco_polarisation_before_scaling, after=reco_polarisation_after_scaling))
def run(self, plotData=None): super(EstimateWjets, self).run(plotData) # make sure that all necessary histograms are available for nicks in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): for nick in nicks: if isinstance(nick, basestring): assert isinstance( plotData.plotdict["root_objects"].get(nick), ROOT.TH1) elif not isinstance(nick, bool): for subnick in nick: assert isinstance( plotData.plotdict["root_objects"].get(subnick), ROOT.TH1) for wjets_from_mc, wjets_shape_nick, wjets_data_control_nick, wjets_data_substract_nicks, wjets_mc_signal_nick, wjets_mc_control_nick in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): if not wjets_from_mc: # skips the full estimation of this module and uses MC estimate of WJ instead. # Get yield and uncertainity in data in the control region yield_data_control = tools.PoissonYield( plotData.plotdict["root_objects"] [wjets_data_control_nick])() for nick in wjets_data_substract_nicks: # subtract yields of all backgrounds yield_bkg_control = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() if nick in plotData.metadata: yield_bkg_control = uncertainties.ufloat( plotData.metadata[nick].get( "yield", yield_bkg_control.nominal_value), plotData.metadata[nick].get( "yield_unc", yield_bkg_control.std_dev)) yield_data_control -= yield_bkg_control # make sure we don't have negative yields yield_data_control = uncertainties.ufloat( max(0.0, yield_data_control.nominal_value), yield_data_control.std_dev) yield_mc_signal = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_mc_signal_nick])() yield_mc_control = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_mc_control_nick])() assert (yield_data_control * yield_mc_signal == 0.0) or (yield_mc_control != 0.0) # the final yield in the signal region is N_data, WJ^{SR} = N_data, WJ^{CR} * N_MC,WJ^{SR} / N_MC,WJ^{CR} final_yield = yield_data_control * yield_mc_signal if final_yield != 0.0: final_yield /= yield_mc_control log.debug( "Relative statistical uncertainty of the yield for process W+jets (nick \"{nick}\") is {unc}." .format(nick=wjets_shape_nick, unc=final_yield.std_dev / final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0)) plotData.metadata[wjets_shape_nick] = { "yield": final_yield.nominal_value, "yield_unc": final_yield.std_dev, "yield_unc_rel": abs(final_yield.std_dev / final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0), } plotData.metadata # scale the wj file by the ratio of the estimated yield and the yield given by MC. integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_shape_nick])() if integral_shape != 0.0: scale_factor = final_yield / integral_shape log.debug( "Scale factor for process W+jets (nick \"{nick}\") is {scale_factor}." .format(nick=wjets_shape_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][wjets_shape_nick].Scale( scale_factor.nominal_value)
def run(self, plotData=None): super(EstimateQcd, self).run(plotData) for qcd_data_shape_nick, qcd_data_yield_nick, qcd_data_control_nick, qcd_data_substract_nicks, qcd_extrapolation_factor_ss_os, qcd_subtract_shape in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): yield_data_control = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_data_control_nick])() yield_qcd_control = yield_data_control for nick in qcd_data_substract_nicks: yield_bkg_control = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() if nick in plotData.metadata: yield_bkg_control = uncertainties.ufloat( plotData.metadata[nick].get( "yield", yield_bkg_control.nominal_value), plotData.metadata[nick].get("yield_unc", yield_bkg_control.std_dev)) yield_qcd_control -= yield_bkg_control if qcd_subtract_shape: plotData.plotdict["root_objects"][ qcd_data_control_nick].Add( plotData.plotdict["root_objects"][nick], -1.0 / plotData.plotdict["qcd_scale_factor"]) if qcd_subtract_shape: plotData.plotdict["root_objects"][ qcd_data_shape_nick] = plotData.plotdict["root_objects"][ qcd_data_control_nick] yield_qcd_control = max(0.0, yield_qcd_control) scale_factor = yield_qcd_control * qcd_extrapolation_factor_ss_os if yield_data_control != 0.0: scale_factor /= yield_data_control final_yield = tools.PoissonYield( plotData.plotdict["root_objects"] [qcd_data_yield_nick])() * scale_factor log.debug( "Relative statistical uncertainty of the yield for process QCD (nick \"{nick}\") is {unc}." .format(nick=qcd_data_shape_nick, unc=final_yield.std_dev / final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0)) plotData.metadata[qcd_data_shape_nick] = { "yield": final_yield.nominal_value, "yield_unc": final_yield.std_dev, "yield_unc_rel": abs(final_yield.std_dev / final_yield.nominal_value if final_yield.nominal_value != 0.0 else 0.0), } integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_data_shape_nick])() if integral_shape != 0.0: scale_factor = final_yield / integral_shape log.debug( "Scale factor for process QCD (nick \"{nick}\") is {scale_factor}." .format(nick=qcd_data_shape_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][qcd_data_shape_nick].Scale( scale_factor.nominal_value)
def run(self, plotData=None): super(EstimateWjetsAndQCD, self).run(plotData) for qcd_extrapolation_factor_ss_os, qcd_shape_nick, qcd_ss_lowmt_nick, qcd_ss_highmt_shape_nick, qcd_os_highmt_nick, qcd_shape_highmt_substract_nick, qcd_yield_nick, qcd_shape_substract_nick, qcd_yield_substract_nick, wjets_ss_mc_nick, wjets_os_mc_nick, wjets_os_highmt_mc_nick, wjets_os_lowmt_mc_nick, wjets_ss_highmt_mc_nick, wjets_ss_substract_nick, wjets_ss_data_nick, wjets_os_substract_nick, wjets_os_data_nick, wjets_shape_nick in zip( *[plotData.plotdict[key] for key in self._plotdict_keys]): # estimate QCD for the lowmT for nick in qcd_shape_substract_nick: plotData.plotdict["root_objects"][qcd_shape_nick].Add( plotData.plotdict["root_objects"][nick], -1) yield_qcd_control = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_yield_nick])() for nick in qcd_yield_substract_nick: yield_bkg_control = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() if nick in plotData.metadata: yield_bkg_control = uncertainties.ufloat( plotData.metadata[nick].get( "yield", yield_bkg_control.nominal_value), plotData.metadata[nick].get("yield_unc", yield_bkg_control.std_dev)) yield_qcd_control -= yield_bkg_control yield_qcd_control = max(0.0, yield_qcd_control) integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_shape_nick])() if integral_shape != 0.0: scale_factor = yield_qcd_control * qcd_extrapolation_factor_ss_os / integral_shape plotData.plotdict["root_objects"][qcd_shape_nick].Scale( scale_factor.nominal_value) integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_ss_lowmt_nick])() if integral_shape != 0.0: scale_factor = yield_qcd_control / integral_shape plotData.plotdict["root_objects"][qcd_ss_lowmt_nick].Scale( scale_factor.nominal_value) # estimate W+jets yield_ss_control = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_ss_data_nick])() for nick in wjets_ss_substract_nick: yield_bkg_control = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() yield_ss_control -= yield_bkg_control yield_os_control = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_os_data_nick])() for nick in wjets_os_substract_nick: yield_bkg_control = tools.PoissonYield( plotData.plotdict["root_objects"][nick])() yield_os_control -= yield_bkg_control wjets_extrapolation_factor_ss_os = tools.PoissonYield( plotData.plotdict["root_objects"] [wjets_os_mc_nick])() / tools.PoissonYield( plotData.plotdict["root_objects"][wjets_ss_mc_nick])() wjets_extrapolation_factor_mt = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_os_lowmt_mc_nick] )() / tools.PoissonYield( plotData.plotdict["root_objects"][wjets_os_highmt_mc_nick])() wjets_yield = ( yield_os_control - qcd_extrapolation_factor_ss_os * yield_ss_control ) * wjets_extrapolation_factor_ss_os / ( wjets_extrapolation_factor_ss_os - qcd_extrapolation_factor_ss_os) * wjets_extrapolation_factor_mt # scale signal region histograms integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_shape_nick])() if integral_shape != 0.0: scale_factor = wjets_yield / integral_shape log.debug( "Scale factor for process W+jets (nick \"{nick}\") is {scale_factor}." .format(nick=wjets_shape_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][wjets_shape_nick].Scale( scale_factor.nominal_value) integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_os_highmt_mc_nick])() if integral_shape != 0.0: scale_factor = wjets_yield / (integral_shape * wjets_extrapolation_factor_mt) log.debug( "Scale factor for process W+jets (nick \"{nick}\") is {scale_factor}." .format(nick=wjets_os_highmt_mc_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][ wjets_os_highmt_mc_nick].Scale(scale_factor.nominal_value) integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][wjets_ss_highmt_mc_nick])() if integral_shape != 0.0: scale_factor = wjets_yield / (integral_shape * wjets_extrapolation_factor_mt * wjets_extrapolation_factor_ss_os) log.debug( "Scale factor for process W+jets (nick \"{nick}\") is {scale_factor}." .format(nick=wjets_ss_highmt_mc_nick, scale_factor=scale_factor)) plotData.plotdict["root_objects"][ wjets_ss_highmt_mc_nick].Scale(scale_factor.nominal_value) # estimate QCD for the highmT region for nick in qcd_shape_highmt_substract_nick + [ wjets_ss_highmt_mc_nick ]: plotData.plotdict["root_objects"][ qcd_ss_highmt_shape_nick].Add( plotData.plotdict["root_objects"][nick], -1) yield_qcd_ss_highmt = yield_ss_control - tools.PoissonYield( plotData.plotdict["root_objects"][wjets_ss_highmt_mc_nick])() yield_qcd_ss_highmt = max(0.0, yield_qcd_ss_highmt) integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_ss_highmt_shape_nick])() if integral_shape != 0.0: scale_factor = yield_qcd_ss_highmt / integral_shape plotData.plotdict["root_objects"][ qcd_ss_highmt_shape_nick].Scale(scale_factor.nominal_value) integral_shape = tools.PoissonYield( plotData.plotdict["root_objects"][qcd_os_highmt_nick])() if integral_shape != 0.0: scale_factor = yield_qcd_ss_highmt * qcd_extrapolation_factor_ss_os / integral_shape plotData.plotdict["root_objects"][qcd_os_highmt_nick].Scale( scale_factor.nominal_value)