ATLAS Offline Software
Loading...
Searching...
No Matches
CombinedMassUncertaintyComponent.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
8
9#include "TFile.h"
10
11namespace jet
12{
13
15// //
16// Constructor/destructor/initialization //
17// //
19
36
38 : UncertaintyComponent(component,0)
39 , m_combMassType(component.combMassType)
40 , m_setWeightMassDefs(false)
41 , m_caloMassComp(nullptr)
42 , m_TAMassComp(nullptr)
43 , m_caloMassWeight(nullptr)
44 , m_TAMassWeight(nullptr)
48 , m_truthLabelName(component.LargeRJetTruthLabelName)
49 , m_truthLabels(component.LargeRJetTruthLabels)
50{
51 ATH_MSG_DEBUG("Created CombinedMassUncertaintyComponent named " << getName().Data());
52}
53
74
79
85
87{
88 if (m_isInit)
89 {
90 ATH_MSG_ERROR("Can only set the calo mass term before initialization: " << getName().Data());
91 return StatusCode::FAILURE;
92 }
93 if (m_caloMassComp != nullptr)
94 {
95 ATH_MSG_ERROR("Calo mass term has already been set, blocking double-init: " << getName().Data());
96 return StatusCode::FAILURE;
97 }
98 m_caloMassComp = caloComp;
99
100 return StatusCode::SUCCESS;
101}
102
104{
105 if (m_isInit)
106 {
107 ATH_MSG_ERROR("Can only set the TA mass term before initialization: " << getName().Data());
108 return StatusCode::FAILURE;
109 }
110 if (m_TAMassComp != nullptr)
111 {
112 ATH_MSG_ERROR("TA mass term has already been set, blocking double-init: " << getName().Data());
113 return StatusCode::FAILURE;
114 }
115 m_TAMassComp = TAComp;
116
117 return StatusCode::SUCCESS;
118}
119
121{
122 if (m_isInit)
123 {
124 ATH_MSG_ERROR("Can only set the calo mass weights before initialization: " << getName().Data());
125 return StatusCode::FAILURE;
126 }
127 if (m_caloMassWeight != nullptr)
128 {
129 ATH_MSG_ERROR("Calo mass weights has already been set, blocking double-init: " << getName().Data());
130 return StatusCode::FAILURE;
131 }
132 m_caloMassWeight = caloWeights;
133
134 return StatusCode::SUCCESS;
135}
136
138{
139 if (m_isInit)
140 {
141 ATH_MSG_ERROR("Can only set the TA mass weights before initialization: " << getName().Data());
142 return StatusCode::FAILURE;
143 }
144 if (m_TAMassWeight != nullptr)
145 {
146 ATH_MSG_ERROR("TA mass weights has already been set, blocking double-init: " << getName().Data());
147 return StatusCode::FAILURE;
148 }
149 m_TAMassWeight = TAWeights;
150
151 return StatusCode::SUCCESS;
152}
153
155{
156 if (m_isInit)
157 {
158 ATH_MSG_ERROR("Can only set the weight mass definitions before initialization: " << getName().Data());
159 return StatusCode::FAILURE;
160 }
162 {
163 ATH_MSG_ERROR("Already set the weights, blocking double-setting: " << getName().Data());
164 return StatusCode::FAILURE;
165 }
166 switch (caloMassDef)
167 {
171 break;
172 default:
173 ATH_MSG_ERROR("Unsupported mass parametrization for the combined mass calo weights: " << getName().Data());
174 return StatusCode::FAILURE;
175 }
176 switch (TAMassDef)
177 {
181 break;
182 default:
183 ATH_MSG_ERROR("Unsupported mass parametrization for the combined mass TA weights: " << getName().Data());
184 return StatusCode::FAILURE;
185 }
186
187 m_setWeightMassDefs = true;
188 return StatusCode::SUCCESS;
189}
190
192{
193 if (m_isInit)
194 {
195 ATH_MSG_ERROR("Can only set the weight parametrization before initialization: " << getName().Data());
196 return StatusCode::FAILURE;
197 }
198 m_weightParam = param;
199
200 return StatusCode::SUCCESS;
201}
202
204{
205 // We are completely different here than the normal case
206 // Ignore the base component initialization procedure
207
208 // Prevent double-initialization
209 if (m_isInit)
210 {
211 ATH_MSG_ERROR("Component is already initialized: " << getName().Data());
212 return StatusCode::FAILURE;
213 }
214
215 // Ensure that the combination weights exist
216 if (!m_caloMassWeight)
217 {
218 ATH_MSG_ERROR("Calorimeter mass weights were not defined: " << getName().Data());
219 return StatusCode::FAILURE;
220 }
221 if (!m_TAMassWeight)
222 {
223 ATH_MSG_ERROR("Track-assisted mass weights were not defined: " << getName().Data());
224 return StatusCode::FAILURE;
225 }
226
227 // Ensure that the weight mass definitions were set
229 {
230 ATH_MSG_ERROR("The mass definitions for the combination weight factors were not set: " << getName().Data());
231 return StatusCode::FAILURE;
232 }
233
234 // Understand what situation we are in
236 {
237 ATH_MSG_ERROR("Unknown combined mass uncertainty type: " << getName().Data());
238 return StatusCode::FAILURE;
239 }
241 {
242 // Only the calo mass component should be specified
243 if (!m_caloMassComp)
244 {
245 ATH_MSG_ERROR("Calo mass term was not specified for a CombMass_calo component: " << getName().Data());
246 return StatusCode::FAILURE;
247 }
248 if (m_TAMassComp)
249 {
250 ATH_MSG_ERROR("TA mass term was specified for a CombMass_calo component: " << getName().Data());
251 return StatusCode::FAILURE;
252 }
253 }
255 {
256 // Only the TA mass component should be specified
257 if (m_caloMassComp)
258 {
259 ATH_MSG_ERROR("Calo mass term was specified for a CombMass_TA component: " << getName().Data());
260 return StatusCode::FAILURE;
261 }
262 if (!m_TAMassComp)
263 {
264 ATH_MSG_ERROR("TA mass term was not specified for a CombMass_TA component: " << getName().Data());
265 return StatusCode::FAILURE;
266 }
267 }
269 {
270 // Both components should be specified
271 if (!m_caloMassComp)
272 {
273 ATH_MSG_ERROR("Calo mass term was not specified for a CombMass_both component: " << getName().Data());
274 return StatusCode::FAILURE;
275 }
276 if (!m_TAMassComp)
277 {
278 ATH_MSG_ERROR("TA mass term was not specified for a CombMass_both component: " << getName().Data());
279 return StatusCode::FAILURE;
280 }
281 }
282
283 // Initialize the component(s)
284 if (m_caloMassComp && m_caloMassComp->initialize(histFile).isFailure())
285 {
286 ATH_MSG_ERROR("Failed to initialize calo mass portion of a comb mass uncertainty: " << getName().Data());
287 return StatusCode::FAILURE;
288 }
289 if (m_TAMassComp && m_TAMassComp->initialize(histFile).isFailure())
290 {
291 ATH_MSG_ERROR("Failed to initialize TA mass portion of a comb mass uncertainty: " << getName().Data());
292 return StatusCode::FAILURE;
293 }
294
295
296 // Done!
297 m_isInit = true;
298 return StatusCode::SUCCESS;
299}
300
301
303// //
304// Validity and uncertainty retrieval //
305// //
307
309{
310 return getValidityCalo(jet,eInfo) && getValidityTA(jet,eInfo);
311}
312
313StatusCode CombinedMassUncertaintyComponent::calculateCombinedMass(const xAOD::Jet& jet, const double shiftFactorCalo, const double shiftFactorTA, double& combMass) const
314{
315 // Accessors for the scales we need
319
320 // Get the weight factors
321 const double factorCalo = getWeightFactorCalo(jet,shiftFactorCalo);
322 const double factorTA = getWeightFactorTA(jet,shiftFactorTA);
323
324 // Watch for division by zero
325 if (factorCalo+factorTA == 0)
326 {
327 if (combMassScale.m(jet) == 0)
328 {
329 // JetCalibTools sets the mass to zero when this situation occurs
330 // This is therefore not an error state, rather we want to be consistent
331 combMass = 0;
332 return StatusCode::SUCCESS;
333 }
334 else
335 {
336 // We somehow have invalid calo and TA masses, but a "valid" combined mass
337 // This is an error state that should result in a message to the user
338 // If this occurs, most likely there is something wrong in the inputs
339 ATH_MSG_ERROR("Encountered division by zero when calculating weights: mCalo = " << caloMassScale.m(jet) << ", mTA = " << TAMassScale.m(jet) << ", mComb = " << combMassScale.m(jet));
340 return StatusCode::FAILURE;
341 }
342 }
343
344 // Calculate the weights
345 const double caloWeight = factorCalo/(factorCalo+factorTA);
346 const double TAWeight = factorTA/(factorCalo+factorTA);
347
348 // Watch for zero masses
349 // If one mass is zero, use the other without a weight
350 // If both are zero, it doesn't matter, the combined mass is zero
351 if (caloMassScale.m(jet) == 0)
352 combMass = TAMassScale.m(jet)*shiftFactorTA;
353 else if (TAMassScale.m(jet) == 0)
354 combMass = caloMassScale.m(jet)*shiftFactorCalo;
355 else
356 combMass = (caloMassScale.m(jet)*shiftFactorCalo*caloWeight) + (TAMassScale.m(jet)*shiftFactorTA*TAWeight);
357
358 return StatusCode::SUCCESS;
359}
360
362{
363 // Check if we need to do anything at all - this uncertainty may be zero based on the jet truth label
364 // Truth labels are usually not expected for this component, so check if we need to do this
365 if (!m_truthLabels.empty())
366 {
367 // Truth labels are specified, so we need to check if this jet is labelled appropriately or not
369 if (!accTruthLabel.isAvailable(jet) || accTruthLabel(jet) == LargeRJetTruthLabel::UNKNOWN)
370 {
371 ATH_MSG_ERROR("Unable to retrieve the LargeRJetTruthLabel: " << m_truthLabelName << " from the jet. Please use JetTruthLabelingTool before calling this function.");
372 return JESUNC_ERROR_CODE;
373 }
374 const LargeRJetTruthLabel::TypeEnum jetTruthLabel = LargeRJetTruthLabel::intToEnum(accTruthLabel(jet));
375
376 // We now have the truth jet label, check if it matches one of the label(s) assigned to this component
377 // The uncertainty is only applied to same-labelled jets (zero otherwise)
378 bool labelApplies = false;
380 {
381 if (aLabel == jetTruthLabel)
382 {
383 labelApplies = true;
384 break;
385 }
386 }
387 // If the jet is not of the relevant label, then there is no uncertainty for this jet
388 if (!labelApplies)
389 return 0;
390 }
391
392 // Get the per-part uncertainties
393 double uncCalo = 0;
394 if (m_caloMassComp && !m_caloMassComp->getValidUncertainty(uncCalo,jet,eInfo,CompScaleVar::Mass))
395 {
396 // Not valid
397 ATH_MSG_ERROR("Combined mass is outside of the validity range (calo part)");
398 return JESUNC_ERROR_CODE;
399 }
400 double uncTA = 0;
401 if (m_TAMassComp && !m_TAMassComp->getValidUncertainty(uncTA,jet,eInfo,CompScaleVar::Mass))
402 {
403 // Not valid
404 ATH_MSG_ERROR("Combined mass is outside of the validity range (TA part)");
405 return JESUNC_ERROR_CODE;
406 }
407
408 // Get the mass values (both up and down shifts)
409 // The resolution functions evaluated for masses shifted up and down may not be symmetric
410 // For now, take the average of the up and down shifts
411 // Note that we also only consider correlated shifts here
412 // Uncorrelated shifts can be handled as two separate components
413 // Anticorelated shifts are currently not supported (no need so far)
414 double massDefault = 0;
415 if (!calculateCombinedMass(jet,1,1,massDefault)) return JESUNC_ERROR_CODE;
416 if (massDefault == 0) return 0; // This is a relative uncertainty
417 double massUp = 0;
418 if (!calculateCombinedMass(jet,1+uncCalo,1+uncTA,massUp)) return JESUNC_ERROR_CODE;
419 double massDown = 0;
420 if (!calculateCombinedMass(jet,1-uncCalo,1-uncTA,massDown)) return JESUNC_ERROR_CODE;
421
422 const double massUncUp = fabs((massUp-massDefault)/massDefault);
423 const double massUncDown = fabs((massDown-massDefault)/massDefault);
424
425 return (massUncUp+massUncDown)/2.;
426}
427
428
429
431{
432 return !m_caloMassComp ? true : m_caloMassComp->getValidity(jet,eInfo,CompScaleVar::Mass);
433}
434
436{
437 return !m_TAMassComp ? true : m_TAMassComp->getValidity(jet,eInfo,CompScaleVar::Mass);
438}
439
441{
442 return !m_caloMassComp ? 0 : m_caloMassComp->getUncertainty(jet,eInfo,CompScaleVar::Mass);
443}
444
446{
447 return !m_TAMassComp ? 0 : m_TAMassComp->getUncertainty(jet,eInfo,CompScaleVar::Mass);
448}
449
451{
452 return !m_caloMassComp ? true : m_caloMassComp->getValidUncertainty(unc,jet,eInfo,CompScaleVar::Mass);
453}
454
456{
457 return !m_TAMassComp ? true : m_TAMassComp->getValidUncertainty(unc,jet,eInfo,CompScaleVar::Mass);
458}
459
460double CombinedMassUncertaintyComponent::readHistoFromParam(const xAOD::JetFourMom_t& jet4vec, const UncertaintyHistogram& histo, const CompParametrization::TypeEnum param, const double massShiftFactor) const
461{
462 double resolution = 0;
463 switch (param)
464 {
466 resolution = histo.getValue(jet4vec.Pt()*m_energyScale);
467 break;
469 resolution = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.Eta());
470 break;
472 resolution = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.M()*m_energyScale*massShiftFactor);
473 break;
475 resolution = histo.getValue(jet4vec.Pt()*m_energyScale,fabs(jet4vec.Eta()));
476 break;
478 resolution = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.M()*massShiftFactor/jet4vec.Pt());
479 break;
481 resolution = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.M()*massShiftFactor/jet4vec.Pt(),jet4vec.Eta());
482 break;
484 resolution = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.M()*massShiftFactor/jet4vec.Pt(),fabs(jet4vec.Eta()));
485 break;
487 resolution = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.M()*m_energyScale*massShiftFactor,jet4vec.Eta());
488 break;
490 resolution = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.M()*m_energyScale*massShiftFactor,fabs(jet4vec.Eta()));
491 break;
493 resolution = histo.getValue(jet4vec.E()*m_energyScale,log(jet4vec.M()*massShiftFactor/jet4vec.E()));
494 break;
496 resolution = histo.getValue(jet4vec.E()*m_energyScale,log(jet4vec.M()*massShiftFactor/jet4vec.E()),jet4vec.Eta());
497 break;
499 resolution = histo.getValue(jet4vec.E()*m_energyScale,log(jet4vec.M()*massShiftFactor/jet4vec.E()),fabs(jet4vec.Eta()));
500 break;
501 default:
502 ATH_MSG_ERROR("Failed to read histogram due to unknown parametrization type in " << getName());
503 break;
504 }
505 return resolution == 0 ? 0 : 1./(resolution*resolution);
506}
507
508double CombinedMassUncertaintyComponent::getWeightFactorCalo(const xAOD::Jet& jet, const double massShiftFactor) const
509{
510 if(m_caloMassScale_weights(jet).M() < 0.0) return 0;
511 if(!m_caloMassWeight) return 0;
513}
514
515double CombinedMassUncertaintyComponent::getWeightFactorTA(const xAOD::Jet& jet, const double massShiftFactor) const
516{
517 if(m_TAMassScale_weights(jet).M() < 0.0) return 0;
518 if(!m_TAMassWeight) return 0;
520}
521
522
523
525// //
526// Base class method overrides //
527// //
529
531{
532 if (!m_isInit)
533 {
534 ATH_MSG_ERROR("Cannot call method before initialization, component: " << getName().Data());
535 return false;
536 }
537
538 return (!m_caloMassComp || m_caloMassComp->isAlwaysZero()) && (!m_TAMassComp || m_TAMassComp->isAlwaysZero());
539}
540
541
542
543
544} // end jet namespace
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
@ Data
Definition BaseObject.h:11
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
virtual StatusCode setCaloTerm(UncertaintyGroup *caloComp)
virtual StatusCode setCombWeightParam(const CompParametrization::TypeEnum param)
CombinedMassUncertaintyComponent(const ComponentHelper &component)
virtual bool getValidUncertaintyCalo(double &unc, const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
virtual StatusCode setTAWeights(const UncertaintyHistogram *TAWeights)
virtual StatusCode setCombWeightMassDefs(const CompMassDef::TypeEnum caloMassDef, const CompMassDef::TypeEnum TAMassDef)
virtual double getWeightFactorCalo(const xAOD::Jet &jet, const double shiftFactor) const
virtual bool getValidityTA(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
double readHistoFromParam(const xAOD::JetFourMom_t &jet4vec, const UncertaintyHistogram &histo, const CompParametrization::TypeEnum param, const double massShiftFactor) const
virtual CombinedMassUncertaintyComponent * clone() const
virtual double getUncertaintyImpl(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
virtual double getUncertaintyCalo(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
virtual bool getValidityCalo(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
virtual double getUncertaintyTA(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
StatusCode calculateCombinedMass(const xAOD::Jet &jet, const double shiftFactorCalo, const double shiftFactorTA, double &combMass) const
virtual StatusCode setCaloWeights(const UncertaintyHistogram *caloWeights)
std::vector< LargeRJetTruthLabel::TypeEnum > m_truthLabels
virtual double getWeightFactorTA(const xAOD::Jet &jet, const double shiftFactor) const
virtual bool getValidUncertaintyTA(double &unc, const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
virtual bool getValidityImpl(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
virtual StatusCode setTATerm(UncertaintyGroup *TAComp)
JetFourMomAccessor is an extension of JetAttributeAccessor::AccessorWrapper<xAOD::JetFourMom_t> Acces...
UncertaintyComponent(const ComponentHelper &component, const size_t numHist=1)
virtual TString getName() const
TypeEnum intToEnum(const int type)
TString getJetScaleString(const TypeEnum type)
Jet_v1 Jet
Definition of the current "jet version".
EventInfo_v1 EventInfo
Definition of the latest event info version.
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
Definition JetTypes.h:17