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

3414  {
3415 
3416  // Find all PS clusters with type psElement associated to ECAL cluster iEcal,
3417  // within all PFBlockElement "elements" of a given PFBlock "block"
3418  // psElement can be reco::PFBlockElement::PS1 or reco::PFBlockElement::PS2
3419  // Returns a vector of PS cluster energies, and updates the "active" vector.
3420 
3421  // Find all PS clusters linked to the iEcal cluster
3422  std::multimap<double, unsigned> sortedPS;
3423  typedef std::multimap<double, unsigned>::iterator IE;
3424  block.associatedElements( iEcal, linkData,
3425  sortedPS, psElementType,
3427 
3428  // Loop over these PS clusters
3429  double totalPS = 0.;
3430  for ( IE ips=sortedPS.begin(); ips!=sortedPS.end(); ++ips ) {
3431 
3432  // CLuster index and distance to iEcal
3433  unsigned iPS = ips->second;
3434  // double distPS = ips->first;
3435 
3436  // Ignore clusters already in use
3437  if (!active[iPS]) continue;
3438 
3439  // Check that this cluster is not closer to another ECAL cluster
3440  std::multimap<double, unsigned> sortedECAL;
3441  block.associatedElements( iPS, linkData,
3442  sortedECAL,
3445  unsigned jEcal = sortedECAL.begin()->second;
3446  if ( jEcal != iEcal ) continue;
3447 
3448  // Update PS energy
3449  PFBlockElement::Type pstype = elements[ iPS ].type();
3450  assert( pstype == psElementType );
3451  PFClusterRef psclusterref = elements[iPS].clusterRef();
3452  assert(!psclusterref.isNull() );
3453  totalPS += psclusterref->energy();
3454  psEne[0] += psclusterref->energy();
3455  active[iPS] = false;
3456  }
3457 
3458 
3459 }
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 3606 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(), RecoTauCleanerPlugins::pt, reco::LeafCandidate::pt(), reco::LeafCandidate::px(), reco::LeafCandidate::py(), reconstructCluster(), createPayload::skip, mathSSE::sqrt(), and reco::PFRecHit::time().

Referenced by PFRootEventManager::particleFlow().

3606  {
3607 
3608 
3609  // No hits to recover, leave.
3610  if ( !cleanedHits.size() ) return;
3611 
3612  //Compute met and met significance (met/sqrt(SumEt))
3613  double metX = 0.;
3614  double metY = 0.;
3615  double sumet = 0;
3616  std::vector<unsigned int> hitsToBeAdded;
3617  for(unsigned i=0; i<pfCandidates_->size(); i++) {
3618  const PFCandidate& pfc = (*pfCandidates_)[i];
3619  metX += pfc.px();
3620  metY += pfc.py();
3621  sumet += pfc.pt();
3622  }
3623  double met2 = metX*metX+metY*metY;
3624  double met2_Original = met2;
3625  // Select events with large MET significance.
3626  // double significance = std::sqrt(met2/sumet);
3627  // double significanceCor = significance;
3628  double metXCor = metX;
3629  double metYCor = metY;
3630  double sumetCor = sumet;
3631  double met2Cor = met2;
3632  bool next = true;
3633  unsigned iCor = 1E9;
3634 
3635  // Find the cleaned hit with the largest effect on the MET
3636  while ( next ) {
3637 
3638  double metReduc = -1.;
3639  // Loop on the candidates
3640  for(unsigned i=0; i<cleanedHits.size(); ++i) {
3641  const PFRecHit& hit = cleanedHits[i];
3642  double length = std::sqrt(hit.position().Mag2());
3643  double px = hit.energy() * hit.position().x()/length;
3644  double py = hit.energy() * hit.position().y()/length;
3645  double pt = std::sqrt(px*px + py*py);
3646 
3647  // Check that it is not already scheculed to be cleaned
3648  bool skip = false;
3649  for(unsigned j=0; j<hitsToBeAdded.size(); ++j) {
3650  if ( i == hitsToBeAdded[j] ) skip = true;
3651  if ( skip ) break;
3652  }
3653  if ( skip ) continue;
3654 
3655  // Now add the candidate to the MET
3656  double metXInt = metX + px;
3657  double metYInt = metY + py;
3658  double sumetInt = sumet + pt;
3659  double met2Int = metXInt*metXInt+metYInt*metYInt;
3660 
3661  // And check if it could contribute to a MET reduction
3662  if ( met2Int < met2Cor ) {
3663  metXCor = metXInt;
3664  metYCor = metYInt;
3665  metReduc = (met2-met2Int)/met2Int;
3666  met2Cor = met2Int;
3667  sumetCor = sumetInt;
3668  // significanceCor = std::sqrt(met2Cor/sumetCor);
3669  iCor = i;
3670  }
3671  }
3672  //
3673  // If the MET must be significanly reduced, schedule the candidate to be added
3674  //
3675  if ( metReduc > minDeltaMet_ ) {
3676  hitsToBeAdded.push_back(iCor);
3677  metX = metXCor;
3678  metY = metYCor;
3679  sumet = sumetCor;
3680  met2 = met2Cor;
3681  } else {
3682  // Otherwise just stop the loop
3683  next = false;
3684  }
3685  }
3686  //
3687  // At least 10 GeV MET reduction
3688  if ( std::sqrt(met2_Original) - std::sqrt(met2) > 5. ) {
3689  if ( debug_ ) {
3690  std::cout << hitsToBeAdded.size() << " hits were re-added " << std::endl;
3691  std::cout << "MET reduction = " << std::sqrt(met2_Original) << " -> "
3692  << std::sqrt(met2Cor) << " = " << std::sqrt(met2Cor) - std::sqrt(met2_Original)
3693  << std::endl;
3694  std::cout << "Added after cleaning check : " << std::endl;
3695  }
3696  for(unsigned j=0; j<hitsToBeAdded.size(); ++j) {
3697  const PFRecHit& hit = cleanedHits[hitsToBeAdded[j]];
3698  PFCluster cluster(hit.layer(), hit.energy(),
3699  hit.position().x(), hit.position().y(), hit.position().z() );
3700  reconstructCluster(cluster,hit.energy());
3701  if ( debug_ ) {
3702  std::cout << pfCandidates_->back() << ". time = " << hit.time() << std::endl;
3703  }
3704  }
3705  }
3706 
3707 }
int i
Definition: DBlmapReader.cc:9
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:43
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:3231
virtual double py() const GCC11_FINAL
y coordinate of momentum vector
PFLayer::Layer layer() const
rechit layer
Definition: PFRecHit.h:108
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
Definition: PFRecHit.h:31
T sqrt(T t)
Definition: SSEVec.h:48
virtual double px() const GCC11_FINAL
x coordinate of momentum vector
int j
Definition: DBlmapReader.cc:9
const math::XYZPoint & position() const
is seed ?
Definition: PFRecHit.h:141
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:38
double energy() const
rechit energy
Definition: PFRecHit.h:111
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:117
virtual float pt() const GCC11_FINAL
transverse momentum
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 3396 of file PFAlgo.cc.

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

Referenced by reconstructParticles().

3397  {
3398 
3399  if( blockHandle_.isValid() ) {
3400  return reco::PFBlockRef( blockHandle_, bi );
3401  }
3402  else {
3403  return reco::PFBlockRef( &blocks, bi );
3404  }
3405 }
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 3463 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().

3463  {
3464 
3467  // reco::PFBlockElement::TrackType T_FROM_GAMMACONV = reco::PFBlockElement::T_FROM_GAMMACONV;
3469 
3470  bool bPrimary = (order.find("primary") != string::npos);
3471  bool bSecondary = (order.find("secondary") != string::npos);
3472  bool bAll = (order.find("all") != string::npos);
3473 
3474  bool isToDisp = usePFNuclearInteractions_ && eTrack.trackType(T_TO_DISP);
3475  bool isFromDisp = usePFNuclearInteractions_ && eTrack.trackType(T_FROM_DISP);
3476 
3477  if (bPrimary && isToDisp) return true;
3478  if (bSecondary && isFromDisp ) return true;
3479  if (bAll && ( isToDisp || isFromDisp ) ) return true;
3480 
3481 // bool isFromConv = usePFConversions_ && eTrack.trackType(T_FROM_GAMMACONV);
3482 
3483 // if ((bAll || bSecondary)&& isFromConv) return true;
3484 
3485  bool isFromDecay = (bAll || bSecondary) && usePFDecays_ && eTrack.trackType(T_FROM_V0);
3486 
3487  return isFromDecay;
3488 
3489 
3490 }
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 3343 of file PFAlgo.cc.

References mathSSE::sqrt().

Referenced by processBlock().

3343  {
3344 
3345  // Add a protection
3346  if ( clusterEnergyHCAL < 1. ) clusterEnergyHCAL = 1.;
3347 
3348  double resol = fabs(eta) < 1.48 ?
3349  sqrt (1.02*1.02/clusterEnergyHCAL + 0.065*0.065)
3350  :
3351  sqrt (1.20*1.20/clusterEnergyHCAL + 0.028*0.028);
3352 
3353  return resol;
3354 
3355 }
T eta() const
T sqrt(T t)
Definition: SSEVec.h:48
double PFAlgo::nSigmaHCAL ( double  clusterEnergy,
double  clusterEta 
) const
protected

Definition at line 3358 of file PFAlgo.cc.

References create_public_lumi_plots::exp, and nSigmaHCAL_.

Referenced by processBlock(), and setParameters().

3358  {
3359  double nS = fabs(eta) < 1.48 ?
3360  nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.))
3361  :
3362  nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.));
3363 
3364  return nS;
3365 }
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 3499 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(), createPayload::skip, and mathSSE::sqrt().

Referenced by reconstructParticles().

3499  {
3500 
3501  // Check if the post HF Cleaning was requested - if not, do nothing
3502  if ( !postHFCleaning_ ) return;
3503 
3504  //Compute met and met significance (met/sqrt(SumEt))
3505  double metX = 0.;
3506  double metY = 0.;
3507  double sumet = 0;
3508  std::vector<unsigned int> pfCandidatesToBeRemoved;
3509  for(unsigned i=0; i<pfCandidates_->size(); i++) {
3510  const PFCandidate& pfc = (*pfCandidates_)[i];
3511  metX += pfc.px();
3512  metY += pfc.py();
3513  sumet += pfc.pt();
3514  }
3515  double met2 = metX*metX+metY*metY;
3516  // Select events with large MET significance.
3517  double significance = std::sqrt(met2/sumet);
3518  double significanceCor = significance;
3519  if ( significance > minSignificance_ ) {
3520 
3521  double metXCor = metX;
3522  double metYCor = metY;
3523  double sumetCor = sumet;
3524  double met2Cor = met2;
3525  double deltaPhi = 3.14159;
3526  double deltaPhiPt = 100.;
3527  bool next = true;
3528  unsigned iCor = 1E9;
3529 
3530  // Find the HF candidate with the largest effect on the MET
3531  while ( next ) {
3532 
3533  double metReduc = -1.;
3534  // Loop on the candidates
3535  for(unsigned i=0; i<pfCandidates_->size(); ++i) {
3536  const PFCandidate& pfc = (*pfCandidates_)[i];
3537 
3538  // Check that the pfCandidate is in the HF
3539  if ( pfc.particleId() != reco::PFCandidate::h_HF &&
3540  pfc.particleId() != reco::PFCandidate::egamma_HF ) continue;
3541 
3542  // Check if has meaningful pt
3543  if ( pfc.pt() < minHFCleaningPt_ ) continue;
3544 
3545  // Check that it is not already scheculed to be cleaned
3546  bool skip = false;
3547  for(unsigned j=0; j<pfCandidatesToBeRemoved.size(); ++j) {
3548  if ( i == pfCandidatesToBeRemoved[j] ) skip = true;
3549  if ( skip ) break;
3550  }
3551  if ( skip ) continue;
3552 
3553  // Check that the pt and the MET are aligned
3554  deltaPhi = std::acos((metX*pfc.px()+metY*pfc.py())/(pfc.pt()*std::sqrt(met2)));
3555  deltaPhiPt = deltaPhi*pfc.pt();
3556  if ( deltaPhiPt > maxDeltaPhiPt_ ) continue;
3557 
3558  // Now remove the candidate from the MET
3559  double metXInt = metX - pfc.px();
3560  double metYInt = metY - pfc.py();
3561  double sumetInt = sumet - pfc.pt();
3562  double met2Int = metXInt*metXInt+metYInt*metYInt;
3563  if ( met2Int < met2Cor ) {
3564  metXCor = metXInt;
3565  metYCor = metYInt;
3566  metReduc = (met2-met2Int)/met2Int;
3567  met2Cor = met2Int;
3568  sumetCor = sumetInt;
3569  significanceCor = std::sqrt(met2Cor/sumetCor);
3570  iCor = i;
3571  }
3572  }
3573  //
3574  // If the MET must be significanly reduced, schedule the candidate to be cleaned
3575  if ( metReduc > minDeltaMet_ ) {
3576  pfCandidatesToBeRemoved.push_back(iCor);
3577  metX = metXCor;
3578  metY = metYCor;
3579  sumet = sumetCor;
3580  met2 = met2Cor;
3581  } else {
3582  // Otherwise just stop the loop
3583  next = false;
3584  }
3585  }
3586  //
3587  // The significance must be significantly reduced to indeed clean the candidates
3588  if ( significance - significanceCor > minSignificanceReduction_ &&
3589  significanceCor < maxSignificance_ ) {
3590  std::cout << "Significance reduction = " << significance << " -> "
3591  << significanceCor << " = " << significanceCor - significance
3592  << std::endl;
3593  for(unsigned j=0; j<pfCandidatesToBeRemoved.size(); ++j) {
3594  std::cout << "Removed : " << (*pfCandidates_)[pfCandidatesToBeRemoved[j]] << std::endl;
3595  pfCleanedCandidates_->push_back( (*pfCandidates_)[ pfCandidatesToBeRemoved[j] ] );
3596  (*pfCandidates_)[pfCandidatesToBeRemoved[j]].rescaleMomentum(1E-6);
3597  //reco::PFCandidate::ParticleType unknown = reco::PFCandidate::X;
3598  //(*pfCandidates_)[pfCandidatesToBeRemoved[j]].setParticleType(unknown);
3599  }
3600  }
3601  }
3602 
3603 }
int i
Definition: DBlmapReader.cc:9
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
std::auto_ptr< reco::PFCandidateCollection > pfCleanedCandidates_
Definition: PFAlgo.h:290
virtual double py() const GCC11_FINAL
y coordinate of momentum vector
double minSignificanceReduction_
Definition: PFAlgo.h:404
bool postHFCleaning_
Definition: PFAlgo.h:399
T sqrt(T t)
Definition: SSEVec.h:48
virtual double px() const GCC11_FINAL
x coordinate of momentum vector
int j
Definition: DBlmapReader.cc:9
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:38
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
tuple cout
Definition: gather_cfg.py:121
virtual ParticleType particleId() const
Definition: PFCandidate.h:355
virtual float pt() const GCC11_FINAL
transverse momentum
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(), CastorDataFrameFilter_impl::check(), gather_cfg::cout, debug_, dptRel_DispVtx_, reco::PFCandidate::e, ECAL, reco::PFBlockElement::ECAL, reco::PFCandidate::egammaExtraRef(), asciidump::elements, reco::PFCandidate::elementsInBlocks(), reco::LeafCandidate::energy(), reco::LeafCandidate::eta(), 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::PFBlockElement::HO, i, cuy::ii, getHLTprescales::index, 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, max(), bookConverter::min, reco::PFCandidate::mu, muonECAL_, muonHCAL_, muonHO_, reco::PFCandidate::mva_e_pi(), neutralHadronEnergyResolution(), nSigmaECAL_, nSigmaHCAL(), nSigmaTRACK_, nVtx_, convertSQLiteXML::ok, AlCaHLTBitMon_ParallelJobs::p, PFEGammaFilters::passElectronSelection(), PFEGammaFilters::passPhotonSelection(), pfCandidates_, pfegamma_, pfEgammaCandidates_, pfele_, pfElectronCandidates_, pfElectronExtra_, pfpho_, pfPhotonCandidates_, pfPhotonExtra_, reco::LeafCandidate::phi(), 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_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(), createPayload::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());
713 
714  if(egmLocalDebug) {
715  cout << " PFAlgo: found an electron with NEW EGamma code " << endl;
716  cout << " myPFElectron: pt " << myPFElectron.pt()
717  << " eta,phi " << myPFElectron.eta() << ", " <<myPFElectron.phi()
718  << " mva " << myPFElectron.mva_e_pi()
719  << " charge " << myPFElectron.charge() << endl;
720  }
721 
722 
723  // Lock all the elements
724  if(egmLocalBlockDebug)
725  cout << " THE BLOCK " << *blockref << endl;
726  for (PFCandidate::ElementsInBlocks::const_iterator ieb = theElements.begin();
727  ieb<theElements.end(); ++ieb) {
728  active[ieb->second] = false;
729  if(egmLocalBlockDebug)
730  cout << " Elements used " << ieb->second << endl;
731  }
732 
733  // The electron is considered safe for JetMET and the additional tracks pointing to it are locked
734  if(lockTracks) {
735  const PFCandidate::ElementsInBlocks& extraTracks = myPFElectron.egammaExtraRef()->extraNonConvTracks();
736  for (PFCandidate::ElementsInBlocks::const_iterator itrk = extraTracks.begin();
737  itrk<extraTracks.end(); ++itrk) {
738  active[itrk->second] = false;
739  }
740  }
741 
742  pfCandidates_->push_back(myPFElectron);
743 
744  }
745  else {
746  if(egmLocalDebug)
747  cout << "PFAlgo: Electron DISCARDED, NOT SAFE FOR JETMET " << endl;
748  }
749  }
750  if(isGoodPhoton) {
751  reco::PhotonRef gedPhoRef = (*valueMapGedPhotons_)[pfEgmRef];
752  reco::PFCandidate myPFPhoton = *pfEgmRef;
753  bool isSafe = true;
755  isSafe = pfegamma_->isPhotonSafeForJetMET(*gedPhoRef,myPFPhoton);
756  }
757 
758 
759 
760  if(isSafe) {
762  myPFPhoton.setParticleType(particleType);
763  myPFPhoton.setCharge(0);
764  myPFPhoton.set_mva_nothing_gamma(1.);
766  myPFPhoton.setVertex( v );
767  myPFPhoton.setP4(gedPhoRef->p4());
768  if(egmLocalDebug) {
769  cout << " PFAlgo: found a photon with NEW EGamma code " << endl;
770  cout << " myPFPhoton: pt " << myPFPhoton.pt()
771  << " eta,phi " << myPFPhoton.eta() << ", " <<myPFPhoton.phi()
772  << " charge " << myPFPhoton.charge() << endl;
773  }
774 
775  // Lock all the elements
776  if(egmLocalBlockDebug)
777  cout << " THE BLOCK " << *blockref << endl;
778  for (PFCandidate::ElementsInBlocks::const_iterator ieb = theElements.begin();
779  ieb<theElements.end(); ++ieb) {
780  active[ieb->second] = false;
781  if(egmLocalBlockDebug)
782  cout << " Elements used " << ieb->second << endl;
783  }
784  pfCandidates_->push_back(myPFPhoton);
785 
786  } // end isSafe
787  } // end isGoodPhoton
788  } // end loop on EGM candidates
789  } // end if use EGammaFilters
790 
791 
792 
793  //Lock extra conversion tracks not used by Photon Algo
794  if (usePFConversions_ )
795  {
796  for(unsigned iEle=0; iEle<elements.size(); iEle++) {
797  PFBlockElement::Type type = elements[iEle].type();
798  if(type==PFBlockElement::TRACK)
799  {
800  if(elements[iEle].trackRef()->algo() == 12)
801  active[iEle]=false;
802  if(elements[iEle].trackRef()->quality(reco::TrackBase::highPurity))continue;
803  const reco::PFBlockElementTrack * trackRef = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[iEle]));
804  if(!(trackRef->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)))continue;
805  if(elements[iEle].convRef().isNonnull())active[iEle]=false;
806  }
807  }
808  }
809 
810 
811 
812 
813 
814  if(debug_)
815  cout<<endl<<"--------------- loop 1 ------------------"<<endl;
816 
817  //COLINFEB16
818  // In loop 1, we loop on all elements.
819 
820  // The primary goal is to deal with tracks that are:
821  // - not associated to an HCAL cluster
822  // - not identified as an electron.
823  // Those tracks should be predominantly relatively low energy charged
824  // hadrons which are not detected in the ECAL.
825 
826  // The secondary goal is to prepare for the next loops
827  // - The ecal and hcal elements are sorted in separate vectors
828  // which will be used as a base for the corresponding loops.
829  // - For tracks which are connected to more than one HCAL cluster,
830  // the links between the track and the cluster are cut for all clusters
831  // but the closest one.
832  // - HF only blocks ( HFEM, HFHAD, HFEM+HFAD) are identified
833 
834  // obsolete comments?
835  // loop1:
836  // - sort ecal and hcal elements in separate vectors
837  // - for tracks:
838  // - lock closest ecal cluster
839  // - cut link to farthest hcal cluster, if more than 1.
840 
841  // vectors to store indices to ho, hcal and ecal elements
842  vector<unsigned> hcalIs;
843  vector<unsigned> hoIs;
844  vector<unsigned> ecalIs;
845  vector<unsigned> trackIs;
846  vector<unsigned> ps1Is;
847  vector<unsigned> ps2Is;
848 
849  vector<unsigned> hfEmIs;
850  vector<unsigned> hfHadIs;
851 
852 
853  for(unsigned iEle=0; iEle<elements.size(); iEle++) {
854  PFBlockElement::Type type = elements[iEle].type();
855 
856  if(debug_ && type != PFBlockElement::BREM ) cout<<endl<<elements[iEle];
857 
858  switch( type ) {
859  case PFBlockElement::TRACK:
860  if ( active[iEle] ) {
861  trackIs.push_back( iEle );
862  if(debug_) cout<<"TRACK, stored index, continue"<<endl;
863  }
864  break;
865  case PFBlockElement::ECAL:
866  if ( active[iEle] ) {
867  ecalIs.push_back( iEle );
868  if(debug_) cout<<"ECAL, stored index, continue"<<endl;
869  }
870  continue;
872  if ( active[iEle] ) {
873  hcalIs.push_back( iEle );
874  if(debug_) cout<<"HCAL, stored index, continue"<<endl;
875  }
876  continue;
877  case PFBlockElement::HO:
878  if (useHO_) {
879  if ( active[iEle] ) {
880  hoIs.push_back( iEle );
881  if(debug_) cout<<"HO, stored index, continue"<<endl;
882  }
883  }
884  continue;
885  case PFBlockElement::HFEM:
886  if ( active[iEle] ) {
887  hfEmIs.push_back( iEle );
888  if(debug_) cout<<"HFEM, stored index, continue"<<endl;
889  }
890  continue;
891  case PFBlockElement::HFHAD:
892  if ( active[iEle] ) {
893  hfHadIs.push_back( iEle );
894  if(debug_) cout<<"HFHAD, stored index, continue"<<endl;
895  }
896  continue;
897  default:
898  continue;
899  }
900 
901  // we're now dealing with a track
902  unsigned iTrack = iEle;
903  reco::MuonRef muonRef = elements[iTrack].muonRef();
904 
905  //Check if the track is a primary track of a secondary interaction
906  //If that is the case reconstruct a charged hadron noly using that
907  //track
908  if (active[iTrack] && isFromSecInt(elements[iEle], "primary")){
909  bool isPrimaryTrack = elements[iEle].displacedVertexRef(PFBlockElement::T_TO_DISP)->displacedVertexRef()->isTherePrimaryTracks();
910  if (isPrimaryTrack) {
911  if (debug_) cout << "Primary Track reconstructed alone" << endl;
912 
913  unsigned tmpi = reconstructTrack(elements[iEle]);
914  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEle );
915  active[iTrack] = false;
916  }
917  }
918 
919 
920  if(debug_) {
921  if ( !active[iTrack] )
922  cout << "Already used by electrons, muons, conversions" << endl;
923  }
924 
925  // Track already used as electron, muon, conversion?
926  // Added a check on the activated element
927  if ( ! active[iTrack] ) continue;
928 
929  reco::TrackRef trackRef = elements[iTrack].trackRef();
930  assert( !trackRef.isNull() );
931 
932  if (debug_ ) {
933  cout <<"PFAlgo:processBlock "<<" "<<trackIs.size()<<" "<<ecalIs.size()<<" "<<hcalIs.size()<<" "<<hoIs.size()<<endl;
934  }
935 
936  // look for associated elements of all types
937  //COLINFEB16
938  // all types of links are considered.
939  // the elements are sorted by increasing distance
940  std::multimap<double, unsigned> ecalElems;
941  block.associatedElements( iTrack, linkData,
942  ecalElems ,
945 
946  std::multimap<double, unsigned> hcalElems;
947  block.associatedElements( iTrack, linkData,
948  hcalElems,
951 
952  // When a track has no HCAL cluster linked, but another track is linked to the same
953  // ECAL cluster and an HCAL cluster, link the track to the HCAL cluster for
954  // later analysis
955  if ( hcalElems.empty() && !ecalElems.empty() ) {
956  // debug_ = true;
957  unsigned ntt = 1;
958  unsigned index = ecalElems.begin()->second;
959  std::multimap<double, unsigned> sortedTracks;
960  block.associatedElements( index, linkData,
961  sortedTracks,
964  // std::cout << "The ECAL is linked to " << sortedTracks.size() << std::endl;
965 
966  // Loop over all tracks
967  for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
968  unsigned jTrack = ie->second;
969  // std::cout << "Track " << jTrack << std::endl;
970  // Track must be active
971  if ( !active[jTrack] ) continue;
972  //std::cout << "Active " << std::endl;
973 
974  // The loop is on the other tracks !
975  if ( jTrack == iTrack ) continue;
976  //std::cout << "A different track ! " << std::endl;
977 
978  // Check if the ECAL closest to this track is the current ECAL
979  // Otherwise ignore this track in the neutral energy determination
980  std::multimap<double, unsigned> sortedECAL;
981  block.associatedElements( jTrack, linkData,
982  sortedECAL,
985  if ( sortedECAL.begin()->second != index ) continue;
986  //std::cout << "With closest ECAL identical " << std::endl;
987 
988 
989  // Check if this track is also linked to an HCAL
990  std::multimap<double, unsigned> sortedHCAL;
991  block.associatedElements( jTrack, linkData,
992  sortedHCAL,
995  if ( !sortedHCAL.size() ) continue;
996  //std::cout << "With an HCAL cluster " << sortedHCAL.begin()->first << std::endl;
997  ntt++;
998 
999  // In that case establish a link with the first track
1000  block.setLink( iTrack,
1001  sortedHCAL.begin()->second,
1002  sortedECAL.begin()->first,
1003  linkData,
1004  PFBlock::LINKTEST_RECHIT );
1005 
1006  } // End other tracks
1007 
1008  // Redefine HCAL elements
1009  block.associatedElements( iTrack, linkData,
1010  hcalElems,
1013 
1014  if ( debug_ && hcalElems.size() )
1015  std::cout << "Track linked back to HCAL due to ECAL sharing with other tracks" << std::endl;
1016  }
1017 
1018  //MICHELE
1019  //TEMPORARY SOLUTION FOR ELECTRON REJECTION IN PFTAU
1020  //COLINFEB16
1021  // in case particle flow electrons are not reconstructed,
1022  // the mva_e_pi of the charged hadron will be set to 1
1023  // if a GSF element is associated to the current TRACK element
1024  // This information will be used in the electron rejection for tau ID.
1025  std::multimap<double,unsigned> gsfElems;
1026  if (usePFElectrons_ == false) {
1027  block.associatedElements( iTrack, linkData,
1028  gsfElems ,
1030  }
1031  //
1032 
1033  if(hcalElems.empty() && debug_) {
1034  cout<<"no hcal element connected to track "<<iTrack<<endl;
1035  }
1036 
1037  // will now loop on associated elements ...
1038  // typedef std::multimap<double, unsigned>::iterator IE;
1039 
1040  bool hcalFound = false;
1041 
1042  if(debug_)
1043  cout<<"now looping on elements associated to the track"<<endl;
1044 
1045  // ... first on associated ECAL elements
1046  // Check if there is still a free ECAL for this track
1047  for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
1048 
1049  unsigned index = ie->second;
1050  // Sanity checks and optional printout
1051  PFBlockElement::Type type = elements[index].type();
1052  if(debug_) {
1053  double dist = ie->first;
1054  cout<<"\telement "<<elements[index]<<" linked with distance = "<< dist <<endl;
1055  if ( ! active[index] ) cout << "This ECAL is already used - skip it" << endl;
1056  }
1057  assert( type == PFBlockElement::ECAL );
1058 
1059  // This ECAL is not free (taken by an electron?) - just skip it
1060  if ( ! active[index] ) continue;
1061 
1062  // Flag ECAL clusters for which the corresponding track is not linked to an HCAL cluster
1063 
1064  //reco::PFClusterRef clusterRef = elements[index].clusterRef();
1065  //assert( !clusterRef.isNull() );
1066  if( !hcalElems.empty() && debug_)
1067  cout<<"\t\tat least one hcal element connected to the track."
1068  <<" Sparing Ecal cluster for the hcal loop"<<endl;
1069 
1070  } //loop print ecal elements
1071 
1072 
1073  // tracks which are not linked to an HCAL
1074  // are reconstructed now.
1075 
1076  if( hcalElems.empty() ) {
1077 
1078  if ( debug_ )
1079  std::cout << "Now deals with tracks linked to no HCAL clusters" << std::endl;
1080  // vector<unsigned> elementIndices;
1081  // elementIndices.push_back(iTrack);
1082 
1083  // The track momentum
1084  double trackMomentum = elements[iTrack].trackRef()->p();
1085  if ( debug_ )
1086  std::cout << elements[iTrack] << std::endl;
1087 
1088  // Is it a "tight" muon ? In that case assume no
1089  //Track momentum corresponds to the calorimeter
1090  //energy for now
1091  bool thisIsAMuon = PFMuonAlgo::isMuon(elements[iTrack]);
1092  if ( thisIsAMuon ) trackMomentum = 0.;
1093 
1094  // If it is not a muon check if Is it a fake track ?
1095  //Michalis: I wonder if we should convert this to dpt/pt?
1096  bool rejectFake = false;
1097  if ( !thisIsAMuon && elements[iTrack].trackRef()->ptError() > ptError_ ) {
1098 
1099  double deficit = trackMomentum;
1100  double resol = neutralHadronEnergyResolution(trackMomentum,
1101  elements[iTrack].trackRef()->eta());
1102  resol *= trackMomentum;
1103 
1104  if ( !ecalElems.empty() ) {
1105  unsigned thisEcal = ecalElems.begin()->second;
1106  reco::PFClusterRef clusterRef = elements[thisEcal].clusterRef();
1107  deficit -= clusterRef->energy();
1108  resol = neutralHadronEnergyResolution(trackMomentum,
1109  clusterRef->positionREP().Eta());
1110  resol *= trackMomentum;
1111  }
1112 
1113  bool isPrimary = isFromSecInt(elements[iTrack], "primary");
1114 
1115  if ( deficit > nSigmaTRACK_*resol && !isPrimary) {
1116  rejectFake = true;
1117  active[iTrack] = false;
1118  if ( debug_ )
1119  std::cout << elements[iTrack] << std::endl
1120  << "is probably a fake (1) --> lock the track"
1121  << std::endl;
1122  }
1123  }
1124 
1125  if ( rejectFake ) continue;
1126 
1127  // Create a track candidate
1128  // unsigned tmpi = reconstructTrack( elements[iTrack] );
1129  //active[iTrack] = false;
1130  std::vector<unsigned> tmpi;
1131  std::vector<unsigned> kTrack;
1132 
1133  // Some cleaning : secondary tracks without calo's and large momentum must be fake
1134  double Dpt = trackRef->ptError();
1135 
1136  if ( rejectTracks_Step45_ && ecalElems.empty() &&
1137  trackMomentum > 30. && Dpt > 0.5 &&
1138  ( trackRef->algo() == TrackBase::iter4 ||
1139  trackRef->algo() == TrackBase::iter5 ||
1140  trackRef->algo() == TrackBase::iter6 ) ) {
1141 
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();
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 = c1;
1605  reco::PFClusterRef chad = c0;
1606 
1607  if( c0->layer()== PFLayer::HF_EM ) {
1608  if ( c1->layer()== PFLayer::HF_HAD ) {
1609  cem = c0; chad = c1;
1610  } else {
1611  assert(0);
1612  }
1613  // do EM+HAD calibration here
1614  double energyHfEm = cem->energy();
1615  double energyHfHad = chad->energy();
1616  double uncalibratedenergyHFEm = energyHfEm;
1617  double uncalibratedenergyHFHad = energyHfHad;
1618  if(thepfEnergyCalibrationHF_->getcalibHF_use()==true){
1619 
1620  energyHfEm = thepfEnergyCalibrationHF_->energyEmHad(uncalibratedenergyHFEm,
1621  0.0,
1622  c0->positionREP().Eta(),
1623  c0->positionREP().Phi());
1624  energyHfHad = thepfEnergyCalibrationHF_->energyEmHad(0.0,
1625  uncalibratedenergyHFHad,
1626  c1->positionREP().Eta(),
1627  c1->positionREP().Phi());
1628  }
1629  unsigned tmpi = reconstructCluster( *chad, energyHfEm+energyHfHad );
1630  (*pfCandidates_)[tmpi].setEcalEnergy( uncalibratedenergyHFEm, energyHfEm );
1631  (*pfCandidates_)[tmpi].setHcalEnergy( uncalibratedenergyHFHad, energyHfHad);
1632  (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1633  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1634  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1635  (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfEmIs[0] );
1636  (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfHadIs[0] );
1637  //std::cout << "HF EM+HAD found ! " << energyHfEm << " " << energyHfHad << std::endl;
1638 
1639  }
1640  else {
1641  cerr<<"Warning: 2 elements, but not 1 HFEM and 1 HFHAD"<<endl;
1642  cerr<<block<<endl;
1643 // assert( c1->layer()== PFLayer::HF_EM &&
1644 // c0->layer()== PFLayer::HF_HAD );
1645  }
1646  }
1647  else {
1648  // 1 HF element in the block,
1649  // but number of elements not equal to 1 or 2
1650  cerr<<"Warning: HF, but n elem different from 1 or 2"<<endl;
1651  cerr<<block<<endl;
1652 // assert(0);
1653 // cerr<<"not ready for navigation in the HF!"<<endl;
1654  }
1655  }
1656 
1657 
1658 
1659  if(debug_) {
1660  cout<<endl;
1661  cout<<endl<<"--------------- loop hcal ---------------------"<<endl;
1662  }
1663 
1664  // track information:
1665  // trackRef
1666  // ecal energy
1667  // hcal energy
1668  // rescale
1669 
1670  for(unsigned i=0; i<hcalIs.size(); i++) {
1671 
1672  unsigned iHcal= hcalIs[i];
1673  PFBlockElement::Type type = elements[iHcal].type();
1674 
1675  assert( type == PFBlockElement::HCAL );
1676 
1677  if(debug_) cout<<endl<<elements[iHcal]<<endl;
1678 
1679  // vector<unsigned> elementIndices;
1680  // elementIndices.push_back(iHcal);
1681 
1682  // associated tracks
1683  std::multimap<double, unsigned> sortedTracks;
1684  block.associatedElements( iHcal, linkData,
1685  sortedTracks,
1688 
1689  std::multimap< unsigned, std::pair<double, unsigned> > associatedEcals;
1690 
1691  std::map< unsigned, std::pair<double, double> > associatedPSs;
1692 
1693  std::multimap<double, std::pair<unsigned,bool> > associatedTracks;
1694 
1695  // A temporary maps for ECAL satellite clusters
1696  std::multimap<double,std::pair<unsigned,math::XYZVector> > ecalSatellites;
1697  std::pair<unsigned,math::XYZVector> fakeSatellite = make_pair(iHcal,math::XYZVector(0.,0.,0.));
1698  ecalSatellites.insert( make_pair(-1., fakeSatellite) );
1699 
1700  std::multimap< unsigned, std::pair<double, unsigned> > associatedHOs;
1701 
1702  PFClusterRef hclusterref = elements[iHcal].clusterRef();
1703  assert(!hclusterref.isNull() );
1704 
1705 
1706  //if there is no track attached to that HCAL, then do not
1707  //reconstruct an HCAL alone, check if it can be recovered
1708  //first
1709 
1710  // if no associated tracks, create a neutral hadron
1711  //if(sortedTracks.empty() ) {
1712 
1713  if( sortedTracks.empty() ) {
1714  if(debug_)
1715  cout<<"\tno associated tracks, keep for later"<<endl;
1716  continue;
1717  }
1718 
1719  // Lock the HCAL cluster
1720  active[iHcal] = false;
1721 
1722 
1723  // in the following, tracks are associated to this hcal cluster.
1724  // will look for an excess of energy in the calorimeters w/r to
1725  // the charged energy, and turn this excess into a neutral hadron or
1726  // a photon.
1727 
1728  if(debug_) cout<<"\t"<<sortedTracks.size()<<" associated tracks:"<<endl;
1729 
1730  double totalChargedMomentum = 0;
1731  double sumpError2 = 0.;
1732  double totalHO = 0.;
1733  double totalEcal = 0.;
1734  double totalHcal = hclusterref->energy();
1735  vector<double> hcalP;
1736  vector<double> hcalDP;
1737  vector<unsigned> tkIs;
1738  double maxDPovP = -9999.;
1739 
1740  //Keep track of how much energy is assigned to calorimeter-vs-track energy/momentum excess
1741  vector< unsigned > chargedHadronsIndices;
1742  vector< unsigned > chargedHadronsInBlock;
1743  double mergedNeutralHadronEnergy = 0;
1744  double mergedPhotonEnergy = 0;
1745  double muonHCALEnergy = 0.;
1746  double muonECALEnergy = 0.;
1747  double muonHCALError = 0.;
1748  double muonECALError = 0.;
1749  unsigned nMuons = 0;
1750 
1751 
1752  math::XYZVector photonAtECAL(0.,0.,0.);
1753  math::XYZVector hadronDirection(hclusterref->position().X(),
1754  hclusterref->position().Y(),
1755  hclusterref->position().Z());
1756  hadronDirection = hadronDirection.Unit();
1757  math::XYZVector hadronAtECAL = totalHcal * hadronDirection;
1758 
1759  // Loop over all tracks associated to this HCAL cluster
1760  for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
1761 
1762  unsigned iTrack = ie->second;
1763 
1764  // Check the track has not already been used (e.g., in electrons, conversions...)
1765  if ( !active[iTrack] ) continue;
1766  // Sanity check 1
1767  PFBlockElement::Type type = elements[iTrack].type();
1768  assert( type == reco::PFBlockElement::TRACK );
1769  // Sanity check 2
1770  reco::TrackRef trackRef = elements[iTrack].trackRef();
1771  assert( !trackRef.isNull() );
1772 
1773  // The direction at ECAL entrance
1774  const math::XYZPointF& chargedPosition =
1775  dynamic_cast<const reco::PFBlockElementTrack*>(&elements[iTrack])->positionAtECALEntrance();
1776  math::XYZVector chargedDirection(chargedPosition.X(),chargedPosition.Y(),chargedPosition.Z());
1777  chargedDirection = chargedDirection.Unit();
1778 
1779  // look for ECAL elements associated to iTrack (associated to iHcal)
1780  std::multimap<double, unsigned> sortedEcals;
1781  block.associatedElements( iTrack, linkData,
1782  sortedEcals,
1785 
1786  if(debug_) cout<<"\t\t\tnumber of Ecal elements linked to this track: "
1787  <<sortedEcals.size()<<endl;
1788 
1789  // look for HO elements associated to iTrack (associated to iHcal)
1790  std::multimap<double, unsigned> sortedHOs;
1791  if (useHO_) {
1792  block.associatedElements( iTrack, linkData,
1793  sortedHOs,
1796 
1797  }
1798  if(debug_)
1799  cout<<"PFAlgo : number of HO elements linked to this track: "
1800  <<sortedHOs.size()<<endl;
1801 
1802  // Create a PF Candidate right away if the track is a tight muon
1803  reco::MuonRef muonRef = elements[iTrack].muonRef();
1804 
1805 
1806  bool thisIsAMuon = PFMuonAlgo::isMuon(elements[iTrack]);
1807  bool thisIsAnIsolatedMuon = PFMuonAlgo::isIsolatedMuon(elements[iTrack]);
1808  bool thisIsALooseMuon = false;
1809 
1810 
1811  if(!thisIsAMuon ) {
1812  thisIsALooseMuon = PFMuonAlgo::isLooseMuon(elements[iTrack]);
1813  }
1814 
1815 
1816  if ( thisIsAMuon ) {
1817  if ( debug_ ) {
1818  std::cout << "\t\tThis track is identified as a muon - remove it from the stack" << std::endl;
1819  std::cout << "\t\t" << elements[iTrack] << std::endl;
1820  }
1821 
1822  // Create a muon.
1823 
1824  unsigned tmpi = reconstructTrack( elements[iTrack] );
1825 
1826 
1827  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
1828  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
1829  double muonHcal = std::min(muonHCAL_[0]+muonHCAL_[1],totalHcal);
1830 
1831  // if muon is isolated and muon momentum exceeds the calo energy, absorb the calo energy
1832  // rationale : there has been a EM showering by the muon in the calorimeter - or the coil -
1833  // and we don't want to double count the energy
1834  bool letMuonEatCaloEnergy = false;
1835 
1836  if(thisIsAnIsolatedMuon){
1837  // The factor 1.3 is the e/pi factor in HCAL...
1838  double totalCaloEnergy = totalHcal / 1.30;
1839  unsigned iEcal = 0;
1840  if( !sortedEcals.empty() ) {
1841  iEcal = sortedEcals.begin()->second;
1842  PFClusterRef eclusterref = elements[iEcal].clusterRef();
1843  totalCaloEnergy += eclusterref->energy();
1844  }
1845 
1846  if (useHO_) {
1847  // The factor 1.3 is assumed to be the e/pi factor in HO, too.
1848  unsigned iHO = 0;
1849  if( !sortedHOs.empty() ) {
1850  iHO = sortedHOs.begin()->second;
1851  PFClusterRef eclusterref = elements[iHO].clusterRef();
1852  totalCaloEnergy += eclusterref->energy() / 1.30;
1853  }
1854  }
1855 
1856  // std::cout << "muon p / total calo = " << muonRef->p() << " " << (pfCandidates_->back()).p() << " " << totalCaloEnergy << std::endl;
1857  //if(muonRef->p() > totalCaloEnergy ) letMuonEatCaloEnergy = true;
1858  if( (pfCandidates_->back()).p() > totalCaloEnergy ) letMuonEatCaloEnergy = true;
1859  }
1860 
1861  if(letMuonEatCaloEnergy) muonHcal = totalHcal;
1862  double muonEcal =0.;
1863  unsigned iEcal = 0;
1864  if( !sortedEcals.empty() ) {
1865  iEcal = sortedEcals.begin()->second;
1866  PFClusterRef eclusterref = elements[iEcal].clusterRef();
1867  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
1868  muonEcal = std::min(muonECAL_[0]+muonECAL_[1],eclusterref->energy());
1869  if(letMuonEatCaloEnergy) muonEcal = eclusterref->energy();
1870  // If the muon expected energy accounts for the whole ecal cluster energy, lock the ecal cluster
1871  if ( eclusterref->energy() - muonEcal < 0.2 ) active[iEcal] = false;
1872  (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(), muonEcal);
1873  }
1874  unsigned iHO = 0;
1875  double muonHO =0.;
1876  if (useHO_) {
1877  if( !sortedHOs.empty() ) {
1878  iHO = sortedHOs.begin()->second;
1879  PFClusterRef hoclusterref = elements[iHO].clusterRef();
1880  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
1881  muonHO = std::min(muonHO_[0]+muonHO_[1],hoclusterref->energy());
1882  if(letMuonEatCaloEnergy) muonHO = hoclusterref->energy();
1883  // If the muon expected energy accounts for the whole HO cluster energy, lock the HO cluster
1884  if ( hoclusterref->energy() - muonHO < 0.2 ) active[iHO] = false;
1885  (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
1886  (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(), muonHO);
1887  }
1888  } else {
1889  (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
1890  }
1891 
1892  if(letMuonEatCaloEnergy){
1893  muonHCALEnergy += totalHcal;
1894  if (useHO_) muonHCALEnergy +=muonHO;
1895  muonHCALError += 0.;
1896  muonECALEnergy += muonEcal;
1897  muonECALError += 0.;
1898  photonAtECAL -= muonEcal*chargedDirection;
1899  hadronAtECAL -= totalHcal*chargedDirection;
1900  if ( !sortedEcals.empty() ) active[iEcal] = false;
1901  active[iHcal] = false;
1902  if (useHO_ && !sortedHOs.empty() ) active[iHO] = false;
1903  }
1904  else{
1905  // Estimate of the energy deposit & resolution in the calorimeters
1906  muonHCALEnergy += muonHCAL_[0];
1907  muonHCALError += muonHCAL_[1]*muonHCAL_[1];
1908  if ( muonHO > 0. ) {
1909  muonHCALEnergy += muonHO_[0];
1910  muonHCALError += muonHO_[1]*muonHO_[1];
1911  }
1912  muonECALEnergy += muonECAL_[0];
1913  muonECALError += muonECAL_[1]*muonECAL_[1];
1914  // ... as well as the equivalent "momentum" at ECAL entrance
1915  photonAtECAL -= muonECAL_[0]*chargedDirection;
1916  hadronAtECAL -= muonHCAL_[0]*chargedDirection;
1917  }
1918 
1919  // Remove it from the stack
1920  active[iTrack] = false;
1921  // Go to next track
1922  continue;
1923  }
1924 
1925  //
1926 
1927  if(debug_) cout<<"\t\t"<<elements[iTrack]<<endl;
1928 
1929  // introduce tracking errors
1930  double trackMomentum = trackRef->p();
1931  totalChargedMomentum += trackMomentum;
1932 
1933  // If the track is not a tight muon, but still resembles a muon
1934  // keep it for later for blocks with too large a charged energy
1935  if ( thisIsALooseMuon && !thisIsAMuon ) nMuons += 1;
1936 
1937  // ... and keep anyway the pt error for possible fake rejection
1938  // ... blow up errors of 5th anf 4th iteration, to reject those
1939  // ... tracks first (in case it's needed)
1940  double Dpt = trackRef->ptError();
1941  double blowError = 1.;
1942  switch (trackRef->algo()) {
1943  case TrackBase::ctf:
1944  case TrackBase::iter0:
1945  case TrackBase::iter1:
1946  case TrackBase::iter2:
1947  case TrackBase::iter3:
1948  case TrackBase::iter4:
1949  blowError = 1.;
1950  break;
1951  case TrackBase::iter5:
1952  blowError = factors45_[0];
1953  break;
1954  case TrackBase::iter6:
1955  blowError = factors45_[1];
1956  break;
1957  default:
1958  blowError = 1E9;
1959  break;
1960  }
1961  // except if it is from an interaction
1962  bool isPrimaryOrSecondary = isFromSecInt(elements[iTrack], "all");
1963 
1964  if ( isPrimaryOrSecondary ) blowError = 1.;
1965 
1966  std::pair<unsigned,bool> tkmuon = make_pair(iTrack,thisIsALooseMuon);
1967  associatedTracks.insert( make_pair(-Dpt*blowError, tkmuon) );
1968 
1969  // Also keep the total track momentum error for comparison with the calo energy
1970  double Dp = trackRef->qoverpError()*trackMomentum*trackMomentum;
1971  sumpError2 += Dp*Dp;
1972 
1973  bool connectedToEcal = false; // Will become true if there is at least one ECAL cluster connected
1974  if( !sortedEcals.empty() )
1975  { // start case: at least one ecal element associated to iTrack
1976 
1977  // Loop over all connected ECAL clusters
1978  for ( IE iec=sortedEcals.begin();
1979  iec!=sortedEcals.end(); ++iec ) {
1980 
1981  unsigned iEcal = iec->second;
1982  double dist = iec->first;
1983 
1984  // Ignore ECAL cluters already used
1985  if( !active[iEcal] ) {
1986  if(debug_) cout<<"\t\tcluster locked"<<endl;
1987  continue;
1988  }
1989 
1990  // Sanity checks
1991  PFBlockElement::Type type = elements[ iEcal ].type();
1992  assert( type == PFBlockElement::ECAL );
1993  PFClusterRef eclusterref = elements[iEcal].clusterRef();
1994  assert(!eclusterref.isNull() );
1995 
1996  // Check if this ECAL is not closer to another track - ignore it in that case
1997  std::multimap<double, unsigned> sortedTracksEcal;
1998  block.associatedElements( iEcal, linkData,
1999  sortedTracksEcal,
2002  unsigned jTrack = sortedTracksEcal.begin()->second;
2003  if ( jTrack != iTrack ) continue;
2004 
2005  // double chi2Ecal = block.chi2(jTrack,iEcal,linkData,
2006  // reco::PFBlock::LINKTEST_ALL);
2007  double distEcal = block.dist(jTrack,iEcal,linkData,
2009 
2010  // totalEcal += eclusterref->energy();
2011  // float ecalEnergyUnCalibrated = eclusterref->energy();
2012  //std::cout << "Ecal Uncalibrated " << ecalEnergyUnCalibrated << std::endl;
2013 
2014  // check the presence of preshower clusters in the vicinity
2015  vector<double> ps1Ene(1,static_cast<double>(0.));
2017  block, elements, linkData, active,
2018  ps1Ene);
2019  vector<double> ps2Ene(1,static_cast<double>(0.));
2021  block, elements, linkData, active,
2022  ps2Ene);
2023  std::pair<double,double> psEnes = make_pair(ps1Ene[0],
2024  ps2Ene[0]);
2025  associatedPSs.insert(make_pair(iEcal,psEnes));
2026 
2027  // Calibrate the ECAL energy for photons
2028  bool crackCorrection = false;
2029  float ecalEnergyCalibrated = calibration_->energyEm(*eclusterref,ps1Ene,ps2Ene,crackCorrection);
2030  math::XYZVector photonDirection(eclusterref->position().X(),
2031  eclusterref->position().Y(),
2032  eclusterref->position().Z());
2033  photonDirection = photonDirection.Unit();
2034 
2035  if ( !connectedToEcal ) { // This is the closest ECAL cluster - will add its energy later
2036 
2037  if(debug_) cout<<"\t\t\tclosest: "
2038  <<elements[iEcal]<<endl;
2039 
2040  connectedToEcal = true;
2041  // PJ 1st-April-09 : To be done somewhere !!! (Had to comment it, but it is needed)
2042  // currentChargedHadron.addElementInBlock( blockref, iEcal );
2043 
2044  std::pair<unsigned,math::XYZVector> satellite =
2045  make_pair(iEcal,ecalEnergyCalibrated*photonDirection);
2046  ecalSatellites.insert( make_pair(-1., satellite) );
2047 
2048  } else { // Keep satellite clusters for later
2049 
2050  std::pair<unsigned,math::XYZVector> satellite =
2051  make_pair(iEcal,ecalEnergyCalibrated*photonDirection);
2052  ecalSatellites.insert( make_pair(dist, satellite) );
2053 
2054  }
2055 
2056  std::pair<double, unsigned> associatedEcal
2057  = make_pair( distEcal, iEcal );
2058  associatedEcals.insert( make_pair(iTrack, associatedEcal) );
2059 
2060  } // End loop ecal associated to iTrack
2061  } // end case: at least one ecal element associated to iTrack
2062 
2063  if( useHO_ && !sortedHOs.empty() )
2064  { // start case: at least one ho element associated to iTrack
2065 
2066  // Loop over all connected HO clusters
2067  for ( IE ieho=sortedHOs.begin(); ieho!=sortedHOs.end(); ++ieho ) {
2068 
2069  unsigned iHO = ieho->second;
2070  double distHO = ieho->first;
2071 
2072  // Ignore HO cluters already used
2073  if( !active[iHO] ) {
2074  if(debug_) cout<<"\t\tcluster locked"<<endl;
2075  continue;
2076  }
2077 
2078  // Sanity checks
2079  PFBlockElement::Type type = elements[ iHO ].type();
2080  assert( type == PFBlockElement::HO );
2081  PFClusterRef hoclusterref = elements[iHO].clusterRef();
2082  assert(!hoclusterref.isNull() );
2083 
2084  // Check if this HO is not closer to another track - ignore it in that case
2085  std::multimap<double, unsigned> sortedTracksHO;
2086  block.associatedElements( iHO, linkData,
2087  sortedTracksHO,
2090  unsigned jTrack = sortedTracksHO.begin()->second;
2091  if ( jTrack != iTrack ) continue;
2092 
2093  // double chi2HO = block.chi2(jTrack,iHO,linkData,
2094  // reco::PFBlock::LINKTEST_ALL);
2095  //double distHO = block.dist(jTrack,iHO,linkData,
2096  // reco::PFBlock::LINKTEST_ALL);
2097 
2098  // Increment the total energy by the energy of this HO cluster
2099  totalHO += hoclusterref->energy();
2100  active[iHO] = false;
2101  // Keep track for later reference in the PFCandidate.
2102  std::pair<double, unsigned> associatedHO
2103  = make_pair( distHO, iHO );
2104  associatedHOs.insert( make_pair(iTrack, associatedHO) );
2105 
2106  } // End loop ho associated to iTrack
2107  } // end case: at least one ho element associated to iTrack
2108 
2109 
2110  } // end loop on tracks associated to hcal element iHcal
2111 
2112  // Include totalHO in totalHCAL for the time being (it will be calibrated as HCAL energy)
2113  totalHcal += totalHO;
2114 
2115  // test compatibility between calo and tracker. //////////////
2116 
2117  double caloEnergy = 0.;
2118  double slopeEcal = 1.0;
2119  double calibEcal = 0.;
2120  double calibHcal = 0.;
2121  hadronDirection = hadronAtECAL.Unit();
2122 
2123  // Determine the expected calo resolution from the total charged momentum
2124  double Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2125  Caloresolution *= totalChargedMomentum;
2126  // Account for muons
2127  Caloresolution = std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2128  totalEcal -= std::min(totalEcal,muonECALEnergy);
2129  totalHcal -= std::min(totalHcal,muonHCALEnergy);
2130  if ( totalEcal < 1E-9 ) photonAtECAL = math::XYZVector(0.,0.,0.);
2131  if ( totalHcal < 1E-9 ) hadronAtECAL = math::XYZVector(0.,0.,0.);
2132 
2133  // Loop over all ECAL satellites, starting for the closest to the various tracks
2134  // and adding other satellites until saturation of the total track momentum
2135  // Note : for code simplicity, the first element of the loop is the HCAL cluster
2136  // with 0 energy in the ECAL
2137  for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
2138 
2139  // Add the energy of this ECAL cluster
2140  double previousCalibEcal = calibEcal;
2141  double previousCalibHcal = calibHcal;
2142  double previousCaloEnergy = caloEnergy;
2143  double previousSlopeEcal = slopeEcal;
2144  math::XYZVector previousHadronAtECAL = hadronAtECAL;
2145  //
2146  totalEcal += sqrt(is->second.second.Mag2());
2147  photonAtECAL += is->second.second;
2148  calibEcal = std::max(0.,totalEcal);
2149  calibHcal = std::max(0.,totalHcal);
2150  hadronAtECAL = calibHcal * hadronDirection;
2151  // Calibrate ECAL and HCAL energy under the hadron hypothesis.
2152  calibration_->energyEmHad(totalChargedMomentum,calibEcal,calibHcal,
2153  hclusterref->positionREP().Eta(),
2154  hclusterref->positionREP().Phi());
2155  caloEnergy = calibEcal+calibHcal;
2156  if ( totalEcal > 0.) slopeEcal = calibEcal/totalEcal;
2157 
2158  hadronAtECAL = calibHcal * hadronDirection;
2159 
2160  // Continue looping until all closest clusters are exhausted and as long as
2161  // the calorimetric energy does not saturate the total momentum.
2162  if ( is->first < 0. || caloEnergy - totalChargedMomentum <= 0. ) {
2163  if(debug_) cout<<"\t\t\tactive, adding "<<is->second.second
2164  <<" to ECAL energy, and locking"<<endl;
2165  active[is->second.first] = false;
2166  continue;
2167  }
2168 
2169  // Otherwise, do not consider the last cluster examined and exit.
2170  // active[is->second.first] = true;
2171  totalEcal -= sqrt(is->second.second.Mag2());
2172  photonAtECAL -= is->second.second;
2173  calibEcal = previousCalibEcal;
2174  calibHcal = previousCalibHcal;
2175  hadronAtECAL = previousHadronAtECAL;
2176  slopeEcal = previousSlopeEcal;
2177  caloEnergy = previousCaloEnergy;
2178 
2179  break;
2180 
2181  }
2182 
2183  // Sanity check !
2184  assert(caloEnergy>=0);
2185 
2186 
2187  // And now check for hadronic energy excess...
2188 
2189  //colin: resolution should be measured on the ecal+hcal case.
2190  // however, the result will be close.
2191  // double Caloresolution = neutralHadronEnergyResolution( caloEnergy );
2192  // Caloresolution *= caloEnergy;
2193  // PJ The resolution is on the expected charged calo energy !
2194  //double Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2195  //Caloresolution *= totalChargedMomentum;
2196  // that of the charged particles linked to the cluster!
2197  double TotalError = sqrt(sumpError2 + Caloresolution*Caloresolution);
2198 
2199  /* */
2201  if ( totalChargedMomentum - caloEnergy > nSigmaTRACK_*Caloresolution ) {
2202 
2203  /*
2204  cout<<"\tCompare Calo Energy to total charged momentum "<<endl;
2205  cout<<"\t\tsum p = "<<totalChargedMomentum<<" +- "<<sqrt(sumpError2)<<endl;
2206  cout<<"\t\tsum ecal = "<<totalEcal<<endl;
2207  cout<<"\t\tsum hcal = "<<totalHcal<<endl;
2208  cout<<"\t\t => Calo Energy = "<<caloEnergy<<" +- "<<Caloresolution<<endl;
2209  cout<<"\t\t => Calo Energy- total charged momentum = "
2210  <<caloEnergy-totalChargedMomentum<<" +- "<<TotalError<<endl;
2211  cout<<endl;
2212  cout << "\t\tNumber/momentum of muons found in the block : " << nMuons << std::endl;
2213  */
2214  // First consider loose muons
2215  if ( nMuons > 0 ) {
2216  for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2217  unsigned iTrack = it->second.first;
2218  // Only active tracks
2219  if ( !active[iTrack] ) continue;
2220  // Only muons
2221  if ( !it->second.second ) continue;
2222 
2223  double trackMomentum = elements[it->second.first].trackRef()->p();
2224 
2225  // look for ECAL elements associated to iTrack (associated to iHcal)
2226  std::multimap<double, unsigned> sortedEcals;
2227  block.associatedElements( iTrack, linkData,
2228  sortedEcals,
2231  std::multimap<double, unsigned> sortedHOs;
2232  block.associatedElements( iTrack, linkData,
2233  sortedHOs,
2236 
2237  //Here allow for loose muons!
2238  unsigned tmpi = reconstructTrack( elements[iTrack],true);
2239 
2240  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2241  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2242  double muonHcal = std::min(muonHCAL_[0]+muonHCAL_[1],totalHcal-totalHO);
2243  double muonHO = 0.;
2244  (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal,muonHcal);
2245  if( !sortedEcals.empty() ) {
2246  unsigned iEcal = sortedEcals.begin()->second;
2247  PFClusterRef eclusterref = elements[iEcal].clusterRef();
2248  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
2249  double muonEcal = std::min(muonECAL_[0]+muonECAL_[1],eclusterref->energy());
2250  (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(),muonEcal);
2251  }
2252  if( useHO_ && !sortedHOs.empty() ) {
2253  unsigned iHO = sortedHOs.begin()->second;
2254  PFClusterRef hoclusterref = elements[iHO].clusterRef();
2255  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
2256  muonHO = std::min(muonHO_[0]+muonHO_[1],hoclusterref->energy());
2257  (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal-totalHO,muonHcal);
2258  (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(),muonHO);
2259  }
2260  // Remove it from the block
2261  const math::XYZPointF& chargedPosition =
2262  dynamic_cast<const reco::PFBlockElementTrack*>(&elements[it->second.first])->positionAtECALEntrance();
2263  math::XYZVector chargedDirection(chargedPosition.X(), chargedPosition.Y(), chargedPosition.Z());
2264  chargedDirection = chargedDirection.Unit();
2265  totalChargedMomentum -= trackMomentum;
2266  // Update the calo energies
2267  if ( totalEcal > 0. )
2268  calibEcal -= std::min(calibEcal,muonECAL_[0]*calibEcal/totalEcal);
2269  if ( totalHcal > 0. )
2270  calibHcal -= std::min(calibHcal,muonHCAL_[0]*calibHcal/totalHcal);
2271  totalEcal -= std::min(totalEcal,muonECAL_[0]);
2272  totalHcal -= std::min(totalHcal,muonHCAL_[0]);
2273  if ( totalEcal > muonECAL_[0] ) photonAtECAL -= muonECAL_[0] * chargedDirection;
2274  if ( totalHcal > muonHCAL_[0] ) hadronAtECAL -= muonHCAL_[0]*calibHcal/totalHcal * chargedDirection;
2275  caloEnergy = calibEcal+calibHcal;
2276  muonHCALEnergy += muonHCAL_[0];
2277  muonHCALError += muonHCAL_[1]*muonHCAL_[1];
2278  if ( muonHO > 0. ) {
2279  muonHCALEnergy += muonHO_[0];
2280  muonHCALError += muonHO_[1]*muonHO_[1];
2281  if ( totalHcal > 0. ) {
2282  calibHcal -= std::min(calibHcal,muonHO_[0]*calibHcal/totalHcal);
2283  totalHcal -= std::min(totalHcal,muonHO_[0]);
2284  }
2285  }
2286  muonECALEnergy += muonECAL_[0];
2287  muonECALError += muonECAL_[1]*muonECAL_[1];
2288  active[iTrack] = false;
2289  // Stop the loop whenever enough muons are removed
2290  //Commented out: Keep looking for muons since they often come in pairs -Matt
2291  //if ( totalChargedMomentum < caloEnergy ) break;
2292  }
2293  // New calo resolution.
2294  Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2295  Caloresolution *= totalChargedMomentum;
2296  Caloresolution = std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2297  }
2298  }
2299  /*
2300  if(debug_){
2301  cout<<"\tBefore Cleaning "<<endl;
2302  cout<<"\tCompare Calo Energy to total charged momentum "<<endl;
2303  cout<<"\t\tsum p = "<<totalChargedMomentum<<" +- "<<sqrt(sumpError2)<<endl;
2304  cout<<"\t\tsum ecal = "<<totalEcal<<endl;
2305  cout<<"\t\tsum hcal = "<<totalHcal<<endl;
2306  cout<<"\t\t => Calo Energy = "<<caloEnergy<<" +- "<<Caloresolution<<endl;
2307  cout<<"\t\t => Calo Energy- total charged momentum = "
2308  <<caloEnergy-totalChargedMomentum<<" +- "<<TotalError<<endl;
2309  cout<<endl;
2310  }
2311  */
2312 
2313  // Second consider bad tracks (if still needed after muon removal)
2314  unsigned corrTrack = 10000000;
2315  double corrFact = 1.;
2316 
2317  if (rejectTracks_Bad_ &&
2318  totalChargedMomentum - caloEnergy > nSigmaTRACK_*Caloresolution) {
2319 
2320  for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2321  unsigned iTrack = it->second.first;
2322  // Only active tracks
2323  if ( !active[iTrack] ) continue;
2324  const reco::TrackRef& trackref = elements[it->second.first].trackRef();
2325 
2326  double dptRel = fabs(it->first)/trackref->pt()*100;
2327  bool isSecondary = isFromSecInt(elements[iTrack], "secondary");
2328  bool isPrimary = isFromSecInt(elements[iTrack], "primary");
2329 
2330  if ( isSecondary && dptRel < dptRel_DispVtx_ ) continue;
2331  // Consider only bad tracks
2332  if ( fabs(it->first) < ptError_ ) break;
2333  // What would become the block charged momentum if this track were removed
2334  double wouldBeTotalChargedMomentum =
2335  totalChargedMomentum - trackref->p();
2336  // Reject worst tracks, as long as the total charged momentum
2337  // is larger than the calo energy
2338 
2339  if ( wouldBeTotalChargedMomentum > caloEnergy ) {
2340 
2341  if (debug_ && isSecondary) {
2342  cout << "In bad track rejection step dptRel = " << dptRel << " dptRel_DispVtx_ = " << dptRel_DispVtx_ << endl;
2343  cout << "The calo energy would be still smaller even without this track but it is attached to a NI"<< endl;
2344  }
2345 
2346 
2347  if(isPrimary || (isSecondary && dptRel < dptRel_DispVtx_)) continue;
2348  active[iTrack] = false;
2349  totalChargedMomentum = wouldBeTotalChargedMomentum;
2350  if ( debug_ )
2351  std::cout << "\tElement " << elements[iTrack]
2352  << " rejected (Dpt = " << -it->first
2353  << " GeV/c, algo = " << trackref->algo() << ")" << std::endl;
2354  // Just rescale the nth worst track momentum to equalize the calo energy
2355  } else {
2356  if(isPrimary) break;
2357  corrTrack = iTrack;
2358  corrFact = (caloEnergy - wouldBeTotalChargedMomentum)/elements[it->second.first].trackRef()->p();
2359  if ( trackref->p()*corrFact < 0.05 ) {
2360  corrFact = 0.;
2361  active[iTrack] = false;
2362  }
2363  totalChargedMomentum -= trackref->p()*(1.-corrFact);
2364  if ( debug_ )
2365  std::cout << "\tElement " << elements[iTrack]
2366  << " (Dpt = " << -it->first
2367  << " GeV/c, algo = " << trackref->algo()
2368  << ") rescaled by " << corrFact
2369  << " Now the total charged momentum is " << totalChargedMomentum << endl;
2370  break;
2371  }
2372  }
2373  }
2374 
2375  // New determination of the calo and track resolution avec track deletion/rescaling.
2376  Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2377  Caloresolution *= totalChargedMomentum;
2378  Caloresolution = std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2379 
2380  // Check if the charged momentum is still very inconsistent with the calo measurement.
2381  // In this case, just drop all tracks from 4th and 5th iteration linked to this block
2382 
2383  if ( rejectTracks_Step45_ &&
2384  sortedTracks.size() > 1 &&
2385  totalChargedMomentum - caloEnergy > nSigmaTRACK_*Caloresolution ) {
2386  for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2387  unsigned iTrack = it->second.first;
2388  reco::TrackRef trackref = elements[iTrack].trackRef();
2389  if ( !active[iTrack] ) continue;
2390 
2391  double dptRel = fabs(it->first)/trackref->pt()*100;
2392  bool isPrimaryOrSecondary = isFromSecInt(elements[iTrack], "all");
2393 
2394 
2395 
2396 
2397  if (isPrimaryOrSecondary && dptRel < dptRel_DispVtx_) continue;
2398  //
2399  switch (trackref->algo()) {
2400  case TrackBase::ctf:
2401  case TrackBase::iter0:
2402  case TrackBase::iter1:
2403  case TrackBase::iter2:
2404  case TrackBase::iter3:
2405  case TrackBase::iter4:
2406  break;
2407  case TrackBase::iter5:
2408  case TrackBase::iter6:
2409  active[iTrack] = false;
2410  totalChargedMomentum -= trackref->p();
2411 
2412  if ( debug_ )
2413  std::cout << "\tElement " << elements[iTrack]
2414  << " rejected (Dpt = " << -it->first
2415  << " GeV/c, algo = " << trackref->algo() << ")" << std::endl;
2416  break;
2417  default:
2418  break;
2419  }
2420  }
2421  }
2422 
2423  // New determination of the calo and track resolution avec track deletion/rescaling.
2424  Caloresolution = neutralHadronEnergyResolution( totalChargedMomentum, hclusterref->positionREP().Eta());
2425  Caloresolution *= totalChargedMomentum;
2426  Caloresolution = std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2427 
2428  // Make PF candidates with the remaining tracks in the block
2429  sumpError2 = 0.;
2430  for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2431  unsigned iTrack = it->second.first;
2432  if ( !active[iTrack] ) continue;
2433  reco::TrackRef trackRef = elements[iTrack].trackRef();
2434  double trackMomentum = trackRef->p();
2435  double Dp = trackRef->qoverpError()*trackMomentum*trackMomentum;
2436  unsigned tmpi = reconstructTrack( elements[iTrack] );
2437 
2438 
2439  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2440  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2441  std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2442  for (II ii=myEcals.first; ii!=myEcals.second; ++ii ) {
2443  unsigned iEcal = ii->second.second;
2444  if ( active[iEcal] ) continue;
2445  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2446  }
2447 
2448  if (useHO_) {
2449  std::pair<II,II> myHOs = associatedHOs.equal_range(iTrack);
2450  for (II ii=myHOs.first; ii!=myHOs.second; ++ii ) {
2451  unsigned iHO = ii->second.second;
2452  if ( active[iHO] ) continue;
2453  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO );
2454  }
2455  }
2456 
2457  if ( iTrack == corrTrack ) {
2458  (*pfCandidates_)[tmpi].rescaleMomentum(corrFact);
2459  trackMomentum *= corrFact;
2460  }
2461  chargedHadronsIndices.push_back( tmpi );
2462  chargedHadronsInBlock.push_back( iTrack );
2463  active[iTrack] = false;
2464  hcalP.push_back(trackMomentum);
2465  hcalDP.push_back(Dp);
2466  if (Dp/trackMomentum > maxDPovP) maxDPovP = Dp/trackMomentum;
2467  sumpError2 += Dp*Dp;
2468  }
2469 
2470  // The total uncertainty of the difference Calo-Track
2471  TotalError = sqrt(sumpError2 + Caloresolution*Caloresolution);
2472 
2473  if ( debug_ ) {
2474  cout<<"\tCompare Calo Energy to total charged momentum "<<endl;
2475  cout<<"\t\tsum p = "<<totalChargedMomentum<<" +- "<<sqrt(sumpError2)<<endl;
2476  cout<<"\t\tsum ecal = "<<totalEcal<<endl;
2477  cout<<"\t\tsum hcal = "<<totalHcal<<endl;
2478  cout<<"\t\t => Calo Energy = "<<caloEnergy<<" +- "<<Caloresolution<<endl;
2479  cout<<"\t\t => Calo Energy- total charged momentum = "
2480  <<caloEnergy-totalChargedMomentum<<" +- "<<TotalError<<endl;
2481  cout<<endl;
2482  }
2483 
2484  /* */
2485 
2487  double nsigma = nSigmaHCAL(totalChargedMomentum,hclusterref->positionREP().Eta());
2488  //double nsigma = nSigmaHCAL(caloEnergy,hclusterref->positionREP().Eta());
2489  if ( abs(totalChargedMomentum-caloEnergy)<nsigma*TotalError ) {
2490 
2491  // deposited caloEnergy compatible with total charged momentum
2492  // if tracking errors are large take weighted average
2493 
2494  if(debug_) {
2495  cout<<"\t\tcase 1: COMPATIBLE "
2496  <<"|Calo Energy- total charged momentum| = "
2497  <<abs(caloEnergy-totalChargedMomentum)
2498  <<" < "<<nsigma<<" x "<<TotalError<<endl;
2499  if (maxDPovP < 0.1 )
2500  cout<<"\t\t\tmax DP/P = "<< maxDPovP
2501  <<" less than 0.1: do nothing "<<endl;
2502  else
2503  cout<<"\t\t\tmax DP/P = "<< maxDPovP
2504  <<" > 0.1: take weighted averages "<<endl;
2505  }
2506 
2507  // if max DP/P < 10% do nothing
2508  if (maxDPovP > 0.1) {
2509 
2510  // for each track associated to hcal
2511  // int nrows = tkIs.size();
2512  int nrows = chargedHadronsIndices.size();
2513  TMatrixTSym<double> a (nrows);
2514  TVectorD b (nrows);
2515  TVectorD check(nrows);
2516  double sigma2E = Caloresolution*Caloresolution;
2517  for(int i=0; i<nrows; i++) {
2518  double sigma2i = hcalDP[i]*hcalDP[i];
2519  if (debug_){
2520  cout<<"\t\t\ttrack associated to hcal "<<i
2521  <<" P = "<<hcalP[i]<<" +- "
2522  <<hcalDP[i]<<endl;
2523  }
2524  a(i,i) = 1./sigma2i + 1./sigma2E;
2525  b(i) = hcalP[i]/sigma2i + caloEnergy/sigma2E;
2526  for(int j=0; j<nrows; j++) {
2527  if (i==j) continue;
2528  a(i,j) = 1./sigma2E;
2529  } // end loop on j
2530  } // end loop on i
2531 
2532  // solve ax = b
2533  //if (debug_){// debug1
2534  //cout<<" matrix a(i,j) "<<endl;
2535  //a.Print();
2536  //cout<<" vector b(i) "<<endl;
2537  //b.Print();
2538  //} // debug1
2539  TDecompChol decomp(a);
2540  bool ok = false;
2541  TVectorD x = decomp.Solve(b, ok);
2542  // for each track create a PFCandidate track
2543  // with a momentum rescaled to weighted average
2544  if (ok) {
2545  for (int i=0; i<nrows; i++){
2546  // unsigned iTrack = trackInfos[i].index;
2547  unsigned ich = chargedHadronsIndices[i];
2548  double rescaleFactor = x(i)/hcalP[i];
2549  (*pfCandidates_)[ich].rescaleMomentum( rescaleFactor );
2550 
2551  if(debug_){
2552  cout<<"\t\t\told p "<<hcalP[i]
2553  <<" new p "<<x(i)
2554  <<" rescale "<<rescaleFactor<<endl;
2555  }
2556  }
2557  }
2558  else {
2559  cerr<<"not ok!"<<endl;
2560  assert(0);
2561  }
2562  }
2563  }
2564 
2566  else if( caloEnergy > totalChargedMomentum ) {
2567 
2568  //case 2: caloEnergy > totalChargedMomentum + nsigma*TotalError
2569  //there is an excess of energy in the calos
2570  //create a neutral hadron or a photon
2571 
2572  /*
2573  //If it's isolated don't create neutrals since the energy deposit is always coming from a showering muon
2574  bool thisIsAnIsolatedMuon = false;
2575  for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
2576  unsigned iTrack = ie->second;
2577  if(PFMuonAlgo::isIsolatedMuon(elements[iTrack].muonRef())) thisIsAnIsolatedMuon = true;
2578  }
2579 
2580  if(thisIsAnIsolatedMuon){
2581  if(debug_)cout<<" Not looking for neutral b/c this is an isolated muon "<<endl;
2582  break;
2583  }
2584  */
2585  double eNeutralHadron = caloEnergy - totalChargedMomentum;
2586  double ePhoton = (caloEnergy - totalChargedMomentum) / slopeEcal;
2587 
2588  if(debug_) {
2589  if(!sortedTracks.empty() ){
2590  cout<<"\t\tcase 2: NEUTRAL DETECTION "
2591  <<caloEnergy<<" > "<<nsigma<<"x"<<TotalError
2592  <<" + "<<totalChargedMomentum<<endl;
2593  cout<<"\t\tneutral activity detected: "<<endl
2594  <<"\t\t\t photon = "<<ePhoton<<endl
2595  <<"\t\t\tor neutral hadron = "<<eNeutralHadron<<endl;
2596 
2597  cout<<"\t\tphoton or hadron ?"<<endl;}
2598 
2599  if(sortedTracks.empty() )
2600  cout<<"\t\tno track -> hadron "<<endl;
2601  else
2602  cout<<"\t\t"<<sortedTracks.size()
2603  <<"tracks -> check if the excess is photonic or hadronic"<<endl;
2604  }
2605 
2606 
2607  double ratioMax = 0.;
2608  reco::PFClusterRef maxEcalRef;
2609  unsigned maxiEcal= 9999;
2610 
2611  // for each track associated to hcal: iterator IE ie :
2612 
2613  for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
2614 
2615  unsigned iTrack = ie->second;
2616 
2617  PFBlockElement::Type type = elements[iTrack].type();
2618  assert( type == reco::PFBlockElement::TRACK );
2619 
2620  reco::TrackRef trackRef = elements[iTrack].trackRef();
2621  assert( !trackRef.isNull() );
2622 
2623  II iae = associatedEcals.find(iTrack);
2624 
2625  if( iae == associatedEcals.end() ) continue;
2626 
2627  // double distECAL = iae->second.first;
2628  unsigned iEcal = iae->second.second;
2629 
2630  PFBlockElement::Type typeEcal = elements[iEcal].type();
2631  assert(typeEcal == reco::PFBlockElement::ECAL);
2632 
2633  reco::PFClusterRef clusterRef = elements[iEcal].clusterRef();
2634  assert( !clusterRef.isNull() );
2635 
2636  double pTrack = trackRef->p();
2637  double eECAL = clusterRef->energy();
2638  double eECALOverpTrack = eECAL / pTrack;
2639 
2640  if ( eECALOverpTrack > ratioMax ) {
2641  ratioMax = eECALOverpTrack;
2642  maxEcalRef = clusterRef;
2643  maxiEcal = iEcal;
2644  }
2645 
2646  } // end loop on tracks associated to hcal: iterator IE ie
2647 
2648  std::vector<reco::PFClusterRef> pivotalClusterRef;
2649  std::vector<unsigned> iPivotal;
2650  std::vector<double> particleEnergy, ecalEnergy, hcalEnergy, rawecalEnergy, rawhcalEnergy;
2651  std::vector<math::XYZVector> particleDirection;
2652 
2653  // If the excess is smaller than the ecal energy, assign the whole
2654  // excess to a photon
2655  if ( ePhoton < totalEcal || eNeutralHadron-calibEcal < 1E-10 ) {
2656 
2657  if ( !maxEcalRef.isNull() ) {
2658  particleEnergy.push_back(ePhoton);
2659  particleDirection.push_back(photonAtECAL);
2660  ecalEnergy.push_back(ePhoton);
2661  hcalEnergy.push_back(0.);
2662  rawecalEnergy.push_back(totalEcal);
2663  rawhcalEnergy.push_back(totalHcal);
2664  pivotalClusterRef.push_back(maxEcalRef);
2665  iPivotal.push_back(maxiEcal);
2666  // So the merged photon energy is,
2667  mergedPhotonEnergy = ePhoton;
2668  }
2669 
2670  } else {
2671 
2672  // Otherwise assign the whole ECAL energy to the photon
2673  if ( !maxEcalRef.isNull() ) {
2674  pivotalClusterRef.push_back(maxEcalRef);
2675  particleEnergy.push_back(totalEcal);
2676  particleDirection.push_back(photonAtECAL);
2677  ecalEnergy.push_back(totalEcal);
2678  hcalEnergy.push_back(0.);
2679  rawecalEnergy.push_back(totalEcal);
2680  rawhcalEnergy.push_back(totalHcal);
2681  iPivotal.push_back(maxiEcal);
2682  // So the merged photon energy is,
2683  mergedPhotonEnergy = totalEcal;
2684  }
2685 
2686  // ... and assign the remaining excess to a neutral hadron
2687  mergedNeutralHadronEnergy = eNeutralHadron-calibEcal;
2688  if ( mergedNeutralHadronEnergy > 1.0 ) {
2689  pivotalClusterRef.push_back(hclusterref);
2690  particleEnergy.push_back(mergedNeutralHadronEnergy);
2691  particleDirection.push_back(hadronAtECAL);
2692  ecalEnergy.push_back(0.);
2693  hcalEnergy.push_back(mergedNeutralHadronEnergy);
2694  rawecalEnergy.push_back(totalEcal);
2695  rawhcalEnergy.push_back(totalHcal);
2696  iPivotal.push_back(iHcal);
2697  }
2698 
2699  }
2700 
2701 
2702  // reconstructing a merged neutral
2703  // the type of PFCandidate is known from the
2704  // reference to the pivotal cluster.
2705 
2706  for ( unsigned iPivot=0; iPivot<iPivotal.size(); ++iPivot ) {
2707 
2708  if ( particleEnergy[iPivot] < 0. )
2709  std::cout << "ALARM = Negative energy ! "
2710  << particleEnergy[iPivot] << std::endl;
2711 
2712  bool useDirection = true;
2713  unsigned tmpi = reconstructCluster( *pivotalClusterRef[iPivot],
2714  particleEnergy[iPivot],
2715  useDirection,
2716  particleDirection[iPivot].X(),
2717  particleDirection[iPivot].Y(),
2718  particleDirection[iPivot].Z());
2719 
2720 
2721  (*pfCandidates_)[tmpi].setEcalEnergy( rawecalEnergy[iPivot],ecalEnergy[iPivot] );
2722  if ( !useHO_ ) {
2723  (*pfCandidates_)[tmpi].setHcalEnergy( rawhcalEnergy[iPivot],hcalEnergy[iPivot] );
2724  (*pfCandidates_)[tmpi].setHoEnergy(0., 0.);
2725  } else {
2726  (*pfCandidates_)[tmpi].setHcalEnergy( rawhcalEnergy[iPivot]-totalHO,hcalEnergy[iPivot]*(1.-totalHO/rawhcalEnergy[iPivot]));
2727  (*pfCandidates_)[tmpi].setHoEnergy(totalHO, totalHO * hcalEnergy[iPivot]/rawhcalEnergy[iPivot]);
2728  }
2729  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
2730  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
2731  (*pfCandidates_)[tmpi].set_mva_nothing_gamma( -1. );
2732  // (*pfCandidates_)[tmpi].addElement(&elements[iPivotal]);
2733  // (*pfCandidates_)[tmpi].addElementInBlock(blockref, iPivotal[iPivot]);
2734  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2735  for ( unsigned ich=0; ich<chargedHadronsInBlock.size(); ++ich) {
2736  unsigned iTrack = chargedHadronsInBlock[ich];
2737  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2738  // Assign the position of the track at the ECAL entrance
2739  const math::XYZPointF& chargedPosition =
2740  dynamic_cast<const reco::PFBlockElementTrack*>(&elements[iTrack])->positionAtECALEntrance();
2741  (*pfCandidates_)[tmpi].setPositionAtECALEntrance(chargedPosition);
2742 
2743  std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2744  for (II ii=myEcals.first; ii!=myEcals.second; ++ii ) {
2745  unsigned iEcal = ii->second.second;
2746  if ( active[iEcal] ) continue;
2747  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2748  }
2749  }
2750 
2751  }
2752 
2753  } // excess of energy
2754 
2755 
2756  // will now share the hcal energy between the various charged hadron
2757  // candidates, taking into account the potential neutral hadrons
2758 
2759  double totalHcalEnergyCalibrated = calibHcal;
2760  double totalEcalEnergyCalibrated = calibEcal;
2761  //JB: The question is: we've resolved the merged photons cleanly, but how should
2762  //the remaining hadrons be assigned the remaining ecal energy?
2763  //*Temporary solution*: follow HCAL example with fractions...
2764 
2765  /*
2766  if(totalEcal>0) {
2767  // removing ecal energy from abc calibration
2768  totalHcalEnergyCalibrated -= calibEcal;
2769  // totalHcalEnergyCalibrated -= calibration_->paramECALplusHCAL_slopeECAL() * totalEcal;
2770  }
2771  */
2772  // else caloEnergy = hcal only calibrated energy -> ok.
2773 
2774  // remove the energy of the potential neutral hadron
2775  totalHcalEnergyCalibrated -= mergedNeutralHadronEnergy;
2776  // similarly for the merged photons
2777  totalEcalEnergyCalibrated -= mergedPhotonEnergy;
2778  // share between the charged hadrons
2779 
2780  //COLIN can compute this before
2781  // not exactly equal to sum p, this is sum E
2782  double chargedHadronsTotalEnergy = 0;
2783  for( unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2784  unsigned index = chargedHadronsIndices[ich];
2785  reco::PFCandidate& chargedHadron = (*pfCandidates_)[index];
2786  chargedHadronsTotalEnergy += chargedHadron.energy();
2787  }
2788 
2789  for( unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2790  unsigned index = chargedHadronsIndices[ich];
2791  reco::PFCandidate& chargedHadron = (*pfCandidates_)[index];
2792  float fraction = chargedHadron.energy()/chargedHadronsTotalEnergy;
2793 
2794  if ( !useHO_ ) {
2795  chargedHadron.setHcalEnergy( fraction * totalHcal, fraction * totalHcalEnergyCalibrated );
2796  chargedHadron.setHoEnergy( 0., 0. );
2797  } else {
2798  chargedHadron.setHcalEnergy( fraction * (totalHcal-totalHO), fraction * totalHcalEnergyCalibrated * (1.-totalHO/totalHcal) );
2799  chargedHadron.setHoEnergy( fraction * totalHO, fraction * totalHO * totalHcalEnergyCalibrated / totalHcal );
2800  }
2801  //JB: fixing up (previously omitted) setting of ECAL energy gouzevit
2802  chargedHadron.setEcalEnergy( fraction * totalEcal, fraction * totalEcalEnergyCalibrated );
2803  }
2804 
2805  // Finally treat unused ecal satellites as photons.
2806  for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
2807 
2808  // Ignore satellites already taken
2809  unsigned iEcal = is->second.first;
2810  if ( !active[iEcal] ) continue;
2811 
2812  // Sanity checks again (well not useful, this time!)
2813  PFBlockElement::Type type = elements[ iEcal ].type();
2814  assert( type == PFBlockElement::ECAL );
2815  PFClusterRef eclusterref = elements[iEcal].clusterRef();
2816  assert(!eclusterref.isNull() );
2817 
2818  // Lock the cluster
2819  active[iEcal] = false;
2820 
2821  // Find the associated tracks
2822  std::multimap<double, unsigned> assTracks;
2823  block.associatedElements( iEcal, linkData,
2824  assTracks,
2827 
2828  // Create a photon
2829  unsigned tmpi = reconstructCluster( *eclusterref, sqrt(is->second.second.Mag2()) );
2830  (*pfCandidates_)[tmpi].setEcalEnergy( eclusterref->energy(),sqrt(is->second.second.Mag2()) );
2831  (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
2832  (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
2833  (*pfCandidates_)[tmpi].setPs1Energy( associatedPSs[iEcal].first );
2834  (*pfCandidates_)[tmpi].setPs2Energy( associatedPSs[iEcal].second );
2835  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2836  (*pfCandidates_)[tmpi].addElementInBlock( blockref, sortedTracks.begin()->second) ;
2837  }
2838 
2839 
2840  }
2841 
2842  // end loop on hcal element iHcal= hcalIs[i]
2843 
2844 
2845  // Processing the remaining HCAL clusters
2846  if(debug_) {
2847  cout<<endl;
2848  if(debug_)
2849  cout<<endl
2850  <<"---- loop remaining hcal ------- "<<endl;
2851  }
2852 
2853 
2854  //COLINFEB16
2855  // now dealing with the HCAL elements that are not linked to any track
2856  for(unsigned ihcluster=0; ihcluster<hcalIs.size(); ihcluster++) {
2857  unsigned iHcal = hcalIs[ihcluster];
2858 
2859  // Keep ECAL and HO elements for reference in the PFCandidate
2860  std::vector<unsigned> ecalRefs;
2861  std::vector<unsigned> hoRefs;
2862 
2863  if(debug_)
2864  cout<<endl<<elements[iHcal]<<" ";
2865 
2866 
2867  if( !active[iHcal] ) {
2868  if(debug_)
2869  cout<<"not active"<<endl;
2870  continue;
2871  }
2872 
2873  // Find the ECAL elements linked to it
2874  std::multimap<double, unsigned> ecalElems;
2875  block.associatedElements( iHcal, linkData,
2876  ecalElems ,
2879 
2880  // Loop on these ECAL elements
2881  float totalEcal = 0.;
2882  float ecalMax = 0.;
2883  reco::PFClusterRef eClusterRef;
2884  for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
2885 
2886  unsigned iEcal = ie->second;
2887  double dist = ie->first;
2888  PFBlockElement::Type type = elements[iEcal].type();
2889  assert( type == PFBlockElement::ECAL );
2890 
2891  // Check if already used
2892  if( !active[iEcal] ) continue;
2893 
2894  // Check the distance (one HCALPlusECAL tower, roughly)
2895  // if ( dist > 0.15 ) continue;
2896 
2897  //COLINFEB16
2898  // what could be done is to
2899  // - link by rechit.
2900  // - take in the neutral hadron all the ECAL clusters
2901  // which are within the same CaloTower, according to the distance,
2902  // except the ones which are closer to another HCAL cluster.
2903  // - all the other ECAL linked to this HCAL are photons.
2904  //
2905  // about the closest HCAL cluster.
2906  // it could maybe be easier to loop on the ECAL clusters first
2907  // to cut the links to all HCAL clusters except the closest, as is
2908  // done in the first track loop. But maybe not!
2909  // or add an helper function to the PFAlgo class to ask
2910  // if a given element is the closest of a given type to another one?
2911 
2912  // Check if not closer from another free HCAL
2913  std::multimap<double, unsigned> hcalElems;
2914  block.associatedElements( iEcal, linkData,
2915  hcalElems ,
2918 
2919  bool isClosest = true;
2920  for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
2921 
2922  unsigned jHcal = ih->second;
2923  double distH = ih->first;
2924 
2925  if ( !active[jHcal] ) continue;
2926 
2927  if ( distH < dist ) {
2928  isClosest = false;
2929  break;
2930  }
2931 
2932  }
2933 
2934  if (!isClosest) continue;
2935 
2936 
2937  if(debug_) {
2938  cout<<"\telement "<<elements[iEcal]<<" linked with dist "<< dist<<endl;
2939  cout<<"Added to HCAL cluster to form a neutral hadron"<<endl;
2940  }
2941 
2942  reco::PFClusterRef eclusterRef = elements[iEcal].clusterRef();
2943  assert( !eclusterRef.isNull() );
2944 
2945  // Check the presence of ps clusters in the vicinity
2946  vector<double> ps1Ene(1,static_cast<double>(0.));
2947  associatePSClusters(iEcal, reco::PFBlockElement::PS1, block, elements, linkData, active, ps1Ene);
2948  vector<double> ps2Ene(1,static_cast<double>(0.));
2949  associatePSClusters(iEcal, reco::PFBlockElement::PS2, block, elements, linkData, active, ps2Ene);
2950  bool crackCorrection = false;
2951  double ecalEnergy = calibration_->energyEm(*eclusterRef,ps1Ene,ps2Ene,crackCorrection);
2952 
2953  //std::cout << "EcalEnergy, ps1, ps2 = " << ecalEnergy
2954  // << ", " << ps1Ene[0] << ", " << ps2Ene[0] << std::endl;
2955  totalEcal += ecalEnergy;
2956  if ( ecalEnergy > ecalMax ) {
2957  ecalMax = ecalEnergy;
2958  eClusterRef = eclusterRef;
2959  }
2960 
2961  ecalRefs.push_back(iEcal);
2962  active[iEcal] = false;
2963 
2964 
2965  }// End loop ECAL
2966 
2967  // Now find the HO clusters linked to the HCAL cluster
2968  double totalHO = 0.;
2969  double hoMax = 0.;
2970  //unsigned jHO = 0;
2971  if (useHO_) {
2972  std::multimap<double, unsigned> hoElems;
2973  block.associatedElements( iHcal, linkData,
2974  hoElems ,
2977 
2978  // Loop on these HO elements
2979  // double totalHO = 0.;
2980  // double hoMax = 0.;
2981  // unsigned jHO = 0;
2982  reco::PFClusterRef hoClusterRef;
2983  for(IE ie = hoElems.begin(); ie != hoElems.end(); ++ie ) {
2984 
2985  unsigned iHO = ie->second;
2986  double dist = ie->first;
2987  PFBlockElement::Type type = elements[iHO].type();
2988  assert( type == PFBlockElement::HO );
2989 
2990  // Check if already used
2991  if( !active[iHO] ) continue;
2992 
2993  // Check the distance (one HCALPlusHO tower, roughly)
2994  // if ( dist > 0.15 ) continue;
2995 
2996  // Check if not closer from another free HCAL
2997  std::multimap<double, unsigned> hcalElems;
2998  block.associatedElements( iHO, linkData,
2999  hcalElems ,
3002 
3003  bool isClosest = true;
3004  for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
3005 
3006  unsigned jHcal = ih->second;
3007  double distH = ih->first;
3008 
3009  if ( !active[jHcal] ) continue;
3010 
3011  if ( distH < dist ) {
3012  isClosest = false;
3013  break;
3014  }
3015 
3016  }
3017 
3018  if (!isClosest) continue;
3019 
3020  if(debug_ && useHO_) {
3021  cout<<"\telement "<<elements[iHO]<<" linked with dist "<< dist<<endl;
3022  cout<<"Added to HCAL cluster to form a neutral hadron"<<endl;
3023  }
3024 
3025  reco::PFClusterRef hoclusterRef = elements[iHO].clusterRef();
3026  assert( !hoclusterRef.isNull() );
3027 
3028  double hoEnergy = hoclusterRef->energy(); // calibration_->energyEm(*hoclusterRef,ps1Ene,ps2Ene,crackCorrection);
3029 
3030  totalHO += hoEnergy;
3031  if ( hoEnergy > hoMax ) {
3032  hoMax = hoEnergy;
3033  hoClusterRef = hoclusterRef;
3034  //jHO = iHO;
3035  }
3036 
3037  hoRefs.push_back(iHO);
3038  active[iHO] = false;
3039 
3040  }// End loop HO
3041  }
3042 
3043  PFClusterRef hclusterRef
3044  = elements[iHcal].clusterRef();
3045  assert( !hclusterRef.isNull() );
3046 
3047  // HCAL energy
3048  double totalHcal = hclusterRef->energy();
3049  // Include the HO energy
3050  if ( useHO_ ) totalHcal += totalHO;
3051 
3052  // std::cout << "Hcal Energy,eta : " << totalHcal
3053  // << ", " << hclusterRef->positionREP().Eta()
3054  // << std::endl;
3055  // Calibration
3056  //double caloEnergy = totalHcal;
3057  // double slopeEcal = 1.0;
3058  double calibEcal = totalEcal > 0. ? totalEcal : 0.;
3059  double calibHcal = std::max(0.,totalHcal);
3060  if ( hclusterRef->layer() == PFLayer::HF_HAD ||
3061  hclusterRef->layer() == PFLayer::HF_EM ) {
3062  //caloEnergy = totalHcal/0.7;
3063  calibEcal = totalEcal;
3064  } else {
3065  calibration_->energyEmHad(-1.,calibEcal,calibHcal,
3066  hclusterRef->positionREP().Eta(),
3067  hclusterRef->positionREP().Phi());
3068  //caloEnergy = calibEcal+calibHcal;
3069  }
3070 
3071  // std::cout << "CalibEcal,HCal = " << calibEcal << ", " << calibHcal << std::endl;
3072  // std::cout << "-------------------------------------------------------------------" << std::endl;
3073  // ECAL energy : calibration
3074 
3075  // double particleEnergy = caloEnergy;
3076  // double particleEnergy = totalEcal + calibHcal;
3077  // particleEnergy /= (1.-0.724/sqrt(particleEnergy)-0.0226/particleEnergy);
3078 
3079  unsigned tmpi = reconstructCluster( *hclusterRef,
3080  calibEcal+calibHcal );
3081 
3082 
3083  (*pfCandidates_)[tmpi].setEcalEnergy( totalEcal, calibEcal );
3084  if ( !useHO_ ) {
3085  (*pfCandidates_)[tmpi].setHcalEnergy( totalHcal, calibHcal );
3086  (*pfCandidates_)[tmpi].setHoEnergy(0.,0.);
3087  } else {
3088  (*pfCandidates_)[tmpi].setHcalEnergy( totalHcal-totalHO, calibHcal*(1.-totalHO/totalHcal));
3089  (*pfCandidates_)[tmpi].setHoEnergy(totalHO,totalHO*calibHcal/totalHcal);
3090  }
3091  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
3092  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
3093  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
3094  for (unsigned iec=0; iec<ecalRefs.size(); ++iec)
3095  (*pfCandidates_)[tmpi].addElementInBlock( blockref, ecalRefs[iec] );
3096  for (unsigned iho=0; iho<hoRefs.size(); ++iho)
3097  (*pfCandidates_)[tmpi].addElementInBlock( blockref, hoRefs[iho] );
3098 
3099  }//loop hcal elements
3100 
3101 
3102 
3103 
3104  if(debug_) {
3105  cout<<endl;
3106  if(debug_) cout<<endl<<"---- loop ecal------- "<<endl;
3107  }
3108 
3109  // for each ecal element iEcal = ecalIs[i] in turn:
3110 
3111  for(unsigned i=0; i<ecalIs.size(); i++) {
3112  unsigned iEcal = ecalIs[i];
3113 
3114  if(debug_)
3115  cout<<endl<<elements[iEcal]<<" ";
3116 
3117  if( ! active[iEcal] ) {
3118  if(debug_)
3119  cout<<"not active"<<endl;
3120  continue;
3121  }
3122 
3123  PFBlockElement::Type type = elements[ iEcal ].type();
3124  assert( type == PFBlockElement::ECAL );
3125 
3126  PFClusterRef clusterref = elements[iEcal].clusterRef();
3127  assert(!clusterref.isNull() );
3128 
3129  active[iEcal] = false;
3130 
3131  // Check the presence of ps clusters in the vicinity
3132  vector<double> ps1Ene(1,static_cast<double>(0.));
3133  associatePSClusters(iEcal, reco::PFBlockElement::PS1, block, elements, linkData, active, ps1Ene);
3134  vector<double> ps2Ene(1,static_cast<double>(0.));
3135  associatePSClusters(iEcal, reco::PFBlockElement::PS2, block, elements, linkData, active, ps2Ene);
3136  bool crackCorrection = false;
3137  float ecalEnergy = calibration_->energyEm(*clusterref,ps1Ene,ps2Ene,crackCorrection);
3138  // float ecalEnergy = calibration_->energyEm( clusterref->energy() );
3139  double particleEnergy = ecalEnergy;
3140 
3141  unsigned tmpi = reconstructCluster( *clusterref,
3142  particleEnergy );
3143 
3144  (*pfCandidates_)[tmpi].setEcalEnergy( clusterref->energy(),ecalEnergy );
3145  (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
3146  (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
3147  (*pfCandidates_)[tmpi].setPs1Energy( 0. );
3148  (*pfCandidates_)[tmpi].setPs2Energy( 0. );
3149  (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
3150 
3151 
3152  } // end loop on ecal elements iEcal = ecalIs[i]
3153 
3154 } // end processBlock
const double Z[kNumberCalorimeter]
type
Definition: HCALResponse.h:21
virtual double energy() const GCC11_FINAL
energy
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:3463
bool usePFConversions_
Definition: PFAlgo.h:378
std::vector< double > muonHCAL_
Variables for muons and fakes.
Definition: PFAlgo.h:391
virtual void setCharge(Charge q) GCC11_FINAL
set electric charge
ParticleType
particle types
Definition: PFCandidate.h:43
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:311
static bool isMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:153
const std::vector< reco::PFCandidate > & getAllElectronCandidates()
unsigned reconstructCluster(const reco::PFCluster &cluster, double particleEnergy, bool useDirection=false, double particleX=0., double particleY=0., double particleZ=0.)
Definition: PFAlgo.cc:3231
double y() const
y coordinate
Definition: Vertex.h:96
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:247
#define X(str)
Definition: MuonsGrabber.cc:48
list elements
Definition: asciidump.py:414
RefToBase< value_type > refAt(size_type i) const
virtual void setVertex(const math::XYZPoint &p)
set vertex
Definition: PFCandidate.h:390
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:368
std::vector< double > factors45_
Definition: PFAlgo.h:396
bool useHO_
Definition: PFAlgo.h:334
void set_mva_e_pi(float mva)
Definition: PFCandidate.h:291
U second(std::pair< T, U > const &p)
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
bool isElectron(const reco::GsfElectron &)
void push_back(D *&d)
Definition: OwnVector.h:273
virtual float phi() const GCC11_FINAL
momentum azimuthal angle
bool isNull() const
Checks for null.
Definition: Ref.h:247
const T & max(const T &a, const T &b)
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:3408
void setParticleType(ParticleType type)
set Particle Type
Definition: PFCandidate.cc:252
bool passPhotonSelection(const reco::Photon &)
T sqrt(T t)
Definition: SSEVec.h:48
bool check(const DataFrame &df, bool capcheck, bool dvercheck)
const std::vector< reco::PFCandidateElectronExtra > & getElectronExtra()
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:98
reco::Vertex primaryVertex_
Definition: PFAlgo.h:410
double nSigmaHCAL(double clusterEnergy, double clusterEta) const
Definition: PFAlgo.cc:3358
std::vector< double > muonECAL_
Definition: PFAlgo.h:392
void setPositionAtECALEntrance(float x, float y, float z)
set position at ECAL entrance
std::vector< LinkConnSpec >::const_iterator IT
bool first
Definition: L1TdeRCT.cc:79
PFEGammaFilters * pfegamma_
Definition: PFAlgo.h:362
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
the extra photon collection
Definition: PFAlgo.h:295
virtual float eta() const GCC11_FINAL
momentum pseudorapidity
void setEcalEnergy(float eeRaw, float eeCorr)
set corrected Ecal energy
Definition: PFCandidate.h:200
float mva_e_pi() const
mva for electron-pion discrimination
Definition: PFCandidate.h:294
const std::vector< reco::PFCandidate > & getElectronCandidates()
double x() const
x coordinate
Definition: Vertex.h:94
virtual bool trackType(TrackType trType) const
unsigned reconstructTrack(const reco::PFBlockElement &elt, bool allowLoose=false)
Definition: PFAlgo.cc:3157
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
virtual int charge() const GCC11_FINAL
electric charge
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
size_type size() const
double b
Definition: hdecay.h:120
reco::TrackRef trackRef() const
void setHoEnergy(float eoRaw, float eoCorr)
set corrected Hcal energy
Definition: PFCandidate.h:220
bool isElectronValidCandidate(const reco::PFBlockRef &blockRef, std::vector< bool > &active, const reco::Vertex &primaryVertex)
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:38
boost::shared_ptr< PFEnergyCalibrationHF > thepfEnergyCalibrationHF_
Definition: PFAlgo.h:331
virtual void setP4(const LorentzVector &p4) GCC11_FINAL
set 4-momentum
double a
Definition: hdecay.h:121
reco::PFCandidateEGammaExtraRef egammaExtraRef() const
return a reference to the EGamma extra
Definition: PFCandidate.cc:592
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:3343
virtual float pt() const GCC11_FINAL
transverse momentum
reco::PFCandidateElectronExtraCollection pfElectronExtra_
the unfiltered electron collection
Definition: PFAlgo.h:293
bool usePFPhotons_
Definition: PFAlgo.h:343
const ElementsInBlocks & elementsInBlocks() const
Definition: PFCandidate.cc:675
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:210
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 3231 of file PFAlgo.cc.

References DeDxDiscriminatorTools::charge(), gather_cfg::cout, debug_, PFLayer::ECAL_BARREL, PFLayer::ECAL_ENDCAP, PFLayer::HCAL_BARREL1, PFLayer::HCAL_ENDCAP, PFLayer::HF_EM, PFLayer::HF_HAD, reco::PFCluster::layer(), 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().

3236  {
3237 
3239 
3240  // need to convert the math::XYZPoint data member of the PFCluster class=
3241  // to a displacement vector:
3242 
3243  // Transform particleX,Y,Z to a position at ECAL/HCAL entrance
3244  double factor = 1.;
3245  if ( useDirection ) {
3246  switch( cluster.layer() ) {
3247  case PFLayer::ECAL_BARREL:
3248  case PFLayer::HCAL_BARREL1:
3249  factor = std::sqrt(cluster.position().Perp2()/(particleX*particleX+particleY*particleY));
3250  break;
3251  case PFLayer::ECAL_ENDCAP:
3252  case PFLayer::HCAL_ENDCAP:
3253  case PFLayer::HF_HAD:
3254  case PFLayer::HF_EM:
3255  factor = cluster.position().Z()/particleZ;
3256  break;
3257  default:
3258  assert(0);
3259  }
3260  }
3261  //MIKE First of all let's check if we have vertex.
3262  math::XYZPoint vertexPos;
3263  if(useVertices_)
3265  else
3266  vertexPos = math::XYZPoint(0.0,0.0,0.0);
3267 
3268 
3269  math::XYZVector clusterPos( cluster.position().X()-vertexPos.X(),
3270  cluster.position().Y()-vertexPos.Y(),
3271  cluster.position().Z()-vertexPos.Z());
3272  math::XYZVector particleDirection ( particleX*factor-vertexPos.X(),
3273  particleY*factor-vertexPos.Y(),
3274  particleZ*factor-vertexPos.Z() );
3275 
3276  //math::XYZVector clusterPos( cluster.position().X(), cluster.position().Y(),cluster.position().Z() );
3277  //math::XYZVector particleDirection ( particleX, particleY, particleZ );
3278 
3279  clusterPos = useDirection ? particleDirection.Unit() : clusterPos.Unit();
3280  clusterPos *= particleEnergy;
3281 
3282  // clusterPos is now a vector along the cluster direction,
3283  // with a magnitude equal to the cluster energy.
3284 
3285  double mass = 0;
3286  ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double> >
3287  momentum( clusterPos.X(), clusterPos.Y(), clusterPos.Z(), mass);
3288  // mathcore is a piece of #$%
3290  // implicit constructor not allowed
3291  tmp = momentum;
3292 
3293  // Charge
3294  int charge = 0;
3295 
3296  // Type
3297  switch( cluster.layer() ) {
3298  case PFLayer::ECAL_BARREL:
3299  case PFLayer::ECAL_ENDCAP:
3300  particleType = PFCandidate::gamma;
3301  break;
3302  case PFLayer::HCAL_BARREL1:
3303  case PFLayer::HCAL_ENDCAP:
3304  particleType = PFCandidate::h0;
3305  break;
3306  case PFLayer::HF_HAD:
3307  particleType = PFCandidate::h_HF;
3308  break;
3309  case PFLayer::HF_EM:
3310  particleType = PFCandidate::egamma_HF;
3311  break;
3312  default:
3313  assert(0);
3314  }
3315 
3316  // The pf candidate
3317  pfCandidates_->push_back( PFCandidate( charge,
3318  tmp,
3319  particleType ) );
3320 
3321  // The position at ECAL entrance (well: watch out, it is not true
3322  // for HCAL clusters... to be fixed)
3323  pfCandidates_->back().
3324  setPositionAtECALEntrance(math::XYZPointF(cluster.position().X(),
3325  cluster.position().Y(),
3326  cluster.position().Z()));
3327 
3328  //Set the cnadidate Vertex
3329  pfCandidates_->back().setVertex(vertexPos);
3330 
3331  if(debug_)
3332  cout<<"** candidate: "<<pfCandidates_->back()<<endl;
3333 
3334  // returns index to the newly created PFCandidate
3335  return pfCandidates_->size()-1;
3336 
3337 }
PFLayer::Layer layer() const
cluster layer, see PFLayer.h in this directory
Definition: PFCluster.cc:81
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:124
ParticleType
particle types
Definition: PFCandidate.h:43
double y() const
y coordinate
Definition: Vertex.h:96
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
double charge(const std::vector< uint8_t > &Ampls)
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
T sqrt(T t)
Definition: SSEVec.h:48
double z() const
y coordinate
Definition: Vertex.h:98
reco::Vertex primaryVertex_
Definition: PFAlgo.h:410
double x() const
x coordinate
Definition: Vertex.h:94
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
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:38
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_.

Referenced by PFRootEventManager::particleFlow().

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:948
std::auto_ptr< reco::PFCandidateCollection > pfPhotonCandidates_
the unfiltered photon collection
Definition: PFAlgo.h:288
size_type size() const
Definition: OwnVector.h:247
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:3396
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:3499
void postClean(reco::PFCandidateCollection *)
Definition: PFMuonAlgo.cc:846
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 3157 of file PFAlgo.cc.

References DeDxDiscriminatorTools::charge(), 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(), 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().

3157  {
3158 
3159  const reco::PFBlockElementTrack* eltTrack
3160  = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
3161 
3162  reco::TrackRef trackRef = eltTrack->trackRef();
3163  const reco::Track& track = *trackRef;
3164  reco::MuonRef muonRef = eltTrack->muonRef();
3165  int charge = track.charge()>0 ? 1 : -1;
3166 
3167  // Assume this particle is a charged Hadron
3168  double px = track.px();
3169  double py = track.py();
3170  double pz = track.pz();
3171  double energy = sqrt(track.p()*track.p() + 0.13957*0.13957);
3172 
3173  // Create a PF Candidate
3174  math::XYZTLorentzVector momentum(px,py,pz,energy);
3175  reco::PFCandidate::ParticleType particleType
3177 
3178  // Add it to the stack
3179  pfCandidates_->push_back( PFCandidate( charge,
3180  momentum,
3181  particleType ) );
3182  //Set vertex and stuff like this
3183  pfCandidates_->back().setVertexSource( PFCandidate::kTrkVertex );
3184  pfCandidates_->back().setTrackRef( trackRef );
3185  pfCandidates_->back().setPositionAtECALEntrance( eltTrack->positionAtECALEntrance());
3186  if( muonRef.isNonnull())
3187  pfCandidates_->back().setMuonRef( muonRef );
3188 
3189 
3190 
3191  //OK Now try to reconstruct the particle as a muon
3192  bool isMuon=pfmu_->reconstructMuon(pfCandidates_->back(),muonRef,allowLoose);
3193  bool isFromDisp = isFromSecInt(elt, "secondary");
3194 
3195 
3196  if ((!isMuon) && isFromDisp) {
3197  double Dpt = trackRef->ptError();
3198  double dptRel = Dpt/trackRef->pt()*100;
3199  //If the track is ill measured it is better to not refit it, since the track information probably would not be used.
3200  //In the PFAlgo we use the trackref information. If the track error is too big the refitted information might be very different
3201  // from the not refitted one.
3202  if (dptRel < dptRel_DispVtx_){
3203  if (debug_)
3204  cout << "Not refitted px = " << px << " py = " << py << " pz = " << pz << " energy = " << energy << endl;
3205  //reco::TrackRef trackRef = eltTrack->trackRef();
3207  reco::Track trackRefit = vRef->refittedTrack(trackRef);
3208  //change the momentum with the refitted track
3209  math::XYZTLorentzVector momentum(trackRefit.px(),
3210  trackRefit.py(),
3211  trackRefit.pz(),
3212  sqrt(trackRefit.p()*trackRefit.p() + 0.13957*0.13957));
3213  if (debug_)
3214  cout << "Refitted px = " << px << " py = " << py << " pz = " << pz << " energy = " << energy << endl;
3215  }
3216  pfCandidates_->back().setFlag( reco::PFCandidate::T_FROM_DISP, true);
3217  pfCandidates_->back().setDisplacedVertexRef( eltTrack->displacedVertexRef(reco::PFBlockElement::T_FROM_DISP)->displacedVertexRef(), reco::PFCandidate::T_FROM_DISP);
3218  }
3219 
3220  // 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
3221  if(isFromSecInt(elt, "primary") && !isMuon) {
3222  pfCandidates_->back().setFlag( reco::PFCandidate::T_TO_DISP, true);
3223  pfCandidates_->back().setDisplacedVertexRef( eltTrack->displacedVertexRef(reco::PFBlockElement::T_TO_DISP)->displacedVertexRef(), reco::PFCandidate::T_TO_DISP);
3224  }
3225  // returns index to the newly created PFCandidate
3226  return pfCandidates_->size()-1;
3227 }
double p() const
momentum vector magnitude
Definition: TrackBase.h:127
bool isFromSecInt(const reco::PFBlockElement &eTrack, std::string order) const
Definition: PFAlgo.cc:3463
ParticleType
particle types
Definition: PFCandidate.h:43
bool isMuon(const Candidate &part)
Definition: pdgIdUtils.h:11
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:131
PFMuonAlgo * pfmu_
Definition: PFAlgo.h:357
double charge(const std::vector< uint8_t > &Ampls)
const math::XYZPointF & positionAtECALEntrance() const
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
reco::MuonRef muonRef() const
T sqrt(T t)
Definition: SSEVec.h:48
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:135
double dptRel_DispVtx_
Definition: PFAlgo.h:383
reco::TrackRef trackRef() const
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:38
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
bool debug_
Definition: PFAlgo.h:336
tuple cout
Definition: gather_cfg.py:121
int charge() const
track electric charge
Definition: TrackBase.h:111
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:133
bool reconstructMuon(reco::PFCandidate &, const reco::MuonRef &, bool allowLoose=false)
Definition: PFMuonAlgo.cc:685
PFDisplacedTrackerVertexRef displacedVertexRef(TrackType trType) const
void PFAlgo::setAlgo ( int  algo)
inline

Definition at line 63 of file PFAlgo.h.

References algo_.

Referenced by PFRootEventManager::readOptions().

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

Referenced by PFRootEventManager::readOptions().

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

Referenced by PFRootEventManager::readOptions().

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_.

Referenced by PFRootEventManager::readOptions().

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

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

Referenced by PFRootEventManager::particleFlow().

3494  {
3496 }
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 3711 of file PFAlgo.cc.

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

Referenced by PFRootEventManager::particleFlow().

3711  {
3712  if(!usePFElectrons_) return;
3713  // std::cout << " setElectronExtraRef " << std::endl;
3714  unsigned size=pfCandidates_->size();
3715 
3716  for(unsigned ic=0;ic<size;++ic) {
3717  // select the electrons and add the extra
3718  if((*pfCandidates_)[ic].particleId()==PFCandidate::e) {
3719 
3720  PFElectronExtraEqual myExtraEqual((*pfCandidates_)[ic].gsfTrackRef());
3721  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3722  if(it!=pfElectronExtra_.end()) {
3723  // std::cout << " Index " << it-pfElectronExtra_.begin() << std::endl;
3724  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3725  (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3726  }
3727  else {
3728  (*pfCandidates_)[ic].setPFElectronExtraRef(PFCandidateElectronExtraRef());
3729  }
3730  }
3731  else // else save the mva and the extra as well !
3732  {
3733  if((*pfCandidates_)[ic].trackRef().isNonnull()) {
3734  PFElectronExtraKfEqual myExtraEqual((*pfCandidates_)[ic].trackRef());
3735  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3736  if(it!=pfElectronExtra_.end()) {
3737  (*pfCandidates_)[ic].set_mva_e_pi(it->mvaVariable(PFCandidateElectronExtra::MVA_MVA));
3738  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3739  (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3740  (*pfCandidates_)[ic].setGsfTrackRef(it->gsfTrackRef());
3741  }
3742  }
3743  }
3744 
3745  }
3746 
3747  size=pfElectronCandidates_->size();
3748  for(unsigned ic=0;ic<size;++ic) {
3749  // select the electrons - this test is actually not needed for this collection
3750  if((*pfElectronCandidates_)[ic].particleId()==PFCandidate::e) {
3751  // find the corresponding extra
3752  PFElectronExtraEqual myExtraEqual((*pfElectronCandidates_)[ic].gsfTrackRef());
3753  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3754  if(it!=pfElectronExtra_.end()) {
3755  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3756  (*pfElectronCandidates_)[ic].setPFElectronExtraRef(theRef);
3757 
3758  }
3759  }
3760  }
3761 
3762 }
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_.

Referenced by PFRootEventManager::readOptions().

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_.

Referenced by PFRootEventManager::readOptions().

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:3358
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_.

Referenced by PFRootEventManager::readOptions().

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

Referenced by PFRootEventManager::readOptions().

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_, usePFPhotons_, and useVertices_.

Referenced by PFRootEventManager::readOptions().

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

Referenced by PFRootEventManager::readOptions().

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_, and useVertices_.

Referenced by PFRootEventManager::particleFlow().

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:1163
void PFAlgo::setPhotonExtraRef ( const edm::OrphanHandle< reco::PFCandidatePhotonExtraCollection > &  pf_extrah)

Definition at line 3763 of file PFAlgo.cc.

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

3763  {
3764  if(!usePFPhotons_) return;
3765  unsigned int size=pfCandidates_->size();
3766  unsigned int sizePhExtra = pfPhotonExtra_.size();
3767  for(unsigned ic=0;ic<size;++ic) {
3768  // select the electrons and add the extra
3769  if((*pfCandidates_)[ic].particleId()==PFCandidate::gamma && (*pfCandidates_)[ic].mva_nothing_gamma() > 0.99) {
3770  if((*pfCandidates_)[ic].superClusterRef().isNonnull()) {
3771  bool found = false;
3772  for(unsigned pcextra=0;pcextra<sizePhExtra;++pcextra) {
3773  if((*pfCandidates_)[ic].superClusterRef() == pfPhotonExtra_[pcextra].superClusterRef()) {
3774  reco::PFCandidatePhotonExtraRef theRef(ph_extrah,pcextra);
3775  (*pfCandidates_)[ic].setPFPhotonExtraRef(theRef);
3776  found = true;
3777  break;
3778  }
3779  }
3780  if(!found)
3781  (*pfCandidates_)[ic].setPFPhotonExtraRef((PFCandidatePhotonExtraRef())); // null ref
3782  }
3783  else {
3784  (*pfCandidates_)[ic].setPFPhotonExtraRef((PFCandidatePhotonExtraRef())); // null ref
3785  }
3786  }
3787  }
3788 }
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_.

Referenced by PFRootEventManager::readOptions().

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_.

Referenced by PFRootEventManager::particleFlow().

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.

Referenced by PFRootEventManager::particleFlow().

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