ATLAS Offline Software
JetPileupCorrection.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <TEnv.h>
7 
10 
12 #include "PUResidual3DCorrection.h"
13 
14 #include <memory>
15 #include <utility>
16 
19  m_config(nullptr), m_jetAlgo(""), m_calibAreaTag(""), m_dev(false), m_doResidual(false),
20  m_doJetArea(false), m_doOrigin(false), m_isData(false),
21  m_useFull4vectorArea(false), m_residualOffsetCorr(nullptr), m_originScale("JetOriginConstitScaleMomentum")
22 {}
23 
24 JetPileupCorrection::JetPileupCorrection(const std::string& name, TEnv* config, TString jetAlgo, TString calibAreaTag,
25  bool doResidual, bool doJetArea, bool doOrigin, const std::string& originScale,
26  bool isData, bool dev)
28  m_config(config), m_jetAlgo(std::move(jetAlgo)), m_calibAreaTag(std::move(calibAreaTag)), m_dev(dev),
29  m_doResidual(doResidual), m_doJetArea(doJetArea), m_doOrigin(doOrigin), m_isData(isData),
30  m_useFull4vectorArea(false), m_residualOffsetCorr(nullptr), m_originScale(originScale)
31 {}
32 
34 
36 
37 }
38 
39 
41 
42  ATH_MSG_INFO("Initializing pileup correction.");
43 
44  if (m_doOrigin) ATH_MSG_INFO("OriginScale: " << m_originScale);
45 
46  if(!m_config){
47  ATH_MSG_ERROR("Jet pileup correction tool received a null config pointer.");
48  return StatusCode::FAILURE;
49  }
50 
51  m_doOnlyResidual = m_config->GetValue("ApplyOnlyResidual",false);
53  ATH_MSG_FATAL("If you're trying to apply only the Residual pile up correction, it needs to be specify in the Calibration Sequence. ApplyOnlyResidual should be true in the configuration file and the PileupStartScale should be specified.");
54  return StatusCode::FAILURE;
55  }
56 
57  m_doMuOnly = m_config->GetValue("ApplyOnlyMuResidual",false);
58  m_doNPVOnly = m_config->GetValue("ApplyOnlyNPVResidual",false);
59  m_doNJetOnly = m_config->GetValue("ApplyOnlyNJetResidual",false);
60  m_doSequentialResidual = m_config->GetValue("DoSequentialResidual",false); // first mu and then NPV/NJet corrections
61  bool useNjet = m_config->GetValue("OffsetCorrection.UseNjet", false);
62 
63  m_do3Dcorrection = m_config->GetValue("Do3DCorrection", false);
64 
65  if(m_doSequentialResidual) ATH_MSG_DEBUG("The pileup residual calibrations will be applied sequentially.");
66  else ATH_MSG_DEBUG("The pileup residual calibrations will be applied simultaneously (default).");
67  if(m_doMuOnly) ATH_MSG_INFO("Only the pileup mu-based calibration will be applied.");
68  if(m_doNPVOnly) ATH_MSG_INFO("Only the pileup NPV-based calibration will be applied.");
69  if(m_doNJetOnly) ATH_MSG_INFO("Only the pileup NJet-based calibration will be applied.");
70  else if (useNjet) ATH_MSG_DEBUG("NJet will be used instead of NPV in the pileup corrections.");
71 
72  // Protections
74  ATH_MSG_FATAL("Sequential residual calibration can not be applied in doMuOnly or doNPVOnly or doNJetOnly cases.");
75  return StatusCode::FAILURE;
76  }
77  if(useNjet && (m_doMuOnly || m_doNPVOnly)){
78  ATH_MSG_FATAL("Conflicting configuation, UseNjet true but doMuOnly or doNPVOnly also true.");
79  return StatusCode::FAILURE;
80  }
81  if(m_doMuOnly && m_doNPVOnly){
82  ATH_MSG_FATAL("It was requested to apply only the mu-based AND the NPV-based calibrations.");
83  return StatusCode::FAILURE;
84  }
85  if(m_doMuOnly && m_doNJetOnly){
86  ATH_MSG_FATAL("It was requested to apply only the mu-based AND the NJet-based calibrations.");
87  return StatusCode::FAILURE;
88  }
89  if(!useNjet && m_doNJetOnly){
90  ATH_MSG_FATAL("It was requested to apply only the NJet-based calibration but not to use Njet instead of NPV.");
91  return StatusCode::FAILURE;
92  }
94  ATH_MSG_FATAL("It was requested to apply NJet-based and NPV calibrations.");
95  return StatusCode::FAILURE;
96  }
97 
99  ATH_MSG_FATAL("3D correction incompatible with any other PU correction. Please turn off any PU residual options.");
100  return StatusCode::FAILURE;
101 
102  }
103 
104  m_jetStartScale = m_config->GetValue("PileupStartingScale","JetConstitScaleMomentum");
105  ATH_MSG_INFO("JetPileupCorrection: Starting scale: " << m_jetStartScale);
106  if ( m_jetStartScale.compare("DO_NOT_USE") == 0 ) {
107  ATH_MSG_WARNING("Configuration file does not specify the jet starting scale!");
108  }
109 
110  m_useFull4vectorArea = m_config->GetValue("ApplyFullJetArea4MomentumCorrection", false);
111  if(m_doJetArea) ATH_MSG_INFO("Jet area pile up correction will be applied.");
112  if ( m_useFull4vectorArea ) ATH_MSG_INFO(" Full 4-vector jet area correction is activated.");
113  //ATH_MSG_INFO(" \n");
114 
115  if(m_do3Dcorrection){
116  m_residual3DCorr = std::make_unique<PUCorrection::PU3DCorrectionHelper>( ) ;
117 
118  TString PUCalibFile3D = m_config->GetValue("PU3DCorrection.constants", "pu3DResidualsConstants.root");
119 
120  if(m_dev){
121  //Currently hard coded that we remove "JetCalibTools/CalibrationFactors/" from the string in dev mode
122  //Same implementation as in other JetCalibTools classes for now, will be changed everywhere during major overhaul of package for r22
123  PUCalibFile3D.Remove(0,33);
124  PUCalibFile3D.Insert(0,"JetCalibTools/");
125  }
126  else{
127  PUCalibFile3D.Insert(14,m_calibAreaTag);
128  }
129 
130  const std::string calibFilePU = PathResolverFindCalibFile(PUCalibFile3D.Data());
131 
132  m_residual3DCorr->loadParameters(calibFilePU);
133  m_residual3DCorr->m_rhoEnergyScale = m_config->GetValue("PU3DCorrection.rhoEnergyScale", 0.001);
134  m_residual3DCorr->m_pTEnergyScale = m_config->GetValue("PU3DCorrection.pTEnergyScale", 0.001);
135  m_residual3DCorr->m_applyDeltaPtTerm = m_config->GetValue("PU3DCorrection.applyDeltaPtTerm", true);
136  ATH_MSG_INFO("Pile-up 3D correction. Configured with :");
137  ATH_MSG_INFO(" calib constants file="<< m_config->GetValue("PU3DCorrection.constants", "pu3DResidualsConstants.root") );
138  ATH_MSG_INFO(" rho scale ="<<m_residual3DCorr->m_rhoEnergyScale );
139  ATH_MSG_INFO(" pT scale ="<<m_residual3DCorr->m_pTEnergyScale);
140  ATH_MSG_INFO(" apply deltaPt term = " << m_residual3DCorr->m_applyDeltaPtTerm);
141  } else if ( m_doResidual ) {
142  std::string suffix = "_Residual";
144  m_residualOffsetCorr->msg().setLevel( this->msg().level() );
146  }
147 
149  ATH_MSG_WARNING("JetPileupCorrection::initializeTool : WARNING!! You have requested the 4 vector jet area correction and the residual offset correction. This configuration is not currently supported, the residual offset correction will be deactivated.");
150  return StatusCode::SUCCESS;
151  } else if ( !m_doResidual && !m_useFull4vectorArea ) {
152  ATH_MSG_VERBOSE("JetPileupCorrection::initializeTool : You have requested the transverse jet area correction without the residual offset correction. This configuration is not recommended.");
153  return StatusCode::SUCCESS;
154  } else {
155  return StatusCode::SUCCESS;
156  }
157  return StatusCode::FAILURE;
158 }
159 
161  ATH_MSG_VERBOSE(" Applying pileup calibration to jet " << jet.index());
162  ATH_MSG_VERBOSE(" Initial jet pT = " << 0.001*jet.pt() << " GeV");
163 
164  xAOD::JetFourMom_t jetStartP4;
166  jetStartP4 = jet.jetP4();
167 
168  const double E_det = jetStartP4.e();
169  const double pT_det = jetStartP4.pt();
170  const double eta_det = jetStartP4.eta();
171  const double mass_det = jetStartP4.mass();
172 
173  if ( E_det < mass_det ) {
174  ATH_MSG_WARNING( "JetPileupCorrection::calibrateImpl : Current jet has mass=" << mass_det/m_GeV << " GeV, which is greater than it's energy=" << E_det/m_GeV << " GeV?? Aborting." );
175  return StatusCode::FAILURE;
176  }
177 
178  xAOD::JetFourMom_t jetareaP4 = jet.getAttribute<xAOD::JetFourMom_t>("ActiveArea4vec");
179  ATH_MSG_VERBOSE(" Area = " << jetareaP4);
180  const double rho = jetEventInfo.rho();
181  ATH_MSG_VERBOSE(" Rho = " << rho);
182 
183  if(m_do3Dcorrection){
184  int NPV = jetEventInfo.NPV();
185  float mu = jetEventInfo.mu();
186 
187  double pt_calib= m_residual3DCorr->correctedPt(pT_det, eta_det, jetareaP4.Pt(), rho, mu, NPV ) ;
188  double scaleF = pt_calib < 0 ? 0.01*m_GeV/pT_det : pt_calib/pT_det;
189  xAOD::JetFourMom_t calibP4 = jetStartP4 * scaleF;
190  jet.setAttribute<int>("PileupCorrected",true);
191  jet.setAttribute<xAOD::JetFourMom_t>("JetPileupScaleMomentum",calibP4);
192  jet.setJetP4( calibP4 );
193 
194  } else if (m_useFull4vectorArea) {
195  ATH_MSG_VERBOSE(" Applying area-subtraction calibration to jet " << jet.index() << " with pT = " << 0.001*jet.pt() << " GeV");
196  //subtract rho * the jet area from the jet
197  xAOD::JetFourMom_t calibP4 = jetStartP4 - rho*jetareaP4;
198  //Attribute to track if a jet has received the pileup subtraction (always true if this code was run)
199  jet.setAttribute<int>("PileupCorrected",true);
200  //Transfer calibrated jet properties to the Jet object
201  jet.setAttribute<xAOD::JetFourMom_t>("JetPileupScaleMomentum",calibP4);
202  jet.setJetP4( calibP4 );
203 
204  } else if ( m_residualOffsetCorr && !m_useFull4vectorArea ) {
205  ATH_MSG_VERBOSE(" Applying residual pileup calibration to jet " << jet.index() << " with pT = " << 0.001*jet.pt() << " GeV");
206 
207  const double NPV = jetEventInfo.NPV();
208  const double mu = jetEventInfo.mu();
209  const int nJet = jetEventInfo.nJet();
210 
211  // Retrieve the offset correction from the residual correction class
212  double offsetET = 0; // pT residual subtraction
213  double pT_offset = pT_det; // pT difference before/after pileup corrections
214  double pileup_SF = 1; // final calibration factor applied to the four vector
215 
216  xAOD::JetFourMom_t calibP4;
217  if(!m_doSequentialResidual){ // Default, both corrections are applied simultaneously
218  offsetET = m_residualOffsetCorr->GetResidualOffset(fabs(eta_det), mu, NPV, nJet, m_doMuOnly, m_doNPVOnly||m_doNJetOnly);
219 
220  // Calculate the pT after jet areas and residual offset
221  pT_offset = m_doJetArea ? pT_det - rho*jetareaP4.pt() - offsetET : pT_det - offsetET;
222 
223  // Set the jet pT to 10 MeV if the pT is negative after the jet area and residual offset corrections
224  pileup_SF = pT_offset >= 0 ? pT_offset / pT_det : 0.01*m_GeV/pT_det;
225 
226  if ( m_doOrigin ) {
227  xAOD::JetFourMom_t jetOriginP4;
228  static std::atomic<unsigned int> originWarnings = 0;
229  if ( jet.getAttribute<xAOD::JetFourMom_t>(m_originScale.c_str(),jetOriginP4) )
230  calibP4 = jetOriginP4*pileup_SF;
231  else {
232  if ( originWarnings < 20 ) {
233  ATH_MSG_WARNING("Could not retrieve " << m_originScale << " jet attribute, origin correction will not be applied.");
234  ++originWarnings;
235  }
236  calibP4 = jetStartP4*pileup_SF;
237  }
238  } else {
239  calibP4 = jetStartP4*pileup_SF;
240  }
241  } else {
242 
243  // Calculate mu-based correction factor
244  offsetET = m_residualOffsetCorr->GetResidualOffset(fabs(eta_det), mu, NPV, nJet, true, false);
245  pT_offset = m_doJetArea ? pT_det - rho*jetareaP4.pt() - offsetET : pT_det - offsetET;
246  double muSF = pT_offset >= 0 ? pT_offset / pT_det : 0.01*m_GeV/pT_det;
247 
248  // Apply mu-based calibration
249  if ( m_doOrigin ) {
250  xAOD::JetFourMom_t jetOriginP4;
251  static std::atomic<unsigned int> originWarnings = 0;
252  if ( jet.getAttribute<xAOD::JetFourMom_t>(m_originScale.c_str(),jetOriginP4) )
253  calibP4 = jetOriginP4*muSF;
254  else {
255  if ( originWarnings < 20 ) {
256  ATH_MSG_WARNING("Could not retrieve " << m_originScale << " jet attribute, origin correction will not be applied.");
257  ++originWarnings;
258  }
259  calibP4 = jetStartP4*muSF;
260  }
261  } else {
262  calibP4 = jetStartP4*muSF;
263  }
264 
265  // Calculate and apply NPV/Njet-based calibration
266  offsetET = m_residualOffsetCorr->GetResidualOffset(fabs(eta_det), mu, NPV, nJet, false, true);
267  double pT_afterMuCalib = calibP4.pt();
268  pT_offset = pT_afterMuCalib - offsetET;
269  double SF = pT_offset >= 0 ? pT_offset / pT_afterMuCalib : 0.01*m_GeV/pT_afterMuCalib;
270  calibP4 = calibP4*SF;
271 
272  }
273 
274  //Attribute to track if a jet has received the origin correction
275  jet.setAttribute<int>("OriginCorrected",m_doOrigin);
276  //Attribute to track if a jet has received the pileup subtraction (always true if this code was run)
277  jet.setAttribute<int>("PileupCorrected",true);
278 
279  //Transfer calibrated jet properties to the Jet object
280  jet.setAttribute<xAOD::JetFourMom_t>("JetPileupScaleMomentum",calibP4);
281  jet.setJetP4( calibP4 );
282 
283  } else {
284  ATH_MSG_VERBOSE(" Applying postive-only area-subtraction calibration to jet " << jet.index() << " with pT = " << 0.001*jet.pt() << " GeV");
285  //Set the jet pT to 10 MeV if the pT or energy is negative after the jet area correction
286  const double area_SF = (pT_det-rho*jetareaP4.pt()<=0 || E_det-rho*jetareaP4.e()<=0) ? 10/pT_det : (pT_det-rho*jetareaP4.pt())/pT_det;
287  xAOD::JetFourMom_t calibP4;
288  if ( m_doOrigin ) {
289  xAOD::JetFourMom_t jetOriginP4;
290  static std::atomic<unsigned int> originWarnings = 0;
291  if ( jet.getAttribute<xAOD::JetFourMom_t>(m_originScale.c_str(),jetOriginP4) )
292  calibP4 = jetOriginP4*area_SF;
293  else {
294  if ( originWarnings < 20 ) {
295  ATH_MSG_WARNING("Could not retrieve " << m_originScale << " jet attribute, origin correction will not be applied.");
296  ++originWarnings;
297  }
298  calibP4 = jetStartP4*area_SF;
299  }
300  } else calibP4 = jetStartP4*area_SF;
301 
302  //Attribute to track if a jet has received the origin correction
303  jet.setAttribute<int>("OriginCorrected",m_doOrigin);
304  //Attribute to track if a jet has received the pileup subtraction (always true if this code was run)
305  jet.setAttribute<int>("PileupCorrected",true);
306 
307  //Transfer calibrated jet properties to the Jet object
308  jet.setAttribute<xAOD::JetFourMom_t>("JetPileupScaleMomentum",calibP4);
309  jet.setJetP4( calibP4 );
310  }
311 
312  ATH_MSG_VERBOSE(" Calibrated jet pT = " << 0.001*jet.pt() << " GeV");
313  return StatusCode::SUCCESS;
314 }
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
hotSpotInTAG.suffix
string suffix
Definition: hotSpotInTAG.py:186
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
JetCalibrationStep::setStartP4
virtual StatusCode setStartP4(xAOD::Jet &jet) const
Definition: JetCalibrationStep.cxx:21
JetPileupCorrection::JetPileupCorrection
JetPileupCorrection()
Definition: JetPileupCorrection.cxx:17
ResidualOffsetCorrection
Definition: ResidualOffsetCorrection.h:27
JetPileupCorrection::m_doJetArea
bool m_doJetArea
Definition: JetPileupCorrection.h:45
TRT_PAI_gasdata::SF
const float SF[NF]
Cross sections for Fluor.
Definition: TRT_PAI_gasdata.h:285
JetCalibrationStep::m_name
std::string m_name
Definition: JetCalibrationStep.h:42
JetEventInfo::nJet
int nJet()
Definition: JetEventInfo.h:29
JetEventInfo::NPV
double NPV()
Definition: JetEventInfo.h:28
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
JetPileupCorrection::m_isData
bool m_isData
Definition: JetPileupCorrection.h:47
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
IJetCalibrationTool.h
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
JetEventInfo
Definition: JetEventInfo.h:8
ResidualOffsetCorrection::initialize
virtual StatusCode initialize()
Definition: ResidualOffsetCorrection.cxx:34
JetPileupCorrection::m_calibAreaTag
TString m_calibAreaTag
Definition: JetPileupCorrection.h:42
JetPileupCorrection::m_residual3DCorr
std::unique_ptr< PUCorrection::PU3DCorrectionHelper > m_residual3DCorr
Definition: JetPileupCorrection.h:58
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
JetEventInfo::mu
double mu()
Definition: JetEventInfo.h:27
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
JetPileupCorrection::m_doNJetOnly
bool m_doNJetOnly
Definition: JetPileupCorrection.h:50
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
PUResidual3DCorrection.h
JetPileupCorrection::m_originScale
std::string m_originScale
Definition: JetPileupCorrection.h:62
JetPileupCorrection::~JetPileupCorrection
virtual ~JetPileupCorrection()
Definition: JetPileupCorrection.cxx:33
asg::AsgMessaging::msg
MsgStream & msg() const
The standard message stream.
Definition: AsgMessaging.cxx:49
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
JetPileupCorrection::m_doResidual
bool m_doResidual
Definition: JetPileupCorrection.h:44
JetPileupCorrection::m_residualOffsetCorr
ResidualOffsetCorrection * m_residualOffsetCorr
Definition: JetPileupCorrection.h:56
JetPileupCorrection::m_doMuOnly
bool m_doMuOnly
Definition: JetPileupCorrection.h:48
JetPileupCorrection::m_doNPVOnly
bool m_doNPVOnly
Definition: JetPileupCorrection.h:49
JetEventInfo::rho
double rho()
Definition: JetEventInfo.h:26
xAOD::JetFourMom_t
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
Definition: JetTypes.h:17
PathResolver.h
JetCalibrationStep::m_jetStartScale
std::string m_jetStartScale
Definition: JetCalibrationStep.h:41
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
ResidualOffsetCorrection::GetResidualOffset
double GetResidualOffset(double abseta, double mu, double NPV, int nJet, bool MuOnly, bool NOnly) const
Definition: ResidualOffsetCorrection.cxx:118
JetPileupCorrection::m_doSequentialResidual
bool m_doSequentialResidual
Definition: JetPileupCorrection.h:51
JetPileupCorrection::m_useFull4vectorArea
bool m_useFull4vectorArea
Definition: JetPileupCorrection.h:55
JetPileupCorrection::initialize
virtual StatusCode initialize() override
Definition: JetPileupCorrection.cxx:40
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
JetPileupCorrection::m_doOrigin
bool m_doOrigin
Definition: JetPileupCorrection.h:46
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
JetPileupCorrection::m_do3Dcorrection
bool m_do3Dcorrection
Definition: JetPileupCorrection.h:53
JetPileupCorrection::m_config
TEnv * m_config
Definition: JetPileupCorrection.h:40
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
JetPileupCorrection::m_jetAlgo
TString m_jetAlgo
Definition: JetPileupCorrection.h:41
ResidualOffsetCorrection.h
python.grid.isData
def isData(dataset)
Definition: grid.py:491
JetPileupCorrection::m_doOnlyResidual
bool m_doOnlyResidual
Definition: JetPileupCorrection.h:60
JetPileupCorrection.h
JetPileupCorrection::m_dev
bool m_dev
Definition: JetPileupCorrection.h:43
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
fitman.rho
rho
Definition: fitman.py:532
JetCalibrationStep::m_GeV
double m_GeV
Definition: JetCalibrationStep.h:40
JetPileupCorrection::calibrate
virtual StatusCode calibrate(xAOD::Jet &jet, JetEventInfo &jetEventInfo) const override
Definition: JetPileupCorrection.cxx:160
JetCalibrationStep
Definition: JetCalibrationStep.h:20