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 edm::ESHandle<HcalTopology> topology;
00054 c.get<IdealGeometryRecord>().get(topology);
00055
00056
00057 reco::CaloJet::Specific specific;
00058 makeSpecific (constituents, *towerGeometry, &specific, *topology);
00059
00060 jet = reco::CaloJet( p4, point, specific, constituents);
00061 }
00062
00063
00064
00065
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
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
00084 reco::GenJet::Specific specific;
00085 makeSpecific (constituents, &specific);
00086
00087 jet = reco::GenJet( p4, point, specific, constituents);
00088 }
00089
00090
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
00098 reco::PFJet::Specific specific;
00099 makeSpecific (constituents, &specific);
00100
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
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
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
00143
00144
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
00167 eECal_i.push_back(tower->emEnergy());
00168 eInEm += tower->emEnergy();
00169
00170 eHCal_i.push_back(tower->hadEnergy());
00171 eInHad += tower->hadEnergy();
00172
00173
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
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 {
00224 caloJetSpecific->mEnergyFractionHadronic = 1.;
00225 caloJetSpecific->mEnergyFractionEm = 0.;
00226 }
00227 caloJetSpecific->mTowersArea = jetArea;
00228 caloJetSpecific->mMaxEInEmTowers = 0;
00229 caloJetSpecific->mMaxEInHadTowers = 0;
00230
00231
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
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
00252
00253
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:
00286 chargedHadronEnergy += pfCand->energy();
00287 chargedHadronMultiplicity++;
00288 chargedMultiplicity++;
00289 break;
00290
00291 case PFCandidate::h0 :
00292 neutralHadronEnergy += pfCand->energy();
00293 neutralHadronMultiplicity++;
00294 neutralMultiplicity++;
00295 break;
00296
00297 case PFCandidate::gamma:
00298 photonEnergy += pfCand->energy();
00299 photonMultiplicity++;
00300 neutralEmEnergy += pfCand->energy();
00301 neutralMultiplicity++;
00302 break;
00303
00304 case PFCandidate::e:
00305 electronEnergy += pfCand->energy();
00306 electronMultiplicity++;
00307 chargedEmEnergy += pfCand->energy();
00308 chargedMultiplicity++;
00309 break;
00310
00311 case PFCandidate::mu:
00312 muonEnergy += pfCand->energy();
00313 muonMultiplicity++;
00314 chargedMuEnergy += pfCand->energy();
00315 chargedMultiplicity++;
00316 break;
00317
00318 case PFCandidate::h_HF :
00319 HFHadronEnergy += pfCand->energy();
00320 HFHadronMultiplicity++;
00321 neutralMultiplicity++;
00322 break;
00323
00324 case PFCandidate::egamma_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:
00389 case 11:
00390 genJetSpecific->m_EmEnergy += e;
00391 break;
00392 case 211:
00393 case 321:
00394 case 130:
00395 case 2212:
00396 case 2112:
00397 genJetSpecific->m_HadEnergy += e;
00398 break;
00399 case 13:
00400 case 12:
00401 case 14:
00402 case 16:
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