ATLAS Offline Software
Loading...
Searching...
No Matches
EfficiencyScaleFactor.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4
8#include <TRandom3.h>
9#include <TClass.h>
10namespace ADD_CMODE(CP) {
11 const unsigned int EfficiencyScaleFactor::m_warningLimit = 10;
12 EfficiencyScaleFactor::EfficiencyScaleFactor(std::shared_ptr<EfficiencyScaleFactor> nominal,
13 const MuonEfficiencyScaleFactors& ref_tool,
14 const std::string& file,
15 const std::string& time_unit,
16 const std::string& syst_name,
17 int syst_type_bitmap):
18 m_measurement(ref_tool.measurement()),
19 m_syst_name(syst_name),
20 m_is_up(syst_type_bitmap & EffiCollection::UpVariation),
21 m_is_lowpt(syst_type_bitmap & EffiCollection::JPsiAnalysis),
22 m_respond_to_kineDepSyst(syst_type_bitmap & EffiCollection::PtDependent),
23 m_separateBinSyst(syst_type_bitmap & EffiCollection::UnCorrelated),
24 m_sf(),
25 m_eff(),
26 m_mc_eff(),
27
28 m_sf_decor(std::make_unique<FloatDecorator>(ref_tool.sf_decoration()+ (m_syst_name.empty()? "" :"_"+ m_syst_name + (m_is_up? "_1UP": "_1DN")))),
29 m_eff_decor(std::make_unique<FloatDecorator>(ref_tool.data_effi_decoration()+ (m_syst_name.empty()? "" :"_"+ m_syst_name + (m_is_up? "_1UP": "_1DN")))),
30 m_mc_eff_decor(std::make_unique<FloatDecorator>(ref_tool.mc_effi_decoration()+ (m_syst_name.empty()? "" :"_"+ m_syst_name + (m_is_up? "_1UP": "_1DN")))),
31 m_sf_rep_decor(std::make_unique<FloatVectorDecorator>(ref_tool.sf_replica_decoration()+ (m_syst_name.empty()? "" :"_"+ m_syst_name + (m_is_up? "_1UP": "_1DN")))),
32 m_eff_rep_decor(std::make_unique<FloatVectorDecorator>(ref_tool.data_effi_replica_decoration()+ (m_syst_name.empty()? "" :"_"+ m_syst_name + (m_is_up? "_1UP": "_1DN")))),
33 m_mc_eff_rep_decor(std::make_unique<FloatVectorDecorator>(ref_tool.mc_effi_replica_deocration()+ (m_syst_name.empty()? "" :"_"+ m_syst_name + (m_is_up? "_1UP": "_1DN")))),
34
35 m_sf_KineDepsys(),
36 m_sf_replicas(),
37 m_eff_replicas(),
38 m_mc_eff_replicas(),
39 m_NominalFallBack(nominal),
40 m_SystematicBin(-1),
41 m_default_eff(1.),
42 m_default_eff_ttva(1.),
43 m_warnsPrinted(0),
44 m_firstRun(1),
45 m_lastRun(999999){
46
47 if (ref_tool.measurement() == MuonEfficiencyType::Iso){
48 dRJetAxisHandler::set_close_jet_decorator(ref_tool.close_by_jet_decoration());
49 dRJetAxisHandler::set_use_2D_sf(ref_tool.use_2D_iso_corrections());
50 }
51 // open the file
52 std::unique_ptr<TFile> f (TFile::Open(file.c_str(), "READ"));
53 if (!f || !f->IsOpen()) {
54 Error("EfficiencyScaleFactor", "Unable to open file %s", file.c_str());
55 return;
56 }
57 // now we can read our three mean histograms Histos
58 m_eff = ReadHistFromFile(this, "Eff", f.get(), time_unit);
59 m_mc_eff = ReadHistFromFile(this, "MC_Eff", f.get(), time_unit);
60 m_sf = ReadHistFromFile(this, "SF", f.get(), time_unit);
62 if (syst_name.empty()) return;
63
64
65 if (IsUpVariation()){
66 m_default_eff = 2.;
67 m_default_eff_ttva = 1. + 1.e-9;
68 } else {
69 m_default_eff = 0.;
70 m_default_eff_ttva = 1. - 1.e-9;
71 }
72 std::function<void(std::unique_ptr<HistHandler>&, const std::string& )> syst_loader = [this, &f, &time_unit, &syst_type_bitmap] (std::unique_ptr<HistHandler>& nominal, const std::string& hist_type) {
73 if(!nominal) return;
74 std::unique_ptr<HistHandler> sys = ReadHistFromFile(this, Form("%s_%s_%s", hist_type.c_str() ,
75 m_syst_name.c_str(),
76 (syst_type_bitmap & EffiCollection::Symmetric ? "SYM" : (m_is_up ? "1UP" : "1DN")) ),
77 f.get(), time_unit);
78 if (sys) {
79 for (int i = 1; i <= nominal->nBins(); ++i) {
80 double content = nominal->GetBinContent(i);
81 double variation = (IsUpVariation() ? 1. : -1.)*sys->GetBinContent(i);
82 nominal->SetBinContent(i,content + variation);
83 }
84 return;
85 }
89 if (m_syst_name == "SYS"){
90 std::unique_ptr<HistHandler> old_sys = ReadHistFromFile(this, hist_type +"_sys", f.get(), time_unit);
92 if (!old_sys){
93 nominal.reset();
94 return;
95 }
96
97 for (int i = 1; i<= nominal->nBins(); ++i) {
98 nominal->SetBinContent(i, nominal->GetBinContent(i) + (IsUpVariation() ? 1. : -1.)*old_sys->GetBinContent(i));
99 }
100 }
102 else if (m_syst_name == "STAT") {
103 for (int i = 1; i<= nominal->nBins(); ++i) {
104 nominal->SetBinContent(i, nominal->GetBinContent(i) + (IsUpVariation() ? 1. : -1.)*nominal->GetBinError(i));
105 }
106 }
108 else if (m_syst_name == "PTDEPENDENCY"){
109 return;
110 }
112 else{
113 Error("EfficiencyScaleFactor()", "Failed to load sytstematic variation %s for measurement %s and histo-type %s", sysname(true).c_str(),
114 EfficiencyTypeName(m_measurement).c_str(),
115 hist_type.c_str());
116 nominal.reset();
117 }
118 };
120 syst_loader(m_sf,"SF");
121 syst_loader(m_eff,"Eff");
122 syst_loader(m_mc_eff,"MC_Eff");
123
125 if (m_is_lowpt || (file == ref_tool.filename_HighEta() && ref_tool.filename_HighEta() != ref_tool.filename_Central()) ||
126 (file == ref_tool.filename_Calo() && ref_tool.filename_Calo() != ref_tool.filename_Central())) m_respond_to_kineDepSyst =false;
128
130 if (!m_respond_to_kineDepSyst){
131 return;
132 }
133 // Load the systematic of the bad veto
134 if (m_measurement == MuonEfficiencyType::BadMuonVeto) {
135 TDirectory* SystDir = nullptr;
136 f->GetObject(("KinematicSystHandler_" + time_unit).c_str(), SystDir);
138 if (SystDir) {
139 m_sf_KineDepsys = std::make_unique<BadMuonVetoSystHandler>(SystDir);
140 } else {
142 f->GetObject("BadMuonVetoSyst_3Stations", SystDir);
143 TDirectory* SystDir_2Stat = nullptr;
144 f->GetObject("BadMuonVetoSyst_2Stations", SystDir_2Stat);
145 m_sf_KineDepsys = std::make_unique<BadMuonVetoSystHandler>(SystDir, SystDir_2Stat);
146 }
147 m_sf_KineDepsys->SetSystematicWeight( IsUpVariation() ? 1 : -1);
148 if (!m_sf_KineDepsys->initialize()){
149 Error("EfficiencyScaleFactor()", "Pt dependent systematic could not be loaded");
150 m_sf_KineDepsys.reset();
151 }
152 if (m_sf_KineDepsys)
153 addSubtool (*m_sf_KineDepsys);
154 return;
155 } else if (m_measurement == MuonEfficiencyType::TTVA){
156 m_sf_KineDepsys = std::make_unique<TTVAClosureSysHandler>(ReadHistFromFile(this,"SF_NonClosure_sys",f.get(),time_unit));
157 if (!m_sf_KineDepsys->initialize()){
158 Error("EfficiencyScaleFactor()", "TTVA non closure systematic could not be loaded.");
159 m_sf_KineDepsys.reset();
160 }
161 else
162 m_sf_KineDepsys->SetSystematicWeight( IsUpVariation() ? 1 : -1);
163 if (m_sf_KineDepsys)
164 addSubtool (*m_sf_KineDepsys);
165 return;
166
167 }
169 m_sf_KineDepsys = std::make_unique<PtKinematicSystHandler>(ReadHistFromFile(this, Form("SF_PtFlatness_1%s", m_is_up?"UP" :"DN"), f.get(), time_unit), ReadHistFromFile(this, "SF_PtDep_sys", f.get(), time_unit));
170
172 if(!m_sf_KineDepsys->initialize()){
173 m_sf_KineDepsys = std::make_unique<PrimodialPtSystematic>(ReadHistFromFile(this, "SF_PtDep_sys", f.get(), time_unit));
174 }
175 m_sf_KineDepsys->SetSystematicWeight( IsUpVariation() ? 1 : -1);
176 addSubtool (*m_sf_KineDepsys);
177 }
178 EfficiencyScaleFactor::EfficiencyScaleFactor(const MuonEfficiencyScaleFactors& ref_tool,
179 const std::string &file,
180 const std::string &time_unit):
181 EfficiencyScaleFactor(std::shared_ptr<EfficiencyScaleFactor>(),
182 ref_tool,file, time_unit, "",0){}
183
184 std::string EfficiencyScaleFactor::sysname(bool with_direction) const {
185 return m_syst_name.empty() ? "" : EfficiencyTypeName(m_measurement) + "_" + m_syst_name +(m_is_lowpt ? "_LOWPT" : "") + (with_direction ? (m_is_up ?"__1UP" : "__1DN") :"");
186 }
187 bool EfficiencyScaleFactor::separateBinSyst() const {
188 return m_separateBinSyst;
189 }
190 bool EfficiencyScaleFactor::IsUpVariation() const{
191 return m_is_up;
192 }
193 unsigned int EfficiencyScaleFactor::firstRun() const{
194 return m_firstRun;
195 }
196 unsigned int EfficiencyScaleFactor::lastRun() const{
197 return m_lastRun;
198 }
199 bool EfficiencyScaleFactor::coversRunNumber(unsigned int run) const{
200 return m_firstRun <= run && run <= m_lastRun;
201 }
202 void EfficiencyScaleFactor::setFirstLastRun(unsigned int first, unsigned int last){
203 m_firstRun = first;
204 m_lastRun = last;
205 }
206 bool EfficiencyScaleFactor::CheckConsistency() {
207 //Check whether the SFs could be successfully loaded
208 if (!m_sf) {
209 Error("EfficiencyScaleFactor()", "Could not load the SF for measurement %s and systematic %s",EfficiencyTypeName(m_measurement).c_str(), sysname().c_str());
210 return false;
211 }
212 if (m_respond_to_kineDepSyst && !m_sf_KineDepsys->initialize()) {
213 Error("EfficiencyScaleFactor()", "Could not load the SF pt-dependent systematic for %s and systematic %s", EfficiencyTypeName(m_measurement).c_str(), sysname().c_str() );
214 return false;
215 }
216 if (m_NominalFallBack.get() == this) {
217 Error("EfficiencyScaleFactor()", "The EfficiencyScaleFactor %s has itself as Nominal Fall back.", EfficiencyTypeName(m_measurement).c_str());
218 m_NominalFallBack.reset();
219 return false;
220 }
221 if (m_NominalFallBack) {
222 if (!m_NominalFallBack->sysname().empty() || sysname().empty()){
223 Error("EfficiencyScaleFactor()", "Either nominal is assigned with a fall back (%s) or the nominal fall back is invald(%s).", sysname().c_str(), m_NominalFallBack->sysname().c_str() );
224 return false;
225 }
226 }
227 if (firstRun() > lastRun()){
228 Error("EfficiencyScaleFactor()", "Invalid run number range. Since the map is ranging from %u to %u.", firstRun(), lastRun());
229 return false;
230 }
231 std::function<bool(const std::unique_ptr<HistHandler>&)> consistent_histo = [](const std::unique_ptr<HistHandler>& histo)->bool{
234 if (!histo) return true;
235 for ( int i = 1; i <= histo->nBins(); ++i){
236 if (std::isnan(histo->GetBinContent(i)) || std::isinf(histo->GetBinContent(i))){
237 Error("EfficiencyScaleFactor()", "The %d-th bin %s has not a number (%f)",i, histo->GetBinName(i).c_str(), histo->GetBinContent(i));
238 return false;
239 }
240 }
241 return true;
242 };
243 if (!consistent_histo(m_sf)){
244 Error("EfficiencyScaleFactor()", "Invalid scalefactor in %s", sysname().c_str());
245 return false;
246 }
247 if (!consistent_histo(m_eff)){
248 Error("EfficiencyScaleFactor()", "Invalid data-efficiency in %s", sysname().c_str());
249 return false;
250 }
251 if (!consistent_histo(m_mc_eff)){
252 Error("EfficiencyScaleFactor()", "Invalid MC-efficiency in %s", sysname().c_str());
253 return false;
254 }
255 return true;
256 }
257 std::unique_ptr<HistHandler> EfficiencyScaleFactor::ReadHistFromFile(columnar::ColumnarTool<>* parent, const std::string& name, TFile* f, const std::string& time_unit) {
258
259 TH1* hist_from_file = nullptr;
260
261 f->GetObject((name + std::string("_") + time_unit).c_str(), hist_from_file);
262 // if no period weighting, the histo may also not have a time period in the name at all
263
264 if (!hist_from_file && time_unit == "All") {
265 f->GetObject(name.c_str(), hist_from_file);
266 }
267 if (!hist_from_file) {
268 return std::unique_ptr<HistHandler>();
269 }
270 return package_histo(parent, hist_from_file);
271 }
272 std::unique_ptr<HistHandler> EfficiencyScaleFactor::package_histo(columnar::ColumnarTool<>* parent, TH1* h) {
273 // make sure that the correct type of histo is used
274 // Dynamic cast for TH2 Poly otherwise we can rely on the GetDimension() ,ethod
275 if (!h) return std::unique_ptr<HistHandler>();
276 if (dynamic_cast<TH2Poly*>(h)) {
277 return std::make_unique<HistHandler_TH2Poly>(parent, dynamic_cast<TH2Poly*>(h));
278 }else if (h->GetDimension() == 3) {
279 return std::make_unique<HistHandler_TH3>(parent, h);
280 }else if (h->GetDimension() == 2) {
281 return std::make_unique<HistHandler_TH2>(parent, h);
282 } else if (h->GetDimension() == 1) {
283 return std::make_unique<HistHandler_TH1>(parent, h);
284 }
285 Error("EfficiencyScaleFactor", "Unable to package histo %s (%s) in a known HistHandler", h->GetName(), h->IsA()->GetName());
286 return std::unique_ptr<HistHandler>();
287 }
288 int EfficiencyScaleFactor::nBins() const {
289 return m_sf ? m_sf->nBins() : -1;
290 }
291 int EfficiencyScaleFactor::nOverFlowBins() const{
292 return m_sf ? m_sf->nOverFlowBins() : -1;
293 }
294 bool EfficiencyScaleFactor::isOverFlowBin(int b) const{
295 return m_sf ? m_sf->isOverFlowBin(b) : true;
296 }
297 CP::CorrectionCode EfficiencyScaleFactor::ScaleFactor(const xAOD::Muon& mu, float & SF) const {
298 return ScaleFactor (columnar::MuonId (mu), SF);
299 }
300 CP::CorrectionCode EfficiencyScaleFactor::ScaleFactor(columnar::MuonId mu, float & SF) const {
301 if (m_separateBinSyst && m_NominalFallBack) {
302 int bin = -1;
303 CP::CorrectionCode cc = m_sf->FindBin(mu, bin);
304 if (cc == CP::CorrectionCode::Error) {
305 return cc;
306 }
307 if (bin != m_SystematicBin) {
308 return m_NominalFallBack->ScaleFactor(mu, SF);
309 }
310 }
311 CP::CorrectionCode cc = GetContentFromHist(m_sf.get(), mu, SF, true);
312 if (cc == CP::CorrectionCode::Error) Error("EfficiencyScaleFactor", "Could not apply the scale factor");
313 return cc;
314 }
315
316 CP::CorrectionCode EfficiencyScaleFactor::DataEfficiency(const xAOD::Muon& mu, float & Eff) const {
317 if (m_separateBinSyst && m_NominalFallBack && m_eff) {
318 int bin = -1;
319 CP::CorrectionCode cc = m_eff->FindBin(mu, bin);
320 if (cc == CP::CorrectionCode::Error) {
321 return cc;
322 }
323 if (bin != m_SystematicBin) {
324 return m_NominalFallBack->DataEfficiency(mu, Eff);
325 }
326 }
327 CP::CorrectionCode cc = GetContentFromHist(m_eff.get(), mu, Eff, true);
328 if (cc == CP::CorrectionCode::Error) Error("EfficiencyScaleFactor", "Could not apply the data efficiency");
329 return cc;
330 }
331 CP::CorrectionCode EfficiencyScaleFactor::MCEfficiency(const xAOD::Muon& mu, float & Eff) const {
332 if (m_separateBinSyst && m_NominalFallBack && m_mc_eff) {
333 int bin = -1;
334 CP::CorrectionCode cc = m_mc_eff->FindBin(mu, bin);
335 if (cc == CP::CorrectionCode::Error) {
336 return cc;
337 }
338 if (bin != m_SystematicBin) {
339 return m_NominalFallBack->MCEfficiency(mu, Eff);
340 }
341 }
342 CP::CorrectionCode cc = GetContentFromHist(m_mc_eff.get(), mu, Eff, false);
343 if (cc == CP::CorrectionCode::Error) Error("EfficiencyScaleFactor", "Could not apply the Monte Carlo efficiency");
344 return cc;
345 }
346
347 CP::CorrectionCode EfficiencyScaleFactor::GetContentFromHist(const HistHandler* Hist, const xAOD::Muon& mu, float & Eff, bool add_kine_syst) const {
348 return GetContentFromHist (Hist, columnar::MuonId (mu), Eff, add_kine_syst);
349 }
350 CP::CorrectionCode EfficiencyScaleFactor::GetContentFromHist(const HistHandler* Hist, columnar::MuonId mu, float & Eff, bool add_kine_syst) const {
351 Eff = m_default_eff;
352 if (!Hist) {
353 if (m_warnsPrinted < m_warningLimit){
354 Warning("EfficiencyScaleFactor", "Could not find histogram for variation %s and muon with pt=%.4f, eta=%.2f and phi=%.2f, returning %.1f", sysname().c_str(), ptAcc(mu), etaAcc(mu), phiAcc(mu), m_default_eff);
355 ++m_warnsPrinted;
356 }
358 }
359 if (m_measurement == MuonEfficiencyType::TTVA && std::abs(etaAcc(mu)) > 2.5 && std::abs(etaAcc(mu)) <= 2.7 && muonTypeAcc(mu) == xAOD::Muon::MuonType::MuonStandAlone) {
360 if (m_warnsPrinted < m_warningLimit){
361 Info("EfficiencyScaleFactor", "No TTVA sf/efficiency provided for standalone muons with 2.5<|eta|<2.7 for variation %s and muon with pt=%.4f, eta=%.2f and phi=%.2f, returning %.1f", sysname().c_str(), ptAcc(mu), etaAcc(mu), phiAcc(mu), m_default_eff_ttva);
362 ++m_warnsPrinted;
363 }
364 Eff = m_default_eff_ttva;
366 }
367 int bin = -1;
368 CP::CorrectionCode cc = Hist->FindBin(mu, bin);
369 if (cc != CP::CorrectionCode::Ok) return cc;
370 else Eff = Hist->GetBinContent(bin);
371
372 if (add_kine_syst && m_respond_to_kineDepSyst) {
373 return m_sf_KineDepsys->GetKineDependent(mu, Eff);
374 }
376 }
377 CP::CorrectionCode EfficiencyScaleFactor::ApplyScaleFactor(const xAOD::Muon& mu) const{
378 float sf = 0;
379 CP::CorrectionCode result = ScaleFactor(mu, sf);
380 (*m_sf_decor)(mu) = sf;
381 return result;
382 }
383 CP::CorrectionCode EfficiencyScaleFactor::ApplyScaleFactorReplicas(const xAOD::Muon& mu, int n_replicas) {
384 std::vector<float> replicas(n_replicas);
385 CP::CorrectionCode result = ScaleFactorReplicas(mu, replicas);
386 (*m_sf_rep_decor)(mu)= replicas;
387 return result;
388 }
389
390 CP::CorrectionCode EfficiencyScaleFactor::ApplyDataEfficiency(const xAOD::Muon& mu) const {
391 float effi = 0;
392 CP::CorrectionCode result = DataEfficiency(mu, effi);
393 (*m_eff_decor)(mu) = effi;
394 return result;
395 }
396 CP::CorrectionCode EfficiencyScaleFactor::ApplyDataEfficiencyReplicas(const xAOD::Muon& mu, int n_replicas){
397 std::vector<float> replicas(n_replicas);
398 CP::CorrectionCode result = DataEfficiencyReplicas(mu, replicas);
399 (*m_eff_rep_decor)(mu) = replicas;
400 return result;
401 }
402 CP::CorrectionCode EfficiencyScaleFactor::ApplyMCEfficiency(const xAOD::Muon& mu) const {
403 float effi = 0;
404 CP::CorrectionCode result = MCEfficiency(mu, effi);
405 (*m_mc_eff_decor)(mu) = effi;
406 return result;
407 }
408 CP::CorrectionCode EfficiencyScaleFactor::ApplyMCEfficiencyReplicas(const xAOD::Muon& mu, int n_replicas){
409 std::vector<float> replicas(n_replicas);
410 CP::CorrectionCode result = MCEfficiencyReplicas(mu, replicas);
411 (*m_mc_eff_rep_decor)(mu) = replicas;
412 return result;
413 }
414 CP::CorrectionCode EfficiencyScaleFactor::ScaleFactorReplicas(const xAOD::Muon& mu, std::vector<float> & SF) {
415 return GetContentReplicasFromHist(m_sf_replicas, mu, SF, true);
416 }
417 CP::CorrectionCode EfficiencyScaleFactor::DataEfficiencyReplicas(const xAOD::Muon& mu, std::vector<float> & eff) {
418 return GetContentReplicasFromHist(m_eff_replicas, mu, eff, true);
419 }
420 CP::CorrectionCode EfficiencyScaleFactor::MCEfficiencyReplicas(const xAOD::Muon& mu, std::vector<float> & eff) {
421 return GetContentReplicasFromHist(m_mc_eff_replicas, mu, eff, false);
422 }
423 CP::CorrectionCode EfficiencyScaleFactor::GetContentReplicasFromHist(EfficiencyScaleFactor::SFReplicaVec &replicas, const xAOD::Muon& mu, std::vector<float> & SF, bool add_kine_syst) {
424 if (replicas.size() != SF.size()) GenerateReplicas(SF.size(), 1000. * mu.phi() + mu.eta());
425 if (replicas.empty()) return CP::CorrectionCode::OutOfValidityRange;
426 if (m_measurement == MuonEfficiencyType::TTVA && std::abs(mu.eta()) > 2.5 && std::abs(mu.eta()) <= 2.7 && mu.muonType() == xAOD::Muon::MuonType::MuonStandAlone) {
427 if (m_warnsPrinted < m_warningLimit){
428 Info("EfficiencyScaleFactor", "No TTVA sf/efficiency provided for standalone muons with 2.5<|eta|<2.7 for variation %s and muon with pt=%.4f, eta=%.2f and phi=%.2f, returning %.1f", sysname().c_str(), mu.pt(), mu.eta(), mu.phi(), m_default_eff_ttva);
429 ++m_warnsPrinted;
430 }
431 for (auto& r : SF)
432 r = m_default_eff_ttva;
434 }
435 int bin = -1;
436 float extra_sys = 1;
437 if (add_kine_syst && m_respond_to_kineDepSyst) {
438 CP::CorrectionCode cc = m_sf_KineDepsys->GetKineDependent(mu, extra_sys);
439 if (cc != CP::CorrectionCode::Ok) {}
440 }
441
442 CP::CorrectionCode res = (*replicas.begin())->FindBin(mu, bin);
443 if (res != CP::CorrectionCode::Ok) return res;
444 else {
445 for (size_t k = 0; k < SF.size(); k++) {
446 SF[k] = replicas.at(k)->GetBinContent(bin) * extra_sys;
447 }
448 }
449 return res;
450 }
451 void EfficiencyScaleFactor::GenerateReplicas(int nrep, int seed) {
452 GenerateReplicasFromHist(m_eff.get(), nrep, seed, m_eff_replicas);
453 GenerateReplicasFromHist(m_sf.get(), nrep, seed, m_sf_replicas);
454 GenerateReplicasFromHist(m_mc_eff.get(), nrep, seed, m_mc_eff_replicas);
455 }
456 void EfficiencyScaleFactor::GenerateReplicasFromHist(HistHandler* h, int nrep, int seed, EfficiencyScaleFactor::SFReplicaVec &replicas) {
457 if (!h) return;
458 TRandom3 Rndm(seed);
459 replicas.clear();
460 replicas.reserve(nrep);
461 int nBins = h->nBins();
462 for (int t = 0; t < nrep; t++) {
463 replicas.push_back(package_histo(this, h->GetHist()));
464 HistHandler* replica = replicas.back().get();
465 for (int bin = 0; bin < nBins; bin++) {
466 replica->SetBinContent(bin, Rndm.Gaus(h->GetBinContent(bin), h->GetBinError(bin)));
467 }
468 }
469 }
470
471 bool EfficiencyScaleFactor::SetSystematicBin(int bin) {
472 if (m_syst_name.empty()) return true;
473 if (!m_NominalFallBack) {
474 Error("EfficiencyScaleFactor::SetSystematicBin()", "No fallback has been given for %s", sysname().c_str());
475 return false;
476 }
477 if (!m_separateBinSyst || bin < 1 || bin > nBins()) {
478 Error("EfficiencyScaleFactor::SetSystematicBin()", "The current bin %i is out of the maximum range %u ", bin, nBins());
479 return false;
480 }
481 m_SystematicBin = bin;
482 return true;
483 }
484 std::string EfficiencyScaleFactor::GetBinName(int bin) const {
485 if (bin < 1 || bin > nBins()) {
486 Error("EfficiencyScaleFactor::GetBinName()", "The current bin %i is out of the maximum range %u ", bin, nBins());
487 return "Out of range";
488 }
489 return m_sf->GetBinName(bin);
490 }
491
492 int EfficiencyScaleFactor::FindBinSF(const xAOD::Muon & mu) const {
493 int bin = -1;
494 CP::CorrectionCode cc = m_sf->FindBin(mu, bin);
495 if (cc == CP::CorrectionCode::Error) {
496 return -1;
497 }
498 return bin;
499 }
500
501} /* namespace ADD_CMODE(CP) */
std::pair< std::vector< unsigned int >, bool > res
static const Attributes_t empty
Header file for AthHistogramAlgorithm.
Return value from object correction CP tools.
@ Error
Some error happened during the object correction.
@ OutOfValidityRange
Input object is out of validity range.
@ Ok
The correction was done successfully.
int r
Definition globals.cxx:22
ObjectId< MuonDef > MuonId
Definition MuonDef.h:22
Muon_v1 Muon
Reference the current persistent version:
Definition Muon.h:13
TFile * file
int run(int argc, char *argv[])