00001
00002
00003
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
00035
00036
00037
00038
00039
00040
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
00048 edm::ESHandle<CaloGeometry> geometry;
00049 c.get<CaloGeometryRecord>().get(geometry);
00050 const CaloSubdetectorGeometry* towerGeometry =
00051 geometry->getSubdetectorGeometry(DetId::Calo, CaloTowerDetId::SubdetId);
00052
00053
00054 reco::CaloJet::Specific specific;
00055 makeSpecific (constituents, *towerGeometry, &specific);
00056
00057 jet = reco::CaloJet( p4, point, specific, constituents);
00058 }
00059
00060
00061
00062
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
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
00081 reco::GenJet::Specific specific;
00082 makeSpecific (constituents, &specific);
00083
00084 jet = reco::GenJet( p4, point, specific, constituents);
00085 }
00086
00087
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
00095 reco::PFJet::Specific specific;
00096 makeSpecific (constituents, &specific);
00097
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
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
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
00139
00140
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
00163 eECal_i.push_back(tower->emEnergy());
00164 eInEm += tower->emEnergy();
00165
00166 eHCal_i.push_back(tower->hadEnergy());
00167 eInHad += tower->hadEnergy();
00168
00169
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
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 {
00220 caloJetSpecific->mEnergyFractionHadronic = 1.;
00221 caloJetSpecific->mEnergyFractionEm = 0.;
00222 }
00223 caloJetSpecific->mTowersArea = jetArea;
00224 caloJetSpecific->mMaxEInEmTowers = 0;
00225 caloJetSpecific->mMaxEInHadTowers = 0;
00226
00227
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
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
00248
00249
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:
00282 chargedHadronEnergy += pfCand->energy();
00283 chargedHadronMultiplicity++;
00284 chargedMultiplicity++;
00285 break;
00286
00287 case PFCandidate::h0 :
00288 neutralHadronEnergy += pfCand->energy();
00289 neutralHadronMultiplicity++;
00290 neutralMultiplicity++;
00291 break;
00292
00293 case PFCandidate::gamma:
00294 photonEnergy += pfCand->energy();
00295 photonMultiplicity++;
00296 neutralEmEnergy += pfCand->energy();
00297 neutralMultiplicity++;
00298 break;
00299
00300 case PFCandidate::e:
00301 electronEnergy += pfCand->energy();
00302 electronMultiplicity++;
00303 chargedEmEnergy += pfCand->energy();
00304 chargedMultiplicity++;
00305 break;
00306
00307 case PFCandidate::mu:
00308 muonEnergy += pfCand->energy();
00309 muonMultiplicity++;
00310 chargedMuEnergy += pfCand->energy();
00311 chargedMultiplicity++;
00312 break;
00313
00314 case PFCandidate::h_HF :
00315 HFHadronEnergy += pfCand->energy();
00316 HFHadronMultiplicity++;
00317 neutralMultiplicity++;
00318 break;
00319
00320 case PFCandidate::egamma_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:
00385 case 11:
00386 genJetSpecific->m_EmEnergy += e;
00387 break;
00388 case 211:
00389 case 321:
00390 case 130:
00391 case 2212:
00392 case 2112:
00393 genJetSpecific->m_HadEnergy += e;
00394 break;
00395 case 13:
00396 case 12:
00397 case 14:
00398 case 16:
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