CMS 3D CMS Logo

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

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