CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/RecoJets/JetProducers/src/JetSpecific.cc

Go to the documentation of this file.
00001 
00002 //
00003 // JetSpecific
00004 // -----------
00005 //
00007 
00008 
00009 #include "RecoJets/JetProducers/interface/JetSpecific.h"
00010 
00011 
00012 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00013 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00014 #include "DataFormats/CaloTowers/interface/CaloTowerDetId.h"
00015 #include "DataFormats/RecoCandidate/interface/RecoCaloTowerCandidate.h"
00016 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
00017 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00018 #include "Geometry/CaloTopology/interface/HcalTopology.h"
00019 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00020 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022 #include "FWCore/Framework/interface/ESHandle.h"
00023 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00024 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00025 
00026 #include <cmath>
00027 
00028 
00029 using namespace std;
00030 
00031 
00033 // implementation of global functions
00035 
00036 //______________________________________________________________________________    
00037 // Overloaded methods to write out specific types
00038 
00039 
00040 // CaloJet
00041 void reco::writeSpecific(reco::CaloJet & jet,
00042                          reco::Particle::LorentzVector const & p4,
00043                          reco::Particle::Point const & point, 
00044                          std::vector<reco::CandidatePtr> const & constituents,
00045                          edm::EventSetup const & c  )
00046 {
00047   // Get geometry
00048   edm::ESHandle<CaloGeometry> geometry;
00049   c.get<CaloGeometryRecord>().get(geometry);
00050   const CaloSubdetectorGeometry* towerGeometry = 
00051     geometry->getSubdetectorGeometry(DetId::Calo, CaloTowerDetId::SubdetId);
00052 
00053   // Make the specific
00054   reco::CaloJet::Specific specific;
00055   makeSpecific (constituents, *towerGeometry, &specific);
00056   // Set the calo jet
00057   jet = reco::CaloJet( p4, point, specific, constituents);  
00058 }
00059   
00060 
00061     
00062 // BasicJet
00063 void reco::writeSpecific(reco::BasicJet  & jet,
00064                          reco::Particle::LorentzVector const & p4,
00065                          reco::Particle::Point const & point, 
00066                          std::vector<reco::CandidatePtr> const & constituents,
00067                          edm::EventSetup const & c  )
00068 {
00069   jet = reco::BasicJet( p4, point, constituents);  
00070 }
00071     
00072 // GenJet
00073 void reco::writeSpecific(reco::GenJet  & jet,
00074                          reco::Particle::LorentzVector const & p4,
00075                          reco::Particle::Point const & point, 
00076                          std::vector<reco::CandidatePtr> const & constituents,
00077                          edm::EventSetup const & c  )
00078 {
00079 
00080   // Make the specific
00081   reco::GenJet::Specific specific;
00082   makeSpecific (constituents, &specific);
00083   // Set to the jet
00084   jet = reco::GenJet( p4, point, specific, constituents);  
00085 }
00086     
00087 // PFJet
00088 void reco::writeSpecific(reco::PFJet  & jet,
00089                          reco::Particle::LorentzVector const & p4,
00090                          reco::Particle::Point const & point, 
00091                          std::vector<reco::CandidatePtr> const & constituents,
00092                          edm::EventSetup const & c  )
00093 {
00094   // Make the specific
00095   reco::PFJet::Specific specific;
00096   makeSpecific (constituents, &specific);
00097   // now make jet charge
00098   int charge = 0.;
00099   for ( std::vector<reco::CandidatePtr>::const_iterator ic = constituents.begin(),
00100           icbegin = constituents.begin(), icend = constituents.end();
00101         ic != icend; ++ic ) {
00102     charge += (*ic)->charge();
00103   }
00104   jet = reco::PFJet( p4, point, specific, constituents);  
00105   jet.setCharge( charge );
00106 }
00107     
00108 
00109 // TrackJet
00110 void reco::writeSpecific(reco::TrackJet & jet,
00111                          reco::Particle::LorentzVector const & p4,
00112                          reco::Particle::Point const & point, 
00113                          std::vector<reco::CandidatePtr> const & constituents,
00114                          edm::EventSetup const & c  )
00115 {
00116   jet = reco::TrackJet(p4, point, constituents);  
00117 }
00118     
00119 // PFClusterJet
00120 void reco::writeSpecific(reco::PFClusterJet & jet,
00121                          reco::Particle::LorentzVector const & p4,
00122                          reco::Particle::Point const & point, 
00123                          std::vector<reco::CandidatePtr> const & constituents,
00124                          edm::EventSetup const & c  )
00125 {
00126   jet = reco::PFClusterJet( p4, point, constituents);  
00127 }
00128   
00129 
00130 
00131 //______________________________________________________________________________
00132 bool reco::makeSpecific(vector<reco::CandidatePtr> const & towers,
00133                         const CaloSubdetectorGeometry& towerGeometry,
00134                         CaloJet::Specific* caloJetSpecific)
00135 {
00136   if (0==caloJetSpecific) return false;
00137 
00138   // 1.- Loop over the tower Ids, 
00139   // 2.- Get the corresponding CaloTower
00140   // 3.- Calculate the different CaloJet specific quantities
00141   vector<double> eECal_i;
00142   vector<double> eHCal_i;
00143   double eInHad = 0.;
00144   double eInEm = 0.;
00145   double eInHO = 0.;
00146   double eInHB = 0.;
00147   double eInHE = 0.;
00148   double eHadInHF = 0.;
00149   double eEmInHF = 0.;
00150   double eInEB = 0.;
00151   double eInEE = 0.;
00152   double jetArea = 0.;
00153   
00154   vector<reco::CandidatePtr>::const_iterator itTower;
00155   for (itTower=towers.begin();itTower!=towers.end();++itTower) {
00156     if ( itTower->isNull() || !itTower->isAvailable() ) { 
00157       edm::LogWarning("DataNotFound") << " JetSpecific: Tower is invalid\n";
00158       continue;
00159     }
00160     const CaloTower* tower = dynamic_cast<const CaloTower*>(itTower->get());
00161     if (tower) {
00162       //Array of energy in EM Towers:
00163       eECal_i.push_back(tower->emEnergy());
00164       eInEm += tower->emEnergy();
00165       //Array of energy in HCAL Towers:
00166       eHCal_i.push_back(tower->hadEnergy()); 
00167       eInHad += tower->hadEnergy();
00168       
00169       //  figure out contributions
00170       switch (reco::hcalSubdetector(tower->id().ieta())) {
00171       case HcalBarrel:
00172         eInHB += tower->hadEnergy(); 
00173         eInHO += tower->outerEnergy();
00174         eInEB += tower->emEnergy();
00175         break;
00176       case HcalEndcap:
00177         eInHE += tower->hadEnergy();
00178         eInEE += tower->emEnergy();
00179         break;
00180       case HcalForward:
00181         eHadInHF += tower->hadEnergy();
00182         eEmInHF += tower->emEnergy();
00183         break;
00184       default:
00185         break;
00186       }
00187       // get area of the tower (++ minus --)
00188       const CaloCellGeometry* geometry = towerGeometry.getGeometry(tower->id());
00189       if (geometry) {
00190         float dEta = fabs(geometry->getCorners()[0].eta()-
00191                           geometry->getCorners()[2].eta());
00192         float dPhi = fabs(geometry->getCorners()[0].phi() -
00193                           geometry->getCorners()[2].phi());
00194         jetArea += dEta * dPhi;
00195       }
00196       else {
00197         edm::LogWarning("DataNotFound") <<"reco::makeCaloJetSpecific: Geometry for cell "
00198                                         <<tower->id()<<" can not be found. Ignoring cell\n";
00199       }
00200     }
00201     else {
00202       edm::LogWarning("DataNotFound")<<"reco::makeCaloJetSpecific: Constituent is not of "
00203                                      <<"CaloTower type\n";
00204     }
00205   }
00206 
00207   double towerEnergy = eInHad + eInEm;
00208   caloJetSpecific->mHadEnergyInHO = eInHO;
00209   caloJetSpecific->mHadEnergyInHB = eInHB;
00210   caloJetSpecific->mHadEnergyInHE = eInHE;
00211   caloJetSpecific->mHadEnergyInHF = eHadInHF;
00212   caloJetSpecific->mEmEnergyInHF = eEmInHF;
00213   caloJetSpecific->mEmEnergyInEB = eInEB;
00214   caloJetSpecific->mEmEnergyInEE = eInEE;
00215   if (towerEnergy > 0) {
00216     caloJetSpecific->mEnergyFractionHadronic = eInHad / towerEnergy;
00217     caloJetSpecific->mEnergyFractionEm = eInEm / towerEnergy;
00218   }
00219   else { // HO only jet
00220     caloJetSpecific->mEnergyFractionHadronic = 1.;
00221     caloJetSpecific->mEnergyFractionEm = 0.;
00222   }
00223   caloJetSpecific->mTowersArea = jetArea;
00224   caloJetSpecific->mMaxEInEmTowers = 0;
00225   caloJetSpecific->mMaxEInHadTowers = 0;
00226   
00227   //Sort the arrays
00228   sort(eECal_i.begin(), eECal_i.end(), greater<double>());
00229   sort(eHCal_i.begin(), eHCal_i.end(), greater<double>());
00230   
00231   if (!towers.empty()) {
00232     //Highest value in the array is the first element of the array
00233     caloJetSpecific->mMaxEInEmTowers  = eECal_i.front(); 
00234     caloJetSpecific->mMaxEInHadTowers = eHCal_i.front();
00235   }
00236   
00237   return true;
00238 }
00239 
00240 
00241 //______________________________________________________________________________
00242 bool reco::makeSpecific(vector<reco::CandidatePtr> const & particles,      
00243                         PFJet::Specific* pfJetSpecific)
00244 {
00245   if (0==pfJetSpecific) return false;
00246   
00247   // 1.- Loop over PFCandidates, 
00248   // 2.- Get the corresponding PFCandidate
00249   // 3.- Calculate the different PFJet specific quantities
00250   
00251   float chargedHadronEnergy=0.;
00252   float neutralHadronEnergy=0.;
00253   float photonEnergy=0.;
00254   float electronEnergy=0.;
00255   float muonEnergy=0.;
00256   float HFHadronEnergy=0.;
00257   float HFEMEnergy=0.;
00258   int   chargedHadronMultiplicity=0;
00259   int   neutralHadronMultiplicity=0;
00260   int   photonMultiplicity=0;
00261   int   electronMultiplicity=0;
00262   int   muonMultiplicity=0;
00263   int   HFHadronMultiplicity=0;
00264   int   HFEMMultiplicity=0;
00265 
00266   float chargedEmEnergy=0.;
00267   float neutralEmEnergy=0.;
00268   float chargedMuEnergy=0.;
00269   int   chargedMultiplicity=0;
00270   int   neutralMultiplicity=0;
00271   
00272   vector<reco::CandidatePtr>::const_iterator itParticle;
00273   for (itParticle=particles.begin();itParticle!=particles.end();++itParticle){
00274     if ( itParticle->isNull() || !itParticle->isAvailable() ) { 
00275       edm::LogWarning("DataNotFound") << " JetSpecific: PF Particle is invalid\n";
00276       continue;
00277     }    
00278     const PFCandidate* pfCand = dynamic_cast<const PFCandidate*> (itParticle->get());
00279     if (pfCand) {
00280       switch (PFCandidate::ParticleType(pfCand->particleId())) {
00281       case PFCandidate::h:       // charged hadron
00282         chargedHadronEnergy += pfCand->energy();
00283         chargedHadronMultiplicity++;
00284         chargedMultiplicity++;
00285         break;
00286 
00287       case PFCandidate::h0 :    // neutral hadron
00288         neutralHadronEnergy += pfCand->energy();
00289         neutralHadronMultiplicity++;
00290         neutralMultiplicity++;
00291       break;
00292 
00293       case PFCandidate::gamma:   // photon
00294         photonEnergy += pfCand->energy();
00295         photonMultiplicity++;
00296         neutralEmEnergy += pfCand->energy();
00297         neutralMultiplicity++;
00298       break;
00299 
00300       case PFCandidate::e:       // electron 
00301         electronEnergy += pfCand->energy();
00302         electronMultiplicity++;
00303         chargedEmEnergy += pfCand->energy(); 
00304         chargedMultiplicity++;
00305         break;
00306 
00307       case PFCandidate::mu:      // muon
00308         muonEnergy += pfCand->energy();
00309         muonMultiplicity++;
00310         chargedMuEnergy += pfCand->energy();
00311         chargedMultiplicity++;
00312         break;
00313 
00314       case PFCandidate::h_HF :    // hadron in HF
00315         HFHadronEnergy += pfCand->energy();
00316         HFHadronMultiplicity++;
00317         neutralMultiplicity++;
00318         break;
00319 
00320       case PFCandidate::egamma_HF :    // electromagnetic in HF
00321         HFEMEnergy += pfCand->energy();
00322         HFEMMultiplicity++;
00323         neutralEmEnergy += pfCand->energy();
00324         neutralMultiplicity++;
00325         break;
00326         
00327 
00328       default:
00329         edm::LogWarning("DataNotFound") <<"reco::makePFJetSpecific: Unknown PFCandidate::ParticleType: "
00330                                         <<pfCand->particleId()<<" is ignored\n";
00331         break;
00332       }
00333     }
00334     else {
00335       edm::LogWarning("DataNotFound") <<"reco::makePFJetSpecific: Referred constituent is not "
00336                                       <<"a PFCandidate\n";
00337     }
00338   }
00339   
00340   pfJetSpecific->mChargedHadronEnergy=chargedHadronEnergy;
00341   pfJetSpecific->mNeutralHadronEnergy= neutralHadronEnergy;
00342   pfJetSpecific->mPhotonEnergy= photonEnergy;
00343   pfJetSpecific->mElectronEnergy= electronEnergy;
00344   pfJetSpecific->mMuonEnergy= muonEnergy;
00345   pfJetSpecific->mHFHadronEnergy= HFHadronEnergy;
00346   pfJetSpecific->mHFEMEnergy= HFEMEnergy;
00347 
00348   pfJetSpecific->mChargedHadronMultiplicity=chargedHadronMultiplicity;
00349   pfJetSpecific->mNeutralHadronMultiplicity= neutralHadronMultiplicity;
00350   pfJetSpecific->mPhotonMultiplicity= photonMultiplicity;
00351   pfJetSpecific->mElectronMultiplicity= electronMultiplicity;
00352   pfJetSpecific->mMuonMultiplicity= muonMultiplicity;
00353   pfJetSpecific->mHFHadronMultiplicity= HFHadronMultiplicity;
00354   pfJetSpecific->mHFEMMultiplicity= HFEMMultiplicity;
00355 
00356   pfJetSpecific->mChargedEmEnergy=chargedEmEnergy;
00357   pfJetSpecific->mChargedMuEnergy=chargedMuEnergy;
00358   pfJetSpecific->mNeutralEmEnergy=neutralEmEnergy;
00359   pfJetSpecific->mChargedMultiplicity=chargedMultiplicity;
00360   pfJetSpecific->mNeutralMultiplicity=neutralMultiplicity;
00361 
00362   return true;
00363 }
00364 
00365 
00366 //______________________________________________________________________________
00367 bool reco::makeSpecific(vector<reco::CandidatePtr> const & mcparticles, 
00368                         GenJet::Specific* genJetSpecific)
00369 {
00370   if (0==genJetSpecific) return false;
00371 
00372   vector<reco::CandidatePtr>::const_iterator itMcParticle=mcparticles.begin();
00373   for (;itMcParticle!=mcparticles.end();++itMcParticle) {
00374     if ( itMcParticle->isNull() || !itMcParticle->isAvailable() ) { 
00375       edm::LogWarning("DataNotFound") << " JetSpecific: MC Particle is invalid\n";
00376       continue;
00377     }
00378     const Candidate* candidate = itMcParticle->get();
00379     if (candidate->hasMasterClone()) candidate = candidate->masterClone().get();
00380     const GenParticle* genParticle = GenJet::genParticle(candidate);
00381     if (genParticle) {
00382       double e = genParticle->energy();
00383       switch (abs (genParticle->pdgId ())) {
00384       case 22: // photon
00385       case 11: // e
00386         genJetSpecific->m_EmEnergy += e;
00387         break;
00388       case 211: // pi
00389       case 321: // K
00390       case 130: // KL
00391       case 2212: // p
00392       case 2112: // n
00393         genJetSpecific->m_HadEnergy += e;
00394         break;
00395       case 13: // muon
00396       case 12: // nu_e
00397       case 14: // nu_mu
00398       case 16: // nu_tau
00399         
00400         genJetSpecific->m_InvisibleEnergy += e;
00401         break;
00402       default: 
00403         genJetSpecific->m_AuxiliaryEnergy += e;
00404       }
00405     }
00406     else {
00407       edm::LogWarning("DataNotFound") <<"reco::makeGenJetSpecific: Referred  GenParticleCandidate "
00408                                       <<"is not available in the event\n";
00409     }
00410   }
00411   
00412   return true;
00413 }
00414 
00415 
00416 //______________________________________________________________________________
00417 HcalSubdetector reco::hcalSubdetector(int iEta)
00418 {
00419   static const HcalTopology topology;
00420   int eta = std::abs(iEta);
00421   if      (eta <= topology.lastHBRing()) return HcalBarrel;
00422   else if (eta <= topology.lastHERing()) return HcalEndcap;
00423   else if (eta <= topology.lastHFRing()) return HcalForward;
00424   return HcalEmpty;
00425 }
00426 
00427 
00428