File indexing completed on 2024-04-06 12:04:55
0001
0002
0003
0004 #ifndef DataFormats_PatCandidates_PATObject_h
0005 #define DataFormats_PatCandidates_PATObject_h
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include "DataFormats/Common/interface/Ptr.h"
0020 #include "DataFormats/Candidate/interface/CandidateFwd.h"
0021 #include "DataFormats/Candidate/interface/Candidate.h"
0022 #include <vector>
0023 #include <string>
0024 #include <iosfwd>
0025
0026 #include "DataFormats/PatCandidates/interface/TriggerObjectStandAlone.h"
0027 #include "DataFormats/PatCandidates/interface/LookupTableRecord.h"
0028
0029 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
0030
0031 #include "DataFormats/PatCandidates/interface/UserData.h"
0032 #include "DataFormats/Common/interface/OwnVector.h"
0033
0034 #include "DataFormats/PatCandidates/interface/CandKinResolution.h"
0035
0036 #include "DataFormats/PatCandidates/interface/throwMissingLabel.h"
0037
0038 namespace pat {
0039 const reco::CandidatePtrVector &get_empty_cpv();
0040 const std::string &get_empty_str();
0041
0042 template <class ObjectType>
0043 class PATObject : public ObjectType {
0044 public:
0045 typedef ObjectType base_type;
0046
0047
0048 PATObject();
0049
0050 PATObject(const ObjectType &obj);
0051
0052 PATObject(const edm::RefToBase<ObjectType> &ref);
0053
0054 PATObject(const edm::Ptr<ObjectType> &ref);
0055
0056 ~PATObject() override {}
0057
0058
0059
0060
0061 const reco::Candidate *originalObject() const;
0062
0063 const edm::Ptr<reco::Candidate> &originalObjectRef() const;
0064
0065
0066
0067
0068
0069
0070 const TriggerObjectStandAloneCollection &triggerObjectMatches() const { return triggerObjectMatchesEmbedded_; };
0071
0072 const TriggerObjectStandAlone *triggerObjectMatch(const size_t idx = 0) const;
0073
0074
0075 const TriggerObjectStandAloneCollection triggerObjectMatchesByType(
0076 const trigger::TriggerObjectType triggerObjectType) const;
0077 const TriggerObjectStandAloneCollection triggerObjectMatchesByType(const unsigned triggerObjectType) const {
0078 return triggerObjectMatchesByType(trigger::TriggerObjectType(triggerObjectType));
0079 };
0080
0081 const TriggerObjectStandAloneCollection triggerObjectMatchesByFilterID(const unsigned triggerObjectType) const {
0082 return triggerObjectMatchesByType(trigger::TriggerObjectType(triggerObjectType));
0083 };
0084
0085 const TriggerObjectStandAlone *triggerObjectMatchByType(const trigger::TriggerObjectType triggerObjectType,
0086 const size_t idx = 0) const;
0087 const TriggerObjectStandAlone *triggerObjectMatchByType(const unsigned triggerObjectType,
0088 const size_t idx = 0) const {
0089 return triggerObjectMatchByType(trigger::TriggerObjectType(triggerObjectType), idx);
0090 };
0091
0092 const TriggerObjectStandAlone *triggerObjectMatchByFilterID(const unsigned triggerObjectType,
0093 const size_t idx = 0) const {
0094 return triggerObjectMatchByType(trigger::TriggerObjectType(triggerObjectType), idx);
0095 };
0096
0097 const TriggerObjectStandAloneCollection triggerObjectMatchesByCollection(const std::string &coll) const;
0098
0099 const TriggerObjectStandAloneCollection triggerObjectMatchesByCollection(const char *coll) const {
0100 return triggerObjectMatchesByCollection(std::string(coll));
0101 };
0102
0103 const TriggerObjectStandAlone *triggerObjectMatchByCollection(const std::string &coll, const size_t idx = 0) const;
0104
0105 const TriggerObjectStandAlone *triggerObjectMatchByCollection(const char *coll, const size_t idx = 0) const {
0106 return triggerObjectMatchByCollection(std::string(coll), idx);
0107 };
0108
0109 const TriggerObjectStandAloneCollection triggerObjectMatchesByCondition(const std::string &nameCondition) const;
0110
0111 const TriggerObjectStandAloneCollection triggerObjectMatchesByCondition(const char *nameCondition) const {
0112 return triggerObjectMatchesByCondition(std::string(nameCondition));
0113 };
0114
0115 const TriggerObjectStandAlone *triggerObjectMatchByCondition(const std::string &nameCondition,
0116 const size_t idx = 0) const;
0117
0118 const TriggerObjectStandAlone *triggerObjectMatchByCondition(const char *nameCondition,
0119 const size_t idx = 0) const {
0120 return triggerObjectMatchByCondition(std::string(nameCondition), idx);
0121 };
0122
0123
0124
0125 const TriggerObjectStandAloneCollection triggerObjectMatchesByAlgorithm(const std::string &nameAlgorithm,
0126 const bool algoCondAccepted = true) const;
0127
0128 const TriggerObjectStandAloneCollection triggerObjectMatchesByAlgorithm(const char *nameAlgorithm,
0129 const bool algoCondAccepted = true) const {
0130 return triggerObjectMatchesByAlgorithm(std::string(nameAlgorithm), algoCondAccepted);
0131 };
0132
0133 const TriggerObjectStandAloneCollection triggerObjectMatchesByAlgorithm(const std::string &nameAlgorithm,
0134 const unsigned algoCondAccepted) const {
0135 return triggerObjectMatchesByAlgorithm(nameAlgorithm, bool(algoCondAccepted));
0136 };
0137
0138 const TriggerObjectStandAloneCollection triggerObjectMatchesByAlgorithm(const char *nameAlgorithm,
0139 const unsigned algoCondAccepted) const {
0140 return triggerObjectMatchesByAlgorithm(std::string(nameAlgorithm), bool(algoCondAccepted));
0141 };
0142
0143
0144
0145 const TriggerObjectStandAlone *triggerObjectMatchByAlgorithm(const std::string &nameAlgorithm,
0146 const bool algoCondAccepted = true,
0147 const size_t idx = 0) const;
0148
0149 const TriggerObjectStandAlone *triggerObjectMatchByAlgorithm(const char *nameAlgorithm,
0150 const bool algoCondAccepted = true,
0151 const size_t idx = 0) const {
0152 return triggerObjectMatchByAlgorithm(std::string(nameAlgorithm), algoCondAccepted, idx);
0153 };
0154
0155 const TriggerObjectStandAlone *triggerObjectMatchByAlgorithm(const std::string &nameAlgorithm,
0156 const unsigned algoCondAccepted,
0157 const size_t idx = 0) const {
0158 return triggerObjectMatchByAlgorithm(nameAlgorithm, bool(algoCondAccepted), idx);
0159 };
0160
0161 const TriggerObjectStandAlone *triggerObjectMatchByAlgorithm(const char *nameAlgorithm,
0162 const unsigned algoCondAccepted,
0163 const size_t idx = 0) const {
0164 return triggerObjectMatchByAlgorithm(std::string(nameAlgorithm), bool(algoCondAccepted), idx);
0165 };
0166
0167 const TriggerObjectStandAloneCollection triggerObjectMatchesByFilter(const std::string &labelFilter) const;
0168
0169 const TriggerObjectStandAloneCollection triggerObjectMatchesByFilter(const char *labelFilter) const {
0170 return triggerObjectMatchesByFilter(std::string(labelFilter));
0171 };
0172
0173 const TriggerObjectStandAlone *triggerObjectMatchByFilter(const std::string &labelFilter,
0174 const size_t idx = 0) const;
0175
0176 const TriggerObjectStandAlone *triggerObjectMatchByFilter(const char *labelFilter, const size_t idx = 0) const {
0177 return triggerObjectMatchByFilter(std::string(labelFilter), idx);
0178 };
0179
0180
0181
0182
0183
0184 const TriggerObjectStandAloneCollection triggerObjectMatchesByPath(const std::string &namePath,
0185 const bool pathLastFilterAccepted = false,
0186 const bool pathL3FilterAccepted = true) const;
0187
0188 const TriggerObjectStandAloneCollection triggerObjectMatchesByPath(const char *namePath,
0189 const bool pathLastFilterAccepted = false,
0190 const bool pathL3FilterAccepted = true) const {
0191 return triggerObjectMatchesByPath(std::string(namePath), pathLastFilterAccepted, pathL3FilterAccepted);
0192 };
0193
0194 const TriggerObjectStandAloneCollection triggerObjectMatchesByPath(const std::string &namePath,
0195 const unsigned pathLastFilterAccepted,
0196 const unsigned pathL3FilterAccepted = 1) const {
0197 return triggerObjectMatchesByPath(namePath, bool(pathLastFilterAccepted), bool(pathL3FilterAccepted));
0198 };
0199
0200 const TriggerObjectStandAloneCollection triggerObjectMatchesByPath(const char *namePath,
0201 const unsigned pathLastFilterAccepted,
0202 const unsigned pathL3FilterAccepted = 1) const {
0203 return triggerObjectMatchesByPath(
0204 std::string(namePath), bool(pathLastFilterAccepted), bool(pathL3FilterAccepted));
0205 };
0206
0207
0208
0209
0210
0211 const TriggerObjectStandAlone *triggerObjectMatchByPath(const std::string &namePath,
0212 const bool pathLastFilterAccepted = false,
0213 const bool pathL3FilterAccepted = true,
0214 const size_t idx = 0) const;
0215
0216 const TriggerObjectStandAlone *triggerObjectMatchByPath(const char *namePath,
0217 const bool pathLastFilterAccepted = false,
0218 const bool pathL3FilterAccepted = true,
0219 const size_t idx = 0) const {
0220 return triggerObjectMatchByPath(std::string(namePath), pathLastFilterAccepted, pathL3FilterAccepted, idx);
0221 };
0222
0223 const TriggerObjectStandAlone *triggerObjectMatchByPath(const std::string &namePath,
0224 const unsigned pathLastFilterAccepted,
0225 const unsigned pathL3FilterAccepted = 1,
0226 const size_t idx = 0) const {
0227 return triggerObjectMatchByPath(namePath, bool(pathLastFilterAccepted), bool(pathL3FilterAccepted), idx);
0228 };
0229
0230 const TriggerObjectStandAlone *triggerObjectMatchByPath(const char *namePath,
0231 const unsigned pathLastFilterAccepted,
0232 const unsigned pathL3FilterAccepted = 1,
0233 const size_t idx = 0) const {
0234 return triggerObjectMatchByPath(
0235 std::string(namePath), bool(pathLastFilterAccepted), bool(pathL3FilterAccepted), idx);
0236 };
0237
0238 void addTriggerObjectMatch(const TriggerObjectStandAlone &trigObj) {
0239 triggerObjectMatchesEmbedded_.push_back(trigObj);
0240 };
0241
0242 void unpackTriggerObjectPathNames(const edm::TriggerNames &names) {
0243 for (std::vector<TriggerObjectStandAlone>::iterator it = triggerObjectMatchesEmbedded_.begin(),
0244 ed = triggerObjectMatchesEmbedded_.end();
0245 it != ed;
0246 ++it)
0247 it->unpackPathNames(names);
0248 }
0249
0250
0251 const pat::LookupTableRecord &efficiency(const std::string &name) const;
0252
0253 std::vector<std::pair<std::string, pat::LookupTableRecord> > efficiencies() const;
0254
0255 const std::vector<std::string> &efficiencyNames() const { return efficiencyNames_; }
0256
0257 const std::vector<pat::LookupTableRecord> &efficiencyValues() const { return efficiencyValues_; }
0258
0259
0260
0261 void setEfficiency(const std::string &name, const pat::LookupTableRecord &value);
0262
0263
0264
0265 reco::GenParticleRef genParticleRef(size_t idx = 0) const {
0266 if (idx >= genParticlesSize())
0267 return reco::GenParticleRef();
0268 return genParticleEmbedded_.empty() ? genParticleRef_[idx] : reco::GenParticleRef(&genParticleEmbedded_, idx);
0269 }
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281 reco::GenParticleRef genParticleById(int pdgId, int status, uint8_t autoCharge = 0) const;
0282
0283
0284
0285 const reco::GenParticle *genParticle(size_t idx = 0) const {
0286 reco::GenParticleRef ref = genParticleRef(idx);
0287 return ref.isNonnull() ? ref.get() : nullptr;
0288 }
0289
0290 size_t genParticlesSize() const {
0291 return genParticleEmbedded_.empty() ? genParticleRef_.size() : genParticleEmbedded_.size();
0292 }
0293
0294
0295 std::vector<reco::GenParticleRef> genParticleRefs() const;
0296
0297
0298 void setGenParticleRef(const reco::GenParticleRef &ref, bool embed = false);
0299
0300
0301 void addGenParticleRef(const reco::GenParticleRef &ref);
0302
0303 void setGenParticle(const reco::GenParticle &particle);
0304
0305
0306 void embedGenParticle();
0307
0308
0309 bool hasOverlaps(const std::string &label) const;
0310
0311
0312 const reco::CandidatePtrVector &overlaps(const std::string &label) const;
0313
0314 const std::vector<std::string> &overlapLabels() const { return overlapLabels_; }
0315
0316
0317
0318 void setOverlaps(const std::string &label, const reco::CandidatePtrVector &overlaps);
0319
0320
0321 template <typename T>
0322 const T *userData(const std::string &key) const {
0323 const pat::UserData *data = userDataObject_(key);
0324 return (data != nullptr ? data->template get<T>() : nullptr);
0325 }
0326
0327 bool hasUserData(const std::string &key) const { return (userDataObject_(key) != nullptr); }
0328
0329 const std::string &userDataObjectType(const std::string &key) const {
0330 const pat::UserData *data = userDataObject_(key);
0331 return (data != nullptr ? data->typeName() : get_empty_str());
0332 };
0333
0334 const std::vector<std::string> &userDataNames() const { return userDataLabels_; }
0335
0336
0337
0338 const void *userDataBare(const std::string &key) const {
0339 const pat::UserData *data = userDataObject_(key);
0340 return (data != nullptr ? data->bareData() : nullptr);
0341 }
0342
0343
0344
0345
0346
0347 template <typename T>
0348 void addUserData(const std::string &label, const T &data, bool transientOnly = false, bool overwrite = false) {
0349 std::unique_ptr<pat::UserData> made(pat::UserData::make<T>(data, transientOnly));
0350 addUserDataObject_(label, std::move(made), overwrite);
0351 }
0352
0353
0354
0355 void addUserDataFromPtr(const std::string &label, const edm::Ptr<pat::UserData> &data, bool overwrite = false) {
0356 std::unique_ptr<pat::UserData> cloned(data->clone());
0357 addUserDataObject_(label, std::move(cloned), overwrite);
0358 }
0359
0360
0361
0362 float userFloat(const std::string &key) const;
0363
0364 std::vector<float> userFloatRange(const std::string &key) const;
0365
0366 float userFloat(const char *key) const { return userFloat(std::string(key)); }
0367
0368
0369 void addUserFloat(const std::string &label, float data, const bool overwrite = false);
0370
0371 const std::vector<std::string> &userFloatNames() const { return userFloatLabels_; }
0372
0373 bool hasUserFloat(const std::string &key) const {
0374 auto it = std::lower_bound(userFloatLabels_.cbegin(), userFloatLabels_.cend(), key);
0375 return (it != userFloatLabels_.cend() && *it == key);
0376 }
0377
0378 bool hasUserFloat(const char *key) const { return hasUserFloat(std::string(key)); }
0379
0380
0381
0382 int32_t userInt(const std::string &key) const;
0383
0384 std::vector<int> userIntRange(const std::string &key) const;
0385
0386 void addUserInt(const std::string &label, int32_t data, const bool overwrite = false);
0387
0388 const std::vector<std::string> &userIntNames() const { return userIntLabels_; }
0389
0390 bool hasUserInt(const std::string &key) const {
0391 auto it = std::lower_bound(userIntLabels_.cbegin(), userIntLabels_.cend(), key);
0392 return (it != userIntLabels_.cend() && *it == key);
0393 }
0394
0395
0396
0397 reco::CandidatePtr userCand(const std::string &key) const;
0398
0399 void addUserCand(const std::string &label, const reco::CandidatePtr &data, const bool overwrite = false);
0400
0401 const std::vector<std::string> &userCandNames() const { return userCandLabels_; }
0402
0403 bool hasUserCand(const std::string &key) const {
0404 auto it = std::lower_bound(userCandLabels_.cbegin(), userCandLabels_.cend(), key);
0405 return (it != userCandLabels_.cend() && *it == key);
0406 }
0407
0408
0409
0410
0411 const pat::CandKinResolution &getKinResolution(const std::string &label = "") const;
0412
0413
0414 bool hasKinResolution(const std::string &label = "") const;
0415
0416
0417 void setKinResolution(const pat::CandKinResolution &resol, const std::string &label = "");
0418
0419
0420 double resolEta(const std::string &label = "") const { return getKinResolution(label).resolEta(this->p4()); }
0421
0422
0423 double resolTheta(const std::string &label = "") const { return getKinResolution(label).resolTheta(this->p4()); }
0424
0425
0426 double resolPhi(const std::string &label = "") const { return getKinResolution(label).resolPhi(this->p4()); }
0427
0428
0429 double resolE(const std::string &label = "") const { return getKinResolution(label).resolE(this->p4()); }
0430
0431
0432 double resolEt(const std::string &label = "") const { return getKinResolution(label).resolEt(this->p4()); }
0433
0434
0435 double resolP(const std::string &label = "") const { return getKinResolution(label).resolP(this->p4()); }
0436
0437
0438 double resolPt(const std::string &label = "") const { return getKinResolution(label).resolPt(this->p4()); }
0439
0440
0441 double resolPInv(const std::string &label = "") const { return getKinResolution(label).resolPInv(this->p4()); }
0442
0443
0444 double resolPx(const std::string &label = "") const { return getKinResolution(label).resolPx(this->p4()); }
0445
0446
0447 double resolPy(const std::string &label = "") const { return getKinResolution(label).resolPy(this->p4()); }
0448
0449
0450 double resolPz(const std::string &label = "") const { return getKinResolution(label).resolPz(this->p4()); }
0451
0452
0453
0454 double resolM(const std::string &label = "") const { return getKinResolution(label).resolM(this->p4()); }
0455
0456 protected:
0457
0458 edm::Ptr<reco::Candidate> refToOrig_;
0459
0460
0461 TriggerObjectStandAloneCollection triggerObjectMatchesEmbedded_;
0462
0463
0464 std::vector<pat::LookupTableRecord> efficiencyValues_;
0465
0466 std::vector<std::string> efficiencyNames_;
0467
0468
0469 std::vector<reco::GenParticleRef> genParticleRef_;
0470
0471 std::vector<reco::GenParticle> genParticleEmbedded_;
0472
0473
0474 std::vector<std::string> overlapLabels_;
0475
0476 std::vector<reco::CandidatePtrVector> overlapItems_;
0477
0478
0479 std::vector<std::string> userDataLabels_;
0480 pat::UserDataCollection userDataObjects_;
0481
0482 std::vector<std::string> userFloatLabels_;
0483 std::vector<float> userFloats_;
0484
0485 std::vector<std::string> userIntLabels_;
0486 std::vector<int32_t> userInts_;
0487
0488 std::vector<std::string> userCandLabels_;
0489 std::vector<reco::CandidatePtr> userCands_;
0490
0491
0492 std::vector<pat::CandKinResolution> kinResolutions_;
0493
0494
0495 std::vector<std::string> kinResolutionLabels_;
0496
0497 void addUserDataObject_(const std::string &label, std::unique_ptr<pat::UserData> value, bool overwrite = false);
0498
0499 private:
0500 const pat::UserData *userDataObject_(const std::string &key) const;
0501 };
0502
0503 template <class ObjectType>
0504 PATObject<ObjectType>::PATObject() {}
0505
0506 template <class ObjectType>
0507 PATObject<ObjectType>::PATObject(const ObjectType &obj) : ObjectType(obj), refToOrig_() {}
0508
0509 template <class ObjectType>
0510 PATObject<ObjectType>::PATObject(const edm::RefToBase<ObjectType> &ref)
0511 : ObjectType(*ref),
0512 refToOrig_(ref.id(),
0513 ref.get(),
0514 ref.key())
0515
0516 {}
0517
0518 template <class ObjectType>
0519 PATObject<ObjectType>::PATObject(const edm::Ptr<ObjectType> &ref) : ObjectType(*ref), refToOrig_(ref) {}
0520
0521 template <class ObjectType>
0522 const reco::Candidate *PATObject<ObjectType>::originalObject() const {
0523 if (refToOrig_.isNull()) {
0524
0525
0526 return nullptr;
0527 } else if (!refToOrig_.isAvailable()) {
0528 throw edm::Exception(edm::errors::ProductNotFound)
0529 << "The original collection from which this PAT object was made is not present any more in the event, hence "
0530 "you cannot access the originating object anymore.";
0531 } else {
0532 return refToOrig_.get();
0533 }
0534 }
0535
0536 template <class ObjectType>
0537 const edm::Ptr<reco::Candidate> &PATObject<ObjectType>::originalObjectRef() const {
0538 return refToOrig_;
0539 }
0540
0541 template <class ObjectType>
0542 const TriggerObjectStandAlone *PATObject<ObjectType>::triggerObjectMatch(const size_t idx) const {
0543 if (idx >= triggerObjectMatches().size())
0544 return nullptr;
0545 TriggerObjectStandAloneRef ref(&triggerObjectMatchesEmbedded_, idx);
0546 return ref.isNonnull() ? ref.get() : nullptr;
0547 }
0548
0549 template <class ObjectType>
0550 const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByType(
0551 const trigger::TriggerObjectType triggerObjectType) const {
0552 TriggerObjectStandAloneCollection matches;
0553 for (size_t i = 0; i < triggerObjectMatches().size(); ++i) {
0554 if (triggerObjectMatch(i) != 0 && triggerObjectMatch(i)->hasTriggerObjectType(triggerObjectType))
0555 matches.push_back(*(triggerObjectMatch(i)));
0556 }
0557 return matches;
0558 }
0559
0560 template <class ObjectType>
0561 const TriggerObjectStandAlone *PATObject<ObjectType>::triggerObjectMatchByType(
0562 const trigger::TriggerObjectType triggerObjectType, const size_t idx) const {
0563 std::vector<size_t> refs;
0564 for (size_t i = 0; i < triggerObjectMatches().size(); ++i) {
0565 if (triggerObjectMatch(i) != nullptr && triggerObjectMatch(i)->hasTriggerObjectType(triggerObjectType))
0566 refs.push_back(i);
0567 }
0568 if (idx >= refs.size())
0569 return nullptr;
0570 TriggerObjectStandAloneRef ref(&triggerObjectMatchesEmbedded_, refs.at(idx));
0571 return ref.isNonnull() ? ref.get() : nullptr;
0572 }
0573
0574 template <class ObjectType>
0575 const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByCollection(
0576 const std::string &coll) const {
0577 TriggerObjectStandAloneCollection matches;
0578 for (size_t i = 0; i < triggerObjectMatches().size(); ++i) {
0579 if (triggerObjectMatch(i) != 0 && triggerObjectMatch(i)->hasCollection(coll))
0580 matches.push_back(*(triggerObjectMatch(i)));
0581 }
0582 return matches;
0583 }
0584
0585 template <class ObjectType>
0586 const TriggerObjectStandAlone *PATObject<ObjectType>::triggerObjectMatchByCollection(const std::string &coll,
0587 const size_t idx) const {
0588 std::vector<size_t> refs;
0589 for (size_t i = 0; i < triggerObjectMatches().size(); ++i) {
0590 if (triggerObjectMatch(i) != 0 && triggerObjectMatch(i)->hasCollection(coll)) {
0591 refs.push_back(i);
0592 }
0593 }
0594 if (idx >= refs.size())
0595 return nullptr;
0596 TriggerObjectStandAloneRef ref(&triggerObjectMatchesEmbedded_, refs.at(idx));
0597 return ref.isNonnull() ? ref.get() : nullptr;
0598 }
0599
0600 template <class ObjectType>
0601 const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByCondition(
0602 const std::string &nameCondition) const {
0603 TriggerObjectStandAloneCollection matches;
0604 for (size_t i = 0; i < triggerObjectMatches().size(); ++i) {
0605 if (triggerObjectMatch(i) != 0 && triggerObjectMatch(i)->hasConditionName(nameCondition))
0606 matches.push_back(*(triggerObjectMatch(i)));
0607 }
0608 return matches;
0609 }
0610
0611 template <class ObjectType>
0612 const TriggerObjectStandAlone *PATObject<ObjectType>::triggerObjectMatchByCondition(const std::string &nameCondition,
0613 const size_t idx) const {
0614 std::vector<size_t> refs;
0615 for (size_t i = 0; i < triggerObjectMatches().size(); ++i) {
0616 if (triggerObjectMatch(i) != 0 && triggerObjectMatch(i)->hasConditionName(nameCondition))
0617 refs.push_back(i);
0618 }
0619 if (idx >= refs.size())
0620 return nullptr;
0621 TriggerObjectStandAloneRef ref(&triggerObjectMatchesEmbedded_, refs.at(idx));
0622 return ref.isNonnull() ? ref.get() : nullptr;
0623 }
0624
0625 template <class ObjectType>
0626 const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByAlgorithm(
0627 const std::string &nameAlgorithm, const bool algoCondAccepted) const {
0628 TriggerObjectStandAloneCollection matches;
0629 for (size_t i = 0; i < triggerObjectMatches().size(); ++i) {
0630 if (triggerObjectMatch(i) != 0 && triggerObjectMatch(i)->hasAlgorithmName(nameAlgorithm, algoCondAccepted))
0631 matches.push_back(*(triggerObjectMatch(i)));
0632 }
0633 return matches;
0634 }
0635
0636 template <class ObjectType>
0637 const TriggerObjectStandAlone *PATObject<ObjectType>::triggerObjectMatchByAlgorithm(const std::string &nameAlgorithm,
0638 const bool algoCondAccepted,
0639 const size_t idx) const {
0640 std::vector<size_t> refs;
0641 for (size_t i = 0; i < triggerObjectMatches().size(); ++i) {
0642 if (triggerObjectMatch(i) != 0 && triggerObjectMatch(i)->hasAlgorithmName(nameAlgorithm, algoCondAccepted))
0643 refs.push_back(i);
0644 }
0645 if (idx >= refs.size())
0646 return nullptr;
0647 TriggerObjectStandAloneRef ref(&triggerObjectMatchesEmbedded_, refs.at(idx));
0648 return ref.isNonnull() ? ref.get() : nullptr;
0649 }
0650
0651 template <class ObjectType>
0652 const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByFilter(
0653 const std::string &labelFilter) const {
0654 TriggerObjectStandAloneCollection matches;
0655 for (size_t i = 0; i < triggerObjectMatches().size(); ++i) {
0656 if (triggerObjectMatch(i) != 0 && triggerObjectMatch(i)->hasFilterLabel(labelFilter))
0657 matches.push_back(*(triggerObjectMatch(i)));
0658 }
0659 return matches;
0660 }
0661
0662 template <class ObjectType>
0663 const TriggerObjectStandAlone *PATObject<ObjectType>::triggerObjectMatchByFilter(const std::string &labelFilter,
0664 const size_t idx) const {
0665 std::vector<size_t> refs;
0666 for (size_t i = 0; i < triggerObjectMatches().size(); ++i) {
0667 if (triggerObjectMatch(i) != 0 && triggerObjectMatch(i)->hasFilterLabel(labelFilter))
0668 refs.push_back(i);
0669 }
0670 if (idx >= refs.size())
0671 return nullptr;
0672 TriggerObjectStandAloneRef ref(&triggerObjectMatchesEmbedded_, refs.at(idx));
0673 return ref.isNonnull() ? ref.get() : nullptr;
0674 }
0675
0676 template <class ObjectType>
0677 const TriggerObjectStandAloneCollection PATObject<ObjectType>::triggerObjectMatchesByPath(
0678 const std::string &namePath, const bool pathLastFilterAccepted, const bool pathL3FilterAccepted) const {
0679 TriggerObjectStandAloneCollection matches;
0680 for (size_t i = 0; i < triggerObjectMatches().size(); ++i) {
0681 if (triggerObjectMatch(i) != nullptr &&
0682 triggerObjectMatch(i)->hasPathName(namePath, pathLastFilterAccepted, pathL3FilterAccepted))
0683 matches.push_back(*(triggerObjectMatch(i)));
0684 }
0685 return matches;
0686 }
0687
0688 template <class ObjectType>
0689 const TriggerObjectStandAlone *PATObject<ObjectType>::triggerObjectMatchByPath(const std::string &namePath,
0690 const bool pathLastFilterAccepted,
0691 const bool pathL3FilterAccepted,
0692 const size_t idx) const {
0693 std::vector<size_t> refs;
0694 for (size_t i = 0; i < triggerObjectMatches().size(); ++i) {
0695 if (triggerObjectMatch(i) != nullptr &&
0696 triggerObjectMatch(i)->hasPathName(namePath, pathLastFilterAccepted, pathL3FilterAccepted))
0697 refs.push_back(i);
0698 }
0699 if (idx >= refs.size())
0700 return nullptr;
0701 TriggerObjectStandAloneRef ref(&triggerObjectMatchesEmbedded_, refs.at(idx));
0702 return ref.isNonnull() ? ref.get() : nullptr;
0703 }
0704
0705 template <class ObjectType>
0706 const pat::LookupTableRecord &PATObject<ObjectType>::efficiency(const std::string &name) const {
0707
0708 auto it = std::lower_bound(efficiencyNames_.cbegin(), efficiencyNames_.cend(), name);
0709 if ((it == efficiencyNames_.end()) || (*it != name)) {
0710 throw cms::Exception("Invalid Label") << "There is no efficiency with name '" << name << "' in this PAT Object\n";
0711 }
0712 return efficiencyValues_[std::distance(efficiencyNames_.cbegin(), it)];
0713 }
0714
0715 template <class ObjectType>
0716 std::vector<std::pair<std::string, pat::LookupTableRecord> > PATObject<ObjectType>::efficiencies() const {
0717 std::vector<std::pair<std::string, pat::LookupTableRecord> > ret;
0718 std::vector<std::string>::const_iterator itn = efficiencyNames_.begin(), edn = efficiencyNames_.end();
0719 std::vector<pat::LookupTableRecord>::const_iterator itv = efficiencyValues_.begin();
0720 for (; itn != edn; ++itn, ++itv) {
0721 ret.emplace_back(*itn, *itv);
0722 }
0723 return ret;
0724 }
0725
0726 template <class ObjectType>
0727 void PATObject<ObjectType>::setEfficiency(const std::string &name, const pat::LookupTableRecord &value) {
0728
0729 auto it = std::lower_bound(efficiencyNames_.begin(), efficiencyNames_.end(), name);
0730 const auto dist = std::distance(efficiencyNames_.begin(), it);
0731 if (it == efficiencyNames_.end()) {
0732 efficiencyNames_.push_back(name);
0733 efficiencyValues_.push_back(value);
0734 } else if (*it == name) {
0735 efficiencyValues_[dist] = value;
0736 } else {
0737 efficiencyNames_.insert(it, name);
0738 efficiencyValues_.insert(efficiencyValues_.begin() + dist, value);
0739 }
0740 }
0741
0742 template <class ObjectType>
0743 void PATObject<ObjectType>::setGenParticleRef(const reco::GenParticleRef &ref, bool embed) {
0744 genParticleRef_ = std::vector<reco::GenParticleRef>(1, ref);
0745 genParticleEmbedded_.clear();
0746 if (embed)
0747 embedGenParticle();
0748 }
0749
0750 template <class ObjectType>
0751 void PATObject<ObjectType>::addGenParticleRef(const reco::GenParticleRef &ref) {
0752 if (!genParticleEmbedded_.empty()) {
0753 if (ref.isNonnull())
0754 genParticleEmbedded_.push_back(*ref);
0755 } else {
0756 genParticleRef_.push_back(ref);
0757 }
0758 }
0759
0760 template <class ObjectType>
0761 void PATObject<ObjectType>::setGenParticle(const reco::GenParticle &particle) {
0762 genParticleEmbedded_.clear();
0763 genParticleEmbedded_.push_back(particle);
0764 genParticleRef_.clear();
0765 }
0766
0767 template <class ObjectType>
0768 void PATObject<ObjectType>::embedGenParticle() {
0769 genParticleEmbedded_.clear();
0770 for (std::vector<reco::GenParticleRef>::const_iterator it = genParticleRef_.begin(); it != genParticleRef_.end();
0771 ++it) {
0772 if (it->isNonnull())
0773 genParticleEmbedded_.push_back(**it);
0774 }
0775 genParticleRef_.clear();
0776 }
0777
0778 template <class ObjectType>
0779 std::vector<reco::GenParticleRef> PATObject<ObjectType>::genParticleRefs() const {
0780 if (genParticleEmbedded_.empty())
0781 return genParticleRef_;
0782 std::vector<reco::GenParticleRef> ret(genParticleEmbedded_.size());
0783 for (size_t i = 0, n = ret.size(); i < n; ++i) {
0784 ret[i] = reco::GenParticleRef(&genParticleEmbedded_, i);
0785 }
0786 return ret;
0787 }
0788
0789 template <class ObjectType>
0790 reco::GenParticleRef PATObject<ObjectType>::genParticleById(int pdgId, int status, uint8_t autoCharge) const {
0791
0792 const std::vector<reco::GenParticleRef> &vec = (genParticleEmbedded_.empty() ? genParticleRef_ : genParticleRefs());
0793 for (std::vector<reco::GenParticleRef>::const_iterator ref = vec.begin(), end = vec.end(); ref != end; ++ref) {
0794 if (ref->isNonnull()) {
0795 const reco::GenParticle &g = **ref;
0796 if ((status != 0) && (g.status() != status))
0797 continue;
0798 if (pdgId == 0) {
0799 return *ref;
0800 } else if (!autoCharge) {
0801 if (pdgId == g.pdgId())
0802 return *ref;
0803 } else if (abs(pdgId) == abs(g.pdgId())) {
0804
0805 if (g.charge() == 0)
0806 return *ref;
0807 else if ((this->charge() == 0) && (pdgId == g.pdgId()))
0808 return *ref;
0809 else if (g.charge() * this->charge() * pdgId > 0)
0810 return *ref;
0811 }
0812 }
0813 }
0814 return reco::GenParticleRef();
0815 }
0816
0817 template <class ObjectType>
0818 bool PATObject<ObjectType>::hasOverlaps(const std::string &label) const {
0819 auto match = std::lower_bound(overlapLabels_.cbegin(), overlapLabels_.cend(), label);
0820 return (match != overlapLabels_.end() && *match == label);
0821 }
0822
0823 template <class ObjectType>
0824 const reco::CandidatePtrVector &PATObject<ObjectType>::overlaps(const std::string &label) const {
0825 auto match = std::lower_bound(overlapLabels_.cbegin(), overlapLabels_.cend(), label);
0826 if (match == overlapLabels_.cend() || *match != label)
0827 return get_empty_cpv();
0828 return overlapItems_[std::distance(overlapLabels_.begin(), match)];
0829 }
0830
0831 template <class ObjectType>
0832 void PATObject<ObjectType>::setOverlaps(const std::string &label, const reco::CandidatePtrVector &overlaps) {
0833 auto match = std::lower_bound(overlapLabels_.begin(), overlapLabels_.end(), label);
0834 const auto dist = std::distance(overlapLabels_.begin(), match);
0835 if (match == overlapLabels_.end() || *match != label) {
0836 overlapLabels_.insert(match, label);
0837 overlapItems_.insert(overlapItems_.begin() + dist, overlaps);
0838 } else {
0839 overlapItems_[dist] = overlaps;
0840 }
0841 }
0842
0843 template <class ObjectType>
0844 const pat::UserData *PATObject<ObjectType>::userDataObject_(const std::string &key) const {
0845 auto it = std::lower_bound(userDataLabels_.cbegin(), userDataLabels_.cend(), key);
0846 if (it != userDataLabels_.cend() && *it == key) {
0847 return &userDataObjects_[std::distance(userDataLabels_.cbegin(), it)];
0848 }
0849 return nullptr;
0850 }
0851
0852 template <class ObjectType>
0853 void PATObject<ObjectType>::addUserDataObject_(const std::string &label,
0854 std::unique_ptr<pat::UserData> data,
0855 bool overwrite) {
0856 auto it = std::lower_bound(userDataLabels_.begin(), userDataLabels_.end(), label);
0857 const auto dist = std::distance(userDataLabels_.begin(), it);
0858 if (it == userDataLabels_.end() || *it != label) {
0859 userDataLabels_.insert(it, label);
0860 userDataObjects_.insert(userDataObjects_.begin() + dist, std::move(data));
0861 } else if (overwrite) {
0862 userDataObjects_.set(dist, std::move(data));
0863 } else {
0864
0865 userDataLabels_.insert(it + 1, label);
0866 userDataObjects_.insert(userDataObjects_.begin() + dist + 1, std::move(data));
0867 }
0868 }
0869
0870 template <class ObjectType>
0871 float PATObject<ObjectType>::userFloat(const std::string &key) const {
0872 auto it = std::lower_bound(userFloatLabels_.cbegin(), userFloatLabels_.cend(), key);
0873 if (it != userFloatLabels_.cend() && *it == key) {
0874 return userFloats_[std::distance(userFloatLabels_.cbegin(), it)];
0875 }
0876 throwMissingLabel("UserFloat", key, userFloatLabels_);
0877 return std::numeric_limits<float>::quiet_NaN();
0878 }
0879
0880 template <class ObjectType>
0881 std::vector<float> PATObject<ObjectType>::userFloatRange(const std::string &key) const {
0882 auto range = std::equal_range(userFloatLabels_.cbegin(), userFloatLabels_.cend(), key);
0883 std::vector<float> result;
0884 result.reserve(std::distance(range.first, range.second));
0885 for (auto it = range.first; it != range.second; ++it) {
0886 result.push_back(userFloats_[std::distance(userFloatLabels_.cbegin(), it)]);
0887 }
0888 return result;
0889 }
0890
0891 template <class ObjectType>
0892 void PATObject<ObjectType>::addUserFloat(const std::string &label, float data, const bool overwrite) {
0893 auto it = std::lower_bound(userFloatLabels_.begin(), userFloatLabels_.end(), label);
0894 const auto dist = std::distance(userFloatLabels_.begin(), it);
0895 if (it == userFloatLabels_.end() || *it != label) {
0896 userFloatLabels_.insert(it, label);
0897 userFloats_.insert(userFloats_.begin() + dist, data);
0898 } else if (overwrite) {
0899 userFloats_[dist] = data;
0900 } else {
0901
0902 userFloatLabels_.insert(it + 1, label);
0903 userFloats_.insert(userFloats_.begin() + dist + 1, data);
0904 }
0905 }
0906
0907 template <class ObjectType>
0908 int PATObject<ObjectType>::userInt(const std::string &key) const {
0909 auto it = std::lower_bound(userIntLabels_.cbegin(), userIntLabels_.cend(), key);
0910 if (it != userIntLabels_.cend() && *it == key) {
0911 return userInts_[std::distance(userIntLabels_.cbegin(), it)];
0912 }
0913 throwMissingLabel("UserInt", key, userIntLabels_);
0914 return std::numeric_limits<int>::max();
0915 }
0916
0917 template <class ObjectType>
0918 std::vector<int> PATObject<ObjectType>::userIntRange(const std::string &key) const {
0919 auto range = std::equal_range(userIntLabels_.cbegin(), userIntLabels_.cend(), key);
0920 std::vector<int> result;
0921 result.reserve(std::distance(range.first, range.second));
0922 for (auto it = range.first; it != range.second; ++it) {
0923 result.push_back(userInts_[std::distance(userIntLabels_.cbegin(), it)]);
0924 }
0925 return result;
0926 }
0927
0928 template <class ObjectType>
0929 void PATObject<ObjectType>::addUserInt(const std::string &label, int data, bool overwrite) {
0930 auto it = std::lower_bound(userIntLabels_.begin(), userIntLabels_.end(), label);
0931 const auto dist = std::distance(userIntLabels_.begin(), it);
0932 if (it == userIntLabels_.end() || *it != label) {
0933 userIntLabels_.insert(it, label);
0934 userInts_.insert(userInts_.begin() + dist, data);
0935 } else if (overwrite) {
0936 userInts_[dist] = data;
0937 } else {
0938
0939 userIntLabels_.insert(it + 1, label);
0940 userInts_.insert(userInts_.begin() + dist + 1, data);
0941 }
0942 }
0943
0944 template <class ObjectType>
0945 reco::CandidatePtr PATObject<ObjectType>::userCand(const std::string &key) const {
0946 auto it = std::lower_bound(userCandLabels_.cbegin(), userCandLabels_.cend(), key);
0947 if (it != userCandLabels_.cend()) {
0948 return userCands_[std::distance(userCandLabels_.begin(), it)];
0949 }
0950 return reco::CandidatePtr();
0951 }
0952
0953 template <class ObjectType>
0954 void PATObject<ObjectType>::addUserCand(const std::string &label,
0955 const reco::CandidatePtr &data,
0956 const bool overwrite) {
0957 auto it = std::lower_bound(userCandLabels_.begin(), userCandLabels_.end(), label);
0958 const auto dist = std::distance(userCandLabels_.begin(), it);
0959 if (it == userCandLabels_.end() || *it != label) {
0960 userCandLabels_.insert(it, label);
0961 userCands_.insert(userCands_.begin() + dist, data);
0962 } else if (overwrite) {
0963 userCands_[dist] = data;
0964 } else {
0965 userCandLabels_.insert(it + 1, label);
0966 userCands_.insert(userCands_.begin() + dist + 1, data);
0967 }
0968 }
0969
0970 template <class ObjectType>
0971 const pat::CandKinResolution &PATObject<ObjectType>::getKinResolution(const std::string &label) const {
0972 const bool has_unlabelled = (kinResolutionLabels_.size() + 1 == kinResolutions_.size());
0973 if (label.empty()) {
0974 if (has_unlabelled) {
0975 return kinResolutions_[0];
0976 } else {
0977 throw cms::Exception("Missing Data", "This object does not contain an un-labelled kinematic resolution");
0978 }
0979 } else {
0980 auto match = std::lower_bound(kinResolutionLabels_.cbegin(), kinResolutionLabels_.cend(), label);
0981 const auto dist = std::distance(kinResolutionLabels_.begin(), match);
0982 const size_t increment = (has_unlabelled ? 1 : 0);
0983 if (match == kinResolutionLabels_.end() || *match != label) {
0984 cms::Exception ex("Missing Data");
0985 ex << "This object does not contain a kinematic resolution with name '" << label << "'.\n";
0986 ex << "The known labels are: ";
0987 for (std::vector<std::string>::const_iterator it = kinResolutionLabels_.cbegin();
0988 it != kinResolutionLabels_.cend();
0989 ++it) {
0990 ex << "'" << *it << "' ";
0991 }
0992 ex << "\n";
0993 throw ex;
0994 } else {
0995 return kinResolutions_[dist + increment];
0996 }
0997 }
0998 }
0999
1000 template <class ObjectType>
1001 bool PATObject<ObjectType>::hasKinResolution(const std::string &label) const {
1002 if (label.empty()) {
1003 return (kinResolutionLabels_.size() + 1 == kinResolutions_.size());
1004 } else {
1005 auto match = std::lower_bound(kinResolutionLabels_.cbegin(), kinResolutionLabels_.cend(), label);
1006 return (match != kinResolutionLabels_.cend() && *match == label);
1007 }
1008 }
1009
1010 template <class ObjectType>
1011 void PATObject<ObjectType>::setKinResolution(const pat::CandKinResolution &resol, const std::string &label) {
1012 const bool has_unlabelled = (kinResolutionLabels_.size() + 1 == kinResolutions_.size());
1013 if (label.empty()) {
1014 if (has_unlabelled) {
1015
1016 kinResolutions_[0] = resol;
1017 } else {
1018
1019
1020 kinResolutions_.insert(kinResolutions_.begin(), resol);
1021 }
1022 } else {
1023 auto match = std::lower_bound(kinResolutionLabels_.begin(), kinResolutionLabels_.end(), label);
1024 const auto dist = std::distance(kinResolutionLabels_.begin(), match);
1025 const size_t increment = (has_unlabelled ? 1 : 0);
1026 if (match != kinResolutionLabels_.end() && *match == label) {
1027
1028 kinResolutions_[dist + increment] = resol;
1029 } else {
1030 kinResolutionLabels_.insert(match, label);
1031 kinResolutions_.insert(kinResolutions_.begin() + dist + increment, resol);
1032 }
1033 }
1034 }
1035
1036 }
1037
1038 #endif