18namespace ADD_CMODE(CP)
21 MuonCalibTool::MuonCalibTool(
const std::string &name) :
asg::AsgTool(name){
24 m_MuonSelectionTool.declarePropertyFor(
this,
"MuonSelectionTool",
"Instance of the MuonSelectionTool needed for the HighPt categorization");
25 m_MuonIntSagittaTool.declarePropertyFor(
this,
"SagittaTool",
"Instance of the Sagitta bias corrections sub tool");
26 m_MuonIntScaleSmearTool.declarePropertyFor(
this,
"ScaleAndSmearTool",
"Instance of the tool that applies the smearing & scale corrections");
27 m_MuonIntHighTSmearTool.declarePropertyFor(
this,
"HighPtSmearingTool",
"Extra smearing of the high pt working point");
30 StatusCode MuonCalibTool::initialize()
39 if (m_calibMode == MuonCalibTool::correctData_CB) {
40 ATH_MSG_INFO(
"Data will be corrected for sagitta bias and Montecarlo will be corrected using CB calibration");
41 m_applyCorrectionOnData =
true;
42 }
else if (m_calibMode == MuonCalibTool::correctData_IDMS) {
43 ATH_MSG_INFO(
"Data will be corrected for sagitta bias and Montecarlo will be corrected using ID+MS calibration");
44 m_applyCorrectionOnData =
true;
45 }
else if (m_calibMode == MuonCalibTool::notCorrectData_IDMS) {
46 ATH_MSG_INFO(
"Data will be untouched (no sagitta bias corrections) and Montecarlo will be corrected using ID+MS calibration");
47 m_applyCorrectionOnData =
false;
48 }
else if (m_calibMode == MuonCalibTool::notCorrectData_CB) {
49 ATH_MSG_INFO(
"Data will be untouched (no sagitta bias corrections) and Montecarlo will be corrected using CB calibration");
50 m_applyCorrectionOnData =
false;
51 }
else if (m_calibMode == MuonCalibTool::correctData_IDonly) {
52 ATH_MSG_INFO(
"Data will be corrected for sagitta bias and Montecarlo will be corrected using ID calibration only");
53 m_applyCorrectionOnData =
true;
54 }
else if (m_calibMode == MuonCalibTool::correctData_MSonly) {
55 ATH_MSG_INFO(
"Data will be corrected for sagitta bias and Montecarlo will be corrected using MS calibration only");
56 m_applyCorrectionOnData =
true;
57 }
else if (m_calibMode == MuonCalibTool::userDefined) {
61 ATH_MSG_FATAL(
"Invalid calibration mode: " << m_calibMode <<
" Allowed modes are correctData_CB("
62 << MuonCalibTool::correctData_CB <<
") correctData_IDMS ("
63 << MuonCalibTool::correctData_IDMS <<
") or notCorrectData_IDMS ("
64 << MuonCalibTool::notCorrectData_IDMS <<
") or notCorrectData_CB ("
65 << MuonCalibTool::notCorrectData_CB <<
") or correctData_IDonly ("
66 << MuonCalibTool::correctData_IDonly <<
") or correctData_MSonly ("
67 << MuonCalibTool::correctData_MSonly <<
")");
68 return StatusCode::FAILURE;
71 if (!m_skipResolutionCategory.value())
74 if (m_MuonSelectionTool.empty()) {
75 m_MuonSelectionTool.setTypeAndName(
"CP::MuonSelectionTool/MCaST_Own_MST");
76 ATH_CHECK(m_MuonSelectionTool.setProperty(
"MaxEta", 2.7));
77 ATH_CHECK(m_MuonSelectionTool.setProperty(
"MuQuality", 1));
78 ATH_CHECK(m_MuonSelectionTool.setProperty(
"TurnOffMomCorr",
true));
79 ATH_CHECK(m_MuonSelectionTool.setProperty(
"IsRun3Geo", m_isRun3.value()));
80 ATH_CHECK(m_MuonSelectionTool.setProperty(
"OutputLevel",
msg().level()));
81 ATH_CHECK(m_MuonSelectionTool.setProperty(
"ExcludeNSWFromPrecisionLayers", m_excludeNSWFromPrecisionLayers.value()));
83 ATH_CHECK(m_MuonSelectionTool.retrieve());
85 addSubtool (*selectionTool);
89 if (m_MuonIntSagittaTool.empty()) {
90 m_MuonIntSagittaTool.setTypeAndName(
columnar::add_cmode(
"CP") +
"::MuonCalibIntSagittaTool/" + name() +
"_MCaST_Sagitta");
91 ATH_CHECK(m_MuonIntSagittaTool.setProperty(
"release", m_release.value()));
92 ATH_CHECK(m_MuonIntSagittaTool.setProperty(
"systematicScheme", m_sysScheme.value()));
93 ATH_CHECK(m_MuonIntSagittaTool.setProperty(
"calibMode", m_calibMode));
94 ATH_CHECK(m_MuonIntSagittaTool.setProperty(
"doEtaSagittaSys", m_doEtaSagittaSys.value()));
95 ATH_CHECK(m_MuonIntSagittaTool.setProperty(
"OutputLevel",
msg().level()));
97 ATH_CHECK(m_MuonIntSagittaTool.retrieve());
100 if (m_MuonIntScaleSmearTool.empty()) {
101 m_MuonIntScaleSmearTool.setTypeAndName(
columnar::add_cmode(
"CP") +
"::MuonCalibIntScaleSmearTool/" + name() +
"_MCaST_ScaleSmear");
102 ATH_CHECK(m_MuonIntScaleSmearTool.setProperty(
"release", m_release.value()));
103 ATH_CHECK(m_MuonIntScaleSmearTool.setProperty(
"systematicScheme", m_sysScheme.value()));
104 ATH_CHECK(m_MuonIntScaleSmearTool.setProperty(
"calibMode", m_calibMode));
105 ATH_CHECK(m_MuonIntScaleSmearTool.setProperty(
"OutputLevel",
msg().level()));
107 ATH_CHECK(m_MuonIntScaleSmearTool.retrieve());
110 if (m_extra_highpt_smearing || m_2stations_highpt_smearing) {
111 if (m_MuonIntHighTSmearTool.empty()) {
112 m_MuonIntHighTSmearTool.setTypeAndName(
columnar::add_cmode(
"CP") +
"::MuonCalibIntHighpTSmearTool/" + name() +
"_MCaST_highPtScaleSmear");
113 ATH_CHECK(m_MuonIntHighTSmearTool.setProperty(
"release", m_release.value()));
114 ATH_CHECK(m_MuonIntHighTSmearTool.setProperty(
"OutputLevel",
msg().level()));
116 ATH_CHECK(m_MuonIntHighTSmearTool.retrieve());
117 m_MuonIntHighTSmearToolInitialized = !m_MuonIntHighTSmearTool.empty();
122 return StatusCode::FAILURE;
125 if (registry.registerSystematics(*
this) != StatusCode::SUCCESS)
128 return StatusCode::FAILURE;
132 return StatusCode::SUCCESS;
145 ATH_MSG_VERBOSE(
"Muon Type = " << mu(acc.muonTypeAcc) <<
" ( 0: Combined, 1: StandAlone, 2: SegmentTagged, 3: CaloTagged, 4: SiliconAssociatedForwardMuon)");
162 if (m_applyCorrectionOnData)
173 if (mu(acc.muonTypeAcc) == xAOD::Muon::MuonType::Combined)
175 acc.ptOutDec (mu) = muonObj.
CB.
calib_pt * GeVtoMeV;
179 acc.dec_idPt(mu) = muonObj.
ID.
calib_pt * GeVtoMeV;
180 acc.dec_mePt(mu) = muonObj.
ME.
calib_pt * GeVtoMeV;
184 ATH_MSG_DEBUG(
"Checking Output Muon Info for data - Pt_ID: " << acc.dec_idPt(mu));
185 ATH_MSG_DEBUG(
"Checking Output Muon Info for data - Pt_MS: " << acc.dec_mePt(mu));
186 ATH_MSG_DEBUG(
"Checking Output Muon Info for data - Pt_CB: " << mu(acc.ptAcc));
196 if ((mu(acc.muonTypeAcc) != xAOD::Muon::MuonType::SiliconAssociatedForwardMuon))
209 acc.ptOutDec(mu) = muonObj.
CB.
calib_pt * GeVtoMeV;
211 acc.dec_idPt(mu) = muonObj.
ID.
calib_pt * GeVtoMeV;
212 acc.dec_mePt(mu) = muonObj.
ME.
calib_pt * GeVtoMeV;
216 if(!m_validationMode && !m_skipResolutionCategory.value())
226 if (((extra_smearing || highpt_smearing)) && (mu(acc.ptAcc) > m_HighPtSystThreshold * GeVtoMeV))
228 sgCode = m_MuonIntHighTSmearTool->applyCorrection(muonObj);
233 acc.ptOutDec(mu) = muonObj.
CB.
calib_pt * GeVtoMeV;
234 acc.dec_idPt(mu) = muonObj.
ID.
calib_pt * GeVtoMeV;
235 acc.dec_mePt(mu) = muonObj.
ME.
calib_pt * GeVtoMeV;
238 ATH_MSG_DEBUG(
"Checking Output Muon Info - Pt_ID: " << acc.dec_idPt(mu));
239 ATH_MSG_DEBUG(
"Checking Output Muon Info - Pt_MS: " << acc.dec_mePt(mu));
240 ATH_MSG_DEBUG(
"Checking Output Muon Info - Pt_CB: " << acc.ptOutDec(mu));
261 inTrk.
charge() / (res_pt * std::cosh(inTrk.
eta())));
272 "Non-null pointer received. "
273 "There's a possible memory leak!");
279 output->makePrivateStore(input);
292 return sys.find(systematic) != sys.end();
298 result.insert(m_MuonIntScaleSmearTool->affectingSystematics());
299 if (m_MuonIntHighTSmearToolInitialized) result.insert(m_MuonIntHighTSmearTool->affectingSystematics());
303 CP::SystematicSet MuonCalibTool::recommendedSystematics()
const {
return affectingSystematics(); }
305 StatusCode MuonCalibTool::applySystematicVariation(
const CP::SystematicSet &systConfig)
308 StatusCode code = m_MuonIntSagittaTool->applySystematicVariation(systConfig);
309 if(code != StatusCode::SUCCESS)
return code;
311 code = m_MuonIntScaleSmearTool->applySystematicVariation(systConfig);
312 if(code != StatusCode::SUCCESS)
return code;
314 if (m_MuonIntHighTSmearToolInitialized){
315 code = m_MuonIntHighTSmearTool->applySystematicVariation(systConfig);
316 if(code != StatusCode::SUCCESS)
return code;
321 double MuonCalibTool::expectedResolution(
const std::string &
DetType,
const xAOD::Muon &mu,
const bool addMCCorrectionSmearing)
const
336 double MuonCalibTool::expectedResolution(
const int &
DetType,
const xAOD::Muon &mu,
const bool addMCCorrectionSmearing)
const
347 if (m_validationMode) isData = m_expertMode_isData;
355 MCP::DataYear dataYear = MuonCalibTool::getPeriod(isData, evtInfo);
362 double Primary_eta = mu(acc.etaAcc);
363 double Primary_phi = mu(acc.phiAcc);
365 if (m_validationMode)
371 loc_ptid = id_pt(mu.getXAODObject()) * MeVtoGeV;
372 loc_ptms = ms_pt(mu.getXAODObject()) * MeVtoGeV;
373 loc_ptcb = cb_pt(mu.getXAODObject()) * MeVtoGeV;
378 auto CB_track = mu(acc.combinedTrackParticleLinkAcc);
379 auto ID_track = mu(acc.inDetTrackParticleLinkAcc).opt_value();
380 auto ME_track = mu(acc.extrapolatedMuonSpectrometerTrackParticleLinkAcc);
389 return m_MuonIntScaleSmearTool->getExpectedResolution(
DetType, loc_ptms, Primary_eta, Primary_phi, dataYear, addMCCorrectionSmearing);
393 return m_MuonIntScaleSmearTool->getExpectedResolution(
DetType, loc_ptid, Primary_eta, Primary_phi, dataYear, addMCCorrectionSmearing);
402 double sigmaID = expectedResolution(
MCP::DetectorType::ID, mu, evtInfo, addMCCorrectionSmearing) * loc_ptid;
403 double sigmaMS = expectedResolution(
MCP::DetectorType::MS, mu, evtInfo, addMCCorrectionSmearing) * loc_ptms;
404 double denominator = (loc_ptcb)*std::sqrt(sigmaID * sigmaID + sigmaMS * sigmaMS);
405 return denominator ? sigmaID * sigmaMS / denominator : 0.;
421 if (m_validationMode) isData = m_expertMode_isData;
430 auto year = MuonCalibTool::getPeriod(isData, evtInfo);
433 double Primary_eta = mu(acc.etaAcc);
434 double Primary_phi = mu(acc.phiAcc);
435 int charge = mu(acc.chargeAcc);
438 if (m_validationMode)
456 initializeRandNumbers(muonObj, evtInfo);
468 auto CB_track = mu(acc.combinedTrackParticleLinkAcc);
469 auto ID_track = mu(acc.inDetTrackParticleLinkAcc).opt_value();
470 auto ME_track = mu(acc.extrapolatedMuonSpectrometerTrackParticleLinkAcc);
473 if (mu(acc.muonTypeAcc) == xAOD::Muon::MuonType::SiliconAssociatedForwardMuon)
475 if (CB_track)
charge = CB_track.value()(acc.trkChargeAcc);
484 initializeRandNumbers(muonObj, evtInfo);
505 auto year = MuonCalibTool::getPeriod(isData, *evtInfo);
530 TRandom3 loc_random3;
532 unsigned long long eventNumber = 0;
533 if(m_expertMode_EvtNumber.value()!=0) eventNumber=m_expertMode_EvtNumber.value();
534 else eventNumber = evtInfo(acc.eventNumberAcc);
536 const UInt_t seed = 1 + std::abs(muonObj.
CB.
phi) * 1E6 + std::abs(muonObj.
CB.
eta) * 1E3 + eventNumber;
537 loc_random3.SetSeed(seed);
539 muonObj.
rnd_g0 = loc_random3.Gaus(0, 1);
540 muonObj.
rnd_g1 = loc_random3.Gaus(0, 1);
541 muonObj.
rnd_g2 = loc_random3.Gaus(0, 1);
542 muonObj.
rnd_g3 = loc_random3.Gaus(0, 1);
543 muonObj.
rnd_g4 = loc_random3.Gaus(0, 1);
559 constexpr unsigned int last_run_16 = 320000;
560 constexpr unsigned int last_run_17 = 342000;
561 constexpr unsigned int last_run_18 = 370000;
562 constexpr unsigned int last_run_22 = 440613;
563 constexpr unsigned int last_run_23 = 461002;
564 constexpr unsigned int last_run_24 = 486894;
565 constexpr unsigned int last_run_25 = 509891;
566 constexpr unsigned int last_run_26 = 524099;
568 static const std::set<int> MCperiods1516{284500};
569 static const std::set<int> MCperiods17{300000, 304000, 305000};
570 static const std::set<int> MCperiods18{310000};
571 static const std::set<int> MCperiods22{330000, 410000};
572 static const std::set<int> MCperiods23{450000, 460000};
573 static const std::set<int> MCperiods24{470000, 488000, 488600};
574 static const std::set<int> MCperiods25{495000};
576 static const std::set<int> MCperiodsRun4{350000, 350060, 350140, 350200};
579 unsigned int run = 0;
580 if(m_expertMode_RunNumber.value()!=0)
run=m_expertMode_RunNumber.value();
581 else run = evtInfo(acc.runNumberAcc);
583 if (!isData && m_useRndRun) {
584 if (acc.acc_rnd.isAvailable(evtInfo))
585 run = acc.acc_rnd(evtInfo);
588 "No random runnumber could be found although the tool is configured to assign the years based on it. Please make sure "
589 "to apply the prwTool before-hand or consider to set the property 'useRandomRunNumber' to false.");
594 if (!isData && (!m_useRndRun || !acc.acc_rnd.isAvailable(evtInfo))) {
595 if (MCperiods1516.count(
run)) {
596 ATH_MSG_DEBUG(
"The current run " <<
run <<
" corresponds to data mc20a / data15-16");
598 }
else if (MCperiods17.count(
run)) {
599 ATH_MSG_DEBUG(
"The current run " <<
run <<
" corresponds to data mc20d / data17");
601 }
else if (MCperiods18.count(
run)) {
602 ATH_MSG_DEBUG(
"The current run " <<
run <<
" corresponds to data mc20e / data18");
604 }
else if (MCperiods22.count(
run)) {
605 ATH_MSG_DEBUG(
"The current run " <<
run <<
" corresponds to data mc21 / mc23a / data22");
607 }
else if (MCperiods23.count(
run)) {
608 ATH_MSG_DEBUG(
"The current run " <<
run <<
" corresponds to data mc23c / mc23d / data23");
610 }
else if (MCperiods24.count(
run)) {
611 ATH_MSG_DEBUG(
"The current run " <<
run <<
" corresponds to data mc23e / data24");
613 }
else if (MCperiods25.count(
run)) {
614 ATH_MSG_DEBUG(
"The current run " <<
run <<
" corresponds to data mc23g / data25 / data26");
616 }
else if (MCperiodsRun4.count(
run)) {
623 else if (isData || m_useRndRun) {
624 if (
run < last_run_16) {
627 }
else if (
run <= last_run_17) {
630 }
else if (
run <= last_run_18) {
633 }
else if (
run <= last_run_22) {
636 }
else if (
run <= last_run_23) {
639 }
else if (
run <= last_run_24) {
642 }
else if (
run <= last_run_25) {
645 }
else if (
run <= last_run_26) {
650 static std::atomic<bool> warningPrinted {
false};
651 if (!warningPrinted) {
652 ATH_MSG_WARNING(
"Could not assign run-number " <<
run <<
" to a specific year of data-taking, using default run 4");
653 warningPrinted =
true;
663 switch (applyCorrection(muon, event).code())
668 throw std::runtime_error(
"OutOfValidityRange in applyCorrection");
671 throw std::runtime_error(
"Error in applyCorrection");
680 auto eventInfo = acc.m_eventInfoCol(event);
681 callSingleEvent (acc.m_muons(event), eventInfo);