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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
//
//

#include "DataFormats/PatCandidates/interface/GenericParticle.h"

using pat::GenericParticle;

/// default constructor
GenericParticle::GenericParticle() : PATObject<reco::RecoCandidate>() {}

/// constructor from Candidate
GenericParticle::GenericParticle(const Candidate &cand) : PATObject<reco::RecoCandidate>() { fillInFrom(cand); }

/// constructor from ref to RecoCandidate
GenericParticle::GenericParticle(const edm::RefToBase<Candidate> &cand) : PATObject<reco::RecoCandidate>() {
  fillInFrom(*cand);
  refToOrig_ = edm::Ptr<reco::Candidate>(cand.id(), cand.get(), cand.key());  // correct RefToBase=>Ptr conversion
}

/// constructor from ref to RecoCandidate
GenericParticle::GenericParticle(const edm::Ptr<Candidate> &cand) : PATObject<reco::RecoCandidate>() {
  fillInFrom(*cand);
  refToOrig_ = cand;
}

/// destructor
GenericParticle::~GenericParticle() {}

// ====== SETTERS =====
/// sets master track reference (or even embed it into the object)
void GenericParticle::setTrack(const reco::TrackRef &ref, bool embed) {
  trackRef_ = ref;
  if (embed)
    embedTrack();
  else
    track_.clear();
}

/// sets multiple track references (or even embed the tracks into the object - whatch out for disk size issues!)
void GenericParticle::setTracks(const reco::TrackRefVector &refs, bool embed) {
  trackRefs_ = refs;
  if (embed)
    embedTracks();
  else
    tracks_.clear();
}

/// sets stand-alone muon track reference (or even embed it into the object)
void GenericParticle::setStandAloneMuon(const reco::TrackRef &ref, bool embed) {
  standaloneTrackRef_ = ref;
  if (embed)
    embedStandalone();
  else
    standaloneTrack_.clear();
}

/// sets combined muon track reference (or even embed it into the object)
void GenericParticle::setCombinedMuon(const reco::TrackRef &ref, bool embed) {
  combinedTrackRef_ = ref;
  if (embed)
    embedCombined();
  else
    combinedTrack_.clear();
}

/// sets gsf track reference (or even embed it into the object)
void GenericParticle::setGsfTrack(const reco::GsfTrackRef &ref, bool embed) {
  gsfTrackRef_ = ref;
  if (embed)
    embedGsfTrack();
  else
    gsfTrack_.clear();
}

/// sets supercluster reference (or even embed it into the object)
void GenericParticle::setSuperCluster(const reco::SuperClusterRef &ref, bool embed) {
  superClusterRef_ = ref;
  if (embed)
    embedSuperCluster();
  else
    superCluster_.clear();
}

/// sets calotower reference (or even embed it into the object)
void GenericParticle::setCaloTower(const CaloTowerRef &ref, bool embed) {
  caloTowerRef_ = ref;
  if (embed) {
    embedCaloTower();
  } else if (!caloTower_.empty()) {
    CaloTowerCollection().swap(caloTower_);
  }
}

// ========== EMBEDDER METHODS
/// embeds the master track instead of keeping a reference to it
void GenericParticle::embedTrack() {
  track_.clear();
  if (trackRef_.isNonnull())
    track_.push_back(*trackRef_);  // import
  trackRef_ = reco::TrackRef();    // clear, to save space (zeroes compress better)
}
/// embeds the other tracks instead of keeping references
void GenericParticle::embedTracks() {
  tracks_.clear();
  tracks_.reserve(trackRefs_.size());
  for (reco::TrackRefVector::const_iterator it = trackRefs_.begin(); it != trackRefs_.end(); ++it) {
    if (it->isNonnull())
      tracks_.push_back(**it);  // embed track
  }
  trackRefs_ = reco::TrackRefVector();  // clear, to save space
}
/// embeds the stand-alone track instead of keeping a reference to it
void GenericParticle::embedStandalone() {
  standaloneTrack_.clear();
  if (standaloneTrackRef_.isNonnull())
    standaloneTrack_.push_back(*standaloneTrackRef_);  // import
  standaloneTrackRef_ = reco::TrackRef();              // clear, to save space (zeroes compress better)
}
/// embeds the combined track instead of keeping a reference to it
void GenericParticle::embedCombined() {
  combinedTrack_.clear();
  if (combinedTrackRef_.isNonnull())
    combinedTrack_.push_back(*combinedTrackRef_);  // import
  combinedTrackRef_ = reco::TrackRef();            // clear, to save space (zeroes compress better)
}
/// embeds the gsf track instead of keeping a reference to it
void GenericParticle::embedGsfTrack() {
  gsfTrack_.clear();
  if (gsfTrackRef_.isNonnull())
    gsfTrack_.push_back(*gsfTrackRef_);  // import
  gsfTrackRef_ = reco::GsfTrackRef();    // clear, to save space (zeroes compress better)
}

/// embeds the supercluster instead of keeping a reference to it
void GenericParticle::embedSuperCluster() {
  superCluster_.clear();
  if (superClusterRef_.isNonnull())
    superCluster_.push_back(*superClusterRef_);  // import
  superClusterRef_ = reco::SuperClusterRef();    // clear, to save space (zeroes compress better)
}
/// embeds the calotower instead of keeping a reference to it
void GenericParticle::embedCaloTower() {
  if (!caloTower_.empty())
    CaloTowerCollection().swap(caloTower_);
  if (caloTowerRef_.isNonnull())
    caloTower_.push_back(*caloTowerRef_);  // import
  caloTowerRef_ = CaloTowerRef();          // clear, to save space (zeroes compress better)
}

void GenericParticle::fillInFrom(const reco::Candidate &cand) {
  // first, kinematics & status
  setCharge(cand.charge());
  setP4(cand.polarP4());
  setVertex(cand.vertex());
  setPdgId(cand.pdgId());
  setStatus(cand.status());
  // then RECO part, if available
  const reco::RecoCandidate *rc = dynamic_cast<const reco::RecoCandidate *>(&cand);
  if (rc != nullptr) {
    setTrack(rc->track());
    setGsfTrack(rc->gsfTrack());
    setStandAloneMuon(rc->standAloneMuon());
    setCombinedMuon(rc->combinedMuon());
    setSuperCluster(rc->superCluster());
    setCaloTower(rc->caloTower());
    size_t ntracks = rc->numberOfTracks();
    if (ntracks > 0) {
      reco::TrackRefVector tracks;
      for (size_t i = 0; i < ntracks; ++i) {
        tracks.push_back(rc->track(i));
      }
      setTracks(tracks);
    }
  }
}

bool GenericParticle::overlap(const reco::Candidate &cand) const {
  const reco::RecoCandidate *rc = dynamic_cast<const reco::RecoCandidate *>(&cand);
  if (rc != nullptr) {
    if (rc->track().isNonnull() && (track() == rc->track()))
      return true;
    if (rc->gsfTrack().isNonnull() && (gsfTrack() == rc->gsfTrack()))
      return true;
    if (rc->standAloneMuon().isNonnull() && (standAloneMuon() == rc->standAloneMuon()))
      return true;
    if (rc->combinedMuon().isNonnull() && (combinedMuon() == rc->combinedMuon()))
      return true;
    if (rc->superCluster().isNonnull() && (superCluster() == rc->superCluster()))
      return true;
    if (rc->caloTower().isNonnull() && (caloTower() == rc->caloTower()))
      return true;
  }
  const GenericParticle *rc2 = dynamic_cast<const GenericParticle *>(&cand);
  if (rc2 != nullptr) {
    if (rc2->track().isNonnull() && (track() == rc2->track()))
      return true;
    if (rc2->gsfTrack().isNonnull() && (gsfTrack() == rc2->gsfTrack()))
      return true;
    if (rc2->standAloneMuon().isNonnull() && (standAloneMuon() == rc2->standAloneMuon()))
      return true;
    if (rc2->combinedMuon().isNonnull() && (combinedMuon() == rc2->combinedMuon()))
      return true;
    if (rc2->superCluster().isNonnull() && (superCluster() == rc2->superCluster()))
      return true;
    if (rc2->caloTower().isNonnull() && (caloTower() == rc2->caloTower()))
      return true;
  }
  return false;
}