ATLAS Offline Software
Loading...
Searching...
No Matches
FFJetSmearingTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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
198 CP::SystematicSet result;
199 result.insert(m_SysList);
200
201 return result;
202 }
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>(static_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>(static_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 const std::string to_find = "MCTYPE";
394 const std::string to_replace = m_MCType_string;
395 for (size_t iComp = 0; iComp < 999; ++iComp){
396 const TString prefix = Form("JMRComponent.%zu.",iComp);
397 std::string Syst_Name = settings.GetValue(prefix+"Name","");
398 replaceAllOccurrences(Syst_Name, to_find, to_replace);
399
400 if (!Syst_Name.empty()){
401
402 m_SysList.insert( CP::SystematicVariation(Syst_Name, 1) );
403 m_SysList.insert( CP::SystematicVariation(Syst_Name, -1) );
404 m_Syst_MassDefAffected_map[Syst_Name] = settings.GetValue(prefix+"MassDef","");
405 m_Syst_TopologyAffected_map[Syst_Name] = settings.GetValue(prefix+"Topology","");
406 m_Syst_Affects_JMSorJMR[Syst_Name] = "JMR";
407 m_Syst_HistPath_map[Syst_Name] = settings.GetValue(prefix+"Hist","");
408 m_Syst_uncertparam[Syst_Name] = settings.GetValue(prefix+"Param","");
409
410 replaceAllOccurrences(m_Syst_HistPath_map[Syst_Name], to_find, to_replace);
411
412 // Processing the input histogram name
413 if (m_Syst_uncertparam[Syst_Name] == "PtAbsMass"){
414 m_Syst_Hist_map[Syst_Name] = std::unique_ptr<TH2>(dynamic_cast<TH2*>(data_file->Get(m_Syst_HistPath_map[Syst_Name].c_str())));
415 m_Syst_Hist_map[Syst_Name]->SetDirectory(nullptr);
416 }else if (m_Syst_uncertparam[Syst_Name] == "eLOGmOeAbsEta"){
417 m_Syst_Hist_map3d[Syst_Name] = std::unique_ptr<TH3F>(dynamic_cast<TH3F*>(data_file->Get(m_Syst_HistPath_map[Syst_Name].c_str())));
418 m_Syst_Hist_map3d[Syst_Name]->SetDirectory(nullptr);
419 }
420
421 // For Comb mass we need to read two histograms
423 m_Syst_HistTAPath_map[Syst_Name] = settings.GetValue(prefix+"HistTA","");
424 if (!m_Syst_HistTAPath_map[Syst_Name].empty()){
425 if (m_Syst_uncertparam[Syst_Name] == "PtAbsMass"){
426 m_Syst_HistTA_map[Syst_Name] = std::unique_ptr<TH2>(dynamic_cast<TH2*>(data_file->Get(m_Syst_HistTAPath_map[Syst_Name].c_str())));
427 m_Syst_HistTA_map[Syst_Name]->SetDirectory(nullptr);
428 }else if (m_Syst_uncertparam[Syst_Name] == "eLOGmOeAbsEta"){
429 m_Syst_HistTA_map3d[Syst_Name] = std::unique_ptr<TH3F>(dynamic_cast<TH3F*>(data_file->Get(m_Syst_HistTAPath_map[Syst_Name].c_str())));
430 m_Syst_HistTA_map3d[Syst_Name]->SetDirectory(nullptr);
431 }
432 }
433 }
434
435 }
436 }
437
438 data_file->Close();
439
440 // Skip for UFO -> Read the Calo and TA mass weight histograms from the same file that JetUncertainties uses
442
443 TString Calo_TA_weight_file_name = settings.GetValue("JetUncertainties_UncertaintyRootFile","");
444 const TString Calo_TA_weight_file_path = jet::utils::findFilePath(Calo_TA_weight_file_name.Data(),m_path.c_str(),m_calibArea.c_str());
445
446 if (Calo_TA_weight_file_path.IsNull()){
447 ATH_MSG_ERROR("Cannot find the file with the Calo and TA weights");
448 return StatusCode::FAILURE;
449 }
450
451 TString Calo_weight_hist_name = settings.GetValue("CombMassWeightCaloHist","");
452 if (Calo_weight_hist_name.IsNull()){
453 ATH_MSG_ERROR("Cannot find the histogram name that contains the Calo weights in the config file");
454 return StatusCode::FAILURE;
455 }
456
457 TString TA_weight_hist_name = settings.GetValue("CombMassWeightTAHist","");
458 if (TA_weight_hist_name.IsNull()){
459 ATH_MSG_ERROR("Cannot find the histogram name that contains the TA weights in the config file");
460 return StatusCode::FAILURE;
461 }
462
463 ATH_MSG_INFO(Form(" Calo weights hist: \"%s\"",Calo_weight_hist_name.Data()));
464 ATH_MSG_INFO(Form(" TA weights hist: \"%s\"",TA_weight_hist_name.Data()));
465 ATH_MSG_INFO(Form(" Location: %s",Calo_TA_weight_file_path.Data()));
466
467
468 std::unique_ptr<TFile> Calo_TA_weight_file ( TFile::Open(Calo_TA_weight_file_path));
469 if (!Calo_TA_weight_file || Calo_TA_weight_file->IsZombie()){
470 ATH_MSG_FATAL( "Could not open the first input file: " << Calo_TA_weight_file_path );
471 return StatusCode::FAILURE;
472 }
473
474 m_caloMassWeight = std::unique_ptr<TH3F>(static_cast<TH3F*>(Calo_TA_weight_file->Get(Calo_weight_hist_name)));
475 m_TAMassWeight = std::unique_ptr<TH3F>(static_cast<TH3F*>(Calo_TA_weight_file->Get(TA_weight_hist_name)));
476
477 m_caloMassWeight->SetDirectory(nullptr);
478 m_TAMassWeight->SetDirectory(nullptr);//To keep it open when we close the .root file
479
480
481 Calo_TA_weight_file->Close();
482
483 }
484
485 return StatusCode::SUCCESS;
486 }
487
488
489 //-----------------------------------------------------------------------------
490 // 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.
491 //-----------------------------------------------------------------------------
492
493 StatusCode FFJetSmearingTool::getMatchedTruthJet(xAOD::Jet& jet_reco, xAOD::Jet& jet_truth_matched) const{
494
495 // Get the truth jets of the event
496 const xAOD::JetContainer* jets_truth = nullptr;
497
498 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
499
500 double dRmax_truthJet = 0.75;// matching condition
501 double dRmin=9999; //we will take the closest jet reco-truth
502
503 //Loop over the truth jets in the event to match
504 const xAOD::Jet* close_jet = nullptr;
505 for (const auto *const jet_truth : *jets_truth){
506 float dR_Test = jet_reco.p4().DeltaR(jet_truth->p4());
507 if (dR_Test < dRmax_truthJet){
508 if (dR_Test < dRmin){
509 close_jet = jet_truth;
510 dRmin = dR_Test;
511 }
512 }
513 }
514 if (dRmin > 999){ return StatusCode::FAILURE;}
515
516 jet_truth_matched.setJetP4(close_jet->jetP4());
517 return StatusCode::SUCCESS;
518 }
519
520
521 //-----------------------------------------------------------------------------
522 // The function "getJetTopology" gets the topology of the given jet. "QCD" jets have a extra source of uncertainties called "MODELLINGUNCERTAINTIESQCDJETS".
523 //-----------------------------------------------------------------------------
524
525 StatusCode FFJetSmearingTool::getJetTopology( xAOD::Jet& jet_reco, std::string& jetTopology) const{
526 const SG::AuxElement::ConstAccessor<int> accTruthLabel(m_truthlabelaccessor);
527 if (!accTruthLabel.isAvailable(jet_reco) )
528 {
529 ATH_MSG_ERROR("Unable to retrieve the FatjetTruthLabel from the jet. Please call the BoostedJetTaggers decorateTruthLabel() function before calling this function.");
530 return StatusCode::FAILURE;
531 }
532
533 LargeRJetTruthLabel::TypeEnum jetTruthLabel = LargeRJetTruthLabel::intToEnum(accTruthLabel(jet_reco));
534
535 if (jetTruthLabel == LargeRJetTruthLabel::tqqb || jetTruthLabel == LargeRJetTruthLabel::other_From_t){
536 jetTopology="Top";
537 }else if (jetTruthLabel == LargeRJetTruthLabel::Wqq || jetTruthLabel == LargeRJetTruthLabel::Zqq || jetTruthLabel == LargeRJetTruthLabel::Wqq_From_t || jetTruthLabel == LargeRJetTruthLabel::other_From_V){
538 jetTopology="V";
539 }else if (jetTruthLabel == LargeRJetTruthLabel::qcd){
540 jetTopology="QCD";
541 }else if (jetTruthLabel == LargeRJetTruthLabel::Hbb || jetTruthLabel == LargeRJetTruthLabel::other_From_H){
542 jetTopology="H";
543 }else if (jetTruthLabel == LargeRJetTruthLabel::notruth){
544 jetTopology="no_match";
545 ATH_MSG_DEBUG("No truth jet match with this reco jet. The jet will not be smeared.");
546 }else{
547 jetTopology="QCD"; // We should never arrive here
548 }
549
550 ATH_MSG_VERBOSE("The topology of this jet correspond to a " << jetTopology << " large-R jet");
551
552 return StatusCode::SUCCESS;
553 }
554
555
556 //-----------------------------------------------------------------------------
557 // The function "getJMSJMR" read the JMS and JMR uncertainties associated with the systematic
558 //-----------------------------------------------------------------------------
559
560 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{
561
562 // JMS/JMR systematic variations
563 JMS_err = 0;
564 JMR_err = 0;
565
566 // Some variables to simplify the logic in the "if" structure found below
571
572 const auto & massAffectedSys = m_Syst_MassDefAffected_map.at(m_currentSysData->SysBaseName);
573 const auto & topologyAffected = m_Syst_TopologyAffected_map.at(m_currentSysData->SysBaseName);
574 const auto & uncertparam = m_Syst_uncertparam.at(m_currentSysData->SysBaseName);
575
576 if (massAffectedSys == JetTools::enumToString(MassDef_of_syst) || massAffectedSys == JetTools::enumToString(comb) ){
577 ATH_MSG_VERBOSE("This uncertainty affects to the " << JetTools::enumToString(MassDef_of_syst) << " mass");
578 }else{ // Only apply the systematic to the proper mass definition
579 return StatusCode::SUCCESS;
580 }
581
582 if (topologyAffected != "All" && !TString(topologyAffected).Contains(jetTopology)){
583 ATH_MSG_VERBOSE("The systematic does not affect to this jet topology");
584 return StatusCode::SUCCESS;
585 }
586
587 float jet_mass = jet_mass_value*m_MeVtoGeV; // jet_reco->m()*m_MeVtoGeV; The TA mass can not be extracted this way
588 float jet_pT = jet_reco.pt()*m_MeVtoGeV;
589
590 if (m_Syst_Affects_JMSorJMR.at(m_currentSysData->SysBaseName) == "JMS"){
591
592 JMR_err = 0;
593
594 const TH2* hist = nullptr; // This variable will contain the pointer to the proper histogram to use in the interpolation
595
596 // TA and Calo mass defs take values from one hisogram only
597 if (massAffectedSys == JetTools::enumToString(calo) || massAffectedSys == JetTools::enumToString(ta) ){
598 hist = m_Syst_Hist_map.at(m_currentSysData->SysBaseName).get();
599 }else if (massAffectedSys == JetTools::enumToString(comb) ){ // Comb mass defs can take values from two histograms, depending ifits Calo- or TA- part is affected
600 if (MassDef_of_syst == calo){
601 hist = m_Syst_Hist_map.at(m_currentSysData->SysBaseName).get();
602 }else if (MassDef_of_syst == ta){
603 hist = m_Syst_HistTA_map.at(m_currentSysData->SysBaseName).get();
604 }
605 }
606 JMS_err = FFJetSmearingTool::Interpolate2D(hist, jet_pT, jet_mass) * m_currentSysData->SysParameter;
607
608 }else if (m_Syst_Affects_JMSorJMR.at(m_currentSysData->SysBaseName) == "JMR"){
609
610 JMS_err = 0;
611
612 const TH2* hist = nullptr;
613 const TH3F* hist3d = nullptr;
614
615 // TA and Calo mass defs take values from one hisogram only
616 if (massAffectedSys == JetTools::enumToString(calo) || massAffectedSys == JetTools::enumToString(ta) || massAffectedSys == JetTools::enumToString(ufo)){
617 if (uncertparam == "eLOGmOeAbsEta"){
618 hist3d = m_Syst_Hist_map3d.at(m_currentSysData->SysBaseName).get();
619 }else{ // Usually, uncertparam == "PtAbsMass"
620 hist = m_Syst_Hist_map.at(m_currentSysData->SysBaseName).get();
621 }
622 }else if (massAffectedSys == JetTools::enumToString(comb) ){ // Comb mass defs can take values from two histograms, depending ifits Calo- or TA- part is affected
623 if (MassDef_of_syst == calo){
624 if (uncertparam == "eLOGmOeAbsEta"){
625 hist3d = m_Syst_Hist_map3d.at(m_currentSysData->SysBaseName).get();
626 }else{ // Usually, uncertparam == "PtAbsMass"
627 hist = m_Syst_Hist_map.at(m_currentSysData->SysBaseName).get();
628 }
629 }else if (MassDef_of_syst == ta){
630 if (uncertparam == "eLOGmOeAbsEta"){
631 hist3d = m_Syst_HistTA_map3d.at(m_currentSysData->SysBaseName).get();
632 }else{ // Usually, uncertparam == "PtAbsMass"
633 hist = m_Syst_HistTA_map.at(m_currentSysData->SysBaseName).get();
634 }
635 }
636 }
637
638 if (uncertparam == "eLOGmOeAbsEta"){
639 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;
640 }else{ // uncertparam == "PtAbsMass"
641 JMR_err = FFJetSmearingTool::Interpolate2D(hist, jet_pT, jet_mass) * m_currentSysData->SysParameter;
642 }
643
644 }
645
646 ATH_MSG_DEBUG("Systematic applied: " << m_currentSysData->SysBaseName);
647
648 ATH_MSG_VERBOSE("JMS_err: " << JMS_err);
649 ATH_MSG_VERBOSE("JMR_err: " << JMR_err);
650
651 return StatusCode::SUCCESS;
652 }
653
654
655 //-----------------------------------------------------------------------------
656 // 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)
657 //-----------------------------------------------------------------------------
658
660
661 ATH_MSG_VERBOSE("//---------------------------------------------------------------//");
662 ATH_MSG_VERBOSE("Reco Jet to Smear: pt = " << jet_reco.pt() << ", mass = " << jet_reco.m() << ", eta = " << jet_reco.eta());
663
664 if (std::abs(jet_reco.eta()) > m_EtaRange){//JetCalibTools do not properly for jets with |eta|>2
665 ATH_MSG_DEBUG("This jet exceeds the eta range that the tool allows (|eta|<" << m_EtaRange << ")");
667 }
668 if (jet_reco.m() > m_MaxMass){
669 ATH_MSG_DEBUG("This jet exceeds the mass range that the tool allows jet_mass <" << m_MaxMass << " MeV)");
671 }
672 if (jet_reco.pt() > m_MaxPt){
673 ATH_MSG_DEBUG("This jet exceeds the maximum pt that the tool allows jet_pt <" << m_MaxPt << " MeV)");
675 }
676 if (jet_reco.m() <= 0){
677 ATH_MSG_DEBUG("This jet has negative mass");
679 }
680
681 // Find matched truth jet
682 xAOD::Jet jet_truth_matched;
683 jet_truth_matched.makePrivateStore();
684
685 if (!(getMatchedTruthJet(jet_reco, jet_truth_matched).isSuccess())){
686 ATH_MSG_VERBOSE("No truth jet match with this reco jet. The jet will not be smeared.");
688 }
689
690 ATH_MSG_VERBOSE("Matched truth Jet: pt = " << jet_truth_matched.pt() << ", mass = " << jet_truth_matched.m() << ", eta = " << jet_truth_matched.eta());
691
692 // Get the jet topology
693 std::string jetTopology;
694
695 if (!(getJetTopology( jet_reco, jetTopology)).isSuccess()){
696 ATH_MSG_ERROR("Imposible to obtain the jetTopology");
698 }
699 if (jetTopology == "no_match"){
701 }
702
703 // 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.
704
705 double jet_mass_UFO = 0;
706 double jet_mass_CALO = 0;
707 double jet_mass_TA = 0;
708 double calo_mass_weight=1; // m_comb = Weight*m_Calo + (1-Weight)*m_TA
709
710 float JetTrackAssistedMassCalibrated_from_JetCalibTools;
711
713
714 xAOD::JetFourMom_t jet_reco_CALO;
715 xAOD::JetFourMom_t jet_reco_TA;
716 xAOD::JetFourMom_t jet_reco_Comb;
717
718 jet_reco.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumCalo",jet_reco_CALO);
719 jet_reco.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumTA",jet_reco_TA);
720 jet_reco.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumCombQCD",jet_reco_Comb);
721
722 ATH_MSG_VERBOSE("CALO jet mass " << jet_reco_CALO.mass());
723 ATH_MSG_VERBOSE("TA jet mass " << jet_reco_TA.mass() );
724 ATH_MSG_VERBOSE("Comb jet mass " << jet_reco_Comb.mass() );
725
726 jet_mass_CALO = jet_reco_CALO.mass();
727 jet_mass_TA = jet_reco_TA.mass();
728 jet_reco.getAttribute<float>("JetTrackAssistedMassCalibrated", JetTrackAssistedMassCalibrated_from_JetCalibTools);
729
731 jet_mass_CALO = jet_reco.m();
732 calo_mass_weight = 1;
734 jet_mass_TA = jet_reco.m();
735 jet_reco.getAttribute<float>("JetTrackAssistedMassCalibrated", JetTrackAssistedMassCalibrated_from_JetCalibTools);
736 calo_mass_weight = 0;
738 jet_mass_UFO = jet_reco.m();
739 calo_mass_weight = 1;
740 }
741
742 // 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
743
744 double avg_response_UFO=1;
745 double avg_response_CALO=1;
746 double avg_response_TA=1;
747
749 avg_response_CALO = FFJetSmearingTool::Interpolate2D(m_CALO_ResponseMap.get(), jet_reco.pt()*m_MeVtoGeV, jet_truth_matched.m()*m_MeVtoGeV);
750 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)
751 }
752
754 avg_response_TA = FFJetSmearingTool::Interpolate2D(m_TA_ResponseMap.get(), jet_reco.pt()*m_MeVtoGeV, jet_truth_matched.m()*m_MeVtoGeV);
755 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)
756 }
757
759 avg_response_UFO = FFJetSmearingTool::Interpolate2D(m_UFO_ResponseMap.get(), jet_reco.pt()*m_MeVtoGeV, jet_truth_matched.m()*m_MeVtoGeV);
760 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)
761 }
762
763 // Obtain the jet mass scale (JMS) and the jet mass resolution (JMR) nominal values and variation that correspond to the jet_reco
764
765 double JMS(1), JMS_err(0), JMR(1), JMR_err(0);
766 double scale;
767 double resolution;
768
769 double smeared_UFO_mass = jet_mass_UFO;
770 double smeared_CALO_mass = jet_mass_CALO;
771 double smeared_TA_mass = jet_mass_TA;
772
773 bool is_UFO_mass_smeared = false;
774 bool is_CALO_mass_smeared = false;
775 bool is_TA_mass_smeared = false;
776
778
779 if (!(getJMSJMR(jet_reco, jet_mass_CALO, JetTools::FFJetAllowedMassDefEnum::Calo, jetTopology, JMS_err, JMR_err)).isSuccess()){
781 }
782
783 scale = JMS + JMS_err;
784 resolution = JMR + JMR_err;
785
786 if (TMath::Abs(scale-1) > 0.0001 || TMath::Abs(resolution-1) > 0.0001){
787 is_CALO_mass_smeared = true;
788
789 ATH_MSG_VERBOSE("Forward Folding CALO procedure will use scale=" << scale << ", resolution=" << resolution << " and average respose=" << avg_response_CALO);
790
791 //FF procedure
792 smeared_CALO_mass = jet_mass_CALO * scale + (jet_mass_CALO - avg_response_CALO*jet_truth_matched.m())*(resolution-scale); // FF formula
793 }
794
795 }
796
798
799 if (!(getJMSJMR(jet_reco, jet_mass_TA, JetTools::FFJetAllowedMassDefEnum::TA, jetTopology, JMS_err, JMR_err))){
801 }
802
803 scale = JMS + JMS_err;
804 resolution = JMR + JMR_err;
805
806 if (TMath::Abs(scale-1) > 0.0001 || TMath::Abs(resolution-1) > 0.0001){
807
808 is_TA_mass_smeared = true;
809
810 ATH_MSG_VERBOSE("Forward Folding TA procedure will use scale=" << scale << ", resolution=" << resolution << " and average respose=" << avg_response_TA);
811
812 //FF procedure
813 smeared_TA_mass = jet_mass_TA * scale + (jet_mass_TA - avg_response_TA*jet_truth_matched.m())*(resolution-scale); // FF formula
814 }
815
816 }
817
819
820 if (!(getJMSJMR(jet_reco, jet_mass_UFO, JetTools::FFJetAllowedMassDefEnum::UFO, jetTopology, JMS_err, JMR_err)).isSuccess()){
822 }
823
824 scale = JMS + JMS_err;
825 resolution = JMR + JMR_err;
826
827 if (TMath::Abs(scale-1) > 0.0001 || TMath::Abs(resolution-1) > 0.0001){
828 is_UFO_mass_smeared = true;
829
830 ATH_MSG_VERBOSE("Forward Folding UFO procedure will use scale=" << scale << ", resolution=" << resolution << " and average respose=" << avg_response_UFO);
831
832 //FF procedure
833 smeared_UFO_mass = jet_mass_UFO * scale + (jet_mass_UFO - avg_response_UFO*jet_truth_matched.m())*(resolution-scale); // FF formula
834 }
835
836 }
837
838 // We only smear the jet if we have to. If not, avoid doing extra calculations
839 if (!is_CALO_mass_smeared && !is_TA_mass_smeared && !is_UFO_mass_smeared){
840 ATH_MSG_VERBOSE("This jet is not affected by the systematic. The jet won't be modified");
841 ATH_MSG_VERBOSE("//---------------------------------------------------------------//");
842
844 }
845
846 // Recalculate the weights after the smearing
847 if (m_MassDef == JetTools::FFJetAllowedMassDefEnum::Comb && JetTrackAssistedMassCalibrated_from_JetCalibTools != 0 && jet_mass_CALO != 0){
848 //we check that JetTrackAssistedMassCalibrated_from_JetCalibTools != 0 instead of jet_mass_TA != 0 becuase
849 //there is a problem in the conversion between the mass itself and the four-vector representation (due to a
850 //limitation of floating). This makes the value of jet_mass_TA!=0 in situations where it should be 0.
851 //In order to work arround it we check JetTrackAssistedMassCalibrated_from_JetCalibTools != 0 insead.
852 double caloRes;
853 double TARes;
854
855 xAOD::JetFourMom_t jet_reco_CALO;
856 xAOD::JetFourMom_t jet_reco_TA;
857
858 jet_reco.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumCalo",jet_reco_CALO);
859 jet_reco.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumTA",jet_reco_TA);
860
861
862 //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
863 //the Calo and TA four momenta before looking at the weights map
864 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
865
866 jet_reco_TA = xAOD::JetFourMom_t(jet_reco_TA.pt(),jet_reco_TA.eta(),jet_reco_TA.phi(),smeared_TA_mass);
867
868
869 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()));
870
871 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()));
872
873 //The histograms with the weights that we are reading were defined with the code "e_LOGmOe_eta" which means that each axis correspond to:
874 //-X: Jet Energy
875 //-Y: Log(Jet_Energy/Jet_mass)
876 //-Z:Eta
877 //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.
878 //We have to use a custom "My_Interpolate" because the Z axis has just one bin (and this makes the Root Interpolate function fail)
879
880 double caloFactor;
881 double TAFactor;
882
883 if (caloRes == 0 ){
884 caloFactor = 0; TAFactor = 1;
885 }else if (TARes == 0){
886 caloFactor = 1; TAFactor = 0;
887 }else{
888 caloFactor = 1./(caloRes*caloRes);
889 TAFactor = 1./(TARes*TARes);
890 }
891
892 calo_mass_weight = caloFactor /(caloFactor + TAFactor);
893
894 ATH_MSG_VERBOSE(" Map Calo weight = " << calo_mass_weight );
895 ATH_MSG_VERBOSE(" Map TA weight = " << 1 - calo_mass_weight );
896 }else if (JetTrackAssistedMassCalibrated_from_JetCalibTools == 0){
897 calo_mass_weight = 1;
898 }else if (jet_mass_CALO == 0){
899 calo_mass_weight = 0;
900 }
901
902 // Calculate the final smeared mass
903 double smeared_mass = 0;
905 smeared_mass = smeared_UFO_mass;
906 ATH_MSG_VERBOSE("Smeared UFO mass " << smeared_UFO_mass);
907 }else{
908 smeared_mass = calo_mass_weight*smeared_CALO_mass + (1 - calo_mass_weight)*smeared_TA_mass;
909 ATH_MSG_VERBOSE("Smeared CALO mass " << smeared_CALO_mass);
910 ATH_MSG_VERBOSE("Smeared TA mass " << smeared_TA_mass);
911 }
912
913 xAOD::JetFourMom_t p4 = jet_reco.jetP4();
914
915 p4 = xAOD::JetFourMom_t(jet_reco.pt(),jet_reco.eta(),jet_reco.phi(),smeared_mass);
916 jet_reco.setJetP4(p4);
917
918 ATH_MSG_VERBOSE("Smeared Reco Jet: pt = " << jet_reco.pt() << ", mass = " << jet_reco.m() << ", eta = " << jet_reco.eta());
919
920 ATH_MSG_VERBOSE("//---------------------------------------------------------------//");
921
923 }
924
925
926 // To apply the correction into a copied jet
928 xAOD::Jet* copy = new xAOD::Jet(input);
929
930 // Call the implemented function
932 delete copy;
934 }
935 output = copy;
937 }
938
939
940 // To apply the correction into all the jets inside a jet containter
943
944 // Loop over the container
945 for (size_t iJet = 0; iJet < inputs.size(); ++iJet)
946 {
947 result = applyCorrection(*inputs.at(iJet));
948 if (result == CP::CorrectionCode::Error){
949 break;
950 }
951 }
952 return result;
953 }
954
955
956 // 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
957 double FFJetSmearingTool::Read3DHistogram(const TH3* histo, double x, double y, double z) const{
958
959 if (not histo){
960 ATH_MSG_ERROR("Histogram pointer is null in FFJetSmearingTool::Read3DHistogram");
961 return 0.;
962 }
963
964 double aux_x = x;
965 double aux_y = y;
966 double aux_z = z;
967
968 // Asymptotic values
969 //If the value is outside the histogram region, we take the closest value to that one
970
971 double xMax = histo->GetXaxis()->GetBinLowEdge(histo->GetNbinsX()+1);
972 double xMin = histo->GetXaxis()->GetBinLowEdge(1);
973 double yMax = histo->GetYaxis()->GetBinLowEdge(histo->GetNbinsY()+1);
974 double yMin = histo->GetYaxis()->GetBinLowEdge(1);
975 double zMax = histo->GetZaxis()->GetBinLowEdge(histo->GetNbinsZ()+1);
976 double zMin = histo->GetZaxis()->GetBinLowEdge(1);
977
978 if (x >= xMax) aux_x = xMax-1e-6 ; //so it fits the up-most x-bin
979 if (x <= xMin) aux_x = xMin+1e-6 ; //so it fits the low-most x-bin
980 if (std::isnan(y)) return 0; // no weight if the input is NaN, can happen for log(X)
981 if (y >= yMax) aux_y = yMax-1e-6 ; //so it fits the up-most y-bin
982 if (y <= yMin) aux_y = yMin+1e-6 ; //so it fits the low-most y-bin
983 if (z >= zMax) aux_z = zMax-1e-6 ; //so it fits the up-most z-bin
984 if (z <= zMin) aux_z = zMin+1e-6 ; //so it fits the low-most z-bin
985
986 //Use the interpolate function from JetHelpers.cxx
987 double weight = JetHelpers::Interpolate(histo, aux_x, aux_y, aux_z);
988
989 return weight;
990 }
991
992
993 // The function in JetHelpers can not be used because it needs a TH1 and we use TH2 histograms. We define our own function.
994 double FFJetSmearingTool::Interpolate2D(const TH2* histo, double x, double y) const{
995 if (not histo){
996 ATH_MSG_ERROR("Histogram pointer is null in FFJetSmearingTool::Interpolate2D");
997 return 0.;
998 }
999 Int_t bin_x = histo->GetXaxis()->FindFixBin(x);
1000 Int_t bin_y = histo->GetYaxis()->FindFixBin(y);
1001 if (bin_x<1 || bin_x>histo->GetNbinsX() || bin_y<1 || bin_y>histo->GetNbinsY()){
1002 ATH_MSG_VERBOSE("The point is outside the histogram domain.");
1003 return 0.;
1004 }
1005
1006 double interpolated_value = JetHelpers::Interpolate(histo, x, y);
1007 return interpolated_value;
1008 }
1009
1010
1011 // Function to replace all occurrences of 'to_find' with 'to_replace' in 'str'
1012 void FFJetSmearingTool::replaceAllOccurrences(std::string& str, const std::string& to_find, const std::string& to_replace){
1013 size_t pos = 0;
1014 while ((pos = str.find(to_find, pos)) != std::string::npos){
1015 str.replace(pos, to_find.length(), to_replace);
1016 pos += to_replace.length(); // Move past the last replaced position
1017 }
1018 }
1019
1020
1021} // 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
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:182
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