00001 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00002
00003
00004 #include "DataFormats/MuonReco/interface/Muon.h"
00005
00006 #include "FWCore/Utilities/interface/Exception.h"
00007
00008 #include <ostream>
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
00074 if( particleId_ == h ||
00075 particleId_ == e ||
00076 particleId_ == mu ) {
00077
00078 if( charge == 0 ) {
00079 string err;
00080 err+="Attempt to construct a charged PFCandidate with a zero charge";
00081 throw cms::Exception("InconsistentValue",
00082 err.c_str() );
00083 }
00084 }
00085 else {
00086 if( charge ) {
00087 string err;
00088 err += "Attempt to construct a neutral PFCandidate ";
00089 err += "with a non-zero charge";
00090 throw cms::Exception("InconsistentValue",
00091 err.c_str() );
00092 }
00093 }
00094 setPdgId( translateTypeToPdgId( particleId_ ) );
00095 }
00096
00097
00098
00099 PFCandidate * PFCandidate::clone() const {
00100 return new PFCandidate( * this );
00101 }
00102
00103
00104 void PFCandidate::addElementInBlock( const reco::PFBlockRef& blockref,
00105 unsigned elementIndex ) {
00106 elementsInBlocks_.push_back( make_pair(blockref, elementIndex) );
00107 }
00108
00109
00110 int PFCandidate::translateTypeToPdgId( ParticleType type ) const {
00111
00112 int thecharge = charge();
00113
00114 switch( type ) {
00115 case h: return thecharge*211;
00116 case e: return thecharge*(-11);
00117 case mu: return thecharge*(-13);
00118 case gamma: return 22;
00119 case h0: return 130;
00120 case h_HF: return 130;
00121 case egamma_HF: return 22;
00122 case X:
00123 default: return 0;
00124 }
00125 }
00126
00127
00128 void PFCandidate::setParticleType( ParticleType type ) {
00129 particleId_ = type;
00130 setPdgId( translateTypeToPdgId( type ) );
00131 }
00132
00133
00134 void PFCandidate::setTrackRef(const reco::TrackRef& ref) {
00135 if(!charge()) {
00136 string err;
00137 err += "PFCandidate::setTrackRef: this is a neutral candidate! ";
00138 err += "particleId_=";
00139 char num[4];
00140 sprintf( num, "%d", particleId_);
00141 err += num;
00142
00143 throw cms::Exception("InconsistentReference",
00144 err.c_str() );
00145 }
00146
00147 trackRef_ = ref;
00148 }
00149
00150 void PFCandidate::setGsfTrackRef(const reco::GsfTrackRef& ref) {
00151 if( particleId_ != e ) {
00152 string err;
00153 err += "PFCandidate::setGsfTrackRef: this is not an electron ! particleId_=";
00154 char num[4];
00155 sprintf( num, "%d", particleId_);
00156 err += num;
00157
00158 throw cms::Exception("InconsistentReference",
00159 err.c_str() );
00160 }
00161 gsfTrackRef_ = ref;
00162 }
00163
00164 void PFCandidate::setMuonRef(const reco::MuonRef& ref) {
00165
00166 if( trackRef_ != ref->track() ) {
00167 string err;
00168 err += "PFCandidate::setMuonRef: inconsistent track references!";
00169
00170 throw cms::Exception("InconsistentReference",
00171 err.c_str() );
00172 }
00173
00174 muonRef_ = ref;
00175 }
00176
00177 void PFCandidate::setConversionRef(const reco::ConversionRef& ref) {
00178
00179 if( particleId_ != gamma ) {
00180 string err;
00181 err += "PFCandidate::setConversionRef: this is not a (converted) photon ! particleId_=";
00182 char num[4];
00183 sprintf( num, "%d", particleId_);
00184 err += num;
00185
00186 throw cms::Exception("InconsistentReference",
00187 err.c_str() );
00188 }
00189 else if( !flag( GAMMA_TO_GAMMACONV ) ) {
00190 string err;
00191 err += "PFCandidate::setConversionRef: particule flag is not GAMMA_TO_GAMMACONV";
00192
00193 throw cms::Exception("InconsistentReference",
00194 err.c_str() );
00195 }
00196
00197 conversionRef_ = ref;
00198 }
00199
00200
00201
00202 void PFCandidate::setDisplacedVertexRef(const reco::PFDisplacedVertexRef& ref, Flags type) {
00203
00204 if( particleId_ != h ) {
00205 string err;
00206 err += "PFCandidate::setDisplacedVertexRef: this is not a hadron! particleId_=";
00207 char num[4];
00208 sprintf( num, "%d", particleId_);
00209 err += num;
00210
00211 throw cms::Exception("InconsistentReference",
00212 err.c_str() );
00213 }
00214 else if( !flag( T_FROM_DISP ) && !flag( T_TO_DISP ) ) {
00215 string err;
00216 err += "PFCandidate::setDisplacedVertexRef: particule flag is neither T_FROM_DISP nor T_TO_DISP";
00217
00218 throw cms::Exception("InconsistentReference",
00219 err.c_str() );
00220 }
00221
00222 if (type == T_TO_DISP && flag( T_TO_DISP )) displacedVertexDaughterRef_ = ref;
00223 else if (type == T_FROM_DISP && flag( T_FROM_DISP )) displacedVertexMotherRef_ = ref;
00224 else if ( (type == T_FROM_DISP && !flag( T_FROM_DISP ))
00225 ||
00226 (type == T_TO_DISP && !flag( T_TO_DISP )) ){
00227 string err;
00228 err += "PFCandidate::setDisplacedVertexRef: particule flag is not switched on";
00229
00230 throw cms::Exception("InconsistentReference",
00231 err.c_str() );
00232 }
00233
00234 }
00235
00236
00237 void PFCandidate::setV0Ref(const reco::VertexCompositeCandidateRef& ref) {
00238
00239 v0Ref_ = ref;
00240
00241 }
00242
00243 bool PFCandidate::overlap(const reco::Candidate & other) const {
00244 CandidatePtr myPtr = sourceCandidatePtr(0);
00245 if (myPtr.isNull()) return false;
00246 for (size_t i = 0, n = other.numberOfSourceCandidatePtrs(); i < n; ++i) {
00247 CandidatePtr otherPtr = other.sourceCandidatePtr(i);
00248 if ((otherPtr == myPtr) ||
00249 (sourcePtr_.isNonnull() && otherPtr.isNonnull() && sourcePtr_->overlap(*otherPtr))) {
00250 return true;
00251 }
00252 }
00253 return false;
00254 }
00255
00256
00257
00258
00259
00260 void PFCandidate::rescaleMomentum( double rescaleFactor ) {
00261 LorentzVector rescaledp4 = p4();
00262 rescaledp4 *= rescaleFactor;
00263 setP4( rescaledp4 );
00264 }
00265
00266
00267 void PFCandidate::setFlag(Flags theFlag, bool value) {
00268
00269 if(value)
00270 flags_ = flags_ | (1<<theFlag);
00271 else
00272 flags_ = flags_ ^ (1<<theFlag);
00273 }
00274
00275
00276
00277 bool PFCandidate::flag(Flags theFlag) const {
00278
00279 return (flags_>>theFlag) & 1;
00280 }
00281
00282
00283
00284
00285 ostream& reco::operator<<(ostream& out,
00286 const PFCandidate& c ) {
00287
00288 if(!out) return out;
00289
00290 out<<"\tPFCandidate type: "<<c.particleId();
00291 out<<setiosflags(ios::right);
00292 out<<setiosflags(ios::fixed);
00293 out<<setprecision(3);
00294 out<<" E/pT/eta/phi "
00295 <<c.energy()<<"/"
00296 <<c.pt()<<"/"
00297 <<c.eta()<<"/"
00298 <<c.phi();
00299 if( c.flag( PFCandidate::T_FROM_DISP ) ) out<<", T_FROM_DISP" << endl;
00300 else if( c.flag( PFCandidate::T_TO_DISP ) ) out<<", T_TO_DISP" << endl;
00301 else if( c.flag( PFCandidate::T_FROM_GAMMACONV ) ) out<<", T_FROM_GAMMACONV" << endl;
00302 else if( c.flag( PFCandidate::GAMMA_TO_GAMMACONV ) ) out<<", GAMMA_TO_GAMMACONV" << endl;
00303
00304 out<<", blocks/iele: ";
00305
00306 PFCandidate::ElementsInBlocks eleInBlocks = c.elementsInBlocks();
00307 for(unsigned i=0; i<eleInBlocks.size(); i++) {
00308 PFBlockRef blockRef = eleInBlocks[i].first;
00309 unsigned indexInBlock = eleInBlocks[i].second;
00310
00311 out<<"("<<blockRef.key()<<"|"<<indexInBlock<<"), ";
00312 }
00313
00314 out<<" source:"<<c.sourcePtr_.id()<<"/"<<c.sourcePtr_.key();
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 out<<resetiosflags(ios::right|ios::fixed);
00329 return out;
00330 }