CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/DataFormats/ParticleFlowCandidate/src/PFCandidate.cc

Go to the documentation of this file.
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 #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 //   blockRef_(blockRef), 
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   /*       ,elementIndices_(elementIndices)  */ 
00068 {
00069 
00070   
00071   // proceed with various consistency checks
00072 
00073   // charged candidate: track ref and charge must be non null
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; // pi+
00116   case e:     return thecharge*(-11);
00117   case mu:    return thecharge*(-13);
00118   case gamma: return 22;
00119   case h0:    return 130; // K_L0
00120   case h_HF:         return 130; // dummy pdg code 
00121   case egamma_HF:    return 22;  // dummy pdg code
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 //   PFBlockRef blockRef = c.block(); 
00317 //   int blockid = blockRef.key(); 
00318 //   const edm::OwnVector< reco::PFBlockElement >& elements = c.elements();
00319 //   out<< "\t# of elements " << elements.size() 
00320 //      <<" from block " << blockid << endl;
00321 
00322 //   // print each element in turn
00323   
00324 //   for(unsigned ie=0; ie<elements.size(); ie++) {
00325 //     out<<"\t"<< elements[ie] <<endl;
00326 //   }
00327   
00328   out<<resetiosflags(ios::right|ios::fixed);
00329   return out;
00330 }