00001 #include "RecoParticleFlow/PFBlockAlgo/interface/PFBlockAlgo.h"
00002 #include "RecoParticleFlow/PFBlockAlgo/interface/Utils.h"
00003 #include "RecoParticleFlow/PFClusterTools/interface/PFResolutionMap.h"
00004 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
00005 #include "DataFormats/TrackReco/interface/Track.h"
00006
00007 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00008
00009 #include <stdexcept>
00010 #include "TMath.h"
00011
00012 using namespace std;
00013 using namespace reco;
00014
00015
00016
00017
00018 const PFBlockAlgo::Mask PFBlockAlgo::dummyMask_;
00019
00020 PFBlockAlgo::PFBlockAlgo() :
00021 blocks_( new reco::PFBlockCollection ),
00022
00023
00024
00025 resMapEtaECAL_(0),
00026 resMapPhiECAL_(0),
00027 resMapEtaHCAL_(0),
00028 resMapPhiHCAL_(0),
00029 DPtovPtCut_(999),
00030 chi2TrackECAL_(-1),
00031 chi2GSFECAL_(-1),
00032 chi2TrackHCAL_(-1),
00033 chi2ECALHCAL_ (-1),
00034 chi2PSECAL_ (-1),
00035 chi2PSTrack_ (-1),
00036 chi2PSHV_ (-1),
00037 resPSpitch_ (0),
00038 resPSlength_ (0),
00039 debug_(false) {}
00040
00041
00042
00043 void PFBlockAlgo::setParameters( const char* resMapEtaECAL,
00044 const char* resMapPhiECAL,
00045 const char* resMapEtaHCAL,
00046 const char* resMapPhiHCAL,
00047 double DPtovPtCut,
00048 double chi2TrackECAL,
00049 double chi2GSFECAL,
00050 double chi2TrackHCAL,
00051 double chi2ECALHCAL,
00052 double chi2PSECAL,
00053 double chi2PSTrack,
00054 double chi2PSHV,
00055 bool multiLink ) {
00056
00057 try {
00058 resMapEtaECAL_ = new PFResolutionMap("resmapEtaECAL",resMapEtaECAL);
00059 resMapPhiECAL_ = new PFResolutionMap("resmapPhiECAL",resMapPhiECAL);
00060 resMapEtaHCAL_ = new PFResolutionMap("resmapEtaHCAL",resMapEtaHCAL);
00061 resMapPhiHCAL_ = new PFResolutionMap("resmapPhiHCAL",resMapPhiHCAL);
00062 }
00063 catch(std::exception& err ) {
00064
00065 throw;
00066 }
00067
00068 DPtovPtCut_ = DPtovPtCut;
00069 chi2TrackECAL_ = chi2TrackECAL;
00070 chi2GSFECAL_ = chi2GSFECAL;
00071 chi2TrackHCAL_ = chi2TrackHCAL;
00072 chi2ECALHCAL_ = chi2ECALHCAL;
00073 chi2PSECAL_ = chi2PSECAL;
00074 chi2PSTrack_ = chi2PSTrack;
00075 chi2PSHV_ = chi2PSHV;
00076 double strip_pitch = 0.19;
00077 double strip_length = 6.1;
00078 resPSpitch_ = strip_pitch/sqrt(12.);
00079 resPSlength_ = strip_length/sqrt(12.);
00080
00081 multipleLink_ = multiLink;
00082 }
00083
00084 PFBlockAlgo::~PFBlockAlgo() {
00085
00086 #ifdef PFLOW_DEBUG
00087 if(debug_)
00088 cout<<"~PFBlockAlgo - number of remaining elements: "
00089 <<elements_.size()<<endl;
00090 #endif
00091
00092 if(resMapEtaECAL_) delete resMapEtaECAL_;
00093
00094 if(resMapPhiECAL_) delete resMapPhiECAL_;
00095
00096 if(resMapEtaHCAL_) delete resMapEtaHCAL_;
00097
00098 if(resMapPhiHCAL_) delete resMapPhiHCAL_;
00099
00100 }
00101
00102 void PFBlockAlgo::findBlocks() {
00103
00104
00105
00106
00107 if(blocks_.get() )blocks_->clear();
00108 else
00109 blocks_.reset( new reco::PFBlockCollection );
00110
00111 blocks_->reserve(elements_.size());
00112 for(IE ie = elements_.begin();
00113 ie != elements_.end();) {
00114
00115 #ifdef PFLOW_DEBUG
00116 if(debug_) {
00117 cout<<" PFBlockAlgo::findBlocks() ----------------------"<<endl;
00118 cout<<" element "<<**ie<<endl;
00119 cout<<" creating new block"<<endl;
00120 }
00121 #endif
00122
00123 blocks_->push_back( PFBlock() );
00124
00125 vector< PFBlockLink > links;
00126
00127
00128 ie = associate( elements_.end() , ie, links );
00129
00130
00131 packLinks( blocks_->back(), links );
00132 }
00133 }
00134
00135
00136
00137
00138 PFBlockAlgo::IE PFBlockAlgo::associate( IE last,
00139 IE next,
00140 vector<PFBlockLink>& links ) {
00141
00142
00143 #ifdef PFLOW_DEBUG
00144 if(debug_ ) cout<<"PFBlockAlgo::associate start ----"<<endl;
00145 #endif
00146
00147 if( last!= elements_.end() ) {
00148 PFBlockLink::Type linktype = PFBlockLink::NONE;
00149 double chi2 = -1;
00150 double dist = -1;
00151 PFBlock::LinkTest linktest = PFBlock::LINKTEST_CHI2;
00152 link( *last, *next, linktype, linktest, chi2, dist );
00153
00154
00155 if(chi2<-0.5) {
00156 #ifdef PFLOW_DEBUG
00157 if(debug_ ) cout<<"link failed"<<endl;
00158 #endif
00159 return ++next;
00160 }
00161 else {
00162
00163 blocks_->back().addElement( *next );
00164
00165
00166
00167
00168
00169
00170
00171 links.push_back( PFBlockLink(linktype,
00172 linktest,
00173 chi2,
00174 dist,
00175 (*last)->index(),
00176 (*next)->index() ) );
00177
00178
00179
00180 }
00181 }
00182 else {
00183
00184 #ifdef PFLOW_DEBUG
00185 if(debug_ ) cout<<"adding to block element "<<(**next)<<endl;
00186 #endif
00187 blocks_->back().addElement( *next );
00188
00189
00190 }
00191
00192
00193
00194
00195
00196
00197
00198 for(IE ie = elements_.begin();
00199 ie != elements_.end();) {
00200
00201 if( ie == last || ie == next ) {
00202 ++ie;
00203 continue;
00204 }
00205
00206
00207 if( (*ie)->locked() ) {
00208 #ifdef PFLOW_DEBUG
00209 if(debug_ ) cout<<"element "<<(**ie)<<"already used"<<endl;
00210 #endif
00211 ++ie;
00212 continue;
00213 }
00214
00215
00216 #ifdef PFLOW_DEBUG
00217 if(debug_ ) cout<<"calling associate "<<(**next)<<" & "<<(**ie)<<endl;
00218 #endif
00219 ie = associate(next, ie, links);
00220 }
00221
00222 #ifdef PFLOW_DEBUG
00223 if(debug_ ) {
00224 cout<<"**** deleting element "<<endl;
00225 cout<<**next<<endl;
00226 }
00227 #endif
00228 delete *next;
00229
00230 #ifdef PFLOW_DEBUG
00231 if(debug_ ) {
00232 cout<<"**** removing element "<<endl;
00233 }
00234 #endif
00235
00236 IE iteratorToNextFreeElement = elements_.erase( next );
00237
00238 #ifdef PFLOW_DEBUG
00239 if(debug_ ) cout<<"PFBlockAlgo::associate stop ----"<<endl;
00240 #endif
00241
00242 return iteratorToNextFreeElement;
00243 }
00244
00245
00246
00247 void PFBlockAlgo::packLinks( reco::PFBlock& block,
00248 const vector<PFBlockLink>& links ) const {
00249
00250
00251 const edm::OwnVector< reco::PFBlockElement >& els = block.elements();
00252
00253 block.bookLinkData();
00254
00255
00256 for( unsigned i1=0; i1<els.size(); i1++ ) {
00257 for( unsigned i2=0; i2<els.size(); i2++ ) {
00258
00259
00260 if( i1==i2 ) continue;
00261
00262 double chi2 = -1;
00263 double dist = -1;
00264
00265 bool linked = false;
00266 PFBlock::LinkTest linktest
00267 = PFBlock::LINKTEST_CHI2;
00268
00269
00270
00271
00272 for( unsigned il=0; il<links.size(); il++ ) {
00273 if( (links[il].element1() == i1 &&
00274 links[il].element2() == i2) ||
00275 (links[il].element1() == i2 &&
00276 links[il].element2() == i1) ) {
00277
00278 chi2 = links[il].chi2();
00279 dist = links[il].dist();
00280 linked = true;
00281
00282
00283
00284 linktest = links[il].test();
00285 #ifdef PFLOW_DEBUG
00286 if( debug_ )
00287 cout << "Reading link vector: linktest used="
00288 << linktest
00289 << " chi2= " << chi2
00290 << endl;
00291 #endif
00292
00293
00294 break;
00295 }
00296 }
00297
00298 if(!linked) {
00299 PFBlockLink::Type linktype = PFBlockLink::NONE;
00300 link( & els[i1], & els[i2], linktype, linktest, chi2, dist);
00301 }
00302
00303
00304
00305 #ifdef PFLOW_DEBUG
00306 if( debug_ )
00307 cout << "Setting link between elements " << i1 << " and " << i2
00308 << " of chi2 =" << chi2 << " computed from link test "
00309 << linktest << endl;
00310 #endif
00311 block.setLink( i1, i2, chi2, dist, block.linkData(), linktest );
00312 }
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 checkNuclearLinks( block );
00435 }
00436
00437
00438
00439 void PFBlockAlgo::buildGraph() {
00440
00441 }
00442
00443
00444
00445 void PFBlockAlgo::link( const reco::PFBlockElement* el1,
00446 const reco::PFBlockElement* el2,
00447 PFBlockLink::Type& linktype,
00448 reco::PFBlock::LinkTest& linktest,
00449 double& chi2, double& dist) const {
00450
00451
00452
00453 chi2=-1;
00454 dist=-1.;
00455 std::pair<double,double> lnk(chi2,dist);
00456 linktest = PFBlock::LINKTEST_CHI2;
00457
00458 PFBlockElement::Type type1 = el1->type();
00459 PFBlockElement::Type type2 = el2->type();
00460
00461 if( type1==type2 ) {
00462
00463
00464 if( type1!=PFBlockElement::TRACK ) return;
00465
00466 else if (
00467 ((!el1->isSecondary()) && (!el2->isSecondary())) &&
00468 ((!el1->trackType(reco::PFBlockElement::T_FROM_V0)) ||
00469 (!el2->trackType(reco::PFBlockElement::T_FROM_V0)))
00470 ) return;
00471 }
00472
00473 linktype = static_cast<PFBlockLink::Type>
00474 ((1<< (type1-1) ) | (1<< (type2-1) ));
00475
00476 if(debug_ ) std::cout << " PFBlockAlgo links type1 " << type1 << " type2 " << type2 << std::endl;
00477
00478 PFBlockElement::Type lowType = type1;
00479 PFBlockElement::Type highType = type2;
00480 const PFBlockElement* lowEl = el1;
00481 const PFBlockElement* highEl = el2;
00482
00483 if(type1>type2) {
00484 lowType = type2;
00485 highType = type1;
00486 lowEl = el2;
00487 highEl = el1;
00488 }
00489
00490 switch(linktype) {
00491 case PFBlockLink::TRACKandPS1:
00492 case PFBlockLink::TRACKandPS2:
00493 {
00494
00495 PFRecTrackRef trackref = lowEl->trackRefPF();
00496 PFClusterRef clusterref = highEl->clusterRef();
00497 assert( !trackref.isNull() );
00498 assert( !clusterref.isNull() );
00499 lnk = testTrackAndPS( *trackref, *clusterref );
00500 chi2 = lnk.first;
00501 dist = lnk.second;
00502 break;
00503 }
00504
00505 case PFBlockLink::TRACKandECAL:
00506 {
00507 if(debug_ ) cout<<"TRACKandECAL"<<endl;
00508 PFRecTrackRef trackref = lowEl->trackRefPF();
00509
00510 if(debug_ ) std::cout << " Track pt " << trackref->trackRef()->pt() << std::endl;
00511
00512 PFClusterRef clusterref = highEl->clusterRef();
00513 assert( !trackref.isNull() );
00514 assert( !clusterref.isNull() );
00515 lnk = testTrackAndECAL( *trackref, *clusterref );
00516 chi2 = lnk.first;
00517 dist = lnk.second;
00518 if(debug_ ) std::cout << " chi2 from testTrackAndECAL " << chi2 << std::endl;
00519
00520 if( ( chi2 > chi2TrackECAL_ || chi2 < 0 )
00521 && multipleLink_ ){
00522
00523
00524
00525
00526
00527
00528 if(debug_ ) std::cout << " try testLinkByRecHit " << std::endl;
00529 lnk = testLinkByRecHit( *trackref, *clusterref );
00530 chi2 = lnk.first;
00531 dist = lnk.second;
00532 if(debug_ ) std::cout << " chi2 testLinkByRecHit " << chi2 << std::endl;
00533 linktest = PFBlock::LINKTEST_RECHIT;
00534 }
00535
00536 if ( chi2>0) {
00537 if(debug_ ) std::cout << " Here a link has been established between a track an Ecal with chi2 " << chi2 << std::endl;
00538 } else {
00539 if(debug_ ) std::cout << " No link found " << std::endl;
00540 }
00541
00542
00543
00544 break;
00545 }
00546 case PFBlockLink::TRACKandHCAL:
00547 {
00548
00549 PFRecTrackRef trackref = lowEl->trackRefPF();
00550 PFClusterRef clusterref = highEl->clusterRef();
00551 assert( !trackref.isNull() );
00552 assert( !clusterref.isNull() );
00553 lnk = testTrackAndHCAL( *trackref, *clusterref );
00554 chi2 = lnk.first;
00555 dist = lnk.second;
00556
00557 if( ( chi2 > chi2TrackHCAL_ || chi2 < 0 )
00558 && multipleLink_ ){
00559
00560
00561
00562
00563
00564
00565
00566 lnk = testLinkByRecHit( *trackref, *clusterref );
00567 chi2 = lnk.first;
00568 dist = lnk.second;
00569 linktest = PFBlock::LINKTEST_RECHIT;
00570 }
00571
00572 break;
00573 }
00574 case PFBlockLink::ECALandHCAL:
00575 {
00576
00577 PFClusterRef ecalref = lowEl->clusterRef();
00578 PFClusterRef hcalref = highEl->clusterRef();
00579 assert( !ecalref.isNull() );
00580 assert( !hcalref.isNull() );
00581 lnk = testECALAndHCAL( *ecalref, *hcalref );
00582 chi2 = lnk.first;
00583 dist = lnk.second;
00584 break;
00585 }
00586 case PFBlockLink::PS1andECAL:
00587 case PFBlockLink::PS2andECAL:
00588 {
00589
00590 PFClusterRef psref = lowEl->clusterRef();
00591 PFClusterRef ecalref = highEl->clusterRef();
00592 assert( !psref.isNull() );
00593 assert( !ecalref.isNull() );
00594 lnk = testPSAndECAL( *psref, *ecalref );
00595 chi2 = lnk.first;
00596 dist = lnk.second;
00597 break;
00598 }
00599 case PFBlockLink::PS1andPS2:
00600 {
00601 PFClusterRef ps1ref = lowEl->clusterRef();
00602 PFClusterRef ps2ref = highEl->clusterRef();
00603 assert( !ps1ref.isNull() );
00604 assert( !ps2ref.isNull() );
00605 lnk = testPS1AndPS2( *ps1ref, *ps2ref );
00606 chi2 = lnk.first;
00607 dist = lnk.second;
00608 break;
00609 }
00610 case PFBlockLink::TRACKandTRACK:
00611 {
00612 if(debug_ ) cout<<"TRACKandTRACK"<<endl;
00613 lnk = testLinkByVertex(lowEl, highEl);
00614 chi2 = lnk.first;
00615 dist = lnk.second;
00616 if(debug_ ) std::cout << " PFBlockLink::TRACKandTRACK chi2 " << chi2 << std::endl;
00617 break;
00618 }
00619 case PFBlockLink::ECALandGSF:
00620 {
00621 PFClusterRef clusterref = lowEl->clusterRef();
00622 assert( !clusterref.isNull() );
00623 const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
00624 const PFRecTrack * myTrack = &(GsfEl->GsftrackPF());
00625 lnk = testTrackAndECAL( *myTrack, *clusterref);
00626 chi2 = lnk.first;
00627 dist = lnk.second;
00628 break;
00629 }
00630 case PFBlockLink::TRACKandGSF:
00631 {
00632 PFRecTrackRef trackref = lowEl->trackRefPF();
00633 assert( !trackref.isNull() );
00634 const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
00635 GsfPFRecTrackRef gsfref = GsfEl->GsftrackRefPF();
00636 reco::TrackRef kftrackref= (*trackref).trackRef();
00637 assert( !gsfref.isNull() );
00638 PFRecTrackRef refkf = (*gsfref).kfPFRecTrackRef();
00639 if(refkf.isNonnull())
00640 {
00641 reco::TrackRef gsftrackref = (*refkf).trackRef();
00642 if (gsftrackref.isNonnull()&&kftrackref.isNonnull()) {
00643 if (kftrackref == gsftrackref) {
00644 chi2 = 1;
00645 dist = 0.001;
00646
00647 } else {
00648 chi2 = -1;
00649 dist = -1.;
00650
00651 }
00652 }
00653 else {
00654 chi2 = -1;
00655 dist = -1.;
00656
00657 }
00658 }
00659 else
00660 {
00661 chi2 = -1;
00662 dist = -1.;
00663
00664 }
00665 break;
00666 }
00667
00668 case PFBlockLink::GSFandBREM:
00669 {
00670 const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(lowEl);
00671 const reco::PFBlockElementBrem * BremEl = dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
00672 GsfPFRecTrackRef gsfref = GsfEl->GsftrackRefPF();
00673 GsfPFRecTrackRef bremref = BremEl->GsftrackRefPF();
00674 assert( !gsfref.isNull() );
00675 assert( !bremref.isNull() );
00676 if (gsfref == bremref) {
00677 chi2 = 1;
00678 dist = 0.001;
00679 } else {
00680 chi2 = -1;
00681 dist = -1.;
00682 }
00683 break;
00684 }
00685 case PFBlockLink::ECALandBREM:
00686 {
00687 PFClusterRef clusterref = lowEl->clusterRef();
00688 assert( !clusterref.isNull() );
00689 const reco::PFBlockElementBrem * BremEl = dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
00690 const PFRecTrack * myTrack = &(BremEl->trackPF());
00691 double DP = (BremEl->DeltaP())*(-1.);
00692 double SigmaDP = BremEl->SigmaDeltaP();
00693 double SignBremDp = DP/SigmaDP;
00694 lnk = testTrackAndECAL( *myTrack, *clusterref, SignBremDp);
00695 chi2 = lnk.first;
00696 dist = lnk.second;
00697 break;
00698 }
00699 case PFBlockLink::PS1andGSF:
00700 case PFBlockLink::PS2andGSF:
00701 {
00702 PFClusterRef psref = lowEl->clusterRef();
00703 assert( !psref.isNull() );
00704 const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
00705 const PFRecTrack * myTrack = &(GsfEl->GsftrackPF());
00706 lnk = testTrackAndPS( *myTrack, *psref );
00707 chi2 = lnk.first;
00708 dist = lnk.second;
00709 break;
00710 }
00711 case PFBlockLink::PS1andBREM:
00712 case PFBlockLink::PS2andBREM:
00713 {
00714 PFClusterRef psref = lowEl->clusterRef();
00715 assert( !psref.isNull() );
00716 const reco::PFBlockElementBrem * BremEl = dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
00717 const PFRecTrack * myTrack = &(BremEl->trackPF());
00718 lnk = testTrackAndPS( *myTrack, *psref );
00719 chi2 = lnk.first;
00720 dist = lnk.second;
00721 break;
00722 }
00723 case PFBlockLink::HCALandGSF:
00724 {
00725 PFClusterRef clusterref = lowEl->clusterRef();
00726 assert( !clusterref.isNull() );
00727 const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
00728 const PFRecTrack * myTrack = &(GsfEl->GsftrackPF());
00729 lnk = testTrackAndHCAL( *myTrack, *clusterref);
00730 chi2 = lnk.first;
00731 dist = lnk.second;
00732 break;
00733 }
00734 case PFBlockLink::HCALandBREM:
00735 {
00736 PFClusterRef clusterref = lowEl->clusterRef();
00737 assert( !clusterref.isNull() );
00738 const reco::PFBlockElementBrem * BremEl = dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
00739 const PFRecTrack * myTrack = &(BremEl->trackPF());
00740 lnk = testTrackAndHCAL( *myTrack, *clusterref);
00741 chi2 = lnk.first;
00742 dist = lnk.second;
00743 break;
00744 }
00745
00746
00747 default:
00748 chi2 = -1.;
00749 dist = -1.;
00750
00751
00752 return;
00753 }
00754 }
00755
00756 std::pair<double,double>
00757 PFBlockAlgo::testTrackAndPS(const PFRecTrack& track,
00758 const PFCluster& ps) const {
00759
00760
00761
00762 double dx=0.;
00763 double dy=0.;
00764
00765 unsigned layerid =0;
00766
00767 switch (ps.layer()) {
00768 case PFLayer::PS1:
00769 layerid = reco::PFTrajectoryPoint::PS1;
00770
00771
00772 dx = resPSpitch_;
00773 dy = resPSlength_;
00774 break;
00775 case PFLayer::PS2:
00776 layerid = reco::PFTrajectoryPoint::PS2;
00777
00778 dy = resPSpitch_;
00779 dx = resPSlength_;
00780 break;
00781 default:
00782 break;
00783 }
00784 const reco::PFTrajectoryPoint& atPS
00785 = track.extrapolatedPoint( layerid );
00786
00787 if( ! atPS.isValid() ) return std::pair<double,double>(-1,-1);
00788
00789 double trackx = atPS.position().X();
00790 double tracky = atPS.position().Y();
00791
00792
00793 double psx = ps.position().X();
00794 double psy = ps.position().Y();
00795
00796
00797
00798 double trackresolx = 0.;
00799 double trackresoly = 0.;
00800
00801 double chi2 = (psx-trackx)*(psx-trackx)/(dx*dx + trackresolx*trackresolx)
00802 + (psy-tracky)*(psy-tracky)/(dy*dy + trackresoly*trackresoly);
00803
00804 double dist = std::sqrt( (psx-trackx)*(psx-trackx)
00805 + (psy-tracky)*(psy-tracky));
00806
00807
00808 #ifdef PFLOW_DEBUG
00809 if(debug_) cout<<"testTrackAndPS "<<chi2<<" "<<endl;
00810 if(debug_){
00811 cout<<" trackx " << trackx << " trackresolx " << trackresolx
00812 <<" tracky " << tracky << " trackresoly " << trackresoly << endl
00813 <<" psx " << psx << " dx " << dx
00814 <<" psy " << psy << " dy " << dy << endl;
00815 }
00816 #endif
00817
00818
00819 if(chi2<chi2PSTrack_ || chi2PSTrack_<0 )
00820 return std::pair<double,double>(chi2,dist);
00821 else
00822 return std::pair<double,double>(-1,-1);
00823 }
00824
00825
00826
00827 std::pair<double,double>
00828 PFBlockAlgo::testTrackAndECAL(const PFRecTrack& track,
00829 const PFCluster& ecal,
00830 double SignBremDp) const {
00831
00832
00833
00834
00835 double tracketa;
00836 double trackphi;
00837
00838
00839 double chi2cut = (track.algoType()!=PFRecTrack::GSF) ? chi2TrackECAL_ : chi2GSFECAL_;
00840
00841
00842
00843 if (SignBremDp > 3) {
00844 const reco::PFTrajectoryPoint& atECAL
00845 = track.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax );
00846 if( ! atECAL.isValid() ) return std::pair<double,double>(-1,-1);
00847 tracketa = atECAL.positionREP().Eta();
00848 trackphi = atECAL.positionREP().Phi();
00849
00850
00851
00852 }
00853 else {
00854
00855
00856
00857 const reco::PFTrajectoryPoint& atECAL
00858 = track.extrapolatedPoint( reco::PFTrajectoryPoint::ECALEntrance );
00859 if( ! atECAL.isValid() ) return std::pair<double,double>(-1,-1);
00860 math::XYZVector posatecal( atECAL.position().x(),
00861 atECAL.position().y(),
00862 atECAL.position().z());
00863
00864 bool isBelowPS=(fabs(ecal.positionREP().Eta())>1.65) ? true :false;
00865 double clusenergy = ecal.energy();
00866 double ecalShowerDepth
00867 = reco::PFCluster::getDepthCorrection(clusenergy, isBelowPS,false);
00868
00869 math::XYZVector direction(atECAL.momentum().x(),
00870 atECAL.momentum().y(),
00871 atECAL.momentum().z() );
00872
00873 direction=direction.unit();
00874 posatecal += ecalShowerDepth*direction;
00875 tracketa = posatecal.eta();
00876 trackphi = posatecal.phi();
00877 }
00878
00879
00880 double ecaleta = ecal.positionREP().Eta();
00881 double ecalphi = ecal.positionREP().Phi();
00882
00883
00884 PFResolutionMap* mapeta = const_cast<PFResolutionMap*>(resMapEtaECAL_);
00885 PFResolutionMap* mapphi = const_cast<PFResolutionMap*>(resMapPhiECAL_);
00886
00887
00888 double ecaletares
00889 = mapeta->GetBinContent(mapeta->FindBin(ecaleta,
00890 ecal.energy() ) );
00891 double ecalphires
00892 = mapphi->GetBinContent(mapphi->FindBin(ecaleta,
00893 ecal.energy() ) );
00894
00895
00896
00897 double trackres = 0;
00898
00899 std::pair<double,double> lnk = computeChi2( ecaleta, ecaletares,
00900 ecalphi, ecalphires,
00901 tracketa, trackres,
00902 trackphi, trackres);
00903 double chi2 = lnk.first;
00904
00905 #ifdef PFLOW_DEBUG
00906 if(debug_) cout<<"testTrackAndECAL "<<chi2<<" "<<endl;
00907 if(debug_){
00908 cout<<" ecaleta " << ecaleta << " ecaletares " <<ecaletares
00909 <<" ecalphi " << ecalphi << " ecalphires " <<ecalphires
00910 <<" tracketa " << tracketa << " trackres " <<trackres
00911 <<" trackphi " << trackphi << " trackres " <<trackres << endl;
00912 }
00913 #endif
00914
00915
00916 if(chi2<chi2cut || chi2TrackECAL_<0 )
00917 return lnk;
00918 else
00919 return std::pair<double,double>(-1,-1);
00920 }
00921
00922
00923
00924 std::pair<double,double>
00925 PFBlockAlgo::testTrackAndHCAL(const PFRecTrack& track,
00926 const PFCluster& hcal) const {
00927
00928
00929
00930
00931
00932
00933
00934
00935 const reco::PFTrajectoryPoint& atHCAL
00936 = track.extrapolatedPoint( reco::PFTrajectoryPoint::HCALEntrance );
00937
00938
00939
00940
00941
00942
00943 if( ! atHCAL.isValid() ) return std::pair<double,double>(-1,-1);
00944
00945 double tracketa = atHCAL.positionREP().Eta();
00946 double trackphi = atHCAL.positionREP().Phi();
00947 double hcaleta = hcal.positionREP().Eta();
00948 double hcalphi = hcal.positionREP().Phi();
00949
00950
00951 PFResolutionMap* mapeta = const_cast<PFResolutionMap*>(resMapEtaHCAL_);
00952 PFResolutionMap* mapphi = const_cast<PFResolutionMap*>(resMapPhiHCAL_);
00953
00954 double hcaletares
00955 = mapeta->GetBinContent(mapeta->FindBin(hcaleta,
00956 hcal.energy() ) );
00957 double hcalphires
00958 = mapphi->GetBinContent(mapphi->FindBin(hcaleta,
00959 hcal.energy() ) );
00960
00961
00962
00963 double trackres = 0;
00964
00965 std::pair<double,double> lnk = computeChi2( hcaleta, hcaletares,
00966 hcalphi, hcalphires,
00967 tracketa, trackres,
00968 trackphi, trackres);
00969 double chi2 = lnk.first;
00970
00971 #ifdef PFLOW_DEBUG
00972 if(debug_) cout<<"testTrackAndHCAL "<<chi2<<" "<<endl;
00973 if(debug_){
00974 cout<<" hcaleta " << hcaleta << " hcaletares "<<hcaletares
00975 <<" hcalphi " << hcalphi << " hcalphires "<<hcalphires
00976 <<" tracketa " << tracketa<< " trackres " <<trackres
00977 <<" trackphi " << trackphi<< " trackres " <<trackres << endl;
00978 }
00979 #endif
00980
00981 if(chi2<chi2TrackHCAL_ || chi2TrackHCAL_<0 )
00982 return lnk;
00983 else
00984 return std::pair<double,double>(-1,-1);
00985 }
00986
00987
00988 std::pair<double,double>
00989 PFBlockAlgo::testECALAndHCAL(const PFCluster& ecal,
00990 const PFCluster& hcal) const {
00991
00992
00993
00994
00995 PFResolutionMap* mapetaECAL = const_cast<PFResolutionMap*>(resMapEtaECAL_);
00996 PFResolutionMap* mapphiECAL = const_cast<PFResolutionMap*>(resMapPhiECAL_);
00997
00998 PFResolutionMap* mapetaHCAL = const_cast<PFResolutionMap*>(resMapEtaHCAL_);
00999 PFResolutionMap* mapphiHCAL = const_cast<PFResolutionMap*>(resMapPhiHCAL_);
01000
01001
01002 double ecaletares
01003 = mapetaECAL->GetBinContent(mapetaECAL->FindBin(ecal.positionREP().Eta(),
01004 ecal.energy() ) );
01005 double ecalphires
01006 = mapphiECAL->GetBinContent(mapphiECAL->FindBin(ecal.positionREP().Eta(),
01007 ecal.energy() ) );
01008
01009 double hcaletares
01010 = mapetaHCAL->GetBinContent(mapetaHCAL->FindBin(hcal.positionREP().Eta(),
01011 hcal.energy() ) );
01012 double hcalphires
01013 = mapphiHCAL->GetBinContent(mapphiHCAL->FindBin(hcal.positionREP().Eta(),
01014 hcal.energy() ) );
01015
01016
01017 std::pair<double,double> lnk =
01018 computeChi2( ecal.positionREP().Eta(), ecaletares,
01019 ecal.positionREP().Phi(), ecalphires,
01020 hcal.positionREP().Eta(), hcaletares,
01021 hcal.positionREP().Phi(), hcalphires );
01022 double chi2 = lnk.first;
01023
01024 #ifdef PFLOW_DEBUG
01025 if(debug_) cout<<"testECALAndHCAL "<<chi2<<" "<<endl;
01026 if(debug_){
01027 cout<<" ecaleta " << ecal.positionREP().Eta()<< " ecaletares "<<ecaletares
01028 <<" ecalphi " << ecal.positionREP().Phi()<< " ecalphires "<<ecalphires
01029 <<" hcaleta " << hcal.positionREP().Eta()<< " hcaletares "<<hcaletares
01030 <<" hcalphi " << hcal.positionREP().Phi()<< " hcalphires "<<hcalphires<< endl;
01031 }
01032 #endif
01033
01034
01035 if(chi2<chi2ECALHCAL_ || chi2ECALHCAL_<0 )
01036 return lnk;
01037 else
01038 return std::pair<double,double>(-1,-1);
01039 }
01040 std::pair<double,double>
01041 PFBlockAlgo::testPSAndECAL(const PFCluster& ps,
01042 const PFCluster& ecal) const {
01043
01044
01045
01046 PFResolutionMap* mapetaECAL = const_cast<PFResolutionMap*>(resMapEtaECAL_);
01047 PFResolutionMap* mapphiECAL = const_cast<PFResolutionMap*>(resMapPhiECAL_);
01048
01049
01050 double ecaletares
01051 = mapetaECAL->GetBinContent(mapetaECAL->FindBin(ecal.positionREP().Eta(),
01052 ecal.energy() ) );
01053 double ecalphires
01054 = mapphiECAL->GetBinContent(mapphiECAL->FindBin(ecal.positionREP().Eta(),
01055 ecal.energy() ) );
01056
01057 double ecaleta = ecal.positionREP().Eta();
01058 double ecalphi = ecal.positionREP().Phi();
01059
01060
01061
01062 double pseta = ps.positionREP().Eta();
01063 double psphi = ps.positionREP().Phi();
01064 double psrho = ps.positionREP().Rho();
01065 double psrho2 = psrho*psrho;
01066 double psx = ps.position().X();
01067 double psy = ps.position().Y();
01068 double psz = ps.position().Z();
01069 double psR = ps.position().R();
01070
01071 double dxdx =0.;
01072 double dydy =0.;
01073 switch (ps.layer()) {
01074 case PFLayer::PS1:
01075
01076 dxdx = resPSpitch_*resPSpitch_;
01077 dydy = resPSlength_*resPSlength_;
01078 break;
01079 case PFLayer::PS2:
01080
01081 dydy = resPSpitch_*resPSpitch_;
01082 dxdx = resPSlength_*resPSlength_;
01083 break;
01084 default:
01085 break;
01086 }
01087
01088 double detadx = psx*psz/(psrho2*psR);
01089 double detady = psy*psz/(psrho2*psR);
01090 double dphidx = -psy/psrho2;
01091 double dphidy = psx/psrho2;
01092
01093 double detadeta = detadx*detadx*dxdx + detady*detady*dydy;
01094 double dphidphi = dphidx*dphidx*dxdx + dphidy*dphidy*dydy;
01095 double detadphi = detadx*dphidx*dxdx + detady*dphidy*dydy;
01096
01097 double detadetas = detadeta + ecaletares*ecaletares;
01098 double dphidphis = dphidphi + ecalphires*ecalphires;
01099
01100 double deta = pseta - ecaleta;
01101 double dphi = Utils::mpi_pi(psphi - ecalphi);
01102 double det = detadetas*dphidphis - detadphi*detadphi;
01103 double chi2
01104 = (dphidphis*deta*deta + detadetas*dphi*dphi - 2.*detadphi*deta*dphi)/det;
01105 double dist = std::sqrt(deta*deta+dphi*dphi);
01106
01107
01108 #ifdef PFLOW_DEBUG
01109 if(debug_) cout<<"testPSAndECAL "<<chi2<<" "<<endl;
01110 if(debug_){
01111 double psetares = sqrt(detadeta);
01112 double psphires = sqrt (dphidphi);
01113 cout<< " pseta " <<pseta << " psetares " << psetares
01114 << " psphi " <<psphi << " psphires " << psphires << endl
01115 << " ecaleta "<<ecaleta << " ecaletares " << ecaletares
01116 << " ecalphi "<<ecalphi << " ecalphires " << ecalphires<< endl;
01117 }
01118 #endif
01119
01120
01121 if(chi2<chi2PSECAL_ || chi2PSECAL_<0 )
01122 return std::pair<double,double>(chi2,dist);
01123 else
01124 return std::pair<double,double>(-1,-1);
01125 }
01126
01127
01128 std::pair<double,double>
01129 PFBlockAlgo::testPS1AndPS2(const PFCluster& ps1,
01130 const PFCluster& ps2) const {
01131
01132
01133
01134
01135
01136
01137
01138 double x1 = ps1.position().X();
01139 double y1 = ps1.position().Y();
01140 double z1 = ps1.position().Z();
01141 double x2 = ps2.position().X();
01142 double y2 = ps2.position().Y();
01143 double z2 = ps2.position().Z();
01144
01145 double scale = z2/z1;
01146 double x1atPS2 = x1*scale;
01147 double y1atPS2 = y1*scale;
01148
01149
01150 double dx1dx1 = resPSpitch_*resPSpitch_*scale*scale;
01151 double dy1dy1 = resPSlength_*resPSlength_*scale*scale;
01152
01153 double dy2dy2 = resPSpitch_*resPSpitch_;
01154 double dx2dx2 = resPSlength_*resPSlength_;
01155
01156 double chi2 = (x2-x1atPS2)*(x2-x1atPS2)/(dx1dx1 + dx2dx2)
01157 + (y2-y1atPS2)*(y2-y1atPS2)/(dy1dy1 + dy2dy2);
01158
01159 double dist = std::sqrt( (x2-x1atPS2)*(x2-x1atPS2)
01160 + (y2-y1atPS2)*(y2-y1atPS2));
01161
01162 #ifdef PFLOW_DEBUG
01163 if(debug_) cout<<"testPS1AndPS2 "<<chi2<<" "<<endl;
01164 if(debug_){
01165 cout<<" x1atPS2 "<< x1atPS2 << " dx1 "<<resPSpitch_*scale
01166 <<" y1atPS2 "<< y1atPS2 << " dy1 "<<resPSlength_*scale<< endl
01167 <<" x2 " <<x2 << " dx2 "<<resPSlength_
01168 <<" y2 " << y2 << " dy2 "<<resPSpitch_<< endl;
01169 }
01170 #endif
01171 if(chi2<chi2PSHV_ || chi2PSHV_<0 )
01172 return std::pair<double,double>(chi2,dist);
01173 else
01174 return std::pair<double,double>(-1,-1);
01175 }
01176
01177 std::pair<double,double>
01178 PFBlockAlgo::testLinkByVertex( const reco::PFBlockElement* elt1,
01179 const reco::PFBlockElement* elt2) const {
01180
01181 double result=-1.;
01182 if( (elt1->trackType(reco::PFBlockElement::T_TO_NUCL) &&
01183 elt2->trackType(reco::PFBlockElement::T_FROM_NUCL)) ||
01184 (elt1->trackType(reco::PFBlockElement::T_FROM_NUCL) &&
01185 elt2->trackType(reco::PFBlockElement::T_TO_NUCL)) ||
01186 (elt1->trackType(reco::PFBlockElement::T_FROM_NUCL) &&
01187 elt2->trackType(reco::PFBlockElement::T_FROM_NUCL))) {
01188
01189 NuclearInteractionRef ni1_ = elt1->nuclearRef();
01190 NuclearInteractionRef ni2_ = elt2->nuclearRef();
01191 if( ni1_.isNonnull() && ni2_.isNonnull() ) {
01192 if( ni1_ == ni2_ ) result= 1.0;
01193 }
01194 }
01195 else if ( elt1->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) &&
01196 elt2->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) ) {
01197
01198 if(debug_ ) std::cout << " testLinkByVertex On Conversions " << std::endl;
01199
01200 if ( elt1->convRef().isNonnull() && elt2->convRef().isNonnull() ) {
01201 if(debug_ ) std::cout << " PFBlockAlgo.cc testLinkByVertex Cconversion Refs are non null " << std::endl;
01202 if ( elt1->convRef() == elt2->convRef() ) {
01203 result=1.0;
01204 if(debug_ ) std::cout << " testLinkByVertex Cconversion Refs are equal " << std::endl;
01205 }
01206 }
01207
01208 }
01209 else if ( elt1->trackType(reco::PFBlockElement::T_FROM_V0) &&
01210 elt2->trackType(reco::PFBlockElement::T_FROM_V0) ) {
01211 if(debug_ ) std::cout << " testLinkByVertex On V0 " << std::endl;
01212 if ( elt1->V0Ref().isNonnull() && elt2->V0Ref().isNonnull() ) {
01213 if(debug_ ) std::cout << " PFBlockAlgo.cc testLinkByVertex V0 Refs are non null " << std::endl;
01214 if ( elt1->V0Ref() == elt2->V0Ref() ) {
01215 result=1.0;
01216 if(debug_ ) std::cout << " testLinkByVertex V0 Refs are equal " << std::endl;
01217 }
01218 }
01219 }
01220
01221 return std::pair<double,double>(result,0.);
01222 }
01223
01224 std::pair<double,double>
01225 PFBlockAlgo::testLinkByRecHit( const PFRecTrack& track,
01226 const PFCluster& cluster) const {
01227
01228 #ifdef PFLOW_DEBUG
01229 if( debug_ )
01230 cout<<"entering test link by rechit function"<<endl;
01231 #endif
01232
01233
01234 double clustereta = cluster.positionREP().Eta();
01235 double clusterphi = cluster.positionREP().Phi();
01236
01237 bool barrel = false;
01238
01239
01240 const reco::PFTrajectoryPoint& atECAL
01241 = track.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax );
01242 const reco::PFTrajectoryPoint& atHCAL
01243 = track.extrapolatedPoint( reco::PFTrajectoryPoint::HCALEntrance );
01244
01245
01246 double tracketa = 999999.9;
01247 double trackphi = 999999.9;
01248 double track_X = 999999.9;
01249 double track_Y = 999999.9;
01250
01251
01252 PFResolutionMap* mapeta;
01253 PFResolutionMap* mapphi;
01254 switch (cluster.layer()) {
01255 case PFLayer::ECAL_BARREL: barrel = true;
01256 case PFLayer::ECAL_ENDCAP:
01257 #ifdef PFLOW_DEBUG
01258 if( debug_ )
01259 cout << "Fetching Ecal Resolution Maps"
01260 << endl;
01261 #endif
01262 mapeta = const_cast<PFResolutionMap*>(resMapEtaECAL_);
01263 mapphi = const_cast<PFResolutionMap*>(resMapPhiECAL_);
01264
01265
01266 if( ! atECAL.isValid() ) return std::pair<double,double>(-1,-1);
01267
01268 tracketa = atECAL.positionREP().Eta();
01269 trackphi = atECAL.positionREP().Phi();
01270 track_X = atECAL.position().X();
01271 track_Y = atECAL.position().Y();
01272
01273 break;
01274 case PFLayer::HCAL_BARREL1: barrel = true;
01275 case PFLayer::HCAL_ENDCAP:
01276 #ifdef PFLOW_DEBUG
01277 if( debug_ )
01278 cout << "Fetching Hcal Resolution Maps"
01279 << endl;
01280 #endif
01281 mapeta = const_cast<PFResolutionMap*>(resMapEtaHCAL_);
01282 mapphi = const_cast<PFResolutionMap*>(resMapPhiHCAL_);
01283
01284
01285 if( ! atHCAL.isValid() ) return std::pair<double,double>(-1,-1);
01286
01287 tracketa = atHCAL.positionREP().Eta();
01288 trackphi = atHCAL.positionREP().Phi();
01289 track_X = atHCAL.position().X();
01290 track_Y = atHCAL.position().Y();
01291
01292 break;
01293 case PFLayer::PS1:
01294 case PFLayer::PS2:
01295
01296
01297 #ifdef PFLOW_DEBUG
01298 if( debug_ )
01299 cout << "No link by rechit possible for pre-shower yet!"
01300 << endl;
01301 #endif
01302 return std::pair<double,double>(-1,-1);
01303 default:
01304 return std::pair<double,double>(-1,-1);
01305 }
01306
01307 double clusteretares
01308 = mapeta->GetBinContent(mapeta->FindBin(clustereta,
01309 cluster.energy() ) );
01310 double clusterphires
01311 = mapphi->GetBinContent(mapphi->FindBin(clustereta,
01312 cluster.energy() ) );
01313
01314
01315
01316
01317 double trackres = 0;
01318
01319 std::pair<double,double> lnk = computeChi2( clustereta, clusteretares,
01320 clusterphi, clusterphires,
01321 tracketa, trackres,
01322 trackphi, trackres);
01323
01324 #ifdef PFLOW_DEBUG
01325 double chi2 = lnk.first;
01326 if(debug_) cout<<"test link by rechit "<<chi2<<" "<<endl;
01327 if(debug_){
01328 cout<<" clustereta " << clustereta << " clusteretares "<<clusteretares
01329 <<" clusterphi " << clusterphi << " clusterphires "<<clusterphires
01330 <<" tracketa " << tracketa<< " trackres " <<trackres
01331 <<" trackphi " << trackphi<< " trackres " <<trackres << endl;
01332 }
01333 #endif
01334
01335
01336
01337
01338
01339
01340 const std::vector< reco::PFRecHitFraction >&
01341 fracs = cluster.recHitFractions();
01342
01343 bool linkedbyrechit = false;
01344
01345 for(unsigned int rhit = 0; rhit < fracs.size(); ++rhit){
01346
01347 const reco::PFRecHitRef& rh = fracs[rhit].recHitRef();
01348 if(rh.isNull()) continue;
01349
01350
01351 const reco::PFRecHit& rechit_cluster = *rh;
01352
01353
01354 const reco::PFRecHit::REPPoint& posrep
01355 = rechit_cluster.positionREP();
01356
01357
01358 const std::vector< math::XYZPoint >&
01359 cornersxyz = rechit_cluster.getCornersXYZ();
01360 const std::vector<reco::PFRecHit::REPPoint>& corners =
01361 rechit_cluster.getCornersREP();
01362 assert(corners.size() == 4);
01363
01364
01365 if( barrel ){
01366
01367
01368 double rhsizeEta
01369 = fabs(corners[0].Eta() - corners[2].Eta());
01370 double rhsizePhi
01371 = fabs(corners[0].Phi() - corners[2].Phi());
01372 if ( rhsizePhi > M_PI ) rhsizePhi = 2.*M_PI - rhsizePhi;
01373
01374 #ifdef PFLOW_DEBUG
01375 if( debug_ ) {
01376 cout << rhit << " Hcal RecHit="
01377 << posrep.Eta() << " "
01378 << posrep.Phi() << " "
01379 << rechit_cluster.energy()
01380 << endl;
01381 for ( unsigned jc=0; jc<4; ++jc )
01382 cout<<"corners "<<jc<<" "<<corners[jc].Eta()
01383 <<" "<<corners[jc].Phi()<<endl;
01384
01385 cout << "RecHit SizeEta=" << rhsizeEta
01386 << " SizePhi=" << rhsizePhi << endl;
01387 }
01388 #endif
01389
01390
01391
01392
01393 double deta = fabs(posrep.Eta() - tracketa);
01394 double dphi = fabs(posrep.Phi() - trackphi);
01395 if ( dphi > M_PI ) dphi = 2.*M_PI - dphi;
01396
01397 #ifdef PFLOW_DEBUG
01398 if( debug_ ){
01399 cout << "distance="
01400 << deta << " "
01401 << dphi << " ";
01402 if(deta < (rhsizeEta/2.) && dphi < (rhsizePhi/2.))
01403 cout << " link here !" << endl;
01404 else cout << endl;
01405 }
01406 #endif
01407
01408 if(deta < (rhsizeEta/2.) && dphi < (rhsizePhi/2.)){
01409 linkedbyrechit = true;
01410 break;
01411 }
01412 }
01413 else {
01414
01415 #ifdef PFLOW_DEBUG
01416 if( debug_ ){
01417 const math::XYZPoint& posxyz
01418 = rechit_cluster.position();
01419
01420 cout << "RH " << posxyz.X()
01421 << " " << posxyz.Y()
01422 << endl;
01423
01424 cout << "TRACK " << track_X
01425 << " " << track_Y
01426 << endl;
01427 }
01428 #endif
01429
01430 double x[5];
01431 double y[5];
01432 for ( unsigned jc=0; jc<4; ++jc ) {
01433 math::XYZPoint cornerposxyz = cornersxyz[jc];
01434 x[jc] = cornerposxyz.X();
01435 y[jc] = cornerposxyz.Y();
01436
01437 #ifdef PFLOW_DEBUG
01438 if( debug_ ){
01439 cout<<"corners "<<jc
01440 << " " << cornerposxyz.X()
01441 << " " << cornerposxyz.Y()
01442 << endl;
01443 }
01444 #endif
01445 }
01446
01447
01448
01449 x[4] = x[0];
01450 y[4] = y[0];
01451
01452
01453
01454 bool isinside = TMath::IsInside(track_X,
01455 track_Y,
01456 5,x,y);
01457
01458 if( isinside ){
01459 linkedbyrechit = true;
01460 break;
01461 }
01462 }
01463
01464 }
01465
01466 if( linkedbyrechit ) {
01467 #ifdef PFLOW_DEBUG
01468 if( debug_ )
01469 cout << "Track and Cluster LINKED BY RECHIT" << endl;
01470 #endif
01471 return lnk;
01472 }
01473 else
01474 return std::pair<double,double>(-1,-1);
01475 }
01476
01477 std::pair<double,double>
01478 PFBlockAlgo::computeChi2( double eta1, double reta1,
01479 double phi1, double rphi1,
01480 double eta2, double reta2,
01481 double phi2, double rphi2 ) const {
01482
01483 double phicor = Utils::mpi_pi(phi1 - phi2);
01484
01485 double chi2 =
01486 (eta1 - eta2)*(eta1 - eta2) / ( reta1*reta1+ reta2*reta2 ) +
01487 phicor*phicor / ( rphi1*rphi1+ rphi2*rphi2 );
01488
01489 double dist = std::sqrt( (eta1 - eta2)*(eta1 - eta2)
01490 + phicor*phicor);
01491
01492 return std::pair<double,double>(chi2,dist);
01493
01494 }
01495
01496 void PFBlockAlgo::checkMaskSize( const reco::PFRecTrackCollection& tracks,
01497 const reco::GsfPFRecTrackCollection& gsftracks,
01498 const reco::PFClusterCollection& ecals,
01499 const reco::PFClusterCollection& hcals,
01500 const reco::PFClusterCollection& pss,
01501 const Mask& trackMask,
01502 const Mask& gsftrackMask,
01503 const Mask& ecalMask,
01504 const Mask& hcalMask,
01505 const Mask& psMask ) const {
01506
01507 if( !trackMask.empty() &&
01508 trackMask.size() != tracks.size() ) {
01509 string err = "PFBlockAlgo::setInput: ";
01510 err += "The size of the track mask is different ";
01511 err += "from the size of the track vector.";
01512 throw std::length_error( err.c_str() );
01513 }
01514
01515 if( !gsftrackMask.empty() &&
01516 gsftrackMask.size() != gsftracks.size() ) {
01517 string err = "PFBlockAlgo::setInput: ";
01518 err += "The size of the gsf track mask is different ";
01519 err += "from the size of the gsftrack vector.";
01520 throw std::length_error( err.c_str() );
01521 }
01522
01523 if( !ecalMask.empty() &&
01524 ecalMask.size() != ecals.size() ) {
01525 string err = "PFBlockAlgo::setInput: ";
01526 err += "The size of the ecal mask is different ";
01527 err += "from the size of the ecal clusters vector.";
01528 throw std::length_error( err.c_str() );
01529 }
01530
01531 if( !hcalMask.empty() &&
01532 hcalMask.size() != hcals.size() ) {
01533 string err = "PFBlockAlgo::setInput: ";
01534 err += "The size of the hcal mask is different ";
01535 err += "from the size of the hcal clusters vector.";
01536 throw std::length_error( err.c_str() );
01537 }
01538 if( !psMask.empty() &&
01539 psMask.size() != pss.size() ) {
01540 string err = "PFBlockAlgo::setInput: ";
01541 err += "The size of the ps mask is different ";
01542 err += "from the size of the ps clusters vector.";
01543 throw std::length_error( err.c_str() );
01544 }
01545
01546 }
01547
01548
01549 std::ostream& operator<<(std::ostream& out, const PFBlockAlgo& a) {
01550 if(! out) return out;
01551
01552 out<<"====== Particle Flow Block Algorithm ======= ";
01553 out<<endl;
01554 out<<"resMapEtaECAL "<<a.resMapEtaECAL_->GetMapFile()<<endl;
01555 out<<"resMapPhiECAL "<<a.resMapPhiECAL_->GetMapFile()<<endl;
01556 out<<"resMapEtaHCAL "<<a.resMapEtaHCAL_->GetMapFile()<<endl;
01557 out<<"resMapPhiHCAL "<<a.resMapPhiHCAL_->GetMapFile()<<endl;
01558 out<<"chi2TrackECAL "<<a.chi2TrackECAL_<<endl;
01559 out<<"chi2TrackHCAL "<<a.chi2TrackHCAL_<<endl;
01560 out<<"chi2ECALHCAL "<<a.chi2ECALHCAL_<<endl;
01561 out<<"chi2PSECAL "<<a.chi2PSECAL_ <<endl;
01562 out<<"chi2PSTRACK "<<a.chi2PSTrack_ <<endl;
01563 out<<"chi2PSHV "<<a.chi2PSHV_ <<endl;
01564 out<<endl;
01565 out<<"number of unassociated elements : "<<a.elements_.size()<<endl;
01566 out<<endl;
01567
01568 for(PFBlockAlgo::IEC ie = a.elements_.begin();
01569 ie != a.elements_.end(); ie++) {
01570 out<<"\t"<<**ie <<endl;
01571 }
01572
01573
01574
01575
01576 const std::auto_ptr< reco::PFBlockCollection >& blocks
01577 = a.blocks();
01578
01579 if(!blocks.get() ) {
01580 out<<"blocks already transfered"<<endl;
01581 }
01582 else {
01583 out<<"number of blocks : "<<blocks->size()<<endl;
01584 out<<endl;
01585
01586 for(PFBlockAlgo::IBC ib=blocks->begin();
01587 ib != blocks->end(); ib++) {
01588 out<<(*ib)<<endl;
01589 }
01590 }
01591
01592 return out;
01593 }
01594
01595 bool PFBlockAlgo::goodPtResolution( const reco::TrackRef& trackref) {
01596 double Pt = trackref->pt();
01597 double DPt = trackref->ptError();
01598 if (debug_) cout << " PFBlockAlgo: PFrecTrack->Track Pt= "
01599 << Pt << " DPt = " << DPt << endl;
01600 if (DPt/Pt > DPtovPtCut_ ) {
01601 if (debug_) cout << " PFBlockAlgo: skip badly measured track Pt= "
01602 << Pt << " DPt = " << DPt << endl;
01603 if (debug_) cout << " cut is DPt/Pt < " << DPtovPtCut_<< endl;
01604 return false;
01605 }
01606 return true;
01607 }
01608
01609 void PFBlockAlgo::fillSecondaries( const reco::PFNuclearInteractionRef& nuclref ) {
01610
01611 for( reco::PFNuclearInteraction::pfTrackref_iterator
01612 pftkref = nuclref->secPFRecTracks_begin();
01613 pftkref != nuclref->secPFRecTracks_end(); ++pftkref) {
01614 if( !goodPtResolution( (*pftkref)->trackRef() ) ) continue;
01615 reco::PFBlockElement *secondaryTrack
01616 = new reco::PFBlockElementTrack( *pftkref );
01617 secondaryTrack->setNuclearRef( nuclref->nuclInterRef(),
01618 reco::PFBlockElement::T_FROM_NUCL );
01619
01620 elements_.push_back( secondaryTrack );
01621 }
01622 }
01623
01624 int PFBlockAlgo::niAssocToTrack( const reco::TrackRef& primTkRef,
01625 const edm::Handle<reco::PFNuclearInteractionCollection>& nuclh) const {
01626 if( nuclh.isValid() ) {
01627
01628 for( unsigned int k=0; k<nuclh->size(); ++k) {
01629 const edm::RefToBase< reco::Track >& trk = nuclh->at(k).primaryTrack();
01630 if( trk.castTo<reco::TrackRef>() == primTkRef) return k;
01631 }
01632 return -1;
01633 }
01634 else return -1;
01635 }
01636
01637
01638 int PFBlockAlgo::niAssocToTrack( const reco::TrackRef& primTkRef,
01639 const edm::OrphanHandle<reco::PFNuclearInteractionCollection>& nuclh) const {
01640 if( nuclh.isValid() ) {
01641
01642 for( unsigned int k=0; k<nuclh->size(); ++k) {
01643 const edm::RefToBase< reco::Track >& trk = nuclh->at(k).primaryTrack();
01644 if( trk.castTo<reco::TrackRef>() == primTkRef) return k;
01645 }
01646 return -1;
01647 }
01648 else return -1;
01649 }
01650
01651 int PFBlockAlgo::muAssocToTrack( const reco::TrackRef& trackref,
01652 const edm::Handle<reco::MuonCollection>& muonh) const {
01653 if(muonh.isValid() ) {
01654 for(unsigned j=0;j<muonh->size(); j++) {
01655 reco::MuonRef muonref( muonh, j );
01656 if (muonref->track().isNonnull())
01657 if( muonref->track() == trackref ) return j;
01658 }
01659 }
01660 return -1;
01661 }
01662
01663 int PFBlockAlgo::v0AssocToTrack( const reco::TrackRef& primTkRef,
01664 const edm::Handle<reco::PFV0Collection>& v0) const {
01665 if( v0.isValid() ) {
01666
01667 for( unsigned int k=0; k<v0->size(); ++k) {
01668 for (uint itk=0;itk<(*v0)[k].Tracks().size();itk++){
01669 if( (*v0)[k].Tracks()[itk] == primTkRef) return k;
01670 }
01671 }
01672 return -1;
01673 }
01674 else return -1;
01675 }
01676
01677
01678 int PFBlockAlgo::v0AssocToTrack( const reco::TrackRef& primTkRef,
01679 const edm::OrphanHandle<reco::PFV0Collection>& v0) const {
01680 if( v0.isValid() ) {
01681
01682 for( unsigned int k=0; k<v0->size(); ++k) {
01683 for (uint itk=0;itk<(*v0)[k].Tracks().size();itk++){
01684 if( (*v0)[k].Tracks()[itk] == primTkRef) return k;
01685 }
01686
01687 }
01688 return -1;
01689 }
01690 else return -1;
01691 }
01692
01693
01694 int PFBlockAlgo::muAssocToTrack( const reco::TrackRef& trackref,
01695 const edm::OrphanHandle<reco::MuonCollection>& muonh) const {
01696 if(muonh.isValid() ) {
01697 for(unsigned j=0;j<muonh->size(); j++) {
01698 reco::MuonRef muonref( muonh, j );
01699 if (muonref->track().isNonnull())
01700 if( muonref->track() == trackref ) return j;
01701 }
01702 }
01703 return -1;
01704 }
01705
01706
01707 void PFBlockAlgo::checkNuclearLinks( reco::PFBlock& block ) const {
01708
01709
01710
01711
01712 typedef std::multimap<double, unsigned>::iterator IE;
01713
01714 const edm::OwnVector< reco::PFBlockElement >& els = block.elements();
01715
01716 for( unsigned i1=0; i1 != els.size(); ++i1 ) {
01717 if( els[i1].type() == PFBlockElement::TRACK ) continue;
01718 std::multimap<double, unsigned> assocTracks;
01719
01720 block.associatedElements( i1, block.linkData(),
01721 assocTracks,
01722 reco::PFBlockElement::TRACK,
01723 reco::PFBlock::LINKTEST_ALL );
01724 for( IE ie = assocTracks.begin(); ie != assocTracks.end(); ++ie) {
01725 double chi2prim = ie->first;
01726 unsigned iprim = ie->second;
01727
01728 if( els[iprim].trackType(PFBlockElement::T_TO_NUCL) ) {
01729 std::multimap<double, unsigned> secTracks;
01730
01731 block.associatedElements( iprim, block.linkData(),
01732 secTracks,
01733 reco::PFBlockElement::TRACK,
01734 reco::PFBlock::LINKTEST_ALL );
01735 for( IE ie2 = secTracks.begin(); ie2 != secTracks.end(); ++ie2) {
01736 unsigned isec = ie2->second;
01737 double chi2sec_rechit = block.chi2( i1, isec, block.linkData(),
01738 PFBlock::LINKTEST_RECHIT );
01739 double chi2sec_chi2 = block.chi2( i1, isec, block.linkData(),
01740 PFBlock::LINKTEST_CHI2 );
01741 double chi2sec;
01742
01743
01744
01745 if( chi2sec_chi2 > 0) chi2sec = chi2sec_chi2;
01746 else chi2sec=chi2sec_rechit;
01747
01748
01749
01750 if( chi2sec < 0 ) continue;
01751 else if( chi2sec < chi2prim ) {
01752 block.setLink( i1, iprim, -1, -1, block.linkData(),
01753 PFBlock::LINKTEST_CHI2 );
01754 block.setLink( i1, iprim, -1, -1, block.linkData(),
01755 PFBlock::LINKTEST_RECHIT );
01756 continue;
01757 }
01758 }
01759 }
01760
01761 }
01762 }
01763 }
01764
01765