CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
KDTreeLinkerTrackHcal.cc
Go to the documentation of this file.
2 
4 #include "TMath.h"
5 
8 {
10  setPhiOffset(0.32);
11 }
12 
14 {
15  clear();
16 }
17 
18 void
20 {
21  targetSet_.insert(track);
22 }
23 
24 
25 void
27 {
28  reco::PFClusterRef clusterref = hcalCluster->clusterRef();
29 
30  // This test is more or less done in PFBlockAlgo.h. In others cases, it should be switch on.
31  // if (!((clusterref->layer() == PFLayer::HCAL_ENDCAP) ||
32  // (clusterref->layer() == PFLayer::HCAL_BARREL1)))
33  // return;
34 
35  const std::vector<reco::PFRecHitFraction> &fraction = clusterref->recHitFractions();
36 
37  // We create a list of hcalCluster
38  fieldClusterSet_.insert(hcalCluster);
39  for(size_t rhit = 0; rhit < fraction.size(); ++rhit) {
40  const reco::PFRecHitRef& rh = fraction[rhit].recHitRef();
41  double fract = fraction[rhit].fraction();
42 
43  if ((rh.isNull()) || (fract < 1E-4))
44  continue;
45 
46  const reco::PFRecHit& rechit = *rh;
47 
48  // We save the links rechit to HcalClusters
49  rechit2ClusterLinks_[&rechit].insert(hcalCluster);
50 
51  // We create a liste of rechits
52  rechitsSet_.insert(&rechit);
53  }
54 }
55 
56 void
58 {
59  // List of pseudo-rechits that will be used to create the KDTree
60  std::vector<KDTreeNodeInfo> eltList;
61 
62  // Filling of this list
63  for(RecHitSet::const_iterator it = rechitsSet_.begin();
64  it != rechitsSet_.end(); it++) {
65 
66  const reco::PFRecHit::REPPoint &posrep = (*it)->positionREP();
67 
68  KDTreeNodeInfo rh1 (*it, posrep.Eta(), posrep.Phi());
69  eltList.push_back(rh1);
70 
71  // Here we solve the problem of phi circular set by duplicating some rechits
72  // too close to -Pi (or to Pi) and adding (substracting) to them 2 * Pi.
73  if (rh1.dim2 > (M_PI - getPhiOffset())) {
74  double phi = rh1.dim2 - 2 * M_PI;
75  KDTreeNodeInfo rh2(*it, posrep.Eta(), phi);
76  eltList.push_back(rh2);
77  }
78 
79  if (rh1.dim2 < (M_PI * -1.0 + getPhiOffset())) {
80  double phi = rh1.dim2 + 2 * M_PI;
81  KDTreeNodeInfo rh3(*it, posrep.Eta(), phi);
82  eltList.push_back(rh3);
83  }
84  }
85 
86  // Here we define the upper/lower bounds of the 2D space (eta/phi).
87  double phimin = -1.0 * M_PI - getPhiOffset();
88  double phimax = M_PI + getPhiOffset();
89 
90  // etamin-etamax, phimin-phimax
91  KDTreeBox region(-3.0, 3.0, phimin, phimax);
92 
93  // We may now build the KDTree
94  tree_.build(eltList, region);
95 }
96 
97 void
99 {
100  // Must of the code has been taken from LinkByRecHit.cc
101 
102  // We iterate over the tracks.
103  for(BlockEltSet::iterator it = targetSet_.begin();
104  it != targetSet_.end(); it++) {
105 
106  reco::PFRecTrackRef trackref = (*it)->trackRefPF();
107 
108  const reco::PFTrajectoryPoint& atHCAL =
109  trackref->extrapolatedPoint(reco::PFTrajectoryPoint::HCALEntrance);
110  const reco::PFTrajectoryPoint& atHCALExit =
111  trackref->extrapolatedPoint(reco::PFTrajectoryPoint::HCALExit);
112 
113  // The track didn't reach hcal
114  if( ! atHCAL.isValid()) continue;
115 
116  double dHEta = atHCALExit.positionREP().Eta() - atHCAL.positionREP().Eta();
117  double dHPhi = atHCALExit.positionREP().Phi() - atHCAL.positionREP().Phi();
118  if ( dHPhi > M_PI ) dHPhi = dHPhi - 2. * M_PI;
119  else if ( dHPhi < -M_PI ) dHPhi = dHPhi + 2. * M_PI;
120 
121  double tracketa = atHCAL.positionREP().Eta() + 0.1 * dHEta;
122  double trackphi = atHCAL.positionREP().Phi() + 0.1 * dHPhi;
123 
124  if (trackphi > M_PI) trackphi -= 2 * M_PI;
125  else if (trackphi < -M_PI) trackphi += 2 * M_PI;
126 
127  // Estimate the maximal envelope in phi/eta that will be used to find rechit candidates.
128  // Same envelope for cap et barrel rechits.
129  double inflation = 1.;
130  double rangeEta = (getCristalPhiEtaMaxSize() * (1.5 + 0.5) + 0.2 * fabs(dHEta)) * inflation;
131  double rangePhi = (getCristalPhiEtaMaxSize() * (1.5 + 0.5) + 0.2 * fabs(dHPhi)) * inflation;
132 
133  // We search for all candidate recHits, ie all recHits contained in the maximal size envelope.
134  std::vector<KDTreeNodeInfo> recHits;
135  KDTreeBox trackBox(tracketa - rangeEta, tracketa + rangeEta,
136  trackphi - rangePhi, trackphi + rangePhi);
137  tree_.search(trackBox, recHits);
138 
139  // Here we check all rechit candidates using the non-approximated method.
140  for(std::vector<KDTreeNodeInfo>::const_iterator rhit = recHits.begin();
141  rhit != recHits.end(); ++rhit) {
142 
143  const reco::PFRecHit::REPPoint &rhrep = rhit->ptr->positionREP();
144  const std::vector<reco::PFRecHit::REPPoint>& corners = rhit->ptr->getCornersREP();
145  if(corners.size() != 4) continue;
146 
147  double rhsizeEta = fabs(corners[0].Eta() - corners[2].Eta());
148  double rhsizePhi = fabs(corners[0].Phi() - corners[2].Phi());
149  if ( rhsizePhi > M_PI ) rhsizePhi = 2.*M_PI - rhsizePhi;
150 
151  double deta = fabs(rhrep.Eta() - tracketa);
152  double dphi = fabs(rhrep.Phi() - trackphi);
153  if ( dphi > M_PI ) dphi = 2.*M_PI - dphi;
154 
155  // Find all clusters associated to given rechit
156  RecHit2BlockEltMap::iterator ret = rechit2ClusterLinks_.find(rhit->ptr);
157 
158  for(BlockEltSet::iterator clusterIt = ret->second.begin();
159  clusterIt != ret->second.end(); clusterIt++) {
160 
161  const reco::PFClusterRef clusterref = (*clusterIt)->clusterRef();
162  int fracsNbr = clusterref->recHitFractions().size();
163 
164  double _rhsizeEta = rhsizeEta * (1.5 + 0.5 / fracsNbr) + 0.2 * fabs(dHEta);
165  double _rhsizePhi = rhsizePhi * (1.5 + 0.5 / fracsNbr) + 0.2 * fabs(dHPhi);
166 
167  // Check if the track and the cluster are linked
168  if(deta < (_rhsizeEta / 2.) && dphi < (_rhsizePhi / 2.))
169  cluster2TargetLinks_[*clusterIt].insert(*it);
170  }
171  }
172  }
173 }
174 
175 void
177 {
178  //TODO YG : Check if cluster positionREP() is valid ?
179 
180  // Here we save in each HCAL cluster the list of phi/eta values of linked clusters.
181  for (BlockElt2BlockEltMap::iterator it = cluster2TargetLinks_.begin();
182  it != cluster2TargetLinks_.end(); ++it) {
183  reco::PFMultiLinksTC multitracks(true);
184 
185  for (BlockEltSet::iterator jt = it->second.begin();
186  jt != it->second.end(); ++jt) {
187 
188  reco::PFRecTrackRef trackref = (*jt)->trackRefPF();
189  const reco::PFTrajectoryPoint& atHCAL =
190  trackref->extrapolatedPoint(reco::PFTrajectoryPoint::HCALEntrance);
191  double tracketa = atHCAL.positionREP().Eta();
192  double trackphi = atHCAL.positionREP().Phi();
193 
194  multitracks.linkedClusters.push_back(std::make_pair(trackphi, tracketa));
195  }
196 
197  it->first->setMultilinks(multitracks);
198  }
199 
200  // We set the multilinks flag of the track to true. It will allow us to
201  // use in an optimized way our algo results in the recursive linking algo.
202  for (BlockEltSet::iterator it = fieldClusterSet_.begin();
203  it != fieldClusterSet_.end(); ++it)
204  (*it)->setIsValidMultilinks(true);
205 
206 }
207 
208 void
210 {
211  targetSet_.clear();
212  fieldClusterSet_.clear();
213 
214  rechitsSet_.clear();
215 
216  rechit2ClusterLinks_.clear();
217  cluster2TargetLinks_.clear();
218 
219  tree_.clear();
220 }
const REPPoint & positionREP() const
trajectory position in (rho, eta, phi) base
void insertFieldClusterElt(reco::PFBlockElement *hcalCluster)
Abstract base class for a PFBlock element (track, cluster...)
ROOT::Math::PositionVector3D< ROOT::Math::CylindricalEta3D< Double32_t > > REPPoint
Definition: PFRecHit.h:39
bool isNull() const
Checks for null.
Definition: Ref.h:247
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
Definition: PFRecHit.h:31
RecHit2BlockEltMap rechit2ClusterLinks_
void setPhiOffset(double phiOffset)
PFMultilinksType linkedClusters
virtual PFClusterRef clusterRef() const
BlockElt2BlockEltMap cluster2TargetLinks_
const Fraction< n, m >::type & fract()
Definition: Fraction.h:38
void build(std::vector< KDTreeNodeInfo > &eltList, const KDTreeBox &region)
void insertTargetElt(reco::PFBlockElement *track)
#define M_PI
Definition: BFit3D.cc:3
void setCristalPhiEtaMaxSize(float size)
void search(const KDTreeBox &searchBox, std::vector< KDTreeNodeInfo > &resRecHitList)
bool isValid() const
is this point valid ?
float getCristalPhiEtaMaxSize() const
A PFTrack holds several trajectory points, which basically contain the position and momentum of a tra...
float getPhiOffset() const
Definition: DDAxes.h:10