ATLAS Offline Software
Loading...
Searching...
No Matches
ConstituentSubtractorTool.cxx
Go to the documentation of this file.
1 /*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Source code for the ConstituentSubtractorTool implementation class
6//
7//
9
11
12
13#include "fastjet/PseudoJet.hh"
14#include "fastjet/contrib/ConstituentSubtractor.hh"
15#include "fastjet/Selector.hh"
16#include "fastjet/tools/GridMedianBackgroundEstimator.hh"
17#include "fastjet/contrib/RescalingClasses.hh"
18
19#include "xAODPFlow/PFO.h"
23#include "TFile.h"
24
25using namespace fastjet;
28
29
31
34 ATH_MSG_ERROR("Incompatible configuration: setting both IgnoreChargedPFO and ApplyToChargedPFO to true"
35 << "will set all cPFOs to zero");
36 return StatusCode::FAILURE;
37 }
39 ATH_MSG_ERROR("Incompatible configuration: ApplyToNeutralPFO=False -- what kind of pileup do you wish to suppress?");
40 return StatusCode::FAILURE;
41 }
42 }
43 ATH_CHECK( m_eventinfokey.initialize() );
44
45
47 ATH_MSG_ERROR("Incompatible configuration: You set both, DoRapidityRescaling and DoRapidityPhiRescaling, to true. Use maximally only one of them.");
48 return StatusCode::FAILURE;
49 }
50
52 ATH_MSG_ERROR("Incompatible configuration: You have chosen a background rescaling, but you have not specified the path to the file with rescaling histograms or the name of the histogram. Specify properties FileRescaling and HistogramRescaling.");
53 return StatusCode::FAILURE;
54 }
55
57 std::string fullPathToFile=PathResolverFindCalibFile(m_rescalingFileName); // returns "" if file not found
58 if (fullPathToFile.empty()){
59 ATH_MSG_ERROR("Incompatible configuration: The provided file for rescaling was not found using PathResolver.");
60 return StatusCode::FAILURE;
61 }
62 std::unique_ptr<TFile> file(TFile::Open(fullPathToFile.data(), "READ"));
63 if (file->IsZombie()){
64 ATH_MSG_ERROR("Incompatible configuration: The file for rescaling has been tried to open, but it was found it is zombie.");
65 return StatusCode::FAILURE;
66 }
67 std::unique_ptr<TObject> object(file->Get(m_rescalingHistogramName.value().data()));
68 if (!object){
69 ATH_MSG_ERROR("Incompatible configuration: The provided histogram name was not found in the root file.");
70 return StatusCode::FAILURE;
71 }
72
74 if (object->InheritsFrom(TH1D::Class())){
75 m_hist.reset(static_cast<TH1D*>(object->Clone("hist_cloned")));
76 m_hist->SetDirectory(nullptr);
77 m_rescaling.reset(static_cast<fastjet::FunctionOfPseudoJet<double>*>(new contrib::BackgroundRescalingYFromRoot<TH1D>(m_hist.get())));
78 }
79 else{
80 ATH_MSG_ERROR("Incompatible configuration: You want to do rapidity rescaling, but the provided histogram name is not a TH1D.");
81 return StatusCode::FAILURE;
82 }
83 }
85 if (object->InheritsFrom(TH2D::Class())){
86 m_hist2D.reset(static_cast<TH2D*>(object->Clone("hist_cloned")));
87 m_hist2D->SetDirectory(nullptr);
88 m_rescaling.reset(static_cast<fastjet::FunctionOfPseudoJet<double>*>(new contrib::BackgroundRescalingYPhiFromRoot<TH2D>(m_hist2D.get())));
89 }
90 else{
91 ATH_MSG_ERROR("Incompatible configuration: You want to do rapidity-phi rescaling, but the provided histogram name is not a TH2D.");
92 return StatusCode::FAILURE;
93 }
94 }
95 }
96
97
98 return StatusCode::SUCCESS;
99}
100
101
102// Apply PU weighting and decorate the CaloCluster container appropriately:
103
105
106 contrib::ConstituentSubtractor subtractor;
107
108 // free parameter for the maximal allowed distance sqrt((y_i-y_k)^2+(phi_i-phi_k)^2) between particle i and ghost k
109 subtractor.set_max_standardDeltaR(m_maxDeltaR);
110
111 // free parameter for the distance measure (the exponent of particle pt). The larger the parameter alpha, the more are favoured the lower pt particles in the subtraction process
112 subtractor.set_alpha(m_alpha);
113
114 // free parameter for the density of ghosts. The smaller, the better - but also the computation is slower.
115 subtractor.set_ghost_area(m_ghostArea);
116
117 // This is added to fix ATR-23552. It has no effect on the performance. Once the bug is fixed in fastjet-contrib, it can be removed.
118 subtractor.set_use_nearby_hard(-1,-1);
119
120 // prepare PseudoJet input
121 std::vector<PseudoJet> inputs_to_correct, inputs_to_not_correct;
122 inputs_to_correct.reserve(cont->size());
123 inputs_to_not_correct.reserve(cont->size());
124 size_t i =0; // Corresponds to the index in the input container
125 // We don't use part->index() because it might be a view container
126 // combining more than one owning container
127
128 // Minimal and maximum rapidities needed for the workaround for the bug in fastjet-contrib ConstituentSubtractor, see ATLASG-1417
129 double minRap=1000;
130 double maxRap=-1000;
131
132 for(xAOD::IParticle * part: *cont){
133 // Only use positive E
134 bool accept = part->e() > -1*FLT_MIN;
135 // For PFlow we would only want to apply the correction to neutral PFOs,
136 // because charged hadron subtraction handles the charged PFOs.
137 // However, we might still want to use the cPFOs for the min pt calculation
140 xAOD::PFO* pfo = static_cast<xAOD::PFO*>(part);
141 accept &= fabs(pfo->charge())<FLT_MIN;
142 }
144 xAOD::FlowElement* fe = static_cast<xAOD::FlowElement*>(part);
145 accept &= !(fe->isCharged());
146 }
147 }
149 xAOD::TrackCaloCluster* tcc = static_cast<xAOD::TrackCaloCluster*>(part);
150 accept &= (tcc->taste()!= 0)*(tcc->pt()>-1.*FLT_MIN);
151 }
152 // Reject object if outside maximum eta range
153 accept &= fabs(part->eta()) <= m_maxEta;
154
155 PseudoJet pj( part->p4() );
156 pj.set_user_index( i );
157 if(accept) {
158 ATH_MSG_VERBOSE("Using " << part->type() << " with pt " << part->pt());
159 inputs_to_correct.push_back(pj);
160 // Minimal and maximum rapidities needed for the workaround for the bug in fastjet-contrib ConstituentSubtractor, see ATLASG-1417
161 if (pj.rap()<minRap) minRap = pj.rap();
162 if (pj.rap()>maxRap) maxRap = pj.rap();
163 } else {
164 ATH_MSG_VERBOSE("Will not correct " << part->type() << " with pt " << part->pt());
165 inputs_to_not_correct.push_back(pj);
166 }
167
168 ++i;
169 }
170
171 // create what we need for the background estimation
172 //----------------------------------------------------------
173 // maximal rapidity is used (not pseudo-rapidity). Since the inputs are massless, it does not matter
174 GridMedianBackgroundEstimator bge_rho(m_maxRapForRhoComputation, m_gridSize);
175 bge_rho.set_rescaling_class(m_rescaling.get());
176 bge_rho.set_particles(inputs_to_correct);
177 subtractor.set_background_estimator(&bge_rho);
178
179 // for massless input particles it does not make any difference (rho_m is always zero)
180
181 ATH_MSG_DEBUG("Subtracting event density from constituents");
182 std::vector<PseudoJet> corrected_event=subtractor.subtract_event(inputs_to_correct,m_maxEta);
183
184 // Define a vector holding the corrected four-momenta for all output constituents
185 // This is defaulted to zero, because fastjet will only return non-zero pseudojets
186 std::vector<xAOD::JetFourMom_t> corrected_p4s(cont->size(),xAOD::JetFourMom_t(0.,0.,0.,0.));
187 // Set the corrected four-vectors
188 for(PseudoJet & pj : corrected_event) {
189 ATH_MSG_VERBOSE("Setting four-mom for constituent " << pj.user_index() << ", pt = " << pj.pt());
190 corrected_p4s[pj.user_index()].SetCoordinates(pj.pt(),pj.eta(),pj.phi(),pj.m());
191 }
192 for(PseudoJet & pj : inputs_to_not_correct) {
193 ATH_MSG_VERBOSE("Setting four-mom for constituent " << pj.user_index() << ", pt = " << pj.pt());
194 corrected_p4s[pj.user_index()].SetCoordinates(pj.pt(),pj.eta(),pj.phi(),pj.m());
195 }
196 for(PseudoJet & pj : inputs_to_not_correct) {
197 ATH_MSG_VERBOSE("Setting four-mom for constituent " << pj.user_index() << ", pt = " << pj.pt());
198 corrected_p4s[pj.user_index()].SetCoordinates(pj.pt(),pj.eta(),pj.phi(),pj.m());
199 }
200
201 // Set every constituent's four-vector in the output container
202 i = 0; // Again, we need to track the input container index, not the owning container index
203 const static SG::AuxElement::Accessor<float> weightAcc("CSWeight"); // Handle for PU weighting here
204 for(xAOD::IParticle * part: *cont){
205 ATH_MSG_VERBOSE("Now on constituent " << i);
206 ATH_MSG_VERBOSE("Initial pt: " << part->pt() << ", subtracted pt: " << corrected_p4s[i].Pt());
207 ATH_MSG_VERBOSE("Initial eta: " << part->eta() << ", subtracted pt: " << corrected_p4s[i].Eta());
208 ATH_MSG_VERBOSE("Initial phi: " << part->phi() << ", subtracted pt: " << corrected_p4s[i].Phi());
209 ATH_CHECK( setP4(part,corrected_p4s[i], &weightAcc) );
210 ++i;
211 }
212
213
214
215 return StatusCode::SUCCESS;
216}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading from StoreGate.
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Gaudi::Property< bool > m_ignoreChargedPFOs
Gaudi::Property< float > m_maxRapForRhoComputation
Gaudi::Property< float > m_maxEta
StatusCode initialize()
Dummy implementation of the initialisation function.
Gaudi::Property< std::string > m_rescalingHistogramName
Gaudi::Property< float > m_alpha
Gaudi::Property< std::string > m_rescalingFileName
std::unique_ptr< fastjet::FunctionOfPseudoJet< double > > m_rescaling
Gaudi::Property< float > m_ghostArea
StatusCode process_impl(xAOD::IParticleContainer *cont) const
ConstituentSubtractorTool(const std::string &name)
Gaudi::Property< bool > m_doRapidityPhiRescaling
Gaudi::Property< float > m_maxDeltaR
SG::ReadHandleKey< xAOD::EventInfo > m_eventinfokey
Handle to EventInfo. This is used to get the evt&run number to set the Ghost area random seeds.
Gaudi::Property< float > m_gridSize
Gaudi::Property< bool > m_doRapidityRescaling
size_type size() const noexcept
Returns the number of elements in the collection.
JetConstituentModifierBase(const std::string &name)
StatusCode setP4(xAOD::IParticle *obj, const xAOD::JetFourMom_t &p4, const SG::AuxElement::Accessor< float > *weightAcc=nullptr) const
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
Class providing the definition of the 4-vector interface.
float charge() const
get charge of PFO
virtual int taste() const
The taste of the particle.
virtual double pt() const
The transverse momentum ( ) of the particle.
@ ParticleFlow
The object is a particle-flow object.
Definition ObjectType.h:41
@ FlowElement
The object is a track-calo-cluster.
Definition ObjectType.h:52
@ TrackCaloCluster
The object is a track-calo-cluster.
Definition ObjectType.h:51
PFO_v1 PFO
Definition of the current "pfo version".
Definition PFO.h:17
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition FlowElement.h:16
TrackCaloCluster_v1 TrackCaloCluster
Reference the current persistent version:
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
Definition JetTypes.h:17
TFile * file