ATLAS Offline Software
Loading...
Searching...
No Matches
MuonEfficiencyScaleFactors.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4
8
14
15#include <TTree.h>
16#include <TFile.h>
17namespace CP {
18
32
35 m_wp("Medium"),
36 m_sf_sets(),
49 m_calibration_version("230213_Preliminary_r22run2"),
51 m_iso_jet_dR("dRJet"),
52 m_use2DIsoCorr(false),
55 m_init(false),
56 m_seperateSystBins(false),
57 m_breakDownSyst(false),
59 m_useLRT(false),
61
62 m_accessors = std::make_unique<Accessors>(this);
63
64 declareProperty("WorkingPoint", m_wp);
65
66 // these are for debugging / testing, *not* for general use!
67 declareProperty("CustomInputFolder", m_custom_dir);
68 declareProperty("CustomFileCaloTag", m_custom_file_Calo);
69 declareProperty("CustomFileCombined", m_custom_file_Combined);
70 declareProperty("CustomFileHighEta", m_custom_file_HighEta);
71 declareProperty("CustomFileLowPt", m_custom_file_LowPt);
72 declareProperty("CustomFileLowPtCalo", m_custom_file_LowPtCalo);
73 declareProperty("CustomFileLRTCombined", m_custom_file_LRTCombined);
74 declareProperty("CustomFileLRTLowPt", m_custom_file_LRTLowPt);
75
76 // Apply additional systematics to account for negelected pt dependency
77 // in the maps themselves or for non-closure
78 declareProperty("ApplyKinematicSystematic", m_applyKineDepSys);
79
80 // Set specific names for the decorations of the scale-factors to the muon
81 declareProperty("DataEfficiencyDecorationName", m_efficiency_decoration_name_data);
82 declareProperty("MCEfficiencyDecorationName", m_efficiency_decoration_name_mc);
83 declareProperty("ScaleFactorDecorationName", m_sf_decoration_name);
84
85 declareProperty("CalibrationRelease", m_calibration_version);
86 // Set this property to -1 if you do not want to use the JPsi
87 // reconstruction scale-factors
88 declareProperty("LowPtThreshold", m_lowpt_threshold);
89 declareProperty("UncorrelateSystematics", m_seperateSystBins);
90 declareProperty("BreakDownSystematics", m_breakDownSyst);
93 declareProperty("CloseJetDRDecorator", m_iso_jet_dR);
94 declareProperty("Use2DIsoCorrections", m_use2DIsoCorr);
96 declareProperty("UseLRT", m_useLRT);
97 }
100 return m_iso_jet_dR;
101 }
113 return m_sf_decoration_name.empty() ? std::string("SF") + m_wp : m_sf_decoration_name;
114 }
116 return m_efficiency_decoration_name_data.empty() ? std::string("DataEffi") + m_wp : m_efficiency_decoration_name_data;
117 }
119 return m_efficiency_decoration_name_mc.empty() ? std::string("MCEffi") + m_wp : m_efficiency_decoration_name_mc;
120 }
122 return std::string("Replica") + sf_decoration();
123 }
125 return std::string("Replica") + data_effi_decoration();
126 }
128 return std::string("Replica") + mc_effi_decoration();
129 }
131 size_t i = 0;
132 for (const auto& sf: m_sf_sets) {
133 if (sf.get() == coll) return i;
134 ++i;
135 }
136 return i;
137 }
139 return m_sf_sets.size();
140 }
142 return m_useLRT;
143 }
145 if (m_init) {
146 ATH_MSG_INFO("The tool using working point " << m_wp << " is already initialized.");
147 return StatusCode::SUCCESS;
148 }
149 if (m_wp.find("Iso") != std::string::npos) {
151
152 } else if (m_wp.find("BadMuon") != std::string::npos) {
155 m_applyKineDepSys = true;
156 } else if (m_wp.find("TTVA") != std::string::npos) {
158 } else {
160 if (m_useLRT && m_wp!="Medium") {
161 ATH_MSG_FATAL(Form("Only Medium identification WP is supported for LRT muons. You chose %s.", m_wp.c_str()));
162 return StatusCode::FAILURE;
163 }
164 }
165 ATH_MSG_INFO("Efficiency type is = " << EfficiencyTypeName(m_Type));
166
167 // temporary workaround to avoid bad Jpsi scale factors
168 if (m_lowpt_threshold < 0) { // not set by the user, use default values
169 if (m_calibration_version.find("run3") != std::string::npos) {
170 m_lowpt_threshold = 1e4;
171 } else {
172 m_lowpt_threshold = 15e3;
173 }
174 }
175
179 ATH_MSG_DEBUG("We are running Isolation or TTVA or High Pt reco SF, so we use Zmumu based SF for the whole pt range!");
181 } else if (m_lowpt_threshold <= 0) {
182 ATH_MSG_INFO("Low pt SF turned off as crossover threshold is negative! Using Zmumu based SF for all pt values.");
183 } else {
184 ATH_MSG_INFO("JPsi based low pt SF will start to rock below " << m_lowpt_threshold / 1000. << " GeV!");
185 }
186
187 std::set<std::string> decorations{
188 sf_decoration() ,
194 };
195 if (decorations.size() != 6){
196 ATH_MSG_FATAL("At least one of the decoration names for scale-factor/ data-efficiency / mc-efficiency is not uniquely defined... Please check your properties");
197 return StatusCode::FAILURE;
198 }
199
200 ATH_CHECK(m_eventInfo.initialize());
201
202 if (!m_custom_dir.empty()) ATH_MSG_WARNING("Note: setting up with user specified input file location " << m_custom_dir << " - this is not encouraged!");
203 if (!m_custom_file_Calo.empty()) ATH_MSG_WARNING("Note: setting up with user specified CaloTag input file " << m_custom_file_Calo << " - this is not encouraged!");
204 if (!m_custom_file_Combined.empty()) ATH_MSG_WARNING("Note: setting up with user specified Central muon input file " << m_custom_file_Combined << " - this is not encouraged! ");
205 if (!m_custom_file_HighEta.empty()) ATH_MSG_WARNING("Note: setting up with user specified High Eta input file " << m_custom_file_HighEta << " - this is not encouraged! ");
206 if (!m_custom_file_LowPt.empty()) ATH_MSG_WARNING("Note: setting up with user specified Low Pt input file " << m_custom_file_LowPt << " - this is not encouraged! ");
207 if (!m_custom_file_LowPtCalo.empty()) ATH_MSG_WARNING("Note: setting up with user specified Low Pt CaloTag input file " << m_custom_file_LowPtCalo << " - this is not encouraged! ");
208 if (!m_custom_file_LRTCombined.empty()) ATH_MSG_WARNING("Note: setting up with user specified Central LRT muon input file " << m_custom_file_LRTCombined << " - this is not encouraged! ");
209 if (!m_custom_file_LRTLowPt.empty()) ATH_MSG_WARNING("Note: setting up with user specified Low Pt LRT muon input file " << m_custom_file_LowPt << " - this is not encouraged! ");
210 if (m_custom_dir.empty()) ATH_MSG_INFO("Trying to initialize, with working point " << m_wp << ", using calibration release " << m_calibration_version);
211
213
214 // m_init has to be true for affectingSystematics()
215 m_init = true;
217 // set up for default running without systematics
219 ATH_MSG_ERROR("loading the central value systematic set failed");
220 return StatusCode::FAILURE;
221 }
222
223 // Add the affecting systematics to the global registry
225 if (!registry.registerSystematics(*this)) {
226 ATH_MSG_ERROR("unable to register the systematics");
227 return StatusCode::FAILURE;
228 }
229 ATH_MSG_INFO("Successfully initialized! ");
230
231 for (auto& sf_set : m_sf_sets)
232 addSubtool (*sf_set);
233 ATH_CHECK (initializeColumns());
234 return StatusCode::SUCCESS;
235 }
237 if (!info) {
239 info = evtInfo.operator->();
240 if (!info) {
241 ATH_MSG_ERROR("Could not retrieve the xAOD::EventInfo. Return 999999");
242 return 999999;
243 }
244 }
246 }
248 const auto& acc = *m_accessors;
249 if (!acc.eventTypeAcc(info,xAOD::EventInfo::IS_SIMULATION)) {
250 ATH_MSG_DEBUG("The current event is a data event. Return runNumber instead.");
251 return acc.runNumberAcc (info);
252 }
253 if (!acc.acc_rnd.isAvailable(info)) {
254 ATH_MSG_WARNING("Failed to find the RandomRunNumber decoration. Please call the apply() method from the PileupReweightingTool before hand in order to get period dependent SFs. You'll receive SFs from the most recent period.");
255 return 999999;
256 } else if (acc.acc_rnd(info) == 0) {
257 ATH_MSG_DEBUG("Pile up tool has given runNumber 0. Return SF from latest period.");
258 return 999999;
259 }
260 return acc.acc_rnd(info);
261 }
263 if (!m_init) {
264 ATH_MSG_ERROR("The tool has not been initialized yet.");
266 }
267 if (!info) {
269 info = evtInfo.operator->();
270 if (!info) {
271 ATH_MSG_ERROR("Could not retrieve the xAOD::EventInfo. Return 999999");
273 }
274 }
276 }
278 if (!m_init) {
279 ATH_MSG_ERROR("The tool has not been initialized yet.");
281 }
282 unsigned int RunNumber = getRandomRunNumber(info);
283 return m_current_sf->retrieveSF(mu, RunNumber)->ScaleFactor(mu, sf);
284 }
286 if (!m_init) {
287 ATH_MSG_ERROR("The tool has not been initialized yet");
289 }
290 unsigned int RunNumber = getRandomRunNumber(info);
291 return m_current_sf->retrieveSF(mu, RunNumber)->ApplyScaleFactor(mu);
292 }
293
295 if (!m_init) {
296 ATH_MSG_ERROR("The tool has not been initialized yet");
298 }
299 unsigned int RunNumber = getRandomRunNumber(info);
300 return m_current_sf->retrieveSF(mu, RunNumber)->ScaleFactorReplicas(mu, sfs);
301 }
303 if (!m_init) {
304 ATH_MSG_ERROR("The tool has not been initialized yet");
306 }
307 unsigned int RunNumber = getRandomRunNumber(info);
308 return m_current_sf->retrieveSF(mu, RunNumber)->ApplyScaleFactorReplicas(mu, nreplicas);
309 }
311 if (!m_init) {
312 ATH_MSG_ERROR("The tool has not been initialized yet");
314 }
315 unsigned int RunNumber = getRandomRunNumber(info);
316 return m_current_sf->retrieveSF(mu, RunNumber)->DataEfficiency(mu, eff);
317 }
319 if (!m_init) {
320 ATH_MSG_ERROR("The tool has not been initialized yet");
322 }
323 unsigned int RunNumber = getRandomRunNumber(info);
324 return m_current_sf->retrieveSF(mu, RunNumber)->ApplyDataEfficiency(mu);
325 }
326 CorrectionCode MuonEfficiencyScaleFactors::getDataEfficiencyReplicas(const xAOD::Muon& mu, std::vector<float> & sf_err, const xAOD::EventInfo* info) const {
327 if (!m_init) {
328 ATH_MSG_ERROR("The tool has not been initialized yet");
330 }
331 unsigned int RunNumber = getRandomRunNumber(info);
332 return m_current_sf->retrieveSF(mu, RunNumber)->DataEfficiencyReplicas(mu, sf_err);
333 }
335 if (!m_init) {
336 ATH_MSG_ERROR("The tool has not been initialized yet");
338 }
339 unsigned int RunNumber = getRandomRunNumber(info);
340 return m_current_sf->retrieveSF(mu, RunNumber)->ApplyDataEfficiencyReplicas(mu, nreplicas);
341 }
343 if (!m_init) {
344 ATH_MSG_ERROR("The tool has not been initialized yet");
346 }
347 unsigned int RunNumber = getRandomRunNumber(info);
348 return m_current_sf->retrieveSF(mu, RunNumber)->MCEfficiency(mu, eff);
349 }
351 if (!m_init) {
352 ATH_MSG_ERROR("The tool has not been initialized yet");
354 }
355 unsigned int RunNumber = getRandomRunNumber(info);
356 return m_current_sf->retrieveSF(mu, RunNumber)->ApplyMCEfficiency(mu);
357 }
358 CorrectionCode MuonEfficiencyScaleFactors::getMCEfficiencyReplicas(const xAOD::Muon& mu, std::vector<float> & sf_err, const xAOD::EventInfo* info) const {
359 if (!m_init) {
360 ATH_MSG_ERROR("The tool has not been initialized yet");
362 }
363 unsigned int RunNumber = getRandomRunNumber(info);
364 return m_current_sf->retrieveSF(mu, RunNumber)->MCEfficiencyReplicas(mu, sf_err);
365 }
367 if (!m_init) {
368 ATH_MSG_ERROR("The tool has not been initialized yet");
370 }
371 unsigned int RunNumber = getRandomRunNumber(info);
372 return m_current_sf->retrieveSF(mu, RunNumber)->ApplyMCEfficiencyReplicas(mu, nreplicas);
373 }
374
375 std::string MuonEfficiencyScaleFactors::resolve_file_location(const std::string &filename) const{
376 if (!m_custom_dir.empty()) {
377 return m_custom_dir + "/" + filename;
378 }
379 std::string fullPathToFile = PathResolverFindCalibFile(Form("MuonEfficiencyCorrections/%s/%s", m_calibration_version.c_str(), filename.c_str()));
380 if (fullPathToFile.empty()) {
381 ATH_MSG_ERROR("Unable to resolve the input file " << m_calibration_version << "/" << filename << " via the PathResolver!");
382 }
383 return fullPathToFile;
384 }
388 return resolve_file_location(Form("Iso_%s_Z.root", m_wp.c_str()));
389 } else if (m_Type == CP::MuonEfficiencyType::TTVA) {
390 return resolve_file_location("TTVA_Z.root");
392 return resolve_file_location("BadMuonVeto_HighPt_Z.root");
393 } else if (m_Type == CP::MuonEfficiencyType::Reco) {
394 return resolve_file_location(Form("Reco_%s_Z.root", m_wp.c_str()));
395 }
396 ATH_MSG_ERROR("What?");
397 return "";
398 }
402 ATH_MSG_WARNING("Using standard isolation SF for LRT muons");
403 return resolve_file_location(Form("Iso_%s_Z.root", m_wp.c_str()));
404 } else if (m_Type == CP::MuonEfficiencyType::TTVA) {
405 ATH_MSG_WARNING("Using standard TTVA SF for LRT muons");
406 return resolve_file_location("TTVA_Z.root");
408 ATH_MSG_WARNING("Using standard BadMuonVeto SF for LRT muons");
409 return resolve_file_location("BadMuonVeto_HighPt_Z.root");
410 } else if (m_Type == CP::MuonEfficiencyType::Reco) {
411 return resolve_file_location(Form("Reco_%sLRT_Z.root", m_wp.c_str()));
412 }
413 ATH_MSG_ERROR("What?");
414 return "";
415 }
417
420 return filename_Central();
421 } else return resolve_file_location("Reco_CaloTag_Z.root"); //note that in rel22 we switched from CaloTag to CaloScore. Now, we're not updating the filename yet to ensure backward compatibility, but it must be clear that in rel22 calibration areas this file will actually contain the CaloScore SFs.
422 }
424
427 return filename_Central();
428 } else return resolve_file_location("Reco_HighEta_Z.root");
429 }
431
433 // for the no reco WPs, we currently use the existing Z SF also for the low pt regime
435 return filename_Central();
436 } else return resolve_file_location(Form("Reco_%s_JPsi.root", m_wp.c_str()));
437 }
439
441 // we use the Z SF for the low pt regime for Run-3
442 else if (m_Type != CP::MuonEfficiencyType::Reco || m_lowpt_threshold < 0 || m_calibration_version.find("run3") != std::string::npos) {
443 return filename_LRTCentral();
444 } else return resolve_file_location(Form("Reco_%sLRT_JPsi.root", m_wp.c_str()));
445 }
447
449 // for the no reco WPs, we currently use the existing Z SF also for the low pt regime
451 return filename_Central();
452 } else return resolve_file_location("Reco_CaloTag_JPsi.root"); //note that in rel22 we switched from CaloTag to CaloScore. Now, we're not updating the filename yet to ensure backward compatibility, but it must be clear that in rel22 calibration areas this file will actually contain the CaloScore SFs.
453 }
454 // load the SF histos
455
457 if (!m_sf_sets.empty()){
458 ATH_MSG_DEBUG("Input already loaded will not do it again");
459 return StatusCode::SUCCESS;
460 }
461 std::map<std::string, unsigned int> systematics = lookUpSystematics();
464 if (systematics.empty()){
465 ATH_MSG_FATAL("No valid systematic could be loaded. Not even the statistical uncertainties");
466 return StatusCode::FAILURE;
467 }
468
470 m_sf_sets.push_back( std::make_unique<EffiCollection>(*this));
471 EffiCollection* nominal = m_sf_sets.back().get();
472
473 std::function<unsigned int(unsigned int, unsigned int)> not_inB = [](unsigned int a , unsigned int b){
474 unsigned int b_flipped = ~b;
475 return a & b_flipped;
476 };
478 for (const auto& syst: systematics){
480 if ((syst.second & EffiCollection::ZAnalysis) && (syst.second & EffiCollection::JPsiAnalysis)) {
482 m_sf_sets.push_back(std::make_unique < EffiCollection > (nominal, *this, syst.first, not_inB(syst.second, EffiCollection::ZAnalysis), false));
483 m_sf_sets.push_back(std::make_unique < EffiCollection > (nominal, *this, syst.first, not_inB(syst.second, EffiCollection::ZAnalysis), true));
485 m_sf_sets.push_back(std::make_unique < EffiCollection > (nominal, *this, syst.first, not_inB(syst.second, EffiCollection::JPsiAnalysis), true));
486 m_sf_sets.push_back(std::make_unique < EffiCollection > (nominal, *this, syst.first, not_inB(syst.second, EffiCollection::JPsiAnalysis), false));
487 } else {
488 m_sf_sets.push_back(std::make_unique < EffiCollection > (nominal, *this, syst.first, syst.second, false));
489 m_sf_sets.push_back(std::make_unique < EffiCollection > (nominal, *this, syst.first, syst.second, true));
490 }
491 }
492 for(auto& sf: m_sf_sets){
493 if (!sf->CheckConsistency()) {
494 ATH_MSG_FATAL("Inconsistent scalefactor maps have been found for "<<(sf->getSystSet() ?sf->getSystSet()->name() : "UNKOWN"));
495 return StatusCode::FAILURE;
496 }
497 }
498 for (auto& sf_set : m_sf_sets)
499 addSubtool (*sf_set);
500 return StatusCode::SUCCESS;
501 }
502 std::map<std::string, unsigned int> MuonEfficiencyScaleFactors::lookUpSystematics(){
503 std::map<std::string, unsigned int> syst_map;
506 std::set<std::string> files_to_look_up{
512 };
513 if (m_useLRT) {
514 files_to_look_up.insert(filename_LRTCentral());
515 files_to_look_up.insert(filename_LRTLowPt());
516 }
517 std::function<int(const std::string&)> get_bit = [this](const std::string& file_name){
518 if (file_name == filename_Central()) return EffiCollection::Central;
519 if (file_name == filename_LowPt()) return EffiCollection::CentralLowPt;
520 if (file_name == filename_Calo()) return EffiCollection::Calo;
521 if (file_name == filename_LowPtCalo()) return EffiCollection::CaloLowPt;
522 if (this->use_lrt()) {
523 if (file_name == filename_LRTCentral()) return EffiCollection::Central;
524 if (file_name == filename_LRTLowPt()) return EffiCollection::CentralLowPt;
525 }
526 // last file which remains is forward
528 };
529
530 std::function<void(const std::string&,int)> insert_bit =[&syst_map](const std::string& key, unsigned int bit){
531 if (syst_map.find(key) == syst_map.end()) syst_map.insert(std::pair<std::string, unsigned int>(key,bit));
532 else syst_map[key] = syst_map[key] | bit;
533 };
534 for (const auto& look_up : files_to_look_up){
535 std::unique_ptr<TFile> root_file(TFile::Open(look_up.c_str(), "READ"));
536 if (!root_file || !root_file->IsOpen()){
537 ATH_MSG_FATAL("Could not open file "<<look_up);
538 syst_map.clear();
539 break;
540 }
544 insert_bit("STAT", get_bit(look_up));
545 }
547 if (m_seperateSystBins) insert_bit("STAT", EffiCollection::UnCorrelated);
548
549 TTree* syst_tree = nullptr;
550 root_file->GetObject("Systematics", syst_tree);
551
554 if (!m_breakDownSyst || syst_tree == nullptr){
555 ATH_MSG_DEBUG("The file "<<look_up<<" does not contain any systematic tree. No break down for that one will be considered");
556 insert_bit("SYS",get_bit(look_up));
559 insert_bit("SYS", EffiCollection::PtDependent);
560 }
561 continue;
562 }
564 std::string* syst_name = nullptr;
565 bool is_symmetric(0), has_pt_sys(0), uncorrelated(0);
566 if (syst_tree->SetBranchAddress("Name", &syst_name) != 0 ||
567 syst_tree->SetBranchAddress("IsSymmetric", &is_symmetric) != 0 ||
568 syst_tree->SetBranchAddress("HasPtDependentSys", &has_pt_sys) !=0 ||
569 syst_tree->SetBranchAddress("CanBeUncorrelated", &uncorrelated) !=0){
570
571
572 ATH_MSG_FATAL("Although "<<look_up<<" has a systematic tree. There is no proper connection to the branches");
573 syst_map.clear();
574 break;
575 }
576 for (int i =0; syst_tree->GetEntry(i); ++i){
577 insert_bit( *syst_name, get_bit(look_up));
578 if (is_symmetric) insert_bit(*syst_name, EffiCollection::Symmetric);
579
580 if (m_applyKineDepSys && has_pt_sys) {
581 insert_bit(*syst_name, EffiCollection::PtDependent);
582 }if (m_seperateSystBins && uncorrelated) insert_bit(*syst_name, EffiCollection::UnCorrelated);
583 }
584 }
585 return syst_map;
586 }
588 return m_affectingSys.find(systematic) != m_affectingSys.end();
589 }
590
592 if (!m_affectingSys.empty()) return m_affectingSys;
594 for (auto& collection : m_sf_sets){
595 if (!collection->getSystSet()){
596 ATH_MSG_FATAL("No systematic defined for scale-factor map. ");
597 return SystematicSet();
598 }
599 result.insert(*collection->getSystSet());
600 }
601 return result;
602 }
603
606 if (!m_init) {
607 ATH_MSG_ERROR("The tool has not been initialized yet");
608 return CP::SystematicSet();
609 }
610 return affectingSystematics();
611 }
613 if (!m_init) {
614 ATH_MSG_ERROR("Initialize first the tool!");
615 return StatusCode::FAILURE;
616 }
617
618 //check if systematics is cached
619 std::unordered_map<CP::SystematicSet, EffiCollection*>::const_iterator itr = m_filtered_sys_sets.find (systConfig);
620
621 SystematicSet mySysConf(systConfig);
622
623 if (itr == m_filtered_sys_sets.end()) {
625 ATH_MSG_ERROR("Unsupported combination of systematics passed to the tool! ");
626 return StatusCode::FAILURE;
627 }
628 itr = m_filtered_sys_sets.find(mySysConf);
629 }
630
631 // No cache is available
632 if (itr == m_filtered_sys_sets.end()){
633 std::vector<std::unique_ptr<EffiCollection>>::const_iterator coll_itr = std::find_if(m_sf_sets.begin(), m_sf_sets.end(),[&mySysConf](const std::unique_ptr<EffiCollection>& a){return a->isAffectedBySystematic(mySysConf);});
634 if (coll_itr == m_sf_sets.end()){
635 ATH_MSG_WARNING("Invalid systematic given.");
636 return StatusCode::FAILURE;
637 }
638 m_filtered_sys_sets.insert(std::pair<SystematicSet, EffiCollection*>(systConfig, coll_itr->get()));
639 itr = m_filtered_sys_sets.find(systConfig);
640 }
641 m_current_sf = itr->second;
642
643 if (m_seperateSystBins && !itr->first.name().empty()){
644 for (std::set<SystematicVariation>::const_iterator t = mySysConf.begin(); t != mySysConf.end(); ++t) {
645 if ((*t).isToyVariation()) {
646 // First entry corresponds to the bin number and
647 // the second entry to the position in which the map is ordered
648 // into the m_sf_sets container
649 std::pair<unsigned, float> pair = (*t).getToyVariation();
650 if (pair.first != 0 && !m_current_sf->SetSystematicBin(pair.first)){
651 ATH_MSG_WARNING("Could not apply systematic " << (*t).name() << " for bin " << pair.first);
652 return StatusCode::FAILURE;
653 }
654 return StatusCode::SUCCESS;
655 }
656 }
657 }
658 return StatusCode::SUCCESS;
659 }
660 std::string MuonEfficiencyScaleFactors::getUncorrelatedSysBinName(unsigned int Bin) const {
661 if (!m_current_sf){
662 throw std::runtime_error("No systematic has been loaded. Cannot return any syst-bin") ;
663 ATH_MSG_FATAL("No systematic has been loaded. Cannot return any syst-bin");
664
665 }
666 return m_current_sf->GetBinName(Bin);
667 }
669 if (!m_current_sf){
670 ATH_MSG_WARNING("No systematic has been loaded. Cannot return any syst-bin");
671 return -1;
672 }
673 return m_current_sf->getUnCorrelatedSystBin(mu);
674 }
676 for (std::set<SystematicVariation>::const_iterator t = systConfig.begin(); t != systConfig.end(); ++t) {
677 if ((*t).isToyVariation()) {
678 std::pair<unsigned, float> pair = (*t).getToyVariation();
679 return getUncorrelatedSysBinName(pair.first);
680 }
681 }
682 ATH_MSG_ERROR("The given systematic " << systConfig.name() << " is not an unfolded one. Return unknown bin ");
683 return "unknown bin";
684 }
685
687 {
688 const auto& acc = *m_accessors;
689 for (columnar::MuonId muon : muons)
690 {
691 float sf = 0;
692 switch (getEfficiencyScaleFactor(muon, sf, event).code())
693 {
695 acc.sfDec(muon) = sf;
696 acc.validDec(muon) = true;
697 break;
699 acc.sfDec(muon) = sf;
700 acc.validDec(muon) = false;
701 break;
702 default:
703 throw std::runtime_error("Error in getEfficiencyScaleFactor");
704 }
705 }
706 }
707
709 const auto& acc = *m_accessors;
710 for (columnar::EventContextId event : events)
711 {
712 auto eventInfo = acc.eventInfoCol(event);
713 callSingleEvent (acc.muons(event), eventInfo);
714 }
715 }
716
717} /* namespace CP */
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading from StoreGate.
static Double_t a
static const std::vector< std::string > systematics
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
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.
The EffiCollection class handles the 5 different scale-factor maps binned in time.
@ JPsiAnalysis
Distinguish these two because the systematics are named with an extra LOWPT.
@ Central
The five different scale-factor maps.
std::string filename_LRTCentral() const
LRT muons have their own efficiency maps.
bool uncorrelate_sys() const
Returns a boolean whether the uncorrelation of systematics has been switched on.
std::string filename_HighEta() const
High-eta reconstruction scale-factors are not obtained by the means of are not obtained by the means ...
std::string resolve_file_location(const std::string &filename) const
utility method to 'dress' a filename using the path resolver
virtual SystematicSet recommendedSystematics() const override
returns: the list of all systematics this tool recommends to use
virtual int getUnCorrelatedSystBin(const xAOD::Muon &mu) const override
virtual CorrectionCode getDataEfficiencyReplicas(const xAOD::Muon &mu, std::vector< float > &sf_err, const xAOD::EventInfo *info=0) const
virtual CorrectionCode getMCEfficiency(const xAOD::Muon &mu, float &eff, const xAOD::EventInfo *info=0) const override
Obtain the muon efficiency measured using the MC.
virtual StatusCode applySystematicVariation(const SystematicSet &systConfig) override
effects: configure this tool for the given list of systematic variations.
virtual CorrectionCode getMCEfficiencyReplicas(const xAOD::Muon &mu, std::vector< float > &sf_err, const xAOD::EventInfo *info=0) const
virtual CorrectionCode applyEfficiencyScaleFactorReplicas(const xAOD::Muon &mu, int nreplicas=50, const xAOD::EventInfo *info=0) const override
decorate the muon with a set of SF replica weights.
virtual std::string getUncorrelatedSysBinName(unsigned int Bin) const override
float m_lowpt_threshold
threshold below which low-pt SF (i.e. from JPsi) should be used
virtual CorrectionCode applyMCEfficiency(const xAOD::Muon &mu, const xAOD::EventInfo *info=0) const override
std::string filename_Calo() const
Reconstruction scale-factors have a dedicated map for calo-tag muons around |\eta|<0....
std::map< std::string, unsigned int > lookUpSystematics()
Scale-factor files since Moriond2019 contain the breakdown of systematics into their individual compo...
std::string m_wp
the working point to operate on
std::string sf_decoration() const
The apply<Blah> methods decorate their result directly to the muon.
virtual SystematicSet affectingSystematics() const override
returns: the list of all systematics this tool can be affected by
std::unique_ptr< Accessors > m_accessors
std::unordered_map< CP::SystematicSet, EffiCollection * > m_filtered_sys_sets
It turned out that the code spends a large time in the look up of the systematics.
bool use_2D_iso_corrections() const
option to set if we want to use 1D or 2D isolation SFs
void callSingleEvent(columnar::MuonRange muons, columnar::EventInfoId event) const
virtual CorrectionCode applyDataEfficiency(const xAOD::Muon &mu, const xAOD::EventInfo *info=0) const override
decorate a muon with the efficiency information
virtual CorrectionCode applyEfficiencyScaleFactor(const xAOD::Muon &mu, const xAOD::EventInfo *info=0) const override
decorate the muon with scale factor information
std::vector< std::unique_ptr< EffiCollection > > m_sf_sets
This vector stores all scale-factor maps.
unsigned int getRandomRunNumber(const xAOD::EventInfo *info) const
std::string filename_Central() const
The following methods are meant to propagate information from the central tool to the subtool managin...
virtual CorrectionCode getEfficiencyScaleFactorReplicas(const xAOD::Muon &mu, std::vector< float > &sf_err, const xAOD::EventInfo *info=0) const override
replica generation
virtual StatusCode initialize() override
initialize the tool once all settings are in place!
size_t getNCollections() const
Returns the number of EffiCollections stored in this class.
std::string m_iso_jet_dR
Name of the decoration to catch up the close by jets.
float lowPtTransition() const
If the pt of the muon is below that threshold the J/Psi or Upsilon map is used given that it's availa...
EffiCollection * m_current_sf
Pointer to the current active map in terms of systematics.
virtual bool isAffectedBySystematic(const SystematicVariation &systematic) const override
returns: whether this tool is affected by the given systematis
virtual CorrectionCode applyDataEfficiencyReplicas(const xAOD::Muon &mu, int nreplicas=50, const xAOD::EventInfo *info=0) const
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfo
size_t getPosition(const EffiCollection *coll) const
Returns the position of the collection in the syst set vector.
virtual CorrectionCode getDataEfficiency(const xAOD::Muon &mu, float &eff, const xAOD::EventInfo *info=0) const override
Obtain the muon efficiency measured using the data.
CP::MuonEfficiencyType measurement() const
Returns the type of the measurement to be carried out... E.g. Reco/TTVA/Iso.
virtual void callEvents(columnar::EventContextRange events) const override
virtual CorrectionCode applyMCEfficiencyReplicas(const xAOD::Muon &mu, int nreplicas=50, const xAOD::EventInfo *info=0) const
bool use_lrt() const
option to set if we want to use LRT muons
std::string filename_LowPt() const
Returns the scale-factor maps from a complementary scale-factor measurement using the J/Psi or Upsilo...
virtual CorrectionCode getEfficiencyScaleFactor(const xAOD::Muon &mu, float &sf, const xAOD::EventInfo *info=0) const override
Retrieve the Scale factor and decorate the muon.
std::string m_calibration_version
subfolder to load from the calibration db
const std::string & close_by_jet_decoration() const
Returns the string telling the tool in which float AuxElement the information of the separation to th...
bool m_useLRT
Turn on if using LRT objects.
MuonEfficiencyScaleFactors(const std::string &name)
StatusCode LoadInputs()
load the SF histos
This module implements the central registry for handling systematic uncertainties with CP tools.
static SystematicRegistry & getInstance()
Get the singleton instance of the registry for the curren thread.
StatusCode registerSystematics(const IReentrantSystematicsTool &tool)
effects: register all the systematics from the tool
Class to wrap a set of SystematicVariations.
std::string name() const
returns: the systematics joined into a single string.
const_iterator end() const
description: const iterator to the end of the set
const_iterator begin() const
description: const iterator to the beginning of the set
static StatusCode filterForAffectingSystematics(const SystematicSet &systConfig, const SystematicSet &affectingSystematics, SystematicSet &filteredSystematics)
description: filter the systematics for the affected systematics returns: success guarantee: strong f...
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
the base class for all columnar components
STL class.
@ IS_SIMULATION
true: simulation, false: data
Select isolated Photons, Electrons and Muons.
static std::string EfficiencyTypeName(CP::MuonEfficiencyType M)
ObjectId< ContainerId::muon > MuonId
Definition MuonDef.h:25
AccessorTemplate< ContainerId::eventInfo, CT, ColumnAccessMode::input, CM > EventInfoAccessor
AccessorTemplate< ContainerId::muon, CT, ColumnAccessMode::output, CM > MuonDecorator
Definition MuonDef.h:28
ObjectRange< ContainerId::eventContext > EventContextRange
ObjectId< ContainerId::eventContext > EventContextId
ObjectRange< ContainerId::muon > MuonRange
Definition MuonDef.h:24
ObjectId< ContainerId::eventInfo > EventInfoId
AccessorTemplate< ContainerId::muon, CT, ColumnAccessMode::input, CM > MuonAccessor
Definition MuonDef.h:27
EventInfo_v1 EventInfo
Definition of the latest event info version.
setRawEt setRawPhi int
Muon_v1 Muon
Reference the current persistent version:
static const SG::AuxElement::Accessor< ElementLink< IParticleContainer > > acc("originalObjectLink")
Object used for setting/getting the dynamic decoration in question.
columnar::EventInfoAccessor< uint32_t > runNumberAcc
columnar::EventInfoAccessor< unsigned int > acc_rnd
columnar::EventInfoHelpers::EventTypeAccessor eventTypeAcc
columnar::EventInfoAccessor< columnar::ObjectColumn > eventInfoCol
columnar::MuonAccessor< columnar::ObjectColumn > muons