Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
#include "DataFormats/PatCandidates/interface/PackedGenParticle.h"
#include "DataFormats/Math/interface/libminifloat.h"
#include "DataFormats/Math/interface/deltaPhi.h"

void pat::PackedGenParticle::pack(bool unpackAfterwards) {
  packedPt_ = MiniFloatConverter::float32to16(p4_.load()->Pt());
  packedY_ = int16_t(p4_.load()->Rapidity() / 6.0f * std::numeric_limits<int16_t>::max());
  packedPhi_ = int16_t(p4_.load()->Phi() / 3.2f * std::numeric_limits<int16_t>::max());
  packedM_ = MiniFloatConverter::float32to16(p4_.load()->M());
  if (unpackAfterwards) {
    delete p4_.exchange(nullptr);
    delete p4c_.exchange(nullptr);
    unpack();  // force the values to match with the packed ones
  }
}

void pat::PackedGenParticle::unpack() const {
  float y = int16_t(packedY_) * 6.0f / std::numeric_limits<int16_t>::max();
  float pt = MiniFloatConverter::float16to32(packedPt_);
  float m = MiniFloatConverter::float16to32(packedM_);
  float pz = std::tanh(y) * std::sqrt((m * m + pt * pt) / (1. - std::tanh(y) * std::tanh(y)));
  float eta = 0;
  if (pt != 0.) {
    eta = std::asinh(pz / pt);
  }
  double shift = (pt < 1. ? 0.1 * pt : 0.1 / pt);    // shift particle phi to break degeneracies in angular separations
  double sign = ((int(pt * 10) % 2 == 0) ? 1 : -1);  // introduce a pseudo-random sign of the shift
  double phi = int16_t(packedPhi_) * 3.2f / std::numeric_limits<int16_t>::max() +
               sign * shift * 3.2 / std::numeric_limits<int16_t>::max();
  auto p4 = std::make_unique<PolarLorentzVector>(pt, eta, phi, m);
  PolarLorentzVector* expectp4 = nullptr;
  if (p4_.compare_exchange_strong(expectp4, p4.get())) {
    p4.release();
  }
  auto p4c = std::make_unique<LorentzVector>(*p4_);
  LorentzVector* expectp4c = nullptr;
  if (p4c_.compare_exchange_strong(expectp4c, p4c.get())) {
    p4c.release();
  }
}

pat::PackedGenParticle::~PackedGenParticle() {
  delete p4_.load();
  delete p4c_.load();
}

float pat::PackedGenParticle::dxy(const Point& p) const {
  unpack();
  return -(vertex_.X() - p.X()) * std::sin(float(p4_.load()->Phi())) +
         (vertex_.Y() - p.Y()) * std::cos(float(p4_.load()->Phi()));
}
float pat::PackedGenParticle::dz(const Point& p) const {
  unpack();
  return (vertex_.Z() - p.X()) - ((vertex_.X() - p.X()) * std::cos(float(p4_.load()->Phi())) +
                                  (vertex_.Y() - p.Y()) * std::sin(float(p4_.load()->Phi()))) *
                                     p4_.load()->Pz() / p4_.load()->Pt();
}

//// Everything below is just trivial implementations of reco::Candidate methods

const reco::CandidateBaseRef& pat::PackedGenParticle::masterClone() const {
  throw cms::Exception("Invalid Reference") << "this Candidate has no master clone reference."
                                            << "Can't call masterClone() method.\n";
}

bool pat::PackedGenParticle::hasMasterClone() const { return false; }

bool pat::PackedGenParticle::hasMasterClonePtr() const { return false; }

const reco::CandidatePtr& pat::PackedGenParticle::masterClonePtr() const {
  throw cms::Exception("Invalid Reference") << "this Candidate has no master clone ptr."
                                            << "Can't call masterClonePtr() method.\n";
}

size_t pat::PackedGenParticle::numberOfDaughters() const { return 0; }

size_t pat::PackedGenParticle::numberOfMothers() const {
  if (motherRef().isNonnull())
    return 1;
  return 0;
}

bool pat::PackedGenParticle::overlap(const reco::Candidate& o) const {
  return p4() == o.p4() && vertex() == o.vertex() && charge() == o.charge();
  //  return  p4() == o.p4() && charge() == o.charge();
}

const reco::Candidate* pat::PackedGenParticle::daughter(size_type) const { return nullptr; }

const reco::Candidate* pat::PackedGenParticle::mother(size_type) const { return motherRef().get(); }

const reco::Candidate* pat::PackedGenParticle::daughter(const std::string&) const {
  throw edm::Exception(edm::errors::UnimplementedFeature)
      << "This Candidate type does not implement daughter(std::string). "
      << "Please use CompositeCandidate or NamedCompositeCandidate.\n";
}

reco::Candidate* pat::PackedGenParticle::daughter(const std::string&) {
  throw edm::Exception(edm::errors::UnimplementedFeature)
      << "This Candidate type does not implement daughter(std::string). "
      << "Please use CompositeCandidate or NamedCompositeCandidate.\n";
}

reco::Candidate* pat::PackedGenParticle::daughter(size_type) { return nullptr; }

double pat::PackedGenParticle::vertexChi2() const { return 0; }

double pat::PackedGenParticle::vertexNdof() const { return 0; }

double pat::PackedGenParticle::vertexNormalizedChi2() const { return 0; }

double pat::PackedGenParticle::vertexCovariance(int i, int j) const {
  throw edm::Exception(edm::errors::UnimplementedFeature)
      << "reco::ConcreteCandidate does not implement vertex covariant matrix.\n";
}

void pat::PackedGenParticle::fillVertexCovariance(CovarianceMatrix& err) const {
  throw edm::Exception(edm::errors::UnimplementedFeature)
      << "reco::ConcreteCandidate does not implement vertex covariant matrix.\n";
}

bool pat::PackedGenParticle::isElectron() const { return false; }

bool pat::PackedGenParticle::isMuon() const { return false; }

bool pat::PackedGenParticle::isGlobalMuon() const { return false; }

bool pat::PackedGenParticle::isStandAloneMuon() const { return false; }

bool pat::PackedGenParticle::isTrackerMuon() const { return false; }

bool pat::PackedGenParticle::isCaloMuon() const { return false; }

bool pat::PackedGenParticle::isPhoton() const { return false; }

bool pat::PackedGenParticle::isConvertedPhoton() const { return false; }

bool pat::PackedGenParticle::isJet() const { return false; }

bool pat::PackedGenParticle::longLived() const { return false; }

bool pat::PackedGenParticle::massConstraint() const { return false; }