00001
00002
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/TriggerPrimitive.h"
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
00059
00060
00062 const reco::Candidate * originalObject() const;
00064 const edm::Ptr<reco::Candidate> & originalObjectRef() const;
00065
00067 const std::vector<TriggerPrimitive> & triggerMatches() const;
00068 const std::vector<TriggerPrimitive> triggerMatchesByFilter(const std::string & aFilt) const;
00070 void addTriggerMatch(const pat::TriggerPrimitive & aTrigPrim);
00072 const TriggerObjectStandAloneCollection & triggerObjectMatches() const;
00073 const TriggerObjectStandAloneCollection triggerObjectMatchesByFilterID( const unsigned id ) const;
00074 const TriggerObjectStandAloneCollection triggerObjectMatchesByCollection( const std::string & coll ) const;
00075 const TriggerObjectStandAloneCollection triggerObjectMatchesByFilter( const std::string & labelFilter ) const;
00076 const TriggerObjectStandAloneCollection triggerObjectMatchesByPath( const std::string & namePath ) const;
00078 void addTriggerObjectMatch( const TriggerObjectStandAlone & trigObj );
00079
00081 const pat::LookupTableRecord & efficiency(const std::string &name) const ;
00083 std::vector<std::pair<std::string,pat::LookupTableRecord> > efficiencies() const ;
00085 const std::vector<std::string> & efficiencyNames() const { return efficiencyNames_; }
00087 const std::vector<pat::LookupTableRecord> & efficiencyValues() const { return efficiencyValues_; }
00091 void setEfficiency(const std::string &name, const pat::LookupTableRecord & value) ;
00092
00095 reco::GenParticleRef genParticleRef(size_t idx=0) const {
00096 if (idx >= genParticlesSize()) return reco::GenParticleRef();
00097 return genParticleEmbedded_.empty() ? genParticleRef_[idx] : reco::GenParticleRef(&genParticleEmbedded_, idx);
00098 }
00102 reco::GenParticleRef genParticleById(int pdgId, int status) const ;
00103
00106 const reco::GenParticle * genParticle(size_t idx=0) const {
00107 reco::GenParticleRef ref = genParticleRef(idx);
00108 return ref.isNonnull() ? ref.get() : 0;
00109 }
00111 size_t genParticlesSize() const {
00112 return genParticleEmbedded_.empty() ? genParticleRef_.size() : genParticleEmbedded_.size();
00113 }
00116 std::vector<reco::GenParticleRef> genParticleRefs() const ;
00117
00119 void setGenParticleRef(const reco::GenParticleRef &ref, bool embed=false) ;
00122 void addGenParticleRef(const reco::GenParticleRef &ref) ;
00124 void setGenParticle( const reco::GenParticle &particle ) ;
00127 void embedGenParticle() ;
00128
00130 bool hasOverlaps(const std::string &label) const ;
00133 const reco::CandidatePtrVector & overlaps(const std::string &label) const ;
00135 const std::vector<std::string> & overlapLabels() const { return overlapLabels_; }
00139 void setOverlaps(const std::string &label, const reco::CandidatePtrVector & overlaps) ;
00140
00142 template<typename T> const T * userData(const std::string &key) const {
00143 const pat::UserData * data = userDataObject_(key);
00144 return (data != 0 ? data->template get<T>() : 0);
00145
00146 }
00148 bool hasUserData(const std::string &key) const {
00149 return (userDataObject_(key) != 0);
00150 }
00152 const std::string & userDataObjectType(const std::string &key) const {
00153 static const std::string EMPTY("");
00154 const pat::UserData * data = userDataObject_(key);
00155 return (data != 0 ? data->typeName() : EMPTY);
00156 };
00158 const std::vector<std::string> & userDataNames() const { return userDataLabels_; }
00159
00162 const void * userDataBare(const std::string &key) const {
00163 const pat::UserData * data = userDataObject_(key);
00164 return (data != 0 ? data->bareData() : 0);
00165 }
00166
00171 template<typename T>
00172 void addUserData( const std::string & label, const T & data, bool transientOnly=false ) {
00173 userDataLabels_.push_back(label);
00174 userDataObjects_.push_back(pat::UserData::make<T>(data, transientOnly));
00175 }
00176
00179 void addUserDataFromPtr( const std::string & label, const edm::Ptr<pat::UserData> & data ) {
00180 userDataLabels_.push_back(label);
00181 userDataObjects_.push_back(data->clone());
00182 }
00183
00186 float userFloat( const std::string & key ) const;
00188 void addUserFloat( const std::string & label, float data );
00190 const std::vector<std::string> & userFloatNames() const { return userFloatLabels_; }
00192 bool hasUserFloat( const std::string & key ) const {
00193 return std::find(userFloatLabels_.begin(), userFloatLabels_.end(), key) != userFloatLabels_.end();
00194 }
00197 int32_t userInt( const std::string & key ) const;
00199 void addUserInt( const std::string & label, int32_t data );
00201 const std::vector<std::string> & userIntNames() const { return userIntLabels_; }
00203 bool hasUserInt( const std::string & key ) const {
00204 return std::find(userIntLabels_.begin(), userIntLabels_.end(), key) != userIntLabels_.end();
00205 }
00206
00207
00210 const pat::CandKinResolution & getKinResolution(const std::string &label="") const ;
00211
00213 bool hasKinResolution(const std::string &label="") const ;
00214
00216 void setKinResolution(const pat::CandKinResolution &resol, const std::string &label="") ;
00217
00219 double resolEta(const std::string &label="") const { return getKinResolution(label).resolEta(this->p4()); }
00220
00222 double resolTheta(const std::string &label="") const { return getKinResolution(label).resolTheta(this->p4()); }
00223
00225 double resolPhi(const std::string &label="") const { return getKinResolution(label).resolPhi(this->p4()); }
00226
00228 double resolE(const std::string &label="") const { return getKinResolution(label).resolE(this->p4()); }
00229
00231 double resolEt(const std::string &label="") const { return getKinResolution(label).resolEt(this->p4()); }
00232
00234 double resolP(const std::string &label="") const { return getKinResolution(label).resolP(this->p4()); }
00235
00237 double resolPt(const std::string &label="") const { return getKinResolution(label).resolPt(this->p4()); }
00238
00240 double resolPInv(const std::string &label="") const { return getKinResolution(label).resolPInv(this->p4()); }
00241
00243 double resolPx(const std::string &label="") const { return getKinResolution(label).resolPx(this->p4()); }
00244
00246 double resolPy(const std::string &label="") const { return getKinResolution(label).resolPy(this->p4()); }
00247
00249 double resolPz(const std::string &label="") const { return getKinResolution(label).resolPz(this->p4()); }
00250
00253 double resolM(const std::string &label="") const { return getKinResolution(label).resolM(this->p4()); }
00254
00255
00256 protected:
00257
00258 edm::Ptr<reco::Candidate> refToOrig_;
00259
00261 std::vector<pat::TriggerPrimitive> triggerMatches_;
00263 TriggerObjectStandAloneCollection triggerObjectMatchesEmbedded_;
00264
00266 std::vector<pat::LookupTableRecord> efficiencyValues_;
00268 std::vector<std::string> efficiencyNames_;
00269
00271 std::vector<reco::GenParticleRef> genParticleRef_;
00273 std::vector<reco::GenParticle> genParticleEmbedded_;
00274
00276 std::vector<std::string> overlapLabels_;
00278 std::vector<reco::CandidatePtrVector> overlapItems_;
00279
00281 std::vector<std::string> userDataLabels_;
00282 pat::UserDataCollection userDataObjects_;
00283
00284 std::vector<std::string> userFloatLabels_;
00285 std::vector<float> userFloats_;
00286
00287 std::vector<std::string> userIntLabels_;
00288 std::vector<int32_t> userInts_;
00289
00291 std::vector<pat::CandKinResolution> kinResolutions_;
00294 std::vector<std::string> kinResolutionLabels_;
00295
00296 private:
00297 const pat::UserData * userDataObject_(const std::string &key) const ;
00298 };
00299
00300
00301 template <class ObjectType> PATObject<ObjectType>::PATObject() {
00302 }
00303
00304 template <class ObjectType> PATObject<ObjectType>::PATObject(const ObjectType & obj) :
00305 ObjectType(obj),
00306 refToOrig_() {
00307 }
00308
00309 template <class ObjectType> PATObject<ObjectType>::PATObject(const edm::RefToBase<ObjectType> & ref) :
00310 ObjectType(*ref),
00311 refToOrig_(ref.id(), ref.get(), ref.key())
00312
00313 {
00314 }
00315
00316 template <class ObjectType> PATObject<ObjectType>::PATObject(const edm::Ptr<ObjectType> & ref) :
00317 ObjectType(*ref),
00318 refToOrig_(ref) {
00319 }
00320
00321
00322 template <class ObjectType> const reco::Candidate * PATObject<ObjectType>::originalObject() const {
00323 if (refToOrig_.isNull()) {
00324
00325
00326 return 0;
00327 } else if (!refToOrig_.isAvailable()) {
00328 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.";
00329 } else {
00330 return refToOrig_.get();
00331 }
00332 }
00333
00334 template <class ObjectType>
00335 const edm::Ptr<reco::Candidate> & PATObject<ObjectType>::originalObjectRef() const { return refToOrig_; }
00336
00337 template <class ObjectType>
00338 const std::vector<TriggerPrimitive> & PATObject<ObjectType>::triggerMatches() const { return triggerMatches_; }
00339
00340 template <class ObjectType>
00341 const std::vector<TriggerPrimitive> PATObject<ObjectType>::triggerMatchesByFilter(const std::string & aFilt) const {
00342 std::vector<TriggerPrimitive> selectedMatches;
00343 for ( size_t i = 0; i < triggerMatches_.size(); i++ ) {
00344 if ( triggerMatches_.at(i).filterName() == aFilt ) selectedMatches.push_back(triggerMatches_.at(i));
00345 }
00346 return selectedMatches;
00347 }
00348
00349 template <class ObjectType>
00350 void PATObject<ObjectType>::addTriggerMatch(const pat::TriggerPrimitive & aTrigPrim) {
00351 triggerMatches_.push_back(aTrigPrim);
00352 }
00353
00354 template <class ObjectType>
00355 const TriggerObjectStandAloneCollection & PATObject<ObjectType>::triggerObjectMatches() const { return triggerObjectMatchesEmbedded_; }
00356
00357 template <class ObjectType>
00358 const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByFilterID( const unsigned id ) const {
00359 TriggerObjectStandAloneCollection matches;
00360 for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00361 if ( triggerObjectMatches().at( i ).hasFilterId( id ) ) matches.push_back( triggerObjectMatches().at( i ) );
00362 }
00363 return matches;
00364 }
00365
00366 template <class ObjectType>
00367 const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByCollection( const std::string & coll ) const {
00368 TriggerObjectStandAloneCollection matches;
00369 for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00370 if ( triggerObjectMatches().at( i ).collection() == coll ) matches.push_back( triggerObjectMatches().at( i ) );
00371 }
00372 return matches;
00373 }
00374
00375 template <class ObjectType>
00376 const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByFilter( const std::string & labelFilter ) const {
00377 TriggerObjectStandAloneCollection matches;
00378 for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00379 if ( triggerObjectMatches().at( i ).hasFilterLabel( labelFilter ) ) matches.push_back( triggerObjectMatches().at( i ) );
00380 }
00381 return matches;
00382 }
00383
00384 template <class ObjectType>
00385 const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByPath( const std::string & namePath ) const {
00386 TriggerObjectStandAloneCollection matches;
00387 for ( size_t i = 0; i < triggerObjectMatches().size(); ++i ) {
00388 if ( triggerObjectMatches().at( i ).hasPathName( namePath ) ) matches.push_back( triggerObjectMatches().at( i ) );
00389 }
00390 return matches;
00391 }
00392
00393 template <class ObjectType>
00394 void PATObject<ObjectType>::addTriggerObjectMatch( const TriggerObjectStandAlone & trigObj ) {
00395 triggerObjectMatchesEmbedded_.push_back( trigObj );
00396 }
00397
00398 template <class ObjectType>
00399 const pat::LookupTableRecord &
00400 PATObject<ObjectType>::efficiency(const std::string &name) const {
00401
00402 std::vector<std::string>::const_iterator it = std::lower_bound(efficiencyNames_.begin(), efficiencyNames_.end(), name);
00403 if ((it == efficiencyNames_.end()) || (*it != name)) {
00404 throw cms::Exception("Invalid Label") << "There is no efficiency with name '" << name << "' in this PAT Object\n";
00405 }
00406 return efficiencyValues_[it - efficiencyNames_.begin()];
00407 }
00408
00409 template <class ObjectType>
00410 std::vector<std::pair<std::string,pat::LookupTableRecord> >
00411 PATObject<ObjectType>::efficiencies() const {
00412 std::vector<std::pair<std::string,pat::LookupTableRecord> > ret;
00413 std::vector<std::string>::const_iterator itn = efficiencyNames_.begin(), edn = efficiencyNames_.end();
00414 std::vector<pat::LookupTableRecord>::const_iterator itv = efficiencyValues_.begin();
00415 for ( ; itn != edn; ++itn, ++itv) {
00416 ret.push_back( std::pair<std::string,pat::LookupTableRecord>(*itn, *itv) );
00417 }
00418 return ret;
00419 }
00420
00421 template <class ObjectType>
00422 void PATObject<ObjectType>::setEfficiency(const std::string &name, const pat::LookupTableRecord & value) {
00423
00424 std::vector<std::string>::iterator it = std::lower_bound(efficiencyNames_.begin(), efficiencyNames_.end(), name);
00425 if (it == efficiencyNames_.end()) {
00426 efficiencyNames_.push_back(name);
00427 efficiencyValues_.push_back(value);
00428 } else if (*it == name) {
00429 efficiencyValues_[it - efficiencyNames_.begin()] = value;
00430 } else {
00431 efficiencyNames_. insert(it, name);
00432 efficiencyValues_.insert( efficiencyValues_.begin() + (it - efficiencyNames_.begin()), value );
00433 }
00434 }
00435
00436 template <class ObjectType>
00437 void PATObject<ObjectType>::setGenParticleRef(const reco::GenParticleRef &ref, bool embed) {
00438 genParticleRef_ = std::vector<reco::GenParticleRef>(1,ref);
00439 genParticleEmbedded_.clear();
00440 if (embed) embedGenParticle();
00441 }
00442
00443 template <class ObjectType>
00444 void PATObject<ObjectType>::addGenParticleRef(const reco::GenParticleRef &ref) {
00445 if (!genParticleEmbedded_.empty()) {
00446 if (ref.isNonnull()) genParticleEmbedded_.push_back(*ref);
00447 } else {
00448 genParticleRef_.push_back(ref);
00449 }
00450 }
00451
00452 template <class ObjectType>
00453 void PATObject<ObjectType>::setGenParticle( const reco::GenParticle &particle ) {
00454 genParticleEmbedded_.clear();
00455 genParticleEmbedded_.push_back(particle);
00456 genParticleRef_.clear();
00457 }
00458
00459 template <class ObjectType>
00460 void PATObject<ObjectType>::embedGenParticle() {
00461 genParticleEmbedded_.clear();
00462 for (std::vector<reco::GenParticleRef>::const_iterator it = genParticleRef_.begin(); it != genParticleRef_.end(); ++it) {
00463 if (it->isNonnull()) genParticleEmbedded_.push_back(**it);
00464 }
00465 genParticleRef_.clear();
00466 }
00467
00468 template <class ObjectType>
00469 std::vector<reco::GenParticleRef> PATObject<ObjectType>::genParticleRefs() const {
00470 if (genParticleEmbedded_.empty()) return genParticleRef_;
00471 std::vector<reco::GenParticleRef> ret(genParticleEmbedded_.size());
00472 for (size_t i = 0, n = ret.size(); i < n; ++i) {
00473 ret[i] = reco::GenParticleRef(&genParticleEmbedded_, i);
00474 }
00475 return ret;
00476 }
00477
00478 template <class ObjectType>
00479 reco::GenParticleRef PATObject<ObjectType>::genParticleById(int pdgId, int status) const {
00480
00481 const std::vector<reco::GenParticleRef> & vec = (genParticleEmbedded_.empty() ? genParticleRef_ : genParticleRefs());
00482 for (std::vector<reco::GenParticleRef>::const_iterator ref = vec.begin(), end = vec.end(); ref != end; ++ref) {
00483 if (ref->isNonnull() && ((*ref)->pdgId() == pdgId) && ((*ref)->status() == status)) return *ref;
00484 }
00485 return reco::GenParticleRef();
00486 }
00487
00488 template <class ObjectType>
00489 bool PATObject<ObjectType>::hasOverlaps(const std::string &label) const {
00490 return std::find(overlapLabels_.begin(), overlapLabels_.end(), label) != overlapLabels_.end();
00491 }
00492
00493 template <class ObjectType>
00494 const reco::CandidatePtrVector & PATObject<ObjectType>::overlaps(const std::string &label) const {
00495 static const reco::CandidatePtrVector EMPTY;
00496 std::vector<std::string>::const_iterator match = std::find(overlapLabels_.begin(), overlapLabels_.end(), label);
00497 if (match == overlapLabels_.end()) return EMPTY;
00498 return overlapItems_[match - overlapLabels_.begin()];
00499 }
00500
00501 template <class ObjectType>
00502 void PATObject<ObjectType>::setOverlaps(const std::string &label, const reco::CandidatePtrVector & overlaps) {
00503 if (!overlaps.empty()) {
00504 std::vector<std::string>::const_iterator match = std::find(overlapLabels_.begin(), overlapLabels_.end(), label);
00505 if (match == overlapLabels_.end()) {
00506 overlapLabels_.push_back(label);
00507 overlapItems_.push_back(overlaps);
00508 } else {
00509 overlapItems_[match - overlapLabels_.begin()] = overlaps;
00510 }
00511 }
00512 }
00513
00514 template <class ObjectType>
00515 const pat::UserData * PATObject<ObjectType>::userDataObject_( const std::string & key ) const
00516 {
00517 std::vector<std::string>::const_iterator it = std::find(userDataLabels_.begin(), userDataLabels_.end(), key);
00518 if (it != userDataLabels_.end()) {
00519 return & userDataObjects_[it - userDataLabels_.begin()];
00520 }
00521 return 0;
00522 }
00523
00524 template <class ObjectType>
00525 float PATObject<ObjectType>::userFloat( const std::string &key ) const
00526 {
00527 std::vector<std::string>::const_iterator it = std::find(userFloatLabels_.begin(), userFloatLabels_.end(), key);
00528 if (it != userFloatLabels_.end()) {
00529 return userFloats_[it - userFloatLabels_.begin()];
00530 }
00531 return 0.0;
00532 }
00533
00534 template <class ObjectType>
00535 void PATObject<ObjectType>::addUserFloat( const std::string & label,
00536 float data )
00537 {
00538 userFloatLabels_.push_back(label);
00539 userFloats_.push_back( data );
00540 }
00541
00542
00543 template <class ObjectType>
00544 int PATObject<ObjectType>::userInt( const std::string & key ) const
00545 {
00546 std::vector<std::string>::const_iterator it = std::find(userIntLabels_.begin(), userIntLabels_.end(), key);
00547 if (it != userIntLabels_.end()) {
00548 return userInts_[it - userIntLabels_.begin()];
00549 }
00550 return 0;
00551 }
00552
00553 template <class ObjectType>
00554 void PATObject<ObjectType>::addUserInt( const std::string &label,
00555 int data )
00556 {
00557 userIntLabels_.push_back(label);
00558 userInts_.push_back( data );
00559 }
00560
00561 template <class ObjectType>
00562 const pat::CandKinResolution & PATObject<ObjectType>::getKinResolution(const std::string &label) const {
00563 if (label.empty()) {
00564 if (kinResolutionLabels_.size()+1 == kinResolutions_.size()) {
00565 return kinResolutions_[0];
00566 } else {
00567 throw cms::Exception("Missing Data", "This object does not contain an un-labelled kinematic resolution");
00568 }
00569 } else {
00570 std::vector<std::string>::const_iterator match = std::find(kinResolutionLabels_.begin(), kinResolutionLabels_.end(), label);
00571 if (match == kinResolutionLabels_.end()) {
00572 cms::Exception ex("Missing Data");
00573 ex << "This object does not contain a kinematic resolution with name '" << label << "'.\n";
00574 ex << "The known labels are: " ;
00575 for (std::vector<std::string>::const_iterator it = kinResolutionLabels_.begin(); it != kinResolutionLabels_.end(); ++it) {
00576 ex << "'" << *it << "' ";
00577 }
00578 ex << "\n";
00579 throw ex;
00580 } else {
00581 if (kinResolutionLabels_.size()+1 == kinResolutions_.size()) {
00582
00583 return kinResolutions_[match - kinResolutionLabels_.begin() + 1];
00584 } else {
00585
00586 return kinResolutions_[match - kinResolutionLabels_.begin()];
00587 }
00588 }
00589 }
00590 }
00591
00592 template <class ObjectType>
00593 bool PATObject<ObjectType>::hasKinResolution(const std::string &label) const {
00594 if (label.empty()) {
00595 return (kinResolutionLabels_.size()+1 == kinResolutions_.size());
00596 } else {
00597 std::vector<std::string>::const_iterator match = std::find(kinResolutionLabels_.begin(), kinResolutionLabels_.end(), label);
00598 return match != kinResolutionLabels_.end();
00599 }
00600 }
00601
00602 template <class ObjectType>
00603 void PATObject<ObjectType>::setKinResolution(const pat::CandKinResolution &resol, const std::string &label) {
00604 if (label.empty()) {
00605 if (kinResolutionLabels_.size()+1 == kinResolutions_.size()) {
00606
00607 kinResolutions_[0] = resol;
00608 } else {
00609
00610
00611 kinResolutions_.insert(kinResolutions_.begin(), resol);
00612 }
00613 } else {
00614 std::vector<std::string>::iterator match = std::find(kinResolutionLabels_.begin(), kinResolutionLabels_.end(), label);
00615 if (match != kinResolutionLabels_.end()) {
00616
00617 if (kinResolutionLabels_.size()+1 == kinResolutions_.size()) {
00618 kinResolutions_[(match - kinResolutionLabels_.begin())+1] = resol;
00619 } else {
00620 kinResolutions_[(match - kinResolutionLabels_.begin())] = resol;
00621 }
00622 } else {
00623 kinResolutionLabels_.push_back(label);
00624 kinResolutions_.push_back(resol);
00625 }
00626 }
00627 }
00628
00629
00630
00631 }
00632
00633 #endif