ATLAS Offline Software
PuppiWeightTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
5 
6 #include "fastjet/PseudoJet.hh"
7 #include <vector>
8 
9 #include "xAODCore/ShallowCopy.h"
15 
16 using namespace std;
17 
18 //------------------------------------------------------------------------------
19 
22 
23  declareProperty("R0", m_R0 = 0.3);
24  declareProperty("Rmin", m_Rmin = 0.001);
25  declareProperty("Beta", m_beta = 1);
26  declareProperty("CentralPTCutOffset", m_centralPTCutOffset = 0);
27  declareProperty("CentralPTCutSlope", m_centralPTCutSlope = 0);
28  declareProperty("ForwardPTCutOffset", m_forwardPTCutOffset = 0);
29  declareProperty("ForwardPTCutSlope", m_forwardPTCutSlope = 0);
30  declareProperty("EtaBoundary",m_etaBoundary = 2.5);
31 
32  declareProperty("ApplyWeight",m_applyWeight=true);
33  declareProperty("IncludeCentralNeutralsInAlpha",m_includeCentralNeutralsInAlpha=false);
34 }
35 
36 //------------------------------------------------------------------------------
37 
39  ATH_MSG_INFO("Initializing tool " << name() << "...");
40 
41  ATH_CHECK(m_vertexContainer_key.initialize());
42 
44  if(!m_applyToNeutralPFO) {
45  ATH_MSG_ERROR("Incompatible configuration: ApplyToNeutralPFO=False -- what kind of pileup do you wish to suppress?");
46  return StatusCode::FAILURE;
47  }
48  } else {
49  ATH_MSG_ERROR("Incompatible configuration: PUPPI canot be used for inputs of type " << m_inputType);
50  return StatusCode::FAILURE;
51  }
52 
53  return StatusCode::SUCCESS;
54 }
55 
56 //------------------------------------------------------------------------------
57 
59  ATH_MSG_INFO("Finializing tool " << name() << "...");
60 
61  return StatusCode::SUCCESS;
62 }
63 
64 //------------------------------------------------------------------------------
65 
68  xAOD::FlowElementContainer* feCont = static_cast<xAOD::FlowElementContainer*> (cont);
69  return applyPuppiWeights(feCont);
70  }
71  xAOD::PFOContainer* pfoCont = static_cast<xAOD::PFOContainer*> (cont);
72  return applyPuppiWeights(pfoCont);
73 }
74 
75 //------------------------------------------------------------------------------
76 
78 
79  const static SG::AuxElement::Accessor<bool> PVMatchedAcc("matchedToPV");
80  const static SG::AuxElement::Accessor<double> alphaAcc("PUPPI_alpha");
81  const static SG::AuxElement::Accessor<double> weightAcc("PUPPI_weight");
82 
83  std::vector<fastjet::PseudoJet> chargedHSVector;
84  std::vector<fastjet::PseudoJet> chargedPUVector;
85  std::vector<fastjet::PseudoJet> neutralVector;
86  std::vector<fastjet::PseudoJet> forwardVector;
87 
88  // Fill input particle vectors for puppi
89  for ( xAOD::PFO* ppfo : *cont ) {
90  if (!PVMatchedAcc.isAvailable(*ppfo)){
91  ATH_MSG_ERROR("Not known if PFO is matched to primary vertex. Run CorrectPFOTool before ChargedHadronSubtractionTool");
92  return StatusCode::FAILURE;
93  }
94 
95  if (ppfo->pt()<=FLT_MIN) continue;
96 
97  fastjet::PseudoJet pj(ppfo->p4());
98  //pj.set_user_info(new PuppiUserInfo({someOtherChi2,yetAnotherChi2})); //example of how additional information could be exploited - needs to be calculated somewhere above
99 
100  float charge = ppfo->charge();
101  bool isCharged = (fabs(charge) > FLT_MIN);
102 
103  if(fabs(ppfo->eta()) > m_etaBoundary) forwardVector.push_back(pj);
104  else{
105  if(isCharged){
106  bool matchedToPrimaryVertex=PVMatchedAcc(*ppfo);
107  if(matchedToPrimaryVertex) chargedHSVector.push_back(pj);
108  else chargedPUVector.push_back(pj);
109  }
110  else neutralVector.push_back(pj);
111  }
112  }
113 
114  //Count the number of primary vertices
115  const xAOD::VertexContainer* pvtxs = nullptr;
116  auto handle = SG::makeHandle(m_vertexContainer_key);
117  if (!handle.isValid()){
118  ATH_MSG_WARNING(" This event has no primary vertices " );
119  return StatusCode::FAILURE;
120  }
121 
122  pvtxs = handle.cptr();
123  if(pvtxs->empty()){
124  ATH_MSG_WARNING(" This event has no primary vertices " );
125  return StatusCode::FAILURE;
126  }
127 
128  int nPV=0;
129  for( const auto *vtx_itr : *pvtxs ){
130  if((int)vtx_itr->nTrackParticles() < 2 ) continue;
131  ++nPV;
132  }
133 
135  puppi.setParticles(chargedHSVector, chargedPUVector, neutralVector, forwardVector, nPV);
136 
137  for ( xAOD::PFO* ppfo : *cont ) {
138  float charge = ppfo->charge();
139  bool isCharged = (fabs(charge) > FLT_MIN);
140  bool isForward = (fabs(ppfo->eta()) > m_etaBoundary);
141 
142  fastjet::PseudoJet pj(ppfo->p4());
143 
144  double weight = puppi.getWeight(pj);
145  double alpha = puppi.getAlpha(pj);
146 
147  if ((!isCharged || isForward) && m_applyWeight) ppfo->setP4(weight*ppfo->p4());
148  alphaAcc(*ppfo) = alpha;
149  weightAcc(*ppfo) = weight;
150  }
151 
152  ATH_MSG_DEBUG("Median: "<<puppi.getMedian());
153  ATH_MSG_DEBUG("RMS: "<<puppi.getRMS());
154 
155  return StatusCode::SUCCESS;
156 }
157 
159 
160  const static SG::AuxElement::Accessor<bool> PVMatchedAcc("matchedToPV");
161  const static SG::AuxElement::Accessor<double> alphaAcc("PUPPI_alpha");
162  const static SG::AuxElement::Accessor<double> weightAcc("PUPPI_weight");
163 
164  std::vector<fastjet::PseudoJet> chargedHSVector;
165  std::vector<fastjet::PseudoJet> chargedPUVector;
166  std::vector<fastjet::PseudoJet> neutralVector;
167  std::vector<fastjet::PseudoJet> forwardVector;
168 
169  // Fill input particle vectors for puppi
170  for ( xAOD::FlowElement* pfe : *cont ) {
171  if (!PVMatchedAcc.isAvailable(*pfe)){
172  ATH_MSG_ERROR("Not known if FlowElement is matched to primary vertex. Run CorrectPFOTool before ChargedHadronSubtractionTool");
173  return StatusCode::FAILURE;
174  }
175 
176  if (pfe->pt()<=FLT_MIN) continue;
177 
178  fastjet::PseudoJet pj(pfe->p4());
179 
180  if(fabs(pfe->eta()) > m_etaBoundary) forwardVector.push_back(pj);
181  else{
182  if(pfe->isCharged()){
183  bool matchedToPrimaryVertex=PVMatchedAcc(*pfe);
184  if(matchedToPrimaryVertex) chargedHSVector.push_back(pj);
185  else chargedPUVector.push_back(pj);
186  }
187  else neutralVector.push_back(pj);
188  }
189  }
190 
191  //Count the number of primary vertices
192  const xAOD::VertexContainer* pvtxs = nullptr;
193  auto handle = SG::makeHandle(m_vertexContainer_key);
194  if (!handle.isValid()){
195  ATH_MSG_WARNING(" This event has no primary vertices " );
196  return StatusCode::FAILURE;
197  }
198 
199  pvtxs = handle.cptr();
200  if(pvtxs->empty()){
201  ATH_MSG_WARNING(" This event has no primary vertices " );
202  return StatusCode::FAILURE;
203  }
204 
205  int nPV=0;
206  for( const auto *vtx_itr : *pvtxs ){
207  if((int)vtx_itr->nTrackParticles() < 2 ) continue;
208  ++nPV;
209  }
210 
212  puppi.setParticles(chargedHSVector, chargedPUVector, neutralVector, forwardVector, nPV);
213 
214  for ( xAOD::FlowElement* pfe : *cont ) {
215  bool isForward = (fabs(pfe->eta()) > m_etaBoundary);
216 
217  fastjet::PseudoJet pj(pfe->p4());
218 
219  double weight = puppi.getWeight(pj);
220  double alpha = puppi.getAlpha(pj);
221 
222  if ((!(pfe->isCharged()) || isForward) && m_applyWeight) pfe->setP4(weight*pfe->p4());
223  alphaAcc(*pfe) = alpha;
224  weightAcc(*pfe) = weight;
225  }
226 
227  ATH_MSG_DEBUG("Median: "<<puppi.getMedian());
228  ATH_MSG_DEBUG("RMS: "<<puppi.getRMS());
229 
230  return StatusCode::SUCCESS;
231 }
ShallowCopy.h
PuppiWeightTool::m_vertexContainer_key
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexContainer_key
Definition: PuppiWeightTool.h:48
Puppi::getMedian
double getMedian()
Definition: Puppi.cxx:163
JetConstituentModifierBase::m_applyToNeutralPFO
bool m_applyToNeutralPFO
Definition: JetConstituentModifierBase.h:63
PuppiWeightTool::applyPuppiWeights
StatusCode applyPuppiWeights(xAOD::PFOContainer *cont) const
Definition: PuppiWeightTool.cxx:77
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PuppiWeightTool::process_impl
virtual StatusCode process_impl(xAOD::IParticleContainer *cont) const override final
Definition: PuppiWeightTool.cxx:66
Puppi
Definition: Puppi.h:22
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:66
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
Puppi::setParticles
void setParticles(const std::vector< fastjet::PseudoJet > &chargedHS, const std::vector< fastjet::PseudoJet > &chargedPU, const std::vector< fastjet::PseudoJet > &neutral, const std::vector< fastjet::PseudoJet > &forward, int nPU)
Definition: Puppi.cxx:26
PuppiWeightTool::initialize
virtual StatusCode initialize() override final
Dummy implementation of the initialisation function.
Definition: PuppiWeightTool.cxx:38
ShallowAuxContainer.h
PuppiWeightTool::m_Rmin
double m_Rmin
Definition: PuppiWeightTool.h:37
PuppiWeightTool::finalize
virtual StatusCode finalize() override
Definition: PuppiWeightTool.cxx:58
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:269
PuppiWeightTool::m_applyWeight
bool m_applyWeight
Definition: PuppiWeightTool.h:46
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
PuppiWeightTool::m_R0
double m_R0
Definition: PuppiWeightTool.h:36
CaloCluster.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
PuppiWeightTool::m_forwardPTCutSlope
double m_forwardPTCutSlope
Definition: PuppiWeightTool.h:42
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Puppi::getAlpha
double getAlpha(const fastjet::PseudoJet &pfo)
Definition: Puppi.cxx:83
xAOD::FlowElement
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition: FlowElement.h:16
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAODType::ParticleFlow
@ ParticleFlow
The object is a particle-flow object.
Definition: ObjectType.h:41
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
PuppiWeightTool::m_beta
double m_beta
Definition: PuppiWeightTool.h:38
xAOD::PFO_v1
Class describing a particle flow object.
Definition: PFO_v1.h:35
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
JetConstituentModifierBase
Definition: JetConstituentModifierBase.h:22
ReadHandle.h
Handle class for reading from StoreGate.
PuppiWeightTool::m_etaBoundary
double m_etaBoundary
Definition: PuppiWeightTool.h:43
charge
double charge(const T &p)
Definition: AtlasPID.h:494
PuppiWeightTool.h
Puppi::getRMS
double getRMS()
Definition: Puppi.cxx:166
JetConstituentModifierBase::m_inputType
unsigned int m_inputType
Definition: JetConstituentModifierBase.h:60
isCharged
bool isCharged(const T &p)
Definition: AtlasPID.h:496
PuppiWeightTool::m_centralPTCutSlope
double m_centralPTCutSlope
Definition: PuppiWeightTool.h:40
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Puppi::getWeight
double getWeight(const fastjet::PseudoJet &pfo)
Definition: Puppi.cxx:49
CaloClusterContainer.h
SG::ConstAccessor< T, AuxAllocator_t< T > >::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
IParticleHelpers.h
PuppiWeightTool::m_includeCentralNeutralsInAlpha
bool m_includeCentralNeutralsInAlpha
Definition: PuppiWeightTool.h:45
PuppiWeightTool::m_centralPTCutOffset
double m_centralPTCutOffset
Definition: PuppiWeightTool.h:39
PuppiWeightTool::PuppiWeightTool
PuppiWeightTool(const std::string &name)
Definition: PuppiWeightTool.cxx:20
DataVector::empty
bool empty() const noexcept
Returns true if the collection is empty.
PuppiWeightTool::m_forwardPTCutOffset
double m_forwardPTCutOffset
Definition: PuppiWeightTool.h:41
xAOD::FlowElement_v1
A detector object made of other lower level object(s)
Definition: FlowElement_v1.h:25