Go to the documentation of this file.00001 #include "RecoParticleFlow/PFProducer/interface/KDTreeLinkerTrackEcal.h"
00002
00003 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00004 #include "TMath.h"
00005
00006 KDTreeLinkerTrackEcal::KDTreeLinkerTrackEcal()
00007 : KDTreeLinkerBase()
00008 {}
00009
00010 KDTreeLinkerTrackEcal::~KDTreeLinkerTrackEcal()
00011 {
00012 clear();
00013 }
00014
00015 void
00016 KDTreeLinkerTrackEcal::insertTargetElt(reco::PFBlockElement *track)
00017 {
00018 targetSet_.insert(track);
00019 }
00020
00021
00022 void
00023 KDTreeLinkerTrackEcal::insertFieldClusterElt(reco::PFBlockElement *ecalCluster)
00024 {
00025 reco::PFClusterRef clusterref = ecalCluster->clusterRef();
00026
00027
00028
00029
00030
00031
00032 const std::vector<reco::PFRecHitFraction> &fraction = clusterref->recHitFractions();
00033
00034
00035 fieldClusterSet_.insert(ecalCluster);
00036 for(size_t rhit = 0; rhit < fraction.size(); ++rhit) {
00037 const reco::PFRecHitRef& rh = fraction[rhit].recHitRef();
00038 double fract = fraction[rhit].fraction();
00039
00040 if ((rh.isNull()) || (fract < 1E-4))
00041 continue;
00042
00043 const reco::PFRecHit& rechit = *rh;
00044
00045
00046 rechit2ClusterLinks_[&rechit].insert(ecalCluster);
00047
00048
00049 rechitsSet_.insert(&rechit);
00050 }
00051 }
00052
00053 void
00054 KDTreeLinkerTrackEcal::buildTree()
00055 {
00056
00057 std::vector<KDTreeNodeInfo> eltList;
00058
00059
00060 for(RecHitSet::const_iterator it = rechitsSet_.begin();
00061 it != rechitsSet_.end(); it++) {
00062
00063 const reco::PFRecHit::REPPoint &posrep = (*it)->positionREP();
00064
00065 KDTreeNodeInfo rh1 (*it, posrep.Eta(), posrep.Phi());
00066 eltList.push_back(rh1);
00067
00068
00069
00070 if (rh1.dim2 > (M_PI - getPhiOffset())) {
00071 double phi = rh1.dim2 - 2 * M_PI;
00072 KDTreeNodeInfo rh2(*it, posrep.Eta(), phi);
00073 eltList.push_back(rh2);
00074 }
00075
00076 if (rh1.dim2 < (M_PI * -1.0 + getPhiOffset())) {
00077 double phi = rh1.dim2 + 2 * M_PI;
00078 KDTreeNodeInfo rh3(*it, posrep.Eta(), phi);
00079 eltList.push_back(rh3);
00080 }
00081 }
00082
00083
00084 double phimin = -1.0 * M_PI - getPhiOffset();
00085 double phimax = M_PI + getPhiOffset();
00086
00087
00088 KDTreeBox region(-3.0, 3.0, phimin, phimax);
00089
00090
00091 tree_.build(eltList, region);
00092 }
00093
00094 void
00095 KDTreeLinkerTrackEcal::searchLinks()
00096 {
00097
00098
00099
00100 for(BlockEltSet::iterator it = targetSet_.begin();
00101 it != targetSet_.end(); it++) {
00102
00103 reco::PFRecTrackRef trackref = (*it)->trackRefPF();
00104
00105
00106
00107 (*it)->setIsValidMultilinks(true);
00108
00109 const reco::PFTrajectoryPoint& atECAL =
00110 trackref->extrapolatedPoint(reco::PFTrajectoryPoint::ECALShowerMax);
00111
00112
00113 if( ! atECAL.isValid() ) continue;
00114
00115 const reco::PFTrajectoryPoint& atVertex =
00116 trackref->extrapolatedPoint( reco::PFTrajectoryPoint::ClosestApproach );
00117
00118 double trackPt = sqrt(atVertex.momentum().Vect().Perp2());
00119 double tracketa = atECAL.positionREP().Eta();
00120 double trackphi = atECAL.positionREP().Phi();
00121 double trackx = atECAL.position().X();
00122 double tracky = atECAL.position().Y();
00123 double trackz = atECAL.position().Z();
00124
00125
00126
00127 double range = getCristalPhiEtaMaxSize() * (2.0 + 1.0 / std::min(1., trackPt / 2.));
00128
00129
00130 std::vector<KDTreeNodeInfo> recHits;
00131 KDTreeBox trackBox(tracketa-range, tracketa+range, trackphi-range, trackphi+range);
00132 tree_.search(trackBox, recHits);
00133
00134
00135 for(std::vector<KDTreeNodeInfo>::const_iterator rhit = recHits.begin();
00136 rhit != recHits.end(); ++rhit) {
00137
00138 const std::vector< math::XYZPoint >& cornersxyz = rhit->ptr->getCornersXYZ();
00139 const math::XYZPoint& posxyz = rhit->ptr->position();
00140 const reco::PFRecHit::REPPoint &rhrep = rhit->ptr->positionREP();
00141 const std::vector<reco::PFRecHit::REPPoint>& corners = rhit->ptr->getCornersREP();
00142 if(corners.size() != 4) continue;
00143
00144 double rhsizeEta = fabs(corners[0].Eta() - corners[2].Eta());
00145 double rhsizePhi = fabs(corners[0].Phi() - corners[2].Phi());
00146 if ( rhsizePhi > M_PI ) rhsizePhi = 2.*M_PI - rhsizePhi;
00147
00148 double deta = fabs(rhrep.Eta() - tracketa);
00149 double dphi = fabs(rhrep.Phi() - trackphi);
00150 if ( dphi > M_PI ) dphi = 2.*M_PI - dphi;
00151
00152
00153 RecHit2BlockEltMap::iterator ret = rechit2ClusterLinks_.find(rhit->ptr);
00154
00155 for(BlockEltSet::const_iterator clusterIt = ret->second.begin();
00156 clusterIt != ret->second.end(); clusterIt++) {
00157
00158 reco::PFClusterRef clusterref = (*clusterIt)->clusterRef();
00159 double clusterz = clusterref->position().Z();
00160 int fracsNbr = clusterref->recHitFractions().size();
00161
00162 if (clusterref->layer() == PFLayer::ECAL_BARREL){
00163
00164 if (fabs(trackz) > 300.) continue;
00165
00166 double _rhsizeEta = rhsizeEta * (2.00 + 1.0 / (fracsNbr * std::min(1.,trackPt/2.)));
00167 double _rhsizePhi = rhsizePhi * (2.00 + 1.0 / (fracsNbr * std::min(1.,trackPt/2.)));
00168
00169
00170 if(deta < (_rhsizeEta / 2.) && dphi < (_rhsizePhi / 2.))
00171 target2ClusterLinks_[*it].insert(*clusterIt);
00172
00173
00174 } else {
00175
00176
00177 if (fabs(trackz) < 300.) continue;
00178 if (trackz * clusterz < 0.) continue;
00179
00180 double x[5];
00181 double y[5];
00182 for ( unsigned jc=0; jc<4; ++jc ) {
00183 math::XYZPoint cornerposxyz = cornersxyz[jc];
00184 x[jc] = cornerposxyz.X() + (cornerposxyz.X()-posxyz.X())
00185 * (1.00+0.50/fracsNbr /std::min(1.,trackPt/2.));
00186 y[jc] = cornerposxyz.Y() + (cornerposxyz.Y()-posxyz.Y())
00187 * (1.00+0.50/fracsNbr /std::min(1.,trackPt/2.));
00188 }
00189
00190 x[4] = x[0];
00191 y[4] = y[0];
00192
00193 bool isinside = TMath::IsInside(trackx,
00194 tracky,
00195 5,x,y);
00196
00197
00198 if( isinside )
00199 target2ClusterLinks_[*it].insert(*clusterIt);
00200 }
00201 }
00202 }
00203 }
00204 }
00205
00206 void
00207 KDTreeLinkerTrackEcal::updatePFBlockEltWithLinks()
00208 {
00209
00210
00211
00212 for (BlockElt2BlockEltMap::iterator it = target2ClusterLinks_.begin();
00213 it != target2ClusterLinks_.end(); ++it) {
00214 reco::PFMultiLinksTC multitracks(true);
00215
00216 for (BlockEltSet::iterator jt = it->second.begin();
00217 jt != it->second.end(); ++jt) {
00218
00219 double clusterPhi = (*jt)->clusterRef()->positionREP().Phi();
00220 double clusterEta = (*jt)->clusterRef()->positionREP().Eta();
00221
00222 multitracks.linkedClusters.push_back(std::make_pair(clusterPhi, clusterEta));
00223 }
00224
00225 it->first->setMultilinks(multitracks);
00226 }
00227 }
00228
00229 void
00230 KDTreeLinkerTrackEcal::clear()
00231 {
00232 targetSet_.clear();
00233 fieldClusterSet_.clear();
00234
00235 rechitsSet_.clear();
00236
00237 rechit2ClusterLinks_.clear();
00238 target2ClusterLinks_.clear();
00239
00240 tree_.clear();
00241 }