Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Pileup1DResidualCalibStep.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
11 
12 #include "xAODJet/JetAccessors.h"
13 
14 
16 
17 #include <memory>
18 #include <utility>
19 
20 
22  : asg::AsgTool( name ) { }
23 
24 
25 
26 
28 
30  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.");
31  return StatusCode::FAILURE;
32  }
33 
34  ATH_CHECK( m_muKey.initialize() );
35  ATH_CHECK( m_pvKey.initialize() );
36  ATH_CHECK( m_rhoKey.initialize() );
38 
39 
40 
41  if(m_doSequentialResidual) ATH_MSG_DEBUG("The pileup residual calibrations will be applied sequentially.");
42  else ATH_MSG_DEBUG("The pileup residual calibrations will be applied simultaneously (default).");
43  if(m_doMuOnly) ATH_MSG_INFO("Only the pileup mu-based calibration will be applied.");
44  if(m_doNPVOnly) ATH_MSG_INFO("Only the pileup NPV-based calibration will be applied.");
45  if(m_doNJetOnly) ATH_MSG_INFO("Only the pileup NJet-based calibration will be applied.");
46  if (m_useNjet) ATH_MSG_DEBUG("NJet will be used instead of NPV in the pileup corrections.");
47 
48  // Protections
50  "Sequential residual calibration can not be applied in doMuOnly or doNPVOnly or doNJetOnly cases.");
51 
53  "Conflicting configuation, UseNjet true but doMuOnly or doNPVOnly also true.");
54 
56  "It was requested to apply only the mu-based AND the NPV-based calibrations.");
57 
59  "It was requested to apply only the mu-based AND the NJet-based calibrations.");
60 
62  "It was requested to apply only the NJet-based calibration but not to use Njet instead of NPV.");
63 
65  "It was requested to apply NJet-based and NPV calibrations.");
66 
67  if(m_doJetArea) ATH_MSG_INFO("Jet area pile up correction will be applied.");
68 
69 
71  "OffsetCorrection.DefaultMuRef not specified.");
72 
74  "OffsetCorrection.DefaultNPVRef not specified.");
75 
77  "OffsetCorrection.DefaultNjetRef not specified.");
78 
79 
80  m_resOffsetBins = new TAxis(m_offsetEtaBins.size()-1,&m_offsetEtaBins[0]);
81 
82  if(!m_doNPVOnly && !m_doNJetOnly){
83  CHECK_THEN_ERROR( (int)m_resOffsetMu.size()!=(m_resOffsetBins->GetNbins()+1),
84  "Incorrect specification of MuTerm binning" );
85  }
86 
87  if(m_useNjet) {
88  CHECK_THEN_ERROR( (int)m_resOffsetNjet.size()!= (m_resOffsetBins->GetNbins()+1),
89  "Incorrect specification of nJetTerm binning." );
90  } else if(!m_doMuOnly){
91  CHECK_THEN_ERROR( (int)m_resOffsetNPV.size()!= (m_resOffsetBins->GetNbins()+1),
92  "Incorrect specification of NPVTerm binning." );
93 
96  ATH_MSG_INFO("\n NPV beamspot correction will be applied.");
97  }
98  }
99 
100  return StatusCode::SUCCESS;
101 }
102 
103 
104 
106 
108  CHECK_THEN_ERROR( ! eventInfoDecor.isPresent() , "EventInfo decoration not available! "<< m_muKey.key() );
109  double mu = eventInfoDecor(0) ;
110 
111 
113  CHECK_THEN_ERROR( ! PVCont.isValid() , "No Primary Vertices "<< m_pvKey.key() );
114  double NPV = JetCalibUtils::countNPV(*PVCont);
115 
117  CHECK_THEN_ERROR( ! eventShape.isValid() , "Could not retrieve xAOD::EventShape DataHandle : "<< m_rhoKey.key());
118  double rho=0;
120  "Could not retrieve xAOD::EventShape::Density from xAOD::EventShape "<< m_rhoKey.key() );
121 
122  int nJets=0;
123  if(m_useNjet){
125  CHECK_THEN_ERROR( !nJetCont.isValid() , "Jet container needed for nJet not found: "<< m_nJetContainerKey.key());
126  for(const xAOD::Jet*jet: *nJetCont){
127  if(jet->pt()/1000. > m_njetThreshold)
128  nJets += 1;
129  }
130  }
131 
132 
133  ATH_MSG_DEBUG(" Rho = " << 0.001*rho << " GeV");
134  static const double toGeV = 0.001;
136  const xAOD::JetAttributeAccessor::AccessorWrapper<xAOD::JetFourMom_t> puScaleMomAcc("JetPileupScaleMomentum");
137  const xAOD::JetAttributeAccessor::AccessorWrapper<xAOD::JetFourMom_t> cstScaleMomAcc("JetConstitScaleMomentum");
138  SG::AuxElement::Accessor<int> puCorrectedAcc("PileupCorrected");
139 
140  for( xAOD::Jet * jet : jetCont){
141 
142 
143  xAOD::JetFourMom_t jetStartP4 = cstScaleMomAcc.getAttribute(*jet);
144 
145  const double E_det = jetStartP4.e();
146  const double pT_det = jetStartP4.pt();
147  const double eta_det = jetStartP4.eta();
148  const double mass_det = jetStartP4.mass();
149 
150  if ( E_det < mass_det ) {
151  ATH_MSG_ERROR( "JetPileupCorrection::calibrateImpl : Current jet has mass=" << mass_det*toGeV << " GeV, which is greater than it's energy=" << E_det*toGeV << " GeV?? Aborting." );
152  return StatusCode::FAILURE;
153  }
154 
155  xAOD::JetFourMom_t jetareaP4 = areaAcc.getAttribute(*jet);
156  ATH_MSG_VERBOSE(" Area = " << jetareaP4);
157 
158  double offsetET = 0; // pT residual subtraction
159  double pT_offset = pT_det; // pT difference before/after pileup corrections
160  double pileup_SF = 1; // final calibration factor applied to the four vector
161 
162  xAOD::JetFourMom_t calibP4;
163  if(!m_doSequentialResidual){ // Default, both corrections are applied simultaneously
164 
165  offsetET = getResidualOffset(fabs(eta_det), mu, NPV, nJets, m_doMuOnly, m_doNPVOnly||m_doNJetOnly);
166 
167  // Calculate the pT after jet areas and residual offset
168  pT_offset = m_doJetArea ? pT_det - rho*jetareaP4.pt() - offsetET : pT_det - offsetET;
169 
170  // Set the jet pT to 10 MeV if the pT is negative after the jet area and residual offset corrections
171  pileup_SF = pT_offset >= 0 ? pT_offset / pT_det : 10./pT_det;
172 
173  calibP4 = jetStartP4*pileup_SF;
174 
175  }else{
176  // Calculate mu-based correction factor
177  offsetET = getResidualOffset(fabs(eta_det), mu, NPV, nJets, true, false);
178  pT_offset = m_doJetArea ? pT_det - rho*jetareaP4.pt() - offsetET : pT_det - offsetET;
179  double muSF = pT_offset >= 0 ? pT_offset / pT_det : 10./pT_det;
180 
181  calibP4 = jetStartP4*muSF;
182 
183  // Calculate and apply NPV/Njet-based calibration
184  offsetET = getResidualOffset(fabs(eta_det), mu, NPV, nJets, false, true);
185  double pT_afterMuCalib = calibP4.pt();
186  pT_offset = pT_afterMuCalib - offsetET;
187  double SF = pT_offset >= 0 ? pT_offset / pT_afterMuCalib : 10./pT_afterMuCalib;
188  calibP4 = calibP4*SF;
189 
190  }
191 
192  //Attribute to track if a jet has received the pileup subtraction (always true if this code was run)
193  puCorrectedAcc(*jet) = 1 ;
194  //Transfer calibrated jet properties to the Jet object
195  puScaleMomAcc.setAttribute(*jet, calibP4 );
196  jet->setJetP4( calibP4 );
197 
198  }
199 
200 
201  return StatusCode::SUCCESS;
202 }
203 
204 
205 double Pileup1DResidualCalibStep::getResidualOffset ( double abseta, double mu, double NPV,
206  int nJet, bool MuOnly, bool NOnly ) const {
207  return getResidualOffsetET(abseta, mu, NPV, nJet, MuOnly, NOnly,
209 }
210 
211 double Pileup1DResidualCalibStep::getResidualOffsetET( double abseta, double mu, double NPV,
212  int nJet, bool MuOnly, bool NOnly,
213  const std::vector<double>& OffsetMu,
214  const std::vector<double>& OffsetNPV,
215  const std::vector<double>& OffsetNjet,
216  const TAxis *OffsetBins ) const {
217 
218  static const double toMeV= 1000.;
219  //mu rescaling
220  const double muCorr = m_isData ? mu : mu*m_muSF;
221  if(m_useNjet) {
222  // further correction to nJet if desired
223  int nJetCorr = nJet;
224 
225  double alpha, beta, etaEdge;
226  if(!MuOnly){ beta = OffsetNjet[0];
227  } else { beta = 0; }
228  if(!NOnly){ alpha = OffsetMu[0];
229  } else { alpha = 0; }
230  etaEdge=0;
231  int bin=1;
232  for (;bin<=OffsetBins->GetNbins();++bin) {
233  etaEdge = OffsetBins->GetBinLowEdge(bin);
234  const double width=OffsetBins->GetBinWidth(bin);
235  if (abseta<etaEdge+width) break;
236  if(!NOnly) alpha += width*OffsetMu[bin];
237  if(!MuOnly) beta += width*OffsetNjet[bin];
238  }
239  if(!NOnly) alpha += OffsetMu[bin]*(abseta-etaEdge);
240  if(!MuOnly) beta += OffsetNjet[bin]*(abseta-etaEdge);
241  return (alpha*(muCorr-m_mu_ref) + beta*(nJetCorr-m_nJet_ref))*toMeV;
242  } else {
243  //NPV beamspot correction
244  const double NPVCorr = getNPVBeamspotCorrection(NPV);
245 
246  double alpha, beta, etaEdge;
247  if(!MuOnly){ beta = OffsetNPV[0];
248  } else { beta = 0; }
249  if(!NOnly){ alpha = OffsetMu[0];
250  } else { alpha = 0; }
251  etaEdge = 0;
252  int bin=1;
253  for (;bin<=OffsetBins->GetNbins();++bin) {
254  etaEdge = OffsetBins->GetBinLowEdge(bin);
255  const double width=OffsetBins->GetBinWidth(bin);
256  if (abseta<etaEdge+width) break;
257  if(!NOnly) alpha += width*OffsetMu[bin];
258  if(!MuOnly) beta += width*OffsetNPV[bin];
259  }
260  if(!NOnly) alpha += OffsetMu[bin]*(abseta-etaEdge);
261  if(!MuOnly) beta += OffsetNPV[bin]*(abseta-etaEdge);
262  return (alpha*(muCorr-m_mu_ref) + beta*(NPVCorr-m_NPV_ref))*toMeV;
263  }
264 
265 }
266 
268  if(!m_isData && m_applyNPVBeamspotCorrection) return std::as_const(m_npvBeamspotCorr)->GetNVertexBsCorrection(NPV);
269  return NPV;
270 }
xAOD::EventShape_v1::getDensity
bool getDensity(EventDensityID id, double &v) const
Get a density variable from the object.
Definition: EventShape_v1.cxx:135
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
add-xsec-uncert-quadrature-N.alpha
alpha
Definition: add-xsec-uncert-quadrature-N.py:110
Pileup1DResidualCalibStep::calibrate
virtual StatusCode calibrate(xAOD::JetContainer &jetCont) const override
Apply calibration to a jet container.
Definition: Pileup1DResidualCalibStep.cxx:105
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Pileup1DResidualCalibStep::m_applyNPVBeamspotCorrection
Gaudi::Property< bool > m_applyNPVBeamspotCorrection
Definition: Pileup1DResidualCalibStep.h:106
Pileup1DResidualCalibStep::m_doOnlyResidual
Gaudi::Property< bool > m_doOnlyResidual
Definition: Pileup1DResidualCalibStep.h:111
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
Pileup1DResidualCalibStep::getNPVBeamspotCorrection
double getNPVBeamspotCorrection(double NPV) const
Definition: Pileup1DResidualCalibStep.cxx:267
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
xAOD::JetAttributeAccessor::AccessorWrapper::setAttribute
void setAttribute(SG::AuxElement &p, const TYPE &v) const
Definition: JetAccessors.h:54
asg
Definition: DataHandleTestTool.h:28
TRT_PAI_gasdata::SF
const float SF[NF]
Cross sections for Fluor.
Definition: TRT_PAI_gasdata.h:285
bin
Definition: BinsDiffFromStripMedian.h:43
xAOD::JetAttributeAccessor::AccessorWrapper::getAttribute
void getAttribute(const SG::AuxElement &p, TYPE &v) const
Definition: JetAccessors.h:58
SG::ReadDecorHandle::isPresent
bool isPresent() const
Is the referenced container present in SG?
Pileup1DResidualCalibStep::m_doMuOnly
Gaudi::Property< bool > m_doMuOnly
Definition: Pileup1DResidualCalibStep.h:78
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
Pileup1DResidualCalibStep::m_isData
Gaudi::Property< bool > m_isData
Definition: Pileup1DResidualCalibStep.h:67
NPVBeamspotCorrection.h
Pileup1DResidualCalibStep::m_npvBeamspotCorr
NPVBeamspotCorrection * m_npvBeamspotCorr
Definition: Pileup1DResidualCalibStep.h:107
IJetCalibrationTool.h
Pileup1DResidualCalibStep.h
xAOD::EventShape_v1::Density
@ Density
Definition: EventShape_v1.h:47
Pileup1DResidualCalibStep::m_resOffsetBins
TAxis * m_resOffsetBins
Definition: Pileup1DResidualCalibStep.h:103
Pileup1DResidualCalibStep::initialize
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
Definition: Pileup1DResidualCalibStep.cxx:27
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SG::ReadDecorHandle
Handle class for reading a decoration on an object.
Definition: StoreGate/StoreGate/ReadDecorHandle.h:94
Pileup1DResidualCalibStep::m_offsetEtaBins
Gaudi::Property< std::vector< double > > m_offsetEtaBins
Definition: Pileup1DResidualCalibStep.h:99
Pileup1DResidualCalibStep::m_nJetContainerKey
SG::ReadHandleKey< xAOD::JetContainer > m_nJetContainerKey
Definition: Pileup1DResidualCalibStep.h:87
Pileup1DResidualCalibStep::m_resOffsetNjet
Gaudi::Property< std::vector< double > > m_resOffsetNjet
Definition: Pileup1DResidualCalibStep.h:101
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
CHECK_THEN_ERROR
#define CHECK_THEN_ERROR(checkcode, message)
Definition: JetCalibUtils.h:20
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Pileup1DResidualCalibStep::m_muKey
SG::ReadDecorHandleKey< xAOD::EventInfo > m_muKey
Definition: Pileup1DResidualCalibStep.h:70
Pileup1DResidualCalibStep::m_nJet_ref
Gaudi::Property< float > m_nJet_ref
Definition: Pileup1DResidualCalibStep.h:84
toGeV
#define toGeV
Definition: HIEfficiencyResponseHistos.cxx:16
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Pileup1DResidualCalibStep::m_useNjet
Gaudi::Property< bool > m_useNjet
Definition: Pileup1DResidualCalibStep.h:90
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
jet::PileupComp::OffsetNPV
@ OffsetNPV
Definition: UncertaintyEnum.h:165
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
Pileup1DResidualCalibStep::m_mu_ref
Gaudi::Property< float > m_mu_ref
Definition: Pileup1DResidualCalibStep.h:83
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
xAOD::JetFourMom_t
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
Definition: JetTypes.h:17
Pileup1DResidualCalibStep::m_doSequentialResidual
Gaudi::Property< bool > m_doSequentialResidual
Definition: Pileup1DResidualCalibStep.h:109
PathResolver.h
JetCalibUtils.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
plotBeamSpotVxVal.bin
int bin
Definition: plotBeamSpotVxVal.py:83
Pileup1DResidualCalibStep::getResidualOffset
double getResidualOffset(double abseta, double mu, double NPV, int nJet, bool MuOnly, bool NOnly) const
Definition: Pileup1DResidualCalibStep.cxx:205
Pileup1DResidualCalibStep::Pileup1DResidualCalibStep
Pileup1DResidualCalibStep(const std::string &name="Pileup1DResidualCalibStep")
Definition: Pileup1DResidualCalibStep.cxx:21
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
jet::PileupComp::OffsetMu
@ OffsetMu
Definition: UncertaintyEnum.h:166
Pileup1DResidualCalibStep::m_NPV_ref
Gaudi::Property< float > m_NPV_ref
Definition: Pileup1DResidualCalibStep.h:82
Pileup1DResidualCalibStep::m_doNJetOnly
Gaudi::Property< bool > m_doNJetOnly
Definition: Pileup1DResidualCalibStep.h:80
Base_Fragment.width
width
Definition: Sherpa_i/share/common/Base_Fragment.py:59
Pileup1DResidualCalibStep::m_doNPVOnly
Gaudi::Property< bool > m_doNPVOnly
Definition: Pileup1DResidualCalibStep.h:79
xAOD::JetAttributeAccessor::AccessorWrapper< xAOD::JetFourMom_t >
Pileup1DResidualCalibStep::m_njetThreshold
Gaudi::Property< int > m_njetThreshold
Definition: Pileup1DResidualCalibStep.h:91
Pileup1DResidualCalibStep::m_resOffsetNPV
Gaudi::Property< std::vector< double > > m_resOffsetNPV
Definition: Pileup1DResidualCalibStep.h:102
ReadDecorHandle.h
Handle class for reading a decoration on an object.
Pileup1DResidualCalibStep::m_rhoKey
SG::ReadHandleKey< xAOD::EventShape > m_rhoKey
Definition: Pileup1DResidualCalibStep.h:74
Pileup1DResidualCalibStep::m_pvKey
SG::ReadHandleKey< xAOD::VertexContainer > m_pvKey
Definition: Pileup1DResidualCalibStep.h:75
JetCalibUtils::countNPV
int countNPV(const VXCONT &vxCont)
Definition: JetCalibUtils.h:39
Pileup1DResidualCalibStep::m_muSF
Gaudi::Property< float > m_muSF
Definition: Pileup1DResidualCalibStep.h:85
Pileup1DResidualCalibStep::m_doJetArea
Gaudi::Property< bool > m_doJetArea
Definition: Pileup1DResidualCalibStep.h:68
MuonParameters::beta
@ beta
Definition: MuonParamDefs.h:144
JetAccessors.h
This header defines wrapper classes around SG::AuxElement::Accessor used internally in the Jet EDM.
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:30
Pileup1DResidualCalibStep::m_resOffsetMu
Gaudi::Property< std::vector< double > > m_resOffsetMu
Definition: Pileup1DResidualCalibStep.h:100
Pileup1DResidualCalibStep::getResidualOffsetET
double getResidualOffsetET(double abseta, double mu, double NPV, int nJet, bool MuOnly, bool NOnly, const std::vector< double > &OffsetMu, const std::vector< double > &OffsetNPV, const std::vector< double > &OffsetNjet, const TAxis *OffsetBins) const
Definition: Pileup1DResidualCalibStep.cxx:211
fitman.rho
rho
Definition: fitman.py:532
NPVBeamspotCorrection
Definition: NPVBeamspotCorrection.h:21