CMS 3D CMS Logo

LumiReweightingStandAlone.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_Utilities_interface_LumiReWeighting_h
2 #define PhysicsTools_Utilities_interface_LumiReWeighting_h
3 
4 
20 #include "TH1F.h"
21 #include "TH3.h"
22 #include "TFile.h"
23 #include "TRandom1.h"
24 #include "TRandom2.h"
25 #include "TRandom3.h"
26 #include "TStopwatch.h"
27 #include <string>
28 #include <vector>
29 #include <cmath>
30 #include <algorithm>
31 
32 namespace reweight {
33 
34 
35  // add a class to shift the mean of a poisson-like luminosity distribution by an arbitrary amount.
36  // Only valid for small (<1.5) shifts about the 2011 lumi distribution for now, because shifts are non-linear
37  // Each PoissonMeanShifter does one shift, so defining multiples can give you an arbitrary collection
38 
39  class PoissonMeanShifter {
40 
41  public:
42 
44 
45  PoissonMeanShifter( float Shift ){
46 
47  // these are the polynomial or exponential coefficients for each bin of a 25-bin sequence that
48  // convert the Distribution of the 2011 luminosity to something with a lower or higher peak luminosity.
49  // The distributions aren't quite poisson because they model luminosity decreasing during a fill. This implies that
50  // they do get wider as the mean increases, so the weights are not linear with increasing mean.
51 
52  static const double p0_minus[20] = { 1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1. };
53  static const double p1_minus[20] = {
54  -0.677786,
55  -0.619614,
56  -0.49465,
57  -0.357963,
58  -0.238359,
59  -0.110002,
60  0.0348629,
61  0.191263,
62  0.347648,
63  0.516615,
64  0.679646,
65  0.836673,
66  0.97764,
67  1.135,
68  1.29922,
69  1.42467,
70  1.55901,
71  1.61762,
72  1.67275,
73  1.96008
74  };
75  static const double p2_minus[20] = {
76  0.526164,
77  0.251816,
78  0.11049,
79  0.026917,
80  -0.0464692,
81  -0.087022,
82  -0.0931581,
83  -0.0714295,
84  -0.0331772,
85  0.0347473,
86  0.108658,
87  0.193048,
88  0.272314,
89  0.376357,
90  0.4964,
91  0.58854,
92  0.684959,
93  0.731063,
94  0.760044,
95  1.02386
96  };
97 
98  static const double p1_expoM[5] = {
99  1.63363e-03,
100  6.79290e-04,
101  3.69900e-04,
102  2.24349e-04,
103  9.87156e-06
104  };
105 
106  static const double p2_expoM[5] = {
107  2.64692,
108  3.26585,
109  3.53229,
110  4.18035,
111  5.64027
112  };
113 
114 
115  static const double p0_plus[20] = { 1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1. };
116  static const double p1_plus[20] = {
117  -0.739059,
118  -0.594445,
119  -0.477276,
120  -0.359707,
121  -0.233573,
122  -0.103458,
123  0.0373401,
124  0.176571,
125  0.337617,
126  0.499074,
127  0.675126,
128  0.840522,
129  1.00917,
130  1.15847,
131  1.23816,
132  1.44271,
133  1.52982,
134  1.46385,
135  1.5802,
136  0.988689
137  };
138  static const double p2_plus[20] = {
139  0.208068,
140  0.130033,
141  0.0850356,
142  0.0448344,
143  0.000749832,
144  -0.0331347,
145  -0.0653281,
146  -0.0746009,
147  -0.0800667,
148  -0.0527636,
149  -0.00402649,
150  0.103338,
151  0.261261,
152  0.491084,
153  0.857966,
154  1.19495,
155  1.75071,
156  2.65559,
157  3.35433,
158  5.48835
159  };
160 
161  static const double p1_expoP[5] = {
162  1.42463e-01,
163  4.18966e-02,
164  1.12697e-01,
165  1.66197e-01,
166  1.50768e-01
167  };
168 
169  static const double p2_expoP[5] = {
170  1.98758,
171  2.27217,
172  2.26799,
173  2.38455,
174  2.52428
175  };
176 
177  // initialize weights based on desired Shift
178 
179 
180 
181  for (int ibin=0;ibin<20;ibin++) {
182 
183  if( Shift < .0) {
184  Pweight_[ibin] = p0_minus[ibin] + p1_minus[ibin]*Shift + p2_minus[ibin]*Shift*Shift;
185  }
186  else {
187  Pweight_[ibin] = p0_plus[ibin] + p1_plus[ibin]*Shift + p2_plus[ibin]*Shift*Shift;
188  }
189  }
190 
191  // last few bins fit better to an exponential...
192 
193  for (int ibin=20;ibin<25;ibin++) {
194  if( Shift < 0.) {
195  Pweight_[ibin] = p1_expoM[ibin-20]*exp(p2_expoM[ibin-20]*Shift);
196  }
197  else {
198  Pweight_[ibin] = p1_expoP[ibin-20]*exp(p2_expoP[ibin-20]*Shift);
199  }
200  }
201 
202  };
203 
204  double ShiftWeight( int ibin ) {
205 
206  if(ibin<25 && ibin>=0) { return Pweight_[ibin]; }
207  else { return 0;}
208 
209  };
210 
211  double ShiftWeight( float pvnum ) {
212 
213  int ibin = int(pvnum);
214 
215  if(ibin<25 && ibin>=0) { return Pweight_[ibin]; }
216  else { return 0;}
217 
218  };
219 
220  private:
221 
222  double Pweight_[25];
223 
224  };
225 
226 
228  public:
229 
230  LumiReWeighting ( ) { } ;
231 
232  LumiReWeighting( std::string generatedFile,
233  std::string dataFile,
234  std::string GenHistName,
235  std::string DataHistName) :
236  generatedFileName_( generatedFile),
237  dataFileName_ ( dataFile ),
238  GenHistName_ ( GenHistName ),
239  DataHistName_ ( DataHistName )
240  {
241  generatedFile_ = new TFile( generatedFileName_.c_str() ) ; //MC distribution
242  dataFile_ = new TFile( dataFileName_.c_str() ); //Data distribution
243 
244  Data_distr_ = new TH1F( *(static_cast<TH1F*>(dataFile_->Get( DataHistName_.c_str() )->Clone() )) );
245  MC_distr_ = new TH1F( *(static_cast<TH1F*>(generatedFile_->Get( GenHistName_.c_str() )->Clone() )) );
246 
247  // normalize both histograms first
248 
249  Data_distr_->Scale( 1.0/ Data_distr_->Integral() );
250  MC_distr_->Scale( 1.0/ MC_distr_->Integral() );
251 
252  weights_ = new TH1F( *(Data_distr_)) ;
253 
254  // MC * data/MC = data, so the weights are data/MC:
255 
256  weights_->SetName("lumiWeights");
257 
258  TH1F* den = new TH1F(*(MC_distr_));
259 
260  weights_->Divide( den ); // so now the average weight should be 1.0
261 
262  std::cout << " Lumi/Pileup Reweighting: Computed Weights per In-Time Nint " << std::endl;
263 
264  int NBins = weights_->GetNbinsX();
265 
266  for(int ibin = 1; ibin<NBins+1; ++ibin){
267  std::cout << " " << ibin-1 << " " << weights_->GetBinContent(ibin) << std::endl;
268  }
269 
270  weightOOT_init();
271 
272  FirstWarning_ = true;
273 
274  }
275 
276 
277  LumiReWeighting( const std::vector< float >& MC_distr, const std::vector< float >& Lumi_distr){
278  // no histograms for input: use vectors
279 
280  // now, make histograms out of them:
281 
282  // first, check they are the same size...
283 
284  if( MC_distr.size() != Lumi_distr.size() ){
285 
286  std::cerr <<"ERROR: LumiReWeighting: input vectors have different sizes. Quitting... \n";
287  return;
288 
289  }
290 
291  Int_t NBins = MC_distr.size();
292 
293  MC_distr_ = new TH1F("MC_distr","MC dist",NBins,-0.5, float(NBins)-0.5);
294  Data_distr_ = new TH1F("Data_distr","Data dist",NBins,-0.5, float(NBins)-0.5);
295 
296  weights_ = new TH1F("luminumer","luminumer",NBins,-0.5, float(NBins)-0.5);
297  TH1F* den = new TH1F("lumidenom","lumidenom",NBins,-0.5, float(NBins)-0.5);
298 
299  for(int ibin = 1; ibin<NBins+1; ++ibin ) {
300  weights_->SetBinContent(ibin, Lumi_distr[ibin-1]);
301  Data_distr_->SetBinContent(ibin, Lumi_distr[ibin-1]);
302  den->SetBinContent(ibin,MC_distr[ibin-1]);
303  MC_distr_->SetBinContent(ibin,MC_distr[ibin-1]);
304  }
305 
306  // check integrals, make sure things are normalized
307 
308  float deltaH = weights_->Integral();
309  if(fabs(1.0 - deltaH) > 0.02 ) { //*OOPS*...
310  weights_->Scale( 1.0/ deltaH );
311  Data_distr_->Scale( 1.0/ deltaH );
312  }
313  float deltaMC = den->Integral();
314  if(fabs(1.0 - deltaMC) > 0.02 ) {
315  den->Scale(1.0/ deltaMC );
316  MC_distr_->Scale(1.0/ deltaMC );
317  }
318 
319  weights_->Divide( den ); // so now the average weight should be 1.0
320 
321  std::cout << " Lumi/Pileup Reweighting: Computed Weights per In-Time Nint " << std::endl;
322 
323  for(int ibin = 1; ibin<NBins+1; ++ibin){
324  std::cout << " " << ibin-1 << " " << weights_->GetBinContent(ibin) << std::endl;
325  }
326 
327  weightOOT_init();
328 
329  FirstWarning_ = true;
330 
331  }
332 
333  void weight3D_init( float ScaleFactor, std::string WeightOutputFile="") {
334 
335  //create histogram to write output weights, save pain of generating them again...
336 
337  TH3D* WHist = new TH3D("WHist","3D weights",50,0.,50.,50,0.,50.,50,0.,50. );
338  TH3D* DHist = new TH3D("DHist","3D weights",50,0.,50.,50,0.,50.,50,0.,50. );
339  TH3D* MHist = new TH3D("MHist","3D weights",50,0.,50.,50,0.,50.,50,0.,50. );
340 
341 
342  using std::min;
343 
344  if( MC_distr_->GetEntries() == 0 ) {
345  std::cout << " MC and Data distributions are not initialized! You must call the LumiReWeighting constructor. " << std::endl;
346  }
347 
348  // arrays for storing number of interactions
349 
350  double MC_ints[50][50][50];
351  double Data_ints[50][50][50];
352 
353  for (int i=0; i<50; i++) {
354  for(int j=0; j<50; j++) {
355  for(int k=0; k<50; k++) {
356  MC_ints[i][j][k] = 0.;
357  Data_ints[i][j][k] = 0.;
358  }
359  }
360  }
361 
362  double factorial[50];
363  double PowerSer[50];
364  double base = 1.;
365 
366  factorial[0] = 1.;
367  PowerSer[0]=1.;
368 
369  for (int i = 1; i<50; ++i) {
370  base = base*float(i);
371  factorial[i] = base;
372  }
373 
374 
375  double x;
376  double xweight;
377  double probi, probj, probk;
378  double Expval, mean;
379  int xi;
380 
381  // Get entries for Data, MC, fill arrays:
382  int NMCbin = MC_distr_->GetNbinsX();
383 
384  for (int jbin=1;jbin<NMCbin+1;jbin++) {
385  x = MC_distr_->GetBinCenter(jbin);
386  xweight = MC_distr_->GetBinContent(jbin); //use as weight for matrix
387 
388  //for Summer 11, we have this int feature:
389  xi = int(x);
390 
391  // Generate Poisson distribution for each value of the mean
392  mean = double(xi);
393 
394  if(mean<0.) {
395  std::cout << "LumiReweighting:BadInputValue" << " Your histogram generates MC luminosity values less than zero!"
396  << " Please Check. Terminating." << std::endl;
397  }
398 
399 
400  if(mean==0.){
401  Expval = 1.;
402  }
403  else {
404  Expval = exp(-1.*mean);
405  }
406 
407  base = 1.;
408 
409  for (int i = 1; i<50; ++i) {
410  base = base*mean;
411  PowerSer[i] = base; // PowerSer is mean^i
412  }
413 
414  // compute poisson probability for each Nvtx in weight matrix
415  for (int i=0; i<50; i++) {
416  probi = PowerSer[i]/factorial[i]*Expval;
417  for(int j=0; j<50; j++) {
418  probj = PowerSer[j]/factorial[j]*Expval;
419  for(int k=0; k<50; k++) {
420  probk = PowerSer[k]/factorial[k]*Expval;
421  // joint probability is product of event weights multiplied by weight of input distribution bin
422  MC_ints[i][j][k] = MC_ints[i][j][k]+probi*probj*probk*xweight;
423  }
424  }
425  }
426 
427  }
428 
429  int NDatabin = Data_distr_->GetNbinsX();
430 
431  for (int jbin=1;jbin<NDatabin+1;jbin++) {
432  mean = (Data_distr_->GetBinCenter(jbin))*ScaleFactor;
433  xweight = Data_distr_->GetBinContent(jbin);
434 
435  // Generate poisson distribution for each value of the mean
436  if(mean<0.) {
437  std::cout << "LumiReweighting:BadInputValue" << " Your histogram generates MC luminosity values less than zero!"
438  << " Please Check. Terminating." << std::endl;
439  }
440 
441  if(mean==0.){
442  Expval = 1.;
443  }
444  else {
445  Expval = exp(-1.*mean);
446  }
447 
448  base = 1.;
449 
450  for (int i = 1; i<50; ++i) {
451  base = base*mean;
452  PowerSer[i] = base;
453  }
454 
455  // compute poisson probability for each Nvtx in weight matrix
456 
457  for (int i=0; i<50; i++) {
458  probi = PowerSer[i]/factorial[i]*Expval;
459  for(int j=0; j<50; j++) {
460  probj = PowerSer[j]/factorial[j]*Expval;
461  for(int k=0; k<50; k++) {
462  probk = PowerSer[k]/factorial[k]*Expval;
463  // joint probability is product of event weights multiplied by weight of input distribution bin
464  Data_ints[i][j][k] = Data_ints[i][j][k]+probi*probj*probk*xweight;
465  }
466  }
467  }
468 
469  }
470 
471 
472  for (int i=0; i<50; i++) {
473  //if(i<5) std::cout << "i = " << i << std::endl;
474  for(int j=0; j<50; j++) {
475  for(int k=0; k<50; k++) {
476  if( (MC_ints[i][j][k])>0.) {
477  Weight3D_[i][j][k] = Data_ints[i][j][k]/MC_ints[i][j][k];
478  }
479  else {
480  Weight3D_[i][j][k] = 0.;
481  }
482  WHist->SetBinContent( i+1,j+1,k+1,Weight3D_[i][j][k] );
483  DHist->SetBinContent( i+1,j+1,k+1,Data_ints[i][j][k] );
484  MHist->SetBinContent( i+1,j+1,k+1,MC_ints[i][j][k] );
485  // if(i<5 && j<5 && k<5) std::cout << Weight3D_[i][j][k] << " " ;
486  }
487  // if(i<5 && j<5) std::cout << std::endl;
488  }
489  }
490 
491  if(! WeightOutputFile.empty() ) {
492  std::cout << " 3D Weight Matrix initialized! " << std::endl;
493  std::cout << " Writing weights to file " << WeightOutputFile << " for re-use... " << std::endl;
494 
495 
496  TFile * outfile = new TFile(WeightOutputFile.c_str(),"RECREATE");
497  WHist->Write();
498  MHist->Write();
499  DHist->Write();
500  outfile->Write();
501  outfile->Close();
502  outfile->Delete();
503  }
504 
505  return;
506  }
507 
508 
509  void weight3D_set( std::string WeightFileName ) {
510 
511  TFile *infile = new TFile(WeightFileName.c_str());
512  TH1F *WHist = (TH1F*)infile->Get("WHist");
513 
514  // Check if the histogram exists
515  if (!WHist) {
516  std::cout << " Could not find the histogram WHist in the file "
517  << "in the file " << WeightFileName << "." << std::endl;
518  return;
519  }
520 
521  for (int i=0; i<50; i++) {
522  for(int j=0; j<50; j++) {
523  for(int k=0; k<50; k++) {
524  Weight3D_[i][j][k] = WHist->GetBinContent(i,j,k);
525  }
526  }
527  }
528 
529  std::cout << " 3D Weight Matrix initialized! " << std::endl;
530 
531  return;
532 
533 
534  }
535 
536 
537 
538  void weightOOT_init() {
539 
540  // The following are poisson distributions with different means, where the maximum
541  // of the function has been normalized to weight 1.0
542  // These are used to reweight the out-of-time pileup to match the in-time distribution.
543  // The total event weight is the product of the in-time weight, the out-of-time weight,
544  // and a residual correction to fix the distortions caused by the fact that the out-of-time
545  // distribution is not flat.
546 
547  static const double weight_24[25] = {
548  0,
549  0,
550  0,
551  0,
552  2.46277e-06,
553  2.95532e-05,
554  0.000104668,
555  0.000401431,
556  0.00130034,
557  0.00342202,
558  0.00818132,
559  0.0175534,
560  0.035784,
561  0.0650836,
562  0.112232,
563  0.178699,
564  0.268934,
565  0.380868,
566  0.507505,
567  0.640922,
568  0.768551,
569  0.877829,
570  0.958624,
571  0.99939,
572  1
573  };
574 
575  static const double weight_23[25] = {
576  0,
577  1.20628e-06,
578  1.20628e-06,
579  2.41255e-06,
580  1.20628e-05,
581  6.39326e-05,
582  0.000252112,
583  0.000862487,
584  0.00244995,
585  0.00616527,
586  0.0140821,
587  0.0293342,
588  0.0564501,
589  0.100602,
590  0.164479,
591  0.252659,
592  0.36268,
593  0.491427,
594  0.627979,
595  0.75918,
596  0.873185,
597  0.957934,
598  0.999381,
599  1,
600  0.957738
601  };
602 
603  static const double weight_22[25] = {
604  0,
605  0,
606  0,
607  5.88636e-06,
608  3.0609e-05,
609  0.000143627,
610  0.000561558,
611  0.00173059,
612  0.00460078,
613  0.0110616,
614  0.0238974,
615  0.0475406,
616  0.0875077,
617  0.148682,
618  0.235752,
619  0.343591,
620  0.473146,
621  0.611897,
622  0.748345,
623  0.865978,
624  0.953199,
625  0.997848,
626  1,
627  0.954245,
628  0.873688
629  };
630 
631  static const double weight_21[25] = {
632  0,
633  0,
634  1.15381e-06,
635  8.07665e-06,
636  7.1536e-05,
637  0.000280375,
638  0.00107189,
639  0.00327104,
640  0.00809396,
641  0.0190978,
642  0.0401894,
643  0.0761028,
644  0.13472,
645  0.216315,
646  0.324649,
647  0.455125,
648  0.598241,
649  0.739215,
650  0.861866,
651  0.953911,
652  0.998918,
653  1,
654  0.956683,
655  0.872272,
656  0.76399
657  };
658 
659 
660  static const double weight_20[25] = {
661  0,
662  0,
663  1.12532e-06,
664  2.58822e-05,
665  0.000145166,
666  0.000633552,
667  0.00215048,
668  0.00592816,
669  0.0145605,
670  0.0328367,
671  0.0652649,
672  0.11893,
673  0.19803,
674  0.305525,
675  0.436588,
676  0.581566,
677  0.727048,
678  0.8534,
679  0.949419,
680  0.999785,
681  1,
682  0.953008,
683  0.865689,
684  0.753288,
685  0.62765
686  };
687  static const double weight_19[25] = {
688  0,
689  0,
690  1.20714e-05,
691  5.92596e-05,
692  0.000364337,
693  0.00124994,
694  0.00403953,
695  0.0108149,
696  0.025824,
697  0.0544969,
698  0.103567,
699  0.17936,
700  0.283532,
701  0.416091,
702  0.562078,
703  0.714714,
704  0.846523,
705  0.947875,
706  1,
707  0.999448,
708  0.951404,
709  0.859717,
710  0.742319,
711  0.613601,
712  0.48552
713  };
714 
715  static const double weight_18[25] = {
716  0,
717  3.20101e-06,
718  2.88091e-05,
719  0.000164319,
720  0.000719161,
721  0.00250106,
722  0.00773685,
723  0.0197513,
724  0.0443693,
725  0.0885998,
726  0.159891,
727  0.262607,
728  0.392327,
729  0.543125,
730  0.69924,
731  0.837474,
732  0.943486,
733  0.998029,
734  1,
735  0.945937,
736  0.851807,
737  0.729309,
738  0.596332,
739  0.467818,
740  0.350434
741  };
742 
743 
744  static const double weight_17[25] = {
745  1.03634e-06,
746  7.25437e-06,
747  4.97443e-05,
748  0.000340956,
749  0.00148715,
750  0.00501485,
751  0.0143067,
752  0.034679,
753  0.0742009,
754  0.140287,
755  0.238288,
756  0.369416,
757  0.521637,
758  0.682368,
759  0.828634,
760  0.939655,
761  1,
762  0.996829,
763  0.94062,
764  0.841575,
765  0.716664,
766  0.582053,
767  0.449595,
768  0.331336,
769  0.234332
770  };
771 
772 
773  static const double weight_16[25] = {
774  4.03159e-06,
775  2.41895e-05,
776  0.000141106,
777  0.00081942,
778  0.00314565,
779  0.00990662,
780  0.026293,
781  0.0603881,
782  0.120973,
783  0.214532,
784  0.343708,
785  0.501141,
786  0.665978,
787  0.820107,
788  0.938149,
789  1,
790  0.99941,
791  0.940768,
792  0.837813,
793  0.703086,
794  0.564023,
795  0.42928,
796  0.312515,
797  0.216251,
798  0.14561
799  };
800 
801 
802  static const double weight_15[25] = {
803  9.76084e-07,
804  5.07564e-05,
805  0.000303562,
806  0.00174036,
807  0.00617959,
808  0.0188579,
809  0.047465,
810  0.101656,
811  0.189492,
812  0.315673,
813  0.474383,
814  0.646828,
815  0.809462,
816  0.934107,
817  0.998874,
818  1,
819  0.936163,
820  0.827473,
821  0.689675,
822  0.544384,
823  0.40907,
824  0.290648,
825  0.198861,
826  0.12951,
827  0.0808051
828  };
829 
830 
831  static const double weight_14[25] = {
832  1.13288e-05,
833  0.000124617,
834  0.000753365,
835  0.00345056,
836  0.0123909,
837  0.0352712,
838  0.0825463,
839  0.16413,
840  0.287213,
841  0.44615,
842  0.625826,
843  0.796365,
844  0.930624,
845  0.999958,
846  1,
847  0.934414,
848  0.816456,
849  0.672939,
850  0.523033,
851  0.386068,
852  0.269824,
853  0.180342,
854  0.114669,
855  0.0698288,
856  0.0406496
857  };
858 
859 
860  static const double weight_13[25] = {
861  2.54296e-05,
862  0.000261561,
863  0.00167018,
864  0.00748083,
865  0.0241308,
866  0.0636801,
867  0.138222,
868  0.255814,
869  0.414275,
870  0.600244,
871  0.779958,
872  0.92256,
873  0.999155,
874  1,
875  0.927126,
876  0.804504,
877  0.651803,
878  0.497534,
879  0.35976,
880  0.245834,
881  0.160904,
882  0.0991589,
883  0.0585434,
884  0.0332437,
885  0.0180159
886  };
887 
888  static const double weight_12[25] = {
889  5.85742e-05,
890  0.000627706,
891  0.00386677,
892  0.0154068,
893  0.0465892,
894  0.111683,
895  0.222487,
896  0.381677,
897  0.5719,
898  0.765001,
899  0.915916,
900  1,
901  0.999717,
902  0.921443,
903  0.791958,
904  0.632344,
905  0.475195,
906  0.334982,
907  0.223666,
908  0.141781,
909  0.0851538,
910  0.048433,
911  0.0263287,
912  0.0133969,
913  0.00696683
914  };
915 
916 
917  static const double weight_11[25] = {
918  0.00015238,
919  0.00156064,
920  0.00846044,
921  0.0310939,
922  0.0856225,
923  0.187589,
924  0.343579,
925  0.541892,
926  0.74224,
927  0.909269,
928  0.998711,
929  1,
930  0.916889,
931  0.77485,
932  0.608819,
933  0.447016,
934  0.307375,
935  0.198444,
936  0.121208,
937  0.070222,
938  0.0386492,
939  0.0201108,
940  0.0100922,
941  0.00484937,
942  0.00222458
943  };
944 
945  static const double weight_10[25] = {
946  0.000393044,
947  0.00367001,
948  0.0179474,
949  0.060389,
950  0.151477,
951  0.302077,
952  0.503113,
953  0.720373,
954  0.899568,
955  1,
956  0.997739,
957  0.909409,
958  0.75728,
959  0.582031,
960  0.415322,
961  0.277663,
962  0.174147,
963  0.102154,
964  0.0566719,
965  0.0298642,
966  0.0147751,
967  0.00710995,
968  0.00319628,
969  0.00140601,
970  0.000568796
971  };
972 
973 
974  static const double weight_9[25] = {
975  0.00093396,
976  0.00854448,
977  0.0380306,
978  0.113181,
979  0.256614,
980  0.460894,
981  0.690242,
982  0.888781,
983  1,
984  0.998756,
985  0.899872,
986  0.735642,
987  0.552532,
988  0.382726,
989  0.246114,
990  0.147497,
991  0.0825541,
992  0.0441199,
993  0.0218157,
994  0.0103578,
995  0.00462959,
996  0.0019142,
997  0.000771598,
998  0.000295893,
999  0.000111529
1000  };
1001 
1002 
1003  static const double weight_8[25] = {
1004  0.00240233,
1005  0.0192688,
1006  0.0768653,
1007  0.205008,
1008  0.410958,
1009  0.65758,
1010  0.875657,
1011  0.999886,
1012  1,
1013  0.889476,
1014  0.711446,
1015  0.517781,
1016  0.345774,
1017  0.212028,
1018  0.121208,
1019  0.0644629,
1020  0.0324928,
1021  0.0152492,
1022  0.00673527,
1023  0.0028547,
1024  0.00117213,
1025  0.000440177,
1026  0.000168471,
1027  5.80689e-05,
1028  1.93563e-05
1029  };
1030 
1031  static const double weight_7[25] = {
1032  0.00617233,
1033  0.0428714,
1034  0.150018,
1035  0.350317,
1036  0.612535,
1037  0.856525,
1038  0.999923,
1039  1,
1040  0.87544,
1041  0.679383,
1042  0.478345,
1043  0.303378,
1044  0.176923,
1045  0.0950103,
1046  0.0476253,
1047  0.0222211,
1048  0.00972738,
1049  0.00392962,
1050  0.0015258,
1051  0.000559168,
1052  0.000183928,
1053  6.77983e-05,
1054  1.67818e-05,
1055  7.38398e-06,
1056  6.71271e-07
1057  };
1058 
1059  static const double weight_6[25] = {
1060  0.0154465,
1061  0.0923472,
1062  0.277322,
1063  0.55552,
1064  0.833099,
1065  0.999035,
1066  1,
1067  0.855183,
1068  0.641976,
1069  0.428277,
1070  0.256804,
1071  0.139798,
1072  0.0700072,
1073  0.0321586,
1074  0.0137971,
1075  0.00544756,
1076  0.00202316,
1077  0.000766228,
1078  0.000259348,
1079  8.45836e-05,
1080  1.80362e-05,
1081  8.70713e-06,
1082  3.73163e-06,
1083  6.21938e-07,
1084  0
1085  };
1086 
1087 
1088  static const double weight_5[25] = {
1089  0.0382845,
1090  0.191122,
1091  0.478782,
1092  0.797314,
1093  1,
1094  0.997148,
1095  0.831144,
1096  0.59461,
1097  0.371293,
1098  0.205903,
1099  0.103102,
1100  0.0471424,
1101  0.0194997,
1102  0.00749415,
1103  0.00273709,
1104  0.000879189,
1105  0.000286049,
1106  0.000102364,
1107  1.70606e-05,
1108  3.98081e-06,
1109  2.27475e-06,
1110  0,
1111  0,
1112  0,
1113  0
1114  };
1115 
1116 
1117  static const double weight_4[25] = {
1118  0.0941305,
1119  0.373824,
1120  0.750094,
1121  1,
1122  0.997698,
1123  0.800956,
1124  0.532306,
1125  0.304597,
1126  0.152207,
1127  0.0676275,
1128  0.0270646,
1129  0.00975365,
1130  0.00326077,
1131  0.00101071,
1132  0.000301781,
1133  7.41664e-05,
1134  1.58563e-05,
1135  3.58045e-06,
1136  1.02299e-06,
1137  0,
1138  5.11493e-07,
1139  0,
1140  0,
1141  0,
1142  0
1143  };
1144 
1145 
1146  static const double weight_3[25] = {
1147  0.222714,
1148  0.667015,
1149  1,
1150  0.999208,
1151  0.750609,
1152  0.449854,
1153  0.224968,
1154  0.0965185,
1155  0.0361225,
1156  0.012084,
1157  0.00359618,
1158  0.000977166,
1159  0.000239269,
1160  6.29422e-05,
1161  1.16064e-05,
1162  1.78559e-06,
1163  0,
1164  4.46398e-07,
1165  0,
1166  0,
1167  0,
1168  0,
1169  0,
1170  0,
1171  0
1172  };
1173 
1174  static const double weight_2[25] = {
1175  0.499541,
1176  0.999607,
1177  1,
1178  0.666607,
1179  0.333301,
1180  0.13279,
1181  0.0441871,
1182  0.0127455,
1183  0.00318434,
1184  0.00071752,
1185  0.000132204,
1186  2.69578e-05,
1187  5.16999e-06,
1188  2.21571e-06,
1189  0,
1190  0,
1191  0,
1192  0,
1193  0,
1194  0,
1195  0,
1196  0,
1197  0,
1198  0,
1199  0
1200  };
1201 
1202  static const double weight_1[25] = {
1203  0.999165,
1204  1,
1205  0.499996,
1206  0.166868,
1207  0.0414266,
1208  0.00831053,
1209  0.00137472,
1210  0.000198911,
1211  2.66302e-05,
1212  2.44563e-06,
1213  2.71737e-07,
1214  2.71737e-07,
1215  0,
1216  0,
1217  0,
1218  0,
1219  0,
1220  0,
1221  0,
1222  0,
1223  0,
1224  0,
1225  0,
1226  0,
1227  0
1228  };
1229 
1230  static const double weight_0[25] = {
1231  1,
1232  0,
1233  0,
1234  0,
1235  0,
1236  0,
1237  0,
1238  0,
1239  0,
1240  0,
1241  0,
1242  0,
1243  0,
1244  0,
1245  0,
1246  0,
1247  0,
1248  0,
1249  0,
1250  0,
1251  0,
1252  0,
1253  0,
1254  0,
1255  0
1256  };
1257 
1258  //WeightOOTPU_ = {0};
1259 
1260  const double* WeightPtr = 0;
1261 
1262  for(int iint = 0; iint<25; ++iint){
1263  if(iint ==0) WeightPtr = weight_0;
1264  if(iint ==1) WeightPtr = weight_1;
1265  if(iint ==2) WeightPtr = weight_2;
1266  if(iint ==3) WeightPtr = weight_3;
1267  if(iint ==4) WeightPtr = weight_4;
1268  if(iint ==5) WeightPtr = weight_5;
1269  if(iint ==6) WeightPtr = weight_6;
1270  if(iint ==7) WeightPtr = weight_7;
1271  if(iint ==8) WeightPtr = weight_8;
1272  if(iint ==9) WeightPtr = weight_9;
1273  if(iint ==10) WeightPtr = weight_10;
1274  if(iint ==11) WeightPtr = weight_11;
1275  if(iint ==12) WeightPtr = weight_12;
1276  if(iint ==13) WeightPtr = weight_13;
1277  if(iint ==14) WeightPtr = weight_14;
1278  if(iint ==15) WeightPtr = weight_15;
1279  if(iint ==16) WeightPtr = weight_16;
1280  if(iint ==17) WeightPtr = weight_17;
1281  if(iint ==18) WeightPtr = weight_18;
1282  if(iint ==19) WeightPtr = weight_19;
1283  if(iint ==20) WeightPtr = weight_20;
1284  if(iint ==21) WeightPtr = weight_21;
1285  if(iint ==22) WeightPtr = weight_22;
1286  if(iint ==23) WeightPtr = weight_23;
1287  if(iint ==24) WeightPtr = weight_24;
1288 
1289  for(int ibin = 0; ibin<25; ++ibin){
1290  WeightOOTPU_[iint][ibin] = *(WeightPtr+ibin);
1291  }
1292  }
1293 
1294  }
1295 
1296 
1297  double ITweight( int npv ){
1298  int bin = weights_->GetXaxis()->FindBin( npv );
1299  return weights_->GetBinContent( bin );
1300  }
1301 
1302  double ITweight3BX( float ave_int ){
1303  int bin = weights_->GetXaxis()->FindBin( ave_int );
1304  return weights_->GetBinContent( bin );
1305  }
1306 
1307  double weight( float n_int ){
1308  int bin = weights_->GetXaxis()->FindBin( n_int );
1309  return weights_->GetBinContent( bin );
1310  }
1311 
1312 
1313  double weight3D( int pv1, int pv2, int pv3 ) {
1314 
1315  using std::min;
1316 
1317  int npm1 = min(pv1,34);
1318  int np0 = min(pv2,34);
1319  int npp1 = min(pv3,34);
1320 
1321  return Weight3D_[npm1][np0][npp1];
1322 
1323  }
1324 
1325 
1326 
1327  double weightOOT( int npv_in_time, int npv_m50nsBX ){
1328 
1329  static const double Correct_Weights2011[25] = { // residual correction to match lumi spectrum
1330  5.30031,
1331  2.07903,
1332  1.40729,
1333  1.27687,
1334  1.0702,
1335  0.902094,
1336  0.902345,
1337  0.931449,
1338  0.78202,
1339  0.824686,
1340  0.837735,
1341  0.910261,
1342  1.01394,
1343  1.1599,
1344  1.12778,
1345  1.58423,
1346  1.78868,
1347  1.58296,
1348  2.3291,
1349  3.86641,
1350  0,
1351  0,
1352  0,
1353  0,
1354  0
1355  };
1356 
1357 
1358  if(FirstWarning_) {
1359 
1360  std::cout << " **** Warning: Out-of-time pileup reweighting appropriate only for PU_S3 **** " << std::endl;
1361  std::cout << " **** will be applied **** " << std::endl;
1362 
1363  FirstWarning_ = false;
1364 
1365  }
1366 
1367 
1368  // Note: for the "uncorrelated" out-of-time pileup, reweighting is only done on the 50ns
1369  // "late" bunch (BX=+1), since that is basically the only one that matters in terms of
1370  // energy deposition.
1371 
1372  if(npv_in_time < 0) {
1373  std::cerr << " no in-time beam crossing found\n! " ;
1374  std::cerr << " Returning event weight=0\n! ";
1375  return 0.;
1376  }
1377  if(npv_m50nsBX < 0) {
1378  std::cerr << " no out-of-time beam crossing found\n! " ;
1379  std::cerr << " Returning event weight=0\n! ";
1380  return 0.;
1381  }
1382 
1383  int bin = weights_->GetXaxis()->FindBin( npv_in_time );
1384 
1385  double inTimeWeight = weights_->GetBinContent( bin );
1386 
1387  double TotalWeight = 1.0;
1388 
1389 
1390  TotalWeight = inTimeWeight * WeightOOTPU_[bin-1][npv_m50nsBX] * Correct_Weights2011[bin-1];
1391 
1392 
1393  return TotalWeight;
1394 
1395  }
1396 
1397  protected:
1398 
1404  TFile *dataFile_;
1405  TH1F *weights_;
1406 
1407  //keep copies of normalized distributions:
1408  TH1F* MC_distr_;
1410 
1411  double WeightOOTPU_[25][25];
1412  double Weight3D_[50][50][50];
1413 
1415 
1416 
1417  };
1418 }
1419 
1420 
1421 
1422 #endif
LumiReWeighting(std::string generatedFile, std::string dataFile, std::string GenHistName, std::string DataHistName)
void weight3D_init(float ScaleFactor, std::string WeightOutputFile="")
int iint
T x() const
Cartesian x coordinate.
void weight3D_set(std::string WeightFileName)
LumiReWeighting(const std::vector< float > &MC_distr, const std::vector< float > &Lumi_distr)
T min(T a, T b)
Definition: MathUtil.h:58
base
Make Sure CMSSW is Setup ##.
double weightOOT(int npv_in_time, int npv_m50nsBX)
int k[5][pyjets_maxn]
bin
set the eta bin as selection string.
double weight3D(int pv1, int pv2, int pv3)
int factorial(int n)
factorial function