ATLAS Offline Software
PFMatcher.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /*
6  * PFMatcher.h
7  *
8  * Created on: 03.04.2014
9  * Author: tlodd
10  */
11 
12 #ifndef PFMATCHER_H_
13 #define PFMATCHER_H_
14 
16 #include <algorithm>
17 #include <utility>
18 #include <cmath>
19 
20 class DistanceProvider;
21 
22 namespace PFMatch {
23 
24  typedef std::pair<ICluster*,double> MatchDistance;
25 
30 public:
31  TrackClusterMatcher( std::unique_ptr<IDistanceProvider> distanceProvider, double matchCut):
32  m_distanceProvider(std::move(distanceProvider)), m_matchCut(matchCut) { setDRParameters(); }
33 
34  virtual ~TrackClusterMatcher() {};
35 
36  MatchDistance match(ITrack* track, ICluster* cluster) const;
37 
38  template<class ClusterType>
40  ITrack* track,
41  const std::vector<ClusterType*>& clusters) const;
42  template<class ClusterType>
43  std::vector<MatchDistance> bestMatches(ITrack* track,
44  std::vector<ClusterType*>& clusters,
45  int nMatches,
46  double energyThreshold) const;
47  template<class ClusterType>
48  double getDRCutSquared(ClusterType* theCluster) const;
49 
50 private:
51 
52  std::unique_ptr<IDistanceProvider> m_distanceProvider;
53  double m_matchCut;
55  float m_drcut_par[9][3];
56 
58  void setDRParameters();
59 
60 
61 };
62 
63 template<class ClusterType>
65  ClusterType* bestCluster = nullptr;
66  double bestDistance(m_matchCut);
67  unsigned int nClusters(clusters.size());
68  for (unsigned int iCluster = 0; iCluster < nClusters; ++iCluster){
69 
70  ClusterType* thisCluster = clusters[iCluster];
71  double thisDistance(m_distanceProvider->distanceBetween(track, clusters[iCluster]));
72  double mybestdistance = getDRCutSquared(thisCluster);
73 
74  if (thisDistance < mybestdistance){
75  if (thisDistance < bestDistance) {
76  bestDistance = thisDistance;
77  bestCluster = thisCluster;
78  }
79  }
80  }
81 
82  return MatchDistance(bestCluster, bestDistance);
83  }
84 
85 template<class ClusterType>
86 std::vector<MatchDistance> TrackClusterMatcher::bestMatches(ITrack* track, std::vector<ClusterType*>& clusters, int nMatches, double energyThreshold) const {
87 
88  std::vector<MatchDistance> result;
89  unsigned const nClusters(clusters.size());
90 
91  if (nMatches == -1) {
92  for (unsigned int iCluster = 0; iCluster < nClusters; ++iCluster) {
93  ClusterType* thisCluster = clusters[iCluster];
94  double thisDistance(m_distanceProvider->distanceBetween(track, thisCluster));
95  if (thisDistance < m_matchCut) {
96  result.push_back(MatchDistance(thisCluster, thisDistance));
97  }
98  }
99  }
100 
101  else{
102  int nLoops = nMatches;
103  std::vector<unsigned int> masked;
104  std::vector<int> maskedType;
105  for (int imatch = 0; imatch < nLoops; ++imatch) {
106  ClusterType* bestCluster = nullptr;
107  double bestDistance(m_matchCut);
108  int iMasked = -1;
109  for (unsigned int iCluster = 0; iCluster < nClusters; ++iCluster) {
110  /* Do not consider matched ones. */
111  if (masked.size() != 0 && find(masked.begin(), masked.end(), iCluster) != masked.end()) {
112  continue;
113  }
114 
115  ClusterType* thisCluster = clusters[iCluster];
116 
117  /* Require that first matched cluster energy is above energyThreshold (10% of track energy). */
118  if(imatch == 0 && thisCluster->e() <= energyThreshold) {
119  continue;
120  }
121 
122  /* Do not consider the same type (ECAL, HCAL or FCAL) ones. */
123  /* First we check if another ECAL, HCAL or FCAL cluster is found */
124  if ((maskedType.size() != 0 && find(maskedType.begin(), maskedType.end(),
125  thisCluster->getEfRecCluster()->getClusterType()) != maskedType.end())
126  || (thisCluster->getEfRecCluster()->getClusterType() == 4)) { /* then also veto if it is type 4, which means "unknown" type */
127  continue;
128  }
129 
130  double thisDistance(m_distanceProvider->distanceBetween(track, thisCluster));
131 
132  if (thisDistance < bestDistance) {
133  iMasked = iCluster;
134  bestDistance = thisDistance;
135  bestCluster = thisCluster;
136  }
137  }
138  if (iMasked == -1 || nullptr == bestCluster) break;
139 
140  masked.push_back(iMasked);
141  maskedType.push_back(bestCluster->getEfRecCluster()->getClusterType());
142 
143  result.push_back(MatchDistance(bestCluster, bestDistance));
144  }
145  assert(maskedType.size() == masked.size());
146  }
147 
148  return result;
149 
150  }
151 
152 template<class ClusterType>
153  double TrackClusterMatcher::getDRCutSquared( ClusterType* theCluster) const {
154 
155  double m_coneRSq = 1.64*1.64;
156  double coneRSq = m_coneRSq;
157  int ieta = -1;
158  double clusEta;
159 
160  clusEta = theCluster->eta();
161 
162  if (std::abs(clusEta)<0.6) ieta=0;
163  if (std::abs(clusEta)>=0.6 && std::abs(clusEta)<1.6) ieta = 1 + int((std::abs(clusEta) - 0.6)/0.2) ;
164  if (std::abs(clusEta)>=1.6 && std::abs(clusEta)<2.0) ieta = 6 ;
165  if (std::abs(clusEta)>=2.0 && std::abs(clusEta)<2.5) ieta = 7 ;
166  if (std::abs(clusEta)>=2.5) ieta = 8 ;
167 
168  double clusterEnergy = theCluster->e()/1000.0;
169 
170  double drcut = m_drcut_par[ieta][0]+m_drcut_par[ieta][1]*exp(m_drcut_par[ieta][2]*clusterEnergy);
171  coneRSq = drcut*drcut;
172 
173  if (coneRSq>m_coneRSq) coneRSq = m_coneRSq;
174  double conemin = m_drcut_par[ieta][0]+m_drcut_par[ieta][1]*exp(m_drcut_par[ieta][2]*10);
175 
176  if (coneRSq<conemin*conemin) coneRSq = conemin*conemin;
177  return coneRSq;
178 
179  }
180 
181 }
182 
183 #endif /* PFMATCHER_H_ */
PFMatch::MatchDistance
std::pair< ICluster *, double > MatchDistance
Definition: PFMatcher.h:24
PFMatchInterfaces.h
get_generator_info.result
result
Definition: get_generator_info.py:21
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
PFMatch::ICluster
Definition: PFMatchInterfaces.h:37
PFMatch::ITrack
Definition: PFMatchInterfaces.h:28
PFMatch::TrackClusterMatcher::m_matchCut
double m_matchCut
Definition: PFMatcher.h:53
PFMatch::TrackClusterMatcher
Checks if a cluster should be matched to a track or not, and has methods to return list of best match...
Definition: PFMatcher.h:29
PFMatch::TrackClusterMatcher::~TrackClusterMatcher
virtual ~TrackClusterMatcher()
Definition: PFMatcher.h:34
PFMatch::TrackClusterMatcher::bestMatchDRparametrized
MatchDistance bestMatchDRparametrized(ITrack *track, const std::vector< ClusterType * > &clusters) const
Definition: PFMatcher.h:64
PFMatch::TrackClusterMatcher::m_distanceProvider
std::unique_ptr< IDistanceProvider > m_distanceProvider
Definition: PFMatcher.h:52
PFMatch::TrackClusterMatcher::TrackClusterMatcher
TrackClusterMatcher(std::unique_ptr< IDistanceProvider > distanceProvider, double matchCut)
Definition: PFMatcher.h:31
PFMatch
Definition: PFMatchDistance.h:17
RunTileMonitoring.clusters
clusters
Definition: RunTileMonitoring.py:133
PFMatch::TrackClusterMatcher::match
MatchDistance match(ITrack *track, ICluster *cluster) const
Definition: PFMatcher.cxx:17
PFMatch::TrackClusterMatcher::getDRCutSquared
double getDRCutSquared(ClusterType *theCluster) const
Definition: PFMatcher.h:153
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
PFMatch::TrackClusterMatcher::bestMatches
std::vector< MatchDistance > bestMatches(ITrack *track, std::vector< ClusterType * > &clusters, int nMatches, double energyThreshold) const
Definition: PFMatcher.h:86
PFMatch::TrackClusterMatcher::setDRParameters
void setDRParameters()
This sets the parameters in the above array.
Definition: PFMatcher.cxx:21
PFMatch::TrackClusterMatcher::m_drcut_par
float m_drcut_par[9][3]
This stores the parameters to vary DR cut with Pt.
Definition: PFMatcher.h:55