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