CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_10_patch1/src/PhysicsTools/Utilities/interface/LumiReweightingStandAlone.h

Go to the documentation of this file.
00001 #ifndef PhysicsTools_Utilities_interface_LumiReWeighting_h
00002 #define PhysicsTools_Utilities_interface_LumiReWeighting_h
00003 
00004 
00020 #include "TH1.h"
00021 #include "TH3.h"
00022 #include "TFile.h"
00023 #include "TRandom1.h"
00024 #include "TRandom2.h"
00025 #include "TRandom3.h"
00026 #include "TStopwatch.h"
00027 #include <string>
00028 #include <vector>
00029 #include <cmath>
00030 #include <algorithm>
00031 
00032 namespace reweight {
00033 
00034 
00035   // add a class to shift the mean of a poisson-like luminosity distribution by an arbitrary amount. 
00036   // Only valid for small (<1.5) shifts about the 2011 lumi distribution for now, because shifts are non-linear
00037   // Each PoissonMeanShifter does one shift, so defining multiples can give you an arbitrary collection
00038 
00039   class PoissonMeanShifter {
00040 
00041   public:
00042 
00043     PoissonMeanShifter() { };
00044 
00045     PoissonMeanShifter( float Shift ){
00046 
00047       // these are the polynomial or exponential coefficients for each bin of a 25-bin sequence that
00048       // convert the Distribution of the 2011 luminosity to something with a lower or higher peak luminosity.
00049       // The distributions aren't quite poisson because they model luminosity decreasing during a fill. This implies that
00050       // they do get wider as the mean increases, so the weights are not linear with increasing mean.
00051 
00052       static double p0_minus[20] = { 1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1. };
00053       static double p1_minus[20] = {
00054         -0.677786,
00055         -0.619614,
00056         -0.49465,
00057         -0.357963,
00058         -0.238359,
00059         -0.110002,
00060         0.0348629,
00061         0.191263,
00062         0.347648,
00063         0.516615,
00064         0.679646,
00065         0.836673,
00066         0.97764,
00067         1.135,
00068         1.29922,
00069         1.42467,
00070         1.55901,
00071         1.61762,
00072         1.67275,
00073         1.96008
00074       };
00075       static double p2_minus[20] = {
00076         0.526164,
00077         0.251816,
00078         0.11049,
00079         0.026917,
00080         -0.0464692,
00081         -0.087022,
00082         -0.0931581,
00083         -0.0714295,
00084         -0.0331772,
00085         0.0347473,
00086         0.108658,
00087         0.193048,
00088         0.272314,
00089         0.376357,
00090         0.4964,
00091         0.58854,
00092         0.684959,
00093         0.731063,
00094         0.760044,
00095         1.02386
00096       };
00097 
00098       static double p1_expoM[5] = {
00099         1.63363e-03,
00100         6.79290e-04,
00101         3.69900e-04,
00102         2.24349e-04,
00103         9.87156e-06
00104       };
00105 
00106       static double p2_expoM[5] = {
00107         2.64692,
00108         3.26585,
00109         3.53229,
00110         4.18035,
00111         5.64027
00112       };
00113 
00114 
00115       static double p0_plus[20] = { 1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1. };
00116       static double p1_plus[20] = {
00117         -0.739059,
00118         -0.594445,
00119         -0.477276,
00120         -0.359707,
00121         -0.233573,
00122         -0.103458,
00123         0.0373401,
00124         0.176571,
00125         0.337617,
00126         0.499074,
00127         0.675126,
00128         0.840522,
00129         1.00917,
00130         1.15847,
00131         1.23816,
00132         1.44271,
00133         1.52982,
00134         1.46385,
00135         1.5802,
00136         0.988689
00137       };
00138       static double p2_plus[20] = {
00139         0.208068,
00140         0.130033,
00141         0.0850356,
00142         0.0448344,
00143         0.000749832,
00144         -0.0331347,
00145         -0.0653281,
00146         -0.0746009,
00147         -0.0800667,
00148         -0.0527636,
00149         -0.00402649,
00150         0.103338,
00151         0.261261,
00152         0.491084,
00153         0.857966,
00154         1.19495,
00155         1.75071,
00156         2.65559,
00157         3.35433,
00158         5.48835
00159       };
00160 
00161       static double p1_expoP[5] = {
00162         1.42463e-01,
00163         4.18966e-02,
00164         1.12697e-01,
00165         1.66197e-01,
00166         1.50768e-01
00167       };
00168 
00169       static double p2_expoP[5] = {
00170         1.98758,
00171         2.27217,
00172         2.26799,
00173         2.38455,
00174         2.52428
00175       };
00176 
00177       // initialize weights based on desired Shift
00178 
00179 
00180 
00181       for (int ibin=0;ibin<20;ibin++) {
00182 
00183         if( Shift < .0) {
00184           Pweight_[ibin] = p0_minus[ibin] + p1_minus[ibin]*Shift + p2_minus[ibin]*Shift*Shift;
00185         }
00186         else {
00187           Pweight_[ibin] = p0_plus[ibin] + p1_plus[ibin]*Shift + p2_plus[ibin]*Shift*Shift;
00188         }
00189       }
00190 
00191       // last few bins fit better to an exponential...
00192 
00193       for (int ibin=20;ibin<25;ibin++) {
00194         if( Shift < 0.) {
00195           Pweight_[ibin] = p1_expoM[ibin-20]*exp(p2_expoM[ibin-20]*Shift);
00196         }
00197         else {
00198           Pweight_[ibin] = p1_expoP[ibin-20]*exp(p2_expoP[ibin-20]*Shift);
00199         }
00200       } 
00201 
00202     };
00203 
00204     double ShiftWeight( int ibin ) {
00205 
00206       if(ibin<25 && ibin>=0) { return Pweight_[ibin]; }
00207       else { return 0;}
00208 
00209     };
00210 
00211     double ShiftWeight( float pvnum ) {
00212 
00213       int ibin = int(pvnum);
00214 
00215       if(ibin<25 && ibin>=0) { return Pweight_[ibin]; }
00216       else { return 0;}
00217 
00218     };
00219 
00220   private:
00221 
00222     double Pweight_[25];
00223 
00224   };
00225 
00226 
00227   class LumiReWeighting {
00228   public:
00229 
00230     LumiReWeighting ( ) { } ;
00231 
00232     LumiReWeighting( std::string generatedFile,
00233                      std::string dataFile,
00234                      std::string GenHistName,
00235                      std::string DataHistName) :
00236       generatedFileName_( generatedFile), 
00237       dataFileName_     ( dataFile ), 
00238       GenHistName_      ( GenHistName ), 
00239       DataHistName_     ( DataHistName )
00240         {
00241           generatedFile_ = new TFile( generatedFileName_.c_str() ) ; //MC distribution
00242           dataFile_      = new TFile( dataFileName_.c_str() );       //Data distribution
00243 
00244           Data_distr_ = new TH1(  *(static_cast<TH1*>(dataFile_->Get( DataHistName_.c_str() )->Clone() )) );
00245           MC_distr_ = new TH1(  *(static_cast<TH1*>(generatedFile_->Get( GenHistName_.c_str() )->Clone() )) );
00246 
00247           // normalize both histograms first                                                                            
00248 
00249           Data_distr_->Scale( 1.0/ Data_distr_->Integral() );
00250           MC_distr_->Scale( 1.0/ MC_distr_->Integral() );
00251 
00252           weights_ = new TH1( *(Data_distr_)) ;
00253 
00254           // MC * data/MC = data, so the weights are data/MC:
00255 
00256           weights_->SetName("lumiWeights");
00257 
00258           TH1* den = new TH1(*(MC_distr_));
00259 
00260           weights_->Divide( den );  // so now the average weight should be 1.0
00261 
00262           std::cout << " Lumi/Pileup Reweighting: Computed Weights per In-Time Nint " << std::endl;
00263 
00264           int NBins = weights_->GetNbinsX();
00265 
00266           for(int ibin = 1; ibin<NBins+1; ++ibin){
00267             std::cout << "   " << ibin-1 << " " << weights_->GetBinContent(ibin) << std::endl;
00268           }
00269 
00270           weightOOT_init();
00271 
00272           FirstWarning_ = true;
00273 
00274         }
00275 
00276     
00277       LumiReWeighting( std::vector< float > MC_distr, std::vector< float > Lumi_distr){
00278         // no histograms for input: use vectors
00279   
00280         // now, make histograms out of them:
00281 
00282         // first, check they are the same size...
00283 
00284         if( MC_distr.size() != Lumi_distr.size() ){   
00285 
00286           std::cerr <<"ERROR: LumiReWeighting: input vectors have different sizes. Quitting... \n";
00287           return;
00288 
00289         }
00290 
00291         Int_t NBins = MC_distr.size();
00292 
00293         MC_distr_ = new TH1F("MC_distr","MC dist",NBins,-0.5, float(NBins)-0.5);
00294         Data_distr_ = new TH1F("Data_distr","Data dist",NBins,-0.5, float(NBins)-0.5);
00295 
00296         weights_ = new TH1F("luminumer","luminumer",NBins,-0.5, float(NBins)-0.5);
00297         TH1* den = new TH1F("lumidenom","lumidenom",NBins,-0.5, float(NBins)-0.5);
00298 
00299         for(int ibin = 1; ibin<NBins+1; ++ibin ) {
00300           weights_->SetBinContent(ibin, Lumi_distr[ibin-1]);
00301           Data_distr_->SetBinContent(ibin, Lumi_distr[ibin-1]);
00302           den->SetBinContent(ibin,MC_distr[ibin-1]);
00303           MC_distr_->SetBinContent(ibin,MC_distr[ibin-1]);
00304         }
00305 
00306         // check integrals, make sure things are normalized
00307 
00308         float deltaH = weights_->Integral();
00309         if(fabs(1.0 - deltaH) > 0.02 ) { //*OOPS*...
00310           weights_->Scale( 1.0/ deltaH );
00311           Data_distr_->Scale( 1.0/ deltaH );
00312         }
00313         float deltaMC = den->Integral();
00314         if(fabs(1.0 - deltaMC) > 0.02 ) {
00315           den->Scale(1.0/ deltaMC );
00316           MC_distr_->Scale(1.0/ deltaMC );
00317         }
00318 
00319         weights_->Divide( den );  // so now the average weight should be 1.0    
00320 
00321         std::cout << " Lumi/Pileup Reweighting: Computed Weights per In-Time Nint " << std::endl;
00322 
00323         for(int ibin = 1; ibin<NBins+1; ++ibin){
00324           std::cout << "   " << ibin-1 << " " << weights_->GetBinContent(ibin) << std::endl;
00325         }
00326 
00327         weightOOT_init();
00328 
00329         FirstWarning_ = true;
00330 
00331       }
00332 
00333       void weight3D_init( float ScaleFactor, std::string WeightOutputFile="") { 
00334 
00335         //create histogram to write output weights, save pain of generating them again...
00336 
00337         TH3D* WHist = new TH3D("WHist","3D weights",50,0.,50.,50,0.,50.,50,0.,50. );
00338         TH3D* DHist = new TH3D("DHist","3D weights",50,0.,50.,50,0.,50.,50,0.,50. );
00339         TH3D* MHist = new TH3D("MHist","3D weights",50,0.,50.,50,0.,50.,50,0.,50. );
00340 
00341 
00342         using std::min;
00343 
00344         if( MC_distr_->GetEntries() == 0 ) {
00345           std::cout << " MC and Data distributions are not initialized! You must call the LumiReWeighting constructor. " << std::endl;
00346         }
00347 
00348         // arrays for storing number of interactions
00349 
00350         double MC_ints[50][50][50];
00351         double Data_ints[50][50][50];
00352 
00353         for (int i=0; i<50; i++) {
00354           for(int j=0; j<50; j++) {
00355             for(int k=0; k<50; k++) {
00356               MC_ints[i][j][k] = 0.;
00357               Data_ints[i][j][k] = 0.;
00358             }
00359           }
00360         }
00361 
00362         double factorial[50];
00363         double PowerSer[50];
00364         double base = 1.;
00365 
00366         factorial[0] = 1.;
00367         PowerSer[0]=1.;
00368 
00369         for (int i = 1; i<50; ++i) {
00370           base = base*float(i);
00371           factorial[i] = base;
00372         }
00373 
00374 
00375         double x;
00376         double xweight;
00377         double probi, probj, probk;
00378         double Expval, mean;
00379         int xi;
00380 
00381         // Get entries for Data, MC, fill arrays:                                                                                                 
00382         int NMCbin = MC_distr_->GetNbinsX();
00383 
00384         for (int jbin=1;jbin<NMCbin+1;jbin++) {
00385           x =  MC_distr_->GetBinCenter(jbin);
00386           xweight = MC_distr_->GetBinContent(jbin); //use as weight for matrix         
00387 
00388           //for Summer 11, we have this int feature:                      
00389           xi = int(x);
00390 
00391           // Generate Poisson distribution for each value of the mean     
00392           mean = double(xi);
00393 
00394           if(mean<0.) {
00395             std::cout << "LumiReweighting:BadInputValue" << " Your histogram generates MC luminosity values less than zero!"
00396                                                   << " Please Check.  Terminating." << std::endl;
00397           }
00398 
00399 
00400           if(mean==0.){
00401             Expval = 1.;
00402           }
00403           else {
00404             Expval = exp(-1.*mean);
00405           }
00406 
00407           base = 1.;
00408 
00409           for (int i = 1; i<50; ++i) {
00410             base = base*mean;
00411             PowerSer[i] = base; // PowerSer is mean^i                        
00412           }
00413 
00414           // compute poisson probability for each Nvtx in weight matrix      
00415           for (int i=0; i<50; i++) {
00416             probi = PowerSer[i]/factorial[i]*Expval;
00417             for(int j=0; j<50; j++) {
00418               probj = PowerSer[j]/factorial[j]*Expval;
00419               for(int k=0; k<50; k++) {
00420                 probk = PowerSer[k]/factorial[k]*Expval;
00421                 // joint probability is product of event weights multiplied by weight of input distribution bin                                   
00422                 MC_ints[i][j][k] = MC_ints[i][j][k]+probi*probj*probk*xweight;
00423               }
00424             }
00425           }
00426 
00427         }
00428 
00429         int NDatabin = Data_distr_->GetNbinsX();
00430 
00431         for (int jbin=1;jbin<NDatabin+1;jbin++) {
00432           mean =  (Data_distr_->GetBinCenter(jbin))*ScaleFactor;
00433           xweight = Data_distr_->GetBinContent(jbin);
00434 
00435           // Generate poisson distribution for each value of the mean
00436           if(mean<0.) {
00437             std::cout << "LumiReweighting:BadInputValue" << " Your histogram generates MC luminosity values less than zero!"
00438                                                   << " Please Check.  Terminating." << std::endl;
00439           }
00440 
00441           if(mean==0.){
00442             Expval = 1.;
00443           }
00444           else {
00445             Expval = exp(-1.*mean);
00446           }
00447 
00448           base = 1.;
00449 
00450           for (int i = 1; i<50; ++i) {
00451             base = base*mean;
00452             PowerSer[i] = base;
00453           }
00454 
00455           // compute poisson probability for each Nvtx in weight matrix                                                                           
00456 
00457           for (int i=0; i<50; i++) {
00458             probi = PowerSer[i]/factorial[i]*Expval;
00459             for(int j=0; j<50; j++) {
00460               probj = PowerSer[j]/factorial[j]*Expval;
00461               for(int k=0; k<50; k++) {
00462                 probk = PowerSer[k]/factorial[k]*Expval;
00463                 // joint probability is product of event weights multiplied by weight of input distribution bin                                   
00464                 Data_ints[i][j][k] = Data_ints[i][j][k]+probi*probj*probk*xweight;
00465               }
00466             }
00467           }
00468 
00469         }
00470 
00471 
00472         for (int i=0; i<50; i++) {
00473           //if(i<5) std::cout << "i = " << i << std::endl;                       
00474           for(int j=0; j<50; j++) {
00475             for(int k=0; k<50; k++) {
00476               if( (MC_ints[i][j][k])>0.) {
00477                 Weight3D_[i][j][k]  =  Data_ints[i][j][k]/MC_ints[i][j][k];
00478               }
00479               else {
00480                 Weight3D_[i][j][k]  = 0.;
00481               }
00482               WHist->SetBinContent( i+1,j+1,k+1,Weight3D_[i][j][k] );
00483               DHist->SetBinContent( i+1,j+1,k+1,Data_ints[i][j][k] );
00484               MHist->SetBinContent( i+1,j+1,k+1,MC_ints[i][j][k] );
00485               //      if(i<5 && j<5 && k<5) std::cout << Weight3D_[i][j][k] << " " ;    
00486             }
00487             //      if(i<5 && j<5) std::cout << std::endl;        
00488           }
00489         }
00490 
00491         if(! WeightOutputFile.empty() ) {
00492           std::cout << " 3D Weight Matrix initialized! " << std::endl;
00493           std::cout << " Writing weights to file " << WeightOutputFile << " for re-use...  " << std::endl;
00494 
00495 
00496           TFile * outfile = new TFile(WeightOutputFile.c_str(),"RECREATE");
00497           WHist->Write();
00498           MHist->Write();
00499           DHist->Write();
00500           outfile->Write();
00501           outfile->Close();
00502           outfile->Delete();
00503         }
00504         
00505         return;
00506       }
00507 
00508 
00509       void weight3D_set( std::string WeightFileName ) { 
00510 
00511         TFile *infile = new TFile(WeightFileName.c_str());
00512         TH1F *WHist = (TH1F*)infile->Get("WHist");
00513 
00514         // Check if the histogram exists           
00515         if (!WHist) {
00516           std::cout << " Could not find the histogram WHist in the file "
00517                                                     << "in the file " << WeightFileName << "." << std::endl;
00518           return;
00519         }
00520 
00521         for (int i=0; i<50; i++) {  
00522           for(int j=0; j<50; j++) {
00523             for(int k=0; k<50; k++) {
00524               Weight3D_[i][j][k] = WHist->GetBinContent(i,j,k);
00525             }
00526           }
00527         }
00528 
00529         std::cout << " 3D Weight Matrix initialized! " << std::endl;
00530 
00531         return;
00532 
00533 
00534       }
00535 
00536 
00537 
00538       void weightOOT_init() {
00539 
00540         // The following are poisson distributions with different means, where the maximum
00541         // of the function has been normalized to weight 1.0
00542         // These are used to reweight the out-of-time pileup to match the in-time distribution.
00543         // The total event weight is the product of the in-time weight, the out-of-time weight,
00544         // and a residual correction to fix the distortions caused by the fact that the out-of-time
00545         // distribution is not flat.
00546 
00547         static double weight_24[25] = {
00548           0,
00549           0,
00550           0,
00551           0,
00552           2.46277e-06,
00553           2.95532e-05,
00554           0.000104668,
00555           0.000401431,
00556           0.00130034,
00557           0.00342202,
00558           0.00818132,
00559           0.0175534,
00560           0.035784,
00561           0.0650836,
00562           0.112232,
00563           0.178699,
00564           0.268934,
00565           0.380868,
00566           0.507505,
00567           0.640922,
00568           0.768551,
00569           0.877829,
00570           0.958624,
00571           0.99939,
00572           1
00573         };
00574 
00575         static double weight_23[25] = {
00576           0,
00577           1.20628e-06,
00578           1.20628e-06,
00579           2.41255e-06,
00580           1.20628e-05,
00581           6.39326e-05,
00582           0.000252112,
00583           0.000862487,
00584           0.00244995,
00585           0.00616527,
00586           0.0140821,
00587           0.0293342,
00588           0.0564501,
00589           0.100602,
00590           0.164479,
00591           0.252659,
00592           0.36268,
00593           0.491427,
00594           0.627979,
00595           0.75918,
00596           0.873185,
00597           0.957934,
00598           0.999381,
00599           1,
00600           0.957738
00601         };
00602 
00603         static double weight_22[25] = {
00604           0,
00605           0,
00606           0,
00607           5.88636e-06,
00608           3.0609e-05,
00609           0.000143627,
00610           0.000561558,
00611           0.00173059,
00612           0.00460078,
00613           0.0110616,
00614           0.0238974,
00615           0.0475406,
00616           0.0875077,
00617           0.148682,
00618           0.235752,
00619           0.343591,
00620           0.473146,
00621           0.611897,
00622           0.748345,
00623           0.865978,
00624           0.953199,
00625           0.997848,
00626           1,
00627           0.954245,
00628           0.873688
00629         };
00630 
00631         static double weight_21[25] = {
00632           0,
00633           0,
00634           1.15381e-06,
00635           8.07665e-06,
00636           7.1536e-05,
00637           0.000280375,
00638           0.00107189,
00639           0.00327104,
00640           0.00809396,
00641           0.0190978,
00642           0.0401894,
00643           0.0761028,
00644           0.13472,
00645           0.216315,
00646           0.324649,
00647           0.455125,
00648           0.598241,
00649           0.739215,
00650           0.861866,
00651           0.953911,
00652           0.998918,
00653           1,
00654           0.956683,
00655           0.872272,
00656           0.76399
00657         };
00658  
00659  
00660         static double weight_20[25] = {
00661           0,
00662           0,
00663           1.12532e-06,
00664           2.58822e-05,
00665           0.000145166,
00666           0.000633552,
00667           0.00215048,
00668           0.00592816,
00669           0.0145605,
00670           0.0328367,
00671           0.0652649,
00672           0.11893,
00673           0.19803,
00674           0.305525,
00675           0.436588,
00676           0.581566,
00677           0.727048,
00678           0.8534,
00679           0.949419,
00680           0.999785,
00681           1,
00682           0.953008,
00683           0.865689,
00684           0.753288,
00685           0.62765
00686         }; 
00687         static double weight_19[25] = {
00688           0,
00689           0,
00690           1.20714e-05,
00691           5.92596e-05,
00692           0.000364337,
00693           0.00124994,
00694           0.00403953,
00695           0.0108149,
00696           0.025824,
00697           0.0544969,
00698           0.103567,
00699           0.17936,
00700           0.283532,
00701           0.416091,
00702           0.562078,
00703           0.714714,
00704           0.846523,
00705           0.947875,
00706           1,
00707           0.999448,
00708           0.951404,
00709           0.859717,
00710           0.742319,
00711           0.613601,
00712           0.48552
00713         };
00714 
00715         static double weight_18[25] = {
00716           0,
00717           3.20101e-06,
00718           2.88091e-05,
00719           0.000164319,
00720           0.000719161,
00721           0.00250106,
00722           0.00773685,
00723           0.0197513,
00724           0.0443693,
00725           0.0885998,
00726           0.159891,
00727           0.262607,
00728           0.392327,
00729           0.543125,
00730           0.69924,
00731           0.837474,
00732           0.943486,
00733           0.998029,
00734           1,
00735           0.945937,
00736           0.851807,
00737           0.729309,
00738           0.596332,
00739           0.467818,
00740           0.350434
00741         };
00742 
00743  
00744         static double weight_17[25] = {
00745           1.03634e-06,
00746           7.25437e-06,
00747           4.97443e-05,
00748           0.000340956,
00749           0.00148715,
00750           0.00501485,
00751           0.0143067,
00752           0.034679,
00753           0.0742009,
00754           0.140287,
00755           0.238288,
00756           0.369416,
00757           0.521637,
00758           0.682368,
00759           0.828634,
00760           0.939655,
00761           1,
00762           0.996829,
00763           0.94062,
00764           0.841575,
00765           0.716664,
00766           0.582053,
00767           0.449595,
00768           0.331336,
00769           0.234332
00770         };
00771 
00772  
00773         static double weight_16[25] = {
00774           4.03159e-06,
00775           2.41895e-05,
00776           0.000141106,
00777           0.00081942,
00778           0.00314565,
00779           0.00990662,
00780           0.026293,
00781           0.0603881,
00782           0.120973,
00783           0.214532,
00784           0.343708,
00785           0.501141,
00786           0.665978,
00787           0.820107,
00788           0.938149,
00789           1,
00790           0.99941,
00791           0.940768,
00792           0.837813,
00793           0.703086,
00794           0.564023,
00795           0.42928,
00796           0.312515,
00797           0.216251,
00798           0.14561
00799         };
00800  
00801  
00802         static double weight_15[25] = {
00803           9.76084e-07,
00804           5.07564e-05,
00805           0.000303562,
00806           0.00174036,
00807           0.00617959,
00808           0.0188579,
00809           0.047465,
00810           0.101656,
00811           0.189492,
00812           0.315673,
00813           0.474383,
00814           0.646828,
00815           0.809462,
00816           0.934107,
00817           0.998874,
00818           1,
00819           0.936163,
00820           0.827473,
00821           0.689675,
00822           0.544384,
00823           0.40907,
00824           0.290648,
00825           0.198861,
00826           0.12951,
00827           0.0808051
00828         };
00829  
00830  
00831         static double weight_14[25] = {
00832           1.13288e-05,
00833           0.000124617,
00834           0.000753365,
00835           0.00345056,
00836           0.0123909,
00837           0.0352712,
00838           0.0825463,
00839           0.16413,
00840           0.287213,
00841           0.44615,
00842           0.625826,
00843           0.796365,
00844           0.930624,
00845           0.999958,
00846           1,
00847           0.934414,
00848           0.816456,
00849           0.672939,
00850           0.523033,
00851           0.386068,
00852           0.269824,
00853           0.180342,
00854           0.114669,
00855           0.0698288,
00856           0.0406496
00857         };
00858 
00859  
00860         static double weight_13[25] = {
00861           2.54296e-05,
00862           0.000261561,
00863           0.00167018,
00864           0.00748083,
00865           0.0241308,
00866           0.0636801,
00867           0.138222,
00868           0.255814,
00869           0.414275,
00870           0.600244,
00871           0.779958,
00872           0.92256,
00873           0.999155,
00874           1,
00875           0.927126,
00876           0.804504,
00877           0.651803,
00878           0.497534,
00879           0.35976,
00880           0.245834,
00881           0.160904,
00882           0.0991589,
00883           0.0585434,
00884           0.0332437,
00885           0.0180159
00886         };
00887 
00888         static double weight_12[25] = {
00889           5.85742e-05,
00890           0.000627706,
00891           0.00386677,
00892           0.0154068,
00893           0.0465892,
00894           0.111683,
00895           0.222487,
00896           0.381677,
00897           0.5719,
00898           0.765001,
00899           0.915916,
00900           1,
00901           0.999717,
00902           0.921443,
00903           0.791958,
00904           0.632344,
00905           0.475195,
00906           0.334982,
00907           0.223666,
00908           0.141781,
00909           0.0851538,
00910           0.048433,
00911           0.0263287,
00912           0.0133969,
00913           0.00696683
00914         };
00915 
00916  
00917         static double weight_11[25] = {
00918           0.00015238,
00919           0.00156064,
00920           0.00846044,
00921           0.0310939,
00922           0.0856225,
00923           0.187589,
00924           0.343579,
00925           0.541892,
00926           0.74224,
00927           0.909269,
00928           0.998711,
00929           1,
00930           0.916889,
00931           0.77485,
00932           0.608819,
00933           0.447016,
00934           0.307375,
00935           0.198444,
00936           0.121208,
00937           0.070222,
00938           0.0386492,
00939           0.0201108,
00940           0.0100922,
00941           0.00484937,
00942           0.00222458
00943         };
00944 
00945         static double weight_10[25] = {
00946           0.000393044,
00947           0.00367001,
00948           0.0179474,
00949           0.060389,
00950           0.151477,
00951           0.302077,
00952           0.503113,
00953           0.720373,
00954           0.899568,
00955           1,
00956           0.997739,
00957           0.909409,
00958           0.75728,
00959           0.582031,
00960           0.415322,
00961           0.277663,
00962           0.174147,
00963           0.102154,
00964           0.0566719,
00965           0.0298642,
00966           0.0147751,
00967           0.00710995,
00968           0.00319628,
00969           0.00140601,
00970           0.000568796
00971         };
00972 
00973  
00974         static double weight_9[25] = {
00975           0.00093396,
00976           0.00854448,
00977           0.0380306,
00978           0.113181,
00979           0.256614,
00980           0.460894,
00981           0.690242,
00982           0.888781,
00983           1,
00984           0.998756,
00985           0.899872,
00986           0.735642,
00987           0.552532,
00988           0.382726,
00989           0.246114,
00990           0.147497,
00991           0.0825541,
00992           0.0441199,
00993           0.0218157,
00994           0.0103578,
00995           0.00462959,
00996           0.0019142,
00997           0.000771598,
00998           0.000295893,
00999           0.000111529
01000         };
01001 
01002  
01003         static double weight_8[25] = {
01004           0.00240233,
01005           0.0192688,
01006           0.0768653,
01007           0.205008,
01008           0.410958,
01009           0.65758,
01010           0.875657,
01011           0.999886,
01012           1,
01013           0.889476,
01014           0.711446,
01015           0.517781,
01016           0.345774,
01017           0.212028,
01018           0.121208,
01019           0.0644629,
01020           0.0324928,
01021           0.0152492,
01022           0.00673527,
01023           0.0028547,
01024           0.00117213,
01025           0.000440177,
01026           0.000168471,
01027           5.80689e-05,
01028           1.93563e-05
01029         };
01030 
01031         static double weight_7[25] = {
01032           0.00617233,
01033           0.0428714,
01034           0.150018,
01035           0.350317,
01036           0.612535,
01037           0.856525,
01038           0.999923,
01039           1,
01040           0.87544,
01041           0.679383,
01042           0.478345,
01043           0.303378,
01044           0.176923,
01045           0.0950103,
01046           0.0476253,
01047           0.0222211,
01048           0.00972738,
01049           0.00392962,
01050           0.0015258,
01051           0.000559168,
01052           0.000183928,
01053           6.77983e-05,
01054           1.67818e-05,
01055           7.38398e-06,
01056           6.71271e-07
01057         };
01058  
01059         static double weight_6[25] = {
01060           0.0154465,
01061           0.0923472,
01062           0.277322,
01063           0.55552,
01064           0.833099,
01065           0.999035,
01066           1,
01067           0.855183,
01068           0.641976,
01069           0.428277,
01070           0.256804,
01071           0.139798,
01072           0.0700072,
01073           0.0321586,
01074           0.0137971,
01075           0.00544756,
01076           0.00202316,
01077           0.000766228,
01078           0.000259348,
01079           8.45836e-05,
01080           1.80362e-05,
01081           8.70713e-06,
01082           3.73163e-06,
01083           6.21938e-07,
01084           0
01085         };
01086  
01087  
01088         static double weight_5[25] = {
01089           0.0382845,
01090           0.191122,
01091           0.478782,
01092           0.797314,
01093           1,
01094           0.997148,
01095           0.831144,
01096           0.59461,
01097           0.371293,
01098           0.205903,
01099           0.103102,
01100           0.0471424,
01101           0.0194997,
01102           0.00749415,
01103           0.00273709,
01104           0.000879189,
01105           0.000286049,
01106           0.000102364,
01107           1.70606e-05,
01108           3.98081e-06,
01109           2.27475e-06,
01110           0,
01111           0,
01112           0,
01113           0
01114         };
01115  
01116  
01117         static double weight_4[25] = {
01118           0.0941305,
01119           0.373824,
01120           0.750094,
01121           1,
01122           0.997698,
01123           0.800956,
01124           0.532306,
01125           0.304597,
01126           0.152207,
01127           0.0676275,
01128           0.0270646,
01129           0.00975365,
01130           0.00326077,
01131           0.00101071,
01132           0.000301781,
01133           7.41664e-05,
01134           1.58563e-05,
01135           3.58045e-06,
01136           1.02299e-06,
01137           0,
01138           5.11493e-07,
01139           0,
01140           0,
01141           0,
01142           0
01143         };
01144  
01145  
01146         static double weight_3[25] = {
01147           0.222714,
01148           0.667015,
01149           1,
01150           0.999208,
01151           0.750609,
01152           0.449854,
01153           0.224968,
01154           0.0965185,
01155           0.0361225,
01156           0.012084,
01157           0.00359618,
01158           0.000977166,
01159           0.000239269,
01160           6.29422e-05,
01161           1.16064e-05,
01162           1.78559e-06,
01163           0,
01164           4.46398e-07,
01165           0,
01166           0,
01167           0,
01168           0,
01169           0,
01170           0,
01171           0
01172         };
01173  
01174         static double weight_2[25] = {
01175           0.499541,
01176           0.999607,
01177           1,
01178           0.666607,
01179           0.333301,
01180           0.13279,
01181           0.0441871,
01182           0.0127455,
01183           0.00318434,
01184           0.00071752,
01185           0.000132204,
01186           2.69578e-05,
01187           5.16999e-06,
01188           2.21571e-06,
01189           0,
01190           0,
01191           0,
01192           0,
01193           0,
01194           0,
01195           0,
01196           0,
01197           0,
01198           0,
01199           0
01200         };
01201  
01202         static double weight_1[25] = {
01203           0.999165,
01204           1,
01205           0.499996,
01206           0.166868,
01207           0.0414266,
01208           0.00831053,
01209           0.00137472,
01210           0.000198911,
01211           2.66302e-05,
01212           2.44563e-06,
01213           2.71737e-07,
01214           2.71737e-07,
01215           0,
01216           0,
01217           0,
01218           0,
01219           0,
01220           0,
01221           0,
01222           0,
01223           0,
01224           0,
01225           0,
01226           0,
01227           0
01228         };
01229  
01230         static double weight_0[25] = {
01231           1,
01232           0,
01233           0,
01234           0,
01235           0,
01236           0,
01237           0,
01238           0,
01239           0,
01240           0,
01241           0,
01242           0,
01243           0,
01244           0,
01245           0,
01246           0,
01247           0,
01248           0,
01249           0,
01250           0,
01251           0,
01252           0,
01253           0,
01254           0,
01255           0
01256         };
01257 
01258         //WeightOOTPU_ = {0};
01259 
01260         double* WeightPtr = 0;
01261 
01262         for(int iint = 0; iint<25; ++iint){
01263           if(iint ==0) WeightPtr = weight_0;
01264           if(iint ==1) WeightPtr = weight_1;
01265           if(iint ==2) WeightPtr = weight_2;
01266           if(iint ==3) WeightPtr = weight_3;
01267           if(iint ==4) WeightPtr = weight_4;
01268           if(iint ==5) WeightPtr = weight_5;
01269           if(iint ==6) WeightPtr = weight_6;
01270           if(iint ==7) WeightPtr = weight_7;
01271           if(iint ==8) WeightPtr = weight_8;
01272           if(iint ==9) WeightPtr = weight_9;
01273           if(iint ==10) WeightPtr = weight_10;
01274           if(iint ==11) WeightPtr = weight_11;
01275           if(iint ==12) WeightPtr = weight_12;
01276           if(iint ==13) WeightPtr = weight_13;
01277           if(iint ==14) WeightPtr = weight_14;
01278           if(iint ==15) WeightPtr = weight_15;
01279           if(iint ==16) WeightPtr = weight_16;
01280           if(iint ==17) WeightPtr = weight_17;
01281           if(iint ==18) WeightPtr = weight_18;
01282           if(iint ==19) WeightPtr = weight_19;
01283           if(iint ==20) WeightPtr = weight_20;
01284           if(iint ==21) WeightPtr = weight_21;
01285           if(iint ==22) WeightPtr = weight_22;
01286           if(iint ==23) WeightPtr = weight_23;
01287           if(iint ==24) WeightPtr = weight_24;
01288 
01289           for(int ibin = 0; ibin<25; ++ibin){
01290             WeightOOTPU_[iint][ibin] = *(WeightPtr+ibin);
01291           }
01292         }
01293 
01294       }
01295 
01296 
01297       double ITweight( int npv ){
01298         int bin = weights_->GetXaxis()->FindBin( npv );
01299         return weights_->GetBinContent( bin );
01300       }
01301 
01302       double ITweight3BX( float ave_int ){
01303         int bin = weights_->GetXaxis()->FindBin( ave_int );
01304         return weights_->GetBinContent( bin );
01305       }
01306 
01307       double weight( float n_int ){
01308         int bin = weights_->GetXaxis()->FindBin( n_int );
01309         return weights_->GetBinContent( bin );
01310       }
01311 
01312 
01313       double weight3D( int pv1, int pv2, int pv3 ) {
01314 
01315         using std::min;
01316 
01317         int npm1 = min(pv1,34);
01318         int np0 = min(pv2,34);
01319         int npp1 = min(pv3,34);
01320 
01321         return Weight3D_[npm1][np0][npp1];
01322 
01323       }
01324 
01325 
01326 
01327       double weightOOT( int npv_in_time, int npv_m50nsBX ){
01328 
01329         static double Correct_Weights2011[25] = { // residual correction to match lumi spectrum
01330           5.30031,
01331           2.07903,
01332           1.40729,
01333           1.27687,
01334           1.0702,
01335           0.902094,
01336           0.902345,
01337           0.931449,
01338           0.78202,
01339           0.824686,
01340           0.837735,
01341           0.910261,
01342           1.01394,
01343           1.1599,
01344           1.12778,
01345           1.58423,
01346           1.78868,
01347           1.58296,
01348           2.3291,
01349           3.86641,
01350           0,
01351           0,
01352           0,
01353           0,
01354           0
01355         };                        
01356 
01357 
01358         if(FirstWarning_) {
01359 
01360           std::cout << " **** Warning: Out-of-time pileup reweighting appropriate only for PU_S3 **** " << std::endl;
01361           std::cout << " ****                          will be applied                           **** " << std::endl;
01362 
01363           FirstWarning_ = false;
01364 
01365         }
01366 
01367 
01368         // Note: for the "uncorrelated" out-of-time pileup, reweighting is only done on the 50ns
01369         // "late" bunch (BX=+1), since that is basically the only one that matters in terms of 
01370         // energy deposition.  
01371 
01372         if(npv_in_time < 0) {
01373           std::cerr << " no in-time beam crossing found\n! " ;
01374           std::cerr << " Returning event weight=0\n! ";
01375           return 0.;
01376         }
01377         if(npv_m50nsBX < 0) {
01378           std::cerr << " no out-of-time beam crossing found\n! " ;
01379           std::cerr << " Returning event weight=0\n! ";
01380           return 0.;
01381         }
01382 
01383         int bin = weights_->GetXaxis()->FindBin( npv_in_time );
01384 
01385         double inTimeWeight = weights_->GetBinContent( bin );
01386 
01387         double TotalWeight = 1.0;
01388 
01389 
01390         TotalWeight = inTimeWeight * WeightOOTPU_[bin-1][npv_m50nsBX] * Correct_Weights2011[bin-1];
01391 
01392 
01393         return TotalWeight;
01394  
01395       }
01396 
01397   protected:
01398 
01399       std::string generatedFileName_;
01400       std::string dataFileName_;
01401       std::string GenHistName_;
01402       std::string DataHistName_;
01403       TFile *generatedFile_;
01404       TFile *dataFile_;
01405       TH1  *weights_;
01406 
01407       //keep copies of normalized distributions:                                                                                  
01408       TH1*      MC_distr_;
01409       TH1*      Data_distr_;
01410 
01411       double WeightOOTPU_[25][25];
01412       double Weight3D_[50][50][50];
01413 
01414       bool FirstWarning_;
01415 
01416 
01417   };
01418 }
01419 
01420 
01421 
01422 #endif