CMS 3D CMS Logo

KDTreeLinkerTrackEcal.cc
Go to the documentation of this file.
4 
5 #include "TMath.h"
6 
7 // This class is used to find all links between Tracks and ECAL clusters
8 // using a KDTree algorithm.
9 // It is used in PFBlockAlgo.cc in the function links().
11 public:
13  ~KDTreeLinkerTrackEcal() override;
14 
15  // With this method, we create the list of psCluster that we want to link.
17 
18  // Here, we create the list of ecalCluster that we want to link. From ecalCluster
19  // and fraction, we will create a second list of rechits that will be used to
20  // build the KDTree.
21  void insertFieldClusterElt(reco::PFBlockElement *ecalCluster) override;
22 
23  // The KDTree building from rechits list.
24  void buildTree() override;
25 
26  // Here we will iterate over all tracks. For each track intersection point with ECAL,
27  // we will search the closest rechits in the KDTree, from rechits we will find the
28  // ecalClusters and after that we will check the links between the track and
29  // all closest ecalClusters.
30  void searchLinks() override;
31 
32  // Here, we will store all PS/ECAL founded links in the PFBlockElement class
33  // of each psCluster in the PFmultilinks field.
34  void updatePFBlockEltWithLinks() override;
35 
36  // Here we free all allocated structures.
37  void clear() override;
38 
39 private:
40  // Data used by the KDTree algorithm : sets of Tracks and ECAL clusters.
43 
44  // Sets of rechits that compose the ECAL clusters.
46 
47  // Map of linked Track/ECAL clusters.
49 
50  // Map of the ECAL clusters associated to a rechit.
52 
53  // KD trees
55 };
56 
57 // the text name is different so that we can easily
58 // construct it when calling the factory
59 DEFINE_EDM_PLUGIN(KDTreeLinkerFactory, KDTreeLinkerTrackEcal, "KDTreeTrackAndECALLinker");
60 
62 
64 
66  if (track->trackRefPF()->extrapolatedPoint(reco::PFTrajectoryPoint::ECALShowerMax).isValid()) {
67  targetSet_.insert(track);
68  }
69 }
70 
72  const reco::PFClusterRef &clusterref = ecalCluster->clusterRef();
73 
74  // This test is more or less done in PFBlockAlgo.h. In others cases, it should be switch on.
75  // if (!((clusterref->layer() == PFLayer::ECAL_ENDCAP) ||
76  // (clusterref->layer() == PFLayer::ECAL_BARREL)))
77  // return;
78 
79  const std::vector<reco::PFRecHitFraction> &fraction = clusterref->recHitFractions();
80 
81  // We create a list of ecalCluster
82  fieldClusterSet_.insert(ecalCluster);
83  for (size_t rhit = 0; rhit < fraction.size(); ++rhit) {
84  const reco::PFRecHitRef &rh = fraction[rhit].recHitRef();
85  double fract = fraction[rhit].fraction();
86 
87  if ((rh.isNull()) || (fract < cutOffFrac))
88  continue;
89 
90  const reco::PFRecHit &rechit = *rh;
91 
92  // We save the links rechit to EcalClusters
93  rechit2ClusterLinks_[&rechit].insert(ecalCluster);
94 
95  // We create a liste of rechits
96  rechitsSet_.insert(&rechit);
97  }
98 }
99 
101  // List of pseudo-rechits that will be used to create the KDTree
102  std::vector<KDTreeNodeInfo<reco::PFRecHit const *, 2>> eltList;
103 
104  // Filling of this list
105  for (RecHitSet::const_iterator it = rechitsSet_.begin(); it != rechitsSet_.end(); it++) {
106  const reco::PFRecHit::REPPoint &posrep = (*it)->positionREP();
107 
108  KDTreeNodeInfo<reco::PFRecHit const *, 2> rh1(*it, posrep.eta(), posrep.phi());
109  eltList.push_back(rh1);
110 
111  // Here we solve the problem of phi circular set by duplicating some rechits
112  // too close to -Pi (or to Pi) and adding (substracting) to them 2 * Pi.
113  if (rh1.dims[1] > (M_PI - phiOffset_)) {
114  float phi = rh1.dims[1] - 2 * M_PI;
115  KDTreeNodeInfo<reco::PFRecHit const *, 2> rh2(*it, float(posrep.eta()), phi);
116  eltList.push_back(rh2);
117  }
118 
119  if (rh1.dims[1] < (M_PI * -1.0 + phiOffset_)) {
120  float phi = rh1.dims[1] + 2 * M_PI;
121  KDTreeNodeInfo<reco::PFRecHit const *, 2> rh3(*it, float(posrep.eta()), phi);
122  eltList.push_back(rh3);
123  }
124  }
125 
126  // Here we define the upper/lower bounds of the 2D space (eta/phi).
127  float phimin = -1.0 * M_PI - phiOffset_;
128  float phimax = M_PI + phiOffset_;
129 
130  // etamin-etamax, phimin-phimax
131  KDTreeBox region(-3.0f, 3.0f, phimin, phimax);
132 
133  // We may now build the KDTree
134  tree_.build(eltList, region);
135 }
136 
138  // Most of the code has been taken from LinkByRecHit.cc
139 
140  // We iterate over the tracks.
141  for (BlockEltSet::iterator it = targetSet_.begin(); it != targetSet_.end(); it++) {
142  reco::PFRecTrackRef trackref = (*it)->trackRefPF();
143 
144  // We set the multilinks flag of the track to true. It will allow us to
145  // use in an optimized way our algo results in the recursive linking algo.
146  (*it)->setIsValidMultilinks(true);
147 
148  const reco::PFTrajectoryPoint &atECAL = trackref->extrapolatedPoint(reco::PFTrajectoryPoint::ECALShowerMax);
149 
150  // The track didn't reach ecal
151  if (!atECAL.isValid())
152  continue;
153 
154  const reco::PFTrajectoryPoint &atVertex = trackref->extrapolatedPoint(reco::PFTrajectoryPoint::ClosestApproach);
155 
156  double trackPt = sqrt(atVertex.momentum().Vect().Perp2());
157  float tracketa = atECAL.positionREP().eta();
158  float trackphi = atECAL.positionREP().phi();
159  double trackx = atECAL.position().X();
160  double tracky = atECAL.position().Y();
161  double trackz = atECAL.position().Z();
162 
163  // Estimate the maximal envelope in phi/eta that will be used to find rechit candidates.
164  // Same envelope for cap et barrel rechits.
165  float range = cristalPhiEtaMaxSize_ * (2.0 + 1.0 / std::min(1., trackPt / 2.));
166 
167  // We search for all candidate recHits, ie all recHits contained in the maximal size envelope.
168  std::vector<reco::PFRecHit const *> recHits;
169  KDTreeBox trackBox(tracketa - range, tracketa + range, trackphi - range, trackphi + range);
170  tree_.search(trackBox, recHits);
171 
172  // Here we check all rechit candidates using the non-approximated method.
173  for (auto const &recHit : recHits) {
174  const auto &cornersxyz = recHit->getCornersXYZ();
175  const auto &posxyz = recHit->position();
176  const auto &rhrep = recHit->positionREP();
177  const auto &corners = recHit->getCornersREP();
178 
179  double rhsizeeta = fabs(corners[3].eta() - corners[1].eta());
180  double rhsizephi = fabs(corners[3].phi() - corners[1].phi());
181  if (rhsizephi > M_PI)
182  rhsizephi = 2. * M_PI - rhsizephi;
183 
184  double deta = fabs(rhrep.eta() - tracketa);
185  double dphi = fabs(rhrep.phi() - trackphi);
186  if (dphi > M_PI)
187  dphi = 2. * M_PI - dphi;
188 
189  // Find all clusters associated to given rechit
190  RecHit2BlockEltMap::iterator ret = rechit2ClusterLinks_.find(recHit);
191 
192  for (BlockEltSet::const_iterator clusterIt = ret->second.begin(); clusterIt != ret->second.end(); clusterIt++) {
193  reco::PFClusterRef clusterref = (*clusterIt)->clusterRef();
194  double clusterz = clusterref->position().z();
195  int fracsNbr = clusterref->recHitFractions().size();
196 
197  if (clusterref->layer() == PFLayer::ECAL_BARREL) { // BARREL
198  // Check if the track is in the barrel
199  if (fabs(trackz) > 300.)
200  continue;
201 
202  double _rhsizeeta = rhsizeeta * (2.00 + 1.0 / (fracsNbr * std::min(1., trackPt / 2.)));
203  double _rhsizephi = rhsizephi * (2.00 + 1.0 / (fracsNbr * std::min(1., trackPt / 2.)));
204 
205  // Check if the track and the cluster are linked
206  if (deta < (_rhsizeeta / 2.) && dphi < (_rhsizephi / 2.))
207  target2ClusterLinks_[*it].insert(*clusterIt);
208 
209  } else { // ENDCAP
210 
211  // Check if the track is in the cap
212  if (fabs(trackz) < 300.)
213  continue;
214  if (trackz * clusterz < 0.)
215  continue;
216 
217  double x[5];
218  double y[5];
219  for (unsigned jc = 0; jc < 4; ++jc) {
220  auto cornerposxyz = cornersxyz[jc];
221  x[3 - jc] = cornerposxyz.x() +
222  (cornerposxyz.x() - posxyz.x()) * (1.00 + 0.50 / fracsNbr / std::min(1., trackPt / 2.));
223  y[3 - jc] = cornerposxyz.y() +
224  (cornerposxyz.y() - posxyz.y()) * (1.00 + 0.50 / fracsNbr / std::min(1., trackPt / 2.));
225  }
226 
227  x[4] = x[0];
228  y[4] = y[0];
229 
230  bool isinside = TMath::IsInside(trackx, tracky, 5, x, y);
231 
232  // Check if the track and the cluster are linked
233  if (isinside)
234  target2ClusterLinks_[*it].insert(*clusterIt);
235  }
236  }
237  }
238  }
239 }
240 
242  //TODO YG : Check if cluster positionREP() is valid ?
243 
244  // Here we save in each track the list of phi/eta values of linked clusters.
245  for (BlockElt2BlockEltMap::iterator it = target2ClusterLinks_.begin(); it != target2ClusterLinks_.end(); ++it) {
246  reco::PFMultiLinksTC multitracks(true);
247 
248  for (BlockEltSet::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) {
249  double clusterphi = (*jt)->clusterRef()->positionREP().phi();
250  double clustereta = (*jt)->clusterRef()->positionREP().eta();
251 
252  multitracks.linkedClusters.push_back(std::make_pair(clusterphi, clustereta));
253  }
254 
255  it->first->setMultilinks(multitracks);
256  }
257 }
258 
260  targetSet_.clear();
261  fieldClusterSet_.clear();
262 
263  rechitsSet_.clear();
264 
265  rechit2ClusterLinks_.clear();
266  target2ClusterLinks_.clear();
267 
268  tree_.clear();
269 }
KDTreeLinkerAlgo.h
runTheMatrix.ret
ret
prodAgent to be discontinued
Definition: runTheMatrix.py:355
FastTimerService_cff.range
range
Definition: FastTimerService_cff.py:34
DDAxes::y
KDTreeLinkerTrackEcal::rechitsSet_
RecHitSet rechitsSet_
Definition: KDTreeLinkerTrackEcal.cc:45
reco::PFTrajectoryPoint::momentum
const math::XYZTLorentzVector & momentum() const
4-momenta quadrivector
Definition: PFTrajectoryPoint.h:109
f
double f[11][100]
Definition: MuScleFitUtils.cc:78
min
T min(T a, T b)
Definition: MathUtil.h:58
phimin
float phimin
Definition: ReggeGribovPartonMCHadronizer.h:107
edm::Ref::isNull
bool isNull() const
Checks for null.
Definition: Ref.h:235
KDTreeLinkerTrackEcal::tree_
KDTreeLinkerAlgo< reco::PFRecHit const * > tree_
Definition: KDTreeLinkerTrackEcal.cc:54
KDTreeLinkerTrackEcal::KDTreeLinkerTrackEcal
KDTreeLinkerTrackEcal(const edm::ParameterSet &conf)
Definition: KDTreeLinkerTrackEcal.cc:61
DDAxes::x
KDTreeLinkerBase::phiOffset_
float phiOffset_
Definition: KDTreeLinkerBase.h:84
rpcPointValidation_cfi.recHit
recHit
Definition: rpcPointValidation_cfi.py:7
KDTreeLinkerBase::cutOffFrac
const float cutOffFrac
Definition: KDTreeLinkerBase.h:87
edm::Ref< PFClusterCollection >
PFLayer::ECAL_BARREL
Definition: PFLayer.h:33
reco::PFTrajectoryPoint::positionREP
const REPPoint & positionREP() const
trajectory position in (rho, eta, phi) base
Definition: PFTrajectoryPoint.h:103
RhoEtaPhi
Definition: PtEtaPhiMass.h:38
KDTreeLinkerAlgo::search
void search(const KDTreeBox< DIM > &searchBox, std::vector< DATA > &resRecHitList)
Definition: KDTreeLinkerAlgo.h:203
KDTreeLinkerTrackEcal::insertTargetElt
void insertTargetElt(reco::PFBlockElement *track) override
Definition: KDTreeLinkerTrackEcal.cc:65
KDTreeLinkerBase.h
PVValHelper::eta
Definition: PVValidationHelpers.h:69
reco::PFTrajectoryPoint::ECALShowerMax
Definition: PFTrajectoryPoint.h:46
mathSSE::sqrt
T sqrt(T t)
Definition: SSEVec.h:19
KDTreeLinkerTrackEcal::insertFieldClusterElt
void insertFieldClusterElt(reco::PFBlockElement *ecalCluster) override
Definition: KDTreeLinkerTrackEcal.cc:71
KDTreeBox
Definition: KDTreeLinkerAlgo.h:14
PFCluster.h
KDTreeLinkerAlgo< reco::PFRecHit const * >
reco::PFMultiLinksTC
Definition: PFMultilinksTC.h:14
KDTreeLinkerTrackEcal::updatePFBlockEltWithLinks
void updatePFBlockEltWithLinks() override
Definition: KDTreeLinkerTrackEcal.cc:241
reco::PFMultiLinksTC::linkedClusters
PFMultilinksType linkedClusters
Definition: PFMultilinksTC.h:17
DEFINE_EDM_PLUGIN
#define DEFINE_EDM_PLUGIN(factory, type, name)
Definition: PluginFactory.h:124
FastTrackerRecHitMaskProducer_cfi.recHits
recHits
Definition: FastTrackerRecHitMaskProducer_cfi.py:8
KDTreeLinkerBase::cristalPhiEtaMaxSize_
float cristalPhiEtaMaxSize_
Definition: KDTreeLinkerBase.h:77
edm::ParameterSet
Definition: ParameterSet.h:36
RecHit2BlockEltMap
std::map< const reco::PFRecHit *, BlockEltSet > RecHit2BlockEltMap
Definition: KDTreeLinkerBase.h:16
reco::PFTrajectoryPoint::position
const math::XYZPoint & position() const
cartesian position (x, y, z)
Definition: PFTrajectoryPoint.h:100
edmplugin::PluginFactory
Definition: PluginFactory.h:34
KDTreeLinkerTrackEcal
Definition: KDTreeLinkerTrackEcal.cc:10
M_PI
#define M_PI
Definition: BXVectorInputProducer.cc:50
funct::fract
const Fraction< n, m >::type & fract()
Definition: Fraction.h:36
KDTreeLinkerTrackEcal::searchLinks
void searchLinks() override
Definition: KDTreeLinkerTrackEcal.cc:137
KDTreeNodeInfo
Definition: KDTreeLinkerAlgo.h:34
RhoEtaPhi::eta
float eta() const
momentum pseudorapidity
Definition: PtEtaPhiMass.h:52
reco::PFTrajectoryPoint::isValid
bool isValid() const
is this point valid ?
Definition: PFTrajectoryPoint.h:84
reco::PFBlockElement
Abstract base class for a PFBlock element (track, cluster...)
Definition: PFBlockElement.h:26
phimax
float phimax
Definition: ReggeGribovPartonMCHadronizer.h:106
DDAxes::phi
BlockElt2BlockEltMap
std::map< reco::PFBlockElement *, BlockEltSet > BlockElt2BlockEltMap
Definition: KDTreeLinkerBase.h:17
RhoEtaPhi::phi
float phi() const
momentum azimuthal angle
Definition: PtEtaPhiMass.h:54
KDTreeLinkerAlgo::clear
void clear()
Definition: KDTreeLinkerAlgo.h:122
reco::PFTrajectoryPoint
A PFTrack holds several trajectory points, which basically contain the position and momentum of a tra...
Definition: PFTrajectoryPoint.h:26
KDTreeLinkerTrackEcal::targetSet_
BlockEltSet targetSet_
Definition: KDTreeLinkerTrackEcal.cc:41
RecHitSet
std::set< const reco::PFRecHit * > RecHitSet
Definition: KDTreeLinkerBase.h:14
KDTreeLinkerTrackEcal::fieldClusterSet_
BlockEltSet fieldClusterSet_
Definition: KDTreeLinkerTrackEcal.cc:42
BlockEltSet
std::set< reco::PFBlockElement * > BlockEltSet
Definition: KDTreeLinkerBase.h:13
HLT_2018_cff.region
region
Definition: HLT_2018_cff.py:81479
reco::PFRecHit
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
Definition: PFRecHit.h:31
KDTreeLinkerAlgo::build
void build(std::vector< KDTreeNodeInfo< DATA, DIM > > &eltList, const KDTreeBox< DIM > &region)
Definition: KDTreeLinkerAlgo.h:147
HLT_2018_cff.track
track
Definition: HLT_2018_cff.py:10352
KDTreeLinkerBase
Definition: KDTreeLinkerBase.h:19
reco::PFTrajectoryPoint::ClosestApproach
Point of closest approach from beam axis (initial point in the case of PFSimParticle)
Definition: PFTrajectoryPoint.h:36
KDTreeLinkerTrackEcal::buildTree
void buildTree() override
Definition: KDTreeLinkerTrackEcal.cc:100
KDTreeLinkerTrackEcal::rechit2ClusterLinks_
RecHit2BlockEltMap rechit2ClusterLinks_
Definition: KDTreeLinkerTrackEcal.cc:51
listHistos.trackPt
trackPt
Definition: listHistos.py:120
HLT_2018_cff.fraction
fraction
Definition: HLT_2018_cff.py:51317
KDTreeLinkerTrackEcal::clear
void clear() override
Definition: KDTreeLinkerTrackEcal.cc:259
reco::PFBlockElement::clusterRef
virtual const PFClusterRef & clusterRef() const
Definition: PFBlockElement.h:90
KDTreeLinkerTrackEcal::target2ClusterLinks_
BlockElt2BlockEltMap target2ClusterLinks_
Definition: KDTreeLinkerTrackEcal.cc:48
KDTreeLinkerTrackEcal::~KDTreeLinkerTrackEcal
~KDTreeLinkerTrackEcal() override
Definition: KDTreeLinkerTrackEcal.cc:63