CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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::auto_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 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, double ph_MinEt, double ph_combIso, double ph_HoE, double ph_sietaieta_eb, double ph_sietaieta_ee, const edm::ParameterSet &ph_protectionsForJetMET)
 
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
< PFEnergyCalibration
thePFEnergyCalibration ()
 return the pointer to the calibration function More...
 
std::auto_ptr
< reco::PFCandidateCollection
transferCandidates ()
 
std::auto_ptr
< reco::PFCandidateCollection > & 
transferCleanedCandidates ()
 
std::auto_ptr
< reco::PFCandidateCollection
transferElectronCandidates ()
 
std::auto_ptr
< reco::PFCandidateElectronExtraCollection
transferElectronExtra ()
 
std::auto_ptr
< reco::PFCandidatePhotonExtraCollection
transferPhotonExtra ()
 
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)
 

Protected Attributes

std::auto_ptr
< reco::PFCandidateCollection
pfCandidates_
 
std::auto_ptr
< reco::PFCandidateCollection
pfCleanedCandidates_
 
std::auto_ptr
< reco::PFCandidateCollection
pfElectronCandidates_
 the unfiltered electron collection More...
 
reco::PFCandidateElectronExtraCollection pfElectronExtra_
 the unfiltered electron collection More...
 
std::auto_ptr
< reco::PFCandidateCollection
pfPhotonCandidates_
 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
< PFEnergyCalibration
calibration_
 
double coneEcalIsoForEgammaSC_
 
double coneTrackIsoForEgammaSC_
 
PFCandConnector connector_
 
bool debug_
 
double dptRel_DispVtx_
 
std::vector< double > factors45_
 
double maxDeltaPhiPt_
 
double maxSignificance_
 
double minDeltaMet_
 
double minHFCleaningPt_
 
double minSignificance_
 
double minSignificanceReduction_
 
std::vector< double > muonECAL_
 
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
< PFEnergyCalibrationHF
thepfEnergyCalibrationHF_
 
boost::shared_ptr
< PFSCEnergyCalibration
thePFSCEnergyCalibration_
 
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 58 of file PFAlgo.cc.

60  nSigmaECAL_(0),
61  nSigmaHCAL_(1),
62  algo_(1),
63  debug_(false),
64  pfele_(0),
65  pfpho_(0),
66  pfegamma_(0),
67  useVertices_(false)
68 {}
double nSigmaHCAL_
number of sigma to judge energy excess in HCAL
Definition: PFAlgo.h:328
PFElectronAlgo * pfele_
Definition: PFAlgo.h:355
int algo_
Definition: PFAlgo.h:335
PFPhotonAlgo * pfpho_
Definition: PFAlgo.h:356
PFEGammaFilters * pfegamma_
Definition: PFAlgo.h:362
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
bool useVertices_
Definition: PFAlgo.h:411
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
bool debug_
Definition: PFAlgo.h:336
double nSigmaECAL_
number of sigma to judge energy excess in ECAL
Definition: PFAlgo.h:325
PFAlgo::~PFAlgo ( )
virtual

destructor

Definition at line 70 of file PFAlgo.cc.

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

70  {
71  if (usePFElectrons_) delete pfele_;
72  if (usePFPhotons_) delete pfpho_;
73  if (useEGammaFilters_) delete pfegamma_;
74 }
PFElectronAlgo * pfele_
Definition: PFAlgo.h:355
PFPhotonAlgo * pfpho_
Definition: PFAlgo.h:356
PFEGammaFilters * pfegamma_
Definition: PFAlgo.h:362
bool useEGammaFilters_
Variables for NEW EGAMMA selection.
Definition: PFAlgo.h:361
bool usePFPhotons_
Definition: PFAlgo.h:343
bool usePFElectrons_
Definition: PFAlgo.h:342

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

3449  {
3450 
3451  // Find all PS clusters with type psElement associated to ECAL cluster iEcal,
3452  // within all PFBlockElement "elements" of a given PFBlock "block"
3453  // psElement can be reco::PFBlockElement::PS1 or reco::PFBlockElement::PS2
3454  // Returns a vector of PS cluster energies, and updates the "active" vector.
3455 
3456  // Find all PS clusters linked to the iEcal cluster
3457  std::multimap<double, unsigned> sortedPS;
3458  typedef std::multimap<double, unsigned>::iterator IE;
3459  block.associatedElements( iEcal, linkData,
3460  sortedPS, psElementType,
3462 
3463  // Loop over these PS clusters
3464  double totalPS = 0.;
3465  for ( IE ips=sortedPS.begin(); ips!=sortedPS.end(); ++ips ) {
3466 
3467  // CLuster index and distance to iEcal
3468  unsigned iPS = ips->second;
3469  // double distPS = ips->first;
3470 
3471  // Ignore clusters already in use
3472  if (!active[iPS]) continue;
3473 
3474  // Check that this cluster is not closer to another ECAL cluster
3475  std::multimap<double, unsigned> sortedECAL;
3476  block.associatedElements( iPS, linkData,
3477  sortedECAL,
3480  unsigned jEcal = sortedECAL.begin()->second;
3481  if ( jEcal != iEcal ) continue;
3482 
3483  // Update PS energy
3484  PFBlockElement::Type pstype = elements[ iPS ].type();
3485  assert( pstype == psElementType );
3486  PFClusterRef psclusterref = elements[iPS].clusterRef();
3487  assert(!psclusterref.isNull() );
3488  totalPS += psclusterref->energy();
3489  psEne[0] += psclusterref->energy();
3490  active[iPS] = false;
3491  }
3492 
3493 
3494 }
bool isNull() const
Checks for null.
Definition: Ref.h:247
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 3641 of file PFAlgo.cc.

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

3641  {
3642 
3643 
3644  // No hits to recover, leave.
3645  if ( !cleanedHits.size() ) return;
3646 
3647  //Compute met and met significance (met/sqrt(SumEt))
3648  double metX = 0.;
3649  double metY = 0.;
3650  double sumet = 0;
3651  std::vector<unsigned int> hitsToBeAdded;
3652  for(unsigned i=0; i<pfCandidates_->size(); i++) {
3653  const PFCandidate& pfc = (*pfCandidates_)[i];
3654  metX += pfc.px();
3655  metY += pfc.py();
3656  sumet += pfc.pt();
3657  }
3658  double met2 = metX*metX+metY*metY;
3659  double met2_Original = met2;
3660  // Select events with large MET significance.
3661  // double significance = std::sqrt(met2/sumet);
3662  // double significanceCor = significance;
3663  double metXCor = metX;
3664  double metYCor = metY;
3665  double sumetCor = sumet;
3666  double met2Cor = met2;
3667  bool next = true;
3668  unsigned iCor = 1E9;
3669 
3670  // Find the cleaned hit with the largest effect on the MET
3671  while ( next ) {
3672 
3673  double metReduc = -1.;
3674  // Loop on the candidates
3675  for(unsigned i=0; i<cleanedHits.size(); ++i) {
3676  const PFRecHit& hit = cleanedHits[i];
3677  double length = std::sqrt(hit.position().Mag2());
3678  double px = hit.energy() * hit.position().x()/length;
3679  double py = hit.energy() * hit.position().y()/length;
3680  double pt = std::sqrt(px*px + py*py);
3681 
3682  // Check that it is not already scheculed to be cleaned
3683  bool skip = false;
3684  for(unsigned j=0; j<hitsToBeAdded.size(); ++j) {
3685  if ( i == hitsToBeAdded[j] ) skip = true;
3686  if ( skip ) break;
3687  }
3688  if ( skip ) continue;
3689 
3690  // Now add the candidate to the MET
3691  double metXInt = metX + px;
3692  double metYInt = metY + py;
3693  double sumetInt = sumet + pt;
3694  double met2Int = metXInt*metXInt+metYInt*metYInt;
3695 
3696  // And check if it could contribute to a MET reduction
3697  if ( met2Int < met2Cor ) {
3698  metXCor = metXInt;
3699  metYCor = metYInt;
3700  metReduc = (met2-met2Int)/met2Int;
3701  met2Cor = met2Int;
3702  sumetCor = sumetInt;
3703  // significanceCor = std::sqrt(met2Cor/sumetCor);
3704  iCor = i;
3705  }
3706  }
3707  //
3708  // If the MET must be significanly reduced, schedule the candidate to be added
3709  //
3710  if ( metReduc > minDeltaMet_ ) {
3711  hitsToBeAdded.push_back(iCor);
3712  metX = metXCor;
3713  metY = metYCor;
3714  sumet = sumetCor;
3715  met2 = met2Cor;
3716  } else {
3717  // Otherwise just stop the loop
3718  next = false;
3719  }
3720  }
3721  //
3722  // At least 10 GeV MET reduction
3723  if ( std::sqrt(met2_Original) - std::sqrt(met2) > 5. ) {
3724  if ( debug_ ) {
3725  std::cout << hitsToBeAdded.size() << " hits were re-added " << std::endl;
3726  std::cout << "MET reduction = " << std::sqrt(met2_Original) << " -> "
3727  << std::sqrt(met2Cor) << " = " << std::sqrt(met2Cor) - std::sqrt(met2_Original)
3728  << std::endl;
3729  std::cout << "Added after cleaning check : " << std::endl;
3730  }
3731  for(unsigned j=0; j<hitsToBeAdded.size(); ++j) {
3732  const PFRecHit& hit = cleanedHits[hitsToBeAdded[j]];
3733  PFCluster cluster(hit.layer(), hit.energy(),
3734  hit.position().x(), hit.position().y(), hit.position().z() );
3735  reconstructCluster(cluster,hit.energy());
3736  if ( debug_ ) {
3737  std::cout << pfCandidates_->back() << ". time = " << hit.time() << std::endl;
3738  }
3739  }
3740  }
3741 
3742 }
int i
Definition: DBlmapReader.cc:9
virtual float pt() const
transverse momentum
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:47
double minDeltaMet_
Definition: PFAlgo.h:406
unsigned reconstructCluster(const reco::PFCluster &cluster, double particleEnergy, bool useDirection=false, double particleX=0., double particleY=0., double particleZ=0.)
Definition: PFAlgo.cc:3266
PFLayer::Layer layer() const
rechit layer
Definition: PFRecHit.h:106
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
Definition: PFRecHit.h:35
T sqrt(T t)
Definition: SSEVec.h:48
int j
Definition: DBlmapReader.cc:9
const math::XYZPoint & position() const
rechit cell centre x, y, z
Definition: PFRecHit.h:128
virtual double px() const
x coordinate of momentum vector
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:39
double energy() const
rechit energy
Definition: PFRecHit.h:109
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
bool debug_
Definition: PFAlgo.h:336
tuple cout
Definition: gather_cfg.py:121
double time() const
timing for cleaned hits
Definition: PFRecHit.h:113
virtual double py() const
y coordinate of momentum vector
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 3431 of file PFAlgo.cc.

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

Referenced by reconstructParticles().

3432  {
3433 
3434  if( blockHandle_.isValid() ) {
3435  return reco::PFBlockRef( blockHandle_, bi );
3436  }
3437  else {
3438  return reco::PFBlockRef( &blocks, bi );
3439  }
3440 }
edm::Ref< PFBlockCollection > PFBlockRef
persistent reference to PFCluster objects
Definition: PFBlockFwd.h:20
bool isValid() const
Definition: HandleBase.h:76
list blocks
Definition: gather_cfg.py:90
reco::PFBlockHandle blockHandle_
input block handle (full framework case)
Definition: PFAlgo.h:322
PFMuonAlgo * PFAlgo::getPFMuonAlgo ( )

Definition at line 92 of file PFAlgo.cc.

References pfmu_.

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

Definition at line 3498 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().

3498  {
3499 
3502  // reco::PFBlockElement::TrackType T_FROM_GAMMACONV = reco::PFBlockElement::T_FROM_GAMMACONV;
3504 
3505  bool bPrimary = (order.find("primary") != string::npos);
3506  bool bSecondary = (order.find("secondary") != string::npos);
3507  bool bAll = (order.find("all") != string::npos);
3508 
3509  bool isToDisp = usePFNuclearInteractions_ && eTrack.trackType(T_TO_DISP);
3510  bool isFromDisp = usePFNuclearInteractions_ && eTrack.trackType(T_FROM_DISP);
3511 
3512  if (bPrimary && isToDisp) return true;
3513  if (bSecondary && isFromDisp ) return true;
3514  if (bAll && ( isToDisp || isFromDisp ) ) return true;
3515 
3516 // bool isFromConv = usePFConversions_ && eTrack.trackType(T_FROM_GAMMACONV);
3517 
3518 // if ((bAll || bSecondary)&& isFromConv) return true;
3519 
3520  bool isFromDecay = (bAll || bSecondary) && usePFDecays_ && eTrack.trackType(T_FROM_V0);
3521 
3522  return isFromDecay;
3523 
3524 
3525 }
bool usePFNuclearInteractions_
Definition: PFAlgo.h:377
virtual bool trackType(TrackType trType) const
bool usePFDecays_
Definition: PFAlgo.h:379
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 3378 of file PFAlgo.cc.

References mathSSE::sqrt().

Referenced by processBlock().

3378  {
3379 
3380  // Add a protection
3381  if ( clusterEnergyHCAL < 1. ) clusterEnergyHCAL = 1.;
3382 
3383  double resol = fabs(eta) < 1.48 ?
3384  sqrt (1.02*1.02/clusterEnergyHCAL + 0.065*0.065)
3385  :
3386  sqrt (1.20*1.20/clusterEnergyHCAL + 0.028*0.028);
3387 
3388  return resol;
3389 
3390 }
T eta() const
T sqrt(T t)
Definition: SSEVec.h:48
double PFAlgo::nSigmaHCAL ( double  clusterEnergy,
double  clusterEta 
) const
protected

Definition at line 3393 of file PFAlgo.cc.

References create_public_lumi_plots::exp, and nSigmaHCAL_.

Referenced by processBlock(), and setParameters().

3393  {
3394  double nS = fabs(eta) < 1.48 ?
3395  nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.))
3396  :
3397  nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.));
3398 
3399  return nS;
3400 }
double nSigmaHCAL_
number of sigma to judge energy excess in HCAL
Definition: PFAlgo.h:328
T eta() const
const std::auto_ptr< reco::PFCandidateCollection >& PFAlgo::pfCandidates ( ) const
inline
Returns
collection of candidates

Definition at line 196 of file PFAlgo.h.

References pfCandidates_.

Referenced by operator<<().

196  {
197  return pfCandidates_;
198  }
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
void PFAlgo::postCleaning ( )
protected

Definition at line 3534 of file PFAlgo.cc.

References gather_cfg::cout, SiPixelRawToDigiRegional_cfi::deltaPhi, reco::PFCandidate::egamma_HF, reco::PFCandidate::h_HF, i, j, 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(), runGlobalFakeInputProducer::skip, and mathSSE::sqrt().

Referenced by reconstructParticles().

3534  {
3535 
3536  // Check if the post HF Cleaning was requested - if not, do nothing
3537  if ( !postHFCleaning_ ) return;
3538 
3539  //Compute met and met significance (met/sqrt(SumEt))
3540  double metX = 0.;
3541  double metY = 0.;
3542  double sumet = 0;
3543  std::vector<unsigned int> pfCandidatesToBeRemoved;
3544  for(unsigned i=0; i<pfCandidates_->size(); i++) {
3545  const PFCandidate& pfc = (*pfCandidates_)[i];
3546  metX += pfc.px();
3547  metY += pfc.py();
3548  sumet += pfc.pt();
3549  }
3550  double met2 = metX*metX+metY*metY;
3551  // Select events with large MET significance.
3552  double significance = std::sqrt(met2/sumet);
3553  double significanceCor = significance;
3554  if ( significance > minSignificance_ ) {
3555 
3556  double metXCor = metX;
3557  double metYCor = metY;
3558  double sumetCor = sumet;
3559  double met2Cor = met2;
3560  double deltaPhi = 3.14159;
3561  double deltaPhiPt = 100.;
3562  bool next = true;
3563  unsigned iCor = 1E9;
3564 
3565  // Find the HF candidate with the largest effect on the MET
3566  while ( next ) {
3567 
3568  double metReduc = -1.;
3569  // Loop on the candidates
3570  for(unsigned i=0; i<pfCandidates_->size(); ++i) {
3571  const PFCandidate& pfc = (*pfCandidates_)[i];
3572 
3573  // Check that the pfCandidate is in the HF
3574  if ( pfc.particleId() != reco::PFCandidate::h_HF &&
3575  pfc.particleId() != reco::PFCandidate::egamma_HF ) continue;
3576 
3577  // Check if has meaningful pt
3578  if ( pfc.pt() < minHFCleaningPt_ ) continue;
3579 
3580  // Check that it is not already scheculed to be cleaned
3581  bool skip = false;
3582  for(unsigned j=0; j<pfCandidatesToBeRemoved.size(); ++j) {
3583  if ( i == pfCandidatesToBeRemoved[j] ) skip = true;
3584  if ( skip ) break;
3585  }
3586  if ( skip ) continue;
3587 
3588  // Check that the pt and the MET are aligned
3589  deltaPhi = std::acos((metX*pfc.px()+metY*pfc.py())/(pfc.pt()*std::sqrt(met2)));
3590  deltaPhiPt = deltaPhi*pfc.pt();
3591  if ( deltaPhiPt > maxDeltaPhiPt_ ) continue;
3592 
3593  // Now remove the candidate from the MET
3594  double metXInt = metX - pfc.px();
3595  double metYInt = metY - pfc.py();
3596  double sumetInt = sumet - pfc.pt();
3597  double met2Int = metXInt*metXInt+metYInt*metYInt;
3598  if ( met2Int < met2Cor ) {
3599  metXCor = metXInt;
3600  metYCor = metYInt;
3601  metReduc = (met2-met2Int)/met2Int;
3602  met2Cor = met2Int;
3603  sumetCor = sumetInt;
3604  significanceCor = std::sqrt(met2Cor/sumetCor);
3605  iCor = i;
3606  }
3607  }
3608  //
3609  // If the MET must be significanly reduced, schedule the candidate to be cleaned
3610  if ( metReduc > minDeltaMet_ ) {
3611  pfCandidatesToBeRemoved.push_back(iCor);
3612  metX = metXCor;
3613  metY = metYCor;
3614  sumet = sumetCor;
3615  met2 = met2Cor;
3616  } else {
3617  // Otherwise just stop the loop
3618  next = false;
3619  }
3620  }
3621  //
3622  // The significance must be significantly reduced to indeed clean the candidates
3623  if ( significance - significanceCor > minSignificanceReduction_ &&
3624  significanceCor < maxSignificance_ ) {
3625  std::cout << "Significance reduction = " << significance << " -> "
3626  << significanceCor << " = " << significanceCor - significance
3627  << std::endl;
3628  for(unsigned j=0; j<pfCandidatesToBeRemoved.size(); ++j) {
3629  std::cout << "Removed : " << (*pfCandidates_)[pfCandidatesToBeRemoved[j]] << std::endl;
3630  pfCleanedCandidates_->push_back( (*pfCandidates_)[ pfCandidatesToBeRemoved[j] ] );
3631  (*pfCandidates_)[pfCandidatesToBeRemoved[j]].rescaleMomentum(1E-6);
3632  //reco::PFCandidate::ParticleType unknown = reco::PFCandidate::X;
3633  //(*pfCandidates_)[pfCandidatesToBeRemoved[j]].setParticleType(unknown);
3634  }
3635  }
3636  }
3637 
3638 }
int i
Definition: DBlmapReader.cc:9
double maxDeltaPhiPt_
Definition: PFAlgo.h:405
double maxSignificance_
Definition: PFAlgo.h:403
virtual float pt() const
transverse momentum
double minHFCleaningPt_
Definition: PFAlgo.h:401
double minDeltaMet_
Definition: PFAlgo.h:406
double minSignificance_
Definition: PFAlgo.h:402
std::auto_ptr< reco::PFCandidateCollection > pfCleanedCandidates_
Definition: PFAlgo.h:290
double minSignificanceReduction_
Definition: PFAlgo.h:404
bool postHFCleaning_
Definition: PFAlgo.h:399
T sqrt(T t)
Definition: SSEVec.h:48
int j
Definition: DBlmapReader.cc:9
virtual double px() const
x coordinate of momentum vector
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:39
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
tuple cout
Definition: gather_cfg.py:121
virtual ParticleType particleId() const
Definition: PFCandidate.h:369
virtual double py() const
y coordinate of momentum vector
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 537 of file PFAlgo.cc.

References a, funct::abs(), associatePSClusters(), b, edm::OwnVector< T, P >::begin(), createPayload::block, alignmentValidation::c1, calibration_, dtNoiseDBValidation_cfg::cerr, reco::LeafCandidate::charge(), DDVectorGetter::check(), gather_cfg::cout, debug_, IterativeDetachedTripletStep_cff::detachedTripletStep, dptRel_DispVtx_, reco::PFCandidate::e, ECAL, reco::PFBlockElement::ECAL, RecoEcal_cff::ecalClusters, reco::PFCandidate::egammaExtraRef(), asciidump::elements, reco::PFCandidate::elementsInBlocks(), reco::LeafCandidate::energy(), eta(), reco::LeafCandidate::eta(), factors45_, first, reco::PFCandidate::gamma, PFElectronAlgo::getAllElectronCandidates(), PFElectronAlgo::getElectronCandidates(), PFElectronAlgo::getElectronExtra(), reco::PFBlockElement::GSF, HCAL, reco::PFBlockElement::HCAL, PFLayer::HF_EM, PFLayer::HF_HAD, reco::TrackBase::highPurity, reco::TrackBase::hltIter0, reco::TrackBase::hltIter1, reco::TrackBase::hltIter2, reco::TrackBase::hltIter3, reco::TrackBase::hltIter4, reco::TrackBase::hltIterX, reco::PFBlockElement::HO, i, cuy::ii, cmsHarvester::index, InitialStep_cff::initialStep, PFEGammaFilters::isElectron(), PFEGammaFilters::isElectronSafeForJetMET(), PFElectronAlgo::isElectronValidCandidate(), isFromSecInt(), PFMuonAlgo::isIsolatedMuon(), PFMuonAlgo::isLooseMuon(), PFMuonAlgo::isMuon(), edm::Ref< C, T, F >::isNonnull(), edm::Ref< C, T, F >::isNull(), PFEGammaFilters::isPhotonSafeForJetMET(), PFPhotonAlgo::isPhotonValidCandidate(), j, reco::PFBlock::LINKTEST_ALL, bookConverter::max, min(), IterativeMixedTripletStep_cff::mixedTripletStep, reco::PFCandidate::mu, muonECAL_, muonHCAL_, muonHO_, reco::PFCandidate::mva_e_pi(), neutralHadronEnergyResolution(), 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(), PixelLessStep_cff::pixelLessStep, primaryVertex_, reco::PFBlockElement::PS1, reco::PFBlockElement::PS2, reco::LeafCandidate::pt(), ptError_, edm::OwnVector< T, P >::push_back(), 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(), 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(), runGlobalFakeInputProducer::skip, mathSSE::sqrt(), 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(), reco::Vertex::y(), Gflash::Z, and reco::Vertex::z().

Referenced by reconstructParticles().

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

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

Referenced by checkCleaning(), and processBlock().

3271  {
3272 
3274 
3275  // need to convert the ::math::XYZPoint data member of the PFCluster class=
3276  // to a displacement vector:
3277 
3278  // Transform particleX,Y,Z to a position at ECAL/HCAL entrance
3279  double factor = 1.;
3280  if ( useDirection ) {
3281  switch( cluster.layer() ) {
3282  case PFLayer::ECAL_BARREL:
3283  case PFLayer::HCAL_BARREL1:
3284  factor = std::sqrt(cluster.position().Perp2()/(particleX*particleX+particleY*particleY));
3285  break;
3286  case PFLayer::ECAL_ENDCAP:
3287  case PFLayer::HCAL_ENDCAP:
3288  case PFLayer::HF_HAD:
3289  case PFLayer::HF_EM:
3290  factor = cluster.position().Z()/particleZ;
3291  break;
3292  default:
3293  assert(0);
3294  }
3295  }
3296  //MIKE First of all let's check if we have vertex.
3297  ::math::XYZPoint vertexPos;
3298  if(useVertices_)
3300  else
3301  vertexPos = ::math::XYZPoint(0.0,0.0,0.0);
3302 
3303 
3304  ::math::XYZVector clusterPos( cluster.position().X()-vertexPos.X(),
3305  cluster.position().Y()-vertexPos.Y(),
3306  cluster.position().Z()-vertexPos.Z());
3307  ::math::XYZVector particleDirection ( particleX*factor-vertexPos.X(),
3308  particleY*factor-vertexPos.Y(),
3309  particleZ*factor-vertexPos.Z() );
3310 
3311  //::math::XYZVector clusterPos( cluster.position().X(), cluster.position().Y(),cluster.position().Z() );
3312  //::math::XYZVector particleDirection ( particleX, particleY, particleZ );
3313 
3314  clusterPos = useDirection ? particleDirection.Unit() : clusterPos.Unit();
3315  clusterPos *= particleEnergy;
3316 
3317  // clusterPos is now a vector along the cluster direction,
3318  // with a magnitude equal to the cluster energy.
3319 
3320  double mass = 0;
3321  ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double> >
3322  momentum( clusterPos.X(), clusterPos.Y(), clusterPos.Z(), mass);
3323  // mathcore is a piece of #$%
3325  // implicit constructor not allowed
3326  tmp = momentum;
3327 
3328  // Charge
3329  int charge = 0;
3330 
3331  // Type
3332  switch( cluster.layer() ) {
3333  case PFLayer::ECAL_BARREL:
3334  case PFLayer::ECAL_ENDCAP:
3335  particleType = PFCandidate::gamma;
3336  break;
3337  case PFLayer::HCAL_BARREL1:
3338  case PFLayer::HCAL_ENDCAP:
3339  particleType = PFCandidate::h0;
3340  break;
3341  case PFLayer::HF_HAD:
3342  particleType = PFCandidate::h_HF;
3343  break;
3344  case PFLayer::HF_EM:
3345  particleType = PFCandidate::egamma_HF;
3346  break;
3347  default:
3348  assert(0);
3349  }
3350 
3351  // The pf candidate
3352  pfCandidates_->push_back( PFCandidate( charge,
3353  tmp,
3354  particleType ) );
3355 
3356  // The position at ECAL entrance (well: watch out, it is not true
3357  // for HCAL clusters... to be fixed)
3358  pfCandidates_->back().
3359  setPositionAtECALEntrance(::math::XYZPointF(cluster.position().X(),
3360  cluster.position().Y(),
3361  cluster.position().Z()));
3362 
3363  //Set the cnadidate Vertex
3364  pfCandidates_->back().setVertex(vertexPos);
3365 
3366  if(debug_)
3367  cout<<"** candidate: "<<pfCandidates_->back()<<endl;
3368 
3369  // returns index to the newly created PFCandidate
3370  return pfCandidates_->size()-1;
3371 
3372 }
PFLayer::Layer layer() const
cluster layer, see PFLayer.h in this directory
Definition: PFCluster.cc:86
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:124
ParticleType
particle types
Definition: PFCandidate.h:44
double y() const
y coordinate
Definition: Vertex.h:110
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
tuple particleType
Definition: autophobj.py:28
T sqrt(T t)
Definition: SSEVec.h:48
double z() const
y coordinate
Definition: Vertex.h:112
reco::Vertex primaryVertex_
Definition: PFAlgo.h:410
double x() const
x coordinate
Definition: Vertex.h:108
bool useVertices_
Definition: PFAlgo.h:411
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
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:39
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
bool debug_
Definition: PFAlgo.h:336
tuple cout
Definition: gather_cfg.py:121
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 414 of file PFAlgo.cc.

References blockHandle_.

414  {
415 
416  blockHandle_ = blockHandle;
418 }
void reconstructParticles(const reco::PFBlockHandle &blockHandle)
Definition: PFAlgo.cc:414
reco::PFBlockHandle blockHandle_
input block handle (full framework case)
Definition: PFAlgo.h:322
void PFAlgo::reconstructParticles ( const reco::PFBlockCollection blocks)
virtual

reconstruct particles

Definition at line 422 of file PFAlgo.cc.

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

422  {
423 
424  // reset output collection
425  if(pfCandidates_.get() )
426  pfCandidates_->clear();
427  else
429 
430  if(pfElectronCandidates_.get() )
431  pfElectronCandidates_->clear();
432  else
434 
435  // Clearing pfPhotonCandidates
436  if( pfPhotonCandidates_.get() )
437  pfPhotonCandidates_->clear();
438  else
440 
441  if(pfCleanedCandidates_.get() )
442  pfCleanedCandidates_->clear();
443  else
445 
446  // not a auto_ptr; shout not be deleted after transfer
447  pfElectronExtra_.clear();
448  pfPhotonExtra_.clear();
449 
450  if( debug_ ) {
451  cout<<"*********************************************************"<<endl;
452  cout<<"***** Particle flow algorithm *****"<<endl;
453  cout<<"*********************************************************"<<endl;
454  }
455 
456  // sort elements in three lists:
457  std::list< reco::PFBlockRef > hcalBlockRefs;
458  std::list< reco::PFBlockRef > ecalBlockRefs;
459  std::list< reco::PFBlockRef > hoBlockRefs;
460  std::list< reco::PFBlockRef > otherBlockRefs;
461 
462  for( unsigned i=0; i<blocks.size(); ++i ) {
463  // reco::PFBlockRef blockref( blockh,i );
464  reco::PFBlockRef blockref = createBlockRef( blocks, i);
465 
466  const reco::PFBlock& block = *blockref;
468  elements = block.elements();
469 
470  bool singleEcalOrHcal = false;
471  if( elements.size() == 1 ){
472  if( elements[0].type() == reco::PFBlockElement::ECAL ){
473  ecalBlockRefs.push_back( blockref );
474  singleEcalOrHcal = true;
475  }
476  if( elements[0].type() == reco::PFBlockElement::HCAL ){
477  hcalBlockRefs.push_back( blockref );
478  singleEcalOrHcal = true;
479  }
480  if( elements[0].type() == reco::PFBlockElement::HO ){
481  // Single HO elements are likely to be noise. Not considered for now.
482  hoBlockRefs.push_back( blockref );
483  singleEcalOrHcal = true;
484  }
485  }
486 
487  if(!singleEcalOrHcal) {
488  otherBlockRefs.push_back( blockref );
489  }
490  }//loop blocks
491 
492  if( debug_ ){
493  cout<<"# Ecal blocks: "<<ecalBlockRefs.size()
494  <<", # Hcal blocks: "<<hcalBlockRefs.size()
495  <<", # HO blocks: "<<hoBlockRefs.size()
496  <<", # Other blocks: "<<otherBlockRefs.size()<<endl;
497  }
498 
499 
500  // loop on blocks that are not single ecal,
501  // and not single hcal.
502 
503  unsigned nblcks = 0;
504  for( IBR io = otherBlockRefs.begin(); io!=otherBlockRefs.end(); ++io) {
505  if ( debug_ ) std::cout << "Block number " << nblcks++ << std::endl;
506  processBlock( *io, hcalBlockRefs, ecalBlockRefs );
507  }
508 
509  std::list< reco::PFBlockRef > empty;
510 
511  unsigned hblcks = 0;
512  // process remaining single hcal blocks
513  for( IBR ih = hcalBlockRefs.begin(); ih!=hcalBlockRefs.end(); ++ih) {
514  if ( debug_ ) std::cout << "HCAL block number " << hblcks++ << std::endl;
515  processBlock( *ih, empty, empty );
516  }
517 
518  unsigned eblcks = 0;
519  // process remaining single ecal blocks
520  for( IBR ie = ecalBlockRefs.begin(); ie!=ecalBlockRefs.end(); ++ie) {
521  if ( debug_ ) std::cout << "ECAL block number " << eblcks++ << std::endl;
522  processBlock( *ie, empty, empty );
523  }
524 
525  // Post HF Cleaning
526  postCleaning();
527 
528  //Muon post cleaning
529  pfmu_->postClean(pfCandidates_.get());
530 
531  //Add Missing muons
532  if( muonHandle_.isValid())
534 }
type
Definition: HCALResponse.h:21
int i
Definition: DBlmapReader.cc:9
void addMissingMuons(edm::Handle< reco::MuonCollection >, reco::PFCandidateCollection *cands)
Definition: PFMuonAlgo.cc:938
std::auto_ptr< reco::PFCandidateCollection > pfPhotonCandidates_
the unfiltered photon collection
Definition: PFAlgo.h:288
size_type size() const
Definition: OwnVector.h:254
virtual void processBlock(const reco::PFBlockRef &blockref, std::list< reco::PFBlockRef > &hcalBlockRefs, std::list< reco::PFBlockRef > &ecalBlockRefs)
Definition: PFAlgo.cc:537
list elements
Definition: asciidump.py:414
const edm::OwnVector< reco::PFBlockElement > & elements() const
Definition: PFBlock.h:107
std::auto_ptr< reco::PFCandidateCollection > pfCleanedCandidates_
Definition: PFAlgo.h:290
PFMuonAlgo * pfmu_
Definition: PFAlgo.h:357
edm::Handle< reco::MuonCollection > muonHandle_
Definition: PFAlgo.h:413
bool isValid() const
Definition: HandleBase.h:76
reco::PFBlockRef createBlockRef(const reco::PFBlockCollection &blocks, unsigned bi)
Definition: PFAlgo.cc:3431
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
the extra photon collection
Definition: PFAlgo.h:295
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
std::list< reco::PFBlockRef >::iterator IBR
Definition: PFAlgo.cc:54
list blocks
Definition: gather_cfg.py:90
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
bool debug_
Definition: PFAlgo.h:336
tuple cout
Definition: gather_cfg.py:121
std::auto_ptr< reco::PFCandidateCollection > pfElectronCandidates_
the unfiltered electron collection
Definition: PFAlgo.h:286
void postCleaning()
Definition: PFAlgo.cc:3534
void postClean(reco::PFCandidateCollection *)
Definition: PFMuonAlgo.cc:827
reco::PFCandidateElectronExtraCollection pfElectronExtra_
the unfiltered electron collection
Definition: PFAlgo.h:293
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 3192 of file PFAlgo.cc.

References reco::TrackBase::charge(), gather_cfg::cout, debug_, reco::PFBlockElementTrack::displacedVertexRef(), dptRel_DispVtx_, relval_parameters_module::energy, reco::PFCandidate::h, isFromSecInt(), reco::isMuon(), edm::Ref< C, T, F >::isNonnull(), reco::PFBlockElementTrack::muonRef(), reco::TrackBase::p(), objects.autophobj::particleType, pfCandidates_, pfmu_, reco::PFBlockElementTrack::positionAtECALEntrance(), 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, and reco::PFBlockElementTrack::trackRef().

Referenced by processBlock().

3192  {
3193 
3194  const reco::PFBlockElementTrack* eltTrack
3195  = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
3196 
3197  reco::TrackRef trackRef = eltTrack->trackRef();
3198  const reco::Track& track = *trackRef;
3199  reco::MuonRef muonRef = eltTrack->muonRef();
3200  int charge = track.charge()>0 ? 1 : -1;
3201 
3202  // Assume this particle is a charged Hadron
3203  double px = track.px();
3204  double py = track.py();
3205  double pz = track.pz();
3206  double energy = sqrt(track.p()*track.p() + 0.13957*0.13957);
3207 
3208  // Create a PF Candidate
3209  ::math::XYZTLorentzVector momentum(px,py,pz,energy);
3212 
3213  // Add it to the stack
3214  pfCandidates_->push_back( PFCandidate( charge,
3215  momentum,
3216  particleType ) );
3217  //Set vertex and stuff like this
3218  pfCandidates_->back().setVertexSource( PFCandidate::kTrkVertex );
3219  pfCandidates_->back().setTrackRef( trackRef );
3220  pfCandidates_->back().setPositionAtECALEntrance( eltTrack->positionAtECALEntrance());
3221  if( muonRef.isNonnull())
3222  pfCandidates_->back().setMuonRef( muonRef );
3223 
3224 
3225 
3226  //OK Now try to reconstruct the particle as a muon
3227  bool isMuon=pfmu_->reconstructMuon(pfCandidates_->back(),muonRef,allowLoose);
3228  bool isFromDisp = isFromSecInt(elt, "secondary");
3229 
3230 
3231  if ((!isMuon) && isFromDisp) {
3232  double Dpt = trackRef->ptError();
3233  double dptRel = Dpt/trackRef->pt()*100;
3234  //If the track is ill measured it is better to not refit it, since the track information probably would not be used.
3235  //In the PFAlgo we use the trackref information. If the track error is too big the refitted information might be very different
3236  // from the not refitted one.
3237  if (dptRel < dptRel_DispVtx_){
3238  if (debug_)
3239  cout << "Not refitted px = " << px << " py = " << py << " pz = " << pz << " energy = " << energy << endl;
3240  //reco::TrackRef trackRef = eltTrack->trackRef();
3242  reco::Track trackRefit = vRef->refittedTrack(trackRef);
3243  //change the momentum with the refitted track
3244  ::math::XYZTLorentzVector momentum(trackRefit.px(),
3245  trackRefit.py(),
3246  trackRefit.pz(),
3247  sqrt(trackRefit.p()*trackRefit.p() + 0.13957*0.13957));
3248  if (debug_)
3249  cout << "Refitted px = " << px << " py = " << py << " pz = " << pz << " energy = " << energy << endl;
3250  }
3251  pfCandidates_->back().setFlag( reco::PFCandidate::T_FROM_DISP, true);
3252  pfCandidates_->back().setDisplacedVertexRef( eltTrack->displacedVertexRef(reco::PFBlockElement::T_FROM_DISP)->displacedVertexRef(), reco::PFCandidate::T_FROM_DISP);
3253  }
3254 
3255  // 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
3256  if(isFromSecInt(elt, "primary") && !isMuon) {
3257  pfCandidates_->back().setFlag( reco::PFCandidate::T_TO_DISP, true);
3258  pfCandidates_->back().setDisplacedVertexRef( eltTrack->displacedVertexRef(reco::PFBlockElement::T_TO_DISP)->displacedVertexRef(), reco::PFCandidate::T_TO_DISP);
3259  }
3260  // returns index to the newly created PFCandidate
3261  return pfCandidates_->size()-1;
3262 }
double p() const
momentum vector magnitude
Definition: TrackBase.h:663
bool isFromSecInt(const reco::PFBlockElement &eTrack, std::string order) const
Definition: PFAlgo.cc:3498
const reco::TrackRef & trackRef() const
ParticleType
particle types
Definition: PFCandidate.h:44
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
bool isMuon(const Candidate &part)
Definition: pdgIdUtils.h:11
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:675
PFMuonAlgo * pfmu_
Definition: PFAlgo.h:357
const math::XYZPointF & positionAtECALEntrance() const
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
tuple particleType
Definition: autophobj.py:28
T sqrt(T t)
Definition: SSEVec.h:48
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:687
double dptRel_DispVtx_
Definition: PFAlgo.h:383
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:39
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
const PFDisplacedTrackerVertexRef & displacedVertexRef(TrackType trType) const
bool debug_
Definition: PFAlgo.h:336
tuple cout
Definition: gather_cfg.py:121
int charge() const
track electric charge
Definition: TrackBase.h:615
const reco::MuonRef & muonRef() const
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:681
bool reconstructMuon(reco::PFCandidate &, const reco::MuonRef &, bool allowLoose=false)
Definition: PFMuonAlgo.cc:701
void PFAlgo::setAlgo ( int  algo)
inline

Definition at line 63 of file PFAlgo.h.

References algo_.

63 {algo_ = algo;}
int algo_
Definition: PFAlgo.h:335
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:388
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 connector_, and PFCandConnector::setParameters().

82  {
83  connector_.setParameters(bCorrect, bCalibPrimary, dptRel_PrimaryTrack, dptRel_MergedTrack, ptErrorSecondary, nuclCalibFactors);
84  }
PFCandConnector connector_
Definition: PFAlgo.h:388
void setParameters(const edm::ParameterSet &iCfgCandConnector)
void PFAlgo::setDebug ( bool  debug)
inline

Definition at line 66 of file PFAlgo.h.

References connector_, debug, debug_, and PFCandConnector::setDebug().

PFCandConnector connector_
Definition: PFAlgo.h:388
#define debug
Definition: HDRShower.cc:19
bool debug_
Definition: PFAlgo.h:336
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 353 of file PFAlgo.cc.

References dptRel_DispVtx_, rejectTracks_Bad_, rejectTracks_Step45_, usePFConversions_, usePFDecays_, and usePFNuclearInteractions_.

358  {
359 
360  rejectTracks_Bad_ = rejectTracks_Bad;
361  rejectTracks_Step45_ = rejectTracks_Step45;
362  usePFNuclearInteractions_ = usePFNuclearInteractions;
363  usePFConversions_ = usePFConversions;
364  usePFDecays_ = usePFDecays;
365  dptRel_DispVtx_ = dptRel_DispVtx;
366 
367 }
bool usePFConversions_
Definition: PFAlgo.h:378
bool rejectTracks_Step45_
Definition: PFAlgo.h:375
bool usePFNuclearInteractions_
Definition: PFAlgo.h:377
double dptRel_DispVtx_
Definition: PFAlgo.h:383
bool rejectTracks_Bad_
Definition: PFAlgo.h:374
bool usePFDecays_
Definition: PFAlgo.h:379
void PFAlgo::setEGammaCollections ( const edm::View< reco::PFCandidate > &  pfEgammaCandidates,
const edm::ValueMap< reco::GsfElectronRef > &  valueMapGedElectrons,
const edm::ValueMap< reco::PhotonRef > &  valueMapGedPhotons 
)

Definition at line 266 of file PFAlgo.cc.

References pfEgammaCandidates_, useEGammaFilters_, valueMapGedElectrons_, and valueMapGedPhotons_.

268  {
269  if(useEGammaFilters_) {
270  pfEgammaCandidates_ = & pfEgammaCandidates;
271  valueMapGedElectrons_ = & valueMapGedElectrons;
272  valueMapGedPhotons_ = & valueMapGedPhotons;
273  }
274 }
const edm::ValueMap< reco::PhotonRef > * valueMapGedPhotons_
Definition: PFAlgo.h:366
const edm::View< reco::PFCandidate > * pfEgammaCandidates_
Definition: PFAlgo.h:364
bool useEGammaFilters_
Variables for NEW EGAMMA selection.
Definition: PFAlgo.h:361
const edm::ValueMap< reco::GsfElectronRef > * valueMapGedElectrons_
Definition: PFAlgo.h:365
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,
double  ph_MinEt,
double  ph_combIso,
double  ph_HoE,
double  ph_sietaieta_eb,
double  ph_sietaieta_ee,
const edm::ParameterSet ph_protectionsForJetMET 
)

Definition at line 211 of file PFAlgo.cc.

References pfegamma_, useEGammaFilters_, and useProtectionsForJetMET_.

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

Definition at line 3529 of file PFAlgo.cc.

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

3529  {
3531 }
PFElectronAlgo * pfele_
Definition: PFAlgo.h:355
bool useEGElectrons_
Definition: PFAlgo.h:346
void setEGElectronCollection(const reco::GsfElectronCollection &egelectrons)
void PFAlgo::setElectronExtraRef ( const edm::OrphanHandle< reco::PFCandidateElectronExtraCollection > &  extrah)

Definition at line 3746 of file PFAlgo.cc.

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

3746  {
3747  if(!usePFElectrons_) return;
3748  // std::cout << " setElectronExtraRef " << std::endl;
3749  unsigned size=pfCandidates_->size();
3750 
3751  for(unsigned ic=0;ic<size;++ic) {
3752  // select the electrons and add the extra
3753  if((*pfCandidates_)[ic].particleId()==PFCandidate::e) {
3754 
3755  PFElectronExtraEqual myExtraEqual((*pfCandidates_)[ic].gsfTrackRef());
3756  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3757  if(it!=pfElectronExtra_.end()) {
3758  // std::cout << " Index " << it-pfElectronExtra_.begin() << std::endl;
3759  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3760  (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3761  }
3762  else {
3763  (*pfCandidates_)[ic].setPFElectronExtraRef(PFCandidateElectronExtraRef());
3764  }
3765  }
3766  else // else save the mva and the extra as well !
3767  {
3768  if((*pfCandidates_)[ic].trackRef().isNonnull()) {
3769  PFElectronExtraKfEqual myExtraEqual((*pfCandidates_)[ic].trackRef());
3770  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3771  if(it!=pfElectronExtra_.end()) {
3772  (*pfCandidates_)[ic].set_mva_e_pi(it->mvaVariable(PFCandidateElectronExtra::MVA_MVA));
3773  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3774  (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3775  (*pfCandidates_)[ic].setGsfTrackRef(it->gsfTrackRef());
3776  }
3777  }
3778  }
3779 
3780  }
3781 
3782  size=pfElectronCandidates_->size();
3783  for(unsigned ic=0;ic<size;++ic) {
3784  // select the electrons - this test is actually not needed for this collection
3785  if((*pfElectronCandidates_)[ic].particleId()==PFCandidate::e) {
3786  // find the corresponding extra
3787  PFElectronExtraEqual myExtraEqual((*pfElectronCandidates_)[ic].gsfTrackRef());
3788  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3789  if(it!=pfElectronExtra_.end()) {
3790  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3791  (*pfElectronCandidates_)[ic].setPFElectronExtraRef(theRef);
3792 
3793  }
3794  }
3795  }
3796 
3797 }
edm::Ref< PFCandidateElectronExtraCollection > PFCandidateElectronExtraRef
persistent reference to a PFCandidateElectronExtra
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
std::auto_ptr< reco::PFCandidateCollection > pfElectronCandidates_
the unfiltered electron collection
Definition: PFAlgo.h:286
reco::PFCandidateElectronExtraCollection pfElectronExtra_
the unfiltered electron collection
Definition: PFAlgo.h:293
tuple size
Write out results.
bool usePFElectrons_
Definition: PFAlgo.h:342
void PFAlgo::setHOTag ( bool  ho)
inline

Definition at line 62 of file PFAlgo.h.

References useHO_.

62 { useHO_ = ho;}
bool useHO_
Definition: PFAlgo.h:334
void PFAlgo::setMuonHandle ( const edm::Handle< reco::MuonCollection > &  muons)

Definition at line 330 of file PFAlgo.cc.

References muonHandle_, and patZpeak::muons.

330  {
331  muonHandle_ = muons;
332 }
edm::Handle< reco::MuonCollection > muonHandle_
Definition: PFAlgo.h:413
tuple muons
Definition: patZpeak.py:38
void PFAlgo::setParameters ( double  nSigmaECAL,
double  nSigmaHCAL,
const boost::shared_ptr< PFEnergyCalibration > &  calibration,
const boost::shared_ptr< PFEnergyCalibrationHF > &  thepfEnergyCalibrationHF 
)

Definition at line 78 of file PFAlgo.cc.

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

81  {
82 
83  nSigmaECAL_ = nSigmaECAL;
85 
86  calibration_ = calibration;
87  thepfEnergyCalibrationHF_ = thepfEnergyCalibrationHF;
88 
89 }
double nSigmaHCAL_
number of sigma to judge energy excess in HCAL
Definition: PFAlgo.h:328
double nSigmaHCAL(double clusterEnergy, double clusterEta) const
Definition: PFAlgo.cc:3393
boost::shared_ptr< PFEnergyCalibration > calibration_
Definition: PFAlgo.h:330
boost::shared_ptr< PFEnergyCalibrationHF > thepfEnergyCalibrationHF_
Definition: PFAlgo.h:331
double nSigmaECAL_
number of sigma to judge energy excess in ECAL
Definition: PFAlgo.h:325
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 98 of file PFAlgo.cc.

References applyCrackCorrectionsElectrons_, coneEcalIsoForEgammaSC_, coneTrackIsoForEgammaSC_, mvaEleCut_, mvaWeightFileEleID_, nTrackIsoForEgammaSC_, pfele_, sumEtEcalIsoForEgammaSC_barrel_, sumEtEcalIsoForEgammaSC_endcap_, sumPtTrackIsoForEgammaSC_barrel_, sumPtTrackIsoForEgammaSC_endcap_, thePFSCEnergyCalibration_, useEGammaSupercluster_, useEGElectrons_, usePFElectrons_, and usePFSCEleCalib_.

113  {
114 
115  mvaEleCut_ = mvaEleCut;
116  usePFElectrons_ = usePFElectrons;
117  applyCrackCorrectionsElectrons_ = applyCrackCorrections;
118  usePFSCEleCalib_ = usePFSCEleCalib;
119  thePFSCEnergyCalibration_ = thePFSCEnergyCalibration;
120  useEGElectrons_ = useEGElectrons;
121  useEGammaSupercluster_ = useEGammaSupercluster;
122  sumEtEcalIsoForEgammaSC_barrel_ = sumEtEcalIsoForEgammaSC_barrel;
123  sumEtEcalIsoForEgammaSC_endcap_ = sumEtEcalIsoForEgammaSC_endcap;
124  coneEcalIsoForEgammaSC_ = coneEcalIsoForEgammaSC;
125  sumPtTrackIsoForEgammaSC_barrel_ = sumPtTrackIsoForEgammaSC_barrel;
126  sumPtTrackIsoForEgammaSC_endcap_ = sumPtTrackIsoForEgammaSC_endcap;
127  coneTrackIsoForEgammaSC_ = coneTrackIsoForEgammaSC;
128  nTrackIsoForEgammaSC_ = nTrackIsoForEgammaSC;
129 
130 
131  if(!usePFElectrons_) return;
132  mvaWeightFileEleID_ = mvaWeightFileEleID;
133  FILE * fileEleID = fopen(mvaWeightFileEleID_.c_str(), "r");
134  if (fileEleID) {
135  fclose(fileEleID);
136  }
137  else {
138  string err = "PFAlgo: cannot open weight file '";
139  err += mvaWeightFileEleID;
140  err += "'";
141  throw invalid_argument( err );
142  }
157 }
unsigned int nTrackIsoForEgammaSC_
Definition: PFAlgo.h:354
double sumEtEcalIsoForEgammaSC_endcap_
Definition: PFAlgo.h:349
double mvaEleCut_
Definition: PFAlgo.h:341
double coneEcalIsoForEgammaSC_
Definition: PFAlgo.h:350
double coneTrackIsoForEgammaSC_
Definition: PFAlgo.h:353
double sumEtEcalIsoForEgammaSC_barrel_
Definition: PFAlgo.h:348
PFElectronAlgo * pfele_
Definition: PFAlgo.h:355
bool useEGammaSupercluster_
Definition: PFAlgo.h:347
boost::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration()
return the pointer to the calibration function
Definition: PFAlgo.h:234
bool useEGElectrons_
Definition: PFAlgo.h:346
std::string mvaWeightFileEleID_
Variables for PFElectrons.
Definition: PFAlgo.h:339
bool usePFSCEleCalib_
Definition: PFAlgo.h:345
boost::shared_ptr< PFSCEnergyCalibration > thePFSCEnergyCalibration_
Definition: PFAlgo.h:332
bool applyCrackCorrectionsElectrons_
Definition: PFAlgo.h:344
double sumPtTrackIsoForEgammaSC_endcap_
Definition: PFAlgo.h:352
double sumPtTrackIsoForEgammaSC_barrel_
Definition: PFAlgo.h:351
bool usePFElectrons_
Definition: PFAlgo.h:342
void PFAlgo::setPFMuonAlgo ( PFMuonAlgo algo)
inline

Definition at line 64 of file PFAlgo.h.

References pfmu_.

64 {pfmu_ =algo;}
PFMuonAlgo * pfmu_
Definition: PFAlgo.h:357
void PFAlgo::setPFMuonAndFakeParameters ( const edm::ParameterSet pset)

Definition at line 301 of file PFAlgo.cc.

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

308 {
309 
310 
311 
312 
313  pfmu_ = new PFMuonAlgo();
314  pfmu_->setParameters(pset);
315 
316  // Muon parameters
317  muonHCAL_= pset.getParameter<std::vector<double> >("muon_HCAL");
318  muonECAL_= pset.getParameter<std::vector<double> >("muon_ECAL");
319  muonHO_= pset.getParameter<std::vector<double> >("muon_HO");
320  assert ( muonHCAL_.size() == 2 && muonECAL_.size() == 2 && muonHO_.size() == 2);
321  nSigmaTRACK_= pset.getParameter<double>("nsigma_TRACK");
322  ptError_= pset.getParameter<double>("pt_Error");
323  factors45_ = pset.getParameter<std::vector<double> >("factors_45");
324  assert ( factors45_.size() == 2 );
325 
326 }
T getParameter(std::string const &) const
double ptError_
Definition: PFAlgo.h:395
std::vector< double > muonHCAL_
Variables for muons and fakes.
Definition: PFAlgo.h:391
void setParameters(const edm::ParameterSet &)
Definition: PFMuonAlgo.cc:29
PFMuonAlgo * pfmu_
Definition: PFAlgo.h:357
std::vector< double > factors45_
Definition: PFAlgo.h:396
std::vector< double > muonECAL_
Definition: PFAlgo.h:392
std::vector< double > muonHO_
Definition: PFAlgo.h:393
double nSigmaTRACK_
Definition: PFAlgo.h:394
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 160 of file PFAlgo.cc.

References alignCSCRings::e, AlCaHLTBitMon_ParallelJobs::p, pfpho_, primaryVertex_, MetAnalyzer::pv(), usePFPhotons_, useVertices_, and hltvertexperformanceanalyzer_cfi::Vertex.

168  {
169 
170  usePFPhotons_ = usePFPhotons;
171 
172  //for MVA pass PV if there is one in the collection otherwise pass a dummy
173  reco::Vertex dummy;
174  if(useVertices_)
175  {
176  dummy = primaryVertex_;
177  }
178  else { // create a dummy PV
180  e(0, 0) = 0.0015 * 0.0015;
181  e(1, 1) = 0.0015 * 0.0015;
182  e(2, 2) = 15. * 15.;
183  reco::Vertex::Point p(0, 0, 0);
184  dummy = reco::Vertex(p, e, 0, 0, 0);
185  }
186  // pv=&dummy;
187  if(! usePFPhotons_) return;
188  FILE * filePhotonConvID = fopen(mvaWeightFileConvID.c_str(), "r");
189  if (filePhotonConvID) {
190  fclose(filePhotonConvID);
191  }
192  else {
193  string err = "PFAlgo: cannot open weight file '";
194  err += mvaWeightFileConvID;
195  err += "'";
196  throw invalid_argument( err );
197  }
198  const reco::Vertex* pv=&dummy;
199  pfpho_ = new PFPhotonAlgo(mvaWeightFileConvID,
200  mvaConvCut,
201  useReg,
202  X0_Map,
203  *pv,
205  sumPtTrackIsoForPhoton,
206  sumPtTrackIsoSlopeForPhoton
207  );
208  return;
209 }
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:234
PFPhotonAlgo * pfpho_
Definition: PFAlgo.h:356
reco::Vertex primaryVertex_
Definition: PFAlgo.h:410
math::XYZPoint Point
point in the space
Definition: Vertex.h:39
bool useVertices_
Definition: PFAlgo.h:411
bool usePFPhotons_
Definition: PFAlgo.h:343
void PFAlgo::setPFPhotonRegWeights ( const GBRForest LCorrForestEB,
const GBRForest LCorrForestEE,
const GBRForest GCorrForestBarrel,
const GBRForest GCorrForestEndcapHr9,
const GBRForest GCorrForestEndcapLr9,
const GBRForest PFEcalResolution 
)

Definition at line 288 of file PFAlgo.cc.

References pfpho_, and PFPhotonAlgo::setGBRForest().

294  {
295 
296  pfpho_->setGBRForest(LCorrForestEB,LCorrForestEE,
297  GCorrForestBarrel, GCorrForestEndcapHr9,
298  GCorrForestEndcapLr9, PFEcalResolution);
299 }
PFPhotonAlgo * pfpho_
Definition: PFAlgo.h:356
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 371 of file PFAlgo.cc.

References alignCSCRings::e, i, nVtx_, AlCaHLTBitMon_ParallelJobs::p, pfmu_, pfpho_, primaryVertex_, PFMuonAlgo::setInputsForCleaning(), PFPhotonAlgo::setnPU(), PFPhotonAlgo::setPhotonPrimaryVtx(), usePFPhotons_, useVertices_, and hltvertexperformanceanalyzer_cfi::Vertex.

372  {
373  useVertices_ = useVertex;
374 
375  //Set the vertices for muon cleaning
376  pfmu_->setInputsForCleaning(primaryVertices);
377 
378 
379  //Now find the primary vertex!
380  bool primaryVertexFound = false;
381  nVtx_ = primaryVertices->size();
382  if(usePFPhotons_){
383  pfpho_->setnPU(nVtx_);
384  }
385  for (unsigned short i=0 ;i<primaryVertices->size();++i)
386  {
387  if(primaryVertices->at(i).isValid()&&(!primaryVertices->at(i).isFake()))
388  {
389  primaryVertex_ = primaryVertices->at(i);
390  primaryVertexFound = true;
391  break;
392  }
393  }
394  //Use vertices if the user wants to but only if it exists a good vertex
395  useVertices_ = useVertex && primaryVertexFound;
396  if(usePFPhotons_) {
397  if (useVertices_ ){
399  }
400  else{
402  e(0, 0) = 0.0015 * 0.0015;
403  e(1, 1) = 0.0015 * 0.0015;
404  e(2, 2) = 15. * 15.;
405  reco::Vertex::Point p(0, 0, 0);
406  reco::Vertex dummy = reco::Vertex(p, e, 0, 0, 0);
407  // std::cout << " PFPho " << pfpho_ << std::endl;
408  pfpho_->setPhotonPrimaryVtx(dummy);
409  }
410  }
411 }
int i
Definition: DBlmapReader.cc:9
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:357
int nVtx_
Definition: PFAlgo.h:384
PFPhotonAlgo * pfpho_
Definition: PFAlgo.h:356
reco::Vertex primaryVertex_
Definition: PFAlgo.h:410
math::XYZPoint Point
point in the space
Definition: Vertex.h:39
bool useVertices_
Definition: PFAlgo.h:411
void setPhotonPrimaryVtx(const reco::Vertex &primary)
Definition: PFPhotonAlgo.h:78
bool usePFPhotons_
Definition: PFAlgo.h:343
void setInputsForCleaning(const reco::VertexCollection *)
Definition: PFMuonAlgo.cc:1153
void PFAlgo::setPhotonExtraRef ( const edm::OrphanHandle< reco::PFCandidatePhotonExtraCollection > &  pf_extrah)

Definition at line 3798 of file PFAlgo.cc.

References newFWLiteAna::found, pfCandidates_, pfPhotonExtra_, findQualityFiles::size, and usePFPhotons_.

3798  {
3799  if(!usePFPhotons_) return;
3800  unsigned int size=pfCandidates_->size();
3801  unsigned int sizePhExtra = pfPhotonExtra_.size();
3802  for(unsigned ic=0;ic<size;++ic) {
3803  // select the electrons and add the extra
3804  if((*pfCandidates_)[ic].particleId()==PFCandidate::gamma && (*pfCandidates_)[ic].mva_nothing_gamma() > 0.99) {
3805  if((*pfCandidates_)[ic].superClusterRef().isNonnull()) {
3806  bool found = false;
3807  for(unsigned pcextra=0;pcextra<sizePhExtra;++pcextra) {
3808  if((*pfCandidates_)[ic].superClusterRef() == pfPhotonExtra_[pcextra].superClusterRef()) {
3809  reco::PFCandidatePhotonExtraRef theRef(ph_extrah,pcextra);
3810  (*pfCandidates_)[ic].setPFPhotonExtraRef(theRef);
3811  found = true;
3812  break;
3813  }
3814  }
3815  if(!found)
3816  (*pfCandidates_)[ic].setPFPhotonExtraRef((PFCandidatePhotonExtraRef())); // null ref
3817  }
3818  else {
3819  (*pfCandidates_)[ic].setPFPhotonExtraRef((PFCandidatePhotonExtraRef())); // null ref
3820  }
3821  }
3822  }
3823 }
edm::Ref< PFCandidatePhotonExtraCollection > PFCandidatePhotonExtraRef
persistent reference to a PFCandidatePhotonExtra
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
the extra photon collection
Definition: PFAlgo.h:295
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
bool usePFPhotons_
Definition: PFAlgo.h:343
tuple size
Write out results.
void PFAlgo::setPostHFCleaningParameters ( bool  postHFCleaning,
double  minHFCleaningPt,
double  minSignificance,
double  maxSignificance,
double  minSignificanceReduction,
double  maxDeltaPhiPt,
double  minDeltaMet 
)

Definition at line 336 of file PFAlgo.cc.

References maxDeltaPhiPt_, maxSignificance_, minDeltaMet_, minHFCleaningPt_, minSignificance_, minSignificanceReduction_, and postHFCleaning_.

342  {
343  postHFCleaning_ = postHFCleaning;
344  minHFCleaningPt_ = minHFCleaningPt;
345  minSignificance_ = minSignificance;
346  maxSignificance_ = maxSignificance;
347  minSignificanceReduction_= minSignificanceReduction;
348  maxDeltaPhiPt_ = maxDeltaPhiPt;
349  minDeltaMet_ = minDeltaMet;
350 }
double maxDeltaPhiPt_
Definition: PFAlgo.h:405
double maxSignificance_
Definition: PFAlgo.h:403
double minHFCleaningPt_
Definition: PFAlgo.h:401
double minDeltaMet_
Definition: PFAlgo.h:406
double minSignificance_
Definition: PFAlgo.h:402
double minSignificanceReduction_
Definition: PFAlgo.h:404
bool postHFCleaning_
Definition: PFAlgo.h:399
boost::shared_ptr<PFEnergyCalibration> PFAlgo::thePFEnergyCalibration ( )
inline

return the pointer to the calibration function

Definition at line 234 of file PFAlgo.h.

References calibration_.

234  {
235  return calibration_;
236  }
boost::shared_ptr< PFEnergyCalibration > calibration_
Definition: PFAlgo.h:330
std::auto_ptr< reco::PFCandidateCollection > PFAlgo::transferCandidates ( )
inline
Returns
auto_ptr to the collection of candidates (transfers ownership)

Definition at line 229 of file PFAlgo.h.

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

229  {
231  }
std::auto_ptr< reco::PFCandidateCollection > connect(std::auto_ptr< reco::PFCandidateCollection > &pfCand)
PFCandConnector connector_
Definition: PFAlgo.h:388
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
std::auto_ptr< reco::PFCandidateCollection >& PFAlgo::transferCleanedCandidates ( )
inline
Returns
collection of cleaned HF candidates

Definition at line 224 of file PFAlgo.h.

References pfCleanedCandidates_.

224  {
225  return pfCleanedCandidates_;
226  }
std::auto_ptr< reco::PFCandidateCollection > pfCleanedCandidates_
Definition: PFAlgo.h:290
std::auto_ptr< reco::PFCandidateCollection> PFAlgo::transferElectronCandidates ( )
inline
Returns
the unfiltered electron collection

Definition at line 201 of file PFAlgo.h.

References pfElectronCandidates_.

201  {
202  return pfElectronCandidates_;
203  }
std::auto_ptr< reco::PFCandidateCollection > pfElectronCandidates_
the unfiltered electron collection
Definition: PFAlgo.h:286
std::auto_ptr< reco::PFCandidateElectronExtraCollection> PFAlgo::transferElectronExtra ( )
inline
Returns
the unfiltered electron extra collection

Definition at line 207 of file PFAlgo.h.

References pfElectronExtra_, and query::result.

207  {
208  std::auto_ptr< reco::PFCandidateElectronExtraCollection> result(new reco::PFCandidateElectronExtraCollection);
209  result->insert(result->end(),pfElectronExtra_.begin(),pfElectronExtra_.end());
210  return result;
211  }
tuple result
Definition: query.py:137
std::vector< reco::PFCandidateElectronExtra > PFCandidateElectronExtraCollection
collection of PFCandidateElectronExtras
reco::PFCandidateElectronExtraCollection pfElectronExtra_
the unfiltered electron collection
Definition: PFAlgo.h:293
std::auto_ptr< reco::PFCandidatePhotonExtraCollection> PFAlgo::transferPhotonExtra ( )
inline
Returns
the unfiltered photon extra collection

Definition at line 216 of file PFAlgo.h.

References pfPhotonExtra_, and query::result.

216  {
217  std::auto_ptr< reco::PFCandidatePhotonExtraCollection> result(new reco::PFCandidatePhotonExtraCollection);
218  result->insert(result->end(),pfPhotonExtra_.begin(),pfPhotonExtra_.end());
219  return result;
220  }
tuple result
Definition: query.py:137
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
the extra photon collection
Definition: PFAlgo.h:295
std::vector< reco::PFCandidatePhotonExtra > PFCandidatePhotonExtraCollection
collection of PFCandidatePhotonExtras

Friends And Related Function Documentation

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

Member Data Documentation

int PFAlgo::algo_
private

Definition at line 335 of file PFAlgo.h.

Referenced by setAlgo().

bool PFAlgo::applyCrackCorrectionsElectrons_
private

Definition at line 344 of file PFAlgo.h.

Referenced by setPFEleParameters().

reco::PFBlockHandle PFAlgo::blockHandle_
private

input block handle (full framework case)

Definition at line 322 of file PFAlgo.h.

Referenced by createBlockRef(), and reconstructParticles().

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

Definition at line 330 of file PFAlgo.h.

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

double PFAlgo::coneEcalIsoForEgammaSC_
private

Definition at line 350 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::coneTrackIsoForEgammaSC_
private

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

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

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

Definition at line 396 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

double PFAlgo::maxDeltaPhiPt_
private

Definition at line 405 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::maxSignificance_
private

Definition at line 403 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::minDeltaMet_
private

Definition at line 406 of file PFAlgo.h.

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

double PFAlgo::minHFCleaningPt_
private

Definition at line 401 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::minSignificance_
private

Definition at line 402 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::minSignificanceReduction_
private

Definition at line 404 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

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

Definition at line 392 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

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

Definition at line 413 of file PFAlgo.h.

Referenced by reconstructParticles(), and setMuonHandle().

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

Variables for muons and fakes.

Definition at line 391 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

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

Definition at line 393 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

double PFAlgo::mvaEleCut_
private

Definition at line 341 of file PFAlgo.h.

Referenced by setPFEleParameters().

std::string PFAlgo::mvaWeightFileEleID_
private

Variables for PFElectrons.

Definition at line 339 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::nSigmaECAL_
private

number of sigma to judge energy excess in ECAL

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

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

double PFAlgo::nSigmaTRACK_
private

Definition at line 394 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

unsigned int PFAlgo::nTrackIsoForEgammaSC_
private

Definition at line 354 of file PFAlgo.h.

Referenced by setPFEleParameters().

int PFAlgo::nVtx_
private

Definition at line 384 of file PFAlgo.h.

Referenced by processBlock(), and setPFVertexParameters().

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

Definition at line 290 of file PFAlgo.h.

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

PFEGammaFilters* PFAlgo::pfegamma_
private

Definition at line 362 of file PFAlgo.h.

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

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

Definition at line 364 of file PFAlgo.h.

Referenced by processBlock(), and setEGammaCollections().

PFElectronAlgo* PFAlgo::pfele_
private

Definition at line 355 of file PFAlgo.h.

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

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

the unfiltered electron collection

Definition at line 286 of file PFAlgo.h.

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

reco::PFCandidateElectronExtraCollection PFAlgo::pfElectronExtra_
protected

the unfiltered electron collection

Definition at line 293 of file PFAlgo.h.

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

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

the unfiltered photon collection

Definition at line 288 of file PFAlgo.h.

Referenced by processBlock(), and reconstructParticles().

reco::PFCandidatePhotonExtraCollection PFAlgo::pfPhotonExtra_
protected

the extra photon collection

Definition at line 295 of file PFAlgo.h.

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

bool PFAlgo::postHFCleaning_
private

Definition at line 399 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

bool PFAlgo::postMuonCleaning_
private

Definition at line 400 of file PFAlgo.h.

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

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

Referenced by processBlock(), and setDisplacedVerticesParameters().

bool PFAlgo::rejectTracks_Step45_
private

Definition at line 375 of file PFAlgo.h.

Referenced by processBlock(), and setDisplacedVerticesParameters().

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

Definition at line 340 of file PFAlgo.h.

double PFAlgo::sumEtEcalIsoForEgammaSC_barrel_
private

Definition at line 348 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::sumEtEcalIsoForEgammaSC_endcap_
private

Definition at line 349 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::sumPtTrackIsoForEgammaSC_barrel_
private

Definition at line 351 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::sumPtTrackIsoForEgammaSC_endcap_
private

Definition at line 352 of file PFAlgo.h.

Referenced by setPFEleParameters().

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

Definition at line 331 of file PFAlgo.h.

Referenced by processBlock(), and setParameters().

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

Definition at line 332 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::useBestMuonTrack_
private

Definition at line 407 of file PFAlgo.h.

bool PFAlgo::useEGammaFilters_
private

Variables for NEW EGAMMA selection.

Definition at line 361 of file PFAlgo.h.

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

bool PFAlgo::useEGammaSupercluster_
private

Definition at line 347 of file PFAlgo.h.

Referenced by setPFEleParameters().

bool PFAlgo::useEGElectrons_
private

Definition at line 346 of file PFAlgo.h.

Referenced by setEGElectronCollection(), and setPFEleParameters().

bool PFAlgo::useHO_
private

Definition at line 334 of file PFAlgo.h.

Referenced by processBlock(), and setHOTag().

bool PFAlgo::usePFConversions_
private

Definition at line 378 of file PFAlgo.h.

Referenced by processBlock(), and setDisplacedVerticesParameters().

bool PFAlgo::usePFDecays_
private

Definition at line 379 of file PFAlgo.h.

Referenced by isFromSecInt(), and setDisplacedVerticesParameters().

bool PFAlgo::usePFElectrons_
private

Definition at line 342 of file PFAlgo.h.

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

bool PFAlgo::usePFMuonMomAssign_
private

Definition at line 370 of file PFAlgo.h.

bool PFAlgo::usePFNuclearInteractions_
private

Definition at line 377 of file PFAlgo.h.

Referenced by isFromSecInt(), and setDisplacedVerticesParameters().

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

Definition at line 345 of file PFAlgo.h.

Referenced by setPFEleParameters().

bool PFAlgo::useProtectionsForJetMET_
private

Definition at line 363 of file PFAlgo.h.

Referenced by processBlock(), and setEGammaParameters().

bool PFAlgo::useVertices_
private

Definition at line 411 of file PFAlgo.h.

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

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

Definition at line 365 of file PFAlgo.h.

Referenced by setEGammaCollections().

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

Definition at line 366 of file PFAlgo.h.

Referenced by setEGammaCollections().