1 #ifndef PhysicsTools_Utilities_interface_LumiReWeighting_h
2 #define PhysicsTools_Utilities_interface_LumiReWeighting_h
26 #include "TStopwatch.h"
39 class PoissonMeanShifter {
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] = {
75 static const double p2_minus[20] = {
98 static const double p1_expoM[5] = {
106 static const double p2_expoM[5] = {
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] = {
138 static const double p2_plus[20] = {
161 static const double p1_expoP[5] = {
169 static const double p2_expoP[5] = {
181 for (
int ibin=0;ibin<20;ibin++) {
184 Pweight_[ibin] = p0_minus[ibin] + p1_minus[ibin]*Shift + p2_minus[ibin]*Shift*Shift;
187 Pweight_[ibin] = p0_plus[ibin] + p1_plus[ibin]*Shift + p2_plus[ibin]*Shift*Shift;
193 for (
int ibin=20;ibin<25;ibin++) {
195 Pweight_[ibin] = p1_expoM[ibin-20]*
exp(p2_expoM[ibin-20]*Shift);
198 Pweight_[ibin] = p1_expoP[ibin-20]*
exp(p2_expoP[ibin-20]*Shift);
206 if(ibin<25 && ibin>=0) {
return Pweight_[ibin]; }
213 int ibin = int(pvnum);
215 if(ibin<25 && ibin>=0) {
return Pweight_[ibin]; }
249 Data_distr_->Scale( 1.0/ Data_distr_->Integral() );
250 MC_distr_->Scale( 1.0/ MC_distr_->Integral() );
252 weights_ =
new TH1F( *(Data_distr_)) ;
258 TH1F* den =
new TH1F(*(MC_distr_));
262 std::cout <<
" Lumi/Pileup Reweighting: Computed Weights per In-Time Nint " << std::endl;
266 for(
int ibin = 1; ibin<NBins+1; ++ibin){
277 LumiReWeighting(
const std::vector< float >& MC_distr,
const std::vector< float >& Lumi_distr){
284 if( MC_distr.size() != Lumi_distr.size() ){
286 std::cerr <<
"ERROR: LumiReWeighting: input vectors have different sizes. Quitting... \n";
291 Int_t
NBins = MC_distr.size();
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);
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);
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]);
308 float deltaH =
weights_->Integral();
309 if(fabs(1.0 - deltaH) > 0.02 ) {
313 float deltaMC = den->Integral();
314 if(fabs(1.0 - deltaMC) > 0.02 ) {
315 den->Scale(1.0/ deltaMC );
321 std::cout <<
" Lumi/Pileup Reweighting: Computed Weights per In-Time Nint " << std::endl;
323 for(
int ibin = 1; ibin<NBins+1; ++ibin){
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. );
345 std::cout <<
" MC and Data distributions are not initialized! You must call the LumiReWeighting constructor. " << std::endl;
350 double MC_ints[50][50][50];
351 double Data_ints[50][50][50];
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.;
369 for (
int i = 1;
i<50; ++
i) {
370 base = base*float(
i);
377 double probi, probj, probk;
384 for (
int jbin=1;jbin<NMCbin+1;jbin++) {
386 xweight =
MC_distr_->GetBinContent(jbin);
395 std::cout <<
"LumiReweighting:BadInputValue" <<
" Your histogram generates MC luminosity values less than zero!"
396 <<
" Please Check. Terminating." << std::endl;
404 Expval =
exp(-1.*mean);
409 for (
int i = 1;
i<50; ++
i) {
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;
422 MC_ints[
i][
j][
k] = MC_ints[
i][
j][
k]+probi*probj*probk*xweight;
431 for (
int jbin=1;jbin<NDatabin+1;jbin++) {
432 mean = (
Data_distr_->GetBinCenter(jbin))*ScaleFactor;
437 std::cout <<
"LumiReweighting:BadInputValue" <<
" Your histogram generates MC luminosity values less than zero!"
438 <<
" Please Check. Terminating." << std::endl;
445 Expval =
exp(-1.*mean);
450 for (
int i = 1;
i<50; ++
i) {
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;
464 Data_ints[
i][
j][
k] = Data_ints[
i][
j][
k]+probi*probj*probk*xweight;
472 for (
int i=0;
i<50;
i++) {
474 for(
int j=0;
j<50;
j++) {
475 for(
int k=0;
k<50;
k++) {
476 if( (MC_ints[
i][
j][
k])>0.) {
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] );
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;
496 TFile *
outfile =
new TFile(WeightOutputFile.c_str(),
"RECREATE");
511 TFile *
infile =
new TFile(WeightFileName.c_str());
512 TH1F *WHist = (TH1F*)infile->Get(
"WHist");
516 std::cout <<
" Could not find the histogram WHist in the file "
517 <<
"in the file " << WeightFileName <<
"." << std::endl;
521 for (
int i=0;
i<50;
i++) {
522 for(
int j=0;
j<50;
j++) {
523 for(
int k=0;
k<50;
k++) {
529 std::cout <<
" 3D Weight Matrix initialized! " << std::endl;
547 static const double weight_24[25] = {
575 static const double weight_23[25] = {
603 static const double weight_22[25] = {
631 static const double weight_21[25] = {
660 static const double weight_20[25] = {
687 static const double weight_19[25] = {
715 static const double weight_18[25] = {
744 static const double weight_17[25] = {
773 static const double weight_16[25] = {
802 static const double weight_15[25] = {
831 static const double weight_14[25] = {
860 static const double weight_13[25] = {
888 static const double weight_12[25] = {
917 static const double weight_11[25] = {
945 static const double weight_10[25] = {
974 static const double weight_9[25] = {
1003 static const double weight_8[25] = {
1031 static const double weight_7[25] = {
1059 static const double weight_6[25] = {
1088 static const double weight_5[25] = {
1117 static const double weight_4[25] = {
1146 static const double weight_3[25] = {
1174 static const double weight_2[25] = {
1202 static const double weight_1[25] = {
1230 static const double weight_0[25] = {
1260 const double* WeightPtr = 0;
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;
1289 for(
int ibin = 0; ibin<25; ++ibin){
1299 return weights_->GetBinContent( bin );
1303 int bin =
weights_->GetXaxis()->FindBin( ave_int );
1304 return weights_->GetBinContent( bin );
1309 return weights_->GetBinContent( bin );
1317 int npm1 =
min(pv1,34);
1318 int np0 =
min(pv2,34);
1319 int npp1 =
min(pv3,34);
1329 static const double Correct_Weights2011[25] = {
1360 std::cout <<
" **** Warning: Out-of-time pileup reweighting appropriate only for PU_S3 **** " << std::endl;
1361 std::cout <<
" **** will be applied **** " << std::endl;
1372 if(npv_in_time < 0) {
1373 std::cerr <<
" no in-time beam crossing found\n! " ;
1374 std::cerr <<
" Returning event weight=0\n! ";
1377 if(npv_m50nsBX < 0) {
1378 std::cerr <<
" no out-of-time beam crossing found\n! " ;
1379 std::cerr <<
" Returning event weight=0\n! ";
1383 int bin =
weights_->GetXaxis()->FindBin( npv_in_time );
1385 double inTimeWeight =
weights_->GetBinContent( bin );
1387 double TotalWeight = 1.0;
1390 TotalWeight = inTimeWeight *
WeightOOTPU_[bin-1][npv_m50nsBX] * Correct_Weights2011[bin-1];
double WeightOOTPU_[25][25]
LumiReWeighting(std::string generatedFile, std::string dataFile, std::string GenHistName, std::string DataHistName)
void weight3D_init(float ScaleFactor, std::string WeightOutputFile="")
double weight(float n_int)
T x() const
Cartesian x coordinate.
double ShiftWeight(int ibin)
void weight3D_set(std::string WeightFileName)
LumiReWeighting(const std::vector< float > &MC_distr, const std::vector< float > &Lumi_distr)
std::string DataHistName_
double ShiftWeight(float pvnum)
double weightOOT(int npv_in_time, int npv_m50nsBX)
std::string dataFileName_
double Weight3D_[50][50][50]
double ITweight3BX(float ave_int)
double weight3D(int pv1, int pv2, int pv3)
PoissonMeanShifter(float Shift)
int factorial(int n)
factorial function
std::string generatedFileName_