StringCutEventSelector

StringCutsEventSelector

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

#include "FWCore/Framework/interface/ConsumesCollector.h"
#include "CommonTools/UtilAlgos/interface/EventSelector.h"
#include "CommonTools/UtilAlgos/interface/InputTagDistributor.h"
#include "CommonTools/Utils/interface/StringCutObjectSelector.h"
#include "CommonTools/Utils/interface/StringObjectFunction.h"
#include "FWCore/ServiceRegistry/interface/Service.h"

template <typename Object, bool any = false>
class StringCutEventSelector : public EventSelector {
public:
  StringCutEventSelector(const edm::ParameterSet& pset, edm::ConsumesCollector&& iC)
      : StringCutEventSelector(pset, iC) {}
  StringCutEventSelector(const edm::ParameterSet& pset, edm::ConsumesCollector& iC)
      : EventSelector(pset, iC),
        src_(edm::Service<InputTagDistributorService>()->retrieve("src", pset)),
        srcToken_(iC.consumes<edm::View<Object> >(src_)),
        f_(pset.getParameter<std::string>("cut")),
        //put this guy to 0 to do the check on "all" object in the collection
        nFirst_(pset.getParameter<unsigned int>("nFirst")),
        order_(nullptr) {
    std::stringstream ss;
    ss << "string cut based selection on collection: " << src_;
    description_.push_back(ss.str());
    ss.str("");
    description_.push_back(std::string("selection cut is: ") + pset.getParameter<std::string>("cut"));
    if (pset.exists("order"))
      order_ = new StringObjectFunction<Object>(pset.getParameter<std::string>("order"));
  }

  bool select(const edm::Event& e) const override {
    edm::Handle<edm::View<Object> > oH;
    e.getByToken(srcToken_, oH);
    std::vector<const Object*> copyToSort(oH->size());
    for (uint i = 0; i != oH->size(); ++i)
      copyToSort[i] = &(*oH)[i];
    if (order_)
      std::sort(copyToSort.begin(), copyToSort.end(), sortByStringFunction<Object>(order_));

    //reject events if not enough object in collection
    //      if ((nFirst_!=0) && (oH->size()<nFirst_)) return false;
    unsigned int i = 0;
    unsigned int found = 0;
    for (; i != oH->size(); i++) {
      const Object& o = *(copyToSort[i]);
      if (any) {
        if (f_(o))
          ++found;
        if (found >= nFirst_)
          return true;
      } else {
        //stop doing the check if reaching too far in the collection
        if ((nFirst_ != 0) && (i >= nFirst_))
          break;
        if (!f_(o))
          return false;
      }
    }
    return !any;
  }

private:
  edm::InputTag src_;
  edm::EDGetTokenT<edm::View<Object> > srcToken_;
  StringCutObjectSelector<Object> f_;
  unsigned int nFirst_;
  StringObjectFunction<Object>* order_;
};

template <typename Object, bool existenceMatter = true>
class StringCutsEventSelector : public EventSelector {
public:
  StringCutsEventSelector(const edm::ParameterSet& pset, edm::ConsumesCollector&& iC)
      : StringCutsEventSelector(pset, iC) {}
  StringCutsEventSelector(const edm::ParameterSet& pset, edm::ConsumesCollector& iC)
      : EventSelector(pset, iC),
        src_(edm::Service<InputTagDistributorService>()->retrieve("src", pset)),
        srcToken_(iC.consumes<edm::View<Object> >(src_)),
        order_(nullptr) {
    std::vector<std::string> selection = pset.getParameter<std::vector<std::string> >("cut");
    std::stringstream ss;
    ss << "string cut based selection on collection: " << src_;
    description_.push_back(ss.str());
    ss.str("");
    description_.push_back("selection cuts are:");
    for (unsigned int i = 0; i != selection.size(); i++)
      if (selection[i] != "-") {
        f_.push_back(new StringCutObjectSelector<Object>(selection[i]));
        ss << "[" << i << "]: " << selection[i];
        description_.push_back(ss.str());
        ss.str("");
      } else {
        f_.push_back(nullptr);
        ss << "[" << i << "]: no selection";
        description_.push_back(ss.str());
        ss.str("");
      }
    if (pset.exists("order"))
      order_ = new StringObjectFunction<Object>(pset.getParameter<std::string>("order"));
  }
  ~StringCutsEventSelector() override {
    unsigned int i = 0;
    for (; i != f_.size(); i++)
      if (f_[i]) {
        delete f_[i];
        f_[i] = nullptr;
      }
    if (order_)
      delete order_;
  }

  bool select(const edm::Event& e) const override {
    edm::Handle<edm::View<Object> > oH;
    e.getByToken(srcToken_, oH);
    std::vector<const Object*> copyToSort(oH->size());
    for (uint i = 0; i != oH->size(); ++i)
      copyToSort[i] = &(*oH)[i];
    if (order_)
      std::sort(copyToSort.begin(), copyToSort.end(), sortByStringFunction<Object>(order_));

    unsigned int i = 0;
    if (existenceMatter && oH->size() < f_.size())
      return false;
    for (; i != f_.size(); i++) {
      if (!existenceMatter && i == oH->size())
        break;
      if (!f_[i])
        continue;
      const Object& o = *(copyToSort[i]);
      if (!(*f_[i])(o))
        return false;
    }
    return true;
  }

private:
  edm::InputTag src_;
  edm::EDGetTokenT<edm::View<Object> > srcToken_;
  std::vector<StringCutObjectSelector<Object>*> f_;
  StringObjectFunction<Object>* order_;
};

#endif