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