00001
00002
00003
00004 #include <sstream>
00005 #include <typeinfo>
00006
00007 #include "FWCore/Utilities/interface/Exception.h"
00008 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00009 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
00010
00011
00012 #include "DataFormats/JetReco/interface/PFJet.h"
00013
00014 using namespace reco;
00015
00016 PFJet::PFJet (const LorentzVector& fP4, const Point& fVertex,
00017 const Specific& fSpecific,
00018 const Jet::Constituents& fConstituents)
00019 : Jet (fP4, fVertex, fConstituents),
00020 m_specific (fSpecific)
00021 {}
00022
00023 PFJet::PFJet (const LorentzVector& fP4, const Point& fVertex,
00024 const Specific& fSpecific)
00025 : Jet (fP4, fVertex),
00026 m_specific (fSpecific)
00027 {}
00028
00029 PFJet::PFJet (const LorentzVector& fP4,
00030 const Specific& fSpecific,
00031 const Jet::Constituents& fConstituents)
00032 : Jet (fP4, Point(0,0,0), fConstituents),
00033 m_specific (fSpecific)
00034 {}
00035
00036 const reco::PFCandidate* PFJet::getPFCandidate (const reco::Candidate* fConstituent) {
00037 if (!fConstituent) return 0;
00038 const reco::Candidate* base = fConstituent;
00039 if (fConstituent->hasMasterClone ()) base = fConstituent->masterClone().get();
00040 if (!base) return 0;
00041 const PFCandidate* candidate = dynamic_cast <const PFCandidate*> (base);
00042 if (!candidate) {
00043 throw cms::Exception("Invalid Constituent") << "PFJet constituent is not of PFCandidate type."
00044 << "Actual type is " << typeid (*base).name();
00045 }
00046 return candidate;
00047 }
00048
00049 const reco::PFCandidate* PFJet::getPFConstituent (unsigned fIndex) const {
00050 return getPFCandidate (daughter (fIndex));
00051 }
00052
00053 std::vector <const reco::PFCandidate*> PFJet::getPFConstituents () const {
00054 std::vector <const reco::PFCandidate*> result;
00055 for (unsigned i = 0; i < numberOfDaughters (); i++) result.push_back (getPFConstituent (i));
00056 return result;
00057 }
00058
00059
00060 reco::TrackRefVector PFJet::getTrackRefs() const {
00061
00062 reco::TrackRefVector result;
00063 result.reserve( chargedMultiplicity() );
00064 for (unsigned i = 0; i < numberOfDaughters (); i++) {
00065 const reco::PFCandidate* pfcand = getPFConstituent (i);
00066 reco::TrackRef trackref = pfcand->trackRef();
00067 if( trackref.isNonnull() ) {
00068 result.push_back( trackref );
00069 }
00070 }
00071
00072 return result;
00073 }
00074
00075
00076 PFJet* PFJet::clone () const {
00077 return new PFJet (*this);
00078 }
00079
00080 bool PFJet::overlap( const Candidate & ) const {
00081 return false;
00082 }
00083
00084 std::string PFJet::print () const {
00085 std::ostringstream out;
00086 out << Jet::print ()
00087 << " PFJet specific:" << std::endl
00088 << " charged/neutral hadrons energy: " << chargedHadronEnergy () << '/' << neutralHadronEnergy () << std::endl
00089 << " charged/neutral em energy: " << chargedEmEnergy () << '/' << neutralEmEnergy () << std::endl
00090 << " charged muon energy: " << chargedMuEnergy () << '/' << std::endl
00091 << " charged/neutral multiplicity: " << chargedMultiplicity () << '/' << neutralMultiplicity () << std::endl;
00092 out << " PFCandidate constituents:" << std::endl;
00093 std::vector <const PFCandidate*> constituents = getPFConstituents ();
00094 for (unsigned i = 0; i < constituents.size (); ++i) {
00095 if (constituents[i]) {
00096 out << " #" << i << " " << *(constituents[i]) << std::endl;
00097 }
00098 else {
00099 out << " #" << i << " PFCandidate is not available in the event" << std::endl;
00100 }
00101 }
00102 return out.str ();
00103 }
00104
00105 std::ostream& reco::operator<<(std::ostream& out, const reco::PFJet& jet) {
00106
00107 if(!out ) return out;
00108 out<<"PFJet "
00109 <<"(pt, eta, phi) = "<<jet.pt()<<","<<jet.eta()<<","<<jet.phi()
00110 <<" (CHEF,NHEF,GEF) = "
00111 <<jet.chargedHadronEnergyFraction()<<","
00112 <<jet.neutralHadronEnergyFraction()<<","
00113 <<jet.neutralEmEnergyFraction();
00114 return out;
00115 }