Efficiency

PrescaleEventFilter

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
// -*- C++ -*-
//
// Package:    CalibTracker/SiStripCommon
// Class:      PrescaleEventFilter
//
/**\class PrescaleEventFilter PrescaleEventFilter.cc CalibTracker/SiStripCommon/plugins/PrescaleEventFilter.cc

 Description: Simple class to prescale events entering the Strip Tracker Calibration Tree

 Implementation:
     Largely copied from HLTrigger/HLTcore/plugins/HLTPrescaler.cc, without the need to specify a specific trigger path
*/
//
// Original Author:  Marco Musich
//         Created:  Wed, 29 Nov 2017 15:27:07 GMT
//
//

// system include files
#include <memory>

// user include files
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/stream/EDFilter.h"

#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/MakerMacros.h"

#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/StreamID.h"

namespace prescale {
  struct Efficiency {
    Efficiency() : eventCount_(0), acceptCount_(0) {}
    mutable std::atomic<unsigned int> eventCount_;
    mutable std::atomic<unsigned int> acceptCount_;
  };
}  // namespace prescale

//
// class declaration
//

class PrescaleEventFilter : public edm::stream::EDFilter<edm::GlobalCache<prescale::Efficiency> > {
public:
  explicit PrescaleEventFilter(edm::ParameterSet const& iConfig, const prescale::Efficiency* efficiency);
  ~PrescaleEventFilter() override;

  static std::unique_ptr<prescale::Efficiency> initializeGlobalCache(edm::ParameterSet const&) {
    return std::make_unique<prescale::Efficiency>();
  };

  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
  static void globalEndJob(const prescale::Efficiency* efficiency);

private:
  void beginStream(edm::StreamID) override;
  bool filter(edm::Event&, const edm::EventSetup&) override;
  void endStream() override;

  // ----------member data ---------------------------

  /// accept one in prescaleFactor_; 0 means never to accept an event
  unsigned int prescaleFactor_;

  /// event counter
  unsigned int eventCount_;

  /// accept counter
  unsigned int acceptCount_;

  /// initial offset
  unsigned int offsetCount_;
  unsigned int offsetPhase_;

  /// check for (re)initialization of the prescale
  bool newLumi_;

  /// "seed" used to initialize the prescale counter
  static const unsigned int prescaleSeed_ = 65537;
};

//
// constructors and destructor
//
PrescaleEventFilter::PrescaleEventFilter(const edm::ParameterSet& iConfig, const prescale::Efficiency* efficiency)
    : prescaleFactor_(iConfig.getParameter<unsigned int>("prescale")),
      eventCount_(0),
      acceptCount_(0),
      offsetCount_(0),
      offsetPhase_(iConfig.getParameter<unsigned int>("offset")) {
  //now do what ever initialization is needed
}

PrescaleEventFilter::~PrescaleEventFilter() {}

//
// member functions
//

// ------------ method called on each new Event  ------------
bool PrescaleEventFilter::filter(edm::Event& iEvent, const edm::EventSetup& iSetup) {
  using namespace edm;

  bool needsInit(eventCount_ == 0);

  if (needsInit && (prescaleFactor_ != 0)) {
    // initialize the prescale counter to the first event number multiplied by a big "seed"
    offsetCount_ = ((uint64_t)(iEvent.id().event() + offsetPhase_) * prescaleSeed_) % prescaleFactor_;
  }

  const bool result((prescaleFactor_ == 0) ? false : ((eventCount_ + offsetCount_) % prescaleFactor_ == 0));

  ++eventCount_;
  if (result)
    ++acceptCount_;
  return result;
}

// ------------ method called once each stream before processing any runs, lumis or events  ------------
void PrescaleEventFilter::beginStream(edm::StreamID) {}

//_____________________________________________________________________________
void PrescaleEventFilter::endStream() {
  //since these are std::atomic, it is safe to increment them
  // even if multiple endStreams are being called.
  globalCache()->eventCount_ += eventCount_;
  globalCache()->acceptCount_ += acceptCount_;
  return;
}

//_____________________________________________________________________________
void PrescaleEventFilter::globalEndJob(const prescale::Efficiency* efficiency) {
  unsigned int accept(efficiency->acceptCount_);
  unsigned int event(efficiency->eventCount_);
  edm::LogInfo("PrescaleSummary") << accept << "/" << event << " ("
                                  << 100. * accept / static_cast<double>(std::max(1u, event))
                                  << "% of events accepted).";
  return;
}

// ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
void PrescaleEventFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
  edm::ParameterSetDescription desc;
  desc.add<unsigned int>("prescale", 1);
  desc.add<unsigned int>("offset", 0);
  descriptions.add("prescaleEvent", desc);
}
//define this as a plug-in
DEFINE_FWK_MODULE(PrescaleEventFilter);