19{
20
21 MuonCalibIntSagittaTool::MuonCalibIntSagittaTool(
const std::string &name) :
asg::AsgTool(
name)
22 { }
23
24 StatusCode MuonCalibIntSagittaTool::initialize()
25 {
26
28
29
31
32
34 {
38
39
44 }
45
46 m_currentParameters = nullptr;
47
48 m_Parameters.initialize(affectingSystematics(), [
this](
const CP::SystematicSet &systConfig, ParameterSetSagitta ¶m)
49 { return calcSystematicVariation(systConfig, param); });
51 {
53 return StatusCode::FAILURE;
54 }
56 if (
registry.registerSystematics(*
this) != StatusCode::SUCCESS)
57 {
59 return StatusCode::FAILURE;
60 }
61
62 return StatusCode::SUCCESS;
63 }
64
66 {
70
71
72 double corrIDpT =
mu.ID.calib_pt;
73 applySagittaCorrection(corrIDpT, IDCorrections,
mu.ID.calib_charge,
mu.ID.isData);
74
75 double corrMEpT =
mu.ME.calib_pt;
76 applySagittaCorrection(corrMEpT, MECorrections,
mu.ME.calib_charge,
mu.ME.isData);
77
78 double corrDirectCBpT =
mu.CB.calib_pt;
79 applySagittaCorrection(corrDirectCBpT, CBCorrections,
mu.CB.calib_charge,
mu.CB.isData);
80
81
82 double corrStatCombCBpT = statCombCorrection(mu, corrIDpT, corrMEpT,
mu.CB.calib_pt);
83
84
85
86
87
88
89 double central(45.2),
width(15.5);
91
92
94 {
95 double sigmaID =
mu.expectedResID;
96 double sigmaME =
mu.expectedResME;
97 double denominator =
mu.CB.calib_pt * std::sqrt(sigmaID * sigmaID + sigmaME * sigmaME);
99
101 {
102 central += std::abs(0.5 *
res * central);
104 {
105 central -= std::abs(0.5 *
res * central);
106 }
107 }
108
109
110 if (!m_useFixedRho)
111 {
112 double sigmas = std::max(1.,(std::abs(
mu.CB.calib_pt - central) /
width));
114
115 }
116 else rho = m_fixedRhoValue;
117
118
119 double corrCBpT =
rho * corrDirectCBpT + (1 -
rho) * corrStatCombCBpT;
120
121 ATH_MSG_DEBUG(
"Saggita correction - corrDirectCBpT: " << corrDirectCBpT <<
" corrStatCombCBpT: " << corrStatCombCBpT <<
" rho " << rho<<
" corrCBPt: "<<corrCBpT);
122
123
124 mu.ID.calib_pt = corrIDpT;
125 mu.ME.calib_pt = corrMEpT;
126
127 if(m_calibMode == MuonCalibTool::correctData_CB)
mu.CB.calib_pt = corrCBpT;
128 else if(m_calibMode == MuonCalibTool::correctData_IDMS)
mu.CB.calib_pt = corrStatCombCBpT;
129 else if(m_calibMode == MuonCalibTool::correctData_IDonly)
mu.CB.calib_pt = corrIDpT;
130 else if(m_calibMode == MuonCalibTool::correctData_MSonly)
mu.CB.calib_pt = corrMEpT;
131
132
134 }
135
136
137 void MuonCalibIntSagittaTool::applySagittaCorrection(
double& pt,
const std::vector<double>& correction,
const int&
charge,
const bool& isData)
const
138 {
139 for(const auto& corr: correction)
140 {
141 double originalPt =
pt;
144 ATH_MSG_DEBUG(
"CorrectForCharge - in pT: " << originalPt <<
" corrPt: " << pt <<
" applied saggita: " << corr);
145
146 }
147 }
148
149
150
151 std::vector<double> MuonCalibIntSagittaTool::getCorrections(
const MCP::TrackCalibObj& trk)
const
152 {
155 SagittaCorrConstMap const *corrMap{nullptr};
156 SagittaCorrConstMap const *kinematicTermMap{nullptr};
158 {
159 corrMap = &m_sagittaCorrConst_CB.at(trk.
year);
160 kinematicTermMap = &m_sagittaCorrConst_mcCB.at(trk.
year);
161 }
163 {
164 corrMap = &m_sagittaCorrConst_ID.at(trk.
year);
165 kinematicTermMap = &m_sagittaCorrConst_mcID.at(trk.
year);
166 }
168 {
169 corrMap = &m_sagittaCorrConst_ME.at(trk.
year);
170 kinematicTermMap = &m_sagittaCorrConst_mcME.at(trk.
year);
171 }
172
173 std::vector<double> corrections;
175 {
176 if(!m_applyCorrectionOnData) return corrections;
177 else if (m_applyCorrectionOnData)
178 {
179
182 corrections.push_back(corr);
183 }
184 }
185 else
186 {
187
189 {
191
193 {
194 ATH_MSG_ERROR(
"Sagitta correction is not applied to data, yet Eta dependant systematics are requested. This configuration is not supported");
195 return corrections;
196 }
197
198
199
200 if(!m_applyCorrectionOnData)
201 {
202
205
206
209 corrections.push_back(corr);
210 }
211
212
216
217
220
221 corrections.push_back(corr);
223 }
225 {
227
228 double deltas = m_extraRebiasSys;
229
231 if(m_release.value().find("Recs2023") != std::string::npos) deltas = 1.2 * deltas;
232 else if(std::abs(
eta)>1.05) deltas = 1.5 * deltas;
233 }
234 double corr = deltas *
scale;
236
237 corrections.push_back(corr);
239
240 }
242 {
244
245
246
247
248
249
250 double corr = 0;
251 double deltas = 0.00002;
252
255 if (pT > 450.0)
256 corr += std::abs(450.0 - 45) * deltas;
257 else
258 corr += std::abs(pT - 45) * deltas;
259 } else {
260
261 if (
eta > 2 || (
eta > -2 &&
eta < -1.05)) {
262 if (pT > 450.0)
263 corr += std::abs(450.0 - 45) / 100 * deltas;
264 else
265 corr += std::abs(pT - 45) / 100 * deltas;
266 }
268 if (pT > 450.0)
269 corr += std::abs(450.0 - 45) / 200 * deltas;
270 else
271 corr += std::abs(pT - 45) / 200 * deltas;
272 }
273
274 if (m_release.value().find("Recs2023") != std::string::npos) {
277 else if (
eta < -1.05) corr += 1.1*deltas;
278 else if (
eta > 0.5 ) corr += 0.8*deltas;
279 }
280 } else {
282 if (
eta > -2 &&
eta < -1.05) corr = corr*2.5;
283 if (
eta < -2) corr = corr*6;
284 if (
eta > 1.5 &&
eta < 2) {
285 if (pT > 450.0)
286 corr += std::abs(450.0 - 45) / 80 * deltas;
287 else
288 corr += std::abs(pT - 45) / 80 * deltas;
289 }
290 if (
eta > 1.05 &&
eta < 1.5) {
291 if (pT > 450.0)
292 corr += std::abs(450.0 - 45) / 40 * deltas;
293 else
294 corr += std::abs(pT - 45) / 40 * deltas;
295 }
296 }
297 }
298
299 }
300
301 corrections.push_back(corr*scale);
302 ATH_MSG_VERBOSE(
"High pT variation for pT "<<pT<<
" deltas "<<deltas<<
" final corr: "<<corr);
303
304 }
306 {
308
309
310
312 corr *= (0.5 *
scale);
314 corrections.push_back(corr);
315 }
317 {
318
319 }
320 else
321 {
322
323 }
324 }
325
326 return corrections;
327 }
328
329
330 double MuonCalibIntSagittaTool::statCombCorrection(
const MCP::MuonObj& mu,
double corrIDpT,
double corrMEpT,
double CBpT)
const
331 {
335
336
337 if(
mu.ID.calib_pt == 0)
return CBpT;
338 if(
mu.ME.calib_pt == 0)
return CBpT;
339 if(corrIDpT == 0) return CBpT;
340 if(corrMEpT == 0) return CBpT;
341
342 double chi2Nom = -999;
349
352
353
354
355 using TLV =
ROOT::Math::LorentzVector<
ROOT::Math::PtEtaPhiM4D<
double>>;
356 TLV tlv{
mu.ID.calib_pt,
mu.ID.eta,
mu.ID.phi,
mu.ID.mass};
357
358 if(tlv.P() == 0) parsID[4] = 1e12;
359 else parsID[4] = 1.0 / (tlv.P() * 1e3);
360
361 tlv.SetCoordinates(
mu.ME.calib_pt,
mu.ME.eta,
mu.ME.phi,
mu.ME.mass);
362
363 if(tlv.P() == 0) parsMS[4] = 1e12;
364 else parsMS[4] = 1.0 / (tlv.P() * 1e3);
365
366 CP::CorrectionCode SysCorrCode = applyStatCombination(parsID, covID, parsMS, covMS,
mu.CB.calib_charge, parsCBNom, covCBNom, chi2Nom);
368
369
370
371
372 tlv.SetCoordinates(corrIDpT,
mu.ID.eta,
mu.ID.phi,
mu.ID.mass);
373
374 if(tlv.P() == 0) parsID[4] = 1e12;
375 else parsID[4] = 1.0 / (tlv.P() * 1e3);
376
377 tlv.SetCoordinates(corrMEpT,
mu.ME.eta,
mu.ME.phi,
mu.ME.mass);
378
379 if(tlv.P() == 0) parsMS[4] = 1e12;
380 else parsMS[4] = 1.0 / (tlv.P() * 1e3);
381
382 SysCorrCode = applyStatCombination(parsID, covID, parsMS, covMS,
mu.CB.calib_charge, parsCBCorr, covCBCorr, chi2Nom);
384
385
386 double statCombPtNom = std::sin(parsCBNom[3]) / std::abs(parsCBNom[4]);
387 double statCombPtCorr = std::sin(parsCBCorr[3]) / std::abs(parsCBCorr[4]);
388 double corrCBpT = CBpT * (statCombPtCorr / statCombPtNom);
389
390 return corrCBpT;
391
392 }
397 parsID[4] = std::abs(parsID[4]);
398 parsMS[4] = std::abs(parsMS[4]);
399
400
402 if (!matID.isInvertible()) {
405 }
407
408
410 if (!matMS.isInvertible()) {
413 }
415
416
417 Eigen::FullPivLU<
AmgSymMatrix(5)> matCB(weightID + weightMS);
418 if (!matCB.isInvertible()) {
421 }
422 covCB = matCB.inverse();
423
424
425 Eigen::FullPivLU<
AmgSymMatrix(5)> matSum(covID + covMS);
426 if (!matSum.isInvertible()) {
429 }
431
432
434 chi2 = diffPars.transpose() * invCovSum * diffPars;
436
437 parsCB = covCB * (weightID * parsID + weightMS * parsMS);
439
441 parsCB[2] -= 2. *
M_PI;
442 else
if (parsCB[2] < -
M_PI)
443 parsCB[2] += 2. *
M_PI;
445 }
446
447
448
450 {
452 return sys.find(systematic) !=
sys.end();
453 }
454
456 {
461 if (!m_useFixedRho || m_sysScheme == "AllSys") {
464 }
465
466 if (m_doEtaSagittaSys) {
467
470
473
474 }
475 else {
476
479 }
480
483
486
489
491 }
492
493 CP::SystematicSet MuonCalibIntSagittaTool::recommendedSystematics()
const {
return affectingSystematics(); }
494
496 {
503
504
506
509 else if (!syst.
empty())
return StatusCode::FAILURE;
510
511
513
516 else if (!syst.
empty())
return StatusCode::FAILURE;
517
518
520
523 else if (!syst.
empty())
return StatusCode::FAILURE;
524
525
527
530 else if (!syst.
empty())
return StatusCode::FAILURE;
531
532
534
536 {
539 }
541 {
544 }
545 else if (!syst.
empty())
return StatusCode::FAILURE;
546
547
549
551 {
554 }
556 {
559 }
560 else if (!syst.
empty())
return StatusCode::FAILURE;
561
562
564
567 else if (!syst.
empty())
return StatusCode::FAILURE;
568
569
570 ATH_MSG_DEBUG(
"Systematic variation's parameters, SagittaRho: " << param.SagittaRho);
571 ATH_MSG_DEBUG(
"Systematic variation's parameters, SagittaBias: " << param.SagittaBias);
572 ATH_MSG_DEBUG(
"Systematic variation's parameters, SagittaGlobal: " << param.SagittaGlobal);
573 ATH_MSG_DEBUG(
"Systematic variation's parameters, SagittaPtExtra: " << param.SagittaPtExtra);
574 ATH_MSG_DEBUG(
"Systematic variation's parameters, SagittaDataStat: " << param.SagittaDataStat);
575 ATH_MSG_DEBUG(
"Systematic variation's parameters, SagittaEtaSlice: " << param.SagittaEtaSlice);
576
577 return StatusCode::SUCCESS;
578 }
579
581 {
582 return m_Parameters.get(systConfig, m_currentParameters);
583 }
584
585
586
587}
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
double charge(const T &p)
#define AmgSymMatrix(dim)
std::pair< std::vector< unsigned int >, bool > res
Return value from object correction CP tools.
@ Error
Some error happened during the object correction.
@ Ok
The correction was done successfully.
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.
Class to wrap a set of SystematicVariations.
SystematicVariation getSystematicByBaseName(const std::string &basename) const
description: get the first systematic matching basename
bool empty() const
returns: whether this is an empty systematic, i.e.
Return value from object correction CP tools.
double chi2(TH1 *h0, TH1 *h1)
Select isolated Photons, Electrons and Muons.
::StatusCode StatusCode
StatusCode definition for legacy code.
std::map< SagittaCorrection, std::shared_ptr< CalibContainer > > createSagittaCorrMap(DataYear dataYear, TrackType type, const std::string &recommendationPath, const std::string &correctionType)
static constexpr std::array< MCP::DataYear, 8 > dataYearList
Selection rules: declare transient members.
double getCorrections(TH2F *corrections, double eta, double phi, double Et, double charge)
Basic object to cache all relevant information from the track.
const double eta
Value of the track-eta.
double calib_pt
Smeared track pt.
const TrackType type
Flag telling the code whether this is CB/ME/ID.