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

3421  {
3422 
3423  // Find all PS clusters with type psElement associated to ECAL cluster iEcal,
3424  // within all PFBlockElement "elements" of a given PFBlock "block"
3425  // psElement can be reco::PFBlockElement::PS1 or reco::PFBlockElement::PS2
3426  // Returns a vector of PS cluster energies, and updates the "active" vector.
3427 
3428  // Find all PS clusters linked to the iEcal cluster
3429  std::multimap<double, unsigned> sortedPS;
3430  typedef std::multimap<double, unsigned>::iterator IE;
3431  block.associatedElements( iEcal, linkData,
3432  sortedPS, psElementType,
3434 
3435  // Loop over these PS clusters
3436  double totalPS = 0.;
3437  for ( IE ips=sortedPS.begin(); ips!=sortedPS.end(); ++ips ) {
3438 
3439  // CLuster index and distance to iEcal
3440  unsigned iPS = ips->second;
3441  // double distPS = ips->first;
3442 
3443  // Ignore clusters already in use
3444  if (!active[iPS]) continue;
3445 
3446  // Check that this cluster is not closer to another ECAL cluster
3447  std::multimap<double, unsigned> sortedECAL;
3448  block.associatedElements( iPS, linkData,
3449  sortedECAL,
3452  unsigned jEcal = sortedECAL.begin()->second;
3453  if ( jEcal != iEcal ) continue;
3454 
3455  // Update PS energy
3456  PFBlockElement::Type pstype = elements[ iPS ].type();
3457  assert( pstype == psElementType );
3458  PFClusterRef psclusterref = elements[iPS].clusterRef();
3459  assert(!psclusterref.isNull() );
3460  totalPS += psclusterref->energy();
3461  psEne[0] += psclusterref->energy();
3462  active[iPS] = false;
3463  }
3464 
3465 
3466 }
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 3613 of file PFAlgo.cc.

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

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

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

Referenced by reconstructParticles().

3404  {
3405 
3406  if( blockHandle_.isValid() ) {
3407  return reco::PFBlockRef( blockHandle_, bi );
3408  }
3409  else {
3410  return reco::PFBlockRef( &blocks, bi );
3411  }
3412 }
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 3470 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().

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

References mathSSE::sqrt().

Referenced by processBlock().

3350  {
3351 
3352  // Add a protection
3353  if ( clusterEnergyHCAL < 1. ) clusterEnergyHCAL = 1.;
3354 
3355  double resol = fabs(eta) < 1.48 ?
3356  sqrt (1.02*1.02/clusterEnergyHCAL + 0.065*0.065)
3357  :
3358  sqrt (1.20*1.20/clusterEnergyHCAL + 0.028*0.028);
3359 
3360  return resol;
3361 
3362 }
T eta() const
T sqrt(T t)
Definition: SSEVec.h:48
double PFAlgo::nSigmaHCAL ( double  clusterEnergy,
double  clusterEta 
) const
protected

Definition at line 3365 of file PFAlgo.cc.

References create_public_lumi_plots::exp, and nSigmaHCAL_.

Referenced by processBlock(), and setParameters().

3365  {
3366  double nS = fabs(eta) < 1.48 ?
3367  nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.))
3368  :
3369  nSigmaHCAL_ * (1. + exp(-clusterEnergyHCAL/100.));
3370 
3371  return nS;
3372 }
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 3506 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().

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

process one block. can be reimplemented in more sophisticated algorithms

Reimplemented in PFAlgoTestBenchConversions, and PFAlgoTestBenchElectrons.

Definition at line 537 of file PFAlgo.cc.

References a, funct::abs(), associatePSClusters(), b, edm::OwnVector< T, P >::begin(), createPayload::block, alignmentValidation::c1, calibration_, dtNoiseDBValidation_cfg::cerr, reco::LeafCandidate::charge(), DDVectorGetter::check(), gather_cfg::cout, debug_, IterativeDetachedTripletStep_cff::detachedTripletStep, dptRel_DispVtx_, reco::PFCandidate::e, ECAL, reco::PFBlockElement::ECAL, RecoEcal_cff::ecalClusters, reco::PFCandidate::egammaExtraRef(), asciidump::elements, reco::PFCandidate::elementsInBlocks(), reco::LeafCandidate::energy(), eta(), reco::LeafCandidate::eta(), factors45_, first, reco::PFCandidate::gamma, PFElectronAlgo::getAllElectronCandidates(), PFElectronAlgo::getElectronCandidates(), PFElectronAlgo::getElectronExtra(), reco::PFBlockElement::GSF, HCAL, reco::PFBlockElement::HCAL, PFLayer::HF_EM, PFLayer::HF_HAD, reco::TrackBase::highPurity, reco::TrackBase::hltIter0, reco::TrackBase::hltIter1, reco::TrackBase::hltIter2, reco::TrackBase::hltIter3, reco::TrackBase::hltIter4, reco::TrackBase::hltIterX, reco::PFBlockElement::HO, i, cuy::ii, cmsHarvester::index, InitialStep_cff::initialStep, PFEGammaFilters::isElectron(), PFEGammaFilters::isElectronSafeForJetMET(), PFElectronAlgo::isElectronValidCandidate(), isFromSecInt(), PFMuonAlgo::isIsolatedMuon(), PFMuonAlgo::isLooseMuon(), PFMuonAlgo::isMuon(), edm::Ref< C, T, F >::isNonnull(), edm::Ref< C, T, F >::isNull(), PFEGammaFilters::isPhotonSafeForJetMET(), PFPhotonAlgo::isPhotonValidCandidate(), j, reco::PFBlock::LINKTEST_ALL, bookConverter::max, min(), IterativeMixedTripletStep_cff::mixedTripletStep, reco::PFCandidate::mu, muonECAL_, muonHCAL_, muonHO_, reco::PFCandidate::mva_e_pi(), neutralHadronEnergyResolution(), nSigmaECAL_, nSigmaHCAL(), nSigmaTRACK_, nVtx_, convertSQLiteXML::ok, AlCaHLTBitMon_ParallelJobs::p, objects.autophobj::particleType, PFEGammaFilters::passElectronSelection(), PFEGammaFilters::passPhotonSelection(), pfCandidates_, pfegamma_, pfEgammaCandidates_, pfele_, pfElectronCandidates_, pfElectronExtra_, pfpho_, pfPhotonCandidates_, pfPhotonExtra_, reco::LeafCandidate::phi(), PixelLessStep_cff::pixelLessStep, primaryVertex_, reco::PFBlockElement::PS1, reco::PFBlockElement::PS2, reco::LeafCandidate::pt(), ptError_, edm::OwnVector< T, P >::push_back(), reconstructCluster(), reconstructTrack(), edm::View< T >::refAt(), rejectTracks_Bad_, rejectTracks_Step45_, edm::second(), reco::PFCandidate::set_mva_e_pi(), reco::PFCandidate::set_mva_Isolated(), reco::PFCandidate::set_mva_nothing_gamma(), reco::LeafCandidate::setCharge(), reco::PFCandidate::setEcalEnergy(), reco::PFCandidate::setHcalEnergy(), reco::PFCandidate::setHoEnergy(), reco::LeafCandidate::setP4(), reco::PFCandidate::setParticleType(), reco::PFBlockElementTrack::setPositionAtECALEntrance(), reco::PFCandidate::setVertex(), edm::OwnVector< T, P >::size(), edm::View< T >::size(), runGlobalFakeInputProducer::skip, mathSSE::sqrt(), reco::PFBlockElement::T_FROM_GAMMACONV, thepfEnergyCalibrationHF_, reco::PFBlockElement::TRACK, reco::btau::trackMomentum, reco::PFBlockElementTrack::trackType(), funct::true, useEGammaFilters_, useHO_, usePFConversions_, usePFElectrons_, usePFPhotons_, useProtectionsForJetMET_, findQualityFiles::v, x, X, reco::Vertex::x(), reco::Vertex::y(), Gflash::Z, and reco::Vertex::z().

Referenced by reconstructParticles().

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

Reconstruct a neutral particle from a cluster. If chargedEnergy is specified, the neutral particle is created only if the cluster energy is significantly larger than the chargedEnergy. In this case, the energy of the neutral particle is cluster energy - chargedEnergy

Definition at line 3238 of file PFAlgo.cc.

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

Referenced by checkCleaning(), and processBlock().

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

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

Definition at line 414 of file PFAlgo.cc.

References blockHandle_.

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

reconstruct particles

Definition at line 422 of file PFAlgo.cc.

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

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

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

Definition at line 3164 of file PFAlgo.cc.

References reco::TrackBase::charge(), gather_cfg::cout, debug_, reco::PFBlockElementTrack::displacedVertexRef(), dptRel_DispVtx_, relval_parameters_module::energy, reco::PFCandidate::h, isFromSecInt(), reco::isMuon(), edm::Ref< C, T, F >::isNonnull(), reco::PFBlockElementTrack::muonRef(), reco::TrackBase::p(), objects.autophobj::particleType, pfCandidates_, pfmu_, reco::PFBlockElementTrack::positionAtECALEntrance(), reco::TrackBase::px(), reco::TrackBase::py(), reco::TrackBase::pz(), PFMuonAlgo::reconstructMuon(), mathSSE::sqrt(), reco::PFBlockElement::T_FROM_DISP, reco::PFCandidate::T_FROM_DISP, reco::PFBlockElement::T_TO_DISP, reco::PFCandidate::T_TO_DISP, and reco::PFBlockElementTrack::trackRef().

Referenced by processBlock().

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

Definition at line 63 of file PFAlgo.h.

References algo_.

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

Definition at line 73 of file PFAlgo.h.

References connector_, and PFCandConnector::setParameters().

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

Definition at line 77 of file PFAlgo.h.

References connector_, and PFCandConnector::setParameters().

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

Definition at line 66 of file PFAlgo.h.

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

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

Definition at line 353 of file PFAlgo.cc.

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

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

Definition at line 266 of file PFAlgo.cc.

References pfEgammaCandidates_, useEGammaFilters_, valueMapGedElectrons_, and valueMapGedPhotons_.

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

Definition at line 211 of file PFAlgo.cc.

References pfegamma_, useEGammaFilters_, and useProtectionsForJetMET_.

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

Definition at line 3501 of file PFAlgo.cc.

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

3501  {
3503 }
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 3718 of file PFAlgo.cc.

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

3718  {
3719  if(!usePFElectrons_) return;
3720  // std::cout << " setElectronExtraRef " << std::endl;
3721  unsigned size=pfCandidates_->size();
3722 
3723  for(unsigned ic=0;ic<size;++ic) {
3724  // select the electrons and add the extra
3725  if((*pfCandidates_)[ic].particleId()==PFCandidate::e) {
3726 
3727  PFElectronExtraEqual myExtraEqual((*pfCandidates_)[ic].gsfTrackRef());
3728  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3729  if(it!=pfElectronExtra_.end()) {
3730  // std::cout << " Index " << it-pfElectronExtra_.begin() << std::endl;
3731  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3732  (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3733  }
3734  else {
3735  (*pfCandidates_)[ic].setPFElectronExtraRef(PFCandidateElectronExtraRef());
3736  }
3737  }
3738  else // else save the mva and the extra as well !
3739  {
3740  if((*pfCandidates_)[ic].trackRef().isNonnull()) {
3741  PFElectronExtraKfEqual myExtraEqual((*pfCandidates_)[ic].trackRef());
3742  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3743  if(it!=pfElectronExtra_.end()) {
3744  (*pfCandidates_)[ic].set_mva_e_pi(it->mvaVariable(PFCandidateElectronExtra::MVA_MVA));
3745  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3746  (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3747  (*pfCandidates_)[ic].setGsfTrackRef(it->gsfTrackRef());
3748  }
3749  }
3750  }
3751 
3752  }
3753 
3754  size=pfElectronCandidates_->size();
3755  for(unsigned ic=0;ic<size;++ic) {
3756  // select the electrons - this test is actually not needed for this collection
3757  if((*pfElectronCandidates_)[ic].particleId()==PFCandidate::e) {
3758  // find the corresponding extra
3759  PFElectronExtraEqual myExtraEqual((*pfElectronCandidates_)[ic].gsfTrackRef());
3760  std::vector<PFCandidateElectronExtra>::const_iterator it=find_if(pfElectronExtra_.begin(),pfElectronExtra_.end(),myExtraEqual);
3761  if(it!=pfElectronExtra_.end()) {
3762  reco::PFCandidateElectronExtraRef theRef(extrah,it-pfElectronExtra_.begin());
3763  (*pfElectronCandidates_)[ic].setPFElectronExtraRef(theRef);
3764 
3765  }
3766  }
3767  }
3768 
3769 }
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:3365
boost::shared_ptr< PFEnergyCalibration > calibration_
Definition: PFAlgo.h:330
boost::shared_ptr< PFEnergyCalibrationHF > thepfEnergyCalibrationHF_
Definition: PFAlgo.h:331
double nSigmaECAL_
number of sigma to judge energy excess in ECAL
Definition: PFAlgo.h:325
void PFAlgo::setPFEleParameters ( double  mvaEleCut,
std::string  mvaWeightFileEleID,
bool  usePFElectrons,
const boost::shared_ptr< PFSCEnergyCalibration > &  thePFSCEnergyCalibration,
const boost::shared_ptr< PFEnergyCalibration > &  thePFEnergyCalibration,
double  sumEtEcalIsoForEgammaSC_barrel,
double  sumEtEcalIsoForEgammaSC_endcap,
double  coneEcalIsoForEgammaSC,
double  sumPtTrackIsoForEgammaSC_barrel,
double  sumPtTrackIsoForEgammaSC_endcap,
unsigned int  nTrackIsoForEgammaSC,
double  coneTrackIsoForEgammaSC,
bool  applyCrackCorrections = false,
bool  usePFSCEleCalib = true,
bool  useEGElectrons = false,
bool  useEGammaSupercluster = true 
)

Definition at line 98 of file PFAlgo.cc.

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

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

Definition at line 64 of file PFAlgo.h.

References pfmu_.

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

Definition at line 301 of file PFAlgo.cc.

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

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

Definition at line 160 of file PFAlgo.cc.

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

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

Definition at line 288 of file PFAlgo.cc.

References pfpho_, and PFPhotonAlgo::setGBRForest().

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

Definition at line 371 of file PFAlgo.cc.

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

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

Definition at line 3770 of file PFAlgo.cc.

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

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