CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoParticleFlow/PFProducer/interface/PFBlockAlgo.h

Go to the documentation of this file.
00001 #ifndef RecoParticleFlow_PFProducer_PFBlockAlgo_h
00002 #define RecoParticleFlow_PFProducer_PFBlockAlgo_h 
00003 
00004 #include <set>
00005 #include <vector>
00006 #include <iostream>
00007 
00008 // #include "FWCore/Framework/interface/Handle.h"
00009 #include "DataFormats/Common/interface/Handle.h"
00010 // #include "FWCore/Framework/interface/OrphanHandle.h"
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" // gouzevitch
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 // Glowinski & Gouzevitch
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 // !Glowinski & Gouzevitch
00038 
00039 // #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
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   // Glowinski & Gouzevitch
00091   void setUseOptimization(bool useKDTreeTrackEcalLinker);
00092   // ! Glowinski & Gouzevitch
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     //T<reco::MuonCollection> muonh;
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   /*   const  reco::PFBlockCollection& blocks() const {return *blocks_;} */
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   // PFResolutionMap* openResolutionMap(const char* resMapName);
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   // std::vector< reco::PFCandidate >   particles_;
00312 
00313   // the test elements will be transferred to the blocks
00314   std::list< reco::PFBlockElement* >     elements_;
00315 
00316   // Glowinski & Gouzevitch
00317   bool useKDTreeTrackEcalLinker_;
00318   KDTreeLinkerTrackEcal TELinker_;
00319   KDTreeLinkerTrackHcal THLinker_;
00320   KDTreeLinkerPSEcal    PSELinker_;
00321   // !Glowinski & Gouzevitch
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   // This parameters defines the level of purity of
00341   // nuclear interactions choosen.
00342   // Level 1 is only high Purity sample labeled as isNucl.
00343   // Level 2 isNucl + isNucl_Loose (2 secondary tracks vertices)
00344   // Level 3 isNucl + isNucl_Loose + isNucl_Kink
00345   //         (low purity sample made of 1 primary and 1 secondary track)
00346   // By default the level 1 is teh safest one.
00347   int nuclearInteractionsPurity_;
00348 
00350   bool  useConvBremPFRecTracks_;
00351 
00353   const PhotonSelectorAlgo * photonSelector_;
00355   std::vector<reco::SuperClusterRef > superClusters_;
00356 
00358   //  std::map<reco::PFClusterRef,int>  pfcRefSCMap_;
00359   std::vector<int> pfcSCVec_;
00360 
00361   // A boolean to avoid to compare ECAL and ECAl if there i no superclusters in the event
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   // Create links between tracks or HCAL clusters, and HO clusters
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   if (nucleartrackh.isValid()){
00437     for(unsigned i=0;i<nucleartrackh->size(); i++) {
00438       reco::PFRecTrackRef trackRef(nucleartrackh,i);
00439       std::cout << *trackRef << std::endl;
00440     }
00441   }
00442   */
00443 
00445   std::vector<reco::PFRecTrackRef> convBremPFRecTracks;
00446   convBremPFRecTracks.clear();
00447   // Super cluster mapping
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       // retrieve and save the SC if ECAL-driven - Florian
00463       if(gsf->extra().isAvailable() && gsf->extra()->seedRef().isAvailable()) {
00464         reco::ElectronSeedRef seedRef=  gsf->extra()->seedRef().castTo<reco::ElectronSeedRef>();
00465         // check that the seed is valid
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             // not present, add it
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 // it is already present, update the PFBE
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                     //              std::cout << " Updating element to add electron information" << std::endl;
00488                   }
00489 //              else
00490 //                {
00491 //                  std::cout << " Missing element " << std::endl;
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           //const math::XYZTLorentzVector GsfMoment = itPfGsfPoint->momentum();
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       //      std::cout << " Selected a supercluster" << std::endl;
00564       // Add only the super clusters not already included 
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               //              std::cout << " Updating element to add Photon information " << photonSelector_->passPhotonSelection((*egphh)[isc]) << std::endl;
00585 
00586             }
00587 //        else
00588 //          {
00589 //            std::cout << " Missing element " << std::endl;
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       //if(!photonSelector_->passPhotonSelection((*egphh)[isc])) continue;
00614       
00615       //      std::cout << " Selected a supercluster" << std::endl;
00616       // Add only the super clusters not already included 
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           //fillFromPhoton(egphh,isc,sce);
00625           //sce->setFromPhoton(true);
00626           elements_.push_back(sce);
00627         }
00628 //       else
00629 //      {
00630 //        PFBlockElementSCEqual myEqual(scRef);
00631 //        std::list<reco::PFBlockElement*>::iterator itcheck=find_if(elements_.begin(),elements_.end(),myEqual);
00632 //        if(itcheck!=elements_.end())
00633 //          {
00634 //            reco::PFBlockElementSuperCluster* thePFBE=dynamic_cast<reco::PFBlockElementSuperCluster*>(*itcheck);
00635 //            //fillFromPhoton(egphh,isc,thePFBE);
00636 //            //thePFBE->setFromPhoton(true);
00637 //            //              std::cout << " Updating element to add Photon information " << photonSelector_->passPhotonSelection((*egphh)[isc]) << std::endl;
00638 // 
00639 //          }
00640 // //     else
00641 // //       {
00642 // //         std::cout << " Missing element " << std::endl;
00643 // //       }
00644 //      }
00645     }
00646   }  
00647   
00648   // set the vector to the right size so to allow random access
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       //      std::cout << "Nuclear Interactions Purity " <<  nuclearInteractionsPurity_ << std::endl;
00739       //     dispacedVertexRef->displacedVertexRef()->Dump();
00740       //bool bIncludeVertices = true;
00741       // We add a cut at rho > 2.7 since this corresponds to the lower edge of the beam pipe
00742       // This cut have to be changer when a new beam pipe would be installed
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           // This peace of code looks weired at first but it seems to be necessary to let 
00766           // PFRooTEvent work properly. Since the track position called REPPoint is transient 
00767           // it has to be calculated and the PFRecTrack collection associted to Displaced Vertex is not
00768           // anymore the original collection. So here we match both collections if possible
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       // this track has been disabled
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       // Get the eventual muon associated to this track
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       // Reject bad tracks (except if identified as muon
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         // if a muon has been found
00900         reco::MuonRef muonref( muonh, muId_ );
00901 
00902         // If this track was already added to the collection, we just need to find the associated element and 
00903         // attach to it the reference
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       // set track type T_FROM_GAMMA for pfrectracks associated to conv brems
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   // -------------- GSF tracks and brems for Conversion Recovery ----------
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           //const math::XYZTLorentzVector GsfMoment = itPfGsfPoint->momentum();
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       // IMPORTANT SET T_FROM_GAMMACONV trackType() FOR CONVERSIONS
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   // -------------- ECAL clusters ---------------------
01008 
01009 
01010   if(ecalh.isValid() ) {
01011     //  pfcSCVec_.resize(ecalh->size(),-1);
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       // this ecal cluster has been disabled
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         // Now mapping with Superclusters
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   // -------------- HCAL clusters ---------------------
01047 
01048   if(hcalh.isValid() ) {
01049     
01050     for(unsigned i=0;i<hcalh->size(); ++i)  {
01051       
01052       // this hcal cluster has been disabled
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   // -------------- HO clusters ---------------------
01065 
01066   if(useHO_ && hoh.isValid() ) {
01067     
01068     for(unsigned i=0;i<hoh->size(); ++i)  {
01069       
01070       // this hcal cluster has been disabled
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   // -------------- HFEM clusters ---------------------
01083 
01084   if(hfemh.isValid() ) {
01085     
01086     for(unsigned i=0;i<hfemh->size(); ++i)  {
01087       
01088       // this hfem cluster has been disabled
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   // -------------- HFHAD clusters ---------------------
01102 
01103   if(hfhadh.isValid() ) {
01104     
01105     for(unsigned i=0;i<hfhadh->size(); ++i)  {
01106       
01107       // this hfhad cluster has been disabled
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   // -------------- PS clusters ---------------------
01123 
01124   if(psh.isValid() ) {
01125     for(unsigned i=0;i<psh->size(); ++i)  {
01126 
01127       // this ps cluster has been disabled
01128       if( !psMask.empty() &&
01129           !psMask[i] ) continue;
01130       reco::PFBlockElement::Type type = reco::PFBlockElement::NONE;
01131       reco::PFClusterRef ref( psh,i );
01132       // two types of elements:  PS1 (V) and PS2 (H) 
01133       // depending on layer:  PS1 or PS2
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   // -------------- Loop over block elements ---------------------
01153 
01154   // Here we provide to all KDTree linkers the collections to link.
01155   // Glowinski & Gouzevitch
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         // THLinker_.insertFieldClusterElt(*it);
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