CMS 3D CMS Logo

Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | Friends

PFAlgo Class Reference

#include <PFAlgo.h>

Inheritance diagram for PFAlgo:
PFAlgoTestBenchConversions PFAlgoTestBenchElectrons

List of all members.

Public Member Functions

void checkCleaning (const reco::PFRecHitCollection &cleanedHF)
 Check HF Cleaning.
 PFAlgo ()
 constructor
const std::auto_ptr
< reco::PFCandidateCollection > & 
pfCandidates () const
void postMuonCleaning (const edm::Handle< reco::MuonCollection > &muonh, const reco::VertexCollection &primaryVertices)
void reconstructParticles (const reco::PFBlockHandle &blockHandle)
virtual void reconstructParticles (const reco::PFBlockCollection &blocks)
 reconstruct particles
void setAlgo (int algo)
void setCandConnectorParameters (const edm::ParameterSet &iCfgCandConnector)
void setCandConnectorParameters (bool bCorrect, bool bCalibPrimary, double dptRel_PrimaryTrack, double dptRel_MergedTrack, double ptErrorSecondary, std::vector< double > nuclCalibFactors)
void setDebug (bool debug)
void setDisplacedVerticesParameters (bool rejectTracks_Bad, bool rejectTracks_Step45, bool usePFNuclearInteractions, bool usePFConversions, bool usePFDecays, double dptRel_DispVtx)
void setEGElectronCollection (const reco::GsfElectronCollection &egelectrons)
void setElectronExtraRef (const edm::OrphanHandle< reco::PFCandidateElectronExtraCollection > &extrah)
void setParameters (double nSigmaECAL, double nSigmaHCAL, const boost::shared_ptr< PFEnergyCalibration > &calibration, const boost::shared_ptr< pftools::PFClusterCalibration > &clusterCalibration, const boost::shared_ptr< PFEnergyCalibrationHF > &thepfEnergyCalibrationHF, unsigned int newCalib)
void setPFEleParameters (double mvaEleCut, std::string mvaWeightFileEleID, bool usePFElectrons, const boost::shared_ptr< PFSCEnergyCalibration > &thePFSCEnergyCalibration, double sumEtEcalIsoForEgammaSC_barrel, double sumEtEcalIsoForEgammaSC_endcap, double coneEcalIsoForEgammaSC, double sumPtTrackIsoForEgammaSC_barrel, double sumPtTrackIsoForEgammaSC_endcap, unsigned int nTrackIsoForEgammaSC, double coneTrackIsoForEgammaSC, bool applyCrackCorrections=false, bool usePFSCEleCalib=true, bool useEGElectrons=false, bool useEGammaSupercluster=true)
void setPFMuonAndFakeParameters (std::vector< double > muonHCAL, std::vector< double > muonECAL, double nSigmaTRACK, double ptError, std::vector< double > factors45, bool usePFMuonMomAssign)
void setPFVertexParameters (bool useVertex, const reco::VertexCollection &primaryVertices)
void setPostHFCleaningParameters (bool postHFCleaning, double minHFCleaningPt, double minSignificance, double maxSignificance, double minSignificanceReduction, double maxDeltaPhiPt, double minDeltaMet)
std::auto_ptr
< reco::PFCandidateCollection
transferAddedMuonCandidates ()
std::auto_ptr
< reco::PFCandidateCollection
transferCandidates ()
std::auto_ptr
< reco::PFCandidateCollection > & 
transferCleanedCandidates ()
std::auto_ptr
< reco::PFCandidateCollection
transferCleanedTrackerAndGlobalMuonCandidates ()
std::auto_ptr
< reco::PFCandidateCollection
transferCosmicsMuonCleanedCandidates ()
std::auto_ptr
< reco::PFCandidateCollection
transferElectronCandidates ()
std::auto_ptr
< reco::PFCandidateElectronExtraCollection
transferElectronExtra ()
std::auto_ptr
< reco::PFCandidateCollection
transferFakeMuonCleanedCandidates ()
std::auto_ptr
< reco::PFCandidateCollection
transferPunchThroughHadronCleanedCandidates ()
std::auto_ptr
< reco::PFCandidateCollection
transferPunchThroughMuonCleanedCandidates ()
virtual ~PFAlgo ()
 destructor

Protected Member Functions

void associatePSClusters (unsigned iEcal, reco::PFBlockElement::Type psElementType, const reco::PFBlock &block, const edm::OwnVector< reco::PFBlockElement > &elements, const reco::PFBlock::LinkData &linkData, std::vector< bool > &active, std::vector< double > &psEne)
 Associate PS clusters to a given ECAL cluster, and return their energy.
bool isFromSecInt (const reco::PFBlockElement &eTrack, std::string order) const
bool isSatelliteCluster (const reco::PFRecTrack &track, const reco::PFCluster &cluster)
double neutralHadronEnergyResolution (double clusterEnergy, double clusterEta) const
 todo: use PFClusterTools for this
double nSigmaHCAL (double clusterEnergy, double clusterEta) const
void postCleaning ()
virtual void processBlock (const reco::PFBlockRef &blockref, std::list< reco::PFBlockRef > &hcalBlockRefs, std::list< reco::PFBlockRef > &ecalBlockRefs)
unsigned reconstructCluster (const reco::PFCluster &cluster, double particleEnergy, bool useDirection=false, double particleX=0., double particleY=0., double particleZ=0.)
unsigned reconstructTrack (const reco::PFBlockElement &elt)

Protected Attributes

std::auto_ptr
< reco::PFCandidateCollection
pfAddedMuonCandidates_
 the collection of added muon candidates
std::auto_ptr
< reco::PFCandidateCollection
pfCandidates_
std::auto_ptr
< reco::PFCandidateCollection
pfCleanedCandidates_
std::auto_ptr
< reco::PFCandidateCollection
pfCleanedTrackerAndGlobalMuonCandidates_
 the collection of tracker/global cleaned muon candidates
std::auto_ptr
< reco::PFCandidateCollection
pfCosmicsMuonCleanedCandidates_
 the collection of cosmics cleaned muon candidates
std::auto_ptr
< reco::PFCandidateCollection
pfElectronCandidates_
 the unfiltered electron collection
reco::PFCandidateElectronExtraCollection pfElectronExtra_
 the unfiltered electron collection
std::auto_ptr
< reco::PFCandidateCollection
pfFakeMuonCleanedCandidates_
 the collection of fake cleaned muon candidates
std::auto_ptr
< reco::PFCandidateCollection
pfPunchThroughHadronCleanedCandidates_
 the collection of punch-through cleaned neutral hadron candidates
std::auto_ptr
< reco::PFCandidateCollection
pfPunchThroughMuonCleanedCandidates_
 the collection of punch-through cleaned muon candidates

Private Member Functions

reco::PFBlockRef createBlockRef (const reco::PFBlockCollection &blocks, unsigned bi)

Private Attributes

int algo_
bool applyCrackCorrectionsElectrons_
reco::PFBlockHandle blockHandle_
 input block handle (full framework case)
boost::shared_ptr
< PFEnergyCalibration
calibration_
boost::shared_ptr
< pftools::PFClusterCalibration
clusterCalibration_
double coneEcalIsoForEgammaSC_
double coneTrackIsoForEgammaSC_
PFCandConnector connector_
bool debug_
double dptRel_DispVtx_
std::vector< double > factors45_
double maxDeltaPhiPt_
double maxSignificance_
double minDeltaMet_
double minHFCleaningPt_
double minSignificance_
double minSignificanceReduction_
std::vector< double > muonECAL_
std::vector< double > muonHCAL_
 Variables for muons and fakes.
double mvaEleCut_
std::string mvaWeightFileEleID_
 Variables for PFElectrons.
unsigned int newCalib_
double nSigmaECAL_
 number of sigma to judge energy excess in ECAL
double nSigmaHCAL_
 number of sigma to judge energy excess in HCAL
double nSigmaTRACK_
unsigned int nTrackIsoForEgammaSC_
PFConversionAlgopfConversion_
PFElectronAlgopfele_
bool postHFCleaning_
bool postMuonCleaning_
reco::Vertex primaryVertex_
double ptError_
bool rejectTracks_Bad_
bool rejectTracks_Step45_
std::vector< double > setchi2Values_
double sumEtEcalIsoForEgammaSC_barrel_
double sumEtEcalIsoForEgammaSC_endcap_
double sumPtTrackIsoForEgammaSC_barrel_
double sumPtTrackIsoForEgammaSC_endcap_
boost::shared_ptr
< PFEnergyCalibrationHF
thepfEnergyCalibrationHF_
boost::shared_ptr
< PFSCEnergyCalibration
thePFSCEnergyCalibration_
bool useEGammaSupercluster_
bool useEGElectrons_
bool usePFConversions_
bool usePFDecays_
bool usePFElectrons_
bool usePFMuonMomAssign_
bool usePFNuclearInteractions_
bool usePFSCEleCalib_
bool useVertices_

Friends

std::ostream & operator<< (std::ostream &out, const PFAlgo &algo)

Detailed Description

Definition at line 49 of file PFAlgo.h.


Constructor & Destructor Documentation

PFAlgo::PFAlgo ( )

constructor

Definition at line 56 of file PFAlgo.cc.

PFAlgo::~PFAlgo ( ) [virtual]

destructor

Definition at line 66 of file PFAlgo.cc.

References pfConversion_, pfele_, usePFConversions_, and usePFElectrons_.

                {
  if (usePFElectrons_) delete pfele_;
  if (usePFConversions_) delete pfConversion_;
}

Member Function Documentation

void PFAlgo::associatePSClusters ( unsigned  iEcal,
reco::PFBlockElement::Type  psElementType,
const reco::PFBlock block,
const edm::OwnVector< reco::PFBlockElement > &  elements,
const reco::PFBlock::LinkData linkData,
std::vector< bool > &  active,
std::vector< double > &  psEne 
) [protected]

Associate PS clusters to a given ECAL cluster, and return their energy.

Definition at line 3009 of file PFAlgo.cc.

References reco::PFBlock::associatedElements(), reco::PFBlockElement::ECAL, edm::Ref< C, T, F >::isNull(), and reco::PFBlock::LINKTEST_ALL.

Referenced by PFAlgoTestBenchElectrons::processBlock().

                                                      {

  // Find all PS clusters with type psElement associated to ECAL cluster iEcal, 
  // within all PFBlockElement "elements" of a given PFBlock "block"
  // psElement can be reco::PFBlockElement::PS1 or reco::PFBlockElement::PS2
  // Returns a vector of PS cluster energies, and updates the "active" vector.

  // Find all PS clusters linked to the iEcal cluster
  std::multimap<double, unsigned> sortedPS;
  typedef std::multimap<double, unsigned>::iterator IE;
  block.associatedElements( iEcal,  linkData,
                            sortedPS, psElementType,
                            reco::PFBlock::LINKTEST_ALL );

  // Loop over these PS clusters
  double totalPS = 0.;
  for ( IE ips=sortedPS.begin(); ips!=sortedPS.end(); ++ips ) {

    // CLuster index and distance to iEcal
    unsigned iPS = ips->second;
    // double distPS = ips->first;

    // Ignore clusters already in use
    if (!active[iPS]) continue;

    // Check that this cluster is not closer to another ECAL cluster
    std::multimap<double, unsigned> sortedECAL;
    block.associatedElements( iPS,  linkData,
                              sortedECAL,
                              reco::PFBlockElement::ECAL,
                              reco::PFBlock::LINKTEST_ALL );
    unsigned jEcal = sortedECAL.begin()->second;
    if ( jEcal != iEcal ) continue; 
    
    // Update PS energy
    PFBlockElement::Type pstype = elements[ iPS ].type();
    assert( pstype == psElementType );
    PFClusterRef psclusterref = elements[iPS].clusterRef();
    assert(!psclusterref.isNull() );
    totalPS += psclusterref->energy(); 
    psEne[0] += psclusterref->energy();
    active[iPS] = false;
  }
            

}
void PFAlgo::checkCleaning ( const reco::PFRecHitCollection cleanedHF)

Check HF Cleaning.

Definition at line 3213 of file PFAlgo.cc.

References gather_cfg::cout, debug_, reco::PFRecHit::energy(), i, j, reco::PFRecHit::layer(), minDeltaMet_, pfCandidates_, reco::PFRecHit::position(), ExpressReco_HICollisions_FallBack::pt, reco::LeafCandidate::pt(), reco::LeafCandidate::px(), reco::LeafCandidate::py(), reconstructCluster(), createPayload::skip, mathSSE::sqrt(), and reco::PFRecHit::time().

Referenced by PFRootEventManager::particleFlow().

                                                                 { 
  

  // No hits to recover, leave.
  if ( !cleanedHits.size() ) return;

  //Compute met and met significance (met/sqrt(SumEt))
  double metX = 0.;
  double metY = 0.;
  double sumet = 0;
  std::vector<unsigned int> hitsToBeAdded;
  for(unsigned i=0; i<pfCandidates_->size(); i++) {
    const PFCandidate& pfc = (*pfCandidates_)[i];
    metX += pfc.px();
    metY += pfc.py();
    sumet += pfc.pt();
  }
  double met2 = metX*metX+metY*metY;
  double met2_Original = met2;
  // Select events with large MET significance.
  // double significance = std::sqrt(met2/sumet);
  // double significanceCor = significance;
  double metXCor = metX;
  double metYCor = metY;
  double sumetCor = sumet;
  double met2Cor = met2;
  bool next = true;
  unsigned iCor = 1E9;
  
  // Find the cleaned hit with the largest effect on the MET
  while ( next ) { 
    
    double metReduc = -1.;
    double setReduc = -1.;
    // Loop on the candidates
    for(unsigned i=0; i<cleanedHits.size(); ++i) {
      const PFRecHit& hit = cleanedHits[i];
      double length = std::sqrt(hit.position().Mag2()); 
      double px = hit.energy() * hit.position().x()/length;
      double py = hit.energy() * hit.position().y()/length;
      double pt = std::sqrt(px*px + py*py);
      
      // Check that it is  not already scheculed to be cleaned
      bool skip = false;
      for(unsigned j=0; j<hitsToBeAdded.size(); ++j) {
        if ( i == hitsToBeAdded[j] ) skip = true;
        if ( skip ) break;
      }
      if ( skip ) continue;
      
      // Now add the candidate to the MET
      double metXInt = metX + px;
      double metYInt = metY + py;
      double sumetInt = sumet + pt;
      double met2Int = metXInt*metXInt+metYInt*metYInt;

      // And check if it could contribute to a MET reduction
      if ( met2Int < met2Cor ) {
        metXCor = metXInt;
        metYCor = metYInt;
        metReduc = (met2-met2Int)/met2Int; 
        setReduc = (std::sqrt(met2Int)-std::sqrt(met2))/(sumetInt-sumet); 
        met2Cor = met2Int;
        sumetCor = sumetInt;
        // significanceCor = std::sqrt(met2Cor/sumetCor);
        iCor = i;
      }
    }
    //
    // If the MET must be significanly reduced, schedule the candidate to be added
    //
    if ( metReduc > minDeltaMet_ ) { 
      hitsToBeAdded.push_back(iCor);
      metX = metXCor;
      metY = metYCor;
      sumet = sumetCor;
      met2 = met2Cor;
    } else { 
      // Otherwise just stop the loop
      next = false;
    }
  }
  //
  // At least 10 GeV MET reduction
  if ( std::sqrt(met2_Original) - std::sqrt(met2) > 5. ) { 
    if ( debug_ ) { 
      std::cout << hitsToBeAdded.size() << " hits were re-added " << std::endl;
      std::cout << "MET reduction = " << std::sqrt(met2_Original) << " -> " 
                << std::sqrt(met2Cor) << " = " <<  std::sqrt(met2Cor) - std::sqrt(met2_Original)  
                << std::endl;
      std::cout << "Added after cleaning check : " << std::endl; 
    }
    for(unsigned j=0; j<hitsToBeAdded.size(); ++j) {
      const PFRecHit& hit = cleanedHits[hitsToBeAdded[j]];
      PFCluster cluster(hit.layer(), hit.energy(),
                        hit.position().x(), hit.position().y(), hit.position().z() );
      reconstructCluster(cluster,hit.energy());
      if ( debug_ ) { 
        std::cout << pfCandidates_->back() << ". time = " << hit.time() << std::endl;
      }
    }
  }

}
reco::PFBlockRef PFAlgo::createBlockRef ( const reco::PFBlockCollection blocks,
unsigned  bi 
) [private]

create a reference to a block, transient or persistent depending on the needs

Definition at line 2997 of file PFAlgo.cc.

References blockHandle_, and edm::HandleBase::isValid().

Referenced by reconstructParticles().

                                      {

  if( blockHandle_.isValid() ) {
    return reco::PFBlockRef(  blockHandle_, bi );
  } 
  else {
    return reco::PFBlockRef(  &blocks, bi );
  }
}
bool PFAlgo::isFromSecInt ( const reco::PFBlockElement eTrack,
std::string  order 
) const [protected]

Definition at line 3064 of file PFAlgo.cc.

References reco::PFBlockElement::T_FROM_DISP, reco::PFBlockElement::T_FROM_GAMMACONV, reco::PFBlockElement::T_FROM_V0, reco::PFBlockElement::T_TO_DISP, reco::PFBlockElement::trackType(), usePFConversions_, usePFDecays_, and usePFNuclearInteractions_.

Referenced by PFAlgoTestBenchElectrons::processBlock(), and reconstructTrack().

                                                                         {

  reco::PFBlockElement::TrackType T_TO_DISP = reco::PFBlockElement::T_TO_DISP;
  reco::PFBlockElement::TrackType T_FROM_DISP = reco::PFBlockElement::T_FROM_DISP;
  reco::PFBlockElement::TrackType T_FROM_GAMMACONV = reco::PFBlockElement::T_FROM_GAMMACONV;
  reco::PFBlockElement::TrackType T_FROM_V0 = reco::PFBlockElement::T_FROM_V0;

  bool bPrimary = (order.find("primary") != string::npos);
  bool bSecondary = (order.find("secondary") != string::npos);
  bool bAll = (order.find("all") != string::npos);

  bool isToDisp = usePFNuclearInteractions_ && eTrack.trackType(T_TO_DISP);
  bool isFromDisp = usePFNuclearInteractions_ && eTrack.trackType(T_FROM_DISP);

  if (bPrimary && isToDisp) return true;
  if (bSecondary && isFromDisp ) return true;
  if (bAll && ( isToDisp || isFromDisp ) ) return true;

  bool isFromConv = usePFConversions_ && eTrack.trackType(T_FROM_GAMMACONV);

  if ((bAll || bSecondary)&& isFromConv) return true;

  bool isFromDecay = (bAll || bSecondary) && usePFDecays_ && eTrack.trackType(T_FROM_V0);

  return isFromDecay;


}
bool PFAlgo::isSatelliteCluster ( const reco::PFRecTrack track,
const reco::PFCluster cluster 
) [protected]

Checking if a given cluster is a satellite cluster of a given charged hadron (track)

Definition at line 2950 of file PFAlgo.cc.

References funct::cos(), gather_cfg::cout, debug_, reco::PFTrack::extrapolatedPoint(), PFLayer::HCAL_BARREL1, PFLayer::HCAL_ENDCAP, reco::PFTrajectoryPoint::HCALEntrance, reco::PFTrajectoryPoint::isValid(), reco::PFCluster::layer(), link(), reco::PFTrajectoryPoint::position(), reco::PFCluster::positionREP(), and mathSSE::sqrt().

                                                           {
  //This is to check whether a HCAL cluster could be 
  //a satellite cluster of a given track (charged hadron)
  //Definitions:
  //Track-Hcal: An Hcal cluster can be associated to a 
  //            track if it is found in a region around (dr<0.17 ~ 3x3 matrix)
  //            the position of the track extrapolated to the Hcal.

  bool link = false;

  if( cluster.layer() == PFLayer::HCAL_BARREL1 ||
      cluster.layer() == PFLayer::HCAL_ENDCAP ) { //Hcal case
    
    const reco::PFTrajectoryPoint& atHCAL 
      = track.extrapolatedPoint( reco::PFTrajectoryPoint::HCALEntrance );
              
    if( atHCAL.isValid() ){ //valid extrapolation?
      double tracketa = atHCAL.position().Eta();
      double trackphi = atHCAL.position().Phi();
      double hcaleta  = cluster.positionREP().Eta();
      double hcalphi  = cluster.positionREP().Phi();
                  
      //distance track-cluster
      double deta = hcaleta - tracketa;
      double dphi = acos(cos(hcalphi - trackphi));
      double dr   = sqrt(deta*deta + dphi*dphi);

      if( debug_ ){
        cout<<"\t\t\tSatellite Test " 
            <<tracketa<<" "<<trackphi<<" "
            <<hcaleta<<" "<<hcalphi<<" dr="<<dr 
            <<endl;
      }
      
      //looking if cluster is in the  
      //region around the track. 
      //Alex: Will have to adjust this cut?
      if( dr < 0.17 ) link = true;
    }//extrapolation
    
  }//HCAL
  
  return link; 
}
double PFAlgo::neutralHadronEnergyResolution ( double  clusterEnergy,
double  clusterEta 
) const [protected]

todo: use PFClusterTools for this

Returns:
calibrated energy of a photon
calibrated energy of a neutral hadron, which can leave some energy in the ECAL ( energyECAL>0 )

Definition at line 2884 of file PFAlgo.cc.

References newCalib_, and mathSSE::sqrt().

Referenced by PFAlgoTestBenchElectrons::processBlock().

                                                                                {

  // Add a protection
  if ( clusterEnergyHCAL < 1. ) clusterEnergyHCAL = 1.;

  double resol = 0.;
  if ( newCalib_ == 1 ) 
    resol =   1.40/sqrt(clusterEnergyHCAL) +5.00/clusterEnergyHCAL;
  else if ( newCalib_ == 0 ) 
    resol =   1.50/sqrt(clusterEnergyHCAL) +3.00/clusterEnergyHCAL;
  else
    resol =   fabs(eta) < 1.48 ? 
      //min(0.25,sqrt (1.02*1.02/clusterEnergyHCAL + 0.065*0.065)):
      //min(0.30,sqrt (1.35*1.35/clusterEnergyHCAL + 0.018*0.018));
      // sqrt (1.02*1.02/clusterEnergyHCAL + 0.065*0.065)
      sqrt (0.9*0.9/clusterEnergyHCAL + 0.065*0.065)
      :
      // sqrt (1.35*1.35/clusterEnergyHCAL + 0.018*0.018);
      sqrt (1.10*1.10/clusterEnergyHCAL + 0.018*0.018);

  return resol;
}
double PFAlgo::nSigmaHCAL ( double  clusterEnergy,
double  clusterEta 
) const [protected]

Definition at line 2908 of file PFAlgo.cc.

References funct::exp(), newCalib_, and nSigmaHCAL_.

Referenced by PFAlgoTestBenchElectrons::processBlock(), and setParameters().

                                                             {
  double nS;
  if ( newCalib_ == 2 ) 
    nS =   fabs(eta) < 1.48 ? 
      nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.))     
      :
      nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/200.));
  else 
    nS = nSigmaHCAL_;
  
  return nS;
}
const std::auto_ptr< reco::PFCandidateCollection >& PFAlgo::pfCandidates ( ) const [inline]
Returns:
collection of candidates

Definition at line 148 of file PFAlgo.h.

References pfCandidates_.

Referenced by operator<<().

                                                                       {
    return pfCandidates_;
  }
void PFAlgo::postCleaning ( ) [protected]

Definition at line 3100 of file PFAlgo.cc.

References gather_cfg::cout, Geom::deltaPhi(), reco::PFCandidate::egamma_HF, reco::PFCandidate::h_HF, i, j, maxDeltaPhiPt_, maxSignificance_, minDeltaMet_, minHFCleaningPt_, minSignificance_, minSignificanceReduction_, reco::PFCandidate::particleId(), pfCandidates_, pfCleanedCandidates_, postHFCleaning_, reco::LeafCandidate::pt(), reco::LeafCandidate::px(), reco::LeafCandidate::py(), createPayload::skip, and mathSSE::sqrt().

Referenced by reconstructParticles().

                     { 
  
  // Check if the post HF Cleaning was requested - if not, do nothing
  if ( !postHFCleaning_ ) return;

  //Compute met and met significance (met/sqrt(SumEt))
  double metX = 0.;
  double metY = 0.;
  double sumet = 0;
  std::vector<unsigned int> pfCandidatesToBeRemoved;
  for(unsigned i=0; i<pfCandidates_->size(); i++) {
    const PFCandidate& pfc = (*pfCandidates_)[i];
    metX += pfc.px();
    metY += pfc.py();
    sumet += pfc.pt();
  }    
  double met2 = metX*metX+metY*metY;
  // Select events with large MET significance.
  double significance = std::sqrt(met2/sumet);
  double significanceCor = significance;
  if ( significance > minSignificance_ ) { 
    
    double metXCor = metX;
    double metYCor = metY;
    double sumetCor = sumet;
    double met2Cor = met2;
    double deltaPhi = 3.14159;
    double deltaPhiPt = 100.;
    double deltaPhiCor = 3.14159;
    double deltaPhiPtCor = 100.;
    bool next = true;
    unsigned iCor = 1E9;

    // Find the HF candidate with the largest effect on the MET
    while ( next ) { 

      double metReduc = -1.;
      double setReduc = -1.;
      // Loop on the candidates
      for(unsigned i=0; i<pfCandidates_->size(); ++i) {
        const PFCandidate& pfc = (*pfCandidates_)[i];

        // Check that the pfCandidate is in the HF
        if ( pfc.particleId() != reco::PFCandidate::h_HF && 
             pfc.particleId() != reco::PFCandidate::egamma_HF ) continue;

        // Check if has meaningful pt
        if ( pfc.pt() < minHFCleaningPt_ ) continue;
        
        // Check that it is  not already scheculed to be cleaned
        bool skip = false;
        for(unsigned j=0; j<pfCandidatesToBeRemoved.size(); ++j) {
          if ( i == pfCandidatesToBeRemoved[j] ) skip = true;
          if ( skip ) break;
        }
        if ( skip ) continue;
        
        // Check that the pt and the MET are aligned
        deltaPhi = std::acos((metX*pfc.px()+metY*pfc.py())/(pfc.pt()*std::sqrt(met2)));
        deltaPhiPt = deltaPhi*pfc.pt();
        if ( deltaPhiPt > maxDeltaPhiPt_ ) continue;

        // Now remove the candidate from the MET
        double metXInt = metX - pfc.px();
        double metYInt = metY - pfc.py();
        double sumetInt = sumet - pfc.pt();
        double met2Int = metXInt*metXInt+metYInt*metYInt;
        if ( met2Int < met2Cor ) {
          metXCor = metXInt;
          metYCor = metYInt;
          metReduc = (met2-met2Int)/met2Int; 
          setReduc = (std::sqrt(met2Int)-std::sqrt(met2))/(sumetInt-sumet); 
          met2Cor = met2Int;
          sumetCor = sumetInt;
          significanceCor = std::sqrt(met2Cor/sumetCor);
          iCor = i;
          deltaPhiCor = deltaPhi;
          deltaPhiPtCor = deltaPhiPt;
        }
      }
      //
      // If the MET must be significanly reduced, schedule the candidate to be cleaned
      if ( metReduc > minDeltaMet_ ) { 
        pfCandidatesToBeRemoved.push_back(iCor);
        metX = metXCor;
        metY = metYCor;
        sumet = sumetCor;
        met2 = met2Cor;
      } else { 
      // Otherwise just stop the loop
        next = false;
      }
    }
    //
    // The significance must be significantly reduced to indeed clean the candidates
    if ( significance - significanceCor > minSignificanceReduction_ && 
         significanceCor < maxSignificance_ ) {
      std::cout << "Significance reduction = " << significance << " -> " 
                << significanceCor << " = " << significanceCor - significance 
                << std::endl;
      for(unsigned j=0; j<pfCandidatesToBeRemoved.size(); ++j) {
        std::cout << "Removed : " << (*pfCandidates_)[pfCandidatesToBeRemoved[j]] << std::endl;
        pfCleanedCandidates_->push_back( (*pfCandidates_)[ pfCandidatesToBeRemoved[j] ] );
        (*pfCandidates_)[pfCandidatesToBeRemoved[j]].rescaleMomentum(0.);
        //reco::PFCandidate::ParticleType unknown = reco::PFCandidate::X;
        //(*pfCandidates_)[pfCandidatesToBeRemoved[j]].setParticleType(unknown);
      }
    }
  }

}
void PFAlgo::postMuonCleaning ( const edm::Handle< reco::MuonCollection > &  muonh,
const reco::VertexCollection primaryVertices 
)

Definition at line 3320 of file PFAlgo.cc.

References DeDxDiscriminatorTools::charge(), gather_cfg::cout, reco::PFCandidate::elementsInBlocks(), relval_parameters_module::energy, reco::LeafCandidate::eta(), reco::PFCandidate::h, h, reco::PFCandidate::h0, i, PFMuonAlgo::isIsolatedMuon(), edm::Ref< C, T, F >::isNonnull(), edm::Ref< C, T, F >::key(), max(), reco::PFCandidate::mu, reco::PFCandidate::muonRef(), reco::LeafCandidate::p(), p4, reco::PFCandidate::particleId(), ExpressReco_HICollisions_FallBack::particleType, pfAddedMuonCandidates_, ExpressReco_HICollisions_FallBack::PFCandidate, pfCandidates_, pfCleanedTrackerAndGlobalMuonCandidates_, pfCosmicsMuonCleanedCandidates_, pfFakeMuonCleanedCandidates_, pfPunchThroughHadronCleanedCandidates_, pfPunchThroughMuonCleanedCandidates_, primaryVertex_, ExpressReco_HICollisions_FallBack::pt, reco::LeafCandidate::pt(), reco::LeafCandidate::px(), reco::LeafCandidate::py(), CosmicsPD_Skims::radius, reco::PFCandidate::rawEcalEnergy(), reco::PFCandidate::rawHcalEnergy(), findQualityFiles::size, mathSSE::sqrt(), reco::PFCandidate::trackRef(), reco::LeafCandidate::vx(), reco::LeafCandidate::vy(), reco::Vertex::x(), and reco::Vertex::y().

Referenced by PFRootEventManager::particleFlow().

                                                                       {
  

  bool printout = false;
  // Check if the post muon Cleaning was requested - if not, do nothing
  //if ( !postMuonCleaning_ ) return;

  // Estimate SumEt from pile-up
  double sumetPU = 0.;
  for (unsigned short i=1 ;i<primaryVertices.size();++i ) {
    if ( !primaryVertices[i].isValid() || primaryVertices[i].isFake() ) continue; 
    primaryVertices[i];
    for ( reco::Vertex::trackRef_iterator itr = primaryVertices[i].tracks_begin();
          itr <  primaryVertices[i].tracks_end(); ++itr ) { 
      sumetPU += (*itr)->pt();
    }
  }
  sumetPU /= 0.65; // To estimate the neutral contribution from PU
  // std::cout << "Evaluation of sumetPU from " << primaryVertices.size() << " vertices : " << sumetPU << std::endl;

  //Compute met and met significance (met/sqrt(SumEt))
  double metX = 0.;
  double metY = 0.;
  double sumet = 0;
  double metXCosmics = 0.;
  double metYCosmics = 0.;
  double sumetCosmics = 0.;

  std::map<double,unsigned int> pfMuons;
  std::map<double,unsigned int> pfCosmics;
  typedef std::multimap<double, unsigned int>::iterator IE;

  for(unsigned i=0; i<pfCandidates_->size(); i++) {
    const PFCandidate& pfc = (*pfCandidates_)[i];
    double origin = 
      (pfc.vx()-primaryVertex_.x())*(pfc.vx()-primaryVertex_.x()) + 
      (pfc.vy()-primaryVertex_.y())*(pfc.vy()-primaryVertex_.y());

    // Compute MET
    metX += pfc.px();
    metY += pfc.py();
    sumet += pfc.pt();

    // Remember the muons and order them by decreasing energy
    // Remember the cosmic muons too 
    if ( pfc.particleId() == reco::PFCandidate::mu ) { 
      pfMuons.insert(std::pair<double,unsigned int>(-pfc.pt(),i));
      if ( origin > 1.0 ) { 
        pfCosmics.insert(std::pair<double,unsigned int>(-pfc.pt(),i));
        metXCosmics += pfc.px();
        metYCosmics += pfc.py();
        sumetCosmics += pfc.pt();
      }
    }
      
  }

  double met2 = metX*metX+metY*metY;
  double met2Cosmics = (metX-metXCosmics)*(metX-metXCosmics)+(metY-metYCosmics)*(metY-metYCosmics);

  // Clean cosmic muons
  if ( sumetCosmics > (sumet-sumetPU)/10. && met2Cosmics < met2 ) { 
    if ( printout ) 
      std::cout << "MEX,MEY,MET Before (Cosmics)" << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
    for ( IE imu = pfCosmics.begin(); imu != pfCosmics.end(); ++imu ) { 
      const PFCandidate& pfc = (*pfCandidates_)[imu->second];
      //const PFCandidate pfcopy = pfc;
      pfCosmicsMuonCleanedCandidates_->push_back(pfc);
      if ( printout ) 
        std::cout << "Muon cleaned (cosmic). pt/d0 = " << pfc.pt() << " " 
                  << std::sqrt(pfc.vx()*pfc.vx() + pfc.vy()*pfc.vy()) << std::endl; 
      metX -= pfc.px();
      metY -= pfc.py();
      sumet -= pfc.pt();
      (*pfCandidates_)[imu->second].rescaleMomentum(0.);
    }
    met2 = metX*metX+metY*metY;
    if ( printout ) 
      std::cout << "MEX,MEY,MET After  (Cosmics)" << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
  }

  // The remaining met
  // double metInitial = std::sqrt(met2);
  
  // Clean mismeasured muons
  for ( IE imu = pfMuons.begin(); imu != pfMuons.end(); ++imu ) { 
    const PFCandidate& pfc = (*pfCandidates_)[imu->second];

    // Don't care about low momentum muons
    if ( pfc.pt() < 20. ) continue;

    double metXNO = metX - pfc.px();
    double metYNO = metY - pfc.py();
    double met2NO = metXNO*metXNO + metYNO*metYNO; 
    double sumetNO = sumet - pfc.pt();
    double factor = std::max(2.,2000./sumetNO);

    reco::MuonRef muonRef = pfc.muonRef();
    reco::TrackRef combinedMu = muonRef->combinedMuon();
    reco::TrackRef trackerMu = muonRef->track();
    reco::TrackRef standAloneMu = muonRef->standAloneMuon();

    if ( !combinedMu || !trackerMu ) { 
      if ( sumetNO-sumetPU > 500. && met2NO < met2/4.) { 
        pfFakeMuonCleanedCandidates_->push_back(pfc);
        if ( printout ) {
          std::cout << "Muon cleaned (NO-bad) " << sumetNO << std::endl;
          std::cout << "sumet NO " << sumetNO << std::endl;
        }
        (*pfCandidates_)[imu->second].rescaleMomentum(0.);
        if ( printout ) 
          std::cout << "MEX,MEY,MET            " << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
        metX = metXNO;
        metY = metYNO;
        met2 = met2NO;
        sumet = sumetNO;
        if ( printout ) {
          std::cout << "Muon cleaned (NO/TK) ! " << std::endl;
          std::cout << "MEX,MEY,MET Now (NO/TK)" << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
        }
      }
    } else { 
      /*
      std::cout << "PF Muon vx,vy " << pfc.vx() << " " << pfc.vy() << std::endl;
      std::cout << "PF Muon px,py,pt: " << pfc.px() << " " << pfc.py() << " " << pfc.pt() << std::endl;
      std::cout << "TK Muon px,py,pt: " << trackerMu->px() << " " << trackerMu->py() << " " << trackerMu->pt() << " " << std::endl;
      std::cout << "GL Muon px,py,pt: " << combinedMu->px() << " " << combinedMu->py() << " " << combinedMu->pt() << " " << std::endl; 
      std::cout << "ST Muon px,py,pt: " << standAloneMu->px() << " " << standAloneMu->py() << " " << standAloneMu->pt() << " " << std::endl;
      std::cout << "isolated ? " << PFMuonAlgo::isIsolatedMuon(muonRef) << std::endl; 
      */
      double metXTK = metXNO + trackerMu->px(); 
      double metYTK = metYNO + trackerMu->py();
      double met2TK = metXTK*metXTK + metYTK*metYTK;
 
      double metXGL = metXNO + combinedMu->px();
      double metYGL = metYNO + combinedMu->py();
      double met2GL = metXGL*metXGL + metYGL*metYGL; 

      /*
      double metXST = metXNO + standAloneMu->px();
      double metYST = metYNO + standAloneMu->py();
      double met2ST = metXST*metXST + metYST*metYST; 
      */

      /*
      std::cout << "sumet NO " << sumetNO << std::endl;
      std::cout << "MEX,MEY,MET NO" << metXNO << " " << metYNO << " " << std::sqrt(met2NO) << std::endl;
      std::cout << "MEX,MEY,MET TK" << metXTK << " " << metYTK << " " << std::sqrt(met2TK) << std::endl;
      std::cout << "MEX,MEY,MET GL" << metXGL << " " << metYGL << " " << std::sqrt(met2GL) << std::endl;
      std::cout << "MEX,MEY,MET ST" << metXST << " " << metYST << " " << std::sqrt(met2ST) << std::endl;
      */

      bool fixed = false;
      if ( ( sumetNO-sumetPU > 250. && met2TK < met2/4. && met2TK < met2GL ) || 
           ( met2TK < met2/2. && trackerMu->pt() < combinedMu->pt()/4. && met2TK < met2GL ) )  { 
        pfCleanedTrackerAndGlobalMuonCandidates_->push_back(pfc);
        math::XYZTLorentzVectorD p4(trackerMu->px(),trackerMu->py(),trackerMu->pz(),
                                    std::sqrt(trackerMu->p()*trackerMu->p()+0.1057*0.1057));
        if ( printout ) 
          std::cout << "Muon cleaned (TK) ! " << met2TK/met2 << " " << trackerMu->pt() / combinedMu->pt() << std::endl;
        (*pfCandidates_)[imu->second].setP4(p4);
        if ( printout ) 
          std::cout << "MEX,MEY,MET Before (TK)" << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
        metX = metXTK;
        metY = metYTK;
        met2 = met2TK;
        fixed = true;
        if ( printout ) 
          std::cout << "MEX,MEY,MET Now    (TK)" << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
      } 
      
      else if ( ( sumetNO-sumetPU > 250. && met2GL < met2/4. && met2GL < met2TK ) ||  
                ( met2GL < met2/2. && combinedMu->pt() < trackerMu->pt()/4.&& met2GL < met2TK ) )  { 
        pfCleanedTrackerAndGlobalMuonCandidates_->push_back(pfc);
        math::XYZTLorentzVectorD p4(combinedMu->px(),combinedMu->py(),combinedMu->pz(),
                                    std::sqrt(combinedMu->p()*combinedMu->p()+0.1057*0.1057));
        if ( printout ) 
          std::cout << "Muon cleaned (GL) ! " << met2GL/met2 << " " << combinedMu->pt()/trackerMu->pt() <<  std::endl;
        (*pfCandidates_)[imu->second].setP4(p4);
        if ( printout ) 
          std::cout << "MEX,MEY,MET before (GL)" << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
        metX = metXGL;
        metY = metYGL;
        met2 = met2GL;
        fixed = true;
        if ( printout ) 
          std::cout << "MEX,MEY,MET Now    (GL)" << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
      }

      // Fake muons at large pseudo-rapidity
      bool fake = 
        fabs ( pfc.eta() ) > 2.15 && 
        met2NO < met2/25. && 
        (met2GL < met2TK/2. || met2TK < met2GL/2.) &&
        standAloneMu->pt() < combinedMu->pt()/10. &&
        standAloneMu->pt() < trackerMu->pt()/10.; 

      // Fake and/or punch-through candidates
      bool punchthrough1 =  
        ( sumetNO-sumetPU > 250. && met2NO < met2/4. && (met2GL < met2TK/factor || met2TK < met2GL/factor) );

      // Now look for punch through candidates (i.e., muon with large neutral hadron behind)
      bool punchthrough2 =  
        pfc.p() > 100. &&  pfc.rawHcalEnergy() > 100. && 
        pfc.rawEcalEnergy()+pfc.rawHcalEnergy() > pfc.p()/3. &&
        !PFMuonAlgo::isIsolatedMuon(muonRef) && met2NO < met2/4.;

      if ( punchthrough1 ||  punchthrough2 || fake ) { 
        
        // Find the block of the muon
        const PFCandidate::ElementsInBlocks& eleInBlocks = pfc.elementsInBlocks();
        PFBlockRef blockRefMuon = eleInBlocks[0].first;
        unsigned indexMuon = eleInBlocks[0].second;
        for ( unsigned iele = 1; iele < eleInBlocks.size(); ++iele ) { 
          indexMuon = eleInBlocks[iele].second;
          break;
        }
        
        // Check if the muon gave rise to a neutral hadron
        double iHad = 1E9;
        bool hadron = false;
        for ( unsigned i = imu->second+1; i < pfCandidates_->size(); ++i ) { 
          const PFCandidate& pfcn = (*pfCandidates_)[i];
          const PFCandidate::ElementsInBlocks& ele = pfcn.elementsInBlocks();
          PFBlockRef blockRefHadron = ele[0].first;
          unsigned indexHadron = ele[0].second;
          // We are out of the block -> exit the loop
          if ( blockRefHadron.key() != blockRefMuon.key() ) break;
          // Check that this particle is a neutral hadron
          if ( indexHadron == indexMuon && 
               pfcn.particleId() == reco::PFCandidate::h0 ) {
            iHad = i;
            hadron = true;
          }
          if ( hadron ) break;
        }

        if ( hadron ) { 
          const PFCandidate& pfch = (*pfCandidates_)[iHad];
          pfPunchThroughMuonCleanedCandidates_->push_back(pfc);
          pfPunchThroughHadronCleanedCandidates_->push_back(pfch);
          //std::cout << pfc << std::endl;
          //std::cout << "Raw ecal/hcal : " << pfc.rawEcalEnergy() << " " << pfc.rawHcalEnergy() << std::endl;
          //std::cout << "Hadron: " << (*pfCandidates_)[iHad] << std::endl;
          double rescaleFactor = (*pfCandidates_)[iHad].p()/(*pfCandidates_)[imu->second].p();
          metX -=  (*pfCandidates_)[imu->second].px() + (*pfCandidates_)[iHad].px();
          metY -=  (*pfCandidates_)[imu->second].py() + (*pfCandidates_)[iHad].py();
          (*pfCandidates_)[imu->second].rescaleMomentum(rescaleFactor);
          (*pfCandidates_)[iHad].rescaleMomentum(0);
          (*pfCandidates_)[imu->second].setParticleType(reco::PFCandidate::h);
          if ( printout ) 
            std::cout << "MEX,MEY,MET Before " << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
          metX +=  (*pfCandidates_)[imu->second].px();
          metY +=  (*pfCandidates_)[imu->second].py();    
          met2 = metX*metX + metY*metY;
          if ( printout ) {
            std::cout << "Muon changed to charged hadron" << std::endl;
            std::cout << "MEX,MEY,MET Now (NO)" << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
          }
        } else if ( punchthrough1 || fake ) {
          const PFCandidate& pfc = (*pfCandidates_)[imu->second];
          pfFakeMuonCleanedCandidates_->push_back(pfc);
          if ( printout ) 
            std::cout << "MEX,MEY,MET Before " << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
          metX -=  (*pfCandidates_)[imu->second].px();
          metY -=  (*pfCandidates_)[imu->second].py();    
          met2 = metX*metX + metY*metY;
          (*pfCandidates_)[imu->second].rescaleMomentum(0.);
          if ( printout ) {
            std::cout << "Muon cleaned (NO)" << std::endl;
            std::cout << "MEX,MEY,MET Now (NO)" << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
          }
        }
      }

      /*
      if ( !fixed ) { 
        std::cout << "TK Muon px,py,pt: " << trackerMu->px() << " " << trackerMu->py() << " " << trackerMu->pt() << " " << std::endl;
        std::cout << "GL Muon px,py,pt: " << combinedMu->px() << " " << combinedMu->py() << " " << combinedMu->pt() << " " << std::endl;
        std::cout << "MEX,MEY,MET PF " << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
        std::cout << "MEX,MEY,MET NO " << metXNO << " " << metYNO << " " << std::sqrt(met2NO) << std::endl;
        std::cout << "MEX,MEY,MET TK " << metXTK << " " << metYTK << " " << std::sqrt(met2TK) << std::endl;
        std::cout << "MEX,MEY,MET GL " << metXGL << " " << metYGL << " " << std::sqrt(met2GL) << std::endl;
      }
      */
    }

  }

  // And now, add muons which did not make it for various reasons
  for ( unsigned imu = 0; imu < muonh->size(); ++imu ) {
    reco::MuonRef muonRef( muonh, imu );
    // If not used, check its effect on met
    reco::TrackRef combinedMu = muonRef->combinedMuon();
    reco::TrackRef trackerMu = muonRef->track();
    reco::TrackRef standAloneMu = muonRef->standAloneMuon();

    // check if the muons has already been taken
    bool used = false;
    bool hadron = false;
    unsigned iHad = 1E9;
    for(unsigned i=0; i<pfCandidates_->size(); i++) {
      const PFCandidate& pfc = (*pfCandidates_)[i];
      if ( pfc.trackRef().isNonnull() && pfc.trackRef() == trackerMu ) { 
        hadron = true;
        iHad = i;
      }
      if ( !pfc.muonRef().isNonnull() || pfc.muonRef() != muonRef ) continue;
      used = true;
      if ( used ) break;
    }

    if ( used ) continue;

    double ptGL = muonRef->isGlobalMuon() ? combinedMu->pt() : 0.;
    double pxGL = muonRef->isGlobalMuon() ? combinedMu->px() : 0.;
    double pyGL = muonRef->isGlobalMuon() ? combinedMu->py() : 0.;
    double pzGL = muonRef->isGlobalMuon() ? combinedMu->pz() : 0.;

    double ptTK = muonRef->isTrackerMuon() ? trackerMu->pt() : 0.;
    double pxTK = muonRef->isTrackerMuon() ? trackerMu->px() : 0.;
    double pyTK = muonRef->isTrackerMuon() ? trackerMu->py() : 0.;
    double pzTK = muonRef->isTrackerMuon() ? trackerMu->pz() : 0.;

    double ptST = muonRef->isStandAloneMuon() ? standAloneMu->pt() : 0.;
    double pxST = muonRef->isStandAloneMuon() ? standAloneMu->px() : 0.;
    double pyST = muonRef->isStandAloneMuon() ? standAloneMu->py() : 0.;
    double pzST = muonRef->isStandAloneMuon() ? standAloneMu->pz() : 0.;

    //std::cout << "pT TK/GL/ST : " << ptTK << " " << ptGL << " " << ptST << std::endl;

    double metXTK = metX + pxTK; 
    double metYTK = metY + pyTK;
    double met2TK = metXTK*metXTK + metYTK*metYTK;
    
    double metXGL = metX + pxGL;
    double metYGL = metY + pyGL;
    double met2GL = metXGL*metXGL + metYGL*metYGL; 

    double metXST = metX + pxST; 
    double metYST = metY + pyST;
    double met2ST = metXST*metXST + metYST*metYST;

    //std::cout << "met TK/GL/ST : " << sqrt(met2) << " " << sqrt(met2TK) << " " << sqrt(met2GL) << " " << sqrt(met2ST) << std::endl;


    if ( ptTK > 20. && met2TK < met2/4. && met2TK < met2GL && met2TK < met2ST ) { 
      double energy = std::sqrt(pxTK*pxTK+pyTK*pyTK+pzTK*pzTK+0.1057*0.1057);
      int charge = trackerMu->charge()>0 ? 1 : -1;
      math::XYZTLorentzVector momentum(pxTK,pyTK,pzTK,energy);
      reco::PFCandidate::ParticleType particleType = 
         ptGL > 20. ? reco::PFCandidate::mu : reco::PFCandidate::h;
      double radius = std::sqrt(
         (trackerMu->vertex().x()-primaryVertex_.x())*(trackerMu->vertex().x()-primaryVertex_.x())+
         (trackerMu->vertex().y()-primaryVertex_.y())*(trackerMu->vertex().y()-primaryVertex_.y()));
      
      // Add it to the stack ( if not already in the list ) 
      if ( !hadron && radius < 1.0 ) { 
        pfCandidates_->push_back( PFCandidate( charge, 
                                               momentum,
                                               particleType ) );
        
        pfCandidates_->back().setVertex( trackerMu->vertex() );
        pfCandidates_->back().setTrackRef( trackerMu );
        pfCandidates_->back().setMuonRef( muonRef );
        
        if ( printout ) {
          std::cout << "MEX,MEY,MET before " << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
          std::cout << "Muon TK added " << std::endl;
          std::cout << "pT TK/GL/ST : " << ptTK << " " << ptGL << " " << ptST << std::endl;
        }
        metX +=  pfCandidates_->back().px();
        metY +=  pfCandidates_->back().py();      
        met2 = metX*metX + metY*metY;
        if ( printout ) {
          std::cout <<  pfCandidates_->back() << std::endl;
          std::cout << "MEX,MEY,MET   now " << metX << " " << metY << " " << std::sqrt(met2) << std::endl; 
        }

        const PFCandidate& pfc = pfCandidates_->back();
        pfAddedMuonCandidates_->push_back(pfc);

      }

    } else  if (  ptGL > 20. && met2GL < met2/4. && met2GL < met2TK && met2GL < met2ST ) { 

      double energy = std::sqrt(pxGL*pxGL+pyGL*pyGL+pzGL*pzGL+0.1057*0.1057);
      int charge = combinedMu->charge()>0 ? 1 : -1;
      math::XYZTLorentzVector momentum(pxGL,pyGL,pzGL,energy);
      reco::PFCandidate::ParticleType particleType = reco::PFCandidate::mu;
      double radius = std::sqrt(
        (combinedMu->vertex().x()-primaryVertex_.x())*(combinedMu->vertex().x()-primaryVertex_.x())+
        (combinedMu->vertex().y()-primaryVertex_.y())*(combinedMu->vertex().y()-primaryVertex_.y()));
      
      // Add it to the stack
      if ( radius < 1.0 ) { 
        pfCandidates_->push_back( PFCandidate( charge, 
                                               momentum,
                                               particleType ) );
        
        pfCandidates_->back().setVertex( combinedMu->vertex() );
        //if ( ptTK > 0. ) 
        if (trackerMu.isNonnull() ) pfCandidates_->back().setTrackRef( trackerMu );
        pfCandidates_->back().setMuonRef( muonRef );
        
        if ( printout ) {
          std::cout << "MEX,MEY,MET before " << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
          std::cout << "Muon GL added " << std::endl;
          std::cout << "pT TK/GL/ST : " << ptTK << " " << ptGL << " " << ptST << std::endl;
        }
        
        metX +=  pfCandidates_->back().px();
        metY +=  pfCandidates_->back().py();      
        met2 = metX*metX + metY*metY;
        
        if ( printout ) {
          std::cout <<  pfCandidates_->back() << std::endl;
          std::cout << "MEX,MEY,MET   now " << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
        }

        const PFCandidate& pfc = pfCandidates_->back();
        pfAddedMuonCandidates_->push_back(pfc);

      }
        
    } else  if ( ptST > 20. &&  met2ST < met2/4. && met2ST < met2TK && met2ST < met2GL ) { 

      double energy = std::sqrt(pxST*pxST+pyST*pyST+pzST*pzST+0.1057*0.1057);
      int charge = standAloneMu->charge()>0 ? 1 : -1;
      math::XYZTLorentzVector momentum(pxST,pyST,pzST,energy);
      reco::PFCandidate::ParticleType particleType = reco::PFCandidate::mu;
      double radius = std::sqrt(
        (standAloneMu->vertex().x()-primaryVertex_.x())*(standAloneMu->vertex().x()-primaryVertex_.x())+
        (standAloneMu->vertex().y()-primaryVertex_.y())*(standAloneMu->vertex().y()-primaryVertex_.y()));
      
      // Add it to the stack
      if ( radius < 1.0 ) { 
        pfCandidates_->push_back( PFCandidate( charge, 
                                               momentum,
                                               particleType ) );
        
        pfCandidates_->back().setVertex( standAloneMu->vertex() );
        if (trackerMu.isNonnull() ) pfCandidates_->back().setTrackRef( trackerMu );
        pfCandidates_->back().setMuonRef( muonRef );
        
        if ( printout ) {
          std::cout << "MEX,MEY,MET before " << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
          std::cout << "Muon ST added " << std::endl;
          std::cout << "pT TK/GL/ST : " << ptTK << " " << ptGL << " " << ptST << std::endl;
        }

        metX +=  pfCandidates_->back().px();
        metY +=  pfCandidates_->back().py();      
        met2 = metX*metX + metY*metY;
        
        if ( printout ) {
          std::cout <<  pfCandidates_->back() << std::endl;
          std::cout << "MEX,MEY,MET   now " << metX << " " << metY << " " << std::sqrt(met2) << std::endl;
        }

        const PFCandidate& pfc = pfCandidates_->back();
        pfAddedMuonCandidates_->push_back(pfc);

      }
    }

  }

  /*
  if ( std::sqrt(met2) > 500. ) { 
    std::cout << "MET initial : " << metInitial << std::endl;
    std::cout << "MET final : " << std::sqrt(met2) << std::endl;
  }
  */

}
virtual void PFAlgo::processBlock ( const reco::PFBlockRef blockref,
std::list< reco::PFBlockRef > &  hcalBlockRefs,
std::list< reco::PFBlockRef > &  ecalBlockRefs 
) [protected, virtual]

process one block. can be reimplemented in more sophisticated algorithms

Reimplemented in PFAlgoTestBenchConversions, and PFAlgoTestBenchElectrons.

Referenced by reconstructParticles().

unsigned PFAlgo::reconstructCluster ( const reco::PFCluster cluster,
double  particleEnergy,
bool  useDirection = false,
double  particleX = 0.,
double  particleY = 0.,
double  particleZ = 0. 
) [protected]

Reconstruct a neutral particle from a cluster. If chargedEnergy is specified, the neutral particle is created only if the cluster energy is significantly larger than the chargedEnergy. In this case, the energy of the neutral particle is cluster energy - chargedEnergy

Definition at line 2772 of file PFAlgo.cc.

References DeDxDiscriminatorTools::charge(), gather_cfg::cout, debug_, PFLayer::ECAL_BARREL, PFLayer::ECAL_ENDCAP, PFLayer::HCAL_BARREL1, PFLayer::HCAL_ENDCAP, PFLayer::HF_EM, PFLayer::HF_HAD, reco::PFCluster::layer(), ExpressReco_HICollisions_FallBack::particleType, ExpressReco_HICollisions_FallBack::PFCandidate, pfCandidates_, reco::CaloCluster::position(), primaryVertex_, mathSSE::sqrt(), tmp, useVertices_, reco::Vertex::x(), X, reco::Vertex::y(), and reco::Vertex::z().

Referenced by checkCleaning(), and PFAlgoTestBenchElectrons::processBlock().

                                             {
  
  reco::PFCandidate::ParticleType particleType = reco::PFCandidate::X;

  // need to convert the math::XYZPoint data member of the PFCluster class=
  // to a displacement vector: 

  // Transform particleX,Y,Z to a position at ECAL/HCAL entrance
  double factor = 1.;
  if ( useDirection ) { 
    switch( cluster.layer() ) {
    case PFLayer::ECAL_BARREL:
    case PFLayer::HCAL_BARREL1:
      factor = std::sqrt(cluster.position().Perp2()/(particleX*particleX+particleY*particleY));
      break;
    case PFLayer::ECAL_ENDCAP:
    case PFLayer::HCAL_ENDCAP:
    case PFLayer::HF_HAD:
    case PFLayer::HF_EM:
      factor = cluster.position().Z()/particleZ;
      break;
    default:
      assert(0);
    }
  }
  //MIKE First of all let's check if we have vertex.
  math::XYZPoint vertexPos; 
  if(useVertices_)
    vertexPos = math::XYZPoint(primaryVertex_.x(),primaryVertex_.y(),primaryVertex_.z());
  else
    vertexPos = math::XYZPoint(0.0,0.0,0.0);


  math::XYZVector clusterPos( cluster.position().X()-vertexPos.X(), 
                              cluster.position().Y()-vertexPos.Y(),
                              cluster.position().Z()-vertexPos.Z());
  math::XYZVector particleDirection ( particleX*factor-vertexPos.X(), 
                                      particleY*factor-vertexPos.Y(), 
                                      particleZ*factor-vertexPos.Z() );

  //math::XYZVector clusterPos( cluster.position().X(), cluster.position().Y(),cluster.position().Z() );
  //math::XYZVector particleDirection ( particleX, particleY, particleZ );

  clusterPos = useDirection ? particleDirection.Unit() : clusterPos.Unit();
  clusterPos *= particleEnergy;

  // clusterPos is now a vector along the cluster direction, 
  // with a magnitude equal to the cluster energy.
  
  double mass = 0;
  ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double> > 
    momentum( clusterPos.X(), clusterPos.Y(), clusterPos.Z(), mass); 
  // mathcore is a piece of #$%
  math::XYZTLorentzVector  tmp;
  // implicit constructor not allowed
  tmp = momentum;

  // Charge
  int charge = 0;

  // Type
  switch( cluster.layer() ) {
  case PFLayer::ECAL_BARREL:
  case PFLayer::ECAL_ENDCAP:
    particleType = PFCandidate::gamma;
    break;
  case PFLayer::HCAL_BARREL1:
  case PFLayer::HCAL_ENDCAP:
    particleType = PFCandidate::h0;
    break;
  case PFLayer::HF_HAD:
    particleType = PFCandidate::h_HF;
    break;
  case PFLayer::HF_EM:
    particleType = PFCandidate::egamma_HF;
    break;
  default:
    assert(0);
  }

  // The pf candidate
  pfCandidates_->push_back( PFCandidate( charge, 
                                         tmp, 
                                         particleType ) );

  // The position at ECAL entrance (well: watch out, it is not true
  // for HCAL clusters... to be fixed)
  pfCandidates_->back().
    setPositionAtECALEntrance(math::XYZPointF(cluster.position().X(),
                                              cluster.position().Y(),
                                              cluster.position().Z()));

  //Set the cnadidate Vertex
  pfCandidates_->back().setVertex(vertexPos);  

  if(debug_) 
    cout<<"** candidate: "<<pfCandidates_->back()<<endl; 

  // returns index to the newly created PFCandidate
  return pfCandidates_->size()-1;

}
void PFAlgo::reconstructParticles ( const reco::PFBlockCollection blocks) [virtual]

reconstruct particles

Definition at line 233 of file PFAlgo.cc.

References Association::block, gather_cfg::cout, createBlockRef(), debug_, ECAL, reco::PFBlock::elements(), asciidump::elements, relativeConstraints::empty, reco::PFBlockElement::HCAL, i, pfAddedMuonCandidates_, pfCandidates_, pfCleanedCandidates_, pfCleanedTrackerAndGlobalMuonCandidates_, pfCosmicsMuonCleanedCandidates_, pfElectronCandidates_, pfElectronExtra_, pfFakeMuonCleanedCandidates_, pfPunchThroughHadronCleanedCandidates_, pfPunchThroughMuonCleanedCandidates_, postCleaning(), processBlock(), edm::OwnVector< T, P >::push_back(), and edm::OwnVector< T, P >::size().

                                                                       {

  // reset output collection
  if(pfCandidates_.get() )
    pfCandidates_->clear();
  else 
    pfCandidates_.reset( new reco::PFCandidateCollection );

  if(pfElectronCandidates_.get() )
    pfElectronCandidates_->clear();
  else
    pfElectronCandidates_.reset( new reco::PFCandidateCollection);

  if(pfCleanedCandidates_.get() ) 
    pfCleanedCandidates_->clear();
  else
    pfCleanedCandidates_.reset( new reco::PFCandidateCollection );
  
  if(pfCosmicsMuonCleanedCandidates_.get() )
    pfCosmicsMuonCleanedCandidates_->clear();
  else 
    pfCosmicsMuonCleanedCandidates_.reset( new reco::PFCandidateCollection );

  if(pfCleanedTrackerAndGlobalMuonCandidates_.get() )
    pfCleanedTrackerAndGlobalMuonCandidates_->clear();
  else 
    pfCleanedTrackerAndGlobalMuonCandidates_.reset( new reco::PFCandidateCollection );

  if(pfFakeMuonCleanedCandidates_.get() )
    pfFakeMuonCleanedCandidates_->clear();
  else 
    pfFakeMuonCleanedCandidates_.reset( new reco::PFCandidateCollection );

  if(pfPunchThroughMuonCleanedCandidates_.get() )
    pfPunchThroughMuonCleanedCandidates_->clear();
  else 
    pfPunchThroughMuonCleanedCandidates_.reset( new reco::PFCandidateCollection );

  if(pfPunchThroughHadronCleanedCandidates_.get() )
    pfPunchThroughHadronCleanedCandidates_->clear();
  else 
    pfPunchThroughHadronCleanedCandidates_.reset( new reco::PFCandidateCollection );

  if(pfAddedMuonCandidates_.get() )
    pfAddedMuonCandidates_->clear();
  else 
    pfAddedMuonCandidates_.reset( new reco::PFCandidateCollection );

  // not a auto_ptr; shout not be deleted after transfer
  pfElectronExtra_.clear();
  
  if( debug_ ) {
    cout<<"*********************************************************"<<endl;
    cout<<"*****           Particle flow algorithm             *****"<<endl;
    cout<<"*********************************************************"<<endl;
  }

  // sort elements in three lists:
  std::list< reco::PFBlockRef > hcalBlockRefs;
  std::list< reco::PFBlockRef > ecalBlockRefs;
  std::list< reco::PFBlockRef > otherBlockRefs;
  
  for( unsigned i=0; i<blocks.size(); ++i ) {
    // reco::PFBlockRef blockref( blockh,i );
    reco::PFBlockRef blockref = createBlockRef( blocks, i);
    
    const reco::PFBlock& block = *blockref;
   const edm::OwnVector< reco::PFBlockElement >& 
      elements = block.elements();
        
    bool singleEcalOrHcal = false;
    if( elements.size() == 1 ){
      if( elements[0].type() == reco::PFBlockElement::ECAL ){
        ecalBlockRefs.push_back( blockref );
        singleEcalOrHcal = true;
      }
      if( elements[0].type() == reco::PFBlockElement::HCAL ){
        hcalBlockRefs.push_back( blockref );
        singleEcalOrHcal = true;
      }
    }      
    
    if(!singleEcalOrHcal) {
      otherBlockRefs.push_back( blockref );
    }
  }//loop blocks
  
  if( debug_ ){
    cout<<"# Ecal blocks: "<<ecalBlockRefs.size()
        <<", # Hcal blocks: "<<hcalBlockRefs.size()
        <<", # Other blocks: "<<otherBlockRefs.size()<<endl;
  }


  // loop on blocks that are not single ecal, 
  // and not single hcal.

  for( IBR io = otherBlockRefs.begin(); io!=otherBlockRefs.end(); ++io) {
    processBlock( *io, hcalBlockRefs, ecalBlockRefs );
  }

  std::list< reco::PFBlockRef > empty;

  // process remaining single hcal blocks
  for( IBR ih = hcalBlockRefs.begin(); ih!=hcalBlockRefs.end(); ++ih) {
    processBlock( *ih, empty, empty );
  }

  // process remaining single ecal blocks
  for( IBR ie = ecalBlockRefs.begin(); ie!=ecalBlockRefs.end(); ++ie) {
    processBlock( *ie, empty, empty );
  }

  // Post HF Cleaning
  postCleaning();
}
void PFAlgo::reconstructParticles ( const reco::PFBlockHandle blockHandle)

reconstruct particles (full framework case) will keep track of the block handle to build persistent references, and call reconstructParticles( const reco::PFBlockCollection& blocks )

Definition at line 225 of file PFAlgo.cc.

References blockHandle_.

Referenced by PFRootEventManager::particleFlow().

unsigned PFAlgo::reconstructTrack ( const reco::PFBlockElement elt) [protected]

Reconstruct a charged hadron from a track Returns the index of the newly created candidate in pfCandidates_

Definition at line 2589 of file PFAlgo.cc.

References reco::TrackBase::charge(), DeDxDiscriminatorTools::charge(), gather_cfg::cout, debug_, reco::PFBlockElementTrack::displacedVertexRef(), dptRel_DispVtx_, relval_parameters_module::energy, h, reco::TrackBase::hitPattern(), isFromSecInt(), PFMuonAlgo::isGlobalTightMuon(), PFMuonAlgo::isIsolatedMuon(), reco::isMuon(), edm::Ref< C, T, F >::isNonnull(), PFMuonAlgo::isTrackerTightMuon(), reco::PFCandidate::mu, reco::PFBlockElementTrack::muonRef(), reco::HitPattern::numberOfValidPixelHits(), reco::HitPattern::numberOfValidTrackerHits(), reco::TrackBase::p(), ExpressReco_HICollisions_FallBack::particleType, ExpressReco_HICollisions_FallBack::PFCandidate, pfCandidates_, reco::PFBlockElementTrack::positionAtECALEntrance(), PFMuonAlgo::printMuonProperties(), reco::TrackBase::ptError(), reco::TrackBase::px(), reco::TrackBase::py(), reco::TrackBase::pz(), mathSSE::sqrt(), reco::PFBlockElement::T_FROM_DISP, reco::PFCandidate::T_FROM_DISP, reco::PFBlockElement::T_TO_DISP, reco::PFCandidate::T_TO_DISP, ExpressReco_HICollisions_FallBack::track, reco::PFBlockElementTrack::trackRef(), usePFMuonMomAssign_, and reco::TrackBase::vertex().

Referenced by PFAlgoTestBenchElectrons::processBlock().

                                                                 {

  const reco::PFBlockElementTrack* eltTrack 
    = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);

  reco::TrackRef trackRef = eltTrack->trackRef();
  const reco::Track& track = *trackRef;

  reco::MuonRef muonRef = eltTrack->muonRef();

  int charge = track.charge()>0 ? 1 : -1;

  // Assign the pion mass to all charged particles
  double px = track.px();
  double py = track.py();
  double pz = track.pz();
  double energy = sqrt(track.p()*track.p() + 0.13957*0.13957);


  // Except if it is a muon, of course ! 
  bool thisIsAMuon = PFMuonAlgo::isMuon(elt);
  bool thisIsAnIsolatedMuon = PFMuonAlgo::isIsolatedMuon(elt);

  bool thisIsAGlobalTightMuon = PFMuonAlgo::isGlobalTightMuon(elt);
  bool thisIsATrackerTightMuon = PFMuonAlgo::isTrackerTightMuon(elt);

  // Or from nuclear inetraction then use the refitted momentum
  bool isFromDisp = isFromSecInt(elt, "secondary");
  bool isToDisp  = isFromSecInt(elt, "primary");
  //isFromNucl = false;
  bool globalFitUsed = false;

  if ( thisIsAMuon ) { 
    
    //By default take muon kinematics directly from the muon object (usually determined by the track) 
    px = muonRef->px();
    py = muonRef->py();
    pz = muonRef->pz();
    energy = sqrt(muonRef->p()*muonRef->p() + 0.1057*0.1057);

    reco::TrackBase::TrackQuality trackQualityHighPurity = TrackBase::qualityByName("highPurity");
    if(debug_)if(!trackRef->quality(trackQualityHighPurity))cout<<" Low Purity Track "<<endl;

    if(muonRef->isGlobalMuon() && !usePFMuonMomAssign_){
    
      reco::TrackRef combinedMu = muonRef->combinedMuon(); 

      // take the global fit instead under special circumstances
      bool useGlobalFit = false;
      
      if(thisIsAnIsolatedMuon && (!muonRef->isTrackerMuon() || (muonRef->pt() > combinedMu->pt() && track.ptError() > 5.0*combinedMu->ptError()))) useGlobalFit = true;
      else if(!trackRef->quality(trackQualityHighPurity)) useGlobalFit = true;
      else if(muonRef->pt() > combinedMu->pt() &&
              (track.hitPattern().numberOfValidTrackerHits() < 8 || track.hitPattern().numberOfValidPixelHits() == 0 ) &&
              track.ptError() > 5.0*combinedMu->ptError()) useGlobalFit = true;

      if(useGlobalFit){
        px = combinedMu->px();
        py = combinedMu->py();
        pz = combinedMu->pz();
        energy = sqrt(combinedMu->p()*combinedMu->p() + 0.1057*0.1057);   
        globalFitUsed = true;
      }
    }      
    else if(usePFMuonMomAssign_){
      // If this option is set we take more liberties choosing the muon kinematics (not advised by the muon POG)
      if(thisIsAGlobalTightMuon)
        {
          // If the global muon above 10 GeV and is a tracker muon take the global pT     
          if(muonRef->isTrackerMuon()){
            if(sqrt(px*px+py*py) > 10){
              reco::TrackRef combinedMu = muonRef->combinedMuon(); 
              px = combinedMu->px();
              py = combinedMu->py();
              pz = combinedMu->pz();
              energy = sqrt(combinedMu->p()*combinedMu->p() + 0.1057*0.1057);   
              globalFitUsed = true;
            }
          }   // If it's not a tracker muon, choose between the global pT and the STA pT
          else{  
            reco::TrackRef combinedMu =
              muonRef->combinedMuon()->normalizedChi2() < muonRef->standAloneMuon()->normalizedChi2() ?
              muonRef->combinedMuon() : 
              muonRef->standAloneMuon() ;
            px = combinedMu->px();
            py = combinedMu->py();
            pz = combinedMu->pz();
            energy = sqrt(combinedMu->p()*combinedMu->p() + 0.1057*0.1057);   
            globalFitUsed = true;
          }
        } // close else if(thisIsAGlobalTightMuon)
    } // close (usePFPFMuonMomAssign_)      
  }// close if(thisIsAMuon)
  else if (isFromDisp) {
    double Dpt = trackRef->ptError();
    double dptRel = Dpt/trackRef->pt()*100;
    //If the track is ill measured it is better to not refit it, since the track information probably would not be used.
    //In the PFAlgo we use the trackref information. If the track error is too big the refitted information might be very different
    // from the not refitted one.
    if (dptRel < dptRel_DispVtx_){

      if (debug_) 
        cout << "Not refitted px = " << px << " py = " << py << " pz = " << pz << " energy = " << energy << endl; 
      //reco::TrackRef trackRef = eltTrack->trackRef();
      reco::PFDisplacedVertexRef vRef = eltTrack->displacedVertexRef(reco::PFBlockElement::T_FROM_DISP)->displacedVertexRef();
      reco::Track trackRefit = vRef->refittedTrack(trackRef);
      px = trackRefit.px();
      py = trackRefit.py();
      pz = trackRefit.pz();
      energy = sqrt(trackRefit.p()*trackRefit.p() + 0.13957*0.13957);
      if (debug_) 
        cout << "Refitted px = " << px << " py = " << py << " pz = " << pz << " energy = " << energy << endl; 
    
    }
  }
  
  if ((isFromDisp || isToDisp) && debug_) cout << "Final px = " << px << " py = " << py << " pz = " << pz << " energy = " << energy << endl; 

  // Create a PF Candidate
  math::XYZTLorentzVector momentum(px,py,pz,energy);
  reco::PFCandidate::ParticleType particleType 
    = reco::PFCandidate::h;

  // Add it to the stack
  pfCandidates_->push_back( PFCandidate( charge, 
                                         momentum,
                                         particleType ) );

  // displaced vertices 
  if( isFromDisp ) {
    pfCandidates_->back().setFlag( reco::PFCandidate::T_FROM_DISP, true);
    pfCandidates_->back().setDisplacedVertexRef( eltTrack->displacedVertexRef(reco::PFBlockElement::T_FROM_DISP)->displacedVertexRef(), reco::PFCandidate::T_FROM_DISP);
  }
  
  // do not label as primary a track which would be recognised as a muon. A muon cannot produce NI. It is with high probability a fake
  if( isToDisp && !thisIsAMuon ) {
    pfCandidates_->back().setFlag( reco::PFCandidate::T_TO_DISP, true);
    pfCandidates_->back().setDisplacedVertexRef( eltTrack->displacedVertexRef(reco::PFBlockElement::T_TO_DISP)->displacedVertexRef(), reco::PFCandidate::T_TO_DISP);
  }



  if ( thisIsAMuon && globalFitUsed ) 
    pfCandidates_->back().setVertex(  muonRef->combinedMuon()->vertex() );
  else
    pfCandidates_->back().setVertex( track.vertex() );

  pfCandidates_->back().setTrackRef( trackRef );
  pfCandidates_->back().setPositionAtECALEntrance( eltTrack->positionAtECALEntrance());



  // setting the muon ref if there is
  if (muonRef.isNonnull()) {
    pfCandidates_->back().setMuonRef( muonRef );
    // setting the muon particle type if it is a global muon
    if ( thisIsAMuon) {
      particleType = reco::PFCandidate::mu;
      pfCandidates_->back().setParticleType( particleType );
      if (debug_) {
        if(thisIsAGlobalTightMuon) cout << "PFAlgo: particle type set to muon (global, tight), pT = " <<muonRef->pt()<< endl; 
        else if(thisIsATrackerTightMuon) cout << "PFAlgo: particle type set to muon (tracker, tight), pT = " <<muonRef->pt()<< endl;
        else if(thisIsAnIsolatedMuon) cout << "PFAlgo: particle type set to muon (isolated), pT = " <<muonRef->pt()<< endl; 
        else cout<<" problem with muon assignment "<<endl;
        PFMuonAlgo::printMuonProperties( muonRef );
      }
    }
  }  

  // conversion...

  if(debug_) 
    cout<<"** candidate: "<<pfCandidates_->back()<<endl; 
  
  // returns index to the newly created PFCandidate
  return pfCandidates_->size()-1;
}
void PFAlgo::setAlgo ( int  algo) [inline]

Definition at line 59 of file PFAlgo.h.

References ExpressReco_HICollisions_FallBack::algo, and algo_.

Referenced by PFRootEventManager::readOptions().

{algo_ = algo;}
void PFAlgo::setCandConnectorParameters ( const edm::ParameterSet iCfgCandConnector) [inline]

Definition at line 70 of file PFAlgo.h.

References connector_, and PFCandConnector::setParameters().

Referenced by PFRootEventManager::readOptions().

                                                                             {
    connector_.setParameters(iCfgCandConnector);
  }
void PFAlgo::setCandConnectorParameters ( bool  bCorrect,
bool  bCalibPrimary,
double  dptRel_PrimaryTrack,
double  dptRel_MergedTrack,
double  ptErrorSecondary,
std::vector< double >  nuclCalibFactors 
) [inline]

Definition at line 74 of file PFAlgo.h.

References connector_, and PFCandConnector::setParameters().

                                                                     {
    connector_.setParameters(bCorrect, bCalibPrimary, dptRel_PrimaryTrack, dptRel_MergedTrack, ptErrorSecondary, nuclCalibFactors);
  }
void PFAlgo::setDebug ( bool  debug) [inline]
void PFAlgo::setDisplacedVerticesParameters ( bool  rejectTracks_Bad,
bool  rejectTracks_Step45,
bool  usePFNuclearInteractions,
bool  usePFConversions,
bool  usePFDecays,
double  dptRel_DispVtx 
)
void PFAlgo::setEGElectronCollection ( const reco::GsfElectronCollection egelectrons)
void PFAlgo::setElectronExtraRef ( const edm::OrphanHandle< reco::PFCandidateElectronExtraCollection > &  extrah)

Definition at line 3798 of file PFAlgo.cc.

References ExpressReco_HICollisions_FallBack::e, pfCandidates_, pfElectronCandidates_, pfElectronExtra_, findQualityFiles::size, and usePFElectrons_.

                                                                                                       {
  if(!usePFElectrons_) return;
  //  std::cout << " setElectronExtraRef " << std::endl;
  unsigned size=pfCandidates_->size();

  for(unsigned ic=0;ic<size;++ic) {
    // select the electrons and add the extra
    if((*pfCandidates_)[ic].particleId()==PFCandidate::e) {
      
      PFElectronExtraEqual myExtraEqual((*pfCandidates_)[ic].gsfTrackRef());
      std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
      if(it!=pfElectronExtra_.end()) {
        //      std::cout << " Index " << it-pfElectronExtra_.begin() << std::endl;
        reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
        (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
      }
      else {
        (*pfCandidates_)[ic].setPFElectronExtraRef(PFCandidateElectronExtraRef());
      }
    }
    else  // else save the mva and the extra as well ! 
      {
        if((*pfCandidates_)[ic].trackRef().isNonnull()) {
          PFElectronExtraKfEqual myExtraEqual((*pfCandidates_)[ic].trackRef());
          std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
          if(it!=pfElectronExtra_.end()) {
            (*pfCandidates_)[ic].set_mva_e_pi(it->mvaVariable(PFCandidateElectronExtra::MVA_MVA));
            reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
            (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
          }     
        }
      }

  }

  size=pfElectronCandidates_->size();
  for(unsigned ic=0;ic<size;++ic) {
    // select the electrons - this test is actually not needed for this collection
    if((*pfElectronCandidates_)[ic].particleId()==PFCandidate::e) {
      // find the corresponding extra
      PFElectronExtraEqual myExtraEqual((*pfElectronCandidates_)[ic].gsfTrackRef());
      std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
      if(it!=pfElectronExtra_.end()) {
        reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
        (*pfElectronCandidates_)[ic].setPFElectronExtraRef(theRef);

      }
    }
  }

}
void PFAlgo::setParameters ( double  nSigmaECAL,
double  nSigmaHCAL,
const boost::shared_ptr< PFEnergyCalibration > &  calibration,
const boost::shared_ptr< pftools::PFClusterCalibration > &  clusterCalibration,
const boost::shared_ptr< PFEnergyCalibrationHF > &  thepfEnergyCalibrationHF,
unsigned int  newCalib 
)

Definition at line 73 of file PFAlgo.cc.

References calibration_, clusterCalibration_, newCalib_, nSigmaECAL_, nSigmaHCAL(), nSigmaHCAL_, and thepfEnergyCalibrationHF_.

Referenced by PFRootEventManager::readOptions().

                                             {

  nSigmaECAL_ = nSigmaECAL;
  nSigmaHCAL_ = nSigmaHCAL;

  calibration_ = calibration;
  clusterCalibration_ = clusterCalibration;
  thepfEnergyCalibrationHF_ = thepfEnergyCalibrationHF;
  newCalib_ = newCalib;
  // std::cout << "Cluster calibration parameters : " << *clusterCalibration_ << std::endl;

}
void PFAlgo::setPFEleParameters ( double  mvaEleCut,
std::string  mvaWeightFileEleID,
bool  usePFElectrons,
const boost::shared_ptr< PFSCEnergyCalibration > &  thePFSCEnergyCalibration,
double  sumEtEcalIsoForEgammaSC_barrel,
double  sumEtEcalIsoForEgammaSC_endcap,
double  coneEcalIsoForEgammaSC,
double  sumPtTrackIsoForEgammaSC_barrel,
double  sumPtTrackIsoForEgammaSC_endcap,
unsigned int  nTrackIsoForEgammaSC,
double  coneTrackIsoForEgammaSC,
bool  applyCrackCorrections = false,
bool  usePFSCEleCalib = true,
bool  useEGElectrons = false,
bool  useEGammaSupercluster = true 
)

Definition at line 93 of file PFAlgo.cc.

References applyCrackCorrectionsElectrons_, ExpressReco_HICollisions_FallBack::coneEcalIsoForEgammaSC, coneEcalIsoForEgammaSC_, ExpressReco_HICollisions_FallBack::coneTrackIsoForEgammaSC, coneTrackIsoForEgammaSC_, mvaEleCut_, mvaWeightFileEleID_, ExpressReco_HICollisions_FallBack::nTrackIsoForEgammaSC, nTrackIsoForEgammaSC_, pfele_, ExpressReco_HICollisions_FallBack::sumEtEcalIsoForEgammaSC_barrel, sumEtEcalIsoForEgammaSC_barrel_, ExpressReco_HICollisions_FallBack::sumEtEcalIsoForEgammaSC_endcap, sumEtEcalIsoForEgammaSC_endcap_, ExpressReco_HICollisions_FallBack::sumPtTrackIsoForEgammaSC_barrel, sumPtTrackIsoForEgammaSC_barrel_, ExpressReco_HICollisions_FallBack::sumPtTrackIsoForEgammaSC_endcap, sumPtTrackIsoForEgammaSC_endcap_, thePFSCEnergyCalibration_, ExpressReco_HICollisions_FallBack::useEGammaSupercluster, useEGammaSupercluster_, useEGElectrons_, ExpressReco_HICollisions_FallBack::usePFElectrons, usePFElectrons_, ExpressReco_HICollisions_FallBack::usePFSCEleCalib, and usePFSCEleCalib_.

Referenced by PFRootEventManager::readOptions().

void PFAlgo::setPFMuonAndFakeParameters ( std::vector< double >  muonHCAL,
std::vector< double >  muonECAL,
double  nSigmaTRACK,
double  ptError,
std::vector< double >  factors45,
bool  usePFMuonMomAssign 
)
void PFAlgo::setPFVertexParameters ( bool  useVertex,
const reco::VertexCollection primaryVertices 
)

Definition at line 205 of file PFAlgo.cc.

References i, primaryVertex_, and useVertices_.

Referenced by PFRootEventManager::particleFlow().

                                                                           {
  useVertices_ = useVertex;
  //Now find the primary vertex!
  bool primaryVertexFound = false;
  for (unsigned short i=0 ;i<primaryVertices.size();++i)
    {
      if(primaryVertices[i].isValid()&&(!primaryVertices[i].isFake()))
        {
          primaryVertex_ = primaryVertices[i];
          primaryVertexFound = true;
          break;
        }
    }
  //Use vertices if the user wants to but only if it exists a good vertex 
  useVertices_ = useVertex && primaryVertexFound; 

}
void PFAlgo::setPostHFCleaningParameters ( bool  postHFCleaning,
double  minHFCleaningPt,
double  minSignificance,
double  maxSignificance,
double  minSignificanceReduction,
double  maxDeltaPhiPt,
double  minDeltaMet 
)
std::auto_ptr< reco::PFCandidateCollection > PFAlgo::transferAddedMuonCandidates ( ) [inline]
Returns:
collection of added muon candidates

Definition at line 197 of file PFAlgo.h.

References pfAddedMuonCandidates_.

std::auto_ptr< reco::PFCandidateCollection > PFAlgo::transferCandidates ( ) [inline]
Returns:
auto_ptr to the collection of candidates (transfers ownership)

Definition at line 202 of file PFAlgo.h.

References PFCandConnector::connect(), connector_, and pfCandidates_.

Referenced by PFRootEventManager::particleFlow().

std::auto_ptr< reco::PFCandidateCollection >& PFAlgo::transferCleanedCandidates ( ) [inline]
Returns:
collection of cleaned HF candidates

Definition at line 167 of file PFAlgo.h.

References pfCleanedCandidates_.

                                                                        {
    return pfCleanedCandidates_;
  }
std::auto_ptr< reco::PFCandidateCollection > PFAlgo::transferCleanedTrackerAndGlobalMuonCandidates ( ) [inline]
Returns:
collection of tracker/global cleaned muon candidates

Definition at line 177 of file PFAlgo.h.

References pfCleanedTrackerAndGlobalMuonCandidates_.

std::auto_ptr< reco::PFCandidateCollection > PFAlgo::transferCosmicsMuonCleanedCandidates ( ) [inline]
Returns:
collection of cosmics cleaned muon candidates

Definition at line 172 of file PFAlgo.h.

References pfCosmicsMuonCleanedCandidates_.

std::auto_ptr< reco::PFCandidateCollection> PFAlgo::transferElectronCandidates ( ) [inline]
Returns:
the unfiltered electron collection

Definition at line 153 of file PFAlgo.h.

References pfElectronCandidates_.

                                                                        {
    return pfElectronCandidates_;
  }
std::auto_ptr< reco::PFCandidateElectronExtraCollection> PFAlgo::transferElectronExtra ( ) [inline]
Returns:
the unfiltered electron extra collection

Definition at line 159 of file PFAlgo.h.

References pfElectronExtra_, and query::result.

                                                                                {
    std::auto_ptr< reco::PFCandidateElectronExtraCollection> result(new reco::PFCandidateElectronExtraCollection);
    result->insert(result->end(),pfElectronExtra_.begin(),pfElectronExtra_.end());
    return result;
  }
std::auto_ptr< reco::PFCandidateCollection > PFAlgo::transferFakeMuonCleanedCandidates ( ) [inline]
Returns:
collection of fake cleaned muon candidates

Definition at line 182 of file PFAlgo.h.

References pfFakeMuonCleanedCandidates_.

std::auto_ptr< reco::PFCandidateCollection > PFAlgo::transferPunchThroughHadronCleanedCandidates ( ) [inline]
Returns:
collection of punch-through cleaned neutral hadron candidates

Definition at line 192 of file PFAlgo.h.

References pfPunchThroughHadronCleanedCandidates_.

std::auto_ptr< reco::PFCandidateCollection > PFAlgo::transferPunchThroughMuonCleanedCandidates ( ) [inline]
Returns:
collection of punch-through cleaned muon candidates

Definition at line 187 of file PFAlgo.h.

References pfPunchThroughMuonCleanedCandidates_.


Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  out,
const PFAlgo algo 
) [friend]

Member Data Documentation

int PFAlgo::algo_ [private]

Definition at line 319 of file PFAlgo.h.

Referenced by setAlgo().

Definition at line 327 of file PFAlgo.h.

Referenced by setPFEleParameters().

input block handle (full framework case)

Definition at line 302 of file PFAlgo.h.

Referenced by createBlockRef(), and reconstructParticles().

boost::shared_ptr<PFEnergyCalibration> PFAlgo::calibration_ [private]

Definition at line 310 of file PFAlgo.h.

Referenced by operator<<(), PFAlgoTestBenchElectrons::processBlock(), and setParameters().

Definition at line 311 of file PFAlgo.h.

Referenced by PFAlgoTestBenchElectrons::processBlock(), and setParameters().

Definition at line 333 of file PFAlgo.h.

Referenced by setPFEleParameters().

Definition at line 336 of file PFAlgo.h.

Referenced by setPFEleParameters().

A tool used for a postprocessing of displaced vertices based on reconstructed PFCandidates

Definition at line 360 of file PFAlgo.h.

Referenced by setCandConnectorParameters(), setDebug(), and transferCandidates().

bool PFAlgo::debug_ [private]
double PFAlgo::dptRel_DispVtx_ [private]

Maximal relative uncertainty on the tracks going to or incoming from the displcaed vertex to be used in the PFAlgo

Definition at line 355 of file PFAlgo.h.

Referenced by PFAlgoTestBenchElectrons::processBlock(), reconstructTrack(), and setDisplacedVerticesParameters().

std::vector<double> PFAlgo::factors45_ [private]

Definition at line 367 of file PFAlgo.h.

Referenced by PFAlgoTestBenchElectrons::processBlock(), and setPFMuonAndFakeParameters().

double PFAlgo::maxDeltaPhiPt_ [private]

Definition at line 376 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::maxSignificance_ [private]

Definition at line 374 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::minDeltaMet_ [private]

Definition at line 377 of file PFAlgo.h.

Referenced by checkCleaning(), postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::minHFCleaningPt_ [private]

Definition at line 372 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::minSignificance_ [private]

Definition at line 373 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

Definition at line 375 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

std::vector<double> PFAlgo::muonECAL_ [private]

Definition at line 364 of file PFAlgo.h.

Referenced by PFAlgoTestBenchElectrons::processBlock(), and setPFMuonAndFakeParameters().

std::vector<double> PFAlgo::muonHCAL_ [private]

Variables for muons and fakes.

Definition at line 363 of file PFAlgo.h.

Referenced by PFAlgoTestBenchElectrons::processBlock(), and setPFMuonAndFakeParameters().

double PFAlgo::mvaEleCut_ [private]

Definition at line 325 of file PFAlgo.h.

Referenced by setPFEleParameters().

std::string PFAlgo::mvaWeightFileEleID_ [private]

Variables for PFElectrons.

Definition at line 323 of file PFAlgo.h.

Referenced by setPFEleParameters().

unsigned int PFAlgo::newCalib_ [private]
double PFAlgo::nSigmaECAL_ [private]

number of sigma to judge energy excess in ECAL

Definition at line 305 of file PFAlgo.h.

Referenced by operator<<(), PFAlgoTestBenchElectrons::processBlock(), and setParameters().

double PFAlgo::nSigmaHCAL_ [private]

number of sigma to judge energy excess in HCAL

Definition at line 308 of file PFAlgo.h.

Referenced by nSigmaHCAL(), operator<<(), and setParameters().

double PFAlgo::nSigmaTRACK_ [private]

Definition at line 365 of file PFAlgo.h.

Referenced by PFAlgoTestBenchElectrons::processBlock(), and setPFMuonAndFakeParameters().

unsigned int PFAlgo::nTrackIsoForEgammaSC_ [private]

Definition at line 337 of file PFAlgo.h.

Referenced by setPFEleParameters().

the collection of added muon candidates

Definition at line 267 of file PFAlgo.h.

Referenced by postMuonCleaning(), reconstructParticles(), and transferAddedMuonCandidates().

std::auto_ptr< reco::PFCandidateCollection > PFAlgo::pfCandidates_ [protected]

Definition at line 255 of file PFAlgo.h.

Referenced by postCleaning(), reconstructParticles(), and transferCleanedCandidates().

the collection of tracker/global cleaned muon candidates

Definition at line 259 of file PFAlgo.h.

Referenced by postMuonCleaning(), reconstructParticles(), and transferCleanedTrackerAndGlobalMuonCandidates().

the collection of cosmics cleaned muon candidates

Definition at line 257 of file PFAlgo.h.

Referenced by postMuonCleaning(), reconstructParticles(), and transferCosmicsMuonCleanedCandidates().

the unfiltered electron collection

Definition at line 253 of file PFAlgo.h.

Referenced by PFAlgoTestBenchElectrons::processBlock(), reconstructParticles(), setElectronExtraRef(), and transferElectronCandidates().

the unfiltered electron collection

Definition at line 270 of file PFAlgo.h.

Referenced by PFAlgoTestBenchElectrons::processBlock(), reconstructParticles(), setElectronExtraRef(), and transferElectronExtra().

the collection of fake cleaned muon candidates

Definition at line 261 of file PFAlgo.h.

Referenced by postMuonCleaning(), reconstructParticles(), and transferFakeMuonCleanedCandidates().

the collection of punch-through cleaned neutral hadron candidates

Definition at line 265 of file PFAlgo.h.

Referenced by postMuonCleaning(), reconstructParticles(), and transferPunchThroughHadronCleanedCandidates().

the collection of punch-through cleaned muon candidates

Definition at line 263 of file PFAlgo.h.

Referenced by postMuonCleaning(), reconstructParticles(), and transferPunchThroughMuonCleanedCandidates().

bool PFAlgo::postHFCleaning_ [private]

Definition at line 370 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

bool PFAlgo::postMuonCleaning_ [private]

Definition at line 371 of file PFAlgo.h.

Definition at line 380 of file PFAlgo.h.

Referenced by postMuonCleaning(), reconstructCluster(), and setPFVertexParameters().

double PFAlgo::ptError_ [private]

Definition at line 366 of file PFAlgo.h.

Referenced by PFAlgoTestBenchElectrons::processBlock(), and setPFMuonAndFakeParameters().

bool PFAlgo::rejectTracks_Bad_ [private]

Flags to use the protection against fakes and not reconstructed displaced vertices

Definition at line 345 of file PFAlgo.h.

Referenced by PFAlgoTestBenchElectrons::processBlock(), and setDisplacedVerticesParameters().

std::vector<double> PFAlgo::setchi2Values_ [private]

Definition at line 324 of file PFAlgo.h.

Definition at line 331 of file PFAlgo.h.

Referenced by setPFEleParameters().

Definition at line 332 of file PFAlgo.h.

Referenced by setPFEleParameters().

Definition at line 334 of file PFAlgo.h.

Referenced by setPFEleParameters().

Definition at line 335 of file PFAlgo.h.

Referenced by setPFEleParameters().

Definition at line 312 of file PFAlgo.h.

Referenced by PFAlgoTestBenchElectrons::processBlock(), and setParameters().

Definition at line 313 of file PFAlgo.h.

Referenced by setPFEleParameters().

Definition at line 330 of file PFAlgo.h.

Referenced by setPFEleParameters().

bool PFAlgo::useEGElectrons_ [private]

Definition at line 329 of file PFAlgo.h.

Referenced by setEGElectronCollection(), and setPFEleParameters().

bool PFAlgo::usePFConversions_ [private]
bool PFAlgo::usePFDecays_ [private]

Definition at line 351 of file PFAlgo.h.

Referenced by isFromSecInt(), and setDisplacedVerticesParameters().

bool PFAlgo::usePFElectrons_ [private]

Definition at line 341 of file PFAlgo.h.

Referenced by reconstructTrack(), and setPFMuonAndFakeParameters().

Definition at line 348 of file PFAlgo.h.

Referenced by isFromSecInt(), and setDisplacedVerticesParameters().

bool PFAlgo::usePFSCEleCalib_ [private]

Definition at line 328 of file PFAlgo.h.

Referenced by setPFEleParameters().

bool PFAlgo::useVertices_ [private]

Definition at line 381 of file PFAlgo.h.

Referenced by reconstructCluster(), and setPFVertexParameters().