ATLAS Offline Software
UncertaintyComponent.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
7 
8 #include "TFile.h"
9 
10 namespace jet
11 {
12 
13 bool operator < (const UncertaintyComponent& componentA, const UncertaintyComponent& componentB)
14 {
15  return componentA.getName() < componentB.getName();
16 }
17 
18 bool operator == (const UncertaintyComponent& componentA, const UncertaintyComponent& componentB)
19 {
20  return componentA.getName() == componentB.getName();
21 }
22 
23 
25 // //
26 // Constructor/destructor/initialization //
27 // //
29 
31  : asg::AsgMessaging(name)
32  , m_isInit(false)
33  , m_uncHistName("")
34  , m_validHistName("")
35  , m_scaleVar(CompScaleVar::UNKNOWN)
36  , m_topology(JetTopology::UNKNOWN)
37  , m_energyScale(1)
38  , m_interpolate(Interpolate::UNKNOWN)
39  , m_splitNumber(0)
40  , m_numExpectedHist(0)
41  , m_uncHist(nullptr)
42  , m_validHist(nullptr)
43 {
45 }
46 
47 UncertaintyComponent::UncertaintyComponent(const ComponentHelper& component, const size_t numHist)
48  : asg::AsgMessaging(component.name.Data())
49  , m_isInit(false)
50  , m_uncHistName(!component.uncNames.empty()?component.uncNames.at(0):"NONE")
51  , m_validHistName(component.validName)
52  , m_scaleVar(component.scaleVar)
53  , m_topology(component.topology)
54  , m_energyScale(component.energyScale)
55  , m_interpolate(component.interpolate)
56  , m_splitNumber(component.splitNum)
57  , m_uncHist(nullptr)
58  , m_validHist(nullptr)
59 {
60  ATH_MSG_DEBUG("Creating UncertaintyComponent named " << m_uncHistName.Data());
61  if (m_uncHistName == "")
62  ATH_MSG_FATAL("Cannot create an UncertaintyComponent with an empty uncHistName");
64  ATH_MSG_FATAL("Cannot create an UncertaintyComponent scaling an UNKNOWN variable");
65  if (numHist != component.uncNames.size())
66  ATH_MSG_FATAL("Expected " << numHist << " uncertainty histograms, but received " << component.uncNames.size() << " : " << m_uncHistName.Data());
67 }
68 
70  : asg::AsgMessaging(Form("%s_copy",toCopy.m_uncHistName.Data()))
71  , m_isInit(toCopy.m_isInit)
72  , m_uncHistName(toCopy.m_uncHistName)
73  , m_validHistName(toCopy.m_validHistName)
74  , m_scaleVar(toCopy.m_scaleVar)
75  , m_topology(toCopy.m_topology)
76  , m_energyScale(toCopy.m_energyScale)
77  , m_interpolate(toCopy.m_interpolate)
78  , m_splitNumber(toCopy.m_splitNumber)
79  , m_uncHist(nullptr)
80  , m_validHist(nullptr)
81 {
82 
83  if (toCopy.m_uncHist)
85  if (toCopy.m_validHist)
87 }
88 
90 {
91  ATH_MSG_DEBUG("Deleting UncertaintyComponent named " << UncertaintyComponent::getName().Data());
94 }
95 
97 {
98  // Prevent double-initialization
99  if (m_isInit)
100  {
101  ATH_MSG_ERROR("Component is already initialized: " << getName().Data());
102  return StatusCode::FAILURE;
103  }
104 
105  // Create the histograms
107  if (!m_uncHist)
108  {
109  ATH_MSG_ERROR("Failed to create uncertainty histogram for component: " << getName().Data());
110  return StatusCode::FAILURE;
111  }
112  if (m_validHistName != "")
113  {
115  if (!m_validHist)
116  {
117  ATH_MSG_ERROR("Failed to create validity histogram of name \"" << getValidName().Data() << "\" for component: " << getName().Data());
118  return StatusCode::FAILURE;
119  }
120  }
121 
122  // Initialize the histograms
123  if (m_uncHist->initialize(histFile).isFailure()) return StatusCode::FAILURE;
124  if (m_validHist && m_validHist->initialize(histFile).isFailure()) return StatusCode::FAILURE;
125 
126  // Print a summary
127  ATH_MSG_DEBUG("Successfully initialized UncertaintyComponent named " << getName().Data());
128 
129  m_isInit = true;
130  return StatusCode::SUCCESS;
131 }
132 
133 
135 // //
136 // Methods to test for special cases //
137 // //
139 
141 {
142  if (!m_isInit)
143  {
144  ATH_MSG_ERROR("Cannot call method before initialization, component: " << getName().Data());
145  return false;
146  }
147 
148  const TH1* histo = m_uncHist->getHisto();
149  return !(fabs(histo->GetMinimum()) > 1.e-8 || fabs(histo->GetMaximum()) > 1.e-8);
150 }
151 
152 
154 // //
155 // Uncertainty/validity retrieval methods //
156 // //
158 
160 {
161  if (!m_isInit)
162  {
163  ATH_MSG_ERROR("Component hasn't been initialized: " << getName().Data());
164  return false;
165  }
166  return getValidityImpl(jet,eInfo);
167 }
168 
170 {
171  if (!m_isInit)
172  {
173  ATH_MSG_ERROR("Component hasn't been initialized: " << getName().Data());
174  return JESUNC_ERROR_CODE;
175  }
176  return getUncertaintyImpl(jet,eInfo)*getSplitFactor(jet);
177 }
178 
179 bool UncertaintyComponent::getValidUncertainty(double& unc, const xAOD::Jet& jet, const xAOD::EventInfo& eInfo) const
180 {
181  if (getValidity(jet,eInfo))
182  {
183  unc = getUncertainty(jet,eInfo);
184  return true;
185  }
186  return false;
187 }
188 
189 
191 // //
192 // Split factor methods //
193 // //
195 
197 {
198  // Immediate return for the most common case
199  if (!m_splitNumber)
200  return 1;
201 
202  // SplitNumber was specified, we have to calculate the factor
203  double splitFactor = 1;
204  const TH1* histo = m_uncHist->getHisto();
205 
206  if (m_splitNumber == 1 || m_splitNumber == -1)
207  {
208  // Straight line in log(pT) from 0 to 1
209  // y = mx+b
210  // m = 1/[log(max)-log(min)]
211  // x = log(min) --> b = -m*log(min)
212 
213  const double minPt = histo->GetXaxis()->GetBinLowEdge(1);
214  const double maxPt = histo->GetXaxis()->GetBinLowEdge(histo->GetNbinsX()+1);
215  const double valPt = jet.pt()*m_energyScale;
216 
217  const double slope = 1./(log(maxPt)-log(minPt));
218  const double intercept = -slope*log(minPt);
219 
220  splitFactor = slope*log(valPt <= minPt ? minPt+1.e-3 : valPt >= maxPt ? maxPt-1.e-3 : valPt)+intercept;
221  }
222  else if (m_splitNumber == 2 || m_splitNumber == -2)
223  {
224  // Straight line in |eta| from 0 to 1
225  // y = mx + b
226  // m = 1/(max - min)
227  // x = min --> b = -m*min
228  const double minEta = 0;
229  const double maxEta = 4.5;
230  const double absEta = fabs(jet.eta());
231 
232  const double slope = 1./(maxEta - minEta);
233  const double intercept = -slope*minEta;
234 
235  splitFactor = slope*(absEta <= minEta ? minEta+1.e-3 : absEta >= maxEta ? maxEta-1.e-3 : absEta)+intercept;
236  }
237  else if (m_splitNumber == 3 || m_splitNumber == -3)
238  {
239  // Increasing with log(pT) and increasing with |eta|
240  // z = mx + ny + c
241  // z(min,min) = 0
242  // z(max,max) = 1
243  // Linear in both dimensions means need factor of 1/2 in a single dimension
244  // m = 0.5/[log(maxPt)-log(minPt)]
245  // n = 0.5/(maxEta - minEta)
246  // c = -minPt*m - minEta*n
247  // 2*z = (logx-logxmin)/(logxmax-logxmin) + (y-ymin)/(ymax-ymin)
248  const double minPt = histo->GetXaxis()->GetBinLowEdge(1);
249  const double maxPt = histo->GetXaxis()->GetBinLowEdge(histo->GetNbinsX()+1);
250  const double valPt = jet.pt()*m_energyScale;
251 
252  const double minEta = 0;
253  const double maxEta = 4.5;
254  const double absEta = fabs(jet.eta());
255 
256  const double slopePt = 1./(log(maxPt)-log(minPt));
257  const double slopeEta = 1./(maxEta-minEta);
258 
259  const double fixedPt = valPt <= minPt ? minPt+1.e-3 : valPt >= maxPt ? maxPt - 1.e-3 : valPt;
260  const double fixedEta = absEta <= minEta ? minEta+1.e-3 : absEta >= maxEta ? maxEta-1.e-3 : absEta;
261 
262  splitFactor = (slopePt*(log(fixedPt)-log(minPt)) + slopeEta*(fixedEta-minEta))/2.;
263  }
264  else if (m_splitNumber == 4 || m_splitNumber == -4)
265  {
266  // Increasing with log(pT) and decreasing with |eta|
267  // See description above, follows similarly
268  // 2*z = (logx-logxmin)/(logxmax-logxmin) + (ymax-y)/(ymax-ymin)
269  const double minPt = histo->GetXaxis()->GetBinLowEdge(1);
270  const double maxPt = histo->GetXaxis()->GetBinLowEdge(histo->GetNbinsX()+1);
271  const double valPt = jet.pt()*m_energyScale;
272 
273  const double minEta = 0;
274  const double maxEta = 4.5;
275  const double absEta = fabs(jet.eta());
276 
277  const double slopePt = 1./(log(maxPt)-log(minPt));
278  const double slopeEta = 1./(maxEta-minEta);
279 
280  const double fixedPt = valPt <= minPt ? minPt+1.e-3 : valPt >= maxPt ? maxPt - 1.e-3 : valPt;
281  const double fixedEta = absEta <= minEta ? minEta+1.e-3 : absEta >= maxEta ? maxEta-1.e-3 : absEta;
282 
283  splitFactor = (slopePt*(log(fixedPt)-log(minPt)) + slopeEta*(maxEta-fixedEta))/2.;
284  }
285 
286 
287  // Now check if this is the functional part or the complementary part
288  if (m_splitNumber < 0)
289  splitFactor = sqrt(1-splitFactor*splitFactor);
290 
291  return splitFactor;
292 }
293 
294 
296 // //
297 // Helper methods //
298 // //
300 
301 bool UncertaintyComponent::getValidBool(const double validity) const
302 {
303  if (validity < 1.e-5 && validity > -1.e-5) return false;
304  if (validity < 1+1.e-5 && validity > 1-1.e-5) return true;
305  ATH_MSG_ERROR(Form("Validity value not in expected range: %lf for histogram %s",validity,getValidName().Data()));
306  return false;
307 }
308 
310 {
311  // Check for the simple case (where we want the default four-vector itself)
312  if (massDef == CompMassDef::UNKNOWN || massDef == CompMassDef::FourVecMass)
313  return jet.m();
314 
315  // Not the simple case, check for the specified four-vector instead and return it if it is available
317  if (scale.isAvailable(jet))
318  return scale(jet).M();
319 
320  // Fall-back on the TA moment as a float if applicable (legacy support)
321  SG::AuxElement::ConstAccessor<float> scaleTAMoment("JetTrackAssistedMassCalibrated");
322  if (massDef == CompMassDef::TAMass && scaleTAMoment.isAvailable(jet))
323  return scaleTAMoment(jet);
324 
325  // Fall-back on the calo mass as the 4-vec if applicable (legacy support)
326  if (massDef == CompMassDef::CaloMass)
327  return jet.m();
328 
329  // Specified scale is not available, error
330  ATH_MSG_ERROR("Failed to retrieve the " << CompMassDef::enumToString(massDef).Data() << " mass from the jet");
331  return JESUNC_ERROR_CODE;
332 }
333 
335 {
336  // Check for the simple case (where we want the default four-vector itself)
337  if (massDef == CompMassDef::UNKNOWN || massDef == CompMassDef::FourVecMass)
338  return jet.m()/jet.pt();
339 
340  // Not the simple case, check for the specified four-vector instead and return it if it is available
342  if (scale.isAvailable(jet))
343  return scale(jet).M()/scale(jet).Pt();
344 
345  // Fall-back on the TA moment as a float if applicable (legacy support)
346  SG::AuxElement::ConstAccessor<float> scaleTAMoment("JetTrackAssistedMassCalibrated");
347  if (massDef == CompMassDef::TAMass && scaleTAMoment.isAvailable(jet))
348  return scaleTAMoment(jet)/jet.pt();
349 
350  // Fall-back on the calo mass as the 4-vec if applicable (legacy support)
351  if (massDef == CompMassDef::CaloMass)
352  return jet.m()/jet.pt();
353 
354  // Specified scale is not available, error
355  ATH_MSG_ERROR("Failed to retrieve the " << CompMassDef::enumToString(massDef).Data() << " mass from the jet");
356  return JESUNC_ERROR_CODE;
357 
358 }
359 
361 {
362  // Check for the simple case (where we want the default four-vector itself)
363  if (massDef == CompMassDef::UNKNOWN || massDef == CompMassDef::FourVecMass)
364  return jet.m()/jet.e();
365 
366  // Not the simple case, check for the specified four-vector instead and return it if it is available
368  if (scale.isAvailable(jet))
369  return scale(jet).M()/scale(jet).E();
370 
371  // Fall-back on the TA moment as a float if applicable (legacy support)
372  SG::AuxElement::ConstAccessor<float> scaleTAMoment("JetTrackAssistedMassCalibrated");
373  if (massDef == CompMassDef::TAMass && scaleTAMoment.isAvailable(jet))
374  return scaleTAMoment(jet)/jet.e();
375 
376  // Fall-back on the calo mass as the 4-vec if applicable (legacy support)
377  if (massDef == CompMassDef::CaloMass)
378  return jet.m()/jet.e();
379 
380  // Specified scale is not available, error
381  ATH_MSG_ERROR("Failed to retrieve the " << CompMassDef::enumToString(massDef).Data() << " mass from the jet");
382  return JESUNC_ERROR_CODE;
383 
384 }
385 
386 } // end jet namespace
387 
jet::CompMassDef::TypeEnum
TypeEnum
Definition: UncertaintyEnum.h:71
jet::UncertaintyComponent::getValidityImpl
virtual bool getValidityImpl(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const =0
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
jet::UncertaintyComponent::getMassOverPt
virtual double getMassOverPt(const xAOD::Jet &jet, const CompMassDef::TypeEnum massDef) const
Definition: UncertaintyComponent.cxx:334
jet::CompMassDef::FourVecMass
@ FourVecMass
Definition: UncertaintyEnum.h:73
jet::UncertaintyComponent::getMassOverE
virtual double getMassOverE(const xAOD::Jet &jet, const CompMassDef::TypeEnum massDef) const
Definition: UncertaintyComponent.cxx:360
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
jet::UncertaintyComponent::m_energyScale
const float m_energyScale
Definition: UncertaintyComponent.h:55
jet::UncertaintyComponent::getSplitFactor
virtual double getSplitFactor(const xAOD::Jet &jet) const
Definition: UncertaintyComponent.cxx:196
jet::UncertaintyComponent::m_interpolate
const Interpolate::TypeEnum m_interpolate
Definition: UncertaintyComponent.h:56
Data
@ Data
Definition: BaseObject.h:11
jet::CompMassDef::CaloMass
@ CaloMass
Definition: UncertaintyEnum.h:74
asg
Definition: DataHandleTestTool.h:28
jet::UncertaintyHistogram::getHisto
const TH1 * getHisto() const
Definition: UncertaintyHistogram.h:37
jet::ComponentHelper
Definition: ConfigHelper.h:24
jet::ComponentHelper::uncNames
std::vector< TString > uncNames
Definition: ConfigHelper.h:72
jet::UncertaintyComponent::~UncertaintyComponent
virtual ~UncertaintyComponent()
Definition: UncertaintyComponent.cxx:89
jet::UncertaintyComponent::m_uncHistName
const TString m_uncHistName
Definition: UncertaintyComponent.h:51
jet::operator==
bool operator==(const UncertaintyComponent &componentA, const UncertaintyComponent &componentB)
Definition: UncertaintyComponent.cxx:18
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:55
jet::UncertaintyComponent::initialize
virtual StatusCode initialize(TFile *histFile)
Definition: UncertaintyComponent.cxx:96
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
jet::UncertaintyComponent::m_isInit
bool m_isInit
Definition: UncertaintyComponent.h:50
empty
bool empty(TH1 *h)
Definition: computils.cxx:294
jet::UncertaintyComponent::getValidBool
virtual bool getValidBool(const double validity) const
Definition: UncertaintyComponent.cxx:301
Helpers.h
PUfitVar::maxEta
constexpr float maxEta
Definition: GepMETPufitAlg.cxx:13
jet::UncertaintyComponent
Definition: UncertaintyComponent.h:25
jet::UncertaintyHistogram::initialize
virtual StatusCode initialize(TFile *histFile)
Definition: UncertaintyHistogram.cxx:85
JESUNC_ERROR_CODE
#define JESUNC_ERROR_CODE
Definition: Reconstruction/Jet/JetUncertainties/JetUncertainties/Helpers.h:23
jet::UncertaintyComponent::m_validHistName
const TString m_validHistName
Definition: UncertaintyComponent.h:52
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
JESUNC_SAFE_DELETE
#define JESUNC_SAFE_DELETE(T)
Definition: Reconstruction/Jet/JetUncertainties/JetUncertainties/Helpers.h:25
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
jet::operator<
bool operator<(const UncertaintyComponent &componentA, const UncertaintyComponent &componentB)
Definition: UncertaintyComponent.cxx:13
jet::CompMassDef::getJetScaleString
TString getJetScaleString(const TypeEnum type)
Definition: UncertaintyEnum.cxx:225
jet::CompMassDef::TAMass
@ TAMass
Definition: UncertaintyEnum.h:75
jet::UncertaintyComponent::m_validHist
UncertaintyHistogram * m_validHist
Definition: UncertaintyComponent.h:61
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
jet::UncertaintyComponent::getName
virtual TString getName() const
Definition: UncertaintyComponent.h:35
jet::UncertaintyComponent::isAlwaysZero
virtual bool isAlwaysZero() const
Definition: UncertaintyComponent.cxx:140
jet::JetFourMomAccessor
JetFourMomAccessor is an extension of JetAttributeAccessor::AccessorWrapper<xAOD::JetFourMom_t> Acces...
Definition: JetCalibTools_PlotJESFactors.cxx:32
jet::Interpolate::None
@ None
Definition: UncertaintyEnum.h:243
jet::UncertaintyComponent::getAbsMass
virtual double getAbsMass(const xAOD::Jet &jet, const CompMassDef::TypeEnum massDef) const
Definition: UncertaintyComponent.cxx:309
jet::CompScaleVar::UNKNOWN
@ UNKNOWN
Definition: UncertaintyEnum.h:93
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
jet::UncertaintyComponent::m_splitNumber
const int m_splitNumber
Definition: UncertaintyComponent.h:57
jet::UncertaintyComponent::getUncertaintyImpl
virtual double getUncertaintyImpl(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const =0
jet::UncertaintyHistogram
Definition: UncertaintyHistogram.h:25
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
JESUNC_NO_DEFAULT_CONSTRUCTOR
#define JESUNC_NO_DEFAULT_CONSTRUCTOR
Definition: Reconstruction/Jet/JetUncertainties/JetUncertainties/Helpers.h:24
jet::UncertaintyComponent::getValidName
virtual TString getValidName() const
Definition: UncertaintyComponent.h:36
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
jet::CompMassDef::UNKNOWN
@ UNKNOWN
Definition: UncertaintyEnum.h:72
jet::UncertaintyComponent::m_scaleVar
const CompScaleVar::TypeEnum m_scaleVar
Definition: UncertaintyComponent.h:53
CaloClusterCorr::interpolate
float interpolate(const CaloRec::Array< 2 > &a, float x, unsigned int degree, unsigned int ycol=1, const CaloRec::Array< 1 > &regions=CaloRec::Array< 1 >(), int n_points=-1, bool fixZero=false)
Polynomial interpolation in a table.
Definition: interpolate.cxx:75
jet::UncertaintyComponent::getUncertainty
virtual double getUncertainty(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
Definition: UncertaintyComponent.cxx:169
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
TauGNNUtils::Variables::absEta
bool absEta(const xAOD::TauJet &tau, double &out)
Definition: TauGNNUtils.cxx:234
jet::UncertaintyComponent::UncertaintyComponent
UncertaintyComponent(const ComponentHelper &component, const size_t numHist=1)
Definition: UncertaintyComponent.cxx:47
SG::ConstAccessor::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
jet::UncertaintyComponent::m_uncHist
UncertaintyHistogram * m_uncHist
Definition: UncertaintyComponent.h:60
UncertaintyComponent.h
jet::UncertaintyComponent::getValidUncertainty
virtual bool getValidUncertainty(double &unc, const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
Definition: UncertaintyComponent.cxx:179
jet::CompMassDef::enumToString
TString enumToString(const TypeEnum type)
Definition: UncertaintyEnum.cxx:188
plotBeamSpotCompare.histo
histo
Definition: plotBeamSpotCompare.py:415
jet::UncertaintyComponent::getValidity
virtual bool getValidity(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
Definition: UncertaintyComponent.cxx:159
TRT_PAI_utils::Interpolate
float Interpolate(const float &xval, const std::vector< float > &xtabulated, const std::vector< float > &ytabulated)
Interpolation function.
Definition: TRT_PAI_utils.cxx:14