Go to the documentation of this file.00001 #include "RecoParticleFlow/PFClusterTools/interface/LinkByRecHit.h"
00002 #include "DataFormats/Math/interface/normalizedPhi.h"
00003 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00004 #include "TMath.h"
00005
00006
00007
00008
00009 double
00010 LinkByRecHit::testTrackAndClusterByRecHit ( const reco::PFRecTrack& track,
00011 const reco::PFCluster& cluster,
00012 bool isBrem,
00013 bool debug) {
00014
00015 #ifdef PFLOW_DEBUG
00016 if( debug )
00017 std::cout<<"entering test link by rechit function"<<std::endl;
00018 #endif
00019
00020
00021 double clustereta = cluster.positionREP().Eta();
00022 double clusterphi = cluster.positionREP().Phi();
00023 double clusterX = cluster.position().X();
00024 double clusterY = cluster.position().Y();
00025 double clusterZ = cluster.position().Z();
00026
00027 bool barrel = false;
00028 bool hcal = false;
00029 double distance = 999999.9;
00030
00031
00032 const reco::PFTrajectoryPoint& atVertex
00033 = track.extrapolatedPoint( reco::PFTrajectoryPoint::ClosestApproach );
00034 const reco::PFTrajectoryPoint& atECAL
00035 = track.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax );
00036
00037
00038 double tracketa = 999999.9;
00039 double trackphi = 999999.9;
00040 double track_X = 999999.9;
00041 double track_Y = 999999.9;
00042 double track_Z = 999999.9;
00043 double dHEta = 0.;
00044 double dHPhi = 0.;
00045
00046
00047 double trackPt = isBrem ? 999. : sqrt(atVertex.momentum().Vect().Perp2());
00048
00049
00050
00051 switch (cluster.layer()) {
00052 case PFLayer::ECAL_BARREL: barrel = true;
00053 case PFLayer::ECAL_ENDCAP:
00054 #ifdef PFLOW_DEBUG
00055 if( debug )
00056 std::cout << "Fetching Ecal Resolution Maps"
00057 << std::endl;
00058 #endif
00059
00060 if( ! atECAL.isValid() ) return -1.;
00061
00062 tracketa = atECAL.positionREP().Eta();
00063 trackphi = atECAL.positionREP().Phi();
00064 track_X = atECAL.position().X();
00065 track_Y = atECAL.position().Y();
00066 track_Z = atECAL.position().Z();
00067
00068 distance
00069 = std::sqrt( (track_X-clusterX)*(track_X-clusterX)
00070 +(track_Y-clusterY)*(track_Y-clusterY)
00071 +(track_Z-clusterZ)*(track_Z-clusterZ)
00072 );
00073
00074 break;
00075
00076 case PFLayer::HCAL_BARREL1: barrel = true;
00077 case PFLayer::HCAL_ENDCAP:
00078 #ifdef PFLOW_DEBUG
00079 if( debug )
00080 std::cout << "Fetching Hcal Resolution Maps"
00081 << std::endl;
00082 #endif
00083 if( isBrem ) {
00084 return -1.;
00085 } else {
00086 hcal=true;
00087 const reco::PFTrajectoryPoint& atHCAL
00088 = track.extrapolatedPoint( reco::PFTrajectoryPoint::HCALEntrance );
00089 const reco::PFTrajectoryPoint& atHCALExit
00090 = track.extrapolatedPoint( reco::PFTrajectoryPoint::HCALExit );
00091
00092 if( ! atHCAL.isValid() ) return -1.;
00093
00094
00095 dHEta = atHCALExit.positionREP().Eta()-atHCAL.positionREP().Eta();
00096 dHPhi = atHCALExit.positionREP().Phi()-atHCAL.positionREP().Phi();
00097 if ( dHPhi > M_PI ) dHPhi = dHPhi - 2.*M_PI;
00098 else if ( dHPhi < -M_PI ) dHPhi = dHPhi + 2.*M_PI;
00099 tracketa = atHCAL.positionREP().Eta() + 0.1*dHEta;
00100 trackphi = atHCAL.positionREP().Phi() + 0.1*dHPhi;
00101 track_X = atHCAL.position().X();
00102 track_Y = atHCAL.position().Y();
00103 track_Z = atHCAL.position().Z();
00104 distance
00105 = -std::sqrt( (track_X-clusterX)*(track_X-clusterX)
00106 +(track_Y-clusterY)*(track_Y-clusterY)
00107 +(track_Z-clusterZ)*(track_Z-clusterZ)
00108 );
00109
00110 }
00111 break;
00112 case PFLayer::PS1:
00113 case PFLayer::PS2:
00114
00115
00116 #ifdef PFLOW_DEBUG
00117 if( debug )
00118 std::cout << "No link by rechit possible for pre-shower yet!"
00119 << std::endl;
00120 #endif
00121 return -1.;
00122 default:
00123 return -1.;
00124 }
00125
00126
00127
00128
00129
00130
00131
00132 if ( !barrel ) {
00133
00134 if ( !hcal && fabs(track_Z) < 300. ) return -1.;
00135 if ( track_Z * clusterZ < 0. ) return -1.;
00136 }
00137
00138
00139 if ( barrel )
00140 if ( !hcal && fabs(track_Z) > 300. ) return -1.;
00141
00142
00143
00144
00145
00146 double dist = LinkByRecHit::computeDist( clustereta, clusterphi,
00147 tracketa, trackphi);
00148
00149 #ifdef PFLOW_DEBUG
00150 if(debug) std::cout<<"test link by rechit "<< dist <<" "<<std::endl;
00151 if(debug){
00152 std::cout<<" clustereta " << clustereta
00153 <<" clusterphi " << clusterphi
00154 <<" tracketa " << tracketa
00155 <<" trackphi " << trackphi << std::endl;
00156 }
00157 #endif
00158
00159
00160
00161
00162
00163
00164 const std::vector< reco::PFRecHitFraction >&
00165 fracs = cluster.recHitFractions();
00166
00167 bool linkedbyrechit = false;
00168
00169 for(unsigned int rhit = 0; rhit < fracs.size(); ++rhit){
00170
00171 const reco::PFRecHitRef& rh = fracs[rhit].recHitRef();
00172 double fraction = fracs[rhit].fraction();
00173 if(fraction < 1E-4) continue;
00174 if(rh.isNull()) continue;
00175
00176
00177 const reco::PFRecHit& rechit_cluster = *rh;
00178 const math::XYZPoint& posxyz
00179 = rechit_cluster.position();
00180 const reco::PFRecHit::REPPoint& posrep
00181 = rechit_cluster.positionREP();
00182
00183
00184 const std::vector< math::XYZPoint >&
00185 cornersxyz = rechit_cluster.getCornersXYZ();
00186 const std::vector<reco::PFRecHit::REPPoint>& corners =
00187 rechit_cluster.getCornersREP();
00188 assert(corners.size() == 4);
00189
00190 if( barrel || hcal ){
00191
00192
00193
00194
00195
00196 double rhsizeEta
00197 = fabs(corners[0].Eta() - corners[2].Eta());
00198 double rhsizePhi
00199 = fabs(corners[0].Phi() - corners[2].Phi());
00200 if ( rhsizePhi > M_PI ) rhsizePhi = 2.*M_PI - rhsizePhi;
00201 if ( hcal ) {
00202 rhsizeEta = rhsizeEta * (1.50 + 0.5/fracs.size()) + 0.2*fabs(dHEta);
00203 rhsizePhi = rhsizePhi * (1.50 + 0.5/fracs.size()) + 0.2*fabs(dHPhi);
00204
00205 } else {
00206 rhsizeEta *= 2.00 + 1.0/fracs.size()/std::min(1.,trackPt/2.);
00207 rhsizePhi *= 2.00 + 1.0/fracs.size()/std::min(1.,trackPt/2.);
00208 }
00209
00210 #ifdef PFLOW_DEBUG
00211 if( debug ) {
00212 std::cout << rhit << " Hcal RecHit="
00213 << posrep.Eta() << " "
00214 << posrep.Phi() << " "
00215 << rechit_cluster.energy()
00216 << std::endl;
00217 for ( unsigned jc=0; jc<4; ++jc )
00218 std::cout<<"corners "<<jc<<" "<<corners[jc].Eta()
00219 <<" "<<corners[jc].Phi()<<std::endl;
00220
00221 std::cout << "RecHit SizeEta=" << rhsizeEta
00222 << " SizePhi=" << rhsizePhi << std::endl;
00223 }
00224 #endif
00225
00226
00227
00228
00229 double deta = fabs(posrep.Eta() - tracketa);
00230 double dphi = fabs(posrep.Phi() - trackphi);
00231 if ( dphi > M_PI ) dphi = 2.*M_PI - dphi;
00232
00233 #ifdef PFLOW_DEBUG
00234 if( debug ){
00235 std::cout << "distance="
00236 << deta << " "
00237 << dphi << " ";
00238 if(deta < (rhsizeEta/2.) && dphi < (rhsizePhi/2.))
00239 std::cout << " link here !" << std::endl;
00240 else std::cout << std::endl;
00241 }
00242 #endif
00243
00244 if(deta < (rhsizeEta/2.) && dphi < (rhsizePhi/2.)){
00245 linkedbyrechit = true;
00246 break;
00247 }
00248 }
00249 else {
00250
00251 #ifdef PFLOW_DEBUG
00252 if( debug ){
00253 const math::XYZPoint& posxyz
00254 = rechit_cluster.position();
00255
00256 std::cout << "RH " << posxyz.X()
00257 << " " << posxyz.Y()
00258 << std::endl;
00259
00260 std::cout << "TRACK " << track_X
00261 << " " << track_Y
00262 << std::endl;
00263 }
00264 #endif
00265
00266 double x[5];
00267 double y[5];
00268
00269 for ( unsigned jc=0; jc<4; ++jc ) {
00270 math::XYZPoint cornerposxyz = cornersxyz[jc];
00271 x[jc] = cornerposxyz.X() + (cornerposxyz.X()-posxyz.X())
00272 * (1.00+0.50/fracs.size()/std::min(1.,trackPt/2.));
00273 y[jc] = cornerposxyz.Y() + (cornerposxyz.Y()-posxyz.Y())
00274 * (1.00+0.50/fracs.size()/std::min(1.,trackPt/2.));
00275
00276 #ifdef PFLOW_DEBUG
00277 if( debug ){
00278 std::cout<<"corners "<<jc
00279 << " " << cornerposxyz.X()
00280 << " " << cornerposxyz.Y()
00281 << std::endl;
00282 }
00283 #endif
00284 }
00285
00286
00287
00288 x[4] = x[0];
00289 y[4] = y[0];
00290
00291
00292
00293 bool isinside = TMath::IsInside(track_X,
00294 track_Y,
00295 5,x,y);
00296
00297 if( isinside ){
00298 linkedbyrechit = true;
00299 break;
00300 }
00301 }
00302
00303 }
00304
00305 if( linkedbyrechit ) {
00306 #ifdef PFLOW_DEBUG
00307 if( debug )
00308 std::cout << "Track and Cluster LINKED BY RECHIT" << std::endl;
00309 #endif
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 return dist;
00329 } else {
00330 return -1.;
00331 }
00332
00333 }
00334
00335
00336
00337 double
00338 LinkByRecHit::testECALAndPSByRecHit( const reco::PFCluster& clusterECAL,
00339 const reco::PFCluster& clusterPS,
00340 bool debug) {
00341
00342
00343
00344 static double resPSpitch = 0.19/sqrt(12.);
00345 static double resPSlength = 6.1/sqrt(12.);
00346
00347
00348 if ( clusterECAL.layer() != PFLayer::ECAL_ENDCAP ||
00349 ( clusterPS.layer() != PFLayer::PS1 &&
00350 clusterPS.layer() != PFLayer::PS2 ) ) return -1.;
00351
00352 #ifdef PFLOW_DEBUG
00353 if( debug )
00354 std::cout<<"entering test link by rechit function for ECAL and PS"<<std::endl;
00355 #endif
00356
00357
00358 double zECAL = clusterECAL.position().Z();
00359 double xECAL = clusterECAL.position().X();
00360 double yECAL = clusterECAL.position().Y();
00361
00362
00363 double zPS = clusterPS.position().Z();
00364 double xPS = clusterPS.position().X();
00365 double yPS = clusterPS.position().Y();
00366
00367 if (zECAL*zPS <0.) return -1.;
00368 double deltaX = 0.;
00369 double deltaY = 0.;
00370 double sqr12 = std::sqrt(12.);
00371 switch (clusterPS.layer()) {
00372 case PFLayer::PS1:
00373
00374 deltaX = resPSpitch * sqr12;
00375 deltaY = resPSlength * sqr12;
00376 break;
00377 case PFLayer::PS2:
00378
00379 deltaY = resPSpitch * sqr12;
00380 deltaX = resPSlength * sqr12;
00381 break;
00382 default:
00383 break;
00384 }
00385
00386
00387 const std::vector< reco::PFRecHitFraction >& fracs = clusterECAL.recHitFractions();
00388 bool linkedbyrechit = false;
00389
00390 for(unsigned int rhit = 0; rhit < fracs.size(); ++rhit){
00391
00392 const reco::PFRecHitRef& rh = fracs[rhit].recHitRef();
00393 double fraction = fracs[rhit].fraction();
00394 if(fraction < 1E-4) continue;
00395 if(rh.isNull()) continue;
00396
00397
00398 const reco::PFRecHit& rechit_cluster = *rh;
00399
00400
00401 const std::vector< math::XYZPoint >& corners = rechit_cluster.getCornersXYZ();
00402 assert(corners.size() == 4);
00403
00404 const math::XYZPoint& posxyz = rechit_cluster.position() * zPS/zECAL;
00405 #ifdef PFLOW_DEBUG
00406 if( debug ){
00407 std::cout << "Ecal rechit " << posxyz.X() << " " << posxyz.Y() << std::endl;
00408 std::cout << "PS cluster " << xPS << " " << yPS << std::endl;
00409 }
00410 #endif
00411
00412 double x[5];
00413 double y[5];
00414 for ( unsigned jc=0; jc<4; ++jc ) {
00415
00416 math::XYZPoint cornerpos = corners[jc] * zPS/zECAL;
00417
00418 x[jc] = cornerpos.X() + (cornerpos.X()-posxyz.X()) * (0.05 +1.0/fabs((cornerpos.X()-posxyz.X()))*deltaX/2.);
00419 y[jc] = cornerpos.Y() + (cornerpos.Y()-posxyz.Y()) * (0.05 +1.0/fabs((cornerpos.Y()-posxyz.Y()))*deltaY/2.);
00420
00421 #ifdef PFLOW_DEBUG
00422 if( debug ){
00423 std::cout<<"corners "<<jc
00424 << " " << cornerpos.X() << " " << x[jc]
00425 << " " << cornerpos.Y() << " " << y[jc]
00426 << std::endl;
00427 }
00428 #endif
00429 }
00430
00431
00432
00433 x[4] = x[0];
00434 y[4] = y[0];
00435
00436
00437
00438 bool isinside = TMath::IsInside(xPS,yPS,5,x,y);
00439
00440 if( isinside ){
00441 linkedbyrechit = true;
00442 break;
00443 }
00444
00445 }
00446
00447 if( linkedbyrechit ) {
00448 if( debug ) std::cout << "Cluster PS and Cluster ECAL LINKED BY RECHIT" << std::endl;
00449 double dist = computeDist( xECAL/1000.,yECAL/1000.,
00450 xPS/1000. ,yPS/1000,
00451 false);
00452 return dist;
00453 } else {
00454 return -1.;
00455 }
00456
00457 }
00458
00459
00460
00461 double
00462 LinkByRecHit::testHFEMAndHFHADByRecHit(const reco::PFCluster& clusterHFEM,
00463 const reco::PFCluster& clusterHFHAD,
00464 bool debug) {
00465
00466 math::XYZPoint posxyzEM = clusterHFEM.position();
00467 math::XYZPoint posxyzHAD = clusterHFHAD.position();
00468
00469 double dX = posxyzEM.X()-posxyzHAD.X();
00470 double dY = posxyzEM.Y()-posxyzHAD.Y();
00471 double sameZ = posxyzEM.Z()*posxyzHAD.Z();
00472
00473 if(sameZ<0) return -1.;
00474
00475 double dist2 = dX*dX + dY*dY;
00476
00477 if( dist2 < 0.1 ) {
00478
00479 double dist = sqrt( dist2 );
00480 return dist;;
00481 }
00482 else
00483 return -1.;
00484
00485 }
00486
00487 double
00488 LinkByRecHit::computeDist( double eta1, double phi1,
00489 double eta2, double phi2,
00490 bool etaPhi ) {
00491
00492 double phicor = etaPhi ? normalizedPhi(phi1 - phi2) : phi1 - phi2;
00493
00494
00495
00496
00497
00498 double dist = std::sqrt( (eta1 - eta2)*(eta1 - eta2)
00499 + phicor*phicor);
00500
00501 return dist;
00502
00503 }