ATLAS Offline Software
Loading...
Searching...
No Matches
FFJetSmearingTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5/*************************************************************************************\
6 * *
7 * Name: FFJetSmearingTool *
8 * Purpose: Perform a jet mass smearing using Forward Folding. *
9 * This tool allows the user to stimate the JMS & JMR *
10 * systematics uncertainities. *
11 * *
12 * Note: normally used for JMR uncertainties since the *
13 * JMS is done using the JetUncertainties tool. *
14 * *
15\*************************************************************************************/
16
22
23// Local includes
25
26// Other includes
28
29namespace CP {
30
31
32 // Constructor
34 : asg::AsgTool(name)
35 , m_isInit(false)
36 , m_release("")
37 , m_truth_jetColl("")
38 , m_EtaRange(0)
39 , m_calibArea("CalibArea-08")
40 , m_histFileName("")
41 {
42 declareProperty("MassDef",m_MassDef_string = "");
43 declareProperty("MCType",m_MCType_string = "");
44 declareProperty("ConfigFile",m_configFile = ""); // Path to the config file, by default it points to XXX
45 declareProperty("Path",m_path);
46 }
47
48
49 // Destructor
51
52
53 // Initialize
55 // Ensure it hasn't been initialized already
56 if (m_isInit){
57 ATH_MSG_FATAL(Form("Blocking re-initialization of tool named %s",AsgTool::name().c_str())); //AsgTool::name() calls the name
58 return StatusCode::FAILURE;
59 }
60
61 ATH_MSG_INFO(Form("Preparing to initialize the FFJetSmearingTool named %s",AsgTool::name().c_str()));
62
63 if (AsgTool::name().empty()){
64 ATH_MSG_FATAL("No name specified. Aborting.");
65 return StatusCode::FAILURE;
66 }
67
68 if (m_MassDef_string.empty()){
69 ATH_MSG_FATAL("No jet mass type specified. Aborting.");
70 return StatusCode::FAILURE;
71 }
72
73 if (m_MCType_string.empty()){
74 ATH_MSG_FATAL("No MC campaign specified. Aborting.");
75 return StatusCode::FAILURE;
76 }
77
78 // Make sure we have a valid mass definition
79 ATH_CHECK(JetTools::stringToEnum(m_MassDef_string, m_MassDef)); //If it fails it means that there is No Systematic Uncertainties derived for to the given mass definition.
80 //The mass definition should be 'Calo', 'TA' or 'Comb'. Show an error and exits.
81
82 //reading the config file as in JetUncertaintiesTool
83 TEnv settings;
84
85 const TString configFilePath = jet::utils::findFilePath(m_configFile.c_str(),m_path.c_str(),m_calibArea.c_str());
86
87 if (settings.ReadFile( configFilePath.Data(),kEnvGlobal)){
88 ATH_MSG_ERROR("Cannot read config file: " << configFilePath.Data());
89 return StatusCode::FAILURE;
90 }
91 // We can read it - start printing
92 ATH_MSG_INFO("================================================");
93 ATH_MSG_INFO(Form(" Initializing the FFJetSmearingTool named %s",AsgTool::name().c_str()));
94 ATH_MSG_INFO(" Configuration file: " << m_configFile);
95 ATH_MSG_INFO(" Location: " << configFilePath.Data());
96
97 m_release = settings.GetValue("UncertaintyRelease","UNKNOWN");
98 ATH_MSG_INFO(" Uncertainty release: " << m_release.c_str());
99
100 // Check the jet definition
101 m_truth_jetColl = settings.GetValue("TruthJetColl","");
102 if (m_truth_jetColl.empty()){
103 ATH_MSG_ERROR("Cannot find the truth jet collection to use in config");
104 return StatusCode::FAILURE;
105 }
106 ATH_MSG_INFO(" Truth Jet Collection: " << m_truth_jetColl);
107
108 // Check the name of the truth label accessor for BoostjetTaggers
109 m_truthlabelaccessor = settings.GetValue("TruthLabelAccessor","");
110 if (m_truthlabelaccessor.empty()){
111 ATH_MSG_ERROR("Cannot find the TruthLabelAccessor to use in config");
112 return StatusCode::FAILURE;
113 }
114 ATH_MSG_INFO(" Truth Label Accessor: " << m_truthlabelaccessor);
115
116 // Check the MC campaign
117 m_supportedmctypes = settings.GetValue("SupportedMCTypes","");
118 if (m_supportedmctypes.empty()){
119 ATH_MSG_ERROR("Cannot find the SupportedMCTypes to use in config");
120 return StatusCode::FAILURE;
121 }
122 ATH_MSG_INFO(" Supported MC types: " << m_supportedmctypes);
123 // Protection for the MCType
124 if (m_supportedmctypes.find(m_MCType_string)!=std::string::npos){
125 ATH_MSG_INFO(" You are running with MC type: " << m_MCType_string);
126 }else{
127 ATH_MSG_ERROR("You are not running with a supported MC type");
128 return StatusCode::FAILURE;
129 }
130
131 // Eta range of the tool
132 m_EtaRange = settings.GetValue("EtaRange",0);
133 if (m_EtaRange == 0){
134 ATH_MSG_ERROR("Cannot find the EtaRange parameter in the config file");
135 return StatusCode::FAILURE;
136 }
137 ATH_MSG_INFO(" EtaRange : Abs(eta) < " << m_EtaRange);
138
139 // Mass range of the tool
140 m_MaxMass = settings.GetValue("MaxMass",0);
141 if (m_MaxMass == 0){
142 ATH_MSG_ERROR("Cannot find the MaxMass parameter in the config file");
143 return StatusCode::FAILURE;
144 }
145 ATH_MSG_INFO(" MaxMass : jet_mass < " << m_MaxMass);
146
147 // Pt range of the tool
148 m_MaxPt = settings.GetValue("MaxPt",0);
149 if (m_MaxPt == 0){
150 ATH_MSG_ERROR("Cannot find the MaxPt parameter in the config file");
151 return StatusCode::FAILURE;
152 }
153 ATH_MSG_INFO(" MaxPt : jet_pt < " << m_MaxPt);
154
155 // Get the file to read uncertainties in from
156 m_histFileName = settings.GetValue("UncertaintyRootFile","");
158 if (m_histFileName.empty()){
159 ATH_MSG_ERROR("Cannot find uncertainty histogram file in the config file");
160 return StatusCode::FAILURE;
161 }
162 ATH_MSG_INFO(" UncertaintyFile: " << m_histFileName);
163 ATH_MSG_INFO(" Location: " << m_HistogramsFilePath);
164
165 // Read all the histogram files where the jms jmr variations are saved
166 // If fail, it shows an Error message and exits
168
169 // Add the affecting systematics to the global registry
171 if (registry.registerSystematics(*this) != StatusCode::SUCCESS){
172 ATH_MSG_ERROR("Unable to register systematics!");
173 return StatusCode::FAILURE;
174 }
175
176 m_isInit = true;
177
178 // ANA_CHECK (applySystematicVariation (CP::SystematicSet()));
179
180 return StatusCode::SUCCESS;
181 }
182
183
184 //-----------------------------------------------------------------------------
185 // Declare affecting systematics
186 //-----------------------------------------------------------------------------
187
189 // Using 'find' is sufficient until this tool supports continuous
190 // // variations, at which point I'll need to use the 'match' method.
192 return sys.find(systematic) != sys.end();
193 }
194
195 //-----------------------------------------------------------------------------
196
203
204 //-----------------------------------------------------------------------------
205
207 CP::SystematicSet filteredSysts;
208
209 // Take only Calo-like uncertainties
211 for (auto ci = m_SysList.begin(); ci != m_SysList.end(); ci++){
212 if ((*ci).basename().find("CALO_")!=std::string::npos){
213 filteredSysts.insert(*ci);
214 }
215 }
216 return filteredSysts;
217 }
218
219 // Take only TA-like uncertainties
221 for (auto ci = m_SysList.begin(); ci != m_SysList.end(); ci++){
222 if ((*ci).basename().find("TA_") !=std::string::npos){
223 filteredSysts.insert(*ci);
224 }
225 }
226 return filteredSysts;
227 }
228
229 // Take only Comb-like uncertainties
231 for (auto ci = m_SysList.begin(); ci != m_SysList.end(); ci++){
232 if ((*ci).basename().find("COMB_")!=std::string::npos){
233 filteredSysts.insert(*ci);
234 }
235 }
236 return filteredSysts;
237 }
238
239 // Take only UFO-like uncertainties
241 for (auto ci = m_SysList.begin(); ci != m_SysList.end(); ci++){
242 if ((*ci).basename().find("JET_JMRUnc_")!=std::string::npos){
243 filteredSysts.insert(*ci);
244 }
245 }
246 return filteredSysts;
247 }
248
249 return m_SysList;
250 }
251
252
253 //-----------------------------------------------------------------------------
254 // Apply systematic configuration
255 //-----------------------------------------------------------------------------
256
258 // First check if we already know this systematic configuration.
259 // Look for it in our sysData map.
260 auto iter = m_sysData.find (systematics);
261
262 // If this is a new input set, we need to filter it.
263 if (iter == m_sysData.end()){
264 // Filter the input systematics with my affecting systematics.
265 const CP::SystematicSet affectingSysts = affectingSystematics();
266 CP::SystematicSet filteredSysts;
267 if ( CP::SystematicSet::
268 filterForAffectingSystematics(systematics, affectingSysts, filteredSysts) != StatusCode::SUCCESS ){
269 ATH_MSG_ERROR("Received unsupported systematics: " << systematics.name());
270 return StatusCode::FAILURE;
271 }
272
273 // At this point, we can do some additional checks for consistency
274 // with the JMS/JMR functionality. For example, if the tool can only handle
275 // one type of systematic at a time, we return an error if the filtered
276 // set has more than one item:
277 if (filteredSysts.size() > 1){
278 ATH_MSG_ERROR("No support for more than one JMS/JMR sys at a time: " << filteredSysts.name());
279 return StatusCode::FAILURE;
280 }
281 if (filteredSysts.size() == 0) {
282 ATH_MSG_VERBOSE("Found zero systematics!");
283 return StatusCode::SUCCESS;
284 }
285
286 // Insert the new systematic data onto our map
287 SysData myData;
288
289 const CP::SystematicVariation& sys = *filteredSysts.begin();
290
291 myData.SysParameter = sys.parameter(); //Up (+1) and Down (-1) systematic variation
292 myData.SysBaseName = sys.basename(); //Name of the systematic variation
293
294 iter = m_sysData.emplace (systematics, myData).first;
295 }
296
297 // Apply the filtered systematics
298 m_currentSysData = &iter->second;
299
300 return StatusCode::SUCCESS;
301 }
302
303
304 //-----------------------------------------------------------------------------
305 // Read the external file that conatins the JSS recomendations for FatJets
306 //-----------------------------------------------------------------------------
307
309 std::unique_ptr<TFile> data_file ( TFile::Open(m_HistogramsFilePath.c_str()));
310 if (!data_file || data_file->IsZombie()){
311 ATH_MSG_FATAL( "Could not open the first input file: " << m_HistogramsFilePath );
312 return StatusCode::FAILURE;
313 }
314
315 // Check whether we need the ResponseMap or not
316 m_doGaussianSmearing = settings.GetValue("doGaussianSmearing",true);
317 ATH_MSG_INFO(" doGaussianSmearing: " << m_doGaussianSmearing);
318
320 TString CaloResponseMap_path = settings.GetValue("CaloResponseMap","");
321
322 if (CaloResponseMap_path.IsNull()){
323 ATH_MSG_ERROR("Cannot find the CaloResponseMap in the config file");
324 return StatusCode::FAILURE;
325 }
326
327 m_CALO_ResponseMap = std::unique_ptr<TH2>(static_cast<TH2*>(data_file->Get( CaloResponseMap_path )));
328 m_CALO_ResponseMap->SetDirectory(nullptr);
329
330 ATH_MSG_INFO(" ResponseMap: " << CaloResponseMap_path);
331 }
332
334 TString TAResponseMap_path = settings.GetValue("TAResponseMap","");
335
336 if (TAResponseMap_path.IsNull()){
337 ATH_MSG_ERROR("Cannot find the TAResponseMap in the config file");
338 return StatusCode::FAILURE;
339 }
340
341 m_TA_ResponseMap = std::unique_ptr<TH2>(static_cast<TH2*>(data_file->Get( TAResponseMap_path )));
342 m_TA_ResponseMap->SetDirectory(nullptr);//To keep it open when we close the .root file
343
344 ATH_MSG_INFO(" ResponseMap: " << TAResponseMap_path);
345 }
346
348 TString UFOResponseMap_path = settings.GetValue("UFOResponseMap","");
349
350 if (UFOResponseMap_path.IsNull()){
351 ATH_MSG_ERROR("Cannot find the UFOResponseMap in the config file");
352 return StatusCode::FAILURE;
353 }
354
355 m_UFO_ResponseMap = std::unique_ptr<TH2>(dynamic_cast<TH2*>(data_file->Get( UFOResponseMap_path )));
356 m_UFO_ResponseMap->SetDirectory(nullptr);
357
358 ATH_MSG_INFO(" ResponseMap: " << UFOResponseMap_path);
359 }
360
361 // JMS systematics
362 for (size_t iComp = 0; iComp < 999; ++iComp){
363
364 const TString prefix = Form("JMSComponent.%zu.",iComp);
365 std::string Syst_Name = settings.GetValue(prefix+"Name","");
366
367 if (!Syst_Name.empty()){
368
369 m_SysList.insert( CP::SystematicVariation(Syst_Name, 1) );
370 m_SysList.insert( CP::SystematicVariation(Syst_Name, -1) );
371 m_Syst_MassDefAffected_map[Syst_Name] = settings.GetValue(prefix+"MassDef","");
372 m_Syst_TopologyAffected_map[Syst_Name] = settings.GetValue(prefix+"Topology","");
373 m_Syst_Affects_JMSorJMR[Syst_Name] = "JMS";
374 m_Syst_HistPath_map[Syst_Name] = settings.GetValue(prefix+"Hist","");
375
376 // Processing the input histogram name
377 m_Syst_Hist_map[Syst_Name] = std::unique_ptr<TH2>(dynamic_cast<TH2*>(data_file->Get(m_Syst_HistPath_map[Syst_Name].c_str())));
378 m_Syst_Hist_map[Syst_Name]->SetDirectory(nullptr);
379
380 // For Comb mass we need to read two histograms
382 m_Syst_HistTAPath_map[Syst_Name] = settings.GetValue(prefix+"HistTA","");
383 if (!m_Syst_HistTAPath_map[Syst_Name].empty()){
384 m_Syst_HistTA_map[Syst_Name] = std::unique_ptr<TH2>(dynamic_cast<TH2*>(data_file->Get(m_Syst_HistTAPath_map[Syst_Name].c_str())));
385 m_Syst_HistTA_map[Syst_Name]->SetDirectory(nullptr);
386 }
387 }
388
389 }
390 }
391
392 // JMR Systematics
393 for (size_t iComp = 0; iComp < 999; ++iComp){
394
395 const TString prefix = Form("JMRComponent.%zu.",iComp);
396 std::string Syst_Name = settings.GetValue(prefix+"Name","");
397
398 std::string to_find = "MCTYPE";
399 std::string to_replace = m_MCType_string;
400 replaceAllOccurrences(Syst_Name, to_find, to_replace);
401
402 if (!Syst_Name.empty()){
403
404 m_SysList.insert( CP::SystematicVariation(Syst_Name, 1) );
405 m_SysList.insert( CP::SystematicVariation(Syst_Name, -1) );
406 m_Syst_MassDefAffected_map[Syst_Name] = settings.GetValue(prefix+"MassDef","");
407 m_Syst_TopologyAffected_map[Syst_Name] = settings.GetValue(prefix+"Topology","");
408 m_Syst_Affects_JMSorJMR[Syst_Name] = "JMR";
409 m_Syst_HistPath_map[Syst_Name] = settings.GetValue(prefix+"Hist","");
410 m_Syst_uncertparam[Syst_Name] = settings.GetValue(prefix+"Param","");
411
412 replaceAllOccurrences(m_Syst_HistPath_map[Syst_Name], to_find, to_replace);
413
414 // Processing the input histogram name
415 if (m_Syst_uncertparam[Syst_Name] == "PtAbsMass"){
416 m_Syst_Hist_map[Syst_Name] = std::unique_ptr<TH2>(dynamic_cast<TH2*>(data_file->Get(m_Syst_HistPath_map[Syst_Name].c_str())));
417 m_Syst_Hist_map[Syst_Name]->SetDirectory(nullptr);
418 }else if (m_Syst_uncertparam[Syst_Name] == "eLOGmOeAbsEta"){
419 m_Syst_Hist_map3d[Syst_Name] = std::unique_ptr<TH3F>(dynamic_cast<TH3F*>(data_file->Get(m_Syst_HistPath_map[Syst_Name].c_str())));
420 m_Syst_Hist_map3d[Syst_Name]->SetDirectory(nullptr);
421 }
422
423 // For Comb mass we need to read two histograms
425 m_Syst_HistTAPath_map[Syst_Name] = settings.GetValue(prefix+"HistTA","");
426 if (!m_Syst_HistTAPath_map[Syst_Name].empty()){
427 if (m_Syst_uncertparam[Syst_Name] == "PtAbsMass"){
428 m_Syst_HistTA_map[Syst_Name] = std::unique_ptr<TH2>(dynamic_cast<TH2*>(data_file->Get(m_Syst_HistTAPath_map[Syst_Name].c_str())));
429 m_Syst_HistTA_map[Syst_Name]->SetDirectory(nullptr);
430 }else if (m_Syst_uncertparam[Syst_Name] == "eLOGmOeAbsEta"){
431 m_Syst_HistTA_map3d[Syst_Name] = std::unique_ptr<TH3F>(dynamic_cast<TH3F*>(data_file->Get(m_Syst_HistTAPath_map[Syst_Name].c_str())));
432 m_Syst_HistTA_map3d[Syst_Name]->SetDirectory(nullptr);
433 }
434 }
435 }
436
437 }
438 }
439
440 data_file->Close();
441
442 // Skip for UFO -> Read the Calo and TA mass weight histograms from the same file that JetUncertainties uses
444
445 TString Calo_TA_weight_file_name = settings.GetValue("JetUncertainties_UncertaintyRootFile","");
446 const TString Calo_TA_weight_file_path = jet::utils::findFilePath(Calo_TA_weight_file_name.Data(),m_path.c_str(),m_calibArea.c_str());
447
448 if (Calo_TA_weight_file_path.IsNull()){
449 ATH_MSG_ERROR("Cannot find the file with the Calo and TA weights");
450 return StatusCode::FAILURE;
451 }
452
453 TString Calo_weight_hist_name = settings.GetValue("CombMassWeightCaloHist","");
454 if (Calo_weight_hist_name.IsNull()){
455 ATH_MSG_ERROR("Cannot find the histogram name that contains the Calo weights in the config file");
456 return StatusCode::FAILURE;
457 }
458
459 TString TA_weight_hist_name = settings.GetValue("CombMassWeightTAHist","");
460 if (TA_weight_hist_name.IsNull()){
461 ATH_MSG_ERROR("Cannot find the histogram name that contains the TA weights in the config file");
462 return StatusCode::FAILURE;
463 }
464
465 ATH_MSG_INFO(Form(" Calo weights hist: \"%s\"",Calo_weight_hist_name.Data()));
466 ATH_MSG_INFO(Form(" TA weights hist: \"%s\"",TA_weight_hist_name.Data()));
467 ATH_MSG_INFO(Form(" Location: %s",Calo_TA_weight_file_path.Data()));
468
469
470 std::unique_ptr<TFile> Calo_TA_weight_file ( TFile::Open(Calo_TA_weight_file_path));
471 if (!Calo_TA_weight_file || Calo_TA_weight_file->IsZombie()){
472 ATH_MSG_FATAL( "Could not open the first input file: " << Calo_TA_weight_file_path );
473 return StatusCode::FAILURE;
474 }
475
476 m_caloMassWeight = std::unique_ptr<TH3F>(static_cast<TH3F*>(Calo_TA_weight_file->Get(Calo_weight_hist_name)));
477 m_TAMassWeight = std::unique_ptr<TH3F>(static_cast<TH3F*>(Calo_TA_weight_file->Get(TA_weight_hist_name)));
478
479 m_caloMassWeight->SetDirectory(nullptr);
480 m_TAMassWeight->SetDirectory(nullptr);//To keep it open when we close the .root file
481
482
483 Calo_TA_weight_file->Close();
484
485 }
486
487 return StatusCode::SUCCESS;
488 }
489
490
491 //-----------------------------------------------------------------------------
492 // The function "getMatchedTruthJet" finds the truth jet that match with the given jet_reco and it save it in the given jet_truth_matched jet.
493 //-----------------------------------------------------------------------------
494
495 StatusCode FFJetSmearingTool::getMatchedTruthJet(xAOD::Jet& jet_reco, xAOD::Jet& jet_truth_matched) const{
496
497 // Get the truth jets of the event
498 const xAOD::JetContainer* jets_truth = nullptr;
499
500 ATH_CHECK(evtStore()->retrieve(jets_truth,m_truth_jetColl));//If fail, it means that we are "Unable to retrieve jetColl Info". It shows an Error message and exits
501
502 double dRmax_truthJet = 0.75;// matching condition
503 double dRmin=9999; //we will take the closest jet reco-truth
504
505 //Loop over the truth jets in the event to match
506 const xAOD::Jet* close_jet = nullptr;
507 for (const auto *const jet_truth : *jets_truth){
508 float dR_Test = jet_reco.p4().DeltaR(jet_truth->p4());
509 if (dR_Test < dRmax_truthJet){
510 if (dR_Test < dRmin){
511 close_jet = jet_truth;
512 dRmin = dR_Test;
513 }
514 }
515 }
516 if (dRmin > 999){ return StatusCode::FAILURE;}
517
518 jet_truth_matched.setJetP4(close_jet->jetP4());
519 return StatusCode::SUCCESS;
520 }
521
522
523 //-----------------------------------------------------------------------------
524 // The function "getJetTopology" gets the topology of the given jet. "QCD" jets have a extra source of uncertainties called "MODELLINGUNCERTAINTIESQCDJETS".
525 //-----------------------------------------------------------------------------
526
527 StatusCode FFJetSmearingTool::getJetTopology( xAOD::Jet& jet_reco, std::string& jetTopology) const{
529 if (!accTruthLabel.isAvailable(jet_reco) )
530 {
531 ATH_MSG_ERROR("Unable to retrieve the FatjetTruthLabel from the jet. Please call the BoostedJetTaggers decorateTruthLabel() function before calling this function.");
532 return StatusCode::FAILURE;
533 }
534
535 LargeRJetTruthLabel::TypeEnum jetTruthLabel = LargeRJetTruthLabel::intToEnum(accTruthLabel(jet_reco));
536
537 if (jetTruthLabel == LargeRJetTruthLabel::tqqb || jetTruthLabel == LargeRJetTruthLabel::other_From_t){
538 jetTopology="Top";
539 }else if (jetTruthLabel == LargeRJetTruthLabel::Wqq || jetTruthLabel == LargeRJetTruthLabel::Zqq || jetTruthLabel == LargeRJetTruthLabel::Wqq_From_t || jetTruthLabel == LargeRJetTruthLabel::other_From_V){
540 jetTopology="V";
541 }else if (jetTruthLabel == LargeRJetTruthLabel::qcd){
542 jetTopology="QCD";
543 }else if (jetTruthLabel == LargeRJetTruthLabel::Hbb || jetTruthLabel == LargeRJetTruthLabel::other_From_H){
544 jetTopology="H";
545 }else if (jetTruthLabel == LargeRJetTruthLabel::notruth){
546 jetTopology="no_match";
547 ATH_MSG_DEBUG("No truth jet match with this reco jet. The jet will not be smeared.");
548 }else{
549 jetTopology="QCD"; // We should never arrive here
550 }
551
552 ATH_MSG_VERBOSE("The topology of this jet correspond to a " << jetTopology << " large-R jet");
553
554 return StatusCode::SUCCESS;
555 }
556
557
558 //-----------------------------------------------------------------------------
559 // The function "getJMSJMR" read the JMS and JMR uncertainties associated with the systematic
560 //-----------------------------------------------------------------------------
561
562 StatusCode FFJetSmearingTool::getJMSJMR( xAOD::Jet& jet_reco, double jet_mass_value, JetTools::FFJetAllowedMassDefEnum MassDef_of_syst, const std::string& jetTopology, double& JMS_err, double& JMR_err) const{
563
564 // JMS/JMR systematic variations
565 JMS_err = 0;
566 JMR_err = 0;
567
568 // Some variables to simplify the logic in the "if" structure found below
573
574 const auto & massAffectedSys = m_Syst_MassDefAffected_map.at(m_currentSysData->SysBaseName);
575 const auto & topologyAffected = m_Syst_TopologyAffected_map.at(m_currentSysData->SysBaseName);
576 const auto & uncertparam = m_Syst_uncertparam.at(m_currentSysData->SysBaseName);
577
578 if (massAffectedSys == JetTools::enumToString(MassDef_of_syst) || massAffectedSys == JetTools::enumToString(comb) ){
579 ATH_MSG_VERBOSE("This uncertainty affects to the " << JetTools::enumToString(MassDef_of_syst) << " mass");
580 }else{ // Only apply the systematic to the proper mass definition
581 return StatusCode::SUCCESS;
582 }
583
584 if (topologyAffected != "All" && !TString(topologyAffected).Contains(jetTopology)){
585 ATH_MSG_VERBOSE("The systematic does not affect to this jet topology");
586 return StatusCode::SUCCESS;
587 }
588
589 float jet_mass = jet_mass_value*m_MeVtoGeV; // jet_reco->m()*m_MeVtoGeV; The TA mass can not be extracted this way
590 float jet_pT = jet_reco.pt()*m_MeVtoGeV;
591
592 if (m_Syst_Affects_JMSorJMR.at(m_currentSysData->SysBaseName) == "JMS"){
593
594 JMR_err = 0;
595
596 const TH2* hist = nullptr; // This variable will contain the pointer to the proper histogram to use in the interpolation
597
598 // TA and Calo mass defs take values from one hisogram only
599 if (massAffectedSys == JetTools::enumToString(calo) || massAffectedSys == JetTools::enumToString(ta) ){
600 hist = m_Syst_Hist_map.at(m_currentSysData->SysBaseName).get();
601 }else if (massAffectedSys == JetTools::enumToString(comb) ){ // Comb mass defs can take values from two histograms, depending ifits Calo- or TA- part is affected
602 if (MassDef_of_syst == calo){
603 hist = m_Syst_Hist_map.at(m_currentSysData->SysBaseName).get();
604 }else if (MassDef_of_syst == ta){
605 hist = m_Syst_HistTA_map.at(m_currentSysData->SysBaseName).get();
606 }
607 }
608 JMS_err = FFJetSmearingTool::Interpolate2D(hist, jet_pT, jet_mass) * m_currentSysData->SysParameter;
609
610 }else if (m_Syst_Affects_JMSorJMR.at(m_currentSysData->SysBaseName) == "JMR"){
611
612 JMS_err = 0;
613
614 const TH2* hist = nullptr;
615 const TH3F* hist3d = nullptr;
616
617 // TA and Calo mass defs take values from one hisogram only
618 if (massAffectedSys == JetTools::enumToString(calo) || massAffectedSys == JetTools::enumToString(ta) || massAffectedSys == JetTools::enumToString(ufo)){
619 if (uncertparam == "eLOGmOeAbsEta"){
620 hist3d = m_Syst_Hist_map3d.at(m_currentSysData->SysBaseName).get();
621 }else{ // Usually, uncertparam == "PtAbsMass"
622 hist = m_Syst_Hist_map.at(m_currentSysData->SysBaseName).get();
623 }
624 }else if (massAffectedSys == JetTools::enumToString(comb) ){ // Comb mass defs can take values from two histograms, depending ifits Calo- or TA- part is affected
625 if (MassDef_of_syst == calo){
626 if (uncertparam == "eLOGmOeAbsEta"){
627 hist3d = m_Syst_Hist_map3d.at(m_currentSysData->SysBaseName).get();
628 }else{ // Usually, uncertparam == "PtAbsMass"
629 hist = m_Syst_Hist_map.at(m_currentSysData->SysBaseName).get();
630 }
631 }else if (MassDef_of_syst == ta){
632 if (uncertparam == "eLOGmOeAbsEta"){
633 hist3d = m_Syst_HistTA_map3d.at(m_currentSysData->SysBaseName).get();
634 }else{ // Usually, uncertparam == "PtAbsMass"
635 hist = m_Syst_HistTA_map.at(m_currentSysData->SysBaseName).get();
636 }
637 }
638 }
639
640 if (uncertparam == "eLOGmOeAbsEta"){
641 JMR_err = FFJetSmearingTool::Read3DHistogram(hist3d, jet_reco.e()*m_MeVtoGeV, TMath::Log(jet_reco.m()/jet_reco.e()), std::abs(jet_reco.eta())) * m_currentSysData->SysParameter;
642 }else{ // uncertparam == "PtAbsMass"
643 JMR_err = FFJetSmearingTool::Interpolate2D(hist, jet_pT, jet_mass) * m_currentSysData->SysParameter;
644 }
645
646 }
647
648 ATH_MSG_DEBUG("Systematic applied: " << m_currentSysData->SysBaseName);
649
650 ATH_MSG_VERBOSE("JMS_err: " << JMS_err);
651 ATH_MSG_VERBOSE("JMR_err: " << JMR_err);
652
653 return StatusCode::SUCCESS;
654 }
655
656
657 //-----------------------------------------------------------------------------
658 // Once the tool is initialized. The user can call the function "SmearJetMass" to perform the jet smearing using FF (for the current systematic in his loop)
659 //-----------------------------------------------------------------------------
660
662
663 ATH_MSG_VERBOSE("//---------------------------------------------------------------//");
664 ATH_MSG_VERBOSE("Reco Jet to Smear: pt = " << jet_reco.pt() << ", mass = " << jet_reco.m() << ", eta = " << jet_reco.eta());
665
666 if (std::abs(jet_reco.eta()) > m_EtaRange){//JetCalibTools do not properly for jets with |eta|>2
667 ATH_MSG_DEBUG("This jet exceeds the eta range that the tool allows (|eta|<" << m_EtaRange << ")");
669 }
670 if (jet_reco.m() > m_MaxMass){
671 ATH_MSG_DEBUG("This jet exceeds the mass range that the tool allows jet_mass <" << m_MaxMass << " MeV)");
673 }
674 if (jet_reco.pt() > m_MaxPt){
675 ATH_MSG_DEBUG("This jet exceeds the maximum pt that the tool allows jet_pt <" << m_MaxPt << " MeV)");
677 }
678 if (jet_reco.m() <= 0){
679 ATH_MSG_DEBUG("This jet has negative mass");
681 }
682
683 // Find matched truth jet
684 xAOD::Jet jet_truth_matched;
685 jet_truth_matched.makePrivateStore();
686
687 if (!(getMatchedTruthJet(jet_reco, jet_truth_matched).isSuccess())){
688 ATH_MSG_VERBOSE("No truth jet match with this reco jet. The jet will not be smeared.");
690 }
691
692 ATH_MSG_VERBOSE("Matched truth Jet: pt = " << jet_truth_matched.pt() << ", mass = " << jet_truth_matched.m() << ", eta = " << jet_truth_matched.eta());
693
694 // Get the jet topology
695 std::string jetTopology;
696
697 if (!(getJetTopology( jet_reco, jetTopology)).isSuccess()){
698 ATH_MSG_ERROR("Imposible to obtain the jetTopology");
700 }
701 if (jetTopology == "no_match"){
703 }
704
705 // The TA mass is saved in an attribute so you can not access to it using ->m(). (if calibrated as Calo mass and not as Combined Mass), The Calo mass is not set as an attribute so you can not access it using ->getAttribute.
706
707 double jet_mass_UFO = 0;
708 double jet_mass_CALO = 0;
709 double jet_mass_TA = 0;
710 double calo_mass_weight=1; // m_comb = Weight*m_Calo + (1-Weight)*m_TA
711
712 float JetTrackAssistedMassCalibrated_from_JetCalibTools;
713
715
716 xAOD::JetFourMom_t jet_reco_CALO;
717 xAOD::JetFourMom_t jet_reco_TA;
718 xAOD::JetFourMom_t jet_reco_Comb;
719
720 jet_reco.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumCalo",jet_reco_CALO);
721 jet_reco.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumTA",jet_reco_TA);
722 jet_reco.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumCombQCD",jet_reco_Comb);
723
724 ATH_MSG_VERBOSE("CALO jet mass " << jet_reco_CALO.mass());
725 ATH_MSG_VERBOSE("TA jet mass " << jet_reco_TA.mass() );
726 ATH_MSG_VERBOSE("Comb jet mass " << jet_reco_Comb.mass() );
727
728 jet_mass_CALO = jet_reco_CALO.mass();
729 jet_mass_TA = jet_reco_TA.mass();
730 jet_reco.getAttribute<float>("JetTrackAssistedMassCalibrated", JetTrackAssistedMassCalibrated_from_JetCalibTools);
731
733 jet_mass_CALO = jet_reco.m();
734 calo_mass_weight = 1;
736 jet_mass_TA = jet_reco.m();
737 jet_reco.getAttribute<float>("JetTrackAssistedMassCalibrated", JetTrackAssistedMassCalibrated_from_JetCalibTools);
738 calo_mass_weight = 0;
740 jet_mass_UFO = jet_reco.m();
741 calo_mass_weight = 1;
742 }
743
744 // Obtain the average mass response of the jet. The response will depend in the chosed topology (top, W or QCD) and also in the mass definition (CALO, TA, Combined). By default the map used correspond to QCD jets
745
746 double avg_response_UFO=1;
747 double avg_response_CALO=1;
748 double avg_response_TA=1;
749
751 avg_response_CALO = FFJetSmearingTool::Interpolate2D(m_CALO_ResponseMap.get(), jet_reco.pt()*m_MeVtoGeV, jet_truth_matched.m()*m_MeVtoGeV);
752 if (avg_response_CALO == 0) avg_response_CALO=1; // If we look outside the Th2 histogram, we would obtain 0, so we apply the nominal response (1)
753 }
754
756 avg_response_TA = FFJetSmearingTool::Interpolate2D(m_TA_ResponseMap.get(), jet_reco.pt()*m_MeVtoGeV, jet_truth_matched.m()*m_MeVtoGeV);
757 if (avg_response_TA == 0) avg_response_TA = 1; // If we look outside the Th2 histogram, we would obtain 0, so we apply the nominal response (1)
758 }
759
761 avg_response_UFO = FFJetSmearingTool::Interpolate2D(m_UFO_ResponseMap.get(), jet_reco.pt()*m_MeVtoGeV, jet_truth_matched.m()*m_MeVtoGeV);
762 if (avg_response_UFO == 0) avg_response_UFO = 1; // If we look outside the Th2 histogram, we would obtain 0, so we apply the nominal response (1)
763 }
764
765 // Obtain the jet mass scale (JMS) and the jet mass resolution (JMR) nominal values and variation that correspond to the jet_reco
766
767 double JMS(1), JMS_err(0), JMR(1), JMR_err(0);
768 double scale;
769 double resolution;
770
771 double smeared_UFO_mass = jet_mass_UFO;
772 double smeared_CALO_mass = jet_mass_CALO;
773 double smeared_TA_mass = jet_mass_TA;
774
775 bool is_UFO_mass_smeared = false;
776 bool is_CALO_mass_smeared = false;
777 bool is_TA_mass_smeared = false;
778
780
781 if (!(getJMSJMR(jet_reco, jet_mass_CALO, JetTools::FFJetAllowedMassDefEnum::Calo, jetTopology, JMS_err, JMR_err)).isSuccess()){
783 }
784
785 scale = JMS + JMS_err;
786 resolution = JMR + JMR_err;
787
788 if (TMath::Abs(scale-1) > 0.0001 || TMath::Abs(resolution-1) > 0.0001){
789 is_CALO_mass_smeared = true;
790
791 ATH_MSG_VERBOSE("Forward Folding CALO procedure will use scale=" << scale << ", resolution=" << resolution << " and average respose=" << avg_response_CALO);
792
793 //FF procedure
794 smeared_CALO_mass = jet_mass_CALO * scale + (jet_mass_CALO - avg_response_CALO*jet_truth_matched.m())*(resolution-scale); // FF formula
795 }
796
797 }
798
800
801 if (!(getJMSJMR(jet_reco, jet_mass_TA, JetTools::FFJetAllowedMassDefEnum::TA, jetTopology, JMS_err, JMR_err))){
803 }
804
805 scale = JMS + JMS_err;
806 resolution = JMR + JMR_err;
807
808 if (TMath::Abs(scale-1) > 0.0001 || TMath::Abs(resolution-1) > 0.0001){
809
810 is_TA_mass_smeared = true;
811
812 ATH_MSG_VERBOSE("Forward Folding TA procedure will use scale=" << scale << ", resolution=" << resolution << " and average respose=" << avg_response_TA);
813
814 //FF procedure
815 smeared_TA_mass = jet_mass_TA * scale + (jet_mass_TA - avg_response_TA*jet_truth_matched.m())*(resolution-scale); // FF formula
816 }
817
818 }
819
821
822 if (!(getJMSJMR(jet_reco, jet_mass_UFO, JetTools::FFJetAllowedMassDefEnum::UFO, jetTopology, JMS_err, JMR_err)).isSuccess()){
824 }
825
826 scale = JMS + JMS_err;
827 resolution = JMR + JMR_err;
828
829 if (TMath::Abs(scale-1) > 0.0001 || TMath::Abs(resolution-1) > 0.0001){
830 is_UFO_mass_smeared = true;
831
832 ATH_MSG_VERBOSE("Forward Folding UFO procedure will use scale=" << scale << ", resolution=" << resolution << " and average respose=" << avg_response_UFO);
833
834 //FF procedure
835 smeared_UFO_mass = jet_mass_UFO * scale + (jet_mass_UFO - avg_response_UFO*jet_truth_matched.m())*(resolution-scale); // FF formula
836 }
837
838 }
839
840 // We only smear the jet if we have to. If not, avoid doing extra calculations
841 if (!is_CALO_mass_smeared && !is_TA_mass_smeared && !is_UFO_mass_smeared){
842 ATH_MSG_VERBOSE("This jet is not affected by the systematic. The jet won't be modified");
843 ATH_MSG_VERBOSE("//---------------------------------------------------------------//");
844
846 }
847
848 // Recalculate the weights after the smearing
849 if (m_MassDef == JetTools::FFJetAllowedMassDefEnum::Comb && JetTrackAssistedMassCalibrated_from_JetCalibTools != 0 && jet_mass_CALO != 0){
850 //we check that JetTrackAssistedMassCalibrated_from_JetCalibTools != 0 instead of jet_mass_TA != 0 becuase
851 //there is a problem in the conversion between the mass itself and the four-vector representation (due to a
852 //limitation of floating). This makes the value of jet_mass_TA!=0 in situations where it should be 0.
853 //In order to work arround it we check JetTrackAssistedMassCalibrated_from_JetCalibTools != 0 insead.
854 double caloRes;
855 double TARes;
856
857 xAOD::JetFourMom_t jet_reco_CALO;
858 xAOD::JetFourMom_t jet_reco_TA;
859
860 jet_reco.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumCalo",jet_reco_CALO);
861 jet_reco.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumTA",jet_reco_TA);
862
863
864 //The smearing do not change the pt but it changes the mass (so the energy too) so, if we want to perform the smearing properly, we have to change
865 //the Calo and TA four momenta before looking at the weights map
866 jet_reco_CALO = xAOD::JetFourMom_t(jet_reco_CALO.pt(),jet_reco_CALO.eta(),jet_reco_CALO.phi(),smeared_CALO_mass);//The smearing do not change the pt but it changes the Energy
867
868 jet_reco_TA = xAOD::JetFourMom_t(jet_reco_TA.pt(),jet_reco_TA.eta(),jet_reco_TA.phi(),smeared_TA_mass);
869
870
871 caloRes=FFJetSmearingTool::Read3DHistogram(m_caloMassWeight.get() ,jet_reco_CALO.e()*m_MeVtoGeV,TMath::Log(jet_reco_CALO.M()/jet_reco_CALO.e()),std::abs(jet_reco_CALO.eta()));
872
873 TARes=FFJetSmearingTool::Read3DHistogram(m_TAMassWeight.get() ,jet_reco_TA.e()*m_MeVtoGeV,TMath::Log(jet_reco_TA.M()/jet_reco_TA.e()),std::abs(jet_reco_TA.eta()));
874
875 //The histograms with the weights that we are reading were defined with the code "e_LOGmOe_eta" which means that each axis correspond to:
876 //-X: Jet Energy
877 //-Y: Log(Jet_Energy/Jet_mass)
878 //-Z:Eta
879 //Domain is [200-6000],[-6,0],[0,2] but, the ReadHistogram function put the value of the extream of the histogram to the values outside the domain.
880 //We have to use a custom "My_Interpolate" because the Z axis has just one bin (and this makes the Root Interpolate function fail)
881
882 double caloFactor;
883 double TAFactor;
884
885 if (caloRes == 0 ){
886 caloFactor = 0; TAFactor = 1;
887 }else if (TARes == 0){
888 caloFactor = 1; TAFactor = 0;
889 }else{
890 caloFactor = 1./(caloRes*caloRes);
891 TAFactor = 1./(TARes*TARes);
892 }
893
894 calo_mass_weight = caloFactor /(caloFactor + TAFactor);
895
896 ATH_MSG_VERBOSE(" Map Calo weight = " << calo_mass_weight );
897 ATH_MSG_VERBOSE(" Map TA weight = " << 1 - calo_mass_weight );
898 }else if (JetTrackAssistedMassCalibrated_from_JetCalibTools == 0){
899 calo_mass_weight = 1;
900 }else if (jet_mass_CALO == 0){
901 calo_mass_weight = 0;
902 }
903
904 // Calculate the final smeared mass
905 double smeared_mass = 0;
907 smeared_mass = smeared_UFO_mass;
908 ATH_MSG_VERBOSE("Smeared UFO mass " << smeared_UFO_mass);
909 }else{
910 smeared_mass = calo_mass_weight*smeared_CALO_mass + (1 - calo_mass_weight)*smeared_TA_mass;
911 ATH_MSG_VERBOSE("Smeared CALO mass " << smeared_CALO_mass);
912 ATH_MSG_VERBOSE("Smeared TA mass " << smeared_TA_mass);
913 }
914
915 xAOD::JetFourMom_t p4 = jet_reco.jetP4();
916
917 p4 = xAOD::JetFourMom_t(jet_reco.pt(),jet_reco.eta(),jet_reco.phi(),smeared_mass);
918 jet_reco.setJetP4(p4);
919
920 ATH_MSG_VERBOSE("Smeared Reco Jet: pt = " << jet_reco.pt() << ", mass = " << jet_reco.m() << ", eta = " << jet_reco.eta());
921
922 ATH_MSG_VERBOSE("//---------------------------------------------------------------//");
923
925 }
926
927
928 // To apply the correction into a copied jet
930 xAOD::Jet* copy = new xAOD::Jet(input);
931
932 // Call the implemented function
934 delete copy;
936 }
937 output = copy;
939 }
940
941
942 // To apply the correction into all the jets inside a jet containter
945
946 // Loop over the container
947 for (size_t iJet = 0; iJet < inputs.size(); ++iJet)
948 {
949 result = applyCorrection(*inputs.at(iJet));
951 break;
952 }
953 }
954 return result;
955 }
956
957
958 // Functions from JetUncertainties. We copy them in order to read the map exactly as it is done in JetUncertainties and get EXACTLY the same result
959 double FFJetSmearingTool::Read3DHistogram(const TH3* histo, double x, double y, double z) const{
960
961 if (not histo){
962 ATH_MSG_ERROR("Histogram pointer is null in FFJetSmearingTool::Read3DHistogram");
963 return 0.;
964 }
965
966 double aux_x = x;
967 double aux_y = y;
968 double aux_z = z;
969
970 // Asymptotic values
971 //If the value is outside the histogram region, we take the closest value to that one
972
973 double xMax = histo->GetXaxis()->GetBinLowEdge(histo->GetNbinsX()+1);
974 double xMin = histo->GetXaxis()->GetBinLowEdge(1);
975 double yMax = histo->GetYaxis()->GetBinLowEdge(histo->GetNbinsY()+1);
976 double yMin = histo->GetYaxis()->GetBinLowEdge(1);
977 double zMax = histo->GetZaxis()->GetBinLowEdge(histo->GetNbinsZ()+1);
978 double zMin = histo->GetZaxis()->GetBinLowEdge(1);
979
980 if (x >= xMax) aux_x = xMax-1e-6 ; //so it fits the up-most x-bin
981 if (x <= xMin) aux_x = xMin+1e-6 ; //so it fits the low-most x-bin
982 if (std::isnan(y)) return 0; // no weight if the input is NaN, can happen for log(X)
983 if (y >= yMax) aux_y = yMax-1e-6 ; //so it fits the up-most y-bin
984 if (y <= yMin) aux_y = yMin+1e-6 ; //so it fits the low-most y-bin
985 if (z >= zMax) aux_z = zMax-1e-6 ; //so it fits the up-most z-bin
986 if (z <= zMin) aux_z = zMin+1e-6 ; //so it fits the low-most z-bin
987
988 //Use the interpolate function from JetHelpers.cxx
989 double weight = JetHelpers::Interpolate(histo, aux_x, aux_y, aux_z);
990
991 return weight;
992 }
993
994
995 // The function in JetHelpers can not be used because it needs a TH1 and we use TH2 histograms. We define our own function.
996 double FFJetSmearingTool::Interpolate2D(const TH2* histo, double x, double y) const{
997 if (not histo){
998 ATH_MSG_ERROR("Histogram pointer is null in FFJetSmearingTool::Interpolate2D");
999 return 0.;
1000 }
1001 Int_t bin_x = histo->GetXaxis()->FindFixBin(x);
1002 Int_t bin_y = histo->GetYaxis()->FindFixBin(y);
1003 if (bin_x<1 || bin_x>histo->GetNbinsX() || bin_y<1 || bin_y>histo->GetNbinsY()){
1004 ATH_MSG_VERBOSE("The point is outside the histogram domain.");
1005 return 0.;
1006 }
1007
1008 double interpolated_value = JetHelpers::Interpolate(histo, x, y);
1009 return interpolated_value;
1010 }
1011
1012
1013 // Function to replace all occurrences of 'to_find' with 'to_replace' in 'str'
1014 void FFJetSmearingTool::replaceAllOccurrences(std::string& str, const std::string& to_find, const std::string& to_replace){
1015 size_t pos = 0;
1016 while ((pos = str.find(to_find, pos)) != std::string::npos){
1017 str.replace(pos, to_find.length(), to_replace);
1018 pos += to_replace.length(); // Move past the last replaced position
1019 }
1020 }
1021
1022
1023} // namespace CP
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
static const std::vector< std::string > systematics
#define y
#define x
#define z
static const Attributes_t empty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
Return value from object correction CP tools.
@ Error
Some error happened during the object correction.
@ OutOfValidityRange
Input object is out of validity range.
@ Ok
The correction was done successfully.
virtual CP::SystematicSet recommendedSystematics() const override
List of all systematics recommended for this tool.
std::map< std::string, std::string > m_Syst_uncertparam
std::unique_ptr< TH2 > m_TA_ResponseMap
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
std::map< std::string, std::string > m_Syst_HistPath_map
virtual StatusCode applySystematicVariation(const CP::SystematicSet &systematics) override
Configure tool to apply systematic variation.
virtual CP::CorrectionCode applyContainerCorrection(xAOD::JetContainer &inputs) const override
std::map< std::string, std::unique_ptr< TH3F > > m_Syst_Hist_map3d
StatusCode getMatchedTruthJet(xAOD::Jet &jet_reco, xAOD::Jet &jet_truth_matched) const
std::map< std::string, std::unique_ptr< TH3F > > m_Syst_HistTA_map3d
static constexpr float m_MeVtoGeV
virtual ~FFJetSmearingTool()
CP::SystematicSet m_SysList
StatusCode getJetTopology(xAOD::Jet &jet_reco, std::string &jetTopology) const
double Interpolate2D(const TH2 *histo, double x, double y) const
std::map< std::string, std::string > m_Syst_Affects_JMSorJMR
StatusCode getJMSJMR(xAOD::Jet &jet_reco, double jet_mass, JetTools::FFJetAllowedMassDefEnum MassDef_of_syst, const std::string &jetTopology, double &JMS_err, double &JMR_err) const
virtual bool isAffectedBySystematic(const CP::SystematicVariation &systematic) const override
Specify whether tool is affected by provided systematic.
virtual CP::SystematicSet affectingSystematics() const override
List of all systematics affecting this tool.
std::unique_ptr< TH3F > m_caloMassWeight
SysData * m_currentSysData
Points to the current systematic configuration.
JetTools::FFJetAllowedMassDefEnum m_MassDef
void replaceAllOccurrences(std::string &str, const std::string &to_find, const std::string &to_replace)
std::map< std::string, std::unique_ptr< TH2 > > m_Syst_HistTA_map
std::map< std::string, std::string > m_Syst_TopologyAffected_map
std::map< std::string, std::string > m_Syst_MassDefAffected_map
StatusCode readFFJetSmearingToolSimplifiedData(TEnv &settings)
std::unordered_map< CP::SystematicSet, SysData > m_sysData
std::unique_ptr< TH3F > m_TAMassWeight
std::unique_ptr< TH2 > m_CALO_ResponseMap
virtual CP::CorrectionCode correctedCopy(const xAOD::Jet &input, xAOD::Jet *&output) const override
std::unique_ptr< TH2 > m_UFO_ResponseMap
std::map< std::string, std::unique_ptr< TH2 > > m_Syst_Hist_map
double Read3DHistogram(const TH3 *histo, double x, double y, double z) const
virtual CP::CorrectionCode applyCorrection(xAOD::Jet &jet_reco) const override
Apply a systematic variation of get a new copy.
std::map< std::string, std::string > m_Syst_HistTAPath_map
FFJetSmearingTool(const std::string &name)
Proper constructor for Athena.
This module implements the central registry for handling systematic uncertainties with CP tools.
static SystematicRegistry & getInstance()
Get the singleton instance of the registry for the curren thread.
StatusCode registerSystematics(const IReentrantSystematicsTool &tool)
effects: register all the systematics from the tool
Class to wrap a set of SystematicVariations.
std::string name() const
returns: the systematics joined into a single string.
void insert(const SystematicVariation &systematic)
description: insert a systematic into the set
const_iterator begin() const
description: const iterator to the beginning of the set
size_t size() const
returns: size of the set
void makePrivateStore()
Create a new (empty) private store for this object.
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
virtual double phi() const
The azimuthal angle ( ) of the particle.
Definition Jet_v1.cxx:54
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition Jet_v1.cxx:71
void setJetP4(const JetFourMom_t &p4)
Definition Jet_v1.cxx:171
virtual double pt() const
The transverse momentum ( ) of the particle.
Definition Jet_v1.cxx:44
virtual double m() const
The invariant mass of the particle.
Definition Jet_v1.cxx:59
bool getAttribute(AttributeID type, T &value) const
Retrieve attribute moment by enum.
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition Jet_v1.cxx:49
virtual double e() const
The total energy of the particle.
Definition Jet_v1.cxx:63
JetFourMom_t jetP4() const
The full 4-momentum of the particle : internal jet type.
Definition Jet_v1.cxx:76
Select isolated Photons, Electrons and Muons.
double Interpolate(const TH1 *histo, const double x)
StatusCode stringToEnum(const TString &name, FFJetAllowedMassDefEnum &result)
TString enumToString(const FFJetAllowedMassDefEnum type)
TypeEnum intToEnum(const int type)
TString findFilePath(const TString &fileName, const TString &path="", const TString &calibArea="")
Jet_v1 Jet
Definition of the current "jet version".
JetContainer_v1 JetContainer
Definition of the current "jet container version".
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
Definition JetTypes.h:17