CMS 3D CMS Logo

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