CMS 3D CMS Logo

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