ATLAS Offline Software
JetUncertaintiesTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // General package includes
12 
13 // UncertaintyHistogram types
16 
17 // UncertaintyComponent types
37 
38 // xAOD includes
39 #include "xAODCore/ShallowCopy.h"
41 
42 // CP interface includes
45 
46 // ROOT includes
47 #include "TString.h"
48 #include "TFile.h"
49 #include "TDirectory.h"
50 #include "TROOT.h"
51 #include "TEnv.h"
52 #include "TH2D.h"
53 
54 // C++ includes
55 #include <unordered_set>
56 
57 using namespace jet;
58 
60 // //
61 // Constructor/destructor/initialization //
62 // //
64 
66  : asg::AsgTool(name)
67  , m_isInit(false)
68  , m_name(name)
69  , m_energyScale(1.e-3)
70  , m_release("")
71  , m_jetDef("")
72  , m_mcType("")
73  , m_configFile("")
74  , m_calibArea("CalibArea-08")
75  , m_path("")
76  , m_analysisFile("")
77  , m_analysisHistPattern("")
78  , m_systFilters()
79  , m_defAnaFile("")
80  , m_refNPV(-1)
81  , m_refMu(-1)
82  , m_refNPVHist(nullptr)
83  , m_refMuHist(nullptr)
84  , m_groups()
85  , m_recognizedSystematics()
86  , m_recommendedSystematics()
87  , m_currentSystSet()
88  , m_currentUncSet(nullptr)
89  , m_systFilterMap()
90  , m_systSetMap()
91  , m_fileValidHist(nullptr)
92  , m_caloMassWeight(nullptr)
93  , m_TAMassWeight(nullptr)
94  , m_combMassWeightCaloMassDef(CompMassDef::UNKNOWN)
95  , m_combMassWeightTAMassDef(CompMassDef::UNKNOWN)
96  , m_combMassParam(CompParametrization::UNKNOWN)
97  , m_userSeed(0)
98  , m_rand()
99  , m_isData(true)
100  , m_resHelper(nullptr)
101  , m_namePrefix("JET_")
102  , m_accTagScaleFactor("temp_SF")
103  , m_accEffSF("temp_effSF")
104  , m_accSigeffSF("temp_sigeffSF")
105  , m_accEfficiency("temp_efficiency")
106  , m_accTagResult("temp_accept")
107  , m_absEtaGluonFraction(true)
108  , m_pseudoDataJERsmearingMode(false)
109 {
110  declareProperty("JetDefinition",m_jetDef);
111  declareProperty("MCType",m_mcType);
112  declareProperty("ConfigFile",m_configFile);
113  declareProperty("CalibArea",m_calibArea);
114  declareProperty("Path",m_path);
115  declareProperty("AnalysisFile",m_analysisFile);
116  declareProperty("AnalysisHistPattern",m_analysisHistPattern);
117  declareProperty("VariablesToShift",m_systFilters);
118  declareProperty("IsData",m_isData);
119  declareProperty("AbsEtaGluonFraction",m_absEtaGluonFraction);
120  declareProperty("PseudoDataJERsmearingMode",m_pseudoDataJERsmearingMode);
121 
122  ATH_MSG_DEBUG("Creating JetUncertaintiesTool named "<<m_name);
123 
124  // Set dummy default systematic (do nothing)
125  // Prevents NULL access if user tries to apply correction without first calling function
127  ATH_MSG_ERROR(Form("Failed to pre-set applySystematicVariation to no variation"));
128 }
129 
131  : asg::AsgTool(toCopy.m_name+"_copy")
132  , m_isInit(toCopy.m_isInit)
133  , m_name(toCopy.m_name+"_copy")
134  , m_energyScale(1.e-3)
135  , m_release(toCopy.m_release)
136  , m_jetDef(toCopy.m_jetDef)
137  , m_mcType(toCopy.m_mcType)
138  , m_configFile(toCopy.m_configFile)
139  , m_calibArea(toCopy.m_calibArea)
140  , m_path(toCopy.m_path)
141  , m_analysisFile(toCopy.m_analysisFile)
142  , m_analysisHistPattern(toCopy.m_analysisHistPattern)
143  , m_systFilters(toCopy.m_systFilters)
144  , m_defAnaFile(toCopy.m_defAnaFile)
145  , m_refNPV(toCopy.m_refNPV)
146  , m_refMu(toCopy.m_refMu)
147  , m_refNPVHist(toCopy.m_refNPVHist?new UncertaintyHistogram(*toCopy.m_refNPVHist):nullptr)
148  , m_refMuHist(toCopy.m_refMuHist?new UncertaintyHistogram(*toCopy.m_refMuHist):nullptr)
149  , m_groups()
150  , m_recognizedSystematics(toCopy.m_recognizedSystematics)
151  , m_recommendedSystematics(toCopy.m_recommendedSystematics)
152  , m_currentSystSet(toCopy.m_currentSystSet)
153  , m_currentUncSet(nullptr)
154  , m_systFilterMap()
155  , m_systSetMap()
156  , m_fileValidHist(toCopy.m_fileValidHist)
157  , m_caloMassWeight(nullptr)
158  , m_TAMassWeight(nullptr)
159  , m_combMassWeightCaloMassDef(CompMassDef::UNKNOWN)
160  , m_combMassWeightTAMassDef(CompMassDef::UNKNOWN)
161  , m_combMassParam(CompParametrization::UNKNOWN)
162  , m_userSeed(toCopy.m_userSeed)
163  , m_rand(toCopy.m_rand)
164  , m_isData(toCopy.m_isData)
165  , m_resHelper(new ResolutionHelper(*toCopy.m_resHelper))
166  , m_namePrefix(toCopy.m_namePrefix)
167  , m_accTagScaleFactor(toCopy.m_accTagScaleFactor)
168  , m_accEffSF(toCopy.m_accEffSF)
169  , m_accSigeffSF(toCopy.m_accSigeffSF)
170  , m_accEfficiency(toCopy.m_accEfficiency)
171  , m_accTagResult(toCopy.m_accTagResult)
172  , m_absEtaGluonFraction(toCopy.m_absEtaGluonFraction)
173  , m_pseudoDataJERsmearingMode(toCopy.m_pseudoDataJERsmearingMode)
174 {
175  ATH_MSG_DEBUG("Creating copy of JetUncertaintiesTool named "<<m_name);
176 
177  for (size_t iGroup = 0; iGroup < toCopy.m_groups.size(); ++iGroup)
178  m_groups.push_back(new UncertaintyGroup(*toCopy.m_groups.at(iGroup)));
179 
181  ATH_MSG_ERROR(Form("Failed to re-set applySystematicVariation in new tool copy"));
182 }
183 
185 {
186  ATH_MSG_DEBUG(Form("Deleting JetUncertaintiesTool named %s",m_name.c_str()));
187 
188  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup)
189  JESUNC_SAFE_DELETE(m_groups.at(iGroup));
190  m_groups.clear();
191 
197 
198  m_currentUncSet = nullptr;
199 
200  m_systFilterMap.clear();
201 
203  for (iter = m_systSetMap.begin(); iter != m_systSetMap.end(); ++iter)
204  JESUNC_SAFE_DELETE(iter->second);
205  m_systSetMap.clear();
206 
208 }
209 
211 {
212  // Ensure it hasn't been initialized yet
213  if (m_isInit)
214  {
215  ATH_MSG_FATAL("Cannot set the energy scale after initialization of tool: " << m_name);
216  return StatusCode::FAILURE;
217  }
218 
219  m_energyScale = 1.e-3;
220  return StatusCode::SUCCESS;
221 }
222 
224 {
225  // Ensure it hasn't been initialized yet
226  if (m_isInit)
227  {
228  ATH_MSG_FATAL("Cannot set the energy scale after initialization of tool: " << m_name);
229  return StatusCode::FAILURE;
230  }
231 
232  m_energyScale = 1;
233  return StatusCode::SUCCESS;
234 }
235 
237 {
238  // Ensure it hasn't been initialized already
239  if (m_isInit)
240  {
241  ATH_MSG_FATAL(Form("Blocking re-initialization of tool named %s",m_name.c_str()));
242  return StatusCode::FAILURE;
243  }
244 
245  ATH_MSG_INFO(Form("Preparing to initialize the JetUncertaintiesTool named %s",m_name.c_str()));
246 
247  // Cache the current directory
248  TDirectory* currentDir = gDirectory;
249  gROOT->cd();
250 
251  // Read the config file
252  const TString configFilePath = jet::utils::findFilePath(m_configFile.c_str(),m_path.c_str(),m_calibArea.c_str());
253  if (configFilePath == "")
254  {
255  ATH_MSG_ERROR("Cannot find config file: " << m_configFile << " (path is \"" << m_path << "\", CalibArea is \"" << m_calibArea << "\")");
256  return StatusCode::FAILURE;
257  }
258 
259  TEnv settings;
260  if (settings.ReadFile(configFilePath.Data(),kEnvGlobal))
261  {
262  ATH_MSG_ERROR("Cannot read config file: " << configFilePath.Data());
263  return StatusCode::FAILURE;
264  }
265 
266  // We can read it - start printing
267  ATH_MSG_INFO(Form("================================================"));
268  ATH_MSG_INFO(Form(" Initializing the JetUncertaintiesTool named %s",m_name.c_str()));
269  ATH_MSG_INFO(Form(" Path is: \"%s\"",m_path.c_str()));
270  ATH_MSG_INFO(Form(" CalibArea is: \"%s\"",m_calibArea.c_str()));
271  ATH_MSG_INFO(Form(" IsData is: \"%s\"",m_isData ? "true" : "false"));
272  ATH_MSG_INFO(Form(" Configuration file: \"%s\"",m_configFile.c_str()));
273  ATH_MSG_INFO(Form(" Location: %s",configFilePath.Data()));
274 
275 
276  // Get the uncertainty release
277  m_release = settings.GetValue("UncertaintyRelease","UNKNOWN");
278  ATH_MSG_INFO(Form(" Uncertainty release: %s",m_release.c_str()));
279 
280  // Check the jet definition
281  TString allowedJetDefStr = settings.GetValue("SupportedJetDefs","");
282  if (allowedJetDefStr == "")
283  {
284  ATH_MSG_ERROR("Cannot find supported jet definitions in config");
285  return StatusCode::FAILURE;
286  }
287  std::vector<TString> allowedJetDefs = jet::utils::vectorize<TString>(allowedJetDefStr," ,");
288  bool foundJetDef = false;
289  for (size_t iDef = 0; iDef < allowedJetDefs.size(); ++iDef)
290  if (!allowedJetDefs.at(iDef).CompareTo(m_jetDef.c_str(),TString::kIgnoreCase))
291  {
292  foundJetDef = true;
293  m_jetDef = allowedJetDefs.at(iDef); // To ensure right capitalization
294  break;
295  }
296  if (!foundJetDef)
297  {
298  ATH_MSG_ERROR("Unsupported jet definition: " << m_jetDef);
299  return StatusCode::FAILURE;
300  }
301  ATH_MSG_INFO(Form(" Jet definition: %s",m_jetDef.c_str()));
302 
303  // Check the MC type
304  TString allowedMCtypeStr = settings.GetValue("SupportedMCTypes","");
305  if (allowedMCtypeStr == "")
306  {
307  ATH_MSG_ERROR("Cannot find supported MC types in config");
308  return StatusCode::FAILURE;
309  }
310  std::vector<TString> allowedMCtypes = jet::utils::vectorize<TString>(allowedMCtypeStr," ,");
311  bool foundMCtype = false;
312  for (size_t iType = 0; iType < allowedMCtypes.size(); ++iType)
313  if (!allowedMCtypes.at(iType).CompareTo(m_mcType.c_str(),TString::kIgnoreCase))
314  {
315  foundMCtype = true;
316  m_mcType = allowedMCtypes.at(iType); // To ensure right capitalization
317  break;
318  }
319  if (!foundMCtype)
320  {
321  ATH_MSG_ERROR("Unsupported MC type: " << m_mcType);
322  return StatusCode::FAILURE;
323  }
324  ATH_MSG_INFO(Form(" MC type: %s",m_mcType.c_str()));
325 
326 
327  // Get the file to read uncertainties in from
328  TString histFileName = settings.GetValue("UncertaintyRootFile","");
329  if (histFileName == "")
330  {
331  ATH_MSG_ERROR("Cannot find uncertainty histogram file");
332  return StatusCode::FAILURE;
333  }
334  ATH_MSG_INFO(Form(" UncertaintyFile: \"%s\"",histFileName.Data()));
335 
336  // Now find the histogram file
337  const TString histFilePath = utils::findFilePath(histFileName,m_path.c_str(),m_calibArea.c_str());
338  if (histFilePath == "")
339  {
340  ATH_MSG_ERROR("Cannot find the path of the uncertainty histogram file");
341  return StatusCode::FAILURE;
342  }
343  ATH_MSG_INFO(Form(" Location: %s",histFilePath.Data()));
344 
345  // Now open the histogram file
346  TFile* histFile = new TFile(histFilePath,"READ");
347  if (!histFile || histFile->IsZombie())
348  {
349  ATH_MSG_ERROR("Cannot open uncertainty histogram file: " << histFileName.Data());
350  return StatusCode::FAILURE;
351  }
352 
353 
354  // Get the default analysis ROOT file for later use
355  // Overwrite the analysisFile if it wasn't specified
356  m_defAnaFile = settings.GetValue("AnalysisRootFile","");
357  if (m_analysisFile.empty())
359  if (!m_analysisFile.empty())
360  {
361  ATH_MSG_INFO(Form(" AnalysisFile: \"%s\"",m_analysisFile.c_str()));
362  // Ensure that we can find the file
363  const TString analysisFilePath = utils::findFilePath(m_analysisFile.c_str(),m_path.c_str(),m_calibArea.c_str());
364  if (analysisFilePath == "")
365  {
366  ATH_MSG_ERROR("Cannot find the path of the analysis histogram file");
367  return StatusCode::FAILURE;
368  }
369  ATH_MSG_INFO(Form(" Location: %s",analysisFilePath.Data()));
370  }
371  if (m_defAnaFile != m_analysisFile && !m_defAnaFile.empty())
372  {
373  ATH_MSG_INFO(Form(" DefaultAnalysisFile: \"%s\"",m_defAnaFile.c_str()));
374  // Ensure that we can find the file
375  const TString analysisFilePath = utils::findFilePath(m_defAnaFile.c_str(),m_path.c_str(),m_calibArea.c_str());
376  if (analysisFilePath == "")
377  {
378  ATH_MSG_ERROR("Cannot find the path of the default analysis histogram file");
379  return StatusCode::FAILURE;
380  }
381  ATH_MSG_INFO(Form(" Location: %s",analysisFilePath.Data()));
382  // if a histogram pattern was provided, then use it (only if an analysis file is used)
383  if (!m_analysisHistPattern.empty())
384  {
385  ATH_MSG_INFO(Form(" AnalysisHistPattern: \"%s\"",m_analysisHistPattern.c_str()));
386  }
387  }
388 
389  // Get a file-wide validity histogram if specified
390  TString validHistForFile = settings.GetValue("FileValidHistogram","");
391  if (validHistForFile != "")
392  {
393  // Ensure that the parametrization is also specified
394  TString validHistForFileParam = settings.GetValue("FileValidHistParam","");
395  if (validHistForFileParam == "")
396  {
397  ATH_MSG_ERROR("Specified a FileValidHistogram without an accompanying FileValidHistParam: " << validHistForFile.Data());
398  return StatusCode::FAILURE;
399  }
400 
401  // Translate parametrization to enum
402  const CompParametrization::TypeEnum validHistParam = CompParametrization::stringToEnum(validHistForFileParam);
403 
404  // Check if a mass def was specified (optional)
405  const CompMassDef::TypeEnum validHistMassDef = CompMassDef::stringToEnum(settings.GetValue("FileValidHistMassDef",""));
406 
407  // Create and initialize the validity histogram
408  m_fileValidHist = new ValidityHistogram(validHistForFile+"_"+m_jetDef,validHistParam,m_energyScale,validHistMassDef);
409  if (m_fileValidHist->initialize(histFile).isFailure())
410  return StatusCode::FAILURE;
411 
412  ATH_MSG_INFO(Form(" FileValidHistogram: %s (%s)%s",validHistForFile.Data(),validHistForFileParam.Data(),validHistMassDef == CompMassDef::UNKNOWN ? "" : Form(" [%s]",CompMassDef::enumToString(validHistMassDef).Data())));
413  }
414 
415  // Check if combined mass weights have been specified
416  const TString caloMassWeight = TString(settings.GetValue("CombMassWeightCaloHist",""));
417  const TString TAMassWeight = TString(settings.GetValue("CombMassWeightTAHist",""));
418  if (caloMassWeight != "" && TAMassWeight != "")
419  {
420  m_caloMassWeight = new UncertaintyHistogram(caloMassWeight+"_"+m_jetDef.c_str(),Interpolate::Full);
421  m_TAMassWeight = new UncertaintyHistogram(TAMassWeight+"_"+m_jetDef.c_str(),Interpolate::Full);
422 
423  if (m_caloMassWeight->initialize(histFile).isFailure())
424  return StatusCode::FAILURE;
425  if (m_TAMassWeight->initialize(histFile).isFailure())
426  return StatusCode::FAILURE;
427 
428  // Get the weight parametrization, defaulting to pT vs m/pT
429  const TString combMassParam = TString(settings.GetValue("CombMassWeightParam","PtMass"));
432  {
433  ATH_MSG_ERROR("Unexpected combined mass parametrization: " << combMassParam.Data());
434  return StatusCode::FAILURE;
435  }
436 
437  ATH_MSG_INFO(" Found and loaded combined mass weight factors");
438  ATH_MSG_INFO(" WeightCaloHist = " << m_caloMassWeight->getName());
439  ATH_MSG_INFO(" WeightTAHist = " << m_TAMassWeight->getName());
441 
442  // Check for custom mass definitions for the weight factors (not required, defaults exist)
443  const TString caloWeightMassDef = settings.GetValue("CombMassWeightCaloMassDef","Calo");
444  const TString TAWeightMassDef = settings.GetValue("CombMassWeightTAMassDef","TA");
445  if (caloWeightMassDef != "")
446  {
448  ATH_MSG_INFO(" WeightCaloMassDef was set to " << CompMassDef::enumToString(m_combMassWeightCaloMassDef).Data());
449  }
450  if (TAWeightMassDef != "")
451  {
453  ATH_MSG_INFO(" WeightTAMassDef was set to " << CompMassDef::enumToString(m_combMassWeightTAMassDef).Data());
454  }
455  }
456  else if (caloMassWeight != "" && TAMassWeight == "")
457  {
458  ATH_MSG_ERROR(" Found combined mass weight factors for the calo term, but not the TA term");
459  return StatusCode::FAILURE;
460  }
461  else if (caloMassWeight == "" && TAMassWeight != "")
462  {
463  ATH_MSG_ERROR(" Found combined mass weight factors for the TA term, but not the calo term");
464  return StatusCode::FAILURE;
465  }
466 
467  // Get name of accessor to SF value
468  m_name_TagScaleFactor = TString(settings.GetValue("TagSFName","temp_SF"));
469  m_name_EffSF = TString(settings.GetValue("TagSFEffName","temp_effSF"));
470  m_name_Efficiency = TString(settings.GetValue("TagEfficiencyName","temp_efficiency"));
471  m_name_TagResult = TString(settings.GetValue("TagResultName","temp_accept")).ReplaceAll("accept", "Tagged");
472  m_name_SigeffSF = TString(m_name_EffSF).ReplaceAll("effSF", "sigeffSF");
473  if ( m_name_TagScaleFactor != "temp_SF") {
474  ATH_MSG_INFO(" accessor of SF is " << m_name_TagScaleFactor);
475  }
481 
482  // Get the NPV/mu reference values
483  // These may not be set - only needed if a pileup component is requested
484  TString refNPV = settings.GetValue("Pileup.NPVRef","");
485  TString refMu = settings.GetValue("Pileup.MuRef","");
486  if ( (refNPV != "" && refMu == "") || (refNPV == "" && refMu != "") )
487  {
488  ATH_MSG_ERROR(Form("Only one of the pileup references was specified: (NPV,mu) = (%.1f,%.1f)",m_refNPV,m_refMu));
489  return StatusCode::FAILURE;
490  }
491  else if ( refNPV != "" && refMu != "")
492  {
493  // Check if these are floating point values for the pileup references
494  // If so, then fill the float, otherwise retrieve the histogram
495  if (utils::isTypeObjFromString<float>(refNPV))
496  m_refNPV = utils::getTypeObjFromString<float>(refNPV);
497  else
498  {
500  if (m_refNPVHist->initialize(histFile).isFailure())
501  return StatusCode::FAILURE;
502  }
503 
504  if (utils::isTypeObjFromString<float>(refMu))
505  m_refMu = utils::getTypeObjFromString<float>(refMu);
506  else
507  {
509  if (m_refMuHist->initialize(histFile).isFailure())
510  return StatusCode::FAILURE;
511  }
512  }
513 
514  // If systematic filters were specified, first-order validate them
515  // Then inform the user
516  if (!m_systFilters.empty())
517  {
518  std::string varString = "";
519  for (size_t iFilter = 0; iFilter < m_systFilters.size(); ++iFilter)
520  {
522  {
523  ATH_MSG_ERROR("Unable to parse VariablesToShift due to unknown variable, please check for typos: " << m_systFilters.at(iFilter));
524  return StatusCode::FAILURE;
525  }
526  if (!varString.empty())
527  varString += ", ";
528  varString += m_systFilters.at(iFilter);
529  }
530  ATH_MSG_INFO(Form(" VariablesToShift: %s",varString.c_str()));
531  }
532 
533  // Attempt to read in nominal resolution information
534  // There may be no such information - this is perfectly normal
536  if(m_resHelper->initialize(settings,histFile,m_mcType.c_str()).isFailure())
537  return StatusCode::FAILURE;
538 
539  // Prepare for reading components and groups
540  // Components can be a group by themself (single component groups) if "Group" == 0
541  // Components can also form simple groups with "SubComp"
542  // Otherwise, need to specify group info separately from component info
543  // As such, start with groups, then handle components
544 
545  // Loop over uncertainty components and groups in the config
546  ATH_MSG_INFO("");
547  ATH_MSG_INFO(Form("%6s %-40s : %s","","JES uncert. comp.","Description"));
548  ATH_MSG_INFO(Form("%6s %-40s -%s","","-----------------","-----------"));
549  for (size_t iGroup = 0; iGroup < 999; ++iGroup)
550  {
551  // Format the style
552  const TString prefix = Form("JESGroup.%zu.",iGroup);
553 
554  // Read in information in the uncertainty group
556  if (helper.initialize(settings).isFailure())
557  return StatusCode::FAILURE;
558 
559  // Ignore the group if it's not defined
560  if (!helper.isGroup()) continue;
561 
562  // All groups have to follow a given prefix matching ASG conventions
563  // Enforce this condition here where the helper is not yet const
564  if (!m_namePrefix.empty())
565  helper.enforceGroupNamePrefix(m_namePrefix);
566 
567  // Call the uncertainty group helper method to add a new group
568  if (addUncertaintyGroup(helper).isFailure())
569  return StatusCode::FAILURE;
570  }
571  for (size_t iComp = 0; iComp < 999; ++iComp)
572  {
573  // Format the style
574  const TString prefix = Form("JESComponent.%zu.",iComp);
575 
576  // Read in information on the uncertainty component
578  if (helper.initialize(settings).isFailure())
579  return StatusCode::FAILURE;
580 
581  // Ignore component if it is not defined
582  if (!helper.isComponent() && !helper.isCompGroup())
583  continue;
584 
585  // All groups have to follow a given prefix matching ASG conventions
586  // Enforce this condition here where the helper is not yet const
587  // (Still relevant for components as many will be simple groups)
588  if (!m_namePrefix.empty())
589  helper.enforceGroupNamePrefix(m_namePrefix);
590 
591  // Also add the component name suffix for the jet definition
592  helper.setComponentJetDefSuffix(m_jetDef);
593 
594  // Call the uncertainty component helper method to add a new component
595  if(addUncertaintyComponent(helper).isFailure())
596  return StatusCode::FAILURE;
597  }
598 
599  // Preparing for a sanity check done after group merger
600  // Do this with components rather than groups to make sure totals are the same
601  size_t numCompsBeforeMerger = 0;
602  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup) {
603  numCompsBeforeMerger += m_groups.at(iGroup)->getNumComponents();
604 // std::cout << "Beginning group " << m_groups.at(iGroup)->getName() << std::endl;
605 // for (int i=0; i<m_groups.at(iGroup)->getComponents().size(); i++) {
606 // std::cout << "\t" << m_groups.at(iGroup)->getComponents().at(i)->getName() << std::endl;
607 // }
608 // for (int i=0; i<m_groups.at(iGroup)->getSubgroups().size(); i++) {
609 // for (int j=0; j<m_groups.at(iGroup)->getSubgroups().at(i)->getComponents().size(); j++)
610 // std::cout << "\t" << m_groups.at(iGroup)->getSubgroups().at(i)->getComponents().at(j)->getName() << std::endl;
611 // }
612  }
613 
614  // Merge all of the subgroups into their parent groups
615  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup)
616  {
617  const int groupNum = m_groups.at(iGroup)->getGroupNum();
618  const int subgroupNum = m_groups.at(iGroup)->getSubgroupNum();
619 
620  // groupNum == 0 means this is an independent group (no merging possible)
621  // subgroupNum == 0 means this is not a subgroup of anything (no merging possible)
622  if (!groupNum || !subgroupNum) continue;
623 
624  // Ensure we didn't do something silly
625  if (groupNum == subgroupNum)
626  {
627  ATH_MSG_ERROR(Form("Specified group %d (%s) as the parent of itself, blocking for safety",groupNum,m_groups.at(iGroup)->getName().Data()));
628  return StatusCode::FAILURE;
629  }
630 
631  // Find the parent group
632  for (size_t iParentGroup = 0; iParentGroup < m_groups.size(); ++iParentGroup)
633  {
634  if (iParentGroup == iGroup) continue;
635 
636  const int parentGroupNum = m_groups.at(iParentGroup)->getGroupNum();
637  if (parentGroupNum == subgroupNum)
638  {
639  // Add the subgroup to the parent group
640  if (m_groups.at(iParentGroup)->addSubgroup(m_groups.at(iGroup)).isFailure())
641  {
642  ATH_MSG_ERROR(Form("Failed to add group %d (%s) as a subgroup of group %d (%s)",groupNum,m_groups.at(iGroup)->getName().Data(),parentGroupNum,m_groups.at(iParentGroup)->getName().Data()));
643  return StatusCode::FAILURE;
644  }
645  }
646  }
647  }
648 
649  // Remove all of the subgroups from the class vector which contains the outermost groups for users to interact with
650  // Faster to do it this way rather than deleting individual entries of the vector
651  std::vector<UncertaintyGroup*> localGroupVec;
652  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup)
653  localGroupVec.push_back(m_groups.at(iGroup));
654  m_groups.clear();
655 
656  for (size_t iGroup = 0; iGroup < localGroupVec.size(); ++iGroup)
657  {
658  // If the group is not a sub-group, keep it
659  if (!localGroupVec.at(iGroup)->getSubgroupNum())
660  m_groups.push_back(localGroupVec.at(iGroup));
661  }
662 
663  // Sanity check that things make sense
664  // Do this with components rather than groups to make sure totals are the same
665  size_t numCompsAfterMerger = 0;
666  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup) {
667  numCompsAfterMerger += m_groups.at(iGroup)->getNumComponents();
668 // std::cout << "Beginning group " << m_groups.at(iGroup)->getName() << std::endl;
669 // for (int i=0; i<m_groups.at(iGroup)->getComponents().size(); i++) {
670 // std::cout << "\t" << m_groups.at(iGroup)->getComponents().at(i)->getName() << std::endl;
671 // }
672 // for (int i=0; i<m_groups.at(iGroup)->getSubgroups().size(); i++) {
673 // for (int j=0; j<m_groups.at(iGroup)->getSubgroups().at(i)->getComponents().size(); j++)
674 // std::cout << "\t" << m_groups.at(iGroup)->getSubgroups().at(i)->getComponents().at(j)->getName() << std::endl;
675 // }
676  }
677 
678  if (numCompsBeforeMerger != numCompsAfterMerger)
679  {
680  ATH_MSG_ERROR(Form("Something went wrong merging groups: %zu before merger and %zu after merger",numCompsBeforeMerger,numCompsAfterMerger));
681  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup)
682  {
683  ATH_MSG_ERROR(Form("\tFound %zu components in group: %s",m_groups.at(iGroup)->getNumComponents(),m_groups.at(iGroup)->getName().Data()));
684  }
685  return StatusCode::FAILURE;
686  }
687 
688 
689 
690  // Initialize all of the groups (and thus all of the components)
691  // Also ensure that there are no empty groups
692  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup)
693  {
694  if (m_groups.at(iGroup)->getNumComponents() == 0)
695  {
696  ATH_MSG_ERROR("An empty group was encountered: " << m_groups.at(iGroup)->getName().Data());
697  return StatusCode::FAILURE;
698  }
699  if (m_groups.at(iGroup)->initialize(histFile).isFailure())
700  return StatusCode::FAILURE;
701 
702  // Determine if the group is a recommended systematic
703  // Currently, all small-R systematics are recommended with one exception:
704  // MC closure systematics can be zero (when working with the reference MC)
705  // Still, check if the component is always zero and don't recommend if so
706  // For large-R, users are allowed to specify a set of filters for systematics
707  // Done for Moriond2017 as many variables were provided for studies
708  // Allows for users to not run variations of variables they don't use
709  // If unspecified, all variables are systematically shifted by default
710  const bool isRecommended = checkIfRecommendedSystematic(*m_groups.at(iGroup));
711  CP::SystematicVariation systVar(m_groups.at(iGroup)->getName().Data(),CP::SystematicVariation::CONTINUOUS);
712  if (addAffectingSystematic(systVar,isRecommended) != StatusCode::SUCCESS)
713  return StatusCode::FAILURE;
715  if (systVar.basename().find("JER") != std::string::npos) {
716  CP::SystematicVariation systVarPD(systVar.basename()+"_PseudoData",CP::SystematicVariation::CONTINUOUS);
717  if (addAffectingSystematic(systVarPD,isRecommended) != StatusCode::SUCCESS)
718  return StatusCode::FAILURE;
719  }
720  }
721  }
722 
723  // Ensure that we have nominal resolutions for any requested resolution uncertainties
724  // Do this at initialization, even if it is also checked in execution
725  // Also ensure that it was specified whether this is data or MC if resolutions are specified
726  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup)
727  {
728  std::set<CompScaleVar::TypeEnum> scaleVars = m_groups.at(iGroup)->getScaleVars();
729  for (CompScaleVar::TypeEnum var : scaleVars)
730  {
732  {
733  if (!m_resHelper->hasRelevantInfo(var,m_groups.at(iGroup)->getTopology()))
734  {
735  ATH_MSG_ERROR("Config file requests a resolution uncertainty without specifying the corresponding nominal resolution: " << CompScaleVar::enumToString(var).Data());
736  return StatusCode::FAILURE;
737  }
738  }
739  }
740  }
741 
742 
743  // Ensure that the filters are sane (they are all associated to at least one group)
744  for (size_t iFilter = 0; iFilter < m_systFilters.size(); ++iFilter)
745  {
746  bool filterIsSane = false;
747  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup)
748  {
749  if (m_groups.at(iGroup)->getScaleVars().count(CompScaleVar::stringToEnum(m_systFilters.at(iFilter))))
750  {
751  filterIsSane = true;
752  break;
753  }
754  }
755  if (!filterIsSane)
756  {
757  ATH_MSG_ERROR(" One of the specified VariablesToShift is not associated with any components, please check for typos: " << m_systFilters.at(iFilter));
758  return StatusCode::FAILURE;
759  }
760  }
761 
762 
763  // Determine the number of input parameters
764  size_t numCompInGroups = 0;
765  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup)
766  numCompInGroups += m_groups.at(iGroup)->getNumComponents();
767 
768  // Summary message
769  ATH_MSG_INFO(Form(" Found and read in %zu individual components into %zu component groups of which %zu are recommended",numCompInGroups,m_groups.size(),m_recommendedSystematics.size()));
770 
772  //ATH_MSG_INFO(Form(" Found and read in %zu components%s",m_components.size(),m_groups.size()?Form(" (%zu inputs in %zu groups, %zu independent input%s):",numCompInGroups,m_groups.size(),m_components.size()-m_groups.size(),m_components.size()-m_groups.size()!=1?"s":""):""));
773  //if (m_groups.size())
774  // for (size_t iComp = 0; iComp < m_components.size(); ++iComp)
775  // ATH_MSG_INFO(Form("%5zu. %-35s : %s",iComp+1,m_components.at(iComp)->getName().Data(),m_components.at(iComp)->getDesc().Data()));
776  ATH_MSG_INFO(Form("================================================"));
777 
778  // Close the histogram file
779  histFile->Close();
780  // Go back to initial directory
782 
783  // Finally done!
784  m_isInit = true;
785  return asg::AsgTool::initialize();
786 }
787 
789 // //
790 // Initialization helper methods //
791 // //
793 
795 {
796  const GroupHelper& group = *helper.getGroupInfo();
797 
798  // Ensure the group number is specified and doesn't conflict with existing groups
799  if (group.groupNum == 0)
800  {
801  ATH_MSG_ERROR("Group number was not specified for group: " << group.name.Data());
802  return StatusCode::FAILURE;
803  }
804  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup)
805  if (m_groups.at(iGroup)->getGroupNum() == group.groupNum)
806  {
807  ATH_MSG_ERROR("Group number matches previous group (" << m_groups.at(iGroup)->getName().Data() << "): " << group.name.Data());
808  return StatusCode::FAILURE;
809  }
810 
811  // Build the new group
813  if (!toAdd)
814  {
815  ATH_MSG_ERROR("Failed to build new group: " << group.name.Data());
816  return StatusCode::FAILURE;
817  }
818 
819  m_groups.push_back(toAdd);
820  if (!m_groups.back()->getSubgroupNum())
821  {
822  size_t numGroups = 0;
823  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup)
824  if (!m_groups.at(iGroup)->getSubgroupNum())
825  numGroups++;
826  ATH_MSG_INFO(Form("%5zu. %-40s : %s",numGroups //m_groups.size()
827  ,m_groups.back()->getName().Data()
828  ,m_groups.back()->getDesc().Data() ));
829  }
830  return StatusCode::SUCCESS;
831 }
832 
834 {
835  const bool isSimpleGroup = helper.isCompGroup();
836  const ComponentHelper& component = *helper.getComponentInfo();
837  const GroupHelper& group = *helper.getGroupInfo();
838 
839  ATH_MSG_DEBUG(Form("Starting to process %s named %s",isSimpleGroup?"simple component group":"standard component",component.name.Data()));
840 
841  // Find the group index that this component belongs to
842  // Note that if this is a simple group, we first need to build the associated group
843  if (isSimpleGroup)
844  {
845  UncertaintyGroup* simpleGroup = new UncertaintyGroup(group);
846  if (!simpleGroup)
847  {
848  ATH_MSG_ERROR("Failed to build simple group for component: " << component.name.Data());
849  return StatusCode::FAILURE;
850  }
851  const size_t groupIndex = m_groups.size();
852  m_groups.push_back(simpleGroup);
853  ATH_MSG_DEBUG(Form("Created new group \"%s\" for a simple component at index %zu",simpleGroup->getName().Data(),groupIndex));
854 
855  if (!m_groups.back()->getSubgroupNum())
856  {
857  size_t numGroups = 0;
858  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup)
859  if (!m_groups.at(iGroup)->getSubgroupNum())
860  numGroups++;
861  ATH_MSG_INFO(Form("%5zu. %-40s : %s",numGroups //m_groups.size()
862  ,m_groups.back()->getName().Data()
863  ,m_groups.back()->getDesc().Data() ));
864  }
865 
866  // We now have the simple component group
867  // Check if we are in the simple case (one component) or more difficult case (sub components)
868  if (component.subComps.empty())
869  {
870  // Easy case, build the component and add it directly
871  UncertaintyComponent* compObject = buildUncertaintyComponent(component);
872  if (!compObject)
873  return StatusCode::FAILURE;
874 
875  if (m_groups.at(groupIndex)->addComponent(compObject).isFailure())
876  return StatusCode::FAILURE;
877  ATH_MSG_DEBUG(Form("Added single component \"%s\" to simple group \"%s\" (index %zu)",compObject->getName().Data(),m_groups.at(groupIndex)->getName().Data(),groupIndex));
878  }
879  else
880  {
881  for (size_t iSubComp = 0; iSubComp < component.subComps.size(); ++iSubComp)
882  {
883  // Build a new ComponentHelper object for each subcomponent
884  ComponentHelper subComp(component);
885  subComp.uncNames.clear();
886  subComp.subComps.clear();
887  subComp.name = component.subComps.at(iSubComp);
888  subComp.uncNames.push_back(component.subComps.at(iSubComp));
889 
890  UncertaintyComponent* subCompObject = buildUncertaintyComponent(subComp);
891  if (!subCompObject)
892  return StatusCode::FAILURE;
893 
894  if (m_groups.at(groupIndex)->addComponent(subCompObject).isFailure())
895  return StatusCode::FAILURE;
896  ATH_MSG_DEBUG(Form("Added component \"%s\" (%zu of %zu) to simple group \"%s\" (index %zu)",subCompObject->getName().Data(),iSubComp+1,component.subComps.size(),m_groups.at(groupIndex)->getName().Data(),groupIndex));
897  }
898  }
899  }
900  else
901  {
902  size_t groupIndex = 0;
903  if (m_groups.empty())
904  {
905  ATH_MSG_ERROR("No groups exist to add the component to: " << component.name.Data());
906  return StatusCode::FAILURE;
907  }
908  for (size_t iGroup = 0; iGroup < m_groups.size(); ++iGroup)
909  if (m_groups.at(iGroup)->getGroupNum() == component.groupNum)
910  {
911  groupIndex = iGroup;
912  break;
913  }
914  if (groupIndex == 0 && m_groups.at(0)->getGroupNum() != component.groupNum)
915  {
916  ATH_MSG_ERROR("Failed to find group " << component.groupNum << " for the component: " << component.name.Data());
917  return StatusCode::FAILURE;
918  }
919 
920  // We now have the group index where the component belongs
921  // Get the component we want to add (complicated function...)
922  UncertaintyComponent* compObject = buildUncertaintyComponent(component);
923  if (!compObject)
924  return StatusCode::FAILURE;
925 
926  if (m_groups.at(groupIndex)->addComponent(compObject).isFailure())
927  return StatusCode::FAILURE;
928  ATH_MSG_DEBUG(Form("Added component \"%s\" to group \"%s\" (index %zu)",compObject->getName().Data(),m_groups.at(groupIndex)->getName().Data(),groupIndex));
929  }
930 
931  return StatusCode::SUCCESS;
932 }
933 
935 {
936  // Safety checks for required information
937  if (component.name == "")
938  {
939  ATH_MSG_ERROR("Attempting to create a component with no name");
940  return nullptr;
941  }
943  {
944  ATH_MSG_ERROR("Attempting to create a component with no parametrization: " << component.name.Data());
945  return nullptr;
946  }
947  if (component.scaleVar == CompScaleVar::UNKNOWN)
948  {
949  ATH_MSG_ERROR("Attempting to create a component with no variable to scale: " << component.name.Data());
950  return nullptr;
951  }
952 
953  // Special cases first
954  if (component.isSpecial)
955  {
956  // First check pileup components
957  if (component.pileupType != PileupComp::UNKNOWN)
958  {
959  // Ensure that the reference values were specified
960  if (m_refNPV < 0 && !m_refNPVHist)
961  {
962  ATH_MSG_ERROR("Attempted to create pileup component without NPV reference value: " << component.name.Data());
963  return nullptr;
964  }
965  if (m_refMu < 0 && !m_refMuHist)
966  {
967  ATH_MSG_ERROR("Attempted to create pileup component without mu reference value: " << component.name.Data());
968  return nullptr;
969  }
970 
972  {
973  if (m_refNPVHist && m_refMuHist)
975  else if (!m_refNPVHist && !m_refMuHist)
976  return new PileupUncertaintyComponent(component,m_refNPV,m_refMu);
977  else if (m_refNPVHist && !m_refMuHist)
978  return new PileupUncertaintyComponent(component,m_refNPVHist,m_refMu);
979  else if (!m_refNPVHist && m_refMuHist)
980  return new PileupUncertaintyComponent(component,m_refNPV,m_refMuHist);
981  }
982  else
983  {
984  ATH_MSG_ERROR(Form("Unexpected parametrization of %s for component %s",CompParametrization::enumToString(component.parametrization).Data(),component.name.Data()));
985  return nullptr;
986  }
987  }
988  // Next check flavour components
989  else if (component.flavourType != FlavourComp::UNKNOWN)
990  {
991  if (m_analysisFile.empty())
992  {
993  ATH_MSG_ERROR("Attempting to create a flavour uncertainty component without having specified an AnalysisRootFile");
994  return nullptr;
995  }
997  {
998 
999  if (component.flavourType == FlavourComp::PerJetResponse ||
1004  return new PerJetFlavourUncertaintyComponent(component);
1005  }else
1007 
1008  }
1009  else
1010  {
1011  ATH_MSG_ERROR(Form("Unexpected parametrization of %s for component %s",CompParametrization::enumToString(component.parametrization).Data(),component.name.Data()));
1012  return nullptr;
1013  }
1014  }
1015  // Next check punchthrough
1016  else if (component.name.Contains("PunchThrough",TString::kIgnoreCase))
1017  {
1019  return new PunchthroughUncertaintyComponent(component);
1020  else
1021  {
1022  ATH_MSG_ERROR(Form("Unexpected parametrization of %s for component %s",CompParametrization::enumToString(component.parametrization).Data(),component.name.Data()));
1023  return nullptr;
1024  }
1025  }
1026  // Next check closeby
1027  else if (component.name.Contains("Closeby",TString::kIgnoreCase))
1028  {
1029  if (component.parametrization == CompParametrization::Pt)
1030  return new ClosebyUncertaintyComponent(component);
1031  else
1032  {
1033  ATH_MSG_ERROR(Form("Unexpected parametrization of %s for component %s",CompParametrization::enumToString(component.parametrization).Data(),component.name.Data()));
1034  return nullptr;
1035  }
1036  }
1037  // Next check combined mass
1038  else if (component.combMassType != CombMassComp::UNKNOWN)
1039  {
1040  // Ensure we have the weights we need for combined mass uncertainties
1042  {
1043  ATH_MSG_ERROR("Asking to create a combined mass term without specifying weights: " << component.name.Data());
1044  return nullptr;
1045  }
1046 
1047  // Create the component
1048  ComponentHelper combComp(component);
1049  combComp.name = component.name;
1050  combComp.uncNames.clear();
1052 
1053  // Set the weights
1054  if (cmuc->setCaloWeights(m_caloMassWeight).isFailure()) return nullptr;
1055  if (cmuc->setTAWeights(m_TAMassWeight).isFailure()) return nullptr;
1056  if (cmuc->setCombWeightMassDefs(m_combMassWeightCaloMassDef,m_combMassWeightTAMassDef).isFailure()) return nullptr;
1057  if (cmuc->setCombWeightParam(m_combMassParam).isFailure()) return nullptr;
1058  if (component.combMassType == CombMassComp::Calo || component.combMassType == CombMassComp::Both)
1059  {
1060  // Define the calorimeter group if applicable
1061  GroupHelper caloGroupH(component.name+"_CaloGroup");
1062  caloGroupH.groupNum = 0;
1063  caloGroupH.subgroupNum = 0;
1064  caloGroupH.category = CompCategory::UNKNOWN;
1066  caloGroupH.reducible = false;
1067 
1068  UncertaintyGroup* caloGroup = new UncertaintyGroup(caloGroupH);
1069  if (!caloGroup)
1070  {
1071  ATH_MSG_ERROR("Failed to build calo-group for combined mass component: " << component.name.Data());
1072  return nullptr;
1073  }
1074 
1075  // Get the calo terms and calo mass definitions
1076  std::vector<TString> caloComps = jet::utils::vectorize<TString>(component.caloMassTerm,", ");
1077  std::vector<TString> caloMassDefs = jet::utils::vectorize<TString>(component.caloMassDef,", ");
1078  if (caloComps.size() != caloMassDefs.size())
1079  {
1080  ATH_MSG_ERROR("Unbalanced number of calo mass terms and calo mass definitions, " << caloComps.size() << " vs " << caloMassDefs.size() << " for combined mass component: " << component.name.Data());
1081  return nullptr;
1082  }
1083 
1084  // Build the component(s) and add them directly
1085  for (size_t iComp = 0; iComp < caloComps.size(); ++iComp)
1086  {
1087  // Prepare the helper
1088  ComponentHelper caloCompH(component);
1089  caloCompH.uncNames.clear();
1090  caloCompH.isSpecial = false;
1091  caloCompH.name = caloComps.at(iComp);
1092  caloCompH.uncNames.push_back(caloCompH.name+"_"+m_jetDef);
1093  caloCompH.massDef = CompMassDef::stringToEnum(caloMassDefs.at(iComp));
1094  if (caloCompH.massDef == CompMassDef::UNKNOWN)
1095  {
1096  ATH_MSG_ERROR("Failed to parse calo mass definition " << iComp << " (" << caloMassDefs.at(iComp).Data() << ") for combined mass component: " << component.name.Data());
1097  return nullptr;
1098  }
1099 
1100  // Build the component
1101  UncertaintyComponent* caloComp = buildUncertaintyComponent(caloCompH);
1102  if (!caloComp)
1103  return nullptr;
1104 
1105  if (caloGroup->addComponent(caloComp).isFailure())
1106  return nullptr;
1107  }
1108 
1109  // Done preparations, now set the calo mass group
1110  if (cmuc->setCaloTerm(caloGroup).isFailure())
1111  return nullptr;
1112  }
1113  if (component.combMassType == CombMassComp::TA || component.combMassType == CombMassComp::Both)
1114  {
1115  // Define the track-assisted group if applicable
1116  GroupHelper TAGroupH(component.name+"_TAGroup");
1117  TAGroupH.groupNum = 0;
1118  TAGroupH.subgroupNum = 0;
1119  TAGroupH.category = CompCategory::UNKNOWN;
1121  TAGroupH.reducible = false;
1122 
1123  UncertaintyGroup* TAGroup = new UncertaintyGroup(TAGroupH);
1124  if (!TAGroup)
1125  {
1126  ATH_MSG_ERROR("Failed to build TA-group for combined mass component: " << component.name.Data());
1127  return nullptr;
1128  }
1129 
1130  // Set the TA terms and TA mass definitions
1131  std::vector<TString> TAComps = jet::utils::vectorize<TString>(component.TAMassTerm,", ");
1132  std::vector<TString> TAMassDefs = jet::utils::vectorize<TString>(component.TAMassDef,", ");
1133  if (TAComps.size() != TAMassDefs.size())
1134  {
1135  ATH_MSG_ERROR("Unbalanced number of TA mass terms and TA mass definitions, " << TAComps.size() << " vs " << TAMassDefs.size() << " for combined mass component: " << component.name.Data());
1136  return nullptr;
1137  }
1138 
1139  // Build the component(s) and add them directly
1140  for (size_t iComp = 0; iComp < TAComps.size(); ++iComp)
1141  {
1142  // Prepare the helper
1143  ComponentHelper TACompH(component);
1144  TACompH.uncNames.clear();
1145  TACompH.isSpecial = false;
1146  TACompH.name = TAComps.at(iComp);
1147  TACompH.uncNames.push_back(TACompH.name+"_"+m_jetDef);
1148  TACompH.massDef = CompMassDef::stringToEnum(TAMassDefs.at(iComp));
1149  if (TACompH.massDef == CompMassDef::UNKNOWN)
1150  {
1151  ATH_MSG_ERROR("Failed to parse TA mass definition " << iComp << " (" << TAMassDefs.at(iComp).Data() << ") for combined mass component: " << component.name.Data());
1152  return nullptr;
1153  }
1154 
1155  //ATH_MSG_INFO("Creating TA component \"" << TACompH.name.Data() << "\" for combined mass component: " << component.name.Data());
1156 
1157  // Build the component
1159  if (!TAComp)
1160  return nullptr;
1161 
1162  if (TAGroup->addComponent(TAComp).isFailure())
1163  return nullptr;
1164  }
1165 
1166  // Done preparations, now set the TA mass group
1167  if (cmuc->setTATerm(TAGroup).isFailure())
1168  return nullptr;
1169  }
1170 
1171  // Done, return the component
1172  return cmuc;
1173  }
1174  // Next check large-R topology
1175  else if (component.name.Contains("Large",TString::kIgnoreCase) && component.name.Contains("Topology",TString::kIgnoreCase))
1176  {
1178  {
1179  if (!component.LargeRJetTruthLabels.empty())
1180  {
1181  return new LargeRTopologyUncertaintyComponent(component);
1182  }
1183  else
1184  {
1185  ATH_MSG_ERROR(Form("No LargeRJetTruthLabels specified for Large-R jet topology component %s",component.name.Data()));
1186  return nullptr;
1187  }
1188  }
1189  else
1190  {
1191  ATH_MSG_ERROR(Form("Unexpected parametrization of %s for component %s",CompParametrization::enumToString(component.parametrization).Data(),component.name.Data()));
1192  return nullptr;
1193  }
1194  }
1195  else
1196  {
1197  ATH_MSG_ERROR("Unexpected special component: " << component.name.Data());
1198  return nullptr;
1199  }
1200 
1201  }
1202  // Standard components
1203  else
1204  {
1205  switch(component.parametrization)
1206  {
1208  return new PtUncertaintyComponent(component);
1211  return new PtEtaUncertaintyComponent(component);
1213  return new PtAbsMassUncertaintyComponent(component);
1215  return new PtMassUncertaintyComponent(component);
1217  return new PtLogPtMassForTagSFUncertaintyComponent(component);
1220  return new PtMassEtaUncertaintyComponent(component);
1223  return new PtAbsMassEtaUncertaintyComponent(component);
1225  return new ELogMassUncertaintyComponent(component);
1228  return new ELogMassEtaUncertaintyComponent(component);
1229  default:
1230  ATH_MSG_ERROR("Encountered unexpected parameter type: " << component.param.Data());
1231  return nullptr;
1232  }
1233  }
1234 
1235  ATH_MSG_ERROR("Failed to find the type of component to build: " << component.name.Data());
1236  return nullptr;
1237 }
1238 
1239 
1240 
1242 // //
1243 // Methods to implement from ISystematicsTool //
1244 // //
1246 
1248 {
1249  // Compare using basenames to avoid continious vs fixed value comparisons
1250  const std::set<std::string> baseNames = m_recognizedSystematics.getBaseNames();
1251  return baseNames.find(systematic.basename()) != baseNames.end();
1252  //return m_recognizedSystematics.find(systematic) != m_recognizedSystematics.end();
1253 }
1254 
1256 {
1257  return m_recognizedSystematics;
1258 }
1259 
1261 {
1262  return m_recommendedSystematics;
1263 }
1264 
1266 {
1267  return m_currentSystSet;
1268 }
1269 
1271 {
1272  // Check for things like AFII non-closure in full sim configurations
1273  if (systematic.isAlwaysZero())
1274  return false;
1275 
1276  // Check for filters
1277  bool passesFilter = m_systFilters.empty();
1278  const std::set<CompScaleVar::TypeEnum> scaleVars = systematic.getScaleVars();
1279 
1280  for (size_t iFilter = 0; iFilter < m_systFilters.size(); ++iFilter)
1281  {
1282  if (scaleVars.count(CompScaleVar::stringToEnum(m_systFilters.at(iFilter))))
1283  {
1284  passesFilter = true;
1285  break;
1286  }
1287  }
1288  if (!passesFilter)
1289  return false;
1290 
1291  // All checked, this is a recommended systematic
1292  return true;
1293 }
1294 
1296 {
1298  registry.registerSystematic(systematic);
1299  m_recognizedSystematics.insert(systematic);
1300  if (recommended)
1301  {
1302  m_recommendedSystematics.insert(systematic);
1303  if (registry.addSystematicToRecommended(systematic) != StatusCode::SUCCESS)
1304  {
1305  ATH_MSG_ERROR("Failed to add systematic to list of recommended systematics: " << systematic.name());
1306  return StatusCode::FAILURE;
1307  }
1308  }
1309  return StatusCode::SUCCESS;
1310 }
1311 
1313 {
1314  //if (!m_isInit)
1315  //{
1316  // ATH_MSG_FATAL("Tool must be initialized before calling applySystematicVariation");
1317  // return StatusCode::FAILURE;
1318  //}
1319  CP::SystematicSet filteredSet;
1321  std::string remappedName = systConfig.name();
1322  size_t found = remappedName.find("_PseudoData");
1323  if (found != std::string::npos) {
1324  remappedName.erase(found, std::string("_PseudoData").length());
1325  }
1326 
1327  CP::SystematicSet altConfig(remappedName);
1328  // Filter the full set of systematics to the set we care about
1329  if (getFilteredSystematicSet(altConfig,filteredSet) != StatusCode::SUCCESS)
1330  return StatusCode::FAILURE;
1331  }
1332  else {
1333  // Filter the full set of systematics to the set we care about
1334  if (getFilteredSystematicSet(systConfig,filteredSet) != StatusCode::SUCCESS)
1335  return StatusCode::FAILURE;
1336  }
1337 
1338  // Get the uncertainty set associated to the filtered systematics set
1339  jet::UncertaintySet* uncSet = nullptr;
1340  if (getUncertaintySet(filteredSet,uncSet) != StatusCode::SUCCESS)
1341  return StatusCode::FAILURE;
1342 
1343  // Change the current state
1344  m_currentSystSet.swap(filteredSet);
1345  m_currentUncSet = uncSet;
1346  return StatusCode::SUCCESS;
1347 }
1348 
1350 {
1351  // Check if we have already encountered this set
1353  if (iter != m_systFilterMap.end())
1354  filteredSet = iter->second;
1355  // Make the filtered set and store it
1356  else
1357  {
1358  if (CP::SystematicSet::filterForAffectingSystematics(systConfig,m_recognizedSystematics,filteredSet) != StatusCode::SUCCESS)
1359  return StatusCode::FAILURE;
1360  m_systFilterMap.insert(std::make_pair(systConfig,filteredSet));
1361  }
1362 
1363  return StatusCode::SUCCESS;
1364 }
1365 
1367 {
1368  // Check if we have already encountered this set
1370 
1371  // If we have dealt with this set previously, we're done
1372  if (iter != m_systSetMap.end())
1373  {
1374  uncSet = iter->second;
1375  }
1376  // Make the new set and store it
1377  else
1378  {
1379  uncSet = new UncertaintySet(filteredSet.name());
1380  if (uncSet == nullptr || uncSet->initialize(filteredSet,m_groups).isFailure())
1381  {
1382  ATH_MSG_ERROR("Failed to create UncertaintySet for filtered CP::SystematicSet: " << filteredSet.name());
1383  JESUNC_SAFE_DELETE(uncSet);
1384  return StatusCode::FAILURE;
1385  }
1386  m_systSetMap.insert(std::make_pair(filteredSet,uncSet));
1387  }
1388 
1389  return StatusCode::SUCCESS;
1390 }
1391 
1392 
1394 // //
1395 // Information retrieval methods //
1396 // //
1398 
1400 {
1401  float sqrtS = -1;
1402  const TString release = getRelease().c_str();
1403  if (release.BeginsWith("2011_"))
1404  sqrtS = 7000.*m_energyScale;
1405  else if (release.BeginsWith("2012_"))
1406  sqrtS = 8000.*m_energyScale;
1407  else if (release.BeginsWith("2015_") || release.BeginsWith("2016"))
1408  sqrtS = 13000.*m_energyScale;
1409  return sqrtS;
1410 }
1411 
1412 
1414 {
1415  if (!m_isInit)
1416  {
1417  ATH_MSG_FATAL("Tool must be initialized before calling getRefMu");
1418  return JESUNC_ERROR_CODE;
1419  }
1420  if (m_refMuHist)
1421  {
1422  ATH_MSG_FATAL("Tool contains a histogram for refMu, cannot return float");
1423  return JESUNC_ERROR_CODE;
1424  }
1425  return m_refMu;
1426 }
1427 
1429 {
1430  if (!m_isInit)
1431  {
1432  ATH_MSG_FATAL("Tool must be initialized before calling getRefNPV");
1433  return JESUNC_ERROR_CODE;
1434  }
1435  if (m_refNPVHist)
1436  {
1437  ATH_MSG_FATAL("Tool contains a histogram for refNPV, cannot return float");
1438  return JESUNC_ERROR_CODE;
1439  }
1440  return m_refNPV;
1441 }
1442 
1444 {
1445  if (!m_isInit)
1446  {
1447  ATH_MSG_FATAL("Tool must be initialized before calling getRefMu");
1448  return JESUNC_ERROR_CODE;
1449  }
1450  return m_refMuHist ? m_refMuHist->getValue(fabs(jet.eta())) : m_refMu;
1451 }
1452 
1454 {
1455  if (!m_isInit)
1456  {
1457  ATH_MSG_FATAL("Tool must be initialized before calling getRefNPV");
1458  return JESUNC_ERROR_CODE;
1459  }
1460  return m_refNPVHist ? m_refNPVHist->getValue(fabs(jet.eta())) : m_refNPV;
1461 }
1462 
1463 
1465 {
1466  if (!m_isInit)
1467  {
1468  ATH_MSG_FATAL("Tool must be initialized before calling getNumComponents");
1469  return 0;
1470  }
1471 
1472  return m_groups.size();
1473 }
1474 
1475 size_t JetUncertaintiesTool::getComponentIndex(const std::string& name) const
1476 {
1477  return getComponentIndex(TString(name.c_str()));
1478 }
1479 
1480 size_t JetUncertaintiesTool::getComponentIndex(const TString& name) const
1481 {
1482  if (!m_isInit)
1483  {
1484  ATH_MSG_FATAL("Tool must be initialized before calling getComponentIndex");
1485  return m_groups.size();
1486  }
1487 
1488  for (size_t iComp = 0; iComp < m_groups.size(); ++iComp)
1489  if (m_groups.at(iComp)->getName().CompareTo(name,TString::kIgnoreCase) == 0)
1490  return iComp;
1491 
1492  ATH_MSG_ERROR("Failed to find index for requested component: " << name.Data());
1493  return m_groups.size();
1494 }
1495 
1496 std::string JetUncertaintiesTool::getComponentName(const size_t index) const
1497 {
1498  if (!m_isInit)
1499  {
1500  ATH_MSG_FATAL("Tool must be initialized before calling getComponentName");
1501  return "";
1502  }
1503 
1504  if (index < m_groups.size())
1505  return m_groups.at(index)->getName().Data();
1506 
1507  ATH_MSG_ERROR("Index out of bounds for component name: " << index);
1508  return "";
1509 }
1510 
1511 std::string JetUncertaintiesTool::getComponentDesc(const size_t index) const
1512 {
1513  if (!m_isInit)
1514  {
1515  ATH_MSG_FATAL("Tool must be initialized before calling getComponentDesc");
1516  return "";
1517  }
1518 
1519  if (index < m_groups.size())
1520  return m_groups.at(index)->getDesc().Data();
1521 
1522  ATH_MSG_ERROR("Index out of bounds for component desc: " << index);
1523  return "";
1524 }
1525 
1526 std::string JetUncertaintiesTool::getComponentCategory(const size_t index) const
1527 {
1528  if (!m_isInit)
1529  {
1530  ATH_MSG_FATAL("Tool must be initialized before calling getComponentCategory");
1531  return "";
1532  }
1533 
1534  if (index < m_groups.size())
1535  return CompCategory::enumToString(m_groups.at(index)->getCategory()).Data();
1536 
1537  ATH_MSG_ERROR("Index out of bounds for component category: " << index);
1538  return "";
1539 }
1540 
1542 {
1543  if (!m_isInit)
1544  {
1545  ATH_MSG_FATAL("Tool must be initialized before calling getComponentIsReducible");
1546  return false;
1547  }
1548 
1549  if (index < m_groups.size())
1550  return m_groups.at(index)->getIsReducible();
1551 
1552  ATH_MSG_ERROR("Index out of bounds for component category: " << index);
1553  return false;
1554 }
1555 
1557 {
1558  if (!m_isInit)
1559  {
1560  ATH_MSG_FATAL("Tool must be initialized before asking for information pertaining to a given component index");
1561  return StatusCode::FAILURE;
1562  }
1563 
1564  if (index >= m_groups.size())
1565  {
1566  ATH_MSG_ERROR(Form("Index out of bounds, asking for %zu in a container of size %zu",index,m_groups.size()));
1567  return StatusCode::FAILURE;
1568  }
1569 
1570 
1571  return StatusCode::SUCCESS;
1572 }
1573 
1574 bool checkScalesSingleVar(const std::set<CompScaleVar::TypeEnum>& varSet, const CompScaleVar::TypeEnum var)
1575 {
1576  return varSet.size() == 1 && *(varSet.begin()) == var;
1577 }
1578 
1580 {
1581  if (checkIndexInput(index).isFailure()) return false;
1582  return checkScalesSingleVar(m_groups.at(index)->getScaleVars(),CompScaleVar::FourVec);
1583 }
1585 {
1586  if (checkIndexInput(index).isFailure()) return false;
1587  return checkScalesSingleVar(m_groups.at(index)->getScaleVars(),CompScaleVar::Pt);
1588 }
1590 {
1591  if (checkIndexInput(index).isFailure()) return false;
1592  return checkScalesSingleVar(m_groups.at(index)->getScaleVars(),CompScaleVar::Mass);
1593 }
1595 {
1596  if (checkIndexInput(index).isFailure()) return false;
1597  return checkScalesSingleVar(m_groups.at(index)->getScaleVars(),CompScaleVar::D12);
1598 }
1600 {
1601  if (checkIndexInput(index).isFailure()) return false;
1602  return checkScalesSingleVar(m_groups.at(index)->getScaleVars(),CompScaleVar::D23);
1603 }
1605 {
1606  if (checkIndexInput(index).isFailure()) return false;
1607  return checkScalesSingleVar(m_groups.at(index)->getScaleVars(),CompScaleVar::Tau21);
1608 }
1610 {
1611  if (checkIndexInput(index).isFailure()) return false;
1612  return checkScalesSingleVar(m_groups.at(index)->getScaleVars(),CompScaleVar::Tau32);
1613 }
1615 {
1616  if (checkIndexInput(index).isFailure()) return false;
1617  return checkScalesSingleVar(m_groups.at(index)->getScaleVars(),CompScaleVar::Tau21WTA);
1618 }
1620 {
1621  if (checkIndexInput(index).isFailure()) return false;
1622  return checkScalesSingleVar(m_groups.at(index)->getScaleVars(),CompScaleVar::Tau32WTA);
1623 }
1625 {
1626  if (checkIndexInput(index).isFailure()) return false;
1627  return checkScalesSingleVar(m_groups.at(index)->getScaleVars(),CompScaleVar::D2Beta1);
1628 }
1630 {
1631  if (checkIndexInput(index).isFailure()) return false;
1632  return checkScalesSingleVar(m_groups.at(index)->getScaleVars(),CompScaleVar::C2Beta1);
1633 }
1635 {
1636  if (checkIndexInput(index).isFailure()) return false;
1637  return checkScalesSingleVar(m_groups.at(index)->getScaleVars(),CompScaleVar::Qw);
1638 }
1640 {
1641  if (checkIndexInput(index).isFailure()) return false;
1643 }
1645 {
1646  if (checkIndexInput(index).isFailure()) return false;
1647  return m_groups.at(index)->getScaleVars().size() > 1;
1648 }
1649 std::set<CompScaleVar::TypeEnum> JetUncertaintiesTool::getComponentScaleVars(const size_t index) const
1650 {
1651  if (checkIndexInput(index).isFailure()) return {};
1652  return m_groups.at(index)->getScaleVars();
1653 }
1655 {
1656  if (checkIndexInput(index).isFailure()) return JetTopology::UNKNOWN;
1657  return m_groups.at(index)->getTopology();
1658 }
1659 
1660 
1662 {
1664 }
1665 bool JetUncertaintiesTool::getValidity(size_t index, const xAOD::Jet& jet, const xAOD::EventInfo& eInfo) const
1666 {
1668 }
1670 {
1671  const xAOD::EventInfo* eInfo = getDefaultEventInfo();
1672  if (!eInfo) return false;
1673  return getValidity(index,jet,*eInfo,scaleVar);
1674 }
1675 bool JetUncertaintiesTool::getValidity(size_t index, const xAOD::Jet& jet, const xAOD::EventInfo& eInfo, const CompScaleVar::TypeEnum scaleVar) const
1676 {
1677  if (!m_isInit)
1678  {
1679  ATH_MSG_FATAL("Tool must be initialized before calling getValidity");
1680  return false;
1681  }
1682 
1683  // Ensure we are within bounds
1684  if (index >= m_groups.size())
1685  {
1686  ATH_MSG_ERROR("Index out of bounds for validity: " << index);
1687  return false;
1688  }
1689 
1690  // Check for a global validity histogram
1692  return false;
1693 
1694  // Deal with different possible scale types
1695  // If scaleVar is unknown, work if comp is just one type
1696  // If scaleVar is specified, request that specific type regardless
1697  if (scaleVar == CompScaleVar::UNKNOWN)
1698  {
1699  if (m_groups.at(index)->getScaleVars().size() != 1)
1700  {
1701  ATH_MSG_ERROR("Asked for the validity of a set which scales multiple variables without specifying the variable of interest:" << m_groups.at(index)->getName().Data());
1702  return false;
1703  }
1704  return m_groups.at(index)->getValidity(jet,eInfo,*(m_groups.at(index)->getScaleVars().begin()));
1705  }
1706  return m_groups.at(index)->getValidity(jet,eInfo,scaleVar);
1707 }
1708 
1709 
1710 
1712 {
1714 }
1715 double JetUncertaintiesTool::getUncertainty(size_t index, const xAOD::Jet& jet, const xAOD::EventInfo& eInfo) const
1716 {
1718 }
1720 {
1721  const xAOD::EventInfo* eInfo = getDefaultEventInfo();
1722  if (!eInfo) return JESUNC_ERROR_CODE;
1723  return getUncertainty(index,jet,*eInfo,scaleVar);
1724 }
1725 double JetUncertaintiesTool::getUncertainty(size_t index, const xAOD::Jet& jet, const xAOD::EventInfo& eInfo, const CompScaleVar::TypeEnum scaleVar) const
1726 {
1727  if (!m_isInit)
1728  {
1729  ATH_MSG_FATAL("Tool must be initialized before calling getUncertainty");
1730  return JESUNC_ERROR_CODE;
1731  }
1732 
1733  // Ensure we are within bounds
1734  if (index >= m_groups.size())
1735  {
1736  ATH_MSG_ERROR("Index out of bounds for uncertainty: " << index);
1737  return JESUNC_ERROR_CODE;
1738  }
1739 
1740  // Watch for a global validity histogram
1742  {
1743  ATH_MSG_ERROR("Jet is out of validity bounds for uncertainty: " << index);
1744  return JESUNC_ERROR_CODE;
1745  }
1746 
1747 
1748  // Deal with different possible scale types
1749  // If scaleVar is unknown, work if comp is just one type
1750  // If scaleVar is specified, request that specific type regardless
1751  if (scaleVar == CompScaleVar::UNKNOWN)
1752  {
1753  if (m_groups.at(index)->getScaleVars().size() != 1)
1754  {
1755  ATH_MSG_ERROR("Asked for the uncertainty of a set which scales multiple variables without specifying the variable of interest:" << m_groups.at(index)->getName().Data());
1756  return JESUNC_ERROR_CODE;
1757  }
1758  return m_groups.at(index)->getUncertainty(jet,eInfo,*(m_groups.at(index)->getScaleVars().begin()));
1759  }
1760  return m_groups.at(index)->getUncertainty(jet,eInfo,scaleVar);
1761 }
1762 
1763 
1764 
1765 bool JetUncertaintiesTool::getValidUncertainty(size_t index, double& unc, const xAOD::Jet& jet) const
1766 {
1768 }
1769 bool JetUncertaintiesTool::getValidUncertainty(size_t index, double& unc, const xAOD::Jet& jet, const xAOD::EventInfo& eInfo) const
1770 {
1771  return getValidUncertainty(index, unc, jet, eInfo, CompScaleVar::UNKNOWN);
1772 }
1773 bool JetUncertaintiesTool::getValidUncertainty(size_t index, double& unc, const xAOD::Jet& jet, const CompScaleVar::TypeEnum scaleVar) const
1774 {
1775  const xAOD::EventInfo* eInfo = getDefaultEventInfo();
1776  if (!eInfo) return false;
1777  return getValidUncertainty(index,unc,jet,*eInfo,scaleVar);
1778 }
1779 bool JetUncertaintiesTool::getValidUncertainty(size_t index, double& unc, const xAOD::Jet& jet, const xAOD::EventInfo& eInfo, const CompScaleVar::TypeEnum scaleVar) const
1780 {
1781  if (!m_isInit)
1782  {
1783  ATH_MSG_FATAL("Tool must be initialized before calling getValidUncertainty");
1784  return false;
1785  }
1786 
1787  // Ensure we are within bounds
1788  if (index >= m_groups.size())
1789  {
1790  ATH_MSG_ERROR("Index out of bounds for valid uncertainty: " << index);
1791  return false;
1792  }
1793 
1794  // Check for a global validity histogram
1796  return false;
1797 
1798 
1799  // Deal with different possible scale types
1800  // If scaleVar is unknown, work if comp is just one type
1801  // If scaleVar is specified, request that specific type regardless
1802  if (scaleVar == CompScaleVar::UNKNOWN)
1803  {
1804  if (m_groups.at(index)->getScaleVars().size() != 1)
1805  {
1806  ATH_MSG_ERROR("Asked for the valid uncertainty of a set which scales multiple variables without specifying the variable of interest:" << m_groups.at(index)->getName().Data());
1807  return JESUNC_ERROR_CODE;
1808  }
1809  return m_groups.at(index)->getValidUncertainty(unc,jet,eInfo,*(m_groups.at(index)->getScaleVars().begin()));
1810  }
1811  return m_groups.at(index)->getValidUncertainty(unc,jet,eInfo,scaleVar);
1812 }
1813 
1814 
1816 {
1817  return getNominalResolution(jet,smearType,topology,true);
1818 }
1819 
1821 {
1822  return getNominalResolution(jet,smearType,topology,false);
1823 }
1824 
1825 double JetUncertaintiesTool::getNominalResolution(const xAOD::Jet& jet, const CompScaleVar::TypeEnum smearType, const JetTopology::TypeEnum topology, const bool readMC) const
1826 {
1827  if (!m_isInit)
1828  {
1829  ATH_MSG_FATAL("Tool must be initialized before calling getNominalResolution");
1830  return JESUNC_ERROR_CODE;
1831  }
1832  if (!m_resHelper)
1833  {
1834  ATH_MSG_ERROR("The ResolutionHelper class was not created");
1835  return JESUNC_ERROR_CODE;
1836  }
1837 
1838  // Get the nominal histogram, parametrization, and mass def (if relevant) from the helper
1839  std::tuple<const UncertaintyHistogram*,CompParametrization::TypeEnum,CompMassDef::TypeEnum> resolution = m_resHelper->getNominalResolution(smearType,topology,readMC);
1840 
1841  // Check that we retrieved them successfully
1842  if (!std::get<0>(resolution) || std::get<1>(resolution) == CompParametrization::UNKNOWN)
1843  return JESUNC_ERROR_CODE;
1844  if (CompParametrization::includesMass(std::get<1>(resolution)) && std::get<2>(resolution) == CompMassDef::UNKNOWN)
1845  {
1846  // We should never reach this, as it was also checked during initialization
1847  ATH_MSG_ERROR("Parametrization involves mass but mass def is unknown");
1848  return JESUNC_ERROR_CODE;
1849  }
1850 
1851  // Now read the uncertainty from the histogram
1852  return readHistoFromParam(jet,*std::get<0>(resolution),std::get<1>(resolution),std::get<2>(resolution));
1853 }
1854 
1855 
1857 {
1858  // Simple case (no mass dependence)
1860  return readHistoFromParam(jet.jetP4(),histo,param);
1861 
1862  // Complex case (need to check the mass type to use)
1863  // Simple four-vector case
1864  if (massDef == CompMassDef::UNKNOWN || massDef == CompMassDef::FourVecMass)
1865  return readHistoFromParam(jet.jetP4(),histo,param);
1866  // Special scale case
1867  JetFourMomAccessor massScaleAccessor(CompMassDef::getJetScaleString(massDef).Data());
1868  return readHistoFromParam(massScaleAccessor(jet),histo,param);
1869 }
1870 
1872 {
1873  double value = 0;
1874  switch (param)
1875  {
1877  value = histo.getValue(jet4vec.Pt()*m_energyScale);
1878  break;
1880  value = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.Eta());
1881  break;
1883  value = histo.getValue(jet4vec.Pt()*m_energyScale,fabs(jet4vec.Eta()));
1884  break;
1886  value = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.M()*m_energyScale);
1887  break;
1889  value = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.M()/jet4vec.Pt());
1890  break;
1892  value = histo.getValue(jet4vec.Pt()*m_energyScale,log(jet4vec.M()/jet4vec.Pt()));
1893  break;
1895  value = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.M()/jet4vec.Pt(),jet4vec.Eta());
1896  break;
1898  value = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.M()/jet4vec.Pt(),fabs(jet4vec.Eta()));
1899  break;
1901  value = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.M()*m_energyScale,jet4vec.Eta());
1902  break;
1904  value = histo.getValue(jet4vec.Pt()*m_energyScale,jet4vec.M()*m_energyScale,fabs(jet4vec.Eta()));
1905  break;
1907  value = histo.getValue(jet4vec.E()*m_energyScale,log(jet4vec.M()/jet4vec.E()));
1908  break;
1910  value = histo.getValue(jet4vec.E()*m_energyScale,log(jet4vec.M()/jet4vec.E()),jet4vec.Eta());
1911  break;
1913  value = histo.getValue(jet4vec.E()*m_energyScale,log(jet4vec.M()/jet4vec.E()),fabs(jet4vec.Eta()));
1914  break;
1915  default:
1916  ATH_MSG_ERROR("Failed to read histogram due to unknown parametrization type in " << getName());
1917  break;
1918  }
1919  return value;
1920 }
1921 
1922 
1924 {
1925  if (!m_caloMassWeight || !m_TAMassWeight) return 0;
1926 
1929 
1930  const double caloRes = m_caloMassWeight ? readHistoFromParam(caloScale(jet),*m_caloMassWeight,m_combMassParam) : 0;
1931  const double TARes = m_TAMassWeight ? readHistoFromParam(TAScale(jet),*m_TAMassWeight,m_combMassParam) : 0;
1932 
1933  if (caloRes == 0 || TARes == 0) return 0;
1934 
1935  const double caloFactor = (caloRes == 0) ? 0 : 1./(caloRes*caloRes);
1936  const double TAFactor = ( TARes == 0) ? 0 : 1./(TARes*TARes);
1937 
1938  if (caloFactor + TAFactor == 0) return 0;
1939 
1940  return caloFactor/(caloFactor+TAFactor);
1941 }
1942 
1944 {
1945  if (!m_caloMassWeight || !m_TAMassWeight) return 0;
1946 
1949 
1950 
1951  const double caloRes = m_caloMassWeight->getValue(caloScale.pt(jet)*m_energyScale,caloScale.m(jet)/caloScale.pt(jet) );
1952  const double TARes = m_TAMassWeight->getValue(TAScale.pt(jet)*m_energyScale,TAScale.m(jet)/TAScale.pt(jet));
1953 
1954  if (caloRes == 0 || TARes == 0) return 0;
1955 
1956  const double caloFactor = 1./(caloRes*caloRes);
1957  const double TAFactor = 1./(TARes*TARes);
1958 
1959  if (caloFactor + TAFactor == 0) return 0;
1960 
1961  return TAFactor/(caloFactor+TAFactor);
1962 }
1963 
1965 // //
1966 // Mulit-component retrieval methods //
1967 // //
1969 
1970 std::vector<std::string> JetUncertaintiesTool::getComponentCategories() const
1971 {
1972  if (!m_isInit)
1973  {
1974  ATH_MSG_FATAL("Tool must be initialized before calling getComponentCategories");
1975  return {};
1976  }
1977 
1978  // Internally use a set for speed
1979  // Use std::string rather than CompCategory::TypeEnum because std::string has a hash
1980  // Hashed access should mean there is no speed difference between using the two types
1981  std::unordered_set<std::string> categories;
1982  for (size_t iComp = 0; iComp < m_groups.size(); ++iComp)
1983  categories.insert(CompCategory::enumToString(m_groups.at(iComp)->getCategory()).Data());
1984 
1985  // Convert the set to a vector
1986  std::vector<std::string> categoryStrings;
1987  for (std::unordered_set<std::string>::const_iterator iter = categories.begin() ; iter != categories.end(); ++iter)
1988  categoryStrings.push_back(*iter);
1989 
1990  return categoryStrings;
1991 }
1992 
1993 std::vector<size_t> JetUncertaintiesTool::getComponentsInCategory(const std::string& category) const
1994 {
1995  if (!m_isInit)
1996  {
1997  ATH_MSG_FATAL("Tool must be initialized before calling getComponentsInCategory");
1998  return {};
1999  }
2000 
2001  // Internally conver to an enum for both checking and speed of comparison
2002  const CompCategory::TypeEnum categoryEnum = CompCategory::stringToEnum(category.c_str());
2003  if (categoryEnum == CompCategory::UNKNOWN)
2004  {
2005  ATH_MSG_WARNING("Unrecognized category: " << category);
2006  return {};
2007  }
2008 
2009  // Now find the components
2010  std::vector<size_t> components;
2011  for (size_t iComp = 0; iComp < m_groups.size(); ++iComp)
2012  if (m_groups.at(iComp)->getCategory() == categoryEnum)
2013  components.push_back(iComp);
2014 
2015  return components;
2016 }
2017 
2018 std::vector<std::string> JetUncertaintiesTool::getComponentNamesInCategory(const std::string& category) const
2019 {
2020  if (!m_isInit)
2021  {
2022  ATH_MSG_FATAL("Tool must be initialized before calling getComponentNamesInCategory");
2023  return {};
2024  }
2025 
2026  std::vector<size_t> components = getComponentsInCategory(category);
2027  std::vector<std::string> names;
2028  for (size_t iComp = 0; iComp < components.size(); ++iComp)
2029  names.push_back(getComponentName(components.at(iComp)));
2030 
2031  return names;
2032 }
2033 
2034 
2036 // //
2037 // Methods to build the correlation matrix //
2038 // //
2040 
2041 TH2D* JetUncertaintiesTool::getPtCorrelationMatrix(const int numBins, const double minPt, const double maxPt, const double valEta)
2042 {
2043  return getPtCorrelationMatrix(numBins,minPt,maxPt,valEta,valEta);
2044 }
2045 
2046 TH2D* JetUncertaintiesTool::getPtCorrelationMatrix(const int numBins, const double minPt, const double maxPt, const double valEta1, const double valEta2)
2047 {
2048  if (!m_isInit)
2049  {
2050  ATH_MSG_FATAL("Tool must be initialized before calling getCorrelationMatrix");
2051  return nullptr;
2052  }
2053 
2054  std::cout << "Creating with max values " << valEta1 << " " << valEta2 << std::endl;
2055  CorrelationMatrix corrMat(Form("%s_varpt_eta%.2f_eta%.2f",m_name.c_str(),valEta1,valEta2),numBins,minPt*m_energyScale,maxPt*m_energyScale,valEta1,valEta2);
2056  if (corrMat.initializeForPt(*this).isFailure())
2057  return nullptr;
2058  return new TH2D(*corrMat.getMatrix());
2059 }
2060 
2061 TH2D* JetUncertaintiesTool::getEtaCorrelationMatrix(const int numBins, const double minEta, const double maxEta, const double valPt)
2062 {
2063  return getEtaCorrelationMatrix(numBins,minEta,maxEta,valPt,valPt);
2064 }
2065 
2066 TH2D* JetUncertaintiesTool::getEtaCorrelationMatrix(const int numBins, const double minEta, const double maxEta, const double valPt1, const double valPt2)
2067 {
2068  if (!m_isInit)
2069  {
2070  ATH_MSG_FATAL("Tool must be initialized before calling getCorrelationMatrix");
2071  return nullptr;
2072  }
2073 
2074  CorrelationMatrix corrMat(Form("%s_vareta_pt%.1f_pt%.1f",m_name.c_str(),valPt1/1.e3,valPt2/1.e3),numBins,minEta,maxEta,valPt1*m_energyScale,valPt2*m_energyScale);
2075  if (corrMat.initializeForEta(*this).isFailure())
2076  return nullptr;
2077  return new TH2D(*corrMat.getMatrix());
2078 }
2079 
2080 
2082 // //
2083 // Methods to apply variations or get a copy //
2084 // //
2086 
2088 {
2089  const xAOD::EventInfo* eInfo = getDefaultEventInfo();
2090  if (!eInfo) return CP::CorrectionCode::Error;
2091  return applyCorrection(jet,*eInfo);
2092 }
2093 
2095 {
2096  if (!m_isInit)
2097  {
2098  ATH_MSG_FATAL("Tool must be initialized before calling applyCorrection");
2100  }
2101 
2102  // Check for a global validity histogram
2105  }
2106 
2107  // Scale the jet and/or its moments by the uncertainty/uncertainties
2108  // Note that uncertainties may be either positive or negative
2109  // Make sure to check the validity at the same time
2110  std::vector< std::pair<CompScaleVar::TypeEnum,double> > uncSet;
2111  const std::vector< std::pair<CompScaleVar::TypeEnum,bool> > validitySet = m_currentUncSet->getValidUncertaintySet(uncSet,jet,eInfo);
2112 
2113  // Ensure every case was successful
2114  bool allValid = true;
2115  for (size_t iVar = 0; iVar < validitySet.size(); ++iVar)
2116  {
2117  const bool validity = validitySet.at(iVar).second;
2118 
2119  if (!validity)
2120  {
2121  allValid = false;
2122  // Disabled following email from Karsten Koeneke on Jan 28 2016: ATLAS rule is no error messages for out of validity range
2123  //const CompScaleVar::TypeEnum scaleVar = validitySet.at(iVar).first;
2124  //ATH_MSG_ERROR("Uncertainty configuration is not valid for the specified jet when attempting to scale " << CompScaleVar::enumToString(scaleVar).Data() << ". Set: " << m_currentUncSet->getName());
2125  }
2126  }
2127  if (!allValid)
2129 
2130  // Ensure that we don't mix relative and absolute resolution uncertainties of the same type
2131  // Such situations violate the current code structure
2132  std::vector<CompScaleVar::TypeEnum> scaleVars = m_currentUncSet->getScaleVars();
2133  bool hasMassRes = false;
2134  bool hasPtRes = false;
2135  bool hasFvRes = false;
2136  for (CompScaleVar::TypeEnum var : scaleVars)
2137  {
2139  {
2140  if (hasMassRes)
2141  {
2142  ATH_MSG_ERROR("Varying both absolute and relative mass resolution components simultaneously is not supported");
2144  }
2145  else
2146  hasMassRes = true;
2147  }
2149  {
2150  if (hasPtRes)
2151  {
2152  ATH_MSG_ERROR("Varying both absolute and relative pT resolution components simultaneously is not supported");
2154  }
2155  else
2156  hasPtRes = true;
2157  }
2159  {
2160  if (hasFvRes)
2161  {
2162  ATH_MSG_ERROR("Varying both absolute and relative four-vector resolution components simultaneously is not supported");
2164  }
2165  else
2166  hasFvRes = true;
2167  }
2168  }
2169 
2170  // Handle each case as needed
2171  for (size_t iVar = 0; iVar < uncSet.size(); ++iVar)
2172  {
2173  const CompScaleVar::TypeEnum scaleVar = uncSet.at(iVar).first;
2174  //const double unc = uncSet.at(iVar).second;
2175  const double shift = 1 + uncSet.at(iVar).second;
2176  const double smear = uncSet.at(iVar).second;
2177 
2178  // Careful of const vs non-const objects with accessors
2179  // Can unintentionally create something new which didn't exist, as jet is non-const
2180  double smearingFactor = 1;
2181  switch (scaleVar)
2182  {
2183  case CompScaleVar::FourVec:
2184  jet.setJetP4(xAOD::JetFourMom_t(shift*jet.pt(),jet.eta(),jet.phi(),shift*jet.m()));
2185  break;
2186  case CompScaleVar::Pt:
2187  jet.setJetP4(xAOD::JetFourMom_t(shift*jet.pt(),jet.eta(),jet.phi(),jet.m()));
2188  break;
2189  case CompScaleVar::Mass:
2190  jet.setJetP4(xAOD::JetFourMom_t(jet.pt(),jet.eta(),jet.phi(),shift*jet.m()));
2191  break;
2192  case CompScaleVar::D12:
2193  if (updateSplittingScale12(jet,shift).isFailure())
2195  break;
2196  case CompScaleVar::D23:
2197  if (updateSplittingScale23(jet,shift).isFailure())
2199  break;
2200  case CompScaleVar::Tau21:
2201  if (updateTau21(jet,shift).isFailure())
2203  break;
2204  case CompScaleVar::Tau32:
2205  if (updateTau32(jet,shift).isFailure())
2207  break;
2209  if (updateTau21WTA(jet,shift).isFailure())
2211  break;
2213  if (updateTau32WTA(jet,shift).isFailure())
2215  break;
2216  case CompScaleVar::D2Beta1:
2217  if (updateD2Beta1(jet,shift).isFailure())
2219  break;
2220  case CompScaleVar::C2Beta1:
2221  if (updateC2Beta1(jet,shift).isFailure())
2223  break;
2224  case CompScaleVar::Qw:
2225  if (updateQw(jet,shift).isFailure())
2227  break;
2229  if (updateTagScaleFactor(jet,shift).isFailure())
2231  break;
2233  if (updateTagEfficiency(jet,uncSet.at(iVar).second).isFailure())
2235  break;
2236  case CompScaleVar::MassRes:
2239  {
2240  // The JMR requires that there is a topology specified
2241  // (JMR uncertainties are topology-specific)
2242  ATH_MSG_ERROR("Smearing the mass without specifying the topology is not supported");
2244  }
2246  {
2247  // We can't handle multi-topology JMR uncertainties
2248  ATH_MSG_ERROR("Smearing the mass using multiple topology definitions is not supported");
2250  }
2251  smearingFactor = getSmearingFactor(jet,scaleVar,smear);
2252  jet.setJetP4(xAOD::JetFourMom_t(jet.pt(),jet.eta(),jet.phi(),smearingFactor*jet.m()));
2253  break;
2254  case CompScaleVar::PtRes:
2256  smearingFactor = getSmearingFactor(jet,scaleVar,smear);
2257  jet.setJetP4(xAOD::JetFourMom_t(smearingFactor*jet.pt(),jet.eta(),jet.phi(),jet.m()));
2258  break;
2261  smearingFactor = getSmearingFactor(jet,scaleVar,smear);
2262  jet.setJetP4(xAOD::JetFourMom_t(smearingFactor*jet.pt(),jet.eta(),jet.phi(),smearingFactor*jet.m()));
2263  break;
2264  default:
2265  ATH_MSG_ERROR("Asked to scale an UNKNOWN variable for set: " << m_currentUncSet->getName());
2267  }
2268  }
2269 
2270  return CP::CorrectionCode::Ok;
2271 }
2272 
2274 {
2275  const xAOD::EventInfo* eInfo = getDefaultEventInfo();
2276  if (!eInfo) return CP::CorrectionCode::Error;
2277  return correctedCopy(input,output,*eInfo);
2278 }
2279 
2281 {
2282  xAOD::Jet* copy = new xAOD::Jet(input);
2283 
2284  // Call the implemented function
2286  {
2287  delete copy;
2289  }
2290  output = copy;
2291  return CP::CorrectionCode::Ok;
2292 }
2293 
2295 {
2296  const xAOD::EventInfo* eInfo = getDefaultEventInfo();
2297  if (!eInfo) return CP::CorrectionCode::Error;
2298  return applyContainerCorrection(inputs,*eInfo);
2299 }
2300 
2302 {
2304 
2305  // Loop over the container
2306  for (size_t iJet = 0; iJet < inputs.size(); ++iJet)
2307  {
2308  result = applyCorrection(*inputs.at(iJet),eInfo);
2310  break;
2311  }
2312  return result;
2313 }
2314 
2316 {
2317  // Define static EventInfo objects
2318  // Unfortunately this is messy, but needed as we are caching across tool calls
2319  // Using voltatile class variables doesn't work well as we need to return a const object
2320  // Interesting enough, the shallow copy link is updated when evtStore()->retrieve() is called
2321  // As such, just retrieving the new EventInfo object updates this copy
2322  // We therefore need to also store our own local copy of the eventNumber
2323  static xAOD::EventInfo* eInfoObj = nullptr;
2324  static xAOD::ShallowAuxContainer* eInfoAux = nullptr;
2325  static unsigned long long eventNum = 0;
2326  static const SG::AuxElement::Accessor<float> accNPV("NPV");
2327 
2328  // Retrieve the EventInfo object
2329  const xAOD::EventInfo* eInfoConst = nullptr;
2330  if (evtStore()->retrieve(eInfoConst,"EventInfo").isFailure())
2331  {
2332  ATH_MSG_ERROR("Failed to retrieve default EventInfo object");
2333  return nullptr;
2334  }
2335 
2336  // Check if this is a new event or if we can re-use the existing EventInfo object
2337  if (eInfoObj && eventNum == eInfoConst->eventNumber())
2338  return eInfoObj;
2339  eventNum = eInfoConst->eventNumber();
2340 
2341  // It's a new event, get rid of the old object and build a new one
2342  JESUNC_SAFE_DELETE(eInfoObj);
2343  JESUNC_SAFE_DELETE(eInfoAux);
2344 
2345  // Make a shallow copy
2346  std::pair<xAOD::EventInfo*,xAOD::ShallowAuxContainer*> eInfoPair = xAOD::shallowCopyObject(*eInfoConst);
2347  eInfoObj = eInfoPair.first;
2348  eInfoAux = eInfoPair.second;
2349 
2350  // Check if NPV already exists on const EventInfo object, return if so
2351  if (accNPV.isAvailable(*eInfoConst))
2352  return eInfoObj;
2353 
2354  // NPV doesn't already exist, so calculate it
2355  const xAOD::VertexContainer* vertices = nullptr;
2356  if (evtStore()->retrieve(vertices,"PrimaryVertices").isFailure())
2357  {
2358  ATH_MSG_ERROR("Failed to retrieve default NPV value from PrimaryVertices");
2359  JESUNC_SAFE_DELETE(eInfoObj);
2360  JESUNC_SAFE_DELETE(eInfoAux);
2361  return nullptr;
2362  }
2363 
2364  unsigned NPV = 0;
2366  for (itr = vertices->begin(); itr != vertices->end(); ++itr)
2367  if ( (*itr)->nTrackParticles() > 1)
2368  NPV++;
2369 
2370  // Add NPV to the shallow copy EventInfo object
2371  accNPV(*eInfoObj) = NPV;
2372 
2373  // Done, return EventInfo decorated with NPV
2374  return eInfoObj;
2375 }
2376 
2377 
2378 
2379 
2380 double JetUncertaintiesTool::getSmearingFactor(const xAOD::Jet& jet, const CompScaleVar::TypeEnum smearType, const double variation) const
2381 {
2382  /*
2383  Below follows discussion between B Malaescu, C Young, and S Schramm on 14/08/2018
2384 
2385  sigma_smear^2 = (sigma_nominal + |n*x + m*y + ...|)^2 - (sigma_nominal)^2
2386  sigma_smear: width of the Gaussian to smear with
2387  sigma_nominal: the nominal resolution in either (pseudo-)data OR mc (see below)
2388  n: #sigma variation for NP1
2389  m: #sigma variation for NP2
2390  x: uncertainty from NP1
2391  y: uncertainty from NP2
2392  Note that n,m,x,y all are signed quantities
2393  n,m are + for upward variations and - for downward variations
2394  x,y are + or - to differentiate regions of anticorrelations within a given NP
2395 
2396  As the MC has been smeared to the data in JetCalibTools and we have saved the histograms
2397  before this smearing has been applied we need to take the maximum of the data and MC
2398  resolutions to find the nominal resolution which to smear against. For cases when the data
2399  resolution is better than that in simulation and we additionally are using data as
2400  pseudo-data (extremely rare in analyses) this might result in a slightly more conservative
2401  uncertainty.
2402  sigma_nominal = max(sigma_MC,sigma_data)
2403 
2404  In some cases, it is not desireable to smear (pseudo-)data
2405  Result: two correlation smearing options, "full" and "simple"
2406  Full = full correlations preserved, smear both (peudo-)data and MC
2407  Simple = simplified correlations (= loss of correlations), smear only MC
2408 
2409  In "simple" case, we are smearing MC even if we should ideally smear (pseudo-)data
2410  sign(nx+my+...) --> no longer matters, always use sigma_nominal^MC
2411  Furthermore, take the absolute value as we are forcing an upward variation
2412  sigma_smear^2 = (sigma_nom^MC + |n*x + m*y + ...|)^2 - (sigma_nom^MC)^2
2413  In the case of 1 NP, analysis gets same result if n is positive or negative
2414  Analysis must symmetrize uncertainties themselves to get downward variations
2415 
2416  The above is all for absolute resolution uncertainties
2417  In the case of relative resolution uncertainties, not much changes
2418  n*x --> n*sigma_nominal*x
2419  n: unchanged from before, #sigma variation for NP1
2420  x: now this is a fractional uncertainty, but it is still the value of NP1
2421  sigma_nominal: uncertainty measurement varies (sign unaffected by nominal)
2422  In other words, all of the above is directly extended
2423 
2424  This all relies on the fact that absolute and relative resolutions are not mixed
2425  This is enforced by the tool enums, which are one or the other
2426  Asking for both relative and absolute smearing is two separate scale variables
2427  The tool checks for such cases and explicitly blocks them
2428 
2429  There is one exception to the above: a "data-MC difference" smearing
2430  If MC is below data, then we smear MC to match data (nominal smearing)
2431  Occurs if (sigma_nom^MC - sigma_nom^data) < 0, or equivalently (sigma_nom^data - sigma_nom^MC) > 0
2432  If data is below MC, we don't want to degrade the resolution of data to match MC
2433  Occurs if (sigma_nom^MC - sigma_nom^data) > 0, or equivalently (sigma_nom^data - sigma_nom^MC) < 0
2434  We also can't anti-smear MC (at least not with Gaussian smearing)
2435  Instead, smear by sigma_smear^2 = (sigma_nom + |Nsigma*[sigma_nom^data - sigma_nom^MC]|)^2 - (sigma_nom)^2
2436  This uses the second form of the above inequalities to stick with convention
2437  This way, we signify that we are smearing data (uncertainty < 0 if Nsigma > 0)
2438  This should be smearing of data (sigma_nom = sigma_nom^data)
2439  However, in the simple scenario, we still only smear MC
2440  Apply the uncertainty as-is, with sigma_nom = sigma_nom^MC
2441  This is actually "conservative" (in magnitude, not necessarily in correlations)
2442  |Nsigma*(sigma_nom^data - sigma_nom^MC)| is a fixed value independent of choice, call it X
2443  sigma_smear^2 = (sigma_nom + X)^2 - (sigma_nom)^2
2444  sigma_smear^2 = sigma_nom^2 [ (1 + X/sigma_nom)^2 - 1 ]
2445  Taylor expand: sigma_smear^2 ~ sigma_nom^2 ( 1 + 2*X/sigma_nom - 1 )
2446  sigma_smear^2 ~ sigma_nom^2 * 2 X / sigma_nom
2447  sigma_smear^2 ~ sigma_nom * 2 X
2448  Therefore, larger sigma_nom --> larger sigma_smear
2449  In this case, we know that sigma_nom^MC > sigma_nom^data (motivation for uncertainty)
2450  As such, sigma_nom = sigma_nom^MC is conservative
2451  This does not need to be handled any different than other uncertainties in the code
2452  However, the inputs will need to be made carefully to do the correct thing
2453  In particular, smear data occurs if sign(unc) < 0
2454  That is why it is written above as (sigma_nom^data - sigma_nom^MC) < 0
2455  In other words, the histogram must be created to be <= 0
2456  It should be <0 when data is below MC, and =0 when data is above MC
2457  This *could* be calculated on-the-fly from the two nominal histograms
2458  This requires substantial code development, as now this one NP is different from all others
2459  In the interest of time and code re-use, instead demand an extra histogram input
2460 
2461  In the end, smear by a Gaussian of mean 1 and width sigma_smear
2462 
2463  ----------
2464 
2465  Given this, the arguments to the function are:
2466  jet: jet to smear, needed for the kinematic dependence of nominal resolutions
2467  smearType: the resolution type to select the relevant nominal resolutions
2468  variation: the signed value of n*x + m*y + ... (for both relative and absolute)
2469 
2470  Dedicated class member variables used by this function are:
2471  m_isData: needed to control whether or not to smear the jet
2472  m_resHelper: contains lots of global resolution information
2473  - Whether to smear MC and data, or only MC
2474  - Nominal resolution histograms for data
2475  - Nominal resolution histograms for MC
2476  - Parametrizations of nominal resolution histograms
2477  m_rand: the random number generator
2478  m_userSeed: the optional user-specified seed to use for the random generator
2479 
2480  Technical detail on relative uncertainties:
2481  The input value of "variation" is always n*x + m*y + ...
2482  This is trivially correct for absolute uncertainties, but not relative
2483  However, for relative uncertainties, all NPs are with respect to same nominal
2484  As such, it factors out, and we can take variation*sigma_nominal^data
2485  Furthermore, as it factors out, the nominal doesn't matter to determine the sign
2486  This is important as the sign sets whether data or MC is the nominal
2487  */
2488 
2489  // Check if we need to do anything at all
2490  if (variation == 0)
2491  return 1; // No smearing if the variation is 0
2492  else if (m_isData)
2493  {
2494  if (m_resHelper->smearOnlyMC())
2495  return 1; // No smearing if this is data and we are in the simple scenario
2496  if (variation > 0)
2497  return 1; // No smearing if this is data and the sign says to smear MC
2498  }
2499  else if (variation < 0 && !m_resHelper->smearOnlyMC())
2500  return 1; // No smearing if this is MC and the sign says to smear data and this is not the simple scenario
2501 
2502  // Get the relevant nominal resolution
2503  const double sigmaMC = getNominalResolution(jet,smearType,m_currentUncSet->getTopology(),true);
2504  const double sigmaData = getNominalResolution(jet,smearType,m_currentUncSet->getTopology(),false);
2505  const double sigmaNom = std::max(sigmaMC,sigmaData);
2506 
2507  // If this is a relative uncertainty, get the relevant nominal data histogram
2508  // This is used to scale the input relative variation to get the absolute impact
2509  const double relativeFactor = CompScaleVar::isRelResolutionType(smearType) ? sigmaNom : 1;
2510 
2511  // We now have the required information, so let's calculate the smearing factor
2512  // Note that relativeFactor is 1 if this is an absolute uncertainty
2513  const double sigmaSmear = sqrt(pow(sigmaNom + fabs(variation)*relativeFactor,2) - pow(sigmaNom,2));
2514 
2515  // Throw an error if the userSeed is set to 1 as this is the seed used in JetCalibTools so leads to correlated smearing
2516  if (m_userSeed == 1){
2517  ATH_MSG_ERROR("A seed of 1e5 times the jet phi is used in JetCalibTools so using it here leads to correlated smearing");
2518  return 0;
2519  }
2520 
2521  // We have the smearing factor, so prepare to smear
2522  // If the user specified a seed, then use it times the jet's phi times 1*10^5
2523  // If not, then use the jet's phi times 2*10^5 in MC, 1.23*10^5 in (pseudo-)data
2524  // Difference in seed between allows for easy use of pseudo-data
2525  long long int seed = m_userSeed != 0 ? m_userSeed*1.00e+5*fabs(jet.phi()) : (m_isData ? 1.23e+5 : 2.00e+5)*fabs(jet.phi());
2526  // SetSeed(0) uses the clock, avoid this
2527  if(seed == 0) seed = m_isData ? 34545654 : 45583453; // arbitrary numbers which the seed couldn't otherwise be
2528  m_rand.SetSeed(seed);
2529 
2530  // Calculate and return the smearing factor
2531  // Force this to be a positive value
2532  // Negative values should be extraordinarily rare, but they do exist
2533  double smearingFactor = -1;
2534  while (smearingFactor < 0)
2535  smearingFactor = m_rand.Gaus(1.,sigmaSmear);
2536  return smearingFactor;
2537 }
2538 
2539 
2540 
2541 
2542 
2543 
2544 
2545 
2547 {
2548  static const SG::AuxElement::Accessor<float> accD12("Split12");
2549 
2550  const xAOD::Jet& constJet = jet;
2551  if (accD12.isAvailable(constJet))
2552  {
2553  const float value = accD12(constJet);
2554  accD12(jet) = shift*value;
2555  return StatusCode::SUCCESS;
2556  }
2557 
2558  ATH_MSG_ERROR("Split12 moment (D12) is not available on the jet, please make sure to set Split12 before calling the tool");
2559  return StatusCode::FAILURE;
2560 }
2561 
2563 {
2564  static const SG::AuxElement::Accessor<float> accD23("Split23");
2565 
2566  const xAOD::Jet& constJet = jet;
2567  if (accD23.isAvailable(constJet))
2568  {
2569  const float value = accD23(constJet);
2570  accD23(jet) = shift*value;
2571  return StatusCode::SUCCESS;
2572  }
2573 
2574  ATH_MSG_ERROR("Split23 moment (D23) is not available on the jet, please make sure to set Split23 before calling the tool");
2575  return StatusCode::FAILURE;
2576 }
2577 
2579 {
2580  static const SG::AuxElement::Accessor<float> accTau1("Tau1");
2581  static const SG::AuxElement::Accessor<float> accTau2("Tau2");
2582  static const SG::AuxElement::Accessor<float> accTau21("Tau21");
2583  static const bool Tau21wasAvailable = accTau21.isAvailable(jet);
2584  static const bool TauNNwasAvailable = accTau2.isAvailable(jet) && accTau1.isAvailable(jet);
2585 
2586  const xAOD::Jet& constJet = jet;
2587  if (Tau21wasAvailable)
2588  {
2589  if (!accTau21.isAvailable(jet))
2590  {
2591  ATH_MSG_ERROR("The Tau21 moment was previously available but is not available on this jet. This functionality is not supported.");
2592  return StatusCode::FAILURE;
2593  }
2594  const float value = accTau21(constJet);
2595  accTau21(jet) = shift*value;
2596  return StatusCode::SUCCESS;
2597  }
2598  if (TauNNwasAvailable)
2599  {
2600  if (! (accTau2.isAvailable(jet) && accTau1.isAvailable(jet)) )
2601  {
2602  ATH_MSG_ERROR("The Tau2 and Tau1 moments were previously available but are not available on this jet. This functionality is not supported.");
2603  return StatusCode::FAILURE;
2604  }
2605  const float tau2 = accTau2(constJet);
2606  const float tau1 = accTau1(constJet);
2607  accTau21(jet) = fabs(tau1) > 1.e-6 ? shift*(tau2/tau1) : -999; // 999 to match JetSubStructureMomentTools/NSubjettinessRatiosTool
2608  return StatusCode::SUCCESS;
2609  }
2610  //if (accTau21.isAvailable(constJet))
2611  //{
2612  // const float value = accTau21(constJet);
2613  // accTau21(jet) = shift*value;
2614  // return StatusCode::SUCCESS;
2615  //}
2616  //if (accTau1.isAvailable(constJet) && accTau2.isAvailable(constJet))
2617  //{
2618  // const float value = accTau2(constJet)/accTau1(constJet);
2619  // accTau21(jet) = shift*value;
2620  // return StatusCode::SUCCESS;
2621  //}
2622 
2623  ATH_MSG_ERROR("Neither Tau21 nor Tau1+Tau2 moments are available on the jet, please make sure one of these options is available before calling the tool.");
2624  return StatusCode::FAILURE;
2625 }
2626 
2628 {
2629  static const SG::AuxElement::Accessor<float> accTau2("Tau2");
2630  static const SG::AuxElement::Accessor<float> accTau3("Tau3");
2631  static const SG::AuxElement::Accessor<float> accTau32("Tau32");
2632  static const bool Tau32wasAvailable = accTau32.isAvailable(jet);
2633  static const bool TauNNwasAvailable = accTau3.isAvailable(jet) && accTau2.isAvailable(jet);
2634 
2635  const xAOD::Jet& constJet = jet;
2636  if (Tau32wasAvailable)
2637  {
2638  if (!accTau32.isAvailable(jet))
2639  {
2640  ATH_MSG_ERROR("The Tau32 moment was previously available but is not available on this jet. This functionality is not supported.");
2641  return StatusCode::FAILURE;
2642  }
2643  const float value = accTau32(constJet);
2644  accTau32(jet) = shift*value;
2645  return StatusCode::SUCCESS;
2646  }
2647  if (TauNNwasAvailable)
2648  {
2649  if (! (accTau3.isAvailable(jet) && accTau2.isAvailable(jet)) )
2650  {
2651  ATH_MSG_ERROR("The Tau3 and Tau2 moments were previously available but are not available on this jet. This functionality is not supported.");
2652  return StatusCode::FAILURE;
2653  }
2654  const float tau3 = accTau3(constJet);
2655  const float tau2 = accTau2(constJet);
2656  accTau32(jet) = fabs(tau2) > 1.e-6 ? shift*(tau3/tau2) : -999; // 999 to match JetSubStructureMomentTools/NSubjettinessRatiosTool
2657  return StatusCode::SUCCESS;
2658  }
2659  //if (accTau32.isAvailable(constJet))
2660  //{
2661  // const float value = accTau32(constJet);
2662  // accTau32(jet) = shift*value;
2663  // return StatusCode::SUCCESS;
2664  //}
2665  //if (accTau2.isAvailable(constJet) && accTau3.isAvailable(constJet))
2666  //{
2667  // const float value = accTau3(constJet)/accTau2(constJet);
2668  // accTau32(jet) = shift*value;
2669  // return StatusCode::SUCCESS;
2670  //}
2671 
2672  ATH_MSG_ERROR("Neither Tau32 nor Tau2+Tau3 moments are available on the jet, please make sure one of these options is available before calling the tool");
2673  return StatusCode::FAILURE;
2674 }
2675 
2677 {
2678  static const SG::AuxElement::Accessor<float> accTau1wta("Tau1_wta");
2679  static const SG::AuxElement::Accessor<float> accTau2wta("Tau2_wta");
2680  static const SG::AuxElement::Accessor<float> accTau21wta("Tau21_wta");
2681  static const SG::AuxElement::Accessor<float> accTau1WTA("Tau1_WTA");
2682  static const SG::AuxElement::Accessor<float> accTau2WTA("Tau2_WTA");
2683  static const SG::AuxElement::Accessor<float> accTau21WTA("Tau21_WTA");
2684  static const bool Tau21wtawasAvailable = accTau21wta.isAvailable(jet);
2685  static const bool Tau21WTAwasAvailable = accTau21WTA.isAvailable(jet);
2686  static const bool TauNNwtawasAvailable = accTau2wta.isAvailable(jet) && accTau1wta.isAvailable(jet);
2687  static const bool TauNNWTAwasAvailable = accTau2WTA.isAvailable(jet) && accTau1WTA.isAvailable(jet);
2688 
2689  const xAOD::Jet& constJet = jet;
2690  if (Tau21wtawasAvailable)
2691  {
2692  if (!accTau21wta.isAvailable(jet))
2693  {
2694  ATH_MSG_ERROR("The Tau21_wta moment was previously available but is not available on this jet. This functionality is not supported.");
2695  return StatusCode::FAILURE;
2696  }
2697  const float value = accTau21wta(constJet);
2698  accTau21wta(jet) = shift*value;
2699  return StatusCode::SUCCESS;
2700  }
2701  if (Tau21WTAwasAvailable)
2702  {
2703  if (!accTau21WTA.isAvailable(jet))
2704  {
2705  ATH_MSG_ERROR("The Tau21_WTA moment was previously available but is not available on this jet. This functionality is not supported.");
2706  return StatusCode::FAILURE;
2707  }
2708  const float value = accTau21WTA(constJet);
2709  accTau21WTA(jet) = shift*value;
2710  return StatusCode::SUCCESS;
2711  }
2712  if (TauNNwtawasAvailable)
2713  {
2714  if (! (accTau2wta.isAvailable(jet) && accTau1wta.isAvailable(jet)) )
2715  {
2716  ATH_MSG_ERROR("The Tau2_wta and Tau1_wta moments were previously available but are not available on this jet. This functionality is not supported.");
2717  return StatusCode::FAILURE;
2718  }
2719  const float tau2 = accTau2wta(constJet);
2720  const float tau1 = accTau1wta(constJet);
2721  accTau21wta(jet) = fabs(tau1) > 1.e-6 ? shift*(tau2/tau1) : -999; // 999 to match JetSubStructureMomentTools/NSubjettinessRatiosTool
2722  return StatusCode::SUCCESS;
2723  }
2724  if (TauNNWTAwasAvailable)
2725  {
2726  if (! (accTau2WTA.isAvailable(jet) && accTau1WTA.isAvailable(jet)) )
2727  {
2728  ATH_MSG_ERROR("The Tau2_WTA and Tau1_WTA moments were previously available but are not available on this jet. This functionality is not supported.");
2729  return StatusCode::FAILURE;
2730  }
2731  const float tau2 = accTau2WTA(constJet);
2732  const float tau1 = accTau1WTA(constJet);
2733  accTau21WTA(jet) = fabs(tau1) > 1.e-6 ? shift*(tau2/tau1) : -999; // 999 to match JetSubStructureMomentTools/NSubjettinessRatiosTool
2734  return StatusCode::SUCCESS;
2735  }
2736 
2737  ATH_MSG_ERROR("Neither Tau21_wta nor Tau1_wta+Tau2_wta moments are available on the jet, please make sure one of these options is available before calling the tool");
2738  return StatusCode::FAILURE;
2739 }
2741 {
2742  static const SG::AuxElement::Accessor<float> accTau2wta("Tau2_wta");
2743  static const SG::AuxElement::Accessor<float> accTau3wta("Tau3_wta");
2744  static const SG::AuxElement::Accessor<float> accTau32wta("Tau32_wta");
2745  static const SG::AuxElement::Accessor<float> accTau2WTA("Tau2_WTA");
2746  static const SG::AuxElement::Accessor<float> accTau3WTA("Tau3_WTA");
2747  static const SG::AuxElement::Accessor<float> accTau32WTA("Tau32_WTA");
2748  static const bool Tau32wtawasAvailable = accTau32wta.isAvailable(jet);
2749  static const bool Tau32WTAwasAvailable = accTau32WTA.isAvailable(jet);
2750  static const bool TauNNwtawasAvailable = accTau3wta.isAvailable(jet) && accTau2wta.isAvailable(jet);
2751  static const bool TauNNWTAwasAvailable = accTau3WTA.isAvailable(jet) && accTau2WTA.isAvailable(jet);
2752 
2753  const xAOD::Jet& constJet = jet;
2754  if (Tau32wtawasAvailable)
2755  {
2756  if (!accTau32wta.isAvailable(jet))
2757  {
2758  ATH_MSG_ERROR("The Tau32_wta moment was previously available but is not available on this jet. This functionality is not supported.");
2759  return StatusCode::FAILURE;
2760  }
2761  const float value = accTau32wta(constJet);
2762  accTau32wta(jet) = shift*value;
2763  return StatusCode::SUCCESS;
2764  }
2765  if (Tau32WTAwasAvailable)
2766  {
2767  if (!accTau32WTA.isAvailable(jet))
2768  {
2769  ATH_MSG_ERROR("The Tau32_WTA moment was previously available but is not available on this jet. This functionality is not supported.");
2770  return StatusCode::FAILURE;
2771  }
2772  const float value = accTau32WTA(constJet);
2773  accTau32WTA(jet) = shift*value;
2774  return StatusCode::SUCCESS;
2775  }
2776  if (TauNNwtawasAvailable)
2777  {
2778  if (! (accTau3wta.isAvailable(jet) && accTau2wta.isAvailable(jet)) )
2779  {
2780  ATH_MSG_ERROR("The Tau3_wta and Tau2_wta moments were previously available but are not available on this jet. This functionality is not supported.");
2781  return StatusCode::FAILURE;
2782  }
2783  const float tau3 = accTau3wta(constJet);
2784  const float tau2 = accTau2wta(constJet);
2785  accTau32wta(jet) = fabs(tau2) > 1.e-6 ? shift*(tau3/tau2) : -999; // 999 to match JetSubStructureMomentTools/NSubjettinessRatiosTool
2786  return StatusCode::SUCCESS;
2787  }
2788  if (TauNNWTAwasAvailable)
2789  {
2790  if (! (accTau3WTA.isAvailable(jet) && accTau2WTA.isAvailable(jet)) )
2791  {
2792  ATH_MSG_ERROR("The Tau3_WTA and Tau2_WTA moments were previously available but are not available on this jet. This functionality is not supported.");
2793  return StatusCode::FAILURE;
2794  }
2795  const float tau3 = accTau3WTA(constJet);
2796  const float tau2 = accTau2WTA(constJet);
2797  accTau32WTA(jet) = fabs(tau2) > 1.e-6 ? shift*(tau3/tau2) : -999; // 999 to match JetSubStructureMomentTools/NSubjettinessRatiosTool
2798  return StatusCode::SUCCESS;
2799  }
2800  //if (accTau32wta.isAvailable(constJet))
2801  //{
2802  // const float value = accTau32wta(constJet);
2803  // accTau32wta(jet) = shift*value;
2804  // return StatusCode::SUCCESS;
2805  //}
2806  //if (accTau32WTA.isAvailable(constJet))
2807  //{
2808  // const float value = accTau32WTA(constJet);
2809  // accTau32WTA(jet) = shift*value;
2810  // return StatusCode::SUCCESS;
2811  //}
2812  //if (accTau2wta.isAvailable(constJet) && accTau3wta.isAvailable(constJet))
2813  //{
2814  // const float value = accTau3wta(constJet)/accTau2wta(constJet);
2815  // accTau32wta(jet) = shift*value;
2816  // return StatusCode::SUCCESS;
2817  //}
2818  //if (accTau2WTA.isAvailable(constJet) && accTau3WTA.isAvailable(constJet))
2819  //{
2820  // const float value = accTau3WTA(constJet)/accTau2WTA(constJet);
2821  // accTau32WTA(jet) = shift*value;
2822  // return StatusCode::SUCCESS;
2823  //}
2824 
2825  ATH_MSG_ERROR("Neither Tau32_wta nor Tau2_wta+Tau3_wta moments are available on the jet, please make sure one of these options is available before calling the tool");
2826  return StatusCode::FAILURE;
2827 }
2828 
2830 {
2831  static const SG::AuxElement::Accessor<float> accD2("D2");
2832  static const SG::AuxElement::Accessor<float> accECF1("ECF1");
2833  static const SG::AuxElement::Accessor<float> accECF2("ECF2");
2834  static const SG::AuxElement::Accessor<float> accECF3("ECF3");
2835  static const bool D2wasAvailable = accD2.isAvailable(jet);
2836  static const bool ECFwasAvailable = accECF1.isAvailable(jet) && accECF2.isAvailable(jet) && accECF3.isAvailable(jet);
2837 
2838  const xAOD::Jet& constJet = jet;
2839  if (D2wasAvailable)
2840  {
2841  if (!accD2.isAvailable(jet))
2842  {
2843  ATH_MSG_ERROR("The D2 moment was previously available but is not available on this jet. This functionality is not supported.");
2844  return StatusCode::FAILURE;
2845  }
2846  const float value = accD2(constJet);
2847  accD2(jet) = shift*value;
2848  return StatusCode::SUCCESS;
2849  }
2850  if (ECFwasAvailable)
2851  {
2852  if (! (accECF1.isAvailable(constJet) && accECF2.isAvailable(constJet) && accECF3.isAvailable(constJet)) )
2853  {
2854  ATH_MSG_ERROR("The ECF1, ECF2, and ECF3 moments were previously available but are not available on this jet. This functionality is not supported.");
2855  return StatusCode::FAILURE;
2856  }
2857  const float ecf1 = accECF1(constJet);
2858  const float ecf2 = accECF2(constJet);
2859  const float ecf3 = accECF3(constJet);
2860  accD2(jet) = fabs(ecf2) > 1.e-6 ? shift * (pow(ecf1/ecf2,3)*ecf3) : -999; // 999 to match JetSubStructureMomentTools/EnergyCorrelatorRatiosTool
2861  return StatusCode::SUCCESS;
2862  }
2863 
2864  //if (accD2.isAvailable(constJet))
2865  //{
2866  // const float value = accD2(constJet);
2867  // accD2(jet) = shift*value;
2868  // return StatusCode::SUCCESS;
2869  //}
2870  //if (accECF1.isAvailable(constJet) && accECF2.isAvailable(constJet) && accECF3.isAvailable(constJet))
2871  //{
2872  // const float ecf1 = accECF1(constJet);
2873  // const float ecf2 = accECF2(constJet);
2874  // const float ecf3 = accECF3(constJet);
2875  // accD2(jet) = shift * (pow(ecf1/ecf2,3)*ecf3);
2876  // return StatusCode::SUCCESS;
2877  //}
2878 
2879  ATH_MSG_ERROR("Neither D2 nor ECF1+ECF2+ECF3 moments are available on the jet, please make sure one of these options is available before calling the tool");
2880  return StatusCode::FAILURE;
2881 }
2882 
2884 {
2885  static const SG::AuxElement::Accessor<float> accC2("C2");
2886  static const SG::AuxElement::Accessor<float> accECF1("ECF1");
2887  static const SG::AuxElement::Accessor<float> accECF2("ECF2");
2888  static const SG::AuxElement::Accessor<float> accECF3("ECF3");
2889  static const bool C2wasAvailable = accC2.isAvailable(jet);
2890  static const bool ECFwasAvailable = accECF1.isAvailable(jet) && accECF2.isAvailable(jet) && accECF3.isAvailable(jet);
2891 
2892  const xAOD::Jet& constJet = jet;
2893  if (C2wasAvailable)
2894  {
2895  if (!accC2.isAvailable(jet))
2896  {
2897  ATH_MSG_ERROR("The C2 moment was previously available but is not available on this jet. This functionality is not supported.");
2898  return StatusCode::FAILURE;
2899  }
2900  const float value = accC2(constJet);
2901  accC2(jet) = shift*value;
2902  return StatusCode::SUCCESS;
2903  }
2904  if (ECFwasAvailable)
2905  {
2906  if (! (accECF1.isAvailable(constJet) && accECF2.isAvailable(constJet) && accECF3.isAvailable(constJet)) )
2907  {
2908  ATH_MSG_ERROR("The ECF1, ECF2, and ECF3 moments were previously available but are not available on this jet. This functionality is not supported.");
2909  return StatusCode::FAILURE;
2910  }
2911  const float ecf1 = accECF1(constJet);
2912  const float ecf2 = accECF2(constJet);
2913  const float ecf3 = accECF3(constJet);
2914  accC2(jet) = fabs(ecf2) > 1.e-6 ? shift * (ecf3*ecf1/pow(ecf2,2)) : -999; // 999 to match JetSubStructureMomentTools/EnergyCorrelatorRatiosTool
2915  return StatusCode::SUCCESS;
2916  }
2917 
2918  ATH_MSG_ERROR("Neither C2 nor ECF1+ECF2+ECF3 moments are available on the jet, please make sure one of these options is available before calling the tool");
2919  return StatusCode::FAILURE;
2920 }
2921 
2923 {
2924  static const SG::AuxElement::Accessor<float> accQw("Qw");
2925 
2926  const xAOD::Jet& constJet = jet;
2927  if (accQw.isAvailable(constJet))
2928  {
2929  const float value = accQw(constJet);
2930  accQw(jet) = shift*value;
2931  return StatusCode::SUCCESS;
2932  }
2933 
2934  ATH_MSG_ERROR("Qw moment is not available on the jet, please make sure to set Qw before calling the tool");
2935  return StatusCode::FAILURE;
2936 }
2937 
2939 {
2940  const bool TagScaleFactorwasAvailable = m_accTagScaleFactor.isAvailable(jet);
2941  const xAOD::Jet& constJet = jet;
2942  if (TagScaleFactorwasAvailable)
2943  {
2944  if (!m_accTagScaleFactor.isAvailable(jet))
2945  {
2946  ATH_MSG_ERROR("TagScaleFactor was previously available but is not available on this jet. This functionality is not supported.");
2947  return StatusCode::FAILURE;
2948  }
2949  const float value = m_accTagScaleFactor(constJet);
2950  if ( value < 1e-5 ) {
2951  // if the central SF is 0, we don't consider any uncertainties
2952  return StatusCode::SUCCESS;
2953  }
2954  if (m_accEffSF.isAvailable(jet)) {
2955  // if efficiency and efficiency SF are available, inefficiency SF will be calculated
2956  const float effSF = m_accEffSF(constJet);
2957  const float efficiency = m_accEfficiency(constJet);
2958 
2959 
2960  const bool tagResult = m_accTagResult(constJet);
2961  if ( tagResult ){
2962  // update the efficiency SF
2963 
2964  if ( shift*value < 0.0 ){
2965  m_accTagScaleFactor(jet) = 0.0;
2966  } else {
2967  m_accTagScaleFactor(jet) = shift*value;
2968  }
2969  return StatusCode::SUCCESS;
2970  } else {
2971  // this jet is "failed", since SF applied to the event is (1-effSF*efficiency)/(1-efficiency)
2972  // so inefficiency SF will be recalculated for given uncertainty
2973  if ( efficiency < 1.0 ){
2974  if ( shift*value < 0.0 ){
2975  m_accTagScaleFactor(jet) = 1.0/(1. - efficiency);
2976  } else {
2977  m_accTagScaleFactor(jet) = (1. - shift*effSF*efficiency) / (1. - efficiency);
2978  }
2979  }
2980  return StatusCode::SUCCESS;
2981  }
2982  } else {
2983  // if efficiency and efficiency SF are NOT available, inefficiency SF will not be calculated
2984 
2985  if ( shift*value < 0.0 ){
2986  m_accTagScaleFactor(jet) = 0.0;
2987  } else {
2988  m_accTagScaleFactor(jet) = shift*value;
2989  }
2990  return StatusCode::SUCCESS;
2991  }
2992  }
2993 
2994  ATH_MSG_ERROR("TagScaleFactor is not available on the jet, please make sure you called BoostedJetTaggers tag() function before calling this function.");
2995  return StatusCode::FAILURE;
2996 }
2997 
2999 {
3000  const bool TagScaleFactorwasAvailable = m_accTagScaleFactor.isAvailable(jet);
3001  const xAOD::Jet& constJet = jet;
3002  if (TagScaleFactorwasAvailable)
3003  {
3004  if (!m_accTagScaleFactor.isAvailable(jet))
3005  {
3006  ATH_MSG_ERROR("TagScaleFactor was previously available but is not available on this jet. This functionality is not supported.");
3007  return StatusCode::FAILURE;
3008  }
3009  const float value = m_accTagScaleFactor(constJet);
3010  if ( value < 1e-5 ) {
3011  // if the central SF is 0, we don't consider any uncertainties
3012  return StatusCode::SUCCESS;
3013  }
3014  if (m_accEffSF.isAvailable(jet)) {
3015  // if efficiency and efficiency SF are available, inefficiency SF will be calculated
3016 
3017  const float effSF = m_accEffSF(constJet);
3018  const float efficiency = m_accEfficiency(constJet);
3019  float sigeffSF = 1.0;
3020  float updated_efficiency = efficiency + shift; // efficiency value is varied
3021 
3022  if ( updated_efficiency < 1e-5 ) updated_efficiency=1e-5;
3023  if ( updated_efficiency > 1.0-1e-5 ) updated_efficiency=1.0-1e-5;
3024  m_accEfficiency(jet) = updated_efficiency;
3025  if (m_accSigeffSF.isAvailable(jet)) sigeffSF = m_accSigeffSF(constJet);
3026 
3027  const bool tagResult = m_accTagResult(constJet);
3028  if ( tagResult ) {
3029  // do nothing, since efficiency variation does not affect the tagged jets
3030  return StatusCode::SUCCESS;
3031  } else {
3032  // this jet is "failed"
3033  // inefficiency SF will be recalculated for given uncertainty
3034  if ( std::abs(effSF - 1.0) < 1e-5 && std::abs(shift)>0 ) {
3035  // For other category, effSF=1.0. So efficiency variation cannot be propagated to the ineffSF i.e. (1 - eff)/(1 - eff) is always 1 not depending on eff value.
3036  // SF for signal (sigeffSF) is used instead of effSF when calculating it
3037  // Relative variation of ineffSF for signal is calculated here and used for the other category
3038  float nominalIneffSFsig = (1. - sigeffSF*efficiency)/(1. - efficiency);
3039  float variatedIneffSFsig = (1. - sigeffSF*updated_efficiency)/(1. - updated_efficiency);
3040  m_accTagScaleFactor(jet) = variatedIneffSFsig/nominalIneffSFsig;
3041  } else {
3042  m_accTagScaleFactor(jet) = (1. - effSF*updated_efficiency) / (1. - updated_efficiency);
3043  }
3044  return StatusCode::SUCCESS;
3045  }
3046  } else {
3047  // if efficiency and efficiency SF are NOT available, inefficiency SF will not be calculated
3048  // do nothing
3049  return StatusCode::SUCCESS;
3050  }
3051  }
3052 
3053  ATH_MSG_ERROR("TagScaleFactor is not available on the jet, please make sure you called BoostedJetTaggers tag() function before calling this function.");
3054  return StatusCode::FAILURE;
3055 }
3056 
jet::CompMassDef::TypeEnum
TypeEnum
Definition: UncertaintyEnum.h:71
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
ShallowCopy.h
python.Dso.registry
registry
Definition: Control/AthenaServices/python/Dso.py:159
jet::UncertaintyHistogram::getName
const TString & getName() const
Definition: UncertaintyHistogram.h:36
jet::CombinedMassUncertaintyComponent::setCombWeightParam
virtual StatusCode setCombWeightParam(const CompParametrization::TypeEnum param)
Definition: CombinedMassUncertaintyComponent.cxx:191
python.StoreID.UNKNOWN
int UNKNOWN
Definition: StoreID.py:16
jet::CompScaleVar::isResolutionType
bool isResolutionType(const TypeEnum type)
Definition: UncertaintyEnum.cxx:348
JetUncertaintiesTool::getUncertainty
virtual double getUncertainty(size_t index, const xAOD::Jet &jet) const
Definition: JetUncertaintiesTool.cxx:1711
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
JetUncertaintiesTool::m_recommendedSystematics
CP::SystematicSet m_recommendedSystematics
Definition: JetUncertaintiesTool.h:210
jet::CompParametrization::PtLOGPtMassForTagSF
@ PtLOGPtMassForTagSF
Definition: UncertaintyEnum.h:59
jet::ValidityHistogram
Definition: ValidityHistogram.h:19
PtMassEtaUncertaintyComponent.h
jet::PtUncertaintyComponent
Definition: PtUncertaintyComponent.h:14
JetUncertaintiesTool::getNominalResolutionData
virtual double getNominalResolutionData(const xAOD::Jet &jet, const jet::CompScaleVar::TypeEnum smearType, const jet::JetTopology::TypeEnum topology=jet::JetTopology::UNKNOWN) const
Definition: JetUncertaintiesTool.cxx:1820
jet::GroupHelper
Definition: ConfigHelper.h:84
beamspotnt.var
var
Definition: bin/beamspotnt.py:1394
JetUncertaintiesTool::m_name
const std::string m_name
Definition: JetUncertaintiesTool.h:180
jet::CompMassDef::FourVecMass
@ FourVecMass
Definition: UncertaintyEnum.h:73
jet::ComponentHelper::scaleVar
CompScaleVar::TypeEnum scaleVar
Definition: ConfigHelper.h:65
jet::ComponentHelper::groupNum
int groupNum
Definition: ConfigHelper.h:46
jet::CompScaleVar::D2Beta1
@ D2Beta1
Definition: UncertaintyEnum.h:105
CP::SystematicVariation::CONTINUOUS
@ CONTINUOUS
Definition: SystematicVariation.h:79
jet::CompScaleVar::FourVecResAbs
@ FourVecResAbs
Definition: UncertaintyEnum.h:117
JetUncertaintiesTool::m_absEtaGluonFraction
bool m_absEtaGluonFraction
Definition: JetUncertaintiesTool.h:276
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
JetUncertaintiesTool::m_fileValidHist
jet::ValidityHistogram * m_fileValidHist
Definition: JetUncertaintiesTool.h:217
UncertaintyGroup.h
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
JetUncertaintiesTool::m_refNPVHist
jet::UncertaintyHistogram * m_refNPVHist
Definition: JetUncertaintiesTool.h:204
JetUncertaintiesTool::initialize
virtual StatusCode initialize()
Dummy implementation of the initialisation function.
Definition: JetUncertaintiesTool.cxx:236
jet::CompScaleVar::MassRes
@ MassRes
Definition: UncertaintyEnum.h:112
UncertaintyHistogram.h
get_generator_info.result
result
Definition: get_generator_info.py:21
JetUncertaintiesTool::m_energyScale
float m_energyScale
Definition: JetUncertaintiesTool.h:181
jet::PunchthroughUncertaintyComponent
Definition: PunchthroughUncertaintyComponent.h:14
jet::UncertaintyGroup::addComponent
virtual StatusCode addComponent(UncertaintyComponent *component)
Definition: UncertaintyGroup.cxx:105
jet::UncertaintySet::getTopology
JetTopology::TypeEnum getTopology(const CompScaleVar::TypeEnum scaleVar=CompScaleVar::UNKNOWN) const
Definition: UncertaintySet.cxx:281
JetUncertaintiesTool::getComponentScalesFourVec
virtual bool getComponentScalesFourVec(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1579
jet::FlavourComp::PerJetResponse_C
@ PerJetResponse_C
Definition: UncertaintyEnum.h:186
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
CP::SystematicSet::swap
void swap(SystematicSet &otherSet)
description: swap elements of a set
Definition: SystematicSet.cxx:108
xAOD::EventInfo_v1::eventNumber
uint64_t eventNumber() const
The current event's event number.
CP::SystematicVariation::basename
std::string basename() const
description: the base name, i.e.
Definition: SystematicVariation.cxx:312
jet::CompScaleVar::D23
@ D23
Definition: UncertaintyEnum.h:100
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
jet::ComponentHelper::caloMassDef
TString caloMassDef
Definition: ConfigHelper.h:50
jet::GroupHelper::correlation
CompCorrelation::TypeEnum correlation
Definition: ConfigHelper.h:101
JetUncertaintiesTool::getComponentScalesTau32
virtual bool getComponentScalesTau32(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1609
jet::CombinedMassUncertaintyComponent::setCombWeightMassDefs
virtual StatusCode setCombWeightMassDefs(const CompMassDef::TypeEnum caloMassDef, const CompMassDef::TypeEnum TAMassDef)
Definition: CombinedMassUncertaintyComponent.cxx:154
jet::ClosebyUncertaintyComponent
Definition: ClosebyUncertaintyComponent.h:14
jet::ComponentHelper::TAMassDef
TString TAMassDef
Definition: ConfigHelper.h:51
CP::SystematicSet::size
size_t size() const
returns: size of the set
Definition: SystematicSet.h:71
index
Definition: index.py:1
JetUncertaintiesTool::correctedCopy
virtual CP::CorrectionCode correctedCopy(const xAOD::Jet &input, xAOD::Jet *&output) const
Definition: JetUncertaintiesTool.cxx:2273
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
PtUncertaintyComponent.h
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
JetUncertaintiesTool::addUncertaintyGroup
StatusCode addUncertaintyGroup(const jet::ConfigHelper &helper)
Definition: JetUncertaintiesTool.cxx:794
jet::CorrelationMatrix
Definition: CorrelationMatrix.h:28
Data
@ Data
Definition: BaseObject.h:11
FlavourUncertaintyComponent.h
JetUncertaintiesTool::m_configFile
std::string m_configFile
Definition: JetUncertaintiesTool.h:187
JetUncertaintiesTool::getComponentCategories
virtual std::vector< std::string > getComponentCategories() const
Definition: JetUncertaintiesTool.cxx:1970
JetUncertaintiesTool::getNormalizedCaloMassWeight
virtual double getNormalizedCaloMassWeight(const xAOD::Jet &jet) const
Definition: JetUncertaintiesTool.cxx:1923
JetUncertaintiesTool::getRelease
virtual std::string getRelease() const
Definition: JetUncertaintiesTool.h:67
checkScalesSingleVar
bool checkScalesSingleVar(const std::set< CompScaleVar::TypeEnum > &varSet, const CompScaleVar::TypeEnum var)
Definition: JetUncertaintiesTool.cxx:1574
JetUncertaintiesTool::addUncertaintyComponent
StatusCode addUncertaintyComponent(const jet::ConfigHelper &helper)
Definition: JetUncertaintiesTool.cxx:833
JetUncertaintiesTool::getComponentScalesTagScaleFactor
virtual bool getComponentScalesTagScaleFactor(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1639
CP::SystematicVariation::name
const std::string & name() const
description: the full systematics name, for use in strings, etc.
Definition: SystematicVariation.cxx:303
CSV_InDetExporter.new
new
Definition: CSV_InDetExporter.py:145
LargeRJetTruthLabel::stringToEnum
TypeEnum stringToEnum(const TString &name)
Definition: LargeRJetLabelEnum.h:81
JetUncertaintiesTool::m_pseudoDataJERsmearingMode
bool m_pseudoDataJERsmearingMode
Definition: JetUncertaintiesTool.h:279
xAOD::ShallowAuxContainer
Class creating a shallow copy of an existing auxiliary container.
Definition: ShallowAuxContainer.h:54
asg
Definition: DataHandleTestTool.h:28
jet::GroupHelper::subgroupNum
int subgroupNum
Definition: ConfigHelper.h:97
CP::SystematicSet
Class to wrap a set of SystematicVariations.
Definition: SystematicSet.h:31
JetUncertaintiesTool::getValidity
virtual bool getValidity(size_t index, const xAOD::Jet &jet) const
Definition: JetUncertaintiesTool.cxx:1661
jet::ComponentHelper
Definition: ConfigHelper.h:24
jet::PerJetFlavourUncertaintyComponent
Definition: PerJetFlavourUncertaintyComponent.h:16
JetUncertaintiesTool::setScaleToGeV
virtual StatusCode setScaleToGeV()
Definition: JetUncertaintiesTool.cxx:223
jet::GroupHelper::category
CompCategory::TypeEnum category
Definition: ConfigHelper.h:100
JetTools::enumToString
TString enumToString(const FFJetAllowedMassDefEnum type)
Definition: FFJetSmearingTool.h:86
JetUncertaintiesTool::m_refNPV
float m_refNPV
Definition: JetUncertaintiesTool.h:202
jet::ValidityHistogram::initialize
virtual StatusCode initialize(TFile *histFile)
Definition: ValidityHistogram.cxx:316
JetUncertaintiesTool::checkIndexInput
StatusCode checkIndexInput(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1556
JetUncertaintiesTool::m_userSeed
long long int m_userSeed
Definition: JetUncertaintiesTool.h:227
jet::ComponentHelper::uncNames
std::vector< TString > uncNames
Definition: ConfigHelper.h:72
CP::SystematicSet::name
std::string name() const
returns: the systematics joined into a single string.
Definition: SystematicSet.cxx:278
jet::ComponentHelper::massDef
CompMassDef::TypeEnum massDef
Definition: ConfigHelper.h:64
athena.value
value
Definition: athena.py:124
PunchthroughUncertaintyComponent.h
JetUncertaintiesTool::m_refMuHist
jet::UncertaintyHistogram * m_refMuHist
Definition: JetUncertaintiesTool.h:205
JetUncertaintiesTool::updateC2Beta1
StatusCode updateC2Beta1(xAOD::Jet &jet, const double shift) const
Definition: JetUncertaintiesTool.cxx:2883
JetUncertaintiesTool::applyCorrection
virtual CP::CorrectionCode applyCorrection(xAOD::Jet &jet) const
Definition: JetUncertaintiesTool.cxx:2087
jet::UncertaintySet::initialize
virtual StatusCode initialize(const CP::SystematicSet &systConfig, const std::vector< UncertaintyGroup * > &groups)
Definition: UncertaintySet.cxx:31
JetUncertaintiesTool::getValidUncertainty
virtual bool getValidUncertainty(size_t index, double &unc, const xAOD::Jet &jet) const
Definition: JetUncertaintiesTool.cxx:1765
JetUncertaintiesTool::getComponentTopology
virtual jet::JetTopology::TypeEnum getComponentTopology(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1654
jet::CorrelationMatrix::getMatrix
virtual const TH2D * getMatrix() const
Definition: CorrelationMatrix.h:45
jet::CorrelationMatrix::initializeForEta
virtual StatusCode initializeForEta(const JetUncertaintiesTool &uncTool)
Definition: CorrelationMatrix.cxx:130
PtAbsMassUncertaintyComponent.h
CP::SystematicVariation
Definition: SystematicVariation.h:47
JetUncertaintiesTool::m_systFilters
std::vector< std::string > m_systFilters
Definition: JetUncertaintiesTool.h:192
jet::CombinedMassUncertaintyComponent::setCaloWeights
virtual StatusCode setCaloWeights(const UncertaintyHistogram *caloWeights)
Definition: CombinedMassUncertaintyComponent.cxx:120
JetUncertaintiesTool::getRefNPV
virtual float getRefNPV() const
Definition: JetUncertaintiesTool.cxx:1428
jet::ELogMassUncertaintyComponent
Definition: ELogMassUncertaintyComponent.h:14
jet::CompScaleVar::isRelResolutionType
bool isRelResolutionType(const TypeEnum type)
Definition: UncertaintyEnum.cxx:379
jet::PtMassUncertaintyComponent
Definition: PtMassUncertaintyComponent.h:14
JetUncertaintiesTool::m_defAnaFile
std::string m_defAnaFile
Definition: JetUncertaintiesTool.h:201
jet::CompScaleVar::FourVec
@ FourVec
Definition: UncertaintyEnum.h:96
jet::FlavourComp::PerJetResponse_B
@ PerJetResponse_B
Definition: UncertaintyEnum.h:185
JetUncertaintiesTool::m_TAMassWeight
jet::UncertaintyHistogram * m_TAMassWeight
Definition: JetUncertaintiesTool.h:221
Dedxcorrection::resolution
double resolution[nGasTypes][nParametersResolution]
Definition: TRT_ToT_Corrections.h:46
jet::CorrelationMatrix::initializeForPt
virtual StatusCode initializeForPt(const JetUncertaintiesTool &uncTool)
Definition: CorrelationMatrix.cxx:64
JetUncertaintiesTool::m_accSigeffSF
SG::AuxElement::Accessor< float > m_accSigeffSF
Definition: JetUncertaintiesTool.h:271
jet::CompParametrization::PtAbsEta
@ PtAbsEta
Definition: UncertaintyEnum.h:49
postInclude.inputs
inputs
Definition: postInclude.SortInput.py:15
JetUncertaintiesTool::getComponentScalesMass
virtual bool getComponentScalesMass(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1589
jet::UncertaintyGroup::getName
virtual TString getName() const
Definition: UncertaintyGroup.h:40
JetUncertaintiesTool::getNominalResolutionMC
virtual double getNominalResolutionMC(const xAOD::Jet &jet, const jet::CompScaleVar::TypeEnum smearType, const jet::JetTopology::TypeEnum topology=jet::JetTopology::UNKNOWN) const
Definition: JetUncertaintiesTool.cxx:1815
JetUncertaintiesTool::getComponentScalesD2Beta1
virtual bool getComponentScalesD2Beta1(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1624
JetUncertaintiesTool::getComponentNamesInCategory
virtual std::vector< std::string > getComponentNamesInCategory(const std::string &category) const
Definition: JetUncertaintiesTool.cxx:2018
jet::UncertaintyHistogram::getValue
double getValue(const double var1) const
Definition: UncertaintyHistogram.cxx:141
Helpers.h
PUfitVar::maxEta
constexpr float maxEta
Definition: GepMETPufitAlg.cxx:13
JetUncertaintiesTool::m_calibArea
std::string m_calibArea
Definition: JetUncertaintiesTool.h:188
UncertaintyEnum.h
jet::UncertaintyComponent
Definition: UncertaintyComponent.h:25
JetUncertaintiesTool::getNominalResolution
double getNominalResolution(const xAOD::Jet &jet, const jet::CompScaleVar::TypeEnum smearType, const jet::JetTopology::TypeEnum topology, const bool readMC) const
Definition: JetUncertaintiesTool.cxx:1825
jet::CompCorrelation::Correlated
@ Correlated
Definition: UncertaintyEnum.h:35
ELogMassEtaUncertaintyComponent.h
jet::GroupHelper::reducible
bool reducible
Definition: ConfigHelper.h:102
JetUncertaintiesTool::checkIfRecommendedSystematic
bool checkIfRecommendedSystematic(const jet::UncertaintyGroup &systematic) const
Definition: JetUncertaintiesTool.cxx:1270
jet::CompParametrization::PtAbsMassAbsEta
@ PtAbsMassAbsEta
Definition: UncertaintyEnum.h:55
jet::PileupUncertaintyComponent
Definition: PileupUncertaintyComponent.h:14
runBeamSpotCalibration.helper
helper
Definition: runBeamSpotCalibration.py:112
LargeRTopologyUncertaintyComponent.h
JetUncertaintiesTool::m_isInit
bool m_isInit
Definition: JetUncertaintiesTool.h:179
CorrelationMatrix.h
jet::UncertaintyHistogram::initialize
virtual StatusCode initialize(TFile *histFile)
Definition: UncertaintyHistogram.cxx:85
JetUncertaintiesTool::getComponentScalesTau21WTA
virtual bool getComponentScalesTau21WTA(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1614
JESUNC_ERROR_CODE
#define JESUNC_ERROR_CODE
Definition: Reconstruction/Jet/JetUncertainties/JetUncertainties/Helpers.h:23
JetUncertaintiesTool::m_analysisHistPattern
std::string m_analysisHistPattern
Definition: JetUncertaintiesTool.h:191
JetUncertaintiesTool::affectingSystematics
virtual CP::SystematicSet affectingSystematics() const
the list of all systematics this tool can be affected by
Definition: JetUncertaintiesTool.cxx:1255
JetUncertaintiesTool::m_caloMassWeight
jet::UncertaintyHistogram * m_caloMassWeight
Definition: JetUncertaintiesTool.h:220
PileupUncertaintyComponent.h
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
CP::CorrectionCode::OutOfValidityRange
@ OutOfValidityRange
Input object is out of validity range.
Definition: CorrectionCode.h:37
JetUncertaintiesTool::m_systSetMap
std::unordered_map< CP::SystematicSet, jet::UncertaintySet * > m_systSetMap
Definition: JetUncertaintiesTool.h:214
CP::CorrectionCode::Error
@ Error
Some error happened during the object correction.
Definition: CorrectionCode.h:36
jet::LargeRTopologyUncertaintyComponent
Definition: LargeRTopologyUncertaintyComponent.h:15
efficiency
void efficiency(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
Definition: dependence.cxx:128
CaloCellPos2Ntuple.None
None
Definition: CaloCellPos2Ntuple.py:23
jet::CompParametrization::PtMassAbsEta
@ PtMassAbsEta
Definition: UncertaintyEnum.h:53
CombinedMassUncertaintyComponent.h
JetUncertaintiesTool::m_name_TagResult
std::string m_name_TagResult
Definition: JetUncertaintiesTool.h:197
jet::UncertaintyGroup::getScaleVars
virtual std::set< CompScaleVar::TypeEnum > getScaleVars() const
Definition: UncertaintyGroup.cxx:247
jet::CompParametrization::eLOGmOeEta
@ eLOGmOeEta
Definition: UncertaintyEnum.h:57
jet::ComponentHelper::caloMassTerm
TString caloMassTerm
Definition: ConfigHelper.h:48
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
JetUncertaintiesTool::m_combMassWeightTAMassDef
jet::CompMassDef::TypeEnum m_combMassWeightTAMassDef
Definition: JetUncertaintiesTool.h:223
JetUncertaintiesTool::getComponentScalesTau32WTA
virtual bool getComponentScalesTau32WTA(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1619
JESUNC_SAFE_DELETE
#define JESUNC_SAFE_DELETE(T)
Definition: Reconstruction/Jet/JetUncertainties/JetUncertainties/Helpers.h:25
JetUncertaintiesTool::updateTau21
StatusCode updateTau21(xAOD::Jet &jet, const double shift) const
Definition: JetUncertaintiesTool.cxx:2578
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
jet::CompScaleVar::C2Beta1
@ C2Beta1
Definition: UncertaintyEnum.h:106
jet::CompMassDef::getJetScaleString
TString getJetScaleString(const TypeEnum type)
Definition: UncertaintyEnum.cxx:225
JetUncertaintiesTool::updateTau32
StatusCode updateTau32(xAOD::Jet &jet, const double shift) const
Definition: JetUncertaintiesTool.cxx:2627
ParseInputs.gDirectory
gDirectory
Definition: Final2012/ParseInputs.py:133
PtLogPtMassForTagSFUncertaintyComponent.h
SystematicRegistry.h
JetUncertaintiesTool
Definition: JetUncertaintiesTool.h:44
JetUncertaintiesTool::m_recognizedSystematics
CP::SystematicSet m_recognizedSystematics
Definition: JetUncertaintiesTool.h:209
JetUncertaintiesTool::m_refMu
float m_refMu
Definition: JetUncertaintiesTool.h:203
JetUncertaintiesTool::m_combMassWeightCaloMassDef
jet::CompMassDef::TypeEnum m_combMassWeightCaloMassDef
Definition: JetUncertaintiesTool.h:222
JetUncertaintiesTool::readHistoFromParam
double readHistoFromParam(const xAOD::Jet &jet, const jet::UncertaintyHistogram &histo, const jet::CompParametrization::TypeEnum param, const jet::CompMassDef::TypeEnum massDef) const
Definition: JetUncertaintiesTool.cxx:1856
jet::CombMassComp::Calo
@ Calo
Definition: UncertaintyEnum.h:197
JetUncertaintiesTool::m_jetDef
std::string m_jetDef
Definition: JetUncertaintiesTool.h:185
xAOD::shallowCopyObject
std::pair< T *, ShallowAuxInfo * > shallowCopyObject(const T &obj)
Function making a shallow copy of a constant standalone object.
Definition: ShallowCopy.h:163
JetUncertaintiesTool::buildUncertaintyComponent
jet::UncertaintyComponent * buildUncertaintyComponent(const jet::ComponentHelper &component) const
Definition: JetUncertaintiesTool.cxx:934
jet::CompParametrization::eLOGmOe
@ eLOGmOe
Definition: UncertaintyEnum.h:56
jet::ComponentHelper::flavourType
FlavourComp::TypeEnum flavourType
Definition: ConfigHelper.h:69
jet::CombinedMassUncertaintyComponent::setTATerm
virtual StatusCode setTATerm(UncertaintyGroup *TAComp)
Definition: CombinedMassUncertaintyComponent.cxx:103
JetUncertaintiesTool::getNumComponents
virtual size_t getNumComponents() const
Definition: JetUncertaintiesTool.cxx:1464
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
jet::CompParametrization::includesMass
bool includesMass(const TypeEnum type)
Definition: UncertaintyEnum.cxx:156
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
python.subdetectors.mmg.names
names
Definition: mmg.py:8
ReweightUtils.category
category
Definition: ReweightUtils.py:15
jet::FlavourComp::PerJetResponse_Gluon
@ PerJetResponse_Gluon
Definition: UncertaintyEnum.h:183
jet::UncertaintyComponent::getName
virtual TString getName() const
Definition: UncertaintyComponent.h:35
jet::CombMassComp::Both
@ Both
Definition: UncertaintyEnum.h:199
jet::CombinedMassUncertaintyComponent::setTAWeights
virtual StatusCode setTAWeights(const UncertaintyHistogram *TAWeights)
Definition: CombinedMassUncertaintyComponent.cxx:137
JetUncertaintiesTool::updateTagScaleFactor
StatusCode updateTagScaleFactor(xAOD::Jet &jet, const double shift) const
Definition: JetUncertaintiesTool.cxx:2938
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
jet::ResolutionHelper::getNominalResolution
std::tuple< const UncertaintyHistogram *, CompParametrization::TypeEnum, CompMassDef::TypeEnum > getNominalResolution(const CompScaleVar::TypeEnum smearType, const JetTopology::TypeEnum topology, const bool readMC) const
Definition: Reconstruction/Jet/JetUncertainties/Root/ResolutionHelper.cxx:354
m_path
std::string m_path
the path being used
Definition: OutputStreamData.cxx:88
jet::CompScaleVar::TagEfficiency
@ TagEfficiency
Definition: UncertaintyEnum.h:109
JetUncertaintiesTool::addAffectingSystematic
virtual StatusCode addAffectingSystematic(const CP::SystematicVariation &systematic, bool recommended)
Definition: JetUncertaintiesTool.cxx:1295
PerJetFlavourUncertaintyComponent.h
jet::ComponentHelper::param
TString param
Definition: ConfigHelper.h:36
JetUncertaintiesTool::getFilteredSystematicSet
virtual StatusCode getFilteredSystematicSet(const CP::SystematicSet &systConfig, CP::SystematicSet &filteredSet)
Definition: JetUncertaintiesTool.cxx:1349
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
jet::CompScaleVar::FourVecRes
@ FourVecRes
Definition: UncertaintyEnum.h:116
jet::CompScaleVar::Qw
@ Qw
Definition: UncertaintyEnum.h:107
jet::ComponentHelper::LargeRJetTruthLabels
std::vector< LargeRJetTruthLabel::TypeEnum > LargeRJetTruthLabels
Definition: ConfigHelper.h:77
JetUncertaintiesTool::m_analysisFile
std::string m_analysisFile
Definition: JetUncertaintiesTool.h:190
JetUncertaintiesTool::appliedSystematics
virtual CP::SystematicSet appliedSystematics() const
Definition: JetUncertaintiesTool.cxx:1265
jet::ComponentHelper::TAMassTerm
TString TAMassTerm
Definition: ConfigHelper.h:49
jet::CompScaleVar::Mass
@ Mass
Definition: UncertaintyEnum.h:98
jet::CompScaleVar::D12
@ D12
Definition: UncertaintyEnum.h:99
jet::CompScaleVar::TagScaleFactor
@ TagScaleFactor
Definition: UncertaintyEnum.h:108
CP::SystematicSet::getBaseNames
std::set< std::string > getBaseNames() const
description: get the set of base systematic names from this set
Definition: SystematicSet.cxx:159
index.currentDir
currentDir
Definition: index.py:37
jet::JetFourMomAccessor
JetFourMomAccessor is an extension of JetAttributeAccessor::AccessorWrapper<xAOD::JetFourMom_t> Acces...
Definition: JetCalibTools_PlotJESFactors.cxx:32
jet::PtMassEtaUncertaintyComponent
Definition: PtMassEtaUncertaintyComponent.h:14
JetUncertaintiesTool::getComponentDesc
virtual std::string getComponentDesc(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1511
jet::ResolutionHelper::initialize
virtual StatusCode initialize(TEnv &settings, TFile *histFile, const TString &MCtype)
Definition: Reconstruction/Jet/JetUncertainties/Root/ResolutionHelper.cxx:199
PtMassUncertaintyComponent.h
jet::GroupHelper::groupNum
int groupNum
Definition: ConfigHelper.h:96
jet::CompScaleVar::PtResAbs
@ PtResAbs
Definition: UncertaintyEnum.h:115
jet::CompScaleVar::PtRes
@ PtRes
Definition: UncertaintyEnum.h:114
JetUncertaintiesTool::getComponentScalesD12
virtual bool getComponentScalesD12(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1594
jet::CompParametrization::PtAbsMassEta
@ PtAbsMassEta
Definition: UncertaintyEnum.h:54
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
DeMoUpdate.toAdd
bool toAdd
Definition: DeMoUpdate.py:1304
PtAbsMassEtaUncertaintyComponent.h
jet::ComponentHelper::name
TString name
Definition: ConfigHelper.h:34
jet::ResolutionHelper::hasRelevantInfo
bool hasRelevantInfo(const CompScaleVar::TypeEnum type, const JetTopology::TypeEnum topology) const
Definition: Reconstruction/Jet/JetUncertainties/Root/ResolutionHelper.cxx:490
JetUncertaintiesTool::getComponentScalesQw
virtual bool getComponentScalesQw(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1634
jet::JetTopology::MIXED
@ MIXED
Definition: UncertaintyEnum.h:214
JetUncertaintiesTool::m_accTagResult
SG::AuxElement::Accessor< bool > m_accTagResult
Definition: JetUncertaintiesTool.h:273
JetUncertaintiesTool::getDefaultEventInfo
const xAOD::EventInfo * getDefaultEventInfo() const
Definition: JetUncertaintiesTool.cxx:2315
JetUncertaintiesTool::getComponentScalesC2Beta1
virtual bool getComponentScalesC2Beta1(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1629
jet::CompParametrization::PtAbsMass
@ PtAbsMass
Definition: UncertaintyEnum.h:50
merge.output
output
Definition: merge.py:17
jet::ResolutionHelper
Definition: Reconstruction/Jet/JetUncertainties/JetUncertainties/ResolutionHelper.h:22
jet::CompParametrization::PtEta
@ PtEta
Definition: UncertaintyEnum.h:48
xAOD::JetFourMom_t
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
Definition: JetTypes.h:17
ClosebyUncertaintyComponent.h
jet::FlavourComp::PerJetResponse
@ PerJetResponse
Definition: UncertaintyEnum.h:182
JetUncertaintiesTool::getComponentScalesD23
virtual bool getComponentScalesD23(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1599
JetUncertaintiesTool::m_mcType
std::string m_mcType
Definition: JetUncertaintiesTool.h:186
JetUncertaintiesTool::getComponentIsReducible
virtual bool getComponentIsReducible(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1541
JetUncertaintiesTool::~JetUncertaintiesTool
virtual ~JetUncertaintiesTool()
Definition: JetUncertaintiesTool.cxx:184
python.EventInfoMgtInit.release
release
Definition: EventInfoMgtInit.py:24
JetUncertaintiesTool::m_currentUncSet
jet::UncertaintySet * m_currentUncSet
Definition: JetUncertaintiesTool.h:212
CP::SystematicSet::insert
void insert(const SystematicVariation &systematic)
description: insert a systematic into the set
Definition: SystematicSet.cxx:88
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
JetUncertaintiesTool::m_release
std::string m_release
Definition: JetUncertaintiesTool.h:184
jet::CompParametrization::TypeEnum
TypeEnum
Definition: UncertaintyEnum.h:45
jet::UncertaintyGroup
Definition: UncertaintyGroup.h:28
jet::ConfigHelper
Definition: ConfigHelper.h:106
JetUncertaintiesTool::m_rand
TRandom3 m_rand
Definition: JetUncertaintiesTool.h:228
jet::PtAbsMassEtaUncertaintyComponent
Definition: PtAbsMassEtaUncertaintyComponent.h:14
JetUncertaintiesTool::m_name_EffSF
std::string m_name_EffSF
Definition: JetUncertaintiesTool.h:194
jet::PtEtaUncertaintyComponent
Definition: PtEtaUncertaintyComponent.h:14
jet::ComponentHelper::isSpecial
bool isSpecial
Definition: ConfigHelper.h:67
JetUncertaintiesTool::m_name_SigeffSF
std::string m_name_SigeffSF
Definition: JetUncertaintiesTool.h:195
jet::CombinedMassUncertaintyComponent::setCaloTerm
virtual StatusCode setCaloTerm(UncertaintyGroup *caloComp)
Definition: CombinedMassUncertaintyComponent.cxx:86
JetUncertaintiesTool::m_combMassParam
jet::CompParametrization::TypeEnum m_combMassParam
Definition: JetUncertaintiesTool.h:224
JetUncertaintiesTool::JetUncertaintiesTool
JetUncertaintiesTool(const std::string &name="JetUncertaintiesTool")
Definition: JetUncertaintiesTool.cxx:65
JetUncertaintiesTool::recommendedSystematics
virtual CP::SystematicSet recommendedSystematics() const
the list of all systematics this tool recommends to use
Definition: JetUncertaintiesTool.cxx:1260
JetUncertaintiesTool::updateSplittingScale23
StatusCode updateSplittingScale23(xAOD::Jet &jet, const double shift) const
Definition: JetUncertaintiesTool.cxx:2562
jet::UncertaintyGroup::isAlwaysZero
virtual bool isAlwaysZero() const
Definition: UncertaintyGroup.cxx:329
JetUncertaintiesTool::m_name_Efficiency
std::string m_name_Efficiency
Definition: JetUncertaintiesTool.h:196
JetUncertaintiesTool::m_resHelper
jet::ResolutionHelper * m_resHelper
Definition: JetUncertaintiesTool.h:230
jet::UncertaintyHistogram
Definition: UncertaintyHistogram.h:25
JetUncertaintiesTool::applySystematicVariation
virtual StatusCode applySystematicVariation(const CP::SystematicSet &systConfig)
effects: configure this tool for the given list of systematic variations.
Definition: JetUncertaintiesTool.cxx:1312
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
jet::ValidityHistogram::getValidity
bool getValidity(const xAOD::Jet &jet) const
Definition: ValidityHistogram.cxx:431
JetUncertaintiesTool::getComponentIndex
virtual size_t getComponentIndex(const std::string &name) const
Definition: JetUncertaintiesTool.cxx:1475
JetUncertaintiesTool::setScaleToMeV
virtual StatusCode setScaleToMeV()
Definition: JetUncertaintiesTool.cxx:210
jet::UncertaintySet::getScaleVars
virtual std::vector< CompScaleVar::TypeEnum > getScaleVars() const
Definition: UncertaintySet.cxx:190
JetUncertaintiesTool::applyContainerCorrection
virtual CP::CorrectionCode applyContainerCorrection(xAOD::JetContainer &inputs) const
Definition: JetUncertaintiesTool.cxx:2294
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
jet::CompParametrization::PtMass
@ PtMass
Definition: UncertaintyEnum.h:51
jet::CompScaleVar::TypeEnum
TypeEnum
Definition: UncertaintyEnum.h:91
JetUncertaintiesTool::getComponentName
virtual std::string getComponentName(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1496
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
CP::CorrectionCode::Ok
@ Ok
The correction was done successfully.
Definition: CorrectionCode.h:38
UncertaintySet.h
mergePhysValFiles.categories
list categories
Definition: PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/mergePhysValFiles.py:18
jet::utils::findFilePath
TString findFilePath(const TString &fileName, const TString &path="", const TString &calibArea="")
Definition: Reconstruction/Jet/JetUncertainties/Root/Helpers.cxx:99
JetUncertaintiesTool::m_path
std::string m_path
Definition: JetUncertaintiesTool.h:189
jet::CompScaleVar::Tau21WTA
@ Tau21WTA
Definition: UncertaintyEnum.h:103
VertexContainer.h
Prompt::Def::Pt
@ Pt
Definition: VarHolder.h:76
JetUncertaintiesTool::getComponentScalesMultiple
virtual bool getComponentScalesMultiple(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1644
CaloLCW_tf.group
group
Definition: CaloLCW_tf.py:28
jet::UncertaintySet::getName
virtual std::string getName() const
Definition: UncertaintySet.cxx:72
jet::CompCategory::TypeEnum
TypeEnum
Definition: UncertaintyEnum.h:16
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
CP::SystematicRegistry
This module implements the central registry for handling systematic uncertainties with CP tools.
Definition: SystematicRegistry.h:25
JetUncertaintiesTool::getComponentCategory
virtual std::string getComponentCategory(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1526
CP::CorrectionCode
Return value from object correction CP tools.
Definition: CorrectionCode.h:31
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
jet::UncertaintySet
Definition: UncertaintySet.h:25
JetUncertaintiesTool::getRefMu
virtual float getRefMu() const
Definition: JetUncertaintiesTool.cxx:1413
JetUncertaintiesTool::m_systFilterMap
std::unordered_map< CP::SystematicSet, CP::SystematicSet > m_systFilterMap
Definition: JetUncertaintiesTool.h:213
jet::CompScaleVar::Tau32
@ Tau32
Definition: UncertaintyEnum.h:102
jet::PtAbsMassUncertaintyComponent
Definition: PtAbsMassUncertaintyComponent.h:14
jet::CompScaleVar::Tau32WTA
@ Tau32WTA
Definition: UncertaintyEnum.h:104
jet::CompParametrization::PtMassEta
@ PtMassEta
Definition: UncertaintyEnum.h:52
JetUncertaintiesTool::updateQw
StatusCode updateQw(xAOD::Jet &jet, const double shift) const
Definition: JetUncertaintiesTool.cxx:2922
JetUncertaintiesTool::getNormalizedTAMassWeight
virtual double getNormalizedTAMassWeight(const xAOD::Jet &jet) const
Definition: JetUncertaintiesTool.cxx:1943
jet::FlavourComp::PerJetResponse_LQ
@ PerJetResponse_LQ
Definition: UncertaintyEnum.h:184
ParticleDataType::Full
@ Full
Definition: Event/EventKernel/EventKernel/IParticle.h:36
JetUncertaintiesTool::getComponentScalesPt
virtual bool getComponentScalesPt(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1584
jet::CompParametrization::eLOGmOeAbsEta
@ eLOGmOeAbsEta
Definition: UncertaintyEnum.h:58
SG::ConstAccessor< T, AuxAllocator_t< T > >::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
JetUncertaintiesTool::updateTagEfficiency
StatusCode updateTagEfficiency(xAOD::Jet &jet, const double shift) const
Definition: JetUncertaintiesTool.cxx:2998
jet::ComponentHelper::parametrization
CompParametrization::TypeEnum parametrization
Definition: ConfigHelper.h:63
JetUncertaintiesTool::getComponentsInCategory
virtual std::vector< size_t > getComponentsInCategory(const std::string &category) const
Definition: JetUncertaintiesTool.cxx:1993
checkxAOD.categoryStrings
categoryStrings
Definition: Tools/PyUtils/bin/checkxAOD.py:47
JetUncertaintiesTool::m_accEffSF
SG::AuxElement::Accessor< float > m_accEffSF
Definition: JetUncertaintiesTool.h:270
UncertaintyComponent.h
jet::PtLogPtMassForTagSFUncertaintyComponent
Definition: PtLogPtMassForTagSFUncertaintyComponent.h:15
ValidityHistogram.h
jet::CombinedMassUncertaintyComponent
Definition: CombinedMassUncertaintyComponent.h:18
JetUncertaintiesTool::updateD2Beta1
StatusCode updateD2Beta1(xAOD::Jet &jet, const double shift) const
Definition: JetUncertaintiesTool.cxx:2829
calibdata.copy
bool copy
Definition: calibdata.py:27
JetUncertaintiesTool::getSmearingFactor
double getSmearingFactor(const xAOD::Jet &jet, const jet::CompScaleVar::TypeEnum smearType, const double variation) const
Definition: JetUncertaintiesTool.cxx:2380
jet::CompScaleVar::Tau21
@ Tau21
Definition: UncertaintyEnum.h:101
jet::CompScaleVar::MassResAbs
@ MassResAbs
Definition: UncertaintyEnum.h:113
JetUncertaintiesTool::getEtaCorrelationMatrix
virtual TH2D * getEtaCorrelationMatrix(const int numBins, const double minEta, const double maxEta, const double valPt)
Definition: JetUncertaintiesTool.cxx:2061
jet::JetTopology::TypeEnum
TypeEnum
Definition: UncertaintyEnum.h:208
JetUncertaintiesTool::m_groups
std::vector< jet::UncertaintyGroup * > m_groups
Definition: JetUncertaintiesTool.h:206
JetUncertaintiesTool::m_accTagScaleFactor
SG::AuxElement::Accessor< float > m_accTagScaleFactor
Definition: JetUncertaintiesTool.h:269
JetUncertaintiesTool::getSqrtS
virtual float getSqrtS() const
Definition: JetUncertaintiesTool.cxx:1399
jet::ELogMassEtaUncertaintyComponent
Definition: ELogMassEtaUncertaintyComponent.h:14
ResolutionHelper.h
plotBeamSpotCompare.histo
histo
Definition: plotBeamSpotCompare.py:415
JetUncertaintiesTool::isAffectedBySystematic
virtual bool isAffectedBySystematic(const CP::SystematicVariation &systematic) const
Declare the interface that this class provides.
Definition: JetUncertaintiesTool.cxx:1247
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
JetUncertaintiesTool::m_namePrefix
const std::string m_namePrefix
Definition: JetUncertaintiesTool.h:233
jet::ResolutionHelper::smearOnlyMC
bool smearOnlyMC() const
Definition: Reconstruction/Jet/JetUncertainties/JetUncertainties/ResolutionHelper.h:32
jet::ComponentHelper::pileupType
PileupComp::TypeEnum pileupType
Definition: ConfigHelper.h:68
JetUncertaintiesTool::m_accEfficiency
SG::AuxElement::Accessor< float > m_accEfficiency
Definition: JetUncertaintiesTool.h:272
asg::AsgTool::initialize
virtual StatusCode initialize()
Dummy implementation of the initialisation function.
Definition: AsgTool.h:133
JetUncertaintiesTool::getUncertaintySet
virtual StatusCode getUncertaintySet(const CP::SystematicSet &filteredSet, jet::UncertaintySet *&uncSet)
Definition: JetUncertaintiesTool.cxx:1366
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
JetUncertaintiesTool::getName
virtual std::string getName() const
Definition: JetUncertaintiesTool.h:66
JetUncertaintiesTool::getComponentScalesTau21
virtual bool getComponentScalesTau21(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1604
xAOD::Jet
Jet_v1 Jet
Definition of the current "jet version".
Definition: Event/xAOD/xAODJet/xAODJet/Jet.h:17
jet::ComponentHelper::subComps
std::vector< TString > subComps
Definition: ConfigHelper.h:73
SystematicVariation.h
JetUncertaintiesTool::m_currentSystSet
CP::SystematicSet m_currentSystSet
Definition: JetUncertaintiesTool.h:211
jet::UncertaintySet::getValidUncertaintySet
virtual std::vector< std::pair< CompScaleVar::TypeEnum, bool > > getValidUncertaintySet(std::vector< std::pair< CompScaleVar::TypeEnum, double > > &unc, const xAOD::Jet &jet, const xAOD::EventInfo &eInfo) const
Definition: UncertaintySet.cxx:246
PtEtaUncertaintyComponent.h
jet::FlavourUncertaintyComponent
Definition: FlavourUncertaintyComponent.h:14
JetUncertaintiesTool::getPtCorrelationMatrix
virtual TH2D * getPtCorrelationMatrix(const int numBins, const double minPt, const double maxPt, const double valEta)
Definition: JetUncertaintiesTool.cxx:2041
JetUncertaintiesTool::updateSplittingScale12
StatusCode updateSplittingScale12(xAOD::Jet &jet, const double shift) const
Definition: JetUncertaintiesTool.cxx:2546
CP::SystematicSet::filterForAffectingSystematics
static StatusCode filterForAffectingSystematics(const SystematicSet &systConfig, const SystematicSet &affectingSystematics, SystematicSet &filteredSystematics)
description: filter the systematics for the affected systematics returns: success guarantee: strong f...
Definition: SystematicSet.cxx:213
JetUncertaintiesTool::getComponentScaleVars
virtual std::set< jet::CompScaleVar::TypeEnum > getComponentScaleVars(const size_t index) const
Definition: JetUncertaintiesTool.cxx:1649
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
jet::CombMassComp::TA
@ TA
Definition: UncertaintyEnum.h:198
JetUncertaintiesTool::updateTau21WTA
StatusCode updateTau21WTA(xAOD::Jet &jet, const double shift) const
Definition: JetUncertaintiesTool.cxx:2676
CP::SystematicRegistry::getInstance
static SystematicRegistry & getInstance()
Get the singleton instance of the registry for the curren thread.
Definition: SystematicRegistry.cxx:25
JetUncertaintiesTool::m_name_TagScaleFactor
std::string m_name_TagScaleFactor
Definition: JetUncertaintiesTool.h:193
JetUncertaintiesTool.h
JetUncertaintiesTool::m_isData
bool m_isData
Definition: JetUncertaintiesTool.h:229
ConfigHelper.h
ELogMassUncertaintyComponent.h
jet::ComponentHelper::combMassType
CombMassComp::TypeEnum combMassType
Definition: ConfigHelper.h:70
JetUncertaintiesTool::updateTau32WTA
StatusCode updateTau32WTA(xAOD::Jet &jet, const double shift) const
Definition: JetUncertaintiesTool.cxx:2740