6#include "fastjet/ClusterSequenceArea.hh"
7#include "fastjet/Selector.hh"
8#include "fastjet/JetDefinition.hh"
9#include "fastjet/tools/JetMedianBackgroundEstimator.hh"
10#include <fastjet/tools/Subtractor.hh>
23 inline bool operator() (
const TLorentzVector& lhs,
const TLorentzVector& rhs)
25 return (lhs.Pt() > rhs.Pt());
28 inline bool operator() (
const TLorentzVector* lhs,
const TLorentzVector* rhs)
30 return (lhs->Pt() > rhs->Pt());
35 return (lhs.
pt() > rhs.
pt());
40 return (lhs->
pt() > rhs->
pt());
48 for(
auto el : *inCont) sortedCont.push_back( el );
57 for(
auto el : *inCont) sortedCont.
push_back( el );
63 bool operator() (
const std::pair<fastjet::PseudoJet, std::vector<float> >& lhsp,
const std::pair<fastjet::PseudoJet, std::vector<float> >& rhsp)
65 fastjet::PseudoJet lhs = lhsp.first;
66 fastjet::PseudoJet rhs = rhsp.first;
67 return lhs.pt()>rhs.pt();
76VoronoiWeightTool :: VoronoiWeightTool(
const std::string& name) :
93 ATH_MSG_ERROR(
"Incompatible configuration: setting both IgnoreChargedPFO and ApplyToChargedPFO to true"
94 <<
"will set all cPFOs to zero");
95 return StatusCode::FAILURE;
98 ATH_MSG_ERROR(
"Incompatible configuration: ApplyToNeutralPFO=False -- what kind of pileup do you wish to suppress?");
99 return StatusCode::FAILURE;
102 return StatusCode::SUCCESS;
110 std::vector<fastjet::PseudoJet> particles; particles.reserve(particlesin->
size());
114 bool accept = part->e() > -1*FLT_MIN;
121 accept &= fabs(pfo->
charge())<FLT_MIN;
125 accept &= (tcc->
taste()!= 0);
136 particles.emplace_back(part->p4() );
141 std::vector< std::pair< fastjet::PseudoJet, std::vector<float> > > ptvec;
158 bool accept = part->e() > FLT_MIN;
162 accept &= fabs(pfo->
charge())<FLT_MIN;
166 accept &= (tcc->
taste()!= 0);
180 bool endContainer = part->e()<FLT_MIN;
181 bool endVec = i>=ptvec.size();
182 if(endVec && endContainer){
185 else if(endContainer || endVec){
186 ATH_MSG_ERROR(
"Filtered particle list doesn't have same number of elements as the list returned by FastJet.");
187 return StatusCode::FAILURE;
191 float Containerpt = part->pt();
192 float PJpt = ptvec[i].first.pt();
193 ATH_MSG_VERBOSE(
"Container pt: " << Containerpt <<
", fastjet initial pt: " << PJpt
194 <<
", subtracted pt: " << ptvec[i].second[alg]);
195 if (fabs(Containerpt-PJpt) > 0.1){
198 return StatusCode::FAILURE;
200 newPt = ptvec[i].second[alg];
207 float w = part->pt()>FLT_MIN ? newPt/part->pt() : 0.;
210 return StatusCode::SUCCESS;
214 std::vector<fastjet::PseudoJet> & inputConst = particles;
215 fastjet::Selector jselector = fastjet::SelectorAbsRapRange(0.0,2.1);
216 fastjet::JetAlgorithm algo = fastjet::kt_algorithm;
218 fastjet::JetDefinition jetDef(algo, jetR,fastjet::E_scheme, fastjet::Best);
219 fastjet::AreaDefinition area_def(fastjet::voronoi_area, fastjet::VoronoiAreaSpec(0.9));
221 fastjet::ClusterSequenceArea clustSeq(inputConst, jetDef, area_def);
222 fastjet::JetMedianBackgroundEstimator bge(jselector,jetDef,area_def);
224 bge.set_particles(inputConst);
225 std::vector<fastjet::PseudoJet> inclusiveJets = sorted_by_pt(clustSeq.inclusive_jets(0));
228 float rho = bge.rho();
229 float sigma = bge.sigma();
230 for(
unsigned int iJet = 0 ; iJet < inclusiveJets.size() ; iJet++){
231 fastjet::PseudoJet
jet = inclusiveJets[iJet];
232 std::vector<fastjet::PseudoJet> constituents =
jet.constituents();
233 for(
const auto& cons : constituents){
234 float pt = cons.pt();
237 float subPt = pt-rho*
area;
238 float voro0pt = subPt * (subPt > 0);
239 float voro1pt = subPt * (subPt > sqrt(
area)*sigma*(float)nsigma);
240 std::vector<float> algopts;
241 algopts.push_back(subPt);
242 algopts.push_back(voro0pt);
243 algopts.push_back(voro1pt);
244 algopts.push_back(0);
245 std::pair <fastjet::PseudoJet,std::vector<float> > pjcptpair (cons,algopts);
246 correctedptvec.push_back(pjcptpair);
252 return StatusCode::SUCCESS;
255void VoronoiWeightTool::spreadPt(std::vector< std::pair< fastjet::PseudoJet,std::vector<float> > >& correctedptvec,
float spreadr,
float alpha)
const{
258 size_t Nparticles = correctedptvec.size();
259 std::vector<float> spreadPT(Nparticles);
260 std::vector<bool> isPositive(Nparticles);
261 for(
size_t iPart = 0; iPart < Nparticles; iPart++){
262 spreadPT[iPart] = correctedptvec[iPart].second[0];
263 isPositive[iPart] = spreadPT[iPart]>0;
266 std::vector<std::vector<std::pair<size_t,float> > > particle_drs;
267 for(
size_t iPart = 0; iPart < Nparticles; iPart++){
268 fastjet::PseudoJet iparticle = correctedptvec[iPart].first;
269 std::vector<std::pair<size_t,float> > this_particle_drs;
270 for(
size_t jPart = 0; jPart < Nparticles; jPart++){
271 if(iPart == jPart)
continue;
272 if(!isPositive[jPart])
continue;
273 fastjet::PseudoJet jparticle = correctedptvec[jPart].first;
274 float dphi = iparticle.delta_phi_to(jparticle);
275 float deta = iparticle.eta() - jparticle.eta();
276 float dr2 =
pow(dphi,2) +
pow(deta,2);
277 if(dr2 >
pow(spreadr,2))
continue;
278 std::pair<size_t,float> jdrpair (jPart,dr2);
279 this_particle_drs.push_back(jdrpair);
281 particle_drs.push_back(this_particle_drs);
284 for(
size_t i = 0; i < Nparticles; i++){
285 if(!(spreadPT[i]<0))
continue;
289 for(
size_t j=0; j<particle_drs[i].size(); j++){
290 float dr = particle_drs[i][j].second;
291 if(dr>FLT_MIN) sumdR2 += 1./(
pow(dr,alpha/2));
294 if(sumdR2 > FLT_MIN){
295 float spreadPT_orig = spreadPT[i];
296 for(
size_t j=0; j<particle_drs[i].size(); j++){
297 float dr = particle_drs[i][j].second;
298 float realid = particle_drs[i][j].first;
300 float weight = (1./
pow(dr,alpha/2))/sumdR2;
301 if(fabs(weight*spreadPT_orig)>spreadPT[realid]){
302 spreadPT[i]+=spreadPT[realid];
306 spreadPT[realid]+=weight*spreadPT_orig;
307 spreadPT[i]-=weight*spreadPT_orig;
314 for(
size_t iPart = 0; iPart < Nparticles; iPart++){
315 correctedptvec[iPart].second[3] = spreadPT[iPart] * (spreadPT[iPart] > 0);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
constexpr int pow(int base, int exp) noexcept
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
DataVector adapter that acts like it holds const pointers.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
iterator begin() noexcept
Return an iterator pointing at the beginning of the collection.
iterator end() noexcept
Return an iterator pointing past the end of the collection.
const DV * asDataVector() const
Return a pointer to this object, as a const DataVector.
size_type size() const noexcept
Returns the number of elements in the collection.
JetConstituentModifierBase(const std::string &name)
StatusCode setEnergyPt(xAOD::IParticle *obj, float e, float pt, const SG::AuxElement::Accessor< float > *weightAcc=nullptr) const
SG::Accessor< T, ALLOC > Accessor
signal_t signalType() const
Class providing the definition of the 4-vector interface.
virtual double pt() const =0
The transverse momentum ( ) of the particle.
float charge() const
get charge of PFO
virtual int taste() const
The taste of the particle.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
T sort_container_pt(T *inCont)
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
@ ParticleFlow
The object is a particle-flow object.
@ FlowElement
The object is a track-calo-cluster.
@ TrackCaloCluster
The object is a track-calo-cluster.
PFO_v1 PFO
Definition of the current "pfo version".
FlowElement_v1 FlowElement
Definition of the current "pfo version".
TrackCaloCluster_v1 TrackCaloCluster
Reference the current persistent version:
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.
bool operator()(const std::pair< fastjet::PseudoJet, std::vector< float > > &lhsp, const std::pair< fastjet::PseudoJet, std::vector< float > > &rhsp)
bool operator()(const TLorentzVector &lhs, const TLorentzVector &rhs)