ATLAS Offline Software
Loading...
Searching...
No Matches
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
15
16using namespace std;
17
18//------------------------------------------------------------------------------
19
20PuppiWeightTool::PuppiWeightTool(const std::string& name) :
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
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;
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;
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}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading from StoreGate.
bool isCharged(const T &p)
Definition AtlasPID.h:1004
double charge(const T &p)
Definition AtlasPID.h:997
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool empty() const noexcept
Returns true if the collection is empty.
JetConstituentModifierBase(const std::string &name)
virtual StatusCode finalize() override
double m_centralPTCutOffset
StatusCode applyPuppiWeights(xAOD::PFOContainer *cont) const
virtual StatusCode process_impl(xAOD::IParticleContainer *cont) const override final
PuppiWeightTool(const std::string &name)
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexContainer_key
virtual StatusCode initialize() override final
Dummy implementation of the initialisation function.
bool m_includeCentralNeutralsInAlpha
double m_forwardPTCutOffset
Definition Puppi.h:22
double getMedian()
Definition Puppi.cxx:163
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
double getAlpha(const fastjet::PseudoJet &pfo)
Definition Puppi.cxx:83
double getWeight(const fastjet::PseudoJet &pfo)
Definition Puppi.cxx:49
double getRMS()
Definition Puppi.cxx:166
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
STL namespace.
@ ParticleFlow
The object is a particle-flow object.
Definition ObjectType.h:41
@ FlowElement
The object is a track-calo-cluster.
Definition ObjectType.h:52
FlowElementContainer_v1 FlowElementContainer
Definition of the current "pfo container version".
PFO_v1 PFO
Definition of the current "pfo version".
Definition PFO.h:17
PFOContainer_v1 PFOContainer
Definition of the current "pfo container version".
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition FlowElement.h:16
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.