GenericParticle

Macros

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 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
//
//

#ifndef DataFormats_PatCandidates_GenericParticle_h
#define DataFormats_PatCandidates_GenericParticle_h

/**
  \class    pat::GenericParticle GenericParticle.h "DataFormats/PatCandidates/interface/GenericParticle.h"
  \brief    Analysis-level Generic Particle class (e.g. for hadron or muon not fully reconstructed)

   GenericParticle implements the analysis-level generic particle class within the 'pat'
   namespace.

  \author   Giovanni Petrucciani
*/

#include "DataFormats/PatCandidates/interface/PATObject.h"
#include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
#include "DataFormats/EgammaReco/interface/SuperClusterFwd.h"
#include "DataFormats/EgammaReco/interface/SuperCluster.h"
#include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
#include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
#include "DataFormats/PatCandidates/interface/Isolation.h"
#include "DataFormats/PatCandidates/interface/Vertexing.h"
#include "DataFormats/HepMCCandidate/interface/GenParticle.h"

// Define typedefs for convenience
namespace pat {
  class GenericParticle;
  typedef std::vector<GenericParticle> GenericParticleCollection;
  typedef edm::Ref<GenericParticleCollection> GenericParticleRef;
  typedef edm::RefVector<GenericParticleCollection> GenericParticleRefVector;
}  // namespace pat

// Class definition
namespace pat {

  class GenericParticle : public PATObject<reco::RecoCandidate> {
  public:
    /// default constructor
    GenericParticle();
    /// constructor from Candidate
    GenericParticle(const reco::Candidate &aGenericParticle);
    /// constructor from ref to Candidate
    GenericParticle(const edm::RefToBase<reco::Candidate> &aGenericParticleRef);
    /// constructor from ref to Candidate
    GenericParticle(const edm::Ptr<reco::Candidate> &aGenericParticleRef);
    /// destructor
    ~GenericParticle() override;

    /// required reimplementation of the Candidate's clone method
    GenericParticle *clone() const override { return new GenericParticle(*this); }

    /// Checks for overlap with another candidate.
    /// It will return 'true' if the other candidate is a RecoCandidate,
    /// and if they reference to at least one same non null track, supercluster or calotower (except for the multiple tracks)
    /// NOTE: It won't work with embedded references
    bool overlap(const Candidate &) const override;

    /// reference to a master track (might be transient refs if Tracks are embedded)
    /// returns null ref if there is no master track
    reco::TrackRef track() const override { return track_.empty() ? trackRef_ : reco::TrackRef(&track_, 0); }
    /// reference to one of a set of multiple tracks (might be transient refs if Tracks are embedded)
    /// throws exception if idx >= numberOfTracks()
    reco::TrackRef track(size_t idx) const override {
      if (idx >= numberOfTracks())
        throw cms::Exception("Index out of bounds")
            << "Requested track " << idx << " out of " << numberOfTracks() << ".\n";
      return (tracks_.empty() ? trackRefs_[idx] : reco::TrackRef(&tracks_, idx));
    }
    /// number of multiple tracks (not including the master one)
    size_t numberOfTracks() const override { return tracks_.empty() ? trackRefs_.size() : tracks_.size(); }
    /// reference to a GsfTrack (might be transient ref if SuperCluster is embedded)
    /// returns null ref if there is no gsf track
    reco::GsfTrackRef gsfTrack() const override {
      return (gsfTrack_.empty() ? gsfTrackRef_ : reco::GsfTrackRef(&gsfTrack_, 0));
    }
    /// reference to a stand-alone muon Track (might be transient ref if SuperCluster is embedded)
    /// returns null ref if there is no stand-alone muon track
    reco::TrackRef standAloneMuon() const override {
      return (standaloneTrack_.empty() ? standaloneTrackRef_ : reco::TrackRef(&standaloneTrack_, 0));
    }
    /// reference to a combined muon Track (might be transient ref if SuperCluster is embedded)
    /// returns null ref if there is no combined muon track
    reco::TrackRef combinedMuon() const override {
      return (combinedTrack_.empty() ? combinedTrackRef_ : reco::TrackRef(&combinedTrack_, 0));
    }
    /// reference to a SuperCluster (might be transient ref if SuperCluster is embedded)
    /// returns null ref if there is no supercluster
    reco::SuperClusterRef superCluster() const override {
      return superCluster_.empty() ? superClusterRef_ : reco::SuperClusterRef(&superCluster_, 0);
    }
    /// reference to a CaloTower  (might be transient ref if CaloTower is embedded)
    /// returns null ref if there is no calotower
    CaloTowerRef caloTower() const override {
      return caloTower_.empty() ? caloTowerRef_ : CaloTowerRef(&caloTower_, 0);
    }

    /// sets master track reference (or even embed it into the object)
    virtual void setTrack(const reco::TrackRef &ref, bool embed = false);
    /// sets multiple track references (or even embed the tracks into the object - whatch out for disk size issues!)
    virtual void setTracks(const reco::TrackRefVector &refs, bool embed = false);
    /// sets stand-alone muon track reference (or even embed it into the object)
    virtual void setStandAloneMuon(const reco::TrackRef &ref, bool embed = false);
    /// sets combined muon track reference (or even embed it into the object)
    virtual void setCombinedMuon(const reco::TrackRef &ref, bool embed = false);
    /// sets gsf track reference (or even embed it into the object)
    virtual void setGsfTrack(const reco::GsfTrackRef &ref, bool embed = false);
    /// sets supercluster reference (or even embed it into the object)
    virtual void setSuperCluster(const reco::SuperClusterRef &ref, bool embed = false);
    /// sets calotower reference (or even embed it into the object)
    virtual void setCaloTower(const CaloTowerRef &ref, bool embed = false);

    /// embeds the master track instead of keeping a reference to it
    void embedTrack();
    /// embeds the other tracks instead of keeping references
    void embedTracks();
    /// embeds the stand-alone track instead of keeping a reference to it
    void embedStandalone();
    /// embeds the combined track instead of keeping a reference to it
    void embedCombined();
    /// embeds the gsf track instead of keeping a reference to it
    void embedGsfTrack();
    /// embeds the supercluster instead of keeping a reference to it
    void embedSuperCluster();
    /// embeds the calotower instead of keeping a reference to it
    void embedCaloTower();

    /// returns a user defined quality value, if set by the user to some meaningful value
    float quality() { return quality_; }
    /// sets a user defined quality value
    void setQuality(float quality) { quality_ = quality; }

    //============ BEGIN ISOLATION BLOCK =====
    /// Returns the isolation variable for a specifc key (or
    /// pseudo-key like CaloIso), or -1.0 if not available
    float userIsolation(IsolationKeys key) const {
      if (key >= 0) {
        //if (key >= isolations_.size()) throw cms::Excepton("Missing Data")
        //<< "Isolation corresponding to key "
        //<< key << " was not stored for this particle.";
        if (size_t(key) >= isolations_.size())
          return -1.0;
        return isolations_[key];
      } else
        switch (key) {
          case pat::CaloIso:
            //if (isolations_.size() <= pat::HcalIso) throw cms::Excepton("Missing Data")
            //<< "CalIsoo Isolation was not stored for this particle.";
            if (isolations_.size() <= pat::HcalIso)
              return -1.0;
            return isolations_[pat::EcalIso] + isolations_[pat::HcalIso];
          default:
            return -1.0;
            //throw cms::Excepton("Missing Data") << "Isolation corresponding to key "
            //<< key << " was not stored for this particle.";
        }
    }
    /// Returns the isolation variable for string type function arguments
    /// (to be used with the cut-string parser);
    /// the possible values of the strings are the enums defined in
    /// DataFormats/PatCandidates/interface/Isolation.h
    float userIsolation(const std::string &key) const {
      // remove leading namespace specifier
      std::string prunedKey = (key.find("pat::") == 0) ? std::string(key, 5) : key;
      if (prunedKey == "TrackIso")
        return userIsolation(pat::TrackIso);
      if (prunedKey == "EcalIso")
        return userIsolation(pat::EcalIso);
      if (prunedKey == "HcalIso")
        return userIsolation(pat::HcalIso);
      if (prunedKey == "PfAllParticleIso")
        return userIsolation(pat::PfAllParticleIso);
      if (prunedKey == "PfChargedHadronIso")
        return userIsolation(pat::PfChargedHadronIso);
      if (prunedKey == "PfNeutralHadronIso")
        return userIsolation(pat::PfNeutralHadronIso);
      if (prunedKey == "PfGammaIso")
        return userIsolation(pat::PfGammaIso);
      if (prunedKey == "User1Iso")
        return userIsolation(pat::User1Iso);
      if (prunedKey == "User2Iso")
        return userIsolation(pat::User2Iso);
      if (prunedKey == "User3Iso")
        return userIsolation(pat::User3Iso);
      if (prunedKey == "User4Iso")
        return userIsolation(pat::User4Iso);
      if (prunedKey == "User5Iso")
        return userIsolation(pat::User5Iso);
      if (prunedKey == "UserBaseIso")
        return userIsolation(pat::UserBaseIso);
      if (prunedKey == "CaloIso")
        return userIsolation(pat::CaloIso);
      //throw cms::Excepton("Missing Data")
      //<< "Isolation corresponding to key "
      //<< key << " was not stored for this particle.";
      return -1.0;
    }
    /// Sets the isolation variable for a specifc key.
    /// Note that you can't set isolation for a pseudo-key like CaloIso
    void setIsolation(IsolationKeys key, float value) {
      if (key >= 0) {
        if (size_t(key) >= isolations_.size())
          isolations_.resize(key + 1, -1.0);
        isolations_[key] = value;
      } else {
        throw cms::Exception("Illegal Argument")
            << "The key for which you're setting isolation does not correspond "
            << "to an individual isolation but to the sum of more independent isolations "
            << "(e.g. Calo = Ecal + Hcal), so you can't SET the value, just GET it.\n"
            << "Please set up each component independly.\n";
      }
    }

    // ---- specific getters ----
    /// Return the tracker isolation variable that was stored in this
    /// object when produced, or -1.0 if there is none
    float trackIso() const { return userIsolation(pat::TrackIso); }
    /// Return the sum of ecal and hcal isolation variable that were
    /// stored in this object when produced, or -1.0 if at least one
    /// is missing
    float caloIso() const { return userIsolation(pat::CaloIso); }
    /// Return the ecal isolation variable that was stored in this
    /// object when produced, or -1.0 if there is none
    float ecalIso() const { return userIsolation(pat::EcalIso); }
    /// Return the hcal isolation variable that was stored in this
    /// object when produced, or -1.0 if there is none
    float hcalIso() const { return userIsolation(pat::HcalIso); }

    // ---- specific setters ----
    /// Sets tracker isolation variable
    void setTrackIso(float trackIso) { setIsolation(pat::TrackIso, trackIso); }
    /// Sets ecal isolation variable
    void setEcalIso(float caloIso) { setIsolation(pat::EcalIso, caloIso); }
    /// Sets hcal isolation variable
    void setHcalIso(float caloIso) { setIsolation(pat::HcalIso, caloIso); }
    /// Sets user isolation variable #index
    void setUserIso(float value, uint8_t index = 0) { setIsolation(IsolationKeys(UserBaseIso + index), value); }

    //============ BEGIN ISODEPOSIT BLOCK =====
    /// Returns the IsoDeposit associated with some key, or a null pointer if it is not available
    const IsoDeposit *isoDeposit(IsolationKeys key) const {
      for (IsoDepositPairs::const_iterator it = isoDeposits_.begin(), ed = isoDeposits_.end(); it != ed; ++it) {
        if (it->first == key)
          return &it->second;
      }
      return nullptr;
    }

    /// Sets the IsoDeposit associated with some key; if it is already existent, it is overwritten.
    void setIsoDeposit(IsolationKeys key, const IsoDeposit &dep) {
      IsoDepositPairs::iterator it = isoDeposits_.begin(), ed = isoDeposits_.end();
      for (; it != ed; ++it) {
        if (it->first == key) {
          it->second = dep;
          return;
        }
      }
      isoDeposits_.push_back(std::make_pair(key, dep));
    }

    // ---- specific getters ----
    const IsoDeposit *trackIsoDeposit() const { return isoDeposit(pat::TrackIso); }
    const IsoDeposit *ecalIsoDeposit() const { return isoDeposit(pat::EcalIso); }
    const IsoDeposit *hcalIsoDeposit() const { return isoDeposit(pat::HcalIso); }
    const IsoDeposit *userIsoDeposit(uint8_t index = 0) const { return isoDeposit(IsolationKeys(UserBaseIso + index)); }

    // ---- specific setters ----
    void trackIsoDeposit(const IsoDeposit &dep) { setIsoDeposit(pat::TrackIso, dep); }
    void ecalIsoDeposit(const IsoDeposit &dep) { setIsoDeposit(pat::EcalIso, dep); }
    void hcalIsoDeposit(const IsoDeposit &dep) { setIsoDeposit(pat::HcalIso, dep); }
    void userIsoDeposit(const IsoDeposit &dep, uint8_t index = 0) {
      setIsoDeposit(IsolationKeys(UserBaseIso + index), dep);
    }

    /// Vertex association (or associations, if any). Return null pointer if none has been set
    const pat::VertexAssociation *vertexAssociation(size_t index = 0) const {
      return vtxAss_.size() > index ? &vtxAss_[index] : nullptr;
    }
    /// Vertex associations. Can be empty if it was not enabled in the config file
    const std::vector<pat::VertexAssociation> &vertexAssociations() const { return vtxAss_; }
    /// Set a single vertex association
    void setVertexAssociation(const pat::VertexAssociation &assoc) {
      vtxAss_ = std::vector<pat::VertexAssociation>(1, assoc);
    }
    /// Set multiple vertex associations
    void setVertexAssociations(const std::vector<pat::VertexAssociation> &assocs) { vtxAss_ = assocs; }

  protected:
    // Any sort of single tracks
    reco::TrackRef trackRef_, standaloneTrackRef_, combinedTrackRef_;  // ref
    reco::TrackCollection track_, standaloneTrack_, combinedTrack_;    // embedded

    // GsfTrack
    reco::GsfTrackRef gsfTrackRef_;      // normal
    reco::GsfTrackCollection gsfTrack_;  // embedded

    // CaloTower
    CaloTowerRef caloTowerRef_;      // ref
    CaloTowerCollection caloTower_;  // embedded

    // SuperCluster
    reco::SuperClusterRef superClusterRef_;      // ref
    reco::SuperClusterCollection superCluster_;  // embedded

    // Multiple tracks
    reco::TrackRefVector trackRefs_;  // by ref
    reco::TrackCollection tracks_;    // embedded

    // information originally in external branches
    // some quality variable
    float quality_;

    // --- Isolation and IsoDeposit related datamebers ---
    typedef std::vector<std::pair<IsolationKeys, pat::IsoDeposit> > IsoDepositPairs;
    IsoDepositPairs isoDeposits_;
    std::vector<float> isolations_;

    // --- Vertexing information
    std::vector<pat::VertexAssociation> vtxAss_;

    void fillInFrom(const reco::Candidate &cand);
  };

}  // namespace pat

#endif