CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DataFormats/PatCandidates/interface/PATObject.h

Go to the documentation of this file.
00001 //
00002 // $Id: PATObject.h,v 1.37 2011/06/08 20:40:18 rwolf 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       void addUserFloat( const  std::string & label, float data );
00318       const std::vector<std::string> & userFloatNames() const  { return userFloatLabels_; }
00320       bool hasUserFloat( const std::string & key ) const {
00321         return std::find(userFloatLabels_.begin(), userFloatLabels_.end(), key) != userFloatLabels_.end();
00322       }
00325       int32_t userInt( const std::string & key ) const;
00327       void addUserInt( const std::string & label,  int32_t data );
00329       const std::vector<std::string> & userIntNames() const  { return userIntLabels_; }
00331       bool hasUserInt( const std::string & key ) const {
00332         return std::find(userIntLabels_.begin(), userIntLabels_.end(), key) != userIntLabels_.end();
00333       }
00334 
00337       reco::CandidatePtr userCand( const std::string & key ) const;
00339       void addUserCand( const std::string & label,  const reco::CandidatePtr & data );
00341       const std::vector<std::string> & userCandNames() const  { return userCandLabels_; }
00343       bool hasUserCand( const std::string & key ) const {
00344         return std::find(userCandLabels_.begin(), userCandLabels_.end(), key) != userCandLabels_.end();
00345       }
00346 
00347       // === New Kinematic Resolutions
00350       const pat::CandKinResolution & getKinResolution(const std::string &label="") const ;
00351 
00353       bool hasKinResolution(const std::string &label="") const ;
00354 
00356       void setKinResolution(const pat::CandKinResolution &resol, const std::string &label="") ;
00357 
00359       double resolEta(const std::string &label="") const { return getKinResolution(label).resolEta(this->p4()); }
00360 
00362       double resolTheta(const std::string &label="") const { return getKinResolution(label).resolTheta(this->p4()); }
00363 
00365       double resolPhi(const std::string &label="") const { return getKinResolution(label).resolPhi(this->p4()); }
00366 
00368       double resolE(const std::string &label="") const { return getKinResolution(label).resolE(this->p4()); }
00369 
00371       double resolEt(const std::string &label="") const { return getKinResolution(label).resolEt(this->p4()); }
00372 
00374       double resolP(const std::string &label="") const { return getKinResolution(label).resolP(this->p4()); }
00375 
00377       double resolPt(const std::string &label="") const { return getKinResolution(label).resolPt(this->p4()); }
00378 
00380       double resolPInv(const std::string &label="") const { return getKinResolution(label).resolPInv(this->p4()); }
00381 
00383       double resolPx(const std::string &label="") const { return getKinResolution(label).resolPx(this->p4()); }
00384 
00386       double resolPy(const std::string &label="") const { return getKinResolution(label).resolPy(this->p4()); }
00387 
00389       double resolPz(const std::string &label="") const { return getKinResolution(label).resolPz(this->p4()); }
00390 
00393       double resolM(const std::string &label="") const { return getKinResolution(label).resolM(this->p4()); }
00394 
00395 
00396 
00397     protected:
00398       // reference back to the original object
00399       edm::Ptr<reco::Candidate> refToOrig_;
00400 
00402       TriggerObjectStandAloneCollection triggerObjectMatchesEmbedded_;
00403 
00405       std::vector<pat::LookupTableRecord> efficiencyValues_;
00407       std::vector<std::string> efficiencyNames_;
00408 
00410       std::vector<reco::GenParticleRef> genParticleRef_;
00412       std::vector<reco::GenParticle>    genParticleEmbedded_;
00413 
00415       std::vector<std::string> overlapLabels_;
00417       std::vector<reco::CandidatePtrVector> overlapItems_;
00418 
00420       std::vector<std::string>      userDataLabels_;
00421       pat::UserDataCollection       userDataObjects_;
00422       // User float values
00423       std::vector<std::string>      userFloatLabels_;
00424       std::vector<float>            userFloats_;
00425       // User int values
00426       std::vector<std::string>      userIntLabels_;
00427       std::vector<int32_t>          userInts_;
00428       // User candidate matches
00429       std::vector<std::string>        userCandLabels_;
00430       std::vector<reco::CandidatePtr> userCands_;
00431 
00433       std::vector<pat::CandKinResolution> kinResolutions_;
00436       std::vector<std::string>            kinResolutionLabels_;
00437 
00438     private:
00439       const pat::UserData *  userDataObject_(const std::string &key) const ;
00440   };
00441 
00442 
00443   template <class ObjectType> PATObject<ObjectType>::PATObject() {
00444   }
00445 
00446   template <class ObjectType> PATObject<ObjectType>::PATObject(const ObjectType & obj) :
00447     ObjectType(obj),
00448     refToOrig_() {
00449   }
00450 
00451   template <class ObjectType> PATObject<ObjectType>::PATObject(const edm::RefToBase<ObjectType> & ref) :
00452     ObjectType(*ref),
00453     refToOrig_(ref.id(), ref.get(), ref.key()) // correct way to convert RefToBase=>Ptr, if ref is guaranteed to be available
00454                                                // which happens to be true, otherwise the line before this throws ex. already
00455       {
00456       }
00457 
00458   template <class ObjectType> PATObject<ObjectType>::PATObject(const edm::Ptr<ObjectType> & ref) :
00459     ObjectType(*ref),
00460     refToOrig_(ref) {
00461   }
00462 
00463   template <class ObjectType> const reco::Candidate * PATObject<ObjectType>::originalObject() const {
00464     if (refToOrig_.isNull()) {
00465       // this object was not produced from a reference, so no link to the
00466       // original object exists -> return a 0-pointer
00467       return 0;
00468     } else if (!refToOrig_.isAvailable()) {
00469       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.";
00470     } else {
00471       return refToOrig_.get();
00472     }
00473   }
00474 
00475   template <class ObjectType>
00476   const edm::Ptr<reco::Candidate> & PATObject<ObjectType>::originalObjectRef() const { return refToOrig_; }
00477 
00478   template <class ObjectType>
00479   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatch( const size_t idx ) const {
00480     if ( idx >= triggerObjectMatches().size() ) return 0;
00481     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, idx );
00482     return ref.isNonnull() ? ref.get() : 0;
00483   }
00484 
00485   template <class ObjectType>
00486   const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByType( const trigger::TriggerObjectType triggerObjectType ) const {
00487     TriggerObjectStandAloneCollection matches;
00488     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00489       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasTriggerObjectType( triggerObjectType ) ) matches.push_back( *( triggerObjectMatch( i ) ) );
00490     }
00491     return matches;
00492   }
00493 
00494   template <class ObjectType>
00495   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatchByType( const trigger::TriggerObjectType triggerObjectType, const size_t idx ) const {
00496     std::vector< size_t > refs;
00497     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00498       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasTriggerObjectType( triggerObjectType ) ) refs.push_back( i );
00499     }
00500     if ( idx >= refs.size() ) return 0;
00501     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, refs.at( idx ) );
00502     return ref.isNonnull() ? ref.get() : 0;
00503   }
00504 
00505   template <class ObjectType>
00506   const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByCollection( const std::string & coll ) const {
00507     TriggerObjectStandAloneCollection matches;
00508     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00509       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasCollection( coll ) ) matches.push_back( *( triggerObjectMatch( i ) ) );
00510     }
00511     return matches;
00512   }
00513 
00514   template <class ObjectType>
00515   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatchByCollection( const std::string & coll, const size_t idx ) const {
00516     std::vector< size_t > refs;
00517     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00518       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasCollection( coll ) ) {
00519         refs.push_back( i );
00520       }
00521     }
00522     if ( idx >= refs.size() ) return 0;
00523     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, refs.at( idx ) );
00524     return ref.isNonnull() ? ref.get() : 0;
00525   }
00526 
00527   template <class ObjectType>
00528   const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByCondition( const std::string & nameCondition ) const {
00529     TriggerObjectStandAloneCollection matches;
00530     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00531       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasConditionName( nameCondition ) ) matches.push_back( *( triggerObjectMatch( i ) ) );
00532     }
00533     return matches;
00534   }
00535 
00536   template <class ObjectType>
00537   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatchByCondition( const std::string & nameCondition, const size_t idx ) const {
00538     std::vector< size_t > refs;
00539     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00540       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasConditionName( nameCondition ) ) refs.push_back( i );
00541     }
00542     if ( idx >= refs.size() ) return 0;
00543     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, refs.at( idx ) );
00544     return ref.isNonnull() ? ref.get() : 0;
00545   }
00546 
00547   template <class ObjectType>
00548   const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByAlgorithm( const std::string & nameAlgorithm, const bool algoCondAccepted ) const {
00549     TriggerObjectStandAloneCollection matches;
00550     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00551       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasAlgorithmName( nameAlgorithm, algoCondAccepted ) ) matches.push_back( *( triggerObjectMatch( i ) ) );
00552     }
00553     return matches;
00554   }
00555 
00556   template <class ObjectType>
00557   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatchByAlgorithm( const std::string & nameAlgorithm, const bool algoCondAccepted, const size_t idx ) const {
00558     std::vector< size_t > refs;
00559     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00560       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasAlgorithmName( nameAlgorithm, algoCondAccepted ) ) refs.push_back( i );
00561     }
00562     if ( idx >= refs.size() ) return 0;
00563     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, refs.at( idx ) );
00564     return ref.isNonnull() ? ref.get() : 0;
00565   }
00566 
00567   template <class ObjectType>
00568   const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByFilter( const std::string & labelFilter ) const {
00569     TriggerObjectStandAloneCollection matches;
00570     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00571       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasFilterLabel( labelFilter ) ) matches.push_back( *( triggerObjectMatch( i ) ) );
00572     }
00573     return matches;
00574   }
00575 
00576   template <class ObjectType>
00577   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatchByFilter( const std::string & labelFilter, const size_t idx ) const {
00578     std::vector< size_t > refs;
00579     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00580       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasFilterLabel( labelFilter ) ) refs.push_back( i );
00581     }
00582     if ( idx >= refs.size() ) return 0;
00583     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, refs.at( idx ) );
00584     return ref.isNonnull() ? ref.get() : 0;
00585   }
00586 
00587   template <class ObjectType>
00588   const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByPath( const std::string & namePath, const bool pathLastFilterAccepted, const bool pathL3FilterAccepted ) const {
00589     TriggerObjectStandAloneCollection matches;
00590     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00591       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasPathName( namePath, pathLastFilterAccepted, pathL3FilterAccepted ) ) matches.push_back( *( triggerObjectMatch( i ) ) );
00592     }
00593     return matches;
00594   }
00595 
00596   template <class ObjectType>
00597   const TriggerObjectStandAlone * PATObject<ObjectType>::triggerObjectMatchByPath( const std::string & namePath, const bool pathLastFilterAccepted, const bool pathL3FilterAccepted, const size_t idx ) const {
00598     std::vector< size_t > refs;
00599     for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00600       if ( triggerObjectMatch( i ) != 0 && triggerObjectMatch( i )->hasPathName( namePath, pathLastFilterAccepted, pathL3FilterAccepted ) ) refs.push_back( i );
00601     }
00602     if ( idx >= refs.size() ) return 0;
00603     TriggerObjectStandAloneRef ref( &triggerObjectMatchesEmbedded_, refs.at( idx ) );
00604     return ref.isNonnull() ? ref.get() : 0;
00605   }
00606 
00607   template <class ObjectType>
00608   const pat::LookupTableRecord &
00609   PATObject<ObjectType>::efficiency(const std::string &name) const {
00610     // find the name in the (sorted) list of names
00611     std::vector<std::string>::const_iterator it = std::lower_bound(efficiencyNames_.begin(), efficiencyNames_.end(), name);
00612     if ((it == efficiencyNames_.end()) || (*it != name)) {
00613         throw cms::Exception("Invalid Label") << "There is no efficiency with name '" << name << "' in this PAT Object\n";
00614     }
00615     return efficiencyValues_[it - efficiencyNames_.begin()];
00616   }
00617 
00618   template <class ObjectType>
00619   std::vector<std::pair<std::string,pat::LookupTableRecord> >
00620   PATObject<ObjectType>::efficiencies() const {
00621     std::vector<std::pair<std::string,pat::LookupTableRecord> > ret;
00622     std::vector<std::string>::const_iterator itn = efficiencyNames_.begin(), edn = efficiencyNames_.end();
00623     std::vector<pat::LookupTableRecord>::const_iterator itv = efficiencyValues_.begin();
00624     for ( ; itn != edn; ++itn, ++itv) {
00625         ret.push_back( std::pair<std::string,pat::LookupTableRecord>(*itn, *itv) );
00626     }
00627     return ret;
00628   }
00629 
00630   template <class ObjectType>
00631   void PATObject<ObjectType>::setEfficiency(const std::string &name, const pat::LookupTableRecord & value) {
00632     // look for the name, or to the place where we can insert it without violating the alphabetic order
00633     std::vector<std::string>::iterator it = std::lower_bound(efficiencyNames_.begin(), efficiencyNames_.end(), name);
00634     if (it == efficiencyNames_.end()) { // insert at the end
00635         efficiencyNames_.push_back(name);
00636         efficiencyValues_.push_back(value);
00637     } else if (*it == name) {           // replace existing
00638         efficiencyValues_[it - efficiencyNames_.begin()] = value;
00639     } else {                            // insert in the middle :-(
00640         efficiencyNames_. insert(it, name);
00641         efficiencyValues_.insert( efficiencyValues_.begin() + (it - efficiencyNames_.begin()), value );
00642     }
00643   }
00644 
00645   template <class ObjectType>
00646   void PATObject<ObjectType>::setGenParticleRef(const reco::GenParticleRef &ref, bool embed) {
00647           genParticleRef_ = std::vector<reco::GenParticleRef>(1,ref);
00648           genParticleEmbedded_.clear();
00649           if (embed) embedGenParticle();
00650   }
00651 
00652   template <class ObjectType>
00653   void PATObject<ObjectType>::addGenParticleRef(const reco::GenParticleRef &ref) {
00654       if (!genParticleEmbedded_.empty()) { // we're embedding
00655           if (ref.isNonnull()) genParticleEmbedded_.push_back(*ref);
00656       } else {
00657           genParticleRef_.push_back(ref);
00658       }
00659   }
00660 
00661   template <class ObjectType>
00662   void PATObject<ObjectType>::setGenParticle( const reco::GenParticle &particle ) {
00663       genParticleEmbedded_.clear();
00664       genParticleEmbedded_.push_back(particle);
00665       genParticleRef_.clear();
00666   }
00667 
00668   template <class ObjectType>
00669   void PATObject<ObjectType>::embedGenParticle() {
00670       genParticleEmbedded_.clear();
00671       for (std::vector<reco::GenParticleRef>::const_iterator it = genParticleRef_.begin(); it != genParticleRef_.end(); ++it) {
00672           if (it->isNonnull()) genParticleEmbedded_.push_back(**it);
00673       }
00674       genParticleRef_.clear();
00675   }
00676 
00677   template <class ObjectType>
00678   std::vector<reco::GenParticleRef> PATObject<ObjectType>::genParticleRefs() const {
00679         if (genParticleEmbedded_.empty()) return genParticleRef_;
00680         std::vector<reco::GenParticleRef> ret(genParticleEmbedded_.size());
00681         for (size_t i = 0, n = ret.size(); i < n; ++i) {
00682             ret[i] = reco::GenParticleRef(&genParticleEmbedded_, i);
00683         }
00684         return ret;
00685   }
00686 
00687   template <class ObjectType>
00688   reco::GenParticleRef PATObject<ObjectType>::genParticleById(int pdgId, int status, uint8_t autoCharge) const {
00689         // get a vector, avoiding an unneeded copy if there is no embedding
00690         const std::vector<reco::GenParticleRef> & vec = (genParticleEmbedded_.empty() ? genParticleRef_ : genParticleRefs());
00691         for (std::vector<reco::GenParticleRef>::const_iterator ref = vec.begin(), end = vec.end(); ref != end; ++ref) {
00692             if (ref->isNonnull()) {
00693                 const reco::GenParticle & g = **ref;
00694                 if ((status != 0) && (g.status() != status)) continue;
00695                 if (pdgId == 0) {
00696                     return *ref;
00697                 } else if (!autoCharge) {
00698                     if (pdgId == g.pdgId()) return *ref;
00699                 } else if (abs(pdgId) == abs(g.pdgId())) {
00700                     // I want pdgId > 0 to match "correct charge" (for charged particles)
00701                     if (g.charge() == 0) return *ref;
00702                     else if ((this->charge() == 0) && (pdgId == g.pdgId())) return *ref;
00703                     else if (g.charge()*this->charge()*pdgId > 0) return *ref;
00704                 }
00705             }
00706         }
00707         return reco::GenParticleRef();
00708   }
00709 
00710   template <class ObjectType>
00711   bool PATObject<ObjectType>::hasOverlaps(const std::string &label) const {
00712         return std::find(overlapLabels_.begin(), overlapLabels_.end(), label) != overlapLabels_.end();
00713   }
00714 
00715   template <class ObjectType>
00716   const reco::CandidatePtrVector & PATObject<ObjectType>::overlaps(const std::string &label) const {
00717         static const reco::CandidatePtrVector EMPTY;
00718         std::vector<std::string>::const_iterator match = std::find(overlapLabels_.begin(), overlapLabels_.end(), label);
00719         if (match == overlapLabels_.end()) return EMPTY;
00720         return overlapItems_[match - overlapLabels_.begin()];
00721   }
00722 
00723   template <class ObjectType>
00724   void PATObject<ObjectType>::setOverlaps(const std::string &label, const reco::CandidatePtrVector & overlaps) {
00725         if (!overlaps.empty()) {
00726             std::vector<std::string>::const_iterator match = std::find(overlapLabels_.begin(), overlapLabels_.end(), label);
00727             if (match == overlapLabels_.end()) {
00728                 overlapLabels_.push_back(label);
00729                 overlapItems_.push_back(overlaps);
00730             } else {
00731                 overlapItems_[match - overlapLabels_.begin()] = overlaps;
00732             }
00733         }
00734   }
00735 
00736   template <class ObjectType>
00737   const pat::UserData * PATObject<ObjectType>::userDataObject_( const std::string & key ) const
00738   {
00739     std::vector<std::string>::const_iterator it = std::find(userDataLabels_.begin(), userDataLabels_.end(), key);
00740     if (it != userDataLabels_.end()) {
00741         return & userDataObjects_[it - userDataLabels_.begin()];
00742     }
00743     return 0;
00744   }
00745 
00746   template <class ObjectType>
00747   float PATObject<ObjectType>::userFloat( const std::string &key ) const
00748   {
00749     std::vector<std::string>::const_iterator it = std::find(userFloatLabels_.begin(), userFloatLabels_.end(), key);
00750     if (it != userFloatLabels_.end()) {
00751         return userFloats_[it - userFloatLabels_.begin()];
00752     }
00753     return 0.0;
00754   }
00755 
00756   template <class ObjectType>
00757   void PATObject<ObjectType>::addUserFloat( const std::string & label,
00758                                             float data )
00759   {
00760     userFloatLabels_.push_back(label);
00761     userFloats_.push_back( data );
00762   }
00763 
00764 
00765   template <class ObjectType>
00766   int PATObject<ObjectType>::userInt( const std::string & key ) const
00767   {
00768     std::vector<std::string>::const_iterator it = std::find(userIntLabels_.begin(), userIntLabels_.end(), key);
00769     if (it != userIntLabels_.end()) {
00770         return userInts_[it - userIntLabels_.begin()];
00771     }
00772     return 0;
00773   }
00774 
00775   template <class ObjectType>
00776   void PATObject<ObjectType>::addUserInt( const std::string &label,
00777                                            int data )
00778   {
00779     userIntLabels_.push_back(label);
00780     userInts_.push_back( data );
00781   }
00782 
00783   template <class ObjectType>
00784   reco::CandidatePtr PATObject<ObjectType>::userCand( const std::string & key ) const
00785   {
00786     std::vector<std::string>::const_iterator it = std::find(userCandLabels_.begin(), userCandLabels_.end(), key);
00787     if (it != userCandLabels_.end()) {
00788         return userCands_[it - userCandLabels_.begin()];
00789     }
00790     return reco::CandidatePtr();
00791   }
00792 
00793   template <class ObjectType>
00794   void PATObject<ObjectType>::addUserCand( const std::string &label,
00795                                            const reco::CandidatePtr & data )
00796   {
00797     userCandLabels_.push_back(label);
00798     userCands_.push_back( data );
00799   }
00800 
00801 
00802   template <class ObjectType>
00803   const pat::CandKinResolution & PATObject<ObjectType>::getKinResolution(const std::string &label) const {
00804     if (label.empty()) {
00805         if (kinResolutionLabels_.size()+1 == kinResolutions_.size()) {
00806             return kinResolutions_[0];
00807         } else {
00808             throw cms::Exception("Missing Data", "This object does not contain an un-labelled kinematic resolution");
00809         }
00810     } else {
00811         std::vector<std::string>::const_iterator match = std::find(kinResolutionLabels_.begin(), kinResolutionLabels_.end(), label);
00812         if (match == kinResolutionLabels_.end()) {
00813             cms::Exception ex("Missing Data");
00814             ex << "This object does not contain a kinematic resolution with name '" << label << "'.\n";
00815             ex << "The known labels are: " ;
00816             for (std::vector<std::string>::const_iterator it = kinResolutionLabels_.begin(); it != kinResolutionLabels_.end(); ++it) {
00817                 ex << "'" << *it << "' ";
00818             }
00819             ex << "\n";
00820             throw ex;
00821         } else {
00822             if (kinResolutionLabels_.size()+1 == kinResolutions_.size()) {
00823                 // skip un-labelled resolution
00824                 return kinResolutions_[match - kinResolutionLabels_.begin() + 1];
00825             } else {
00826                 // all are labelled, so this is the real index
00827                 return kinResolutions_[match - kinResolutionLabels_.begin()];
00828             }
00829         }
00830     }
00831   }
00832 
00833   template <class ObjectType>
00834   bool PATObject<ObjectType>::hasKinResolution(const std::string &label) const {
00835     if (label.empty()) {
00836         return (kinResolutionLabels_.size()+1 == kinResolutions_.size());
00837     } else {
00838         std::vector<std::string>::const_iterator match = std::find(kinResolutionLabels_.begin(), kinResolutionLabels_.end(), label);
00839         return match != kinResolutionLabels_.end();
00840     }
00841   }
00842 
00843   template <class ObjectType>
00844   void PATObject<ObjectType>::setKinResolution(const pat::CandKinResolution &resol, const std::string &label) {
00845     if (label.empty()) {
00846         if (kinResolutionLabels_.size()+1 == kinResolutions_.size()) {
00847             // There is already an un-labelled object. Replace it
00848             kinResolutions_[0] = resol;
00849         } else {
00850             // Insert. Note that the un-labelled is always the first, so we need to insert before begin()
00851             // (for an empty vector, this should not cost more than push_back)
00852             kinResolutions_.insert(kinResolutions_.begin(), resol);
00853         }
00854     } else {
00855         std::vector<std::string>::iterator match = std::find(kinResolutionLabels_.begin(), kinResolutionLabels_.end(), label);
00856         if (match != kinResolutionLabels_.end()) {
00857             // Existing object: replace
00858             if (kinResolutionLabels_.size()+1 == kinResolutions_.size()) {
00859                 kinResolutions_[(match - kinResolutionLabels_.begin())+1] = resol;
00860             } else {
00861                 kinResolutions_[(match - kinResolutionLabels_.begin())] = resol;
00862             }
00863         } else {
00864             kinResolutionLabels_.push_back(label);
00865             kinResolutions_.push_back(resol);
00866         }
00867     }
00868   }
00869 
00870 
00871 
00872 
00873 }
00874 
00875 #endif