CalibratedElectronProducerRun2T

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

#include "DataFormats/Common/interface/Handle.h"
#include "FWCore/Framework/interface/stream/EDProducer.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/EventSetup.h"
#include "FWCore/Framework/interface/ESHandle.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"

#include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
#include "DataFormats/PatCandidates/interface/Electron.h"

#include "CondFormats/DataRecord/interface/GBRWrapperRcd.h"
#include "CondFormats/GBRForest/interface/GBRForest.h"
#include "EgammaAnalysis/ElectronTools/interface/EpCombinationTool.h"
#include "EgammaAnalysis/ElectronTools/interface/ElectronEnergyCalibratorRun2.h"

#include <memory>

#include <TRandom2.h>
#include <random>
#include <vector>

template <typename T>
class CalibratedElectronProducerRun2T : public edm::stream::EDProducer<> {
public:
  explicit CalibratedElectronProducerRun2T(const edm::ParameterSet &);
  ~CalibratedElectronProducerRun2T() override;
  void produce(edm::Event &, const edm::EventSetup &) override;

private:
  edm::EDGetTokenT<edm::View<T> > theElectronToken;
  std::string theGBRForestName;

  EpCombinationTool theEpCombinationTool;
  ElectronEnergyCalibratorRun2 theEnCorrectorRun2;
  std::unique_ptr<TRandom> theSemiDeterministicRng;

  edm::ESGetToken<GBRForest, GBRWrapperRcd> gbrforestToken_;
};

template <typename T>
CalibratedElectronProducerRun2T<T>::CalibratedElectronProducerRun2T(const edm::ParameterSet &conf)
    : theElectronToken(consumes<edm::View<T> >(conf.getParameter<edm::InputTag>("electrons"))),
      theGBRForestName(conf.getParameter<std::string>("gbrForestName")),
      theEpCombinationTool(),
      theEnCorrectorRun2(theEpCombinationTool,
                         conf.getParameter<bool>("isMC"),
                         conf.getParameter<bool>("isSynchronization"),
                         conf.getParameter<std::string>("correctionFile")) {
  if (conf.existsAs<bool>("semiDeterministic") && conf.getParameter<bool>("semiDeterministic")) {
    theSemiDeterministicRng = std::make_unique<TRandom2>();
    theEnCorrectorRun2.initPrivateRng(theSemiDeterministicRng.get());
  }
  gbrforestToken_ = esConsumes(edm::ESInputTag("", theGBRForestName));
  produces<std::vector<T> >();
}

template <typename T>
CalibratedElectronProducerRun2T<T>::~CalibratedElectronProducerRun2T() {}

template <typename T>
void CalibratedElectronProducerRun2T<T>::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
  const GBRForest *theGBRForest = &iSetup.getData(gbrforestToken_);
  theEpCombinationTool.init(theGBRForest);

  edm::Handle<edm::View<T> > in;
  iEvent.getByToken(theElectronToken, in);

  std::unique_ptr<std::vector<T> > out(new std::vector<T>());
  out->reserve(in->size());

  if (theSemiDeterministicRng && !in->empty()) {  // no need to set a seed if in is empty
    const auto &first = in->front();
    std::seed_seq seeder = {int(iEvent.id().event()),
                            int(iEvent.id().luminosityBlock()),
                            int(iEvent.id().run()),
                            int(in->size()),
                            int(std::numeric_limits<int>::max() * first.phi() / M_PI) & 0xFFF,
                            int(first.pdgId())};
    uint32_t seed = 0, tries = 10;
    do {
      seeder.generate(&seed, &seed + 1);
      tries++;
    } while (seed == 0 && tries < 10);
    theSemiDeterministicRng->SetSeed(seed ? seed : iEvent.id().event());
  }

  for (const T &ele : *in) {
    out->push_back(ele);
    theEnCorrectorRun2.calibrate(out->back(), iEvent.id().run(), iEvent.streamID());
  }

  iEvent.put(std::move(out));
}

typedef CalibratedElectronProducerRun2T<reco::GsfElectron> CalibratedElectronProducerRun2;
typedef CalibratedElectronProducerRun2T<pat::Electron> CalibratedPatElectronProducerRun2;

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

DEFINE_FWK_MODULE(CalibratedElectronProducerRun2);
DEFINE_FWK_MODULE(CalibratedPatElectronProducerRun2);

#endif