CMS 3D CMS Logo

PreMixingModule.cc
Go to the documentation of this file.
1 
9 
23 
28 
31 #include "PreMixingPileupCopy.h"
32 
33 #include <CLHEP/Random/RandomEngine.h>
34 
35 #include <functional>
36 #include <vector>
37 
38 namespace edm {
39  class PreMixingModule : public BMixingModule {
40  public:
41  PreMixingModule(const edm::ParameterSet& ps, MixingCache::Config const* globalConf);
42 
43  ~PreMixingModule() override = default;
44 
45  void checkSignal(const edm::Event& e) override{};
46  void createnewEDProduct() override {}
47  void addSignals(const edm::Event& e, const edm::EventSetup& ES) override;
48  void doPileUp(edm::Event& e, const edm::EventSetup& ES) override;
49  void put(edm::Event& e, const edm::EventSetup& ES) override;
50 
51  void initializeEvent(edm::Event const& e, edm::EventSetup const& eventSetup) override;
52  void beginRun(edm::Run const& run, edm::EventSetup const& eventSetup) override;
53  void beginLuminosityBlock(LuminosityBlock const& l1, EventSetup const& c) override;
54  void endLuminosityBlock(LuminosityBlock const& l1, EventSetup const& c) override;
55  void endRun(const edm::Run& r, const edm::EventSetup& setup) override;
56 
57  private:
59  public:
61  : firstRun_(ps.getParameter<unsigned int>("firstRun")),
62  firstBinPileup_(ps.getParameter<unsigned int>("firstBinPileup")),
63  pileupProbabilities_(ps.getParameter<std::vector<double>>("pileupProbabilities")) {
64  for (double p : pileupProbabilities_) {
65  if (p < 0. or p > 1.) {
66  throw cms::Exception("Configuration") << "Invalid probability value " << p << " for firstRun " << firstRun_
67  << ". The probability must be >= 0. and <= 1.";
68  }
69  }
70  }
71 
72  edm::RunNumber_t firstRun() const { return firstRun_; }
73  double probability(float pileup) const {
74  unsigned int bin = static_cast<unsigned int>(pileup);
75  if (bin < firstBinPileup_ or bin >= firstBinPileup_ + pileupProbabilities_.size()) {
76  edm::LogWarning("PreMixingModule")
77  << "Got pileup event with true pileup " << pileup
78  << " that is outside of the configured pileup adjustment bounds [" << firstBinPileup_ << ", "
79  << firstBinPileup_ + pileupProbabilities_.size() - 1 << "]. Using probability 0.";
80  return 0.;
81  }
83  }
84 
85  private:
87  unsigned int firstBinPileup_;
88  std::vector<double> pileupProbabilities_;
89  };
90 
91  bool pileWorker(const edm::EventPrincipal&,
92  int bcr,
93  int EventId,
94  const edm::EventSetup& ES,
95  ModuleCallingContext const*,
96  AdjustPileupDistribution const* pileupAdjuster);
97 
99  bool addedPileup_ = false;
100 
101  std::vector<AdjustPileupDistribution> pileupAdjusters_;
102  std::vector<std::unique_ptr<PreMixingWorker>> workers_;
103  };
104 
106  : BMixingModule(ps, globalConf),
107  puWorker_(ps.getParameter<edm::ParameterSet>("workers").getParameter<edm::ParameterSet>("pileup"),
108  producesCollector(),
109  consumesCollector()),
110  pileupAdjusters_(
111  edm::vector_transform(ps.getParameter<std::vector<edm::ParameterSet>>("adjustPileupDistribution"),
112  [](const auto& ps) { return AdjustPileupDistribution(ps); })) {
113  std::sort(pileupAdjusters_.begin(), pileupAdjusters_.end(), [](const auto& a, const auto& b) {
114  return a.firstRun() < b.firstRun();
115  });
116 
117  const auto& workers = ps.getParameter<edm::ParameterSet>("workers");
118  std::vector<std::string> names = workers.getParameterNames();
119 
120  // Hack to keep the random number sequence unchanged for migration
121  // from DataMixingModule to PreMixingModule. To be removed in a
122  // subsequent PR doing only that.
123  {
124  std::vector<std::string> tmp;
125  auto hack = [&](const std::string& name) {
126  auto i = std::find(names.begin(), names.end(), name);
127  if (i != names.end()) {
128  tmp.push_back(*i);
129  names.erase(i);
130  }
131  };
132  hack("ecal");
133  hack("hcal");
134  hack("strip");
135  hack("pixel");
136  std::copy(names.begin(), names.end(), std::back_inserter(tmp));
137  names = std::move(tmp);
138  }
139 
140  for (const auto& name : names) {
141  if (name == "pileup") {
142  continue;
143  }
144  const auto& pset = workers.getParameter<edm::ParameterSet>(name);
145  std::string type = pset.getParameter<std::string>("workerType");
146  workers_.emplace_back(
147  PreMixingWorkerFactory::get()->create(type, pset, producesCollector(), consumesCollector()));
148  }
149  }
150 
152  for (auto& w : workers_) {
153  w->initializeEvent(e, ES);
154  }
155  }
156 
159  for (auto& w : workers_) {
160  w->beginRun(run, ES);
161  }
162  }
163 
165  for (auto& w : workers_) {
166  w->endRun();
167  }
169  }
170 
172  // fill in maps of hits
173 
174  LogDebug("PreMixingModule") << "===============> adding MC signals for " << e.id();
175 
176  for (auto& w : workers_) {
177  w->addSignals(e, ES);
178  }
179 
180  addedPileup_ = false;
181  }
182 
184  int bcr,
185  int eventNr,
186  const edm::EventSetup& ES,
187  edm::ModuleCallingContext const* mcc,
188  AdjustPileupDistribution const* pileupAdjuster) {
189  InternalContext internalContext(ep.id(), mcc);
190  ParentContext parentContext(&internalContext);
191  ModuleCallingContext moduleCallingContext(&moduleDescription());
192  ModuleContextSentry moduleContextSentry(&moduleCallingContext, parentContext);
193 
194  PileUpEventPrincipal pep(ep, &moduleCallingContext, bcr);
195 
196  if (pileupAdjuster) {
197  float trueNumInteractions = puWorker_.getTrueNumInteractions(pep);
198  double prob = pileupAdjuster->probability(static_cast<unsigned int>(trueNumInteractions));
200  CLHEP::HepRandomEngine& engine = rng->getEngine(ep.streamID());
201  if (engine.flat() > prob) {
202  // engine.flat() should give a double in ]0,1[ range
203  // the choice above means that "prob = 1-ulp" is treatead as 1
204  return false;
205  }
206  }
207 
208  LogDebug("PreMixingModule") << "\n===============> adding pileups from event " << ep.id() << " for bunchcrossing "
209  << bcr;
210 
211  // Note: setupPileUpEvent may modify the run and lumi numbers of the EventPrincipal to match that of the primary event.
212  setupPileUpEvent(ES);
213 
214  // check and see if we need to copy the pileup information from
215  // secondary stream to the output stream
216  // We only have the pileup event here, so pick the first time and store the info
217  if (!addedPileup_) {
219  addedPileup_ = true;
220  }
221 
222  // fill in maps of hits; same code as addSignals, except now applied to the pileup events
223 
224  for (auto& w : workers_) {
225  w->addPileups(pep, ES);
226  }
227 
228  return true;
229  }
230 
232  using namespace std::placeholders;
233 
234  std::vector<edm::SecondaryEventIDAndFileInfo> recordEventID;
235  std::vector<int> PileupList;
236  TrueNumInteractions_.clear();
237 
238  ModuleCallingContext const* mcc = e.moduleCallingContext();
239 
240  AdjustPileupDistribution const* pileupAdjuster = nullptr;
241  if (not pileupAdjusters_.empty()) {
242  // Find the adjustment settings for the run of the signal event
243  // the container should be small-enough to not really gain
244  // anything with binary search
245  auto it = std::find_if(pileupAdjusters_.rbegin(),
246  pileupAdjusters_.rend(),
247  [iRun = e.id().run()](const auto& elem) { return elem.firstRun() <= iRun; });
248  if (it == pileupAdjusters_.rend()) {
249  throw cms::Exception("LogicError") << "Encountered run " << e.id().run()
250  << ", but the first run available in the pileup adjustment configuration is "
251  << pileupAdjusters_.front().firstRun() << ". Please fix the configuration.";
252  }
253  pileupAdjuster = &*it;
254  }
255 
256  for (int bunchCrossing = minBunch_; bunchCrossing <= maxBunch_; ++bunchCrossing) {
257  for (unsigned int isource = 0; isource < maxNbSources_; ++isource) {
258  std::shared_ptr<PileUp> source = inputSources_[isource];
259  if (!source || !(source->doPileUp(bunchCrossing)))
260  continue;
261 
262  if (isource == 0)
263  source->CalculatePileup(minBunch_, maxBunch_, PileupList, TrueNumInteractions_, e.streamID());
264 
265  int NumPU_Events = 0;
266  if (isource == 0) {
267  NumPU_Events = PileupList[bunchCrossing - minBunch_];
268  } else {
269  // non-minbias pileup only gets one event for now. Fix later if desired.
270  NumPU_Events = 1;
271  }
272 
273  for (auto& w : workers_) {
274  w->initializeBunchCrossing(e, ES, bunchCrossing);
275  }
276 
277  source->readPileUp(
278  e.id(),
279  recordEventID,
280  std::bind(
281  &PreMixingModule::pileWorker, std::ref(*this), _1, bunchCrossing, _2, std::cref(ES), mcc, pileupAdjuster),
282  NumPU_Events,
283  e.streamID());
284 
285  for (auto& w : workers_) {
286  w->finalizeBunchCrossing(e, ES, bunchCrossing);
287  }
288  }
289  }
290  }
291 
293  // individual workers...
294  // move pileup first so we have access to the information for the put step
295  const auto& ps = puWorker_.getPileupSummaryInfo();
297 
298  for (auto& w : workers_) {
299  w->put(e, ES, ps, bunchSpacing);
300  }
301 
303  }
304 
307  for (auto& w : workers_) {
308  w->beginLuminosityBlock(l1, c);
309  }
310  }
311 
314  }
315 } // namespace edm
316 
void createnewEDProduct() override
void beginRun(const edm::Run &r, const edm::EventSetup &setup) override
static std::string const source("source")
def create(alignables, pedeDump, additionalData, outputFile, config)
T w() const
void endRun(const edm::Run &r, const edm::EventSetup &setup) override
void beginRun(edm::Run const &run, edm::EventSetup const &eventSetup) override
void putPileupInfo(edm::Event &e)
auto vector_transform(std::vector< InputType > const &input, Function predicate) -> std::vector< typename std::remove_cv< typename std::remove_reference< decltype(predicate(input.front()))>::type >::type >
Definition: transform.h:11
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
const std::string names[nVars_]
void endRun(const edm::Run &r, const edm::EventSetup &setup) override
bool pileWorker(const edm::EventPrincipal &, int bcr, int EventId, const edm::EventSetup &ES, ModuleCallingContext const *, AdjustPileupDistribution const *pileupAdjuster)
void initializeEvent(edm::Event const &e, edm::EventSetup const &eventSetup) override
void endLuminosityBlock(LuminosityBlock const &l1, EventSetup const &c) override
void addPileupInfo(PileUpEventPrincipal const &pep)
const std::vector< PileupSummaryInfo > & getPileupSummaryInfo() const
AdjustPileupDistribution(const edm::ParameterSet &ps)
void put(edm::Event &e, const edm::EventSetup &ES) override
static const unsigned int maxNbSources_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::vector< float > TrueNumInteractions_
void beginLuminosityBlock(LuminosityBlock const &l1, EventSetup const &c) override
double b
Definition: hdecay.h:118
float getTrueNumInteractions(PileUpEventPrincipal const &pep) const
~PreMixingModule() override=default
HLT enums.
std::vector< std::shared_ptr< PileUp > > inputSources_
std::vector< std::unique_ptr< PreMixingWorker > > workers_
double a
Definition: hdecay.h:119
void checkSignal(const edm::Event &e) override
void addSignals(const edm::Event &e, const edm::EventSetup &ES) override
std::vector< AdjustPileupDistribution > pileupAdjusters_
unsigned int RunNumber_t
#define get
Log< level::Warning, false > LogWarning
void beginLuminosityBlock(const edm::LuminosityBlock &l, const edm::EventSetup &setup) override
PreMixingPileupCopy puWorker_
tmp
align.sh
Definition: createJobs.py:716
void setupPileUpEvent(const edm::EventSetup &setup)
void endLuminosityBlock(const edm::LuminosityBlock &l, const edm::EventSetup &setup) override
def move(src, dest)
Definition: eostools.py:511
Definition: Run.h:45
PreMixingModule(const edm::ParameterSet &ps, MixingCache::Config const *globalConf)
#define LogDebug(id)
void doPileUp(edm::Event &e, const edm::EventSetup &ES) override