00001 #include "RecoParticleFlow/PFProducer/interface/PFBlockAlgo.h"
00002 #include "RecoParticleFlow/PFProducer/interface/Utils.h"
00003 #include "RecoParticleFlow/PFClusterTools/interface/LinkByRecHit.h"
00004 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
00005 #include "DataFormats/TrackReco/interface/Track.h"
00006 #include "DataFormats/ParticleFlowReco/interface/PFDisplacedVertex.h"
00007
00008 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00009
00010 #include <stdexcept>
00011 #include "TMath.h"
00012
00013 using namespace std;
00014 using namespace reco;
00015
00016
00017
00018
00019 const PFBlockAlgo::Mask PFBlockAlgo::dummyMask_;
00020
00021 PFBlockAlgo::PFBlockAlgo() :
00022 blocks_( new reco::PFBlockCollection ),
00023 DPtovPtCut_(std::vector<double>(4,static_cast<double>(999.))),
00024 NHitCut_(std::vector<unsigned int>(4,static_cast<unsigned>(0))),
00025 useIterTracking_(true),
00026 debug_(false) {}
00027
00028
00029
00030 void PFBlockAlgo::setParameters( std::vector<double>& DPtovPtCut,
00031 std::vector<unsigned int>& NHitCut,
00032 bool useConvBremPFRecTracks,
00033 bool useIterTracking,
00034 int nuclearInteractionsPurity) {
00035
00036 DPtovPtCut_ = DPtovPtCut;
00037 NHitCut_ = NHitCut;
00038 useIterTracking_ = useIterTracking;
00039 useConvBremPFRecTracks_ = useConvBremPFRecTracks;
00040 nuclearInteractionsPurity_ = nuclearInteractionsPurity;
00041 }
00042
00043 PFBlockAlgo::~PFBlockAlgo() {
00044
00045 #ifdef PFLOW_DEBUG
00046 if(debug_)
00047 cout<<"~PFBlockAlgo - number of remaining elements: "
00048 <<elements_.size()<<endl;
00049 #endif
00050
00051 }
00052
00053 void
00054 PFBlockAlgo::findBlocks() {
00055
00056
00057
00058
00059 if(blocks_.get() )blocks_->clear();
00060 else
00061 blocks_.reset( new reco::PFBlockCollection );
00062
00063 blocks_->reserve(elements_.size());
00064 for(IE ie = elements_.begin();
00065 ie != elements_.end();) {
00066
00067 #ifdef PFLOW_DEBUG
00068 if(debug_) {
00069 cout<<" PFBlockAlgo::findBlocks() ----------------------"<<endl;
00070 cout<<" element "<<**ie<<endl;
00071 cout<<" creating new block"<<endl;
00072 }
00073 #endif
00074
00075 blocks_->push_back( PFBlock() );
00076
00077 vector< PFBlockLink > links;
00078
00079
00080 ie = associate( elements_.end() , ie, links );
00081
00082
00083 packLinks( blocks_->back(), links );
00084 }
00085 }
00086
00087
00088
00089
00090 PFBlockAlgo::IE
00091 PFBlockAlgo::associate( IE last,
00092 IE next,
00093 vector<PFBlockLink>& links ) {
00094
00095
00096 #ifdef PFLOW_DEBUG
00097 if(debug_ ) cout<<"PFBlockAlgo::associate start ----"<<endl;
00098 #endif
00099
00100 if( last!= elements_.end() ) {
00101 PFBlockLink::Type linktype = PFBlockLink::NONE;
00102 double dist = -1;
00103 PFBlock::LinkTest linktest = PFBlock::LINKTEST_RECHIT;
00104 link( *last, *next, linktype, linktest, dist );
00105
00106
00107 if(dist<-0.5) {
00108 #ifdef PFLOW_DEBUG
00109 if(debug_ ) cout<<"link failed"<<endl;
00110 #endif
00111 return ++next;
00112 }
00113 else {
00114
00115 blocks_->back().addElement( *next );
00116
00117
00118
00119
00120
00121
00122
00123 links.push_back( PFBlockLink(linktype,
00124 linktest,
00125 dist,
00126 (*last)->index(),
00127 (*next)->index() ) );
00128
00129
00130
00131 }
00132 }
00133 else {
00134
00135 #ifdef PFLOW_DEBUG
00136 if(debug_ ) cout<<"adding to block element "<<(**next)<<endl;
00137 #endif
00138 blocks_->back().addElement( *next );
00139
00140
00141 }
00142
00143
00144
00145
00146
00147
00148
00149 for(IE ie = elements_.begin();
00150 ie != elements_.end();) {
00151
00152 if( ie == last || ie == next ) {
00153 ++ie;
00154 continue;
00155 }
00156
00157
00158 if( (*ie)->locked() ) {
00159 #ifdef PFLOW_DEBUG
00160 if(debug_ ) cout<<"element "<<(**ie)<<"already used"<<endl;
00161 #endif
00162 ++ie;
00163 continue;
00164 }
00165
00166
00167 #ifdef PFLOW_DEBUG
00168 if(debug_ ) cout<<"calling associate "<<(**next)<<" & "<<(**ie)<<endl;
00169 #endif
00170 ie = associate(next, ie, links);
00171 }
00172
00173 #ifdef PFLOW_DEBUG
00174 if(debug_ ) {
00175 cout<<"**** deleting element "<<endl;
00176 cout<<**next<<endl;
00177 }
00178 #endif
00179 delete *next;
00180
00181 #ifdef PFLOW_DEBUG
00182 if(debug_ ) {
00183 cout<<"**** removing element "<<endl;
00184 }
00185 #endif
00186
00187 IE iteratorToNextFreeElement = elements_.erase( next );
00188
00189 #ifdef PFLOW_DEBUG
00190 if(debug_ ) cout<<"PFBlockAlgo::associate stop ----"<<endl;
00191 #endif
00192
00193 return iteratorToNextFreeElement;
00194 }
00195
00196
00197
00198 void
00199 PFBlockAlgo::packLinks( reco::PFBlock& block,
00200 const vector<PFBlockLink>& links ) const {
00201
00202
00203 const edm::OwnVector< reco::PFBlockElement >& els = block.elements();
00204
00205 block.bookLinkData();
00206
00207
00208 for( unsigned i1=0; i1<els.size(); i1++ ) {
00209 for( unsigned i2=0; i2<els.size(); i2++ ) {
00210
00211
00212 if( i1==i2 ) continue;
00213
00214 double dist = -1;
00215
00216 bool linked = false;
00217 PFBlock::LinkTest linktest
00218 = PFBlock::LINKTEST_RECHIT;
00219
00220
00221
00222
00223 for( unsigned il=0; il<links.size(); il++ ) {
00224 if( (links[il].element1() == i1 &&
00225 links[il].element2() == i2) ||
00226 (links[il].element1() == i2 &&
00227 links[il].element2() == i1) ) {
00228
00229 dist = links[il].dist();
00230 linked = true;
00231
00232
00233
00234 linktest = links[il].test();
00235 #ifdef PFLOW_DEBUG
00236 if( debug_ )
00237 cout << "Reading link vector: linktest used="
00238 << linktest
00239 << " distance = " << dist
00240 << endl;
00241 #endif
00242
00243
00244 break;
00245 }
00246 }
00247
00248 if(!linked) {
00249 PFBlockLink::Type linktype = PFBlockLink::NONE;
00250 link( & els[i1], & els[i2], linktype, linktest, dist);
00251 }
00252
00253
00254
00255 #ifdef PFLOW_DEBUG
00256 if( debug_ )
00257 cout << "Setting link between elements " << i1 << " and " << i2
00258 << " of dist =" << dist << " computed from link test "
00259 << linktest << endl;
00260 #endif
00261 block.setLink( i1, i2, dist, block.linkData(), linktest );
00262 }
00263 }
00264
00265
00266
00267 }
00268
00269
00270
00271 void
00272 PFBlockAlgo::buildGraph() {
00273
00274 }
00275
00276
00277
00278 void
00279 PFBlockAlgo::link( const reco::PFBlockElement* el1,
00280 const reco::PFBlockElement* el2,
00281 PFBlockLink::Type& linktype,
00282 reco::PFBlock::LinkTest& linktest,
00283 double& dist) const {
00284
00285
00286
00287 dist=-1.;
00288 linktest = PFBlock::LINKTEST_RECHIT;
00289
00290 PFBlockElement::Type type1 = el1->type();
00291 PFBlockElement::Type type2 = el2->type();
00292
00293 if( type1==type2 ) {
00294
00295
00296 if( type1!=PFBlockElement::TRACK && type1!=PFBlockElement::GSF &&
00297 type1!=PFBlockElement::ECAL) {
00298 return;
00299 }
00300
00301
00302 if( type1 ==PFBlockElement::TRACK) {
00303 if ( !el1->isLinkedToDisplacedVertex() || !el2->isLinkedToDisplacedVertex())
00304 return;
00305 }
00306 }
00307
00308 linktype = static_cast<PFBlockLink::Type>
00309 ((1<< (type1-1) ) | (1<< (type2-1) ));
00310
00311 if(debug_ ) std::cout << " PFBlockAlgo links type1 " << type1 << " type2 " << type2 << std::endl;
00312
00313 PFBlockElement::Type lowType = type1;
00314 PFBlockElement::Type highType = type2;
00315 const PFBlockElement* lowEl = el1;
00316 const PFBlockElement* highEl = el2;
00317
00318 if(type1>type2) {
00319 lowType = type2;
00320 highType = type1;
00321 lowEl = el2;
00322 highEl = el1;
00323 }
00324
00325 switch(linktype) {
00326 case PFBlockLink::TRACKandPS1:
00327 case PFBlockLink::TRACKandPS2:
00328 {
00329
00330 PFRecTrackRef trackref = lowEl->trackRefPF();
00331 PFClusterRef clusterref = highEl->clusterRef();
00332 assert( !trackref.isNull() );
00333 assert( !clusterref.isNull() );
00334
00335 dist = testTrackAndPS( *trackref, *clusterref );
00336 linktest = PFBlock::LINKTEST_RECHIT;
00337 break;
00338 }
00339
00340 case PFBlockLink::TRACKandECAL:
00341 {
00342 if(debug_ ) cout<<"TRACKandECAL"<<endl;
00343 PFRecTrackRef trackref = lowEl->trackRefPF();
00344
00345 if(debug_ ) std::cout << " Track pt " << trackref->trackRef()->pt() << std::endl;
00346
00347 PFClusterRef clusterref = highEl->clusterRef();
00348 assert( !trackref.isNull() );
00349 assert( !clusterref.isNull() );
00350 dist = LinkByRecHit::testTrackAndClusterByRecHit( *trackref, *clusterref, false, debug_ );
00351 linktest = PFBlock::LINKTEST_RECHIT;
00352
00353 if ( debug_ ) {
00354 if( dist > 0. ) {
00355 std::cout << " Here a link has been established"
00356 << " between a track an Ecal with dist "
00357 << dist << std::endl;
00358 } else {
00359 std::cout << " No link found " << std::endl;
00360 }
00361 }
00362
00363 break;
00364 }
00365 case PFBlockLink::TRACKandHCAL:
00366 {
00367
00368 PFRecTrackRef trackref = lowEl->trackRefPF();
00369 PFClusterRef clusterref = highEl->clusterRef();
00370 assert( !trackref.isNull() );
00371 assert( !clusterref.isNull() );
00372 dist = LinkByRecHit::testTrackAndClusterByRecHit( *trackref, *clusterref, false, debug_ );
00373 linktest = PFBlock::LINKTEST_RECHIT;
00374 break;
00375 }
00376 case PFBlockLink::ECALandHCAL:
00377 {
00378
00379 PFClusterRef ecalref = lowEl->clusterRef();
00380 PFClusterRef hcalref = highEl->clusterRef();
00381 assert( !ecalref.isNull() );
00382 assert( !hcalref.isNull() );
00383
00384
00385 dist = -1.;
00386 linktest = PFBlock::LINKTEST_RECHIT;
00387 break;
00388 }
00389 case PFBlockLink::PS1andECAL:
00390 case PFBlockLink::PS2andECAL:
00391 {
00392
00393 PFClusterRef psref = lowEl->clusterRef();
00394 PFClusterRef ecalref = highEl->clusterRef();
00395 assert( !psref.isNull() );
00396 assert( !ecalref.isNull() );
00397 dist = LinkByRecHit::testECALAndPSByRecHit( *ecalref, *psref ,debug_);
00398 linktest = PFBlock::LINKTEST_RECHIT;
00399 break;
00400 }
00401 case PFBlockLink::PS1andPS2:
00402 {
00403 PFClusterRef ps1ref = lowEl->clusterRef();
00404 PFClusterRef ps2ref = highEl->clusterRef();
00405 assert( !ps1ref.isNull() );
00406 assert( !ps2ref.isNull() );
00407
00408
00409 dist = -1.;
00410 linktest = PFBlock::LINKTEST_RECHIT;
00411 break;
00412 }
00413 case PFBlockLink::TRACKandTRACK:
00414 {
00415 if(debug_ )
00416 cout<<"TRACKandTRACK"<<endl;
00417 dist = testLinkByVertex(lowEl, highEl);
00418 if(debug_ )
00419 std::cout << " PFBlockLink::TRACKandTRACK dist " << dist << std::endl;
00420 linktest = PFBlock::LINKTEST_RECHIT;
00421 break;
00422 }
00423
00424 case PFBlockLink::ECALandECAL:
00425 {
00426
00427 PFClusterRef ecal1ref = lowEl->clusterRef();
00428 PFClusterRef ecal2ref = highEl->clusterRef();
00429 assert( !ecal1ref.isNull() );
00430 assert( !ecal2ref.isNull() );
00431 if(debug_)
00432 cout << " PFBlockLink::ECALandECAL" << endl;
00433 dist = testLinkBySuperCluster(ecal1ref,ecal2ref);
00434 break;
00435 }
00436
00437 case PFBlockLink::ECALandGSF:
00438 {
00439 PFClusterRef clusterref = lowEl->clusterRef();
00440 assert( !clusterref.isNull() );
00441 const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
00442 const PFRecTrack * myTrack = &(GsfEl->GsftrackPF());
00443 dist = LinkByRecHit::testTrackAndClusterByRecHit( *myTrack, *clusterref, false, debug_ );
00444 linktest = PFBlock::LINKTEST_RECHIT;
00445
00446 if ( debug_ ) {
00447 if ( dist > 0. ) {
00448 std::cout << " Here a link has been established"
00449 << " between a GSF track an Ecal with dist "
00450 << dist << std::endl;
00451 } else {
00452 if(debug_ ) std::cout << " No link found " << std::endl;
00453 }
00454 }
00455 break;
00456 }
00457 case PFBlockLink::TRACKandGSF:
00458 {
00459 PFRecTrackRef trackref = lowEl->trackRefPF();
00460 assert( !trackref.isNull() );
00461 const reco::PFBlockElementGsfTrack * GsfEl =
00462 dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
00463 GsfPFRecTrackRef gsfref = GsfEl->GsftrackRefPF();
00464 reco::TrackRef kftrackref= (*trackref).trackRef();
00465 assert( !gsfref.isNull() );
00466 PFRecTrackRef refkf = (*gsfref).kfPFRecTrackRef();
00467 if(refkf.isNonnull()) {
00468 reco::TrackRef gsftrackref = (*refkf).trackRef();
00469 if (gsftrackref.isNonnull()&&kftrackref.isNonnull()) {
00470 if (kftrackref == gsftrackref) {
00471 dist = 0.001;
00472 } else {
00473 dist = -1.;
00474 }
00475 } else {
00476 dist = -1.;
00477 }
00478 } else {
00479 dist = -1.;
00480 }
00481
00482
00483 if(useConvBremPFRecTracks_) {
00484 if(lowEl->isLinkedToDisplacedVertex()){
00485 vector<PFRecTrackRef> pfrectrack_vec = GsfEl->GsftrackRefPF()->convBremPFRecTrackRef();
00486 if(pfrectrack_vec.size() > 0){
00487 for(unsigned int iconv = 0; iconv < pfrectrack_vec.size(); iconv++) {
00488 if( lowEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)) {
00489
00490 if(kftrackref == (*pfrectrack_vec[iconv]).trackRef()) {
00491 dist = 0.001;
00492 }
00493 }
00494 else{
00495
00496 reco::TrackBaseRef newTrackBaseRef((*pfrectrack_vec[iconv]).trackRef());
00497 reco::TrackBaseRef elemTrackBaseRef(kftrackref);
00498 if(newTrackBaseRef == elemTrackBaseRef){
00499 dist = 0.001;
00500 }
00501 }
00502 }
00503 }
00504 }
00505 }
00506
00507
00508 break;
00509 }
00510
00511 case PFBlockLink::GSFandBREM:
00512 {
00513 const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(lowEl);
00514 const reco::PFBlockElementBrem * BremEl = dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
00515 GsfPFRecTrackRef gsfref = GsfEl->GsftrackRefPF();
00516 GsfPFRecTrackRef bremref = BremEl->GsftrackRefPF();
00517 assert( !gsfref.isNull() );
00518 assert( !bremref.isNull() );
00519 if (gsfref == bremref) {
00520 dist = 0.001;
00521 } else {
00522 dist = -1.;
00523 }
00524 break;
00525 }
00526 case PFBlockLink::GSFandGSF:
00527 {
00528 const reco::PFBlockElementGsfTrack * lowGsfEl =
00529 dynamic_cast<const reco::PFBlockElementGsfTrack*>(lowEl);
00530 const reco::PFBlockElementGsfTrack * highGsfEl =
00531 dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
00532
00533 GsfPFRecTrackRef lowgsfref = lowGsfEl->GsftrackRefPF();
00534 GsfPFRecTrackRef highgsfref = highGsfEl->GsftrackRefPF();
00535 assert( !lowgsfref.isNull() );
00536 assert( !highgsfref.isNull() );
00537
00538 if( (lowGsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false &&
00539 highGsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)) ||
00540 (highGsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false &&
00541 lowGsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV))) {
00542 if(lowgsfref->trackId() == highgsfref->trackId()) {
00543 dist = 0.001;
00544 }
00545 else {
00546 dist = -1.;
00547 }
00548 }
00549 break;
00550 }
00551 case PFBlockLink::ECALandBREM:
00552 {
00553 PFClusterRef clusterref = lowEl->clusterRef();
00554 assert( !clusterref.isNull() );
00555 const reco::PFBlockElementBrem * BremEl =
00556 dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
00557 const PFRecTrack * myTrack = &(BremEl->trackPF());
00558
00559
00560
00561
00562
00563 bool isBrem = true;
00564 dist = LinkByRecHit::testTrackAndClusterByRecHit( *myTrack, *clusterref, isBrem, debug_);
00565 if( debug_ && dist > 0. )
00566 std::cout << "ECALandBREM: dist testTrackAndClusterByRecHit "
00567 << dist << std::endl;
00568 linktest = PFBlock::LINKTEST_RECHIT;
00569 break;
00570 }
00571 case PFBlockLink::PS1andGSF:
00572 case PFBlockLink::PS2andGSF:
00573 {
00574 PFClusterRef psref = lowEl->clusterRef();
00575 assert( !psref.isNull() );
00576 const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
00577 const PFRecTrack * myTrack = &(GsfEl->GsftrackPF());
00578
00579 dist = testTrackAndPS( *myTrack, *psref );
00580 linktest = PFBlock::LINKTEST_RECHIT;
00581 break;
00582 }
00583 case PFBlockLink::PS1andBREM:
00584 case PFBlockLink::PS2andBREM:
00585 {
00586 PFClusterRef psref = lowEl->clusterRef();
00587 assert( !psref.isNull() );
00588 const reco::PFBlockElementBrem * BremEl = dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
00589 const PFRecTrack * myTrack = &(BremEl->trackPF());
00590
00591 dist = testTrackAndPS( *myTrack, *psref );
00592 linktest = PFBlock::LINKTEST_RECHIT;
00593 break;
00594 }
00595 case PFBlockLink::HCALandGSF:
00596 {
00597 PFClusterRef clusterref = lowEl->clusterRef();
00598 assert( !clusterref.isNull() );
00599 const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
00600 const PFRecTrack * myTrack = &(GsfEl->GsftrackPF());
00601 dist = LinkByRecHit::testTrackAndClusterByRecHit( *myTrack, *clusterref, false, debug_ );
00602 linktest = PFBlock::LINKTEST_RECHIT;
00603 break;
00604 }
00605 case PFBlockLink::HCALandBREM:
00606 {
00607 PFClusterRef clusterref = lowEl->clusterRef();
00608 assert( !clusterref.isNull() );
00609 const reco::PFBlockElementBrem * BremEl = dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
00610 const PFRecTrack * myTrack = &(BremEl->trackPF());
00611 bool isBrem = true;
00612 dist = LinkByRecHit::testTrackAndClusterByRecHit( *myTrack, *clusterref, isBrem, debug_);
00613 break;
00614 }
00615 case PFBlockLink::HFEMandHFHAD:
00616 {
00617
00618 PFClusterRef eref = lowEl->clusterRef();
00619 PFClusterRef href = highEl->clusterRef();
00620 assert( !eref.isNull() );
00621 assert( !href.isNull() );
00622 dist = LinkByRecHit::testHFEMAndHFHADByRecHit( *eref, *href, debug_ );
00623 linktest = PFBlock::LINKTEST_RECHIT;
00624 break;
00625
00626 break;
00627 }
00628 default:
00629 dist = -1.;
00630 linktest = PFBlock::LINKTEST_RECHIT;
00631
00632
00633 return;
00634 }
00635 }
00636
00637 double
00638 PFBlockAlgo::testTrackAndPS(const PFRecTrack& track,
00639 const PFCluster& ps) const {
00640
00641 #ifdef PFLOW_DEBUG
00642
00643
00644 double dx=0.;
00645 double dy=0.;
00646
00647 unsigned layerid =0;
00648
00649 switch (ps.layer()) {
00650 case PFLayer::PS1:
00651 layerid = reco::PFTrajectoryPoint::PS1;
00652
00653
00654 dx = resPSpitch_;
00655 dy = resPSlength_;
00656 break;
00657 case PFLayer::PS2:
00658 layerid = reco::PFTrajectoryPoint::PS2;
00659
00660 dy = resPSpitch_;
00661 dx = resPSlength_;
00662 break;
00663 default:
00664 break;
00665 }
00666 const reco::PFTrajectoryPoint& atPS
00667 = track.extrapolatedPoint( layerid );
00668
00669 if( ! atPS.isValid() ) return -1.;
00670
00671 double trackx = atPS.position().X();
00672 double tracky = atPS.position().Y();
00673 double trackz = atPS.position().Z();
00674
00675
00676 double psx = ps.position().X();
00677 double psy = ps.position().Y();
00678
00679 double psz = ps.position().Z();
00680 if( trackz*psz < 0.) return -1.;
00681
00682
00683
00684
00685 double dist = std::sqrt( (psx-trackx)*(psx-trackx)
00686 + (psy-tracky)*(psy-tracky));
00687 if(debug_) cout<<"testTrackAndPS "<< dist <<" "<<endl;
00688 if(debug_){
00689 cout<<" trackx " << trackx
00690 <<" tracky " << tracky
00691 <<" psx " << psx
00692 <<" psy " << psy
00693 << endl;
00694 }
00695 #endif
00696
00697
00698 return -1.;
00699 }
00700
00701 double
00702 PFBlockAlgo::testECALAndHCAL(const PFCluster& ecal,
00703 const PFCluster& hcal) const {
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715 #ifdef PFLOW_DEBUG
00716 if(debug_) cout<<"testECALAndHCAL "<< dist <<" "<<endl;
00717 if(debug_){
00718 cout<<" ecaleta " << ecal.positionREP().Eta()
00719 <<" ecalphi " << ecal.positionREP().Phi()
00720 <<" hcaleta " << hcal.positionREP().Eta()
00721 <<" hcalphi " << hcal.positionREP().Phi()
00722 }
00723 #endif
00724
00725
00726 return -1.;
00727 }
00728
00729 double
00730 PFBlockAlgo::testLinkBySuperCluster(const PFClusterRef& ecal1,
00731 const PFClusterRef& ecal2) const {
00732
00733
00734
00735 double dist = -1;
00736
00737
00738 int testindex=pfcSCVec_[ecal1.key()];
00739 if(testindex == -1.) return dist;
00740
00741
00742
00743 const std::vector<reco::PFClusterRef> & thePFClusters(scpfcRefs_[testindex]);
00744
00745 unsigned npf=thePFClusters.size();
00746 for(unsigned i=0;i<npf;++i)
00747 {
00748 if(thePFClusters[i]==ecal2)
00749 {
00750 dist=LinkByRecHit::computeDist( ecal1->positionREP().Eta(),
00751 ecal1->positionREP().Phi(),
00752 ecal2->positionREP().Eta(),
00753 ecal2->positionREP().Phi() );
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 return dist;
00764 }
00765 }
00766 return dist;
00767 }
00768
00769
00770
00771 double
00772 PFBlockAlgo::testPS1AndPS2(const PFCluster& ps1,
00773 const PFCluster& ps2) const {
00774
00775 #ifdef PFLOW_DEBUG
00776
00777
00778
00779
00780
00781
00782 double x1 = ps1.position().X();
00783 double y1 = ps1.position().Y();
00784 double z1 = ps1.position().Z();
00785 double x2 = ps2.position().X();
00786 double y2 = ps2.position().Y();
00787 double z2 = ps2.position().Z();
00788
00789 if (z1*z2<0.) -1.;
00790
00791 double scale = z2/z1;
00792 double x1atPS2 = x1*scale;
00793 double y1atPS2 = y1*scale;
00794
00795
00796 double dx1dx1 = resPSpitch_*resPSpitch_*scale*scale;
00797 double dy1dy1 = resPSlength_*resPSlength_*scale*scale;
00798
00799 double dy2dy2 = resPSpitch_*resPSpitch_;
00800 double dx2dx2 = resPSlength_*resPSlength_;
00801
00802
00803
00804
00805 double dist = std::sqrt( (x2-x1atPS2)*(x2-x1atPS2)
00806 + (y2-y1atPS2)*(y2-y1atPS2));
00807
00808 if(debug_) cout<<"testPS1AndPS2 "<<dist<<" "<<endl;
00809 if(debug_){
00810 cout<<" x1atPS2 "<< x1atPS2 << " dx1 "<<resPSpitch_*scale
00811 <<" y1atPS2 "<< y1atPS2 << " dy1 "<<resPSlength_*scale<< endl
00812 <<" x2 " <<x2 << " dx2 "<<resPSlength_
00813 <<" y2 " << y2 << " dy2 "<<resPSpitch_<< endl;
00814 }
00815 #endif
00816
00817
00818 return -1.;
00819 }
00820
00821
00822
00823 double
00824 PFBlockAlgo::testLinkByVertex( const reco::PFBlockElement* elt1,
00825 const reco::PFBlockElement* elt2) const {
00826
00827
00828
00829 double result=-1.;
00830
00831 reco::PFBlockElement::TrackType T_TO_DISP = reco::PFBlockElement::T_TO_DISP;
00832 reco::PFBlockElement::TrackType T_FROM_DISP = reco::PFBlockElement::T_FROM_DISP;
00833 PFDisplacedTrackerVertexRef ni1_TO_DISP = elt1->displacedVertexRef(T_TO_DISP);
00834 PFDisplacedTrackerVertexRef ni2_TO_DISP = elt2->displacedVertexRef(T_TO_DISP);
00835 PFDisplacedTrackerVertexRef ni1_FROM_DISP = elt1->displacedVertexRef(T_FROM_DISP);
00836 PFDisplacedTrackerVertexRef ni2_FROM_DISP = elt2->displacedVertexRef(T_FROM_DISP);
00837
00838 if( ni1_TO_DISP.isNonnull() && ni2_FROM_DISP.isNonnull())
00839 if( ni1_TO_DISP == ni2_FROM_DISP ) { result = 1.0; return result; }
00840
00841 if( ni1_FROM_DISP.isNonnull() && ni2_TO_DISP.isNonnull())
00842 if( ni1_FROM_DISP == ni2_TO_DISP ) { result = 1.0; return result; }
00843
00844 if( ni1_FROM_DISP.isNonnull() && ni2_FROM_DISP.isNonnull())
00845 if( ni1_FROM_DISP == ni2_FROM_DISP ) { result = 1.0; return result; }
00846
00847
00848 if ( elt1->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) &&
00849 elt2->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) ) {
00850
00851 if(debug_ ) std::cout << " testLinkByVertex On Conversions " << std::endl;
00852
00853 if ( elt1->convRef().isNonnull() && elt2->convRef().isNonnull() ) {
00854 if(debug_ ) std::cout << " PFBlockAlgo.cc testLinkByVertex Cconversion Refs are non null " << std::endl;
00855 if ( elt1->convRef() == elt2->convRef() ) {
00856 result=1.0;
00857 if(debug_ ) std::cout << " testLinkByVertex Cconversion Refs are equal " << std::endl;
00858 return result;
00859 }
00860 }
00861
00862 }
00863
00864 if ( elt1->trackType(reco::PFBlockElement::T_FROM_V0) &&
00865 elt2->trackType(reco::PFBlockElement::T_FROM_V0) ) {
00866 if(debug_ ) std::cout << " testLinkByVertex On V0 " << std::endl;
00867 if ( elt1->V0Ref().isNonnull() && elt2->V0Ref().isNonnull() ) {
00868 if(debug_ ) std::cout << " PFBlockAlgo.cc testLinkByVertex V0 Refs are non null " << std::endl;
00869 if ( elt1->V0Ref() == elt2->V0Ref() ) {
00870 result=1.0;
00871 if(debug_ ) std::cout << " testLinkByVertex V0 Refs are equal " << std::endl;
00872 return result;
00873 }
00874 }
00875 }
00876
00877 return result;
00878 }
00879
00880
00881
00882 void
00883 PFBlockAlgo::checkMaskSize( const reco::PFRecTrackCollection& tracks,
00884 const reco::GsfPFRecTrackCollection& gsftracks,
00885 const reco::PFClusterCollection& ecals,
00886 const reco::PFClusterCollection& hcals,
00887 const reco::PFClusterCollection& hfems,
00888 const reco::PFClusterCollection& hfhads,
00889 const reco::PFClusterCollection& pss,
00890 const Mask& trackMask,
00891 const Mask& gsftrackMask,
00892 const Mask& ecalMask,
00893 const Mask& hcalMask,
00894 const Mask& hfemMask,
00895 const Mask& hfhadMask,
00896 const Mask& psMask ) const {
00897
00898 if( !trackMask.empty() &&
00899 trackMask.size() != tracks.size() ) {
00900 string err = "PFBlockAlgo::setInput: ";
00901 err += "The size of the track mask is different ";
00902 err += "from the size of the track vector.";
00903 throw std::length_error( err.c_str() );
00904 }
00905
00906 if( !gsftrackMask.empty() &&
00907 gsftrackMask.size() != gsftracks.size() ) {
00908 string err = "PFBlockAlgo::setInput: ";
00909 err += "The size of the gsf track mask is different ";
00910 err += "from the size of the gsftrack vector.";
00911 throw std::length_error( err.c_str() );
00912 }
00913
00914 if( !ecalMask.empty() &&
00915 ecalMask.size() != ecals.size() ) {
00916 string err = "PFBlockAlgo::setInput: ";
00917 err += "The size of the ecal mask is different ";
00918 err += "from the size of the ecal clusters vector.";
00919 throw std::length_error( err.c_str() );
00920 }
00921
00922 if( !hcalMask.empty() &&
00923 hcalMask.size() != hcals.size() ) {
00924 string err = "PFBlockAlgo::setInput: ";
00925 err += "The size of the hcal mask is different ";
00926 err += "from the size of the hcal clusters vector.";
00927 throw std::length_error( err.c_str() );
00928 }
00929
00930 if( !hfemMask.empty() &&
00931 hfemMask.size() != hfems.size() ) {
00932 string err = "PFBlockAlgo::setInput: ";
00933 err += "The size of the hfem mask is different ";
00934 err += "from the size of the hfem clusters vector.";
00935 throw std::length_error( err.c_str() );
00936 }
00937
00938 if( !hfhadMask.empty() &&
00939 hfhadMask.size() != hfhads.size() ) {
00940 string err = "PFBlockAlgo::setInput: ";
00941 err += "The size of the hfhad mask is different ";
00942 err += "from the size of the hfhad clusters vector.";
00943 throw std::length_error( err.c_str() );
00944 }
00945
00946 if( !psMask.empty() &&
00947 psMask.size() != pss.size() ) {
00948 string err = "PFBlockAlgo::setInput: ";
00949 err += "The size of the ps mask is different ";
00950 err += "from the size of the ps clusters vector.";
00951 throw std::length_error( err.c_str() );
00952 }
00953
00954 }
00955
00956
00957 std::ostream& operator<<(std::ostream& out, const PFBlockAlgo& a) {
00958 if(! out) return out;
00959
00960 out<<"====== Particle Flow Block Algorithm ======= ";
00961 out<<endl;
00962 out<<"number of unassociated elements : "<<a.elements_.size()<<endl;
00963 out<<endl;
00964
00965 for(PFBlockAlgo::IEC ie = a.elements_.begin();
00966 ie != a.elements_.end(); ie++) {
00967 out<<"\t"<<**ie <<endl;
00968 }
00969
00970
00971
00972
00973 const std::auto_ptr< reco::PFBlockCollection >& blocks
00974 = a.blocks();
00975
00976 if(!blocks.get() ) {
00977 out<<"blocks already transfered"<<endl;
00978 }
00979 else {
00980 out<<"number of blocks : "<<blocks->size()<<endl;
00981 out<<endl;
00982
00983 for(PFBlockAlgo::IBC ib=blocks->begin();
00984 ib != blocks->end(); ib++) {
00985 out<<(*ib)<<endl;
00986 }
00987 }
00988
00989 return out;
00990 }
00991
00992 bool
00993 PFBlockAlgo::goodPtResolution( const reco::TrackRef& trackref) {
00994
00995 double P = trackref->p();
00996 double Pt = trackref->pt();
00997 double DPt = trackref->ptError();
00998 unsigned int NHit = trackref->hitPattern().trackerLayersWithMeasurement();
00999 unsigned int NLostHit = trackref->hitPattern().trackerLayersWithoutMeasurement();
01000 unsigned int LostHits = trackref->numberOfLostHits();
01001 double sigmaHad = sqrt(1.20*1.20/P+0.06*0.06) / (1.+LostHits);
01002
01003
01004 unsigned int Algo = 0;
01005 switch (trackref->algo()) {
01006 case TrackBase::ctf:
01007 case TrackBase::iter0:
01008 case TrackBase::iter1:
01009 Algo = 0;
01010 break;
01011 case TrackBase::iter2:
01012 Algo = 1;
01013 break;
01014 case TrackBase::iter3:
01015 Algo = 2;
01016 break;
01017 case TrackBase::iter4:
01018 Algo = 3;
01019 break;
01020 case TrackBase::iter5:
01021 Algo = 4;
01022 break;
01023 default:
01024 Algo = 5;
01025 break;
01026 }
01027
01028
01029 if ( P < 0.05 ) return false;
01030
01031 if(useIterTracking_){
01032
01033
01034 if ( Algo > 4 ) return false;
01035
01036 if (debug_) cout << " PFBlockAlgo: PFrecTrack->Track Pt= "
01037 << Pt << " DPt = " << DPt << endl;
01038 if ( ( DPtovPtCut_[Algo] > 0. &&
01039 DPt/Pt > DPtovPtCut_[Algo]*sigmaHad ) ||
01040 NHit < NHitCut_[Algo] ) {
01041
01042 if (debug_) cout << " PFBlockAlgo: skip badly measured track"
01043 << ", P = " << P
01044 << ", Pt = " << Pt
01045 << " DPt = " << DPt
01046 << ", N(hits) = " << NHit << " (Lost : " << LostHits << "/" << NLostHit << ")"
01047 << ", Algo = " << Algo
01048 << endl;
01049 if (debug_) cout << " cut is DPt/Pt < " << DPtovPtCut_[Algo] * sigmaHad << endl;
01050 if (debug_) cout << " cut is NHit >= " << NHitCut_[Algo] << endl;
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060 return false;
01061 }
01062
01063 }
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 return true;
01074 }
01075
01076 int
01077 PFBlockAlgo::muAssocToTrack( const reco::TrackRef& trackref,
01078 const edm::Handle<reco::MuonCollection>& muonh) const {
01079 if(muonh.isValid() ) {
01080 for(unsigned j=0;j<muonh->size(); j++) {
01081 reco::MuonRef muonref( muonh, j );
01082 if (muonref->track().isNonnull())
01083 if( muonref->track() == trackref ) return j;
01084 }
01085 }
01086 return -1;
01087 }
01088
01089 int
01090 PFBlockAlgo::muAssocToTrack( const reco::TrackRef& trackref,
01091 const edm::OrphanHandle<reco::MuonCollection>& muonh) const {
01092 if(muonh.isValid() ) {
01093 for(unsigned j=0;j<muonh->size(); j++) {
01094 reco::MuonRef muonref( muonh, j );
01095 if (muonref->track().isNonnull())
01096 if( muonref->track() == trackref ) return j;
01097 }
01098 }
01099 return -1;
01100 }
01101
01102
01103 void
01104 PFBlockAlgo::checkDisplacedVertexLinks( reco::PFBlock& block ) const {
01105
01106
01107 typedef std::multimap<double, unsigned>::iterator IE;
01108
01109 const edm::OwnVector< reco::PFBlockElement >& els = block.elements();
01110
01111 for( unsigned i1=0; i1 != els.size(); ++i1 ) {
01112 if( els[i1].type() == PFBlockElement::TRACK ) continue;
01113 std::multimap<double, unsigned> assocTracks;
01114
01115 block.associatedElements( i1, block.linkData(),
01116 assocTracks,
01117 reco::PFBlockElement::TRACK,
01118 reco::PFBlock::LINKTEST_ALL );
01119 for( IE ie = assocTracks.begin(); ie != assocTracks.end(); ++ie) {
01120
01121 unsigned iprim = ie->second;
01122
01123
01124 if( els[iprim].isPrimary()) {
01125
01126 block.setLink( i1, iprim, -1, block.linkData(),
01127 PFBlock::LINKTEST_RECHIT );
01128 }
01129 }
01130 }
01131
01132 }
01133
01134