CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PileUp.cc
Go to the documentation of this file.
15 
18 
24 
25 #include "CLHEP/Random/RandPoissonQ.h"
26 #include "CLHEP/Random/RandPoisson.h"
27 
28 #include "boost/shared_ptr.hpp"
29 
30 #include <algorithm>
31 
32 namespace edm {
33  PileUp::PileUp(ParameterSet const& pset, double averageNumber, TH1F * const histo, const bool playback) :
34  type_(pset.getParameter<std::string>("type")),
35  averageNumber_(averageNumber),
36  intAverage_(static_cast<int>(averageNumber)),
37  histo_(histo),
38  histoDistribution_(type_ == "histo"),
39  probFunctionDistribution_(type_ == "probFunction"),
40  poisson_(type_ == "poisson"),
41  fixed_(type_ == "fixed"),
42  none_(type_ == "none"),
43  productRegistry_(new SignallingProductRegistry),
44  input_(VectorInputSourceFactory::get()->makeVectorInputSource(pset, InputSourceDescription(
46  *productRegistry_,
47  boost::shared_ptr<BranchIDListHelper>(new BranchIDListHelper),
48  boost::shared_ptr<ActivityRegistry>(new ActivityRegistry),
49  -1, -1,
51  )).release()),
52  processConfiguration_(new ProcessConfiguration(std::string("@MIXING"), getReleaseVersion(), getPassID())),
53  eventPrincipal_(),
54  lumiPrincipal_(),
55  runPrincipal_(),
56  provider_(),
57  vPoissonDistribution_(),
58  vPoissonDistr_OOT_(),
59  randomEngines_(),
60  playback_(playback),
61  sequential_(pset.getUntrackedParameter<bool>("sequential", false)),
62  samelumi_(pset.getUntrackedParameter<bool>("sameLumiBlock", false)),
63  seed_(0) {
64 
65  // Use the empty parameter set for the parameter set ID of our "@MIXING" process.
67 
68  if(pset.existsAs<std::vector<ParameterSet> >("producers", true)) {
69  std::vector<ParameterSet> producers = pset.getParameter<std::vector<ParameterSet> >("producers");
71  }
72 
73  productRegistry_->setFrozen();
74 
75  // A modified HistoryAppender must be used for unscheduled processing.
76  eventPrincipal_.reset(new EventPrincipal(input_->productRegistry(),
77  input_->branchIDListHelper(),
79  nullptr));
80 
81  if (pset.exists("nbPileupEvents")) {
82  seed_=pset.getParameter<edm::ParameterSet>("nbPileupEvents").getUntrackedParameter<int>("seed",0);
83  }
84 
85  bool DB=type_=="readDB";
86 
88  if (!rng.isAvailable()) {
89  throw cms::Exception("Configuration")
90  << "PileUp requires the RandomNumberGeneratorService\n"
91  "which is not present in the configuration file. You must add the service\n"
92  "in the configuration file or remove the modules that require it.";
93  }
94 
95  // Get seed for the case when using user histogram or probability function
96  // RANDOM_NUMBER_ERROR
97  // Random number should be generated by the engines from the
98  // RandomNumberGeneratorService. This appears to use the global
99  // engine in ROOT. This is not thread safe unless the module using
100  // it is a one module and declares a shared resource and all
101  // other modules using it also declare the same shared resource.
102  // This also breaks replay.
104  if(seed_ !=0) {
105  gRandom->SetSeed(seed_);
106  LogInfo("MixingModule") << " Change seed for " << type_ << " mode. The seed is set to " << seed_;
107  }
108  else {
109  gRandom->SetSeed(rng->mySeed());
110  }
111  }
112 
114  throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
115  << "'type' parameter (a string) has a value of '" << type_ << "'.\n"
116  << "Legal values are 'poisson', 'fixed', or 'none'\n";
117  }
118 
119  if (!DB){
120  manage_OOT_ = pset.getUntrackedParameter<bool>("manage_OOT", false);
121 
122  // Check for string describing special processing. Add these here for individual cases
123 
124  PU_Study_ = false;
125  Study_type_ = "";
126 
127  Study_type_ = pset.getUntrackedParameter<std::string>("Special_Pileup_Studies", "");
128 
129  if(Study_type_ == "Fixed_ITPU_Vary_OOTPU") {
130 
131  PU_Study_ = true;
132  intFixed_ITPU_ = pset.getUntrackedParameter<int>("intFixed_ITPU", 0);
133 
134  }
135 
136  if(manage_OOT_) { // figure out what the parameters are
137 
138  // if (playback_) throw cms::Exception("Illegal parameter clash","PileUp::PileUp(ParameterSet const& pset)")
139  // << " manage_OOT option not allowed with playback ";
140 
141  std::string OOT_type = pset.getUntrackedParameter<std::string>("OOT_type");
142 
143  if(OOT_type == "Poisson" || OOT_type == "poisson") {
144  poisson_OOT_ = true;
145  }
146  else if(OOT_type == "Fixed" || OOT_type == "fixed") {
147  fixed_OOT_ = true;
148  // read back the fixed number requested out-of-time
149  intFixed_OOT_ = pset.getUntrackedParameter<int>("intFixed_OOT", -1);
150  if(intFixed_OOT_ < 0) {
151  throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
152  << " Fixed out-of-time pileup requested, but no fixed value given ";
153  }
154  }
155  else {
156  throw cms::Exception("Illegal parameter value","PileUp::PileUp(ParameterSet const& pset)")
157  << "'OOT_type' parameter (a string) has a value of '" << OOT_type << "'.\n"
158  << "Legal values are 'poisson' or 'fixed'\n";
159  }
160  edm::LogInfo("MixingModule") <<" Out-of-time pileup will be generated with a " << OOT_type << " distribution. " ;
161  }
162  }
163 
164  }
166  input_->doBeginJob();
167  if (provider_.get() != nullptr) {
168  provider_->beginJob(*productRegistry_);
169  }
170  }
171 
172  void PileUp::endJob () {
173  if (provider_.get() != nullptr) {
174  provider_->endJob();
175  }
176  input_->doEndJob();
177  }
178 
180  if (provider_.get() != nullptr) {
181  boost::shared_ptr<RunAuxiliary> aux(new RunAuxiliary(run.runAuxiliary()));
182  runPrincipal_.reset(new RunPrincipal(aux, productRegistry_, *processConfiguration_, nullptr, 0));
183  provider_->beginRun(*runPrincipal_, setup, run.moduleCallingContext());
184  }
185  }
187  if (provider_.get() != nullptr) {
188  boost::shared_ptr<LuminosityBlockAuxiliary> aux(new LuminosityBlockAuxiliary(lumi.luminosityBlockAuxiliary()));
190  lumiPrincipal_->setRunPrincipal(runPrincipal_);
191  provider_->beginLuminosityBlock(*lumiPrincipal_, setup, lumi.moduleCallingContext());
192  }
193  }
194 
196  if (provider_.get() != nullptr) {
197  provider_->endRun(*runPrincipal_, setup, run.moduleCallingContext());
198  }
199  }
201  if (provider_.get() != nullptr) {
202  provider_->endLuminosityBlock(*lumiPrincipal_, setup, lumi.moduleCallingContext());
203  }
204  }
205 
207  if (provider_.get() != nullptr) {
208  // note: run and lumi numbers must be modified to match lumiPrincipal_
209  eventPrincipal_->setLuminosityBlockPrincipal(lumiPrincipal_);
210  eventPrincipal_->setRunAndLumiNumber(lumiPrincipal_->run(), lumiPrincipal_->luminosityBlock());
211  provider_->setupPileUpEvent(*eventPrincipal_, setup);
212  }
213  }
214 
216  //get the required parameters from DB.
218  setup.get<MixingRcd>().get(configM);
219 
220  const MixingInputConfig & config=configM->config(inputType_);
221 
222  //get the type
223  type_=config.type();
224  //set booleans
225  histoDistribution_=type_ == "histo";
226  probFunctionDistribution_=type_ == "probFunction";
227  poisson_=type_ == "poisson";
228  fixed_=type_ == "fixed";
229  none_=type_ == "none";
230 
231  if (histoDistribution_) edm::LogError("MisConfiguration")<<"type histo cannot be reloaded from DB, yet";
232 
233  if (fixed_){
235  }
236  else if (poisson_)
237  {
238  averageNumber_=config.averageNumber();
239  for(auto & distribution : vPoissonDistribution_) {
240  if(distribution) {
241  distribution.reset(new CLHEP::RandPoissonQ(distribution->engine(), averageNumber_));
242  }
243  }
244  }
245  else if (probFunctionDistribution_)
246  {
247  //need to reload the histogram from DB
248  const std::vector<int> & dataProbFunctionVar = config.probFunctionVariable();
249  std::vector<double> dataProb = config.probValue();
250 
251  int varSize = (int) dataProbFunctionVar.size();
252  int probSize = (int) dataProb.size();
253 
254  if ((dataProbFunctionVar[0] != 0) || (dataProbFunctionVar[varSize - 1] != (varSize - 1)))
255  throw cms::Exception("BadProbFunction") << "Please, check the variables of the probability function! The first variable should be 0 and the difference between two variables should be 1." << std::endl;
256 
257  // Complete the vector containing the probability function data
258  // with the values "0"
259  if (probSize < varSize){
260  edm::LogWarning("MixingModule") << " The probability function data will be completed with " <<(varSize - probSize) <<" values 0.";
261 
262  for (int i=0; i<(varSize - probSize); i++) dataProb.push_back(0);
263 
264  probSize = dataProb.size();
265  edm::LogInfo("MixingModule") << " The number of the P(x) data set after adding the values 0 is " << probSize;
266  }
267 
268  // Create an histogram with the data from the probability function provided by the user
269  int xmin = (int) dataProbFunctionVar[0];
270  int xmax = (int) dataProbFunctionVar[varSize-1]+1; // need upper edge to be one beyond last value
271  int numBins = varSize;
272 
273  edm::LogInfo("MixingModule") << "An histogram will be created with " << numBins << " bins in the range ("<< xmin << "," << xmax << ")." << std::endl;
274 
275  if (histo_) delete histo_;
276  histo_ = new TH1F("h","Histo from the user's probability function",numBins,xmin,xmax);
277 
278  LogDebug("MixingModule") << "Filling histogram with the following data:" << std::endl;
279 
280  for (int j=0; j < numBins ; j++){
281  LogDebug("MixingModule") << " x = " << dataProbFunctionVar[j ]<< " P(x) = " << dataProb[j];
282  histo_->Fill(dataProbFunctionVar[j]+0.5,dataProb[j]); // assuming integer values for the bins, fill bin centers, not edges
283  }
284 
285  // Check if the histogram is normalized
286  if ( ((histo_->Integral() - 1) > 1.0e-02) && ((histo_->Integral() - 1) < -1.0e-02)){
287  throw cms::Exception("BadProbFunction") << "The probability function should be normalized!!! " << std::endl;
288  }
289  averageNumber_=histo_->GetMean();
290  }
291 
292  int oot=config.outOfTime();
293  manage_OOT_=false;
294  if (oot==1)
295  {
296  manage_OOT_=true;
297  poisson_OOT_ = false;
298  fixed_OOT_ = true;
299  intFixed_OOT_=config.fixedOutOfTime();
300  }
301  else if (oot==2)
302  {
303  manage_OOT_=true;
304  poisson_OOT_ = true;
305  fixed_OOT_ = false;
306  }
307 
308 
309  }
311  }
312 
313  std::unique_ptr<CLHEP::RandPoissonQ> const& PileUp::poissonDistribution(StreamID const& streamID) {
314  unsigned int index = streamID.value();
315  if(index >= vPoissonDistribution_.size()) {
316  // This resizing is not thread safe and only works because
317  // this is used by a "one" type module
318  vPoissonDistribution_.resize(index + 1);
319  }
320  std::unique_ptr<CLHEP::RandPoissonQ>& ptr = vPoissonDistribution_[index];
321  if(!ptr) {
322  CLHEP::HepRandomEngine& engine = *randomEngine(streamID);
323  ptr.reset(new CLHEP::RandPoissonQ(engine, averageNumber_));
324  }
325  return ptr;
326  }
327 
328  std::unique_ptr<CLHEP::RandPoisson> const& PileUp::poissonDistr_OOT(StreamID const& streamID) {
329  unsigned int index = streamID.value();
330  if(index >= vPoissonDistr_OOT_.size()) {
331  // This resizing is not thread safe and only works because
332  // this is used by a "one" type module
333  vPoissonDistr_OOT_.resize(index + 1);
334  }
335  std::unique_ptr<CLHEP::RandPoisson>& ptr = vPoissonDistr_OOT_[index];
336  if(!ptr) {
337  CLHEP::HepRandomEngine& engine = *randomEngine(streamID);
338  ptr.reset(new CLHEP::RandPoisson(engine));
339  }
340  return ptr;
341  }
342 
343  CLHEP::HepRandomEngine* PileUp::randomEngine(StreamID const& streamID) {
344  unsigned int index = streamID.value();
345  if(index >= randomEngines_.size()) {
346  // This resizing is not thread safe and only works because
347  // this is used by a "one" type module
348  randomEngines_.resize(index + 1, nullptr);
349  }
350  CLHEP::HepRandomEngine* ptr = randomEngines_[index];
351  if(!ptr) {
353  ptr = &rng->getEngine(streamID);
354  randomEngines_[index] = ptr;
355  }
356  return ptr;
357  }
358 
359  void PileUp::CalculatePileup(int MinBunch, int MaxBunch, std::vector<int>& PileupSelection, std::vector<float>& TrueNumInteractions, StreamID const& streamID) {
360 
361  // if we are managing the distribution of out-of-time pileup separately, select the distribution for bunch
362  // crossing zero first, save it for later.
363 
364  int nzero_crossing = -1;
365  double Fnzero_crossing = -1;
366 
367  if(manage_OOT_) {
368  if (none_){
369  nzero_crossing = 0;
370  }else if (poisson_){
371  nzero_crossing = poissonDistribution(streamID)->fire() ;
372  }else if (fixed_){
373  nzero_crossing = intAverage_ ;
375  // RANDOM_NUMBER_ERROR
376  // Random number should be generated by the engines from the
377  // RandomNumberGeneratorService. This appears to use the global
378  // engine in ROOT. This is not thread safe unless the module using
379  // it is a one module and declares a shared resource and all
380  // other modules using it also declare the same shared resource.
381  // This also breaks replay.
382  double d = histo_->GetRandom();
383  //n = (int) floor(d + 0.5); // incorrect for bins with integer edges
384  Fnzero_crossing = d;
385  nzero_crossing = int(d);
386  }
387 
388  }
389 
390  for(int bx = MinBunch; bx < MaxBunch+1; ++bx) {
391 
392  if(manage_OOT_) {
393  if(bx==0 && !poisson_OOT_) {
394  PileupSelection.push_back(nzero_crossing) ;
395  TrueNumInteractions.push_back( nzero_crossing );
396  }
397  else{
398  if(poisson_OOT_) {
399  if(PU_Study_ && (Study_type_ == "Fixed_ITPU_Vary_OOTPU" ) && bx==0 ) {
400  PileupSelection.push_back(intFixed_ITPU_) ;
401  }
402  else{
403  PileupSelection.push_back(poissonDistr_OOT(streamID)->fire(Fnzero_crossing)) ;
404  }
405  TrueNumInteractions.push_back( Fnzero_crossing );
406  }
407  else {
408  PileupSelection.push_back(intFixed_OOT_) ;
409  TrueNumInteractions.push_back( intFixed_OOT_ );
410  }
411  }
412  }
413  else {
414  if (none_){
415  PileupSelection.push_back(0);
416  TrueNumInteractions.push_back( 0. );
417  }else if (poisson_){
418  PileupSelection.push_back(poissonDistribution(streamID)->fire());
419  TrueNumInteractions.push_back( averageNumber_ );
420  }else if (fixed_){
421  PileupSelection.push_back(intAverage_);
422  TrueNumInteractions.push_back( intAverage_ );
424  // RANDOM_NUMBER_ERROR
425  // Random number should be generated by the engines from the
426  // RandomNumberGeneratorService. This appears to use the global
427  // engine in ROOT. This is not thread safe unless the module using
428  // it is a one module and declares a shared resource and all
429  // other modules using it also declare the same shared resource.
430  // This also breaks replay.
431  double d = histo_->GetRandom();
432  PileupSelection.push_back(int(d));
433  TrueNumInteractions.push_back( d );
434  }
435  }
436 
437  }
438  }
439 
440 
441 } //namespace edm
#define LogDebug(id)
boost::shared_ptr< RunPrincipal > runPrincipal_
Definition: PileUp.h:103
bool manage_OOT_
Definition: PileUp.h:88
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
std::string getPassID()
Definition: GetPassID.h:8
int i
Definition: DBlmapReader.cc:9
std::unique_ptr< SecondaryEventProvider > provider_
Definition: PileUp.h:104
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:184
unsigned int inputType_
Definition: PileUp.h:78
const int fixedOutOfTime() const
tuple lumi
Definition: fjr2json.py:35
bool exists(std::string const &parameterName) const
checks if a parameter exists
void endJob()
Definition: PileUp.cc:172
TH1F * histo_
Definition: PileUp.h:82
bool fixed_
Definition: PileUp.h:86
const std::vector< double > & probValue() const
const double averageNumber() const
ModuleCallingContext const * moduleCallingContext() const
PileUp(ParameterSet const &pset, double averageNumber, TH1F *const histo, const bool playback)
Definition: PileUp.cc:33
std::vector< CLHEP::HepRandomEngine * > randomEngines_
Definition: PileUp.h:107
int const intAverage_
Definition: PileUp.h:81
bool probFunctionDistribution_
Definition: PileUp.h:84
std::string Study_type_
Definition: PileUp.h:93
boost::shared_ptr< LuminosityBlockPrincipal > lumiPrincipal_
Definition: PileUp.h:102
bool histoDistribution_
Definition: PileUp.h:83
bool poisson_
Definition: PileUp.h:85
void endLuminosityBlock(const edm::LuminosityBlock &lumi, const edm::EventSetup &setup)
Definition: PileUp.cc:200
double averageNumber() const
Definition: PileUp.h:44
const int outOfTime() const
virtual std::uint32_t mySeed() const =0
std::vector< std::unique_ptr< CLHEP::RandPoissonQ > > vPoissonDistribution_
Definition: PileUp.h:105
std::unique_ptr< VectorInputSource > const input_
Definition: PileUp.h:99
bool poisson_OOT_
Definition: PileUp.h:89
void beginJob()
Definition: PileUp.cc:165
tuple averageNumber
set the number of pileup
bool isAvailable() const
Definition: Service.h:46
int j
Definition: DBlmapReader.cc:9
int intFixed_ITPU_
Definition: PileUp.h:96
void beginRun(const edm::Run &run, const edm::EventSetup &setup)
Definition: PileUp.cc:179
std::unique_ptr< CLHEP::RandPoissonQ > const & poissonDistribution(StreamID const &streamID)
Definition: PileUp.cc:313
void CalculatePileup(int MinBunch, int MaxBunch, std::vector< int > &PileupSelection, std::vector< float > &TrueNumInteractions, StreamID const &)
Definition: PileUp.cc:359
bool PU_Study_
Definition: PileUp.h:92
void beginLuminosityBlock(const edm::LuminosityBlock &lumi, const edm::EventSetup &setup)
Definition: PileUp.cc:186
bool fixed_OOT_
Definition: PileUp.h:90
std::string getReleaseVersion()
void setupPileUpEvent(const edm::EventSetup &setup)
Definition: PileUp.cc:206
unsigned int value() const
Definition: StreamID.h:46
std::string type_
Definition: PileUp.h:79
LuminosityBlockAuxiliary const & luminosityBlockAuxiliary() const
boost::shared_ptr< ProductRegistry > productRegistry_
Definition: PileUp.h:98
const T & get() const
Definition: EventSetup.h:55
void endRun(const edm::Run &run, const edm::EventSetup &setup)
Definition: PileUp.cc:195
const std::vector< int > & probFunctionVariable() const
RunAuxiliary const & runAuxiliary() const
Definition: Run.h:55
boost::shared_ptr< ProcessConfiguration > processConfiguration_
Definition: PileUp.h:100
std::unique_ptr< CLHEP::RandPoisson > const & poissonDistr_OOT(StreamID const &streamID)
Definition: PileUp.cc:328
void reload(const edm::EventSetup &setup)
Definition: PileUp.cc:215
int seed_
Definition: PileUp.h:123
ModuleCallingContext const * moduleCallingContext() const
Definition: Run.h:135
bool none_
Definition: PileUp.h:87
CLHEP::HepRandomEngine * randomEngine(StreamID const &streamID)
Definition: PileUp.cc:343
tuple playback
Definition: Playback_cff.py:20
std::vector< std::unique_ptr< CLHEP::RandPoisson > > vPoissonDistr_OOT_
Definition: PileUp.h:106
int intFixed_OOT_
Definition: PileUp.h:95
volatile std::atomic< bool > shutdown_flag false
std::unique_ptr< EventPrincipal > eventPrincipal_
Definition: PileUp.h:101
std::string type() const
static ParameterSetID emptyParameterSetID()
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
T get(const Candidate &c)
Definition: component.h:55
double averageNumber_
Definition: PileUp.h:80
Definition: Run.h:41