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 3566 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().

3572  {
3573 
3574  // Find all PS clusters with type psElement associated to ECAL cluster iEcal,
3575  // within all PFBlockElement "elements" of a given PFBlock "block"
3576  // psElement can be reco::PFBlockElement::PS1 or reco::PFBlockElement::PS2
3577  // Returns a vector of PS cluster energies, and updates the "active" vector.
3578 
3579  // Find all PS clusters linked to the iEcal cluster
3580  std::multimap<double, unsigned> sortedPS;
3581  typedef std::multimap<double, unsigned>::iterator IE;
3582  block.associatedElements( iEcal, linkData,
3583  sortedPS, psElementType,
3585 
3586  // Loop over these PS clusters
3587  double totalPS = 0.;
3588  for ( IE ips=sortedPS.begin(); ips!=sortedPS.end(); ++ips ) {
3589 
3590  // CLuster index and distance to iEcal
3591  unsigned iPS = ips->second;
3592  // double distPS = ips->first;
3593 
3594  // Ignore clusters already in use
3595  if (!active[iPS]) continue;
3596 
3597  // Check that this cluster is not closer to another ECAL cluster
3598  std::multimap<double, unsigned> sortedECAL;
3599  block.associatedElements( iPS, linkData,
3600  sortedECAL,
3603  unsigned jEcal = sortedECAL.begin()->second;
3604  if ( jEcal != iEcal ) continue;
3605 
3606  // Update PS energy
3607  PFBlockElement::Type pstype = elements[ iPS ].type();
3608  assert( pstype == psElementType );
3609  PFClusterRef psclusterref = elements[iPS].clusterRef();
3610  assert(!psclusterref.isNull() );
3611  totalPS += psclusterref->energy();
3612  psEne[0] += psclusterref->energy();
3613  active[iPS] = false;
3614  }
3615 
3616 
3617 }
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 3764 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().

3764  {
3765 
3766 
3767  // No hits to recover, leave.
3768  if ( cleanedHits.empty() ) return;
3769 
3770  //Compute met and met significance (met/sqrt(SumEt))
3771  double metX = 0.;
3772  double metY = 0.;
3773  double sumet = 0;
3774  std::vector<unsigned int> hitsToBeAdded;
3775  for(unsigned i=0; i<pfCandidates_->size(); i++) {
3776  const PFCandidate& pfc = (*pfCandidates_)[i];
3777  metX += pfc.px();
3778  metY += pfc.py();
3779  sumet += pfc.pt();
3780  }
3781  double met2 = metX*metX+metY*metY;
3782  double met2_Original = met2;
3783  // Select events with large MET significance.
3784  // double significance = std::sqrt(met2/sumet);
3785  // double significanceCor = significance;
3786  double metXCor = metX;
3787  double metYCor = metY;
3788  double sumetCor = sumet;
3789  double met2Cor = met2;
3790  bool next = true;
3791  unsigned iCor = 1E9;
3792 
3793  // Find the cleaned hit with the largest effect on the MET
3794  while ( next ) {
3795 
3796  double metReduc = -1.;
3797  // Loop on the candidates
3798  for(unsigned i=0; i<cleanedHits.size(); ++i) {
3799  const PFRecHit& hit = cleanedHits[i];
3800  double length = std::sqrt(hit.position().mag2());
3801  double px = hit.energy() * hit.position().x()/length;
3802  double py = hit.energy() * hit.position().y()/length;
3803  double pt = std::sqrt(px*px + py*py);
3804 
3805  // Check that it is not already scheculed to be cleaned
3806  bool skip = false;
3807  for(unsigned j=0; j<hitsToBeAdded.size(); ++j) {
3808  if ( i == hitsToBeAdded[j] ) skip = true;
3809  if ( skip ) break;
3810  }
3811  if ( skip ) continue;
3812 
3813  // Now add the candidate to the MET
3814  double metXInt = metX + px;
3815  double metYInt = metY + py;
3816  double sumetInt = sumet + pt;
3817  double met2Int = metXInt*metXInt+metYInt*metYInt;
3818 
3819  // And check if it could contribute to a MET reduction
3820  if ( met2Int < met2Cor ) {
3821  metXCor = metXInt;
3822  metYCor = metYInt;
3823  metReduc = (met2-met2Int)/met2Int;
3824  met2Cor = met2Int;
3825  sumetCor = sumetInt;
3826  // significanceCor = std::sqrt(met2Cor/sumetCor);
3827  iCor = i;
3828  }
3829  }
3830  //
3831  // If the MET must be significanly reduced, schedule the candidate to be added
3832  //
3833  if ( metReduc > minDeltaMet_ ) {
3834  hitsToBeAdded.push_back(iCor);
3835  metX = metXCor;
3836  metY = metYCor;
3837  sumet = sumetCor;
3838  met2 = met2Cor;
3839  } else {
3840  // Otherwise just stop the loop
3841  next = false;
3842  }
3843  }
3844  //
3845  // At least 10 GeV MET reduction
3846  if ( std::sqrt(met2_Original) - std::sqrt(met2) > 5. ) {
3847  if ( debug_ ) {
3848  std::cout << hitsToBeAdded.size() << " hits were re-added " << std::endl;
3849  std::cout << "MET reduction = " << std::sqrt(met2_Original) << " -> "
3850  << std::sqrt(met2Cor) << " = " << std::sqrt(met2Cor) - std::sqrt(met2_Original)
3851  << std::endl;
3852  std::cout << "Added after cleaning check : " << std::endl;
3853  }
3854  for(unsigned j=0; j<hitsToBeAdded.size(); ++j) {
3855  const PFRecHit& hit = cleanedHits[hitsToBeAdded[j]];
3856  PFCluster cluster(hit.layer(), hit.energy(),
3857  hit.position().x(), hit.position().y(), hit.position().z() );
3858  reconstructCluster(cluster,hit.energy());
3859  if ( debug_ ) {
3860  std::cout << pfCandidates_->back() << ". time = " << hit.time() << std::endl;
3861  }
3862  }
3863  }
3864 
3865 }
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:3357
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 3554 of file PFAlgo.cc.

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

Referenced by reconstructParticles().

3555  {
3556 
3557  if( blockHandle_.isValid() ) {
3558  return reco::PFBlockRef( blockHandle_, bi );
3559  }
3560  else {
3561  return reco::PFBlockRef( &blocks, bi );
3562  }
3563 }
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 3621 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().

3621  {
3622 
3625  // reco::PFBlockElement::TrackType T_FROM_GAMMACONV = reco::PFBlockElement::T_FROM_GAMMACONV;
3627 
3628  bool bPrimary = (order.find("primary") != string::npos);
3629  bool bSecondary = (order.find("secondary") != string::npos);
3630  bool bAll = (order.find("all") != string::npos);
3631 
3632  bool isToDisp = usePFNuclearInteractions_ && eTrack.trackType(T_TO_DISP);
3633  bool isFromDisp = usePFNuclearInteractions_ && eTrack.trackType(T_FROM_DISP);
3634 
3635  if (bPrimary && isToDisp) return true;
3636  if (bSecondary && isFromDisp ) return true;
3637  if (bAll && ( isToDisp || isFromDisp ) ) return true;
3638 
3639 // bool isFromConv = usePFConversions_ && eTrack.trackType(T_FROM_GAMMACONV);
3640 
3641 // if ((bAll || bSecondary)&& isFromConv) return true;
3642 
3643  bool isFromDecay = (bAll || bSecondary) && usePFDecays_ && eTrack.trackType(T_FROM_V0);
3644 
3645  return isFromDecay;
3646 
3647 
3648 }
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 3502 of file PFAlgo.cc.

References mathSSE::sqrt().

Referenced by processBlock(), and thePFEnergyCalibration().

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

Definition at line 3517 of file PFAlgo.cc.

References JetChargeProducer_cfi::exp, and nSigmaHCAL_.

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

3517  {
3518  double nS = fabs(eta) < 1.48 ?
3519  nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.))
3520  :
3521  nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.));
3522 
3523  return nS;
3524 }
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 3657 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().

3657  {
3658 
3659  // Check if the post HF Cleaning was requested - if not, do nothing
3660  if ( !postHFCleaning_ ) return;
3661 
3662  //Compute met and met significance (met/sqrt(SumEt))
3663  double metX = 0.;
3664  double metY = 0.;
3665  double sumet = 0;
3666  std::vector<unsigned int> pfCandidatesToBeRemoved;
3667  for(unsigned i=0; i<pfCandidates_->size(); i++) {
3668  const PFCandidate& pfc = (*pfCandidates_)[i];
3669  metX += pfc.px();
3670  metY += pfc.py();
3671  sumet += pfc.pt();
3672  }
3673  double met2 = metX*metX+metY*metY;
3674  // Select events with large MET significance.
3675  double significance = std::sqrt(met2/sumet);
3676  double significanceCor = significance;
3677  if ( significance > minSignificance_ ) {
3678 
3679  double metXCor = metX;
3680  double metYCor = metY;
3681  double sumetCor = sumet;
3682  double met2Cor = met2;
3683  double deltaPhi = 3.14159;
3684  double deltaPhiPt = 100.;
3685  bool next = true;
3686  unsigned iCor = 1E9;
3687 
3688  // Find the HF candidate with the largest effect on the MET
3689  while ( next ) {
3690 
3691  double metReduc = -1.;
3692  // Loop on the candidates
3693  for(unsigned i=0; i<pfCandidates_->size(); ++i) {
3694  const PFCandidate& pfc = (*pfCandidates_)[i];
3695 
3696  // Check that the pfCandidate is in the HF
3697  if ( pfc.particleId() != reco::PFCandidate::h_HF &&
3698  pfc.particleId() != reco::PFCandidate::egamma_HF ) continue;
3699 
3700  // Check if has meaningful pt
3701  if ( pfc.pt() < minHFCleaningPt_ ) continue;
3702 
3703  // Check that it is not already scheculed to be cleaned
3704  bool skip = false;
3705  for(unsigned j=0; j<pfCandidatesToBeRemoved.size(); ++j) {
3706  if ( i == pfCandidatesToBeRemoved[j] ) skip = true;
3707  if ( skip ) break;
3708  }
3709  if ( skip ) continue;
3710 
3711  // Check that the pt and the MET are aligned
3712  deltaPhi = std::acos((metX*pfc.px()+metY*pfc.py())/(pfc.pt()*std::sqrt(met2)));
3713  deltaPhiPt = deltaPhi*pfc.pt();
3714  if ( deltaPhiPt > maxDeltaPhiPt_ ) continue;
3715 
3716  // Now remove the candidate from the MET
3717  double metXInt = metX - pfc.px();
3718  double metYInt = metY - pfc.py();
3719  double sumetInt = sumet - pfc.pt();
3720  double met2Int = metXInt*metXInt+metYInt*metYInt;
3721  if ( met2Int < met2Cor ) {
3722  metXCor = metXInt;
3723  metYCor = metYInt;
3724  metReduc = (met2-met2Int)/met2Int;
3725  met2Cor = met2Int;
3726  sumetCor = sumetInt;
3727  significanceCor = std::sqrt(met2Cor/sumetCor);
3728  iCor = i;
3729  }
3730  }
3731  //
3732  // If the MET must be significanly reduced, schedule the candidate to be cleaned
3733  if ( metReduc > minDeltaMet_ ) {
3734  pfCandidatesToBeRemoved.push_back(iCor);
3735  metX = metXCor;
3736  metY = metYCor;
3737  sumet = sumetCor;
3738  met2 = met2Cor;
3739  } else {
3740  // Otherwise just stop the loop
3741  next = false;
3742  }
3743  }
3744  //
3745  // The significance must be significantly reduced to indeed clean the candidates
3746  if ( significance - significanceCor > minSignificanceReduction_ &&
3747  significanceCor < maxSignificance_ ) {
3748  std::cout << "Significance reduction = " << significance << " -> "
3749  << significanceCor << " = " << significanceCor - significance
3750  << std::endl;
3751  for(unsigned j=0; j<pfCandidatesToBeRemoved.size(); ++j) {
3752  std::cout << "Removed : " << (*pfCandidates_)[pfCandidatesToBeRemoved[j]] << std::endl;
3753  pfCleanedCandidates_->push_back( (*pfCandidates_)[ pfCandidatesToBeRemoved[j] ] );
3754  (*pfCandidates_)[pfCandidatesToBeRemoved[j]].rescaleMomentum(1E-6);
3755  //reco::PFCandidate::ParticleType unknown = reco::PFCandidate::X;
3756  //(*pfCandidates_)[pfCandidatesToBeRemoved[j]].setParticleType(unknown);
3757  }
3758  }
3759  }
3760 
3761 }
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 = make_pair(iHcal,::math::XYZVector(0.,0.,0.));
1855  ecalSatellites.insert( make_pair(-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 = make_pair(iTrack,thisIsALooseMuon);
2108  associatedTracks.insert( make_pair(-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 =
2171  make_pair(iEcal,ecalEnergyCalibrated*photonDirection);
2172  ecalSatellites.insert( make_pair(-1., satellite) );
2173 
2174  } else { // Keep satellite clusters for later
2175 
2176  std::pair<unsigned,::math::XYZVector> satellite =
2177  make_pair(iEcal,ecalEnergyCalibrated*photonDirection);
2178  ecalSatellites.insert( make_pair(dist, satellite) );
2179 
2180  }
2181 
2182  std::pair<double, unsigned> associatedEcal
2183  = make_pair( distEcal, iEcal );
2184  associatedEcals.insert( make_pair(iTrack, associatedEcal) );
2185 
2186  } // End loop ecal associated to iTrack
2187  } // end case: at least one ecal element associated to iTrack
2188 
2189  if( useHO_ && !sortedHOs.empty() )
2190  { // start case: at least one ho element associated to iTrack
2191 
2192  // Loop over all connected HO clusters
2193  for ( IE ieho=sortedHOs.begin(); ieho!=sortedHOs.end(); ++ieho ) {
2194 
2195  unsigned iHO = ieho->second;
2196  double distHO = ieho->first;
2197 
2198  // Ignore HO cluters already used
2199  if( !active[iHO] ) {
2200  if(debug_) cout<<"\t\tcluster locked"<<endl;
2201  continue;
2202  }
2203 
2204  // Sanity checks
2205  PFBlockElement::Type type = elements[ iHO ].type();
2206  assert( type == PFBlockElement::HO );
2207  PFClusterRef hoclusterref = elements[iHO].clusterRef();
2208  assert(!hoclusterref.isNull() );
2209 
2210  // Check if this HO is not closer to another track - ignore it in that case
2211  std::multimap<double, unsigned> sortedTracksHO;
2212  block.associatedElements( iHO, linkData,
2213  sortedTracksHO,
2216  unsigned jTrack = sortedTracksHO.begin()->second;
2217  if ( jTrack != iTrack ) continue;
2218 
2219  // double chi2HO = block.chi2(jTrack,iHO,linkData,
2220  // reco::PFBlock::LINKTEST_ALL);
2221  //double distHO = block.dist(jTrack,iHO,linkData,
2222  // reco::PFBlock::LINKTEST_ALL);
2223 
2224  // Increment the total energy by the energy of this HO cluster
2225  totalHO += hoclusterref->energy();
2226  active[iHO] = false;
2227  // Keep track for later reference in the PFCandidate.
2228  std::pair<double, unsigned> associatedHO
2229  = make_pair( distHO, iHO );
2230  associatedHOs.insert( make_pair(iTrack, associatedHO) );
2231 
2232  } // End loop ho associated to iTrack
2233  } // end case: at least one ho element associated to iTrack
2234 
2235 
2236  } // end loop on tracks associated to hcal element iHcal
2237 
2238  // Include totalHO in totalHCAL for the time being (it will be calibrated as HCAL energy)
2239  totalHcal += totalHO;
2240 
2241  // test compatibility between calo and tracker. //////////////
2242 
2243  double caloEnergy = 0.;
2244  double slopeEcal = 1.0;
2245  double calibEcal = 0.;
2246  double calibHcal = 0.;
2247  hadronDirection = hadronAtECAL.Unit();
2248 
2249  // Determine the expected calo resolution from the total charged momentum
2250  double Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2251  Caloresolution *= totalChargedMomentum;
2252  // Account for muons
2253  Caloresolution = std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2254  totalEcal -= std::min(totalEcal,muonECALEnergy);
2255  totalHcal -= std::min(totalHcal,muonHCALEnergy);
2256  if ( totalEcal < 1E-9 ) photonAtECAL = ::math::XYZVector(0.,0.,0.);
2257  if ( totalHcal < 1E-9 ) hadronAtECAL = ::math::XYZVector(0.,0.,0.);
2258 
2259  // Loop over all ECAL satellites, starting for the closest to the various tracks
2260  // and adding other satellites until saturation of the total track momentum
2261  // Note : for code simplicity, the first element of the loop is the HCAL cluster
2262  // with 0 energy in the ECAL
2263  for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
2264 
2265  // Add the energy of this ECAL cluster
2266  double previousCalibEcal = calibEcal;
2267  double previousCalibHcal = calibHcal;
2268  double previousCaloEnergy = caloEnergy;
2269  double previousSlopeEcal = slopeEcal;
2270  ::math::XYZVector previousHadronAtECAL = hadronAtECAL;
2271  //
2272  totalEcal += sqrt(is->second.second.Mag2());
2273  photonAtECAL += is->second.second;
2274  calibEcal = std::max(0.,totalEcal);
2275  calibHcal = std::max(0.,totalHcal);
2276  hadronAtECAL = calibHcal * hadronDirection;
2277  // Calibrate ECAL and HCAL energy under the hadron hypothesis.
2278  calibration_->energyEmHad(totalChargedMomentum,calibEcal,calibHcal,
2279  hclusterref->positionREP().Eta(),
2280  hclusterref->positionREP().Phi());
2281  caloEnergy = calibEcal+calibHcal;
2282  if ( totalEcal > 0.) slopeEcal = calibEcal/totalEcal;
2283 
2284  hadronAtECAL = calibHcal * hadronDirection;
2285 
2286  // Continue looping until all closest clusters are exhausted and as long as
2287  // the calorimetric energy does not saturate the total momentum.
2288  if ( is->first < 0. || caloEnergy - totalChargedMomentum <= 0. ) {
2289  if(debug_) cout<<"\t\t\tactive, adding "<<is->second.second
2290  <<" to ECAL energy, and locking"<<endl;
2291  active[is->second.first] = false;
2292  double clusterEnergy=sqrt(is->second.second.Mag2());
2293  if(clusterEnergy>50) {
2294  ecalClusters.push_back(is->second);
2295  sumEcalClusters+=clusterEnergy;
2296  }
2297  continue;
2298  }
2299 
2300  // Otherwise, do not consider the last cluster examined and exit.
2301  // active[is->second.first] = true;
2302  totalEcal -= sqrt(is->second.second.Mag2());
2303  photonAtECAL -= is->second.second;
2304  calibEcal = previousCalibEcal;
2305  calibHcal = previousCalibHcal;
2306  hadronAtECAL = previousHadronAtECAL;
2307  slopeEcal = previousSlopeEcal;
2308  caloEnergy = previousCaloEnergy;
2309 
2310  break;
2311 
2312  }
2313 
2314  // Sanity check !
2315  assert(caloEnergy>=0);
2316 
2317 
2318  // And now check for hadronic energy excess...
2319 
2320  //colin: resolution should be measured on the ecal+hcal case.
2321  // however, the result will be close.
2322  // double Caloresolution = neutralHadronEnergyResolution( caloEnergy );
2323  // Caloresolution *= caloEnergy;
2324  // PJ The resolution is on the expected charged calo energy !
2325  //double Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2326  //Caloresolution *= totalChargedMomentum;
2327  // that of the charged particles linked to the cluster!
2328 
2329  /* */
2331  if ( totalChargedMomentum - caloEnergy > nSigmaTRACK_*Caloresolution ) {
2332 
2333  /*
2334  cout<<"\tCompare Calo Energy to total charged momentum "<<endl;
2335  cout<<"\t\tsum p = "<<totalChargedMomentum<<" +- "<<sqrt(sumpError2)<<endl;
2336  cout<<"\t\tsum ecal = "<<totalEcal<<endl;
2337  cout<<"\t\tsum hcal = "<<totalHcal<<endl;
2338  cout<<"\t\t => Calo Energy = "<<caloEnergy<<" +- "<<Caloresolution<<endl;
2339  cout<<"\t\t => Calo Energy- total charged momentum = "
2340  <<caloEnergy-totalChargedMomentum<<" +- "<<TotalError<<endl;
2341  cout<<endl;
2342  cout << "\t\tNumber/momentum of muons found in the block : " << nMuons << std::endl;
2343  */
2344  // First consider loose muons
2345  if ( nMuons > 0 ) {
2346  for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2347  unsigned iTrack = it->second.first;
2348  // Only active tracks
2349  if ( !active[iTrack] ) continue;
2350  // Only muons
2351  if ( !it->second.second ) continue;
2352 
2353  double trackMomentum = elements[it->second.first].trackRef()->p();
2354 
2355  // look for ECAL elements associated to iTrack (associated to iHcal)
2356  std::multimap<double, unsigned> sortedEcals;
2357  block.associatedElements( iTrack, linkData,
2358  sortedEcals,
2361  std::multimap<double, unsigned> sortedHOs;
2362  block.associatedElements( iTrack, linkData,
2363  sortedHOs,
2366 
2367  //Here allow for loose muons!
2368  unsigned tmpi = reconstructTrack( elements[iTrack],true);
2369 
2370  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2371  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2372  double muonHcal = std::min(muonHCAL_[0]+muonHCAL_[1],totalHcal-totalHO);
2373  double muonHO = 0.;
2374  (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal,muonHcal);
2375  if( !sortedEcals.empty() ) {
2376  unsigned iEcal = sortedEcals.begin()->second;
2377  PFClusterRef eclusterref = elements[iEcal].clusterRef();
2378  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
2379  double muonEcal = std::min(muonECAL_[0]+muonECAL_[1],eclusterref->energy());
2380  (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(),muonEcal);
2381  }
2382  if( useHO_ && !sortedHOs.empty() ) {
2383  unsigned iHO = sortedHOs.begin()->second;
2384  PFClusterRef hoclusterref = elements[iHO].clusterRef();
2385  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
2386  muonHO = std::min(muonHO_[0]+muonHO_[1],hoclusterref->energy());
2387  (*pfCandidates_)[tmpi].setHcalEnergy(max(totalHcal-totalHO,0.0),muonHcal);
2388  (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(),muonHO);
2389  }
2390  setHcalDepthInfo((*pfCandidates_)[tmpi], *hclusterref);
2391  // Remove it from the block
2392  const ::math::XYZPointF& chargedPosition =
2393  dynamic_cast<const reco::PFBlockElementTrack*>(&elements[it->second.first])->positionAtECALEntrance();
2394  ::math::XYZVector chargedDirection(chargedPosition.X(), chargedPosition.Y(), chargedPosition.Z());
2395  chargedDirection = chargedDirection.Unit();
2396  totalChargedMomentum -= trackMomentum;
2397  // Update the calo energies
2398  if ( totalEcal > 0. )
2399  calibEcal -= std::min(calibEcal,muonECAL_[0]*calibEcal/totalEcal);
2400  if ( totalHcal > 0. )
2401  calibHcal -= std::min(calibHcal,muonHCAL_[0]*calibHcal/totalHcal);
2402  totalEcal -= std::min(totalEcal,muonECAL_[0]);
2403  totalHcal -= std::min(totalHcal,muonHCAL_[0]);
2404  if ( totalEcal > muonECAL_[0] ) photonAtECAL -= muonECAL_[0] * chargedDirection;
2405  if ( totalHcal > muonHCAL_[0] ) hadronAtECAL -= muonHCAL_[0]*calibHcal/totalHcal * chargedDirection;
2406  caloEnergy = calibEcal+calibHcal;
2407  muonHCALEnergy += muonHCAL_[0];
2408  muonHCALError += muonHCAL_[1]*muonHCAL_[1];
2409  if ( muonHO > 0. ) {
2410  muonHCALEnergy += muonHO_[0];
2411  muonHCALError += muonHO_[1]*muonHO_[1];
2412  if ( totalHcal > 0. ) {
2413  calibHcal -= std::min(calibHcal,muonHO_[0]*calibHcal/totalHcal);
2414  totalHcal -= std::min(totalHcal,muonHO_[0]);
2415  }
2416  }
2417  muonECALEnergy += muonECAL_[0];
2418  muonECALError += muonECAL_[1]*muonECAL_[1];
2419  active[iTrack] = false;
2420  // Stop the loop whenever enough muons are removed
2421  //Commented out: Keep looking for muons since they often come in pairs -Matt
2422  //if ( totalChargedMomentum < caloEnergy ) break;
2423  }
2424  // New calo resolution.
2425  Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2426  Caloresolution *= totalChargedMomentum;
2427  Caloresolution = std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2428  }
2429  }
2430 
2431  if(debug_){
2432  cout<<"\tBefore Cleaning "<<endl;
2433  cout<<"\tCompare Calo Energy to total charged momentum "<<endl;
2434  cout<<"\t\tsum p = "<<totalChargedMomentum<<" +- "<<sqrt(sumpError2)<<endl;
2435  cout<<"\t\tsum ecal = "<<totalEcal<<endl;
2436  cout<<"\t\tsum hcal = "<<totalHcal<<endl;
2437  cout<<"\t\t => Calo Energy = "<<caloEnergy<<" +- "<<Caloresolution<<endl;
2438  cout<<"\t\t => Calo Energy- total charged momentum = "
2439  <<caloEnergy-totalChargedMomentum<<" +- "<<sqrt(sumpError2 + Caloresolution*Caloresolution)<<endl;
2440  cout<<endl;
2441  }
2442 
2443 
2444  // Second consider bad tracks (if still needed after muon removal)
2445  unsigned corrTrack = 10000000;
2446  double corrFact = 1.;
2447 
2448  if (rejectTracks_Bad_ &&
2449  totalChargedMomentum - caloEnergy > nSigmaTRACK_*Caloresolution) {
2450 
2451  for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2452  unsigned iTrack = it->second.first;
2453  // Only active tracks
2454  if ( !active[iTrack] ) continue;
2455  const reco::TrackRef& trackref = elements[it->second.first].trackRef();
2456 
2457  double dptRel = fabs(it->first)/trackref->pt()*100;
2458  bool isSecondary = isFromSecInt(elements[iTrack], "secondary");
2459  bool isPrimary = isFromSecInt(elements[iTrack], "primary");
2460 
2461  if ( isSecondary && dptRel < dptRel_DispVtx_ ) continue;
2462  // Consider only bad tracks
2463  if ( fabs(it->first) < ptError_ ) break;
2464  // What would become the block charged momentum if this track were removed
2465  double wouldBeTotalChargedMomentum =
2466  totalChargedMomentum - trackref->p();
2467  // Reject worst tracks, as long as the total charged momentum
2468  // is larger than the calo energy
2469 
2470  if ( wouldBeTotalChargedMomentum > caloEnergy ) {
2471 
2472  if (debug_ && isSecondary) {
2473  cout << "In bad track rejection step dptRel = " << dptRel << " dptRel_DispVtx_ = " << dptRel_DispVtx_ << endl;
2474  cout << "The calo energy would be still smaller even without this track but it is attached to a NI"<< endl;
2475  }
2476 
2477 
2478  if(isPrimary || (isSecondary && dptRel < dptRel_DispVtx_)) continue;
2479  active[iTrack] = false;
2480  totalChargedMomentum = wouldBeTotalChargedMomentum;
2481  if ( debug_ )
2482  std::cout << "\tElement " << elements[iTrack]
2483  << " rejected (Dpt = " << -it->first
2484  << " GeV/c, algo = " << trackref->algo() << ")" << std::endl;
2485  // Just rescale the nth worst track momentum to equalize the calo energy
2486  } else {
2487  if(isPrimary) break;
2488  corrTrack = iTrack;
2489  corrFact = (caloEnergy - wouldBeTotalChargedMomentum)/elements[it->second.first].trackRef()->p();
2490  if ( trackref->p()*corrFact < 0.05 ) {
2491  corrFact = 0.;
2492  active[iTrack] = false;
2493  }
2494  totalChargedMomentum -= trackref->p()*(1.-corrFact);
2495  if ( debug_ )
2496  std::cout << "\tElement " << elements[iTrack]
2497  << " (Dpt = " << -it->first
2498  << " GeV/c, algo = " << trackref->algo()
2499  << ") rescaled by " << corrFact
2500  << " Now the total charged momentum is " << totalChargedMomentum << endl;
2501  break;
2502  }
2503  }
2504  }
2505 
2506  // New determination of the calo and track resolution avec track deletion/rescaling.
2507  Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2508  Caloresolution *= totalChargedMomentum;
2509  Caloresolution = std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2510 
2511  // Check if the charged momentum is still very inconsistent with the calo measurement.
2512  // In this case, just drop all tracks from 4th and 5th iteration linked to this block
2513 
2514  if ( rejectTracks_Step45_ &&
2515  sortedTracks.size() > 1 &&
2516  totalChargedMomentum - caloEnergy > nSigmaTRACK_*Caloresolution ) {
2517  for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2518  unsigned iTrack = it->second.first;
2519  reco::TrackRef trackref = elements[iTrack].trackRef();
2520  if ( !active[iTrack] ) continue;
2521 
2522  double dptRel = fabs(it->first)/trackref->pt()*100;
2523  bool isPrimaryOrSecondary = isFromSecInt(elements[iTrack], "all");
2524 
2525 
2526 
2527 
2528  if (isPrimaryOrSecondary && dptRel < dptRel_DispVtx_) continue;
2529 
2530  if (PFTrackAlgoTools::step5(trackref->algo())) {
2531  active[iTrack] = false;
2532  totalChargedMomentum -= trackref->p();
2533 
2534  if ( debug_ )
2535  std::cout << "\tElement " << elements[iTrack]
2536  << " rejected (Dpt = " << -it->first
2537  << " GeV/c, algo = " << trackref->algo() << ")" << std::endl;
2538 
2539  }
2540  }
2541 
2542  }
2543 
2544  // New determination of the calo and track resolution avec track deletion/rescaling.
2545  Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2546  Caloresolution *= totalChargedMomentum;
2547  Caloresolution = std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2548 
2549  // Make PF candidates with the remaining tracks in the block
2550  sumpError2 = 0.;
2551  for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2552  unsigned iTrack = it->second.first;
2553  if ( !active[iTrack] ) continue;
2554  reco::TrackRef trackRef = elements[iTrack].trackRef();
2555  double trackMomentum = trackRef->p();
2556  double Dp = trackRef->qoverpError()*trackMomentum*trackMomentum;
2557  unsigned tmpi = reconstructTrack( elements[iTrack] );
2558 
2559 
2560  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2561  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2562  setHcalDepthInfo((*pfCandidates_)[tmpi], *hclusterref);
2563  std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2564  for (II ii=myEcals.first; ii!=myEcals.second; ++ii ) {
2565  unsigned iEcal = ii->second.second;
2566  if ( active[iEcal] ) continue;
2567  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2568  }
2569 
2570  if (useHO_) {
2571  std::pair<II,II> myHOs = associatedHOs.equal_range(iTrack);
2572  for (II ii=myHOs.first; ii!=myHOs.second; ++ii ) {
2573  unsigned iHO = ii->second.second;
2574  if ( active[iHO] ) continue;
2575  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO );
2576  }
2577  }
2578 
2579  if ( iTrack == corrTrack ) {
2580  (*pfCandidates_)[tmpi].rescaleMomentum(corrFact);
2581  trackMomentum *= corrFact;
2582  }
2583  chargedHadronsIndices.push_back( tmpi );
2584  chargedHadronsInBlock.push_back( iTrack );
2585  active[iTrack] = false;
2586  hcalP.push_back(trackMomentum);
2587  hcalDP.push_back(Dp);
2588  if (Dp/trackMomentum > maxDPovP) maxDPovP = Dp/trackMomentum;
2589  sumpError2 += Dp*Dp;
2590  }
2591 
2592  // The total uncertainty of the difference Calo-Track
2593  double TotalError = sqrt(sumpError2 + Caloresolution*Caloresolution);
2594 
2595  if ( debug_ ) {
2596  cout<<"\tCompare Calo Energy to total charged momentum "<<endl;
2597  cout<<"\t\tsum p = "<<totalChargedMomentum<<" +- "<<sqrt(sumpError2)<<endl;
2598  cout<<"\t\tsum ecal = "<<totalEcal<<endl;
2599  cout<<"\t\tsum hcal = "<<totalHcal<<endl;
2600  cout<<"\t\t => Calo Energy = "<<caloEnergy<<" +- "<<Caloresolution<<endl;
2601  cout<<"\t\t => Calo Energy- total charged momentum = "
2602  <<caloEnergy-totalChargedMomentum<<" +- "<<TotalError<<endl;
2603  cout<<endl;
2604  }
2605 
2606  /* */
2607 
2609  double nsigma = nSigmaHCAL(totalChargedMomentum,hclusterref->positionREP().Eta());
2610  //double nsigma = nSigmaHCAL(caloEnergy,hclusterref->positionREP().Eta());
2611  if ( abs(totalChargedMomentum-caloEnergy)<nsigma*TotalError ) {
2612 
2613  // deposited caloEnergy compatible with total charged momentum
2614  // if tracking errors are large take weighted average
2615 
2616  if(debug_) {
2617  cout<<"\t\tcase 1: COMPATIBLE "
2618  <<"|Calo Energy- total charged momentum| = "
2619  <<abs(caloEnergy-totalChargedMomentum)
2620  <<" < "<<nsigma<<" x "<<TotalError<<endl;
2621  if (maxDPovP < 0.1 )
2622  cout<<"\t\t\tmax DP/P = "<< maxDPovP
2623  <<" less than 0.1: do nothing "<<endl;
2624  else
2625  cout<<"\t\t\tmax DP/P = "<< maxDPovP
2626  <<" > 0.1: take weighted averages "<<endl;
2627  }
2628 
2629  // if max DP/P < 10% do nothing
2630  if (maxDPovP > 0.1) {
2631 
2632  // for each track associated to hcal
2633  // int nrows = tkIs.size();
2634  int nrows = chargedHadronsIndices.size();
2635  TMatrixTSym<double> a (nrows);
2636  TVectorD b (nrows);
2637  TVectorD check(nrows);
2638  double sigma2E = Caloresolution*Caloresolution;
2639  for(int i=0; i<nrows; i++) {
2640  double sigma2i = hcalDP[i]*hcalDP[i];
2641  if (debug_){
2642  cout<<"\t\t\ttrack associated to hcal "<<i
2643  <<" P = "<<hcalP[i]<<" +- "
2644  <<hcalDP[i]<<endl;
2645  }
2646  a(i,i) = 1./sigma2i + 1./sigma2E;
2647  b(i) = hcalP[i]/sigma2i + caloEnergy/sigma2E;
2648  for(int j=0; j<nrows; j++) {
2649  if (i==j) continue;
2650  a(i,j) = 1./sigma2E;
2651  } // end loop on j
2652  } // end loop on i
2653 
2654  // solve ax = b
2655  //if (debug_){// debug1
2656  //cout<<" matrix a(i,j) "<<endl;
2657  //a.Print();
2658  //cout<<" vector b(i) "<<endl;
2659  //b.Print();
2660  //} // debug1
2661  TDecompChol decomp(a);
2662  bool ok = false;
2663  TVectorD x = decomp.Solve(b, ok);
2664  // for each track create a PFCandidate track
2665  // with a momentum rescaled to weighted average
2666  if (ok) {
2667  for (int i=0; i<nrows; i++){
2668  // unsigned iTrack = trackInfos[i].index;
2669  unsigned ich = chargedHadronsIndices[i];
2670  double rescaleFactor = x(i)/hcalP[i];
2671  (*pfCandidates_)[ich].rescaleMomentum( rescaleFactor );
2672 
2673  if(debug_){
2674  cout<<"\t\t\told p "<<hcalP[i]
2675  <<" new p "<<x(i)
2676  <<" rescale "<<rescaleFactor<<endl;
2677  }
2678  }
2679  }
2680  else {
2681  cerr<<"not ok!"<<endl;
2682  assert(0);
2683  }
2684  }
2685  }
2686 
2688  else if( caloEnergy > totalChargedMomentum ) {
2689 
2690  //case 2: caloEnergy > totalChargedMomentum + nsigma*TotalError
2691  //there is an excess of energy in the calos
2692  //create a neutral hadron or a photon
2693 
2694  /*
2695  //If it's isolated don't create neutrals since the energy deposit is always coming from a showering muon
2696  bool thisIsAnIsolatedMuon = false;
2697  for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
2698  unsigned iTrack = ie->second;
2699  if(PFMuonAlgo::isIsolatedMuon(elements[iTrack].muonRef())) thisIsAnIsolatedMuon = true;
2700  }
2701 
2702  if(thisIsAnIsolatedMuon){
2703  if(debug_)cout<<" Not looking for neutral b/c this is an isolated muon "<<endl;
2704  break;
2705  }
2706  */
2707  double eNeutralHadron = caloEnergy - totalChargedMomentum;
2708  double ePhoton = (caloEnergy - totalChargedMomentum) / slopeEcal;
2709 
2710  if(debug_) {
2711  if(!sortedTracks.empty() ){
2712  cout<<"\t\tcase 2: NEUTRAL DETECTION "
2713  <<caloEnergy<<" > "<<nsigma<<"x"<<TotalError
2714  <<" + "<<totalChargedMomentum<<endl;
2715  cout<<"\t\tneutral activity detected: "<<endl
2716  <<"\t\t\t photon = "<<ePhoton<<endl
2717  <<"\t\t\tor neutral hadron = "<<eNeutralHadron<<endl;
2718 
2719  cout<<"\t\tphoton or hadron ?"<<endl;}
2720 
2721  if(sortedTracks.empty() )
2722  cout<<"\t\tno track -> hadron "<<endl;
2723  else
2724  cout<<"\t\t"<<sortedTracks.size()
2725  <<" tracks -> check if the excess is photonic or hadronic"<<endl;
2726  }
2727 
2728 
2729  double ratioMax = 0.;
2730  reco::PFClusterRef maxEcalRef;
2731  unsigned maxiEcal= 9999;
2732 
2733  // for each track associated to hcal: iterator IE ie :
2734 
2735  for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
2736 
2737  unsigned iTrack = ie->second;
2738 
2739  PFBlockElement::Type type = elements[iTrack].type();
2740  assert( type == reco::PFBlockElement::TRACK );
2741 
2742  reco::TrackRef trackRef = elements[iTrack].trackRef();
2743  assert( !trackRef.isNull() );
2744 
2745  II iae = associatedEcals.find(iTrack);
2746 
2747  if( iae == associatedEcals.end() ) continue;
2748 
2749  // double distECAL = iae->second.first;
2750  unsigned iEcal = iae->second.second;
2751 
2752  PFBlockElement::Type typeEcal = elements[iEcal].type();
2753  assert(typeEcal == reco::PFBlockElement::ECAL);
2754 
2755  reco::PFClusterRef clusterRef = elements[iEcal].clusterRef();
2756  assert( !clusterRef.isNull() );
2757 
2758  double pTrack = trackRef->p();
2759  double eECAL = clusterRef->energy();
2760  double eECALOverpTrack = eECAL / pTrack;
2761 
2762  if ( eECALOverpTrack > ratioMax ) {
2763  ratioMax = eECALOverpTrack;
2764  maxEcalRef = clusterRef;
2765  maxiEcal = iEcal;
2766  }
2767 
2768  } // end loop on tracks associated to hcal: iterator IE ie
2769 
2770  std::vector<reco::PFClusterRef> pivotalClusterRef;
2771  std::vector<unsigned> iPivotal;
2772  std::vector<double> particleEnergy, ecalEnergy, hcalEnergy, rawecalEnergy, rawhcalEnergy;
2773  std::vector<::math::XYZVector> particleDirection;
2774 
2775  // If the excess is smaller than the ecal energy, assign the whole
2776  // excess to photons
2777  if ( ePhoton < totalEcal || eNeutralHadron-calibEcal < 1E-10 ) {
2778  if ( !maxEcalRef.isNull() ) {
2779  // So the merged photon energy is,
2780  mergedPhotonEnergy = ePhoton;
2781  }
2782  } else {
2783  // Otherwise assign the whole ECAL energy to the photons
2784  if ( !maxEcalRef.isNull() ) {
2785  // So the merged photon energy is,
2786  mergedPhotonEnergy = totalEcal;
2787  }
2788  // ... and assign the remaining excess to neutral hadrons using the direction of ecal clusters
2789  mergedNeutralHadronEnergy = eNeutralHadron-calibEcal;
2790  }
2791 
2792  if ( mergedPhotonEnergy > 0 ) {
2793  // Split merged photon into photons for each energetic ecal cluster (necessary for jet substructure reconstruction)
2794  // make only one merged photon if less than 2 ecal clusters
2795  if ( ecalClusters.size()<=1 ) {
2796  ecalClusters.clear();
2797  ecalClusters.push_back(make_pair(maxiEcal, photonAtECAL));
2798  sumEcalClusters=sqrt(photonAtECAL.Mag2());
2799  }
2800  for(std::vector<std::pair<unsigned,::math::XYZVector> >::const_iterator pae = ecalClusters.begin(); pae != ecalClusters.end(); ++pae ) {
2801  double clusterEnergy=sqrt(pae->second.Mag2());
2802  particleEnergy.push_back(mergedPhotonEnergy*clusterEnergy/sumEcalClusters);
2803  particleDirection.push_back(pae->second);
2804  ecalEnergy.push_back(mergedPhotonEnergy*clusterEnergy/sumEcalClusters);
2805  hcalEnergy.push_back(0.);
2806  rawecalEnergy.push_back(totalEcal);
2807  rawhcalEnergy.push_back(totalHcal);
2808  pivotalClusterRef.push_back(elements[pae->first].clusterRef());
2809  iPivotal.push_back(pae->first);
2810  }
2811  }
2812 
2813  if ( mergedNeutralHadronEnergy > 1.0 ) {
2814  // Split merged neutral hadrons according to directions of energetic ecal clusters (necessary for jet substructure reconstruction)
2815  // make only one merged neutral hadron if less than 2 ecal clusters
2816  if ( ecalClusters.size()<=1 ) {
2817  ecalClusters.clear();
2818  ecalClusters.push_back(make_pair(iHcal, hadronAtECAL));
2819  sumEcalClusters=sqrt(hadronAtECAL.Mag2());
2820  }
2821  for(std::vector<std::pair<unsigned,::math::XYZVector> >::const_iterator pae = ecalClusters.begin(); pae != ecalClusters.end(); ++pae ) {
2822  double clusterEnergy=sqrt(pae->second.Mag2());
2823  particleEnergy.push_back(mergedNeutralHadronEnergy*clusterEnergy/sumEcalClusters);
2824  particleDirection.push_back(pae->second);
2825  ecalEnergy.push_back(0.);
2826  hcalEnergy.push_back(mergedNeutralHadronEnergy*clusterEnergy/sumEcalClusters);
2827  rawecalEnergy.push_back(totalEcal);
2828  rawhcalEnergy.push_back(totalHcal);
2829  pivotalClusterRef.push_back(hclusterref);
2830  iPivotal.push_back(iHcal);
2831  }
2832  }
2833 
2834  // reconstructing a merged neutral
2835  // the type of PFCandidate is known from the
2836  // reference to the pivotal cluster.
2837 
2838  for ( unsigned iPivot=0; iPivot<iPivotal.size(); ++iPivot ) {
2839 
2840  if ( particleEnergy[iPivot] < 0. )
2841  std::cout << "ALARM = Negative energy ! "
2842  << particleEnergy[iPivot] << std::endl;
2843 
2844  bool useDirection = true;
2845  unsigned tmpi = reconstructCluster( *pivotalClusterRef[iPivot],
2846  particleEnergy[iPivot],
2847  useDirection,
2848  particleDirection[iPivot].X(),
2849  particleDirection[iPivot].Y(),
2850  particleDirection[iPivot].Z());
2851 
2852 
2853  (*pfCandidates_)[tmpi].setEcalEnergy( rawecalEnergy[iPivot],ecalEnergy[iPivot] );
2854  if ( !useHO_ ) {
2855  (*pfCandidates_)[tmpi].setHcalEnergy( rawhcalEnergy[iPivot],hcalEnergy[iPivot] );
2856  (*pfCandidates_)[tmpi].setHoEnergy(0., 0.);
2857  } else {
2858  (*pfCandidates_)[tmpi].setHcalEnergy( max(rawhcalEnergy[iPivot]-totalHO,0.0),hcalEnergy[iPivot]*(1.-totalHO/rawhcalEnergy[iPivot]));
2859  (*pfCandidates_)[tmpi].setHoEnergy(totalHO, totalHO * hcalEnergy[iPivot]/rawhcalEnergy[iPivot]);
2860  }
2861  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
2862  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
2863  (*pfCandidates_)[tmpi].set_mva_nothing_gamma( -1. );
2864  // (*pfCandidates_)[tmpi].addElement(&elements[iPivotal]);
2865  // (*pfCandidates_)[tmpi].addElementInBlock(blockref, iPivotal[iPivot]);
2866  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2867  for ( unsigned ich=0; ich<chargedHadronsInBlock.size(); ++ich) {
2868  unsigned iTrack = chargedHadronsInBlock[ich];
2869  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2870  // Assign the position of the track at the ECAL entrance
2871  const ::math::XYZPointF& chargedPosition =
2872  dynamic_cast<const reco::PFBlockElementTrack*>(&elements[iTrack])->positionAtECALEntrance();
2873  (*pfCandidates_)[tmpi].setPositionAtECALEntrance(chargedPosition);
2874 
2875  std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2876  for (II ii=myEcals.first; ii!=myEcals.second; ++ii ) {
2877  unsigned iEcal = ii->second.second;
2878  if ( active[iEcal] ) continue;
2879  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2880  }
2881  }
2882 
2883  }
2884 
2885  } // excess of energy
2886 
2887 
2888  // will now share the hcal energy between the various charged hadron
2889  // candidates, taking into account the potential neutral hadrons
2890 
2891  double totalHcalEnergyCalibrated = calibHcal;
2892  double totalEcalEnergyCalibrated = calibEcal;
2893  //JB: The question is: we've resolved the merged photons cleanly, but how should
2894  //the remaining hadrons be assigned the remaining ecal energy?
2895  //*Temporary solution*: follow HCAL example with fractions...
2896 
2897  /*
2898  if(totalEcal>0) {
2899  // removing ecal energy from abc calibration
2900  totalHcalEnergyCalibrated -= calibEcal;
2901  // totalHcalEnergyCalibrated -= calibration_->paramECALplusHCAL_slopeECAL() * totalEcal;
2902  }
2903  */
2904  // else caloEnergy = hcal only calibrated energy -> ok.
2905 
2906  // remove the energy of the potential neutral hadron
2907  totalHcalEnergyCalibrated -= mergedNeutralHadronEnergy;
2908  // similarly for the merged photons
2909  totalEcalEnergyCalibrated -= mergedPhotonEnergy;
2910  // share between the charged hadrons
2911 
2912  //COLIN can compute this before
2913  // not exactly equal to sum p, this is sum E
2914  double chargedHadronsTotalEnergy = 0;
2915  for( unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2916  unsigned index = chargedHadronsIndices[ich];
2917  reco::PFCandidate& chargedHadron = (*pfCandidates_)[index];
2918  chargedHadronsTotalEnergy += chargedHadron.energy();
2919  }
2920 
2921  for( unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2922  unsigned index = chargedHadronsIndices[ich];
2923  reco::PFCandidate& chargedHadron = (*pfCandidates_)[index];
2924  float fraction = chargedHadron.energy()/chargedHadronsTotalEnergy;
2925 
2926  if ( !useHO_ ) {
2927  chargedHadron.setHcalEnergy( fraction * totalHcal, fraction * totalHcalEnergyCalibrated );
2928  chargedHadron.setHoEnergy( 0., 0. );
2929  } else {
2930  chargedHadron.setHcalEnergy( fraction * max(totalHcal-totalHO,0.0), fraction * totalHcalEnergyCalibrated * (1.-totalHO/totalHcal) );
2931  chargedHadron.setHoEnergy( fraction * totalHO, fraction * totalHO * totalHcalEnergyCalibrated / totalHcal );
2932  }
2933  //JB: fixing up (previously omitted) setting of ECAL energy gouzevit
2934  chargedHadron.setEcalEnergy( fraction * totalEcal, fraction * totalEcalEnergyCalibrated );
2935  }
2936 
2937  // Finally treat unused ecal satellites as photons.
2938  for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
2939 
2940  // Ignore satellites already taken
2941  unsigned iEcal = is->second.first;
2942  if ( !active[iEcal] ) continue;
2943 
2944  // Sanity checks again (well not useful, this time!)
2945  PFBlockElement::Type type = elements[ iEcal ].type();
2946  assert( type == PFBlockElement::ECAL );
2947  PFClusterRef eclusterref = elements[iEcal].clusterRef();
2948  assert(!eclusterref.isNull() );
2949 
2950  // Lock the cluster
2951  active[iEcal] = false;
2952 
2953  // Find the associated tracks
2954  std::multimap<double, unsigned> assTracks;
2955  block.associatedElements( iEcal, linkData,
2956  assTracks,
2959 
2960  // Create a photon
2961  unsigned tmpi = reconstructCluster( *eclusterref, sqrt(is->second.second.Mag2()) );
2962  (*pfCandidates_)[tmpi].setEcalEnergy( eclusterref->energy(),sqrt(is->second.second.Mag2()) );
2963  (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
2964  (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
2965  (*pfCandidates_)[tmpi].setPs1Energy( associatedPSs[iEcal].first );
2966  (*pfCandidates_)[tmpi].setPs2Energy( associatedPSs[iEcal].second );
2967  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2968  (*pfCandidates_)[tmpi].addElementInBlock( blockref, sortedTracks.begin()->second) ;
2969  }
2970 
2971 
2972  }
2973 
2974  // end loop on hcal element iHcal= hcalIs[i]
2975 
2976 
2977  // Processing the remaining HCAL clusters
2978  if(debug_) {
2979  cout<<endl;
2980  if(debug_)
2981  cout<<endl
2982  <<"---- loop remaining hcal ------- "<<endl;
2983  }
2984 
2985 
2986  //COLINFEB16
2987  // now dealing with the HCAL elements that are not linked to any track
2988  for(unsigned ihcluster=0; ihcluster<hcalIs.size(); ihcluster++) {
2989  unsigned iHcal = hcalIs[ihcluster];
2990 
2991  // Keep ECAL and HO elements for reference in the PFCandidate
2992  std::vector<unsigned> ecalRefs;
2993  std::vector<unsigned> hoRefs;
2994 
2995  if(debug_)
2996  cout<<endl<<elements[iHcal]<<" ";
2997 
2998 
2999  if( !active[iHcal] ) {
3000  if(debug_)
3001  cout<<"not active"<<endl;
3002  continue;
3003  }
3004 
3005  // Find the ECAL elements linked to it
3006  std::multimap<double, unsigned> ecalElems;
3007  block.associatedElements( iHcal, linkData,
3008  ecalElems ,
3011 
3012  // Loop on these ECAL elements
3013  float totalEcal = 0.;
3014  float ecalMax = 0.;
3015  reco::PFClusterRef eClusterRef;
3016  for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
3017 
3018  unsigned iEcal = ie->second;
3019  double dist = ie->first;
3020  PFBlockElement::Type type = elements[iEcal].type();
3021  assert( type == PFBlockElement::ECAL );
3022 
3023  // Check if already used
3024  if( !active[iEcal] ) continue;
3025 
3026  // Check the distance (one HCALPlusECAL tower, roughly)
3027  // if ( dist > 0.15 ) continue;
3028 
3029  //COLINFEB16
3030  // what could be done is to
3031  // - link by rechit.
3032  // - take in the neutral hadron all the ECAL clusters
3033  // which are within the same CaloTower, according to the distance,
3034  // except the ones which are closer to another HCAL cluster.
3035  // - all the other ECAL linked to this HCAL are photons.
3036  //
3037  // about the closest HCAL cluster.
3038  // it could maybe be easier to loop on the ECAL clusters first
3039  // to cut the links to all HCAL clusters except the closest, as is
3040  // done in the first track loop. But maybe not!
3041  // or add an helper function to the PFAlgo class to ask
3042  // if a given element is the closest of a given type to another one?
3043 
3044  // Check if not closer from another free HCAL
3045  std::multimap<double, unsigned> hcalElems;
3046  block.associatedElements( iEcal, linkData,
3047  hcalElems ,
3050 
3051  bool isClosest = true;
3052  for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
3053 
3054  unsigned jHcal = ih->second;
3055  double distH = ih->first;
3056 
3057  if ( !active[jHcal] ) continue;
3058 
3059  if ( distH < dist ) {
3060  isClosest = false;
3061  break;
3062  }
3063 
3064  }
3065 
3066  if (!isClosest) continue;
3067 
3068 
3069  if(debug_) {
3070  cout<<"\telement "<<elements[iEcal]<<" linked with dist "<< dist<<endl;
3071  cout<<"Added to HCAL cluster to form a neutral hadron"<<endl;
3072  }
3073 
3074  reco::PFClusterRef eclusterRef = elements[iEcal].clusterRef();
3075  assert( !eclusterRef.isNull() );
3076 
3077  double ecalEnergy = eclusterRef->correctedEnergy();
3078 
3079  //std::cout << "EcalEnergy, ps1, ps2 = " << ecalEnergy
3080  // << ", " << ps1Ene[0] << ", " << ps2Ene[0] << std::endl;
3081  totalEcal += ecalEnergy;
3082  if ( ecalEnergy > ecalMax ) {
3083  ecalMax = ecalEnergy;
3084  eClusterRef = eclusterRef;
3085  }
3086 
3087  ecalRefs.push_back(iEcal);
3088  active[iEcal] = false;
3089 
3090 
3091  }// End loop ECAL
3092 
3093  // Now find the HO clusters linked to the HCAL cluster
3094  double totalHO = 0.;
3095  double hoMax = 0.;
3096  //unsigned jHO = 0;
3097  if (useHO_) {
3098  std::multimap<double, unsigned> hoElems;
3099  block.associatedElements( iHcal, linkData,
3100  hoElems ,
3103 
3104  // Loop on these HO elements
3105  // double totalHO = 0.;
3106  // double hoMax = 0.;
3107  // unsigned jHO = 0;
3108  reco::PFClusterRef hoClusterRef;
3109  for(IE ie = hoElems.begin(); ie != hoElems.end(); ++ie ) {
3110 
3111  unsigned iHO = ie->second;
3112  double dist = ie->first;
3113  PFBlockElement::Type type = elements[iHO].type();
3114  assert( type == PFBlockElement::HO );
3115 
3116  // Check if already used
3117  if( !active[iHO] ) continue;
3118 
3119  // Check the distance (one HCALPlusHO tower, roughly)
3120  // if ( dist > 0.15 ) continue;
3121 
3122  // Check if not closer from another free HCAL
3123  std::multimap<double, unsigned> hcalElems;
3124  block.associatedElements( iHO, linkData,
3125  hcalElems ,
3128 
3129  bool isClosest = true;
3130  for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
3131 
3132  unsigned jHcal = ih->second;
3133  double distH = ih->first;
3134 
3135  if ( !active[jHcal] ) continue;
3136 
3137  if ( distH < dist ) {
3138  isClosest = false;
3139  break;
3140  }
3141 
3142  }
3143 
3144  if (!isClosest) continue;
3145 
3146  if(debug_ && useHO_) {
3147  cout<<"\telement "<<elements[iHO]<<" linked with dist "<< dist<<endl;
3148  cout<<"Added to HCAL cluster to form a neutral hadron"<<endl;
3149  }
3150 
3151  reco::PFClusterRef hoclusterRef = elements[iHO].clusterRef();
3152  assert( !hoclusterRef.isNull() );
3153 
3154  double hoEnergy = hoclusterRef->energy(); // calibration_->energyEm(*hoclusterRef,ps1Ene,ps2Ene,crackCorrection);
3155 
3156  totalHO += hoEnergy;
3157  if ( hoEnergy > hoMax ) {
3158  hoMax = hoEnergy;
3159  hoClusterRef = hoclusterRef;
3160  //jHO = iHO;
3161  }
3162 
3163  hoRefs.push_back(iHO);
3164  active[iHO] = false;
3165 
3166  }// End loop HO
3167  }
3168 
3169  PFClusterRef hclusterRef
3170  = elements[iHcal].clusterRef();
3171  assert( !hclusterRef.isNull() );
3172 
3173  // HCAL energy
3174  double totalHcal = hclusterRef->energy();
3175  // Include the HO energy
3176  if ( useHO_ ) totalHcal += totalHO;
3177 
3178  // std::cout << "Hcal Energy,eta : " << totalHcal
3179  // << ", " << hclusterRef->positionREP().Eta()
3180  // << std::endl;
3181  // Calibration
3182  //double caloEnergy = totalHcal;
3183  // double slopeEcal = 1.0;
3184  double calibEcal = totalEcal > 0. ? totalEcal : 0.;
3185  double calibHcal = std::max(0.,totalHcal);
3186  if ( hclusterRef->layer() == PFLayer::HF_HAD ||
3187  hclusterRef->layer() == PFLayer::HF_EM ) {
3188  //caloEnergy = totalHcal/0.7;
3189  calibEcal = totalEcal;
3190  } else {
3191  calibration_->energyEmHad(-1.,calibEcal,calibHcal,
3192  hclusterRef->positionREP().Eta(),
3193  hclusterRef->positionREP().Phi());
3194  //caloEnergy = calibEcal+calibHcal;
3195  }
3196 
3197  // std::cout << "CalibEcal,HCal = " << calibEcal << ", " << calibHcal << std::endl;
3198  // std::cout << "-------------------------------------------------------------------" << std::endl;
3199  // ECAL energy : calibration
3200 
3201  // double particleEnergy = caloEnergy;
3202  // double particleEnergy = totalEcal + calibHcal;
3203  // particleEnergy /= (1.-0.724/sqrt(particleEnergy)-0.0226/particleEnergy);
3204 
3205  unsigned tmpi = reconstructCluster( *hclusterRef,
3206  calibEcal+calibHcal );
3207 
3208 
3209  (*pfCandidates_)[tmpi].setEcalEnergy( totalEcal, calibEcal );
3210  if ( !useHO_ ) {
3211  (*pfCandidates_)[tmpi].setHcalEnergy( totalHcal, calibHcal );
3212  (*pfCandidates_)[tmpi].setHoEnergy(0.,0.);
3213  } else {
3214  (*pfCandidates_)[tmpi].setHcalEnergy( max(totalHcal-totalHO,0.0), calibHcal*(1.-totalHO/totalHcal));
3215  (*pfCandidates_)[tmpi].setHoEnergy(totalHO,totalHO*calibHcal/totalHcal);
3216  }
3217  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
3218  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
3219  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
3220  for (unsigned iec=0; iec<ecalRefs.size(); ++iec)
3221  (*pfCandidates_)[tmpi].addElementInBlock( blockref, ecalRefs[iec] );
3222  for (unsigned iho=0; iho<hoRefs.size(); ++iho)
3223  (*pfCandidates_)[tmpi].addElementInBlock( blockref, hoRefs[iho] );
3224 
3225  }//loop hcal elements
3226 
3227 
3228 
3229 
3230  if(debug_) {
3231  cout<<endl;
3232  if(debug_) cout<<endl<<"---- loop ecal------- "<<endl;
3233  }
3234 
3235  // for each ecal element iEcal = ecalIs[i] in turn:
3236 
3237  for(unsigned i=0; i<ecalIs.size(); i++) {
3238  unsigned iEcal = ecalIs[i];
3239 
3240  if(debug_)
3241  cout<<endl<<elements[iEcal]<<" ";
3242 
3243  if( ! active[iEcal] ) {
3244  if(debug_)
3245  cout<<"not active"<<endl;
3246  continue;
3247  }
3248 
3249  PFBlockElement::Type type = elements[ iEcal ].type();
3250  assert( type == PFBlockElement::ECAL );
3251 
3252  PFClusterRef clusterref = elements[iEcal].clusterRef();
3253  assert(!clusterref.isNull() );
3254 
3255  active[iEcal] = false;
3256 
3257  float ecalEnergy = clusterref->correctedEnergy();
3258  // float ecalEnergy = calibration_->energyEm( clusterref->energy() );
3259  double particleEnergy = ecalEnergy;
3260 
3261  unsigned tmpi = reconstructCluster( *clusterref,
3262  particleEnergy );
3263 
3264  (*pfCandidates_)[tmpi].setEcalEnergy( clusterref->energy(),ecalEnergy );
3265  (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
3266  (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
3267  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
3268  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
3269  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
3270 
3271 
3272  } // end loop on ecal elements iEcal = ecalIs[i]
3273 
3274 } // 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:3621
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:3357
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:3566
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:3517
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:3277
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:3502
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:3471
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 3357 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().

3362  {
3363 
3365 
3366  // need to convert the ::math::XYZPoint data member of the PFCluster class=
3367  // to a displacement vector:
3368 
3369  // Transform particleX,Y,Z to a position at ECAL/HCAL entrance
3370  double factor = 1.;
3371  if ( useDirection ) {
3372  switch( cluster.layer() ) {
3373  case PFLayer::ECAL_BARREL:
3374  case PFLayer::HCAL_BARREL1:
3375  factor = std::sqrt(cluster.position().Perp2()/(particleX*particleX+particleY*particleY));
3376  break;
3377  case PFLayer::ECAL_ENDCAP:
3378  case PFLayer::HCAL_ENDCAP:
3379  case PFLayer::HF_HAD:
3380  case PFLayer::HF_EM:
3381  factor = cluster.position().Z()/particleZ;
3382  break;
3383  default:
3384  assert(0);
3385  }
3386  }
3387  //MIKE First of all let's check if we have vertex.
3388  ::math::XYZPoint vertexPos;
3389  if(useVertices_)
3391  else
3392  vertexPos = ::math::XYZPoint(0.0,0.0,0.0);
3393 
3394 
3395  ::math::XYZVector clusterPos( cluster.position().X()-vertexPos.X(),
3396  cluster.position().Y()-vertexPos.Y(),
3397  cluster.position().Z()-vertexPos.Z());
3398  ::math::XYZVector particleDirection ( particleX*factor-vertexPos.X(),
3399  particleY*factor-vertexPos.Y(),
3400  particleZ*factor-vertexPos.Z() );
3401 
3402  //::math::XYZVector clusterPos( cluster.position().X(), cluster.position().Y(),cluster.position().Z() );
3403  //::math::XYZVector particleDirection ( particleX, particleY, particleZ );
3404 
3405  clusterPos = useDirection ? particleDirection.Unit() : clusterPos.Unit();
3406  clusterPos *= particleEnergy;
3407 
3408  // clusterPos is now a vector along the cluster direction,
3409  // with a magnitude equal to the cluster energy.
3410 
3411  double mass = 0;
3412  ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double> >
3413  momentum( clusterPos.X(), clusterPos.Y(), clusterPos.Z(), mass);
3414  // mathcore is a piece of #$%
3416  // implicit constructor not allowed
3417  tmp = momentum;
3418 
3419  // Charge
3420  int charge = 0;
3421 
3422  // Type
3423  switch( cluster.layer() ) {
3424  case PFLayer::ECAL_BARREL:
3425  case PFLayer::ECAL_ENDCAP:
3426  particleType = PFCandidate::gamma;
3427  break;
3428  case PFLayer::HCAL_BARREL1:
3429  case PFLayer::HCAL_ENDCAP:
3430  particleType = PFCandidate::h0;
3431  break;
3432  case PFLayer::HF_HAD:
3433  particleType = PFCandidate::h_HF;
3434  break;
3435  case PFLayer::HF_EM:
3436  particleType = PFCandidate::egamma_HF;
3437  break;
3438  default:
3439  assert(0);
3440  }
3441 
3442  // The pf candidate
3443  pfCandidates_->push_back( PFCandidate( charge,
3444  tmp,
3445  particleType ) );
3446 
3447  // The position at ECAL entrance (well: watch out, it is not true
3448  // for HCAL clusters... to be fixed)
3449  pfCandidates_->back().
3450  setPositionAtECALEntrance(::math::XYZPointF(cluster.position().X(),
3451  cluster.position().Y(),
3452  cluster.position().Z()));
3453 
3454  //Set the cnadidate Vertex
3455  pfCandidates_->back().setVertex(vertexPos);
3456 
3457  // depth info
3458  setHcalDepthInfo(pfCandidates_->back(), cluster);
3459 
3460  //*TODO* cluster time is not reliable at the moment, so only use track timing
3461 
3462  if(debug_)
3463  cout<<"** candidate: "<<pfCandidates_->back()<<endl;
3464 
3465  // returns index to the newly created PFCandidate
3466  return pfCandidates_->size()-1;
3467 
3468 }
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:3471
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:3554
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:3657
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 3277 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().

3277  {
3278 
3279  const reco::PFBlockElementTrack* eltTrack
3280  = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
3281 
3282  const reco::TrackRef& trackRef = eltTrack->trackRef();
3283  const reco::Track& track = *trackRef;
3284  const reco::MuonRef& muonRef = eltTrack->muonRef();
3285  int charge = track.charge()>0 ? 1 : -1;
3286 
3287  // Assume this particle is a charged Hadron
3288  double px = track.px();
3289  double py = track.py();
3290  double pz = track.pz();
3291  double energy = sqrt(track.p()*track.p() + 0.13957*0.13957);
3292 
3293  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;
3294 
3295 
3296  // Create a PF Candidate
3297  ::math::XYZTLorentzVector momentum(px,py,pz,energy);
3300 
3301  // Add it to the stack
3302  pfCandidates_->push_back( PFCandidate( charge,
3303  momentum,
3304  particleType ) );
3305  //Set vertex and stuff like this
3306  pfCandidates_->back().setVertexSource( PFCandidate::kTrkVertex );
3307  pfCandidates_->back().setTrackRef( trackRef );
3308  pfCandidates_->back().setPositionAtECALEntrance( eltTrack->positionAtECALEntrance());
3309  if( muonRef.isNonnull())
3310  pfCandidates_->back().setMuonRef( muonRef );
3311 
3312 
3313  //Set time
3314  if (elt.isTimeValid()) pfCandidates_->back().setTime( elt.time(), elt.timeError() );
3315 
3316  //OK Now try to reconstruct the particle as a muon
3317  bool isMuon=pfmu_->reconstructMuon(pfCandidates_->back(),muonRef,allowLoose);
3318  bool isFromDisp = isFromSecInt(elt, "secondary");
3319 
3320 
3321  if ((!isMuon) && isFromDisp) {
3322  double Dpt = trackRef->ptError();
3323  double dptRel = Dpt/trackRef->pt()*100;
3324  //If the track is ill measured it is better to not refit it, since the track information probably would not be used.
3325  //In the PFAlgo we use the trackref information. If the track error is too big the refitted information might be very different
3326  // from the not refitted one.
3327  if (dptRel < dptRel_DispVtx_){
3328  if (debug_)
3329  cout << "Not refitted px = " << px << " py = " << py << " pz = " << pz << " energy = " << energy << endl;
3330  //reco::TrackRef trackRef = eltTrack->trackRef();
3332  reco::Track trackRefit = vRef->refittedTrack(trackRef);
3333  //change the momentum with the refitted track
3334  ::math::XYZTLorentzVector momentum(trackRefit.px(),
3335  trackRefit.py(),
3336  trackRefit.pz(),
3337  sqrt(trackRefit.p()*trackRefit.p() + 0.13957*0.13957));
3338  if (debug_)
3339  cout << "Refitted px = " << px << " py = " << py << " pz = " << pz << " energy = " << energy << endl;
3340  }
3341  pfCandidates_->back().setFlag( reco::PFCandidate::T_FROM_DISP, true);
3342  pfCandidates_->back().setDisplacedVertexRef( eltTrack->displacedVertexRef(reco::PFBlockElement::T_FROM_DISP)->displacedVertexRef(), reco::PFCandidate::T_FROM_DISP);
3343  }
3344 
3345  // 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
3346  if(isFromSecInt(elt, "primary") && !isMuon) {
3347  pfCandidates_->back().setFlag( reco::PFCandidate::T_TO_DISP, true);
3348  pfCandidates_->back().setDisplacedVertexRef( eltTrack->displacedVertexRef(reco::PFBlockElement::T_TO_DISP)->displacedVertexRef(), reco::PFCandidate::T_TO_DISP);
3349  }
3350 
3351  // returns index to the newly created PFCandidate
3352  return pfCandidates_->size()-1;
3353 }
double p() const
momentum vector magnitude
Definition: TrackBase.h:615
bool isFromSecInt(const reco::PFBlockElement &eTrack, std::string order) const
Definition: PFAlgo.cc:3621
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:645
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:627
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:651
T sqrt(T t)
Definition: SSEVec.h:18
double pt() const
track transverse momentum
Definition: TrackBase.h:621
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:639
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:567
const reco::MuonRef & muonRef() const override
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:633
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 3652 of file PFAlgo.cc.

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

Referenced by setCandConnectorParameters().

3652  {
3654 }
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 3869 of file PFAlgo.cc.

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

Referenced by setCandConnectorParameters().

3869  {
3870  if(!usePFElectrons_) return;
3871  // std::cout << " setElectronExtraRef " << std::endl;
3872  unsigned size=pfCandidates_->size();
3873 
3874  for(unsigned ic=0;ic<size;++ic) {
3875  // select the electrons and add the extra
3876  if((*pfCandidates_)[ic].particleId()==PFCandidate::e) {
3877 
3878  PFElectronExtraEqual myExtraEqual((*pfCandidates_)[ic].gsfTrackRef());
3879  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3880  if(it!=pfElectronExtra_.end()) {
3881  // std::cout << " Index " << it-pfElectronExtra_.begin() << std::endl;
3882  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3883  (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3884  }
3885  else {
3886  (*pfCandidates_)[ic].setPFElectronExtraRef(PFCandidateElectronExtraRef());
3887  }
3888  }
3889  else // else save the mva and the extra as well !
3890  {
3891  if((*pfCandidates_)[ic].trackRef().isNonnull()) {
3892  PFElectronExtraKfEqual myExtraEqual((*pfCandidates_)[ic].trackRef());
3893  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3894  if(it!=pfElectronExtra_.end()) {
3895  (*pfCandidates_)[ic].set_mva_e_pi(it->mvaVariable(PFCandidateElectronExtra::MVA_MVA));
3896  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3897  (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3898  (*pfCandidates_)[ic].setGsfTrackRef(it->gsfTrackRef());
3899  }
3900  }
3901  }
3902 
3903  }
3904 
3905  size=pfElectronCandidates_->size();
3906  for(unsigned ic=0;ic<size;++ic) {
3907  // select the electrons - this test is actually not needed for this collection
3908  if((*pfElectronCandidates_)[ic].particleId()==PFCandidate::e) {
3909  // find the corresponding extra
3910  PFElectronExtraEqual myExtraEqual((*pfElectronCandidates_)[ic].gsfTrackRef());
3911  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3912  if(it!=pfElectronExtra_.end()) {
3913  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3914  (*pfElectronCandidates_)[ic].setPFElectronExtraRef(theRef);
3915 
3916  }
3917  }
3918  }
3919 
3920 }
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 3471 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().

3471  {
3472  std::array<double,7> energyPerDepth;
3473  std::fill(energyPerDepth.begin(), energyPerDepth.end(), 0.0);
3474  for (auto & hitRefAndFrac : cluster.recHitFractions()) {
3475  const auto & hit = *hitRefAndFrac.recHitRef();
3476  if (DetId(hit.detId()).det() == DetId::Hcal) {
3477  if (hit.depth() == 0) {
3478  edm::LogWarning("setHcalDepthInfo") << "Depth zero found";
3479  continue;
3480  }
3481  if (hit.depth() < 1 || hit.depth() > 7) {
3482  throw cms::Exception("CorruptData") << "Bogus depth " << hit.depth() << " at detid " << hit.detId() << "\n";
3483  }
3484  energyPerDepth[hit.depth()-1] += hitRefAndFrac.fraction()*hit.energy();
3485  }
3486  }
3487  double sum = std::accumulate(energyPerDepth.begin(), energyPerDepth.end(), 0.);
3488  std::array<float,7> depthFractions;
3489  if (sum > 0) {
3490  for (unsigned int i = 0; i < depthFractions.size(); ++i) {
3491  depthFractions[i] = energyPerDepth[i]/sum;
3492  }
3493  } else {
3494  std::fill(depthFractions.begin(), depthFractions.end(), 0.f);
3495  }
3496  cand.setHcalDepthEnergyFractions(depthFractions);
3497 }
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:3517
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 3921 of file PFAlgo.cc.

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

Referenced by setCandConnectorParameters().

3921  {
3922  if(!usePFPhotons_) return;
3923  unsigned int size=pfCandidates_->size();
3924  unsigned int sizePhExtra = pfPhotonExtra_.size();
3925  for(unsigned ic=0;ic<size;++ic) {
3926  // select the electrons and add the extra
3927  if((*pfCandidates_)[ic].particleId()==PFCandidate::gamma && (*pfCandidates_)[ic].mva_nothing_gamma() > 0.99) {
3928  if((*pfCandidates_)[ic].superClusterRef().isNonnull()) {
3929  bool found = false;
3930  for(unsigned pcextra=0;pcextra<sizePhExtra;++pcextra) {
3931  if((*pfCandidates_)[ic].superClusterRef() == pfPhotonExtra_[pcextra].superClusterRef()) {
3932  reco::PFCandidatePhotonExtraRef theRef(ph_extrah,pcextra);
3933  (*pfCandidates_)[ic].setPFPhotonExtraRef(theRef);
3934  found = true;
3935  break;
3936  }
3937  }
3938  if(!found)
3939  (*pfCandidates_)[ic].setPFPhotonExtraRef((PFCandidatePhotonExtraRef())); // null ref
3940  }
3941  else {
3942  (*pfCandidates_)[ic].setPFPhotonExtraRef((PFCandidatePhotonExtraRef())); // null ref
3943  }
3944  }
3945  }
3946 }
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().