ElectronIDPFCandidateSelectorDefinition

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
#ifndef CommonTools_ParticleFlow_ElectronIDPFCandidateSelectorDefinition
#define CommonTools_ParticleFlow_ElectronIDPFCandidateSelectorDefinition

/**
   \class    pf2pat::ElectronIDPFCandidateSelectorDefinition ElectronIDPFCandidateSelectorDefinition.h "CommonTools/ParticleFlow/interface/ElectronIDPFCandidateSelectorDefinition.h"
   \brief    Selects PFCandidates basing on cuts provided with string cut parser

   \author   Giovanni Petrucciani
   \version  $Id: ElectronIDPFCandidateSelectorDefinition.h,v 1.1 2011/01/28 20:56:44 srappocc Exp $
*/

#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/ConsumesCollector.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
#include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
#include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
#include "DataFormats/Common/interface/ValueMap.h"
#include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
#include "CommonTools/ParticleFlow/interface/PFCandidateSelectorDefinition.h"
#include <algorithm>

namespace pf2pat {

  struct ElectronIDPFCandidateSelectorDefinition : public PFCandidateSelectorDefinition {
    ElectronIDPFCandidateSelectorDefinition(const edm::ParameterSet& cfg, edm::ConsumesCollector&& iC)
        : electronsToken_(
              iC.consumes<reco::GsfElectronCollection>(cfg.getParameter<edm::InputTag>("recoGsfElectrons"))),
          electronIdToken_(iC.consumes<edm::ValueMap<float> >(cfg.getParameter<edm::InputTag>("electronIdMap"))) {
      if (cfg.exists("bitsToCheck")) {
        isBitMap_ = true;
        mask_ = 0;
        if (cfg.existsAs<std::vector<std::string> >("bitsToCheck")) {
          std::vector<std::string> strbits = cfg.getParameter<std::vector<std::string> >("bitsToCheck");
          for (std::vector<std::string>::const_iterator istrbit = strbits.begin(), estrbit = strbits.end();
               istrbit != estrbit;
               ++istrbit) {
            if (*istrbit == "id") {
              mask_ |= 1;
            } else if (*istrbit == "iso") {
              mask_ |= 2;
            } else if (*istrbit == "conv") {
              mask_ |= 4;
            } else if (*istrbit == "ip") {
              mask_ |= 8;
            } else
              throw cms::Exception("Configuration")
                  << "ElectronIDPFCandidateSelector: "
                  << "bitsToCheck allowed string values are only id(0), iso(1), conv(2), ip(3).\n"
                  << "Otherwise, use uint32_t bitmask).\n";
          }
        } else if (cfg.existsAs<uint32_t>("bitsToCheck")) {
          mask_ = cfg.getParameter<uint32_t>("bitsToCheck");
        } else {
          throw cms::Exception("Configuration")
              << "ElectronIDPFCandidateSelector: "
              << "bitsToCheck must be either a vector of strings, or a uint32 bitmask.\n";
        }
      } else {
        isBitMap_ = false;
        value_ = cfg.getParameter<double>("electronIdCut");
      }
    }

    static void fillPSetDescription(edm::ParameterSetDescription& desc) {
      desc.add<edm::InputTag>("recoGsfElectrons", edm::InputTag(""));
      desc.add<edm::InputTag>("electronIdMap", edm::InputTag(""));
      //desc.add<std::vector<std::string> >("bitsToCheck");
      //desc.add<uint32_t>("bitsToCheck");
      desc.add<double>("electronIdCut", 0.);
    }

    void select(const HandleToCollection& hc, const edm::Event& e, const edm::EventSetup& s) {
      selected_.clear();

      edm::Handle<reco::GsfElectronCollection> electrons;
      e.getByToken(electronsToken_, electrons);

      edm::Handle<edm::ValueMap<float> > electronId;
      e.getByToken(electronIdToken_, electronId);

      unsigned key = 0;
      for (collection::const_iterator pfc = hc->begin(); pfc != hc->end(); ++pfc, ++key) {
        // Get GsfTrack for matching with reco::GsfElectron objects
        reco::GsfTrackRef PfTk = pfc->gsfTrackRef();

        // skip ones without GsfTrack: they won't be matched anyway
        if (PfTk.isNull())
          continue;

        int match = -1;
        // try first the non-ambiguous tracks
        for (auto it = electrons->begin(), ed = electrons->end(); it != ed; ++it) {
          if (it->gsfTrack() == PfTk) {
            match = it - electrons->begin();
            break;
          }
        }
        // then the ambiguous ones
        if (match == -1) {
          for (auto it = electrons->begin(), ed = electrons->end(); it != ed; ++it) {
            if (std::count(it->ambiguousGsfTracks().begin(), it->ambiguousGsfTracks().end(), PfTk) > 0) {
              match = it - electrons->begin();
              break;
            }
          }
        }
        // if found, make a GsfElectronRef and read electron id
        if (match != -1) {
          reco::GsfElectronRef ref(electrons, match);
          float eleId = (*electronId)[ref];
          bool pass = false;
          if (isBitMap_) {
            uint32_t thisval = eleId;
            pass = ((thisval & mask_) == mask_);
          } else {
            pass = (eleId > value_);
          }
          if (pass) {
            selected_.push_back(reco::PFCandidate(*pfc));
            reco::PFCandidatePtr ptrToMother(hc, key);
            selected_.back().setSourceCandidatePtr(ptrToMother);
          }
        }
      }
    }

  private:
    edm::EDGetTokenT<reco::GsfElectronCollection> electronsToken_;
    edm::EDGetTokenT<edm::ValueMap<float> > electronIdToken_;
    bool isBitMap_;
    uint32_t mask_;
    double value_;
  };
}  // namespace pf2pat

#endif