CMS 3D CMS Logo

BMixingModule.cc
Go to the documentation of this file.
1 // File: BMixingModule.cc
2 // Description: see BMixingModule.h
3 // Author: Ursula Berthon, LLR Palaiseau, Bill Tanenbaum
4 //
5 //--------------------------------------------
6 
16 
17 #include "TFile.h"
18 #include "TH1F.h"
19 #include <iostream>
20 const unsigned int edm::BMixingModule::maxNbSources_ =4;
21 
22 namespace
23 {
24  std::shared_ptr<edm::PileUpConfig>
25  maybeConfigPileUp(edm::ParameterSet const& ps,std::string sourceName, const int minb, const int maxb, const bool playback)
26  {
27  std::shared_ptr<edm::PileUpConfig> pileupconfig; // value to be returned
28  // Make sure we have a parameter named 'sourceName'
29  if (ps.exists(sourceName))
30  {
31  // We have the parameter
32  // and if we have either averageNumber or cfg by luminosity... make the PileUp
33  double averageNumber;
35  std::string histoName =" ";
36  std::unique_ptr<TH1F> h(new TH1F("h","h",10,0,10));
37  std::vector<int> dataProbFunctionVar;
38  std::vector<double> dataProb;
39 
40 
41  const edm::ParameterSet & psin=ps.getParameter<edm::ParameterSet>(sourceName);
42  std::string type_=psin.getParameter<std::string>("type");
43  if (ps.exists("readDB") && ps.getParameter<bool>("readDB")){
44  //in case of DB access, do not try to load anything from the PSet, but wait for beginRun.
45  edm::LogError("BMixingModule")<<"Will read from DB: reset to a dummy PileUp object.";
46  std::unique_ptr<TH1F> h;
47  pileupconfig.reset(new edm::PileUpConfig(sourceName,0.0,h,playback));
48  return pileupconfig;
49  }
50  if (type_!="none"){
51  if (psin.exists("nbPileupEvents")) {
52  edm::ParameterSet psin_average=psin.getParameter<edm::ParameterSet>("nbPileupEvents");
53  if (psin_average.exists("averageNumber"))
54  {
55  averageNumber=psin_average.getParameter<double>("averageNumber");
56  pileupconfig.reset(new edm::PileUpConfig(sourceName,averageNumber,h,playback));
57  edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with averageNumber "<<averageNumber;
58  }
59  else if (psin_average.exists("fileName") && psin_average.exists("histoName")) {
60  std::string histoFileName = psin_average.getUntrackedParameter<std::string>("fileName");
61  std::string histoName = psin_average.getUntrackedParameter<std::string>("histoName");
62 
63  std::unique_ptr<TFile> infile(new TFile(histoFileName.c_str()));
64  std::unique_ptr<TH1F> h((TH1F*)infile->Get(histoName.c_str()));
65 
66  // Check if the histogram exists
67  if (!h) {
68  throw cms::Exception("HistogramNotFound") << " Could not find the histogram " << histoName
69  << "in the file " << histoFileName << "." << std::endl;
70  }else{
71  edm::LogInfo("MixingModule") << "Open a root file " << histoFileName << " containing the probability distribution histogram " << histoName << std::endl;
72  edm::LogInfo("MixingModule") << "The PileUp number to be added will be chosen randomly from this histogram" << std::endl;
73  }
74 
75  // Check if the histogram is normalized
76  if (std::abs(h->Integral() - 1) > 1.0e-02) throw cms::Exception("BadHistoDistribution") << "The histogram should be normalized!" << std::endl;
77 
78  // Get the averageNumber from the histo
79  averageNumber = h->GetMean();
80 
81  pileupconfig.reset(new edm::PileUpConfig(sourceName,averageNumber,h,playback));
82  edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with averageNumber "<<averageNumber;
83 
84  }
85  else if (psin_average.exists("probFunctionVariable") && psin_average.exists("probValue") && psin_average.exists("histoFileName"))
86  {
87  if (type_!="probFunction") {
88  edm::LogError("MisConfiguration")<<"type is set to: "<<type_<<" while parameters implies probFunction; changing.";
89  type_="probFunction";
90  }
91 
92  dataProbFunctionVar = psin_average.getParameter<std::vector<int> >("probFunctionVariable");
93  dataProb = psin_average.getParameter<std::vector<double> >("probValue");
94  histoFileName = psin_average.getUntrackedParameter<std::string>("histoFileName");
95 
96  int varSize = (int) dataProbFunctionVar.size();
97  int probSize = (int) dataProb.size();
98 
99  if ((dataProbFunctionVar[0] != 0) || (dataProbFunctionVar[varSize - 1] != (varSize - 1)))
100  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;
101 
102  // Complete the vector containing the probability function data
103  // with the values "0"
104  if (probSize < varSize){
105  edm::LogInfo("MixingModule") << " The probability function data will be completed with " <<(varSize - probSize) <<" values 0.";
106 
107  for (int i=0; i<(varSize - probSize); i++) dataProb.push_back(0);
108 
109  probSize = dataProb.size();
110  edm::LogInfo("MixingModule") << " The number of the P(x) data set after adding the values 0 is " << probSize;
111  }
112 
113  // Create an histogram with the data from the probability function provided by the user
114  int xmin = (int) dataProbFunctionVar[0];
115  int xmax = (int) dataProbFunctionVar[varSize-1]+1; // need upper edge to be one beyond last value
116  int numBins = varSize;
117 
118  edm::LogInfo("MixingModule") << "An histogram will be created with " << numBins << " bins in the range ("<< xmin << "," << xmax << ")." << std::endl;
119 
120  std::unique_ptr<TH1F> hprob(new TH1F("h","Histo from the user's probability function",numBins,xmin,xmax));
121 
122  LogDebug("MixingModule") << "Filling histogram with the following data:" << std::endl;
123 
124  for (int j=0; j < numBins ; j++){
125  LogDebug("MixingModule") << " x = " << dataProbFunctionVar[j ]<< " P(x) = " << dataProb[j];
126  hprob->Fill(dataProbFunctionVar[j]+0.5,dataProb[j]); // assuming integer values for the bins, fill bin centers, not edges
127  }
128 
129  // Check if the histogram is normalized
130  if (std::abs(hprob->Integral() - 1) > 1.0e-02){
131  throw cms::Exception("BadProbFunction") << "The probability function should be normalized!!! " << std::endl;
132  }
133 
134  averageNumber = hprob->GetMean();
135 
136  // Write the created histogram into a root file
137  edm::LogInfo("MixingModule") << " The histogram created from the x, P(x) values will be written into the root file " << histoFileName;
138 
139  TFile * outfile = new TFile(histoFileName.c_str(),"RECREATE");
140  hprob->Write();
141  outfile->Write();
142  outfile->Close();
143  outfile->Delete();
144 
145  pileupconfig.reset(new edm::PileUpConfig(sourceName,averageNumber,hprob,playback));
146  edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with averageNumber "<<averageNumber;
147  }
148  //special for pileup input
149  else if (sourceName=="input" && psin_average.exists("Lumi") && psin_average.exists("sigmaInel")) {
150  averageNumber=psin_average.getParameter<double>("Lumi")*psin_average.getParameter<double>("sigmaInel")*ps.getParameter<int>("bunchspace")/1000*3564./2808.; //FIXME
151  pileupconfig.reset(new edm::PileUpConfig(sourceName,averageNumber,h,playback));
152  edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with minBunch,maxBunch "<<minb<<" "<<maxb;
153  edm::LogInfo("MixingModule")<<" Luminosity configuration, average number used is "<<averageNumber;
154  }
155  }
156  }
157  }
158  return pileupconfig;
159  }
160 }
161 
162 namespace edm {
163 
164  // Constructor
166  bunchSpace_(globalConf->bunchSpace_),
167  vertexOffset_(0),
168  minBunch_(globalConf->minBunch_),
169  maxBunch_(globalConf->maxBunch_),
170  mixProdStep1_(pset.getParameter<bool>("mixProdStep1")),
171  mixProdStep2_(pset.getParameter<bool>("mixProdStep2")),
172  readDB_(false),
173  playback_(globalConf->playback_)
174  {
175  if (pset.exists("readDB")) readDB_=pset.getParameter<bool>("readDB");
176 
177  for (size_t makeIdx = 0; makeIdx < maxNbSources_; makeIdx++ ) {
178  if (globalConf->inputConfigs_[makeIdx]) {
179  const edm::ParameterSet & psin=pset.getParameter<edm::ParameterSet>(globalConf->inputConfigs_[makeIdx]->sourcename_);
180  inputSources_.push_back(std::make_shared<PileUp>(psin, globalConf->inputConfigs_[makeIdx]));
181  inputSources_.back()->input(makeIdx);
182  } else {
183  inputSources_.push_back(nullptr);
184  }
185  }
186  }
187 
188  // Virtual destructor needed.
190 
191  namespace MixingCache {
192  Config::Config(edm::ParameterSet const& pset, unsigned int maxNbSources) :
193  bunchSpace_(pset.getParameter<int>("bunchspace")),
194  minBunch_((pset.getParameter<int>("minBunch")*25)/bunchSpace_),
195  maxBunch_((pset.getParameter<int>("maxBunch")*25)/bunchSpace_),
196  playback_(pset.getUntrackedParameter<bool>("playback",false))
197  {
198  if (playback_) {
199  //this could be explicitly checked
200  LogInfo("MixingModule") <<" ATTENTION:Mixing will be done in playback mode! \n"
201  <<" ATTENTION:Mixing Configuration must be the same as for the original mixing!";
202  }
203 
204  // Just for debugging print out.
205  sourceNames_.push_back("input");
206  sourceNames_.push_back("cosmics");
207  sourceNames_.push_back("beamhalo_plus");
208  sourceNames_.push_back("beamhalo_minus");
209 
210  for (size_t makeIdx = 0; makeIdx < maxNbSources; makeIdx++ ) {
211  inputConfigs_.push_back(maybeConfigPileUp(pset,sourceNames_[makeIdx],
213  }
214  }
215  }
216 
217  std::unique_ptr<MixingCache::Config> BMixingModule::initializeGlobalCache(edm::ParameterSet const& pset){
218  return std::unique_ptr<MixingCache::Config>(new MixingCache::Config(pset, maxNbSources_));
219  }
220 
221  // update method call at begin run/lumi to reload the mixing configuration
223  update(setup);
224  for (size_t endIdx=0; endIdx<maxNbSources_; ++endIdx) {
225  if(inputSources_[endIdx]) inputSources_[endIdx]->beginLuminosityBlock(lumi, setup);
226  }
227  }
228 
230  update(setup);
231  for (size_t endIdx=0; endIdx<maxNbSources_; ++endIdx) {
232  if(inputSources_[endIdx]) inputSources_[endIdx]->beginRun(run, setup);
233  }
234  }
235 
237  for (size_t endIdx=0; endIdx<maxNbSources_; ++endIdx) {
238  if(inputSources_[endIdx]) inputSources_[endIdx]->endLuminosityBlock(lumi, setup);
239  }
240  }
241 
243  for (size_t endIdx=0; endIdx<maxNbSources_; ++endIdx) {
244  if(inputSources_[endIdx]) inputSources_[endIdx]->endRun(run, setup);
245  }
246  }
247 
249  if (readDB_ && parameterWatcher_.check(setup)){
250  for (size_t makeIdx = 0; makeIdx < maxNbSources_; makeIdx++ ) {
251  if (inputSources_[makeIdx]) inputSources_[makeIdx]->reload(setup);
252  }
253  reload(setup);
254  }
255  }
256 
257  // Functions that get called by framework every event
259  // Check if the signal is present in the root file
260  // for all the objects we want to mix
261  checkSignal(e);
262 
263  // Create EDProduct
264  createnewEDProduct();
265 
266  initializeEvent(e, setup);
267 
268  // Add signals
269  if (!mixProdStep1_){
270  addSignals(e,setup);
271  }
272 
273  doPileUp(e, setup);
274 
275  // Includes putting digi products into the edm::Event.
276  finalizeEvent(e, setup);
277 
278  // Put output into event (here only playback info)
279  put(e,setup);
280  }
281 
283  for (size_t dropIdx=0; dropIdx<maxNbSources_; ++dropIdx) {
284  if(inputSources_[dropIdx]) inputSources_[dropIdx]->setupPileUpEvent(setup);
285  }
286  }
287 
288  void BMixingModule::dropUnwantedBranches(std::vector<std::string> const& wantedBranches) {
289  for (size_t dropIdx=0; dropIdx<maxNbSources_; ++dropIdx) {
290  if(inputSources_[dropIdx]) inputSources_[dropIdx]->dropUnwantedBranches(wantedBranches);
291  }
292  }
293 
295  for (size_t endIdx=0; endIdx<maxNbSources_; ++endIdx) {
296  if(inputSources_[endIdx]) inputSources_[endIdx]->beginStream(iID);
297  }
298  }
299 
301  for (size_t endIdx=0; endIdx<maxNbSources_; ++endIdx) {
302  if(inputSources_[endIdx]) inputSources_[endIdx]->endStream();
303  }
304  }
305 
307  edm::LogWarning("MixingModule") << "BMixingModule::createnewEDProduct must be overwritten!";
308  }
309 
311  edm::LogWarning("MixingModule") << "BMixingModule::checkSignal must be overwritten!";
312  }
313 
315  edm::LogWarning("MixingModule") << "BMixingModule::setBcrOffset must be overwritten!";
316  }
317 
318  void BMixingModule::setSourceOffset (const unsigned int s) {
319  edm::LogWarning("MixingModule") << "BMixingModule::setSourceOffset must be overwritten!";
320  }
321 
323  edm::LogWarning("MixingModule") << "BMixingModule::doPileUp must be overwritten!";
324  }
325 
326 } //edm
#define LogDebug(id)
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
void beginRun(const edm::Run &r, const edm::EventSetup &setup) override
static std::unique_ptr< MixingCache::Config > initializeGlobalCache(edm::ParameterSet const &)
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
void produce(edm::Event &e1, const edm::EventSetup &c) override
std::vector< std::string > sourceNames_
Definition: BMixingModule.h:35
virtual void checkSignal(const edm::Event &e)
bool exists(std::string const &parameterName) const
checks if a parameter exists
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:1
void endStream() override
void endRun(const edm::Run &r, const edm::EventSetup &setup) override
virtual void setBcrOffset()
void put(edm::Event &evt, double value, const char *instanceName)
virtual void createnewEDProduct()
virtual void setSourceOffset(const unsigned int s)
virtual void doPileUp(edm::Event &e, const edm::EventSetup &c)
void beginStream(edm::StreamID) override
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static const unsigned int maxNbSources_
~BMixingModule() override
HLT enums.
#define update(a, b)
std::vector< std::shared_ptr< PileUp > > inputSources_
void dropUnwantedBranches(std::vector< std::string > const &wantedBranches)
void beginLuminosityBlock(const edm::LuminosityBlock &l, const edm::EventSetup &setup) override
void update(edm::EventSetup const &)
std::vector< std::shared_ptr< PileUpConfig > > inputConfigs_
Definition: BMixingModule.h:36
void setupPileUpEvent(const edm::EventSetup &setup)
void endLuminosityBlock(const edm::LuminosityBlock &l, const edm::EventSetup &setup) override
Definition: Run.h:43
BMixingModule(const edm::ParameterSet &ps, MixingCache::Config const *globalConf)