ATLAS Offline Software
PFEGamFlowElementAssoc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // Flow Element EDM
11 #include "xAODEgamma/Electron.h"
12 #include "xAODEgamma/Photon.h"
15 
17 
18 
22 
24  const std::string& name,
25  ISvcLocator* pSvcLocator
26  ):
27  AthReentrantAlgorithm(name,pSvcLocator)
28 {
29 }
30 
31 // Class destructor
33 
35 {
36  ATH_MSG_VERBOSE("Initializing "<<name() << "...");
41 
46 
47  //Init ReadHandleKeys
48  ATH_CHECK(m_photonReadHandleKey.initialize());
50  ATH_CHECK(m_chargedFEReadHandleKey.initialize());
51  ATH_CHECK(m_neutralFEReadHandleKey.initialize());
52 
53  ATH_MSG_VERBOSE("Initialization completed successfully");
54 
55  return StatusCode::SUCCESS;
56 }
57 
59  return StatusCode::SUCCESS;
60 }
68 StatusCode PFEGamFlowElementAssoc::execute(const EventContext &ctx) const
69 {
70  // write decoration handles for the electron, photon and FE containers -- these are the OUTPUT handles
71  //Electron Write Handle
72  ATH_MSG_VERBOSE("Exec start");
77  ATH_MSG_VERBOSE("Defined Electron writehandles");
78  //Photon Write Handle
83  ATH_MSG_VERBOSE("Defined Photon WriteHandles");
84 
85  // This is the READ handles (so the input containers for electron, photon, FE)
86 
89 
90  // Charged and Neutral PFlow "Flow elements"
93  ATH_MSG_VERBOSE("Defined ReadHandles");
94  // now initialise some Flow element link containers
95  std::vector<std::vector<FlowElementLink_t>> electronNeutralFEVec(electronReadHandle->size());
96  std::vector<std::vector<FlowElementLink_t>> electronChargedFEVec(electronReadHandle->size());
97 
98  std::vector<std::vector<FlowElementLink_t>> photonNeutralFEVec(photonReadHandle->size());
99  std::vector<std::vector<FlowElementLink_t>> photonChargedFEVec(photonReadHandle->size());
100  ATH_MSG_VERBOSE("Finished runtime init");
104 
105 
107  // Loop over neutral flow elements (FEs)
109  for (const xAOD::FlowElement* FE: *neutralFEElectronWriteDecorHandle){
110  // init the links
111  std::vector<ElectronLink_t> FEElectronLinks;
112  std::vector<PhotonLink_t> FEPhotonLinks;
113 
114  //nullptr catch for removed NFE clusters - only comes up if using AOD where the alg might have some skimmed components
115  if(FE->otherObjects().empty() || FE->otherObjects().at(0)==nullptr){
116  neutralFEElectronWriteDecorHandle(*FE)=FEElectronLinks;
117  neutralFEPhotonWriteDecorHandle(*FE)=FEPhotonLinks;
118  continue;
119  }
120 
121  //Obtain the index of the FE calo-cluster
122  size_t FEClusterIndex=FE->otherObjects().at(0)->index();
123  double FE_cluster_E=FE->otherObjects().at(0)->p4().E();
124  bool neg_E_cluster=(FE_cluster_E<0);
125 
126  //Loop over electrons:
127 
128  for (const xAOD::Electron* electron: *electronNeutralFEWriteDecorHandle){
129  // get the calo clusters from the electron
130  ATH_MSG_VERBOSE("NFE: start el loop");
131  const std::vector<const xAOD::CaloCluster*> electronTopoClusters = xAOD::EgammaHelpers::getAssociatedTopoClusters(electron->caloCluster());
132  ATH_MSG_VERBOSE("NFE: got calo clusters");
133 
134  for(const xAOD::CaloCluster* cluster : electronTopoClusters){
135  // obtain the index of the electron seed topocluster
136  size_t electronClusterIndex=cluster->index();
137  //match the indices: Cluster match between Flow Element (FE) and electron
138  if(electronClusterIndex==FEClusterIndex){
139  FEElectronLinks.emplace_back(*electronReadHandle,electron->index() );
140  //Add Flow Element (FE) link to a vector
141  //index() is the unique index of the Flow Element in the container
142  electronNeutralFEVec.at(electron->index()).emplace_back(*neutralFEReadHandle, FE->index() );
143  if(neg_E_cluster){
144  ATH_MSG_ERROR("Negative energy cluster found and matched to electron");
145  ATH_MSG_ERROR("Cluster Energy: "<<FE_cluster_E<<"");
146  }
147  }// end of matching block
148 
149  } // end loop over cluster
150 
151  } // end Electron loop
152  ATH_MSG_VERBOSE("NFE: Electron loop finished");
153  // now loop over photons
154  for (const xAOD::Photon* photon: *photonNeutralFEWriteDecorHandle){
155  // retrieve clusters from the photon container
156  const std::vector<const xAOD::CaloCluster*> photonTopoClusters = xAOD::EgammaHelpers::getAssociatedTopoClusters(photon->caloCluster());
157  //loop over clusters, and do the matching
158  for (const xAOD::CaloCluster* cluster: photonTopoClusters){
159  //retrieve index of the cluster
160  size_t photonClusterIndex=cluster->index();
161  //do the matching
162  if(photonClusterIndex==FEClusterIndex){
163  // Add flow element (FE) links to photon
164  FEPhotonLinks.emplace_back(*photonReadHandle,photon->index() );
165  //Add Flow Element (FE) link to a vector
166  //index() is the unique index of the Flow Element in the container
167  photonNeutralFEVec.at(photon->index()).emplace_back(*neutralFEReadHandle, FE->index() );
168 
169  if(neg_E_cluster){
170  ATH_MSG_ERROR("Negative energy cluster found and matched to photon");
171  ATH_MSG_ERROR("Cluster Energy: "<<FE_cluster_E<<"");
172  }
173  }// end of matching block
174  } // end of neutral loop
175 
176 
177  }// end of photon loop
178  ATH_MSG_VERBOSE("NFE: Photon Loop complete");
179  //Add vector of electron element links as decoration to FlowElement container
180  neutralFEElectronWriteDecorHandle(*FE)=FEElectronLinks;
181  neutralFEPhotonWriteDecorHandle(*FE)=FEPhotonLinks;
182  ATH_MSG_VERBOSE("NFE::WriteHandle mapping");
183  } // end neutral FE loop
184  ATH_MSG_VERBOSE("NFE: Loop finished");
186  // Loop over charged Flow Elements (FEs)
188  for (const xAOD::FlowElement* FE: *chargedFEElectronWriteDecorHandle){
189  // Initialise a vector of element links to electrons/Photons
190  std::vector<ElectronLink_t> FEElectronLinks;
191  std::vector<PhotonLink_t> FEPhotonLinks;
192 
193  // Charged Flow Element catch for a case where there are removed tracks - should only apply if running from AOD
194  if(FE->chargedObjects().empty() || FE->chargedObjects().at(0)==nullptr){
195  chargedFEElectronWriteDecorHandle (*FE) = FEElectronLinks;
196  chargedFEPhotonWriteDecorHandle (*FE) = FEPhotonLinks;
197  continue;
198  }
199  // retrieve the track from the Flow element
200  size_t FETrackIndex=FE->chargedObjects().at(0)->index();
201 
202  //loop over electrons
203  for (const xAOD::Electron* electron: *electronChargedFEWriteDecorHandle){
204  //obtain the clusters
205  const std::vector<const xAOD::TrackParticle*> electronTrackParticles = xAOD::EgammaHelpers::getTrackParticlesVec(electron, true, true); // useBremAssoc = true (get original non-GSF track), allParticles = true (include all track particles)
206  // loop over tracks
207  for (const xAOD::TrackParticle* electronTrack: electronTrackParticles){
208  size_t electronTrackIndex = electronTrack->index();
209 
210  //link to FE if track indices match
211  if(electronTrackIndex==FETrackIndex){
212  // Add electron element link to a vector
213  // index() is the unique index of the electron in the electron container
214  FEElectronLinks.emplace_back(*electronReadHandle, electron->index() );
215  // Add FE element link to a vector
216  // index() is the unique index of the cFE in the cFE container
217  electronChargedFEVec.at(electron->index()).emplace_back(*chargedFEReadHandle, FE->index() );
218  }//end of matching block
219 
220  }//end of loop on clusters
221  } // end of loop on electrons
222 
223  for(const xAOD::Photon* photon: *photonChargedFEWriteDecorHandle){
224  //obtain indices of the converted photon's original tracks
225  const std::set<const xAOD::TrackParticle*> photonTrackParticles = xAOD::EgammaHelpers::getTrackParticles(photon, true);
226  // loop over the tracks
227  for (const xAOD::TrackParticle* photonTrack: photonTrackParticles){
228  size_t photonTrackIndex=photonTrack->index();
229 
230  // Link the photon to the Flow Element (FE) if the track indices match
231  if (photonTrackIndex==FETrackIndex){
232  // Add photon element link to a vector
233  // index() is the unique index of the photon in the photon container
234  FEPhotonLinks.emplace_back(*photonReadHandle, photon->index() );
235  // Add FE element link to a vector
236  // index() is the unique index of the cFE in the cFE container
237  photonChargedFEVec.at(photon->index()).emplace_back(*chargedFEReadHandle, FE->index() );
238  }// end of matching block
239 
240  }// end of loop on tracks
241 
242  }//end of loop on photons
243 
244 
245  // Add vector of electron element links as decoration to FE container
246  chargedFEElectronWriteDecorHandle (*FE) = FEElectronLinks;
247  // Add vector of photon element links as decoration to FE container
248  chargedFEPhotonWriteDecorHandle (*FE) = FEPhotonLinks;
249 
250  } // end of charged FE loop
251 
252 
253 
255  // WRITE OUTPUT: ADD HANDLES TO EL/PHOT CONTAINERS
257  // Add the vectors of the Flow Element (FE) Links as decorations to the electron container
258  for (const xAOD::Electron* electron : *electronNeutralFEWriteDecorHandle){
259  electronNeutralFEWriteDecorHandle (*electron) = electronNeutralFEVec.at(electron->index());
260  electronChargedFEWriteDecorHandle (*electron) = electronChargedFEVec.at(electron->index());
261  } //end of photon loop
262  // Add the vectors of the Flow Element (FE) Links as decorations to the photon container
263  for (const xAOD::Photon* photon: *photonNeutralFEWriteDecorHandle){
264  photonNeutralFEWriteDecorHandle (*photon) = photonNeutralFEVec.at(photon->index());
265  photonChargedFEWriteDecorHandle (*photon) = photonChargedFEVec.at(photon->index());
266  } // end of loop on photons
267 
268  ATH_MSG_VERBOSE("Execute completed successfully");
269 
270  return StatusCode::SUCCESS;
271 }
FlowElementContainer.h
xAOD::EgammaHelpers::getAssociatedTopoClusters
std::vector< const xAOD::CaloCluster * > getAssociatedTopoClusters(const xAOD::CaloCluster *cluster)
Return a vector of all the topo clusters associated with the egamma cluster.
Definition: EgammaxAODHelpers.cxx:65
PFEGamFlowElementAssoc::initialize
virtual StatusCode initialize()
Definition: PFEGamFlowElementAssoc.cxx:34
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
PFEGamFlowElementAssoc::m_photonNeutralFEWriteDecorKey
SG::WriteDecorHandleKey< xAOD::PhotonContainer > m_photonNeutralFEWriteDecorKey
The write key for adding Neutral Flow Element element link decorations to photons.
Definition: PFEGamFlowElementAssoc.h:73
PFEGamFlowElementAssoc::execute
virtual StatusCode execute(const EventContext &ctx) const
This algorithm does the following: 1) Read the Input containers for Flow Elements,...
Definition: PFEGamFlowElementAssoc.cxx:68
PFEGamFlowElementAssoc::m_chargedFEPhotonWriteDecorKey
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_chargedFEPhotonWriteDecorKey
The write key for adding photon element link decorations to Charged Flow Elements.
Definition: PFEGamFlowElementAssoc.h:79
ElectronxAODHelpers.h
xAOD::EgammaHelpers::getTrackParticles
std::set< const xAOD::TrackParticle * > getTrackParticles(const xAOD::Egamma *eg, bool useBremAssoc=true, bool allParticles=true)
Return a list of all or only the best TrackParticle associated to the object.
Definition: EgammaxAODHelpers.cxx:120
PFEGamFlowElementAssoc::m_photonReadHandleKey
SG::ReadHandleKey< xAOD::PhotonContainer > m_photonReadHandleKey
Definition: PFEGamFlowElementAssoc.h:51
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
xAOD::EgammaHelpers::getTrackParticlesVec
std::vector< const xAOD::TrackParticle * > getTrackParticlesVec(const xAOD::Egamma *eg, bool useBremAssoc=true, bool allParticles=true)
Return a list of all or only the best TrackParticle associated to the object.
Definition: EgammaxAODHelpers.cxx:141
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
PFEGamFlowElementAssoc::m_neutralFEReadHandleKey
SG::ReadHandleKey< xAOD::FlowElementContainer > m_neutralFEReadHandleKey
Definition: PFEGamFlowElementAssoc.h:54
PFEGamFlowElementAssoc::m_neutralFEElectronWriteDecorKey
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_neutralFEElectronWriteDecorKey
The write key for adding electron element link decorations to Neutral Flow Elements.
Definition: PFEGamFlowElementAssoc.h:66
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
EgammaxAODHelpers.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
PFEGamFlowElementAssoc.h
FlowElement.h
ElectronContainer.h
PFEGamFlowElementAssoc::m_chargedFEReadHandleKey
SG::ReadHandleKey< xAOD::FlowElementContainer > m_chargedFEReadHandleKey
Definition: PFEGamFlowElementAssoc.h:56
Photon.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:99
WriteDecorHandle.h
Handle class for adding a decoration to an object.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
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
PFEGamFlowElementAssoc::m_chargedFEElectronWriteDecorKey
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_chargedFEElectronWriteDecorKey
The write key for adding electron element link decorations to Charged Flow Elements.
Definition: PFEGamFlowElementAssoc.h:69
PFEGamFlowElementAssoc::PFEGamFlowElementAssoc
PFEGamFlowElementAssoc(const std::string &name, ISvcLocator *pSvcLocator)
Definition: PFEGamFlowElementAssoc.cxx:23
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
PFEGamFlowElementAssoc::m_photonChargedFEWriteDecorKey
SG::WriteDecorHandleKey< xAOD::PhotonContainer > m_photonChargedFEWriteDecorKey
The write key for adding Charged Flow Element element link decorations to photons.
Definition: PFEGamFlowElementAssoc.h:75
PFEGamFlowElementAssoc::finalize
virtual StatusCode finalize()
Definition: PFEGamFlowElementAssoc.cxx:58
xAOD::Electron_v1
Definition: Electron_v1.h:34
PFEGamFlowElementAssoc::m_neutralFEPhotonWriteDecorKey
SG::WriteDecorHandleKey< xAOD::FlowElementContainer > m_neutralFEPhotonWriteDecorKey
The write key for adding photon element link decorations to Neutral Flow Elements.
Definition: PFEGamFlowElementAssoc.h:77
xAOD::photon
@ photon
Definition: TrackingPrimitives.h:199
SG::WriteDecorHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
PFEGamFlowElementAssoc::m_electronNeutralFEWriteDecorKey
SG::WriteDecorHandleKey< xAOD::ElectronContainer > m_electronNeutralFEWriteDecorKey
The write key for adding Neutral Flow Element element link decorations to electrons.
Definition: PFEGamFlowElementAssoc.h:60
xAOD::Photon_v1
Definition: Photon_v1.h:37
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
PFEGamFlowElementAssoc::m_electronReadHandleKey
SG::ReadHandleKey< xAOD::ElectronContainer > m_electronReadHandleKey
Definition: PFEGamFlowElementAssoc.h:49
Electron.h
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
PFEGamFlowElementAssoc::m_electronChargedFEWriteDecorKey
SG::WriteDecorHandleKey< xAOD::ElectronContainer > m_electronChargedFEWriteDecorKey
The write key for adding Charged Flow Element element link decorations to electrons.
Definition: PFEGamFlowElementAssoc.h:62
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
PhotonContainer.h
PFEGamFlowElementAssoc::~PFEGamFlowElementAssoc
virtual ~PFEGamFlowElementAssoc()
xAOD::FlowElement_v1
A detector object made of other lower level object(s)
Definition: FlowElement_v1.h:25