CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
KDTreeLinkerPSEcal.cc
Go to the documentation of this file.
1 #include "KDTreeLinkerPSEcal.h"
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  "KDTreePreshowerAndECALLinker");
11 
13  : KDTreeLinkerBase(),
14  resPSpitch_ (0.19),
15  resPSlength_ (6.1),
16  ps1ToEcal_ (1.072),
17  ps2ToEcal_ (1.057)
18 {}
19 
21 {
22  clear();
23 }
24 
25 
26 void
28 {
29  reco::PFClusterRef clusterref = psCluster->clusterRef();
30 
31  // This test is more or less done in PFBlockAlgo.h. In others cases, it should be switch on.
32  // if (!((clusterref->layer() == PFLayer::PS1) ||
33  // (clusterref->layer() == PFLayer::PS2)))
34  // return;
35 
36  targetSet_.insert(psCluster);
37 }
38 
39 
40 void
42 {
43  reco::PFClusterRef clusterref = ecalCluster->clusterRef();
44 
45  if (clusterref->layer() != PFLayer::ECAL_ENDCAP)
46  return;
47 
48  const std::vector<reco::PFRecHitFraction> &fraction = clusterref->recHitFractions();
49 
50  // We create a list of cluster
51  fieldClusterSet_.insert(ecalCluster);
52 
53  double clusterz = clusterref->position().Z();
54  RecHitSet& rechitsSet = (clusterz < 0) ? rechitsNegSet_ : rechitsPosSet_;
55 
56  for(size_t rhit = 0; rhit < fraction.size(); ++rhit) {
57  const reco::PFRecHitRef& rh = fraction[rhit].recHitRef();
58  double fract = fraction[rhit].fraction();
59 
60  if ((rh.isNull()) || (fract < 1E-4))
61  continue;
62 
63  const reco::PFRecHit& rechit = *rh;
64 
65  // We save the links rechit to Clusters
66  rechit2ClusterLinks_[&rechit].insert(ecalCluster);
67 
68  // We create a liste of rechits
69  rechitsSet.insert(&rechit);
70  }
71 }
72 
73 void
75 {
78 }
79 
80 void
83 {
84  // List of pseudo-rechits that will be used to create the KDTree
85  std::vector<KDTreeNodeInfo> eltList;
86 
87  // Filling of this eltList
88  for(RecHitSet::const_iterator it = rechitsSet.begin();
89  it != rechitsSet.end(); it++) {
90 
91  const reco::PFRecHit* rh = *it;
92  const math::XYZPoint& posxyz = rh->position();
93 
94  KDTreeNodeInfo rhinfo (rh, posxyz.X(), posxyz.Y());
95  eltList.push_back(rhinfo);
96  }
97 
98  // xmin-xmax, ymain-ymax
99  KDTreeBox region(-150., 150., -150., 150.);
100 
101  // We may now build the KDTree
102  tree.build(eltList, region);
103 }
104 
105 void
107 {
108  // Must of the code has been taken from LinkByRecHit.cc
109 
110  // We iterate over the PS clusters.
111  for(BlockEltSet::iterator it = targetSet_.begin();
112  it != targetSet_.end(); it++) {
113 
114  (*it)->setIsValidMultilinks(true);
115 
116  reco::PFClusterRef clusterPSRef = (*it)->clusterRef();
117  const reco::PFCluster& clusterPS = *clusterPSRef;
118 
119  // PS cluster position, extrapolated to ECAL
120  double zPS = clusterPS.position().Z();
121  double xPS = clusterPS.position().X();
122  double yPS = clusterPS.position().Y();
123 
124  double etaPS = fabs(clusterPS.positionREP().eta());
125  double deltaX = 0.;
126  double deltaY = 0.;
127  double xPSonEcal = xPS;
128  double yPSonEcal = yPS;
129 
130  if (clusterPS.layer() == PFLayer::PS1) { // PS1
131 
132  // vertical strips, measure x with pitch precision
133  deltaX = resPSpitch_;
134  deltaY = resPSlength_;
135  xPSonEcal *= ps1ToEcal_;
136  yPSonEcal *= ps1ToEcal_;
137 
138  } else { // PS2
139 
140  // horizontal strips, measure y with pitch precision
141  deltaY = resPSpitch_;
142  deltaX = resPSlength_;
143  xPSonEcal *= ps2ToEcal_;
144  yPSonEcal *= ps2ToEcal_;
145 
146  }
147 
148 
149  // Estimate the maximal envelope in phi/eta that will be used to find rechit candidates.
150  // Same envelope for cap et barrel rechits.
151 
152 
153  double maxEcalRadius = getCristalXYMaxSize() / 2.;
154 
155  // The inflation factor includes the approximate projection from Preshower to ECAL
156  double inflation = 2.4 - (etaPS-1.6);
157  double rangeX = maxEcalRadius * (1 + (0.05 + 1.0 / maxEcalRadius * deltaX / 2.)) * inflation;
158  double rangeY = maxEcalRadius * (1 + (0.05 + 1.0 / maxEcalRadius * deltaY / 2.)) * inflation;
159 
160  // We search for all candidate recHits, ie all recHits contained in the maximal size envelope.
161  std::vector<KDTreeNodeInfo> recHits;
162  KDTreeBox trackBox(xPSonEcal - rangeX, xPSonEcal + rangeX,
163  yPSonEcal - rangeY, yPSonEcal + rangeY);
164 
165  if (zPS < 0)
166  treeNeg_.search(trackBox, recHits);
167  else
168  treePos_.search(trackBox, recHits);
169 
170 
171  for(std::vector<KDTreeNodeInfo>::const_iterator rhit = recHits.begin();
172  rhit != recHits.end(); ++rhit) {
173 
174  const std::vector< math::XYZPoint >& corners = rhit->ptr->getCornersXYZ();
175  if(corners.size() != 4) continue;
176 
177  // Find all clusters associated to given rechit
178  RecHit2BlockEltMap::iterator ret = rechit2ClusterLinks_.find(rhit->ptr);
179 
180  for(BlockEltSet::const_iterator clusterIt = ret->second.begin();
181  clusterIt != ret->second.end(); clusterIt++) {
182 
183  reco::PFClusterRef clusterref = (*clusterIt)->clusterRef();
184  double clusterz = clusterref->position().Z();
185 
186  const math::XYZPoint& posxyz = rhit->ptr->position() * zPS / clusterz;
187 
188  double x[5];
189  double y[5];
190  for ( unsigned jc=0; jc<4; ++jc ) {
191  math::XYZPoint cornerpos = corners[jc] * zPS / clusterz;
192  x[jc] = cornerpos.X() + (cornerpos.X()-posxyz.X()) * (0.05 +1.0/fabs((cornerpos.X()-posxyz.X()))*deltaX/2.);
193  y[jc] = cornerpos.Y() + (cornerpos.Y()-posxyz.Y()) * (0.05 +1.0/fabs((cornerpos.Y()-posxyz.Y()))*deltaY/2.);
194  }
195 
196  x[4] = x[0];
197  y[4] = y[0];
198 
199  bool isinside = TMath::IsInside(xPS,
200  yPS,
201  5,x,y);
202 
203  // Check if the track and the cluster are linked
204  if( isinside )
205  target2ClusterLinks_[*it].insert(*clusterIt);
206  }
207  }
208 
209  }
210 }
211 
212 void
214 {
215  //TODO YG : Check if cluster positionREP() is valid ?
216 
217  // Here we save in each track the list of phi/eta values of linked clusters.
218  for (BlockElt2BlockEltMap::iterator it = target2ClusterLinks_.begin();
219  it != target2ClusterLinks_.end(); ++it) {
220  reco::PFMultiLinksTC multitracks(true);
221 
222  for (BlockEltSet::iterator jt = it->second.begin();
223  jt != it->second.end(); ++jt) {
224 
225  double clusterPhi = (*jt)->clusterRef()->positionREP().Phi();
226  double clusterEta = (*jt)->clusterRef()->positionREP().Eta();
227 
228  multitracks.linkedClusters.push_back(std::make_pair(clusterPhi, clusterEta));
229  }
230 
231  it->first->setMultilinks(multitracks);
232  }
233 }
234 
235 void
237 {
238  targetSet_.clear();
239  fieldClusterSet_.clear();
240 
241  rechitsNegSet_.clear();
242  rechitsPosSet_.clear();
243 
244  rechit2ClusterLinks_.clear();
245  target2ClusterLinks_.clear();
246 
247  treeNeg_.clear();
248  treePos_.clear();
249 }
PFLayer::Layer layer() const
cluster layer, see PFLayer.h in this directory
Definition: PFCluster.cc:85
const double resPSlength_
Abstract base class for a PFBlock element (track, cluster...)
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:124
void build(std::vector< KDTreeNodeInfo > &eltList, const KDTreeBox &region)
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:47
virtual const PFClusterRef & clusterRef() const
BlockElt2BlockEltMap target2ClusterLinks_
void insertFieldClusterElt(reco::PFBlockElement *ecalCluster)
const double resPSpitch_
void search(const KDTreeBox &searchBox, std::vector< KDTreeNodeInfo > &resRecHitList)
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:35
const REPPoint & positionREP() const
cluster position: rho, eta, phi
Definition: PFCluster.h:87
PFMultilinksType linkedClusters
float getCristalXYMaxSize() const
const Fraction< n, m >::type & fract()
Definition: Fraction.h:38
const math::XYZPoint & position() const
rechit cell centre x, y, z
Definition: PFRecHit.h:123
std::set< const reco::PFRecHit * > RecHitSet
KDTreeLinkerAlgo treePos_
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
BlockEltSet fieldClusterSet_
void insertTargetElt(reco::PFBlockElement *psCluster)
#define DEFINE_EDM_PLUGIN(factory, type, name)
Definition: DDAxes.h:10
KDTreeLinkerAlgo treeNeg_
RecHit2BlockEltMap rechit2ClusterLinks_