CMS 3D CMS Logo

Public Types | Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | Friends

PFBlockAlgo Class Reference

Particle Flow Algorithm. More...

#include <PFBlockAlgo.h>

List of all members.

Public Types

typedef
reco::PFBlockCollection::const_iterator 
IBC
typedef std::list
< reco::PFBlockElement * >
::iterator 
IE
 define these in *Fwd files in DataFormats/ParticleFlowReco?
typedef std::list
< reco::PFBlockElement * >
::const_iterator 
IEC
typedef std::vector< bool > Mask

Public Member Functions

const std::auto_ptr
< reco::PFBlockCollection > & 
blocks () const
void findBlocks ()
 build blocks
 PFBlockAlgo ()
void setDebug (bool debug)
 sets debug printout flag
template<template< typename > class T>
void setInput (const T< reco::PFRecTrackCollection > &trackh, const T< reco::GsfPFRecTrackCollection > &gsftrackh, const T< reco::GsfPFRecTrackCollection > &convbremgsftrackh, const T< reco::MuonCollection > &muonh, const T< reco::PFDisplacedTrackerVertexCollection > &nuclearh, const T< reco::PFRecTrackCollection > &nucleartrackh, const T< reco::PFConversionCollection > &conv, const T< reco::PFV0Collection > &v0, const T< reco::PFClusterCollection > &ecalh, const T< reco::PFClusterCollection > &hcalh, const T< reco::PFClusterCollection > &hfemh, const T< reco::PFClusterCollection > &hfhadh, const T< reco::PFClusterCollection > &psh, const T< reco::PhotonCollection > &egphh, const Mask &trackMask=dummyMask_, const Mask &gsftrackMask=dummyMask_, const Mask &ecalMask=dummyMask_, const Mask &hcalMask=dummyMask_, const Mask &hfemMask=dummyMask_, const Mask &hfhadMask=dummyMask_, const Mask &psMask=dummyMask_, const Mask &phMask=dummyMask_)
 set input collections of tracks and clusters
template<template< typename > class T>
void setInput (const T< reco::PFRecTrackCollection > &trackh, const T< reco::MuonCollection > &muonh, const T< reco::PFClusterCollection > &ecalh, const T< reco::PFClusterCollection > &hcalh, const T< reco::PFClusterCollection > &hfemh, const T< reco::PFClusterCollection > &hfhadh, const T< reco::PFClusterCollection > &psh, const Mask &trackMask=dummyMask_, const Mask &ecalMask=dummyMask_, const Mask &hcalMask=dummyMask_, const Mask &psMask=dummyMask_)
 COLIN: I think this is for particle flow at HLT...
template<template< typename > class T>
void setInput (const T< reco::PFRecTrackCollection > &trackh, const T< reco::GsfPFRecTrackCollection > &gsftrackh, const T< reco::PFClusterCollection > &ecalh, const T< reco::PFClusterCollection > &hcalh, const T< reco::PFClusterCollection > &psh, const Mask &trackMask=dummyMask_, const Mask &gsftrackMask=dummyMask_, const Mask &ecalMask=dummyMask_, const Mask &hcalMask=dummyMask_, const Mask &psMask=dummyMask_)
 COLIN: what is this setinput function for? can it be removed?
void setParameters (std::vector< double > &DPtovPtCut, std::vector< unsigned > &NHitCut, bool useConvBremPFRecTracks, bool useIterTracking, int nuclearInteractionsPurity, bool useEGPhotons, std::vector< double > &photonSelectionCuts)
std::auto_ptr
< reco::PFBlockCollection
transferBlocks ()
 ~PFBlockAlgo ()

Private Member Functions

IE associate (IE next, IE last, std::vector< PFBlockLink > &links)
void buildGraph ()
void checkDisplacedVertexLinks (reco::PFBlock &block) const
 remove extra links between primary track and clusters
void checkMaskSize (const reco::PFRecTrackCollection &tracks, const reco::GsfPFRecTrackCollection &gsftracks, const reco::PFClusterCollection &ecals, const reco::PFClusterCollection &hcals, const reco::PFClusterCollection &hfems, const reco::PFClusterCollection &hfhads, const reco::PFClusterCollection &pss, const reco::PhotonCollection &egphh, const Mask &trackMask, const Mask &gsftrackMask, const Mask &ecalMask, const Mask &hcalMask, const Mask &hfemMask, const Mask &hfhadMask, const Mask &psMask, const Mask &phMask) const
void fillFromPhoton (const reco::Photon &photon, reco::PFBlockElementSuperCluster *pfbe)
bool goodPtResolution (const reco::TrackRef &trackref)
 open a resolution map
void link (const reco::PFBlockElement *el1, const reco::PFBlockElement *el2, PFBlockLink::Type &linktype, reco::PFBlock::LinkTest &linktest, double &dist) const
 check whether 2 elements are linked. Returns distance and linktype
int muAssocToTrack (const reco::TrackRef &trackref, const edm::OrphanHandle< reco::MuonCollection > &muonh) const
int muAssocToTrack (const reco::TrackRef &trackref, const edm::Handle< reco::MuonCollection > &muonh) const
void packLinks (reco::PFBlock &block, const std::vector< PFBlockLink > &links) const
double testECALAndHCAL (const reco::PFCluster &ecal, const reco::PFCluster &hcal) const
double testLinkBySuperCluster (const reco::PFClusterRef &elt1, const reco::PFClusterRef &elt2) const
 test association by Supercluster between two ECAL
double testLinkByVertex (const reco::PFBlockElement *elt1, const reco::PFBlockElement *elt2) const
double testPS1AndPS2 (const reco::PFCluster &ps1, const reco::PFCluster &ps2) const
double testSuperClusterPFCluster (const reco::SuperClusterRef &sct1, const reco::PFClusterRef &elt2) const
 test association between SuperClusters and ECAL
double testTrackAndPS (const reco::PFRecTrack &track, const reco::PFCluster &ps) const

Private Attributes

std::auto_ptr
< reco::PFBlockCollection
blocks_
bool debug_
 if true, debug printouts activated
std::vector< double > DPtovPtCut_
 DPt/Pt cut for creating atrack element.
std::list< reco::PFBlockElement * > elements_
 actually, particles will be created by a separate producer
std::vector< unsigned > NHitCut_
 Number of layers crossed cut for creating atrack element.
int nuclearInteractionsPurity_
std::vector< int > pfcSCVec_
 SC corresponding to the PF cluster.
const PhotonSelectorAlgophotonSelector_
 PhotonSelector.
std::vector< std::vector
< reco::PFClusterRef > > 
scpfcRefs_
 PF clusters corresponding to a given SC.
std::vector
< reco::SuperClusterRef
superClusters_
 list of superclusters
bool useConvBremPFRecTracks_
 switch on/off Conversions Brem Recovery with KF Tracks
bool useEGPhotons_
 Flag to turn off the import of EG Photons.
bool useIterTracking_
 Flag to turn off quality cuts which require iterative tracking (for heavy-ions)

Static Private Attributes

static const Mask dummyMask_

Friends

std::ostream & operator<< (std::ostream &, const PFBlockAlgo &)

Detailed Description

Particle Flow Algorithm.

Author:
Colin Bernet
Date:
January 2006

Definition at line 64 of file PFBlockAlgo.h.


Member Typedef Documentation

typedef reco::PFBlockCollection::const_iterator PFBlockAlgo::IBC

Definition at line 177 of file PFBlockAlgo.h.

typedef std::list< reco::PFBlockElement* >::iterator PFBlockAlgo::IE

define these in *Fwd files in DataFormats/ParticleFlowReco?

Definition at line 175 of file PFBlockAlgo.h.

typedef std::list< reco::PFBlockElement* >::const_iterator PFBlockAlgo::IEC

Definition at line 176 of file PFBlockAlgo.h.

typedef std::vector<bool> PFBlockAlgo::Mask

Definition at line 82 of file PFBlockAlgo.h.


Constructor & Destructor Documentation

PFBlockAlgo::PFBlockAlgo ( )

Definition at line 21 of file PFBlockAlgo.cc.

                         : 
  blocks_( new reco::PFBlockCollection ),
  DPtovPtCut_(std::vector<double>(4,static_cast<double>(999.))),
  NHitCut_(std::vector<unsigned int>(4,static_cast<unsigned>(0))), 
  useIterTracking_(true),
  photonSelector_(0),
  debug_(false) {}
PFBlockAlgo::~PFBlockAlgo ( )

Definition at line 54 of file PFBlockAlgo.cc.

References gather_cfg::cout, debug_, elements_, and photonSelector_.

                          {

#ifdef PFLOW_DEBUG
  if(debug_)
    cout<<"~PFBlockAlgo - number of remaining elements: "
        <<elements_.size()<<endl;
#endif

  if(photonSelector_) delete photonSelector_;
}

Member Function Documentation

IE PFBlockAlgo::associate ( IE  next,
IE  last,
std::vector< PFBlockLink > &  links 
) [private]

recursive procedure which adds elements from elements_ to the current block, ie blocks_->back(). the resulting links between elements are stored in links, not in the block. afterwards, packLinks( reco::PFBlock& block, const vector<PFBlockLink>& links) has to be called in order to pack the link information in the block.

Referenced by TrackDetectorAssociator::associate(), and findBlocks().

const std::auto_ptr< reco::PFBlockCollection >& PFBlockAlgo::blocks ( ) const [inline]
Returns:
collection of blocks

Definition at line 168 of file PFBlockAlgo.h.

References blocks_.

Referenced by operator<<().

    {return blocks_;}
void PFBlockAlgo::buildGraph ( ) [private]

COLIN: not used. Could be removed. Could also be implemented, to produce a graph of a block, Showing the connections between the elements

Definition at line 284 of file PFBlockAlgo.cc.

                        {
  // loop on all blocks and create a big graph
}
void PFBlockAlgo::checkDisplacedVertexLinks ( reco::PFBlock block) const [private]

remove extra links between primary track and clusters

Definition at line 1156 of file PFBlockAlgo.cc.

References reco::PFBlock::associatedElements(), reco::PFBlock::elements(), asciidump::els, reco::PFBlock::linkData(), reco::PFBlock::LINKTEST_ALL, reco::PFBlock::setLink(), edm::OwnVector< T, P >::size(), and reco::PFBlockElement::TRACK.

                                                                 {
  // method which removes link between primary tracks and the clusters
  
  typedef std::multimap<double, unsigned>::iterator IE;

  const edm::OwnVector< reco::PFBlockElement >& els = block.elements();
  // loop on all elements != TRACK
  for( unsigned i1=0; i1 != els.size(); ++i1 ) {
    if( els[i1].type() == PFBlockElement::TRACK ) continue;
    std::multimap<double, unsigned> assocTracks;
    // get associated tracks
    block.associatedElements( i1,  block.linkData(),
                              assocTracks,
                              reco::PFBlockElement::TRACK,
                              reco::PFBlock::LINKTEST_ALL );
    for( IE ie = assocTracks.begin(); ie != assocTracks.end(); ++ie) {
      //double   distprim  = ie->first;
      unsigned iprim     = ie->second;
      // if this track a primary track (T_TO_DISP)
      // the new strategy gouzevitch: remove all the links from primary track
      if( els[iprim].isPrimary()) {

            block.setLink( i1, iprim, -1, block.linkData(),
                           PFBlock::LINKTEST_RECHIT );      
      }
    } // loop on all associated tracks
  } // loop on all elements
 
}
void PFBlockAlgo::checkMaskSize ( const reco::PFRecTrackCollection tracks,
const reco::GsfPFRecTrackCollection gsftracks,
const reco::PFClusterCollection ecals,
const reco::PFClusterCollection hcals,
const reco::PFClusterCollection hfems,
const reco::PFClusterCollection hfhads,
const reco::PFClusterCollection pss,
const reco::PhotonCollection egphh,
const Mask trackMask,
const Mask gsftrackMask,
const Mask ecalMask,
const Mask hcalMask,
const Mask hfemMask,
const Mask hfhadMask,
const Mask psMask,
const Mask phMask 
) const [private]

checks size of the masks with respect to the vectors they refer to. throws std::length_error if one of the masks has the wrong size

Definition at line 928 of file PFBlockAlgo.cc.

Referenced by setInput().

                                                      {

  if( !trackMask.empty() && 
      trackMask.size() != tracks.size() ) {
    string err = "PFBlockAlgo::setInput: ";
    err += "The size of the track mask is different ";
    err += "from the size of the track vector.";
    throw std::length_error( err.c_str() );
  }

  if( !gsftrackMask.empty() && 
      gsftrackMask.size() != gsftracks.size() ) {
    string err = "PFBlockAlgo::setInput: ";
    err += "The size of the gsf track mask is different ";
    err += "from the size of the gsftrack vector.";
    throw std::length_error( err.c_str() );
  }

  if( !ecalMask.empty() && 
      ecalMask.size() != ecals.size() ) {
    string err = "PFBlockAlgo::setInput: ";
    err += "The size of the ecal mask is different ";
    err += "from the size of the ecal clusters vector.";
    throw std::length_error( err.c_str() );
  }
  
  if( !hcalMask.empty() && 
      hcalMask.size() != hcals.size() ) {
    string err = "PFBlockAlgo::setInput: ";
    err += "The size of the hcal mask is different ";
    err += "from the size of the hcal clusters vector.";
    throw std::length_error( err.c_str() );
  }

  if( !hfemMask.empty() && 
      hfemMask.size() != hfems.size() ) {
    string err = "PFBlockAlgo::setInput: ";
    err += "The size of the hfem mask is different ";
    err += "from the size of the hfem clusters vector.";
    throw std::length_error( err.c_str() );
  }

  if( !hfhadMask.empty() && 
      hfhadMask.size() != hfhads.size() ) {
    string err = "PFBlockAlgo::setInput: ";
    err += "The size of the hfhad mask is different ";
    err += "from the size of the hfhad clusters vector.";
    throw std::length_error( err.c_str() );
  }

  if( !psMask.empty() && 
      psMask.size() != pss.size() ) {
    string err = "PFBlockAlgo::setInput: ";
    err += "The size of the ps mask is different ";
    err += "from the size of the ps clusters vector.";
    throw std::length_error( err.c_str() );
  }
  
    if( !phMask.empty() && 
      phMask.size() != egphh.size() ) {
    string err = "PFBlockAlgo::setInput: ";
    err += "The size of the photon mask is different ";
    err += "from the size of the photon vector.";
    throw std::length_error( err.c_str() );
  }

}
void PFBlockAlgo::fillFromPhoton ( const reco::Photon photon,
reco::PFBlockElementSuperCluster pfbe 
) [private]
void PFBlockAlgo::findBlocks ( )

build blocks

Definition at line 66 of file PFBlockAlgo.cc.

References associate(), blocks_, gather_cfg::cout, debug_, elements_, and packLinks().

Referenced by PFRootEventManager::particleFlow().

                        {

  //  cout<<"findBlocks : "<<blocks_.get()<<endl;
  
  // the blocks have not been passed to the event, and need to be cleared
  if(blocks_.get() )blocks_->clear();
  else 
    blocks_.reset( new reco::PFBlockCollection );

  blocks_->reserve(elements_.size());
  for(IE ie = elements_.begin(); 
      ie != elements_.end();) {
    
#ifdef PFLOW_DEBUG
    if(debug_) {
      cout<<" PFBlockAlgo::findBlocks() ----------------------"<<endl;
      cout<<" element "<<**ie<<endl;
      cout<<" creating new block"<<endl;
    }
#endif
    
    blocks_->push_back( PFBlock() );
    
    vector< PFBlockLink > links;

    //    list< IE > used;
    ie = associate( elements_.end() , ie, links );

    // build remaining links in current block
    packLinks( blocks_->back(), links );
  }       
}
bool PFBlockAlgo::goodPtResolution ( const reco::TrackRef trackref) [private]

open a resolution map

check the Pt resolution

Definition at line 1048 of file PFBlockAlgo.cc.

References gather_cfg::cout, debug_, DPtovPtCut_, NHitCut_, P, reco::tau::disc::Pt(), mathSSE::sqrt(), and useIterTracking_.

Referenced by setInput().

                                                           {

  double P = trackref->p();
  double Pt = trackref->pt();
  double DPt = trackref->ptError();
  unsigned int NHit = trackref->hitPattern().trackerLayersWithMeasurement();
  unsigned int NLostHit = trackref->hitPattern().trackerLayersWithoutMeasurement();
  unsigned int LostHits = trackref->numberOfLostHits();
  double sigmaHad = sqrt(1.20*1.20/P+0.06*0.06) / (1.+LostHits);

  // iteration 1,2,3,4,5 correspond to algo = 1/4,5,6,7,8,9
  unsigned int Algo = 0; 
  switch (trackref->algo()) {
  case TrackBase::ctf:
  case TrackBase::iter0:
  case TrackBase::iter1:
    Algo = 0;
    break;
  case TrackBase::iter2:
    Algo = 1;
    break;
  case TrackBase::iter3:
    Algo = 2;
    break;
  case TrackBase::iter4:
    Algo = 3;
    break;
  case TrackBase::iter5:
    Algo = 4;
    break;
  default:
    Algo = useIterTracking_ ? 5 : 0;
    break;
  }

  // Protection against 0 momentum tracks
  if ( P < 0.05 ) return false;

  // Temporary : Reject all tracking iteration beyond 5th step. 
  if ( Algo > 4 ) return false;
 
  if (debug_) cout << " PFBlockAlgo: PFrecTrack->Track Pt= "
                   << Pt << " DPt = " << DPt << endl;
  if ( ( DPtovPtCut_[Algo] > 0. && 
         DPt/Pt > DPtovPtCut_[Algo]*sigmaHad ) || 
       NHit < NHitCut_[Algo] ) { 
    // (Algo >= 3 && LostHits != 0) ) {
    if (debug_) cout << " PFBlockAlgo: skip badly measured track"
                     << ", P = " << P 
                     << ", Pt = " << Pt 
                     << " DPt = " << DPt 
                     << ", N(hits) = " << NHit << " (Lost : " << LostHits << "/" << NLostHit << ")"
                     << ", Algo = " << Algo
                     << endl;
    if (debug_) cout << " cut is DPt/Pt < " << DPtovPtCut_[Algo] * sigmaHad << endl;
    if (debug_) cout << " cut is NHit >= " << NHitCut_[Algo] << endl;
    /*
    std::cout << "Track REJECTED : ";
    std::cout << ", P = " << P 
              << ", Pt = " << Pt 
              << " DPt = " << DPt 
              << ", N(hits) = " << NHit << " (Lost : " << LostHits << "/" << NLostHit << ")"
              << ", Algo = " << Algo
              << std::endl;
    */
    return false;
  }

  /*
  std::cout << "Track Accepted : ";
  std::cout << ", P = " << P 
       << ", Pt = " << Pt 
       << " DPt = " << DPt 
       << ", N(hits) = " << NHit << " (Lost : " << LostHits << "/" << NLostHit << ")"
       << ", Algo = " << Algo
       << std::endl;
  */
  return true;
}
void PFBlockAlgo::link ( const reco::PFBlockElement el1,
const reco::PFBlockElement el2,
PFBlockLink::Type linktype,
reco::PFBlock::LinkTest linktest,
double &  dist 
) const [private]

check whether 2 elements are linked. Returns distance and linktype

Definition at line 291 of file PFBlockAlgo.cc.

References reco::PFBlockElement::clusterRef(), gather_cfg::cout, debug_, ECAL, PFBlockLink::ECALandBREM, PFBlockLink::ECALandECAL, PFBlockLink::ECALandGSF, PFBlockLink::ECALandHCAL, PFBlockLink::GSFandBREM, PFBlockLink::GSFandGSF, reco::PFBlockElementBrem::GsftrackRefPF(), reco::PFBlockElementGsfTrack::GsftrackRefPF(), PFBlockLink::HCALandBREM, PFBlockLink::HCALandGSF, PFBlockLink::HFEMandHFHAD, reco::PFBlockElement::isLinkedToDisplacedVertex(), edm::Ref< C, T, F >::isNonnull(), edm::Ref< C, T, F >::isNull(), PFBlockLink::PS1andBREM, PFBlockLink::PS1andECAL, PFBlockLink::PS1andGSF, PFBlockLink::PS1andPS2, PFBlockLink::PS2andBREM, PFBlockLink::PS2andECAL, PFBlockLink::PS2andGSF, PFBlockLink::SCandECAL, reco::PFBlockElement::T_FROM_GAMMACONV, LinkByRecHit::testECALAndPSByRecHit(), LinkByRecHit::testHFEMAndHFHADByRecHit(), testLinkBySuperCluster(), testLinkByVertex(), testSuperClusterPFCluster(), LinkByRecHit::testTrackAndClusterByRecHit(), testTrackAndPS(), PFBlockLink::TRACKandECAL, PFBlockLink::TRACKandGSF, PFBlockLink::TRACKandHCAL, PFBlockLink::TRACKandPS1, PFBlockLink::TRACKandPS2, PFBlockLink::TRACKandTRACK, reco::PFBlockElement::trackRefPF(), reco::PFBlockElementGsfTrack::trackType(), reco::PFBlockElement::trackType(), reco::PFBlockElement::type(), and useConvBremPFRecTracks_.

Referenced by TrackDetectorAssociator::associate(), and PFDisplacedVertexCandidateFinder::packLinks().

                                       {
  


  dist=-1.;
  linktest = PFBlock::LINKTEST_RECHIT; //rechit by default 

  PFBlockElement::Type type1 = el1->type();
  PFBlockElement::Type type2 = el2->type();

  if( type1==type2 ) {
    // cannot link 2 elements of the same type. 
    // except if the elements are 2 tracks or 2 ECAL
    if( type1!=PFBlockElement::TRACK && type1!=PFBlockElement::GSF &&
        type1!=PFBlockElement::ECAL) {
      return;
    }

    // cannot link two primary tracks  (except if they come from a V0)
    if( type1 ==PFBlockElement::TRACK) {
      if ( !el1->isLinkedToDisplacedVertex() || !el2->isLinkedToDisplacedVertex()) 
      return;
    }
  }

  linktype = static_cast<PFBlockLink::Type>
    ((1<< (type1-1) ) | (1<< (type2-1) ));

  if(debug_ ) std::cout << " PFBlockAlgo links type1 " << type1 << " type2 " << type2 << std::endl;

  PFBlockElement::Type lowType = type1;
  PFBlockElement::Type highType = type2;
  const PFBlockElement* lowEl = el1;
  const PFBlockElement* highEl = el2;
  
  if(type1>type2) {
    lowType = type2;
    highType = type1;
    lowEl = el2;
    highEl = el1;
  }
  
  switch(linktype) {
  case PFBlockLink::TRACKandPS1:
  case PFBlockLink::TRACKandPS2:
    {
      //       cout<<"TRACKandPS"<<endl;
      PFRecTrackRef trackref = lowEl->trackRefPF();
      PFClusterRef  clusterref = highEl->clusterRef();
      assert( !trackref.isNull() );
      assert( !clusterref.isNull() );
      // PJ - 14-May-09 : A link by rechit is needed here !
      dist = testTrackAndPS( *trackref, *clusterref );
      linktest = PFBlock::LINKTEST_RECHIT;
      break;
    }
    
  case PFBlockLink::TRACKandECAL:
    {
      if(debug_ ) cout<<"TRACKandECAL"<<endl;
      PFRecTrackRef trackref = lowEl->trackRefPF();
      
      if(debug_ ) std::cout << " Track pt " << trackref->trackRef()->pt() << std::endl;
      
      PFClusterRef  clusterref = highEl->clusterRef();
      assert( !trackref.isNull() );
      assert( !clusterref.isNull() );
      dist = LinkByRecHit::testTrackAndClusterByRecHit( *trackref, *clusterref, false, debug_ );
      linktest = PFBlock::LINKTEST_RECHIT;

      if ( debug_ ) { 
        if( dist > 0. ) { 
          std::cout << " Here a link has been established"
                    << " between a track an Ecal with dist  " 
                    << dist <<  std::endl;
        } else {
          std::cout << " No link found " << std::endl;
        }
      }

      break;
    }
  case PFBlockLink::TRACKandHCAL:
    {
      //       cout<<"TRACKandHCAL"<<endl;
      PFRecTrackRef trackref = lowEl->trackRefPF();
      PFClusterRef  clusterref = highEl->clusterRef();
      assert( !trackref.isNull() );
      assert( !clusterref.isNull() );
      dist = LinkByRecHit::testTrackAndClusterByRecHit( *trackref, *clusterref, false, debug_ );
      linktest = PFBlock::LINKTEST_RECHIT;      
      break;
    }
  case PFBlockLink::ECALandHCAL:
    {
      //       cout<<"ECALandHCAL"<<endl;
      PFClusterRef  ecalref = lowEl->clusterRef();
      PFClusterRef  hcalref = highEl->clusterRef();
      assert( !ecalref.isNull() );
      assert( !hcalref.isNull() );
      // PJ - 14-May-09 : A link by rechit is needed here !
      // dist = testECALAndHCAL( *ecalref, *hcalref );
      dist = -1.;
      linktest = PFBlock::LINKTEST_RECHIT;
      break;
    }
  case PFBlockLink::PS1andECAL:
  case PFBlockLink::PS2andECAL:
    {
      //       cout<<"PSandECAL"<<endl;
      PFClusterRef  psref = lowEl->clusterRef();
      PFClusterRef  ecalref = highEl->clusterRef();
      assert( !psref.isNull() );
      assert( !ecalref.isNull() );
      dist = LinkByRecHit::testECALAndPSByRecHit( *ecalref, *psref ,debug_);
      linktest = PFBlock::LINKTEST_RECHIT;      
      break;
    }
  case PFBlockLink::PS1andPS2:
    {
      PFClusterRef  ps1ref = lowEl->clusterRef();
      PFClusterRef  ps2ref = highEl->clusterRef();
      assert( !ps1ref.isNull() );
      assert( !ps2ref.isNull() );
      // PJ - 14-May-09 : A link by rechit is needed here !
      // dist = testPS1AndPS2( *ps1ref, *ps2ref );
      dist = -1.;
      linktest = PFBlock::LINKTEST_RECHIT;
      break;
    }
  case PFBlockLink::TRACKandTRACK:
    {
      if(debug_ ) 
        cout<<"TRACKandTRACK"<<endl;
      dist = testLinkByVertex(lowEl, highEl);
      if(debug_ ) 
        std::cout << " PFBlockLink::TRACKandTRACK dist " << dist << std::endl;
      linktest = PFBlock::LINKTEST_RECHIT;
      break;
    }

  case PFBlockLink::ECALandECAL:
      {
        
        PFClusterRef  ecal1ref = lowEl->clusterRef();
        PFClusterRef  ecal2ref = highEl->clusterRef();
        assert( !ecal1ref.isNull() );
        assert( !ecal2ref.isNull() );
        if(debug_)
          cout << " PFBlockLink::ECALandECAL" << endl;
        dist = testLinkBySuperCluster(ecal1ref,ecal2ref);
        break;
      }

  case PFBlockLink::ECALandGSF:
    {
      PFClusterRef  clusterref = lowEl->clusterRef();
      assert( !clusterref.isNull() );
      const reco::PFBlockElementGsfTrack *  GsfEl =  dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
      const PFRecTrack * myTrack =  &(GsfEl->GsftrackPF());
      dist = LinkByRecHit::testTrackAndClusterByRecHit( *myTrack, *clusterref, false, debug_ );
      linktest = PFBlock::LINKTEST_RECHIT;
      
      if ( debug_ ) {
        if ( dist > 0. ) {
          std::cout << " Here a link has been established" 
                    << " between a GSF track an Ecal with dist  " 
                    << dist <<  std::endl;
        } else {
          if(debug_ ) std::cout << " No link found " << std::endl;
        }
      }
      break;
    }
  case PFBlockLink::TRACKandGSF:
    {
      PFRecTrackRef trackref = lowEl->trackRefPF();
      assert( !trackref.isNull() );
      const reco::PFBlockElementGsfTrack *  GsfEl =  
        dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
      GsfPFRecTrackRef gsfref = GsfEl->GsftrackRefPF();
      reco::TrackRef kftrackref= (*trackref).trackRef();
      assert( !gsfref.isNull() );
      PFRecTrackRef refkf = (*gsfref).kfPFRecTrackRef();
      if(refkf.isNonnull()) {
        reco::TrackRef gsftrackref = (*refkf).trackRef();
        if (gsftrackref.isNonnull()&&kftrackref.isNonnull()) {
          if (kftrackref == gsftrackref) { 
            dist = 0.001;
          } else { 
            dist = -1.;
          }
        } else { 
          dist = -1.;
        }
      } else {
        dist = -1.;
      }
      
      
      if(useConvBremPFRecTracks_) {
        if(lowEl->isLinkedToDisplacedVertex()){
          vector<PFRecTrackRef> pfrectrack_vec = GsfEl->GsftrackRefPF()->convBremPFRecTrackRef();
          if(pfrectrack_vec.size() > 0){
            for(unsigned int iconv = 0; iconv <  pfrectrack_vec.size(); iconv++) {
              if( lowEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)) {
                // use track ref
                if(kftrackref == (*pfrectrack_vec[iconv]).trackRef()) {         
                  dist = 0.001;
                }
              } 
              else{
                // use the track base ref
                reco::TrackBaseRef newTrackBaseRef((*pfrectrack_vec[iconv]).trackRef());
                reco::TrackBaseRef elemTrackBaseRef(kftrackref);              
                if(newTrackBaseRef == elemTrackBaseRef){
                  dist = 0.001;
                } 
              }
            }
          }
        }
      }
 

      break;      
    }
         
  case PFBlockLink::GSFandBREM:
    {
      const reco::PFBlockElementGsfTrack * GsfEl  =  dynamic_cast<const reco::PFBlockElementGsfTrack*>(lowEl);
      const reco::PFBlockElementBrem * BremEl =  dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
      GsfPFRecTrackRef gsfref = GsfEl->GsftrackRefPF();
      GsfPFRecTrackRef bremref = BremEl->GsftrackRefPF();
      assert( !gsfref.isNull() );
      assert( !bremref.isNull() );
      if (gsfref == bremref)  { 
        dist = 0.001;
      } else { 
        dist = -1.;
      }
      break;
    }
  case PFBlockLink::GSFandGSF:
    {
      const reco::PFBlockElementGsfTrack * lowGsfEl  =  
        dynamic_cast<const reco::PFBlockElementGsfTrack*>(lowEl);
      const reco::PFBlockElementGsfTrack * highGsfEl  =  
        dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
      
      GsfPFRecTrackRef lowgsfref = lowGsfEl->GsftrackRefPF();
      GsfPFRecTrackRef highgsfref = highGsfEl->GsftrackRefPF();
      assert( !lowgsfref.isNull() );
      assert( !highgsfref.isNull() );
      
      if( (lowGsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false && 
           highGsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)) ||
          (highGsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false && 
           lowGsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV))) {
        if(lowgsfref->trackId() == highgsfref->trackId()) {
          dist = 0.001;
        }
        else {
          dist = -1.;
        }
      }
      break;
    }
  case PFBlockLink::ECALandBREM:
    {
      PFClusterRef  clusterref = lowEl->clusterRef();
      assert( !clusterref.isNull() );
      const reco::PFBlockElementBrem * BremEl =  
        dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
      const PFRecTrack * myTrack = &(BremEl->trackPF());
      /*
      double DP = (BremEl->DeltaP())*(-1.);
      double SigmaDP = BremEl->SigmaDeltaP();
      double SignBremDp = DP/SigmaDP;
      */
      bool isBrem = true;
      dist = LinkByRecHit::testTrackAndClusterByRecHit( *myTrack, *clusterref, isBrem, debug_);
      if( debug_ && dist > 0. ) 
        std::cout << "ECALandBREM: dist testTrackAndClusterByRecHit " 
                  << dist << std::endl;
      linktest = PFBlock::LINKTEST_RECHIT;
      break;
    }
  case PFBlockLink::PS1andGSF:
  case PFBlockLink::PS2andGSF:
    {
      PFClusterRef  psref = lowEl->clusterRef();
      assert( !psref.isNull() );
      const reco::PFBlockElementGsfTrack *  GsfEl =  dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
      const PFRecTrack * myTrack =  &(GsfEl->GsftrackPF());
      // PJ - 14-May-09 : A link by rechit is needed here !
      dist = testTrackAndPS( *myTrack, *psref );
      linktest = PFBlock::LINKTEST_RECHIT;
      break;
    }
  case PFBlockLink::PS1andBREM:
  case PFBlockLink::PS2andBREM:
    {
      PFClusterRef  psref = lowEl->clusterRef();
      assert( !psref.isNull() );
      const reco::PFBlockElementBrem * BremEl =  dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
      const PFRecTrack * myTrack = &(BremEl->trackPF());
      // PJ - 14-May-09 : A link by rechit is needed here !
      dist = testTrackAndPS( *myTrack, *psref );
      linktest = PFBlock::LINKTEST_RECHIT;
      break;
    }
  case PFBlockLink::HCALandGSF:
    {
      PFClusterRef  clusterref = lowEl->clusterRef();
      assert( !clusterref.isNull() );
      const reco::PFBlockElementGsfTrack *  GsfEl =  dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
      const PFRecTrack * myTrack =  &(GsfEl->GsftrackPF());
      dist = LinkByRecHit::testTrackAndClusterByRecHit( *myTrack, *clusterref, false, debug_ );
      linktest = PFBlock::LINKTEST_RECHIT;
      break;
    }
  case PFBlockLink::HCALandBREM:
    {
      PFClusterRef  clusterref = lowEl->clusterRef();
      assert( !clusterref.isNull() );
      const reco::PFBlockElementBrem * BremEl =  dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
      const PFRecTrack * myTrack = &(BremEl->trackPF());
      bool isBrem = true;
      dist = LinkByRecHit::testTrackAndClusterByRecHit( *myTrack, *clusterref, isBrem, debug_);
      break;
    }
  case PFBlockLink::HFEMandHFHAD:
    {
      // cout<<"HFEMandHFHAD"<<endl;
      PFClusterRef  eref = lowEl->clusterRef();
      PFClusterRef  href = highEl->clusterRef();
      assert( !eref.isNull() );
      assert( !href.isNull() );
      dist = LinkByRecHit::testHFEMAndHFHADByRecHit( *eref, *href, debug_ );
      linktest = PFBlock::LINKTEST_RECHIT;
      break;
      
    }
  case PFBlockLink::SCandECAL:
    {
      PFClusterRef  clusterref = lowEl->clusterRef();

      assert( !clusterref.isNull() );
      
      const reco::PFBlockElementSuperCluster * scEl = 
        dynamic_cast<const reco::PFBlockElementSuperCluster*>(highEl);
      assert (!scEl->superClusterRef().isNull());
      dist = testSuperClusterPFCluster(scEl->superClusterRef(),
                                       clusterref);
      break;
    }
  default:
    dist = -1.;
    linktest = PFBlock::LINKTEST_RECHIT;
    // cerr<<"link type not implemented yet: 0x"<<hex<<linktype<<dec<<endl;
    // assert(0);
    return;
  }
}
int PFBlockAlgo::muAssocToTrack ( const reco::TrackRef trackref,
const edm::Handle< reco::MuonCollection > &  muonh 
) const [private]

Definition at line 1129 of file PFBlockAlgo.cc.

References edm::Ref< C, T, F >::isNonnull(), edm::HandleBase::isValid(), and j.

Referenced by setInput().

                                                                               {
  if(muonh.isValid() ) {
    for(unsigned j=0;j<muonh->size(); j++) {
      reco::MuonRef muonref( muonh, j );
      if (muonref->track().isNonnull()) 
        if( muonref->track() == trackref ) return j;
    }
  }
  return -1; // not found
}
int PFBlockAlgo::muAssocToTrack ( const reco::TrackRef trackref,
const edm::OrphanHandle< reco::MuonCollection > &  muonh 
) const [private]

Definition at line 1142 of file PFBlockAlgo.cc.

References edm::Ref< C, T, F >::isNonnull(), edm::OrphanHandleBase::isValid(), and j.

                                                                                     {
  if(muonh.isValid() ) {
    for(unsigned j=0;j<muonh->size(); j++) {
      reco::MuonRef muonref( muonh, j );
      if (muonref->track().isNonnull())
        if( muonref->track() == trackref ) return j;
    }
  }
  return -1; // not found
}
void PFBlockAlgo::packLinks ( reco::PFBlock block,
const std::vector< PFBlockLink > &  links 
) const [private]

compute missing links in the blocks (the recursive procedure does not build all links)

Referenced by findBlocks().

void PFBlockAlgo::setDebug ( bool  debug) [inline]

sets debug printout flag

Definition at line 160 of file PFBlockAlgo.h.

References debug, and debug_.

Referenced by PFRootEventManager::readOptions().

template<template< typename > class T>
void PFBlockAlgo::setInput ( const T< reco::PFRecTrackCollection > &  trackh,
const T< reco::GsfPFRecTrackCollection > &  gsftrackh,
const T< reco::GsfPFRecTrackCollection > &  convbremgsftrackh,
const T< reco::MuonCollection > &  muonh,
const T< reco::PFDisplacedTrackerVertexCollection > &  nuclearh,
const T< reco::PFRecTrackCollection > &  nucleartrackh,
const T< reco::PFConversionCollection > &  conv,
const T< reco::PFV0Collection > &  v0,
const T< reco::PFClusterCollection > &  ecalh,
const T< reco::PFClusterCollection > &  hcalh,
const T< reco::PFClusterCollection > &  hfemh,
const T< reco::PFClusterCollection > &  hfhadh,
const T< reco::PFClusterCollection > &  psh,
const T< reco::PhotonCollection > &  egphh,
const Mask trackMask = dummyMask_,
const Mask gsftrackMask = dummyMask_,
const Mask ecalMask = dummyMask_,
const Mask hcalMask = dummyMask_,
const Mask hfemMask = dummyMask_,
const Mask hfhadMask = dummyMask_,
const Mask psMask = dummyMask_,
const Mask phMask = dummyMask_ 
)

set input collections of tracks and clusters

-------------- GSF Primary tracks and brems ---------------------

get tracks from converted brems

Loop over the photons

-------------- conversions ---------------------

The tracks from conversions are filled into the elements collection

-------------- V0 ---------------------

The tracks from V0 are filled into the elements collection

One need to cross check if those tracks was not already filled from the conversion collection

This is a new track not yet included into the elements collection

-------------- Displaced Vertices ---------------------

The tracks from Displaced Vertices are filled into the elements collection

One need to cross check if those tracks was not already filled from the conversion or V0 collections

This is a new track not yet included into the elements collection

Fill the displaced vertex ref

-------------- Tracks ---------------------

Mask the tracks in trackh collection already included from Conversions V0 and Displaced Vertices. Take care that all those collections come from the same "generalTracks" collection.

Definition at line 328 of file PFBlockAlgo.h.

References checkMaskSize(), ClusterClusterMapping::checkOverlap(), gather_cfg::cout, debug_, reco::PFBlockElement::DEFAULT, reco::PFBlockElement::ECAL, elements_, fillFromPhoton(), spr::find(), goodPtResolution(), reco::PFBlockElement::HCAL, reco::PFBlockElement::HFEM, reco::PFBlockElement::HFHAD, i, edm::Ref< C, T, F >::isAvailable(), PFMuonAlgo::isLooseMuon(), reco::isMuon(), edm::Ref< C, T, F >::isNonnull(), edm::Ref< C, T, F >::key(), muAssocToTrack(), NONE, nuclearInteractionsPurity_, PhotonSelectorAlgo::passPhotonSelection(), pfcSCVec_, photonSelector_, PFLayer::PS1, reco::PFBlockElement::PS1, PFLayer::PS2, reco::PFBlockElement::PS2, scpfcRefs_, reco::PFBlockElement::setConversionRef(), reco::PFBlockElement::setDisplacedVertexRef(), reco::PFBlockElementSuperCluster::setFromGsfElectron(), reco::PFBlockElementSuperCluster::setFromPhoton(), reco::PFBlockElement::setMuonRef(), reco::PFBlockElement::setTrackType(), reco::PFBlockElement::setV0Ref(), findQualityFiles::size, superClusters_, reco::PFBlockElement::T_FROM_DISP, reco::PFBlockElement::T_FROM_GAMMACONV, reco::PFBlockElement::T_FROM_V0, reco::PFBlockElement::T_TO_DISP, useConvBremPFRecTracks_, useEGPhotons_, and relativeConstraints::value.

Referenced by PFRootEventManager::particleFlow().

                                          {


  checkMaskSize( *trackh,
                 *gsftrackh,
                 *ecalh,
                 *hcalh,
                 *hfemh,
                 *hfhadh,
                 *psh,
                 *egphh,
                 trackMask,
                 gsftrackMask,
                 ecalMask,
                 hcalMask,
                 hfemMask,
                 hfhadMask,
                 psMask,
                 phMask);

  /*
  if (nucleartrackh.isValid()){
    for(unsigned i=0;i<nucleartrackh->size(); i++) {
      reco::PFRecTrackRef trackRef(nucleartrackh,i);
      std::cout << *trackRef << std::endl;
    }
  }
  */

  std::vector<reco::PFRecTrackRef> convBremPFRecTracks;
  convBremPFRecTracks.clear();
  // Super cluster mapping
  superClusters_.clear();
  scpfcRefs_.clear();
  pfcSCVec_.clear();

  if(gsftrackh.isValid() ) {
    const  reco::GsfPFRecTrackCollection PFGsfProd = *(gsftrackh.product());
    for(unsigned i=0;i<gsftrackh->size(); i++) {
      if( !gsftrackMask.empty() &&
          !gsftrackMask[i] ) continue;
      reco::GsfPFRecTrackRef refgsf(gsftrackh,i );   
   
      if((refgsf).isNull()) continue;
      reco::GsfTrackRef gsf=refgsf->gsfTrackRef();

      // retrieve and save the SC if ECAL-driven - Florian
      if(gsf->extra().isAvailable() && gsf->extra()->seedRef().isAvailable()) {
        reco::ElectronSeedRef seedRef=  gsf->extra()->seedRef().castTo<reco::ElectronSeedRef>();
        // check that the seed is valid
        if(seedRef.isAvailable() && seedRef->isEcalDriven()) {
          reco::SuperClusterRef scRef = seedRef->caloCluster().castTo<reco::SuperClusterRef>();
          if(scRef.isNonnull())   {          
            std::vector<reco::SuperClusterRef>::iterator itcheck=find(superClusters_.begin(),superClusters_.end(),scRef);
            // not present, add it
            if(itcheck==superClusters_.end())
              {
                superClusters_.push_back(scRef);
                reco::PFBlockElementSuperCluster * sce =
                  new reco::PFBlockElementSuperCluster(scRef);
                sce->setFromGsfElectron(true);
                elements_.push_back(sce);
              }
            else // it is already present, update the PFBE
              {
                PFBlockElementSCEqual myEqual(scRef);
                std::list<reco::PFBlockElement*>::iterator itcheck=find_if(elements_.begin(),elements_.end(),myEqual);
                if(itcheck!=elements_.end())
                  {
                    reco::PFBlockElementSuperCluster* thePFBE=dynamic_cast<reco::PFBlockElementSuperCluster*>(*itcheck);
                    thePFBE->setFromGsfElectron(true);
                    //              std::cout << " Updating element to add electron information" << std::endl;
                  }
//              else
//                {
//                  std::cout << " Missing element " << std::endl;
//                }
              }
          }
        }
      }

      reco::PFBlockElement* gsfEl;
      
      const  std::vector<reco::PFTrajectoryPoint> 
        PfGsfPoint =  PFGsfProd[i].trajectoryPoints();
  
      unsigned int c_gsf=0;
      bool PassTracker = false;
      bool GetPout = false;
      unsigned int IndexPout = 0;
      
      typedef std::vector<reco::PFTrajectoryPoint>::const_iterator IP;
      for(IP itPfGsfPoint =  PfGsfPoint.begin();  
          itPfGsfPoint!= PfGsfPoint.end();itPfGsfPoint++) {
        
        if (itPfGsfPoint->isValid()){
          int layGsfP = itPfGsfPoint->layer();
          if (layGsfP == -1) PassTracker = true;
          if (PassTracker && layGsfP > 0 && GetPout == false) {
            IndexPout = c_gsf-1;
            GetPout = true;
          }
          //const math::XYZTLorentzVector GsfMoment = itPfGsfPoint->momentum();
          c_gsf++;
        }
      }
      math::XYZTLorentzVector pin = PfGsfPoint[0].momentum();      
      math::XYZTLorentzVector pout = PfGsfPoint[IndexPout].momentum();

      if(useConvBremPFRecTracks_) {
        const std::vector<reco::PFRecTrackRef>& temp_convBremPFRecTracks(refgsf->convBremPFRecTrackRef());
        if(temp_convBremPFRecTracks.size() > 0) {
          for(unsigned int iconv = 0; iconv <temp_convBremPFRecTracks.size(); iconv++) {
            convBremPFRecTracks.push_back(temp_convBremPFRecTracks[iconv]);
          }
        }
      }
      
      gsfEl = new reco::PFBlockElementGsfTrack(refgsf, pin, pout);
      
      elements_.push_back( gsfEl);

      std::vector<reco::PFBrem> pfbrem = refgsf->PFRecBrem();
      
      for (unsigned i2=0;i2<pfbrem.size(); i2++) {
        const double DP = pfbrem[i2].DeltaP();
        const double SigmaDP =  pfbrem[i2].SigmaDeltaP(); 
        const unsigned int TrajP = pfbrem[i2].indTrajPoint();
        if(TrajP == 99) continue;

        reco::PFBlockElement* bremEl;
        bremEl = new reco::PFBlockElementBrem(refgsf,DP,SigmaDP,TrajP);
        elements_.push_back(bremEl);
        
      }
    }

  }

  if(useEGPhotons_ && egphh.isValid()) {
    unsigned size=egphh->size();
    for(unsigned isc=0; isc<size; ++isc) {
      if(!phMask.empty() && !(phMask)[isc] ) continue;
      if(!photonSelector_->passPhotonSelection((*egphh)[isc])) continue;
      //      std::cout << " Selected a supercluster" << std::endl;
      // Add only the super clusters not already included 
      reco::SuperClusterRef scRef((*egphh)[isc].superCluster());
      std::vector<reco::SuperClusterRef>::iterator itcheck=find(superClusters_.begin(),superClusters_.end(),(*egphh)[isc].superCluster());
      if(itcheck==superClusters_.end())
        {
          superClusters_.push_back(scRef);
          reco::PFBlockElementSuperCluster * sce =
            new reco::PFBlockElementSuperCluster((*egphh)[isc].superCluster());
          fillFromPhoton((*egphh)[isc],sce);
          elements_.push_back(sce);
        }
      else
        {
          PFBlockElementSCEqual myEqual(scRef);
          std::list<reco::PFBlockElement*>::iterator itcheck=find_if(elements_.begin(),elements_.end(),myEqual);
          if(itcheck!=elements_.end())
            {
              reco::PFBlockElementSuperCluster* thePFBE=dynamic_cast<reco::PFBlockElementSuperCluster*>(*itcheck);
              fillFromPhoton((*egphh)[isc],thePFBE);
              thePFBE->setFromPhoton(true);
              //              std::cout << " Updating element to add Photon information " << photonSelector_->passPhotonSelection((*egphh)[isc]) << std::endl;

            }
//        else
//          {
//            std::cout << " Missing element " << std::endl;
//          }
        }
    }
  }
  
  // set the vector to the right size so to allow random access
  scpfcRefs_.resize(superClusters_.size());



  if(convh.isValid() ) {
    reco::PFBlockElement* trkFromConversionElement;
    for(unsigned i=0;i<convh->size(); i++) {
      reco::PFConversionRef convRef(convh,i);

      unsigned int trackSize=(convRef->pfTracks()).size();
      if ( convRef->pfTracks().size() < 2) continue;
      for(unsigned iTk=0;iTk<trackSize; iTk++) {
        
        reco::PFRecTrackRef compPFTkRef = convRef->pfTracks()[iTk];     
        trkFromConversionElement = new reco::PFBlockElementTrack(convRef->pfTracks()[iTk]);
        trkFromConversionElement->setConversionRef( convRef->originalConversion(), reco::PFBlockElement::T_FROM_GAMMACONV);

        elements_.push_back( trkFromConversionElement );


        if (debug_){
          std::cout << "PF Block Element from Conversion electron " << 
            (*trkFromConversionElement).trackRef().key() << std::endl;
          std::cout << *trkFromConversionElement << std::endl;
        }
       
      }     
    }  
  }
  
  
  
  
  if(v0.isValid() ) {
    reco::PFBlockElement* trkFromV0Element = 0;
    for(unsigned i=0;i<v0->size(); i++) {
      reco::PFV0Ref v0Ref( v0, i );
      unsigned int trackSize=(v0Ref->pfTracks()).size();
      for(unsigned iTk=0;iTk<trackSize; iTk++) {

        reco::PFRecTrackRef newPFRecTrackRef = (v0Ref->pfTracks())[iTk]; 
        reco::TrackBaseRef newTrackBaseRef(newPFRecTrackRef->trackRef());
        bool bNew = true;
        
        for(IE iel = elements_.begin(); iel != elements_.end(); iel++){
          reco::TrackBaseRef elemTrackBaseRef((*iel)->trackRef());
          if (newTrackBaseRef == elemTrackBaseRef){         
            trkFromV0Element = *iel;
            bNew = false;
            continue;
          }
        } 

        if (bNew) {
          trkFromV0Element = new reco::PFBlockElementTrack(v0Ref->pfTracks()[iTk]);
          elements_.push_back( trkFromV0Element );
        }

        trkFromV0Element->setV0Ref( v0Ref->originalV0(),
                                    reco::PFBlockElement::T_FROM_V0 );
          
        if (debug_){
          std::cout << "PF Block Element from V0 track New = " << bNew 
                    << (*trkFromV0Element).trackRef().key() << std::endl;
          std::cout << *trkFromV0Element << std::endl;
        }

        
      }
    }
  }
  


  if(nuclearh.isValid()) {
    reco::PFBlockElement* trkFromDisplacedVertexElement = 0;
    for(unsigned i=0;i<nuclearh->size(); i++) {

      const reco::PFDisplacedTrackerVertexRef dispacedVertexRef( nuclearh, i );

      //      std::cout << "Nuclear Interactions Purity " <<  nuclearInteractionsPurity_ << std::endl;
      //     dispacedVertexRef->displacedVertexRef()->Dump();
      //bool bIncludeVertices = true;

      
      bool bIncludeVertices = false; 
      bool bNucl = dispacedVertexRef->displacedVertexRef()->isNucl();
      bool bNucl_Loose = dispacedVertexRef->displacedVertexRef()->isNucl_Loose();
      bool bNucl_Kink = dispacedVertexRef->displacedVertexRef()->isNucl_Kink();

      if (nuclearInteractionsPurity_ >= 1) bIncludeVertices = bNucl;
      if (nuclearInteractionsPurity_ >= 2) bIncludeVertices = bIncludeVertices || bNucl_Loose;
      if (nuclearInteractionsPurity_ >= 3) bIncludeVertices = bIncludeVertices || bNucl_Kink;

      if (bIncludeVertices){

        unsigned int trackSize= dispacedVertexRef->pfRecTracks().size();
        if (debug_){
          std::cout << "" << std::endl;
          std::cout << "Displaced Vertex " << i << std::endl;
          dispacedVertexRef->displacedVertexRef()->Dump();
        }
        for(unsigned iTk=0;iTk < trackSize; iTk++) {


          // This peace of code looks weired at first but it seems to be necessary to let 
          // PFRooTEvent work properly. Since the track position called REPPoint is transient 
          // it has to be calculated and the PFRecTrack collection associted to Displaced Vertex is not
          // anymore the original collection. So here we match both collections if possible
          reco::PFRecTrackRef newPFRecTrackRef = dispacedVertexRef->pfRecTracks()[iTk]; 
          reco::TrackBaseRef constTrackBaseRef(newPFRecTrackRef->trackRef());

          
          if (nucleartrackh.isValid()){
            for(unsigned i=0;i<nucleartrackh->size(); i++) {
              reco::PFRecTrackRef transientPFRecTrackRef(nucleartrackh,i);
              reco::TrackBaseRef transientTrackBaseRef(transientPFRecTrackRef->trackRef());
              if (constTrackBaseRef==transientTrackBaseRef){
                newPFRecTrackRef = transientPFRecTrackRef;
                break;
              }
            }
          }
          reco::TrackBaseRef newTrackBaseRef(newPFRecTrackRef->trackRef());
          


          bool bNew = true;
          reco::PFBlockElement::TrackType blockType;

          for(IE iel = elements_.begin(); iel != elements_.end(); iel++){
            reco::TrackBaseRef elemTrackBaseRef((*iel)->trackRef());
            if (newTrackBaseRef == elemTrackBaseRef){
              trkFromDisplacedVertexElement = *iel;
              bNew = false;
              continue;
            }
          }


          if (bNew) { 
            


            trkFromDisplacedVertexElement = new reco::PFBlockElementTrack(newPFRecTrackRef);
            elements_.push_back( trkFromDisplacedVertexElement );
          }

          if (dispacedVertexRef->isIncomingTrack(newPFRecTrackRef)) 
            blockType = reco::PFBlockElement::T_TO_DISP;
          else if (dispacedVertexRef->isOutgoingTrack(newPFRecTrackRef)) 
            blockType = reco::PFBlockElement::T_FROM_DISP;
          else 
            blockType = reco::PFBlockElement::DEFAULT;

          trkFromDisplacedVertexElement->setDisplacedVertexRef( dispacedVertexRef, blockType );


          if (debug_){
            std::cout << "PF Block Element from DisplacedTrackingVertex track New = " << bNew
                      << (*trkFromDisplacedVertexElement).trackRef().key() << std::endl;
            std::cout << *trkFromDisplacedVertexElement << std::endl;
          }
        
        
        }
      }
    }  

    if (debug_) std::cout << "" << std::endl;

  }



  if(trackh.isValid() ) {

    if (debug_) std::cout << "Tracks already in from Displaced Vertices " << std::endl;

    Mask trackMaskVertex;

    for(unsigned i=0;i<trackh->size(); i++) {
      reco::PFRecTrackRef pfRefTrack( trackh,i );
      reco::TrackRef trackRef = pfRefTrack->trackRef();

      bool bMask = true;
      for(IE iel = elements_.begin(); iel != elements_.end(); iel++){
        reco::TrackRef elemTrackRef = (*iel)->trackRef();
        if( trackRef == elemTrackRef ) {
          if (debug_) std::cout << " " << trackRef.key();
          bMask = false; continue;
        }
      }
    
      trackMaskVertex.push_back(bMask);
    }

    if (debug_) std::cout << "" << std::endl;

    if (debug_) std::cout << "Additionnal tracks from main collection " << std::endl;

    for(unsigned i=0;i<trackh->size(); i++) {


      // this track has been disabled
      if( !trackMask.empty() && !trackMask[i] ) continue;
      
      reco::PFRecTrackRef ref( trackh,i );

      if (debug_) std::cout << " " << ref->trackRef().key();

      // Get the eventual muon associated to this track
      int muId_ = muAssocToTrack( ref->trackRef(), muonh );
      bool thisIsAPotentialMuon = false;
      if( muId_ != -1 ) {
        reco::MuonRef muonref( muonh, muId_ );
        thisIsAPotentialMuon = 
          PFMuonAlgo::isLooseMuon(muonref) || 
          PFMuonAlgo::isMuon(muonref);
      }
      // Reject bad tracks (except if identified as muon
      if( !thisIsAPotentialMuon && !goodPtResolution( ref->trackRef() ) ) continue;

      if (thisIsAPotentialMuon && debug_) std::cout << "Potential Muon P " <<  ref->trackRef()->p() 
                                                    << " pt " << ref->trackRef()->p() << std::endl; 



      reco::PFBlockElement* primaryElement = new reco::PFBlockElementTrack( ref );

      if( muId_ != -1 ) {
        // if a muon has been found
        reco::MuonRef muonref( muonh, muId_ );

        // If this track was already added to the collection, we just need to find the associated element and 
        // attach to it the reference
        if (!trackMaskVertex.empty() && !trackMaskVertex[i]){
          reco::TrackRef primaryTrackRef = ref->trackRef();
          for(IE iel = elements_.begin(); iel != elements_.end(); iel++){
            reco::TrackRef elemTrackRef = (*iel)->trackRef();
            if( primaryTrackRef == elemTrackRef ) {
              (*iel)->setMuonRef( muonref );
              if (debug_) std::cout << "One of the tracks identified in displaced vertices collections was spotted as muon" <<std:: endl;
            }
          }
        } else primaryElement->setMuonRef( muonref );

      }

      if (!trackMaskVertex.empty() && !trackMaskVertex[i]) continue;

      
      // set track type T_FROM_GAMMA for pfrectracks associated to conv brems
      if(useConvBremPFRecTracks_) {
        if(convBremPFRecTracks.size() > 0.) {
          for(unsigned int iconv = 0; iconv < convBremPFRecTracks.size(); iconv++) {
            if((*ref).trackRef() == (*convBremPFRecTracks[iconv]).trackRef()) {
              bool value = true;
              primaryElement->setTrackType(reco::PFBlockElement::T_FROM_GAMMACONV, value);
            }
          }
        }
      }
      elements_.push_back( primaryElement );

    }

    if (debug_) std::cout << " " << std::endl;

  }

 
  // -------------- GSF tracks and brems for Conversion Recovery ----------
   
  if(convbremgsftrackh.isValid() ) {
    
 
    const  reco::GsfPFRecTrackCollection ConvPFGsfProd = *(convbremgsftrackh.product());
    for(unsigned i=0;i<convbremgsftrackh->size(); i++) {

      reco::GsfPFRecTrackRef refgsf(convbremgsftrackh,i );   
      
      if((refgsf).isNull()) continue;
      
      reco::PFBlockElement* gsfEl;
      
      const  std::vector<reco::PFTrajectoryPoint> 
        PfGsfPoint =  ConvPFGsfProd[i].trajectoryPoints();
      
      unsigned int c_gsf=0;
      bool PassTracker = false;
      bool GetPout = false;
      unsigned int IndexPout = -1;
      
      typedef std::vector<reco::PFTrajectoryPoint>::const_iterator IP;
      for(IP itPfGsfPoint =  PfGsfPoint.begin();  
          itPfGsfPoint!= PfGsfPoint.end();itPfGsfPoint++) {
        
        if (itPfGsfPoint->isValid()){
          int layGsfP = itPfGsfPoint->layer();
          if (layGsfP == -1) PassTracker = true;
          if (PassTracker && layGsfP > 0 && GetPout == false) {
            IndexPout = c_gsf-1;
            GetPout = true;
          }
          //const math::XYZTLorentzVector GsfMoment = itPfGsfPoint->momentum();
          c_gsf++;
        }
      }
      math::XYZTLorentzVector pin = PfGsfPoint[0].momentum();      
      math::XYZTLorentzVector pout = PfGsfPoint[IndexPout].momentum();
      
      
    
      gsfEl = new reco::PFBlockElementGsfTrack(refgsf, pin, pout);
      
      bool valuegsf = true;
      // IMPORTANT SET T_FROM_GAMMACONV trackType() FOR CONVERSIONS
      gsfEl->setTrackType(reco::PFBlockElement::T_FROM_GAMMACONV, valuegsf);

      

      elements_.push_back( gsfEl);
      std::vector<reco::PFBrem> pfbrem = refgsf->PFRecBrem();
      
      for (unsigned i2=0;i2<pfbrem.size(); i2++) {
        const double DP = pfbrem[i2].DeltaP();
        const double SigmaDP =  pfbrem[i2].SigmaDeltaP(); 
        const unsigned int TrajP = pfbrem[i2].indTrajPoint();
        if(TrajP == 99) continue;

        reco::PFBlockElement* bremEl;
        bremEl = new reco::PFBlockElementBrem(refgsf,DP,SigmaDP,TrajP);
        elements_.push_back(bremEl);
        
      }
    }
  }

  
  // -------------- ECAL clusters ---------------------


  if(ecalh.isValid() ) {
    pfcSCVec_.resize(ecalh->size(),-1);
    for(unsigned i=0;i<ecalh->size(); i++)  {

      // this ecal cluster has been disabled
      if( !ecalMask.empty() &&
          !ecalMask[i] ) continue;

      reco::PFClusterRef ref( ecalh,i );
      reco::PFBlockElement* te
        = new reco::PFBlockElementCluster( ref,
                                           reco::PFBlockElement::ECAL);
      elements_.push_back( te );
      // Now mapping with Superclusters
      int scindex= ClusterClusterMapping::checkOverlap(*ref,superClusters_);

      if(scindex>=0)    {
          pfcSCVec_[ref.key()]=scindex;
          scpfcRefs_[scindex].push_back(ref);
        }
    }
  }

  // -------------- HCAL clusters ---------------------

  if(hcalh.isValid() ) {
    
    for(unsigned i=0;i<hcalh->size(); i++)  {
      
      // this hcal cluster has been disabled
      if( !hcalMask.empty() &&
          !hcalMask[i] ) continue;
      
      reco::PFClusterRef ref( hcalh,i );
      reco::PFBlockElement* th
        = new reco::PFBlockElementCluster( ref,
                                           reco::PFBlockElement::HCAL );
      elements_.push_back( th );
    }
  }


  // -------------- HFEM clusters ---------------------

  if(hfemh.isValid() ) {
    
    for(unsigned i=0;i<hfemh->size(); i++)  {
      
      // this hfem cluster has been disabled
      if( !hfemMask.empty() &&
          !hfemMask[i] ) continue;
      
      reco::PFClusterRef ref( hfemh,i );
      reco::PFBlockElement* th
        = new reco::PFBlockElementCluster( ref,
                                           reco::PFBlockElement::HFEM );
      elements_.push_back( th );
    }
  }


  // -------------- HFHAD clusters ---------------------

  if(hfhadh.isValid() ) {
    
    for(unsigned i=0;i<hfhadh->size(); i++)  {
      
      // this hfhad cluster has been disabled
      if( !hfhadMask.empty() &&
          !hfhadMask[i] ) continue;
      
      reco::PFClusterRef ref( hfhadh,i );
      reco::PFBlockElement* th
        = new reco::PFBlockElementCluster( ref,
                                           reco::PFBlockElement::HFHAD );
      elements_.push_back( th );
    }
  }




  // -------------- PS clusters ---------------------

  if(psh.isValid() ) {
    for(unsigned i=0;i<psh->size(); i++)  {

      // this ps cluster has been disabled
      if( !psMask.empty() &&
          !psMask[i] ) continue;
      reco::PFBlockElement::Type type = reco::PFBlockElement::NONE;
      reco::PFClusterRef ref( psh,i );
      // two types of elements:  PS1 (V) and PS2 (H) 
      // depending on layer:  PS1 or PS2
      switch(ref->layer()){
      case PFLayer::PS1:
        type = reco::PFBlockElement::PS1;
        break;
      case PFLayer::PS2:
        type = reco::PFBlockElement::PS2;
        break;
      default:
        break;
      }
      reco::PFBlockElement* tp
        = new reco::PFBlockElementCluster( ref,
                                           type );
      elements_.push_back( tp );
      
    }
  }
}
template<template< typename > class T>
void PFBlockAlgo::setInput ( const T< reco::PFRecTrackCollection > &  trackh,
const T< reco::MuonCollection > &  muonh,
const T< reco::PFClusterCollection > &  ecalh,
const T< reco::PFClusterCollection > &  hcalh,
const T< reco::PFClusterCollection > &  hfemh,
const T< reco::PFClusterCollection > &  hfhadh,
const T< reco::PFClusterCollection > &  psh,
const Mask trackMask = dummyMask_,
const Mask ecalMask = dummyMask_,
const Mask hcalMask = dummyMask_,
const Mask psMask = dummyMask_ 
) [inline]

COLIN: I think this is for particle flow at HLT...

Definition at line 111 of file PFBlockAlgo.h.

                                                    {
    T<reco::GsfPFRecTrackCollection> gsftrackh;
    T<reco::GsfPFRecTrackCollection> convbremgsftrackh;
    //T<reco::MuonCollection> muonh;
    T<reco::PFDisplacedTrackerVertexCollection> nuclearh;
    T<reco::PFRecTrackCollection>    nucleartrackh;
    T<reco::PFConversionCollection> convh;
    T<reco::PFV0Collection> v0;
    T<reco::PhotonCollection> phh;
    setInput<T>( trackh, gsftrackh, convbremgsftrackh, muonh, nuclearh, nucleartrackh, convh, v0, 
                 ecalh, hcalh, hfemh, hfhadh, psh, phh,
                 trackMask, ecalMask, hcalMask, psMask); 
  }
template<template< typename > class T>
void PFBlockAlgo::setInput ( const T< reco::PFRecTrackCollection > &  trackh,
const T< reco::GsfPFRecTrackCollection > &  gsftrackh,
const T< reco::PFClusterCollection > &  ecalh,
const T< reco::PFClusterCollection > &  hcalh,
const T< reco::PFClusterCollection > &  psh,
const Mask trackMask = dummyMask_,
const Mask gsftrackMask = dummyMask_,
const Mask ecalMask = dummyMask_,
const Mask hcalMask = dummyMask_,
const Mask psMask = dummyMask_ 
) [inline]

COLIN: what is this setinput function for? can it be removed?

Definition at line 137 of file PFBlockAlgo.h.

                                                    {
    T<reco::GsfPFRecTrackCollection> convbremgsftrackh;
    T<reco::MuonCollection> muonh;
    T<reco::PFDisplacedTrackerVertexCollection>  nuclearh;
    T<reco::PFRecTrackCollection>    nucleartrackh;
    T<reco::PFConversionCollection> convh;
    T<reco::PFV0Collection> v0;
    T<reco::PhotonCollection> egphh;
    setInput<T>( trackh, gsftrackh, convbremgsftrackh, muonh, nuclearh, nucleartrackh, convh, v0, ecalh, hcalh, psh, egphh,
                 trackMask, gsftrackMask,ecalMask, hcalMask, psMask); 
  }
void PFBlockAlgo::setParameters ( std::vector< double > &  DPtovPtCut,
std::vector< unsigned > &  NHitCut,
bool  useConvBremPFRecTracks,
bool  useIterTracking,
int  nuclearInteractionsPurity,
bool  useEGPhotons,
std::vector< double > &  photonSelectionCuts 
)
double PFBlockAlgo::testECALAndHCAL ( const reco::PFCluster ecal,
const reco::PFCluster hcal 
) const [private]

tests association between an ECAL and an HCAL cluster

Returns:
distance

Definition at line 726 of file PFBlockAlgo.cc.

References gather_cfg::cout, debug_, and reco::PFCluster::positionREP().

                                                           {
  
  //   cout<<"entering testECALAndHCAL"<<endl;
  
  /*
  double dist = 
    computeDist( ecal.positionREP().Eta(),
                 ecal.positionREP().Phi(), 
                 hcal.positionREP().Eta(), 
                 hcal.positionREP().Phi() );
  */

#ifdef PFLOW_DEBUG
  if(debug_) cout<<"testECALAndHCAL "<< dist <<" "<<endl;
  if(debug_){
    cout<<" ecaleta " << ecal.positionREP().Eta()
        <<" ecalphi " << ecal.positionREP().Phi()
        <<" hcaleta " << hcal.positionREP().Eta()
        <<" hcalphi " << hcal.positionREP().Phi()
  }
#endif

  // Need to implement a link by RecHit
  return -1.;
}
double PFBlockAlgo::testLinkBySuperCluster ( const reco::PFClusterRef elt1,
const reco::PFClusterRef elt2 
) const [private]

test association by Supercluster between two ECAL

Definition at line 754 of file PFBlockAlgo.cc.

References LinkByRecHit::computeDist(), i, edm::Ref< C, T, F >::key(), pfcSCVec_, and scpfcRefs_.

Referenced by link().

                                                                      {
  
  //  cout<<"entering testECALAndECAL "<< pfcRefSCMap_.size() << endl;
  
  double dist = -1;
  
  // the first one is not in any super cluster
  int testindex=pfcSCVec_[ecal1.key()];
  if(testindex == -1.) return dist;
  //  if(itcheck==pfcRefSCMap_.end()) return dist;
  // now retrieve the of PFclusters in this super cluster  

  const std::vector<reco::PFClusterRef> & thePFClusters(scpfcRefs_[testindex]);
  
  unsigned npf=thePFClusters.size();
  for(unsigned i=0;i<npf;++i)
    {
      if(thePFClusters[i]==ecal2) // yes they are in the same SC 
        {
          dist=LinkByRecHit::computeDist( ecal1->positionREP().Eta(),
                                          ecal1->positionREP().Phi(), 
                                          ecal2->positionREP().Eta(), 
                                          ecal2->positionREP().Phi() );
//        std::cout << " DETA " << fabs(ecal1->positionREP().Eta()-ecal2->positionREP().Eta()) << std::endl;
//        if(fabs(ecal1->positionREP().Eta()-ecal2->positionREP().Eta())>0.2)
//          {
//            std::cout <<  " Super Cluster " <<  *(superClusters_[testindex]) << std::endl;
//            std::cout <<  " Cluster1 " <<  *ecal1 << std::endl;
//            std::cout <<  " Cluster2 " <<  *ecal2 << std::endl;
//            ClusterClusterMapping::checkOverlap(*ecal1,superClusters_,0.01,true);
//            ClusterClusterMapping::checkOverlap(*ecal2,superClusters_,0.01,true);
//          }
          return dist;
        }
    }
  return dist;
}
double PFBlockAlgo::testLinkByVertex ( const reco::PFBlockElement elt1,
const reco::PFBlockElement elt2 
) const [private]

Definition at line 869 of file PFBlockAlgo.cc.

References reco::PFBlockElement::convRef(), gather_cfg::cout, debug_, reco::PFBlockElement::displacedVertexRef(), edm::Ref< C, T, F >::isNonnull(), query::result, reco::PFBlockElement::T_FROM_DISP, reco::PFBlockElement::T_FROM_GAMMACONV, reco::PFBlockElement::T_FROM_V0, reco::PFBlockElement::T_TO_DISP, reco::PFBlockElement::trackType(), and reco::PFBlockElement::V0Ref().

Referenced by link().

                                                                     {

  //  cout << "Test link by vertex between" << endl << *elt1 << endl << " and " << endl << *elt2 << endl;

  double result=-1.;

  reco::PFBlockElement::TrackType T_TO_DISP = reco::PFBlockElement::T_TO_DISP;
  reco::PFBlockElement::TrackType T_FROM_DISP = reco::PFBlockElement::T_FROM_DISP;
  PFDisplacedTrackerVertexRef ni1_TO_DISP = elt1->displacedVertexRef(T_TO_DISP);
  PFDisplacedTrackerVertexRef ni2_TO_DISP = elt2->displacedVertexRef(T_TO_DISP);
  PFDisplacedTrackerVertexRef ni1_FROM_DISP = elt1->displacedVertexRef(T_FROM_DISP);
  PFDisplacedTrackerVertexRef ni2_FROM_DISP = elt2->displacedVertexRef(T_FROM_DISP);
  
  if( ni1_TO_DISP.isNonnull() && ni2_FROM_DISP.isNonnull())
    if( ni1_TO_DISP == ni2_FROM_DISP ) { result = 1.0; return result; }

  if( ni1_FROM_DISP.isNonnull() && ni2_TO_DISP.isNonnull())
    if( ni1_FROM_DISP == ni2_TO_DISP ) { result = 1.0; return result; }

  if( ni1_FROM_DISP.isNonnull() && ni2_FROM_DISP.isNonnull())
    if( ni1_FROM_DISP == ni2_FROM_DISP ) { result = 1.0; return result; }
    
  
  if (  elt1->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)  &&
             elt2->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)  ) {
    
    if(debug_ ) std::cout << " testLinkByVertex On Conversions " << std::endl;
    
    if ( elt1->convRef().isNonnull() && elt2->convRef().isNonnull() ) {
      if(debug_ ) std::cout << " PFBlockAlgo.cc testLinkByVertex  Cconversion Refs are non null  " << std::endl;      
      if ( elt1->convRef() ==  elt2->convRef() ) {
        result=1.0;
        if(debug_ ) std::cout << " testLinkByVertex  Cconversion Refs are equal  " << std::endl;      
        return result;
      }
    } 
    
  }
  
  if (  elt1->trackType(reco::PFBlockElement::T_FROM_V0)  &&
             elt2->trackType(reco::PFBlockElement::T_FROM_V0)  ) {
    if(debug_ ) std::cout << " testLinkByVertex On V0 " << std::endl;
    if ( elt1->V0Ref().isNonnull() && elt2->V0Ref().isNonnull() ) {
      if(debug_ ) std::cout << " PFBlockAlgo.cc testLinkByVertex  V0 Refs are non null  " << std::endl;
      if ( elt1->V0Ref() ==  elt2->V0Ref() ) {
        result=1.0;
        if(debug_ ) std::cout << " testLinkByVertex  V0 Refs are equal  " << std::endl;
        return result;
      }
    }
  }

  return result;
}
double PFBlockAlgo::testPS1AndPS2 ( const reco::PFCluster ps1,
const reco::PFCluster ps2 
) const [private]

tests association between a PS1 v cluster and a PS2 h cluster returns distance

Definition at line 817 of file PFBlockAlgo.cc.

References gather_cfg::cout, debug_, reco::CaloCluster::position(), and mathSSE::sqrt().

                                                        {
  
#ifdef PFLOW_DEBUG
  //   cout<<"entering testPS1AndPS2"<<endl;
  
  // compute chi2 in y, z using swimming formulae
  // y2 = y1 * z2/z1   and x2 = x1 *z2/z1
  
  // ps position1  x, y, z
  double x1 = ps1.position().X();
  double y1 = ps1.position().Y();
  double z1 = ps1.position().Z();
  double x2 = ps2.position().X();
  double y2 = ps2.position().Y();
  double z2 = ps2.position().Z();
  // MDN Bug correction Jan 09: check that z1 and z2 have the same sign!
  if (z1*z2<0.) -1.;
  // swim to PS2
  double scale = z2/z1;
  double x1atPS2 = x1*scale;
  double y1atPS2 = y1*scale;
  // resolution of PS cluster dxdx and dydy from strip pitch and length
  // vertical strips in PS1, measure x with pitch precision
  double dx1dx1 = resPSpitch_*resPSpitch_*scale*scale;
  double dy1dy1 = resPSlength_*resPSlength_*scale*scale;
  // horizontal strips in PS2 , measure y with pitch precision
  double dy2dy2 = resPSpitch_*resPSpitch_;
  double dx2dx2 = resPSlength_*resPSlength_;
  
  // double chi2 = (x2-x1atPS2)*(x2-x1atPS2)/(dx1dx1 + dx2dx2) 
  //  + (y2-y1atPS2)*(y2-y1atPS2)/(dy1dy1 + dy2dy2);
  
  double dist = std::sqrt( (x2-x1atPS2)*(x2-x1atPS2)
                         + (y2-y1atPS2)*(y2-y1atPS2));
    
  if(debug_) cout<<"testPS1AndPS2 "<<dist<<" "<<endl;
  if(debug_){
    cout<<" x1atPS2 "<< x1atPS2 << " dx1 "<<resPSpitch_*scale
        <<" y1atPS2 "<< y1atPS2 << " dy1 "<<resPSlength_*scale<< endl
        <<" x2 " <<x2  << " dx2 "<<resPSlength_
        <<" y2 " << y2 << " dy2 "<<resPSpitch_<< endl;
  }
#endif

  // Need a link by rechit here
  return -1.; 
}
double PFBlockAlgo::testSuperClusterPFCluster ( const reco::SuperClusterRef sct1,
const reco::PFClusterRef elt2 
) const [private]

test association between SuperClusters and ECAL

Definition at line 795 of file PFBlockAlgo.cc.

References LinkByRecHit::computeDist(), and muon::overlap().

Referenced by link().

                                                                         {
  
  //  cout<<"entering testECALAndECAL "<< pfcRefSCMap_.size() << endl;
  
  double dist = -1;
  
  bool overlap=ClusterClusterMapping::overlap(*ecal1,*ecal2);
  
  if(overlap)   {
    dist=LinkByRecHit::computeDist( ecal1->position().eta(),
                                    ecal1->position().phi(), 
                                    ecal2->positionREP().Eta(), 
                                    ecal2->positionREP().Phi() );
    return dist;
  }
  return dist;
}
double PFBlockAlgo::testTrackAndPS ( const reco::PFRecTrack track,
const reco::PFCluster ps 
) const [private]

tests association between a track and a PS cluster returns distance

Definition at line 662 of file PFBlockAlgo.cc.

References gather_cfg::cout, debug_, reco::PFTrack::extrapolatedPoint(), reco::PFTrajectoryPoint::isValid(), reco::PFCluster::layer(), reco::PFTrajectoryPoint::position(), reco::CaloCluster::position(), reco::PFTrajectoryPoint::PS1, PFLayer::PS1, reco::PFTrajectoryPoint::PS2, PFLayer::PS2, and mathSSE::sqrt().

Referenced by link().

                                                        {

#ifdef PFLOW_DEBUG
  //   cout<<"entering testTrackAndPS"<<endl;
  // resolution of PS cluster dxdx and dydy from strip pitch and length
  double dx=0.;
  double dy=0.;
  
  unsigned layerid =0;
  // PS1: vertical strips  PS2: horizontal strips
  switch (ps.layer()) {
  case PFLayer::PS1:
    layerid = reco::PFTrajectoryPoint::PS1;
    
    // vertical strips in PS1, measure x with pitch precision
    dx = resPSpitch_;
    dy = resPSlength_; 
    break;
  case PFLayer::PS2:
    layerid = reco::PFTrajectoryPoint::PS2;
    // horizontal strips in PS2, measure y with pitch precision
    dy = resPSpitch_;
    dx = resPSlength_;
    break;
  default:
    break;
  }
  const reco::PFTrajectoryPoint& atPS
    = track.extrapolatedPoint( layerid );  
  // did not reach PS, cannot be associated with a cluster.
  if( ! atPS.isValid() ) return -1.;   
  
  double trackx = atPS.position().X();
  double tracky = atPS.position().Y();
  double trackz = atPS.position().Z(); // MDN jan 09
  
  // ps position  x, y
  double psx = ps.position().X();
  double psy = ps.position().Y();
  // MDN Jan 09: check that trackz and psz have the same sign
  double psz = ps.position().Z();
  if( trackz*psz < 0.) return -1.; 
  
  // double chi2 = (psx-trackx)*(psx-trackx)/(dx*dx + trackresolx*trackresolx)
  //  + (psy-tracky)*(psy-tracky)/(dy*dy + trackresoly*trackresoly);

  double dist = std::sqrt( (psx-trackx)*(psx-trackx)
                         + (psy-tracky)*(psy-tracky));  
  if(debug_) cout<<"testTrackAndPS "<< dist <<" "<<endl;
  if(debug_){
    cout<<" trackx " << trackx 
        <<" tracky " << tracky 
        <<" psx "    <<  psx   
        <<" psy "    << psy    
        << endl;
  }
#endif
  
  // Return -1. as long as no link by rechit is available
  return -1.;
}
std::auto_ptr< reco::PFBlockCollection > PFBlockAlgo::transferBlocks ( ) [inline]
Returns:
auto_ptr to collection of blocks

Definition at line 172 of file PFBlockAlgo.h.

References blocks_.

Referenced by PFRootEventManager::particleFlow().

{return blocks_;}

Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  out,
const PFBlockAlgo a 
) [friend]

Definition at line 1012 of file PFBlockAlgo.cc.

                                                              {
  if(! out) return out;
  
  out<<"====== Particle Flow Block Algorithm ======= ";
  out<<endl;
  out<<"number of unassociated elements : "<<a.elements_.size()<<endl;
  out<<endl;
  
  for(PFBlockAlgo::IEC ie = a.elements_.begin(); 
      ie != a.elements_.end(); ie++) {
    out<<"\t"<<**ie <<endl;
  }

  
  //   const PFBlockCollection& blocks = a.blocks();

  const std::auto_ptr< reco::PFBlockCollection >& blocks
    = a.blocks(); 
    
  if(!blocks.get() ) {
    out<<"blocks already transfered"<<endl;
  }
  else {
    out<<"number of blocks : "<<blocks->size()<<endl;
    out<<endl;
    
    for(PFBlockAlgo::IBC ib=blocks->begin(); 
        ib != blocks->end(); ib++) {
      out<<(*ib)<<endl;
    }
  }

  return out;
}

Member Data Documentation

std::auto_ptr< reco::PFBlockCollection > PFBlockAlgo::blocks_ [private]
bool PFBlockAlgo::debug_ [private]
std::vector<double> PFBlockAlgo::DPtovPtCut_ [private]

DPt/Pt cut for creating atrack element.

Definition at line 279 of file PFBlockAlgo.h.

Referenced by goodPtResolution().

const PFBlockAlgo::Mask PFBlockAlgo::dummyMask_ [static, private]

Definition at line 276 of file PFBlockAlgo.h.

actually, particles will be created by a separate producer

Definition at line 274 of file PFBlockAlgo.h.

Referenced by TrackDetectorAssociator::associate(), findBlocks(), operator<<(), setInput(), and ~PFBlockAlgo().

std::vector<unsigned> PFBlockAlgo::NHitCut_ [private]

Number of layers crossed cut for creating atrack element.

Definition at line 282 of file PFBlockAlgo.h.

Referenced by goodPtResolution().

Definition at line 297 of file PFBlockAlgo.h.

Referenced by setInput().

std::vector<int> PFBlockAlgo::pfcSCVec_ [private]

SC corresponding to the PF cluster.

Definition at line 309 of file PFBlockAlgo.h.

Referenced by setInput(), and testLinkBySuperCluster().

PhotonSelector.

Definition at line 303 of file PFBlockAlgo.h.

Referenced by setInput(), and ~PFBlockAlgo().

std::vector<std::vector<reco::PFClusterRef> > PFBlockAlgo::scpfcRefs_ [private]

PF clusters corresponding to a given SC.

Definition at line 312 of file PFBlockAlgo.h.

Referenced by setInput(), and testLinkBySuperCluster().

list of superclusters

Definition at line 305 of file PFBlockAlgo.h.

Referenced by setInput().

switch on/off Conversions Brem Recovery with KF Tracks

Definition at line 300 of file PFBlockAlgo.h.

Referenced by link(), and setInput().

Flag to turn off the import of EG Photons.

Definition at line 288 of file PFBlockAlgo.h.

Referenced by setInput().

Flag to turn off quality cuts which require iterative tracking (for heavy-ions)

Definition at line 285 of file PFBlockAlgo.h.

Referenced by goodPtResolution().