CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_4/src/DataFormats/PatCandidates/interface/PATObject.h

Go to the documentation of this file.
00001 //
00002 // $Id: PATObject.h,v 1.38 2012/01/20 08:51:05 cbern Exp $
00003 //
00004 
00005 #ifndef DataFormats_PatCandidates_PATObject_h
00006 #define DataFormats_PatCandidates_PATObject_h
00007 
00022 #include "DataFormats/Common/interface/Ptr.h"
00023 #include "DataFormats/Candidate/interface/CandidateFwd.h"
00024 #include "DataFormats/Candidate/interface/Candidate.h"
00025 #include <vector>
00026 #include <string>
00027 #include <iosfwd>
00028 
00029 #include "DataFormats/PatCandidates/interface/TriggerObjectStandAlone.h"
00030 #include "DataFormats/PatCandidates/interface/LookupTableRecord.h"
00031 
00032 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
00033 
00034 #include "DataFormats/PatCandidates/interface/UserData.h"
00035 #include "DataFormats/Common/interface/OwnVector.h"
00036 
00037 #include "DataFormats/PatCandidates/interface/CandKinResolution.h"
00038 
00039 namespace pat {
00040 
00041 
00042   template <class ObjectType>
00043   class PATObject : public ObjectType {
00044     public:
00045 
00046       typedef  ObjectType             base_type;
00047 
00049       PATObject();
00051       PATObject(const ObjectType & obj);
00053       PATObject(const edm::RefToBase<ObjectType> & ref);
00055       PATObject(const edm::Ptr<ObjectType> & ref);
00057       virtual ~PATObject() {}
00058       // returns a clone                                  // NO: ObjectType can be an abstract type like reco::Candidate
00059       // virtual PATObject<ObjectType> * clone() const ;  //     for which the clone() can't be defined
00060 
00062       const reco::Candidate * originalObject() const;
00064       const edm::Ptr<reco::Candidate> & originalObjectRef() const;
00065 
00069 
00071       const TriggerObjectStandAloneCollection & triggerObjectMatches() const { return triggerObjectMatchesEmbedded_; };
00073       const TriggerObjectStandAlone * triggerObjectMatch( const size_t idx = 0 ) const;
00076       const TriggerObjectStandAloneCollection triggerObjectMatchesByType( const trigger::TriggerObjectType triggerObjectType ) const;
00077       const TriggerObjectStandAloneCollection triggerObjectMatchesByType( const unsigned triggerObjectType ) const {
00078         return triggerObjectMatchesByType( trigger::TriggerObjectType( triggerObjectType ) );
00079       };
00080       // for backward compatibility
00081       const TriggerObjectStandAloneCollection triggerObjectMatchesByFilterID( const unsigned triggerObjectType ) const {
00082         return triggerObjectMatchesByType( trigger::TriggerObjectType( triggerObjectType ) );
00083       };
00085       const TriggerObjectStandAlone * triggerObjectMatchByType( const trigger::TriggerObjectType triggerObjectType, const size_t idx = 0 ) const;
00086       const TriggerObjectStandAlone * triggerObjectMatchByType( const unsigned triggerObjectType, const size_t idx = 0 ) const {
00087         return triggerObjectMatchByType( trigger::TriggerObjectType( triggerObjectType ), idx );
00088       };
00089       // for backward compatibility
00090       const TriggerObjectStandAlone * triggerObjectMatchByFilterID( const unsigned triggerObjectType, const size_t idx = 0 ) const {
00091         return triggerObjectMatchByType( trigger::TriggerObjectType( triggerObjectType ), idx );
00092       };
00094       const TriggerObjectStandAloneCollection triggerObjectMatchesByCollection( const std::string & coll ) const;
00095       // for RooT command line
00096       const TriggerObjectStandAloneCollection triggerObjectMatchesByCollection( const char * coll ) const {
00097         return triggerObjectMatchesByCollection( std::string( coll ) );
00098       };
00100       const TriggerObjectStandAlone * triggerObjectMatchByCollection( const std::string & coll, const size_t idx = 0 ) const;
00101       // for RooT command line
00102       const TriggerObjectStandAlone * triggerObjectMatchByCollection( const char * coll, const size_t idx = 0 ) const {
00103         return triggerObjectMatchByCollection( std::string( coll ), idx );
00104       };
00106       const TriggerObjectStandAloneCollection triggerObjectMatchesByCondition( const std::string & nameCondition ) const;
00107       // for RooT command line
00108       const TriggerObjectStandAloneCollection triggerObjectMatchesByCondition( const char * nameCondition ) const {
00109         return triggerObjectMatchesByCondition( std::string( nameCondition ) );
00110       };
00112       const TriggerObjectStandAlone * triggerObjectMatchByCondition( const std::string & nameCondition, const size_t idx = 0 ) const;
00113       // for RooT command line
00114       const TriggerObjectStandAlone * triggerObjectMatchByCondition( const char * nameCondition, const size_t idx = 0 ) const {
00115         return triggerObjectMatchByCondition( std::string( nameCondition ), idx );
00116       };
00120       const TriggerObjectStandAloneCollection triggerObjectMatchesByAlgorithm( const std::string & nameAlgorithm, const bool algoCondAccepted = true ) const;
00121       // for RooT command line
00122       const TriggerObjectStandAloneCollection triggerObjectMatchesByAlgorithm( const char * nameAlgorithm, const bool algoCondAccepted = true ) const {
00123         return triggerObjectMatchesByAlgorithm( std::string( nameAlgorithm ), algoCondAccepted );
00124       };
00125       // for the cut string parser
00126       const TriggerObjectStandAloneCollection triggerObjectMatchesByAlgorithm( const std::string & nameAlgorithm, const unsigned algoCondAccepted ) const {
00127         return triggerObjectMatchesByAlgorithm( nameAlgorithm, bool( algoCondAccepted ) );
00128       };
00129       // for RooT command line and the cut string parser
00130       const TriggerObjectStandAloneCollection triggerObjectMatchesByAlgorithm( const char * nameAlgorithm, const unsigned algoCondAccepted ) const {
00131         return triggerObjectMatchesByAlgorithm( std::string( nameAlgorithm ), bool( algoCondAccepted ) );
00132       };
00136       const TriggerObjectStandAlone * triggerObjectMatchByAlgorithm( const std::string & nameAlgorithm, const bool algoCondAccepted = true, const size_t idx = 0 ) const;
00137       // for RooT command line
00138       const TriggerObjectStandAlone * triggerObjectMatchByAlgorithm( const char * nameAlgorithm, const bool algoCondAccepted = true, const size_t idx = 0 ) const {
00139         return triggerObjectMatchByAlgorithm( std::string( nameAlgorithm ), algoCondAccepted, idx );
00140       };
00141       // for the cut string parser
00142       const TriggerObjectStandAlone * triggerObjectMatchByAlgorithm( const std::string & nameAlgorithm, const unsigned algoCondAccepted, const size_t idx = 0 ) const {
00143         return triggerObjectMatchByAlgorithm( nameAlgorithm, bool( algoCondAccepted ), idx );
00144       };
00145       // for RooT command line and the cut string parser
00146       const TriggerObjectStandAlone * triggerObjectMatchByAlgorithm( const char * nameAlgorithm, const unsigned algoCondAccepted, const size_t idx = 0 ) const {
00147         return triggerObjectMatchByAlgorithm( std::string( nameAlgorithm ), bool( algoCondAccepted ), idx );
00148       };
00150       const TriggerObjectStandAloneCollection triggerObjectMatchesByFilter( const std::string & labelFilter ) const;
00151       // for RooT command line
00152       const TriggerObjectStandAloneCollection triggerObjectMatchesByFilter( const char * labelFilter ) const {
00153         return triggerObjectMatchesByFilter( std::string( labelFilter ) );
00154       };
00156       const TriggerObjectStandAlone * triggerObjectMatchByFilter( const std::string & labelFilter, const size_t idx = 0 ) const;
00157       // for RooT command line
00158       const TriggerObjectStandAlone * triggerObjectMatchByFilter( const char * labelFilter, const size_t idx = 0 ) const {
00159         return triggerObjectMatchByFilter( std::string( labelFilter ), idx );
00160       };
00166       const TriggerObjectStandAloneCollection triggerObjectMatchesByPath( const std::string & namePath, const bool pathLastFilterAccepted = false, const bool pathL3FilterAccepted = true ) const;
00167       // for RooT command line
00168       const TriggerObjectStandAloneCollection triggerObjectMatchesByPath( const char * namePath, const bool pathLastFilterAccepted = false, const bool pathL3FilterAccepted = true ) const {
00169         return triggerObjectMatchesByPath( std::string( namePath ), pathLastFilterAccepted, pathL3FilterAccepted );
00170       };
00171       // for the cut string parser
00172       const TriggerObjectStandAloneCollection triggerObjectMatchesByPath( const std::string & namePath, const unsigned pathLastFilterAccepted, const unsigned pathL3FilterAccepted = 1 ) const {
00173         return triggerObjectMatchesByPath( namePath, bool( pathLastFilterAccepted ), bool( pathL3FilterAccepted ) );
00174       };
00175       // for RooT command line and the cut string parser
00176       const TriggerObjectStandAloneCollection triggerObjectMatchesByPath( const char * namePath, const unsigned pathLastFilterAccepted, const unsigned pathL3FilterAccepted = 1 ) const {
00177         return triggerObjectMatchesByPath( std::string( namePath ), bool( pathLastFilterAccepted ), bool( pathL3FilterAccepted ) );
00178       };
00184       const TriggerObjectStandAlone * triggerObjectMatchByPath( const std::string & namePath, const bool pathLastFilterAccepted = false, const bool pathL3FilterAccepted = true, const size_t idx = 0 ) const;
00185       // for RooT command line
00186       const TriggerObjectStandAlone * triggerObjectMatchByPath( const char * namePath, const bool pathLastFilterAccepted = false, const bool pathL3FilterAccepted = true, const size_t idx = 0 ) const {
00187         return triggerObjectMatchByPath( std::string( namePath ), pathLastFilterAccepted, pathL3FilterAccepted, idx );
00188       };
00189       // for the cut string parser
00190       const TriggerObjectStandAlone * triggerObjectMatchByPath( const std::string & namePath, const unsigned pathLastFilterAccepted, const unsigned pathL3FilterAccepted = 1, const size_t idx = 0 ) const {
00191         return triggerObjectMatchByPath( namePath, bool( pathLastFilterAccepted ), bool( pathL3FilterAccepted ), idx );
00192       };
00193       // for RooT command line and the cut string parser
00194       const TriggerObjectStandAlone * triggerObjectMatchByPath( const char * namePath, const unsigned pathLastFilterAccepted, const unsigned pathL3FilterAccepted = 1, const size_t idx = 0 ) const {
00195         return triggerObjectMatchByPath( std::string( namePath ), bool( pathLastFilterAccepted ), bool( pathL3FilterAccepted ), idx );
00196       };
00198       void addTriggerObjectMatch( const TriggerObjectStandAlone & trigObj ) { triggerObjectMatchesEmbedded_.push_back( trigObj ); };
00199 
00201       const pat::LookupTableRecord       & efficiency(const std::string &name) const ;
00203       std::vector<std::pair<std::string,pat::LookupTableRecord> > efficiencies() const ;
00205       const std::vector<std::string> & efficiencyNames() const { return efficiencyNames_; }
00207       const std::vector<pat::LookupTableRecord> & efficiencyValues() const { return efficiencyValues_; }
00211       void setEfficiency(const std::string &name, const pat::LookupTableRecord & value) ;
00212 
00215       reco::GenParticleRef      genParticleRef(size_t idx=0) const {
00216             if (idx >= genParticlesSize()) return reco::GenParticleRef();
00217             return genParticleEmbedded_.empty() ? genParticleRef_[idx] : reco::GenParticleRef(&genParticleEmbedded_, idx);
00218       }
00229       // implementation note: uint8_t instead of bool, because the string parser doesn't allow bool currently
00230       reco::GenParticleRef      genParticleById(int pdgId, int status, uint8_t autoCharge=0) const ;
00231 
00234       const reco::GenParticle * genParticle(size_t idx=0)    const {
00235             reco::GenParticleRef ref = genParticleRef(idx);
00236             return ref.isNonnull() ? ref.get() : 0;
00237       }
00239       size_t genParticlesSize() const {
00240             return genParticleEmbedded_.empty() ? genParticleRef_.size() : genParticleEmbedded_.size();
00241       }
00244       std::vector<reco::GenParticleRef> genParticleRefs() const ;
00245 
00247       void setGenParticleRef(const reco::GenParticleRef &ref, bool embed=false) ;
00250       void addGenParticleRef(const reco::GenParticleRef &ref) ;
00252       void setGenParticle( const reco::GenParticle &particle ) ;
00255       void embedGenParticle() ;
00256 
00258       bool hasOverlaps(const std::string &label) const ;
00261       const reco::CandidatePtrVector & overlaps(const std::string &label) const ;
00263       const std::vector<std::string> & overlapLabels() const { return overlapLabels_; }
00267       void setOverlaps(const std::string &label, const reco::CandidatePtrVector & overlaps) ;
00268 
00270       template<typename T> const T * userData(const std::string &key) const {
00271           const pat::UserData * data = userDataObject_(key);
00272           return (data != 0 ? data->template get<T>() : 0);
00273 
00274       }
00276       bool hasUserData(const std::string &key) const {
00277           return (userDataObject_(key) != 0);
00278       }
00280       const std::string & userDataObjectType(const std::string &key) const {
00281           static const std::string EMPTY("");
00282           const pat::UserData * data = userDataObject_(key);
00283           return (data != 0 ? data->typeName() : EMPTY);
00284       };
00286       const std::vector<std::string> & userDataNames() const  { return userDataLabels_; }
00287 
00290       const void * userDataBare(const std::string &key) const {
00291           const pat::UserData * data = userDataObject_(key);
00292           return (data != 0 ? data->bareData() : 0);
00293       }
00294 
00299       template<typename T>
00300       void addUserData( const std::string & label, const T & data, bool transientOnly=false ) {
00301           userDataLabels_.push_back(label);
00302           userDataObjects_.push_back(pat::UserData::make<T>(data, transientOnly));
00303       }
00304 
00307       void addUserDataFromPtr( const std::string & label, const edm::Ptr<pat::UserData> & data ) {
00308           userDataLabels_.push_back(label);
00309           userDataObjects_.push_back(data->clone());
00310       }
00311 
00314       float userFloat( const std::string & key ) const;
00316       float userFloat( const char* key ) const { return userFloat( std::string(key) ); }
00317       
00319       void addUserFloat( const  std::string & label, float data );
00321       const std::vector<std::string> & userFloatNames() const  { return userFloatLabels_; }
00323       bool hasUserFloat( const std::string & key ) const {
00324         return std::find(userFloatLabels_.begin(), userFloatLabels_.end(), key) != userFloatLabels_.end();
00325       }
00327       bool hasUserFloat( const char* key ) const {return hasUserFloat( std::string(key) );}
00328 
00331       int32_t userInt( const std::string & key ) const;
00333       void addUserInt( const std::string & label,  int32_t data );
00335       const std::vector<std::string> & userIntNames() const  { return userIntLabels_; }
00337       bool hasUserInt( const std::string & key ) const {
00338         return std::find(userIntLabels_.begin(), userIntLabels_.end(), key) != userIntLabels_.end();
00339       }
00340 
00343       reco::CandidatePtr userCand( const std::string & key ) const;
00345       void addUserCand( const std::string & label,  const reco::CandidatePtr & data );
00347       const std::vector<std::string> & userCandNames() const  { return userCandLabels_; }
00349       bool hasUserCand( const std::string & key ) const {
00350         return std::find(userCandLabels_.begin(), userCandLabels_.end(), key) != userCandLabels_.end();
00351       }
00352 
00353       // === New Kinematic Resolutions
00356       const pat::CandKinResolution & getKinResolution(const std::string &label="") const ;
00357 
00359       bool hasKinResolution(const std::string &label="") const ;
00360 
00362       void setKinResolution(const pat::CandKinResolution &resol, const std::string &label="") ;
00363 
00365       double resolEta(const std::string &label="") const { return getKinResolution(label).resolEta(this->p4()); }
00366 
00368       double resolTheta(const std::string &label="") const { return getKinResolution(label).resolTheta(this->p4()); }
00369 
00371       double resolPhi(const std::string &label="") const { return getKinResolution(label).resolPhi(this->p4()); }
00372 
00374       double resolE(const std::string &label="") const { return getKinResolution(label).resolE(this->p4()); }
00375 
00377       double resolEt(const std::string &label="") const { return getKinResolution(label).resolEt(this->p4()); }
00378 
00380       double resolP(const std::string &label="") const { return getKinResolution(label).resolP(this->p4()); }
00381 
00383       double resolPt(const std::string &label="") const { return getKinResolution(label).resolPt(this->p4()); }
00384 
00386       double resolPInv(const std::string &label="") const { return getKinResolution(label).resolPInv(this->p4()); }
00387 
00389       double resolPx(const std::string &label="") const { return getKinResolution(label).resolPx(this->p4()); }
00390 
00392       double resolPy(const std::string &label="") const { return getKinResolution(label).resolPy(this->p4()); }
00393 
00395       double resolPz(const std::string &label="") const { return getKinResolution(label).resolPz(this->p4()); }
00396 
00399       double resolM(const std::string &label="") const { return getKinResolution(label).resolM(this->p4()); }
00400 
00401 
00402 
00403     protected:
00404       // reference back to the original object
00405       edm::Ptr<reco::Candidate> refToOrig_;
00406 
00408       TriggerObjectStandAloneCollection triggerObjectMatchesEmbedded_;
00409 
00411       std::vector<pat::LookupTableRecord> efficiencyValues_;
00413       std::vector<std::string> efficiencyNames_;
00414 
00416       std::vector<reco::GenParticleRef> genParticleRef_;
00418       std::vector<reco::GenParticle>    genParticleEmbedded_;
00419 
00421       std::vector<std::string> overlapLabels_;
00423       std::vector<reco::CandidatePtrVector> overlapItems_;
00424 
00426       std::vector<std::string>      userDataLabels_;
00427       pat::UserDataCollection       userDataObjects_;
00428       // User float values
00429       std::vector<std::string>      userFloatLabels_;
00430       std::vector<float>            userFloats_;
00431       // User int values
00432       std::vector<std::string>      userIntLabels_;
00433       std::vector<int32_t>          userInts_;
00434       // User candidate matches
00435       std::vector<std::string>        userCandLabels_;
00436       std::vector<reco::CandidatePtr> userCands_;
00437 
00439       std::vector<pat::CandKinResolution> kinResolutions_;
00442       std::vector<std::string>            kinResolutionLabels_;
00443 
00444     private:
00445       const pat::UserData *  userDataObject_(const std::string &key) const ;
00446   };
00447 
00448 
00449   template <class ObjectType> PATObject<ObjectType>::PATObject() {
00450   }
00451 
00452   template <class ObjectType> PATObject<ObjectType>::PATObject(const ObjectType & obj) :
00453     ObjectType(obj),
00454     refToOrig_() {
00455   }
00456 
00457   template <class ObjectType> PATObject<ObjectType>::PATObject(const edm::RefToBase<ObjectType> & ref) :
00458     ObjectType(*ref),
00459     refToOrig_(ref.id(), ref.get(), ref.key()) // correct way to convert RefToBase=>Ptr, if ref is guaranteed to be available
00460                                                // which happens to be true, otherwise the line before this throws ex. already
00461       {
00462       }
00463 
00464   template <class ObjectType> PATObject<ObjectType>::PATObject(const edm::Ptr<ObjectType> & ref) :
00465     ObjectType(*ref),
00466     refToOrig_(ref) {
00467   }
00468 
00469   template <class ObjectType> const reco::Candidate * PATObject<ObjectType>::originalObject() const {
00470     if (refToOrig_.isNull()) {
00471       // this object was not produced from a reference, so no link to the
00472       // original object exists -> return a 0-pointer
00473       return 0;
00474     } else if (!refToOrig_.isAvailable()) {
00475       throw edm::Exception(edm::errors::ProductNotFound) << "The original collection from which this PAT object was made is not present any more in the event, hence you cannot access the originating object anymore.";
00476     } else {
00477       return refToOrig_.get();
00478     }
00479   }
00480 
00481   template <class ObjectType>
00482   const edm::Ptr<reco::Candidate> & PATObject<ObjectType>::originalObjectRef() const { return refToOrig_; }
00483 
00484   template <class ObjectType>
00485   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatch( const size_t idx ) const {
00486     if ( idx >= triggerObjectMatches().size() ) return 0;
00487     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, idx );
00488     return ref.isNonnull() ? ref.get() : 0;
00489   }
00490 
00491   template <class ObjectType>
00492   const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByType( const trigger::TriggerObjectType triggerObjectType ) const {
00493     TriggerObjectStandAloneCollection matches;
00494     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00495       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasTriggerObjectType( triggerObjectType ) ) matches.push_back( *( triggerObjectMatch( i ) ) );
00496     }
00497     return matches;
00498   }
00499 
00500   template <class ObjectType>
00501   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatchByType( const trigger::TriggerObjectType triggerObjectType, const size_t idx ) const {
00502     std::vector< size_t > refs;
00503     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00504       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasTriggerObjectType( triggerObjectType ) ) refs.push_back( i );
00505     }
00506     if ( idx >= refs.size() ) return 0;
00507     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, refs.at( idx ) );
00508     return ref.isNonnull() ? ref.get() : 0;
00509   }
00510 
00511   template <class ObjectType>
00512   const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByCollection( const std::string & coll ) const {
00513     TriggerObjectStandAloneCollection matches;
00514     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00515       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasCollection( coll ) ) matches.push_back( *( triggerObjectMatch( i ) ) );
00516     }
00517     return matches;
00518   }
00519 
00520   template <class ObjectType>
00521   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatchByCollection( const std::string & coll, const size_t idx ) const {
00522     std::vector< size_t > refs;
00523     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00524       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasCollection( coll ) ) {
00525         refs.push_back( i );
00526       }
00527     }
00528     if ( idx >= refs.size() ) return 0;
00529     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, refs.at( idx ) );
00530     return ref.isNonnull() ? ref.get() : 0;
00531   }
00532 
00533   template <class ObjectType>
00534   const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByCondition( const std::string & nameCondition ) const {
00535     TriggerObjectStandAloneCollection matches;
00536     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00537       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasConditionName( nameCondition ) ) matches.push_back( *( triggerObjectMatch( i ) ) );
00538     }
00539     return matches;
00540   }
00541 
00542   template <class ObjectType>
00543   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatchByCondition( const std::string & nameCondition, const size_t idx ) const {
00544     std::vector< size_t > refs;
00545     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00546       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasConditionName( nameCondition ) ) refs.push_back( i );
00547     }
00548     if ( idx >= refs.size() ) return 0;
00549     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, refs.at( idx ) );
00550     return ref.isNonnull() ? ref.get() : 0;
00551   }
00552 
00553   template <class ObjectType>
00554   const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByAlgorithm( const std::string & nameAlgorithm, const bool algoCondAccepted ) const {
00555     TriggerObjectStandAloneCollection matches;
00556     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00557       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasAlgorithmName( nameAlgorithm, algoCondAccepted ) ) matches.push_back( *( triggerObjectMatch( i ) ) );
00558     }
00559     return matches;
00560   }
00561 
00562   template <class ObjectType>
00563   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatchByAlgorithm( const std::string & nameAlgorithm, const bool algoCondAccepted, const size_t idx ) const {
00564     std::vector< size_t > refs;
00565     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00566       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasAlgorithmName( nameAlgorithm, algoCondAccepted ) ) refs.push_back( i );
00567     }
00568     if ( idx >= refs.size() ) return 0;
00569     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, refs.at( idx ) );
00570     return ref.isNonnull() ? ref.get() : 0;
00571   }
00572 
00573   template <class ObjectType>
00574   const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByFilter( const std::string & labelFilter ) const {
00575     TriggerObjectStandAloneCollection matches;
00576     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00577       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasFilterLabel( labelFilter ) ) matches.push_back( *( triggerObjectMatch( i ) ) );
00578     }
00579     return matches;
00580   }
00581 
00582   template <class ObjectType>
00583   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatchByFilter( const std::string & labelFilter, const size_t idx ) const {
00584     std::vector< size_t > refs;
00585     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00586       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasFilterLabel( labelFilter ) ) refs.push_back( i );
00587     }
00588     if ( idx >= refs.size() ) return 0;
00589     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, refs.at( idx ) );
00590     return ref.isNonnull() ? ref.get() : 0;
00591   }
00592 
00593   template <class ObjectType>
00594   const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByPath( const std::string & namePath, const bool pathLastFilterAccepted, const bool pathL3FilterAccepted ) const {
00595     TriggerObjectStandAloneCollection matches;
00596     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00597       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasPathName( namePath, pathLastFilterAccepted, pathL3FilterAccepted ) ) matches.push_back( *( triggerObjectMatch( i ) ) );
00598     }
00599     return matches;
00600   }
00601 
00602   template <class ObjectType>
00603   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatchByPath( const std::string & namePath, const bool pathLastFilterAccepted, const bool pathL3FilterAccepted, const size_t idx ) const {
00604     std::vector< size_t > refs;
00605     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00606       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasPathName( namePath, pathLastFilterAccepted, pathL3FilterAccepted ) ) refs.push_back( i );
00607     }
00608     if ( idx >= refs.size() ) return 0;
00609     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, refs.at( idx ) );
00610     return ref.isNonnull() ? ref.get() : 0;
00611   }
00612 
00613   template <class ObjectType>
00614   const pat::LookupTableRecord &
00615   PATObject<ObjectType>::efficiency(const std::string &name) const {
00616     // find the name in the (sorted) list of names
00617     std::vector<std::string>::const_iterator it = std::lower_bound(efficiencyNames_.begin(), efficiencyNames_.end(), name);
00618     if ((it == efficiencyNames_.end()) || (*it != name)) {
00619         throw cms::Exception("Invalid Label") << "There is no efficiency with name '" << name << "' in this PAT Object\n";
00620     }
00621     return efficiencyValues_[it - efficiencyNames_.begin()];
00622   }
00623 
00624   template <class ObjectType>
00625   std::vector<std::pair<std::string,pat::LookupTableRecord> >
00626   PATObject<ObjectType>::efficiencies() const {
00627     std::vector<std::pair<std::string,pat::LookupTableRecord> > ret;
00628     std::vector<std::string>::const_iterator itn = efficiencyNames_.begin(), edn = efficiencyNames_.end();
00629     std::vector<pat::LookupTableRecord>::const_iterator itv = efficiencyValues_.begin();
00630     for ( ; itn != edn; ++itn, ++itv) {
00631         ret.push_back( std::pair<std::string,pat::LookupTableRecord>(*itn, *itv) );
00632     }
00633     return ret;
00634   }
00635 
00636   template <class ObjectType>
00637   void PATObject<ObjectType>::setEfficiency(const std::string &name, const pat::LookupTableRecord & value) {
00638     // look for the name, or to the place where we can insert it without violating the alphabetic order
00639     std::vector<std::string>::iterator it = std::lower_bound(efficiencyNames_.begin(), efficiencyNames_.end(), name);
00640     if (it == efficiencyNames_.end()) { // insert at the end
00641         efficiencyNames_.push_back(name);
00642         efficiencyValues_.push_back(value);
00643     } else if (*it == name) {           // replace existing
00644         efficiencyValues_[it - efficiencyNames_.begin()] = value;
00645     } else {                            // insert in the middle :-(
00646         efficiencyNames_. insert(it, name);
00647         efficiencyValues_.insert( efficiencyValues_.begin() + (it - efficiencyNames_.begin()), value );
00648     }
00649   }
00650 
00651   template <class ObjectType>
00652   void PATObject<ObjectType>::setGenParticleRef(const reco::GenParticleRef &ref, bool embed) {
00653           genParticleRef_ = std::vector<reco::GenParticleRef>(1,ref);
00654           genParticleEmbedded_.clear();
00655           if (embed) embedGenParticle();
00656   }
00657 
00658   template <class ObjectType>
00659   void PATObject<ObjectType>::addGenParticleRef(const reco::GenParticleRef &ref) {
00660       if (!genParticleEmbedded_.empty()) { // we're embedding
00661           if (ref.isNonnull()) genParticleEmbedded_.push_back(*ref);
00662       } else {
00663           genParticleRef_.push_back(ref);
00664       }
00665   }
00666 
00667   template <class ObjectType>
00668   void PATObject<ObjectType>::setGenParticle( const reco::GenParticle &particle ) {
00669       genParticleEmbedded_.clear();
00670       genParticleEmbedded_.push_back(particle);
00671       genParticleRef_.clear();
00672   }
00673 
00674   template <class ObjectType>
00675   void PATObject<ObjectType>::embedGenParticle() {
00676       genParticleEmbedded_.clear();
00677       for (std::vector<reco::GenParticleRef>::const_iterator it = genParticleRef_.begin(); it != genParticleRef_.end(); ++it) {
00678           if (it->isNonnull()) genParticleEmbedded_.push_back(**it);
00679       }
00680       genParticleRef_.clear();
00681   }
00682 
00683   template <class ObjectType>
00684   std::vector<reco::GenParticleRef> PATObject<ObjectType>::genParticleRefs() const {
00685         if (genParticleEmbedded_.empty()) return genParticleRef_;
00686         std::vector<reco::GenParticleRef> ret(genParticleEmbedded_.size());
00687         for (size_t i = 0, n = ret.size(); i < n; ++i) {
00688             ret[i] = reco::GenParticleRef(&genParticleEmbedded_, i);
00689         }
00690         return ret;
00691   }
00692 
00693   template <class ObjectType>
00694   reco::GenParticleRef PATObject<ObjectType>::genParticleById(int pdgId, int status, uint8_t autoCharge) const {
00695         // get a vector, avoiding an unneeded copy if there is no embedding
00696         const std::vector<reco::GenParticleRef> & vec = (genParticleEmbedded_.empty() ? genParticleRef_ : genParticleRefs());
00697         for (std::vector<reco::GenParticleRef>::const_iterator ref = vec.begin(), end = vec.end(); ref != end; ++ref) {
00698             if (ref->isNonnull()) {
00699                 const reco::GenParticle & g = **ref;
00700                 if ((status != 0) && (g.status() != status)) continue;
00701                 if (pdgId == 0) {
00702                     return *ref;
00703                 } else if (!autoCharge) {
00704                     if (pdgId == g.pdgId()) return *ref;
00705                 } else if (abs(pdgId) == abs(g.pdgId())) {
00706                     // I want pdgId > 0 to match "correct charge" (for charged particles)
00707                     if (g.charge() == 0) return *ref;
00708                     else if ((this->charge() == 0) && (pdgId == g.pdgId())) return *ref;
00709                     else if (g.charge()*this->charge()*pdgId > 0) return *ref;
00710                 }
00711             }
00712         }
00713         return reco::GenParticleRef();
00714   }
00715 
00716   template <class ObjectType>
00717   bool PATObject<ObjectType>::hasOverlaps(const std::string &label) const {
00718         return std::find(overlapLabels_.begin(), overlapLabels_.end(), label) != overlapLabels_.end();
00719   }
00720 
00721   template <class ObjectType>
00722   const reco::CandidatePtrVector & PATObject<ObjectType>::overlaps(const std::string &label) const {
00723         static const reco::CandidatePtrVector EMPTY;
00724         std::vector<std::string>::const_iterator match = std::find(overlapLabels_.begin(), overlapLabels_.end(), label);
00725         if (match == overlapLabels_.end()) return EMPTY;
00726         return overlapItems_[match - overlapLabels_.begin()];
00727   }
00728 
00729   template <class ObjectType>
00730   void PATObject<ObjectType>::setOverlaps(const std::string &label, const reco::CandidatePtrVector & overlaps) {
00731         if (!overlaps.empty()) {
00732             std::vector<std::string>::const_iterator match = std::find(overlapLabels_.begin(), overlapLabels_.end(), label);
00733             if (match == overlapLabels_.end()) {
00734                 overlapLabels_.push_back(label);
00735                 overlapItems_.push_back(overlaps);
00736             } else {
00737                 overlapItems_[match - overlapLabels_.begin()] = overlaps;
00738             }
00739         }
00740   }
00741 
00742   template <class ObjectType>
00743   const pat::UserData * PATObject<ObjectType>::userDataObject_( const std::string & key ) const
00744   {
00745     std::vector<std::string>::const_iterator it = std::find(userDataLabels_.begin(), userDataLabels_.end(), key);
00746     if (it != userDataLabels_.end()) {
00747         return & userDataObjects_[it - userDataLabels_.begin()];
00748     }
00749     return 0;
00750   }
00751 
00752   template <class ObjectType>
00753   float PATObject<ObjectType>::userFloat( const std::string &key ) const
00754   {
00755     std::vector<std::string>::const_iterator it = std::find(userFloatLabels_.begin(), userFloatLabels_.end(), key);
00756     if (it != userFloatLabels_.end()) {
00757         return userFloats_[it - userFloatLabels_.begin()];
00758     }
00759     return 0.0;
00760   }
00761 
00762   template <class ObjectType>
00763   void PATObject<ObjectType>::addUserFloat( const std::string & label,
00764                                             float data )
00765   {
00766     userFloatLabels_.push_back(label);
00767     userFloats_.push_back( data );
00768   }
00769 
00770 
00771   template <class ObjectType>
00772   int PATObject<ObjectType>::userInt( const std::string & key ) const
00773   {
00774     std::vector<std::string>::const_iterator it = std::find(userIntLabels_.begin(), userIntLabels_.end(), key);
00775     if (it != userIntLabels_.end()) {
00776         return userInts_[it - userIntLabels_.begin()];
00777     }
00778     return 0;
00779   }
00780 
00781   template <class ObjectType>
00782   void PATObject<ObjectType>::addUserInt( const std::string &label,
00783                                            int data )
00784   {
00785     userIntLabels_.push_back(label);
00786     userInts_.push_back( data );
00787   }
00788 
00789   template <class ObjectType>
00790   reco::CandidatePtr PATObject<ObjectType>::userCand( const std::string & key ) const
00791   {
00792     std::vector<std::string>::const_iterator it = std::find(userCandLabels_.begin(), userCandLabels_.end(), key);
00793     if (it != userCandLabels_.end()) {
00794         return userCands_[it - userCandLabels_.begin()];
00795     }
00796     return reco::CandidatePtr();
00797   }
00798 
00799   template <class ObjectType>
00800   void PATObject<ObjectType>::addUserCand( const std::string &label,
00801                                            const reco::CandidatePtr & data )
00802   {
00803     userCandLabels_.push_back(label);
00804     userCands_.push_back( data );
00805   }
00806 
00807 
00808   template <class ObjectType>
00809   const pat::CandKinResolution & PATObject<ObjectType>::getKinResolution(const std::string &label) const {
00810     if (label.empty()) {
00811         if (kinResolutionLabels_.size()+1 == kinResolutions_.size()) {
00812             return kinResolutions_[0];
00813         } else {
00814             throw cms::Exception("Missing Data", "This object does not contain an un-labelled kinematic resolution");
00815         }
00816     } else {
00817         std::vector<std::string>::const_iterator match = std::find(kinResolutionLabels_.begin(), kinResolutionLabels_.end(), label);
00818         if (match == kinResolutionLabels_.end()) {
00819             cms::Exception ex("Missing Data");
00820             ex << "This object does not contain a kinematic resolution with name '" << label << "'.\n";
00821             ex << "The known labels are: " ;
00822             for (std::vector<std::string>::const_iterator it = kinResolutionLabels_.begin(); it != kinResolutionLabels_.end(); ++it) {
00823                 ex << "'" << *it << "' ";
00824             }
00825             ex << "\n";
00826             throw ex;
00827         } else {
00828             if (kinResolutionLabels_.size()+1 == kinResolutions_.size()) {
00829                 // skip un-labelled resolution
00830                 return kinResolutions_[match - kinResolutionLabels_.begin() + 1];
00831             } else {
00832                 // all are labelled, so this is the real index
00833                 return kinResolutions_[match - kinResolutionLabels_.begin()];
00834             }
00835         }
00836     }
00837   }
00838 
00839   template <class ObjectType>
00840   bool PATObject<ObjectType>::hasKinResolution(const std::string &label) const {
00841     if (label.empty()) {
00842         return (kinResolutionLabels_.size()+1 == kinResolutions_.size());
00843     } else {
00844         std::vector<std::string>::const_iterator match = std::find(kinResolutionLabels_.begin(), kinResolutionLabels_.end(), label);
00845         return match != kinResolutionLabels_.end();
00846     }
00847   }
00848 
00849   template <class ObjectType>
00850   void PATObject<ObjectType>::setKinResolution(const pat::CandKinResolution &resol, const std::string &label) {
00851     if (label.empty()) {
00852         if (kinResolutionLabels_.size()+1 == kinResolutions_.size()) {
00853             // There is already an un-labelled object. Replace it
00854             kinResolutions_[0] = resol;
00855         } else {
00856             // Insert. Note that the un-labelled is always the first, so we need to insert before begin()
00857             // (for an empty vector, this should not cost more than push_back)
00858             kinResolutions_.insert(kinResolutions_.begin(), resol);
00859         }
00860     } else {
00861         std::vector<std::string>::iterator match = std::find(kinResolutionLabels_.begin(), kinResolutionLabels_.end(), label);
00862         if (match != kinResolutionLabels_.end()) {
00863             // Existing object: replace
00864             if (kinResolutionLabels_.size()+1 == kinResolutions_.size()) {
00865                 kinResolutions_[(match - kinResolutionLabels_.begin())+1] = resol;
00866             } else {
00867                 kinResolutions_[(match - kinResolutionLabels_.begin())] = resol;
00868             }
00869         } else {
00870             kinResolutionLabels_.push_back(label);
00871             kinResolutions_.push_back(resol);
00872         }
00873     }
00874   }
00875 
00876 
00877 
00878 
00879 }
00880 
00881 #endif