CMS 3D CMS Logo

List of all members | 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

Public Member Functions

void checkCleaning (const reco::PFRecHitCollection &cleanedHF)
 Check HF Cleaning. More...
 
PFMuonAlgogetPFMuonAlgo ()
 
 PFAlgo ()
 constructor More...
 
const std::unique_ptr< reco::PFCandidateCollection > & pfCandidates () const
 
void reconstructParticles (const reco::PFBlockHandle &blockHandle)
 
virtual void reconstructParticles (const reco::PFBlockCollection &blocks)
 reconstruct particles More...
 
void setAlgo (int algo)
 
void setBadHcalTrackParams (const edm::ParameterSet &pset)
 
void setCandConnectorParameters (const edm::ParameterSet &iCfgCandConnector)
 
void setCandConnectorParameters (bool bCorrect, bool bCalibPrimary, double dptRel_PrimaryTrack, double dptRel_MergedTrack, double ptErrorSecondary, const 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 setEGammaCollections (const edm::View< reco::PFCandidate > &pfEgammaCandidates, const edm::ValueMap< reco::GsfElectronRef > &valueMapGedElectrons, const edm::ValueMap< reco::PhotonRef > &valueMapGedPhotons)
 
void setEGammaParameters (bool use_EGammaFilters, std::string ele_iso_path_mvaWeightFile, double ele_iso_pt, double ele_iso_mva_barrel, double ele_iso_mva_endcap, double ele_iso_combIso_barrel, double ele_iso_combIso_endcap, double ele_noniso_mva, unsigned int ele_missinghits, bool useProtectionsForJetMET, const edm::ParameterSet &ele_protectionsForJetMET, const edm::ParameterSet &ele_protectionsForBadHcal, double ph_MinEt, double ph_combIso, double ph_HoE, double ph_sietaieta_eb, double ph_sietaieta_ee, const edm::ParameterSet &ph_protectionsForJetMET, const edm::ParameterSet &ph_protectionsForBadHcal)
 
void setEGElectronCollection (const reco::GsfElectronCollection &egelectrons)
 
void setElectronExtraRef (const edm::OrphanHandle< reco::PFCandidateElectronExtraCollection > &extrah)
 
void setHOTag (bool ho)
 
void setMuonHandle (const edm::Handle< reco::MuonCollection > &)
 
void setParameters (double nSigmaECAL, double nSigmaHCAL, const boost::shared_ptr< PFEnergyCalibration > &calibration, const boost::shared_ptr< PFEnergyCalibrationHF > &thepfEnergyCalibrationHF)
 
void setPFEleParameters (double mvaEleCut, std::string mvaWeightFileEleID, bool usePFElectrons, const boost::shared_ptr< PFSCEnergyCalibration > &thePFSCEnergyCalibration, const boost::shared_ptr< PFEnergyCalibration > &thePFEnergyCalibration, 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 setPFMuonAlgo (PFMuonAlgo *algo)
 
void setPFMuonAndFakeParameters (const edm::ParameterSet &pset)
 
void setPFPhotonParameters (bool usePFPhoton, std::string mvaWeightFileConvID, double mvaConvCut, bool useReg, std::string X0_Map, const boost::shared_ptr< PFEnergyCalibration > &thePFEnergyCalibration, double sumPtTrackIsoForPhoton, double sumPtTrackIsoSlopeForPhoton)
 
void setPFPhotonRegWeights (const GBRForest *LCorrForestEB, const GBRForest *LCorrForestEE, const GBRForest *GCorrForestBarrel, const GBRForest *GCorrForestEndcapHr9, const GBRForest *GCorrForestEndcapLr9, const GBRForest *PFEcalResolution)
 
void setPFVertexParameters (bool useVertex, const reco::VertexCollection *primaryVertices)
 
void setPhotonExtraRef (const edm::OrphanHandle< reco::PFCandidatePhotonExtraCollection > &pf_extrah)
 
void setPostHFCleaningParameters (bool postHFCleaning, double minHFCleaningPt, double minSignificance, double maxSignificance, double minSignificanceReduction, double maxDeltaPhiPt, double minDeltaMet)
 
boost::shared_ptr< PFEnergyCalibrationthePFEnergyCalibration ()
 return the pointer to the calibration function More...
 
std::unique_ptr< reco::PFCandidateCollectiontransferCandidates ()
 
std::unique_ptr< reco::PFCandidateCollectiontransferCleanedCandidates ()
 
std::unique_ptr< reco::PFCandidateCollectiontransferElectronCandidates ()
 
std::unique_ptr< reco::PFCandidateElectronExtraCollectiontransferElectronExtra ()
 
std::unique_ptr< reco::PFCandidatePhotonExtraCollectiontransferPhotonExtra ()
 
virtual ~PFAlgo ()
 destructor More...
 

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. More...
 
bool isFromSecInt (const reco::PFBlockElement &eTrack, std::string order) const
 
double neutralHadronEnergyResolution (double clusterEnergy, double clusterEta) const
 todo: use PFClusterTools for this More...
 
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, bool allowLoose=false)
 
void setHcalDepthInfo (reco::PFCandidate &cand, const reco::PFCluster &cluster) const
 

Protected Attributes

std::unique_ptr< reco::PFCandidateCollectionpfCandidates_
 
std::unique_ptr< reco::PFCandidateCollectionpfCleanedCandidates_
 
std::unique_ptr< reco::PFCandidateCollectionpfElectronCandidates_
 the unfiltered electron collection More...
 
reco::PFCandidateElectronExtraCollection pfElectronExtra_
 the unfiltered electron collection More...
 
std::unique_ptr< reco::PFCandidateCollectionpfPhotonCandidates_
 the unfiltered photon collection More...
 
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
 the extra photon collection More...
 

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) More...
 
boost::shared_ptr< PFEnergyCalibrationcalibration_
 
double coneEcalIsoForEgammaSC_
 
double coneTrackIsoForEgammaSC_
 
PFCandConnector connector_
 
bool debug_
 
double dptRel_DispVtx_
 
std::vector< double > factors45_
 
float goodPixelTrackDeadHcal_chi2n_
 
float goodPixelTrackDeadHcal_dxy_
 
float goodPixelTrackDeadHcal_dz_
 
int goodPixelTrackDeadHcal_maxLost3Hit_
 
int goodPixelTrackDeadHcal_maxLost4Hit_
 
float goodPixelTrackDeadHcal_maxPt_
 
float goodPixelTrackDeadHcal_minEta_
 
float goodPixelTrackDeadHcal_ptErrRel_
 
float goodTrackDeadHcal_chi2n_
 
float goodTrackDeadHcal_dxy_
 
int goodTrackDeadHcal_layers_
 
float goodTrackDeadHcal_ptErrRel_
 Variables for track cleaning in bad HCal areas. More...
 
float goodTrackDeadHcal_validFr_
 
double maxDeltaPhiPt_
 
double maxSignificance_
 
double minDeltaMet_
 
double minHFCleaningPt_
 
double minSignificance_
 
double minSignificanceReduction_
 
std::vector< double > muonECAL_
 
edm::Handle< reco::MuonCollectionmuonHandle_
 
std::vector< double > muonHCAL_
 Variables for muons and fakes. More...
 
std::vector< double > muonHO_
 
double mvaEleCut_
 
std::string mvaWeightFileEleID_
 Variables for PFElectrons. More...
 
double nSigmaECAL_
 number of sigma to judge energy excess in ECAL More...
 
double nSigmaHCAL_
 number of sigma to judge energy excess in HCAL More...
 
double nSigmaTRACK_
 
unsigned int nTrackIsoForEgammaSC_
 
int nVtx_
 
PFEGammaFilterspfegamma_
 
const edm::View< reco::PFCandidate > * pfEgammaCandidates_
 
PFElectronAlgopfele_
 
PFMuonAlgopfmu_
 
PFPhotonAlgopfpho_
 
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< PFEnergyCalibrationHFthepfEnergyCalibrationHF_
 
boost::shared_ptr< PFSCEnergyCalibrationthePFSCEnergyCalibration_
 
double useBestMuonTrack_
 
bool useEGammaFilters_
 Variables for NEW EGAMMA selection. More...
 
bool useEGammaSupercluster_
 
bool useEGElectrons_
 
bool useHO_
 
bool usePFConversions_
 
bool usePFDecays_
 
bool usePFElectrons_
 
bool usePFMuonMomAssign_
 
bool usePFNuclearInteractions_
 
bool usePFPhotons_
 
bool usePFSCEleCalib_
 
bool useProtectionsForJetMET_
 
bool useVertices_
 
const edm::ValueMap< reco::GsfElectronRef > * valueMapGedElectrons_
 
const edm::ValueMap< reco::PhotonRef > * valueMapGedPhotons_
 

Friends

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

Detailed Description

Definition at line 52 of file PFAlgo.h.

Constructor & Destructor Documentation

PFAlgo::PFAlgo ( )

constructor

Definition at line 59 of file PFAlgo.cc.

61  nSigmaECAL_(0),
62  nSigmaHCAL_(1),
63  algo_(1),
64  debug_(false),
65  pfele_(nullptr),
66  pfpho_(nullptr),
67  pfegamma_(nullptr),
68  useVertices_(false)
69 {}
std::unique_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:289
double nSigmaHCAL_
number of sigma to judge energy excess in HCAL
Definition: PFAlgo.h:333
PFElectronAlgo * pfele_
Definition: PFAlgo.h:360
int algo_
Definition: PFAlgo.h:340
PFPhotonAlgo * pfpho_
Definition: PFAlgo.h:361
PFEGammaFilters * pfegamma_
Definition: PFAlgo.h:367
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
bool useVertices_
Definition: PFAlgo.h:433
bool debug_
Definition: PFAlgo.h:341
double nSigmaECAL_
number of sigma to judge energy excess in ECAL
Definition: PFAlgo.h:330
PFAlgo::~PFAlgo ( )
virtual

destructor

Definition at line 71 of file PFAlgo.cc.

References pfegamma_, pfele_, pfpho_, useEGammaFilters_, usePFElectrons_, and usePFPhotons_.

71  {
72  if (usePFElectrons_) delete pfele_;
73  if (usePFPhotons_) delete pfpho_;
74  if (useEGammaFilters_) delete pfegamma_;
75 }
PFElectronAlgo * pfele_
Definition: PFAlgo.h:360
PFPhotonAlgo * pfpho_
Definition: PFAlgo.h:361
PFEGammaFilters * pfegamma_
Definition: PFAlgo.h:367
bool useEGammaFilters_
Variables for NEW EGAMMA selection.
Definition: PFAlgo.h:366
bool usePFPhotons_
Definition: PFAlgo.h:348
bool usePFElectrons_
Definition: PFAlgo.h:347

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 3562 of file PFAlgo.cc.

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

Referenced by processBlock().

3568  {
3569 
3570  // Find all PS clusters with type psElement associated to ECAL cluster iEcal,
3571  // within all PFBlockElement "elements" of a given PFBlock "block"
3572  // psElement can be reco::PFBlockElement::PS1 or reco::PFBlockElement::PS2
3573  // Returns a vector of PS cluster energies, and updates the "active" vector.
3574 
3575  // Find all PS clusters linked to the iEcal cluster
3576  std::multimap<double, unsigned> sortedPS;
3577  typedef std::multimap<double, unsigned>::iterator IE;
3578  block.associatedElements( iEcal, linkData,
3579  sortedPS, psElementType,
3581 
3582  // Loop over these PS clusters
3583  double totalPS = 0.;
3584  for ( IE ips=sortedPS.begin(); ips!=sortedPS.end(); ++ips ) {
3585 
3586  // CLuster index and distance to iEcal
3587  unsigned iPS = ips->second;
3588  // double distPS = ips->first;
3589 
3590  // Ignore clusters already in use
3591  if (!active[iPS]) continue;
3592 
3593  // Check that this cluster is not closer to another ECAL cluster
3594  std::multimap<double, unsigned> sortedECAL;
3595  block.associatedElements( iPS, linkData,
3596  sortedECAL,
3599  unsigned jEcal = sortedECAL.begin()->second;
3600  if ( jEcal != iEcal ) continue;
3601 
3602  // Update PS energy
3603  PFBlockElement::Type pstype = elements[ iPS ].type();
3604  assert( pstype == psElementType );
3605  PFClusterRef psclusterref = elements[iPS].clusterRef();
3606  assert(!psclusterref.isNull() );
3607  totalPS += psclusterref->energy();
3608  psEne[0] += psclusterref->energy();
3609  active[iPS] = false;
3610  }
3611 
3612 
3613 }
bool isNull() const
Checks for null.
Definition: Ref.h:250
void associatedElements(unsigned i, const LinkData &linkData, std::multimap< double, unsigned > &sortedAssociates, reco::PFBlockElement::Type type=PFBlockElement::NONE, LinkTest test=LINKTEST_RECHIT) const
Definition: PFBlock.cc:75
void PFAlgo::checkCleaning ( const reco::PFRecHitCollection cleanedHF)

Check HF Cleaning.

Definition at line 3760 of file PFAlgo.cc.

References gather_cfg::cout, debug_, reco::PFRecHit::energy(), mps_fire::i, reco::PFRecHit::layer(), Basic3DVector< T >::mag2(), minDeltaMet_, GetRecoTauVFromDQM_MC_cff::next, pfCandidates_, reco::PFRecHit::position(), EnergyCorrector::pt, reco::LeafCandidate::pt(), reco::LeafCandidate::px(), reco::LeafCandidate::py(), reconstructCluster(), createPayload::skip, mathSSE::sqrt(), reco::PFRecHit::time(), Basic3DVector< T >::x(), Basic3DVector< T >::y(), and Basic3DVector< T >::z().

Referenced by setCandConnectorParameters().

3760  {
3761 
3762 
3763  // No hits to recover, leave.
3764  if ( cleanedHits.empty() ) return;
3765 
3766  //Compute met and met significance (met/sqrt(SumEt))
3767  double metX = 0.;
3768  double metY = 0.;
3769  double sumet = 0;
3770  std::vector<unsigned int> hitsToBeAdded;
3771  for(unsigned i=0; i<pfCandidates_->size(); i++) {
3772  const PFCandidate& pfc = (*pfCandidates_)[i];
3773  metX += pfc.px();
3774  metY += pfc.py();
3775  sumet += pfc.pt();
3776  }
3777  double met2 = metX*metX+metY*metY;
3778  double met2_Original = met2;
3779  // Select events with large MET significance.
3780  // double significance = std::sqrt(met2/sumet);
3781  // double significanceCor = significance;
3782  double metXCor = metX;
3783  double metYCor = metY;
3784  double sumetCor = sumet;
3785  double met2Cor = met2;
3786  bool next = true;
3787  unsigned iCor = 1E9;
3788 
3789  // Find the cleaned hit with the largest effect on the MET
3790  while ( next ) {
3791 
3792  double metReduc = -1.;
3793  // Loop on the candidates
3794  for(unsigned i=0; i<cleanedHits.size(); ++i) {
3795  const PFRecHit& hit = cleanedHits[i];
3796  double length = std::sqrt(hit.position().mag2());
3797  double px = hit.energy() * hit.position().x()/length;
3798  double py = hit.energy() * hit.position().y()/length;
3799  double pt = std::sqrt(px*px + py*py);
3800 
3801  // Check that it is not already scheculed to be cleaned
3802  bool skip = false;
3803  for(unsigned j=0; j<hitsToBeAdded.size(); ++j) {
3804  if ( i == hitsToBeAdded[j] ) skip = true;
3805  if ( skip ) break;
3806  }
3807  if ( skip ) continue;
3808 
3809  // Now add the candidate to the MET
3810  double metXInt = metX + px;
3811  double metYInt = metY + py;
3812  double sumetInt = sumet + pt;
3813  double met2Int = metXInt*metXInt+metYInt*metYInt;
3814 
3815  // And check if it could contribute to a MET reduction
3816  if ( met2Int < met2Cor ) {
3817  metXCor = metXInt;
3818  metYCor = metYInt;
3819  metReduc = (met2-met2Int)/met2Int;
3820  met2Cor = met2Int;
3821  sumetCor = sumetInt;
3822  // significanceCor = std::sqrt(met2Cor/sumetCor);
3823  iCor = i;
3824  }
3825  }
3826  //
3827  // If the MET must be significanly reduced, schedule the candidate to be added
3828  //
3829  if ( metReduc > minDeltaMet_ ) {
3830  hitsToBeAdded.push_back(iCor);
3831  metX = metXCor;
3832  metY = metYCor;
3833  sumet = sumetCor;
3834  met2 = met2Cor;
3835  } else {
3836  // Otherwise just stop the loop
3837  next = false;
3838  }
3839  }
3840  //
3841  // At least 10 GeV MET reduction
3842  if ( std::sqrt(met2_Original) - std::sqrt(met2) > 5. ) {
3843  if ( debug_ ) {
3844  std::cout << hitsToBeAdded.size() << " hits were re-added " << std::endl;
3845  std::cout << "MET reduction = " << std::sqrt(met2_Original) << " -> "
3846  << std::sqrt(met2Cor) << " = " << std::sqrt(met2Cor) - std::sqrt(met2_Original)
3847  << std::endl;
3848  std::cout << "Added after cleaning check : " << std::endl;
3849  }
3850  for(unsigned j=0; j<hitsToBeAdded.size(); ++j) {
3851  const PFRecHit& hit = cleanedHits[hitsToBeAdded[j]];
3852  PFCluster cluster(hit.layer(), hit.energy(),
3853  hit.position().x(), hit.position().y(), hit.position().z() );
3854  reconstructCluster(cluster,hit.energy());
3855  if ( debug_ ) {
3856  std::cout << pfCandidates_->back() << ". time = " << hit.time() << std::endl;
3857  }
3858  }
3859  }
3860 
3861 }
T y() const
Cartesian y coordinate.
T x() const
Cartesian x coordinate.
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:47
double minDeltaMet_
Definition: PFAlgo.h:428
float time() const
timing for cleaned hits
Definition: PFRecHit.h:118
std::unique_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:289
unsigned reconstructCluster(const reco::PFCluster &cluster, double particleEnergy, bool useDirection=false, double particleX=0., double particleY=0., double particleZ=0.)
Definition: PFAlgo.cc:3353
double px() const final
x coordinate of momentum vector
double pt() const final
transverse momentum
PositionType const & position() const
rechit cell centre x, y, z
Definition: PFRecHit.h:129
PFLayer::Layer layer() const
rechit layer
Definition: PFRecHit.h:111
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
Definition: PFRecHit.h:32
T z() const
Cartesian z coordinate.
T sqrt(T t)
Definition: SSEVec.h:18
float energy() const
rechit energy
Definition: PFRecHit.h:114
double py() const final
y coordinate of momentum vector
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
bool debug_
Definition: PFAlgo.h:341
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
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 3550 of file PFAlgo.cc.

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

Referenced by reconstructParticles().

3551  {
3552 
3553  if( blockHandle_.isValid() ) {
3554  return reco::PFBlockRef( blockHandle_, bi );
3555  }
3556  else {
3557  return reco::PFBlockRef( &blocks, bi );
3558  }
3559 }
edm::Ref< PFBlockCollection > PFBlockRef
persistent reference to PFCluster objects
Definition: PFBlockFwd.h:20
bool isValid() const
Definition: HandleBase.h:74
reco::PFBlockHandle blockHandle_
input block handle (full framework case)
Definition: PFAlgo.h:327
PFMuonAlgo * PFAlgo::getPFMuonAlgo ( )

Definition at line 93 of file PFAlgo.cc.

References pfmu_.

Referenced by setCandConnectorParameters().

93  {
94  return pfmu_;
95 }
PFMuonAlgo * pfmu_
Definition: PFAlgo.h:362
bool PFAlgo::isFromSecInt ( const reco::PFBlockElement eTrack,
std::string  order 
) const
protected

Definition at line 3617 of file PFAlgo.cc.

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

Referenced by processBlock(), and reconstructTrack().

3617  {
3618 
3621  // reco::PFBlockElement::TrackType T_FROM_GAMMACONV = reco::PFBlockElement::T_FROM_GAMMACONV;
3623 
3624  bool bPrimary = (order.find("primary") != string::npos);
3625  bool bSecondary = (order.find("secondary") != string::npos);
3626  bool bAll = (order.find("all") != string::npos);
3627 
3628  bool isToDisp = usePFNuclearInteractions_ && eTrack.trackType(T_TO_DISP);
3629  bool isFromDisp = usePFNuclearInteractions_ && eTrack.trackType(T_FROM_DISP);
3630 
3631  if (bPrimary && isToDisp) return true;
3632  if (bSecondary && isFromDisp ) return true;
3633  if (bAll && ( isToDisp || isFromDisp ) ) return true;
3634 
3635 // bool isFromConv = usePFConversions_ && eTrack.trackType(T_FROM_GAMMACONV);
3636 
3637 // if ((bAll || bSecondary)&& isFromConv) return true;
3638 
3639  bool isFromDecay = (bAll || bSecondary) && usePFDecays_ && eTrack.trackType(T_FROM_V0);
3640 
3641  return isFromDecay;
3642 
3643 
3644 }
bool usePFNuclearInteractions_
Definition: PFAlgo.h:382
virtual bool trackType(TrackType trType) const
bool usePFDecays_
Definition: PFAlgo.h:384
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 3498 of file PFAlgo.cc.

References mathSSE::sqrt().

Referenced by processBlock(), and thePFEnergyCalibration().

3498  {
3499 
3500  // Add a protection
3501  if ( clusterEnergyHCAL < 1. ) clusterEnergyHCAL = 1.;
3502 
3503  double resol = fabs(eta) < 1.48 ?
3504  sqrt (1.02*1.02/clusterEnergyHCAL + 0.065*0.065)
3505  :
3506  sqrt (1.20*1.20/clusterEnergyHCAL + 0.028*0.028);
3507 
3508  return resol;
3509 
3510 }
T sqrt(T t)
Definition: SSEVec.h:18
double PFAlgo::nSigmaHCAL ( double  clusterEnergy,
double  clusterEta 
) const
protected

Definition at line 3513 of file PFAlgo.cc.

References JetChargeProducer_cfi::exp, and nSigmaHCAL_.

Referenced by processBlock(), setDebug(), setParameters(), and thePFEnergyCalibration().

3513  {
3514  double nS = fabs(eta) < 1.48 ?
3515  nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.))
3516  :
3517  nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.));
3518 
3519  return nS;
3520 }
double nSigmaHCAL_
number of sigma to judge energy excess in HCAL
Definition: PFAlgo.h:333
const std::unique_ptr<reco::PFCandidateCollection>& PFAlgo::pfCandidates ( ) const
inline
Returns
collection of candidates

Definition at line 200 of file PFAlgo.h.

References pfCandidates_.

Referenced by operator<<().

200  {
201  return pfCandidates_;
202  }
std::unique_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:289
void PFAlgo::postCleaning ( )
protected

Definition at line 3653 of file PFAlgo.cc.

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

Referenced by reconstructParticles().

3653  {
3654 
3655  // Check if the post HF Cleaning was requested - if not, do nothing
3656  if ( !postHFCleaning_ ) return;
3657 
3658  //Compute met and met significance (met/sqrt(SumEt))
3659  double metX = 0.;
3660  double metY = 0.;
3661  double sumet = 0;
3662  std::vector<unsigned int> pfCandidatesToBeRemoved;
3663  for(unsigned i=0; i<pfCandidates_->size(); i++) {
3664  const PFCandidate& pfc = (*pfCandidates_)[i];
3665  metX += pfc.px();
3666  metY += pfc.py();
3667  sumet += pfc.pt();
3668  }
3669  double met2 = metX*metX+metY*metY;
3670  // Select events with large MET significance.
3671  double significance = std::sqrt(met2/sumet);
3672  double significanceCor = significance;
3673  if ( significance > minSignificance_ ) {
3674 
3675  double metXCor = metX;
3676  double metYCor = metY;
3677  double sumetCor = sumet;
3678  double met2Cor = met2;
3679  double deltaPhi = 3.14159;
3680  double deltaPhiPt = 100.;
3681  bool next = true;
3682  unsigned iCor = 1E9;
3683 
3684  // Find the HF candidate with the largest effect on the MET
3685  while ( next ) {
3686 
3687  double metReduc = -1.;
3688  // Loop on the candidates
3689  for(unsigned i=0; i<pfCandidates_->size(); ++i) {
3690  const PFCandidate& pfc = (*pfCandidates_)[i];
3691 
3692  // Check that the pfCandidate is in the HF
3693  if ( pfc.particleId() != reco::PFCandidate::h_HF &&
3694  pfc.particleId() != reco::PFCandidate::egamma_HF ) continue;
3695 
3696  // Check if has meaningful pt
3697  if ( pfc.pt() < minHFCleaningPt_ ) continue;
3698 
3699  // Check that it is not already scheculed to be cleaned
3700  bool skip = false;
3701  for(unsigned j=0; j<pfCandidatesToBeRemoved.size(); ++j) {
3702  if ( i == pfCandidatesToBeRemoved[j] ) skip = true;
3703  if ( skip ) break;
3704  }
3705  if ( skip ) continue;
3706 
3707  // Check that the pt and the MET are aligned
3708  deltaPhi = std::acos((metX*pfc.px()+metY*pfc.py())/(pfc.pt()*std::sqrt(met2)));
3709  deltaPhiPt = deltaPhi*pfc.pt();
3710  if ( deltaPhiPt > maxDeltaPhiPt_ ) continue;
3711 
3712  // Now remove the candidate from the MET
3713  double metXInt = metX - pfc.px();
3714  double metYInt = metY - pfc.py();
3715  double sumetInt = sumet - pfc.pt();
3716  double met2Int = metXInt*metXInt+metYInt*metYInt;
3717  if ( met2Int < met2Cor ) {
3718  metXCor = metXInt;
3719  metYCor = metYInt;
3720  metReduc = (met2-met2Int)/met2Int;
3721  met2Cor = met2Int;
3722  sumetCor = sumetInt;
3723  significanceCor = std::sqrt(met2Cor/sumetCor);
3724  iCor = i;
3725  }
3726  }
3727  //
3728  // If the MET must be significanly reduced, schedule the candidate to be cleaned
3729  if ( metReduc > minDeltaMet_ ) {
3730  pfCandidatesToBeRemoved.push_back(iCor);
3731  metX = metXCor;
3732  metY = metYCor;
3733  sumet = sumetCor;
3734  met2 = met2Cor;
3735  } else {
3736  // Otherwise just stop the loop
3737  next = false;
3738  }
3739  }
3740  //
3741  // The significance must be significantly reduced to indeed clean the candidates
3742  if ( significance - significanceCor > minSignificanceReduction_ &&
3743  significanceCor < maxSignificance_ ) {
3744  std::cout << "Significance reduction = " << significance << " -> "
3745  << significanceCor << " = " << significanceCor - significance
3746  << std::endl;
3747  for(unsigned j=0; j<pfCandidatesToBeRemoved.size(); ++j) {
3748  std::cout << "Removed : " << (*pfCandidates_)[pfCandidatesToBeRemoved[j]] << std::endl;
3749  pfCleanedCandidates_->push_back( (*pfCandidates_)[ pfCandidatesToBeRemoved[j] ] );
3750  (*pfCandidates_)[pfCandidatesToBeRemoved[j]].rescaleMomentum(1E-6);
3751  //reco::PFCandidate::ParticleType unknown = reco::PFCandidate::X;
3752  //(*pfCandidates_)[pfCandidatesToBeRemoved[j]].setParticleType(unknown);
3753  }
3754  }
3755  }
3756 
3757 }
double maxDeltaPhiPt_
Definition: PFAlgo.h:427
double maxSignificance_
Definition: PFAlgo.h:425
double minHFCleaningPt_
Definition: PFAlgo.h:423
double minDeltaMet_
Definition: PFAlgo.h:428
double minSignificance_
Definition: PFAlgo.h:424
std::unique_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:289
double px() const final
x coordinate of momentum vector
double pt() const final
transverse momentum
double minSignificanceReduction_
Definition: PFAlgo.h:426
std::unique_ptr< reco::PFCandidateCollection > pfCleanedCandidates_
Definition: PFAlgo.h:295
bool postHFCleaning_
Definition: PFAlgo.h:421
T sqrt(T t)
Definition: SSEVec.h:18
double py() const final
y coordinate of momentum vector
significance
Definition: met_cff.py:30
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
virtual ParticleType particleId() const
Definition: PFCandidate.h:374
void PFAlgo::processBlock ( const reco::PFBlockRef blockref,
std::list< reco::PFBlockRef > &  hcalBlockRefs,
std::list< reco::PFBlockRef > &  ecalBlockRefs 
)
protectedvirtual

process one block. can be reimplemented in more sophisticated algorithms

Reimplemented in PFAlgoTestBenchConversions, and PFAlgoTestBenchElectrons.

Definition at line 560 of file PFAlgo.cc.

References a, funct::abs(), patPFMETCorrections_cff::algo, associatePSClusters(), b, reco::CaloCluster::badHcalMarker, edm::OwnVector< T, P >::begin(), groupFilesInBlocks::block, fftjetpileupestimator_calo_uncalib_cfi::c0, alignmentValidation::c1, calibration_, MessageLogger_cfi::cerr, reco::LeafCandidate::charge(), muons2muons_cfi::chargedHadron, trackerTree::check(), reco::TrackBase::conversionStep, gather_cfg::cout, debug_, dptRel_DispVtx_, reco::PFCandidate::e, RecoEcal_EventContent_cff::ec, ECAL, reco::PFBlockElement::ECAL, RecoEcal_cff::ecalClusters, reco::PFCandidate::egammaExtraRef(), allElectronIsolations_cfi::elements, reco::PFCandidate::elementsInBlocks(), edm::OwnVector< T, P >::empty(), reco::LeafCandidate::energy(), PFTrackAlgoTools::errorScale(), PVValHelper::eta, reco::LeafCandidate::eta(), factors45_, plotBeamSpotDB::first, flags, dedxEstimators_cff::fraction, reco::PFCandidate::gamma, PFElectronAlgo::getAllElectronCandidates(), PFElectronAlgo::getElectronCandidates(), PFElectronAlgo::getElectronExtra(), goodPixelTrackDeadHcal_chi2n_, goodPixelTrackDeadHcal_dxy_, goodPixelTrackDeadHcal_dz_, goodPixelTrackDeadHcal_maxLost3Hit_, goodPixelTrackDeadHcal_maxLost4Hit_, goodPixelTrackDeadHcal_maxPt_, goodPixelTrackDeadHcal_minEta_, goodPixelTrackDeadHcal_ptErrRel_, goodTrackDeadHcal_chi2n_, goodTrackDeadHcal_dxy_, goodTrackDeadHcal_layers_, goodTrackDeadHcal_ptErrRel_, goodTrackDeadHcal_validFr_, reco::PFBlockElement::GSF, HCAL, reco::PFBlockElement::HCAL, PFLayer::HF_EM, PFLayer::HF_HAD, reco::TrackBase::highPurity, reco::PFBlockElement::HO, hcaldqm::constants::HO, mps_fire::i, cuy::ii, PFEGammaFilters::isElectron(), PFEGammaFilters::isElectronSafeForJetMET(), PFElectronAlgo::isElectronValidCandidate(), isFromSecInt(), PFMuonAlgo::isGlobalTightMuon(), PFMuonAlgo::isIsolatedMuon(), PFMuonAlgo::isLooseMuon(), PFMuonAlgo::isMuon(), edm::Ref< C, T, F >::isNonnull(), edm::Ref< C, T, F >::isNull(), PFEGammaFilters::isPhotonSafeForJetMET(), PFPhotonAlgo::isPhotonValidCandidate(), PFMuonAlgo::isTrackerTightMuon(), reco::PFBlock::LINKTEST_ALL, SiStripPI::max, min(), reco::PFCandidate::mu, muonECAL_, muonHCAL_, muonHO_, reco::PFCandidate::mva_e_pi(), neutralHadronEnergyResolution(), jets_cff::nMuons, nSigmaECAL_, nSigmaHCAL(), nSigmaTRACK_, nVtx_, convertSQLiteXML::ok, AlCaHLTBitMon_ParallelJobs::p, objects.autophobj::particleType, PFEGammaFilters::passElectronSelection(), PFEGammaFilters::passPhotonSelection(), pfCandidates_, pfegamma_, pfEgammaCandidates_, pfele_, pfElectronCandidates_, pfElectronExtra_, pfpho_, pfPhotonCandidates_, pfPhotonExtra_, reco::LeafCandidate::phi(), reco::Vertex::position(), primaryVertex_, reco::PFBlockElement::PS1, reco::PFBlockElement::PS2, reco::LeafCandidate::pt(), ptError_, edm::OwnVector< T, P >::push_back(), jets_cff::quality, reconstructCluster(), reconstructTrack(), edm::View< T >::refAt(), rejectTracks_Bad_, rejectTracks_Step45_, edm::second(), reco::PFCandidate::set_mva_e_pi(), reco::PFCandidate::set_mva_Isolated(), reco::PFCandidate::set_mva_nothing_gamma(), reco::LeafCandidate::setCharge(), reco::PFCandidate::setEcalEnergy(), setHcalDepthInfo(), reco::PFCandidate::setHcalEnergy(), reco::PFCandidate::setHoEnergy(), reco::LeafCandidate::setP4(), reco::PFCandidate::setParticleType(), reco::PFBlockElementTrack::setPositionAtECALEntrance(), reco::PFCandidate::setVertex(), edm::OwnVector< T, P >::size(), edm::View< T >::size(), createPayload::skip, mathSSE::sqrt(), PFTrackAlgoTools::step45(), PFTrackAlgoTools::step5(), reco::PFBlockElement::T_FROM_GAMMACONV, thepfEnergyCalibrationHF_, reco::PFBlockElement::TRACK, reco::btau::trackMomentum, reco::PFBlockElementTrack::trackType(), funct::true, useEGammaFilters_, useHO_, usePFConversions_, usePFElectrons_, usePFPhotons_, useProtectionsForJetMET_, findQualityFiles::v, x, X, reco::Vertex::x(), DOFs::Y, reco::Vertex::y(), DOFs::Z, and reco::Vertex::z().

Referenced by reconstructParticles(), and thePFEnergyCalibration().

562  {
563 
564  // debug_ = false;
565  assert(!blockref.isNull() );
566  const reco::PFBlock& block = *blockref;
567 
568  typedef std::multimap<double, unsigned>::iterator IE;
569  typedef std::multimap<double, std::pair<unsigned,::math::XYZVector> >::iterator IS;
570  typedef std::multimap<double, std::pair<unsigned,bool> >::iterator IT;
571  typedef std::multimap< unsigned, std::pair<double, unsigned> >::iterator II;
572 
573  if(debug_) {
574  cout<<"#########################################################"<<endl;
575  cout<<"##### Process Block: #####"<<endl;
576  cout<<"#########################################################"<<endl;
577  cout<<block<<endl;
578  }
579 
580 
581  const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
582  // make a copy of the link data, which will be edited.
583  PFBlock::LinkData linkData = block.linkData();
584 
585  // keep track of the elements which are still active.
586  vector<bool> active( elements.size(), true );
587 
588 
589  // //PFElectrons:
590  // usePFElectrons_ external configurable parameter to set the usage of pf electron
591  std::vector<reco::PFCandidate> tempElectronCandidates;
592  tempElectronCandidates.clear();
593  if (usePFElectrons_) {
594  if (pfele_->isElectronValidCandidate(blockref,active, primaryVertex_ )){
595  // if there is at least a valid candidate is get the vector of pfcandidates
596  const std::vector<reco::PFCandidate> PFElectCandidates_(pfele_->getElectronCandidates());
597  for ( std::vector<reco::PFCandidate>::const_iterator ec=PFElectCandidates_.begin(); ec != PFElectCandidates_.end(); ++ec )tempElectronCandidates.push_back(*ec);
598 
599  // (***) We're filling the ElectronCandidates into the PFCandiate collection
600  // ..... Once we let PFPhotonAlgo over-write electron-decision, we need to move this to
601  // ..... after the PhotonAlgo has run (Fabian)
602  }
603  // The vector active is automatically changed (it is passed by ref) in PFElectronAlgo
604  // for all the electron candidate
606  pfele_->getAllElectronCandidates().begin(),
607  pfele_->getAllElectronCandidates().end());
608 
609  pfElectronExtra_.insert(pfElectronExtra_.end(),
610  pfele_->getElectronExtra().begin(),
611  pfele_->getElectronExtra().end());
612 
613  }
614  if( /* --- */ usePFPhotons_ /* --- */ ) {
615 
616  if(debug_)
617  cout<<endl<<"--------------- entering PFPhotonAlgo ----------------"<<endl;
618  vector<PFCandidatePhotonExtra> pfPhotonExtraCand;
619  if ( pfpho_->isPhotonValidCandidate(blockref, // passing the reference to the PFBlock
620  active, // std::vector<bool> containing information about acitivity
621  pfPhotonCandidates_, // pointer to candidate vector, to be filled by the routine
622  pfPhotonExtraCand, // candidate extra vector, to be filled by the routine
623  tempElectronCandidates
624  //pfElectronCandidates_ // pointer to some auziliary UNTOUCHED FOR NOW
625  ) ) {
626  if(debug_)
627  std::cout<< " In this PFBlock we found "<<pfPhotonCandidates_->size()<<" Photon Candidates."<<std::endl;
628 
629  // CAUTION: In case we want to allow the PhotonAlgo to 'over-write' what the ElectronAlgo did above
630  // ........ we should NOT fill the PFCandidate-vector with the electrons above (***)
631 
632  // Here we need to add all the photon cands to the pfCandidate list
633  unsigned int extracand =0;
634  PFCandidateCollection::const_iterator cand = pfPhotonCandidates_->begin();
635  for( ; cand != pfPhotonCandidates_->end(); ++cand, ++extracand) {
636  pfCandidates_->push_back(*cand);
637  pfPhotonExtra_.push_back(pfPhotonExtraCand[extracand]);
638  }
639 
640  } // end of 'if' in case photons are found
641  pfPhotonExtraCand.clear();
642  pfPhotonCandidates_->clear();
643  } // end of Photon algo
644 
645  if (usePFElectrons_) {
646  for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin(); ec != tempElectronCandidates.end(); ++ec ){
647  pfCandidates_->push_back(*ec);
648  }
649  tempElectronCandidates.clear();
650  }
651 
652 
653  // New EGamma Reconstruction 10/10/2013
654  if(useEGammaFilters_) {
655 
656  // const edm::ValueMap<reco::GsfElectronRef> & myGedElectronValMap(*valueMapGedElectrons_);
657  bool egmLocalDebug = debug_;
658  bool egmLocalBlockDebug = false;
659 
660  unsigned int negmcandidates = pfEgammaCandidates_->size();
661  for(unsigned int ieg=0 ; ieg < negmcandidates; ++ieg) {
662  // const reco::PFCandidate & egmcand((*pfEgammaCandidates_)[ieg]);
664 
665  const PFCandidate::ElementsInBlocks& theElements = (*pfEgmRef).elementsInBlocks();
666  PFCandidate::ElementsInBlocks::const_iterator iegfirst = theElements.begin();
667  bool sameBlock = false;
668  bool isGoodElectron = false;
669  bool isGoodPhoton = false;
670  bool isPrimaryElectron = false;
671  if(iegfirst->first == blockref)
672  sameBlock = true;
673  if(sameBlock) {
674 
675  if(egmLocalDebug)
676  cout << " I am in looping on EGamma Candidates: pt " << (*pfEgmRef).pt()
677  << " eta,phi " << (*pfEgmRef).eta() << ", " << (*pfEgmRef).phi()
678  << " charge " << (*pfEgmRef).charge() << endl;
679 
680  if((*pfEgmRef).gsfTrackRef().isNonnull()) {
681 
682  reco::GsfElectronRef gedEleRef = (*valueMapGedElectrons_)[pfEgmRef];
683  if(gedEleRef.isNonnull()) {
684  isGoodElectron = pfegamma_->passElectronSelection(*gedEleRef,*pfEgmRef,nVtx_);
685  isPrimaryElectron = pfegamma_->isElectron(*gedEleRef);
686  if(egmLocalDebug){
687  if(isGoodElectron)
688  cout << "** Good Electron, pt " << gedEleRef->pt()
689  << " eta, phi " << gedEleRef->eta() << ", " << gedEleRef->phi()
690  << " charge " << gedEleRef->charge()
691  << " isPrimary " << isPrimaryElectron
692  << " isoDr03 " << (gedEleRef->dr03TkSumPt() + gedEleRef->dr03EcalRecHitSumEt() + gedEleRef->dr03HcalTowerSumEt())
693  << " mva_isolated " << gedEleRef->mva_Isolated()
694  << " mva_e_pi " << gedEleRef->mva_e_pi()
695  << endl;
696  }
697 
698 
699  }
700  }
701  if((*pfEgmRef).superClusterRef().isNonnull()) {
702 
703  reco::PhotonRef gedPhoRef = (*valueMapGedPhotons_)[pfEgmRef];
704  if(gedPhoRef.isNonnull()) {
705  isGoodPhoton = pfegamma_->passPhotonSelection(*gedPhoRef);
706  if(egmLocalDebug) {
707  if(isGoodPhoton)
708  cout << "** Good Photon, pt " << gedPhoRef->pt()
709  << " eta, phi " << gedPhoRef->eta() << ", " << gedPhoRef->phi() << endl;
710  }
711  }
712  }
713  } // end same block
714 
715  if(isGoodElectron && isGoodPhoton) {
716  if(isPrimaryElectron)
717  isGoodPhoton = false;
718  else
719  isGoodElectron = false;
720  }
721 
722  // isElectron
723  if(isGoodElectron) {
724  reco::GsfElectronRef gedEleRef = (*valueMapGedElectrons_)[pfEgmRef];
725  reco::PFCandidate myPFElectron = *pfEgmRef;
726  // run protections
727  bool lockTracks = false;
728  bool isSafe = true;
730  lockTracks = true;
731  isSafe = pfegamma_->isElectronSafeForJetMET(*gedEleRef,myPFElectron,primaryVertex_,lockTracks);
732  }
733 
734  if(isSafe) {
736  myPFElectron.setParticleType(particleType);
737  myPFElectron.setCharge(gedEleRef->charge());
738  myPFElectron.setP4(gedEleRef->p4());
739  myPFElectron.set_mva_e_pi(gedEleRef->mva_e_pi());
740  myPFElectron.set_mva_Isolated(gedEleRef->mva_Isolated());
741 
742  if(egmLocalDebug) {
743  cout << " PFAlgo: found an electron with NEW EGamma code " << endl;
744  cout << " myPFElectron: pt " << myPFElectron.pt()
745  << " eta,phi " << myPFElectron.eta() << ", " <<myPFElectron.phi()
746  << " mva " << myPFElectron.mva_e_pi()
747  << " charge " << myPFElectron.charge() << endl;
748  }
749 
750 
751  // Lock all the elements
752  if(egmLocalBlockDebug)
753  cout << " THE BLOCK " << *blockref << endl;
754  for (PFCandidate::ElementsInBlocks::const_iterator ieb = theElements.begin();
755  ieb<theElements.end(); ++ieb) {
756  active[ieb->second] = false;
757  if(egmLocalBlockDebug||(debug_&&egmLocalDebug))
758  cout << " Elements used " << ieb->second << endl;
759  }
760 
761  // The electron is considered safe for JetMET and the additional tracks pointing to it are locked
762  if(lockTracks) {
763  const PFCandidate::ElementsInBlocks& extraTracks = myPFElectron.egammaExtraRef()->extraNonConvTracks();
764  for (PFCandidate::ElementsInBlocks::const_iterator itrk = extraTracks.begin();
765  itrk<extraTracks.end(); ++itrk) {
766  if(egmLocalBlockDebug||(debug_&&egmLocalDebug))
767  cout << " Extra locked track " << itrk->second << endl;
768  active[itrk->second] = false;
769  }
770  }
771 
772  pfCandidates_->push_back(myPFElectron);
773 
774  }
775  else {
776  if(egmLocalDebug)
777  cout << "PFAlgo: Electron DISCARDED, NOT SAFE FOR JETMET " << endl;
778  }
779  }
780  if(isGoodPhoton) {
781  reco::PhotonRef gedPhoRef = (*valueMapGedPhotons_)[pfEgmRef];
782  reco::PFCandidate myPFPhoton = *pfEgmRef;
783  bool isSafe = true;
785  isSafe = pfegamma_->isPhotonSafeForJetMET(*gedPhoRef,myPFPhoton);
786  }
787 
788 
789 
790  if(isSafe) {
792  myPFPhoton.setParticleType(particleType);
793  myPFPhoton.setCharge(0);
794  myPFPhoton.set_mva_nothing_gamma(1.);
796  myPFPhoton.setVertex( v );
797  myPFPhoton.setP4(gedPhoRef->p4());
798  if(egmLocalDebug) {
799  cout << " PFAlgo: found a photon with NEW EGamma code " << endl;
800  cout << " myPFPhoton: pt " << myPFPhoton.pt()
801  << " eta,phi " << myPFPhoton.eta() << ", " <<myPFPhoton.phi()
802  << " charge " << myPFPhoton.charge() << endl;
803  }
804 
805  // Lock all the elements
806  if(egmLocalBlockDebug)
807  cout << " THE BLOCK " << *blockref << endl;
808  for (PFCandidate::ElementsInBlocks::const_iterator ieb = theElements.begin();
809  ieb<theElements.end(); ++ieb) {
810  active[ieb->second] = false;
811  if(egmLocalBlockDebug||(debug_&&egmLocalDebug))
812  cout << " Elements used " << ieb->second << endl;
813  }
814  pfCandidates_->push_back(myPFPhoton);
815 
816  } // end isSafe
817  } // end isGoodPhoton
818  } // end loop on EGM candidates
819  } // end if use EGammaFilters
820 
821 
822 
823  //Lock extra conversion tracks not used by Photon Algo
824  if (usePFConversions_ )
825  {
826  for(unsigned iEle=0; iEle<elements.size(); iEle++) {
827  PFBlockElement::Type type = elements[iEle].type();
828  if(type==PFBlockElement::TRACK)
829  {
830  if(elements[iEle].trackRef()->algo() == reco::TrackBase::conversionStep)
831  active[iEle]=false;
832  if(elements[iEle].trackRef()->quality(reco::TrackBase::highPurity))continue;
833  const reco::PFBlockElementTrack * trackRef = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[iEle]));
834  if(!(trackRef->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)))continue;
835  if(!elements[iEle].convRefs().empty())active[iEle]=false;
836  }
837  }
838  }
839 
840 
841 
842 
843 
844  if(debug_)
845  cout<<endl<<"--------------- loop 1 ------------------"<<endl;
846 
847  //COLINFEB16
848  // In loop 1, we loop on all elements.
849 
850  // The primary goal is to deal with tracks that are:
851  // - not associated to an HCAL cluster
852  // - not identified as an electron.
853  // Those tracks should be predominantly relatively low energy charged
854  // hadrons which are not detected in the ECAL.
855 
856  // The secondary goal is to prepare for the next loops
857  // - The ecal and hcal elements are sorted in separate vectors
858  // which will be used as a base for the corresponding loops.
859  // - For tracks which are connected to more than one HCAL cluster,
860  // the links between the track and the cluster are cut for all clusters
861  // but the closest one.
862  // - HF only blocks ( HFEM, HFHAD, HFEM+HFAD) are identified
863 
864  // obsolete comments?
865  // loop1:
866  // - sort ecal and hcal elements in separate vectors
867  // - for tracks:
868  // - lock closest ecal cluster
869  // - cut link to farthest hcal cluster, if more than 1.
870 
871  // vectors to store indices to ho, hcal and ecal elements
872  vector<unsigned> hcalIs;
873  vector<unsigned> hoIs;
874  vector<unsigned> ecalIs;
875  vector<unsigned> trackIs;
876  vector<unsigned> ps1Is;
877  vector<unsigned> ps2Is;
878 
879  vector<unsigned> hfEmIs;
880  vector<unsigned> hfHadIs;
881 
882  vector<bool> deadArea(elements.size(), false);
883 
884  for(unsigned iEle=0; iEle<elements.size(); iEle++) {
885  PFBlockElement::Type type = elements[iEle].type();
886 
887  if(debug_ && type != PFBlockElement::BREM ) cout<<endl<<elements[iEle];
888 
889  switch( type ) {
890  case PFBlockElement::TRACK:
891  if ( active[iEle] ) {
892  trackIs.push_back( iEle );
893  if(debug_) cout<<"TRACK, stored index, continue"<<endl;
894  }
895  break;
896  case PFBlockElement::ECAL:
897  if ( active[iEle] ) {
898  ecalIs.push_back( iEle );
899  if(debug_) cout<<"ECAL, stored index, continue"<<endl;
900  }
901  continue;
903  if ( active[iEle] ) {
904  if (elements[iEle].clusterRef()->flags() & reco::CaloCluster::badHcalMarker) {
905  if(debug_) cout<<"HCAL DEAD AREA: remember and skip."<<endl;
906  active[iEle] = false;
907  deadArea[iEle] = true;
908  continue;
909  }
910  hcalIs.push_back( iEle );
911  if(debug_) cout<<"HCAL, stored index, continue"<<endl;
912  }
913  continue;
914  case PFBlockElement::HO:
915  if (useHO_) {
916  if ( active[iEle] ) {
917  hoIs.push_back( iEle );
918  if(debug_) cout<<"HO, stored index, continue"<<endl;
919  }
920  }
921  continue;
922  case PFBlockElement::HFEM:
923  if ( active[iEle] ) {
924  hfEmIs.push_back( iEle );
925  if(debug_) cout<<"HFEM, stored index, continue"<<endl;
926  }
927  continue;
928  case PFBlockElement::HFHAD:
929  if ( active[iEle] ) {
930  hfHadIs.push_back( iEle );
931  if(debug_) cout<<"HFHAD, stored index, continue"<<endl;
932  }
933  continue;
934  default:
935  continue;
936  }
937 
938  // we're now dealing with a track
939  unsigned iTrack = iEle;
940  reco::MuonRef muonRef = elements[iTrack].muonRef();
941  if (debug_ && muonRef.isNonnull()) {
942  cout << "track " << iTrack << " has a valid muon reference. " << std::endl;
943  cout << " - isMuon: " << PFMuonAlgo::isMuon(muonRef) << endl;
944  cout << " - isGlobalTightMuon: " << PFMuonAlgo::isGlobalTightMuon(muonRef) << endl;
945  cout << " - isTrackerTightMuon: " << PFMuonAlgo::isTrackerTightMuon(muonRef) << endl;
946  cout << " - isIsolatedMuon: " << PFMuonAlgo::isIsolatedMuon(muonRef) << endl;
947  }
948 
949  //Check if the track is a primary track of a secondary interaction
950  //If that is the case reconstruct a charged hadron noly using that
951  //track
952  if (active[iTrack] && isFromSecInt(elements[iEle], "primary")){
953  bool isPrimaryTrack = elements[iEle].displacedVertexRef(PFBlockElement::T_TO_DISP)->displacedVertexRef()->isTherePrimaryTracks();
954  if (isPrimaryTrack) {
955  if (debug_) cout << "Primary Track reconstructed alone" << endl;
956 
957  unsigned tmpi = reconstructTrack(elements[iEle]);
958  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEle );
959  active[iTrack] = false;
960  }
961  }
962 
963 
964  if(debug_) {
965  if ( !active[iTrack] )
966  cout << "Already used by electrons, muons, conversions" << endl;
967  }
968 
969  // Track already used as electron, muon, conversion?
970  // Added a check on the activated element
971  if ( ! active[iTrack] ) continue;
972 
973  reco::TrackRef trackRef = elements[iTrack].trackRef();
974  assert( !trackRef.isNull() );
975 
976  if (debug_ ) {
977  cout <<"PFAlgo:processBlock "<<" "<<trackIs.size()<<" "<<ecalIs.size()<<" "<<hcalIs.size()<<" "<<hoIs.size()<<endl;
978  }
979 
980  // look for associated elements of all types
981  //COLINFEB16
982  // all types of links are considered.
983  // the elements are sorted by increasing distance
984  std::multimap<double, unsigned> ecalElems;
985  block.associatedElements( iTrack, linkData,
986  ecalElems ,
989 
990  std::multimap<double, unsigned> hcalElems;
991  block.associatedElements( iTrack, linkData,
992  hcalElems,
995 
996  if (debug_ ) {
997  std::cout << "\tTrack " << iTrack << " is linked to " << ecalElems.size() << " ecal and " << hcalElems.size() << " hcal elements" << std::endl;
998  for (const auto & pair : ecalElems) {
999  std::cout << "ecal: dist " << pair.first << "\t elem " << pair.second << std::endl;
1000  }
1001  for (const auto & pair : hcalElems) {
1002  std::cout << "hcal: dist " << pair.first << "\t elem " << pair.second << (deadArea[pair.second] ? " DEAD AREA MARKER" : "") << std::endl;
1003  }
1004  }
1005  // there's 3 possible options possible here, in principle:
1006  // 1) flag everything that may be associated to a dead hcal marker
1007  // 2) flag everything whose closest hcal link is a dead hcal marker
1008  // 3) flag only things that are linked only to dead hcal marker
1009  // in our first test we go for (2)
1010  //--- option (1) --
1011  //bool hasDeadHcal = false;
1012  //for (auto it = hcalElems.begin(), ed = hcalElems.end(); it != ed; /*NOTE NO ++it HERE */ ) {
1013  // if (deadArea[it->second]) { hasDeadHcal = true; it = hcalElems.erase(it); } // std::multimap::erase returns iterator to next
1014  // else ++it;
1015  //}
1016  //--- option (2) --
1017  bool hasDeadHcal = false;
1018  if (!hcalElems.empty() && deadArea[hcalElems.begin()->second]) {
1019  hasDeadHcal = true;
1020  hcalElems.clear();
1021  }
1022  //--- option (3) --
1023  //bool hasDeadHcal = true;
1024  //for (auto it = hcalElems.begin(), ed = hcalElems.end(); it != ed; /*NOTE NO ++it HERE */ ) {
1025  // if (deadArea[it->second]) { it = hcalElems.erase(it); } // std::multimap::erase returns iterator to next
1026  // else { hasDeadHcal = false; }
1027  //}
1028 
1029  // for tracks with bad Hcal, check the quality
1030  bool goodTrackDeadHcal = false;
1031  if (hasDeadHcal) {
1032  goodTrackDeadHcal = ( trackRef->ptError() < goodTrackDeadHcal_ptErrRel_ * trackRef->pt() &&
1033  trackRef->normalizedChi2() < goodTrackDeadHcal_chi2n_ &&
1034  trackRef->hitPattern().trackerLayersWithMeasurement() >= goodTrackDeadHcal_layers_ &&
1035  trackRef->validFraction() > goodTrackDeadHcal_validFr_ &&
1037  // now we add an extra block for tracks at high |eta|
1038  if (!goodTrackDeadHcal &&
1039  std::abs(trackRef->eta()) > goodPixelTrackDeadHcal_minEta_ && // high eta
1040  trackRef->hitPattern().pixelLayersWithMeasurement() >= 3 && // pixel track
1041  trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::TRACK_HITS) == 0 &&
1042  trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_INNER_HITS) == 0 &&
1043  trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_OUTER_HITS) <= (
1044  trackRef->hitPattern().pixelLayersWithMeasurement() > 3 ?
1046  trackRef->normalizedChi2() < goodPixelTrackDeadHcal_chi2n_ && // tighter cut
1049  trackRef->ptError() < goodPixelTrackDeadHcal_ptErrRel_*trackRef->pt() && // sanity
1050  trackRef->pt() < goodPixelTrackDeadHcal_maxPt_) { // sanity
1051  goodTrackDeadHcal = true;
1052  // FIXME: may decide to do something to the track pT
1053  }
1054  //if (!goodTrackDeadHcal && trackRef->hitPattern().trackerLayersWithMeasurement() == 4 && trackRef->validFraction() == 1
1055  if (debug_) cout << " track pt " << trackRef->pt() << " +- " << trackRef->ptError()
1056  << " layers valid " << trackRef->hitPattern().trackerLayersWithMeasurement()
1057  << ", lost " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::TRACK_HITS)
1058  << ", lost outer " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_OUTER_HITS)
1059  << ", lost inner " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_INNER_HITS)
1060  << "(valid fraction " << trackRef->validFraction() << ")"
1061  << " chi2/ndf " << trackRef->normalizedChi2()
1062  << " |dxy| " << std::abs(trackRef->dxy(primaryVertex_.position())) << " +- " << trackRef->dxyError()
1063  << " |dz| " << std::abs(trackRef->dz(primaryVertex_.position())) << " +- " << trackRef->dzError()
1064  << (goodTrackDeadHcal ? " passes " : " fails ") << "quality cuts" << std::endl;
1065  }
1066 
1067  // When a track has no HCAL cluster linked, but another track is linked to the same
1068  // ECAL cluster and an HCAL cluster, link the track to the HCAL cluster for
1069  // later analysis
1070  if ( hcalElems.empty() && !ecalElems.empty() && !hasDeadHcal) {
1071  // debug_ = true;
1072  unsigned ntt = 1;
1073  unsigned index = ecalElems.begin()->second;
1074  std::multimap<double, unsigned> sortedTracks;
1075  block.associatedElements( index, linkData,
1076  sortedTracks,
1079  if (debug_ ) std::cout << "The closest ECAL cluster is linked to " << sortedTracks.size() << " tracks, with distance = " << ecalElems.begin()->first << std::endl;
1080 
1081  // Loop over all tracks
1082  for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
1083  unsigned jTrack = ie->second;
1084  //std::cout << "Track " << jTrack << std::endl;
1085  // Track must be active
1086  if ( !active[jTrack] ) continue;
1087  //std::cout << "Active " << std::endl;
1088 
1089  // The loop is on the other tracks !
1090  if ( jTrack == iTrack ) continue;
1091  //std::cout << "A different track ! " << std::endl;
1092 
1093  // Check if the ECAL closest to this track is the current ECAL
1094  // Otherwise ignore this track in the neutral energy determination
1095  std::multimap<double, unsigned> sortedECAL;
1096  block.associatedElements( jTrack, linkData,
1097  sortedECAL,
1100  if ( sortedECAL.begin()->second != index ) continue;
1101  if (debug_ ) std::cout << " track " << jTrack << " with closest ECAL identical " << std::endl;
1102 
1103 
1104  // Check if this track is also linked to an HCAL
1105  std::multimap<double, unsigned> sortedHCAL;
1106  block.associatedElements( jTrack, linkData,
1107  sortedHCAL,
1110  if ( sortedHCAL.empty() ) continue;
1111  if (debug_ ) std::cout << " and with an HCAL cluster " << sortedHCAL.begin()->second << std::endl;
1112  ntt++;
1113 
1114  // In that case establish a link with the first track
1115  block.setLink( iTrack,
1116  sortedHCAL.begin()->second,
1117  sortedECAL.begin()->first,
1118  linkData,
1119  PFBlock::LINKTEST_RECHIT );
1120 
1121  } // End other tracks
1122 
1123  // Redefine HCAL elements
1124  block.associatedElements( iTrack, linkData,
1125  hcalElems,
1128 
1129  if ( debug_ && !hcalElems.empty() )
1130  std::cout << "Track linked back to HCAL due to ECAL sharing with other tracks" << std::endl;
1131  }
1132 
1133  //MICHELE
1134  //TEMPORARY SOLUTION FOR ELECTRON REJECTION IN PFTAU
1135  //COLINFEB16
1136  // in case particle flow electrons are not reconstructed,
1137  // the mva_e_pi of the charged hadron will be set to 1
1138  // if a GSF element is associated to the current TRACK element
1139  // This information will be used in the electron rejection for tau ID.
1140  std::multimap<double,unsigned> gsfElems;
1141  if (usePFElectrons_ == false) {
1142  block.associatedElements( iTrack, linkData,
1143  gsfElems ,
1145  }
1146  //
1147 
1148  if(hcalElems.empty() && debug_) {
1149  cout<<"no hcal element connected to track "<<iTrack<<endl;
1150  }
1151 
1152  // will now loop on associated elements ...
1153  // typedef std::multimap<double, unsigned>::iterator IE;
1154 
1155  bool hcalFound = false;
1156 
1157  if(debug_)
1158  cout<<"now looping on elements associated to the track"<<endl;
1159 
1160  // ... first on associated ECAL elements
1161  // Check if there is still a free ECAL for this track
1162  for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
1163 
1164  unsigned index = ie->second;
1165  // Sanity checks and optional printout
1166  PFBlockElement::Type type = elements[index].type();
1167  if(debug_) {
1168  double dist = ie->first;
1169  cout<<"\telement "<<elements[index]<<" linked with distance = "<< dist <<endl;
1170  if ( ! active[index] ) cout << "This ECAL is already used - skip it" << endl;
1171  }
1172  assert( type == PFBlockElement::ECAL );
1173 
1174  // This ECAL is not free (taken by an electron?) - just skip it
1175  if ( ! active[index] ) continue;
1176 
1177  // Flag ECAL clusters for which the corresponding track is not linked to an HCAL cluster
1178 
1179  //reco::PFClusterRef clusterRef = elements[index].clusterRef();
1180  //assert( !clusterRef.isNull() );
1181  if( !hcalElems.empty() && debug_)
1182  cout<<"\t\tat least one hcal element connected to the track."
1183  <<" Sparing Ecal cluster for the hcal loop"<<endl;
1184 
1185  } //loop print ecal elements
1186 
1187 
1188  // tracks which are not linked to an HCAL
1189  // are reconstructed now.
1190 
1191  if( hcalElems.empty() ) {
1192 
1193  if ( debug_ )
1194  std::cout << "Now deals with tracks linked to no HCAL clusters. Was HCal active? " << (!hasDeadHcal) << std::endl;
1195  // vector<unsigned> elementIndices;
1196  // elementIndices.push_back(iTrack);
1197 
1198  // The track momentum
1199  double trackMomentum = elements[iTrack].trackRef()->p();
1200  if ( debug_ )
1201  std::cout << elements[iTrack] << std::endl;
1202 
1203  // Is it a "tight" muon ? In that case assume no
1204  //Track momentum corresponds to the calorimeter
1205  //energy for now
1206  bool thisIsAMuon = PFMuonAlgo::isMuon(elements[iTrack]);
1207  if ( thisIsAMuon ) trackMomentum = 0.;
1208 
1209  // If it is not a muon check if Is it a fake track ?
1210  //Michalis: I wonder if we should convert this to dpt/pt?
1211  bool rejectFake = false;
1212  if ( !thisIsAMuon && elements[iTrack].trackRef()->ptError() > ptError_ ) {
1213 
1214  double deficit = trackMomentum;
1215  double resol = neutralHadronEnergyResolution(trackMomentum,
1216  elements[iTrack].trackRef()->eta());
1217  resol *= trackMomentum;
1218 
1219  if ( !ecalElems.empty() ) {
1220  unsigned thisEcal = ecalElems.begin()->second;
1221  reco::PFClusterRef clusterRef = elements[thisEcal].clusterRef();
1222  bool useCluster = true;
1223  if (hasDeadHcal) {
1224  std::multimap<double, unsigned> sortedTracks;
1225  block.associatedElements( thisEcal, linkData,
1226  sortedTracks,
1229  useCluster = (sortedTracks.begin()->second == iTrack);
1230  }
1231  if (useCluster) {
1232  deficit -= clusterRef->energy();
1233  resol = neutralHadronEnergyResolution(trackMomentum,
1234  clusterRef->positionREP().Eta());
1235  resol *= trackMomentum;
1236  }
1237  }
1238 
1239  bool isPrimary = isFromSecInt(elements[iTrack], "primary");
1240 
1241  if ( deficit > nSigmaTRACK_*resol && !isPrimary && !goodTrackDeadHcal) {
1242  rejectFake = true;
1243  active[iTrack] = false;
1244  if ( debug_ )
1245  std::cout << elements[iTrack] << std::endl
1246  << " deficit " << deficit << " > " << nSigmaTRACK_ << " x " << resol
1247  << " track pt " << trackRef->pt() << " +- " << trackRef->ptError()
1248  << " layers valid " << trackRef->hitPattern().trackerLayersWithMeasurement()
1249  << ", lost " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::TRACK_HITS)
1250  << ", lost outer " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_OUTER_HITS)
1251  << ", lost inner " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_INNER_HITS)
1252  << "(valid fraction " << trackRef->validFraction() <<")"
1253  << " chi2/ndf " << trackRef->normalizedChi2()
1254  << " |dxy| " << std::abs(trackRef->dxy(primaryVertex_.position())) << " +- " << trackRef->dxyError()
1255  << " |dz| " << std::abs(trackRef->dz(primaryVertex_.position())) << " +- " << trackRef->dzError()
1256  << "is probably a fake (1) --> lock the track"
1257  << std::endl;
1258  }
1259  }
1260 
1261  if ( rejectFake ) continue;
1262 
1263  // Create a track candidate
1264  // unsigned tmpi = reconstructTrack( elements[iTrack] );
1265  //active[iTrack] = false;
1266  std::vector<unsigned> tmpi;
1267  std::vector<unsigned> kTrack;
1268 
1269  // Some cleaning : secondary tracks without calo's and large momentum must be fake
1270  double Dpt = trackRef->ptError();
1271 
1272  if ( rejectTracks_Step45_ && ecalElems.empty() &&
1273  trackMomentum > 30. && Dpt > 0.5 &&
1274  ( PFTrackAlgoTools::step45(trackRef->algo())
1275  && !goodTrackDeadHcal) ) {
1276 
1277  double dptRel = Dpt/trackRef->pt()*100;
1278  bool isPrimaryOrSecondary = isFromSecInt(elements[iTrack], "all");
1279 
1280  if ( isPrimaryOrSecondary && dptRel < dptRel_DispVtx_) continue;
1281  unsigned nHits = elements[iTrack].trackRef()->hitPattern().trackerLayersWithMeasurement();
1282  unsigned int NLostHit = trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::TRACK_HITS);
1283 
1284  if ( debug_ )
1285  std::cout << "A track (algo = " << trackRef->algo() << ") with momentum " << trackMomentum
1286  << " / " << elements[iTrack].trackRef()->pt() << " +/- " << Dpt
1287  << " / " << elements[iTrack].trackRef()->eta()
1288  << " without any link to ECAL/HCAL and with " << nHits << " (" << NLostHit
1289  << ") hits (lost hits) has been cleaned" << std::endl;
1290  active[iTrack] = false;
1291  continue;
1292  }
1293 
1294 
1295  tmpi.push_back(reconstructTrack( elements[iTrack]));
1296 
1297  kTrack.push_back(iTrack);
1298  active[iTrack] = false;
1299 
1300  // No ECAL cluster either ... continue...
1301  if ( ecalElems.empty() ) {
1302  (*pfCandidates_)[tmpi[0]].setEcalEnergy( 0., 0. );
1303  (*pfCandidates_)[tmpi[0]].setHcalEnergy( 0., 0. );
1304  (*pfCandidates_)[tmpi[0]].setHoEnergy( 0., 0. );
1305  (*pfCandidates_)[tmpi[0]].setPs1Energy( 0 );
1306  (*pfCandidates_)[tmpi[0]].setPs2Energy( 0 );
1307  (*pfCandidates_)[tmpi[0]].addElementInBlock( blockref, kTrack[0] );
1308  continue;
1309  }
1310 
1311  // Look for closest ECAL cluster
1312  unsigned thisEcal = ecalElems.begin()->second;
1313  reco::PFClusterRef clusterRef = elements[thisEcal].clusterRef();
1314  if ( debug_ ) std::cout << " is associated to " << elements[thisEcal] << std::endl;
1315 
1316 
1317  // Set ECAL energy for muons
1318  if ( thisIsAMuon ) {
1319  (*pfCandidates_)[tmpi[0]].setEcalEnergy( clusterRef->energy(),
1320  std::min(clusterRef->energy(), muonECAL_[0]) );
1321  (*pfCandidates_)[tmpi[0]].setHcalEnergy( 0., 0. );
1322  (*pfCandidates_)[tmpi[0]].setHoEnergy( 0., 0. );
1323  (*pfCandidates_)[tmpi[0]].setPs1Energy( 0 );
1324  (*pfCandidates_)[tmpi[0]].setPs2Energy( 0 );
1325  (*pfCandidates_)[tmpi[0]].addElementInBlock( blockref, kTrack[0] );
1326  }
1327 
1328  double slopeEcal = 1.;
1329  bool connectedToEcal = false;
1330  unsigned iEcal = 99999;
1331  double calibEcal = 0.;
1332  double calibHcal = 0.;
1333  double totalEcal = thisIsAMuon ? -muonECAL_[0] : 0.;
1334 
1335  // Consider charged particles closest to the same ECAL cluster
1336  std::multimap<double, unsigned> sortedTracks;
1337  block.associatedElements( thisEcal, linkData,
1338  sortedTracks,
1341  if (debug_) cout << "the closest ECAL cluster, id " << thisEcal << ", has " << sortedTracks.size() << " associated tracks, now processing them. " << endl;
1342 
1343  if (hasDeadHcal && !sortedTracks.empty()) {
1344  // GP: only allow the ecal cluster closest to this track to be considered
1345  if (debug_) cout << " the closest track to ECAL " << thisEcal << " is " << sortedTracks.begin()->second << " (distance " << sortedTracks.begin()->first << ")" << endl;
1346  if (sortedTracks.begin()->second != iTrack) {
1347  if (debug_) cout << " the closest track to ECAL " << thisEcal << " is " << sortedTracks.begin()->second << " which is not the one being processed. Will skip ECAL linking for this track" << endl;
1348  (*pfCandidates_)[tmpi[0]].setEcalEnergy( 0., 0. );
1349  (*pfCandidates_)[tmpi[0]].setHcalEnergy( 0., 0. );
1350  (*pfCandidates_)[tmpi[0]].setHoEnergy( 0., 0. );
1351  (*pfCandidates_)[tmpi[0]].setPs1Energy( 0 );
1352  (*pfCandidates_)[tmpi[0]].setPs2Energy( 0 );
1353  (*pfCandidates_)[tmpi[0]].addElementInBlock( blockref, kTrack[0] );
1354  continue;
1355  } else {
1356  if (debug_) cout << " the closest track to ECAL " << thisEcal << " is " << sortedTracks.begin()->second << " which is the one being processed. Will skip ECAL linking for all other track" << endl;
1357  sortedTracks.clear();
1358  }
1359  }
1360 
1361  for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
1362  unsigned jTrack = ie->second;
1363 
1364  // Don't consider already used tracks
1365  if ( !active[jTrack] ) continue;
1366 
1367  // The loop is on the other tracks !
1368  if ( jTrack == iTrack ) continue;
1369 
1370  // Check if the ECAL cluster closest to this track is
1371  // indeed the current ECAL cluster. Only tracks not
1372  // linked to an HCAL cluster are considered here
1373  // (GP: this is because if there's a jTrack linked
1374  // to the same Ecal cluster and that also has an Hcal link
1375  // we would have also linked iTrack to that Hcal above)
1376  std::multimap<double, unsigned> sortedECAL;
1377  block.associatedElements( jTrack, linkData,
1378  sortedECAL,
1381  if ( sortedECAL.begin()->second != thisEcal ) continue;
1382 
1383  // Check if this track is a muon
1384  bool thatIsAMuon = PFMuonAlgo::isMuon(elements[jTrack]);
1385  if (debug_) {
1386  cout << " found track " << jTrack << (thatIsAMuon ? " (muon) " : " (non-muon)") << ", with distance = " << sortedECAL.begin()->first << std::endl;
1387  }
1388 
1389 
1390  // Check if this track is not a fake
1391  bool rejectFake = false;
1392  reco::TrackRef trackRef = elements[jTrack].trackRef();
1393  if ( !thatIsAMuon && trackRef->ptError() > ptError_) {
1394  // GP: FIXME this selection should be adapted depending on hasDeadHcal
1395  // but we don't know if jTrack is linked to a dead Hcal or not
1396  double deficit = trackMomentum + trackRef->p() - clusterRef->energy();
1397  double resol = nSigmaTRACK_*neutralHadronEnergyResolution(trackMomentum+trackRef->p(),
1398  clusterRef->positionREP().Eta());
1399  resol *= (trackMomentum+trackRef->p());
1400  if ( deficit > nSigmaTRACK_*resol && !goodTrackDeadHcal) {
1401  rejectFake = true;
1402  kTrack.push_back(jTrack);
1403  active[jTrack] = false;
1404  if ( debug_ )
1405  std::cout << elements[jTrack] << std::endl
1406  << "is probably a fake (2) --> lock the track"
1407  << "(trackMomentum = " << trackMomentum << ", clusterEnergy = " << clusterRef->energy() <<
1408  ", deficit = " << deficit << " > " << nSigmaTRACK_ << " x " << resol <<
1409  " assuming neutralHadronEnergyResolution " << neutralHadronEnergyResolution(trackMomentum+trackRef->p(), clusterRef->positionREP().Eta()) << ") "
1410  << std::endl;
1411  }
1412  }
1413  if ( rejectFake ) continue;
1414 
1415 
1416  // Otherwise, add this track momentum to the total track momentum
1417  /* */
1418  // reco::TrackRef trackRef = elements[jTrack].trackRef();
1419  if ( !thatIsAMuon ) {
1420  if ( debug_ )
1421  std::cout << "Track momentum increased from " << trackMomentum << " GeV ";
1422  trackMomentum += trackRef->p();
1423  if ( debug_ ) {
1424  std::cout << "to " << trackMomentum << " GeV." << std::endl;
1425  std::cout << "with " << elements[jTrack] << std::endl;
1426  }
1427  } else {
1428  totalEcal -= muonECAL_[0];
1429  totalEcal = std::max(totalEcal, 0.);
1430  }
1431 
1432  // And create a charged particle candidate !
1433 
1434  tmpi.push_back(reconstructTrack( elements[jTrack] ));
1435 
1436 
1437  kTrack.push_back(jTrack);
1438  active[jTrack] = false;
1439 
1440  if ( thatIsAMuon ) {
1441  (*pfCandidates_)[tmpi.back()].setEcalEnergy(clusterRef->energy(),
1442  std::min(clusterRef->energy(),muonECAL_[0]));
1443  (*pfCandidates_)[tmpi.back()].setHcalEnergy( 0., 0. );
1444  (*pfCandidates_)[tmpi.back()].setHoEnergy( 0., 0. );
1445  (*pfCandidates_)[tmpi.back()].setPs1Energy( 0 );
1446  (*pfCandidates_)[tmpi.back()].setPs2Energy( 0 );
1447  (*pfCandidates_)[tmpi.back()].addElementInBlock( blockref, kTrack.back() );
1448  }
1449  }
1450 
1451 
1452  if ( debug_ ) std::cout << "Loop over all associated ECAL clusters" << std::endl;
1453  // Loop over all ECAL linked clusters ordered by increasing distance.
1454  for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
1455 
1456  unsigned index = ie->second;
1457  PFBlockElement::Type type = elements[index].type();
1458  assert( type == PFBlockElement::ECAL );
1459  if ( debug_ ) std::cout << elements[index] << std::endl;
1460 
1461  // Just skip clusters already taken
1462  if ( debug_ && ! active[index] ) std::cout << "is not active - ignore " << std::endl;
1463  if ( ! active[index] ) continue;
1464 
1465  // Just skip this cluster if it's closer to another track
1466  /* */
1467  block.associatedElements( index, linkData,
1468  sortedTracks,
1471  bool skip = true;
1472  for (unsigned ic=0; ic<kTrack.size();++ic) {
1473  if ( sortedTracks.begin()->second == kTrack[ic] ) {
1474  skip = false;
1475  break;
1476  }
1477  }
1478  if ( debug_ && skip ) std::cout << "is closer to another track - ignore " << std::endl;
1479  if ( skip ) continue;
1480  /* */
1481 
1482  // The corresponding PFCluster and energy
1483  reco::PFClusterRef clusterRef = elements[index].clusterRef();
1484  assert( !clusterRef.isNull() );
1485 
1486  if ( debug_ ) {
1487  double dist = ie->first;
1488  std::cout <<"Ecal cluster with raw energy = " << clusterRef->energy()
1489  <<" linked with distance = " << dist << std::endl;
1490  }
1491  /*
1492  double dist = ie->first;
1493  if ( !connectedToEcal && dist > 0.1 ) {
1494  std::cout << "Warning - first ECAL cluster at a distance of " << dist << "from the closest track!" << std::endl;
1495  cout<<"\telement "<<elements[index]<<" linked with distance = "<< dist <<endl;
1496  cout<<"\telement "<<elements[iTrack]<<" linked with distance = "<< dist <<endl;
1497  }
1498  */
1499 
1500  // Check the presence of preshower clusters in the vicinity
1501  // Preshower cluster closer to another ECAL cluster are ignored.
1502  //JOSH: This should use the association map already produced by the cluster corrector for consistency,
1503  //but should be ok for now
1504  vector<double> ps1Ene(1,static_cast<double>(0.));
1505  associatePSClusters(index, reco::PFBlockElement::PS1, block, elements, linkData, active, ps1Ene);
1506  vector<double> ps2Ene(1,static_cast<double>(0.));
1507  associatePSClusters(index, reco::PFBlockElement::PS2, block, elements, linkData, active, ps2Ene);
1508 
1509  double ecalEnergy = clusterRef->correctedEnergy();
1510  if ( debug_ )
1511  std::cout << "Corrected ECAL(+PS) energy = " << ecalEnergy << std::endl;
1512 
1513  // Since the electrons were found beforehand, this track must be a hadron. Calibrate
1514  // the energy under the hadron hypothesis.
1515  totalEcal += ecalEnergy;
1516  double previousCalibEcal = calibEcal;
1517  double previousSlopeEcal = slopeEcal;
1518  calibEcal = std::max(totalEcal,0.);
1519  calibHcal = 0.;
1520  calibration_->energyEmHad(trackMomentum,calibEcal,calibHcal,
1521  clusterRef->positionREP().Eta(),
1522  clusterRef->positionREP().Phi());
1523  if ( totalEcal > 0.) slopeEcal = calibEcal/totalEcal;
1524 
1525  if ( debug_ )
1526  std::cout << "The total calibrated energy so far amounts to = " << calibEcal << " (slope = " << slopeEcal << ")" << std::endl;
1527 
1528 
1529  // Stop the loop when adding more ECAL clusters ruins the compatibility
1530  if ( connectedToEcal && calibEcal - trackMomentum >= 0. ) {
1531  // if ( connectedToEcal && calibEcal - trackMomentum >=
1532  // nSigmaECAL_*neutralHadronEnergyResolution(trackMomentum,clusterRef->positionREP().Eta()) ) {
1533  calibEcal = previousCalibEcal;
1534  slopeEcal = previousSlopeEcal;
1535  totalEcal = calibEcal/slopeEcal;
1536 
1537  // Turn this last cluster in a photon
1538  // (The PS clusters are already locked in "associatePSClusters")
1539  active[index] = false;
1540 
1541  // Find the associated tracks
1542  std::multimap<double, unsigned> assTracks;
1543  block.associatedElements( index, linkData,
1544  assTracks,
1547 
1548 
1549  unsigned tmpe = reconstructCluster( *clusterRef, ecalEnergy );
1550  (*pfCandidates_)[tmpe].setEcalEnergy( clusterRef->energy(), ecalEnergy );
1551  (*pfCandidates_)[tmpe].setHcalEnergy( 0., 0. );
1552  (*pfCandidates_)[tmpe].setHoEnergy( 0., 0. );
1553  (*pfCandidates_)[tmpe].setPs1Energy( ps1Ene[0] );
1554  (*pfCandidates_)[tmpe].setPs2Energy( ps2Ene[0] );
1555  (*pfCandidates_)[tmpe].addElementInBlock( blockref, index );
1556  // Check that there is at least one track
1557  if(!assTracks.empty()) {
1558  (*pfCandidates_)[tmpe].addElementInBlock( blockref, assTracks.begin()->second );
1559 
1560  // Assign the position of the track at the ECAL entrance
1561  const ::math::XYZPointF& chargedPosition =
1562  dynamic_cast<const reco::PFBlockElementTrack*>(&elements[assTracks.begin()->second])->positionAtECALEntrance();
1563  (*pfCandidates_)[tmpe].setPositionAtECALEntrance(chargedPosition);
1564  }
1565  break;
1566  }
1567 
1568  // Lock used clusters.
1569  connectedToEcal = true;
1570  iEcal = index;
1571  active[index] = false;
1572  for (unsigned ic=0; ic<tmpi.size();++ic)
1573  (*pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, iEcal );
1574 
1575 
1576  } // Loop ecal elements
1577 
1578  bool bNeutralProduced = false;
1579 
1580  // Create a photon if the ecal energy is too large
1581  if( connectedToEcal ) {
1582  reco::PFClusterRef pivotalRef = elements[iEcal].clusterRef();
1583 
1584  double neutralEnergy = calibEcal - trackMomentum;
1585 
1586  /*
1587  // Check if there are other tracks linked to that ECAL
1588  for(IE ie = sortedTracks.begin(); ie != sortedTracks.end() && neutralEnergy > 0; ++ie ) {
1589  unsigned jTrack = ie->second;
1590 
1591  // The loop is on the other tracks !
1592  if ( jTrack == iTrack ) continue;
1593 
1594  // Check if the ECAL closest to this track is the current ECAL
1595  // Otherwise ignore this track in the neutral energy determination
1596  std::multimap<double, unsigned> sortedECAL;
1597  block.associatedElements( jTrack, linkData,
1598  sortedECAL,
1599  reco::PFBlockElement::ECAL,
1600  reco::PFBlock::LINKTEST_ALL );
1601  if ( sortedECAL.begin()->second != iEcal ) continue;
1602 
1603  // Check if this track is also linked to an HCAL
1604  // (in which case it goes to the next loop and is ignored here)
1605  std::multimap<double, unsigned> sortedHCAL;
1606  block.associatedElements( jTrack, linkData,
1607  sortedHCAL,
1608  reco::PFBlockElement::HCAL,
1609  reco::PFBlock::LINKTEST_ALL );
1610  if ( sortedHCAL.size() ) continue;
1611 
1612  // Otherwise, subtract this track momentum from the ECAL energy
1613  reco::TrackRef trackRef = elements[jTrack].trackRef();
1614  neutralEnergy -= trackRef->p();
1615 
1616  } // End other tracks
1617  */
1618 
1619  // Add a photon is the energy excess is large enough
1620  double resol = neutralHadronEnergyResolution(trackMomentum,pivotalRef->positionREP().Eta());
1621  resol *= trackMomentum;
1622  if ( neutralEnergy > std::max(0.5,nSigmaECAL_*resol) ) {
1623  neutralEnergy /= slopeEcal;
1624  unsigned tmpj = reconstructCluster( *pivotalRef, neutralEnergy );
1625  (*pfCandidates_)[tmpj].setEcalEnergy( pivotalRef->energy(), neutralEnergy );
1626  (*pfCandidates_)[tmpj].setHcalEnergy( 0., 0. );
1627  (*pfCandidates_)[tmpj].setHoEnergy( 0., 0. );
1628  (*pfCandidates_)[tmpj].setPs1Energy( 0. );
1629  (*pfCandidates_)[tmpj].setPs2Energy( 0. );
1630  (*pfCandidates_)[tmpj].addElementInBlock(blockref, iEcal);
1631  bNeutralProduced = true;
1632  for (unsigned ic=0; ic<kTrack.size();++ic)
1633  (*pfCandidates_)[tmpj].addElementInBlock( blockref, kTrack[ic] );
1634  } // End neutral energy
1635 
1636  // Set elements in blocks and ECAL energies to all tracks
1637  for (unsigned ic=0; ic<tmpi.size();++ic) {
1638 
1639  // Skip muons
1640  if ( (*pfCandidates_)[tmpi[ic]].particleId() == reco::PFCandidate::mu ) continue;
1641 
1642  double fraction = trackMomentum > 0 ? (*pfCandidates_)[tmpi[ic]].trackRef()->p()/trackMomentum : 0;
1643  double ecalCal = bNeutralProduced ?
1644  (calibEcal-neutralEnergy*slopeEcal)*fraction : calibEcal*fraction;
1645  double ecalRaw = totalEcal*fraction;
1646 
1647  if (debug_) cout << "The fraction after photon supression is " << fraction << " calibrated ecal = " << ecalCal << endl;
1648 
1649  (*pfCandidates_)[tmpi[ic]].setEcalEnergy( ecalRaw, ecalCal );
1650  (*pfCandidates_)[tmpi[ic]].setHcalEnergy( 0., 0. );
1651  (*pfCandidates_)[tmpi[ic]].setHoEnergy( 0., 0. );
1652  (*pfCandidates_)[tmpi[ic]].setPs1Energy( 0 );
1653  (*pfCandidates_)[tmpi[ic]].setPs2Energy( 0 );
1654  (*pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, kTrack[ic] );
1655  }
1656 
1657  } // End connected ECAL
1658 
1659  // Fill the element_in_block for tracks that are eventually linked to no ECAL clusters at all.
1660  for (unsigned ic=0; ic<tmpi.size();++ic) {
1661  const PFCandidate& pfc = (*pfCandidates_)[tmpi[ic]];
1662  const PFCandidate::ElementsInBlocks& eleInBlocks = pfc.elementsInBlocks();
1663  if ( eleInBlocks.empty() ) {
1664  if ( debug_ )std::cout << "Single track / Fill element in block! " << std::endl;
1665  (*pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, kTrack[ic] );
1666  }
1667  }
1668 
1669  } // end if( hcalElems.empty() )
1670 
1671 
1672  // In case several HCAL elements are linked to this track,
1673  // unlinking all of them except the closest.
1674  for(IE ie = hcalElems.begin(); ie != hcalElems.end(); ++ie ) {
1675 
1676  unsigned index = ie->second;
1677 
1678  PFBlockElement::Type type = elements[index].type();
1679 
1680  if(debug_) {
1681  double dist = block.dist(iTrack,index,linkData,reco::PFBlock::LINKTEST_ALL);
1682  cout<<"\telement "<<elements[index]<<" linked with distance "<< dist <<endl;
1683  }
1684 
1685  assert( type == PFBlockElement::HCAL );
1686 
1687  // all hcal clusters except the closest
1688  // will be unlinked from the track
1689  if( !hcalFound ) { // closest hcal
1690  if(debug_)
1691  cout<<"\t\tclosest hcal cluster, doing nothing"<<endl;
1692 
1693  hcalFound = true;
1694 
1695  // active[index] = false;
1696  // hcalUsed.push_back( index );
1697  }
1698  else { // other associated hcal
1699  // unlink from the track
1700  if(debug_)
1701  cout<<"\t\tsecondary hcal cluster. unlinking"<<endl;
1702  block.setLink( iTrack, index, -1., linkData,
1703  PFBlock::LINKTEST_RECHIT );
1704  }
1705  } //loop hcal elements
1706  } // end of loop 1 on elements iEle of any type
1707 
1708 
1709 
1710  // deal with HF.
1711  if( !(hfEmIs.empty() && hfHadIs.empty() ) ) {
1712  // there is at least one HF element in this block.
1713  // so all elements must be HF.
1714  assert( hfEmIs.size() + hfHadIs.size() == elements.size() );
1715 
1716  if( elements.size() == 1 ) {
1717  //Auguste: HAD-only calibration here
1718  reco::PFClusterRef clusterRef = elements[0].clusterRef();
1719  double energyHF = 0.;
1720  double uncalibratedenergyHF = 0.;
1721  unsigned tmpi = 0;
1722  switch( clusterRef->layer() ) {
1723  case PFLayer::HF_EM:
1724  // do EM-only calibration here
1725  energyHF = clusterRef->energy();
1726  uncalibratedenergyHF = energyHF;
1727  if(thepfEnergyCalibrationHF_->getcalibHF_use()==true){
1728  energyHF = thepfEnergyCalibrationHF_->energyEm(uncalibratedenergyHF,
1729  clusterRef->positionREP().Eta(),
1730  clusterRef->positionREP().Phi());
1731  }
1732  tmpi = reconstructCluster( *clusterRef, energyHF );
1733  (*pfCandidates_)[tmpi].setEcalEnergy( uncalibratedenergyHF, energyHF );
1734  (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0.);
1735  (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1736  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1737  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1738  (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfEmIs[0] );
1739  //std::cout << "HF EM alone ! " << energyHF << std::endl;
1740  break;
1741  case PFLayer::HF_HAD:
1742  // do HAD-only calibration here
1743  energyHF = clusterRef->energy();
1744  uncalibratedenergyHF = energyHF;
1745  if(thepfEnergyCalibrationHF_->getcalibHF_use()==true){
1746  energyHF = thepfEnergyCalibrationHF_->energyHad(uncalibratedenergyHF,
1747  clusterRef->positionREP().Eta(),
1748  clusterRef->positionREP().Phi());
1749  }
1750  tmpi = reconstructCluster( *clusterRef, energyHF );
1751  (*pfCandidates_)[tmpi].setHcalEnergy( uncalibratedenergyHF, energyHF );
1752  (*pfCandidates_)[tmpi].setEcalEnergy( 0., 0.);
1753  (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1754  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1755  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1756  (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfHadIs[0] );
1757  //std::cout << "HF Had alone ! " << energyHF << std::endl;
1758  break;
1759  default:
1760  assert(0);
1761  }
1762  }
1763  else if( elements.size() == 2 ) {
1764  //Auguste: EM + HAD calibration here
1765  reco::PFClusterRef c0 = elements[0].clusterRef();
1766  reco::PFClusterRef c1 = elements[1].clusterRef();
1767  // 2 HF elements. Must be in each layer.
1768  reco::PFClusterRef cem = ( c0->layer() == PFLayer::HF_EM ? c0 : c1 );
1769  reco::PFClusterRef chad = ( c1->layer() == PFLayer::HF_HAD ? c1 : c0 );
1770 
1771  if( cem->layer() != PFLayer::HF_EM || chad->layer() != PFLayer::HF_HAD ) {
1772  cerr<<"Error: 2 elements, but not 1 HFEM and 1 HFHAD"<<endl;
1773  cerr<<block<<endl;
1774  assert(0);
1775 // assert( c1->layer()== PFLayer::HF_EM &&
1776 // c0->layer()== PFLayer::HF_HAD );
1777  }
1778  // do EM+HAD calibration here
1779  double energyHfEm = cem->energy();
1780  double energyHfHad = chad->energy();
1781  double uncalibratedenergyHFEm = energyHfEm;
1782  double uncalibratedenergyHFHad = energyHfHad;
1783  if(thepfEnergyCalibrationHF_->getcalibHF_use()==true){
1784 
1785  energyHfEm = thepfEnergyCalibrationHF_->energyEmHad(uncalibratedenergyHFEm,
1786  0.0,
1787  c0->positionREP().Eta(),
1788  c0->positionREP().Phi());
1789  energyHfHad = thepfEnergyCalibrationHF_->energyEmHad(0.0,
1790  uncalibratedenergyHFHad,
1791  c1->positionREP().Eta(),
1792  c1->positionREP().Phi());
1793  }
1794  unsigned tmpi = reconstructCluster( *chad, energyHfEm+energyHfHad );
1795  (*pfCandidates_)[tmpi].setEcalEnergy( uncalibratedenergyHFEm, energyHfEm );
1796  (*pfCandidates_)[tmpi].setHcalEnergy( uncalibratedenergyHFHad, energyHfHad);
1797  (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1798  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1799  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1800  (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfEmIs[0] );
1801  (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfHadIs[0] );
1802  //std::cout << "HF EM+HAD found ! " << energyHfEm << " " << energyHfHad << std::endl;
1803  }
1804  else {
1805  // 1 HF element in the block,
1806  // but number of elements not equal to 1 or 2
1807  cerr<<"Warning: HF, but n elem different from 1 or 2"<<endl;
1808  cerr<<block<<endl;
1809 // assert(0);
1810 // cerr<<"not ready for navigation in the HF!"<<endl;
1811  }
1812  }
1813 
1814 
1815 
1816  if(debug_) {
1817  cout<<endl;
1818  cout<<endl<<"--------------- loop hcal ---------------------"<<endl;
1819  }
1820 
1821  // track information:
1822  // trackRef
1823  // ecal energy
1824  // hcal energy
1825  // rescale
1826 
1827  for(unsigned i=0; i<hcalIs.size(); i++) {
1828 
1829  unsigned iHcal= hcalIs[i];
1830  PFBlockElement::Type type = elements[iHcal].type();
1831 
1832  assert( type == PFBlockElement::HCAL );
1833 
1834  if(debug_) cout<<endl<<elements[iHcal]<<endl;
1835 
1836  // vector<unsigned> elementIndices;
1837  // elementIndices.push_back(iHcal);
1838 
1839  // associated tracks
1840  std::multimap<double, unsigned> sortedTracks;
1841  block.associatedElements( iHcal, linkData,
1842  sortedTracks,
1845 
1846  std::multimap< unsigned, std::pair<double, unsigned> > associatedEcals;
1847 
1848  std::map< unsigned, std::pair<double, double> > associatedPSs;
1849 
1850  std::multimap<double, std::pair<unsigned,bool> > associatedTracks;
1851 
1852  // A temporary maps for ECAL satellite clusters
1853  std::multimap<double,std::pair<unsigned,::math::XYZVector> > ecalSatellites;
1854  std::pair<unsigned,::math::XYZVector> fakeSatellite(iHcal,::math::XYZVector(0.,0.,0.));
1855  ecalSatellites.emplace(-1., fakeSatellite);
1856 
1857  std::multimap< unsigned, std::pair<double, unsigned> > associatedHOs;
1858 
1859  PFClusterRef hclusterref = elements[iHcal].clusterRef();
1860  assert(!hclusterref.isNull() );
1861 
1862 
1863  //if there is no track attached to that HCAL, then do not
1864  //reconstruct an HCAL alone, check if it can be recovered
1865  //first
1866 
1867  // if no associated tracks, create a neutral hadron
1868  //if(sortedTracks.empty() ) {
1869 
1870  if( sortedTracks.empty() ) {
1871  if(debug_)
1872  cout<<"\tno associated tracks, keep for later"<<endl;
1873  continue;
1874  }
1875 
1876  // Lock the HCAL cluster
1877  active[iHcal] = false;
1878 
1879 
1880  // in the following, tracks are associated to this hcal cluster.
1881  // will look for an excess of energy in the calorimeters w/r to
1882  // the charged energy, and turn this excess into a neutral hadron or
1883  // a photon.
1884 
1885  if(debug_) cout<<"\t"<<sortedTracks.size()<<" associated tracks:"<<endl;
1886 
1887  double totalChargedMomentum = 0;
1888  double sumpError2 = 0.;
1889  double totalHO = 0.;
1890  double totalEcal = 0.;
1891  double totalHcal = hclusterref->energy();
1892  vector<double> hcalP;
1893  vector<double> hcalDP;
1894  vector<unsigned> tkIs;
1895  double maxDPovP = -9999.;
1896 
1897  //Keep track of how much energy is assigned to calorimeter-vs-track energy/momentum excess
1898  vector< unsigned > chargedHadronsIndices;
1899  vector< unsigned > chargedHadronsInBlock;
1900  double mergedNeutralHadronEnergy = 0;
1901  double mergedPhotonEnergy = 0;
1902  double muonHCALEnergy = 0.;
1903  double muonECALEnergy = 0.;
1904  double muonHCALError = 0.;
1905  double muonECALError = 0.;
1906  unsigned nMuons = 0;
1907 
1908 
1909  ::math::XYZVector photonAtECAL(0.,0.,0.);
1910  std::vector<std::pair<unsigned,::math::XYZVector> > ecalClusters;
1911  double sumEcalClusters=0;
1912  ::math::XYZVector hadronDirection(hclusterref->position().X(),
1913  hclusterref->position().Y(),
1914  hclusterref->position().Z());
1915  hadronDirection = hadronDirection.Unit();
1916  ::math::XYZVector hadronAtECAL = totalHcal * hadronDirection;
1917 
1918  // Loop over all tracks associated to this HCAL cluster
1919  for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
1920 
1921  unsigned iTrack = ie->second;
1922 
1923  // Check the track has not already been used (e.g., in electrons, conversions...)
1924  if ( !active[iTrack] ) continue;
1925  // Sanity check 1
1926  PFBlockElement::Type type = elements[iTrack].type();
1927  assert( type == reco::PFBlockElement::TRACK );
1928  // Sanity check 2
1929  reco::TrackRef trackRef = elements[iTrack].trackRef();
1930  assert( !trackRef.isNull() );
1931 
1932  // The direction at ECAL entrance
1933  const ::math::XYZPointF& chargedPosition =
1934  dynamic_cast<const reco::PFBlockElementTrack*>(&elements[iTrack])->positionAtECALEntrance();
1935  ::math::XYZVector chargedDirection(chargedPosition.X(),chargedPosition.Y(),chargedPosition.Z());
1936  chargedDirection = chargedDirection.Unit();
1937 
1938  // look for ECAL elements associated to iTrack (associated to iHcal)
1939  std::multimap<double, unsigned> sortedEcals;
1940  block.associatedElements( iTrack, linkData,
1941  sortedEcals,
1944 
1945  if(debug_) cout<<"\t\t\tnumber of Ecal elements linked to this track: "
1946  <<sortedEcals.size()<<endl;
1947 
1948  // look for HO elements associated to iTrack (associated to iHcal)
1949  std::multimap<double, unsigned> sortedHOs;
1950  if (useHO_) {
1951  block.associatedElements( iTrack, linkData,
1952  sortedHOs,
1955 
1956  }
1957  if(debug_)
1958  cout<<"PFAlgo : number of HO elements linked to this track: "
1959  <<sortedHOs.size()<<endl;
1960 
1961  // Create a PF Candidate right away if the track is a tight muon
1962  reco::MuonRef muonRef = elements[iTrack].muonRef();
1963 
1964 
1965  bool thisIsAMuon = PFMuonAlgo::isMuon(elements[iTrack]);
1966  bool thisIsAnIsolatedMuon = PFMuonAlgo::isIsolatedMuon(elements[iTrack]);
1967  bool thisIsALooseMuon = false;
1968 
1969 
1970  if(!thisIsAMuon ) {
1971  thisIsALooseMuon = PFMuonAlgo::isLooseMuon(elements[iTrack]);
1972  }
1973 
1974 
1975  if ( thisIsAMuon ) {
1976  if ( debug_ ) {
1977  std::cout << "\t\tThis track is identified as a muon - remove it from the stack" << std::endl;
1978  std::cout << "\t\t" << elements[iTrack] << std::endl;
1979  }
1980 
1981  // Create a muon.
1982 
1983  unsigned tmpi = reconstructTrack( elements[iTrack] );
1984 
1985 
1986  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
1987  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
1988  double muonHcal = std::min(muonHCAL_[0]+muonHCAL_[1],totalHcal);
1989 
1990  // if muon is isolated and muon momentum exceeds the calo energy, absorb the calo energy
1991  // rationale : there has been a EM showering by the muon in the calorimeter - or the coil -
1992  // and we don't want to double count the energy
1993  bool letMuonEatCaloEnergy = false;
1994 
1995  if(thisIsAnIsolatedMuon){
1996  // The factor 1.3 is the e/pi factor in HCAL...
1997  double totalCaloEnergy = totalHcal / 1.30;
1998  unsigned iEcal = 0;
1999  if( !sortedEcals.empty() ) {
2000  iEcal = sortedEcals.begin()->second;
2001  PFClusterRef eclusterref = elements[iEcal].clusterRef();
2002  totalCaloEnergy += eclusterref->energy();
2003  }
2004 
2005  if (useHO_) {
2006  // The factor 1.3 is assumed to be the e/pi factor in HO, too.
2007  unsigned iHO = 0;
2008  if( !sortedHOs.empty() ) {
2009  iHO = sortedHOs.begin()->second;
2010  PFClusterRef eclusterref = elements[iHO].clusterRef();
2011  totalCaloEnergy += eclusterref->energy() / 1.30;
2012  }
2013  }
2014 
2015  // std::cout << "muon p / total calo = " << muonRef->p() << " " << (pfCandidates_->back()).p() << " " << totalCaloEnergy << std::endl;
2016  //if(muonRef->p() > totalCaloEnergy ) letMuonEatCaloEnergy = true;
2017  if( (pfCandidates_->back()).p() > totalCaloEnergy ) letMuonEatCaloEnergy = true;
2018  }
2019 
2020  if(letMuonEatCaloEnergy) muonHcal = totalHcal;
2021  double muonEcal =0.;
2022  unsigned iEcal = 0;
2023  if( !sortedEcals.empty() ) {
2024  iEcal = sortedEcals.begin()->second;
2025  PFClusterRef eclusterref = elements[iEcal].clusterRef();
2026  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
2027  muonEcal = std::min(muonECAL_[0]+muonECAL_[1],eclusterref->energy());
2028  if(letMuonEatCaloEnergy) muonEcal = eclusterref->energy();
2029  // If the muon expected energy accounts for the whole ecal cluster energy, lock the ecal cluster
2030  if ( eclusterref->energy() - muonEcal < 0.2 ) active[iEcal] = false;
2031  (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(), muonEcal);
2032  }
2033  unsigned iHO = 0;
2034  double muonHO =0.;
2035  if (useHO_) {
2036  if( !sortedHOs.empty() ) {
2037  iHO = sortedHOs.begin()->second;
2038  PFClusterRef hoclusterref = elements[iHO].clusterRef();
2039  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
2040  muonHO = std::min(muonHO_[0]+muonHO_[1],hoclusterref->energy());
2041  if(letMuonEatCaloEnergy) muonHO = hoclusterref->energy();
2042  // If the muon expected energy accounts for the whole HO cluster energy, lock the HO cluster
2043  if ( hoclusterref->energy() - muonHO < 0.2 ) active[iHO] = false;
2044  (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
2045  (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(), muonHO);
2046  }
2047  } else {
2048  (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
2049  }
2050  setHcalDepthInfo((*pfCandidates_)[tmpi], *hclusterref);
2051 
2052  if(letMuonEatCaloEnergy){
2053  muonHCALEnergy += totalHcal;
2054  if (useHO_) muonHCALEnergy +=muonHO;
2055  muonHCALError += 0.;
2056  muonECALEnergy += muonEcal;
2057  muonECALError += 0.;
2058  photonAtECAL -= muonEcal*chargedDirection;
2059  hadronAtECAL -= totalHcal*chargedDirection;
2060  if ( !sortedEcals.empty() ) active[iEcal] = false;
2061  active[iHcal] = false;
2062  if (useHO_ && !sortedHOs.empty() ) active[iHO] = false;
2063  }
2064  else{
2065  // Estimate of the energy deposit & resolution in the calorimeters
2066  muonHCALEnergy += muonHCAL_[0];
2067  muonHCALError += muonHCAL_[1]*muonHCAL_[1];
2068  if ( muonHO > 0. ) {
2069  muonHCALEnergy += muonHO_[0];
2070  muonHCALError += muonHO_[1]*muonHO_[1];
2071  }
2072  muonECALEnergy += muonECAL_[0];
2073  muonECALError += muonECAL_[1]*muonECAL_[1];
2074  // ... as well as the equivalent "momentum" at ECAL entrance
2075  photonAtECAL -= muonECAL_[0]*chargedDirection;
2076  hadronAtECAL -= muonHCAL_[0]*chargedDirection;
2077  }
2078 
2079  // Remove it from the stack
2080  active[iTrack] = false;
2081  // Go to next track
2082  continue;
2083  }
2084 
2085  //
2086 
2087  if(debug_) cout<<"\t\t"<<elements[iTrack]<<endl;
2088 
2089  // introduce tracking errors
2090  double trackMomentum = trackRef->p();
2091  totalChargedMomentum += trackMomentum;
2092 
2093  // If the track is not a tight muon, but still resembles a muon
2094  // keep it for later for blocks with too large a charged energy
2095  if ( thisIsALooseMuon && !thisIsAMuon ) nMuons += 1;
2096 
2097  // ... and keep anyway the pt error for possible fake rejection
2098  // ... blow up errors of 5th anf 4th iteration, to reject those
2099  // ... tracks first (in case it's needed)
2100  double Dpt = trackRef->ptError();
2101  double blowError = PFTrackAlgoTools::errorScale(trackRef->algo(),factors45_);
2102  // except if it is from an interaction
2103  bool isPrimaryOrSecondary = isFromSecInt(elements[iTrack], "all");
2104 
2105  if ( isPrimaryOrSecondary ) blowError = 1.;
2106 
2107  std::pair<unsigned,bool> tkmuon(iTrack,thisIsALooseMuon);
2108  associatedTracks.emplace(-Dpt*blowError, tkmuon);
2109 
2110  // Also keep the total track momentum error for comparison with the calo energy
2111  double Dp = trackRef->qoverpError()*trackMomentum*trackMomentum;
2112  sumpError2 += Dp*Dp;
2113 
2114  bool connectedToEcal = false; // Will become true if there is at least one ECAL cluster connected
2115  if( !sortedEcals.empty() )
2116  { // start case: at least one ecal element associated to iTrack
2117 
2118  // Loop over all connected ECAL clusters
2119  for ( IE iec=sortedEcals.begin();
2120  iec!=sortedEcals.end(); ++iec ) {
2121 
2122  unsigned iEcal = iec->second;
2123  double dist = iec->first;
2124 
2125  // Ignore ECAL cluters already used
2126  if( !active[iEcal] ) {
2127  if(debug_) cout<<"\t\tcluster locked"<<endl;
2128  continue;
2129  }
2130 
2131  // Sanity checks
2132  PFBlockElement::Type type = elements[ iEcal ].type();
2133  assert( type == PFBlockElement::ECAL );
2134  PFClusterRef eclusterref = elements[iEcal].clusterRef();
2135  assert(!eclusterref.isNull() );
2136 
2137  // Check if this ECAL is not closer to another track - ignore it in that case
2138  std::multimap<double, unsigned> sortedTracksEcal;
2139  block.associatedElements( iEcal, linkData,
2140  sortedTracksEcal,
2143  unsigned jTrack = sortedTracksEcal.begin()->second;
2144  if ( jTrack != iTrack ) continue;
2145 
2146  // double chi2Ecal = block.chi2(jTrack,iEcal,linkData,
2147  // reco::PFBlock::LINKTEST_ALL);
2148  double distEcal = block.dist(jTrack,iEcal,linkData,
2150 
2151  // totalEcal += eclusterref->energy();
2152  // float ecalEnergyUnCalibrated = eclusterref->energy();
2153  //std::cout << "Ecal Uncalibrated " << ecalEnergyUnCalibrated << std::endl;
2154 
2155  float ecalEnergyCalibrated = eclusterref->correctedEnergy();
2156  ::math::XYZVector photonDirection(eclusterref->position().X(),
2157  eclusterref->position().Y(),
2158  eclusterref->position().Z());
2159  photonDirection = photonDirection.Unit();
2160 
2161  if ( !connectedToEcal ) { // This is the closest ECAL cluster - will add its energy later
2162 
2163  if(debug_) cout<<"\t\t\tclosest: "
2164  <<elements[iEcal]<<endl;
2165 
2166  connectedToEcal = true;
2167  // PJ 1st-April-09 : To be done somewhere !!! (Had to comment it, but it is needed)
2168  // currentChargedHadron.addElementInBlock( blockref, iEcal );
2169 
2170  std::pair<unsigned,::math::XYZVector> satellite(iEcal,ecalEnergyCalibrated*photonDirection);
2171  ecalSatellites.emplace(-1., satellite);
2172 
2173  } else { // Keep satellite clusters for later
2174 
2175  std::pair<unsigned,::math::XYZVector> satellite(iEcal,ecalEnergyCalibrated*photonDirection);
2176  ecalSatellites.emplace(dist, satellite);
2177 
2178  }
2179 
2180  std::pair<double, unsigned> associatedEcal( distEcal, iEcal );
2181  associatedEcals.emplace(iTrack, associatedEcal);
2182 
2183  } // End loop ecal associated to iTrack
2184  } // end case: at least one ecal element associated to iTrack
2185 
2186  if( useHO_ && !sortedHOs.empty() )
2187  { // start case: at least one ho element associated to iTrack
2188 
2189  // Loop over all connected HO clusters
2190  for ( IE ieho=sortedHOs.begin(); ieho!=sortedHOs.end(); ++ieho ) {
2191 
2192  unsigned iHO = ieho->second;
2193  double distHO = ieho->first;
2194 
2195  // Ignore HO cluters already used
2196  if( !active[iHO] ) {
2197  if(debug_) cout<<"\t\tcluster locked"<<endl;
2198  continue;
2199  }
2200 
2201  // Sanity checks
2202  PFBlockElement::Type type = elements[ iHO ].type();
2203  assert( type == PFBlockElement::HO );
2204  PFClusterRef hoclusterref = elements[iHO].clusterRef();
2205  assert(!hoclusterref.isNull() );
2206 
2207  // Check if this HO is not closer to another track - ignore it in that case
2208  std::multimap<double, unsigned> sortedTracksHO;
2209  block.associatedElements( iHO, linkData,
2210  sortedTracksHO,
2213  unsigned jTrack = sortedTracksHO.begin()->second;
2214  if ( jTrack != iTrack ) continue;
2215 
2216  // double chi2HO = block.chi2(jTrack,iHO,linkData,
2217  // reco::PFBlock::LINKTEST_ALL);
2218  //double distHO = block.dist(jTrack,iHO,linkData,
2219  // reco::PFBlock::LINKTEST_ALL);
2220 
2221  // Increment the total energy by the energy of this HO cluster
2222  totalHO += hoclusterref->energy();
2223  active[iHO] = false;
2224  // Keep track for later reference in the PFCandidate.
2225  std::pair<double, unsigned> associatedHO( distHO, iHO );
2226  associatedHOs.emplace(iTrack, associatedHO);
2227 
2228  } // End loop ho associated to iTrack
2229  } // end case: at least one ho element associated to iTrack
2230 
2231 
2232  } // end loop on tracks associated to hcal element iHcal
2233 
2234  // Include totalHO in totalHCAL for the time being (it will be calibrated as HCAL energy)
2235  totalHcal += totalHO;
2236 
2237  // test compatibility between calo and tracker. //////////////
2238 
2239  double caloEnergy = 0.;
2240  double slopeEcal = 1.0;
2241  double calibEcal = 0.;
2242  double calibHcal = 0.;
2243  hadronDirection = hadronAtECAL.Unit();
2244 
2245  // Determine the expected calo resolution from the total charged momentum
2246  double Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2247  Caloresolution *= totalChargedMomentum;
2248  // Account for muons
2249  Caloresolution = std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2250  totalEcal -= std::min(totalEcal,muonECALEnergy);
2251  totalHcal -= std::min(totalHcal,muonHCALEnergy);
2252  if ( totalEcal < 1E-9 ) photonAtECAL = ::math::XYZVector(0.,0.,0.);
2253  if ( totalHcal < 1E-9 ) hadronAtECAL = ::math::XYZVector(0.,0.,0.);
2254 
2255  // Loop over all ECAL satellites, starting for the closest to the various tracks
2256  // and adding other satellites until saturation of the total track momentum
2257  // Note : for code simplicity, the first element of the loop is the HCAL cluster
2258  // with 0 energy in the ECAL
2259  for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
2260 
2261  // Add the energy of this ECAL cluster
2262  double previousCalibEcal = calibEcal;
2263  double previousCalibHcal = calibHcal;
2264  double previousCaloEnergy = caloEnergy;
2265  double previousSlopeEcal = slopeEcal;
2266  ::math::XYZVector previousHadronAtECAL = hadronAtECAL;
2267  //
2268  totalEcal += sqrt(is->second.second.Mag2());
2269  photonAtECAL += is->second.second;
2270  calibEcal = std::max(0.,totalEcal);
2271  calibHcal = std::max(0.,totalHcal);
2272  hadronAtECAL = calibHcal * hadronDirection;
2273  // Calibrate ECAL and HCAL energy under the hadron hypothesis.
2274  calibration_->energyEmHad(totalChargedMomentum,calibEcal,calibHcal,
2275  hclusterref->positionREP().Eta(),
2276  hclusterref->positionREP().Phi());
2277  caloEnergy = calibEcal+calibHcal;
2278  if ( totalEcal > 0.) slopeEcal = calibEcal/totalEcal;
2279 
2280  hadronAtECAL = calibHcal * hadronDirection;
2281 
2282  // Continue looping until all closest clusters are exhausted and as long as
2283  // the calorimetric energy does not saturate the total momentum.
2284  if ( is->first < 0. || caloEnergy - totalChargedMomentum <= 0. ) {
2285  if(debug_) cout<<"\t\t\tactive, adding "<<is->second.second
2286  <<" to ECAL energy, and locking"<<endl;
2287  active[is->second.first] = false;
2288  double clusterEnergy=sqrt(is->second.second.Mag2());
2289  if(clusterEnergy>50) {
2290  ecalClusters.push_back(is->second);
2291  sumEcalClusters+=clusterEnergy;
2292  }
2293  continue;
2294  }
2295 
2296  // Otherwise, do not consider the last cluster examined and exit.
2297  // active[is->second.first] = true;
2298  totalEcal -= sqrt(is->second.second.Mag2());
2299  photonAtECAL -= is->second.second;
2300  calibEcal = previousCalibEcal;
2301  calibHcal = previousCalibHcal;
2302  hadronAtECAL = previousHadronAtECAL;
2303  slopeEcal = previousSlopeEcal;
2304  caloEnergy = previousCaloEnergy;
2305 
2306  break;
2307 
2308  }
2309 
2310  // Sanity check !
2311  assert(caloEnergy>=0);
2312 
2313 
2314  // And now check for hadronic energy excess...
2315 
2316  //colin: resolution should be measured on the ecal+hcal case.
2317  // however, the result will be close.
2318  // double Caloresolution = neutralHadronEnergyResolution( caloEnergy );
2319  // Caloresolution *= caloEnergy;
2320  // PJ The resolution is on the expected charged calo energy !
2321  //double Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2322  //Caloresolution *= totalChargedMomentum;
2323  // that of the charged particles linked to the cluster!
2324 
2325  /* */
2327  if ( totalChargedMomentum - caloEnergy > nSigmaTRACK_*Caloresolution ) {
2328 
2329  /*
2330  cout<<"\tCompare Calo Energy to total charged momentum "<<endl;
2331  cout<<"\t\tsum p = "<<totalChargedMomentum<<" +- "<<sqrt(sumpError2)<<endl;
2332  cout<<"\t\tsum ecal = "<<totalEcal<<endl;
2333  cout<<"\t\tsum hcal = "<<totalHcal<<endl;
2334  cout<<"\t\t => Calo Energy = "<<caloEnergy<<" +- "<<Caloresolution<<endl;
2335  cout<<"\t\t => Calo Energy- total charged momentum = "
2336  <<caloEnergy-totalChargedMomentum<<" +- "<<TotalError<<endl;
2337  cout<<endl;
2338  cout << "\t\tNumber/momentum of muons found in the block : " << nMuons << std::endl;
2339  */
2340  // First consider loose muons
2341  if ( nMuons > 0 ) {
2342  for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2343  unsigned iTrack = it->second.first;
2344  // Only active tracks
2345  if ( !active[iTrack] ) continue;
2346  // Only muons
2347  if ( !it->second.second ) continue;
2348 
2349  double trackMomentum = elements[it->second.first].trackRef()->p();
2350 
2351  // look for ECAL elements associated to iTrack (associated to iHcal)
2352  std::multimap<double, unsigned> sortedEcals;
2353  block.associatedElements( iTrack, linkData,
2354  sortedEcals,
2357  std::multimap<double, unsigned> sortedHOs;
2358  block.associatedElements( iTrack, linkData,
2359  sortedHOs,
2362 
2363  //Here allow for loose muons!
2364  unsigned tmpi = reconstructTrack( elements[iTrack],true);
2365 
2366  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2367  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2368  double muonHcal = std::min(muonHCAL_[0]+muonHCAL_[1],totalHcal-totalHO);
2369  double muonHO = 0.;
2370  (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal,muonHcal);
2371  if( !sortedEcals.empty() ) {
2372  unsigned iEcal = sortedEcals.begin()->second;
2373  PFClusterRef eclusterref = elements[iEcal].clusterRef();
2374  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
2375  double muonEcal = std::min(muonECAL_[0]+muonECAL_[1],eclusterref->energy());
2376  (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(),muonEcal);
2377  }
2378  if( useHO_ && !sortedHOs.empty() ) {
2379  unsigned iHO = sortedHOs.begin()->second;
2380  PFClusterRef hoclusterref = elements[iHO].clusterRef();
2381  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
2382  muonHO = std::min(muonHO_[0]+muonHO_[1],hoclusterref->energy());
2383  (*pfCandidates_)[tmpi].setHcalEnergy(max(totalHcal-totalHO,0.0),muonHcal);
2384  (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(),muonHO);
2385  }
2386  setHcalDepthInfo((*pfCandidates_)[tmpi], *hclusterref);
2387  // Remove it from the block
2388  const ::math::XYZPointF& chargedPosition =
2389  dynamic_cast<const reco::PFBlockElementTrack*>(&elements[it->second.first])->positionAtECALEntrance();
2390  ::math::XYZVector chargedDirection(chargedPosition.X(), chargedPosition.Y(), chargedPosition.Z());
2391  chargedDirection = chargedDirection.Unit();
2392  totalChargedMomentum -= trackMomentum;
2393  // Update the calo energies
2394  if ( totalEcal > 0. )
2395  calibEcal -= std::min(calibEcal,muonECAL_[0]*calibEcal/totalEcal);
2396  if ( totalHcal > 0. )
2397  calibHcal -= std::min(calibHcal,muonHCAL_[0]*calibHcal/totalHcal);
2398  totalEcal -= std::min(totalEcal,muonECAL_[0]);
2399  totalHcal -= std::min(totalHcal,muonHCAL_[0]);
2400  if ( totalEcal > muonECAL_[0] ) photonAtECAL -= muonECAL_[0] * chargedDirection;
2401  if ( totalHcal > muonHCAL_[0] ) hadronAtECAL -= muonHCAL_[0]*calibHcal/totalHcal * chargedDirection;
2402  caloEnergy = calibEcal+calibHcal;
2403  muonHCALEnergy += muonHCAL_[0];
2404  muonHCALError += muonHCAL_[1]*muonHCAL_[1];
2405  if ( muonHO > 0. ) {
2406  muonHCALEnergy += muonHO_[0];
2407  muonHCALError += muonHO_[1]*muonHO_[1];
2408  if ( totalHcal > 0. ) {
2409  calibHcal -= std::min(calibHcal,muonHO_[0]*calibHcal/totalHcal);
2410  totalHcal -= std::min(totalHcal,muonHO_[0]);
2411  }
2412  }
2413  muonECALEnergy += muonECAL_[0];
2414  muonECALError += muonECAL_[1]*muonECAL_[1];
2415  active[iTrack] = false;
2416  // Stop the loop whenever enough muons are removed
2417  //Commented out: Keep looking for muons since they often come in pairs -Matt
2418  //if ( totalChargedMomentum < caloEnergy ) break;
2419  }
2420  // New calo resolution.
2421  Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2422  Caloresolution *= totalChargedMomentum;
2423  Caloresolution = std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2424  }
2425  }
2426 
2427  if(debug_){
2428  cout<<"\tBefore Cleaning "<<endl;
2429  cout<<"\tCompare Calo Energy to total charged momentum "<<endl;
2430  cout<<"\t\tsum p = "<<totalChargedMomentum<<" +- "<<sqrt(sumpError2)<<endl;
2431  cout<<"\t\tsum ecal = "<<totalEcal<<endl;
2432  cout<<"\t\tsum hcal = "<<totalHcal<<endl;
2433  cout<<"\t\t => Calo Energy = "<<caloEnergy<<" +- "<<Caloresolution<<endl;
2434  cout<<"\t\t => Calo Energy- total charged momentum = "
2435  <<caloEnergy-totalChargedMomentum<<" +- "<<sqrt(sumpError2 + Caloresolution*Caloresolution)<<endl;
2436  cout<<endl;
2437  }
2438 
2439 
2440  // Second consider bad tracks (if still needed after muon removal)
2441  unsigned corrTrack = 10000000;
2442  double corrFact = 1.;
2443 
2444  if (rejectTracks_Bad_ &&
2445  totalChargedMomentum - caloEnergy > nSigmaTRACK_*Caloresolution) {
2446 
2447  for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2448  unsigned iTrack = it->second.first;
2449  // Only active tracks
2450  if ( !active[iTrack] ) continue;
2451  const reco::TrackRef& trackref = elements[it->second.first].trackRef();
2452 
2453  double dptRel = fabs(it->first)/trackref->pt()*100;
2454  bool isSecondary = isFromSecInt(elements[iTrack], "secondary");
2455  bool isPrimary = isFromSecInt(elements[iTrack], "primary");
2456 
2457  if ( isSecondary && dptRel < dptRel_DispVtx_ ) continue;
2458  // Consider only bad tracks
2459  if ( fabs(it->first) < ptError_ ) break;
2460  // What would become the block charged momentum if this track were removed
2461  double wouldBeTotalChargedMomentum =
2462  totalChargedMomentum - trackref->p();
2463  // Reject worst tracks, as long as the total charged momentum
2464  // is larger than the calo energy
2465 
2466  if ( wouldBeTotalChargedMomentum > caloEnergy ) {
2467 
2468  if (debug_ && isSecondary) {
2469  cout << "In bad track rejection step dptRel = " << dptRel << " dptRel_DispVtx_ = " << dptRel_DispVtx_ << endl;
2470  cout << "The calo energy would be still smaller even without this track but it is attached to a NI"<< endl;
2471  }
2472 
2473 
2474  if(isPrimary || (isSecondary && dptRel < dptRel_DispVtx_)) continue;
2475  active[iTrack] = false;
2476  totalChargedMomentum = wouldBeTotalChargedMomentum;
2477  if ( debug_ )
2478  std::cout << "\tElement " << elements[iTrack]
2479  << " rejected (Dpt = " << -it->first
2480  << " GeV/c, algo = " << trackref->algo() << ")" << std::endl;
2481  // Just rescale the nth worst track momentum to equalize the calo energy
2482  } else {
2483  if(isPrimary) break;
2484  corrTrack = iTrack;
2485  corrFact = (caloEnergy - wouldBeTotalChargedMomentum)/elements[it->second.first].trackRef()->p();
2486  if ( trackref->p()*corrFact < 0.05 ) {
2487  corrFact = 0.;
2488  active[iTrack] = false;
2489  }
2490  totalChargedMomentum -= trackref->p()*(1.-corrFact);
2491  if ( debug_ )
2492  std::cout << "\tElement " << elements[iTrack]
2493  << " (Dpt = " << -it->first
2494  << " GeV/c, algo = " << trackref->algo()
2495  << ") rescaled by " << corrFact
2496  << " Now the total charged momentum is " << totalChargedMomentum << endl;
2497  break;
2498  }
2499  }
2500  }
2501 
2502  // New determination of the calo and track resolution avec track deletion/rescaling.
2503  Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2504  Caloresolution *= totalChargedMomentum;
2505  Caloresolution = std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2506 
2507  // Check if the charged momentum is still very inconsistent with the calo measurement.
2508  // In this case, just drop all tracks from 4th and 5th iteration linked to this block
2509 
2510  if ( rejectTracks_Step45_ &&
2511  sortedTracks.size() > 1 &&
2512  totalChargedMomentum - caloEnergy > nSigmaTRACK_*Caloresolution ) {
2513  for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2514  unsigned iTrack = it->second.first;
2515  reco::TrackRef trackref = elements[iTrack].trackRef();
2516  if ( !active[iTrack] ) continue;
2517 
2518  double dptRel = fabs(it->first)/trackref->pt()*100;
2519  bool isPrimaryOrSecondary = isFromSecInt(elements[iTrack], "all");
2520 
2521 
2522 
2523 
2524  if (isPrimaryOrSecondary && dptRel < dptRel_DispVtx_) continue;
2525 
2526  if (PFTrackAlgoTools::step5(trackref->algo())) {
2527  active[iTrack] = false;
2528  totalChargedMomentum -= trackref->p();
2529 
2530  if ( debug_ )
2531  std::cout << "\tElement " << elements[iTrack]
2532  << " rejected (Dpt = " << -it->first
2533  << " GeV/c, algo = " << trackref->algo() << ")" << std::endl;
2534 
2535  }
2536  }
2537 
2538  }
2539 
2540  // New determination of the calo and track resolution avec track deletion/rescaling.
2541  Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2542  Caloresolution *= totalChargedMomentum;
2543  Caloresolution = std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2544 
2545  // Make PF candidates with the remaining tracks in the block
2546  sumpError2 = 0.;
2547  for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2548  unsigned iTrack = it->second.first;
2549  if ( !active[iTrack] ) continue;
2550  reco::TrackRef trackRef = elements[iTrack].trackRef();
2551  double trackMomentum = trackRef->p();
2552  double Dp = trackRef->qoverpError()*trackMomentum*trackMomentum;
2553  unsigned tmpi = reconstructTrack( elements[iTrack] );
2554 
2555 
2556  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2557  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2558  setHcalDepthInfo((*pfCandidates_)[tmpi], *hclusterref);
2559  std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2560  for (II ii=myEcals.first; ii!=myEcals.second; ++ii ) {
2561  unsigned iEcal = ii->second.second;
2562  if ( active[iEcal] ) continue;
2563  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2564  }
2565 
2566  if (useHO_) {
2567  std::pair<II,II> myHOs = associatedHOs.equal_range(iTrack);
2568  for (II ii=myHOs.first; ii!=myHOs.second; ++ii ) {
2569  unsigned iHO = ii->second.second;
2570  if ( active[iHO] ) continue;
2571  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO );
2572  }
2573  }
2574 
2575  if ( iTrack == corrTrack ) {
2576  (*pfCandidates_)[tmpi].rescaleMomentum(corrFact);
2577  trackMomentum *= corrFact;
2578  }
2579  chargedHadronsIndices.push_back( tmpi );
2580  chargedHadronsInBlock.push_back( iTrack );
2581  active[iTrack] = false;
2582  hcalP.push_back(trackMomentum);
2583  hcalDP.push_back(Dp);
2584  if (Dp/trackMomentum > maxDPovP) maxDPovP = Dp/trackMomentum;
2585  sumpError2 += Dp*Dp;
2586  }
2587 
2588  // The total uncertainty of the difference Calo-Track
2589  double TotalError = sqrt(sumpError2 + Caloresolution*Caloresolution);
2590 
2591  if ( debug_ ) {
2592  cout<<"\tCompare Calo Energy to total charged momentum "<<endl;
2593  cout<<"\t\tsum p = "<<totalChargedMomentum<<" +- "<<sqrt(sumpError2)<<endl;
2594  cout<<"\t\tsum ecal = "<<totalEcal<<endl;
2595  cout<<"\t\tsum hcal = "<<totalHcal<<endl;
2596  cout<<"\t\t => Calo Energy = "<<caloEnergy<<" +- "<<Caloresolution<<endl;
2597  cout<<"\t\t => Calo Energy- total charged momentum = "
2598  <<caloEnergy-totalChargedMomentum<<" +- "<<TotalError<<endl;
2599  cout<<endl;
2600  }
2601 
2602  /* */
2603 
2605  double nsigma = nSigmaHCAL(totalChargedMomentum,hclusterref->positionREP().Eta());
2606  //double nsigma = nSigmaHCAL(caloEnergy,hclusterref->positionREP().Eta());
2607  if ( abs(totalChargedMomentum-caloEnergy)<nsigma*TotalError ) {
2608 
2609  // deposited caloEnergy compatible with total charged momentum
2610  // if tracking errors are large take weighted average
2611 
2612  if(debug_) {
2613  cout<<"\t\tcase 1: COMPATIBLE "
2614  <<"|Calo Energy- total charged momentum| = "
2615  <<abs(caloEnergy-totalChargedMomentum)
2616  <<" < "<<nsigma<<" x "<<TotalError<<endl;
2617  if (maxDPovP < 0.1 )
2618  cout<<"\t\t\tmax DP/P = "<< maxDPovP
2619  <<" less than 0.1: do nothing "<<endl;
2620  else
2621  cout<<"\t\t\tmax DP/P = "<< maxDPovP
2622  <<" > 0.1: take weighted averages "<<endl;
2623  }
2624 
2625  // if max DP/P < 10% do nothing
2626  if (maxDPovP > 0.1) {
2627 
2628  // for each track associated to hcal
2629  // int nrows = tkIs.size();
2630  int nrows = chargedHadronsIndices.size();
2631  TMatrixTSym<double> a (nrows);
2632  TVectorD b (nrows);
2633  TVectorD check(nrows);
2634  double sigma2E = Caloresolution*Caloresolution;
2635  for(int i=0; i<nrows; i++) {
2636  double sigma2i = hcalDP[i]*hcalDP[i];
2637  if (debug_){
2638  cout<<"\t\t\ttrack associated to hcal "<<i
2639  <<" P = "<<hcalP[i]<<" +- "
2640  <<hcalDP[i]<<endl;
2641  }
2642  a(i,i) = 1./sigma2i + 1./sigma2E;
2643  b(i) = hcalP[i]/sigma2i + caloEnergy/sigma2E;
2644  for(int j=0; j<nrows; j++) {
2645  if (i==j) continue;
2646  a(i,j) = 1./sigma2E;
2647  } // end loop on j
2648  } // end loop on i
2649 
2650  // solve ax = b
2651  //if (debug_){// debug1
2652  //cout<<" matrix a(i,j) "<<endl;
2653  //a.Print();
2654  //cout<<" vector b(i) "<<endl;
2655  //b.Print();
2656  //} // debug1
2657  TDecompChol decomp(a);
2658  bool ok = false;
2659  TVectorD x = decomp.Solve(b, ok);
2660  // for each track create a PFCandidate track
2661  // with a momentum rescaled to weighted average
2662  if (ok) {
2663  for (int i=0; i<nrows; i++){
2664  // unsigned iTrack = trackInfos[i].index;
2665  unsigned ich = chargedHadronsIndices[i];
2666  double rescaleFactor = x(i)/hcalP[i];
2667  (*pfCandidates_)[ich].rescaleMomentum( rescaleFactor );
2668 
2669  if(debug_){
2670  cout<<"\t\t\told p "<<hcalP[i]
2671  <<" new p "<<x(i)
2672  <<" rescale "<<rescaleFactor<<endl;
2673  }
2674  }
2675  }
2676  else {
2677  cerr<<"not ok!"<<endl;
2678  assert(0);
2679  }
2680  }
2681  }
2682 
2684  else if( caloEnergy > totalChargedMomentum ) {
2685 
2686  //case 2: caloEnergy > totalChargedMomentum + nsigma*TotalError
2687  //there is an excess of energy in the calos
2688  //create a neutral hadron or a photon
2689 
2690  /*
2691  //If it's isolated don't create neutrals since the energy deposit is always coming from a showering muon
2692  bool thisIsAnIsolatedMuon = false;
2693  for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
2694  unsigned iTrack = ie->second;
2695  if(PFMuonAlgo::isIsolatedMuon(elements[iTrack].muonRef())) thisIsAnIsolatedMuon = true;
2696  }
2697 
2698  if(thisIsAnIsolatedMuon){
2699  if(debug_)cout<<" Not looking for neutral b/c this is an isolated muon "<<endl;
2700  break;
2701  }
2702  */
2703  double eNeutralHadron = caloEnergy - totalChargedMomentum;
2704  double ePhoton = (caloEnergy - totalChargedMomentum) / slopeEcal;
2705 
2706  if(debug_) {
2707  if(!sortedTracks.empty() ){
2708  cout<<"\t\tcase 2: NEUTRAL DETECTION "
2709  <<caloEnergy<<" > "<<nsigma<<"x"<<TotalError
2710  <<" + "<<totalChargedMomentum<<endl;
2711  cout<<"\t\tneutral activity detected: "<<endl
2712  <<"\t\t\t photon = "<<ePhoton<<endl
2713  <<"\t\t\tor neutral hadron = "<<eNeutralHadron<<endl;
2714 
2715  cout<<"\t\tphoton or hadron ?"<<endl;}
2716 
2717  if(sortedTracks.empty() )
2718  cout<<"\t\tno track -> hadron "<<endl;
2719  else
2720  cout<<"\t\t"<<sortedTracks.size()
2721  <<" tracks -> check if the excess is photonic or hadronic"<<endl;
2722  }
2723 
2724 
2725  double ratioMax = 0.;
2726  reco::PFClusterRef maxEcalRef;
2727  unsigned maxiEcal= 9999;
2728 
2729  // for each track associated to hcal: iterator IE ie :
2730 
2731  for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
2732 
2733  unsigned iTrack = ie->second;
2734 
2735  PFBlockElement::Type type = elements[iTrack].type();
2736  assert( type == reco::PFBlockElement::TRACK );
2737 
2738  reco::TrackRef trackRef = elements[iTrack].trackRef();
2739  assert( !trackRef.isNull() );
2740 
2741  II iae = associatedEcals.find(iTrack);
2742 
2743  if( iae == associatedEcals.end() ) continue;
2744 
2745  // double distECAL = iae->second.first;
2746  unsigned iEcal = iae->second.second;
2747 
2748  PFBlockElement::Type typeEcal = elements[iEcal].type();
2749  assert(typeEcal == reco::PFBlockElement::ECAL);
2750 
2751  reco::PFClusterRef clusterRef = elements[iEcal].clusterRef();
2752  assert( !clusterRef.isNull() );
2753 
2754  double pTrack = trackRef->p();
2755  double eECAL = clusterRef->energy();
2756  double eECALOverpTrack = eECAL / pTrack;
2757 
2758  if ( eECALOverpTrack > ratioMax ) {
2759  ratioMax = eECALOverpTrack;
2760  maxEcalRef = clusterRef;
2761  maxiEcal = iEcal;
2762  }
2763 
2764  } // end loop on tracks associated to hcal: iterator IE ie
2765 
2766  std::vector<reco::PFClusterRef> pivotalClusterRef;
2767  std::vector<unsigned> iPivotal;
2768  std::vector<double> particleEnergy, ecalEnergy, hcalEnergy, rawecalEnergy, rawhcalEnergy;
2769  std::vector<::math::XYZVector> particleDirection;
2770 
2771  // If the excess is smaller than the ecal energy, assign the whole
2772  // excess to photons
2773  if ( ePhoton < totalEcal || eNeutralHadron-calibEcal < 1E-10 ) {
2774  if ( !maxEcalRef.isNull() ) {
2775  // So the merged photon energy is,
2776  mergedPhotonEnergy = ePhoton;
2777  }
2778  } else {
2779  // Otherwise assign the whole ECAL energy to the photons
2780  if ( !maxEcalRef.isNull() ) {
2781  // So the merged photon energy is,
2782  mergedPhotonEnergy = totalEcal;
2783  }
2784  // ... and assign the remaining excess to neutral hadrons using the direction of ecal clusters
2785  mergedNeutralHadronEnergy = eNeutralHadron-calibEcal;
2786  }
2787 
2788  if ( mergedPhotonEnergy > 0 ) {
2789  // Split merged photon into photons for each energetic ecal cluster (necessary for jet substructure reconstruction)
2790  // make only one merged photon if less than 2 ecal clusters
2791  if ( ecalClusters.size()<=1 ) {
2792  ecalClusters.clear();
2793  ecalClusters.emplace_back(maxiEcal, photonAtECAL);
2794  sumEcalClusters=sqrt(photonAtECAL.Mag2());
2795  }
2796  for(std::vector<std::pair<unsigned,::math::XYZVector> >::const_iterator pae = ecalClusters.begin(); pae != ecalClusters.end(); ++pae ) {
2797  double clusterEnergy=sqrt(pae->second.Mag2());
2798  particleEnergy.push_back(mergedPhotonEnergy*clusterEnergy/sumEcalClusters);
2799  particleDirection.push_back(pae->second);
2800  ecalEnergy.push_back(mergedPhotonEnergy*clusterEnergy/sumEcalClusters);
2801  hcalEnergy.push_back(0.);
2802  rawecalEnergy.push_back(totalEcal);
2803  rawhcalEnergy.push_back(totalHcal);
2804  pivotalClusterRef.push_back(elements[pae->first].clusterRef());
2805  iPivotal.push_back(pae->first);
2806  }
2807  }
2808 
2809  if ( mergedNeutralHadronEnergy > 1.0 ) {
2810  // Split merged neutral hadrons according to directions of energetic ecal clusters (necessary for jet substructure reconstruction)
2811  // make only one merged neutral hadron if less than 2 ecal clusters
2812  if ( ecalClusters.size()<=1 ) {
2813  ecalClusters.clear();
2814  ecalClusters.emplace_back(iHcal, hadronAtECAL);
2815  sumEcalClusters=sqrt(hadronAtECAL.Mag2());
2816  }
2817  for(std::vector<std::pair<unsigned,::math::XYZVector> >::const_iterator pae = ecalClusters.begin(); pae != ecalClusters.end(); ++pae ) {
2818  double clusterEnergy=sqrt(pae->second.Mag2());
2819  particleEnergy.push_back(mergedNeutralHadronEnergy*clusterEnergy/sumEcalClusters);
2820  particleDirection.push_back(pae->second);
2821  ecalEnergy.push_back(0.);
2822  hcalEnergy.push_back(mergedNeutralHadronEnergy*clusterEnergy/sumEcalClusters);
2823  rawecalEnergy.push_back(totalEcal);
2824  rawhcalEnergy.push_back(totalHcal);
2825  pivotalClusterRef.push_back(hclusterref);
2826  iPivotal.push_back(iHcal);
2827  }
2828  }
2829 
2830  // reconstructing a merged neutral
2831  // the type of PFCandidate is known from the
2832  // reference to the pivotal cluster.
2833 
2834  for ( unsigned iPivot=0; iPivot<iPivotal.size(); ++iPivot ) {
2835 
2836  if ( particleEnergy[iPivot] < 0. )
2837  std::cout << "ALARM = Negative energy ! "
2838  << particleEnergy[iPivot] << std::endl;
2839 
2840  bool useDirection = true;
2841  unsigned tmpi = reconstructCluster( *pivotalClusterRef[iPivot],
2842  particleEnergy[iPivot],
2843  useDirection,
2844  particleDirection[iPivot].X(),
2845  particleDirection[iPivot].Y(),
2846  particleDirection[iPivot].Z());
2847 
2848 
2849  (*pfCandidates_)[tmpi].setEcalEnergy( rawecalEnergy[iPivot],ecalEnergy[iPivot] );
2850  if ( !useHO_ ) {
2851  (*pfCandidates_)[tmpi].setHcalEnergy( rawhcalEnergy[iPivot],hcalEnergy[iPivot] );
2852  (*pfCandidates_)[tmpi].setHoEnergy(0., 0.);
2853  } else {
2854  (*pfCandidates_)[tmpi].setHcalEnergy( max(rawhcalEnergy[iPivot]-totalHO,0.0),hcalEnergy[iPivot]*(1.-totalHO/rawhcalEnergy[iPivot]));
2855  (*pfCandidates_)[tmpi].setHoEnergy(totalHO, totalHO * hcalEnergy[iPivot]/rawhcalEnergy[iPivot]);
2856  }
2857  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
2858  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
2859  (*pfCandidates_)[tmpi].set_mva_nothing_gamma( -1. );
2860  // (*pfCandidates_)[tmpi].addElement(&elements[iPivotal]);
2861  // (*pfCandidates_)[tmpi].addElementInBlock(blockref, iPivotal[iPivot]);
2862  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2863  for ( unsigned ich=0; ich<chargedHadronsInBlock.size(); ++ich) {
2864  unsigned iTrack = chargedHadronsInBlock[ich];
2865  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2866  // Assign the position of the track at the ECAL entrance
2867  const ::math::XYZPointF& chargedPosition =
2868  dynamic_cast<const reco::PFBlockElementTrack*>(&elements[iTrack])->positionAtECALEntrance();
2869  (*pfCandidates_)[tmpi].setPositionAtECALEntrance(chargedPosition);
2870 
2871  std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2872  for (II ii=myEcals.first; ii!=myEcals.second; ++ii ) {
2873  unsigned iEcal = ii->second.second;
2874  if ( active[iEcal] ) continue;
2875  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2876  }
2877  }
2878 
2879  }
2880 
2881  } // excess of energy
2882 
2883 
2884  // will now share the hcal energy between the various charged hadron
2885  // candidates, taking into account the potential neutral hadrons
2886 
2887  double totalHcalEnergyCalibrated = calibHcal;
2888  double totalEcalEnergyCalibrated = calibEcal;
2889  //JB: The question is: we've resolved the merged photons cleanly, but how should
2890  //the remaining hadrons be assigned the remaining ecal energy?
2891  //*Temporary solution*: follow HCAL example with fractions...
2892 
2893  /*
2894  if(totalEcal>0) {
2895  // removing ecal energy from abc calibration
2896  totalHcalEnergyCalibrated -= calibEcal;
2897  // totalHcalEnergyCalibrated -= calibration_->paramECALplusHCAL_slopeECAL() * totalEcal;
2898  }
2899  */
2900  // else caloEnergy = hcal only calibrated energy -> ok.
2901 
2902  // remove the energy of the potential neutral hadron
2903  totalHcalEnergyCalibrated -= mergedNeutralHadronEnergy;
2904  // similarly for the merged photons
2905  totalEcalEnergyCalibrated -= mergedPhotonEnergy;
2906  // share between the charged hadrons
2907 
2908  //COLIN can compute this before
2909  // not exactly equal to sum p, this is sum E
2910  double chargedHadronsTotalEnergy = 0;
2911  for( unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2912  unsigned index = chargedHadronsIndices[ich];
2913  reco::PFCandidate& chargedHadron = (*pfCandidates_)[index];
2914  chargedHadronsTotalEnergy += chargedHadron.energy();
2915  }
2916 
2917  for( unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2918  unsigned index = chargedHadronsIndices[ich];
2919  reco::PFCandidate& chargedHadron = (*pfCandidates_)[index];
2920  float fraction = chargedHadron.energy()/chargedHadronsTotalEnergy;
2921 
2922  if ( !useHO_ ) {
2923  chargedHadron.setHcalEnergy( fraction * totalHcal, fraction * totalHcalEnergyCalibrated );
2924  chargedHadron.setHoEnergy( 0., 0. );
2925  } else {
2926  chargedHadron.setHcalEnergy( fraction * max(totalHcal-totalHO,0.0), fraction * totalHcalEnergyCalibrated * (1.-totalHO/totalHcal) );
2927  chargedHadron.setHoEnergy( fraction * totalHO, fraction * totalHO * totalHcalEnergyCalibrated / totalHcal );
2928  }
2929  //JB: fixing up (previously omitted) setting of ECAL energy gouzevit
2930  chargedHadron.setEcalEnergy( fraction * totalEcal, fraction * totalEcalEnergyCalibrated );
2931  }
2932 
2933  // Finally treat unused ecal satellites as photons.
2934  for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
2935 
2936  // Ignore satellites already taken
2937  unsigned iEcal = is->second.first;
2938  if ( !active[iEcal] ) continue;
2939 
2940  // Sanity checks again (well not useful, this time!)
2941  PFBlockElement::Type type = elements[ iEcal ].type();
2942  assert( type == PFBlockElement::ECAL );
2943  PFClusterRef eclusterref = elements[iEcal].clusterRef();
2944  assert(!eclusterref.isNull() );
2945 
2946  // Lock the cluster
2947  active[iEcal] = false;
2948 
2949  // Find the associated tracks
2950  std::multimap<double, unsigned> assTracks;
2951  block.associatedElements( iEcal, linkData,
2952  assTracks,
2955 
2956  // Create a photon
2957  unsigned tmpi = reconstructCluster( *eclusterref, sqrt(is->second.second.Mag2()) );
2958  (*pfCandidates_)[tmpi].setEcalEnergy( eclusterref->energy(),sqrt(is->second.second.Mag2()) );
2959  (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
2960  (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
2961  (*pfCandidates_)[tmpi].setPs1Energy( associatedPSs[iEcal].first );
2962  (*pfCandidates_)[tmpi].setPs2Energy( associatedPSs[iEcal].second );
2963  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2964  (*pfCandidates_)[tmpi].addElementInBlock( blockref, sortedTracks.begin()->second) ;
2965  }
2966 
2967 
2968  }
2969 
2970  // end loop on hcal element iHcal= hcalIs[i]
2971 
2972 
2973  // Processing the remaining HCAL clusters
2974  if(debug_) {
2975  cout<<endl;
2976  if(debug_)
2977  cout<<endl
2978  <<"---- loop remaining hcal ------- "<<endl;
2979  }
2980 
2981 
2982  //COLINFEB16
2983  // now dealing with the HCAL elements that are not linked to any track
2984  for(unsigned ihcluster=0; ihcluster<hcalIs.size(); ihcluster++) {
2985  unsigned iHcal = hcalIs[ihcluster];
2986 
2987  // Keep ECAL and HO elements for reference in the PFCandidate
2988  std::vector<unsigned> ecalRefs;
2989  std::vector<unsigned> hoRefs;
2990 
2991  if(debug_)
2992  cout<<endl<<elements[iHcal]<<" ";
2993 
2994 
2995  if( !active[iHcal] ) {
2996  if(debug_)
2997  cout<<"not active"<<endl;
2998  continue;
2999  }
3000 
3001  // Find the ECAL elements linked to it
3002  std::multimap<double, unsigned> ecalElems;
3003  block.associatedElements( iHcal, linkData,
3004  ecalElems ,
3007 
3008  // Loop on these ECAL elements
3009  float totalEcal = 0.;
3010  float ecalMax = 0.;
3011  reco::PFClusterRef eClusterRef;
3012  for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
3013 
3014  unsigned iEcal = ie->second;
3015  double dist = ie->first;
3016  PFBlockElement::Type type = elements[iEcal].type();
3017  assert( type == PFBlockElement::ECAL );
3018 
3019  // Check if already used
3020  if( !active[iEcal] ) continue;
3021 
3022  // Check the distance (one HCALPlusECAL tower, roughly)
3023  // if ( dist > 0.15 ) continue;
3024 
3025  //COLINFEB16
3026  // what could be done is to
3027  // - link by rechit.
3028  // - take in the neutral hadron all the ECAL clusters
3029  // which are within the same CaloTower, according to the distance,
3030  // except the ones which are closer to another HCAL cluster.
3031  // - all the other ECAL linked to this HCAL are photons.
3032  //
3033  // about the closest HCAL cluster.
3034  // it could maybe be easier to loop on the ECAL clusters first
3035  // to cut the links to all HCAL clusters except the closest, as is
3036  // done in the first track loop. But maybe not!
3037  // or add an helper function to the PFAlgo class to ask
3038  // if a given element is the closest of a given type to another one?
3039 
3040  // Check if not closer from another free HCAL
3041  std::multimap<double, unsigned> hcalElems;
3042  block.associatedElements( iEcal, linkData,
3043  hcalElems ,
3046 
3047  bool isClosest = true;
3048  for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
3049 
3050  unsigned jHcal = ih->second;
3051  double distH = ih->first;
3052 
3053  if ( !active[jHcal] ) continue;
3054 
3055  if ( distH < dist ) {
3056  isClosest = false;
3057  break;
3058  }
3059 
3060  }
3061 
3062  if (!isClosest) continue;
3063 
3064 
3065  if(debug_) {
3066  cout<<"\telement "<<elements[iEcal]<<" linked with dist "<< dist<<endl;
3067  cout<<"Added to HCAL cluster to form a neutral hadron"<<endl;
3068  }
3069 
3070  reco::PFClusterRef eclusterRef = elements[iEcal].clusterRef();
3071  assert( !eclusterRef.isNull() );
3072 
3073  double ecalEnergy = eclusterRef->correctedEnergy();
3074 
3075  //std::cout << "EcalEnergy, ps1, ps2 = " << ecalEnergy
3076  // << ", " << ps1Ene[0] << ", " << ps2Ene[0] << std::endl;
3077  totalEcal += ecalEnergy;
3078  if ( ecalEnergy > ecalMax ) {
3079  ecalMax = ecalEnergy;
3080  eClusterRef = eclusterRef;
3081  }
3082 
3083  ecalRefs.push_back(iEcal);
3084  active[iEcal] = false;
3085 
3086 
3087  }// End loop ECAL
3088 
3089  // Now find the HO clusters linked to the HCAL cluster
3090  double totalHO = 0.;
3091  double hoMax = 0.;
3092  //unsigned jHO = 0;
3093  if (useHO_) {
3094  std::multimap<double, unsigned> hoElems;
3095  block.associatedElements( iHcal, linkData,
3096  hoElems ,
3099 
3100  // Loop on these HO elements
3101  // double totalHO = 0.;
3102  // double hoMax = 0.;
3103  // unsigned jHO = 0;
3104  reco::PFClusterRef hoClusterRef;
3105  for(IE ie = hoElems.begin(); ie != hoElems.end(); ++ie ) {
3106 
3107  unsigned iHO = ie->second;
3108  double dist = ie->first;
3109  PFBlockElement::Type type = elements[iHO].type();
3110  assert( type == PFBlockElement::HO );
3111 
3112  // Check if already used
3113  if( !active[iHO] ) continue;
3114 
3115  // Check the distance (one HCALPlusHO tower, roughly)
3116  // if ( dist > 0.15 ) continue;
3117 
3118  // Check if not closer from another free HCAL
3119  std::multimap<double, unsigned> hcalElems;
3120  block.associatedElements( iHO, linkData,
3121  hcalElems ,
3124 
3125  bool isClosest = true;
3126  for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
3127 
3128  unsigned jHcal = ih->second;
3129  double distH = ih->first;
3130 
3131  if ( !active[jHcal] ) continue;
3132 
3133  if ( distH < dist ) {
3134  isClosest = false;
3135  break;
3136  }
3137 
3138  }
3139 
3140  if (!isClosest) continue;
3141 
3142  if(debug_ && useHO_) {
3143  cout<<"\telement "<<elements[iHO]<<" linked with dist "<< dist<<endl;
3144  cout<<"Added to HCAL cluster to form a neutral hadron"<<endl;
3145  }
3146 
3147  reco::PFClusterRef hoclusterRef = elements[iHO].clusterRef();
3148  assert( !hoclusterRef.isNull() );
3149 
3150  double hoEnergy = hoclusterRef->energy(); // calibration_->energyEm(*hoclusterRef,ps1Ene,ps2Ene,crackCorrection);
3151 
3152  totalHO += hoEnergy;
3153  if ( hoEnergy > hoMax ) {
3154  hoMax = hoEnergy;
3155  hoClusterRef = hoclusterRef;
3156  //jHO = iHO;
3157  }
3158 
3159  hoRefs.push_back(iHO);
3160  active[iHO] = false;
3161 
3162  }// End loop HO
3163  }
3164 
3165  PFClusterRef hclusterRef
3166  = elements[iHcal].clusterRef();
3167  assert( !hclusterRef.isNull() );
3168 
3169  // HCAL energy
3170  double totalHcal = hclusterRef->energy();
3171  // Include the HO energy
3172  if ( useHO_ ) totalHcal += totalHO;
3173 
3174  // std::cout << "Hcal Energy,eta : " << totalHcal
3175  // << ", " << hclusterRef->positionREP().Eta()
3176  // << std::endl;
3177  // Calibration
3178  //double caloEnergy = totalHcal;
3179  // double slopeEcal = 1.0;
3180  double calibEcal = totalEcal > 0. ? totalEcal : 0.;
3181  double calibHcal = std::max(0.,totalHcal);
3182  if ( hclusterRef->layer() == PFLayer::HF_HAD ||
3183  hclusterRef->layer() == PFLayer::HF_EM ) {
3184  //caloEnergy = totalHcal/0.7;
3185  calibEcal = totalEcal;
3186  } else {
3187  calibration_->energyEmHad(-1.,calibEcal,calibHcal,
3188  hclusterRef->positionREP().Eta(),
3189  hclusterRef->positionREP().Phi());
3190  //caloEnergy = calibEcal+calibHcal;
3191  }
3192 
3193  // std::cout << "CalibEcal,HCal = " << calibEcal << ", " << calibHcal << std::endl;
3194  // std::cout << "-------------------------------------------------------------------" << std::endl;
3195  // ECAL energy : calibration
3196 
3197  // double particleEnergy = caloEnergy;
3198  // double particleEnergy = totalEcal + calibHcal;
3199  // particleEnergy /= (1.-0.724/sqrt(particleEnergy)-0.0226/particleEnergy);
3200 
3201  unsigned tmpi = reconstructCluster( *hclusterRef,
3202  calibEcal+calibHcal );
3203 
3204 
3205  (*pfCandidates_)[tmpi].setEcalEnergy( totalEcal, calibEcal );
3206  if ( !useHO_ ) {
3207  (*pfCandidates_)[tmpi].setHcalEnergy( totalHcal, calibHcal );
3208  (*pfCandidates_)[tmpi].setHoEnergy(0.,0.);
3209  } else {
3210  (*pfCandidates_)[tmpi].setHcalEnergy( max(totalHcal-totalHO,0.0), calibHcal*(1.-totalHO/totalHcal));
3211  (*pfCandidates_)[tmpi].setHoEnergy(totalHO,totalHO*calibHcal/totalHcal);
3212  }
3213  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
3214  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
3215  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
3216  for (unsigned iec=0; iec<ecalRefs.size(); ++iec)
3217  (*pfCandidates_)[tmpi].addElementInBlock( blockref, ecalRefs[iec] );
3218  for (unsigned iho=0; iho<hoRefs.size(); ++iho)
3219  (*pfCandidates_)[tmpi].addElementInBlock( blockref, hoRefs[iho] );
3220 
3221  }//loop hcal elements
3222 
3223 
3224 
3225 
3226  if(debug_) {
3227  cout<<endl;
3228  if(debug_) cout<<endl<<"---- loop ecal------- "<<endl;
3229  }
3230 
3231  // for each ecal element iEcal = ecalIs[i] in turn:
3232 
3233  for(unsigned i=0; i<ecalIs.size(); i++) {
3234  unsigned iEcal = ecalIs[i];
3235 
3236  if(debug_)
3237  cout<<endl<<elements[iEcal]<<" ";
3238 
3239  if( ! active[iEcal] ) {
3240  if(debug_)
3241  cout<<"not active"<<endl;
3242  continue;
3243  }
3244 
3245  PFBlockElement::Type type = elements[ iEcal ].type();
3246  assert( type == PFBlockElement::ECAL );
3247 
3248  PFClusterRef clusterref = elements[iEcal].clusterRef();
3249  assert(!clusterref.isNull() );
3250 
3251  active[iEcal] = false;
3252 
3253  float ecalEnergy = clusterref->correctedEnergy();
3254  // float ecalEnergy = calibration_->energyEm( clusterref->energy() );
3255  double particleEnergy = ecalEnergy;
3256 
3257  unsigned tmpi = reconstructCluster( *clusterref,
3258  particleEnergy );
3259 
3260  (*pfCandidates_)[tmpi].setEcalEnergy( clusterref->energy(),ecalEnergy );
3261  (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
3262  (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
3263  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
3264  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
3265  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
3266 
3267 
3268  } // end loop on ecal elements iEcal = ecalIs[i]
3269 
3270 } // end processBlock
type
Definition: HCALResponse.h:21
static bool isIsolatedMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:227
double ptError_
Definition: PFAlgo.h:400
bool isFromSecInt(const reco::PFBlockElement &eTrack, std::string order) const
Definition: PFAlgo.cc:3617
bool usePFConversions_
Definition: PFAlgo.h:383
float goodTrackDeadHcal_dxy_
Definition: PFAlgo.h:408
std::vector< double > muonHCAL_
Variables for muons and fakes.
Definition: PFAlgo.h:396
ParticleType
particle types
Definition: PFCandidate.h:45
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:253
double eta() const final
momentum pseudorapidity
bool isElectronSafeForJetMET(const reco::GsfElectron &, const reco::PFCandidate &, const reco::Vertex &, bool &lockTracks)
void set_mva_nothing_gamma(float mva)
set mva for gamma detection
Definition: PFCandidate.h:330
bool isPhotonValidCandidate(const reco::PFBlockRef &blockRef, std::vector< bool > &active, std::unique_ptr< reco::PFCandidateCollection > &pfPhotonCandidates, std::vector< reco::PFCandidatePhotonExtra > &pfPhotonExtraCandidates, std::vector< reco::PFCandidate > &tempElectronCandidates)
Definition: PFPhotonAlgo.h:82
static bool isMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:155
const std::vector< reco::PFCandidate > & getAllElectronCandidates()
double errorScale(const reco::TrackBase::TrackAlgorithm &, const std::vector< double > &)
std::unique_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:289
unsigned reconstructCluster(const reco::PFCluster &cluster, double particleEnergy, bool useDirection=false, double particleX=0., double particleY=0., double particleZ=0.)
Definition: PFAlgo.cc:3353
double y() const
y coordinate
Definition: Vertex.h:113
bool useProtectionsForJetMET_
Definition: PFAlgo.h:368
float goodPixelTrackDeadHcal_minEta_
Definition: PFAlgo.h:410
const reco::TrackRef & trackRef() const override
std::map< unsigned int, Link > LinkData
Definition: PFBlock.h:46
size_type size() const
Definition: OwnVector.h:264
#define X(str)
Definition: MuonsGrabber.cc:48
bool trackType(TrackType trType) const override
void setVertex(const math::XYZPoint &p) override
set vertex
Definition: PFCandidate.h:409
size_type size() const
std::vector< Variable::Flags > flags
Definition: MVATrainer.cc:135
double pt() const final
transverse momentum
int charge() const final
electric charge
Definition: LeafCandidate.h:91
bool passElectronSelection(const reco::GsfElectron &, const reco::PFCandidate &, const int &)
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
PFElectronAlgo * pfele_
Definition: PFAlgo.h:360
float goodPixelTrackDeadHcal_dxy_
Definition: PFAlgo.h:416
const Point & position() const
position
Definition: Vertex.h:109
static bool isGlobalTightMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:188
int nVtx_
Definition: PFAlgo.h:389
bool rejectTracks_Step45_
Definition: PFAlgo.h:380
std::vector< ElementInBlock > ElementsInBlocks
Definition: PFCandidate.h:387
std::vector< double > factors45_
Definition: PFAlgo.h:401
bool useHO_
Definition: PFAlgo.h:339
RefToBase< value_type > refAt(size_type i) const
U second(std::pair< T, U > const &p)
void setCharge(Charge q) final
set electric charge
Definition: LeafCandidate.h:93
bool isElectron(const reco::GsfElectron &)
void set_mva_e_pi(float mvaNI)
Definition: PFCandidate.h:312
void push_back(D *&d)
Definition: OwnVector.h:290
void set_mva_Isolated(float mvaI)
Definition: PFCandidate.h:308
const edm::View< reco::PFCandidate > * pfEgammaCandidates_
Definition: PFAlgo.h:369
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.
Definition: PFAlgo.cc:3562
void setParticleType(ParticleType type)
set Particle Type
Definition: PFCandidate.cc:265
bool passPhotonSelection(const reco::Photon &)
T sqrt(T t)
Definition: SSEVec.h:18
bool empty() const
Definition: OwnVector.h:269
const std::vector< reco::PFCandidateElectronExtra > & getElectronExtra()
bool step45(const reco::TrackBase::TrackAlgorithm &)
PFPhotonAlgo * pfpho_
Definition: PFAlgo.h:361
float goodTrackDeadHcal_validFr_
Definition: PFAlgo.h:407
double energy() const final
energy
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double z() const
z coordinate
Definition: Vertex.h:115
reco::Vertex primaryVertex_
Definition: PFAlgo.h:432
double nSigmaHCAL(double clusterEnergy, double clusterEta) const
Definition: PFAlgo.cc:3513
std::vector< double > muonECAL_
Definition: PFAlgo.h:397
void setPositionAtECALEntrance(float x, float y, float z)
set position at ECAL entrance
T min(T a, T b)
Definition: MathUtil.h:58
std::vector< LinkConnSpec >::const_iterator IT
PFEGammaFilters * pfegamma_
Definition: PFAlgo.h:367
bool isNull() const
Checks for null.
Definition: Ref.h:250
int goodPixelTrackDeadHcal_maxLost3Hit_
Definition: PFAlgo.h:414
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
the extra photon collection
Definition: PFAlgo.h:300
ii
Definition: cuy.py:590
void setEcalEnergy(float eeRaw, float eeCorr)
set corrected Ecal energy
Definition: PFCandidate.h:218
float mva_e_pi() const
mva for electron-pion discrimination
Definition: PFCandidate.h:314
std::unique_ptr< reco::PFCandidateCollection > pfPhotonCandidates_
the unfiltered photon collection
Definition: PFAlgo.h:293
const std::vector< reco::PFCandidate > & getElectronCandidates()
float goodPixelTrackDeadHcal_maxPt_
Definition: PFAlgo.h:411
double x() const
x coordinate
Definition: Vertex.h:111
unsigned reconstructTrack(const reco::PFBlockElement &elt, bool allowLoose=false)
Definition: PFAlgo.cc:3273
int goodTrackDeadHcal_layers_
Definition: PFAlgo.h:406
std::vector< double > muonHO_
Definition: PFAlgo.h:398
float goodPixelTrackDeadHcal_ptErrRel_
Definition: PFAlgo.h:412
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
double dptRel_DispVtx_
Definition: PFAlgo.h:388
static bool isLooseMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:168
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
boost::shared_ptr< PFEnergyCalibration > calibration_
Definition: PFAlgo.h:335
double b
Definition: hdecay.h:120
void setHoEnergy(float eoRaw, float eoCorr)
set corrected Hcal energy
Definition: PFCandidate.h:238
bool isElectronValidCandidate(const reco::PFBlockRef &blockRef, std::vector< bool > &active, const reco::Vertex &primaryVertex)
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
boost::shared_ptr< PFEnergyCalibrationHF > thepfEnergyCalibrationHF_
Definition: PFAlgo.h:336
double a
Definition: hdecay.h:121
reco::PFCandidateEGammaExtraRef egammaExtraRef() const
return a reference to the EGamma extra
Definition: PFCandidate.cc:605
bool rejectTracks_Bad_
Definition: PFAlgo.h:379
bool useEGammaFilters_
Variables for NEW EGAMMA selection.
Definition: PFAlgo.h:366
bool debug_
Definition: PFAlgo.h:341
float goodTrackDeadHcal_ptErrRel_
Variables for track cleaning in bad HCal areas.
Definition: PFAlgo.h:404
bool step5(const reco::TrackBase::TrackAlgorithm &)
std::unique_ptr< reco::PFCandidateCollection > pfElectronCandidates_
the unfiltered electron collection
Definition: PFAlgo.h:291
int goodPixelTrackDeadHcal_maxLost4Hit_
Definition: PFAlgo.h:415
float goodPixelTrackDeadHcal_chi2n_
Definition: PFAlgo.h:413
double nSigmaTRACK_
Definition: PFAlgo.h:399
double neutralHadronEnergyResolution(double clusterEnergy, double clusterEta) const
todo: use PFClusterTools for this
Definition: PFAlgo.cc:3498
def check(config)
Definition: trackerTree.py:14
reco::PFCandidateElectronExtraCollection pfElectronExtra_
the unfiltered electron collection
Definition: PFAlgo.h:298
bool usePFPhotons_
Definition: PFAlgo.h:348
const ElementsInBlocks & elementsInBlocks() const
Definition: PFCandidate.cc:691
double phi() const final
momentum azimuthal angle
bool isPhotonSafeForJetMET(const reco::Photon &, const reco::PFCandidate &)
void setP4(const LorentzVector &p4) final
set 4-momentum
float goodTrackDeadHcal_chi2n_
Definition: PFAlgo.h:405
float goodPixelTrackDeadHcal_dz_
Definition: PFAlgo.h:417
void setHcalEnergy(float ehRaw, float ehCorr)
set corrected Hcal energy
Definition: PFCandidate.h:228
void setHcalDepthInfo(reco::PFCandidate &cand, const reco::PFCluster &cluster) const
Definition: PFAlgo.cc:3467
static bool isTrackerTightMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:214
double nSigmaECAL_
number of sigma to judge energy excess in ECAL
Definition: PFAlgo.h:330
Block of elements.
Definition: PFBlock.h:30
bool usePFElectrons_
Definition: PFAlgo.h:347
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 3353 of file PFAlgo.cc.

References ALCARECOTkAlJpsiMuMu_cff::charge, gather_cfg::cout, debug_, PFLayer::ECAL_BARREL, PFLayer::ECAL_ENDCAP, CustomPhysics_cfi::gamma, PFLayer::HCAL_BARREL1, PFLayer::HCAL_ENDCAP, PFLayer::HF_EM, PFLayer::HF_HAD, reco::PFCluster::layer(), ResonanceBuilder::mass, objects.autophobj::particleType, pfElectronTranslator_cfi::PFCandidate, pfCandidates_, reco::CaloCluster::position(), primaryVertex_, setHcalDepthInfo(), mathSSE::sqrt(), tmp, useVertices_, reco::PFCandidate::X, reco::Vertex::x(), reco::Vertex::y(), and reco::Vertex::z().

Referenced by checkCleaning(), processBlock(), and thePFEnergyCalibration().

3358  {
3359 
3361 
3362  // need to convert the ::math::XYZPoint data member of the PFCluster class=
3363  // to a displacement vector:
3364 
3365  // Transform particleX,Y,Z to a position at ECAL/HCAL entrance
3366  double factor = 1.;
3367  if ( useDirection ) {
3368  switch( cluster.layer() ) {
3369  case PFLayer::ECAL_BARREL:
3370  case PFLayer::HCAL_BARREL1:
3371  factor = std::sqrt(cluster.position().Perp2()/(particleX*particleX+particleY*particleY));
3372  break;
3373  case PFLayer::ECAL_ENDCAP:
3374  case PFLayer::HCAL_ENDCAP:
3375  case PFLayer::HF_HAD:
3376  case PFLayer::HF_EM:
3377  factor = cluster.position().Z()/particleZ;
3378  break;
3379  default:
3380  assert(0);
3381  }
3382  }
3383  //MIKE First of all let's check if we have vertex.
3384  ::math::XYZPoint vertexPos;
3385  if(useVertices_)
3387  else
3388  vertexPos = ::math::XYZPoint(0.0,0.0,0.0);
3389 
3390 
3391  ::math::XYZVector clusterPos( cluster.position().X()-vertexPos.X(),
3392  cluster.position().Y()-vertexPos.Y(),
3393  cluster.position().Z()-vertexPos.Z());
3394  ::math::XYZVector particleDirection ( particleX*factor-vertexPos.X(),
3395  particleY*factor-vertexPos.Y(),
3396  particleZ*factor-vertexPos.Z() );
3397 
3398  //::math::XYZVector clusterPos( cluster.position().X(), cluster.position().Y(),cluster.position().Z() );
3399  //::math::XYZVector particleDirection ( particleX, particleY, particleZ );
3400 
3401  clusterPos = useDirection ? particleDirection.Unit() : clusterPos.Unit();
3402  clusterPos *= particleEnergy;
3403 
3404  // clusterPos is now a vector along the cluster direction,
3405  // with a magnitude equal to the cluster energy.
3406 
3407  double mass = 0;
3408  ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double> >
3409  momentum( clusterPos.X(), clusterPos.Y(), clusterPos.Z(), mass);
3410  // mathcore is a piece of #$%
3412  // implicit constructor not allowed
3413  tmp = momentum;
3414 
3415  // Charge
3416  int charge = 0;
3417 
3418  // Type
3419  switch( cluster.layer() ) {
3420  case PFLayer::ECAL_BARREL:
3421  case PFLayer::ECAL_ENDCAP:
3422  particleType = PFCandidate::gamma;
3423  break;
3424  case PFLayer::HCAL_BARREL1:
3425  case PFLayer::HCAL_ENDCAP:
3426  particleType = PFCandidate::h0;
3427  break;
3428  case PFLayer::HF_HAD:
3429  particleType = PFCandidate::h_HF;
3430  break;
3431  case PFLayer::HF_EM:
3432  particleType = PFCandidate::egamma_HF;
3433  break;
3434  default:
3435  assert(0);
3436  }
3437 
3438  // The pf candidate
3439  pfCandidates_->push_back( PFCandidate( charge,
3440  tmp,
3441  particleType ) );
3442 
3443  // The position at ECAL entrance (well: watch out, it is not true
3444  // for HCAL clusters... to be fixed)
3445  pfCandidates_->back().
3446  setPositionAtECALEntrance(::math::XYZPointF(cluster.position().X(),
3447  cluster.position().Y(),
3448  cluster.position().Z()));
3449 
3450  //Set the cnadidate Vertex
3451  pfCandidates_->back().setVertex(vertexPos);
3452 
3453  // depth info
3454  setHcalDepthInfo(pfCandidates_->back(), cluster);
3455 
3456  //*TODO* cluster time is not reliable at the moment, so only use track timing
3457 
3458  if(debug_)
3459  cout<<"** candidate: "<<pfCandidates_->back()<<endl;
3460 
3461  // returns index to the newly created PFCandidate
3462  return pfCandidates_->size()-1;
3463 
3464 }
PFLayer::Layer layer() const
cluster layer, see PFLayer.h in this directory
Definition: PFCluster.cc:120
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:131
ParticleType
particle types
Definition: PFCandidate.h:45
std::unique_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:289
double y() const
y coordinate
Definition: Vertex.h:113
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
T sqrt(T t)
Definition: SSEVec.h:18
double z() const
z coordinate
Definition: Vertex.h:115
reco::Vertex primaryVertex_
Definition: PFAlgo.h:432
double x() const
x coordinate
Definition: Vertex.h:111
bool useVertices_
Definition: PFAlgo.h:433
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
math::XYZVector XYZPoint
bool debug_
Definition: PFAlgo.h:341
void setHcalDepthInfo(reco::PFCandidate &cand, const reco::PFCluster &cluster) const
Definition: PFAlgo.cc:3467
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 437 of file PFAlgo.cc.

References blockHandle_.

Referenced by setCandConnectorParameters().

437  {
438 
439  blockHandle_ = blockHandle;
441 }
void reconstructParticles(const reco::PFBlockHandle &blockHandle)
Definition: PFAlgo.cc:437
reco::PFBlockHandle blockHandle_
input block handle (full framework case)
Definition: PFAlgo.h:327
void PFAlgo::reconstructParticles ( const reco::PFBlockCollection blocks)
virtual

reconstruct particles

Definition at line 445 of file PFAlgo.cc.

References PFMuonAlgo::addMissingMuons(), groupFilesInBlocks::block, gather_cfg::cout, createBlockRef(), debug_, reco::PFBlockElement::ECAL, allElectronIsolations_cfi::elements, reco::PFBlock::elements(), relativeConstraints::empty, reco::PFBlockElement::HCAL, reco::PFBlockElement::HO, mps_fire::i, edm::HandleBase::isValid(), muonHandle_, pfCandidates_, pfCleanedCandidates_, pfElectronCandidates_, pfElectronExtra_, pfmu_, pfPhotonCandidates_, pfPhotonExtra_, PFMuonAlgo::postClean(), postCleaning(), processBlock(), and edm::OwnVector< T, P >::size().

445  {
446 
447  // reset output collection
448  if(pfCandidates_.get() )
449  pfCandidates_->clear();
450  else
452 
453  if(pfElectronCandidates_.get() )
454  pfElectronCandidates_->clear();
455  else
457 
458  // Clearing pfPhotonCandidates
459  if( pfPhotonCandidates_.get() )
460  pfPhotonCandidates_->clear();
461  else
463 
464  if(pfCleanedCandidates_.get() )
465  pfCleanedCandidates_->clear();
466  else
468 
469  // not a unique_ptr; should not be deleted after transfer
470  pfElectronExtra_.clear();
471  pfPhotonExtra_.clear();
472 
473  if( debug_ ) {
474  cout<<"*********************************************************"<<endl;
475  cout<<"***** Particle flow algorithm *****"<<endl;
476  cout<<"*********************************************************"<<endl;
477  }
478 
479  // sort elements in three lists:
480  std::list< reco::PFBlockRef > hcalBlockRefs;
481  std::list< reco::PFBlockRef > ecalBlockRefs;
482  std::list< reco::PFBlockRef > hoBlockRefs;
483  std::list< reco::PFBlockRef > otherBlockRefs;
484 
485  for( unsigned i=0; i<blocks.size(); ++i ) {
486  // reco::PFBlockRef blockref( blockh,i );
487  reco::PFBlockRef blockref = createBlockRef( blocks, i);
488 
489  const reco::PFBlock& block = *blockref;
491  elements = block.elements();
492 
493  bool singleEcalOrHcal = false;
494  if( elements.size() == 1 ){
495  if( elements[0].type() == reco::PFBlockElement::ECAL ){
496  ecalBlockRefs.push_back( blockref );
497  singleEcalOrHcal = true;
498  }
499  if( elements[0].type() == reco::PFBlockElement::HCAL ){
500  hcalBlockRefs.push_back( blockref );
501  singleEcalOrHcal = true;
502  }
503  if( elements[0].type() == reco::PFBlockElement::HO ){
504  // Single HO elements are likely to be noise. Not considered for now.
505  hoBlockRefs.push_back( blockref );
506  singleEcalOrHcal = true;
507  }
508  }
509 
510  if(!singleEcalOrHcal) {
511  otherBlockRefs.push_back( blockref );
512  }
513  }//loop blocks
514 
515  if( debug_ ){
516  cout<<"# Ecal blocks: "<<ecalBlockRefs.size()
517  <<", # Hcal blocks: "<<hcalBlockRefs.size()
518  <<", # HO blocks: "<<hoBlockRefs.size()
519  <<", # Other blocks: "<<otherBlockRefs.size()<<endl;
520  }
521 
522 
523  // loop on blocks that are not single ecal,
524  // and not single hcal.
525 
526  unsigned nblcks = 0;
527  for( IBR io = otherBlockRefs.begin(); io!=otherBlockRefs.end(); ++io) {
528  if ( debug_ ) std::cout << "Block number " << nblcks++ << std::endl;
529  processBlock( *io, hcalBlockRefs, ecalBlockRefs );
530  }
531 
532  std::list< reco::PFBlockRef > empty;
533 
534  unsigned hblcks = 0;
535  // process remaining single hcal blocks
536  for( IBR ih = hcalBlockRefs.begin(); ih!=hcalBlockRefs.end(); ++ih) {
537  if ( debug_ ) std::cout << "HCAL block number " << hblcks++ << std::endl;
538  processBlock( *ih, empty, empty );
539  }
540 
541  unsigned eblcks = 0;
542  // process remaining single ecal blocks
543  for( IBR ie = ecalBlockRefs.begin(); ie!=ecalBlockRefs.end(); ++ie) {
544  if ( debug_ ) std::cout << "ECAL block number " << eblcks++ << std::endl;
545  processBlock( *ie, empty, empty );
546  }
547 
548  // Post HF Cleaning
549  postCleaning();
550 
551  //Muon post cleaning
552  pfmu_->postClean(pfCandidates_.get());
553 
554  //Add Missing muons
555  if( muonHandle_.isValid())
557 }
type
Definition: HCALResponse.h:21
void addMissingMuons(edm::Handle< reco::MuonCollection >, reco::PFCandidateCollection *cands)
Definition: PFMuonAlgo.cc:953
std::unique_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:289
size_type size() const
Definition: OwnVector.h:264
virtual void processBlock(const reco::PFBlockRef &blockref, std::list< reco::PFBlockRef > &hcalBlockRefs, std::list< reco::PFBlockRef > &ecalBlockRefs)
Definition: PFAlgo.cc:560
const edm::OwnVector< reco::PFBlockElement > & elements() const
Definition: PFBlock.h:107
PFMuonAlgo * pfmu_
Definition: PFAlgo.h:362
std::unique_ptr< reco::PFCandidateCollection > pfCleanedCandidates_
Definition: PFAlgo.h:295
edm::Handle< reco::MuonCollection > muonHandle_
Definition: PFAlgo.h:435
bool isValid() const
Definition: HandleBase.h:74
reco::PFBlockRef createBlockRef(const reco::PFBlockCollection &blocks, unsigned bi)
Definition: PFAlgo.cc:3550
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
the extra photon collection
Definition: PFAlgo.h:300
std::unique_ptr< reco::PFCandidateCollection > pfPhotonCandidates_
the unfiltered photon collection
Definition: PFAlgo.h:293
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
std::list< reco::PFBlockRef >::iterator IBR
Definition: PFAlgo.cc:55
bool debug_
Definition: PFAlgo.h:341
std::unique_ptr< reco::PFCandidateCollection > pfElectronCandidates_
the unfiltered electron collection
Definition: PFAlgo.h:291
void postCleaning()
Definition: PFAlgo.cc:3653
void postClean(reco::PFCandidateCollection *)
Definition: PFMuonAlgo.cc:849
reco::PFCandidateElectronExtraCollection pfElectronExtra_
the unfiltered electron collection
Definition: PFAlgo.h:298
Block of elements.
Definition: PFBlock.h:30
unsigned PFAlgo::reconstructTrack ( const reco::PFBlockElement elt,
bool  allowLoose = false 
)
protected

Reconstruct a charged particle from a track Returns the index of the newly created candidate in pfCandidates_ Michalis added a flag here to treat muons inside jets

Definition at line 3273 of file PFAlgo.cc.

References ALCARECOTkAlJpsiMuMu_cff::charge, reco::TrackBase::charge(), gather_cfg::cout, debug_, reco::PFBlockElementTrack::displacedVertexRef(), dptRel_DispVtx_, reco::TrackBase::eta(), reco::PFCandidate::h, isFromSecInt(), reco::isMuon(), edm::Ref< C, T, F >::isNonnull(), reco::PFBlockElement::isTimeValid(), reco::PFBlockElementTrack::muonRef(), reco::TrackBase::p(), objects.autophobj::particleType, pfElectronTranslator_cfi::PFCandidate, pfCandidates_, pfmu_, reco::TrackBase::phi(), reco::PFBlockElementTrack::positionAtECALEntrance(), reco::TrackBase::pt(), reco::TrackBase::px(), reco::TrackBase::py(), reco::TrackBase::pz(), PFMuonAlgo::reconstructMuon(), mathSSE::sqrt(), reco::PFBlockElement::T_FROM_DISP, reco::PFCandidate::T_FROM_DISP, reco::PFBlockElement::T_TO_DISP, reco::PFCandidate::T_TO_DISP, reco::PFBlockElement::time(), reco::PFBlockElement::timeError(), HiIsolationCommonParameters_cff::track, and reco::PFBlockElementTrack::trackRef().

Referenced by processBlock(), and thePFEnergyCalibration().

3273  {
3274 
3275  const reco::PFBlockElementTrack* eltTrack
3276  = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
3277 
3278  const reco::TrackRef& trackRef = eltTrack->trackRef();
3279  const reco::Track& track = *trackRef;
3280  const reco::MuonRef& muonRef = eltTrack->muonRef();
3281  int charge = track.charge()>0 ? 1 : -1;
3282 
3283  // Assume this particle is a charged Hadron
3284  double px = track.px();
3285  double py = track.py();
3286  double pz = track.pz();
3287  double energy = sqrt(track.p()*track.p() + 0.13957*0.13957);
3288 
3289  if (debug_) cout << "Reconstructing PF candidate from track of pT = " << track.pt() << " eta = " << track.eta() << " phi = " << track.phi() << " px = " << px << " py = " << py << " pz = " << pz << " energy = " << energy << endl;
3290 
3291 
3292  // Create a PF Candidate
3293  ::math::XYZTLorentzVector momentum(px,py,pz,energy);
3296 
3297  // Add it to the stack
3298  pfCandidates_->push_back( PFCandidate( charge,
3299  momentum,
3300  particleType ) );
3301  //Set vertex and stuff like this
3302  pfCandidates_->back().setVertexSource( PFCandidate::kTrkVertex );
3303  pfCandidates_->back().setTrackRef( trackRef );
3304  pfCandidates_->back().setPositionAtECALEntrance( eltTrack->positionAtECALEntrance());
3305  if( muonRef.isNonnull())
3306  pfCandidates_->back().setMuonRef( muonRef );
3307 
3308 
3309  //Set time
3310  if (elt.isTimeValid()) pfCandidates_->back().setTime( elt.time(), elt.timeError() );
3311 
3312  //OK Now try to reconstruct the particle as a muon
3313  bool isMuon=pfmu_->reconstructMuon(pfCandidates_->back(),muonRef,allowLoose);
3314  bool isFromDisp = isFromSecInt(elt, "secondary");
3315 
3316 
3317  if ((!isMuon) && isFromDisp) {
3318  double Dpt = trackRef->ptError();
3319  double dptRel = Dpt/trackRef->pt()*100;
3320  //If the track is ill measured it is better to not refit it, since the track information probably would not be used.
3321  //In the PFAlgo we use the trackref information. If the track error is too big the refitted information might be very different
3322  // from the not refitted one.
3323  if (dptRel < dptRel_DispVtx_){
3324  if (debug_)
3325  cout << "Not refitted px = " << px << " py = " << py << " pz = " << pz << " energy = " << energy << endl;
3326  //reco::TrackRef trackRef = eltTrack->trackRef();
3328  reco::Track trackRefit = vRef->refittedTrack(trackRef);
3329  //change the momentum with the refitted track
3330  ::math::XYZTLorentzVector momentum(trackRefit.px(),
3331  trackRefit.py(),
3332  trackRefit.pz(),
3333  sqrt(trackRefit.p()*trackRefit.p() + 0.13957*0.13957));
3334  if (debug_)
3335  cout << "Refitted px = " << px << " py = " << py << " pz = " << pz << " energy = " << energy << endl;
3336  }
3337  pfCandidates_->back().setFlag( reco::PFCandidate::T_FROM_DISP, true);
3338  pfCandidates_->back().setDisplacedVertexRef( eltTrack->displacedVertexRef(reco::PFBlockElement::T_FROM_DISP)->displacedVertexRef(), reco::PFCandidate::T_FROM_DISP);
3339  }
3340 
3341  // 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
3342  if(isFromSecInt(elt, "primary") && !isMuon) {
3343  pfCandidates_->back().setFlag( reco::PFCandidate::T_TO_DISP, true);
3344  pfCandidates_->back().setDisplacedVertexRef( eltTrack->displacedVertexRef(reco::PFBlockElement::T_TO_DISP)->displacedVertexRef(), reco::PFCandidate::T_TO_DISP);
3345  }
3346 
3347  // returns index to the newly created PFCandidate
3348  return pfCandidates_->size()-1;
3349 }
double p() const
momentum vector magnitude
Definition: TrackBase.h:648
bool isFromSecInt(const reco::PFBlockElement &eTrack, std::string order) const
Definition: PFAlgo.cc:3617
ParticleType
particle types
Definition: PFCandidate.h:45
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:253
bool isMuon(const Candidate &part)
Definition: pdgIdUtils.h:11
float time() const
std::unique_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:289
const reco::TrackRef & trackRef() const override
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:678
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:660
PFMuonAlgo * pfmu_
Definition: PFAlgo.h:362
const math::XYZPointF & positionAtECALEntrance() const
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
bool isTimeValid() const
do we have a valid time information
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:684
T sqrt(T t)
Definition: SSEVec.h:18
double pt() const
track transverse momentum
Definition: TrackBase.h:654
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:672
const PFDisplacedTrackerVertexRef & displacedVertexRef(TrackType trType) const override
double dptRel_DispVtx_
Definition: PFAlgo.h:388
bool debug_
Definition: PFAlgo.h:341
int charge() const
track electric charge
Definition: TrackBase.h:600
const reco::MuonRef & muonRef() const override
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:666
float timeError() const
bool reconstructMuon(reco::PFCandidate &, const reco::MuonRef &, bool allowLoose=false)
Definition: PFMuonAlgo.cc:717
void PFAlgo::setAlgo ( int  algo)
inline

Definition at line 63 of file PFAlgo.h.

References patPFMETCorrections_cff::algo, and algo_.

void PFAlgo::setBadHcalTrackParams ( const edm::ParameterSet pset)

Definition at line 334 of file PFAlgo.cc.

References edm::ParameterSet::getParameter(), goodPixelTrackDeadHcal_chi2n_, goodPixelTrackDeadHcal_dxy_, goodPixelTrackDeadHcal_dz_, goodPixelTrackDeadHcal_maxLost3Hit_, goodPixelTrackDeadHcal_maxLost4Hit_, goodPixelTrackDeadHcal_maxPt_, goodPixelTrackDeadHcal_minEta_, goodPixelTrackDeadHcal_ptErrRel_, goodTrackDeadHcal_chi2n_, goodTrackDeadHcal_dxy_, goodTrackDeadHcal_layers_, goodTrackDeadHcal_ptErrRel_, and goodTrackDeadHcal_validFr_.

Referenced by setCandConnectorParameters().

335 {
336  goodTrackDeadHcal_ptErrRel_ = pset.getParameter<double>("goodTrackDeadHcal_ptErrRel");
337  goodTrackDeadHcal_chi2n_ = pset.getParameter<double>("goodTrackDeadHcal_chi2n");
338  goodTrackDeadHcal_layers_ = pset.getParameter<uint32_t>("goodTrackDeadHcal_layers");
339  goodTrackDeadHcal_validFr_ = pset.getParameter<double>("goodTrackDeadHcal_validFr");
340  goodTrackDeadHcal_dxy_ = pset.getParameter<double>("goodTrackDeadHcal_dxy");
341 
342  goodPixelTrackDeadHcal_minEta_ = pset.getParameter<double>("goodPixelTrackDeadHcal_minEta");
343  goodPixelTrackDeadHcal_maxPt_ = pset.getParameter<double>("goodPixelTrackDeadHcal_maxPt");
344  goodPixelTrackDeadHcal_ptErrRel_ = pset.getParameter<double>("goodPixelTrackDeadHcal_ptErrRel");
345  goodPixelTrackDeadHcal_chi2n_ = pset.getParameter<double>("goodPixelTrackDeadHcal_chi2n");
346  goodPixelTrackDeadHcal_maxLost3Hit_ = pset.getParameter<int32_t>("goodPixelTrackDeadHcal_maxLost3Hit");
347  goodPixelTrackDeadHcal_maxLost4Hit_ = pset.getParameter<int32_t>("goodPixelTrackDeadHcal_maxLost4Hit");
348  goodPixelTrackDeadHcal_dxy_ = pset.getParameter<double>("goodPixelTrackDeadHcal_dxy");
349  goodPixelTrackDeadHcal_dz_ = pset.getParameter<double>("goodPixelTrackDeadHcal_dz");
350 }
T getParameter(std::string const &) const
float goodTrackDeadHcal_dxy_
Definition: PFAlgo.h:408
float goodPixelTrackDeadHcal_minEta_
Definition: PFAlgo.h:410
float goodPixelTrackDeadHcal_dxy_
Definition: PFAlgo.h:416
float goodTrackDeadHcal_validFr_
Definition: PFAlgo.h:407
int goodPixelTrackDeadHcal_maxLost3Hit_
Definition: PFAlgo.h:414
float goodPixelTrackDeadHcal_maxPt_
Definition: PFAlgo.h:411
int goodTrackDeadHcal_layers_
Definition: PFAlgo.h:406
float goodPixelTrackDeadHcal_ptErrRel_
Definition: PFAlgo.h:412
float goodTrackDeadHcal_ptErrRel_
Variables for track cleaning in bad HCal areas.
Definition: PFAlgo.h:404
int goodPixelTrackDeadHcal_maxLost4Hit_
Definition: PFAlgo.h:415
float goodPixelTrackDeadHcal_chi2n_
Definition: PFAlgo.h:413
float goodTrackDeadHcal_chi2n_
Definition: PFAlgo.h:405
float goodPixelTrackDeadHcal_dz_
Definition: PFAlgo.h:417
void PFAlgo::setCandConnectorParameters ( const edm::ParameterSet iCfgCandConnector)
inline

Definition at line 73 of file PFAlgo.h.

References connector_, and PFCandConnector::setParameters().

73  {
74  connector_.setParameters(iCfgCandConnector);
75  }
PFCandConnector connector_
Definition: PFAlgo.h:393
void setParameters(const edm::ParameterSet &iCfgCandConnector)
void PFAlgo::setCandConnectorParameters ( bool  bCorrect,
bool  bCalibPrimary,
double  dptRel_PrimaryTrack,
double  dptRel_MergedTrack,
double  ptErrorSecondary,
const std::vector< double > &  nuclCalibFactors 
)
inline

Definition at line 77 of file PFAlgo.h.

References particleFlowSuperClusterECAL_cfi::applyCrackCorrections, gather_cfg::blocks, checkCleaning(), particleFlow_cfi::cleanedHF, particleFlow_cfi::coneEcalIsoForEgammaSC, particleFlow_cfi::coneTrackIsoForEgammaSC, connector_, particleFlow_cfi::dptRel_DispVtx, getPFMuonAlgo(), particleFlow_cfi::maxDeltaPhiPt, particleFlow_cfi::maxSignificance, particleFlow_cfi::minDeltaMet, particleFlow_cfi::minHFCleaningPt, particleFlow_cfi::minSignificance, particleFlow_cfi::minSignificanceReduction, particleFlow_cfi::nTrackIsoForEgammaSC, particleBasedIsoProducer_cfi::pfEgammaCandidates, particleFlow_cfi::postHFCleaning, jets_cff::primaryVertices, muonDTDigis_cfi::pset, reconstructParticles(), hltParticleFlowForJets_cfi::rejectTracks_Bad, hltParticleFlowForJets_cfi::rejectTracks_Step45, setBadHcalTrackParams(), setDisplacedVerticesParameters(), setEGammaCollections(), setEGammaParameters(), setEGElectronCollection(), setElectronExtraRef(), PFCandConnector::setParameters(), setPFEleParameters(), setPFMuonAndFakeParameters(), setPFPhotonParameters(), setPFPhotonRegWeights(), setPFVertexParameters(), setPhotonExtraRef(), setPostHFCleaningParameters(), AlCaHLTBitMon_QueryRunRegistry::string, particleFlow_cfi::sumEtEcalIsoForEgammaSC_barrel, particleFlow_cfi::sumEtEcalIsoForEgammaSC_endcap, particleFlow_cfi::sumPtTrackIsoForEgammaSC_barrel, particleFlow_cfi::sumPtTrackIsoForEgammaSC_endcap, particleFlow_cfi::sumPtTrackIsoForPhoton, particleFlow_cfi::sumPtTrackIsoSlopeForPhoton, thePFEnergyCalibration(), hltParticleFlowForJets_cfi::useEGammaSupercluster, Reconstruction_hiPF_cff::usePFConversions, particleFlow_cfi::usePFDecays, Reconstruction_hiPF_cff::usePFElectrons, hltParticleFlowForJets_cfi::usePFNuclearInteractions, hltParticleFlowForJets_cfi::usePFSCEleCalib, hltParticleFlowForJets_cfi::useProtectionsForJetMET, VerticesFromLeptons_cfi::useVertex, and particleFlow_cfi::X0_Map.

void PFAlgo::setDebug ( bool  debug)
inline

Definition at line 66 of file PFAlgo.h.

References connector_, debug, debug_, nSigmaHCAL(), pfegamma_, PFEGammaFilters::setDebug(), PFCandConnector::setDebug(), and setParameters().

PFCandConnector connector_
Definition: PFAlgo.h:393
PFEGammaFilters * pfegamma_
Definition: PFAlgo.h:367
#define debug
Definition: HDRShower.cc:19
void setDebug(bool debug)
bool debug_
Definition: PFAlgo.h:341
void setDebug(bool debug)
void PFAlgo::setDisplacedVerticesParameters ( bool  rejectTracks_Bad,
bool  rejectTracks_Step45,
bool  usePFNuclearInteractions,
bool  usePFConversions,
bool  usePFDecays,
double  dptRel_DispVtx 
)

Definition at line 376 of file PFAlgo.cc.

References particleFlow_cfi::dptRel_DispVtx, dptRel_DispVtx_, hltParticleFlowForJets_cfi::rejectTracks_Bad, rejectTracks_Bad_, hltParticleFlowForJets_cfi::rejectTracks_Step45, rejectTracks_Step45_, Reconstruction_hiPF_cff::usePFConversions, usePFConversions_, particleFlow_cfi::usePFDecays, usePFDecays_, hltParticleFlowForJets_cfi::usePFNuclearInteractions, and usePFNuclearInteractions_.

Referenced by setCandConnectorParameters().

void PFAlgo::setEGammaCollections ( const edm::View< reco::PFCandidate > &  pfEgammaCandidates,
const edm::ValueMap< reco::GsfElectronRef > &  valueMapGedElectrons,
const edm::ValueMap< reco::PhotonRef > &  valueMapGedPhotons 
)

Definition at line 271 of file PFAlgo.cc.

References particleBasedIsoProducer_cfi::pfEgammaCandidates, pfEgammaCandidates_, useEGammaFilters_, valueMapGedElectrons_, and valueMapGedPhotons_.

Referenced by setCandConnectorParameters().

273  {
274  if(useEGammaFilters_) {
276  valueMapGedElectrons_ = & valueMapGedElectrons;
277  valueMapGedPhotons_ = & valueMapGedPhotons;
278  }
279 }
const edm::ValueMap< reco::PhotonRef > * valueMapGedPhotons_
Definition: PFAlgo.h:371
const edm::View< reco::PFCandidate > * pfEgammaCandidates_
Definition: PFAlgo.h:369
bool useEGammaFilters_
Variables for NEW EGAMMA selection.
Definition: PFAlgo.h:366
const edm::ValueMap< reco::GsfElectronRef > * valueMapGedElectrons_
Definition: PFAlgo.h:370
void PFAlgo::setEGammaParameters ( bool  use_EGammaFilters,
std::string  ele_iso_path_mvaWeightFile,
double  ele_iso_pt,
double  ele_iso_mva_barrel,
double  ele_iso_mva_endcap,
double  ele_iso_combIso_barrel,
double  ele_iso_combIso_endcap,
double  ele_noniso_mva,
unsigned int  ele_missinghits,
bool  useProtectionsForJetMET,
const edm::ParameterSet ele_protectionsForJetMET,
const edm::ParameterSet ele_protectionsForBadHcal,
double  ph_MinEt,
double  ph_combIso,
double  ph_HoE,
double  ph_sietaieta_eb,
double  ph_sietaieta_ee,
const edm::ParameterSet ph_protectionsForJetMET,
const edm::ParameterSet ph_protectionsForBadHcal 
)

Definition at line 212 of file PFAlgo.cc.

References pfegamma_, useEGammaFilters_, hltParticleFlowForJets_cfi::useProtectionsForJetMET, and useProtectionsForJetMET_.

Referenced by setCandConnectorParameters().

232 {
233 
234  useEGammaFilters_ = use_EGammaFilters;
235 
236  if(!useEGammaFilters_ ) return;
237  FILE * fileEGamma_ele_iso_ID = fopen(ele_iso_path_mvaWeightFile.c_str(), "r");
238  if (fileEGamma_ele_iso_ID) {
239  fclose(fileEGamma_ele_iso_ID);
240  }
241  else {
242  string err = "PFAlgo: cannot open weight file '";
243  err += ele_iso_path_mvaWeightFile;
244  err += "'";
245  throw invalid_argument( err );
246  }
247 
248  // ele_iso_mvaID_ = new ElectronMVAEstimator(ele_iso_path_mvaWeightFile_);
250 
251  pfegamma_ = new PFEGammaFilters(ph_MinEt,
252  ph_combIso,
253  ph_HoE,
254  ph_sietaieta_eb,
255  ph_sietaieta_ee,
256  ph_protectionsForJetMET,
257  ph_protectionsForBadHcal,
258  ele_iso_pt,
259  ele_iso_mva_barrel,
260  ele_iso_mva_endcap,
261  ele_iso_combIso_barrel,
262  ele_iso_combIso_endcap,
263  ele_noniso_mva,
264  ele_missinghits,
265  ele_iso_path_mvaWeightFile,
266  ele_protectionsForJetMET,
267  ele_protectionsForBadHcal);
268 
269  return;
270 }
bool useProtectionsForJetMET_
Definition: PFAlgo.h:368
PFEGammaFilters * pfegamma_
Definition: PFAlgo.h:367
bool useEGammaFilters_
Variables for NEW EGAMMA selection.
Definition: PFAlgo.h:366
void PFAlgo::setEGElectronCollection ( const reco::GsfElectronCollection egelectrons)

Definition at line 3648 of file PFAlgo.cc.

References pfele_, PFElectronAlgo::setEGElectronCollection(), and useEGElectrons_.

Referenced by setCandConnectorParameters().

3648  {
3650 }
PFElectronAlgo * pfele_
Definition: PFAlgo.h:360
bool useEGElectrons_
Definition: PFAlgo.h:351
void setEGElectronCollection(const reco::GsfElectronCollection &egelectrons)
void PFAlgo::setElectronExtraRef ( const edm::OrphanHandle< reco::PFCandidateElectronExtraCollection > &  extrah)

Definition at line 3865 of file PFAlgo.cc.

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

Referenced by setCandConnectorParameters().

3865  {
3866  if(!usePFElectrons_) return;
3867  // std::cout << " setElectronExtraRef " << std::endl;
3868  unsigned size=pfCandidates_->size();
3869 
3870  for(unsigned ic=0;ic<size;++ic) {
3871  // select the electrons and add the extra
3872  if((*pfCandidates_)[ic].particleId()==PFCandidate::e) {
3873 
3874  PFElectronExtraEqual myExtraEqual((*pfCandidates_)[ic].gsfTrackRef());
3875  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3876  if(it!=pfElectronExtra_.end()) {
3877  // std::cout << " Index " << it-pfElectronExtra_.begin() << std::endl;
3878  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3879  (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3880  }
3881  else {
3882  (*pfCandidates_)[ic].setPFElectronExtraRef(PFCandidateElectronExtraRef());
3883  }
3884  }
3885  else // else save the mva and the extra as well !
3886  {
3887  if((*pfCandidates_)[ic].trackRef().isNonnull()) {
3888  PFElectronExtraKfEqual myExtraEqual((*pfCandidates_)[ic].trackRef());
3889  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3890  if(it!=pfElectronExtra_.end()) {
3891  (*pfCandidates_)[ic].set_mva_e_pi(it->mvaVariable(PFCandidateElectronExtra::MVA_MVA));
3892  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3893  (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3894  (*pfCandidates_)[ic].setGsfTrackRef(it->gsfTrackRef());
3895  }
3896  }
3897  }
3898 
3899  }
3900 
3901  size=pfElectronCandidates_->size();
3902  for(unsigned ic=0;ic<size;++ic) {
3903  // select the electrons - this test is actually not needed for this collection
3904  if((*pfElectronCandidates_)[ic].particleId()==PFCandidate::e) {
3905  // find the corresponding extra
3906  PFElectronExtraEqual myExtraEqual((*pfElectronCandidates_)[ic].gsfTrackRef());
3907  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3908  if(it!=pfElectronExtra_.end()) {
3909  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3910  (*pfElectronCandidates_)[ic].setPFElectronExtraRef(theRef);
3911 
3912  }
3913  }
3914  }
3915 
3916 }
size
Write out results.
std::unique_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:289
edm::Ref< PFCandidateElectronExtraCollection > PFCandidateElectronExtraRef
persistent reference to a PFCandidateElectronExtra
std::unique_ptr< reco::PFCandidateCollection > pfElectronCandidates_
the unfiltered electron collection
Definition: PFAlgo.h:291
reco::PFCandidateElectronExtraCollection pfElectronExtra_
the unfiltered electron collection
Definition: PFAlgo.h:298
bool usePFElectrons_
Definition: PFAlgo.h:347
void PFAlgo::setHcalDepthInfo ( reco::PFCandidate cand,
const reco::PFCluster cluster 
) const
protected

Definition at line 3467 of file PFAlgo.cc.

References Exception, lumiContext::fill, DetId::Hcal, mps_fire::i, reco::PFCluster::recHitFractions(), and reco::PFCandidate::setHcalDepthEnergyFractions().

Referenced by processBlock(), reconstructCluster(), and thePFEnergyCalibration().

3467  {
3468  std::array<double,7> energyPerDepth;
3469  std::fill(energyPerDepth.begin(), energyPerDepth.end(), 0.0);
3470  for (auto & hitRefAndFrac : cluster.recHitFractions()) {
3471  const auto & hit = *hitRefAndFrac.recHitRef();
3472  if (DetId(hit.detId()).det() == DetId::Hcal) {
3473  if (hit.depth() == 0) {
3474  edm::LogWarning("setHcalDepthInfo") << "Depth zero found";
3475  continue;
3476  }
3477  if (hit.depth() < 1 || hit.depth() > 7) {
3478  throw cms::Exception("CorruptData") << "Bogus depth " << hit.depth() << " at detid " << hit.detId() << "\n";
3479  }
3480  energyPerDepth[hit.depth()-1] += hitRefAndFrac.fraction()*hit.energy();
3481  }
3482  }
3483  double sum = std::accumulate(energyPerDepth.begin(), energyPerDepth.end(), 0.);
3484  std::array<float,7> depthFractions;
3485  if (sum > 0) {
3486  for (unsigned int i = 0; i < depthFractions.size(); ++i) {
3487  depthFractions[i] = energyPerDepth[i]/sum;
3488  }
3489  } else {
3490  std::fill(depthFractions.begin(), depthFractions.end(), 0.f);
3491  }
3492  cand.setHcalDepthEnergyFractions(depthFractions);
3493 }
void setHcalDepthEnergyFractions(const std::array< float, 7 > &fracs)
set the fraction of hcal energy as function of depth (index 0..6 for depth 1..7)
Definition: PFCandidate.h:432
Definition: DetId.h:18
const std::vector< reco::PFRecHitFraction > & recHitFractions() const
vector of rechit fractions
Definition: PFCluster.h:72
void PFAlgo::setHOTag ( bool  ho)
inline

Definition at line 62 of file PFAlgo.h.

References photonIsolationHIProducer_cfi::ho, and useHO_.

void PFAlgo::setMuonHandle ( const edm::Handle< reco::MuonCollection > &  muons)

Definition at line 353 of file PFAlgo.cc.

References muonHandle_, and extraflags_cff::muons.

Referenced by setPFMuonAlgo().

353  {
354  muonHandle_ = muons;
355 }
edm::Handle< reco::MuonCollection > muonHandle_
Definition: PFAlgo.h:435
void PFAlgo::setParameters ( double  nSigmaECAL,
double  nSigmaHCAL,
const boost::shared_ptr< PFEnergyCalibration > &  calibration,
const boost::shared_ptr< PFEnergyCalibrationHF > &  thepfEnergyCalibrationHF 
)

Definition at line 79 of file PFAlgo.cc.

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

Referenced by setDebug().

82  {
83 
84  nSigmaECAL_ = nSigmaECAL;
86 
87  calibration_ = calibration;
88  thepfEnergyCalibrationHF_ = thepfEnergyCalibrationHF;
89 
90 }
double nSigmaHCAL_
number of sigma to judge energy excess in HCAL
Definition: PFAlgo.h:333
double nSigmaHCAL(double clusterEnergy, double clusterEta) const
Definition: PFAlgo.cc:3513
boost::shared_ptr< PFEnergyCalibration > calibration_
Definition: PFAlgo.h:335
boost::shared_ptr< PFEnergyCalibrationHF > thepfEnergyCalibrationHF_
Definition: PFAlgo.h:336
double nSigmaECAL_
number of sigma to judge energy excess in ECAL
Definition: PFAlgo.h:330
void PFAlgo::setPFEleParameters ( double  mvaEleCut,
std::string  mvaWeightFileEleID,
bool  usePFElectrons,
const boost::shared_ptr< PFSCEnergyCalibration > &  thePFSCEnergyCalibration,
const boost::shared_ptr< PFEnergyCalibration > &  thePFEnergyCalibration,
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 99 of file PFAlgo.cc.

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

Referenced by setCandConnectorParameters().

114  {
115 
116  mvaEleCut_ = mvaEleCut;
120  thePFSCEnergyCalibration_ = thePFSCEnergyCalibration;
121  useEGElectrons_ = useEGElectrons;
130 
131 
132  if(!usePFElectrons_) return;
133  mvaWeightFileEleID_ = mvaWeightFileEleID;
134  FILE * fileEleID = fopen(mvaWeightFileEleID_.c_str(), "r");
135  if (fileEleID) {
136  fclose(fileEleID);
137  }
138  else {
139  string err = "PFAlgo: cannot open weight file '";
140  err += mvaWeightFileEleID;
141  err += "'";
142  throw invalid_argument( err );
143  }
158 }
unsigned int nTrackIsoForEgammaSC_
Definition: PFAlgo.h:359
double sumEtEcalIsoForEgammaSC_endcap_
Definition: PFAlgo.h:354
double mvaEleCut_
Definition: PFAlgo.h:346
double coneEcalIsoForEgammaSC_
Definition: PFAlgo.h:355
double coneTrackIsoForEgammaSC_
Definition: PFAlgo.h:358
double sumEtEcalIsoForEgammaSC_barrel_
Definition: PFAlgo.h:353
PFElectronAlgo * pfele_
Definition: PFAlgo.h:360
bool useEGammaSupercluster_
Definition: PFAlgo.h:352
boost::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration()
return the pointer to the calibration function
Definition: PFAlgo.h:238
bool useEGElectrons_
Definition: PFAlgo.h:351
std::string mvaWeightFileEleID_
Variables for PFElectrons.
Definition: PFAlgo.h:344
bool usePFSCEleCalib_
Definition: PFAlgo.h:350
boost::shared_ptr< PFSCEnergyCalibration > thePFSCEnergyCalibration_
Definition: PFAlgo.h:337
bool applyCrackCorrectionsElectrons_
Definition: PFAlgo.h:349
double sumPtTrackIsoForEgammaSC_endcap_
Definition: PFAlgo.h:357
double sumPtTrackIsoForEgammaSC_barrel_
Definition: PFAlgo.h:356
bool usePFElectrons_
Definition: PFAlgo.h:347
void PFAlgo::setPFMuonAlgo ( PFMuonAlgo algo)
inline

Definition at line 64 of file PFAlgo.h.

References patPFMETCorrections_cff::algo, pfmu_, and setMuonHandle().

void PFAlgo::setPFMuonAndFakeParameters ( const edm::ParameterSet pset)

Definition at line 306 of file PFAlgo.cc.

References factors45_, edm::ParameterSet::getParameter(), muonECAL_, muonHCAL_, muonHO_, nSigmaTRACK_, pfmu_, ptError_, and PFMuonAlgo::setParameters().

Referenced by setCandConnectorParameters().

313 {
314 
315 
316 
317 
318  pfmu_ = new PFMuonAlgo();
319  pfmu_->setParameters(pset);
320 
321  // Muon parameters
322  muonHCAL_= pset.getParameter<std::vector<double> >("muon_HCAL");
323  muonECAL_= pset.getParameter<std::vector<double> >("muon_ECAL");
324  muonHO_= pset.getParameter<std::vector<double> >("muon_HO");
325  assert ( muonHCAL_.size() == 2 && muonECAL_.size() == 2 && muonHO_.size() == 2);
326  nSigmaTRACK_= pset.getParameter<double>("nsigma_TRACK");
327  ptError_= pset.getParameter<double>("pt_Error");
328  factors45_ = pset.getParameter<std::vector<double> >("factors_45");
329  assert ( factors45_.size() == 2 );
330 
331 }
T getParameter(std::string const &) const
double ptError_
Definition: PFAlgo.h:400
std::vector< double > muonHCAL_
Variables for muons and fakes.
Definition: PFAlgo.h:396
void setParameters(const edm::ParameterSet &)
Definition: PFMuonAlgo.cc:29
PFMuonAlgo * pfmu_
Definition: PFAlgo.h:362
std::vector< double > factors45_
Definition: PFAlgo.h:401
std::vector< double > muonECAL_
Definition: PFAlgo.h:397
std::vector< double > muonHO_
Definition: PFAlgo.h:398
double nSigmaTRACK_
Definition: PFAlgo.h:399
void PFAlgo::setPFPhotonParameters ( bool  usePFPhoton,
std::string  mvaWeightFileConvID,
double  mvaConvCut,
bool  useReg,
std::string  X0_Map,
const boost::shared_ptr< PFEnergyCalibration > &  thePFEnergyCalibration,
double  sumPtTrackIsoForPhoton,
double  sumPtTrackIsoSlopeForPhoton 
)

Definition at line 161 of file PFAlgo.cc.

References MillePedeFileConverter_cfg::e, AlCaHLTBitMon_ParallelJobs::p, pfpho_, primaryVertex_, MetAnalyzer::pv(), particleFlow_cfi::usePFPhotons, usePFPhotons_, and useVertices_.

Referenced by setCandConnectorParameters().

169  {
170 
172 
173  //for MVA pass PV if there is one in the collection otherwise pass a dummy
175  if(useVertices_)
176  {
177  dummy = primaryVertex_;
178  }
179  else { // create a dummy PV
181  e(0, 0) = 0.0015 * 0.0015;
182  e(1, 1) = 0.0015 * 0.0015;
183  e(2, 2) = 15. * 15.;
184  reco::Vertex::Point p(0, 0, 0);
185  dummy = reco::Vertex(p, e, 0, 0, 0);
186  }
187  // pv=&dummy;
188  if(! usePFPhotons_) return;
189  FILE * filePhotonConvID = fopen(mvaWeightFileConvID.c_str(), "r");
190  if (filePhotonConvID) {
191  fclose(filePhotonConvID);
192  }
193  else {
194  string err = "PFAlgo: cannot open weight file '";
195  err += mvaWeightFileConvID;
196  err += "'";
197  throw invalid_argument( err );
198  }
199  const reco::Vertex* pv=&dummy;
200  pfpho_ = new PFPhotonAlgo(mvaWeightFileConvID,
201  mvaConvCut,
202  useReg,
203  X0_Map,
204  *pv,
208  );
209  return;
210 }
math::Error< dimension >::type Error
covariance error matrix (3x3)
Definition: Vertex.h:43
boost::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration()
return the pointer to the calibration function
Definition: PFAlgo.h:238
PFPhotonAlgo * pfpho_
Definition: PFAlgo.h:361
def pv(vc)
Definition: MetAnalyzer.py:7
reco::Vertex primaryVertex_
Definition: PFAlgo.h:432
math::XYZPoint Point
point in the space
Definition: Vertex.h:39
bool useVertices_
Definition: PFAlgo.h:433
bool usePFPhotons_
Definition: PFAlgo.h:348
void PFAlgo::setPFPhotonRegWeights ( const GBRForest LCorrForestEB,
const GBRForest LCorrForestEE,
const GBRForest GCorrForestBarrel,
const GBRForest GCorrForestEndcapHr9,
const GBRForest GCorrForestEndcapLr9,
const GBRForest PFEcalResolution 
)

Definition at line 293 of file PFAlgo.cc.

References pfpho_, and PFPhotonAlgo::setGBRForest().

Referenced by setCandConnectorParameters().

299  {
300 
301  pfpho_->setGBRForest(LCorrForestEB,LCorrForestEE,
302  GCorrForestBarrel, GCorrForestEndcapHr9,
303  GCorrForestEndcapLr9, PFEcalResolution);
304 }
PFPhotonAlgo * pfpho_
Definition: PFAlgo.h:361
void setGBRForest(const GBRForest *LCorrForest, const GBRForest *GCorrForest, const GBRForest *ResForest)
Definition: PFPhotonAlgo.h:49
void PFAlgo::setPFVertexParameters ( bool  useVertex,
const reco::VertexCollection primaryVertices 
)

Definition at line 394 of file PFAlgo.cc.

References MillePedeFileConverter_cfg::e, mps_fire::i, nVtx_, AlCaHLTBitMon_ParallelJobs::p, pfmu_, pfpho_, primaryVertex_, PFMuonAlgo::setInputsForCleaning(), PFPhotonAlgo::setnPU(), PFPhotonAlgo::setPhotonPrimaryVtx(), usePFPhotons_, VerticesFromLeptons_cfi::useVertex, and useVertices_.

Referenced by setCandConnectorParameters().

395  {
397 
398  //Set the vertices for muon cleaning
400 
401 
402  //Now find the primary vertex!
403  bool primaryVertexFound = false;
404  nVtx_ = primaryVertices->size();
405  if(usePFPhotons_){
406  pfpho_->setnPU(nVtx_);
407  }
408  for (unsigned short i=0 ;i<primaryVertices->size();++i)
409  {
410  if(primaryVertices->at(i).isValid()&&(!primaryVertices->at(i).isFake()))
411  {
413  primaryVertexFound = true;
414  break;
415  }
416  }
417  //Use vertices if the user wants to but only if it exists a good vertex
418  useVertices_ = useVertex && primaryVertexFound;
419  if(usePFPhotons_) {
420  if (useVertices_ ){
422  }
423  else{
425  e(0, 0) = 0.0015 * 0.0015;
426  e(1, 1) = 0.0015 * 0.0015;
427  e(2, 2) = 15. * 15.;
428  reco::Vertex::Point p(0, 0, 0);
429  reco::Vertex dummy = reco::Vertex(p, e, 0, 0, 0);
430  // std::cout << " PFPho " << pfpho_ << std::endl;
431  pfpho_->setPhotonPrimaryVtx(dummy);
432  }
433  }
434 }
void setnPU(int nVtx)
Definition: PFPhotonAlgo.h:75
math::Error< dimension >::type Error
covariance error matrix (3x3)
Definition: Vertex.h:43
PFMuonAlgo * pfmu_
Definition: PFAlgo.h:362
int nVtx_
Definition: PFAlgo.h:389
PFPhotonAlgo * pfpho_
Definition: PFAlgo.h:361
reco::Vertex primaryVertex_
Definition: PFAlgo.h:432
math::XYZPoint Point
point in the space
Definition: Vertex.h:39
bool useVertices_
Definition: PFAlgo.h:433
primaryVertices
Definition: jets_cff.py:130
void setPhotonPrimaryVtx(const reco::Vertex &primary)
Definition: PFPhotonAlgo.h:78
bool usePFPhotons_
Definition: PFAlgo.h:348
void setInputsForCleaning(const reco::VertexCollection *)
Definition: PFMuonAlgo.cc:1168
void PFAlgo::setPhotonExtraRef ( const edm::OrphanHandle< reco::PFCandidatePhotonExtraCollection > &  pf_extrah)

Definition at line 3917 of file PFAlgo.cc.

References runEdmFileComparison::found, CustomPhysics_cfi::gamma, pfCandidates_, pfPhotonExtra_, findQualityFiles::size, and usePFPhotons_.

Referenced by setCandConnectorParameters().

3917  {
3918  if(!usePFPhotons_) return;
3919  unsigned int size=pfCandidates_->size();
3920  unsigned int sizePhExtra = pfPhotonExtra_.size();
3921  for(unsigned ic=0;ic<size;++ic) {
3922  // select the electrons and add the extra
3923  if((*pfCandidates_)[ic].particleId()==PFCandidate::gamma && (*pfCandidates_)[ic].mva_nothing_gamma() > 0.99) {
3924  if((*pfCandidates_)[ic].superClusterRef().isNonnull()) {
3925  bool found = false;
3926  for(unsigned pcextra=0;pcextra<sizePhExtra;++pcextra) {
3927  if((*pfCandidates_)[ic].superClusterRef() == pfPhotonExtra_[pcextra].superClusterRef()) {
3928  reco::PFCandidatePhotonExtraRef theRef(ph_extrah,pcextra);
3929  (*pfCandidates_)[ic].setPFPhotonExtraRef(theRef);
3930  found = true;
3931  break;
3932  }
3933  }
3934  if(!found)
3935  (*pfCandidates_)[ic].setPFPhotonExtraRef((PFCandidatePhotonExtraRef())); // null ref
3936  }
3937  else {
3938  (*pfCandidates_)[ic].setPFPhotonExtraRef((PFCandidatePhotonExtraRef())); // null ref
3939  }
3940  }
3941  }
3942 }
size
Write out results.
edm::Ref< PFCandidatePhotonExtraCollection > PFCandidatePhotonExtraRef
persistent reference to a PFCandidatePhotonExtra
std::unique_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:289
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
the extra photon collection
Definition: PFAlgo.h:300
bool usePFPhotons_
Definition: PFAlgo.h:348
void PFAlgo::setPostHFCleaningParameters ( bool  postHFCleaning,
double  minHFCleaningPt,
double  minSignificance,
double  maxSignificance,
double  minSignificanceReduction,
double  maxDeltaPhiPt,
double  minDeltaMet 
)

Definition at line 359 of file PFAlgo.cc.

References particleFlow_cfi::maxDeltaPhiPt, maxDeltaPhiPt_, particleFlow_cfi::maxSignificance, maxSignificance_, particleFlow_cfi::minDeltaMet, minDeltaMet_, particleFlow_cfi::minHFCleaningPt, minHFCleaningPt_, particleFlow_cfi::minSignificance, minSignificance_, particleFlow_cfi::minSignificanceReduction, minSignificanceReduction_, particleFlow_cfi::postHFCleaning, and postHFCleaning_.

Referenced by setCandConnectorParameters().

boost::shared_ptr<PFEnergyCalibration> PFAlgo::thePFEnergyCalibration ( )
inline

return the pointer to the calibration function

Definition at line 238 of file PFAlgo.h.

References patPFMETCorrections_cff::algo, calibration_, neutralHadronEnergyResolution(), nSigmaHCAL(), operator<<, MillePedeFileConverter_cfg::out, processBlock(), reconstructCluster(), reconstructTrack(), and setHcalDepthInfo().

Referenced by setCandConnectorParameters().

238  {
239  return calibration_;
240  }
boost::shared_ptr< PFEnergyCalibration > calibration_
Definition: PFAlgo.h:335
std::unique_ptr< reco::PFCandidateCollection> PFAlgo::transferCandidates ( )
inline
Returns
unique_ptr to the collection of candidates (transfers ownership)

Definition at line 233 of file PFAlgo.h.

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

233  {
235  }
std::unique_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:289
std::unique_ptr< reco::PFCandidateCollection > connect(std::unique_ptr< reco::PFCandidateCollection > &pfCand)
PFCandConnector connector_
Definition: PFAlgo.h:393
std::unique_ptr<reco::PFCandidateCollection> PFAlgo::transferCleanedCandidates ( )
inline
Returns
collection of cleaned HF candidates

Definition at line 228 of file PFAlgo.h.

References eostools::move(), and pfCleanedCandidates_.

228  {
230  }
std::unique_ptr< reco::PFCandidateCollection > pfCleanedCandidates_
Definition: PFAlgo.h:295
def move(src, dest)
Definition: eostools.py:511
std::unique_ptr<reco::PFCandidateCollection> PFAlgo::transferElectronCandidates ( )
inline
Returns
the unfiltered electron collection

Definition at line 205 of file PFAlgo.h.

References eostools::move(), and pfElectronCandidates_.

205  {
207  }
std::unique_ptr< reco::PFCandidateCollection > pfElectronCandidates_
the unfiltered electron collection
Definition: PFAlgo.h:291
def move(src, dest)
Definition: eostools.py:511
std::unique_ptr<reco::PFCandidateElectronExtraCollection> PFAlgo::transferElectronExtra ( )
inline
Returns
the unfiltered electron extra collection

Definition at line 211 of file PFAlgo.h.

References pfElectronExtra_, and mps_fire::result.

211  {
212  auto result = std::make_unique<reco::PFCandidateElectronExtraCollection>();
213  result->insert(result->end(),pfElectronExtra_.begin(),pfElectronExtra_.end());
214  return result;
215  }
reco::PFCandidateElectronExtraCollection pfElectronExtra_
the unfiltered electron collection
Definition: PFAlgo.h:298
std::unique_ptr< reco::PFCandidatePhotonExtraCollection> PFAlgo::transferPhotonExtra ( )
inline
Returns
the unfiltered photon extra collection

Definition at line 220 of file PFAlgo.h.

References pfPhotonExtra_, and mps_fire::result.

220  {
221  auto result = std::make_unique<reco::PFCandidatePhotonExtraCollection>();
222  result->insert(result->end(),pfPhotonExtra_.begin(),pfPhotonExtra_.end());
223  return result;
224  }
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
the extra photon collection
Definition: PFAlgo.h:300

Friends And Related Function Documentation

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

Referenced by thePFEnergyCalibration().

Member Data Documentation

int PFAlgo::algo_
private

Definition at line 340 of file PFAlgo.h.

Referenced by setAlgo().

bool PFAlgo::applyCrackCorrectionsElectrons_
private

Definition at line 349 of file PFAlgo.h.

Referenced by setPFEleParameters().

reco::PFBlockHandle PFAlgo::blockHandle_
private

input block handle (full framework case)

Definition at line 327 of file PFAlgo.h.

Referenced by createBlockRef(), and reconstructParticles().

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

Definition at line 335 of file PFAlgo.h.

Referenced by operator<<(), processBlock(), setParameters(), and thePFEnergyCalibration().

double PFAlgo::coneEcalIsoForEgammaSC_
private

Definition at line 355 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::coneTrackIsoForEgammaSC_
private

Definition at line 358 of file PFAlgo.h.

Referenced by setPFEleParameters().

PFCandConnector PFAlgo::connector_
private

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

Definition at line 393 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 388 of file PFAlgo.h.

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

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

Definition at line 401 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

float PFAlgo::goodPixelTrackDeadHcal_chi2n_
private

Definition at line 413 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

float PFAlgo::goodPixelTrackDeadHcal_dxy_
private

Definition at line 416 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

float PFAlgo::goodPixelTrackDeadHcal_dz_
private

Definition at line 417 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

int PFAlgo::goodPixelTrackDeadHcal_maxLost3Hit_
private

Definition at line 414 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

int PFAlgo::goodPixelTrackDeadHcal_maxLost4Hit_
private

Definition at line 415 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

float PFAlgo::goodPixelTrackDeadHcal_maxPt_
private

Definition at line 411 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

float PFAlgo::goodPixelTrackDeadHcal_minEta_
private

Definition at line 410 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

float PFAlgo::goodPixelTrackDeadHcal_ptErrRel_
private

Definition at line 412 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

float PFAlgo::goodTrackDeadHcal_chi2n_
private

Definition at line 405 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

float PFAlgo::goodTrackDeadHcal_dxy_
private

Definition at line 408 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

int PFAlgo::goodTrackDeadHcal_layers_
private

Definition at line 406 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

float PFAlgo::goodTrackDeadHcal_ptErrRel_
private

Variables for track cleaning in bad HCal areas.

Definition at line 404 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

float PFAlgo::goodTrackDeadHcal_validFr_
private

Definition at line 407 of file PFAlgo.h.

Referenced by processBlock(), and setBadHcalTrackParams().

double PFAlgo::maxDeltaPhiPt_
private

Definition at line 427 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::maxSignificance_
private

Definition at line 425 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::minDeltaMet_
private

Definition at line 428 of file PFAlgo.h.

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

double PFAlgo::minHFCleaningPt_
private

Definition at line 423 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::minSignificance_
private

Definition at line 424 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::minSignificanceReduction_
private

Definition at line 426 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

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

Definition at line 397 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

edm::Handle<reco::MuonCollection> PFAlgo::muonHandle_
private

Definition at line 435 of file PFAlgo.h.

Referenced by reconstructParticles(), and setMuonHandle().

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

Variables for muons and fakes.

Definition at line 396 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

std::vector<double> PFAlgo::muonHO_
private

Definition at line 398 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

double PFAlgo::mvaEleCut_
private

Definition at line 346 of file PFAlgo.h.

Referenced by setPFEleParameters().

std::string PFAlgo::mvaWeightFileEleID_
private

Variables for PFElectrons.

Definition at line 344 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::nSigmaECAL_
private

number of sigma to judge energy excess in ECAL

Definition at line 330 of file PFAlgo.h.

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

double PFAlgo::nSigmaHCAL_
private

number of sigma to judge energy excess in HCAL

Definition at line 333 of file PFAlgo.h.

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

double PFAlgo::nSigmaTRACK_
private

Definition at line 399 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

unsigned int PFAlgo::nTrackIsoForEgammaSC_
private

Definition at line 359 of file PFAlgo.h.

Referenced by setPFEleParameters().

int PFAlgo::nVtx_
private

Definition at line 389 of file PFAlgo.h.

Referenced by processBlock(), and setPFVertexParameters().

std::unique_ptr<reco::PFCandidateCollection> PFAlgo::pfCandidates_
protected
std::unique_ptr<reco::PFCandidateCollection> PFAlgo::pfCleanedCandidates_
protected

Definition at line 295 of file PFAlgo.h.

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

PFEGammaFilters* PFAlgo::pfegamma_
private

Definition at line 367 of file PFAlgo.h.

Referenced by processBlock(), setDebug(), setEGammaParameters(), and ~PFAlgo().

const edm::View<reco::PFCandidate>* PFAlgo::pfEgammaCandidates_
private

Definition at line 369 of file PFAlgo.h.

Referenced by processBlock(), and setEGammaCollections().

PFElectronAlgo* PFAlgo::pfele_
private

Definition at line 360 of file PFAlgo.h.

Referenced by processBlock(), setEGElectronCollection(), setPFEleParameters(), and ~PFAlgo().

std::unique_ptr<reco::PFCandidateCollection> PFAlgo::pfElectronCandidates_
protected

the unfiltered electron collection

Definition at line 291 of file PFAlgo.h.

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

reco::PFCandidateElectronExtraCollection PFAlgo::pfElectronExtra_
protected

the unfiltered electron collection

Definition at line 298 of file PFAlgo.h.

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

PFMuonAlgo* PFAlgo::pfmu_
private
PFPhotonAlgo* PFAlgo::pfpho_
private
std::unique_ptr<reco::PFCandidateCollection> PFAlgo::pfPhotonCandidates_
protected

the unfiltered photon collection

Definition at line 293 of file PFAlgo.h.

Referenced by processBlock(), and reconstructParticles().

reco::PFCandidatePhotonExtraCollection PFAlgo::pfPhotonExtra_
protected

the extra photon collection

Definition at line 300 of file PFAlgo.h.

Referenced by processBlock(), reconstructParticles(), setPhotonExtraRef(), and transferPhotonExtra().

bool PFAlgo::postHFCleaning_
private

Definition at line 421 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

bool PFAlgo::postMuonCleaning_
private

Definition at line 422 of file PFAlgo.h.

reco::Vertex PFAlgo::primaryVertex_
private
double PFAlgo::ptError_
private

Definition at line 400 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

bool PFAlgo::rejectTracks_Bad_
private

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

Definition at line 379 of file PFAlgo.h.

Referenced by processBlock(), and setDisplacedVerticesParameters().

bool PFAlgo::rejectTracks_Step45_
private

Definition at line 380 of file PFAlgo.h.

Referenced by processBlock(), and setDisplacedVerticesParameters().

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

Definition at line 345 of file PFAlgo.h.

double PFAlgo::sumEtEcalIsoForEgammaSC_barrel_
private

Definition at line 353 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::sumEtEcalIsoForEgammaSC_endcap_
private

Definition at line 354 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::sumPtTrackIsoForEgammaSC_barrel_
private

Definition at line 356 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::sumPtTrackIsoForEgammaSC_endcap_
private

Definition at line 357 of file PFAlgo.h.

Referenced by setPFEleParameters().

boost::shared_ptr<PFEnergyCalibrationHF> PFAlgo::thepfEnergyCalibrationHF_
private

Definition at line 336 of file PFAlgo.h.

Referenced by processBlock(), and setParameters().

boost::shared_ptr<PFSCEnergyCalibration> PFAlgo::thePFSCEnergyCalibration_
private

Definition at line 337 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::useBestMuonTrack_
private

Definition at line 429 of file PFAlgo.h.

bool PFAlgo::useEGammaFilters_
private

Variables for NEW EGAMMA selection.

Definition at line 366 of file PFAlgo.h.

Referenced by processBlock(), setEGammaCollections(), setEGammaParameters(), and ~PFAlgo().

bool PFAlgo::useEGammaSupercluster_
private

Definition at line 352 of file PFAlgo.h.

Referenced by setPFEleParameters().

bool PFAlgo::useEGElectrons_
private

Definition at line 351 of file PFAlgo.h.

Referenced by setEGElectronCollection(), and setPFEleParameters().

bool PFAlgo::useHO_
private

Definition at line 339 of file PFAlgo.h.

Referenced by processBlock(), and setHOTag().

bool PFAlgo::usePFConversions_
private

Definition at line 383 of file PFAlgo.h.

Referenced by processBlock(), and setDisplacedVerticesParameters().

bool PFAlgo::usePFDecays_
private

Definition at line 384 of file PFAlgo.h.

Referenced by isFromSecInt(), and setDisplacedVerticesParameters().

bool PFAlgo::usePFElectrons_
private

Definition at line 347 of file PFAlgo.h.

Referenced by processBlock(), setElectronExtraRef(), setPFEleParameters(), and ~PFAlgo().

bool PFAlgo::usePFMuonMomAssign_
private

Definition at line 375 of file PFAlgo.h.

bool PFAlgo::usePFNuclearInteractions_
private

Definition at line 382 of file PFAlgo.h.

Referenced by isFromSecInt(), and setDisplacedVerticesParameters().

bool PFAlgo::usePFPhotons_
private
bool PFAlgo::usePFSCEleCalib_
private

Definition at line 350 of file PFAlgo.h.

Referenced by setPFEleParameters().

bool PFAlgo::useProtectionsForJetMET_
private

Definition at line 368 of file PFAlgo.h.

Referenced by processBlock(), and setEGammaParameters().

bool PFAlgo::useVertices_
private

Definition at line 433 of file PFAlgo.h.

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

const edm::ValueMap<reco::GsfElectronRef>* PFAlgo::valueMapGedElectrons_
private

Definition at line 370 of file PFAlgo.h.

Referenced by setEGammaCollections().

const edm::ValueMap<reco::PhotonRef>* PFAlgo::valueMapGedPhotons_
private

Definition at line 371 of file PFAlgo.h.

Referenced by setEGammaCollections().