ATLAS Offline Software
egammaForwardBuilder.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "egammaForwardBuilder.h"
13 
15 #include "xAODEgamma/Electron.h"
16 
18 #include "PATCore/AcceptData.h"
19 
20 #include <algorithm>
21 #include <cmath>
22 
23 namespace {
24  constexpr float cellEtaSize = 0.1;
25  constexpr float cellPhiSize = 0.1;
26 }
27 
29  ISvcLocator* pSvcLocator)
30  : AthReentrantAlgorithm(name, pSvcLocator)
31 {}
32 
34 {
35  m_CookieCutPars.maxDelEta = m_maxDelEtaCells * cellEtaSize * 0.5;
36  m_CookieCutPars.maxDelPhi = m_maxDelPhiCells * cellPhiSize * 0.5;
37  m_CookieCutPars.maxDelR2 = m_maxDelR * m_maxDelR; // Square now to avoid a slow sqrt later.
38 
39  // The data handle keys.
44  if (m_outClusterContainerCellLinkKey.key().empty()) {
46  }
48 
49  // Retrieve object quality tool.
50  if (!m_objectQualityTool.empty()) {
51  ATH_CHECK(m_objectQualityTool.retrieve());
52  }
53 
54  else {
55  m_objectQualityTool.disable();
56  }
57 
59 
60  if (
63  ) {
65  "Number of selectors doesn't match number of given fwd-electron selector names"
66  );
67 
68  return StatusCode::FAILURE;
69  }
70 
71  // Retrieve track match builder.
73 
74  // Retrive MVA energy calibration
75  if (m_doEnergyCal) {
76  ATH_CHECK(m_pVtxKey.initialize());
78  ATH_CHECK(m_MVACalibSvc.retrieve());
79  }
80 
81  ATH_MSG_DEBUG("Initialization completed successfully");
82 
83  return StatusCode::SUCCESS;
84 }
85 
87 {
88 
89  ATH_MSG_INFO("====> Forward Egamma Statistics =============");
90  ATH_MSG_INFO(" All Clusters " << m_AllClusters);
91  ATH_MSG_INFO(" Matched Clusters " << m_MatchedClusters);
92  ATH_MSG_INFO("=============================================");
93 
94  return StatusCode::SUCCESS;
95 }
96 
97 StatusCode egammaForwardBuilder::execute(const EventContext& ctx) const
98 {
99  // Create an egamma container and register it.
101  ATH_CHECK(xaodFrwd.record(
102  std::make_unique<xAOD::ElectronContainer>(),
103  std::make_unique<xAOD::ElectronAuxContainer>())
104  );
105 
106  // Create the relevant cluster output and register it.
109  ctx
110  );
111 
113  SG::WriteHandle<CaloClusterCellLinkContainer> outClusterContainerCellLink(
115  ctx
116  );
117 
118  ATH_CHECK(outClusterContainerCellLink.record(
119  std::make_unique<CaloClusterCellLinkContainer>())
120  );
121 
122  // Topo cluster container.
124 
125  // Check is only used for serial running, remove when MT scheduler used.
126  ATH_CHECK(inputClusters.isValid());
127 
128  // Calorimeter description.
129  SG::ReadCondHandle<CaloDetDescrManager> caloDetDescrMgrHandle{
131  };
132  ATH_CHECK(caloDetDescrMgrHandle.isValid());
133  const CaloDetDescrManager* calodetdescrmgr = *caloDetDescrMgrHandle;
134 
135  static const SG::AuxElement::Accessor<
136  std::vector<ElementLink<xAOD::CaloClusterContainer>>
137  > caloClusterLinks("constituentClusterLinks");
138 
139  // Prepare to create clusters.
140  EgammaRecContainer egammaRecsFwd;
141  size_t origClusterIndex = 0;
142 
144  if (m_doEnergyCal) {
145  std::pair<float,float> nPVmu = this->getnPVmu(ctx);
146  gei.nPV = nPVmu.first;
147  gei.acmu = nPVmu.second;
148  ATH_MSG_DEBUG("Retrieved nPV = " << gei.nPV << " and mu = " << gei.acmu);
149  }
150 
151  // Loop over input cluster container and create egRecs to store the electrons.
152  ATH_MSG_VERBOSE("Will run on " << inputClusters->size() << " input clusters, doing cookie cut ? " << m_doCookieCutting);
153  for (const xAOD::CaloCluster* cluster : *inputClusters) {
154 
155  // Create links back to the original clusters.
156  std::vector<ElementLink<xAOD::CaloClusterContainer>> constituentLinks;
157 
158  // The constituent links should contain a CaloCal cluster. When not running
159  // in ITk mode this is the default for the forward clusters used by egamma
160  // so no sister link is needed to get the CaloCal. When running in ITk mode
161  // the clusters used are CaloTopoClusters so need to access the sister
162  // cluster to maintain consistency.
163  if (m_doTrackMatching) {
165  cluster->getSisterClusterLink();
166 
167  if (sisterCluster) {
168  constituentLinks.push_back(sisterCluster);
169  } else {
170  ATH_MSG_WARNING("No sister Link available");
171  }
172  } else {
173  constituentLinks.emplace_back(*inputClusters, origClusterIndex, ctx);
174  }
175 
176  const DataLink<CaloCellContainer>& cellCont =
177  cluster->getCellLinks()->getCellContainerLink();
178 
179  // Create the new cluster.
180  std::unique_ptr<xAOD::CaloCluster> newCluster =
182  egammaClusterCookieCut::cookieCut(*cluster, *calodetdescrmgr,
183  cellCont, m_CookieCutPars) :
184  std::make_unique<xAOD::CaloCluster>(*cluster);
185 
186  if (!newCluster || newCluster->size() == 0) {
187  ATH_MSG_DEBUG("Could not build a new cluster, or has 0 cell");
188  continue;
189  }
190 
191  if (m_doEnergyCal &&
192  m_MVACalibSvc->execute(*newCluster, xAOD::EgammaParameters::forwardelectron, gei).isFailure())
193  { ATH_MSG_ERROR("Problem executing MVA cluster tool for fwd electron"); }
194 
195  caloClusterLinks(*newCluster) = constituentLinks;
196  outClusterContainer->push_back(std::move(newCluster));
197 
198  size_t index = outClusterContainer->size() - 1;
199  const ElementLink<xAOD::CaloClusterContainer> clusterLink(*outClusterContainer, index, ctx);
200  const std::vector<ElementLink<xAOD::CaloClusterContainer>> clusterLinkVector{clusterLink};
201 
202  // Now create the egamma Rec
203  egammaRecsFwd.push_back(std::make_unique<egammaRec>(clusterLinkVector));
204 
205  ++origClusterIndex;
206  }
207 
208  // Add track-cluster matching information if requested.
209  if (m_doTrackMatching) {
210  ATH_CHECK(m_trackMatchBuilder->executeRec(ctx, &egammaRecsFwd));
211  }
212 
213  auto buff_AllClusters = m_AllClusters.buffer();
214  auto buff_MatchedClusters = m_MatchedClusters.buffer();
215 
216  //Loop over the egamma Rec creating electrons
217  for (const egammaRec* egRec : egammaRecsFwd) {
218  if (!egRec) {
219  return StatusCode::FAILURE;
220  }
221 
222  ++buff_AllClusters;
223 
224  if (m_doTrackMatching && egRec->getNumberOfTrackParticles() == 0) {
225  // Later we may want to use these for so called forward photons.
226  ATH_MSG_DEBUG("EgammaRec without track particle");
227  continue;
228  }
229 
230  //common part
231  xAOD::Electron* el = xaodFrwd->push_back(std::make_unique<xAOD::Electron>());
233  el->setCaloClusterLinks(egRec->caloClusterElementLinks());
234 
235  // from here one, we need both track matching and
236  // having tracks .
237  if (m_doTrackMatching) {
238 
239  ++buff_MatchedClusters;
240  el->setTrackParticleLinks(egRec->trackParticleElementLinks());
241 
242  const xAOD::TrackParticle* trackParticle = el->trackParticle();
243  if (trackParticle) {
244  el->setCharge(trackParticle->charge());
245  } else {
246  ATH_MSG_WARNING("Forward electron without track particle, whereas"
247  " corresponding egammaRec has at least one");
248  }
249 
250  // Set DeltaEta, DeltaPhi, DeltaPhiRescaled.
251  el->setTrackCaloMatchValues(
252  egRec->deltaEta(),
253  egRec->deltaPhi(),
254  egRec->deltaPhiRescaled(),
255  egRec->deltaPhiLast()
256  );
257  }
258 
261 
262  // Apply the Forward Electron selectors.
263  for (size_t i = 0; i < m_forwardElectronIsEMSelectors.size(); ++i) {
266 
267  // Save the bool result.
268  const asg::AcceptData accept = selector->accept(ctx, el);
269  el->setPassSelection(static_cast<bool>(accept), name);
270 
271  // Save the isem.
272  el->setSelectionisEM(accept.getCutResultInverted(), "isEM" + name);
273  }
274 
275  }//end of loop over egammaRecs
276 
278  ctx,
279  outClusterContainer,
280  outClusterContainerCellLink);
281 
282  return StatusCode::SUCCESS;
283 }
284 
287  const EventContext& ctx,
289 ) const {
290  // Protection in case tool is not available return success as algorithm can run without it.
291  if (!m_objectQualityTool.isEnabled()) { return StatusCode::SUCCESS; }
292 
293  return m_objectQualityTool->execute(ctx,*eg);
294 }
295 
298 {
299  if (!m_doTrackMatching) {
300  m_trackMatchBuilder.disable();
301  return StatusCode::SUCCESS;
302  }
303 
304  if (m_trackMatchBuilder.empty()) {
305  ATH_MSG_ERROR("EMTrackMatchBuilder is empty, but track matching is enabled");
306  return StatusCode::FAILURE;
307  }
308 
309  if (m_trackMatchBuilder.retrieve().isFailure()) {
310  ATH_MSG_ERROR("Unable to retrieve " << m_trackMatchBuilder);
311  return StatusCode::FAILURE;
312  }
313 
314  return StatusCode::SUCCESS;
315 }
316 
317 std::pair<unsigned int, float> egammaForwardBuilder::getnPVmu(
318  const EventContext& ctx) const {
319  unsigned int npv(0);
320  float mu(0);
321 
323  if (!vtxCont.isValid()) {
324  ATH_MSG_WARNING("Cannot find " << m_pVtxKey.key()
325  << " container, returning nPV = 0");
326  } else {
327  for (const auto *vtx : *vtxCont) {
328  if (vtx->vertexType() == xAOD::VxType::PriVtx ||
329  vtx->vertexType() == xAOD::VxType::PileUp) { ++npv; }
330  }
331  }
332 
334  if (!eiCont.isValid()) {
335  ATH_MSG_WARNING("Cannot find " << m_eiKey.key() << " returning mu = 0");
336  } else {
337  mu = eiCont.get()->actualInteractionsPerCrossing();
338  }
339 
340  return std::make_pair(npv,mu);
341 }
egammaForwardBuilder::m_eiKey
SG::ReadHandleKey< xAOD::EventInfo > m_eiKey
Input EventInfo for fwd energy calibration.
Definition: egammaForwardBuilder.h:122
CaloClusterStoreHelper::finalizeClusters
static StatusCode finalizeClusters(SG::WriteHandle< CaloClusterCellLinkContainer > &h, xAOD::CaloClusterContainer *pClusterColl)
Finalize clusters (move CaloClusterCellLink to a separate container).
Definition: CaloClusterStoreHelper.cxx:64
egammaForwardBuilder::m_CookieCutPars
egammaClusterCookieCut::CookieCutPars m_CookieCutPars
Definition: egammaForwardBuilder.h:216
IAsgForwardElectronIsEMSelector.h
egammaMVACalib::GlobalEventInfo::nPV
int nPV
Definition: GlobalEventInfo.h:10
SG::ReadCondHandle
Definition: ReadCondHandle.h:40
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
CaloClusterStoreHelper::AddContainerWriteHandle
static StatusCode AddContainerWriteHandle(SG::WriteHandle< xAOD::CaloClusterContainer > &clusColl)
Creates a new xAOD::CaloClusterContainer in the given WriteHandle + CaloClusterAuxContainer and recor...
Definition: CaloClusterStoreHelper.cxx:53
ParticleTest.eg
eg
Definition: ParticleTest.py:29
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
xAOD::TrackParticle_v1::charge
float charge() const
Returns the charge.
Definition: TrackParticle_v1.cxx:143
egammaClusterCookieCut::CookieCutPars::maxDelR2
double maxDelR2
Definition: egammaClusterCookieCut.h:14
egammaMVACalib::GlobalEventInfo::acmu
float acmu
Definition: GlobalEventInfo.h:11
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
index
Definition: index.py:1
egammaForwardBuilder::m_forwardElectronIsEMSelectors
ToolHandleArray< IAsgForwardElectronIsEMSelector > m_forwardElectronIsEMSelectors
Handle to the selectors.
Definition: egammaForwardBuilder.h:220
egammaForwardBuilder::egammaForwardBuilder
egammaForwardBuilder(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Definition: egammaForwardBuilder.cxx:28
egammaClusterCookieCut::CookieCutPars::maxDelEta
double maxDelEta
Definition: egammaClusterCookieCut.h:12
CutsMETMaker::accept
StatusCode accept(const xAOD::Muon *mu)
Definition: CutsMETMaker.cxx:18
egammaForwardBuilder::m_AllClusters
Gaudi::Accumulators::Counter m_AllClusters
Definition: egammaForwardBuilder.h:213
egammaForwardBuilder::m_doCookieCutting
Gaudi::Property< bool > m_doCookieCutting
Private member flag to do cookie cutting.
Definition: egammaForwardBuilder.h:182
egammaForwardBuilder::RetrieveEMTrackMatchBuilder
StatusCode RetrieveEMTrackMatchBuilder()
Definition: egammaForwardBuilder.cxx:297
xAOD::Egamma_v1
Definition: Egamma_v1.h:56
egammaForwardBuilder::ExecObjectQualityTool
StatusCode ExecObjectQualityTool(const EventContext &ctx, xAOD::Egamma *eg) const
Definition: egammaForwardBuilder.cxx:286
xAOD::EgammaParameters::AuthorFwdElectron
const uint16_t AuthorFwdElectron
Electron reconstructed by the Forward cluster-based algorithm.
Definition: EgammaDefs.h:30
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
egammaForwardBuilder::m_forwardElectronIsEMSelectorResultNames
Gaudi::Property< std::vector< std::string > > m_forwardElectronIsEMSelectorResultNames
Definition: egammaForwardBuilder.h:227
CaloDetDescrManager.h
Definition of CaloDetDescrManager.
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:74
egammaForwardBuilder::m_maxDelR
Gaudi::Property< float > m_maxDelR
Size of cone to cookie cut on FCal.
Definition: egammaForwardBuilder.h:206
egammaForwardBuilder::m_outClusterContainerCellLinkKey
SG::WriteHandleKey< CaloClusterCellLinkContainer > m_outClusterContainerCellLinkKey
Output cluster container cell links: name taken from containter name.
Definition: egammaForwardBuilder.h:168
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:62
egammaForwardBuilder::initialize
virtual StatusCode initialize() override final
Initialize method.
Definition: egammaForwardBuilder.cxx:33
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
egammaForwardBuilder::execute
virtual StatusCode execute(const EventContext &ctx) const override final
Execute method.
Definition: egammaForwardBuilder.cxx:97
lumiFormat.i
int i
Definition: lumiFormat.py:85
CaloCluster.h
ElectronAuxContainer.h
egammaForwardBuilder::m_doEnergyCal
Gaudi::Property< bool > m_doEnergyCal
Private member flag to do energy calibration.
Definition: egammaForwardBuilder.h:107
egammaClusterCookieCut::cookieCut
std::unique_ptr< xAOD::CaloCluster > cookieCut(const xAOD::CaloCluster &cluster, const CaloDetDescrManager &mgr, const DataLink< CaloCellContainer > &cellCont, const egammaClusterCookieCut::CookieCutPars &pars)
Definition: egammaClusterCookieCut.cxx:28
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::ReadHandle::get
const_pointer_type get() const
Dereference the pointer, but don't cache anything.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
egammaForwardBuilder::m_doTrackMatching
Gaudi::Property< bool > m_doTrackMatching
Private member flag to do the track matching.
Definition: egammaForwardBuilder.h:174
egammaClusterCookieCut::CookieCutPars::maxDelPhi
double maxDelPhi
Definition: egammaClusterCookieCut.h:13
xAOD::VxType::PriVtx
@ PriVtx
Primary vertex.
Definition: TrackingPrimitives.h:572
egammaForwardBuilder::m_maxDelPhiCells
Gaudi::Property< int > m_maxDelPhiCells
Size of maximum search window in phi.
Definition: egammaForwardBuilder.h:198
xAOD::CaloCluster_v1::size
size_t size() const
size method (forwarded from CaloClusterCellLink obj)
Definition: CaloCluster_v1.cxx:920
EMFourMomBuilder.h
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
python.getProblemFolderFromLogs.el
dictionary el
Definition: getProblemFolderFromLogs.py:48
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:795
AcceptData.h
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
egammaForwardBuilder::m_outClusterContainerKey
SG::WriteHandleKey< xAOD::CaloClusterContainer > m_outClusterContainerKey
Output cluster container.
Definition: egammaForwardBuilder.h:160
egammaForwardBuilder.h
egammaForwardBuilder::finalize
virtual StatusCode finalize() override final
Finalize method.
Definition: egammaForwardBuilder.cxx:86
EMFourMomBuilder::calculate
void calculate(xAOD::Electron &electron)
Definition: EMFourMomBuilder.cxx:69
xAOD::VxType::PileUp
@ PileUp
Pile-up vertex.
Definition: TrackingPrimitives.h:574
CookieCutterHelpers.h
egammaForwardBuilder::m_trackMatchBuilder
ToolHandle< IEMTrackMatchBuilder > m_trackMatchBuilder
Tool to perform track-cluster matching.
Definition: egammaForwardBuilder.h:99
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
IegammaBaseTool.h
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
xAOD::Electron_v1
Definition: Electron_v1.h:34
CaloClusterStoreHelper.h
egammaForwardBuilder::getnPVmu
std::pair< unsigned int, float > getnPVmu(const EventContext &ctx) const
Definition: egammaForwardBuilder.cxx:317
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
python.selector.AtlRunQuerySelectorLhcOlc.selector
selector
Definition: AtlRunQuerySelectorLhcOlc.py:610
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:469
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
egammaMVACalib::GlobalEventInfo
A structure holding some global event information.
Definition: GlobalEventInfo.h:9
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
xAOD::EgammaParameters::forwardelectron
@ forwardelectron
Definition: EgammaEnums.h:21
egammaForwardBuilder::m_topoClusterKey
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_topoClusterKey
Input topo cluster type.
Definition: egammaForwardBuilder.h:136
CaloClusterContainer.h
egammaRec
Definition: egammaRec.h:31
egammaForwardBuilder::m_pVtxKey
SG::ReadHandleKey< xAOD::VertexContainer > m_pVtxKey
Input primary vertices for fwd energy calibration.
Definition: egammaForwardBuilder.h:115
Electron.h
egammaForwardBuilder::m_caloDetDescrMgrKey
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloDetDescrMgrKey
Calorimeter description.
Definition: egammaForwardBuilder.h:144
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:44
egammaForwardBuilder::m_MVACalibSvc
ServiceHandle< IegammaMVASvc > m_MVACalibSvc
Handle to the MVA calibration service.
Definition: egammaForwardBuilder.h:129
asg::AcceptData
Definition: AcceptData.h:30
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:51
egammaForwardBuilder::m_MatchedClusters
Gaudi::Accumulators::Counter m_MatchedClusters
Definition: egammaForwardBuilder.h:214
egammaForwardBuilder::m_objectQualityTool
ToolHandle< IegammaOQFlagsBuilder > m_objectQualityTool
Tool to perform object quality.
Definition: egammaForwardBuilder.h:91
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
egammaForwardBuilder::m_maxDelEtaCells
Gaudi::Property< int > m_maxDelEtaCells
Size of maximum search window in eta.
Definition: egammaForwardBuilder.h:190
egammaForwardBuilder::m_electronOutputKey
SG::WriteHandleKey< xAOD::ElectronContainer > m_electronOutputKey
Output electron container.
Definition: egammaForwardBuilder.h:152
xAOD::EventInfo_v1::actualInteractionsPerCrossing
float actualInteractionsPerCrossing() const
Average interactions per crossing for the current BCID - for in-time pile-up.
Definition: EventInfo_v1.cxx:380