CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 
20 using namespace std;
21 
23 const unsigned int edm::BMixingModule::maxNbSources_ =4;
24 
25 namespace
26 {
27  boost::shared_ptr<edm::PileUp>
28  maybeMakePileUp(edm::ParameterSet const& ps,std::string sourceName, const int minb, const int maxb, const bool playback)
29  {
30  boost::shared_ptr<edm::PileUp> pileup; // value to be returned
31  // Make sure we have a parameter named 'sourceName'
32  if (ps.exists(sourceName))
33  {
34  // We have the parameter
35  // and if we have either averageNumber or cfg by luminosity... make the PileUp
36  double averageNumber;
37  std::string histoFileName=" ";
38  std::string histoName =" ";
39  TH1F * h = new TH1F("h","h",10,0,10);
40  vector<int> dataProbFunctionVar;
41  vector<double> dataProb;
42 
43 
44  const edm::ParameterSet & psin=ps.getParameter<edm::ParameterSet>(sourceName);
45  std::string type_=psin.getParameter<std::string>("type");
46  if (ps.exists("readDB") && ps.getParameter<bool>("readDB")){
47  //in case of DB access, do not try to load anything from the PSet, but wait for beginRun.
48  edm::LogError("BMixingModule")<<"Will read from DB: reset to a dummy PileUp object.";
49  pileup.reset(new edm::PileUp(psin,0,0,playback));
50  return pileup;
51  }
52  if (type_!="none"){
53  if (psin.exists("nbPileupEvents")) {
54  edm::ParameterSet psin_average=psin.getParameter<edm::ParameterSet>("nbPileupEvents");
55  if (psin_average.exists("averageNumber"))
56  {
57  averageNumber=psin_average.getParameter<double>("averageNumber");
58  pileup.reset(new edm::PileUp(psin,averageNumber,h,playback));
59  edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with averageNumber "<<averageNumber;
60  }
61  else if (psin_average.exists("fileName") && psin_average.exists("histoName")) {
62  std::string histoFileName = psin_average.getUntrackedParameter<std::string>("fileName");
63  std::string histoName = psin_average.getUntrackedParameter<std::string>("histoName");
64 
65  TFile *infile = new TFile(histoFileName.c_str());
66  TH1F *h = (TH1F*)infile->Get(histoName.c_str());
67 
68  // Check if the histogram exists
69  if (!h) {
70  throw cms::Exception("HistogramNotFound") << " Could not find the histogram " << histoName
71  << "in the file " << histoFileName << "." << std::endl;
72  }else{
73  edm::LogInfo("MixingModule") << "Open a root file " << histoFileName << " containing the probability distribution histogram " << histoName << std::endl;
74  edm::LogInfo("MixingModule") << "The PileUp number to be added will be chosen randomly from this histogram" << std::endl;
75  }
76 
77  // Check if the histogram is normalized
78  if (((h->Integral() - 1) > 1.0e-02) && ((h->Integral() - 1) < -1.0e-02)) throw cms::Exception("BadHistoDistribution") << "The histogram should be normalized!" << std::endl;
79 
80  // Get the averageNumber from the histo
81  averageNumber = h->GetMean();
82 
83  pileup.reset(new edm::PileUp(psin,averageNumber,h,playback));
84  edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with averageNumber "<<averageNumber;
85 
86  }
87  else if (psin_average.exists("probFunctionVariable") && psin_average.exists("probValue") && psin_average.exists("histoFileName"))
88  {
89  if (type_!="probFunction") {
90  edm::LogError("MisConfiguration")<<"type is set to: "<<type_<<" while parameters implies probFunction; changing.";
91  type_="probFunction";
92  }
93 
94  dataProbFunctionVar = psin_average.getParameter<vector<int> >("probFunctionVariable");
95  dataProb = psin_average.getParameter<vector<double> >("probValue");
96  histoFileName = psin_average.getUntrackedParameter<std::string>("histoFileName");
97 
98  int varSize = (int) dataProbFunctionVar.size();
99  int probSize = (int) dataProb.size();
100 
101  if ((dataProbFunctionVar[0] != 0) || (dataProbFunctionVar[varSize - 1] != (varSize - 1)))
102  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." << endl;
103 
104  // Complete the vector containing the probability function data
105  // with the values "0"
106  if (probSize < varSize){
107  edm::LogInfo("MixingModule") << " The probability function data will be completed with " <<(varSize - probSize) <<" values 0.";
108 
109  for (int i=0; i<(varSize - probSize); i++) dataProb.push_back(0);
110 
111  probSize = dataProb.size();
112  edm::LogInfo("MixingModule") << " The number of the P(x) data set after adding the values 0 is " << probSize;
113  }
114 
115  // Create an histogram with the data from the probability function provided by the user
116  int xmin = (int) dataProbFunctionVar[0];
117  int xmax = (int) dataProbFunctionVar[varSize-1]+1; // need upper edge to be one beyond last value
118  int numBins = varSize;
119 
120  edm::LogInfo("MixingModule") << "An histogram will be created with " << numBins << " bins in the range ("<< xmin << "," << xmax << ")." << std::endl;
121 
122  TH1F *hprob = new TH1F("h","Histo from the user's probability function",numBins,xmin,xmax);
123 
124  LogDebug("MixingModule") << "Filling histogram with the following data:" << std::endl;
125 
126  for (int j=0; j < numBins ; j++){
127  LogDebug("MixingModule") << " x = " << dataProbFunctionVar[j ]<< " P(x) = " << dataProb[j];
128  hprob->Fill(dataProbFunctionVar[j]+0.5,dataProb[j]); // assuming integer values for the bins, fill bin centers, not edges
129  }
130 
131  // Check if the histogram is normalized
132  if ( ((hprob->Integral() - 1) > 1.0e-02) && ((hprob->Integral() - 1) < -1.0e-02)){
133  throw cms::Exception("BadProbFunction") << "The probability function should be normalized!!! " << endl;
134  }
135 
136  averageNumber = hprob->GetMean();
137 
138  // Write the created histogram into a root file
139  edm::LogInfo("MixingModule") << " The histogram created from the x, P(x) values will be written into the root file " << histoFileName;
140 
141  TFile * outfile = new TFile(histoFileName.c_str(),"RECREATE");
142  hprob->Write();
143  outfile->Write();
144  outfile->Close();
145  outfile->Delete();
146 
147  pileup.reset(new edm::PileUp(psin,averageNumber,hprob,playback));
148  edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with averageNumber "<<averageNumber;
149 
150  }
151  //special for pileup input
152  else if (sourceName=="input" && psin_average.exists("Lumi") && psin_average.exists("sigmaInel")) {
153  averageNumber=psin_average.getParameter<double>("Lumi")*psin_average.getParameter<double>("sigmaInel")*ps.getParameter<int>("bunchspace")/1000*3564./2808.; //FIXME
154  pileup.reset(new
155  edm::PileUp(psin,averageNumber,h,playback));
156  edm::LogInfo("MixingModule") <<" Created source "<<sourceName<<" with minBunch,maxBunch "<<minb<<" "<<maxb;
157  edm::LogInfo("MixingModule")<<" Luminosity configuration, average number used is "<<averageNumber;
158  }
159  }
160  }
161  }
162  return pileup;
163  }
164 }
165 
166 namespace edm {
167 
168  // Constructor
169  BMixingModule::BMixingModule(const edm::ParameterSet& pset) :
170  bunchSpace_(pset.getParameter<int>("bunchspace")),
171  minBunch_((pset.getParameter<int>("minBunch")*25)/pset.getParameter<int>("bunchspace")),
172  maxBunch_((pset.getParameter<int>("maxBunch")*25)/pset.getParameter<int>("bunchspace")),
173  mixProdStep1_(pset.getParameter<bool>("mixProdStep1")),
174  mixProdStep2_(pset.getParameter<bool>("mixProdStep2")),
175  readDB_(false)
176  {
177  if (pset.exists("readDB")) readDB_=pset.getParameter<bool>("readDB");
178 
179  playback_=pset.getUntrackedParameter<bool>("playback",false);
180 
181  if (playback_) {
182  //this could be explicitely checked
183  LogInfo("MixingModule") <<" ATTENTION:Mixing will be done in playback mode! \n"
184  <<" ATTENTION:Mixing Configuration must be the same as for the original mixing!";
185  }
186 
187  // Just for debugging print out.
188  sourceNames_.push_back("input");
189  sourceNames_.push_back("cosmics");
190  sourceNames_.push_back("beamhalo_plus");
191  sourceNames_.push_back("beamhalo_minus");
192 
193  for (size_t makeIdx = 0; makeIdx < maxNbSources_; makeIdx++ ) {
194  inputSources_.push_back(maybeMakePileUp(pset,sourceNames_[makeIdx],
196  if (inputSources_.back()) inputSources_.back()->input(makeIdx);
197  }
198  }
199 
200  // Virtual destructor needed.
202 
203  // method call at begin run/lumi to reload the mixing configuration
205  update(setup);
206  }
208  update(setup);
209  }
210 
212  if (readDB_ && parameterWatcher_.check(setup)){
213  for (size_t makeIdx = 0; makeIdx < maxNbSources_; makeIdx++ ) {
214  if (inputSources_[makeIdx]) inputSources_[makeIdx]->reload(setup);
215  }
216  reload(setup);
217  }
218  }
219 
220  // Functions that get called by framework every event
222 
223  // Check if the signal is present in the root file
224  // for all the objects we want to mix
225  checkSignal(e);
226 
227  // Create EDProduct
229 
230  // Add signals
231  if (!mixProdStep1_){
232  addSignals(e,setup);
233  }
234 
235  doPileUp(e,setup);
236 
237  // Put output into event (here only playback info)
238  put(e,setup);
239  }
240 
241  void BMixingModule::dropUnwantedBranches(std::vector<std::string> const& wantedBranches) {
242  for (size_t dropIdx=0; dropIdx<maxNbSources_; dropIdx++ ) {
243  if( inputSources_[dropIdx] ) inputSources_[dropIdx]->dropUnwantedBranches(wantedBranches);
244  }
245  }
246 
248  for (size_t endIdx=0; endIdx<maxNbSources_; endIdx++ ) {
249  if( inputSources_[endIdx] ) inputSources_[endIdx]->endJob();
250  }
251  }
252 
253 } //edm
#define LogDebug(id)
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
edm::ESWatcher< MixingRcd > parameterWatcher_
Definition: BMixingModule.h:90
static int vertexoffset
Definition: BMixingModule.h:70
virtual void addSignals(const edm::Event &e, const edm::EventSetup &c)
Definition: BMixingModule.h:56
virtual void endJob()
virtual void beginRun(edm::Run &r, const edm::EventSetup &setup)
tuple histoFileName
Definition: diJetCalib.py:108
bool exists(std::string const &parameterName) const
checks if a parameter exists
virtual void put(edm::Event &e, const edm::EventSetup &c)
Definition: BMixingModule.h:60
virtual void checkSignal(const edm::Event &e)
Definition: BMixingModule.h:55
list outfile
Definition: EdgesToViz.py:91
virtual void beginLuminosityBlock(edm::LuminosityBlock &, edm::EventSetup const &)
int j
Definition: DBlmapReader.cc:9
static const unsigned int maxNbSources_
Definition: BMixingModule.h:79
virtual void reload(const edm::EventSetup &setup)
Definition: BMixingModule.h:45
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:59
std::vector< boost::shared_ptr< PileUp > > inputSources_
Definition: BMixingModule.h:87
bool const mixProdStep1_
Definition: BMixingModule.h:74
virtual ~BMixingModule()
list infile
Definition: EdgesToViz.py:90
virtual void produce(edm::Event &e1, const edm::EventSetup &c)
tuple playback
Definition: Playback_cff.py:20
virtual void doPileUp(edm::Event &e, const edm::EventSetup &c)
Definition: BMixingModule.h:61
void dropUnwantedBranches(std::vector< std::string > const &wantedBranches)
std::vector< std::string > sourceNames_
Definition: BMixingModule.h:80
void update(edm::EventSetup const &)
virtual void createnewEDProduct()
Definition: BMixingModule.h:54
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
Definition: Run.h:33