CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Lumi3DReWeighting.cc
Go to the documentation of this file.
1 #ifndef PhysicsTools_Utilities_interface_Lumi3DReWeighting_cc
2 #define PhysicsTools_Utilities_interface_Lumi3DReWeighting_cc
3 
4 
20 #include "TRandom1.h"
21 #include "TRandom2.h"
22 #include "TRandom3.h"
23 #include "TStopwatch.h"
24 #include "TH1.h"
25 #include "TH3.h"
26 #include "TFile.h"
27 #include <iostream>
28 #include <string>
29 #include <algorithm>
30 #include <boost/shared_ptr.hpp>
37 
38 using namespace edm;
39 
41  std::string dataFile,
42  std::string GenHistName = "pileup",
43  std::string DataHistName = "pileup",
44  std::string WeightOutputFile ="") :
45  generatedFileName_( generatedFile),
46  dataFileName_ ( dataFile ),
47  GenHistName_ ( GenHistName ),
48  DataHistName_ ( DataHistName ),
49  weightFileName_ (WeightOutputFile)
50  {
51  generatedFile_ = boost::shared_ptr<TFile>( new TFile(generatedFileName_.c_str()) ); //MC distribution
52  dataFile_ = boost::shared_ptr<TFile>( new TFile(dataFileName_.c_str()) ); //Data distribution
53 
54  boost::shared_ptr<TH1> Data_temp = boost::shared_ptr<TH1>( (static_cast<TH1*>(dataFile_->Get( DataHistName_.c_str() )->Clone() )) );
55 
56  boost::shared_ptr<TH1> MC_temp = boost::shared_ptr<TH1>( (static_cast<TH1*>(generatedFile_->Get( GenHistName_.c_str() )->Clone() )) );
57 
58 
59  MC_distr_ = boost::shared_ptr<TH1>( (static_cast<TH1*>(generatedFile_->Get( GenHistName_.c_str() )->Clone() )) );
60  Data_distr_ = boost::shared_ptr<TH1>( (static_cast<TH1*>(dataFile_->Get( DataHistName_.c_str() )->Clone() )) );
61 
62  // MC * data/MC = data, so the weights are data/MC:
63 
64  // normalize both histograms first
65 
66  Data_distr_->Scale( 1.0/ Data_distr_->Integral() );
67  MC_distr_->Scale( 1.0/ MC_distr_->Integral() );
68 
69 }
70 
71 Lumi3DReWeighting::Lumi3DReWeighting( const std::vector< float >& MC_distr, const std::vector< float >& Lumi_distr,
72  std::string WeightOutputFile ="") {
73 
74  weightFileName_ = WeightOutputFile;
75 
76  // no histograms for input: use vectors
77 
78  // now, make histograms out of them:
79 
80  Int_t NMCBins = MC_distr.size();
81 
82  MC_distr_ = boost::shared_ptr<TH1> ( new TH1F("MC_distr","MC dist",NMCBins,0., float(NMCBins)) );
83 
84  Int_t NDBins = Lumi_distr.size();
85 
86  Data_distr_ = boost::shared_ptr<TH1> ( new TH1F("Data_distr","Data dist",NDBins,0., float(NDBins)) );
87 
88  for(int ibin = 1; ibin<NMCBins+1; ++ibin ) {
89  MC_distr_->SetBinContent(ibin,MC_distr[ibin-1]);
90  }
91 
92  for(int ibin = 1; ibin<NDBins+1; ++ibin ) {
93  Data_distr_->SetBinContent(ibin, Lumi_distr[ibin-1]);
94  }
95 
96  // check integrals, make sure things are normalized
97 
98  float deltaH = Data_distr_->Integral();
99  if(fabs(1.0 - deltaH) > 0.001 ) { //*OOPS*...
100  Data_distr_->Scale( 1.0/ Data_distr_->Integral() );
101  }
102  float deltaMC = MC_distr_->Integral();
103  if(fabs(1.0 - deltaMC) > 0.001 ) {
104  MC_distr_->Scale(1.0/ MC_distr_->Integral());
105  }
106 
107 }
108 
109 
110 double Lumi3DReWeighting::weight3D( int pv1, int pv2, int pv3 ) {
111 
112  using std::min;
113 
114  int npm1 = min(pv1,49);
115  int np0 = min(pv2,49);
116  int npp1 = min(pv3,49);
117 
118  return Weight3D_[npm1][np0][npp1];
119 
120 }
121 
122 // This version does all of the work for you, just taking an event pointer as input
123 
125 
126  using std::min;
127 
128  // get pileup summary information
129 
131  e.getByLabel(edm::InputTag("addPileupInfo"), PupInfo);
132 
133  std::vector<PileupSummaryInfo>::const_iterator PVI;
134 
135  int npm1=-1;
136  int np0=-1;
137  int npp1=-1;
138 
139  for(PVI = PupInfo->begin(); PVI != PupInfo->end(); ++PVI) {
140 
141  int BX = PVI->getBunchCrossing();
142 
143  if(BX == -1) {
144  npm1 = PVI->getPU_NumInteractions();
145  }
146  if(BX == 0) {
147  np0 = PVI->getPU_NumInteractions();
148  }
149  if(BX == 1) {
150  npp1 = PVI->getPU_NumInteractions();
151  }
152 
153  }
154 
155  npm1 = min(npm1,49);
156  np0 = min(np0,49);
157  npp1 = min(npp1,49);
158 
159  // std::cout << " vertices " << npm1 << " " << np0 << " " << npp1 << std::endl;
160 
161  return Weight3D_[npm1][np0][npp1];
162 
163 }
164 
165 void Lumi3DReWeighting::weight3D_set( std::string generatedFile, std::string dataFile, std::string GenHistName, std::string DataHistName, std::string WeightOutputFile )
166 {
167 
168  generatedFileName_ = generatedFile;
169  dataFileName_ = dataFile ;
170  GenHistName_ = GenHistName ;
171  DataHistName_= DataHistName ;
172  weightFileName_ = WeightOutputFile;
173 
174  std::cout<< " seting values: " << generatedFileName_ << " " << dataFileName_ << " " << GenHistName_ << " " << DataHistName_ << std::endl;
175 
176  generatedFile_ = boost::shared_ptr<TFile>( new TFile(generatedFileName_.c_str()) ); //MC distribution
177  dataFile_ = boost::shared_ptr<TFile>( new TFile(dataFileName_.c_str()) ); //Data distribution
178 
179  boost::shared_ptr<TH1> Data_temp = boost::shared_ptr<TH1>( (static_cast<TH1*>(dataFile_->Get( DataHistName_.c_str() )->Clone() )) );
180 
181  boost::shared_ptr<TH1> MC_temp = boost::shared_ptr<TH1>( (static_cast<TH1*>(generatedFile_->Get( GenHistName_.c_str() )->Clone() )) );
182 
183 
184  MC_distr_ = boost::shared_ptr<TH1>( (static_cast<TH1*>(generatedFile_->Get( GenHistName_.c_str() )->Clone() )) );
185  Data_distr_ = boost::shared_ptr<TH1>( (static_cast<TH1*>(dataFile_->Get( DataHistName_.c_str() )->Clone() )) );
186 
187  // MC * data/MC = data, so the weights are data/MC:
188 
189  // normalize both histograms first
190 
191  Data_distr_->Scale( 1.0/ Data_distr_->Integral() );
192  MC_distr_->Scale( 1.0/ MC_distr_->Integral() );
193 }
194 
195 void Lumi3DReWeighting::weight3D_init( float ScaleFactor ) {
196 
197  // Scale factor is used to shift target distribution (i.e. luminosity scale) 1. = no shift
198 
199  //create histogram to write output weights, save pain of generating them again...
200 
201  TH3D* WHist = new TH3D("WHist","3D weights",50,0.,50.,50,0.,50.,50,0.,50. );
202  TH3D* DHist = new TH3D("DHist","3D weights",50,0.,50.,50,0.,50.,50,0.,50. );
203  TH3D* MHist = new TH3D("MHist","3D weights",50,0.,50.,50,0.,50.,50,0.,50. );
204 
205  using std::min;
206 
207  if( MC_distr_->GetEntries() == 0 ) {
208  std::cout << " MC and Data distributions are not initialized! You must call the Lumi3DReWeighting constructor. " << std::endl;
209  }
210 
211 
212  // arrays for storing number of interactions
213 
214  double MC_ints[50][50][50];
215  double Data_ints[50][50][50];
216 
217  for (int i=0; i<50; i++) {
218  for(int j=0; j<50; j++) {
219  for(int k=0; k<50; k++) {
220  MC_ints[i][j][k] = 0.;
221  Data_ints[i][j][k] = 0.;
222  }
223  }
224  }
225 
226  double factorial[50];
227  double PowerSer[50];
228  double base = 1.;
229 
230  factorial[0] = 1.;
231  PowerSer[0]=1.;
232 
233  for (int i = 1; i<50; ++i) {
234  base = base*float(i);
235  factorial[i] = base;
236  }
237 
238 
239  double x;
240  double xweight;
241  double probi, probj, probk;
242  double Expval, mean;
243  int xi;
244 
245  // Get entries for Data, MC, fill arrays:
246 
247  int NMCbin = MC_distr_->GetNbinsX();
248 
249  for (int jbin=1;jbin<NMCbin+1;jbin++) {
250  x = MC_distr_->GetBinCenter(jbin);
251  xweight = MC_distr_->GetBinContent(jbin); //use as weight for matrix
252 
253  //for Summer 11, we have this int feature:
254  xi = int(x);
255 
256  // Generate Poisson distribution for each value of the mean
257 
258  mean = double(xi);
259 
260  if(mean<0.) {
261  throw cms::Exception("BadInputValue") << " Your histogram generates MC luminosity values less than zero!"
262  << " Please Check. Terminating." << std::endl;
263  }
264 
265 
266  if(mean==0.){
267  Expval = 1.;
268  }
269  else {
270  Expval = exp(-1.*mean);
271  }
272 
273  base = 1.;
274 
275  for (int i = 1; i<50; ++i) {
276  base = base*mean;
277  PowerSer[i] = base; // PowerSer is mean^i
278  }
279 
280  // compute poisson probability for each Nvtx in weight matrix
281 
282  for (int i=0; i<50; i++) {
283  probi = PowerSer[i]/factorial[i]*Expval;
284  for(int j=0; j<50; j++) {
285  probj = PowerSer[j]/factorial[j]*Expval;
286  for(int k=0; k<50; k++) {
287  probk = PowerSer[k]/factorial[k]*Expval;
288  // joint probability is product of event weights multiplied by weight of input distribution bin
289  MC_ints[i][j][k] = MC_ints[i][j][k]+probi*probj*probk*xweight;
290  }
291  }
292  }
293 
294  }
295 
296  int NDatabin = Data_distr_->GetNbinsX();
297 
298  for (int jbin=1;jbin<NDatabin+1;jbin++) {
299  mean = (Data_distr_->GetBinCenter(jbin))*ScaleFactor;
300  xweight = Data_distr_->GetBinContent(jbin);
301 
302  // Generate poisson distribution for each value of the mean
303 
304  if(mean<0.) {
305  throw cms::Exception("BadInputValue") << " Your histogram generates Data luminosity values less than zero!"
306  << " Please Check. Terminating." << std::endl;
307  }
308 
309  if(mean==0.){
310  Expval = 1.;
311  }
312  else {
313  Expval = exp(-1.*mean);
314  }
315 
316  base = 1.;
317 
318  for (int i = 1; i<50; ++i) {
319  base = base*mean;
320  PowerSer[i] = base;
321  }
322 
323  // compute poisson probability for each Nvtx in weight matrix
324 
325  for (int i=0; i<50; i++) {
326  probi = PowerSer[i]/factorial[i]*Expval;
327  for(int j=0; j<50; j++) {
328  probj = PowerSer[j]/factorial[j]*Expval;
329  for(int k=0; k<50; k++) {
330  probk = PowerSer[k]/factorial[k]*Expval;
331  // joint probability is product of event weights multiplied by weight of input distribution bin
332  Data_ints[i][j][k] = Data_ints[i][j][k]+probi*probj*probk*xweight;
333  }
334  }
335  }
336 
337  }
338 
339 
340  for (int i=0; i<50; i++) {
341  //if(i<5) std::cout << "i = " << i << std::endl;
342  for(int j=0; j<50; j++) {
343  for(int k=0; k<50; k++) {
344  if( (MC_ints[i][j][k])>0.) {
345  Weight3D_[i][j][k] = Data_ints[i][j][k]/MC_ints[i][j][k];
346  }
347  else {
348  Weight3D_[i][j][k] = 0.;
349  }
350  WHist->SetBinContent( i+1,j+1,k+1,Weight3D_[i][j][k] );
351  DHist->SetBinContent( i+1,j+1,k+1,Data_ints[i][j][k] );
352  MHist->SetBinContent( i+1,j+1,k+1,MC_ints[i][j][k] );
353  // if(i<5 && j<5 && k<5) std::cout << Weight3D_[i][j][k] << " " ;
354  }
355  // if(i<5 && j<5) std::cout << std::endl;
356  }
357  }
358 
359  if(! weightFileName_.empty() ) {
360  std::cout << " 3D Weight Matrix initialized! " << std::endl;
361  std::cout << " Writing weights to file " << weightFileName_ << " for re-use... " << std::endl;
362 
363 
364  TFile * outfile = new TFile(weightFileName_.c_str(),"RECREATE");
365  WHist->Write();
366  MHist->Write();
367  DHist->Write();
368  outfile->Write();
369  outfile->Close();
370  outfile->Delete();
371  }
372 
373  return;
374 
375 
376 }
377 
378 
380 
381  TFile *infile = new TFile(WeightFileName.c_str());
382  TH1F *WHist = (TH1F*)infile->Get("WHist");
383 
384  // Check if the histogram exists
385  if (!WHist) {
386  throw cms::Exception("HistogramNotFound") << " Could not find the histogram WHist in the file "
387  << "in the file " << WeightFileName << "." << std::endl;
388  }
389 
390  for (int i=0; i<50; i++) {
391  // if(i<5) std::cout << "i = " << i << std::endl;
392  for(int j=0; j<50; j++) {
393  for(int k=0; k<50; k++) {
394  Weight3D_[i][j][k] = WHist->GetBinContent(i+1,j+1,k+1);
395  // if(i<5 && j<5 && k<5) std::cout << Weight3D_[i][j][k] << " ";
396  }
397  // if(i<5 && j<5) std::cout << std::endl;
398 
399  }
400  }
401 
402  std::cout << " 3D Weight Matrix initialized! " << std::endl;
403 
404  return;
405 
406 
407 }
408 
409 void Lumi3DReWeighting::weight3D_init( std::string MCWeightFileName, std::string DataWeightFileName ) {
410 
411  TFile *infileMC = new TFile(MCWeightFileName.c_str());
412  TH3D *MHist = (TH3D*)infileMC->Get("MHist");
413 
414  // Check if the histogram exists
415  if (!MHist) {
416  throw cms::Exception("HistogramNotFound") << " Could not find the histogram MHist in the file "
417  << "in the file " << MCWeightFileName << "." << std::endl;
418  }
419 
420  TFile *infileD = new TFile(DataWeightFileName.c_str());
421  TH3D *DHist = (TH3D*)infileD->Get("DHist");
422 
423  // Check if the histogram exists
424  if (!DHist) {
425  throw cms::Exception("HistogramNotFound") << " Could not find the histogram DHist in the file "
426  << "in the file " << DataWeightFileName << "." << std::endl;
427  }
428 
429  for (int i=0; i<50; i++) {
430  for(int j=0; j<50; j++) {
431  for(int k=0; k<50; k++) {
432  Weight3D_[i][j][k] = DHist->GetBinContent(i+1,j+1,k+1)/MHist->GetBinContent(i+1,j+1,k+1);
433  }
434  }
435  }
436 
437  std::cout << " 3D Weight Matrix initialized! " << std::endl;
438 
439  return;
440 
441 
442 }
443 
444 
445 #endif
tuple base
Main Program
Definition: newFWLiteAna.py:91
double Weight3D_[50][50][50]
int i
Definition: DBlmapReader.cc:9
T x() const
Cartesian x coordinate.
int j
Definition: DBlmapReader.cc:9
EventID const & min(EventID const &lh, EventID const &rh)
Definition: EventID.h:137
T min(T a, T b)
Definition: MathUtil.h:58
double weight3D(const edm::EventBase &e)
void weight3D_set(std::string generatedFile, std::string dataFile, std::string GenHistName, std::string DataHistName, std::string WeightOutputFile)
void weight3D_init(float Scale)
boost::shared_ptr< TH1 > MC_distr_
boost::shared_ptr< TFile > dataFile_
bool getByLabel(InputTag const &, Handle< T > &) const
Definition: EventBase.h:90
int factorial(int n)
factorial function
boost::shared_ptr< TFile > generatedFile_
tuple cout
Definition: gather_cfg.py:145
boost::shared_ptr< TH1 > Data_distr_