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