00001 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00002 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
00003
00004 #include "DataFormats/MuonReco/interface/Muon.h"
00005
00006 #include "FWCore/Utilities/interface/Exception.h"
00007
00008
00009 #include <iomanip>
00010
00011 using namespace reco;
00012 using namespace std;
00013
00014
00015
00016 const float PFCandidate::bigMva_ = 999;
00017
00018 PFCandidate::PFCandidate() :
00019 particleId_( X ),
00020 ecalEnergy_(-1),
00021 hcalEnergy_(-1),
00022 rawEcalEnergy_(-1),
00023 rawHcalEnergy_(-1),
00024 ps1Energy_(-1),
00025 ps2Energy_(-1),
00026 flags_(0),
00027 deltaP_(-1),
00028 mva_e_pi_(-PFCandidate::bigMva_),
00029 mva_e_mu_(-PFCandidate::bigMva_),
00030 mva_pi_mu_(-PFCandidate::bigMva_),
00031 mva_nothing_gamma_(-PFCandidate::bigMva_),
00032 mva_nothing_nh_(-PFCandidate::bigMva_),
00033 mva_gamma_nh_(-PFCandidate::bigMva_) {
00034
00035 setPdgId( translateTypeToPdgId( particleId_ ) );
00036 }
00037
00038
00039 PFCandidate::PFCandidate( const PFCandidatePtr& sourcePtr ) {
00040 *this = *sourcePtr;
00041 sourcePtr_ = sourcePtr;
00042 }
00043
00044
00045 PFCandidate::PFCandidate( Charge charge,
00046 const LorentzVector & p4,
00047 ParticleType particleId ) :
00048
00049 CompositeCandidate(charge, p4),
00050 particleId_(particleId),
00051
00052 ecalEnergy_(0),
00053 hcalEnergy_(0),
00054 rawEcalEnergy_(0),
00055 rawHcalEnergy_(0),
00056 ps1Energy_(-1),
00057 ps2Energy_(-1),
00058 flags_(0),
00059 deltaP_(-1),
00060 mva_e_pi_(-PFCandidate::bigMva_),
00061 mva_e_mu_(-PFCandidate::bigMva_),
00062 mva_pi_mu_(-PFCandidate::bigMva_),
00063 mva_nothing_gamma_(-PFCandidate::bigMva_),
00064 mva_nothing_nh_(-PFCandidate::bigMva_),
00065 mva_gamma_nh_(-PFCandidate::bigMva_)
00066
00067
00068 {
00069
00070
00071
00072
00073 if( particleId_ == h ||
00074 particleId_ == e ||
00075 particleId_ == mu ) {
00076
00077 if( charge == 0 ) {
00078 string err;
00079 err+="Attempt to construct a charged PFCandidate with a zero charge";
00080 throw cms::Exception("InconsistentValue",
00081 err.c_str() );
00082 }
00083 }
00084 else {
00085 if( charge ) {
00086 string err;
00087 err += "Attempt to construct a neutral PFCandidate ";
00088 err += "with a non-zero charge";
00089 throw cms::Exception("InconsistentValue",
00090 err.c_str() );
00091 }
00092 }
00093 setPdgId( translateTypeToPdgId( particleId_ ) );
00094 }
00095
00096
00097
00098 PFCandidate * PFCandidate::clone() const {
00099 return new PFCandidate( * this );
00100 }
00101
00102
00103 void PFCandidate::addElementInBlock( const reco::PFBlockRef& blockref,
00104 unsigned elementIndex ) {
00105 elementsInBlocks_.push_back( make_pair(blockref, elementIndex) );
00106 }
00107
00108
00109 int PFCandidate::translateTypeToPdgId( ParticleType type ) const {
00110
00111 int thecharge = charge();
00112
00113 switch( type ) {
00114 case h: return thecharge*211;
00115 case e: return thecharge*11;
00116 case mu: return thecharge*13;
00117 case gamma: return 22;
00118 case h0: return 130;
00119 case h_HF: return 999211;
00120 case egamma_HF: return 99922;
00121 case X:
00122 default: return 0;
00123 }
00124 }
00125
00126
00127 void PFCandidate::setParticleType( ParticleType type ) {
00128 particleId_ = type;
00129 setPdgId( translateTypeToPdgId( type ) );
00130 }
00131
00132
00133 void PFCandidate::setTrackRef(const reco::TrackRef& ref) {
00134 if(!charge()) {
00135 string err;
00136 err += "PFCandidate::setTrackRef: this is a neutral candidate! ";
00137 err += "particleId_=";
00138 char num[4];
00139 sprintf( num, "%d", particleId_);
00140 err += num;
00141
00142 throw cms::Exception("InconsistentReference",
00143 err.c_str() );
00144 }
00145
00146 trackRef_ = ref;
00147 }
00148
00149 void PFCandidate::setGsfTrackRef(const reco::GsfTrackRef& ref) {
00150 if( particleId_ != e ) {
00151 string err;
00152 err += "PFCandidate::setGsfTrackRef: this is not an electron ! particleId_=";
00153 char num[4];
00154 sprintf( num, "%d", particleId_);
00155 err += num;
00156
00157 throw cms::Exception("InconsistentReference",
00158 err.c_str() );
00159 }
00160 gsfTrackRef_ = ref;
00161 }
00162
00163 void PFCandidate::setMuonRef(const reco::MuonRef& ref) {
00164
00165 if( trackRef_ != ref->track() ) {
00166 string err;
00167 err += "PFCandidate::setMuonRef: inconsistent track references!";
00168
00169 throw cms::Exception("InconsistentReference",
00170 err.c_str() );
00171 }
00172
00173 muonRef_ = ref;
00174 }
00175
00176 void PFCandidate::setConversionRef(const reco::ConversionRef& ref) {
00177
00178 if( particleId_ != gamma ) {
00179 string err;
00180 err += "PFCandidate::setConversionRef: this is not a (converted) photon ! particleId_=";
00181 char num[4];
00182 sprintf( num, "%d", particleId_);
00183 err += num;
00184
00185 throw cms::Exception("InconsistentReference",
00186 err.c_str() );
00187 }
00188 else if( !flag( GAMMA_TO_GAMMACONV ) ) {
00189 string err;
00190 err += "PFCandidate::setConversionRef: particule flag is not GAMMA_TO_GAMMACONV";
00191
00192 throw cms::Exception("InconsistentReference",
00193 err.c_str() );
00194 }
00195
00196 conversionRef_ = ref;
00197 }
00198
00199
00200
00201 void PFCandidate::setNuclearRef(const reco::NuclearInteractionRef& ref) {
00202
00203 if( particleId_ != h ) {
00204 string err;
00205 err += "PFCandidate::setNuclearRef: this is not a hadron! particleId_=";
00206 char num[4];
00207 sprintf( num, "%d", particleId_);
00208 err += num;
00209
00210 throw cms::Exception("InconsistentReference",
00211 err.c_str() );
00212 }
00213 else if( !flag( T_FROM_NUCLINT ) && !flag( T_TO_NUCLINT ) ) {
00214 string err;
00215 err += "PFCandidate::setNuclearRef: particule flag is neither T_FROM_NUCLINT nor T_TO_NUCLINT";
00216
00217 throw cms::Exception("InconsistentReference",
00218 err.c_str() );
00219 }
00220
00221 nuclearRef_ = ref;
00222 }
00223
00224
00225 void PFCandidate::rescaleMomentum( double rescaleFactor ) {
00226 LorentzVector rescaledp4 = p4();
00227 rescaledp4 *= rescaleFactor;
00228 setP4( rescaledp4 );
00229 }
00230
00231
00232 void PFCandidate::setFlag(Flags theFlag, bool value) {
00233
00234 if(value)
00235 flags_ = flags_ | (1<<theFlag);
00236 else
00237 flags_ = flags_ ^ (1<<theFlag);
00238 }
00239
00240
00241
00242 bool PFCandidate::flag(Flags theFlag) const {
00243
00244 return (flags_>>theFlag) & 1;
00245 }
00246
00247
00248
00249
00250 ostream& reco::operator<<(ostream& out,
00251 const PFCandidate& c ) {
00252
00253 if(!out) return out;
00254
00255 out<<"\tPFCandidate type: "<<c.particleId();
00256 out<<setiosflags(ios::right);
00257 out<<setiosflags(ios::fixed);
00258 out<<setprecision(3);
00259 out<<" E/pT/eta/phi "
00260 <<c.energy()<<"/"
00261 <<c.pt()<<"/"
00262 <<c.eta()<<"/"
00263 <<c.phi();
00264 if( c.flag( PFCandidate::T_FROM_NUCLINT ) ) out<<", T_FROM_NUCL" << endl;
00265 else if( c.flag( PFCandidate::T_TO_NUCLINT ) ) out<<", T_TO_NUCL" << endl;
00266 else if( c.flag( PFCandidate::T_FROM_GAMMACONV ) ) out<<", T_FROM_GAMMACONV" << endl;
00267 else if( c.flag( PFCandidate::GAMMA_TO_GAMMACONV ) ) out<<", GAMMA_TO_GAMMACONV" << endl;
00268
00269 out<<", blocks/iele: ";
00270
00271 PFCandidate::ElementsInBlocks eleInBlocks = c.elementsInBlocks();
00272 for(unsigned i=0; i<eleInBlocks.size(); i++) {
00273 PFBlockRef blockRef = eleInBlocks[i].first;
00274 unsigned indexInBlock = eleInBlocks[i].second;
00275
00276 out<<"("<<blockRef.key()<<"|"<<indexInBlock<<"), ";
00277 }
00278
00279 out<<" source:"<<c.sourcePtr_.id()<<"/"<<c.sourcePtr_.key();
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 out<<resetiosflags(ios::right|ios::fixed);
00294 return out;
00295 }