ATLAS Offline Software
FlavourUncertaintyComponent.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4 
7 
8 #include "TFile.h"
9 #include "TList.h"
10 #include "TKey.h"
11 
12 namespace jet
13 {
14 
16 // //
17 // Constructor/destructor/initialization //
18 // //
20 
23  , m_flavourType(FlavourComp::UNKNOWN)
24  , m_jetType("")
25  , m_analysisFileName("")
26  , m_analysisHistPattern("")
27  , m_defAnaFileName("")
28  , m_absEta(false)
29  , m_absEtaGluonFraction(true)
30  , m_secondUncName("")
31  , m_largeRJetTruthLabelName("")
32  , m_largeRJetTruthLabels()
33  , m_secondUncHist(nullptr)
34  , m_respType(FlavourResp_UNKNOWN)
35  , m_secondRespType(FlavourResp_UNKNOWN)
36  , m_BjetAccessor("IsBjet")
37  , m_NjetAccessor("Njet")
38  , m_largeRJetTruthLabelAccessor(m_largeRJetTruthLabelName)
39  , m_gluonFractionHists()
40  , m_gluonFractionErrorHists()
41 {
43 }
44 
46  const TString& jetType,
47  const TString& analysisRootFileName,
48  const TString& defaultAnalysisRootFileName,
49  const TString& path,
50  const TString& calibArea,
51  const bool absEtaGluonFraction,
52  const TString& analysisHistPattern
53  )
54  : UncertaintyComponent(component,component.flavourType == FlavourComp::Composition ? 2 : 1)
55  , m_flavourType(component.flavourType)
56  , m_jetType(jetType)
57  , m_analysisFileName(analysisRootFileName)
58  , m_analysisHistPattern(analysisHistPattern)
59  , m_defAnaFileName(defaultAnalysisRootFileName)
60  , m_path(path)
61  , m_calibArea(calibArea)
62  , m_absEta(CompParametrization::isAbsEta(component.parametrization))
63  , m_absEtaGluonFraction(absEtaGluonFraction)
64  , m_secondUncName(component.uncNames.size()>1 ? component.uncNames.at(1) : "")
65  , m_largeRJetTruthLabelName(component.LargeRJetTruthLabelName)
66  , m_largeRJetTruthLabels(component.LargeRJetTruthLabels)
67  , m_secondUncHist(nullptr)
68  , m_respType(FlavourResp_UNKNOWN)
69  , m_secondRespType(FlavourResp_UNKNOWN)
70  , m_BjetAccessor("IsBjet")
71  , m_NjetAccessor("Njet")
72  , m_largeRJetTruthLabelAccessor(m_largeRJetTruthLabelName)
73  , m_gluonFractionHists()
74  , m_gluonFractionErrorHists()
75 {
76  ATH_MSG_DEBUG("Created FlavourUncertaintyComponent named" << m_uncHistName.Data());
77 
78  // Ensure that the flavour type and ref values are sensible
80  ATH_MSG_FATAL("Flavour type is UNKNOWN: " << m_uncHistName.Data());
81 }
82 
84  : UncertaintyComponent(toCopy)
85  , m_flavourType(toCopy.m_flavourType)
86  , m_jetType(toCopy.m_jetType)
87  , m_analysisFileName(toCopy.m_analysisFileName)
88  , m_analysisHistPattern(toCopy.m_analysisHistPattern)
89  , m_defAnaFileName(toCopy.m_defAnaFileName)
90  , m_path(toCopy.m_path)
91  , m_calibArea(toCopy.m_calibArea)
92  , m_absEta(toCopy.m_absEta)
93  , m_absEtaGluonFraction(toCopy.m_absEtaGluonFraction)
94  , m_secondUncName(toCopy.m_secondUncName)
95  , m_largeRJetTruthLabelName(toCopy.m_largeRJetTruthLabelName)
96  , m_largeRJetTruthLabels(toCopy.m_largeRJetTruthLabels)
97  , m_secondUncHist(nullptr)
98  , m_respType(toCopy.m_respType)
99  , m_secondRespType(toCopy.m_secondRespType)
100  , m_BjetAccessor(toCopy.m_BjetAccessor)
101  , m_NjetAccessor(toCopy.m_NjetAccessor)
102  , m_largeRJetTruthLabelAccessor(toCopy.m_largeRJetTruthLabelAccessor)
103  , m_gluonFractionHists()
104  , m_gluonFractionErrorHists()
105 {
106  ATH_MSG_DEBUG(Form("Creating copy of FlavourUncertaintyComponent named %s",m_uncHistName.Data()));
107 
108  if (toCopy.m_secondUncHist)
110 
111  for (size_t iHist = 0; iHist < toCopy.m_gluonFractionHists.size(); ++iHist)
112  if (toCopy.m_gluonFractionHists.at(iHist))
113  m_gluonFractionHists.push_back(new UncertaintyHistogram(*toCopy.m_gluonFractionHists.at(iHist)));
114 
115  for (size_t iHist = 0; iHist < toCopy.m_gluonFractionErrorHists.size(); ++iHist)
116  if (toCopy.m_gluonFractionErrorHists.at(iHist))
118 }
119 
121 {
122  return new FlavourUncertaintyComponent(*this);
123 }
124 
126 {
128 
129  for (size_t iHisto = 0; iHisto < m_gluonFractionHists.size(); ++iHisto)
130  {
133  }
134  m_gluonFractionHists.clear();
136 }
137 
138 
139 
141 {
142  // Call the base class first
143  if (UncertaintyComponent::initialize(histFile).isFailure())
144  return StatusCode::FAILURE;
145 
146  // Ensure that the number of histograms matches what is expected for Flavour components
148  {
149  if (m_secondUncName != "")
150  {
151  ATH_MSG_ERROR("Expected one histogram for FlavourResponse: " << getName().Data());
152  return StatusCode::FAILURE;
153  }
154  }
156  {
157  ATH_MSG_ERROR("Expected two histograms for FlavourComposition: " << getName().Data());
158  return StatusCode::FAILURE;
159  }
160  else if (m_flavourType == FlavourComp::bJES && m_secondUncName != "")
161  {
162  ATH_MSG_ERROR("Expected one histogram for bJES uncertainty: " << getName().Data());
163  return StatusCode::FAILURE;
164  }
165 
166  // Get the flavour response types if applicable
168  {
169  if ( m_uncHistName.Contains("glu",TString::kIgnoreCase) && (m_secondUncName.Contains("light",TString::kIgnoreCase) || m_secondUncName.Contains("quark",TString::kIgnoreCase)) )
170  {
173  }
174  else if ( (m_uncHistName.Contains("light",TString::kIgnoreCase) || m_uncHistName.Contains("quark",TString::kIgnoreCase)) && m_secondUncName.Contains("glu",TString::kIgnoreCase) )
175  {
178  }
179  else
180  {
181  // Unexpected inputs
182  ATH_MSG_ERROR("Component is FlavourComposition, but histogram names are unexpected (need to discriminate gluon vs quark response histograms): " << m_uncHistName.Data() << " and " << m_secondUncName.Data());
183  return StatusCode::FAILURE;
184  }
185 
186  }
187 
188  // Create the second histogram if applicable
190  {
192  if (!m_secondUncHist)
193  {
194  ATH_MSG_ERROR("Failed to create second uncertainty histogram for component: " << getName().Data());
195  return StatusCode::FAILURE;
196  }
197  if (m_secondUncHist->initialize(histFile).isFailure()) return StatusCode::FAILURE;
198  }
199 
200  // Now read the analysis input histograms if this is not a bJES component
202  {
204  if (!analysisFile || analysisFile->IsZombie())
205  {
206  ATH_MSG_ERROR("Cannot open analysis histogram file: " << m_analysisFileName.Data());
207  return StatusCode::FAILURE;
208  }
209 
210  // Retrieve the gluon fraction(s) and gluon fraction uncertainty(ies)
211  // May be a single histogram (default) or specified by nJet bins
212  // Store all of the key names for now, retrieval will happen later
213  std::vector<TString> gluonFractionKeys;
214  std::vector<TString> gluonFractionErrorKeys;
215  getGluonKeys(analysisFile,gluonFractionKeys,gluonFractionErrorKeys);
216 
217 
218  // Ensure we found histograms...
219  if (gluonFractionKeys.empty() || gluonFractionErrorKeys.empty())
220  {
221  ATH_MSG_ERROR(Form("Failed to find gluon fraction histogram(s), found %zu nominal and %zu error hists in file %s",gluonFractionKeys.size(),gluonFractionErrorKeys.size(),m_analysisFileName.Data()));
222  return StatusCode::FAILURE;
223  }
224 
225  // Determine the max nJet value
226  int nJetsMax = -1;
227  for (size_t iKey = 0; iKey < gluonFractionKeys.size(); ++iKey)
228  {
229  int nJets = -1;
230  if (getNjetFromKey(gluonFractionKeys.at(iKey),nJets).isFailure())
231  return StatusCode::FAILURE;
232  if (nJets > nJetsMax)
233  nJetsMax = nJets;
234  }
235 
236  // If there is only one histogram and it's not an nJets histogram, this is trivial
237  if (nJetsMax < 0 && gluonFractionKeys.size() == 1 && gluonFractionErrorKeys.size() == 1)
238  {
239  m_gluonFractionHists.push_back(new UncertaintyHistogram(gluonFractionKeys.at(0),m_interpolate));
240  m_gluonFractionErrorHists.push_back(new UncertaintyHistogram(gluonFractionErrorKeys.at(0),m_interpolate));
241  }
242  // If there is more than one histogram and they are not nJets histograms, this is a problem
243  else if (nJetsMax < 0 && gluonFractionKeys.size() > 1)
244  {
245  ATH_MSG_ERROR(Form("Found %zu gluon fraction histograms, but they do not appear to be binned by nJets:",gluonFractionKeys.size()));
246  for (size_t iKey = 0; iKey < gluonFractionKeys.size(); ++iKey)
247  ATH_MSG_ERROR(Form("\tKey %zu: %s",iKey,gluonFractionKeys.at(iKey).Data()));
248  return StatusCode::FAILURE;
249  }
250  else
251  {
252  // Fill the actual vectors now, in proper order
253  for (int nJets = 0; nJets <= nJetsMax; ++nJets)
254  {
255  m_gluonFractionHists.push_back(nullptr);
256  m_gluonFractionErrorHists.push_back(nullptr);
257  }
258  if (readNjetsHistograms(m_gluonFractionHists,gluonFractionKeys).isFailure())
259  return StatusCode::FAILURE;
260  if (readNjetsHistograms(m_gluonFractionErrorHists,gluonFractionErrorKeys).isFailure())
261  return StatusCode::FAILURE;
262 
263  // Ensure that every non-NULL gluon fraction has a non-NULL gluon fraction error
264  // (Note that not all indices must be filled, as maybe an analyis is only 4 and 5 jets)
265  for (size_t iJet = 0; iJet < m_gluonFractionHists.size(); ++iJet)
266  {
267  if (m_gluonFractionHists.at(iJet) && !m_gluonFractionErrorHists.at(iJet))
268  {
269  ATH_MSG_ERROR(Form("nJets = %zu was specified for the gluon fraction, but not the error",iJet));
270  return StatusCode::FAILURE;
271  }
272  else if (!m_gluonFractionHists.at(iJet) && m_gluonFractionErrorHists.at(iJet))
273  {
274  ATH_MSG_ERROR(Form("nJets = %zu was specified for the error, but not the gluon fraction",iJet));
275  return StatusCode::FAILURE;
276  }
277  }
278  }
279 
280  // Initialize the non-NULL histograms
281  for (size_t iHist = 0; iHist < m_gluonFractionHists.size(); ++iHist)
282  {
283  if (m_gluonFractionHists.at(iHist) && m_gluonFractionHists.at(iHist)->initialize(analysisFile).isFailure())
284  return StatusCode::FAILURE;
285  if (m_gluonFractionErrorHists.at(iHist) && m_gluonFractionErrorHists.at(iHist)->initialize(analysisFile).isFailure())
286  return StatusCode::FAILURE;
287  }
288 
289  // We're finally done reading that file...
290  analysisFile->Close();
291 
292 
293  // If nJets treatment is specified, and a default analysis file is specified, use this to fill the zero-bin
294  // The zero-bin is used whenever a multiplicity that is not explicitly specified is requested
295  if (m_defAnaFileName != "" && m_gluonFractionHists.size() > 1 && m_gluonFractionHists.at(0) == nullptr)
296  {
297  // Open the default file
299  if (!defAnaFile || defAnaFile->IsZombie())
300  {
301  ATH_MSG_ERROR("Cannot open default analysis histogram file: " << m_defAnaFileName.Data());
302  return StatusCode::FAILURE;
303  }
304 
305  // Retrieve the gluon fraction(s) and gluon fraction uncertainty(ies)
306  // May be a single histogram (default) or specified by nJet bins
307  // Store all of the key names for now, retrieval will happen later
308  std::vector<TString> gluonFractionDefaultKeys;
309  std::vector<TString> gluonFractionErrorDefaultKeys;
310  getGluonKeys(defAnaFile,gluonFractionDefaultKeys,gluonFractionErrorDefaultKeys);
311 
312  // Ensure that there is exactly one histogram (not another nJets file, not missing)
313  if (gluonFractionDefaultKeys.size() != 1 || gluonFractionErrorDefaultKeys.size() != 1)
314  {
315  ATH_MSG_ERROR(Form("When using the default file to fill unspecified nJets histograms, exactly one gluon fraction and one gluon fraction uncertainty histogram are required. Instead, we found %zu and %zu respectively in the file %s",gluonFractionDefaultKeys.size(),gluonFractionErrorDefaultKeys.size(),m_defAnaFileName.Data()));
316  return StatusCode::FAILURE;
317  }
318 
319  // Fill the empty zero-bin histograms
320  m_gluonFractionHists.at(0) = new UncertaintyHistogram(gluonFractionDefaultKeys.at(0),m_interpolate);
321  m_gluonFractionErrorHists.at(0) = new UncertaintyHistogram(gluonFractionErrorDefaultKeys.at(0),m_interpolate);
322 
323  // Now initialize them
324  if (m_gluonFractionHists.at(0)->initialize(defAnaFile).isFailure())
325  return StatusCode::FAILURE;
326  if (m_gluonFractionErrorHists.at(0)->initialize(defAnaFile).isFailure())
327  return StatusCode::FAILURE;
328 
329  // We're done reading that file now too
330  defAnaFile->Close();
331  }
332 
333  }
334 
335  return StatusCode::SUCCESS;
336 }
337 
339 // //
340 // Validity and uncertainty retrieval //
341 // //
343 
345 {
346  // Currently only one validity histogram exists
347  // Might need to expand in the future
348 
349  return !m_validHist ? true : getValidBool(m_validHist->getValue(jet.pt()*m_energyScale,m_absEta ? fabs(jet.eta()) : jet.eta()));
350 
351 // // Valid only if all histogram(s) are valid
352 // // Histograms to consider varies by flavour type
353 // // Start with the standard histograms
354 // for (size_t iHisto = 0; iHisto < m_histos.size(); ++iHisto)
355 // if (!m_histos.at(iHisto)->getValidity(jet.pt()*m_energyScale,m_absEta ? fabs(jet.eta()) : jet.eta()))
356 // return false;
357 //
358 // // Now do analysis histograms
359 // for (size_t iHisto = 0; iHisto < m_gluonFractionHists.size(); ++iHisto)
360 // if (!m_gluonFractionHists.at(iHisto)->getValidity(jet.pt()*m_energyScale,m_absEta ? fabs(jet.eta()) : jet.eta()) ||
361 // !m_gluonFractionErrorHists.at(iHisto)->getValidity(jet.pt()*m_energyScale,m_absEta ? fabs(jet.eta()) : jet.eta()) )
362 // return false;
363 //
364 // return true;
365 }
366 
368 {
369  // First, check if we even want to apply the uncertainty (large-R specific break-out)
370  // Check if we are supposed to only use given truth labels
371  if (!m_largeRJetTruthLabels.empty())
372  {
373  // If we are asking to check truth labels, then retrieve the truth jet label from the jet
374  if (!m_largeRJetTruthLabelAccessor.isAvailable(jet))
375  {
376  // Unable to retrieve truth label, but we were told to look for it, error
377  ATH_MSG_ERROR("Unable to retrieve LargeRJetTruthLabel: " + m_largeRJetTruthLabelName + " from the jet. Please use JetTruthLabeling before calling this function.");
378  return JESUNC_ERROR_CODE;
379  }
380  // Ok, the label exists, now check what it is
382  if (largeRJetTruthLabel == LargeRJetTruthLabel::UNKNOWN)
383  {
384  // This is an error - the label exists but it is unrecognized
385  ATH_MSG_ERROR("UNKNOWN LargeRJetTruthLabel on the jet. Please use JetTruthLabeling before calling this function or check the jet for irregularities.");
386  return JESUNC_ERROR_CODE;
387  }
388  // Not unknown, now check if it is one of the labels we want to apply this uncertainty for
389  bool relevantLabel = false;
391  {
392  if (aLabel == largeRJetTruthLabel)
393  relevantLabel = true;
394  }
395 
396  // If we don't want to apply an uncertainty to jets with this label, then return 0 here (no uncertainty)
397  if (!relevantLabel)
398  return 0;
399  // Otherwise, continue as usual
400  }
401 
402 
403  // Now, we do want t o apply the uncertainty, so do it
404  double unc = JESUNC_ERROR_CODE;
406  unc = getFlavourResponseUncertainty(jet,eInfo);
409  else if (m_flavourType == FlavourComp::bJES)
410  unc = getBJESUncertainty(jet,eInfo);
411  else
412  {
413  ATH_MSG_ERROR("Unknown flavour type for " << getName().Data());
414  return unc;
415  }
416 
417  return unc;
418 }
419 
421 {
422  // Assumption:
423  // dR(q) = JES uncertainty (measured in gamma/Z+jet)
424  // dR(g) = JES uncertainty (+) additional gluon response component
425  // component to be added to JES uncertainty:
426  // fg*dR(gluon response modelling uncertainty)
427  // where gluon response modelling uncertainty is taken as difference between gluon response in Pythia and Herwig++
428 
429  // Check if this is a b-jet
430  if (isBjet(jet))
431  return 0;
432 
433  // Get the number of jets
434  int nJets = 0;
435  if (m_gluonFractionHists.size() > 1)
436  {
437  if (m_NjetAccessor.isAvailable(eInfo))
438  nJets = m_NjetAccessor(eInfo);
439  else
440  {
441  ATH_MSG_ERROR("Specified Njets treatment, but did not decorate EventInfo object");
442  return JESUNC_ERROR_CODE;
443  }
444  }
445 
446  if (checkNjetsInput(nJets).isFailure())
447  return JESUNC_ERROR_CODE;
448 
449  const double pT = jet.pt()*m_energyScale;
450  const double eta = m_absEta ? fabs(jet.eta()) : jet.eta();
451 
452  // return the uncertainty
454 }
455 
457 {
458  // Returns the flavor composition uncertainty using the formula:
459  //
460  // Uncertainty = df * | Rq - Rg | / ( fg * Rg + (1 - fg) * Rq )
461  // with
462  // Rs = fg * Rg + (1 - fg) * Rq as heavy q uncertainties accounted separately
463  // df = error on fg
464  // fg = fraction of gluons
465  // Rq = light quark response
466  // Rg = gluon response
467 
468  // Check if this is a b-jet
469  if (isBjet(jet))
470  return 0;
471 
472  // Get the number of jets
473  int nJets = 0;
474  if (m_gluonFractionHists.size() > 1)
475  {
476  if (m_NjetAccessor.isAvailable(eInfo))
477  nJets = m_NjetAccessor(eInfo);
478  else
479  {
480  ATH_MSG_ERROR("Specified Njets treatment, but did not decorate EventInfo object");
481  return JESUNC_ERROR_CODE;
482  }
483  }
484 
485 
486  if (checkNjetsInput(nJets).isFailure())
487  return JESUNC_ERROR_CODE;
488 
489  const double pT = jet.pt()*m_energyScale;
490  const double eta = m_absEta ? fabs(jet.eta()) : jet.eta();
491 
492  //calculating the sample response:
493  //fg*Rg + (1-fg)*Rq
494  const double gluonFrac = getGluonFraction(pT,eta,nJets);
495  const double Rg = getGluonResponseBaseline(pT,eta);
496  const double Rq = getQuarkResponseBaseline(pT,eta);
497 
498  const double Rsample = gluonFrac * Rg + (1-gluonFrac) * Rq;
499 
500  //this should never happen (it means the Rg == Rq == 0), but checking anyway
501  if (Rsample==0)
502  {
503  ATH_MSG_ERROR(Form("R(sample) = 0 for pT=%.1f, eta=%.2f",pT,eta));
504  return JESUNC_ERROR_CODE;
505  }
506 
507  //calculating the uncertainty
508  const double gluonFracError = getGluonFractionError(pT,eta,nJets);
509  const double flavorCompUnc = gluonFracError*fabs(Rq-Rg)/Rsample;
510 
511  return flavorCompUnc;
512 
513 }
514 
516 {
517  // Ensure this is a b-jet
518  if (!isBjet(jet))
519  return 0;
520  return m_uncHist->getValue(jet.pt()*m_energyScale,m_absEta ? fabs(jet.eta()) : jet.eta());
521 }
522 
523 
525 // //
526 // Wrapper functions for special flavour hists //
527 // //
529 
530 double FlavourUncertaintyComponent::getGluonFraction(const double pT, const double eta, const int nJets) const
531 {
532  // nJets value checking is done in checkNjetsInput
533  return m_gluonFractionHists.at(nJets)->getValue(pT,m_absEtaGluonFraction ? std::abs(eta) : eta);
534 }
535 
536 double FlavourUncertaintyComponent::getGluonFractionError(const double pT, const double eta, const int nJets) const
537 {
538  // nJets value checking is done in checkNjetsInput
539  return m_gluonFractionErrorHists.at(nJets)->getValue(pT,m_absEtaGluonFraction ? std::abs(eta) : eta);
540 }
541 
542 double FlavourUncertaintyComponent::getGluonResponseDifference(const double pT, const double eta) const
543 {
545  {
546  ATH_MSG_ERROR("This method is only useable for FlavourResponse uncertainties, not " << getName().Data());
547  return JESUNC_ERROR_CODE;
548  }
549  return m_uncHist->getValue(pT,eta);
550 }
551 
552 double FlavourUncertaintyComponent::getGluonResponseBaseline(const double pT, const double eta) const
553 {
555  {
556  ATH_MSG_ERROR("This method is only useable for FlavourComposition uncertainties, not " << getName().Data());
557  return JESUNC_ERROR_CODE;
558  }
559 
561  return m_uncHist->getValue(pT,eta);
563  return m_secondUncHist->getValue(pT,eta);
564  ATH_MSG_ERROR("Unexpected flavour response parametrization: " << getName().Data());
565  return JESUNC_ERROR_CODE;
566 }
567 
568 double FlavourUncertaintyComponent::getQuarkResponseBaseline(const double pT, const double eta) const
569 {
571  {
572  ATH_MSG_ERROR("This method is only useable for FlavourComposition uncertainties, not " << getName().Data());
573  return JESUNC_ERROR_CODE;
574  }
576  return m_uncHist->getValue(pT,eta);
578  return m_secondUncHist->getValue(pT,eta);
579  ATH_MSG_ERROR("Unexpected flavour response parametrization: " << getName().Data());
580  return JESUNC_ERROR_CODE;
581 }
582 
583 
585 // //
586 // Private helper functions //
587 // //
589 
590 StatusCode FlavourUncertaintyComponent::readNjetsHistograms(std::vector<UncertaintyHistogram*>& hists, const std::vector<TString>& histKeys)
591 {
592  for (size_t iKey = 0; iKey < histKeys.size(); ++iKey)
593  {
594  const TString& histName = histKeys.at(iKey);
595  int nJets = -1;
596  if (getNjetFromKey(histName,nJets).isFailure())
597  return StatusCode::FAILURE;
598  if (nJets < 0 || nJets >= static_cast<int>(hists.size()))
599  {
600  ATH_MSG_ERROR(Form("Unexpected gluon fraction nJet %d of index %zu: %s",nJets,iKey,histName.Data()));
601  return StatusCode::FAILURE;
602  }
603  if (hists[nJets])
604  {
605  ATH_MSG_ERROR(Form("A histo for nJets of %d was already found, blocking double-creation of %s",nJets,histName.Data()));
606  return StatusCode::FAILURE;
607  }
609  }
610  return StatusCode::SUCCESS;
611 }
612 
614 {
615  std::vector<TString> tokens = utils::vectorize<TString>(key,"_");
616  if (tokens.size() > 2 && tokens.at(tokens.size()-1).Contains("nJet",TString::kIgnoreCase))
617  {
618  TString nJetStr = tokens.at(tokens.size()-1).ReplaceAll("nJet","");
619  nJetStr = nJetStr.ReplaceAll("njet","");
620  nJetStr = nJetStr.ReplaceAll("Njet","");
621  if (!utils::getTypeObjFromString<int>(nJetStr,nJets))
622  {
623  ATH_MSG_ERROR("Found nJets histogram, but failed to parse the index: " << key.Data());
624  return StatusCode::FAILURE;
625  }
626  }
627  return StatusCode::SUCCESS;
628 }
629 
631 {
632  // nJets = 0 is the inclusive composition
633  // nJets = # is the composition for # jets
634  // nJets < 0 uses default if available
635  // nJets > MAX uses default if available
636  // nJets = #, but # is NULL uses default if available
637 
638  // Case of no histograms is checked in initialization, no need to repeat here
639  // Initialization also ensures gluonFractionHists and gluonFractionErrorHists are consistent
640 
641  // Check if we need to use the default histogram
642  if (nJets < 0 || nJets >= static_cast<int>(m_gluonFractionHists.size()) || m_gluonFractionHists.at(nJets) == nullptr)
643  {
644  // Check if we can fall back on the default bin (does it exist?)
645  if (m_gluonFractionHists.at(0) == nullptr)
646  {
647  ATH_MSG_ERROR("nJets of " << nJets << " is invalid, and default does not exist to fall back on, for " << getName().Data());
648  return StatusCode::FAILURE;
649  }
650  // Fall back on the default bin
651  nJets = 0;
652  }
653  // Otherwise, the specified nJets value is fine and doesn't need to be touched
654 
655 
656  return StatusCode::SUCCESS;
657 }
658 
660 {
661  // If not specified, assume it's not a b-jet
662  if (!m_BjetAccessor.isAvailable(jet)) return false;
663 
664  // If it's available, return the value (now a char, so check non-equality with 0)
665  return m_BjetAccessor(jet) != 0;
666 }
667 
668 
669 void FlavourUncertaintyComponent::getGluonKeys(TFile* analysisFile, std::vector<TString>& gluonFractionKeys, std::vector<TString>& gluonFractionErrorKeys) const
670 {
671  TList* keys = analysisFile->GetListOfKeys();
672  TIter nextkey(keys);
673  if (m_analysisHistPattern != "")
674  {
675  ATH_MSG_DEBUG("Ignoring histograms which don't contain pattern " << m_analysisHistPattern.Data());
676  }
677  while (TKey* key = dynamic_cast<TKey*>(nextkey()))
678  {
679  if (!key) continue;
680  const TString keyName = key->GetName();
681  //Ignoring histograms which doesn't contain user-defined pattern
682  if (m_analysisHistPattern != "" && !keyName.Contains(m_analysisHistPattern)) continue;
683  if (keyName.Contains(m_jetType) && !keyName.Contains("valid"))
684  {
685  if (keyName.Contains("gluonFractionError"))
686  gluonFractionErrorKeys.push_back(keyName);
687  else if (keyName.Contains("gluonFraction"))
688  gluonFractionKeys.push_back(keyName);
689  }
690  }
691 }
692 
693 
694 
695 } // end jet namespace
696 
LargeRJetTruthLabel::TypeEnum
TypeEnum
Definition: LargeRJetLabelEnum.h:14
CalculateHighPtTerm.pT
pT
Definition: ICHEP2016/CalculateHighPtTerm.py:57
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
jet::FlavourComp::UNKNOWN
@ UNKNOWN
Definition: UncertaintyEnum.h:178
jet::UncertaintyComponent::m_energyScale
const float m_energyScale
Definition: UncertaintyComponent.h:55
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:126
jet::FlavourUncertaintyComponent::FlavourResp_QUARK
@ FlavourResp_QUARK
Definition: FlavourUncertaintyComponent.h:44
AddEmptyComponent.histName
string histName
Definition: AddEmptyComponent.py:64
jet::UncertaintyComponent::m_interpolate
const Interpolate::TypeEnum m_interpolate
Definition: UncertaintyComponent.h:56
jet::FlavourUncertaintyComponent::m_calibArea
const TString m_calibArea
Definition: FlavourUncertaintyComponent.h:53
LargeRJetTruthLabel::UNKNOWN
@ UNKNOWN
Definition: LargeRJetLabelEnum.h:15
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
Data
@ Data
Definition: BaseObject.h:11
FlavourUncertaintyComponent.h
jet::FlavourUncertaintyComponent::m_flavourType
const FlavourComp::TypeEnum m_flavourType
Definition: FlavourUncertaintyComponent.h:47
jet::ComponentHelper
Definition: ConfigHelper.h:24
jet::FlavourUncertaintyComponent::clone
virtual FlavourUncertaintyComponent * clone() const
Definition: FlavourUncertaintyComponent.cxx:120
jet::FlavourUncertaintyComponent::getBJESUncertainty
double getBJESUncertainty(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
Definition: FlavourUncertaintyComponent.cxx:515
jet::UncertaintyComponent::m_uncHistName
const TString m_uncHistName
Definition: UncertaintyComponent.h:51
jet::FlavourUncertaintyComponent::m_NjetAccessor
SG::AuxElement::Accessor< int > m_NjetAccessor
Definition: FlavourUncertaintyComponent.h:67
jet::CompParametrization::isAbsEta
bool isAbsEta(const TypeEnum type)
Definition: UncertaintyEnum.cxx:143
jet::UncertaintyComponent::initialize
virtual StatusCode initialize(TFile *histFile)
Definition: UncertaintyComponent.cxx:96
jet::FlavourUncertaintyComponent::m_path
const TString m_path
Definition: FlavourUncertaintyComponent.h:52
beamspotman.tokens
tokens
Definition: beamspotman.py:1284
jet::FlavourUncertaintyComponent::FlavourResp_GLUON
@ FlavourResp_GLUON
Definition: FlavourUncertaintyComponent.h:44
jet::UncertaintyComponent::getValidBool
virtual bool getValidBool(const double validity) const
Definition: UncertaintyComponent.cxx:301
jet::UncertaintyHistogram::getValue
double getValue(const double var1) const
Definition: UncertaintyHistogram.cxx:141
jet::FlavourUncertaintyComponent::m_largeRJetTruthLabelAccessor
SG::AuxElement::Accessor< int > m_largeRJetTruthLabelAccessor
Definition: FlavourUncertaintyComponent.h:68
Helpers.h
jet::UncertaintyComponent
Definition: UncertaintyComponent.h:25
jet::FlavourUncertaintyComponent::getGluonFraction
double getGluonFraction(const double pT, const double eta, const int nJets) const
Definition: FlavourUncertaintyComponent.cxx:530
jet::UncertaintyHistogram::initialize
virtual StatusCode initialize(TFile *histFile)
Definition: UncertaintyHistogram.cxx:85
jet::FlavourUncertaintyComponent::m_gluonFractionErrorHists
std::vector< UncertaintyHistogram * > m_gluonFractionErrorHists
Definition: FlavourUncertaintyComponent.h:72
JESUNC_ERROR_CODE
#define JESUNC_ERROR_CODE
Definition: Reconstruction/Jet/JetUncertainties/JetUncertainties/Helpers.h:23
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
jet::FlavourUncertaintyComponent::m_respType
FlavourRespType m_respType
Definition: FlavourUncertaintyComponent.h:64
jet::FlavourUncertaintyComponent::m_gluonFractionHists
std::vector< UncertaintyHistogram * > m_gluonFractionHists
Definition: FlavourUncertaintyComponent.h:71
jet::FlavourUncertaintyComponent::getUncertaintyImpl
virtual double getUncertaintyImpl(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
Definition: FlavourUncertaintyComponent.cxx:367
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::FlavourUncertaintyComponent::isBjet
bool isBjet(const xAOD::Jet &jet) const
Definition: FlavourUncertaintyComponent.cxx:659
jet::FlavourUncertaintyComponent::m_analysisFileName
const TString m_analysisFileName
Definition: FlavourUncertaintyComponent.h:49
jet::UncertaintyComponent::m_validHist
UncertaintyHistogram * m_validHist
Definition: UncertaintyComponent.h:61
jet::FlavourUncertaintyComponent::getFlavourCompositionUncertainty
double getFlavourCompositionUncertainty(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
Definition: FlavourUncertaintyComponent.cxx:456
jet::FlavourComp::bJES
@ bJES
Definition: UncertaintyEnum.h:181
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::FlavourUncertaintyComponent::m_largeRJetTruthLabels
std::vector< LargeRJetTruthLabel::TypeEnum > m_largeRJetTruthLabels
Definition: FlavourUncertaintyComponent.h:61
m_path
std::string m_path
the path being used
Definition: OutputStreamData.cxx:88
jet::FlavourUncertaintyComponent::m_secondUncHist
UncertaintyHistogram * m_secondUncHist
Definition: FlavourUncertaintyComponent.h:63
jet::FlavourComp::Composition
@ Composition
Definition: UncertaintyEnum.h:180
jet::FlavourUncertaintyComponent::readNjetsHistograms
StatusCode readNjetsHistograms(std::vector< UncertaintyHistogram * > &hists, const std::vector< TString > &histKeys)
Definition: FlavourUncertaintyComponent.cxx:590
MakeTH3DFromTH2Ds.hists
hists
Definition: MakeTH3DFromTH2Ds.py:72
plotmaker.keyName
keyName
Definition: plotmaker.py:145
jet::FlavourUncertaintyComponent::m_secondUncName
const TString m_secondUncName
Definition: FlavourUncertaintyComponent.h:56
jet::FlavourUncertaintyComponent::initialize
virtual StatusCode initialize(TFile *histFile)
Definition: FlavourUncertaintyComponent.cxx:140
jet::FlavourUncertaintyComponent::m_largeRJetTruthLabelName
std::string m_largeRJetTruthLabelName
Definition: FlavourUncertaintyComponent.h:58
jet::FlavourUncertaintyComponent::getGluonResponseBaseline
double getGluonResponseBaseline(const double pT, const double eta) const
Definition: FlavourUncertaintyComponent.cxx:552
jet::FlavourUncertaintyComponent::getGluonResponseDifference
double getGluonResponseDifference(const double pT, const double eta) const
Definition: FlavourUncertaintyComponent.cxx:542
jet::FlavourUncertaintyComponent::getFlavourResponseUncertainty
double getFlavourResponseUncertainty(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
Definition: FlavourUncertaintyComponent.cxx:420
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
jet::FlavourUncertaintyComponent::FlavourUncertaintyComponent
FlavourUncertaintyComponent(const ComponentHelper &component, const TString &jetType, const TString &analysisRootFileName, const TString &defaultAnalysisRootFileName, const TString &path, const TString &calibArea, const bool absEtaGluonFraction, const TString &analysisHistPattern="")
Definition: FlavourUncertaintyComponent.cxx:45
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
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
jet::FlavourUncertaintyComponent::m_analysisHistPattern
const TString m_analysisHistPattern
Definition: FlavourUncertaintyComponent.h:50
jet::FlavourUncertaintyComponent::getGluonKeys
void getGluonKeys(TFile *analysisFile, std::vector< TString > &gluonFractionKeys, std::vector< TString > &gluonFractionErrorKeys) const
Definition: FlavourUncertaintyComponent.cxx:669
ConvertOldUJHistosToNewHistos.jetType
string jetType
Definition: ConvertOldUJHistosToNewHistos.py:121
jet::FlavourUncertaintyComponent::getGluonFractionError
double getGluonFractionError(const double pT, const double eta, const int nJets) const
Definition: FlavourUncertaintyComponent.cxx:536
jet::FlavourComp::Response
@ Response
Definition: UncertaintyEnum.h:179
jet::FlavourUncertaintyComponent::m_secondRespType
FlavourRespType m_secondRespType
Definition: FlavourUncertaintyComponent.h:65
LargeRJetTruthLabel::intToEnum
TypeEnum intToEnum(const int type)
Definition: LargeRJetLabelEnum.h:57
jet::FlavourUncertaintyComponent::getQuarkResponseBaseline
double getQuarkResponseBaseline(const double pT, const double eta) const
Definition: FlavourUncertaintyComponent.cxx:568
jet::FlavourUncertaintyComponent::getNjetFromKey
StatusCode getNjetFromKey(const TString &key, int &nJets) const
Definition: FlavourUncertaintyComponent.cxx:613
jet::FlavourUncertaintyComponent::m_absEta
const bool m_absEta
Definition: FlavourUncertaintyComponent.h:54
jet::FlavourUncertaintyComponent::m_jetType
const TString m_jetType
Definition: FlavourUncertaintyComponent.h:48
jet::UncertaintyComponent::m_uncHist
UncertaintyHistogram * m_uncHist
Definition: UncertaintyComponent.h:60
jet::utils::readRootFile
TFile * readRootFile(const TString &fileName, const TString &path="", const TString &calibArea="")
Definition: Reconstruction/Jet/JetUncertainties/Root/Helpers.cxx:139
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:790
jet::FlavourUncertaintyComponent::getValidityImpl
virtual bool getValidityImpl(const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
Definition: FlavourUncertaintyComponent.cxx:344
jet::FlavourUncertaintyComponent::m_defAnaFileName
const TString m_defAnaFileName
Definition: FlavourUncertaintyComponent.h:51
jet::FlavourUncertaintyComponent::checkNjetsInput
StatusCode checkNjetsInput(int &nJets) const
Definition: FlavourUncertaintyComponent.cxx:630
jet::FlavourUncertaintyComponent::~FlavourUncertaintyComponent
virtual ~FlavourUncertaintyComponent()
Definition: FlavourUncertaintyComponent.cxx:125
jet::FlavourUncertaintyComponent::m_BjetAccessor
SG::AuxElement::Accessor< char > m_BjetAccessor
Definition: FlavourUncertaintyComponent.h:66
LArG4GenerateShowerLib.parametrization
parametrization
Definition: LArG4GenerateShowerLib.py:19
jet::FlavourUncertaintyComponent
Definition: FlavourUncertaintyComponent.h:14
jet::FlavourUncertaintyComponent::m_absEtaGluonFraction
const bool m_absEtaGluonFraction
Definition: FlavourUncertaintyComponent.h:55
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37