ATLAS Offline Software
CaloClusterMatchingTool.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 // CaloClusterMatchingTool.cxx
8 // Implementation file for class CaloClusterMatchingTool
9 // Author: S.Binet<binet@cern.ch>
11 
12 // CaloClusterMatching includes
14 
15 // STL includes
16 
17 // FrameWork includes
19 #include <algorithm>
20 #include <utility>
21 
22 namespace ClusterMatching {
23 
24  using namespace xAOD;
25 
26  // Destructor
29 
30  // Athena algtool's Hooks
33  {
34  ATH_MSG_INFO ("Initializing " << name() << "...");
35 
36  if (m_clustersIn.empty()) {
37  ATH_MSG_ERROR("Empty name provided for TopoCluster collection nothing to "
38  "work with -- aborting");
39  return StatusCode::FAILURE;
40  }
41 
42  ATH_CHECK(m_clustersIn.initialize());
43 
44  return StatusCode::SUCCESS;
45  }
46 
48  {
49  ATH_MSG_INFO ("Finalizing " << name() << "...");
50 
51  return StatusCode::SUCCESS;
52  }
53 
55  // Const methods:
57 
58  StatusCode CaloClusterMatchingTool::fillClusterMap(const EventContext& ctx, TopoClusterMap& tcmap) const
59  {
60 
61  SG::ReadHandle<xAOD::CaloClusterContainer> topoclusters (m_clustersIn, ctx);
62  ATH_CHECK( tcmap.SetTopoClusters(topoclusters.cptr()) );
63 
64  return StatusCode::SUCCESS;
65  }
66 
67  // return shared fraction of clustered cell energy
69  const xAOD::CaloCluster& testCluster) const
70  {
71  int nSharedCells(0);
72  float sharedE(0.);
73  float totalE(0.);
74  for (auto tcItr = testCluster.cell_begin(); tcItr != testCluster.cell_end();++tcItr) {
75  if (tcItr->e() > 1e-9 || !m_reqPosE) {
76  for (auto rcItr = refCluster.cell_begin(); rcItr != refCluster.cell_end(); ++rcItr) {
77  if (*tcItr && *rcItr && (*tcItr == *rcItr)) {
78  ++nSharedCells;
79  sharedE += tcItr->e();
80  }
81  }
82  totalE += tcItr->e();
83  }
84  }
85  if(nSharedCells>0) {
86  ATH_MSG_VERBOSE("Reference cluster and target cluster share " << nSharedCells << " cells, " << sharedE << " / " << totalE << " MeV");
87  ATH_MSG_VERBOSE("DeltaR = " << refCluster.p4().DeltaR(testCluster.p4()));
88  }
89  return totalE<1e-9 ? 0. : sharedE/totalE;
90  }
91 
92  // return true if clusters share a given fraction of their cell energy
94  const xAOD::CaloCluster& testCluster) const
95  {
96  return getClusterSharedEfrac(refCluster,testCluster)>m_minSharedEfrac;
97  }
98 
99  // fill a list of clusters from the testClusters container that match the reference cluster
100  // match criteria determined by calling clustersAreMatched
101  // return true if matchedClusters list is non-empty
103  const std::vector<const xAOD::CaloCluster*>& testClusters,
104  std::vector<const xAOD::CaloCluster*>& matchedClusters) const
105  {
106  // check that it's empty?
107  matchedClusters.clear();
108 
109  for(const auto& testCluster : testClusters) {
110  if(clustersAreMatched(refCluster, *testCluster)) matchedClusters.push_back(testCluster);
111  }
112  return !matchedClusters.empty();
113  }
114 
115  // fill a list of clusters from the configured cluster container that match the reference cluster
116  // match criteria determined by calling clustersAreMatched
117  // return true if matchedClusters list is non-empty
119  std::vector<const xAOD::CaloCluster*>& matchedClusters,
120  const TopoClusterMap& tcmap,
121  bool useLeadingCellEtaPhi) const
122  {
123  float refEta(0.), refPhi(0.);
124  if(useLeadingCellEtaPhi) { // needed for muons because muon clusters have no eta/phi
125  const CaloCell* leadcell(nullptr);
126  float leadcellE(0.);
127  for(auto refItr = refCluster.cell_begin(); refItr!=refCluster.cell_end(); ++refItr) {
128  if(refItr->e() > leadcellE) leadcell = *refItr;
129  }
130  if(leadcell) {
131  refEta = leadcell->eta();
132  refPhi = leadcell->phi();
133  }
134  } else {
135  refEta = refCluster.eta();
136  refPhi = refCluster.phi();
137  }
138 
139  // for now use the standard matching sizes determined by egamma, but may need to change for muons??
140  // egamma shower is probably wider than muon cell track
141  const std::vector<const xAOD::CaloCluster*> testClusters =
142  tcmap.RetrieveTopoClusters(refEta, refPhi, refCluster.e()*cosh(refEta));
143 
144  return getMatchedClusters(refCluster, testClusters, matchedClusters);
145  }
146 
147  // fill a list of clusters from the testClusters container that match the reference cluster
148  // match criteria determined by calling clustersAreMatched
149  // return true if matchedClusters list is non-empty
151  const std::vector<const xAOD::CaloCluster*>& testClusters,
152  std::vector<std::pair<const xAOD::CaloCluster*, float> >& matchedClustersAndE) const
153  {
154  // check that it's empty?
155  matchedClustersAndE.clear();
156 
157  for(const auto& testCluster : testClusters) {
158  float sharedEfrac = getClusterSharedEfrac(refCluster, *testCluster);
159  if(sharedEfrac>m_minSharedEfrac) {
160  matchedClustersAndE.emplace_back(testCluster,sharedEfrac);
161  }
162  }
163  return !matchedClustersAndE.empty();
164  }
165 
166  // fill a list of clusters from the configured cluster container that match the reference cluster
167  // match criteria determined by calling clustersAreMatched
168  // return true if matchedClusters list is non-empty
170  std::vector<std::pair<const xAOD::CaloCluster*, float> >& matchedClustersAndE,
171  const TopoClusterMap& tcmap,
172  bool useLeadingCellEtaPhi) const
173  {
174  float refEta(0.), refPhi(0.);
175  if(useLeadingCellEtaPhi) { // needed for muons because muon clusters have no eta/phi
176  const CaloCell* leadcell(nullptr);
177  float leadcellE(0.);
178  for(auto refItr = refCluster.cell_begin(); refItr!=refCluster.cell_end(); ++refItr) {
179  if(refItr->e() > leadcellE) leadcell = *refItr;
180  }
181  if(leadcell) {
182  refEta = leadcell->eta();
183  refPhi = leadcell->phi();
184  }
185  } else {
186  refEta = refCluster.eta();
187  refPhi = refCluster.phi();
188  }
189 
190  // for now use the standard matching sizes determined by egamma, but may need to change for muons??
191  // egamma shower is probably wider than muon cell track
192  const std::vector<const xAOD::CaloCluster*> testClusters =
193  tcmap.RetrieveTopoClusters(refEta, refPhi, refCluster.e()*cosh(refEta));
194 
195  return getMatchedClusters(refCluster, testClusters, matchedClustersAndE);
196  }
197 
198  // set ElementLinks to clusters from the configured cluster container that match the reference cluster
199  // works via getMatchedClusters
200  // return true if matchedClusters list is non-empty
202  const xAOD::CaloCluster& refCluster,
203  const std::vector<const xAOD::CaloCluster*>& testClusters,
204  bool (*gtrthan)(const std::pair<const xAOD::CaloCluster*,float>& pair1,
205  const std::pair<const xAOD::CaloCluster*,float>& pair2)) const
206  {
207  std::vector<std::pair<const CaloCluster*,float> > matchedClustersAndE;
208  std::vector<ElementLink<CaloClusterContainer> > tcLinks;
209  std::vector<float> tcSharedE;
210  if(!testClusters.empty()) {
211  const CaloClusterContainer* pClCont = static_cast<const CaloClusterContainer*>(testClusters.front()->container());
212  if(getMatchedClusters(refCluster, testClusters, matchedClustersAndE)) {
213  std::sort(matchedClustersAndE.begin(),matchedClustersAndE.end(),gtrthan);
214  for(const auto& tcAndE : matchedClustersAndE) {
215  tcLinks.emplace_back(*pClCont,tcAndE.first->index());
216  tcSharedE.push_back(tcAndE.second);
217  }
218  }
219  }
220  // apply the decoration to the reference cluster -- no exceptions
221  elementLinkDec(refCluster) = tcLinks;
222  ATH_MSG_VERBOSE("Decorate cluster " << refCluster.index() << " with " << elementLinkDec(refCluster).size() << " tc links");
223 
224  return StatusCode::SUCCESS;
225  }
226 
227  // set ElementLinks to clusters from the configured cluster container that match the reference cluster
228  // works via getMatchedClusters
229  // return true if matchedClusters list is non-empty
231  elementLinkDecorHandle_t& elementLinkDec,
232  const xAOD::CaloCluster& refCluster,
233  const TopoClusterMap& tcmap,
234  bool useLeadingCellEtaPhi,
235  bool (*gtrthan)(const std::pair<const xAOD::CaloCluster*,float>& pair1,
236  const std::pair<const xAOD::CaloCluster*,float>& pair2)) const
237  {
238  std::vector<std::pair<const CaloCluster*,float> > matchedClustersAndE;
239  std::vector<ElementLink<CaloClusterContainer> > tcLinks;
240  std::vector<float> tcSharedE;
241  // no need to worry about return value.
242  if(getMatchedClusters(refCluster, matchedClustersAndE, tcmap, useLeadingCellEtaPhi)) {
243  const CaloClusterContainer* pClCont = static_cast<const CaloClusterContainer*>(matchedClustersAndE.front().first->container());
244  std::sort(matchedClustersAndE.begin(),matchedClustersAndE.end(),gtrthan);
245  for(const auto& tcAndE : matchedClustersAndE) {
246  tcLinks.emplace_back(*pClCont,tcAndE.first->index());
247  tcSharedE.push_back(tcAndE.second);
248  }
249  }
250  // apply the decoration to the reference cluster -- no exceptions
251  elementLinkDec(refCluster) = tcLinks;
252  ATH_MSG_VERBOSE("Decorate cluster " << refCluster.index() << " with " << elementLinkDec(refCluster).size() << " tc links");
253 
254  return StatusCode::SUCCESS;
255  }
256 }
ClusterMatching::CaloClusterMatchingTool::linkMatchedClusters
StatusCode linkMatchedClusters(elementLinkDecorHandle_t &elementLinkDec, const xAOD::CaloCluster &refCluster, const std::vector< const xAOD::CaloCluster * > &testClusters, bool(*gtrthan)(const std::pair< const xAOD::CaloCluster *, float > &pair1, const std::pair< const xAOD::CaloCluster *, float > &pair2)) const override final
Definition: CaloClusterMatchingTool.cxx:201
xAOD::CaloCluster_v1::phi
virtual double phi() const
The azimuthal angle ( ) of the particle.
Definition: CaloCluster_v1.cxx:256
xAOD::CaloCluster_v1::cell_begin
const_cell_iterator cell_begin() const
Iterator of the underlying CaloClusterCellLink (const version)
Definition: CaloCluster_v1.h:812
CaloCell::phi
virtual double phi() const override final
get phi (through CaloDetDescrElement)
Definition: CaloCell.h:359
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
ClusterMatching::CaloClusterMatchingTool::initialize
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
Definition: CaloClusterMatchingTool.cxx:32
CaloClusterMatchingTool.h
MuonSimDataDict::pair2
std::pair< HepMcParticleLink, CscMcData > pair2
Definition: MuonSimDataDict.h:15
xAOD
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Definition: ICaloAffectedTool.h:24
TopoClusterMap::SetTopoClusters
StatusCode SetTopoClusters(const xAOD::CaloClusterContainer *)
Definition: TopoClusterMap.cxx:41
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
ClusterMatching::CaloClusterMatchingTool::getMatchedClusters
bool getMatchedClusters(const xAOD::CaloCluster &refCluster, const std::vector< const xAOD::CaloCluster * > &testClusters, std::vector< const xAOD::CaloCluster * > &matchedClusters) const override final
Definition: CaloClusterMatchingTool.cxx:102
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
xAOD::CaloCluster_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition: CaloCluster_v1.cxx:251
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::AuxElement::index
size_t index() const
Return the index of this element within its container.
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
ClusterMatching
Definition: ICaloClusterMatchingTool.h:26
xAOD::CaloCluster_v1::p4
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition: CaloCluster_v1.cxx:465
ClusterMatching::CaloClusterMatchingTool::getClusterSharedEfrac
float getClusterSharedEfrac(const xAOD::CaloCluster &refCluster, const xAOD::CaloCluster &testCluster) const override final
Definition: CaloClusterMatchingTool.cxx:68
MuonSimDataDict::pair1
std::pair< HepMcParticleLink,MuonMCData > pair1
Definition: MuonSimDataDict.h:14
TopoClusterMap
Definition: TopoClusterMap.h:11
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
ClusterMatching::CaloClusterMatchingTool::finalize
virtual StatusCode finalize() override
Definition: CaloClusterMatchingTool.cxx:47
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
xAOD::CaloCluster_v1::cell_end
const_cell_iterator cell_end() const
Definition: CaloCluster_v1.h:813
ClusterMatching::CaloClusterMatchingTool::clustersAreMatched
bool clustersAreMatched(const xAOD::CaloCluster &refCluster, const xAOD::CaloCluster &testCluster) const override final
Definition: CaloClusterMatchingTool.cxx:93
TopoClusterMap::RetrieveTopoClusters
std::vector< const xAOD::CaloCluster * > RetrieveTopoClusters(double eta, double phi, double Pt) const
Definition: TopoClusterMap.cxx:118
ClusterMatching::CaloClusterMatchingTool::fillClusterMap
StatusCode fillClusterMap(const EventContext &ctx, TopoClusterMap &tcmap) const override final
Definition: CaloClusterMatchingTool.cxx:58
ClusterMatching::CaloClusterMatchingTool::~CaloClusterMatchingTool
virtual ~CaloClusterMatchingTool()
Destructor:
xAOD::CaloCluster_v1::e
virtual double e() const
The total energy of the particle.
Definition: CaloCluster_v1.cxx:265
CaloCell::eta
virtual double eta() const override final
get eta (through CaloDetDescrElement)
Definition: CaloCell.h:366