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

3431  {
3432 
3433  // Find all PS clusters with type psElement associated to ECAL cluster iEcal,
3434  // within all PFBlockElement "elements" of a given PFBlock "block"
3435  // psElement can be reco::PFBlockElement::PS1 or reco::PFBlockElement::PS2
3436  // Returns a vector of PS cluster energies, and updates the "active" vector.
3437 
3438  // Find all PS clusters linked to the iEcal cluster
3439  std::multimap<double, unsigned> sortedPS;
3440  typedef std::multimap<double, unsigned>::iterator IE;
3441  block.associatedElements( iEcal, linkData,
3442  sortedPS, psElementType,
3444 
3445  // Loop over these PS clusters
3446  double totalPS = 0.;
3447  for ( IE ips=sortedPS.begin(); ips!=sortedPS.end(); ++ips ) {
3448 
3449  // CLuster index and distance to iEcal
3450  unsigned iPS = ips->second;
3451  // double distPS = ips->first;
3452 
3453  // Ignore clusters already in use
3454  if (!active[iPS]) continue;
3455 
3456  // Check that this cluster is not closer to another ECAL cluster
3457  std::multimap<double, unsigned> sortedECAL;
3458  block.associatedElements( iPS, linkData,
3459  sortedECAL,
3462  unsigned jEcal = sortedECAL.begin()->second;
3463  if ( jEcal != iEcal ) continue;
3464 
3465  // Update PS energy
3466  PFBlockElement::Type pstype = elements[ iPS ].type();
3467  assert( pstype == psElementType );
3468  PFClusterRef psclusterref = elements[iPS].clusterRef();
3469  assert(!psclusterref.isNull() );
3470  totalPS += psclusterref->energy();
3471  psEne[0] += psclusterref->energy();
3472  active[iPS] = false;
3473  }
3474 
3475 
3476 }
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 3623 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(), runGlobalFakeInputProducer::skip, mathSSE::sqrt(), and reco::PFRecHit::time().

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

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

Definition at line 3413 of file PFAlgo.cc.

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

Referenced by reconstructParticles().

3414  {
3415 
3416  if( blockHandle_.isValid() ) {
3417  return reco::PFBlockRef( blockHandle_, bi );
3418  }
3419  else {
3420  return reco::PFBlockRef( &blocks, bi );
3421  }
3422 }
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 3480 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().

3480  {
3481 
3484  // reco::PFBlockElement::TrackType T_FROM_GAMMACONV = reco::PFBlockElement::T_FROM_GAMMACONV;
3486 
3487  bool bPrimary = (order.find("primary") != string::npos);
3488  bool bSecondary = (order.find("secondary") != string::npos);
3489  bool bAll = (order.find("all") != string::npos);
3490 
3491  bool isToDisp = usePFNuclearInteractions_ && eTrack.trackType(T_TO_DISP);
3492  bool isFromDisp = usePFNuclearInteractions_ && eTrack.trackType(T_FROM_DISP);
3493 
3494  if (bPrimary && isToDisp) return true;
3495  if (bSecondary && isFromDisp ) return true;
3496  if (bAll && ( isToDisp || isFromDisp ) ) return true;
3497 
3498 // bool isFromConv = usePFConversions_ && eTrack.trackType(T_FROM_GAMMACONV);
3499 
3500 // if ((bAll || bSecondary)&& isFromConv) return true;
3501 
3502  bool isFromDecay = (bAll || bSecondary) && usePFDecays_ && eTrack.trackType(T_FROM_V0);
3503 
3504  return isFromDecay;
3505 
3506 
3507 }
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 3360 of file PFAlgo.cc.

References mathSSE::sqrt().

Referenced by processBlock().

3360  {
3361 
3362  // Add a protection
3363  if ( clusterEnergyHCAL < 1. ) clusterEnergyHCAL = 1.;
3364 
3365  double resol = fabs(eta) < 1.48 ?
3366  sqrt (1.02*1.02/clusterEnergyHCAL + 0.065*0.065)
3367  :
3368  sqrt (1.20*1.20/clusterEnergyHCAL + 0.028*0.028);
3369 
3370  return resol;
3371 
3372 }
T eta() const
T sqrt(T t)
Definition: SSEVec.h:48
double PFAlgo::nSigmaHCAL ( double  clusterEnergy,
double  clusterEta 
) const
protected

Definition at line 3375 of file PFAlgo.cc.

References create_public_lumi_plots::exp, and nSigmaHCAL_.

Referenced by processBlock(), and setParameters().

3375  {
3376  double nS = fabs(eta) < 1.48 ?
3377  nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.))
3378  :
3379  nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.));
3380 
3381  return nS;
3382 }
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 3516 of file PFAlgo.cc.

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

Referenced by reconstructParticles().

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

process one block. can be reimplemented in more sophisticated algorithms

Reimplemented in PFAlgoTestBenchConversions, and PFAlgoTestBenchElectrons.

Definition at line 537 of file PFAlgo.cc.

References a, funct::abs(), associatePSClusters(), b, edm::OwnVector< T, P >::begin(), createPayload::block, alignmentValidation::c1, calibration_, dtNoiseDBValidation_cfg::cerr, reco::LeafCandidate::charge(), CastorDataFrameFilter_impl::check(), gather_cfg::cout, debug_, dptRel_DispVtx_, reco::PFCandidate::e, ECAL, reco::PFBlockElement::ECAL, RecoEcal_cff::ecalClusters, reco::PFCandidate::egammaExtraRef(), asciidump::elements, reco::PFCandidate::elementsInBlocks(), reco::LeafCandidate::energy(), eta(), reco::LeafCandidate::eta(), factors45_, first, reco::PFCandidate::gamma, PFElectronAlgo::getAllElectronCandidates(), PFElectronAlgo::getElectronCandidates(), PFElectronAlgo::getElectronExtra(), reco::PFBlockElement::GSF, HCAL, reco::PFBlockElement::HCAL, PFLayer::HF_EM, PFLayer::HF_HAD, reco::TrackBase::highPurity, reco::PFBlockElement::HO, i, cuy::ii, cmsHarvester::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_Isolated(), reco::PFCandidate::set_mva_nothing_gamma(), reco::LeafCandidate::setCharge(), reco::PFCandidate::setEcalEnergy(), reco::PFCandidate::setHcalEnergy(), reco::PFCandidate::setHoEnergy(), reco::LeafCandidate::setP4(), reco::PFCandidate::setParticleType(), reco::PFBlockElementTrack::setPositionAtECALEntrance(), reco::PFCandidate::setVertex(), edm::View< T >::size(), edm::OwnVector< T, P >::size(), runGlobalFakeInputProducer::skip, mathSSE::sqrt(), reco::PFBlockElement::T_FROM_GAMMACONV, thepfEnergyCalibrationHF_, reco::PFBlockElement::TRACK, reco::btau::trackMomentum, reco::PFBlockElementTrack::trackType(), funct::true, useEGammaFilters_, useHO_, usePFConversions_, usePFElectrons_, usePFPhotons_, useProtectionsForJetMET_, findQualityFiles::v, x, X, reco::Vertex::x(), reco::Vertex::y(), Gflash::Z, and reco::Vertex::z().

Referenced by reconstructParticles().

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

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

3253  {
3254 
3256 
3257  // need to convert the ::math::XYZPoint data member of the PFCluster class=
3258  // to a displacement vector:
3259 
3260  // Transform particleX,Y,Z to a position at ECAL/HCAL entrance
3261  double factor = 1.;
3262  if ( useDirection ) {
3263  switch( cluster.layer() ) {
3264  case PFLayer::ECAL_BARREL:
3265  case PFLayer::HCAL_BARREL1:
3266  factor = std::sqrt(cluster.position().Perp2()/(particleX*particleX+particleY*particleY));
3267  break;
3268  case PFLayer::ECAL_ENDCAP:
3269  case PFLayer::HCAL_ENDCAP:
3270  case PFLayer::HF_HAD:
3271  case PFLayer::HF_EM:
3272  factor = cluster.position().Z()/particleZ;
3273  break;
3274  default:
3275  assert(0);
3276  }
3277  }
3278  //MIKE First of all let's check if we have vertex.
3279  ::math::XYZPoint vertexPos;
3280  if(useVertices_)
3282  else
3283  vertexPos = ::math::XYZPoint(0.0,0.0,0.0);
3284 
3285 
3286  ::math::XYZVector clusterPos( cluster.position().X()-vertexPos.X(),
3287  cluster.position().Y()-vertexPos.Y(),
3288  cluster.position().Z()-vertexPos.Z());
3289  ::math::XYZVector particleDirection ( particleX*factor-vertexPos.X(),
3290  particleY*factor-vertexPos.Y(),
3291  particleZ*factor-vertexPos.Z() );
3292 
3293  //::math::XYZVector clusterPos( cluster.position().X(), cluster.position().Y(),cluster.position().Z() );
3294  //::math::XYZVector particleDirection ( particleX, particleY, particleZ );
3295 
3296  clusterPos = useDirection ? particleDirection.Unit() : clusterPos.Unit();
3297  clusterPos *= particleEnergy;
3298 
3299  // clusterPos is now a vector along the cluster direction,
3300  // with a magnitude equal to the cluster energy.
3301 
3302  double mass = 0;
3303  ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double> >
3304  momentum( clusterPos.X(), clusterPos.Y(), clusterPos.Z(), mass);
3305  // mathcore is a piece of #$%
3307  // implicit constructor not allowed
3308  tmp = momentum;
3309 
3310  // Charge
3311  int charge = 0;
3312 
3313  // Type
3314  switch( cluster.layer() ) {
3315  case PFLayer::ECAL_BARREL:
3316  case PFLayer::ECAL_ENDCAP:
3317  particleType = PFCandidate::gamma;
3318  break;
3319  case PFLayer::HCAL_BARREL1:
3320  case PFLayer::HCAL_ENDCAP:
3321  particleType = PFCandidate::h0;
3322  break;
3323  case PFLayer::HF_HAD:
3324  particleType = PFCandidate::h_HF;
3325  break;
3326  case PFLayer::HF_EM:
3327  particleType = PFCandidate::egamma_HF;
3328  break;
3329  default:
3330  assert(0);
3331  }
3332 
3333  // The pf candidate
3334  pfCandidates_->push_back( PFCandidate( charge,
3335  tmp,
3336  particleType ) );
3337 
3338  // The position at ECAL entrance (well: watch out, it is not true
3339  // for HCAL clusters... to be fixed)
3340  pfCandidates_->back().
3341  setPositionAtECALEntrance(::math::XYZPointF(cluster.position().X(),
3342  cluster.position().Y(),
3343  cluster.position().Z()));
3344 
3345  //Set the cnadidate Vertex
3346  pfCandidates_->back().setVertex(vertexPos);
3347 
3348  if(debug_)
3349  cout<<"** candidate: "<<pfCandidates_->back()<<endl;
3350 
3351  // returns index to the newly created PFCandidate
3352  return pfCandidates_->size()-1;
3353 
3354 }
PFLayer::Layer layer() const
cluster layer, see PFLayer.h in this directory
Definition: PFCluster.cc:86
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:124
ParticleType
particle types
Definition: PFCandidate.h:44
double y() const
y coordinate
Definition: Vertex.h:110
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
T sqrt(T t)
Definition: SSEVec.h:48
double z() const
y coordinate
Definition: Vertex.h:112
reco::Vertex primaryVertex_
Definition: PFAlgo.h:410
double x() const
x coordinate
Definition: Vertex.h:108
bool useVertices_
Definition: PFAlgo.h:411
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
math::XYZVector XYZPoint
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:39
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
bool debug_
Definition: PFAlgo.h:336
tuple cout
Definition: gather_cfg.py:121
void PFAlgo::reconstructParticles ( const reco::PFBlockHandle blockHandle)

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

Definition at line 414 of file PFAlgo.cc.

References blockHandle_.

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

reconstruct particles

Definition at line 422 of file PFAlgo.cc.

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

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

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

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

Definition at line 63 of file PFAlgo.h.

References algo_.

63 {algo_ = algo;}
int algo_
Definition: PFAlgo.h:335
void PFAlgo::setCandConnectorParameters ( const edm::ParameterSet iCfgCandConnector)
inline

Definition at line 73 of file PFAlgo.h.

References connector_, and PFCandConnector::setParameters().

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

Definition at line 77 of file PFAlgo.h.

References connector_, and PFCandConnector::setParameters().

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

Definition at line 66 of file PFAlgo.h.

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

PFCandConnector connector_
Definition: PFAlgo.h:388
#define debug
Definition: HDRShower.cc:19
bool debug_
Definition: PFAlgo.h:336
void setDebug(bool debug)
void PFAlgo::setDisplacedVerticesParameters ( bool  rejectTracks_Bad,
bool  rejectTracks_Step45,
bool  usePFNuclearInteractions,
bool  usePFConversions,
bool  usePFDecays,
double  dptRel_DispVtx 
)

Definition at line 353 of file PFAlgo.cc.

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

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

Definition at line 266 of file PFAlgo.cc.

References pfEgammaCandidates_, useEGammaFilters_, valueMapGedElectrons_, and valueMapGedPhotons_.

268  {
269  if(useEGammaFilters_) {
270  pfEgammaCandidates_ = & pfEgammaCandidates;
271  valueMapGedElectrons_ = & valueMapGedElectrons;
272  valueMapGedPhotons_ = & valueMapGedPhotons;
273  }
274 }
const edm::ValueMap< reco::PhotonRef > * valueMapGedPhotons_
Definition: PFAlgo.h:366
const edm::View< reco::PFCandidate > * pfEgammaCandidates_
Definition: PFAlgo.h:364
bool useEGammaFilters_
Variables for NEW EGAMMA selection.
Definition: PFAlgo.h:361
const edm::ValueMap< reco::GsfElectronRef > * valueMapGedElectrons_
Definition: PFAlgo.h:365
void PFAlgo::setEGammaParameters ( bool  use_EGammaFilters,
std::string  ele_iso_path_mvaWeightFile,
double  ele_iso_pt,
double  ele_iso_mva_barrel,
double  ele_iso_mva_endcap,
double  ele_iso_combIso_barrel,
double  ele_iso_combIso_endcap,
double  ele_noniso_mva,
unsigned int  ele_missinghits,
bool  useProtectionsForJetMET,
const edm::ParameterSet ele_protectionsForJetMET,
double  ph_MinEt,
double  ph_combIso,
double  ph_HoE,
double  ph_sietaieta_eb,
double  ph_sietaieta_ee,
const edm::ParameterSet ph_protectionsForJetMET 
)

Definition at line 211 of file PFAlgo.cc.

References pfegamma_, useEGammaFilters_, and useProtectionsForJetMET_.

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

Definition at line 3511 of file PFAlgo.cc.

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

3511  {
3513 }
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 3728 of file PFAlgo.cc.

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

3728  {
3729  if(!usePFElectrons_) return;
3730  // std::cout << " setElectronExtraRef " << std::endl;
3731  unsigned size=pfCandidates_->size();
3732 
3733  for(unsigned ic=0;ic<size;++ic) {
3734  // select the electrons and add the extra
3735  if((*pfCandidates_)[ic].particleId()==PFCandidate::e) {
3736 
3737  PFElectronExtraEqual myExtraEqual((*pfCandidates_)[ic].gsfTrackRef());
3738  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3739  if(it!=pfElectronExtra_.end()) {
3740  // std::cout << " Index " << it-pfElectronExtra_.begin() << std::endl;
3741  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3742  (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3743  }
3744  else {
3745  (*pfCandidates_)[ic].setPFElectronExtraRef(PFCandidateElectronExtraRef());
3746  }
3747  }
3748  else // else save the mva and the extra as well !
3749  {
3750  if((*pfCandidates_)[ic].trackRef().isNonnull()) {
3751  PFElectronExtraKfEqual myExtraEqual((*pfCandidates_)[ic].trackRef());
3752  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3753  if(it!=pfElectronExtra_.end()) {
3754  (*pfCandidates_)[ic].set_mva_e_pi(it->mvaVariable(PFCandidateElectronExtra::MVA_MVA));
3755  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3756  (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3757  (*pfCandidates_)[ic].setGsfTrackRef(it->gsfTrackRef());
3758  }
3759  }
3760  }
3761 
3762  }
3763 
3764  size=pfElectronCandidates_->size();
3765  for(unsigned ic=0;ic<size;++ic) {
3766  // select the electrons - this test is actually not needed for this collection
3767  if((*pfElectronCandidates_)[ic].particleId()==PFCandidate::e) {
3768  // find the corresponding extra
3769  PFElectronExtraEqual myExtraEqual((*pfElectronCandidates_)[ic].gsfTrackRef());
3770  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3771  if(it!=pfElectronExtra_.end()) {
3772  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3773  (*pfElectronCandidates_)[ic].setPFElectronExtraRef(theRef);
3774 
3775  }
3776  }
3777  }
3778 
3779 }
edm::Ref< PFCandidateElectronExtraCollection > PFCandidateElectronExtraRef
persistent reference to a PFCandidateElectronExtra
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
std::auto_ptr< reco::PFCandidateCollection > pfElectronCandidates_
the unfiltered electron collection
Definition: PFAlgo.h:286
reco::PFCandidateElectronExtraCollection pfElectronExtra_
the unfiltered electron collection
Definition: PFAlgo.h:293
tuple size
Write out results.
bool usePFElectrons_
Definition: PFAlgo.h:342
void PFAlgo::setHOTag ( bool  ho)
inline

Definition at line 62 of file PFAlgo.h.

References useHO_.

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

Definition at line 330 of file PFAlgo.cc.

References muonHandle_, and patZpeak::muons.

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

Definition at line 78 of file PFAlgo.cc.

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

81  {
82 
83  nSigmaECAL_ = nSigmaECAL;
85 
86  calibration_ = calibration;
87  thepfEnergyCalibrationHF_ = thepfEnergyCalibrationHF;
88 
89 }
double nSigmaHCAL_
number of sigma to judge energy excess in HCAL
Definition: PFAlgo.h:328
double nSigmaHCAL(double clusterEnergy, double clusterEta) const
Definition: PFAlgo.cc:3375
boost::shared_ptr< PFEnergyCalibration > calibration_
Definition: PFAlgo.h:330
boost::shared_ptr< PFEnergyCalibrationHF > thepfEnergyCalibrationHF_
Definition: PFAlgo.h:331
double nSigmaECAL_
number of sigma to judge energy excess in ECAL
Definition: PFAlgo.h:325
void PFAlgo::setPFEleParameters ( double  mvaEleCut,
std::string  mvaWeightFileEleID,
bool  usePFElectrons,
const boost::shared_ptr< PFSCEnergyCalibration > &  thePFSCEnergyCalibration,
const boost::shared_ptr< PFEnergyCalibration > &  thePFEnergyCalibration,
double  sumEtEcalIsoForEgammaSC_barrel,
double  sumEtEcalIsoForEgammaSC_endcap,
double  coneEcalIsoForEgammaSC,
double  sumPtTrackIsoForEgammaSC_barrel,
double  sumPtTrackIsoForEgammaSC_endcap,
unsigned int  nTrackIsoForEgammaSC,
double  coneTrackIsoForEgammaSC,
bool  applyCrackCorrections = false,
bool  usePFSCEleCalib = true,
bool  useEGElectrons = false,
bool  useEGammaSupercluster = true 
)

Definition at line 98 of file PFAlgo.cc.

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

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

Definition at line 64 of file PFAlgo.h.

References pfmu_.

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

Definition at line 301 of file PFAlgo.cc.

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

308 {
309 
310 
311 
312 
313  pfmu_ = new PFMuonAlgo();
314  pfmu_->setParameters(pset);
315 
316  // Muon parameters
317  muonHCAL_= pset.getParameter<std::vector<double> >("muon_HCAL");
318  muonECAL_= pset.getParameter<std::vector<double> >("muon_ECAL");
319  muonHO_= pset.getParameter<std::vector<double> >("muon_HO");
320  assert ( muonHCAL_.size() == 2 && muonECAL_.size() == 2 && muonHO_.size() == 2);
321  nSigmaTRACK_= pset.getParameter<double>("nsigma_TRACK");
322  ptError_= pset.getParameter<double>("pt_Error");
323  factors45_ = pset.getParameter<std::vector<double> >("factors_45");
324  assert ( factors45_.size() == 2 );
325 
326 }
T getParameter(std::string const &) const
double ptError_
Definition: PFAlgo.h:395
std::vector< double > muonHCAL_
Variables for muons and fakes.
Definition: PFAlgo.h:391
void setParameters(const edm::ParameterSet &)
Definition: PFMuonAlgo.cc:29
PFMuonAlgo * pfmu_
Definition: PFAlgo.h:357
std::vector< double > factors45_
Definition: PFAlgo.h:396
std::vector< double > muonECAL_
Definition: PFAlgo.h:392
std::vector< double > muonHO_
Definition: PFAlgo.h:393
double nSigmaTRACK_
Definition: PFAlgo.h:394
void PFAlgo::setPFPhotonParameters ( bool  usePFPhoton,
std::string  mvaWeightFileConvID,
double  mvaConvCut,
bool  useReg,
std::string  X0_Map,
const boost::shared_ptr< PFEnergyCalibration > &  thePFEnergyCalibration,
double  sumPtTrackIsoForPhoton,
double  sumPtTrackIsoSlopeForPhoton 
)

Definition at line 160 of file PFAlgo.cc.

References alignCSCRings::e, AlCaHLTBitMon_ParallelJobs::p, pfpho_, primaryVertex_, usePFPhotons_, and useVertices_.

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

Definition at line 288 of file PFAlgo.cc.

References pfpho_, and PFPhotonAlgo::setGBRForest().

294  {
295 
296  pfpho_->setGBRForest(LCorrForestEB,LCorrForestEE,
297  GCorrForestBarrel, GCorrForestEndcapHr9,
298  GCorrForestEndcapLr9, PFEcalResolution);
299 }
PFPhotonAlgo * pfpho_
Definition: PFAlgo.h:356
void setGBRForest(const GBRForest *LCorrForest, const GBRForest *GCorrForest, const GBRForest *ResForest)
Definition: PFPhotonAlgo.h:49
void PFAlgo::setPFVertexParameters ( bool  useVertex,
const reco::VertexCollection primaryVertices 
)

Definition at line 371 of file PFAlgo.cc.

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

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

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

3780  {
3781  if(!usePFPhotons_) return;
3782  unsigned int size=pfCandidates_->size();
3783  unsigned int sizePhExtra = pfPhotonExtra_.size();
3784  for(unsigned ic=0;ic<size;++ic) {
3785  // select the electrons and add the extra
3786  if((*pfCandidates_)[ic].particleId()==PFCandidate::gamma && (*pfCandidates_)[ic].mva_nothing_gamma() > 0.99) {
3787  if((*pfCandidates_)[ic].superClusterRef().isNonnull()) {
3788  bool found = false;
3789  for(unsigned pcextra=0;pcextra<sizePhExtra;++pcextra) {
3790  if((*pfCandidates_)[ic].superClusterRef() == pfPhotonExtra_[pcextra].superClusterRef()) {
3791  reco::PFCandidatePhotonExtraRef theRef(ph_extrah,pcextra);
3792  (*pfCandidates_)[ic].setPFPhotonExtraRef(theRef);
3793  found = true;
3794  break;
3795  }
3796  }
3797  if(!found)
3798  (*pfCandidates_)[ic].setPFPhotonExtraRef((PFCandidatePhotonExtraRef())); // null ref
3799  }
3800  else {
3801  (*pfCandidates_)[ic].setPFPhotonExtraRef((PFCandidatePhotonExtraRef())); // null ref
3802  }
3803  }
3804  }
3805 }
edm::Ref< PFCandidatePhotonExtraCollection > PFCandidatePhotonExtraRef
persistent reference to a PFCandidatePhotonExtra
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
the extra photon collection
Definition: PFAlgo.h:295
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
Definition: PFAlgo.h:284
bool usePFPhotons_
Definition: PFAlgo.h:343
tuple size
Write out results.
void PFAlgo::setPostHFCleaningParameters ( bool  postHFCleaning,
double  minHFCleaningPt,
double  minSignificance,
double  maxSignificance,
double  minSignificanceReduction,
double  maxDeltaPhiPt,
double  minDeltaMet 
)

Definition at line 336 of file PFAlgo.cc.

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

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

return the pointer to the calibration function

Definition at line 234 of file PFAlgo.h.

References calibration_.

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

Definition at line 229 of file PFAlgo.h.

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

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

Definition at line 224 of file PFAlgo.h.

References pfCleanedCandidates_.

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

Definition at line 201 of file PFAlgo.h.

References pfElectronCandidates_.

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

Definition at line 207 of file PFAlgo.h.

References pfElectronExtra_, and query::result.

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

Definition at line 216 of file PFAlgo.h.

References pfPhotonExtra_, and query::result.

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

Friends And Related Function Documentation

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

Member Data Documentation

int PFAlgo::algo_
private

Definition at line 335 of file PFAlgo.h.

Referenced by setAlgo().

bool PFAlgo::applyCrackCorrectionsElectrons_
private

Definition at line 344 of file PFAlgo.h.

Referenced by setPFEleParameters().

reco::PFBlockHandle PFAlgo::blockHandle_
private

input block handle (full framework case)

Definition at line 322 of file PFAlgo.h.

Referenced by createBlockRef(), and reconstructParticles().

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

Definition at line 330 of file PFAlgo.h.

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

double PFAlgo::coneEcalIsoForEgammaSC_
private

Definition at line 350 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::coneTrackIsoForEgammaSC_
private

Definition at line 353 of file PFAlgo.h.

Referenced by setPFEleParameters().

PFCandConnector PFAlgo::connector_
private

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

Definition at line 388 of file PFAlgo.h.

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

bool PFAlgo::debug_
private
double PFAlgo::dptRel_DispVtx_
private

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

Definition at line 383 of file PFAlgo.h.

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

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

Definition at line 396 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

double PFAlgo::maxDeltaPhiPt_
private

Definition at line 405 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::maxSignificance_
private

Definition at line 403 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::minDeltaMet_
private

Definition at line 406 of file PFAlgo.h.

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

double PFAlgo::minHFCleaningPt_
private

Definition at line 401 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::minSignificance_
private

Definition at line 402 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

double PFAlgo::minSignificanceReduction_
private

Definition at line 404 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

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

Definition at line 392 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

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

Definition at line 413 of file PFAlgo.h.

Referenced by reconstructParticles(), and setMuonHandle().

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

Variables for muons and fakes.

Definition at line 391 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

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

Definition at line 393 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

double PFAlgo::mvaEleCut_
private

Definition at line 341 of file PFAlgo.h.

Referenced by setPFEleParameters().

std::string PFAlgo::mvaWeightFileEleID_
private

Variables for PFElectrons.

Definition at line 339 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::nSigmaECAL_
private

number of sigma to judge energy excess in ECAL

Definition at line 325 of file PFAlgo.h.

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

double PFAlgo::nSigmaHCAL_
private

number of sigma to judge energy excess in HCAL

Definition at line 328 of file PFAlgo.h.

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

double PFAlgo::nSigmaTRACK_
private

Definition at line 394 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

unsigned int PFAlgo::nTrackIsoForEgammaSC_
private

Definition at line 354 of file PFAlgo.h.

Referenced by setPFEleParameters().

int PFAlgo::nVtx_
private

Definition at line 384 of file PFAlgo.h.

Referenced by processBlock(), and setPFVertexParameters().

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

Definition at line 290 of file PFAlgo.h.

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

PFEGammaFilters* PFAlgo::pfegamma_
private

Definition at line 362 of file PFAlgo.h.

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

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

Definition at line 364 of file PFAlgo.h.

Referenced by processBlock(), and setEGammaCollections().

PFElectronAlgo* PFAlgo::pfele_
private

Definition at line 355 of file PFAlgo.h.

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

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

the unfiltered electron collection

Definition at line 286 of file PFAlgo.h.

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

reco::PFCandidateElectronExtraCollection PFAlgo::pfElectronExtra_
protected

the unfiltered electron collection

Definition at line 293 of file PFAlgo.h.

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

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

the unfiltered photon collection

Definition at line 288 of file PFAlgo.h.

Referenced by processBlock(), and reconstructParticles().

reco::PFCandidatePhotonExtraCollection PFAlgo::pfPhotonExtra_
protected

the extra photon collection

Definition at line 295 of file PFAlgo.h.

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

bool PFAlgo::postHFCleaning_
private

Definition at line 399 of file PFAlgo.h.

Referenced by postCleaning(), and setPostHFCleaningParameters().

bool PFAlgo::postMuonCleaning_
private

Definition at line 400 of file PFAlgo.h.

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

Definition at line 395 of file PFAlgo.h.

Referenced by processBlock(), and setPFMuonAndFakeParameters().

bool PFAlgo::rejectTracks_Bad_
private

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

Definition at line 374 of file PFAlgo.h.

Referenced by processBlock(), and setDisplacedVerticesParameters().

bool PFAlgo::rejectTracks_Step45_
private

Definition at line 375 of file PFAlgo.h.

Referenced by processBlock(), and setDisplacedVerticesParameters().

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

Definition at line 340 of file PFAlgo.h.

double PFAlgo::sumEtEcalIsoForEgammaSC_barrel_
private

Definition at line 348 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::sumEtEcalIsoForEgammaSC_endcap_
private

Definition at line 349 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::sumPtTrackIsoForEgammaSC_barrel_
private

Definition at line 351 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::sumPtTrackIsoForEgammaSC_endcap_
private

Definition at line 352 of file PFAlgo.h.

Referenced by setPFEleParameters().

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

Definition at line 331 of file PFAlgo.h.

Referenced by processBlock(), and setParameters().

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

Definition at line 332 of file PFAlgo.h.

Referenced by setPFEleParameters().

double PFAlgo::useBestMuonTrack_
private

Definition at line 407 of file PFAlgo.h.

bool PFAlgo::useEGammaFilters_
private

Variables for NEW EGAMMA selection.

Definition at line 361 of file PFAlgo.h.

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

bool PFAlgo::useEGammaSupercluster_
private

Definition at line 347 of file PFAlgo.h.

Referenced by setPFEleParameters().

bool PFAlgo::useEGElectrons_
private

Definition at line 346 of file PFAlgo.h.

Referenced by setEGElectronCollection(), and setPFEleParameters().

bool PFAlgo::useHO_
private

Definition at line 334 of file PFAlgo.h.

Referenced by processBlock(), and setHOTag().

bool PFAlgo::usePFConversions_
private

Definition at line 378 of file PFAlgo.h.

Referenced by processBlock(), and setDisplacedVerticesParameters().

bool PFAlgo::usePFDecays_
private

Definition at line 379 of file PFAlgo.h.

Referenced by isFromSecInt(), and setDisplacedVerticesParameters().

bool PFAlgo::usePFElectrons_
private

Definition at line 342 of file PFAlgo.h.

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

bool PFAlgo::usePFMuonMomAssign_
private

Definition at line 370 of file PFAlgo.h.

bool PFAlgo::usePFNuclearInteractions_
private

Definition at line 377 of file PFAlgo.h.

Referenced by isFromSecInt(), and setDisplacedVerticesParameters().

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

Definition at line 345 of file PFAlgo.h.

Referenced by setPFEleParameters().

bool PFAlgo::useProtectionsForJetMET_
private

Definition at line 363 of file PFAlgo.h.

Referenced by processBlock(), and setEGammaParameters().

bool PFAlgo::useVertices_
private

Definition at line 411 of file PFAlgo.h.

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

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

Definition at line 365 of file PFAlgo.h.

Referenced by setEGammaCollections().

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

Definition at line 366 of file PFAlgo.h.

Referenced by setEGammaCollections().