ATLAS Offline Software
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"
21 #include "xAODPFlow/FlowElement.h"
23 #include "TFile.h"
24 
25 using namespace fastjet;
27 }
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  }
38  if(!m_applyToNeutralPFO) {
39  ATH_MSG_ERROR("Incompatible configuration: ApplyToNeutralPFO=False -- what kind of pileup do you wish to suppress?");
40  return StatusCode::FAILURE;
41  }
42  }
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 }
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
ConstituentSubtractorTool::ConstituentSubtractorTool
ConstituentSubtractorTool(const std::string &name)
Definition: ConstituentSubtractorTool.cxx:26
ConstituentSubtractorTool::process_impl
StatusCode process_impl(xAOD::IParticleContainer *cont) const
Definition: ConstituentSubtractorTool.cxx:104
JetConstituentModifierBase::m_applyToNeutralPFO
bool m_applyToNeutralPFO
Definition: JetConstituentModifierBase.h:63
ConstituentSubtractorTool::m_ghostArea
Gaudi::Property< float > m_ghostArea
Definition: ConstituentSubtractorTool.h:48
fastjet
Definition: FastJetLinkBase.h:22
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:66
xAOD::TrackCaloCluster_v1
Class describing a TrackCaloCluster.
Definition: TrackCaloCluster_v1.h:25
CutsMETMaker::accept
StatusCode accept(const xAOD::Muon *mu)
Definition: CutsMETMaker.cxx:18
TrackCaloCluster.h
ConstituentSubtractorTool::initialize
StatusCode initialize()
Dummy implementation of the initialisation function.
Definition: ConstituentSubtractorTool.cxx:30
ConstituentSubtractorTool::m_rescalingFileName
Gaudi::Property< std::string > m_rescalingFileName
Definition: ConstituentSubtractorTool.h:56
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:40
JetConstituentModifierBase::m_applyToChargedPFO
bool m_applyToChargedPFO
Definition: JetConstituentModifierBase.h:62
xAOD::TrackCaloCluster
TrackCaloCluster_v1 TrackCaloCluster
Reference the current persistent version:
Definition: TrackCaloCluster.h:12
xAOD::TrackCaloCluster_v1::pt
virtual double pt() const
The transverse momentum ( ) of the particle.
ConstituentSubtractorTool::m_doRapidityRescaling
Gaudi::Property< bool > m_doRapidityRescaling
Definition: ConstituentSubtractorTool.h:54
xAOD::FlowElement_v1::isCharged
bool isCharged() const
Definition: FlowElement_v1.cxx:56
PFO.h
ConstituentSubtractorTool.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ConstituentSubtractorTool::m_maxEta
Gaudi::Property< float > m_maxEta
Definition: ConstituentSubtractorTool.h:49
FlowElement.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
ConstituentSubtractorTool::m_maxRapForRhoComputation
Gaudi::Property< float > m_maxRapForRhoComputation
Definition: ConstituentSubtractorTool.h:51
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
xAOD::FlowElement
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition: FlowElement.h:16
xAOD::PFO_v1::charge
float charge() const
get charge of PFO
file
TFile * file
Definition: tile_monitor.h:29
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAODType::ParticleFlow
@ ParticleFlow
The object is a particle-flow object.
Definition: ObjectType.h:41
JetConstituentModifierBase::setP4
StatusCode setP4(xAOD::IParticle *obj, const xAOD::JetFourMom_t &p4, const SG::AuxElement::Accessor< float > *weightAcc=nullptr) const
Definition: JetConstituentModifierBase.cxx:113
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
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
xAOD::JetFourMom_t
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
Definition: JetTypes.h:17
PathResolver.h
xAOD::PFO_v1
Class describing a particle flow object.
Definition: PFO_v1.h:35
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
JetConstituentModifierBase
Definition: JetConstituentModifierBase.h:22
ReadHandle.h
Handle class for reading from StoreGate.
ConstituentSubtractorTool::m_hist2D
std::unique_ptr< TH2D > m_hist2D
Definition: ConstituentSubtractorTool.h:63
ConstituentSubtractorTool::m_hist
std::unique_ptr< TH1D > m_hist
Definition: ConstituentSubtractorTool.h:62
ConstituentSubtractorTool::m_ignoreChargedPFOs
Gaudi::Property< bool > m_ignoreChargedPFOs
Definition: ConstituentSubtractorTool.h:59
xAOD::TrackCaloCluster_v1::taste
virtual int taste() const
The taste of the particle.
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
JetConstituentModifierBase::m_inputType
unsigned int m_inputType
Definition: JetConstituentModifierBase.h:60
ConstituentSubtractorTool::m_maxDeltaR
Gaudi::Property< float > m_maxDeltaR
Definition: ConstituentSubtractorTool.h:46
ConstituentSubtractorTool::m_eventinfokey
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.
Definition: ConstituentSubtractorTool.h:44
ConstituentSubtractorTool::m_rescaling
std::unique_ptr< fastjet::FunctionOfPseudoJet< double > > m_rescaling
Definition: ConstituentSubtractorTool.h:61
ConstituentSubtractorTool::m_gridSize
Gaudi::Property< float > m_gridSize
Definition: ConstituentSubtractorTool.h:52
pickleTool.object
object
Definition: pickleTool.py:30
ConstituentSubtractorTool::m_doRapidityPhiRescaling
Gaudi::Property< bool > m_doRapidityPhiRescaling
Definition: ConstituentSubtractorTool.h:55
ConstituentSubtractorTool::m_rescalingHistogramName
Gaudi::Property< std::string > m_rescalingHistogramName
Definition: ConstituentSubtractorTool.h:57
ConstituentSubtractorTool::m_alpha
Gaudi::Property< float > m_alpha
Definition: ConstituentSubtractorTool.h:47
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
xAOD::FlowElement_v1
A detector object made of other lower level object(s)
Definition: FlowElement_v1.h:25