CMS 3D CMS Logo

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