00001 #ifndef RecoParticleFlow_PFProducer_PFBlockAlgo_h
00002 #define RecoParticleFlow_PFProducer_PFBlockAlgo_h
00003
00004 #include <set>
00005 #include <vector>
00006 #include <iostream>
00007
00008
00009 #include "DataFormats/Common/interface/Handle.h"
00010
00011 #include "DataFormats/Common/interface/OrphanHandle.h"
00012
00013
00014 #include "DataFormats/ParticleFlowReco/interface/PFClusterFwd.h"
00015 #include "DataFormats/ParticleFlowReco/interface/PFRecTrackFwd.h"
00016 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00017 #include "DataFormats/ParticleFlowReco/interface/PFRecTrack.h"
00018 #include "DataFormats/ParticleFlowReco/interface/PFDisplacedTrackerVertex.h"
00019 #include "DataFormats/ParticleFlowReco/interface/PFConversionFwd.h"
00020 #include "DataFormats/ParticleFlowReco/interface/PFConversion.h"
00021 #include "DataFormats/ParticleFlowReco/interface/PFV0Fwd.h"
00022 #include "DataFormats/ParticleFlowReco/interface/PFV0.h"
00023 #include "DataFormats/ParticleFlowReco/interface/GsfPFRecTrack.h"
00024 #include "DataFormats/ParticleFlowReco/interface/GsfPFRecTrackFwd.h"
00025 #include "DataFormats/ParticleFlowReco/interface/PFBrem.h"
00026 #include "DataFormats/ParticleFlowReco/interface/PFTrajectoryPoint.h"
00027
00028 #include "DataFormats/ParticleFlowReco/interface/PFBlockElement.h"
00029 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
00030 #include "DataFormats/ParticleFlowReco/interface/PFBlockFwd.h"
00031
00032
00033 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00034 #include "RecoParticleFlow/PFProducer/interface/KDTreeLinkerTrackEcal.h"
00035 #include "RecoParticleFlow/PFProducer/interface/KDTreeLinkerTrackHcal.h"
00036 #include "RecoParticleFlow/PFProducer/interface/KDTreeLinkerPSEcal.h"
00037
00038
00039
00040
00041 #include "RecoParticleFlow/PFProducer/interface/PFMuonAlgo.h"
00042 #include "RecoParticleFlow/PFProducer/interface/PhotonSelectorAlgo.h"
00043 #include "RecoParticleFlow/PFProducer/interface/PFBlockElementSCEqual.h"
00044 #include "RecoParticleFlow/PFClusterTools/interface/PFResolutionMap.h"
00045
00046 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00047 #include "DataFormats/MuonReco/interface/Muon.h"
00048 #include "DataFormats/EgammaReco/interface/SuperClusterFwd.h"
00049 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
00050 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
00051 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00052 #include "DataFormats/EgammaReco/interface/ElectronSeedFwd.h"
00053 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
00054 #include "DataFormats/EgammaCandidates/interface/PhotonFwd.h"
00055 #include "DataFormats/EgammaCandidates/interface/Photon.h"
00056 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementSuperCluster.h"
00057
00058 #include "RecoParticleFlow/PFClusterTools/interface/ClusterClusterMapping.h"
00059
00060 #include "RecoParticleFlow/PFProducer/interface/PFBlockLink.h"
00061
00062 #include <map>
00063
00064
00066
00071 class PFBlockAlgo {
00072
00073 public:
00074
00075 PFBlockAlgo();
00076
00077 ~PFBlockAlgo();
00078
00079
00080 void setParameters( std::vector<double>& DPtovPtCut,
00081 std::vector<unsigned>& NHitCut,
00082 bool useConvBremPFRecTracks,
00083 bool useIterTracking,
00084 int nuclearInteractionsPurity,
00085 bool useEGPhotons,
00086 std::vector<double> & photonSelectionCuts,
00087 bool useSuperClusters
00088 );
00089
00090
00091 void setUseOptimization(bool useKDTreeTrackEcalLinker);
00092
00093
00094 typedef std::vector<bool> Mask;
00095
00097 template< template<typename> class T>
00098 void setInput(const T<reco::PFRecTrackCollection>& trackh,
00099 const T<reco::GsfPFRecTrackCollection>& gsftrackh,
00100 const T<reco::GsfPFRecTrackCollection>& convbremgsftrackh,
00101 const T<reco::MuonCollection>& muonh,
00102 const T<reco::PFDisplacedTrackerVertexCollection>& nuclearh,
00103 const T<reco::PFRecTrackCollection>& nucleartrackh,
00104 const T<reco::PFConversionCollection>& conv,
00105 const T<reco::PFV0Collection>& v0,
00106 const T<reco::PFClusterCollection>& ecalh,
00107 const T<reco::PFClusterCollection>& hcalh,
00108 const T<reco::PFClusterCollection>& hoh,
00109 const T<reco::PFClusterCollection>& hfemh,
00110 const T<reco::PFClusterCollection>& hfhadh,
00111 const T<reco::PFClusterCollection>& psh,
00112 const T<reco::PhotonCollection>& egphh,
00113 const T<reco::SuperClusterCollection>& sceb,
00114 const T<reco::SuperClusterCollection>& scee,
00115 const Mask& trackMask = dummyMask_,
00116 const Mask& gsftrackMask = dummyMask_,
00117 const Mask& ecalMask = dummyMask_,
00118 const Mask& hcalMask = dummyMask_,
00119 const Mask& hoMask = dummyMask_,
00120 const Mask& hfemMask = dummyMask_,
00121 const Mask& hfhadMask = dummyMask_,
00122 const Mask& psMask = dummyMask_,
00123 const Mask& phMask = dummyMask_,
00124 const Mask& scMask = dummyMask_);
00125
00127 template< template<typename> class T >
00128 void setInput(const T<reco::PFRecTrackCollection>& trackh,
00129 const T<reco::MuonCollection>& muonh,
00130 const T<reco::PFClusterCollection>& ecalh,
00131 const T<reco::PFClusterCollection>& hcalh,
00132 const T<reco::PFClusterCollection>& hoh,
00133 const T<reco::PFClusterCollection>& hfemh,
00134 const T<reco::PFClusterCollection>& hfhadh,
00135 const T<reco::PFClusterCollection>& psh,
00136 const Mask& trackMask = dummyMask_,
00137 const Mask& ecalMask = dummyMask_,
00138 const Mask& hcalMask = dummyMask_,
00139 const Mask& hoMask = dummyMask_,
00140 const Mask& psMask = dummyMask_) {
00141 T<reco::GsfPFRecTrackCollection> gsftrackh;
00142 T<reco::GsfPFRecTrackCollection> convbremgsftrackh;
00143
00144 T<reco::PFDisplacedTrackerVertexCollection> nuclearh;
00145 T<reco::PFRecTrackCollection> nucleartrackh;
00146 T<reco::PFConversionCollection> convh;
00147 T<reco::PFV0Collection> v0;
00148 T<reco::PhotonCollection> phh;
00149 T<reco::SuperClusterCollection> scebh;
00150 T<reco::SuperClusterCollection> sceeh;
00151 setInput<T>( trackh, gsftrackh, convbremgsftrackh, muonh, nuclearh, nucleartrackh, convh, v0,
00152 ecalh, hcalh, hoh, hfemh, hfhadh, psh, phh, scebh, sceeh,
00153 trackMask, ecalMask, hcalMask, hoMask, psMask);
00154 }
00155
00157 template< template<typename> class T >
00158 void setInput(const T<reco::PFRecTrackCollection>& trackh,
00159 const T<reco::GsfPFRecTrackCollection>& gsftrackh,
00160 const T<reco::PFClusterCollection>& ecalh,
00161 const T<reco::PFClusterCollection>& hcalh,
00162 const T<reco::PFClusterCollection>& hoh,
00163 const T<reco::PFClusterCollection>& psh,
00164 const Mask& trackMask = dummyMask_,
00165 const Mask& gsftrackMask = dummyMask_,
00166 const Mask& ecalMask = dummyMask_,
00167 const Mask& hcalMask = dummyMask_,
00168 const Mask& hoMask = dummyMask_,
00169 const Mask& psMask = dummyMask_) {
00170 T<reco::GsfPFRecTrackCollection> convbremgsftrackh;
00171 T<reco::MuonCollection> muonh;
00172 T<reco::PFDisplacedTrackerVertexCollection> nuclearh;
00173 T<reco::PFRecTrackCollection> nucleartrackh;
00174 T<reco::PFConversionCollection> convh;
00175 T<reco::PFV0Collection> v0;
00176 T<reco::PhotonCollection> egphh;
00177 setInput<T>( trackh, gsftrackh, convbremgsftrackh, muonh, nuclearh, nucleartrackh, convh, v0, ecalh, hcalh, hoh, psh, egphh,
00178 trackMask, gsftrackMask,ecalMask, hcalMask, hoMask, psMask);
00179 }
00180
00181
00183 void setDebug( bool debug ) {debug_ = debug;}
00184
00186 void findBlocks();
00187
00188
00190
00191 const std::auto_ptr< reco::PFBlockCollection >& blocks() const
00192 {return blocks_;}
00193
00195 std::auto_ptr< reco::PFBlockCollection > transferBlocks() {return blocks_;}
00196
00198 typedef std::list< reco::PFBlockElement* >::iterator IE;
00199 typedef std::list< reco::PFBlockElement* >::const_iterator IEC;
00200 typedef reco::PFBlockCollection::const_iterator IBC;
00201
00202 void setHOTag(bool ho) { useHO_ = ho;}
00203
00204 private:
00205
00212 IE associate(IE next, IE last, std::vector<PFBlockLink>& links);
00213
00216 void packLinks(reco::PFBlock& block,
00217 const std::vector<PFBlockLink>& links) const;
00218
00220 void checkDisplacedVertexLinks( reco::PFBlock& block ) const;
00221
00225 void buildGraph();
00226
00228 inline bool linkPrefilter(const reco::PFBlockElement* last, const reco::PFBlockElement* next) const;
00229
00231 void link( const reco::PFBlockElement* el1,
00232 const reco::PFBlockElement* el2,
00233 PFBlockLink::Type& linktype,
00234 reco::PFBlock::LinkTest& linktest,
00235 double& dist) const;
00236
00239 double testTrackAndPS(const reco::PFRecTrack& track,
00240 const reco::PFCluster& ps) const;
00241
00244 double testECALAndHCAL(const reco::PFCluster& ecal,
00245 const reco::PFCluster& hcal) const;
00246
00249 double testHCALAndHO(const reco::PFCluster& hcal,
00250 const reco::PFCluster& ho) const;
00251
00252
00255 double testPS1AndPS2(const reco::PFCluster& ps1,
00256 const reco::PFCluster& ps2) const;
00257
00259 double testLinkBySuperCluster(const reco::PFClusterRef & elt1,
00260 const reco::PFClusterRef & elt2) const;
00261
00263 double testSuperClusterPFCluster(const reco::SuperClusterRef & sct1,
00264 const reco::PFClusterRef & elt2) const;
00265
00269 void checkMaskSize( const reco::PFRecTrackCollection& tracks,
00270 const reco::GsfPFRecTrackCollection& gsftracks,
00271 const reco::PFClusterCollection& ecals,
00272 const reco::PFClusterCollection& hcals,
00273 const reco::PFClusterCollection& hos,
00274 const reco::PFClusterCollection& hfems,
00275 const reco::PFClusterCollection& hfhads,
00276 const reco::PFClusterCollection& pss,
00277 const reco::PhotonCollection& egphh,
00278 const reco::SuperClusterCollection& sceb,
00279 const reco::SuperClusterCollection& scee,
00280 const Mask& trackMask,
00281 const Mask& gsftrackMask,
00282 const Mask& ecalMask,
00283 const Mask& hcalMask,
00284 const Mask& hoMask,
00285 const Mask& hfemMask,
00286 const Mask& hfhadMask,
00287 const Mask& psMask,
00288 const Mask& phMask,
00289 const Mask& scMask) const;
00290
00292
00293
00295 bool goodPtResolution( const reco::TrackRef& trackref);
00296
00297 double testLinkByVertex(const reco::PFBlockElement* elt1,
00298 const reco::PFBlockElement* elt2) const;
00299
00300 int muAssocToTrack( const reco::TrackRef& trackref,
00301 const edm::Handle<reco::MuonCollection>& muonh) const;
00302 int muAssocToTrack( const reco::TrackRef& trackref,
00303 const edm::OrphanHandle<reco::MuonCollection>& muonh) const;
00304
00305 template< template<typename> class T>
00306 void fillFromPhoton(const T<reco::PhotonCollection> &, unsigned isc, reco::PFBlockElementSuperCluster * pfbe);
00307
00308 std::auto_ptr< reco::PFBlockCollection > blocks_;
00309
00311
00312
00313
00314 std::list< reco::PFBlockElement* > elements_;
00315
00316
00317 bool useKDTreeTrackEcalLinker_;
00318 KDTreeLinkerTrackEcal TELinker_;
00319 KDTreeLinkerTrackHcal THLinker_;
00320 KDTreeLinkerPSEcal PSELinker_;
00321
00322
00323 static const Mask dummyMask_;
00324
00326 std::vector<double> DPtovPtCut_;
00327
00329 std::vector<unsigned> NHitCut_;
00330
00332 bool useIterTracking_;
00333
00335 bool useEGPhotons_;
00336
00338 bool useSuperClusters_;
00339
00340
00341
00342
00343
00344
00345
00346
00347 int nuclearInteractionsPurity_;
00348
00350 bool useConvBremPFRecTracks_;
00351
00353 const PhotonSelectorAlgo * photonSelector_;
00355 std::vector<reco::SuperClusterRef > superClusters_;
00356
00358
00359 std::vector<int> pfcSCVec_;
00360
00361
00362 bool bNoSuperclus_;
00363
00365 std::vector<std::vector<reco::PFClusterRef> > scpfcRefs_;
00367 bool debug_;
00368
00369 friend std::ostream& operator<<(std::ostream&, const PFBlockAlgo&);
00370
00371
00372 bool useHO_;
00373
00374 };
00375
00376 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementGsfTrack.h"
00377 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementBrem.h"
00378 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementTrack.h"
00379 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementCluster.h"
00380 #include "DataFormats/ParticleFlowReco/interface/PFLayer.h"
00381
00382 template< template<typename> class T >
00383 void
00384 PFBlockAlgo::setInput(const T<reco::PFRecTrackCollection>& trackh,
00385 const T<reco::GsfPFRecTrackCollection>& gsftrackh,
00386 const T<reco::GsfPFRecTrackCollection>& convbremgsftrackh,
00387 const T<reco::MuonCollection>& muonh,
00388 const T<reco::PFDisplacedTrackerVertexCollection>& nuclearh,
00389 const T<reco::PFRecTrackCollection>& nucleartrackh,
00390 const T<reco::PFConversionCollection>& convh,
00391 const T<reco::PFV0Collection>& v0,
00392 const T<reco::PFClusterCollection>& ecalh,
00393 const T<reco::PFClusterCollection>& hcalh,
00394 const T<reco::PFClusterCollection>& hoh,
00395 const T<reco::PFClusterCollection>& hfemh,
00396 const T<reco::PFClusterCollection>& hfhadh,
00397 const T<reco::PFClusterCollection>& psh,
00398 const T<reco::PhotonCollection>& egphh,
00399 const T<reco::SuperClusterCollection>& sceb,
00400 const T<reco::SuperClusterCollection>& scee,
00401 const Mask& trackMask,
00402 const Mask& gsftrackMask,
00403 const Mask& ecalMask,
00404 const Mask& hcalMask,
00405 const Mask& hoMask,
00406 const Mask& hfemMask,
00407 const Mask& hfhadMask,
00408 const Mask& psMask,
00409 const Mask& phMask,
00410 const Mask& scMask) {
00411
00412
00413 checkMaskSize( *trackh,
00414 *gsftrackh,
00415 *ecalh,
00416 *hcalh,
00417 *hoh,
00418 *hfemh,
00419 *hfhadh,
00420 *psh,
00421 *egphh,
00422 *sceb,
00423 *scee,
00424 trackMask,
00425 gsftrackMask,
00426 ecalMask,
00427 hcalMask,
00428 hoMask,
00429 hfemMask,
00430 hfhadMask,
00431 psMask,
00432 phMask,
00433 scMask);
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00445 std::vector<reco::PFRecTrackRef> convBremPFRecTracks;
00446 convBremPFRecTracks.clear();
00447
00448 superClusters_.clear();
00449 scpfcRefs_.clear();
00450 pfcSCVec_.clear();
00451
00452 if(gsftrackh.isValid() ) {
00453 const reco::GsfPFRecTrackCollection PFGsfProd = *(gsftrackh.product());
00454 for(unsigned i=0;i<gsftrackh->size(); ++i) {
00455 if( !gsftrackMask.empty() &&
00456 !gsftrackMask[i] ) continue;
00457 reco::GsfPFRecTrackRef refgsf(gsftrackh,i );
00458
00459 if((refgsf).isNull()) continue;
00460 reco::GsfTrackRef gsf=refgsf->gsfTrackRef();
00461
00462
00463 if(gsf->extra().isAvailable() && gsf->extra()->seedRef().isAvailable()) {
00464 reco::ElectronSeedRef seedRef= gsf->extra()->seedRef().castTo<reco::ElectronSeedRef>();
00465
00466 if(seedRef.isAvailable() && seedRef->isEcalDriven()) {
00467 reco::SuperClusterRef scRef = seedRef->caloCluster().castTo<reco::SuperClusterRef>();
00468 if(scRef.isNonnull()) {
00469 std::vector<reco::SuperClusterRef>::iterator itcheck=find(superClusters_.begin(),superClusters_.end(),scRef);
00470
00471 if(itcheck==superClusters_.end())
00472 {
00473 superClusters_.push_back(scRef);
00474 reco::PFBlockElementSuperCluster * sce =
00475 new reco::PFBlockElementSuperCluster(scRef);
00476 sce->setFromGsfElectron(true);
00477 elements_.push_back(sce);
00478 }
00479 else
00480 {
00481 PFBlockElementSCEqual myEqual(scRef);
00482 std::list<reco::PFBlockElement*>::iterator itcheck=find_if(elements_.begin(),elements_.end(),myEqual);
00483 if(itcheck!=elements_.end())
00484 {
00485 reco::PFBlockElementSuperCluster* thePFBE=dynamic_cast<reco::PFBlockElementSuperCluster*>(*itcheck);
00486 thePFBE->setFromGsfElectron(true);
00487
00488 }
00489
00490
00491
00492
00493 }
00494 }
00495 }
00496 }
00497
00498 reco::PFBlockElement* gsfEl;
00499
00500 const std::vector<reco::PFTrajectoryPoint>
00501 PfGsfPoint = PFGsfProd[i].trajectoryPoints();
00502
00503 unsigned int c_gsf=0;
00504 bool PassTracker = false;
00505 bool GetPout = false;
00506 unsigned int IndexPout = 0;
00507
00508 typedef std::vector<reco::PFTrajectoryPoint>::const_iterator IP;
00509 for(IP itPfGsfPoint = PfGsfPoint.begin();
00510 itPfGsfPoint!= PfGsfPoint.end();++itPfGsfPoint) {
00511
00512 if (itPfGsfPoint->isValid()){
00513 int layGsfP = itPfGsfPoint->layer();
00514 if (layGsfP == -1) PassTracker = true;
00515 if (PassTracker && layGsfP > 0 && GetPout == false) {
00516 IndexPout = c_gsf-1;
00517 GetPout = true;
00518 }
00519
00520 ++c_gsf;
00521 }
00522 }
00523 math::XYZTLorentzVector pin = PfGsfPoint[0].momentum();
00524 math::XYZTLorentzVector pout = PfGsfPoint[IndexPout].momentum();
00525
00527 if(useConvBremPFRecTracks_) {
00528 const std::vector<reco::PFRecTrackRef>& temp_convBremPFRecTracks(refgsf->convBremPFRecTrackRef());
00529 if(temp_convBremPFRecTracks.size() > 0) {
00530 for(unsigned int iconv = 0; iconv <temp_convBremPFRecTracks.size(); ++iconv) {
00531 convBremPFRecTracks.push_back(temp_convBremPFRecTracks[iconv]);
00532 }
00533 }
00534 }
00535
00536 gsfEl = new reco::PFBlockElementGsfTrack(refgsf, pin, pout);
00537
00538 elements_.push_back( gsfEl);
00539
00540 std::vector<reco::PFBrem> pfbrem = refgsf->PFRecBrem();
00541
00542 for (unsigned i2=0;i2<pfbrem.size(); ++i2) {
00543 const double DP = pfbrem[i2].DeltaP();
00544 const double SigmaDP = pfbrem[i2].SigmaDeltaP();
00545 const unsigned int TrajP = pfbrem[i2].indTrajPoint();
00546 if(TrajP == 99) continue;
00547
00548 reco::PFBlockElement* bremEl;
00549 bremEl = new reco::PFBlockElementBrem(refgsf,DP,SigmaDP,TrajP);
00550 elements_.push_back(bremEl);
00551
00552 }
00553 }
00554
00555 }
00556
00558 if(useEGPhotons_ && egphh.isValid()) {
00559 unsigned size=egphh->size();
00560 for(unsigned isc=0; isc<size; ++isc) {
00561 if(!phMask.empty() && !(phMask)[isc] ) continue;
00562 if(!photonSelector_->passPhotonSelection((*egphh)[isc])) continue;
00563
00564
00565 reco::SuperClusterRef scRef((*egphh)[isc].superCluster());
00566 std::vector<reco::SuperClusterRef>::iterator itcheck=find(superClusters_.begin(),superClusters_.end(),(*egphh)[isc].superCluster());
00567 if(itcheck==superClusters_.end())
00568 {
00569 superClusters_.push_back(scRef);
00570 reco::PFBlockElementSuperCluster * sce =
00571 new reco::PFBlockElementSuperCluster((*egphh)[isc].superCluster());
00572 fillFromPhoton(egphh,isc,sce);
00573 elements_.push_back(sce);
00574 }
00575 else
00576 {
00577 PFBlockElementSCEqual myEqual(scRef);
00578 std::list<reco::PFBlockElement*>::iterator itcheck=find_if(elements_.begin(),elements_.end(),myEqual);
00579 if(itcheck!=elements_.end())
00580 {
00581 reco::PFBlockElementSuperCluster* thePFBE=dynamic_cast<reco::PFBlockElementSuperCluster*>(*itcheck);
00582 fillFromPhoton(egphh,isc,thePFBE);
00583 thePFBE->setFromPhoton(true);
00584
00585
00586 }
00587
00588
00589
00590
00591 }
00592 }
00593 }
00594
00596 if(useSuperClusters_ && sceb.isValid() && scee.isValid()) {
00597 std::vector<reco::SuperClusterRef> screfs;
00598 screfs.reserve(sceb->size()+scee->size());
00599
00600 for (unsigned int isc=0; isc<sceb->size(); ++isc) {
00601 reco::SuperClusterRef scRef(sceb,isc);
00602 screfs.push_back(scRef);
00603 }
00604
00605 for (unsigned int isc=0; isc<scee->size(); ++isc) {
00606 reco::SuperClusterRef scRef(scee,isc);
00607 screfs.push_back(scRef);
00608 }
00609
00610 unsigned size=screfs.size();
00611 for(unsigned isc=0; isc<size; ++isc) {
00612 if(!scMask.empty() && !(scMask)[isc] ) continue;
00613
00614
00615
00616
00617 reco::SuperClusterRef &scRef = screfs[isc];
00618 std::vector<reco::SuperClusterRef>::iterator itcheck=find(superClusters_.begin(),superClusters_.end(),scRef);
00619 if(itcheck==superClusters_.end())
00620 {
00621 superClusters_.push_back(scRef);
00622 reco::PFBlockElementSuperCluster * sce =
00623 new reco::PFBlockElementSuperCluster(scRef);
00624
00625
00626 elements_.push_back(sce);
00627 }
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 }
00646 }
00647
00648
00649 scpfcRefs_.resize(superClusters_.size());
00650
00652
00654
00655 if(convh.isValid() ) {
00656 reco::PFBlockElement* trkFromConversionElement;
00657 for(unsigned i=0;i<convh->size(); ++i) {
00658 reco::PFConversionRef convRef(convh,i);
00659
00660 unsigned int trackSize=(convRef->pfTracks()).size();
00661 if ( convRef->pfTracks().size() < 2) continue;
00662 for(unsigned iTk=0;iTk<trackSize; ++iTk) {
00663
00664 reco::PFRecTrackRef compPFTkRef = convRef->pfTracks()[iTk];
00665 trkFromConversionElement = new reco::PFBlockElementTrack(convRef->pfTracks()[iTk]);
00666 trkFromConversionElement->setConversionRef( convRef->originalConversion(), reco::PFBlockElement::T_FROM_GAMMACONV);
00667
00668 elements_.push_back( trkFromConversionElement );
00669
00670
00671 if (debug_){
00672 std::cout << "PF Block Element from Conversion electron " <<
00673 (*trkFromConversionElement).trackRef().key() << std::endl;
00674 std::cout << *trkFromConversionElement << std::endl;
00675 }
00676
00677 }
00678 }
00679 }
00680
00681
00683
00685
00686 if(v0.isValid() ) {
00687 reco::PFBlockElement* trkFromV0Element = 0;
00688 for(unsigned i=0;i<v0->size(); ++i) {
00689 reco::PFV0Ref v0Ref( v0, i );
00690 unsigned int trackSize=(v0Ref->pfTracks()).size();
00691 for(unsigned iTk=0;iTk<trackSize; ++iTk) {
00692
00693 reco::PFRecTrackRef newPFRecTrackRef = (v0Ref->pfTracks())[iTk];
00694 reco::TrackBaseRef newTrackBaseRef(newPFRecTrackRef->trackRef());
00695 bool bNew = true;
00696
00699 for(IE iel = elements_.begin(); iel != elements_.end(); ++iel){
00700 reco::TrackBaseRef elemTrackBaseRef((*iel)->trackRef());
00701 if (newTrackBaseRef == elemTrackBaseRef){
00702 trkFromV0Element = *iel;
00703 bNew = false;
00704 continue;
00705 }
00706 }
00707
00709 if (bNew) {
00710 trkFromV0Element = new reco::PFBlockElementTrack(v0Ref->pfTracks()[iTk]);
00711 elements_.push_back( trkFromV0Element );
00712 }
00713
00714 trkFromV0Element->setV0Ref( v0Ref->originalV0(),
00715 reco::PFBlockElement::T_FROM_V0 );
00716
00717 if (debug_){
00718 std::cout << "PF Block Element from V0 track New = " << bNew
00719 << (*trkFromV0Element).trackRef().key() << std::endl;
00720 std::cout << *trkFromV0Element << std::endl;
00721 }
00722
00723
00724 }
00725 }
00726 }
00727
00729
00731
00732 if(nuclearh.isValid()) {
00733 reco::PFBlockElement* trkFromDisplacedVertexElement = 0;
00734 for(unsigned i=0;i<nuclearh->size(); ++i) {
00735
00736 const reco::PFDisplacedTrackerVertexRef dispacedVertexRef( nuclearh, i );
00737
00738
00739
00740
00741
00742
00743
00744 bool bIncludeVertices = false;
00745 bool bNucl = dispacedVertexRef->displacedVertexRef()->isNucl()
00746 && dispacedVertexRef->displacedVertexRef()->position().rho()> 2.7;
00747 bool bNucl_Loose = dispacedVertexRef->displacedVertexRef()->isNucl_Loose();
00748 bool bNucl_Kink = dispacedVertexRef->displacedVertexRef()->isNucl_Kink();
00749
00750 if (nuclearInteractionsPurity_ >= 1) bIncludeVertices = bNucl;
00751 if (nuclearInteractionsPurity_ >= 2) bIncludeVertices = bIncludeVertices || bNucl_Loose;
00752 if (nuclearInteractionsPurity_ >= 3) bIncludeVertices = bIncludeVertices || bNucl_Kink;
00753
00754 if (bIncludeVertices){
00755
00756 unsigned int trackSize= dispacedVertexRef->pfRecTracks().size();
00757 if (debug_){
00758 std::cout << "" << std::endl;
00759 std::cout << "Displaced Vertex " << i << std::endl;
00760 dispacedVertexRef->displacedVertexRef()->Dump();
00761 }
00762 for(unsigned iTk=0;iTk < trackSize; ++iTk) {
00763
00764
00765
00766
00767
00768
00769 reco::PFRecTrackRef newPFRecTrackRef = dispacedVertexRef->pfRecTracks()[iTk];
00770 reco::TrackBaseRef constTrackBaseRef(newPFRecTrackRef->trackRef());
00771
00772
00773 if (nucleartrackh.isValid()){
00774 for(unsigned i=0;i<nucleartrackh->size(); ++i) {
00775 reco::PFRecTrackRef transientPFRecTrackRef(nucleartrackh,i);
00776 reco::TrackBaseRef transientTrackBaseRef(transientPFRecTrackRef->trackRef());
00777 if (constTrackBaseRef==transientTrackBaseRef){
00778 newPFRecTrackRef = transientPFRecTrackRef;
00779 break;
00780 }
00781 }
00782 }
00783 reco::TrackBaseRef newTrackBaseRef(newPFRecTrackRef->trackRef());
00784
00785
00786
00787 bool bNew = true;
00788 reco::PFBlockElement::TrackType blockType;
00789
00792 for(IE iel = elements_.begin(); iel != elements_.end(); ++iel){
00793 reco::TrackBaseRef elemTrackBaseRef((*iel)->trackRef());
00794 if (newTrackBaseRef == elemTrackBaseRef){
00795 trkFromDisplacedVertexElement = *iel;
00796 bNew = false;
00797 continue;
00798 }
00799 }
00800
00801
00803 if (bNew) {
00804
00805
00806
00807 trkFromDisplacedVertexElement = new reco::PFBlockElementTrack(newPFRecTrackRef);
00808 elements_.push_back( trkFromDisplacedVertexElement );
00809 }
00810
00811 if (dispacedVertexRef->isIncomingTrack(newPFRecTrackRef))
00812 blockType = reco::PFBlockElement::T_TO_DISP;
00813 else if (dispacedVertexRef->isOutgoingTrack(newPFRecTrackRef))
00814 blockType = reco::PFBlockElement::T_FROM_DISP;
00815 else
00816 blockType = reco::PFBlockElement::DEFAULT;
00817
00819 trkFromDisplacedVertexElement->setDisplacedVertexRef( dispacedVertexRef, blockType );
00820
00821
00822 if (debug_){
00823 std::cout << "PF Block Element from DisplacedTrackingVertex track New = " << bNew
00824 << (*trkFromDisplacedVertexElement).trackRef().key() << std::endl;
00825 std::cout << *trkFromDisplacedVertexElement << std::endl;
00826 }
00827
00828
00829 }
00830 }
00831 }
00832
00833 if (debug_) std::cout << "" << std::endl;
00834
00835 }
00836
00838
00842
00843 if(trackh.isValid() ) {
00844
00845 if (debug_) std::cout << "Tracks already in from Displaced Vertices " << std::endl;
00846
00847 Mask trackMaskVertex;
00848
00849 for(unsigned i=0;i<trackh->size(); ++i) {
00850 reco::PFRecTrackRef pfRefTrack( trackh,i );
00851 reco::TrackRef trackRef = pfRefTrack->trackRef();
00852
00853 bool bMask = true;
00854 for(IE iel = elements_.begin(); iel != elements_.end(); ++iel){
00855 reco::TrackRef elemTrackRef = (*iel)->trackRef();
00856 if( trackRef == elemTrackRef ) {
00857 if (debug_) std::cout << " " << trackRef.key();
00858 bMask = false; continue;
00859 }
00860 }
00861
00862 trackMaskVertex.push_back(bMask);
00863 }
00864
00865 if (debug_) std::cout << "" << std::endl;
00866
00867 if (debug_) std::cout << "Additionnal tracks from main collection " << std::endl;
00868
00869 for(unsigned i=0;i<trackh->size(); ++i) {
00870
00871
00872
00873 if( !trackMask.empty() && !trackMask[i] ) continue;
00874
00875 reco::PFRecTrackRef ref( trackh,i );
00876
00877 if (debug_) std::cout << " " << ref->trackRef().key();
00878
00879
00880 int muId_ = muAssocToTrack( ref->trackRef(), muonh );
00881 bool thisIsAPotentialMuon = false;
00882 if( muId_ != -1 ) {
00883 reco::MuonRef muonref( muonh, muId_ );
00884 thisIsAPotentialMuon =
00885 PFMuonAlgo::isLooseMuon(muonref) ||
00886 PFMuonAlgo::isMuon(muonref);
00887 }
00888
00889 if( !thisIsAPotentialMuon && !goodPtResolution( ref->trackRef() ) ) continue;
00890
00891 if (thisIsAPotentialMuon && debug_) std::cout << "Potential Muon P " << ref->trackRef()->p()
00892 << " pt " << ref->trackRef()->p() << std::endl;
00893
00894
00895
00896 reco::PFBlockElement* primaryElement = new reco::PFBlockElementTrack( ref );
00897
00898 if( muId_ != -1 ) {
00899
00900 reco::MuonRef muonref( muonh, muId_ );
00901
00902
00903
00904 if (!trackMaskVertex.empty() && !trackMaskVertex[i]){
00905 reco::TrackRef primaryTrackRef = ref->trackRef();
00906 for(IE iel = elements_.begin(); iel != elements_.end(); ++iel){
00907 reco::TrackRef elemTrackRef = (*iel)->trackRef();
00908 if( primaryTrackRef == elemTrackRef ) {
00909 (*iel)->setMuonRef( muonref );
00910 if (debug_) std::cout << "One of the tracks identified in displaced vertices collections was spotted as muon" <<std:: endl;
00911 }
00912 }
00913 } else primaryElement->setMuonRef( muonref );
00914
00915 }
00916
00917 if (!trackMaskVertex.empty() && !trackMaskVertex[i]) continue;
00918
00919
00920
00921 if(useConvBremPFRecTracks_) {
00922 if(convBremPFRecTracks.size() > 0.) {
00923 for(unsigned int iconv = 0; iconv < convBremPFRecTracks.size(); ++iconv) {
00924 if((*ref).trackRef() == (*convBremPFRecTracks[iconv]).trackRef()) {
00925 bool value = true;
00926 primaryElement->setTrackType(reco::PFBlockElement::T_FROM_GAMMACONV, value);
00927 }
00928 }
00929 }
00930 }
00931 elements_.push_back( primaryElement );
00932 }
00933
00934 if (debug_) std::cout << " " << std::endl;
00935
00936 }
00937
00938
00939
00940
00941 if(convbremgsftrackh.isValid() ) {
00942
00943
00944 const reco::GsfPFRecTrackCollection ConvPFGsfProd = *(convbremgsftrackh.product());
00945 for(unsigned i=0;i<convbremgsftrackh->size(); ++i) {
00946
00947 reco::GsfPFRecTrackRef refgsf(convbremgsftrackh,i );
00948
00949 if((refgsf).isNull()) continue;
00950
00951 reco::PFBlockElement* gsfEl;
00952
00953 const std::vector<reco::PFTrajectoryPoint>
00954 PfGsfPoint = ConvPFGsfProd[i].trajectoryPoints();
00955
00956 unsigned int c_gsf=0;
00957 bool PassTracker = false;
00958 bool GetPout = false;
00959 unsigned int IndexPout = -1;
00960
00961 typedef std::vector<reco::PFTrajectoryPoint>::const_iterator IP;
00962 for(IP itPfGsfPoint = PfGsfPoint.begin();
00963 itPfGsfPoint!= PfGsfPoint.end();++itPfGsfPoint) {
00964
00965 if (itPfGsfPoint->isValid()){
00966 int layGsfP = itPfGsfPoint->layer();
00967 if (layGsfP == -1) PassTracker = true;
00968 if (PassTracker && layGsfP > 0 && GetPout == false) {
00969 IndexPout = c_gsf-1;
00970 GetPout = true;
00971 }
00972
00973 ++c_gsf;
00974 }
00975 }
00976 math::XYZTLorentzVector pin = PfGsfPoint[0].momentum();
00977 math::XYZTLorentzVector pout = PfGsfPoint[IndexPout].momentum();
00978
00979
00980
00981 gsfEl = new reco::PFBlockElementGsfTrack(refgsf, pin, pout);
00982
00983 bool valuegsf = true;
00984
00985 gsfEl->setTrackType(reco::PFBlockElement::T_FROM_GAMMACONV, valuegsf);
00986
00987
00988
00989 elements_.push_back( gsfEl);
00990 std::vector<reco::PFBrem> pfbrem = refgsf->PFRecBrem();
00991
00992 for (unsigned i2=0;i2<pfbrem.size(); ++i2) {
00993 const double DP = pfbrem[i2].DeltaP();
00994 const double SigmaDP = pfbrem[i2].SigmaDeltaP();
00995 const unsigned int TrajP = pfbrem[i2].indTrajPoint();
00996 if(TrajP == 99) continue;
00997
00998 reco::PFBlockElement* bremEl;
00999 bremEl = new reco::PFBlockElementBrem(refgsf,DP,SigmaDP,TrajP);
01000 elements_.push_back(bremEl);
01001
01002 }
01003 }
01004 }
01005
01006
01007
01008
01009
01010 if(ecalh.isValid() ) {
01011
01012
01013 bNoSuperclus_ = (superClusters_.size() == 0);
01014 if (!bNoSuperclus_) pfcSCVec_.resize(ecalh->size(),-1);
01015
01016
01017 for(unsigned i=0;i<ecalh->size(); ++i) {
01018
01019
01020 if( !ecalMask.empty() &&
01021 !ecalMask[i] ) continue;
01022
01023 reco::PFClusterRef ref( ecalh,i );
01024 reco::PFBlockElement* te
01025 = new reco::PFBlockElementCluster( ref,
01026 reco::PFBlockElement::ECAL);
01027 elements_.push_back( te );
01028
01029 if (!bNoSuperclus_) {
01030
01031
01032 int scindex= ClusterClusterMapping::checkOverlap(*ref,superClusters_);
01033
01034 if(scindex>=0) {
01035 pfcSCVec_[ref.key()]=scindex;
01036 scpfcRefs_[scindex].push_back(ref);
01037 }
01038 }
01039
01040 }
01041
01042 bNoSuperclus_ = (scpfcRefs_.size() == 0);
01043
01044 }
01045
01046
01047
01048 if(hcalh.isValid() ) {
01049
01050 for(unsigned i=0;i<hcalh->size(); ++i) {
01051
01052
01053 if( !hcalMask.empty() &&
01054 !hcalMask[i] ) continue;
01055
01056 reco::PFClusterRef ref( hcalh,i );
01057 reco::PFBlockElement* th
01058 = new reco::PFBlockElementCluster( ref,
01059 reco::PFBlockElement::HCAL );
01060 elements_.push_back( th );
01061 }
01062 }
01063
01064
01065
01066 if(useHO_ && hoh.isValid() ) {
01067
01068 for(unsigned i=0;i<hoh->size(); ++i) {
01069
01070
01071 if( !hoMask.empty() &&
01072 !hoMask[i] ) continue;
01073
01074 reco::PFClusterRef ref( hoh,i );
01075 reco::PFBlockElement* th
01076 = new reco::PFBlockElementCluster( ref,
01077 reco::PFBlockElement::HO );
01078 elements_.push_back( th );
01079 }
01080 }
01081
01082
01083
01084 if(hfemh.isValid() ) {
01085
01086 for(unsigned i=0;i<hfemh->size(); ++i) {
01087
01088
01089 if( !hfemMask.empty() &&
01090 !hfemMask[i] ) continue;
01091
01092 reco::PFClusterRef ref( hfemh,i );
01093 reco::PFBlockElement* th
01094 = new reco::PFBlockElementCluster( ref,
01095 reco::PFBlockElement::HFEM );
01096 elements_.push_back( th );
01097 }
01098 }
01099
01100
01101
01102
01103 if(hfhadh.isValid() ) {
01104
01105 for(unsigned i=0;i<hfhadh->size(); ++i) {
01106
01107
01108 if( !hfhadMask.empty() &&
01109 !hfhadMask[i] ) continue;
01110
01111 reco::PFClusterRef ref( hfhadh,i );
01112 reco::PFBlockElement* th
01113 = new reco::PFBlockElementCluster( ref,
01114 reco::PFBlockElement::HFHAD );
01115 elements_.push_back( th );
01116 }
01117 }
01118
01119
01120
01121
01122
01123
01124 if(psh.isValid() ) {
01125 for(unsigned i=0;i<psh->size(); ++i) {
01126
01127
01128 if( !psMask.empty() &&
01129 !psMask[i] ) continue;
01130 reco::PFBlockElement::Type type = reco::PFBlockElement::NONE;
01131 reco::PFClusterRef ref( psh,i );
01132
01133
01134 switch(ref->layer()){
01135 case PFLayer::PS1:
01136 type = reco::PFBlockElement::PS1;
01137 break;
01138 case PFLayer::PS2:
01139 type = reco::PFBlockElement::PS2;
01140 break;
01141 default:
01142 break;
01143 }
01144 reco::PFBlockElement* tp
01145 = new reco::PFBlockElementCluster( ref,
01146 type );
01147 elements_.push_back( tp );
01148 }
01149 }
01150
01151
01152
01153
01154
01155
01156
01157 for (std::list< reco::PFBlockElement* >::iterator it = elements_.begin();
01158 it != elements_.end(); ++it) {
01159 switch ((*it)->type()){
01160
01161 case reco::PFBlockElement::TRACK:
01162 if (useKDTreeTrackEcalLinker_) {
01163 if ( (*it)->trackRefPF()->extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() )
01164 TELinker_.insertTargetElt(*it);
01165 if ( (*it)->trackRefPF()->extrapolatedPoint( reco::PFTrajectoryPoint::HCALEntrance ).isValid() )
01166 THLinker_.insertTargetElt(*it);
01167 }
01168
01169 break;
01170
01171 case reco::PFBlockElement::PS1:
01172 case reco::PFBlockElement::PS2:
01173 if (useKDTreeTrackEcalLinker_)
01174 PSELinker_.insertTargetElt(*it);
01175 break;
01176
01177 case reco::PFBlockElement::HCAL:
01178 if (useKDTreeTrackEcalLinker_)
01179 THLinker_.insertFieldClusterElt(*it);
01180 break;
01181
01182 case reco::PFBlockElement::HO:
01183 if (useHO_ && useKDTreeTrackEcalLinker_) {
01184
01185 }
01186 break;
01187
01188
01189 case reco::PFBlockElement::ECAL:
01190 if (useKDTreeTrackEcalLinker_) {
01191 TELinker_.insertFieldClusterElt(*it);
01192 PSELinker_.insertFieldClusterElt(*it);
01193 }
01194 break;
01195
01196 default:
01197 break;
01198 }
01199 }
01200 }
01201
01202
01203 template< template<typename> class T>
01204 void PFBlockAlgo::fillFromPhoton(const T<reco::PhotonCollection> & egh, unsigned isc, reco::PFBlockElementSuperCluster * pfbe) {
01205 reco::PhotonRef photonRef(egh,isc);
01206 pfbe->setTrackIso(photonRef->trkSumPtHollowConeDR04());
01207 pfbe->setEcalIso(photonRef->ecalRecHitSumEtConeDR04());
01208 pfbe->setHcalIso(photonRef->hcalTowerSumEtConeDR04());
01209 pfbe->setHoE(photonRef->hadronicOverEm());
01210 pfbe->setPhotonRef(photonRef);
01211 pfbe->setFromPhoton(true);
01212 }
01213
01214 #endif
01215
01216