File indexing completed on 2022-10-19 00:01:30
0001 #ifndef __DataFormats_PatCandidates_PackedCandidate_h__
0002 #define __DataFormats_PatCandidates_PackedCandidate_h__
0003
0004 #include "DataFormats/Candidate/interface/Candidate.h"
0005 #include "DataFormats/Candidate/interface/CandidateFwd.h"
0006 #include "DataFormats/Common/interface/Association.h"
0007 #include "DataFormats/Common/interface/RefVector.h"
0008 #include "DataFormats/Math/interface/deltaPhi.h"
0009 #include "DataFormats/PatCandidates/interface/CovarianceParameterization.h"
0010 #include "DataFormats/VertexReco/interface/Vertex.h"
0011 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0012 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0013 #include <atomic>
0014 #include <mutex>
0015
0016
0017
0018
0019 class testPackedCandidate;
0020
0021 namespace pat {
0022 class PackedCandidate : public reco::Candidate {
0023 public:
0024
0025 typedef reco::CandidateCollection daughters;
0026
0027 typedef math::XYZTLorentzVector LorentzVector;
0028
0029 typedef math::PtEtaPhiMLorentzVector PolarLorentzVector;
0030
0031 typedef math::XYZPoint Point;
0032
0033 typedef math::XYZVector Vector;
0034
0035 typedef unsigned int index;
0036
0037 PackedCandidate()
0038 : packedPt_(0),
0039 packedEta_(0),
0040 packedPhi_(0),
0041 packedM_(0),
0042 packedDxy_(0),
0043 packedDz_(0),
0044 packedDPhi_(0),
0045 packedDEta_(0),
0046 packedDTrkPt_(0),
0047 packedCovariance_(),
0048 packedPuppiweight_(0),
0049 packedPuppiweightNoLepDiff_(0),
0050 rawCaloFraction_(0),
0051 rawHcalFraction_(0),
0052 caloFraction_(0),
0053 hcalFraction_(0),
0054 packedTime_(0),
0055 packedTimeError_(0),
0056 isIsolatedChargedHadron_(false),
0057 p4_(new PolarLorentzVector(0, 0, 0, 0)),
0058 p4c_(new LorentzVector(0, 0, 0, 0)),
0059 vertex_(new Point(0, 0, 0)),
0060 dphi_(0),
0061 deta_(0),
0062 dtrkpt_(0),
0063 track_(nullptr),
0064 pdgId_(0),
0065 qualityFlags_(0),
0066 pvRefKey_(reco::VertexRef::invalidKey()),
0067 m_(nullptr),
0068 packedHits_(0),
0069 packedLayers_(0),
0070 normalizedChi2_(0),
0071 covarianceVersion_(0),
0072 covarianceSchema_(0),
0073 firstHit_(0) {}
0074
0075 explicit PackedCandidate(const reco::Candidate &c,
0076 const reco::VertexRefProd &pvRefProd,
0077 reco::VertexRef::key_type pvRefKey)
0078 : packedPuppiweight_(0),
0079 packedPuppiweightNoLepDiff_(0),
0080 rawCaloFraction_(0),
0081 rawHcalFraction_(0),
0082 caloFraction_(0),
0083 hcalFraction_(0),
0084 packedTime_(0),
0085 packedTimeError_(0),
0086 isIsolatedChargedHadron_(false),
0087 p4_(new PolarLorentzVector(c.pt(), c.eta(), c.phi(), c.mass())),
0088 p4c_(new LorentzVector(*p4_)),
0089 vertex_(new Point(c.vertex())),
0090 dphi_(0),
0091 deta_(0),
0092 dtrkpt_(0),
0093 track_(nullptr),
0094 pdgId_(c.pdgId()),
0095 qualityFlags_(0),
0096 pvRefProd_(pvRefProd),
0097 pvRefKey_(pvRefKey),
0098 m_(nullptr),
0099 packedHits_(0),
0100 packedLayers_(0),
0101 normalizedChi2_(0),
0102 covarianceVersion_(0),
0103 covarianceSchema_(0),
0104 firstHit_(0) {
0105 packBoth();
0106 }
0107
0108 explicit PackedCandidate(const PolarLorentzVector &p4,
0109 const Point &vtx,
0110 float trkPt,
0111 float etaAtVtx,
0112 float phiAtVtx,
0113 int pdgId,
0114 const reco::VertexRefProd &pvRefProd,
0115 reco::VertexRef::key_type pvRefKey)
0116 : packedPuppiweight_(0),
0117 packedPuppiweightNoLepDiff_(0),
0118 rawCaloFraction_(0),
0119 rawHcalFraction_(0),
0120 caloFraction_(0),
0121 hcalFraction_(0),
0122 packedTime_(0),
0123 packedTimeError_(0),
0124 isIsolatedChargedHadron_(false),
0125 p4_(new PolarLorentzVector(p4)),
0126 p4c_(new LorentzVector(*p4_)),
0127 vertex_(new Point(vtx)),
0128 dphi_(reco::deltaPhi(phiAtVtx, p4_.load()->phi())),
0129 deta_(std::abs(etaAtVtx - p4_.load()->eta()) >= kMinDEtaToStore_ ? etaAtVtx - p4_.load()->eta() : 0.),
0130 dtrkpt_(std::abs(trkPt - p4_.load()->pt()) >= kMinDTrkPtToStore_ ? trkPt - p4_.load()->pt() : 0.),
0131 track_(nullptr),
0132 pdgId_(pdgId),
0133 qualityFlags_(0),
0134 pvRefProd_(pvRefProd),
0135 pvRefKey_(pvRefKey),
0136 m_(nullptr),
0137 packedHits_(0),
0138 packedLayers_(0),
0139 normalizedChi2_(0),
0140 covarianceVersion_(0),
0141 covarianceSchema_(0),
0142 firstHit_(0) {
0143 packBoth();
0144 }
0145
0146 explicit PackedCandidate(const LorentzVector &p4,
0147 const Point &vtx,
0148 float trkPt,
0149 float etaAtVtx,
0150 float phiAtVtx,
0151 int pdgId,
0152 const reco::VertexRefProd &pvRefProd,
0153 reco::VertexRef::key_type pvRefKey)
0154 : packedPuppiweight_(0),
0155 packedPuppiweightNoLepDiff_(0),
0156 rawCaloFraction_(0),
0157 rawHcalFraction_(0),
0158 caloFraction_(0),
0159 hcalFraction_(0),
0160 packedTime_(0),
0161 packedTimeError_(0),
0162 isIsolatedChargedHadron_(false),
0163 p4_(new PolarLorentzVector(p4.Pt(), p4.Eta(), p4.Phi(), p4.M())),
0164 p4c_(new LorentzVector(p4)),
0165 vertex_(new Point(vtx)),
0166 dphi_(reco::deltaPhi(phiAtVtx, p4_.load()->phi())),
0167 deta_(std::abs(etaAtVtx - p4_.load()->eta()) >= kMinDEtaToStore_ ? etaAtVtx - p4_.load()->eta() : 0.),
0168 dtrkpt_(std::abs(trkPt - p4_.load()->pt()) >= kMinDTrkPtToStore_ ? trkPt - p4_.load()->pt() : 0.),
0169 track_(nullptr),
0170 pdgId_(pdgId),
0171 qualityFlags_(0),
0172 pvRefProd_(pvRefProd),
0173 pvRefKey_(pvRefKey),
0174 m_(nullptr),
0175 packedHits_(0),
0176 packedLayers_(0),
0177 normalizedChi2_(0),
0178 covarianceVersion_(0),
0179 covarianceSchema_(0),
0180 firstHit_(0) {
0181 packBoth();
0182 }
0183
0184 PackedCandidate(const PackedCandidate &iOther)
0185 : packedPt_(iOther.packedPt_),
0186 packedEta_(iOther.packedEta_),
0187 packedPhi_(iOther.packedPhi_),
0188 packedM_(iOther.packedM_),
0189 packedDxy_(iOther.packedDxy_),
0190 packedDz_(iOther.packedDz_),
0191 packedDPhi_(iOther.packedDPhi_),
0192 packedDEta_(iOther.packedDEta_),
0193 packedDTrkPt_(iOther.packedDTrkPt_),
0194 packedCovariance_(iOther.packedCovariance_),
0195 packedPuppiweight_(iOther.packedPuppiweight_),
0196 packedPuppiweightNoLepDiff_(iOther.packedPuppiweightNoLepDiff_),
0197 rawCaloFraction_(iOther.rawCaloFraction_),
0198 rawHcalFraction_(iOther.rawHcalFraction_),
0199 caloFraction_(iOther.caloFraction_),
0200 hcalFraction_(iOther.hcalFraction_),
0201 packedTime_(iOther.packedTime_),
0202 packedTimeError_(iOther.packedTimeError_),
0203 isIsolatedChargedHadron_(iOther.isIsolatedChargedHadron_),
0204
0205 p4_(new PolarLorentzVector(iOther.polarP4())),
0206 p4c_(new LorentzVector(iOther.p4())),
0207 vertex_((iOther.vertex_ ? new Point(iOther.vertex()) : nullptr)),
0208 dxy_(vertex_ ? iOther.dxy_ : 0),
0209 dz_(vertex_ ? iOther.dz_ : 0),
0210 dphi_(vertex_ ? iOther.dphi_ : 0),
0211 deta_(vertex_ ? iOther.deta_ : 0),
0212 dtrkpt_(vertex_ ? iOther.dtrkpt_ : 0),
0213 track_(iOther.track_ ? new reco::Track(*iOther.track_) : nullptr),
0214 pdgId_(iOther.pdgId_),
0215 qualityFlags_(iOther.qualityFlags_),
0216 pvRefProd_(iOther.pvRefProd_),
0217 pvRefKey_(iOther.pvRefKey_),
0218 m_(iOther.m_ ? new reco::TrackBase::CovarianceMatrix(*iOther.m_) : nullptr),
0219 packedHits_(iOther.packedHits_),
0220 packedLayers_(iOther.packedLayers_),
0221 normalizedChi2_(iOther.normalizedChi2_),
0222 covarianceVersion_(iOther.covarianceVersion_),
0223 covarianceSchema_(iOther.covarianceSchema_),
0224 firstHit_(iOther.firstHit_) {}
0225
0226 PackedCandidate(PackedCandidate &&iOther)
0227 : packedPt_(iOther.packedPt_),
0228 packedEta_(iOther.packedEta_),
0229 packedPhi_(iOther.packedPhi_),
0230 packedM_(iOther.packedM_),
0231 packedDxy_(iOther.packedDxy_),
0232 packedDz_(iOther.packedDz_),
0233 packedDPhi_(iOther.packedDPhi_),
0234 packedDEta_(iOther.packedDEta_),
0235 packedDTrkPt_(iOther.packedDTrkPt_),
0236 packedCovariance_(iOther.packedCovariance_),
0237 packedPuppiweight_(iOther.packedPuppiweight_),
0238 packedPuppiweightNoLepDiff_(iOther.packedPuppiweightNoLepDiff_),
0239 rawCaloFraction_(iOther.rawCaloFraction_),
0240 rawHcalFraction_(iOther.rawHcalFraction_),
0241 caloFraction_(iOther.caloFraction_),
0242 hcalFraction_(iOther.hcalFraction_),
0243 packedTime_(iOther.packedTime_),
0244 packedTimeError_(iOther.packedTimeError_),
0245 isIsolatedChargedHadron_(iOther.isIsolatedChargedHadron_),
0246 p4_(iOther.p4_.exchange(nullptr)),
0247 p4c_(iOther.p4c_.exchange(nullptr)),
0248 vertex_(iOther.vertex_.exchange(nullptr)),
0249 dxy_(iOther.dxy_),
0250 dz_(iOther.dz_),
0251 dphi_(iOther.dphi_),
0252 deta_(iOther.deta_),
0253 dtrkpt_(iOther.dtrkpt_),
0254 track_(iOther.track_.exchange(nullptr)),
0255 pdgId_(iOther.pdgId_),
0256 qualityFlags_(iOther.qualityFlags_),
0257 pvRefProd_(iOther.pvRefProd_),
0258 pvRefKey_(iOther.pvRefKey_),
0259 m_(iOther.m_.exchange(nullptr)),
0260 packedHits_(iOther.packedHits_),
0261 packedLayers_(iOther.packedLayers_),
0262 normalizedChi2_(iOther.normalizedChi2_),
0263 covarianceVersion_(iOther.covarianceVersion_),
0264 covarianceSchema_(iOther.covarianceSchema_),
0265 firstHit_(iOther.firstHit_) {}
0266
0267 PackedCandidate &operator=(const PackedCandidate &iOther) {
0268 if (this == &iOther) {
0269 return *this;
0270 }
0271 packedPt_ = iOther.packedPt_;
0272 packedEta_ = iOther.packedEta_;
0273 packedPhi_ = iOther.packedPhi_;
0274 packedM_ = iOther.packedM_;
0275 packedDxy_ = iOther.packedDxy_;
0276 packedDz_ = iOther.packedDz_;
0277 packedDPhi_ = iOther.packedDPhi_;
0278 packedDEta_ = iOther.packedDEta_;
0279 packedDTrkPt_ = iOther.packedDTrkPt_;
0280 packedCovariance_ = iOther.packedCovariance_;
0281 packedPuppiweight_ = iOther.packedPuppiweight_;
0282 packedPuppiweightNoLepDiff_ = iOther.packedPuppiweightNoLepDiff_;
0283 rawCaloFraction_ = iOther.rawCaloFraction_;
0284 rawHcalFraction_ = iOther.rawHcalFraction_;
0285 caloFraction_ = iOther.caloFraction_;
0286 hcalFraction_ = iOther.hcalFraction_;
0287 packedTime_ = iOther.packedTime_;
0288 packedTimeError_ = iOther.packedTimeError_;
0289 isIsolatedChargedHadron_ = iOther.isIsolatedChargedHadron_;
0290
0291 if (p4_) {
0292 *p4_ = iOther.polarP4();
0293 } else {
0294 p4_.store(new PolarLorentzVector(iOther.polarP4()));
0295 }
0296 if (p4c_) {
0297 *p4c_ = iOther.p4();
0298 } else {
0299 p4c_.store(new LorentzVector(iOther.p4()));
0300 }
0301 if (vertex_) {
0302 *vertex_ = iOther.vertex();
0303 } else {
0304 vertex_.store(new Point(iOther.vertex()));
0305 }
0306 dxy_ = iOther.dxy_;
0307 dz_ = iOther.dz_;
0308 dphi_ = iOther.dphi_;
0309 deta_ = iOther.deta_;
0310 dtrkpt_ = iOther.dtrkpt_;
0311
0312 if (!iOther.track_) {
0313 delete track_.exchange(nullptr);
0314 } else {
0315 if (!track_) {
0316 track_.store(new reco::Track(*iOther.track_));
0317 } else {
0318 *track_ = *(iOther.track_);
0319 }
0320 }
0321
0322 pdgId_ = iOther.pdgId_;
0323 qualityFlags_ = iOther.qualityFlags_;
0324 pvRefProd_ = iOther.pvRefProd_;
0325 pvRefKey_ = iOther.pvRefKey_;
0326 if (!iOther.m_) {
0327 delete m_.exchange(nullptr);
0328 } else {
0329 if (!m_) {
0330 m_.store(new reco::Track::CovarianceMatrix(*iOther.m_));
0331 } else {
0332 *m_ = *(iOther.m_);
0333 }
0334 }
0335
0336 packedHits_ = iOther.packedHits_;
0337 packedLayers_ = iOther.packedLayers_;
0338 normalizedChi2_ = iOther.normalizedChi2_;
0339 covarianceVersion_ = iOther.covarianceVersion_;
0340 covarianceSchema_ = iOther.covarianceSchema_;
0341 firstHit_ = iOther.firstHit_;
0342 return *this;
0343 }
0344
0345 PackedCandidate &operator=(PackedCandidate &&iOther) {
0346 if (this == &iOther) {
0347 return *this;
0348 }
0349 packedPt_ = iOther.packedPt_;
0350 packedEta_ = iOther.packedEta_;
0351 packedPhi_ = iOther.packedPhi_;
0352 packedM_ = iOther.packedM_;
0353 packedDxy_ = iOther.packedDxy_;
0354 packedDz_ = iOther.packedDz_;
0355 packedDPhi_ = iOther.packedDPhi_;
0356 packedDEta_ = iOther.packedDEta_;
0357 packedDTrkPt_ = iOther.packedDTrkPt_;
0358 packedCovariance_ = iOther.packedCovariance_;
0359 packedPuppiweight_ = iOther.packedPuppiweight_;
0360 packedPuppiweightNoLepDiff_ = iOther.packedPuppiweightNoLepDiff_;
0361 rawCaloFraction_ = iOther.rawCaloFraction_;
0362 rawHcalFraction_ = iOther.rawHcalFraction_;
0363 caloFraction_ = iOther.caloFraction_;
0364 hcalFraction_ = iOther.hcalFraction_;
0365 packedTime_ = iOther.packedTime_;
0366 packedTimeError_ = iOther.packedTimeError_;
0367 isIsolatedChargedHadron_ = iOther.isIsolatedChargedHadron_;
0368 delete p4_.exchange(iOther.p4_.exchange(nullptr));
0369 delete p4c_.exchange(iOther.p4c_.exchange(nullptr));
0370 delete vertex_.exchange(iOther.vertex_.exchange(nullptr));
0371 dxy_ = iOther.dxy_;
0372 dz_ = iOther.dz_;
0373 dphi_ = iOther.dphi_;
0374 deta_ = iOther.deta_;
0375 dtrkpt_ = iOther.dtrkpt_;
0376 delete track_.exchange(iOther.track_.exchange(nullptr));
0377 pdgId_ = iOther.pdgId_;
0378 qualityFlags_ = iOther.qualityFlags_;
0379 pvRefProd_ = iOther.pvRefProd_;
0380 pvRefKey_ = iOther.pvRefKey_;
0381 delete m_.exchange(iOther.m_.exchange(nullptr));
0382 packedHits_ = iOther.packedHits_;
0383 packedLayers_ = iOther.packedLayers_;
0384 normalizedChi2_ = iOther.normalizedChi2_;
0385 covarianceVersion_ = iOther.covarianceVersion_;
0386 covarianceSchema_ = iOther.covarianceSchema_;
0387 firstHit_ = iOther.firstHit_;
0388 return *this;
0389 }
0390
0391
0392 ~PackedCandidate() override;
0393
0394 size_t numberOfDaughters() const override;
0395
0396 const reco::Candidate *daughter(size_type) const override;
0397
0398 size_t numberOfMothers() const override;
0399
0400 const reco::Candidate *mother(size_type) const override;
0401
0402 reco::Candidate *daughter(size_type) override;
0403
0404 reco::Candidate *daughter(const std::string &s) override;
0405
0406 const reco::Candidate *daughter(const std::string &s) const override;
0407
0408
0409 size_t numberOfSourceCandidatePtrs() const override { return 0; }
0410
0411
0412 reco::CandidatePtr sourceCandidatePtr(size_type i) const override { return reco::CandidatePtr(); }
0413
0414
0415 int charge() const override {
0416 switch (abs(pdgId_)) {
0417 case 211:
0418 return (pdgId_ > 0) - (pdgId_ < 0);
0419 case 11:
0420 return (-1) * (pdgId_ > 0) + (pdgId_ < 0);
0421 case 13:
0422 return (-1) * (pdgId_ > 0) + (pdgId_ < 0);
0423 case 15:
0424 return (-1) * (pdgId_ > 0) + (pdgId_ < 0);
0425 case 24:
0426 return (pdgId_ > 0) - (pdgId_ < 0);
0427 default:
0428 return 0;
0429 }
0430 }
0431
0432 void setCharge(int charge) override {}
0433
0434 int threeCharge() const override { return charge() * 3; }
0435
0436 void setThreeCharge(int threecharge) override {}
0437
0438 const LorentzVector &p4() const override {
0439 if (!p4c_)
0440 unpack();
0441 return *p4c_;
0442 }
0443
0444 const PolarLorentzVector &polarP4() const override {
0445 if (!p4c_)
0446 unpack();
0447 return *p4_;
0448 }
0449
0450 Vector momentum() const override {
0451 if (!p4c_)
0452 unpack();
0453 return p4c_.load()->Vect();
0454 }
0455
0456
0457 Vector boostToCM() const override {
0458 if (!p4c_)
0459 unpack();
0460 return p4c_.load()->BoostToCM();
0461 }
0462
0463 double p() const override {
0464 if (!p4c_)
0465 unpack();
0466 return p4c_.load()->P();
0467 }
0468
0469 double energy() const override {
0470 if (!p4c_)
0471 unpack();
0472 return p4c_.load()->E();
0473 }
0474
0475 double et() const override { return (pt() <= 0) ? 0 : p4c_.load()->Et(); }
0476
0477 double et2() const override { return (pt() <= 0) ? 0 : p4c_.load()->Et2(); }
0478
0479 double mass() const override {
0480 if (!p4c_)
0481 unpack();
0482 return p4_.load()->M();
0483 }
0484
0485 double massSqr() const override {
0486 if (!p4c_)
0487 unpack();
0488 auto m = p4_.load()->M();
0489 return m * m;
0490 }
0491
0492
0493 double mt() const override {
0494 if (!p4c_)
0495 unpack();
0496 return p4_.load()->Mt();
0497 }
0498
0499 double mtSqr() const override {
0500 if (!p4c_)
0501 unpack();
0502 return p4_.load()->Mt2();
0503 }
0504
0505 double px() const override {
0506 if (!p4c_)
0507 unpack();
0508 return p4c_.load()->Px();
0509 }
0510
0511 double py() const override {
0512 if (!p4c_)
0513 unpack();
0514 return p4c_.load()->Py();
0515 }
0516
0517 double pz() const override {
0518 if (!p4c_)
0519 unpack();
0520 return p4c_.load()->Pz();
0521 }
0522
0523 double pt() const override {
0524 if (!p4c_)
0525 unpack();
0526 return p4_.load()->Pt();
0527 }
0528
0529 double phi() const override {
0530 if (!p4c_)
0531 unpack();
0532 return p4_.load()->Phi();
0533 }
0534
0535
0536 virtual double ptTrk() const {
0537 maybeUnpackBoth();
0538 return p4_.load()->pt() + dtrkpt_;
0539 }
0540
0541 virtual float phiAtVtx() const {
0542 maybeUnpackBoth();
0543 float ret = p4_.load()->Phi() + dphi_;
0544 while (ret > float(M_PI))
0545 ret -= 2 * float(M_PI);
0546 while (ret < -float(M_PI))
0547 ret += 2 * float(M_PI);
0548 return ret;
0549 }
0550
0551 virtual float etaAtVtx() const {
0552 maybeUnpackBoth();
0553 return p4_.load()->eta() + deta_;
0554 }
0555
0556
0557 double theta() const override {
0558 if (!p4c_)
0559 unpack();
0560 return p4_.load()->Theta();
0561 }
0562
0563 double eta() const override {
0564 if (!p4c_)
0565 unpack();
0566 return p4_.load()->Eta();
0567 }
0568
0569 double rapidity() const override {
0570 if (!p4c_)
0571 unpack();
0572 return p4_.load()->Rapidity();
0573 }
0574
0575 double y() const override {
0576 if (!p4c_)
0577 unpack();
0578 return p4_.load()->Rapidity();
0579 }
0580
0581 void setP4(const LorentzVector &p4) override {
0582 maybeUnpackBoth();
0583
0584 dphi_ += polarP4().Phi() - p4.Phi();
0585 deta_ += polarP4().Eta() - p4.Eta();
0586 dtrkpt_ += polarP4().Pt() - p4.Pt();
0587 *p4_ = PolarLorentzVector(p4.Pt(), p4.Eta(), p4.Phi(), p4.M());
0588 packBoth();
0589 }
0590
0591 void setP4(const PolarLorentzVector &p4) override {
0592 maybeUnpackBoth();
0593
0594 dphi_ += polarP4().Phi() - p4.Phi();
0595 deta_ += polarP4().Eta() - p4.Eta();
0596 dtrkpt_ += polarP4().Pt() - p4.Pt();
0597 *p4_ = p4;
0598 packBoth();
0599 }
0600
0601 void setMass(double m) override {
0602 if (!p4c_)
0603 unpack();
0604 *p4_ = PolarLorentzVector(p4_.load()->Pt(), p4_.load()->Eta(), p4_.load()->Phi(), m);
0605 pack();
0606 }
0607 void setPz(double pz) override {
0608 maybeUnpackBoth();
0609
0610 *p4c_ = LorentzVector(p4c_.load()->Px(), p4c_.load()->Py(), pz, p4c_.load()->E());
0611 dphi_ += polarP4().Phi() - p4c_.load()->Phi();
0612 deta_ += polarP4().Eta() - p4c_.load()->Eta();
0613 dtrkpt_ += polarP4().Pt() - p4c_.load()->Pt();
0614 *p4_ = PolarLorentzVector(p4c_.load()->Pt(), p4c_.load()->Eta(), p4c_.load()->Phi(), p4c_.load()->M());
0615 packBoth();
0616 }
0617
0618
0619
0620 enum trackHitShiftsAndMasks { trackPixelHitsMask = 7, trackStripHitsMask = 31, trackStripHitsShift = 3 };
0621
0622
0623 virtual void setHits(const reco::Track &tk) {
0624
0625 int numberOfPixelLayers_ = tk.hitPattern().pixelLayersWithMeasurement();
0626 if (numberOfPixelLayers_ > trackPixelHitsMask)
0627 numberOfPixelLayers_ = trackPixelHitsMask;
0628 int numberOfStripLayers_ = tk.hitPattern().stripLayersWithMeasurement();
0629 if (numberOfStripLayers_ > trackStripHitsMask)
0630 numberOfStripLayers_ = trackStripHitsMask;
0631 packedLayers_ = (numberOfPixelLayers_ & trackPixelHitsMask) | (numberOfStripLayers_ << trackStripHitsShift);
0632
0633
0634 int numberOfPixelHits_ = tk.hitPattern().numberOfValidPixelHits() - numberOfPixelLayers_;
0635 if (numberOfPixelHits_ > trackPixelHitsMask)
0636 numberOfPixelHits_ = trackPixelHitsMask;
0637 int numberOfStripHits_ =
0638 tk.hitPattern().numberOfValidHits() - numberOfPixelHits_ - numberOfPixelLayers_ - numberOfStripLayers_;
0639 if (numberOfStripHits_ > trackStripHitsMask)
0640 numberOfStripHits_ = trackStripHitsMask;
0641
0642 packedHits_ = (numberOfPixelHits_ & trackPixelHitsMask) | (numberOfStripHits_ << trackStripHitsShift);
0643 }
0644
0645 virtual void setTrackProperties(const reco::Track &tk,
0646 const reco::Track::CovarianceMatrix &covariance,
0647 int quality,
0648 int covarianceVersion) {
0649 covarianceVersion_ = covarianceVersion;
0650 covarianceSchema_ = quality;
0651 normalizedChi2_ = tk.normalizedChi2();
0652 setHits(tk);
0653 maybeUnpackBoth();
0654 packBoth();
0655 packCovariance(covariance, false);
0656 }
0657
0658
0659
0660 virtual void setTrackProperties(const reco::Track &tk, int quality, int covarianceVersion) {
0661 setTrackProperties(tk, tk.covariance(), quality, covarianceVersion);
0662 }
0663
0664 void setTrackPropertiesLite(unsigned int covSchema,
0665 unsigned int covarianceVersion,
0666 unsigned int nHits,
0667 unsigned int nPixelHits) {
0668 covarianceVersion_ = covarianceVersion;
0669 covarianceSchema_ = covSchema;
0670 packedHits_ =
0671 (nPixelHits & trackPixelHitsMask) | (((nHits - nPixelHits) & trackStripHitsMask) << trackStripHitsShift);
0672 }
0673
0674 int numberOfPixelHits() const { return (packedHits_ & trackPixelHitsMask) + pixelLayersWithMeasurement(); }
0675 int numberOfHits() const {
0676 return (packedHits_ >> trackStripHitsShift) + stripLayersWithMeasurement() + numberOfPixelHits();
0677 }
0678 int pixelLayersWithMeasurement() const { return packedLayers_ & trackPixelHitsMask; }
0679 int stripLayersWithMeasurement() const { return (packedLayers_ >> trackStripHitsShift); }
0680 int trackerLayersWithMeasurement() const { return stripLayersWithMeasurement() + pixelLayersWithMeasurement(); }
0681 virtual void setCovarianceVersion(int v) { covarianceVersion_ = v; }
0682 int covarianceVersion() const { return covarianceVersion_; }
0683 int covarianceSchema() const { return covarianceSchema_; }
0684
0685
0686 const Point &vertex() const override {
0687 maybeUnpackBoth();
0688 return *vertex_;
0689 }
0690
0691 double vx() const override {
0692 maybeUnpackBoth();
0693 return vertex_.load()->X();
0694 }
0695
0696 double vy() const override {
0697 maybeUnpackBoth();
0698 return vertex_.load()->Y();
0699 }
0700
0701 double vz() const override {
0702 maybeUnpackBoth();
0703 return vertex_.load()->Z();
0704 }
0705
0706 void setVertex(const Point &vertex) override {
0707 maybeUnpackBoth();
0708 *vertex_ = vertex;
0709 packVtx();
0710 }
0711
0712
0713
0714 enum PVAssoc { NoPV = 0, PVLoose = 1, PVTight = 2, PVUsedInFit = 3 };
0715 const PVAssoc fromPV(size_t ipv = 0) const {
0716 reco::VertexRef pvRef = vertexRef();
0717 if (pvAssociationQuality() == UsedInFitTight and pvRef.key() == ipv)
0718 return PVUsedInFit;
0719 if (pvRef.key() == ipv or abs(pdgId()) == 13 or abs(pdgId()) == 11)
0720 return PVTight;
0721 if (pvAssociationQuality() == CompatibilityBTag and std::abs(dzAssociatedPV()) > std::abs(dz(ipv)))
0722 return PVTight;
0723
0724 if (pvAssociationQuality() < UsedInFitLoose or pvRef->ndof() < 4.0)
0725 return PVLoose;
0726 return NoPV;
0727 }
0728
0729
0730
0731
0732 enum PVAssociationQuality {
0733 NotReconstructedPrimary = 0,
0734 OtherDeltaZ = 1,
0735 CompatibilityBTag = 4,
0736 CompatibilityDz = 5,
0737 UsedInFitLoose = 6,
0738 UsedInFitTight = 7
0739 };
0740 const PVAssociationQuality pvAssociationQuality() const {
0741 return PVAssociationQuality((qualityFlags_ & assignmentQualityMask) >> assignmentQualityShift);
0742 }
0743 void setAssociationQuality(PVAssociationQuality q) {
0744 qualityFlags_ =
0745 (qualityFlags_ & ~assignmentQualityMask) | ((q << assignmentQualityShift) & assignmentQualityMask);
0746 }
0747
0748 const reco::VertexRef vertexRef() const { return reco::VertexRef(pvRefProd_, pvRefKey_); }
0749
0750
0751 virtual float dxy() const {
0752 maybeUnpackBoth();
0753 return dxy_;
0754 }
0755
0756
0757 virtual float dz(size_t ipv = 0) const {
0758 maybeUnpackBoth();
0759 return dz_ + (*pvRefProd_)[pvRefKey_].position().z() - (*pvRefProd_)[ipv].position().z();
0760 }
0761
0762 virtual float dzAssociatedPV() const {
0763 maybeUnpackBoth();
0764 return dz_;
0765 }
0766
0767
0768 virtual float dxy(const Point &p) const;
0769
0770 virtual float dz(const Point &p) const;
0771
0772
0773 float dzError() const override {
0774 maybeUnpackCovariance();
0775 return sqrt((*m_.load())(4, 4));
0776 }
0777
0778 float dxyError() const override {
0779 maybeUnpackCovariance();
0780 return sqrt((*m_.load())(3, 3));
0781 }
0782
0783
0784
0785 virtual const reco::Track &pseudoTrack() const {
0786 if (!track_)
0787 unpackTrk();
0788 return *track_;
0789 }
0790
0791
0792
0793 virtual const reco::Track pseudoPosDefTrack() const;
0794
0795
0796 const reco::Track *bestTrack() const override {
0797 if (packedHits_ != 0 || packedLayers_ != 0) {
0798 maybeUnpackTrack();
0799 return track_.load();
0800 } else
0801 return nullptr;
0802 }
0803
0804 bool hasTrackDetails() const { return (packedHits_ != 0 || packedLayers_ != 0); }
0805
0806
0807 bool fromTrackCandidate() const { return (packedDz_ != 0 || (packedDxy_ != 0 && packedDxy_ != 32768)); }
0808
0809 bool trackHighPurity() const { return (qualityFlags_ & trackHighPurityMask) >> trackHighPurityShift; }
0810
0811 void setTrackHighPurity(bool highPurity) {
0812 qualityFlags_ =
0813 (qualityFlags_ & ~trackHighPurityMask) | ((highPurity << trackHighPurityShift) & trackHighPurityMask);
0814 }
0815
0816
0817 enum LostInnerHits {
0818 validHitInFirstPixelBarrelLayer = -1,
0819 noLostInnerHits = 0,
0820
0821 oneLostInnerHit = 1,
0822 moreLostInnerHits = 2
0823 };
0824 LostInnerHits lostInnerHits() const {
0825 return LostInnerHits(int16_t((qualityFlags_ & lostInnerHitsMask) >> lostInnerHitsShift) - 1);
0826 }
0827 void setLostInnerHits(LostInnerHits hits) {
0828 int lost = hits;
0829 if (lost > 2)
0830 lost = 2;
0831 lost++;
0832 qualityFlags_ = (qualityFlags_ & ~lostInnerHitsMask) | ((lost << lostInnerHitsShift) & lostInnerHitsMask);
0833 }
0834
0835
0836 void setFirstHit(uint16_t pattern) { firstHit_ = pattern; }
0837
0838 uint16_t firstHit() const { return firstHit_; }
0839
0840 void setMuonID(bool isStandAlone, bool isGlobal) {
0841 int16_t muonFlags = isStandAlone | (2 * isGlobal);
0842 qualityFlags_ = (qualityFlags_ & ~muonFlagsMask) | ((muonFlags << muonFlagsShift) & muonFlagsMask);
0843 }
0844
0845 void setGoodEgamma(bool isGoodEgamma = true) {
0846 int16_t egFlags = (isGoodEgamma << egammaFlagsShift) & egammaFlagsMask;
0847 qualityFlags_ = (qualityFlags_ & ~egammaFlagsMask) | egFlags;
0848 }
0849
0850
0851 int pdgId() const override { return pdgId_; }
0852
0853 void setPdgId(int pdgId) override { pdgId_ = pdgId; }
0854
0855 int status() const override { return qualityFlags_; }
0856
0857 void setStatus(int status) override {}
0858
0859 static const unsigned int longLivedTag = 0;
0860
0861 void setLongLived() override {}
0862
0863 bool longLived() const override;
0864
0865 static const unsigned int massConstraintTag = 0;
0866
0867 void setMassConstraint() override {}
0868
0869 bool massConstraint() const override;
0870
0871
0872 PackedCandidate *clone() const override { return new PackedCandidate(*this); }
0873
0874
0875 double vertexChi2() const override;
0876
0877
0878
0879
0880
0881
0882 double vertexNdof() const override;
0883
0884 double vertexNormalizedChi2() const override;
0885
0886 double vertexCovariance(int i, int j) const override;
0887
0888 CovarianceMatrix vertexCovariance() const override {
0889 CovarianceMatrix m;
0890 fillVertexCovariance(m);
0891 return m;
0892 }
0893
0894 void fillVertexCovariance(CovarianceMatrix &v) const override;
0895
0896
0897 bool hasMasterClone() const override;
0898
0899
0900
0901 const reco::CandidateBaseRef &masterClone() const override;
0902
0903
0904
0905 bool hasMasterClonePtr() const override;
0906
0907
0908
0909
0910 const reco::CandidatePtr &masterClonePtr() const override;
0911
0912
0913 template <typename Ref>
0914 Ref masterRef() const {
0915 return masterClone().template castTo<Ref>();
0916 }
0917
0918 bool isElectron() const override { return false; }
0919 bool isMuon() const override { return false; }
0920 bool isStandAloneMuon() const override { return ((qualityFlags_ & muonFlagsMask) >> muonFlagsShift) & 1; }
0921 bool isGlobalMuon() const override { return ((qualityFlags_ & muonFlagsMask) >> muonFlagsShift) & 2; }
0922 bool isTrackerMuon() const override { return false; }
0923 bool isCaloMuon() const override { return false; }
0924 bool isPhoton() const override { return false; }
0925 bool isConvertedPhoton() const override { return false; }
0926 bool isJet() const override { return false; }
0927 bool isGoodEgamma() const { return (qualityFlags_ & egammaFlagsMask) != 0; }
0928
0929
0930 void setPuppiWeight(float p,
0931 float p_nolep = 0.0);
0932
0933 float puppiWeight() const;
0934 float puppiWeightNoLep() const;
0935
0936
0937 void setRawCaloFraction(float p);
0938
0939 float rawCaloFraction() const {
0940 return (rawCaloFraction_ / 100.);
0941 }
0942 void setRawHcalFraction(float p);
0943 float rawHcalFraction() const {
0944 return (rawHcalFraction_ / 100.);
0945 }
0946 void setCaloFraction(float p);
0947 float caloFraction() const {
0948 return (caloFraction_ / 100.);
0949 }
0950 void setHcalFraction(float p);
0951
0952 float hcalFraction() const {
0953 return (hcalFraction_ / 100.);
0954 }
0955
0956
0957 void setIsIsolatedChargedHadron(bool p);
0958
0959 bool isIsolatedChargedHadron() const {
0960 return isIsolatedChargedHadron_;
0961 }
0962
0963
0964 struct PackedCovariance {
0965 PackedCovariance()
0966 : dxydxy(0), dxydz(0), dzdz(0), dlambdadz(0), dphidxy(0), dptdpt(0), detadeta(0), dphidphi(0) {}
0967
0968 uint16_t dxydxy;
0969 uint16_t dxydz;
0970 uint16_t dzdz;
0971
0972 uint16_t dlambdadz;
0973 uint16_t dphidxy;
0974
0975 uint16_t dptdpt;
0976 uint16_t detadeta;
0977 uint16_t dphidphi;
0978 };
0979
0980
0981 virtual float time() const { return vertexRef()->t() + dtimeAssociatedPV(); }
0982
0983 virtual float dtime(size_t ipv = 0) const {
0984 return dtimeAssociatedPV() + (*pvRefProd_)[pvRefKey_].t() - (*pvRefProd_)[ipv].t();
0985 }
0986
0987 virtual float dtimeAssociatedPV() const {
0988 if (packedTime_ == 0)
0989 return 0.f;
0990 if (packedTimeError_ > 0)
0991 return unpackTimeWithError(packedTime_, packedTimeError_);
0992 else
0993 return unpackTimeNoError(packedTime_);
0994 }
0995
0996 virtual float timeError() const { return unpackTimeError(packedTimeError_); }
0997
0998 void setDTimeAssociatedPV(float aTime, float aTimeError = 0);
0999
1000 void setTime(float aTime, float aTimeError = 0) { setDTimeAssociatedPV(aTime - vertexRef()->t(), aTimeError); }
1001
1002 private:
1003 void unpackCovarianceElement(reco::TrackBase::CovarianceMatrix &m, uint16_t packed, int i, int j) const {
1004 m(i, j) = covarianceParameterization().unpack(
1005 packed, covarianceSchema_, i, j, pt(), eta(), numberOfHits(), numberOfPixelHits());
1006 }
1007 uint16_t packCovarianceElement(const reco::TrackBase::CovarianceMatrix &m, int i, int j) const {
1008 return covarianceParameterization().pack(
1009 m(i, j), covarianceSchema_, i, j, pt(), eta(), numberOfHits(), numberOfPixelHits());
1010 }
1011
1012 protected:
1013 friend class ::testPackedCandidate;
1014 static constexpr float kMinDEtaToStore_ = 0.001;
1015 static constexpr float kMinDTrkPtToStore_ = 0.001;
1016
1017 uint16_t packedPt_, packedEta_, packedPhi_, packedM_;
1018 uint16_t packedDxy_, packedDz_, packedDPhi_, packedDEta_, packedDTrkPt_;
1019 PackedCovariance packedCovariance_;
1020
1021 void pack(bool unpackAfterwards = true);
1022 void unpack() const;
1023 void packVtx(bool unpackAfterwards = true);
1024 void unpackVtx() const;
1025 void packCovariance(const reco::TrackBase::CovarianceMatrix &m, bool unpackAfterwards = true);
1026 void unpackCovariance() const;
1027 void maybeUnpackBoth() const {
1028 if (!p4c_)
1029 unpack();
1030 if (!vertex_)
1031 unpackVtx();
1032 }
1033 void maybeUnpackTrack() const {
1034 if (!track_)
1035 unpackTrk();
1036 }
1037 void maybeUnpackCovariance() const {
1038 if (!m_)
1039 unpackCovariance();
1040 }
1041 void packBoth() {
1042 pack(false);
1043 packVtx(false);
1044 delete p4_.exchange(nullptr);
1045 delete p4c_.exchange(nullptr);
1046 delete vertex_.exchange(nullptr);
1047 unpack();
1048 unpackVtx();
1049 }
1050
1051 void unpackTrk() const;
1052
1053 uint8_t packedPuppiweight_;
1054 int8_t packedPuppiweightNoLepDiff_;
1055
1056 uint8_t rawCaloFraction_;
1057 int8_t rawHcalFraction_;
1058 uint8_t caloFraction_;
1059 int8_t hcalFraction_;
1060 int16_t packedTime_;
1061 uint8_t packedTimeError_;
1062
1063 bool isIsolatedChargedHadron_;
1064
1065
1066 mutable std::atomic<PolarLorentzVector *> p4_;
1067 mutable std::atomic<LorentzVector *> p4c_;
1068
1069 mutable std::atomic<Point *> vertex_;
1070 CMS_THREAD_GUARD(vertex_) mutable float dxy_, dz_, dphi_, deta_, dtrkpt_;
1071
1072 mutable std::atomic<reco::Track *> track_;
1073
1074 int pdgId_;
1075 uint16_t qualityFlags_;
1076
1077 reco::VertexRefProd pvRefProd_;
1078 reco::VertexRef::key_type pvRefKey_;
1079
1080
1081 mutable std::atomic<reco::TrackBase::CovarianceMatrix *> m_;
1082 uint8_t packedHits_,
1083 packedLayers_;
1084
1085
1086
1087
1088 uint8_t normalizedChi2_;
1089 uint16_t covarianceVersion_;
1090 uint16_t covarianceSchema_;
1091 CMS_THREAD_SAFE static CovarianceParameterization covarianceParameterization_;
1092
1093
1094 static std::once_flag covariance_load_flag;
1095 const CovarianceParameterization &covarianceParameterization() const {
1096 if (!hasTrackDetails())
1097 throw edm::Exception(edm::errors::InvalidReference,
1098 "Trying to access covariance matrix for a "
1099 "PackedCandidate for which it's not available. "
1100 "Check hasTrackDetails() before!\n");
1101 std::call_once(
1102 covariance_load_flag, [](int v) { covarianceParameterization_.load(v); }, covarianceVersion_);
1103 if (covarianceParameterization_.loadedVersion() != covarianceVersion_) {
1104 throw edm::Exception(edm::errors::UnimplementedFeature)
1105 << "Attempting to load multiple covariance version in same process. "
1106 "This is not supported.";
1107 }
1108 return covarianceParameterization_;
1109 }
1110
1111
1112 uint16_t firstHit_;
1113
1114
1115 bool overlap(const reco::Candidate &) const override;
1116 template <typename, typename, typename>
1117 friend struct component;
1118 friend class ::OverlapChecker;
1119 friend class ShallowCloneCandidate;
1120 friend class ShallowClonePtrCandidate;
1121
1122 enum qualityFlagsShiftsAndMasks {
1123 assignmentQualityMask = 0x7,
1124 assignmentQualityShift = 0,
1125 trackHighPurityMask = 0x8,
1126 trackHighPurityShift = 3,
1127 lostInnerHitsMask = 0x30,
1128 lostInnerHitsShift = 4,
1129 muonFlagsMask = 0x0600,
1130 muonFlagsShift = 9,
1131 egammaFlagsMask = 0x0800,
1132 egammaFlagsShift = 11
1133 };
1134
1135
1136 static uint8_t packTimeError(float timeError);
1137 static float unpackTimeError(uint8_t timeError);
1138 static float unpackTimeNoError(int16_t time);
1139 static int16_t packTimeNoError(float time);
1140 static float unpackTimeWithError(int16_t time, uint8_t timeError);
1141 static int16_t packTimeWithError(float time, float timeError);
1142 static constexpr float MIN_TIMEERROR = 0.002f;
1143 static constexpr float MIN_TIME_NOERROR = 0.0002f;
1144
1145 static constexpr int EXPO_TIMEERROR = 5;
1146 static constexpr int EXPO_TIME_NOERROR = 6;
1147 static constexpr int EXPO_TIME_WITHERROR = -6;
1148 };
1149
1150 typedef std::vector<pat::PackedCandidate> PackedCandidateCollection;
1151 typedef edm::Ref<pat::PackedCandidateCollection> PackedCandidateRef;
1152 typedef edm::RefVector<pat::PackedCandidateCollection> PackedCandidateRefVector;
1153 }
1154
1155 #endif