int main(int argc, char** argv)
{
  // Set style options
  setTDRStyle();
  gStyle->SetPadTickX(1);
  gStyle->SetPadTickY(1);
  gStyle->SetOptTitle(0); 
  gStyle->SetOptStat(1110); 
  gStyle->SetOptFit(1); 


  float totDAevts = 0;
  float DAevtsHIHI = 0;
  
  // Set fitting options
  TVirtualFitter::SetDefaultFitter("Fumili2");
  

  /// Fitting functions
  /////////////// vs R9                                                                              
  //    TF1* R9_low_2011 = new TF1("R9_low_2011", "[0] + [1]*x + [2]*pow(x,2) + [3]*pow(x,3)", 0.7, 0.94);
  //    R9_low_2011->SetParameters(1.04602750038440662e-01, -5.12399137504689572e-01, 7.26103911422236403e-01, -3.14041397400686317e-01);
  //    TF1* R9_hig_2011 = new TF1("R9_hig_2011", "[0] + [1]*x + [2]*pow(x,2) ", 0.94, 1.02);
  //    R9_hig_2011->SetParameters(-2.65392390285653734e+00, 5.32070916148806727e+00, -2.65288628795334347e+00);
  

  //    TF1* R9_low_2012 = new TF1("R9_low_2012", "[0] + [1]*x + [2]*pow(x,2) + [3]*pow(x,3)", 0.7, 0.94);
  //    R9_low_2012->SetParameters(6.53048217081556359e-01, -2.41796796111481704e+00, 2.90336305058258182e+00, -1.13417753246979647e+00);
  
  // //    TF1* R9_low_2012 = new TF1("R9_low_2012", "[0] ", 0., 0.94);
  // //    R9_low_2012->SetParameter(0, 3.05197369770460669e-03);
  
  //    TF1* R9_hig_2012 = new TF1("R9_hig_2012", "[0] + [1]*x + [2]*pow(x,2) ", 0.94, 1.02);
  //    R9_hig_2012->SetParameters(-2.30712976989725455e-01, 2.92312432577749526e-01, -4.51976365389429174e-02);
  
  // //   ////////////// vs Et
  TF1* Et_highR9_2011 = new TF1("Et_highR9_2011", "[0] * (1 - exp(-[1] * x) ) +[2] ",0., 100.);
  Et_highR9_2011->SetParameters(1.59984924630326465e-02, 4.14188316002253587e-02, -6.49126732859059939e-03);
  TF1* Et_lowR9_2011 = new TF1("Et_lowR9_2011", "[0] * (1 - exp(-[1] * x) ) +[2] ",0., 100.);
  Et_lowR9_2011->SetParameters(2.20638739628473586e-02, 6.98744642383235803e-02, -1.85601207959524978e-02);
  
  TF1* Et_highR9_2012 = new TF1("Et_highR9_2012", "[0] * (1 - exp(-[1] * x) ) +[2] ",0., 100.);
  Et_highR9_2012->SetParameters(1.76747992064786620e-02, 3.73408739026924591e-02, -7.82929065282905561e-03);
  TF1* Et_lowR9_2012 = new TF1("Et_lowR9_2012", "[0] * (1 - exp(-[1] * x) ) +[2] ",0., 100.);
  Et_lowR9_2012->SetParameters(1.97205016874162468e-02, 4.41133183909690751e-02, -1.58915655671104904e-02);


  //MC 52X
  //stimate senza PU
  //   TF1* Et_highR9_2012 = new TF1("Et_highR9_2012", "[0] * (1 - exp(-[1] * x) ) +[2] ",0., 100.);
  //   Et_highR9_2012->SetParameters(1.71373322900473177e-02, 1.55744254105185699e-02,  -2.11477940336727904e-03);
  //   TF1* Et_lowR9_2012 = new TF1("Et_lowR9_2012", "[0] * (1 - exp(-[1] * x) ) +[2] ",0., 100.);
  //   Et_lowR9_2012->SetParameters(2.63075655765558566e-02, 4.57322846169432515e-02, -2.09413281975727485e-02);

  //stimate con PU
  //   TF1* Et_highR9_2012 = new TF1("Et_highR9_2012", "[0] * (1 - exp(-[1] * x) ) +[2] ",0., 100.);
  //   Et_highR9_2012->SetParameters(1.71373322900473177e-02, 1.55744254105185699e-02,  -2.11477940336727904e-03);
  //   TF1* Et_lowR9_2012 = new TF1("Et_lowR9_2012", "[0] * (1 - exp(-[1] * x) ) +[2] ",0., 100.);
  //   Et_lowR9_2012->SetParameters(1.69896128648113487e-02, 1.20797862827948261e-02, -5.86630884749932049e-03);
  
  
  // Settings for corrections
  //  bool UsePhotonRegression = false;
  bool UsePhotonRegression = true;
  
  //     bool correctEt = true;
  bool correctEt = false;
  
  //  bool useShCorr = false;
  bool useShCorr = true;
  
  //-----------------
  // Input parameters
  
  std::cout << "\n*******************************************************************************************************************" << std::endl;
  std::cout << "arcg: " << argc << std::endl;
  char* EBEE = argv[1];
  char* LOWHIGH = argv[2];
  char* ENE = argv[3];
  int PU = atoi(argv[4]);
  int evtsPerPoint = atoi(argv[5]);
  std::string string_year = argv[6];
  int year = atoi(argv[6]);
  std::string doVsEach = argv[7];
  char* SortVariable = argv[8];

  std::cout << "EBEE:         " << EBEE         << std::endl;
  std::cout << "LOWHIGH:      " << LOWHIGH       << std::endl;
  std::cout << "ENE:          " << ENE           << std::endl;
  std::cout << "PU:           " << PU            << std::endl;
  std::cout << "evtsPerPoint: " << evtsPerPoint  << std::endl;
  std::cout << "year:      " << year       << std::endl;
  std::cout << "doVsEach:      " << doVsEach       << std::endl;
  std::cout << "SortVariable:      " << SortVariable       << std::endl;
  

  TPileupReweighting* puReweighting;

  //   //2012 prompt           
  if(year == 2012) puReweighting =
    new TPileupReweighting("/afs/cern.ch/work/a/amartell/public/weights/PUweights_DYJetsToLL_Summer12_53X_ShSkim_ABC_TrueNumInteractions.root","hweights");
  //     new TPileupReweighting("/afs/cern.ch/work/a/amartell/public/weights/PUweights_DYJetsToLL_Summer12_ABC_TrueNumInteractions.root","pileup");
  //     new TPileupReweighting("/afs/cern.ch/work/a/amartell/public/weights/PUweights_DYJetsToLL_Summer12_Prompt_TrueNumInteractions.root","hweights");
  
  //   //2011                                                                                                                                          
  if(year == 2011) puReweighting =
    new TPileupReweighting("/afs/cern.ch/work/a/amartell/public/weights/PUweights_2011_DYJetsToLL_Fall2011_TrueNumInteractions.root", "hweights");
  
  
  std::string R9MOD = std::string(LOWHIGH);
  std::string ENERGY = std::string(ENE);
  std::string SortV = std::string(SortVariable);

  //-------------------
  // Define in/outfiles
  std::string folderName;
  if(PU == 0)
  	folderName = std::string(EBEE)+"_"+std::string(LOWHIGH)+"_"+std::string(ENE)+"_noPU";
  if(PU == 1)
        folderName = std::string(EBEE)+"_"+std::string(LOWHIGH)+"_"+std::string(ENE);
  //if( strcmp(LOWHIGH,"")==0 ) folderName = std::string(EBEE);
  //if( strcmp(EBEE,"")==0 ) folderName = std::string(LOWHIGH);
  
  
  // Get trees
  std::cout << std::endl;
  std::string nameNtuples = "simpleNtupleEoverP/SimpleNtupleEoverP";
  std::string nameNtuplesMC = "simpleNtupleEoverP/SimpleNtupleEoverP";
  //   if(year == 2011) nameNtuples = "ntu";  
  //   if(year == 2011) nameNtuplesMC = "ntu";  
  
  //  if(year == 2012) nameNtuplesMC = "simpleNtupleEoverPSh/SimpleNtupleEoverP";
  TChain* ntu_MC = new TChain(nameNtuplesMC.c_str());
  TChain* ntu_DA = new TChain(nameNtuples.c_str());
  


  if(year == 2012){
    ntu_MC->Add("/tmp/amartell/DYToEE_M-20_CT10_TuneZ2star_v2_8TeV-powheg-pythia6_Summer12_DR53X-PU_S10_START53_V7A-v1_AODSIM.root");
    ntu_MC->Add("/tmp/amartell/DYJetsToLL_M-50_TuneZ2Star_8TeV-madgraph-tarball_Summer12_DR53X-PU_S10_START53_V7A-v1_AODSIM_2.root");
    ntu_DA->Add("/tmp/amartell/DoubleElectronAB_13Jul2012.root");
    ntu_DA->Add("/tmp/amartell/DoubleElectron_C_Prompt.root");

//     ntu_MC->Add("/tmp/amartell/WJetsToLNu_START53_V7A.root");
//     ntu_DA->Add("/tmp/amartell/Single_AB_Prompt.root");
//     ntu_DA->Add("/tmp/amartell/Single_C_Prompt.root");
  }

  if(year == 2011){                                                                                                                      
    ntu_DA->Add("/tmp/amartell/DoubleElectron-RUN2011AB.root");          
    ntu_MC->Add("/tmp/amartell/DYJetsToLL_Fall11_START44_V9B.root");
  }                                                                                                                                      

  std::cout << "     REFERENCE: " << std::setw(8) << ntu_MC->GetEntries() << " entries" << std::endl;
  std::cout << "     DATA: " << std::setw(8) << ntu_DA->GetEntries() << " entries" << std::endl;
  
  if(ntu_DA->GetEntries() == 0 || ntu_MC->GetEntries() == 0 )
  {
    std::cout << "Error: At least one file is empty" << std::endl; 
    return -1;
  }

  
  std::vector<int> run_DA, time_DA, Z_DA, PV_DA;
  std::vector<int> run_MC, time_MC, Z_MC, PV_MC;
  std::vector<float> scE_DA, scEt_reg_DA,scE_reg_DA, R9_DA, P_DA, EoP_DA, Et_DA, scEta_DA, elePhi_DA, ES_DA, isEB_DA, e3x3_DA,e5x5_DA, scERaw_DA;
  std::vector<float> scE_MC, scEt_reg_MC, scE_reg_MC, R9_MC, P_MC, EoP_MC, Et_MC, scEta_MC, elePhi_MC, ES_MC, isEB_MC, puRe, e3x3_MC, e5x5_MC, scERaw_MC;
  std::vector<float> cloneSortVar_DA;
  std::vector<float> cloneSortVar_MC;
  std::vector<float> scEtRaw_DA, scEt_3x3_DA, scEt_5x5_DA;
  std::vector<float> scEtRaw_MC, scEt_3x3_MC, scEt_5x5_MC;
  std::vector<float> ele1ele2_scM_DA, ele1ele2_scM_MC;
  std::vector<int> charge_DA, charge_MC;
  // Set branch addresses
  int isZ,runId,timeStamp,nVtx;
  float npu;
  
  ntu_DA->SetBranchStatus("*",0);
  ntu_DA->SetBranchStatus("runId",1);            ntu_DA->SetBranchAddress("runId", &runId);  
  ntu_DA->SetBranchStatus("timeStampHigh",1);    ntu_DA->SetBranchAddress("timeStampHigh", &timeStamp);  
  ntu_DA->SetBranchStatus("isZ",1);              ntu_DA->SetBranchAddress("isZ", &isZ);
  ntu_DA->SetBranchStatus("PV_n",1);             ntu_DA->SetBranchAddress("PV_n",&nVtx);

 
  ntu_MC->SetBranchStatus("*",0);
  ntu_MC->SetBranchStatus("PUit_TrueNumInteractions", 1);      ntu_MC->SetBranchAddress("PUit_TrueNumInteractions", &npu);
  ntu_MC->SetBranchStatus("runId",1);                          ntu_MC->SetBranchAddress("runId", &runId);  
  ntu_MC->SetBranchStatus("timeStampHigh",1);                  ntu_MC->SetBranchAddress("timeStampHigh", &timeStamp);  
  ntu_MC->SetBranchStatus("isZ",1);                            ntu_MC->SetBranchAddress("isZ", &isZ);
  ntu_MC->SetBranchStatus("PV_n",1);                           ntu_MC->SetBranchAddress("PV_n",&nVtx);


  
  // Electron data
  float scEne1, scEneReg1, EoP1, scEt1, scEta1, elePhi1, ES1, P1, scERaw1, e3x31, e5x51, ele1ele2_scM;
  float scEne2, scEneReg2, EoP2, scEt2, scEta2, elePhi2, ES2, P2, scERaw2, e3x32, e5x52;
  //  float R9_pho1, R9_pho2;
  int isEB1,isEB2;
  int ele1_charge, ele2_charge; 

  ntu_DA->SetBranchStatus("ele1_scE", 1);       ntu_DA->SetBranchAddress("ele1_scE", &scEne1);
  ntu_DA->SetBranchStatus("ele1_scEt", 1);      ntu_DA->SetBranchAddress("ele1_scEt", &scEt1);
  ntu_DA->SetBranchStatus("ele1_scEta", 1);     ntu_DA->SetBranchAddress("ele1_scEta", &scEta1);
  ntu_DA->SetBranchStatus("ele1ele2_scM", 1);   ntu_DA->SetBranchAddress("ele1ele2_scM", &ele1ele2_scM);
  if(!UsePhotonRegression)  {
    ntu_DA->SetBranchStatus("ele1_scE_regression", 1);      ntu_DA->SetBranchAddress("ele1_scE_regression", &scEneReg1);
    ntu_DA->SetBranchStatus("ele2_scE_regression",1);       ntu_DA->SetBranchAddress("ele2_scE_regression", &scEneReg2);
  }
  else {
    ntu_DA->SetBranchStatus("ele1_scE_regression_PhotonTuned", 1);    ntu_DA->SetBranchAddress("ele1_scE_regression_PhotonTuned", &scEneReg1);
    ntu_DA->SetBranchStatus("ele2_scE_regression_PhotonTuned",1);     ntu_DA->SetBranchAddress("ele2_scE_regression_PhotonTuned", &scEneReg2);
  }
  ntu_DA->SetBranchStatus("ele1_scERaw",1);      ntu_DA->SetBranchAddress("ele1_scERaw",&scERaw1);
  ntu_DA->SetBranchStatus("ele1_e3x3",1);        ntu_DA->SetBranchAddress("ele1_e3x3", &e3x31);
  ntu_DA->SetBranchStatus("ele1_e5x5",1);        ntu_DA->SetBranchAddress("ele1_e5x5", &e5x51);
  ntu_DA->SetBranchStatus("ele1_EOverP",1);      ntu_DA->SetBranchAddress("ele1_EOverP",&EoP1);
  ntu_DA->SetBranchStatus("ele1_isEB",1);        ntu_DA->SetBranchAddress("ele1_isEB",&isEB1);
  ntu_DA->SetBranchStatus("ele1_es", 1);         ntu_DA->SetBranchAddress("ele1_es", &ES1);
  ntu_DA->SetBranchStatus("ele1_tkP",1);         ntu_DA->SetBranchAddress("ele1_tkP", &P1);
  ntu_DA->SetBranchStatus("ele1_charge",1);      ntu_DA->SetBranchAddress("ele1_charge", &ele1_charge);
  ntu_DA->SetBranchStatus("ele2_scE", 1);        ntu_DA->SetBranchAddress("ele2_scE", &scEne2);
  ntu_DA->SetBranchStatus("ele2_scEta", 1);      ntu_DA->SetBranchAddress("ele2_scEta", &scEta2);
  ntu_DA->SetBranchStatus("ele2_scEt", 1);       ntu_DA->SetBranchAddress("ele2_scEt", &scEt2);
  ntu_DA->SetBranchStatus("ele2_e3x3",1);        ntu_DA->SetBranchAddress("ele2_e3x3", &e3x32);
  ntu_DA->SetBranchStatus("ele2_e5x5",1);        ntu_DA->SetBranchAddress("ele2_e5x5", &e5x52);

  ntu_DA->SetBranchStatus("ele2_scERaw",1);      ntu_DA->SetBranchAddress("ele2_scERaw",&scERaw2);
  ntu_DA->SetBranchStatus("ele2_EOverP",1);      ntu_DA->SetBranchAddress("ele2_EOverP",&EoP2);
  ntu_DA->SetBranchStatus("ele2_isEB",1);        ntu_DA->SetBranchAddress("ele2_isEB",&isEB2);
  ntu_DA->SetBranchStatus("ele2_es", 1);         ntu_DA->SetBranchAddress("ele2_es", &ES2);
  ntu_DA->SetBranchStatus("ele2_tkP",1);         ntu_DA->SetBranchAddress("ele2_tkP", &P2);
  ntu_DA->SetBranchStatus("ele2_charge",1);      ntu_DA->SetBranchAddress("ele2_charge", &ele2_charge);

  ntu_DA->SetBranchStatus("ele1_phi", 1);   ntu_DA->SetBranchAddress("ele1_phi", &elePhi1);
  ntu_DA->SetBranchStatus("ele2_phi", 1);   ntu_DA->SetBranchAddress("ele2_phi", &elePhi2);
  
  ///////////////////////
  ntu_MC->SetBranchStatus("ele1_scE", 1);       ntu_MC->SetBranchAddress("ele1_scE", &scEne1);
  ntu_MC->SetBranchStatus("ele1_scEt", 1);      ntu_MC->SetBranchAddress("ele1_scEt", &scEt1);
  ntu_MC->SetBranchStatus("ele1_scEta", 1);     ntu_MC->SetBranchAddress("ele1_scEta", &scEta1);
  ntu_MC->SetBranchStatus("ele1ele2_scM", 1);   ntu_MC->SetBranchAddress("ele1ele2_scM", &ele1ele2_scM);
  if(!UsePhotonRegression)  {
    ntu_MC->SetBranchStatus("ele1_scE_regression", 1);      ntu_MC->SetBranchAddress("ele1_scE_regression", &scEneReg1);
    ntu_MC->SetBranchStatus("ele2_scE_regression",1);       ntu_MC->SetBranchAddress("ele2_scE_regression", &scEneReg2);
  }
  else {
    ntu_MC->SetBranchStatus("ele1_scE_regression_PhotonTuned", 1);    ntu_MC->SetBranchAddress("ele1_scE_regression_PhotonTuned", &scEneReg1);
    ntu_MC->SetBranchStatus("ele2_scE_regression_PhotonTuned",1);     ntu_MC->SetBranchAddress("ele2_scE_regression_PhotonTuned", &scEneReg2);
  }
  ntu_MC->SetBranchStatus("ele1_scERaw",1);      ntu_MC->SetBranchAddress("ele1_scERaw",&scERaw1);
  ntu_MC->SetBranchStatus("ele1_e3x3",1);        ntu_MC->SetBranchAddress("ele1_e3x3", &e3x31);
  ntu_MC->SetBranchStatus("ele1_e5x5",1);        ntu_MC->SetBranchAddress("ele1_e5x5", &e5x51);
  ntu_MC->SetBranchStatus("ele1_EOverP",1);      ntu_MC->SetBranchAddress("ele1_EOverP",&EoP1);
  ntu_MC->SetBranchStatus("ele1_isEB",1);        ntu_MC->SetBranchAddress("ele1_isEB",&isEB1);
  ntu_MC->SetBranchStatus("ele1_es", 1);         ntu_MC->SetBranchAddress("ele1_es", &ES1);
  ntu_MC->SetBranchStatus("ele1_tkP",1);         ntu_MC->SetBranchAddress("ele1_tkP", &P1);
  ntu_MC->SetBranchStatus("ele1_charge",1);      ntu_MC->SetBranchAddress("ele1_charge", &ele1_charge);
  ntu_MC->SetBranchStatus("ele2_scE", 1);        ntu_MC->SetBranchAddress("ele2_scE", &scEne2);
  ntu_MC->SetBranchStatus("ele2_scEta", 1);      ntu_MC->SetBranchAddress("ele2_scEta", &scEta2);
  ntu_MC->SetBranchStatus("ele2_scEt", 1);       ntu_MC->SetBranchAddress("ele2_scEt", &scEt2);
  ntu_MC->SetBranchStatus("ele2_e3x3",1);        ntu_MC->SetBranchAddress("ele2_e3x3", &e3x32);
  ntu_MC->SetBranchStatus("ele2_e5x5",1);        ntu_MC->SetBranchAddress("ele2_e5x5", &e5x52);

  ntu_MC->SetBranchStatus("ele2_scERaw",1);      ntu_MC->SetBranchAddress("ele2_scERaw",&scERaw2);
  ntu_MC->SetBranchStatus("ele2_EOverP",1);      ntu_MC->SetBranchAddress("ele2_EOverP",&EoP2);
  ntu_MC->SetBranchStatus("ele2_isEB",1);        ntu_MC->SetBranchAddress("ele2_isEB",&isEB2);
  ntu_MC->SetBranchStatus("ele2_es", 1);         ntu_MC->SetBranchAddress("ele2_es", &ES2);
  ntu_MC->SetBranchStatus("ele2_tkP",1);         ntu_MC->SetBranchAddress("ele2_tkP", &P2);
  ntu_MC->SetBranchStatus("ele2_charge",1);      ntu_MC->SetBranchAddress("ele2_charge", &ele2_charge);

  ntu_MC->SetBranchStatus("ele1_phi", 1);   ntu_MC->SetBranchAddress("ele1_phi", &elePhi1);
  ntu_MC->SetBranchStatus("ele2_phi", 1);   ntu_MC->SetBranchAddress("ele2_phi", &elePhi2);
  //////////////////////
  
  for(int ientry = 0; ientry < ntu_DA -> GetEntries(); ientry++)
  {
  	if( (ientry%100000 == 0) ) std::cout << "reading DATA entry " << ientry << "\r" << std::flush;
        ntu_DA->GetEntry(ientry);  

	if(isZ == 0) continue;

	++totDAevts;
	if(e3x31/scERaw1 > 0.94 && e3x32/scERaw2 > 0.94) ++DAevtsHIHI;

        run_DA.push_back(runId);

	float corrEtR9_1 = 1.;
	float corrEtR9_2 = 1.;

	if(correctEt == true){
 	  if(year == 2012){
   	    if(e3x31/scERaw1 < 0.94 ) corrEtR9_1 = corrEtR9_1 / (1. + Et_lowR9_2012->Eval(scEneReg1));
   	    if(e3x32/scERaw2 < 0.94 ) corrEtR9_2 = corrEtR9_2 / (1. + Et_lowR9_2012->Eval(scEneReg2));
	    if(e3x31/scERaw1 >= 0.94 ) corrEtR9_1 = corrEtR9_1 / (1. + Et_highR9_2012->Eval(scEneReg1));
 	    if(e3x32/scERaw2 >= 0.94 ) corrEtR9_2 = corrEtR9_2 / (1. + Et_highR9_2012->Eval(scEneReg2));
 	  }
 	  if(year == 2011){
 	    if(e3x31/scERaw1 < 0.94 ) corrEtR9_1 = corrEtR9_1 / (1. + Et_lowR9_2011->Eval(scEneReg1));
   	    if(e3x32/scERaw2 < 0.94 ) corrEtR9_2 = corrEtR9_2 / (1. + Et_lowR9_2011->Eval(scEneReg2));
	    if(e3x31/scERaw1 >= 0.94 ) corrEtR9_1 = corrEtR9_1 / (1. + Et_highR9_2011->Eval(scEneReg1));
 	    if(e3x32/scERaw2 >= 0.94 ) corrEtR9_2 = corrEtR9_2 / (1. + Et_highR9_2011->Eval(scEneReg2));
 	  }
	}

	if(useShCorr == true){
	  corrEtR9_1 = corrEtR9_1 * GetShervingCorrections(scEta1, e3x31/scERaw1, runId);
	  corrEtR9_2 = corrEtR9_2 * GetShervingCorrections(scEta2, e3x32/scERaw2, runId);
	}

	charge_DA.push_back(ele1_charge);
	charge_DA.push_back(ele2_charge);

        time_DA.push_back(timeStamp);
        Z_DA.push_back(isZ);
	PV_DA.push_back(nVtx);    

	scE_DA.push_back(scEne1);
	scE_DA.push_back(scEne2);

	scE_reg_DA.push_back(scEneReg1*corrEtR9_1);
	scE_reg_DA.push_back(scEneReg2*corrEtR9_2);

	float Rt1 = sin(2*atan(exp(-scEta1)) );
	float Rt2 = sin(2*atan(exp(-scEta2)) );

	scEt_reg_DA.push_back(scEneReg1*Rt1*corrEtR9_1);
 	scEt_reg_DA.push_back(scEneReg2*Rt2*corrEtR9_2);

	R9_DA.push_back(e3x31/scERaw1);
	R9_DA.push_back(e3x32/scERaw2);

	P_DA.push_back(P1);
	P_DA.push_back(P2);
	EoP_DA.push_back(EoP1);
	EoP_DA.push_back(EoP2);
	Et_DA.push_back(scEt1);
        Et_DA.push_back(scEt2);
	scEta_DA.push_back(scEta1);
	scEta_DA.push_back(scEta2);
        ES_DA.push_back(ES1);
	ES_DA.push_back(ES2);
	isEB_DA.push_back(isEB1);
	isEB_DA.push_back(isEB2);

	e3x3_DA.push_back(e3x31);
	e3x3_DA.push_back(e3x32);
	e5x5_DA.push_back(e5x51);
	e5x5_DA.push_back(e5x52);

	scERaw_DA.push_back(scERaw1);
	scERaw_DA.push_back(scERaw2);
	scEtRaw_DA.push_back(scERaw1*scEt1/scEne1);
	scEtRaw_DA.push_back(scERaw2*scEt2/scEne2);

	scEt_3x3_DA.push_back(e3x31*scEt1/scEne1);
	scEt_3x3_DA.push_back(e3x32*scEt2/scEne2);
	scEt_5x5_DA.push_back(e5x51*scEt1/scEne1);
	scEt_5x5_DA.push_back(e5x52*scEt2/scEne2);

	if(SortV == "Et"){
	  cloneSortVar_DA.push_back(scEneReg1*Rt1*corrEtR9_1);
	  cloneSortVar_DA.push_back(scEneReg2*Rt2*corrEtR9_2);
	}
	if(SortV == "R9"){
	  cloneSortVar_DA.push_back(e3x31/scERaw1);
	  cloneSortVar_DA.push_back(e3x32/scERaw2);
       	}

  }
  
  std::cout << std::endl;
  float ww = 1.;
  for(int ientry = 0; ientry < ntu_MC -> GetEntries(); ientry++)
  {
  	if( (ientry%100000 == 0) ) std::cout << "reading MC entry " << ientry << "\r" << std::flush;
        ntu_MC->GetEntry(ientry);  
  
	if(isZ == 0) continue;
	//	if(nVtx > 20) continue;

	float R9_ele1 = e3x31/scERaw1;
	if(year == 2012 && isEB1 == 1) R9_ele1 = 0.0010 + 1.0045 * e3x31/scERaw1;
	if(year == 2012 && isEB1 == 0) R9_ele1 = -0.0007 + 1.0086 * e3x31/scERaw1;
	if(year == 2011) R9_ele1 = 1.0035 * e3x31/scERaw1;
	float R9_ele2 = e3x32/scERaw2;
	if(year == 2012 && isEB2 == 1) R9_ele2 = 0.0010 + 1.0045 * e3x32/scERaw2;
	if(year == 2012 && isEB2 == 0) R9_ele2 = -0.0007 + 1.0086 * e3x32/scERaw2;
	if(year == 2011) R9_ele2 = 1.0035 * e3x32/scERaw2;

	float energySmearing1 = gRandom->Gaus(1.,0.0075);
	float energySmearing2 = gRandom->Gaus(1.,0.0075);

	energySmearing1 = gRandom->Gaus(1., GetSmearings(scEta1, R9_ele1, year, isEB1));
	energySmearing2 = gRandom->Gaus(1., GetSmearings(scEta2, R9_ele2, year, isEB2));

	charge_MC.push_back(ele1_charge);
	charge_MC.push_back(ele2_charge);

	ww = puReweighting->GetWeight((int)npu);
        puRe.push_back(ww);

        run_MC.push_back(runId);
        time_MC.push_back(timeStamp);
        Z_MC.push_back(isZ);
	PV_MC.push_back(nVtx);    

	scE_MC.push_back(scEne1);
	scE_MC.push_back(scEne2);

	scE_reg_MC.push_back(scEneReg1 * energySmearing1);
	scE_reg_MC.push_back(scEneReg2 * energySmearing2);

	scEt_reg_MC.push_back(scEneReg1/scEne1*scEt1*energySmearing1);
 	scEt_reg_MC.push_back(scEneReg2/scEne2*scEt2*energySmearing2);

	P_MC.push_back(P1);
	P_MC.push_back(P2);
	EoP_MC.push_back(EoP1);
	EoP_MC.push_back(EoP2);

	Et_MC.push_back(scEt1);
        Et_MC.push_back(scEt2);
	scEta_MC.push_back(scEta1);
	scEta_MC.push_back(scEta2);
        ES_MC.push_back(ES1);
	ES_MC.push_back(ES2);
	isEB_MC.push_back(isEB1);
	isEB_MC.push_back(isEB2);

	e5x5_MC.push_back(e5x51);
	e5x5_MC.push_back(e5x52);

	scERaw_MC.push_back(scERaw1);
	scERaw_MC.push_back(scERaw2);

	R9_MC.push_back(R9_ele1);
	R9_MC.push_back(R9_ele2);

	scEtRaw_MC.push_back(scERaw1*scEt1/scEne1);
	scEtRaw_MC.push_back(scERaw2*scEt2/scEne2);

	scEt_5x5_MC.push_back(e5x51*scEt1/scEne1);
	scEt_5x5_MC.push_back(e5x52*scEt2/scEne2);

 	e3x3_MC.push_back(R9_ele1*scERaw1);
 	e3x3_MC.push_back(R9_ele2*scERaw2);
 	scEt_3x3_MC.push_back(R9_ele1*scERaw1*scEt1/scEne1);
 	scEt_3x3_MC.push_back(R9_ele2*scERaw2*scEt2/scEne2);

	if(SortV == "Et"){
	  cloneSortVar_MC.push_back(scEneReg1/scEne1*scEt1*energySmearing1);
	  cloneSortVar_MC.push_back(scEneReg2/scEne2*scEt2*energySmearing2);
	}
	if(SortV == "R9"){
	  cloneSortVar_MC.push_back(R9_ele1);
	  cloneSortVar_MC.push_back(R9_ele2);
       	}
  }
  

//   std::cout << "   totDAevts = " << totDAevts << std::endl;
//   std::cout << "   DAevtsHIHI = " << DAevtsHIHI << std::endl;
  //  return 200;


  // Loop and sort events
  std::cout << std::endl;
  std::cout << "***** Sort events and define bins *****" << std::endl;
  
  int nEntries = cloneSortVar_DA.size();
  int nSavePts = 0;
  std::vector<bool> isSavedEntries(nEntries);
  std::vector<SorterLC> sortedEntries;
  
  for(int ientry = 0; ientry < nEntries; ++ientry)
  {
    isSavedEntries.at(ientry) = false;

    // save only what is needed for the analysis!!!
    if(strcmp(EBEE,"EE")==0 && (fabs(scEta_DA.at(ientry)) < 1.566 || fabs(scEta_DA.at(ientry)) > 2.5 )) continue; 
    if(strcmp(EBEE,"EB")==0 && (fabs(scEta_DA.at(ientry)) > 1.4442 )) continue;

    if(std::string(EBEE) == "BC" && (fabs(scEta_DA.at(ientry)) > 1. )) continue;
    if(std::string(EBEE) == "B4" && (fabs(scEta_DA.at(ientry)) < 1. || fabs(scEta_DA.at(ientry)) > 1.4442)) continue;
    if(std::string(EBEE) == "EL" && (fabs(scEta_DA.at(ientry)) < 1.566 || fabs(scEta_DA.at(ientry)) > 2. )) continue;
    if(std::string(EBEE) == "EH" && (fabs(scEta_DA.at(ientry)) > 2.5 )) continue;

    //    if(R9_DA.at(ientry) < 0.7) continue;
    if(scEt_reg_DA.at(ientry) <  25.) continue;

    //to be fixed -> categories as in Hgg
    if(std::string(LOWHIGH) == "LOW" && R9_DA.at(ientry) >= 0.94) continue;
    if(std::string(LOWHIGH) == "HIGH" && R9_DA.at(ientry) < 0.94 ) continue;

    isSavedEntries.at(ientry) = true;

    SorterLC dummy;
    dummy.laserCorr = cloneSortVar_DA.at(ientry);
    dummy.entry = ientry;
    sortedEntries.push_back(dummy);
    nSavePts++;   
  }

  std::cout << " Effective entries = " << nSavePts << std::endl;
  std::cout << " Effective entries sortedEntries.size()= " << sortedEntries.size() << std::endl;

  std::sort(sortedEntries.begin(),sortedEntries.end(),SorterLC());
  std::cout << "Sorting variable vs " << SortV << std::endl;
  std::cout << "DATA sorted in " << EBEE << " - " << nSavePts << " events" << std::endl;
  
  
   std::map<int,int> antiMap;
   for(unsigned int iSaved = 0; iSaved < sortedEntries.size(); ++iSaved)
   antiMap[sortedEntries.at(iSaved).entry] = iSaved; 
   
  // bins with evtsPerPoint events per bin
   std::cout << " nSavePts = " << nSavePts << std::endl;
   std::cout << " evtsPerPoint = " << evtsPerPoint << std::endl;
  int nBins = std::max(1, int(nSavePts/evtsPerPoint));
   std::cout << " nBins = " << nBins << std::endl;
  int nBinPts = int( nSavePts/nBins );
   std::cout << " nBinPts = " << nBinPts << std::endl;
  int nBinTempPts = 0;

  std::cout << "nBins = " << nBins << std::endl;
  
  std::vector<int> binEntryMax;
  binEntryMax.push_back(0);
  for(int iSaved = 0; iSaved < nSavePts; ++iSaved)
  {
    ++nBinTempPts;
    
    if( nBinTempPts == nBinPts )
    {
      binEntryMax.push_back( iSaved );      
      nBinTempPts = 0;
    }
  }
  binEntryMax.at(nBins) = nSavePts;
  
  std::cout << " fine : nBins = " << nBins << std::endl;
 
  TVirtualFitter::SetDefaultFitter("Fumili2");
  
  // histogram definition
  
  TH1F** h_EoP_DA = new TH1F*[nBins];
  TH1F** h_EoP_MC = new TH1F*[nBins];
  TH1F** h_SortV = new TH1F*[nBins];
  TH1F** h_SortV_MC = new TH1F*[nBins];

  TH1F* h_Et_allDA = new TH1F("h_Et_allDA", "", 5000, 0., 1000.);
  TH1F* h_Et_allMC = new TH1F("h_Et_allMC", "", 5000, 0., 1000.);
  TH1F* h_R9_allDA = new TH1F("h_R9_allDA", "", 2200, 0., 1.1);
  TH1F* h_R9_allMC = new TH1F("h_R9_allMC", "", 2200, 0., 1.1);

  TH1F* h_scE_DA = new TH1F("h_scE_DA", "", 4000, 0., 200.);
  TH1F* h_scReg_DA = new TH1F("h_scReg_DA", "", 4000, 0., 200.);
  TH1F* h_scRaw_DA = new TH1F("h_scRaw_DA", "", 4000, 0., 200.);

  TH1F* h_Vtx_DA = new TH1F("h_Vtx_DA", "", 200, 0., 200.);
  TH1F* h_Vtx_MC = new TH1F("h_Vtx_MC", "", 200, 0., 200.);

  TH2F* h_R9_vsET_MC = new TH2F("h_R9_vsET_MC", "", 200, 0., 200., 220, 0., 1.1);
  TH2F* h_R9_vsET_DA = new TH2F("h_R9_vsET_DA", "", 200, 0., 200., 220, 0., 1.1);
  TProfile* p_R9_vsET_MC = new TProfile("p_R9_vsET_MC", "", 200, 0., 200.);
  TProfile* p_R9_vsET_DA = new TProfile("p_R9_vsET_DA", "", 200, 0., 200.);


  h_Et_allDA->Sumw2();
  h_Et_allMC->Sumw2();
  h_R9_allDA->Sumw2();
  h_R9_allMC->Sumw2();
  h_scE_DA->Sumw2();
  h_scReg_DA->Sumw2();
  h_scRaw_DA->Sumw2();
  h_Vtx_DA->Sumw2();
  h_Vtx_MC->Sumw2();
  h_R9_vsET_MC->Sumw2();
  h_R9_vsET_DA->Sumw2();
  p_R9_vsET_MC->Sumw2();
  p_R9_vsET_DA->Sumw2();

  h_Et_allDA->SetLineColor(kRed+2);
  h_R9_allDA->SetLineColor(kRed+2);
  h_Vtx_DA->SetLineColor(kRed+2);

  h_Et_allMC->SetLineColor(kGreen+2);
  h_R9_allMC->SetLineColor(kGreen+2);
  h_Vtx_MC->SetLineColor(kGreen+2);

  std::vector<float> EtBinEdge;
  EtBinEdge.clear();
  std::vector<float> xNorm_single;


  for(int i = 0; i < nBins; ++i)
  {
    char histoName[80];    
      sprintf(histoName, "EoP_DA_%d", i);
      if(SortV == "Et") h_EoP_DA[i] = new TH1F(histoName, histoName, 600, 0., 3.);
      if(SortV == "R9") h_EoP_DA[i] = new TH1F(histoName, histoName, 400, 0., 2.);
      h_EoP_DA[i]->SetFillColor(kRed+2);
      h_EoP_DA[i]->SetFillStyle(3004);
      h_EoP_DA[i]->SetMarkerStyle(7);
      h_EoP_DA[i]->SetMarkerColor(kRed+2); 
      h_EoP_DA[i]->SetLineColor(kRed+2); 
    
      sprintf(histoName, "EoP_MC_%d", i);
      if(SortV == "Et") h_EoP_MC[i] = new TH1F(histoName, histoName, 600, 0., 3.);
      if(SortV == "R9") h_EoP_MC[i] = new TH1F(histoName, histoName, 400, 0., 2.);
      h_EoP_MC[i] -> SetFillColor(kGreen+2);
      h_EoP_MC[i] -> SetFillStyle(3004);
      h_EoP_MC[i] -> SetMarkerStyle(7);
      h_EoP_MC[i] -> SetMarkerColor(kGreen+2);
      h_EoP_MC[i] -> SetLineColor(kGreen+2);
      
      sprintf(histoName, (SortV+"_%d").c_str(), i);
      if(SortV == "Et") h_SortV[i] = new TH1F(histoName, histoName, 5000, 0., 1000.);
      if(SortV == "R9") h_SortV[i] = new TH1F(histoName, histoName, 2200, 0, 1.1);
      h_SortV[i]->SetLineColor(kRed+2);

      sprintf(histoName, (SortV+"_MC_%d").c_str(), i);
      if(SortV == "Et") h_SortV_MC[i] = new TH1F(histoName, histoName, 5000, 0., 1000.);
      if(SortV == "R9") h_SortV_MC[i] = new TH1F(histoName, histoName, 2200, 0, 1.1);
      h_SortV_MC[i]->SetLineColor(kGreen+2);
      
      h_EoP_DA[i]->Sumw2();
      h_EoP_MC[i]->Sumw2();
      h_SortV[i]->Sumw2();
      h_SortV_MC[i]->Sumw2();
  }

  std::cout << " cloneSortVar_DA.size() = " << cloneSortVar_DA.size() << std::endl;
  std::cout << " cloneSortVar_MC.size() = " << cloneSortVar_MC.size() << std::endl;


  std::vector<float> x;
  std::vector<float> ex;
  std::vector<float> y;
  std::vector<float> ey;
  
  TGraphErrors* finalGraph = new TGraphErrors();
  
  // function definition
  TF1** f_EoP = new TF1*[nBins];
 
  // loop on the saved and sorted events
  std::cout << std::endl;
  std::cout << "***** Fill and fit histograms *****" << std::endl;

  int DAEntries = cloneSortVar_DA.size();
  for(unsigned int ientry = 0; ientry < DAEntries; ++ientry){
    if( (ientry%100000 == 0) ) std::cout << "reading entry " << ientry << std::endl;
      
    if( isSavedEntries.at(ientry) == false) continue;
     
    int iSaved = antiMap[ientry];
    int bin = -1;
    
    for(bin = 0; bin < nBins; ++bin)
      if( iSaved >= binEntryMax.at(bin) && iSaved < binEntryMax.at(bin+1) )
	break;

    h_EoP_DA[bin]->Fill((scE_reg_DA.at(ientry)-ES_DA.at(ientry))/(P_DA.at(ientry)-ES_DA.at(ientry)));
    h_SortV[bin]->Fill(cloneSortVar_DA.at(ientry) );
    h_Et_allDA->Fill(scEt_reg_DA.at(ientry) );
    h_R9_allDA->Fill(R9_DA.at(ientry));
    
    h_Vtx_DA->Fill(PV_DA.at(int(ientry/2)) );
    h_scE_DA->Fill(scE_DA.at(ientry) );
    h_scReg_DA->Fill(scE_reg_DA.at(ientry));
    h_scRaw_DA->Fill(scERaw_DA.at(ientry));

    h_R9_vsET_DA->Fill(scEt_reg_DA.at(ientry), R9_DA.at(ientry));
    p_R9_vsET_DA->Fill(scEt_reg_DA.at(ientry), R9_DA.at(ientry));
  }
  
  std::cout << " dati fillati " << std::endl;
  std::cout << std::endl;
  
  for(int bin = 0; bin < nBins; bin++)
  {
    std::cout << "h_SortV[bin]->GetEntries() =  " << h_SortV[bin]->GetEntries() << std::endl;
    std::cout << "h_EoP_DA[bin]->GetEntries() =  " << h_EoP_DA[bin]->GetEntries() << std::endl;
    for(int i = 1; i < h_SortV[bin]->GetNbinsX()+1; i++)
      {
	if(h_SortV[bin]->GetBinContent(i) > 0) {
	  EtBinEdge.push_back(h_SortV[bin]->GetBinCenter(i)-h_SortV[bin]->GetBinWidth(i) );
	  break;
	}  
      }
  }

  int MCEntries = cloneSortVar_MC.size();
  for(unsigned int ientry = 0; ientry < MCEntries; ++ientry)
    {    
      if( (ientry%100000 == 0) ) std::cout << "reading entry " << ientry << std::endl;
      
      if (strcmp(EBEE,"EE")==0 && (fabs(scEta_MC.at(ientry)) < 1.566 || fabs(scEta_MC.at(ientry)) > 2.5 )) continue; 
      if (strcmp(EBEE,"EB")==0 && (fabs(scEta_MC.at(ientry)) > 1.4442 )) continue;
      
      //      if(R9_MC.at(ientry) < 0.7) continue;
      if(scEt_reg_MC.at(ientry) < 25.) continue;

      //to be fixed -> categories as in Hgg 
      if(std::string(EBEE) == "BC" && (fabs(scEta_MC.at(ientry)) > 1. )) continue; 
      if(std::string(EBEE) == "B4" && (fabs(scEta_MC.at(ientry)) < 1. || fabs(scEta_MC.at(ientry)) > 1.4442)) continue; 
      if(std::string(EBEE) == "EL" && (fabs(scEta_MC.at(ientry)) < 1.566 || fabs(scEta_MC.at(ientry)) > 2. )) continue; 
      if(std::string(EBEE) == "EH" && (fabs(scEta_MC.at(ientry)) > 2.5 )) continue; 
                                                                                                     
      if(std::string(LOWHIGH) == "LOW" && R9_MC.at(ientry) >= 0.94 ) continue;
      if(std::string(LOWHIGH) == "HIGH" && R9_MC.at(ientry) < 0.94 ) continue;

      for(unsigned int bin = 0; bin < EtBinEdge.size(); ++bin){
	if( (bin != EtBinEdge.size()-1 && cloneSortVar_MC.at(ientry) > EtBinEdge.at(bin) && cloneSortVar_MC.at(ientry) < EtBinEdge.at(bin+1)) ||
	    (bin == EtBinEdge.size()-1 && cloneSortVar_MC.at(ientry) > EtBinEdge.at(bin) ) ){
	  if(PU == 0)
	    {
	      h_EoP_MC[(int)bin]->Fill((scE_reg_MC.at(ientry)-ES_MC.at(ientry))/(P_MC.at(ientry)-ES_MC.at(ientry)));
	      h_SortV_MC[int(bin)]->Fill(cloneSortVar_MC.at(ientry));
	      break;
	  }
          if(PU == 1)
	    {
	      h_EoP_MC[(int)bin]->Fill((scE_reg_MC.at(ientry)-ES_MC.at(ientry))/(P_MC.at(ientry)-ES_MC.at(ientry)), puRe.at(int(ientry/2)));
	      h_SortV_MC[int(bin)]->Fill(cloneSortVar_MC.at(ientry), puRe.at(int(ientry/2)) );
	      break;
	    }
	} // get the ok bin
	}//loop over bins
      if(PU == 0){
    	h_Et_allMC->Fill(scEt_reg_MC.at(ientry));
	h_R9_allMC->Fill(R9_MC.at(ientry));
	h_Vtx_MC->Fill(PV_MC.at(int(ientry/2)));
    }
    if(PU == 1){
      h_Et_allMC->Fill(scEt_reg_MC.at(ientry), puRe.at(int(ientry/2)));
      h_R9_allMC->Fill(R9_MC.at(ientry), puRe.at(int(ientry/2)));
      h_Vtx_MC->Fill(PV_MC.at(int(ientry/2)), puRe.at(int(ientry/2)) );
      h_R9_vsET_MC->Fill(scEt_reg_MC.at(ientry), R9_MC.at(ientry), puRe.at(int(ientry/2)));
      p_R9_vsET_MC->Fill(scEt_reg_MC.at(ientry), R9_MC.at(ientry), puRe.at(int(ientry/2)));
    }
    }

  std::cout << " fino a qui ci sono = MC fillati" <<  std::endl;

  for(int i = 0; i < nBins; ++i){
    //------------------------------------
    // Fill the graph for uncorrected data
    // define the fitting function
    // N.B. [0] * ( [1] * f( [1]*(x-[2]) ) )


    float xNorm = h_EoP_DA[i]->Integral()/h_EoP_MC[i]->Integral(); //  * h_EoP_DA[i]->GetBinWidth(1)/h_EoP_MC[i]->GetBinWidth(1);  
    h_EoP_MC[i]->Scale(xNorm);

    float xNorm_all = h_Et_allDA->Integral()/h_Et_allMC->Integral(); //* h_Et_allDA->GetBinWidth()/h_Et_allMC->GetBinWidth();
    if(SortV == "Et") xNorm_all = h_R9_allDA->Integral()/h_R9_allMC->Integral();
    h_Et_allMC->Scale(xNorm_all);
    h_R9_allMC->Scale(xNorm_all);
    h_Vtx_MC->Scale(xNorm_all);

    float xNormSV = h_SortV[i]->Integral()/h_SortV_MC[i]->Integral(); //*h_Et[i]->GetBinWidth()/h_Et_MC[i]->GetBinWidth();  
    h_SortV_MC[i]->Scale(xNormSV);
    
//     std::cout << " i = " << i << " h_EoP_DA[i]->Integral() = " << h_EoP_DA[i]->Integral() << std::endl;
//     std::cout << " i = " << i << " h_Et[i]->Integral() = " << h_Et[i]->Integral() << std::endl;
//     std::cout << " i = " << i << " h_EoP_MC[i]->Integral() = " << h_EoP_MC[i]->Integral() << std::endl;
//     std::cout << " i = " << i << " h_Et_MC[i]->Integral() = " << h_Et_MC[i]->Integral() << std::endl;

//     std::cout << " i = " << i << " h_EoP_DA[i]->Integral() = " << h_EoP_DA[i]->Integral() << std::endl;
//     std::cout << " i = " << i << " h_EoP_MC[i]->Integral() = " << h_EoP_MC[i]->Integral() << std::endl;
//     std::cout << " xNorm = " << xNorm << std::endl;
//     std::cout << " xNormEt = " << xNormEt << std::endl;


    //    h_EoP_MC[i]->Smooth(2);

    //    if(reweightZtoH  == false && reweightEta == false && reweightR9 == false){                              

    if(SortV == "Et"){
    if(std::string(EBEE) == "EB" && year == 2011 && std::string(LOWHIGH) == "HIGH"){h_EoP_MC[i]->Smooth(1); }
    if(std::string(EBEE) == "EB" && year == 2011 && std::string(LOWHIGH) == "LOW"){ h_EoP_MC[i]->Smooth(1); }
    if(std::string(EBEE) == "EB" && year == 2012 && std::string(LOWHIGH) == "HIGH"){ h_EoP_MC[i]->Smooth(2); }
    if(std::string(EBEE) == "EB" && year == 2012 && std::string(LOWHIGH) == "LOW"){h_EoP_MC[i]->Smooth(2); }

    if(std::string(EBEE) == "EE" && year == 2011 && std::string(LOWHIGH) == "HIGH")
      { h_EoP_MC[i]->Smooth(150); h_EoP_DA[i]->Rebin(4); h_EoP_MC[i]->Rebin(4);}
    if(std::string(EBEE) == "EE" && year == 2011 && std::string(LOWHIGH) == "LOW")
      { h_EoP_MC[i]->Smooth(150); h_EoP_DA[i]->Rebin(4); h_EoP_MC[i]->Rebin(4);}
    if(std::string(EBEE) == "EE" && year == 2012 && std::string(LOWHIGH) == "HIGH")
      {   h_EoP_MC[i]->Smooth(150); h_EoP_DA[i]->Rebin(4); h_EoP_MC[i]->Rebin(4);}
    if(std::string(EBEE) == "EE" && year == 2012 && std::string(LOWHIGH) == "LOW")
      {h_EoP_MC[i]->Smooth(150); h_EoP_DA[i]->Rebin(4); h_EoP_MC[i]->Rebin(4);}
    }
                                                                                                     
    if(SortV == "R9"){
     //    h_EoP_DA[i]->Rebin(2); h_EoP_MC[i]->Rebin(2);                                                              
    //    if(reweightZtoH  == false && reweightEta == false && reweightR9 == false){                                 
    if(std::string(EBEE) == "EB" && year == 2011 && std::string(LOWHIGH) == "HIGH"){h_EoP_MC[i]->Smooth(1); }
    if(std::string(EBEE) == "EB" && year == 2011 && std::string(LOWHIGH) == "LOW"){ h_EoP_MC[i]->Smooth(1); }
    if(std::string(EBEE) == "EB" && year == 2012 && std::string(LOWHIGH) == "HIGH"){ h_EoP_MC[i]->Smooth(2); }
    if(std::string(EBEE) == "EB" && year == 2012 && std::string(LOWHIGH) == "LOW"){h_EoP_MC[i]->Smooth(2); }
    if(std::string(EBEE) == "EE" && year == 2011 && std::string(LOWHIGH) == "HIGH")
      { h_EoP_MC[i]->Smooth(150); h_EoP_DA[i]->Rebin(4); h_EoP_MC[i]->Rebin(4);}
    if(std::string(EBEE) == "EE" && year == 2011 && std::string(LOWHIGH) == "LOW")
      { h_EoP_MC[i]->Smooth(150); h_EoP_DA[i]->Rebin(4); h_EoP_MC[i]->Rebin(4);}
    if(std::string(EBEE) == "EE" && year == 2012 && std::string(LOWHIGH) == "HIGH")
      {   h_EoP_MC[i]->Smooth(150); h_EoP_DA[i]->Rebin(4); h_EoP_MC[i]->Rebin(4);}
    if(std::string(EBEE) == "EE" && year == 2012 && std::string(LOWHIGH) == "LOW")
      {h_EoP_MC[i]->Smooth(150); h_EoP_DA[i]->Rebin(4); h_EoP_MC[i]->Rebin(4);}
    }                                                                                                        


    histoFunc* templateHistoFunc = new histoFunc(h_EoP_MC[i]);
    char funcName[50];
    sprintf(funcName,"f_EoP_%d",i);
    f_EoP[i] = new TF1(funcName, templateHistoFunc, 0.7, 1.3, 3, "histoFunc");
    if(std::string(EBEE) == "EE") f_EoP[i] = new TF1(funcName, templateHistoFunc, 0.5, 2.5, 3, "histoFunc");
    if(std::string(EBEE) == "EE" && SortV == "R9")  f_EoP[i] = new TF1(funcName, templateHistoFunc, 0.7, 1.4, 3, "histoFunc");    

    f_EoP[i]->SetParName(0,"Norm"); 
    f_EoP[i]->SetParName(1,"Scale factor"); 
    f_EoP[i]->SetLineWidth(1); 
    f_EoP[i]->SetNpx(10000);
    
    xNorm = 1.;    
    f_EoP[i]->FixParameter(0, xNorm);
    //    f_EoP[i] -> SetParameter(1, gRandom->Gaus(1.,0.005));
    f_EoP[i]->SetParameter(1, 0.99);
    f_EoP[i]->FixParameter(2, 0.);
    f_EoP[i]->SetLineColor(kRed+2); 

    TFitResultPtr rp = h_EoP_DA[i]->Fit(funcName, "QERLS+");
    int fStatus = rp;
    int nTrials = 0;
    while( (fStatus != 0) && (nTrials < 100) )
    {
      rp = h_EoP_DA[i]->Fit(funcName, "QERLS+");
      fStatus = rp;
      if(fStatus == 0) break;
      ++nTrials;
    }

    double eee = f_EoP[i]->GetParError(1); 
    double k = 1./f_EoP[i]->GetParameter(1);


    // Fill the graph      
    if (fStatus == 0 && eee*k > 0.1*h_EoP_DA[i]->GetRMS()/sqrt(evtsPerPoint))
    {
      x.push_back(h_SortV[i]->GetMean());
      ex.push_back((h_SortV[i]->GetRMS())/sqrt(h_SortV[i]->GetEntries()));
      y.push_back(k-1);
      ey.push_back(eee * k * k);
    }
    else
    std::cout << "Fitting uncorrected Et bin: " << i << "   Fail status: " << fStatus << "   sigma: " << eee << std::endl;

  }
   
  for(unsigned int i = 0; i < x.size(); ++i)
  {
    finalGraph->SetPoint(i,  x.at(i) , y.at(i));
    finalGraph->SetPointError(i, ex.at(i), ey.at(i));
  }

  if(year == 2012) finalGraph->SetMarkerColor(kBlue);
  if(year == 2011) finalGraph->SetMarkerColor(kCyan);
  if(strcmp(LOWHIGH,"HIGH")==0 )  finalGraph->GetYaxis()->SetRangeUser(-0.004, 0.014);
  if(strcmp(LOWHIGH,"LOW")==0 )  finalGraph->GetYaxis()->SetRangeUser(-0.03, 0.03);
  finalGraph->GetYaxis()->SetTitle("E/p_{data} - E/p_{mc}");
  finalGraph->GetXaxis()->SetRangeUser(0., 130.);
  finalGraph->GetXaxis()->SetTitle(SortV.c_str());

//   std::cout << "   totDAevts = " << totDAevts << std::endl;
//   std::cout << "   DAevtsHIHI = " << DAevtsHIHI << std::endl;

  std::string plotFolderName = "PLOTS_vs"+SortV;
  if(doVsEach == "true") plotFolderName = "PLOTS_true"; 

  TFile pippo((plotFolderName+"/results_"+folderName+"_"+string_year+".root").c_str(),"recreate");
  finalGraph->Write("finalGraph");
  h_Et_allMC->Write();
  h_Et_allDA->Write();
  h_R9_allMC->Write();
  h_R9_allDA->Write();
  h_R9_vsET_MC->Write();
  h_R9_vsET_DA->Write();
  p_R9_vsET_MC->Write();
  p_R9_vsET_DA->Write();

  h_Vtx_DA->Write();
  h_Vtx_MC->Write();
  h_scE_DA->Write();
  h_scReg_DA->Write();
  h_scRaw_DA->Write();

  for(int i = 0; i < nBins; ++i){
    h_EoP_DA[i]->Write();
    h_EoP_MC[i]->Write();
    h_SortV[i]->Write();
    h_SortV_MC[i]->Write();
  }
  pippo.Close();
  
//   /*
//   // Drawings
//   TPaveStats** s_EoP = new TPaveStats*[nBins];
  
//   TCanvas *c1[100]; 
//   for(int i = 0; i < nBins; ++i)
//   {    
//     char canvasName[50];
//     sprintf(canvasName, "Fits-%0d", i); 
//     c1[i] = new TCanvas(canvasName, canvasName);
//     c1[i]->cd();
//     h_EoP_DA[i] -> GetXaxis() -> SetTitle("E/p");  
//     h_EoP_DA[i] -> GetYaxis() -> SetRangeUser(0., std::max(h_EoP_DA[i]->GetMaximum(), h_EoP_MC[i]->GetMaximum()) + 10.); 
//     h_EoP_DA[i] -> GetXaxis() -> SetRangeUser(0.5,1.5); 
//     //    h_EoP_DA[i] -> Draw("e");
//     h_EoP_DA[i] -> Draw();
//     gPad->Update();
//     s_EoP[i]= (TPaveStats*)(h_EoP_DA[i]->GetListOfFunctions()->FindObject("stats"));
//     s_EoP[i]->SetTextColor(kRed+2);
//     f_EoP[i]->Draw("same");
    
//     h_EoP_MC[i] -> Draw("same");
    
//     char Name[100];
//     if(PU == 0)      sprintf(Name, (plotFolderName+"/"+folderName+"/noPU_fit_%d_"+string_year+".png").c_str(),i);
//     if(PU == 1)      sprintf(Name, (plotFolderName+"/"+folderName+"/fit_%d_"+string_year+".png").c_str(),i);
//     c1[i] -> Print(Name,".png");     
//   }
  
//   TCanvas *c2[100]; 
//   for(int i = 0; i < nBins; ++i)
//   {
//     char canvasName[50];
//     sprintf(canvasName, "Et_DA-%0d", i); 
//     c2[i] = new TCanvas(canvasName, canvasName);
//     c2[i]->cd();

//     h_Et[i]->GetXaxis() -> SetTitle("Et");
//     h_Et[i]->GetYaxis()->SetRangeUser(0, std::max(h_Et[i]->GetMaximum(), h_Et_MC[i]->GetMaximum()) + 10. ); 
//     if(i<nBins-1) h_Et[i]->GetXaxis()->SetRangeUser(EtBinEdge.at(i), EtBinEdge.at(i+1)); 
//     else h_Et[i]->GetXaxis()->SetRangeUser(EtBinEdge.at(i), 150.); 
//     //    h_Et[i] -> Draw("e");
//     h_Et[i]->Draw();
//     h_Et_MC[i]->Draw("same");
//     /*gPad->Update();
//     s_Las[i]= (TPaveStats*)(h_Et[i]->GetListOfFunctions()->FindObject("stats"));
//     s_Las[i]->SetTextColor(kBlack);*/
    
//     char Name[100];
//     if(PU == 0)      sprintf(Name, (plotFolderName+"/"+folderName+"/noPU_Et_%d_"+string_year+".png").c_str(),i);
//     if(PU == 1)      sprintf(Name, (plotFolderName+"/"+folderName+"/Et_%d_"+string_year+".png").c_str(),i);
//     c2[i]->Print(Name,".png");      
//   }



//   TCanvas* Et_spectrum = new TCanvas;
//   gPad->SetLogy();
//   //  h_Et_allDA->GetYaxis()->SetRangeUser(0.1, 10000.);
//   h_Et_allDA->GetXaxis()->SetRangeUser(0., 150.);
//   h_Et_allDA->GetXaxis()->SetTitle("Et ");
//   h_Et_allDA->SetMarkerColor(kRed+2);
//   h_Et_allDA->SetMarkerStyle(7);
//   h_Et_allDA->Draw("e");
//    for(int jj = 0; jj < nBins; ++jj){
//      h_Et_MC[jj]->GetXaxis()->SetRangeUser(0., 150.);
//      h_Et_MC[jj]->Draw("same");
//    }
//   TLegend *tspec = new TLegend(0.64,0.80,0.99,0.99);
//   tspec->SetFillColor(0);
//   tspec->SetTextFont(42); 
//   tspec->AddEntry(h_Et_allDA,"DATA","PL");
//   tspec->AddEntry(h_Et_MC[0],"MC ","PL");
//   tspec->Draw(); 
//   Et_spectrum->Print((plotFolderName+"/"+folderName+"/Et_spectrum_"+string_year+".png").c_str(), ".png");


//   TCanvas* cVtx = new TCanvas();
//   h_Vtx_DA->Draw();
//   h_Vtx_MC->SetLineColor(kGreen+2);
//   h_Vtx_MC->Draw("same");
//   cVtx->Print((plotFolderName+"/"+folderName+"/Vtx_"+string_year+".png").c_str(),".png");


//   std::sort(y.begin(), y.end());
//   std::sort(ey.begin(), ey.end());
//   TCanvas* cplot = new TCanvas("gplot", "gplot",100,100,725,500);
//   cplot->cd();

//   std::cout << " sortato range " << std::endl;

//   TPad *cLeft  = new TPad("pad_0","pad_0",0.00,0.00,1.00,1.00);
//   cLeft->SetLeftMargin(0.17); 
//   cLeft->SetRightMargin(0.025); 
//   cLeft->SetBottomMargin(0.17); 
  
//   cLeft->Draw();
 
//   float tYoffset = 1.75; 
//   float tXoffset = 1.6; 
//   float labSize = 0.04;
//   float labSize2 = 0.07;

//   cLeft->cd(); 
//   cLeft->SetGridx();
//   cLeft->SetGridy();
  
//   float x_min = x.at(0)-ex.at(ex.size()-1)-10;
//   float x_max = x.at(x.size()-1)+ex.at(ex.size()-1)+10;
// //   float y_min = y.at(0)-ey.at(ey.size()-1)-0.002;
// //   float y_max = y.at(y.size()-1)+ey.at(ey.size()-1)+0.002;

// //   float y_min = y.at(0)-ey.at(ey.size()-1)-0.005;
// //   float y_max = y.at(y.size()-1)+ey.at(ey.size()-1)+0.005;

//   float y_min = -0.004;
//   float y_max = 0.014;


//   // pad settings
//   TH1F *hPad = (TH1F*)gPad->DrawFrame(0,y_min,130,y_max);
//   hPad->GetXaxis()->SetTitle("E_{T}");
//   hPad->GetYaxis()->SetTitle("E/p_{data}-E/p_{mc}");
//   hPad->GetYaxis()->SetTitleOffset(tYoffset);
//   hPad->GetXaxis()->SetTitleOffset(tXoffset);
//   hPad->GetXaxis()->SetLabelSize(labSize);
//   hPad->GetXaxis()->SetTitleSize(labSize);
//   hPad->GetYaxis()->SetLabelSize(labSize);
//   hPad->GetYaxis()->SetTitleSize(labSize);
//   finalGraph->Draw("P");
//   cplot->Print((plotFolderName+"/"+folderName+"/EoP_vs_Et_"+string_year+".png").c_str(),".png");
// */
  
  std::cout << " plottato tutto " << std::endl;
  //std::cout << "CREATI I FILES" << std::endl;
  return (0);

}
void trisCheckCorrection_unbinnedfit(Char_t* EBEE = 0,
                         Int_t evtsPerPoint = 0,
                         float laserCorrMin = -1.,
                         float laserCorrMax = -1.)
{
  // Set style options
  gROOT->Reset();
  gROOT->SetStyle("Plain");
  gStyle->SetPadTickX(1);
  gStyle->SetPadTickY(1);
  gStyle->SetOptTitle(0); 
  gStyle->SetOptStat(1110); 
  gStyle->SetOptFit(1); 
  
  
  
  // Check qualifiers
  if ( strcmp(EBEE,"EB")!=0 && strcmp(EBEE,"EE")!=0 )
  {
    std::cout << "CHK-STB Error: unknown partition " << EBEE << std::endl;
    std::cout << "CHK-STB Select either EB or EE ! " << std::endl;
    return;
  }
  
  if ( strcmp(EBEE,"EB") == 0 )
  {
    lcMin = 0.99;
    lcMax = 1.05;
  }
  else
  {
    lcMin = 0.99;
    lcMax = 1.11;
  }
  
  if( (laserCorrMin != -1.) && (laserCorrMax != -1.) )
  {
    lcMin = laserCorrMin;
    lcMax = laserCorrMax;
  }
  
  
  
  // Get trees
  std::cout << std::endl;
  
  TChain* ntu_DA = new TChain("ntu");
  FillChain(ntu_DA,"inputDATA.txt");
  std::cout << "     DATA: " << std::setw(8) << ntu_DA->GetEntries() << " entries" << std::endl;
  
  TChain* ntu_MC = new TChain("ntu");
  FillChain(ntu_MC,"inputMC.txt");
  std::cout << "REFERENCE: " << std::setw(8) << ntu_MC->GetEntries() << " entries" << std::endl;
  
  if (ntu_DA->GetEntries() == 0 || ntu_MC->GetEntries() == 0 )
  {
    std::cout << "CHK-STB Error: At least one file is empty" << std::endl; 
    return;
  }  
  
  
  
  // Set branch addresses
  int runId;
  int isW, isZ;
  int timeStampHigh;
  float seedLaserAlpha;
  float avgLaserCorrection, scCrackCorrection;
  float EoP;
  float scE, scERaw, scEta, scEtaWidth, scPhiWidth;
  int seedIeta,seedIphi;
  int seedIx,seedIy,seedZside;
  float esE;
  float seedLaserCorrection;
  int iPhi,iEta;
  
  ntu_DA->SetBranchAddress("runId", &runId);  
  ntu_DA->SetBranchAddress("isW", &isW);
  //ntu_DA->SetBranchAddress("isZ", &isZ);
  ntu_DA->SetBranchAddress("timeStampHigh", &timeStampHigh);
  ntu_DA->SetBranchAddress("ele1_scCrackCorr", &scCrackCorrection);
  ntu_DA->SetBranchAddress("ele1_scLaserCorr", &avgLaserCorrection);
  ntu_DA->SetBranchAddress("ele1_seedLaserCorr", &seedLaserCorrection);
  ntu_DA->SetBranchAddress("ele1_seedLaserAlpha", &seedLaserAlpha);
  ntu_DA->SetBranchAddress("ele1_es", &esE);
  ntu_DA->SetBranchAddress("ele1_scE", &scE);
  ntu_DA->SetBranchAddress("ele1_scERaw", &scERaw);
  ntu_DA->SetBranchAddress("ele1_scEta", &scEta);
  ntu_DA->SetBranchAddress("ele1_scEtaWidth", &scEtaWidth);
  ntu_DA->SetBranchAddress("ele1_scPhiWidth", &scPhiWidth);
  ntu_DA->SetBranchAddress("ele1_EOverP", &EoP);
  ntu_DA->SetBranchAddress("ele1_seedIphi", &iPhi);
  ntu_DA->SetBranchAddress("ele1_seedIeta", &iEta);
  ntu_DA->SetBranchAddress("ele1_seedIeta",       &seedIeta);
  ntu_DA->SetBranchAddress("ele1_seedIphi",       &seedIphi);
  ntu_DA->SetBranchAddress("ele1_seedIx",         &seedIx);
  ntu_DA->SetBranchAddress("ele1_seedIy",         &seedIy);
  ntu_DA->SetBranchAddress("ele1_seedZside",      &seedZside);
  
  ntu_MC->SetBranchAddress("isW", &isW);
  ntu_MC->SetBranchAddress("isZ", &isZ);
  ntu_MC->SetBranchAddress("ele1_scEta", &scEta);
  ntu_MC->SetBranchAddress("ele1_EOverP", &EoP);
  
  

  float params[42];
  InitializeParams(params);
  
  
  // Build the reference from 'infile2'
  std::cout << std::endl;
  std::cout << "***** Build reference for " << EBEE << " *****" << std::endl;
  
  templateHisto = new TH1F("templateHisto", "", 1200, 0., 5.);

  for(int ientry = 0; ientry < ntu_MC->GetEntries(); ++ientry)
  {
    if( (ientry%100000 == 0) ) std::cout << "reading MC entry " << ientry << std::endl;
    ntu_MC->GetEntry(ientry);
    
    if (strcmp(EBEE,"EB")==0 && fabs(scEta) > 1.4442) continue;                       // barrel
    if (strcmp(EBEE,"EE")==0 && (fabs(scEta) < 1.56 || fabs(scEta) > 2.5 )) continue; // endcap
    
    //if( seedLaserAlpha > 1.5 ) continue;
        
    //if( fabs(scEta) > 0.44 ) continue;
    //if( fabs(scEta) < 0.44 || fabs(scEta) > 0.77 ) continue;
    //if( fabs(scEta) < 0.77 || fabs(scEta) > 1.10 ) continue;
    //if( fabs(scEta) < 1.10 || fabs(scEta) > 1.56 ) continue;
    //if( fabs(scEta) < 1.56 || fabs(scEta) > 2.00 ) continue;
    //if( fabs(scEta) < 2.00 ) continue;
        
    templateHisto -> Fill(EoP);
  }

  int rebin = 4;
  if (strcmp(EBEE,"EB")==0) rebin = 2;
  templateHisto -> Rebin(rebin);  
  FitTemplate();
  
  std::cout << "Reference built for " << EBEE << " - " << templateHisto->GetEntries() << " events" << std::endl;
  
  
  
  // Loop and sort events
  std::cout << std::endl;
  std::cout << "***** Sort events and define bins *****" << std::endl;
  
  int nEntries = ntu_DA -> GetEntriesFast(); 
  int nSavePts = 0; 
  std::vector<bool> isSavedEntries(nEntries);
  std::vector<SorterLC> sortedEntries;
  
  for(int ientry = 0; ientry < nEntries; ++ientry)
  {
    ntu_DA -> GetEntry(ientry); 
    isSavedEntries.at(ientry) = false;
    
    // save only what is needed for the analysis!!!
    if (strcmp(EBEE,"EB")==0 && fabs(scEta) > 1.4442) continue;                       // barrel
    if (strcmp(EBEE,"EE")==0 && (fabs(scEta) < 1.56 || fabs(scEta) > 2.5 )) continue; // endcap
    
    //if( fabs(scEta) > 0.44 ) continue;
    //if( fabs(scEta) < 0.44 || fabs(scEta) > 0.77 ) continue;
    //if( fabs(scEta) < 0.77 || fabs(scEta) > 1.10 ) continue;
    //if( fabs(scEta) < 1.10 || fabs(scEta) > 1.56 ) continue;
    //if( fabs(scEta) < 1.56 || fabs(scEta) > 2.00 ) continue;
    //if( fabs(scEta) < 2.00 ) continue;
    
        
    if( seedLaserCorrection <= 1.) continue;   
    if( seedLaserAlpha < 1.5 ) continue;
    //if( timeStampHigh > 1303862400 ) continue;
    
    if( seedZside < 0 )
      if( (seedIx > 20 ) && (seedIx < 50) && (seedIy > 85) && (seedIy < 92) ) continue;
    if( seedZside == -1 )
      if( (seedIx > 35 ) && (seedIx < 55) && (seedIy > 80) && (seedIy < 87) ) continue;
    if( seedZside > 0 )
      if( (seedIx > 65 ) && (seedIx < 77) && (seedIy > 33) && (seedIy < 57) ) continue;
    if( seedZside > 0 )
      if( (seedIx > 75 ) && (seedIx < 93) && (seedIy > 18) && (seedIy < 37) ) continue;    
    
    //if ( runId < 163045 ) continue;
    //if ( runId >= 163232 ) continue;
    //if ( runId < 163232 ) continue;
    
    
    //*********************** CLUSTER CORR *****************************
    //if( (ientry%1 == 0) ) std::cout << "\n\n\nreading entry " << ientry << std::endl;    
    //Ediff -> Fill( ( (scCrackCorrection*fClusterCorrections(scERaw+esE,scEta,scPhiWidth/scEtaWidth,params))-scE)/scE );
    //Ediff_vsEta -> Fill( scEta, ( (esE+scCrackCorrection*fClusterCorrections(scERaw,scEta,scPhiWidth/scEtaWidth,params))-scE)/scE );
    //if( fabs(fClusterCorrections(scERaw,scEta,scPhiWidth/scEtaWidth,params)-scE) > 0.001 )
    //{
    //  std::cout << "\n\n" << std::endl;
    //  std::cout << "scEta = " << scEta << "   scE = " << scE << "   scERaw = " << scERaw << std::endl;
    //  std::cout << "scERaw_corr = " << fClusterCorrections(scERaw,scEta,scPhiWidth/scEtaWidth,params) << std::endl;
    //}
    //*********************** CLUSTER CORR *****************************
        
    isSavedEntries.at(ientry) = true;
    
    SorterLC dummy;
    dummy.laserCorr = avgLaserCorrection;
    dummy.entry = ientry;
    sortedEntries.push_back(dummy);
    
    nSavePts++; 
  }
  std::sort(sortedEntries.begin(),sortedEntries.end(),SorterLC());
  std::cout << "Data sorted in " << EBEE << " - " << nSavePts << " events" << std::endl;
  
  //TCanvas* c_diff = new TCanvas("c_diff","c_diff");
  //c_diff -> cd();
  //Ediff -> Draw();
  //
  //TCanvas* c_diff_vsEta = new TCanvas("c_diff_vsEta","c_diff");
  //c_diff_vsEta -> cd();
  //Ediff_vsEta -> Draw("colz");
  
  // bins with evtsPerPoint events per bin
  int nBins = std::max(1,int(nSavePts/evtsPerPoint));
  int nBinPts = int( nSavePts/nBins );
  int nBinTempPts = 0;
  
  std::vector<int> binEntryMax;
  binEntryMax.push_back(0);
  for(int iSaved = 0; iSaved < nSavePts; ++iSaved)
  {
    ++nBinTempPts;
    
    if( nBinTempPts == nBinPts )
    {
      binEntryMax.push_back( iSaved );      
      nBinTempPts = 0;
    }
  }
  binEntryMax.at(nBins) = nSavePts;
  
  std::cout << "nBins = " << nBins << std::endl;
  for(int bin = 0; bin < nBins; ++bin)
    std::cout << "bin: " << bin
              << "   entry min: " << setw(6) << binEntryMax.at(bin)
              << "   entry max: " << setw(6) << binEntryMax.at(bin+1)
              << "   events: "    << setw(6) << binEntryMax.at(bin+1)-binEntryMax.at(bin)
              << std::endl;
  TVirtualFitter::SetDefaultFitter("Fumili2");
  
  
  
  // histogram definition
  
  TH1F* h_EoP_spread;
  TH1F* h_EoC_spread;
  TH2F* h_LC_map = new TH2F("h_LC_map","",360,0.,360,170,-85,85);
  
  if ( strcmp(EBEE,"EB")==0 )
  {  
    h_EoP_spread = new TH1F("h_EoP_spread","",100,0.95,1.01);
    h_EoC_spread = new TH1F("h_EoC_spread","",100,0.95,1.01);    
  }
  else 
  {  
    h_EoP_spread = new TH1F("h_EoP_spread","",100,0.91,1.03);
    h_EoC_spread = new TH1F("h_EoC_spread","",100,0.91,1.03);    
  }
  
  h_EoP_spread -> SetLineColor(kRed+2);
  h_EoP_spread -> SetLineWidth(2);
  h_EoP_spread -> GetXaxis() -> SetTitle("Relative E/p scale");

  h_EoC_spread -> SetLineColor(kGreen+2);
  h_EoC_spread -> SetLineWidth(2);
  h_EoC_spread -> GetXaxis() -> SetTitle("Relative E/p scale");  
  
  
  TH1F** h_EoP = new TH1F*[nBins];
  TH1F** h_EoC = new TH1F*[nBins];
  TH1F** h_Las = new TH1F*[nBins];

  for(int i = 0; i < nBins; ++i)
  {
    char histoName[80];
    
    sprintf(histoName, "EoP_%d", i);
    h_EoP[i] = new TH1F(histoName, histoName, 1200, 0., 3.);
    h_EoP[i] -> SetFillColor(kRed+2);
    h_EoP[i] -> SetFillStyle(3004);
    h_EoP[i] -> SetMarkerStyle(7);
    h_EoP[i] -> SetMarkerColor(kRed+2); 
    h_EoP[i] -> SetLineColor(kRed+2); 
    
    sprintf(histoName, "EoC_%d", i);
    h_EoC[i] = new TH1F(histoName, histoName, 1200, 0., 3.);
    h_EoC[i] -> SetFillColor(kGreen+2);
    h_EoC[i] -> SetFillStyle(3004);
    h_EoC[i] -> SetMarkerStyle(7);
    h_EoC[i] -> SetMarkerColor(kGreen+2);
    h_EoC[i] -> SetLineColor(kGreen+2);
    
    sprintf(histoName, "Las_%d", i);
    h_Las[i] = new TH1F(histoName, histoName, 100, 0.5, 1.5);
  }
  
  
  // data definition
  std::vector< std::vector<double>* > dataEoP;
  std::vector< std::vector<double>* > dataEoC;
  
  for (int jbin = 0; jbin< nBins; jbin++){
    dataEoP.push_back(new std::vector<double>);
    dataEoC.push_back(new std::vector<double>);
  }


  // function definition
  TF1** f_EoP = new TF1*[nBins];
  TF1** f_EoC = new TF1*[nBins];
  
  
    
  // loop on the saved and sorted events
  std::cout << std::endl;
  std::cout << "***** Fill and fit histograms *****" << std::endl;

  
  for(int ientry = 0; ientry < nEntries; ++ientry)
  {
    if( (ientry%10000 == 0) ) std::cout << "reading entry " << ientry << std::endl;
    
    if( isSavedEntries.at(ientry) == false ) continue;
    
    int iSaved = -1;
    for(iSaved = 0; iSaved < nSavePts; ++iSaved)
      if( ientry == sortedEntries[iSaved].entry ) break;
    
    int bin = -1;
    for(bin = 0; bin < nBins; ++bin)
      if( iSaved >= binEntryMax.at(bin) && iSaved < binEntryMax.at(bin+1) )
        break;
    
    //std::cout << "ientry = " << ientry << "   iSaved: " << iSaved << "   bin: " << bin << std::endl;
    
    ntu_DA->GetEntry(ientry);
    
    float scale = 1.;
    //scale = sqrt( pow(avgLaserCorrection,((1.52-0.7843)/1.52)-1.) );
    //scale = 1. / (0.1811 + 0.7843*avgLaserCorrection);
    
        
    //// fill the bins 
    (h_Las[bin]) -> Fill(avgLaserCorrection);
    (h_EoP[bin]) -> Fill(EoP/avgLaserCorrection);
    (h_EoC[bin]) -> Fill(EoP * scale);
    h_LC_map->Fill(iPhi,iEta,seedLaserCorrection);

    // fill te vectors data E/p 
    dataEoP[bin]->push_back(EoP/avgLaserCorrection);
    dataEoC[bin]->push_back(EoP);

  }
  

  // Define graph and histograms
  TGraphAsymmErrors* g_fit   = new TGraphAsymmErrors();
  TGraphAsymmErrors* g_c_fit   = new TGraphAsymmErrors();
  
  
  
  // define the fitting function
  // N.B. [0] * ( [1] * f( [1]*(x-[2]) ) )
  histoFunc* templateHistoFunc = new histoFunc(templateHisto);
   
  //templateFunc = new TF1("templateFunc", templateHistoFunc, 0., 5., 3, "histoFunc");
  //templateFunc -> SetParName(0,"Norm"); 
  //templateFunc -> SetParName(1,"Scale factor"); 
  //templateFunc -> SetLineWidth(1); 
  //templateFunc -> SetNpx(10000);
  //templateFunc -> SetParameter(0, 1 );
  //templateFunc -> SetParameter(1, 1);
  //templateFunc -> FixParameter(2, 0.);
  //templateFunc -> FixParameter(0, 1./templateFunc ->Integral(0.,5.) ); // normalized to 1. BUT will be renormalized to 1 at each iteration!
  
  TFitterMinuit* myfit = new TFitterMinuit(1);
  myfit->SetFCN(mylike);
  myfit->SetPrintLevel(-1);
  
  
  
  for(int i = 0; i < nBins; ++i)
  {
    h_EoP[i] -> Rebin(rebin*4);    
    h_EoC[i] -> Rebin(rebin*4);    
    
    
    //------------------------------------
    // Fill the graph for uncorrected data
    
    // fit uncorrected data
    mydata = dataEoP.at(i);
    
    myfit->Clear();
    myfit->SetParameter(0, "scale", 1.,0.0005,0.50,1.50);
    
    double arglist[2];
    arglist[0] = 10000; // Max number of function calls
    arglist[1] = 1e-5;  // Tolerance on likelihood ?????????

    int fStatus = myfit->ExecuteCommand("MIGRAD",arglist,2); 
    
    double amin,edm,errdef;
    int nvpar,nparx;
    myfit->GetStats(amin, edm, errdef, nvpar, nparx);
    double bestScale = myfit->GetParameter(0);
    double eee       = myfit->GetParError(0);
    
    char funcName[50];
    sprintf(funcName,"f_EoP_%d",i);
    f_EoP[i] = (TF1*)(templateFunc->Clone());
    f_EoP[i] -> SetParameter(0,h_EoP[i]->GetEntries());
    f_EoP[i] -> SetParameter(7,1.5);
    f_EoP[i] -> SetParName(0,"Norm"); 
    f_EoP[i] -> SetParName(1,"Scale factor"); 
    f_EoP[i] -> SetLineWidth(1); 
    f_EoP[i] -> SetNpx(10000);
    
    double xNorm = h_EoP[i]->GetEntries()/templateHisto->GetEntries() *
                   h_EoP[i]->GetBinWidth(1)/templateHisto->GetBinWidth(1); 
    
    //f_EoP[i] -> FixParameter(0, xNorm);
    //f_EoP[i] -> SetParameter(1, bestScale);
    //f_EoP[i] -> FixParameter(2, 0.);
    f_EoP[i] -> SetLineColor(kRed+2); 
    
    // Fill the graph
    if( fStatus == 0 && eee > 0. )
    {
      g_fit -> SetPoint(i,  h_Las[i]->GetMean() , 1./bestScale);
      g_fit -> SetPointError(i, h_Las[i]->GetRMS(), h_Las[i]->GetRMS(), eee, eee);
      h_EoP_spread -> Fill(1./bestScale);
    }
    else
      std::cout << "Fitting uncorrected time bin: " << i << "   Fail status: " << fStatus << "   sigma: " << eee << endl;
    
    
    
    //----------------------------------
    // Fill the graph for corrected data

    // fit uncorrected data
    
    mydata = dataEoC.at(i);
    
    myfit->Clear();
    myfit->SetParameter(0, "scale", 1.,0.0005,0.50,1.50);
    
    arglist[0] = 10000; // Max number of function calls
    arglist[1] = 1e-5;  // Tolerance on likelihood ?????????

    fStatus = myfit->ExecuteCommand("MIGRAD",arglist,2); 
    
    myfit->GetStats(amin, edm, errdef, nvpar, nparx);
    bestScale = myfit->GetParameter(0);
    eee       = myfit->GetParError(0);    
    
    
    sprintf(funcName,"f_EoC_%d",i);
    f_EoC[i] = (TF1*)(templateFunc->Clone());
    f_EoC[i] -> SetParameter(0,h_EoC[i]->GetEntries());
    f_EoC[i] -> SetParameter(7,bestScale);
    f_EoC[i] -> SetParName(0,"Norm"); 
    f_EoC[i] -> SetParName(1,"Scale factor"); 
    f_EoC[i] -> SetLineWidth(1); 
    f_EoC[i] -> SetNpx(10000);

    xNorm = h_EoC[i]->GetEntries()/templateHisto->GetEntries() *
            h_EoC[i]->GetBinWidth(1)/templateHisto->GetBinWidth(1); 
    //
    //f_EoC[i] -> SetParameter(1, bestScale);
    //f_EoC[i] -> FixParameter(2, 0.);
    f_EoC[i] -> SetLineColor(kGreen+2); 

    // fill the graph
    if( fStatus == 0 && eee > 0. )
    {        
      g_c_fit -> SetPoint(i,  h_Las[i]->GetMean() , 1./bestScale);
      g_c_fit -> SetPointError(i, h_Las[i]->GetRMS() , h_Las[i]->GetRMS() , eee, eee);
      h_EoC_spread -> Fill(1./bestScale);
    }
    else 
      std::cout << "Fitting corrected time bin: " << i << "   Fail status: " << fStatus << "   sigma: " << eee << endl;
    
    
    
  }
  
  TF1* pol0 = new TF1("pol0","pol0");
  pol0 -> SetLineColor(kGreen+2);
  pol0 -> SetLineWidth(3);
  pol0 -> SetLineStyle(2);
  g_c_fit -> Fit("pol0","Q+");
  
  
  // Drawings
  TPaveStats** s_EoP = new TPaveStats*[nBins];
  TPaveStats** s_EoC = new TPaveStats*[nBins];
  
  TCanvas *c1[100]; 
  for(int i = 0; i < nBins; ++i)
  {
    char canvasName[50];
    if (i%2==0) {
      sprintf(canvasName, "Fits-%0d", i/2); 
      c1[i/2] = new TCanvas(canvasName, canvasName);
      c1[i/2] -> Divide(2,1);
    }
    c1[i/2] -> cd (i%2+1);

    h_EoP[i] -> GetXaxis() -> SetTitle("E/p");  
    h_EoP[i] -> GetXaxis() -> SetRangeUser(0.5,1.5); 
    h_EoP[i] -> Draw("e");
    gPad->Update();
    s_EoP[i]= (TPaveStats*)(h_EoP[i]->GetListOfFunctions()->FindObject("stats"));
    s_EoP[i]->SetTextColor(kRed+2);

    h_EoC[i] -> Draw("esames");
    gPad->Update(); 
    s_EoC[i]= (TPaveStats*)(h_EoC[i]->GetListOfFunctions()->FindObject("stats"));
    s_EoC[i]->SetY1NDC(0.59); //new x start position
    s_EoC[i]->SetY2NDC(0.79); //new x end position
    s_EoC[i]->SetTextColor(kGreen+2);
    s_EoC[i]->Draw();
    
    f_EoP[i]->Draw("same");
    f_EoC[i]->Draw("same");    
  }

  /*  
  TCanvas *c2[100]; 
  for(int i = 0; i < nBins; ++i)
  {
    char canvasName[50];
    if (i%6==0) {
      sprintf(canvasName, "LaserCorr-%0d", i/6); 
      c2[i/6] = new TCanvas(canvasName, canvasName);
      c2[i/6] -> Divide(3,2);
    }
        
    c2[i/6] -> cd (i%6+1);
    h_Las[i] -> GetXaxis() -> SetTitle("laser correction");
    h_Las[i] -> GetXaxis() -> SetRangeUser(0.5,1.5); 
    h_Las[i] -> Draw("");
    gPad->Update();
    s_Las[i]= (TPaveStats*)(h_Las[i]->GetListOfFunctions()->FindObject("stats"));
    s_Las[i]->SetTextColor(kBlack);
  }
  */

  /*  
  TCanvas *cmap = new TCanvas("cmap","cmap");
  cmap->cd();
  gStyle->SetPalette(1);
  h_LC_map->Draw("colz");
  */
  
  // Final plots
  TCanvas* cplot = new TCanvas("gplot", "gplot",100,100,725,500);
  cplot->cd();

  TPad *cLeft  = new TPad("pad_0","pad_0",0.00,0.00,0.64,1.00);
  TPad *cRight = new TPad("pad_1","pad_1",0.64,0.00,1.00,1.00);

  cLeft->SetLeftMargin(0.15); 
  cLeft->SetRightMargin(0.025); 
  cRight->SetLeftMargin(0.025); 

  cLeft->Draw();
  cRight->Draw();

  float tYoffset = 1.5; 
  float labSize = 0.04;
  float labSize2 = 0.07;

  cLeft->cd(); 

  cLeft->SetGridx();
  cLeft->SetGridy();
  
  // pad settings
  TH1F *hPad = (TH1F*)gPad->DrawFrame(lcMin,0.9,lcMax,1.05);
  hPad->GetXaxis()->SetTitle("Laser correction");
  hPad->GetYaxis()->SetTitle("Relative E/p scale"); 
  hPad->GetYaxis()->SetTitleOffset(tYoffset);
  hPad->GetXaxis()->SetLabelSize(labSize);
  hPad->GetXaxis()->SetTitleSize(labSize);
  hPad->GetYaxis()->SetLabelSize(labSize);
  hPad->GetYaxis()->SetTitleSize(labSize);
  if ( strcmp(EBEE,"EB")==0 )
  {  
    hPad -> SetMinimum(0.950);
    hPad -> SetMaximum(1.010);
  }
  else 
  {  
    hPad -> SetMinimum(0.910);
    hPad -> SetMaximum(1.030);
  }
    
  // draw trend plot
  g_fit -> SetMarkerStyle(20);
  g_fit -> SetMarkerSize(0.75);
  g_fit -> SetMarkerColor(kRed+2);
  g_fit -> SetLineColor(kRed+2);
  g_fit -> Draw("P");
  g_c_fit -> SetMarkerStyle(20);
  g_c_fit -> SetMarkerColor(kGreen+2);
  g_c_fit -> SetLineColor(kGreen+2);
  g_c_fit -> SetMarkerSize(0.75);
  g_c_fit -> Draw("P,same");
  
  
  cRight -> cd();

  TPaveStats* s_EoP_spread = new TPaveStats();
  TPaveStats* s_EoC_spread = new TPaveStats();
  
  h_EoC_spread -> SetFillStyle(3001);
  h_EoC_spread -> SetFillColor(kGreen+2);
  h_EoC_spread->GetYaxis()->SetLabelSize(labSize2);
  h_EoC_spread->GetYaxis()->SetTitleSize(labSize2);
  h_EoC_spread->GetYaxis()->SetNdivisions(505);
  h_EoC_spread->GetYaxis()->SetLabelOffset(-0.02);
  h_EoC_spread->GetXaxis()->SetLabelOffset(1000);

  h_EoC_spread -> Draw("hbar");
  gPad -> Update();
  s_EoC_spread = (TPaveStats*)(h_EoC_spread->GetListOfFunctions()->FindObject("stats"));
  s_EoC_spread ->SetTextColor(kGreen+2);
  s_EoC_spread ->SetTextSize(0.06);
  s_EoC_spread->SetX1NDC(0.49); //new x start position
  s_EoC_spread->SetX2NDC(0.99); //new x end position
  s_EoC_spread->SetY1NDC(0.875); //new x start position
  s_EoC_spread->SetY2NDC(0.990); //new x end position
  s_EoC_spread -> SetOptStat(1100);
  s_EoC_spread -> Draw("sames");

  h_EoP_spread -> SetFillStyle(3001);
  h_EoP_spread -> SetFillColor(kRed+2);
  h_EoP_spread -> Draw("hbarsames");
  gPad -> Update();
  s_EoP_spread = (TPaveStats*)(h_EoP_spread->GetListOfFunctions()->FindObject("stats"));
  s_EoP_spread->SetX1NDC(0.49); //new x start position
  s_EoP_spread->SetX2NDC(0.99); //new x end position
  s_EoP_spread->SetY1NDC(0.750); //new x start position
  s_EoP_spread->SetY2NDC(0.875); //new x end position
  s_EoP_spread ->SetOptStat(1100);
  s_EoP_spread ->SetTextColor(kRed+2);
  s_EoP_spread ->SetTextSize(0.06);
  s_EoP_spread -> Draw("sames");
}
int main(int argc, char** argv)
{
  // Set style options
  setTDRStyle();
  gStyle->SetPadTickX(1);
  gStyle->SetPadTickY(1);
  gStyle->SetOptTitle(0); 
  gStyle->SetOptStat(1110); 
  gStyle->SetOptFit(1); 
  
  // Set fitting options
  TVirtualFitter::SetDefaultFitter("Fumili2");
  
  
  
  
  
  
  //-----------------
  // Input parameters
  
  std::cout << "\n***************************************************************************************************************************" << std::endl;
  std::cout << "arcg: " << argc << std::endl;
  char* EBEE = argv[1];
  int evtsPerPoint = atoi(argv[2]);
  int useRegression = atoi(argv[3]);
  std::string dayMin = "";
  std::string dayMax = "";
  std::string dayMinLabel = "";
  std::string dayMaxLabel = "";
  float absEtaMin = -1.;
  float absEtaMax = -1.;
  int IetaMin = -1;
  int IetaMax = -1;
  int IphiMin = -1;
  int IphiMax = -1;
  if(argc >= 5)
  {
    dayMin = std::string(argv[4])+" "+std::string(argv[5])+" "+std::string(argv[6]);
    dayMax = std::string(argv[7])+" "+std::string(argv[8])+" "+std::string(argv[9]);
    dayMinLabel = std::string(argv[4])+"_"+std::string(argv[5])+"_"+std::string(argv[6]);
    dayMaxLabel = std::string(argv[7])+"_"+std::string(argv[8])+"_"+std::string(argv[9]);
    
    t1 = dateToInt(dayMin);
    t2 = dateToInt(dayMax);
  }
  if(argc >= 11)
  {
    yMIN = atof(argv[10]);
    yMAX = atof(argv[11]);
  }
  if(argc >= 13)
  {
    absEtaMin = atof(argv[12]);
    absEtaMax = atof(argv[13]);
  }
  if(argc >= 15)
  {
    IetaMin = atoi(argv[14]);
    IetaMax = atoi(argv[15]);
    IphiMin = atoi(argv[16]);
    IphiMax = atoi(argv[17]);
  }
  
  std::cout << "EBEE: "          << EBEE          << std::endl;
  std::cout << "evtsPerPoint: "  << evtsPerPoint  << std::endl;
  std::cout << "useRegression: " << useRegression << std::endl;
  std::cout << "dayMin: "        << dayMin        << std::endl;
  std::cout << "dayMax: "        << dayMax        << std::endl;
  std::cout << "yMin: "          << yMIN          << std::endl;
  std::cout << "yMax: "          << yMAX          << std::endl;
  std::cout << "absEtaMin: "     << absEtaMin     << std::endl;
  std::cout << "absEtaMax: "     << absEtaMax     << std::endl;
  std::cout << "IetaMin: "       << IetaMin       << std::endl;
  std::cout << "IetaMax: "       << IetaMax       << std::endl;
  std::cout << "IphiMin: "       << IphiMin       << std::endl;
  std::cout << "IphiMax: "       << IphiMax       << std::endl;
  
  
  
  
  
  
  //-------------------
  // Define in/outfiles
  
  std::string folderName = std::string(EBEE) + "_" + dayMinLabel + "_" + dayMaxLabel;
  if( (absEtaMin != -1.) && (absEtaMax != -1.) )
  {
    char absEtaBuffer[50];
    sprintf(absEtaBuffer,"_%.2f-%.2f",absEtaMin,absEtaMax);
    folderName += std::string(absEtaBuffer);
  } 
  
  if( (IetaMin != -1.) && (IetaMax != -1.) && (IphiMin != -1.) && (IphiMax != -1.) )
  {
    char absEtaBuffer[50];
    sprintf(absEtaBuffer,"_Ieta_%d-%d_Iphi_%d-%d",IetaMin,IetaMax,IphiMin,IphiMax);
    folderName += std::string(absEtaBuffer);
  } 
  
  gSystem->mkdir(folderName.c_str());
  TFile* o = new TFile((folderName+"/"+folderName+"_histos.root").c_str(),"RECREATE");
  
  
  
  // Get trees
  std::cout << std::endl;
  
  TChain* ntu_DA = new TChain("simpleNtupleEoverP/SimpleNtupleEoverP");
  FillChain(ntu_DA,"inputDATA.txt");
  std::cout << "     DATA: " << std::setw(8) << ntu_DA->GetEntries() << " entries" << std::endl;
  
  TChain* ntu_MC = new TChain("simpleNtupleEoverP/SimpleNtupleEoverP");
  FillChain(ntu_MC,"inputMC.txt");
  std::cout << "REFERENCE: " << std::setw(8) << ntu_MC->GetEntries() << " entries" << std::endl;
  
  if (ntu_DA->GetEntries() == 0 || ntu_MC->GetEntries() == 0 )
  {
    std::cout << "Error: At least one file is empty" << std::endl; 
    return -1;
  }
  
  
  
  // Set branch addresses
  int runId;
  int timeStampHigh;
  int PV_n;
  float scLaserCorr, seedLaserAlpha, EoP, scEta, scPhi, scE, ES, P;
  int seedIeta, seedIphi, seedIx, seedIy, seedZside;
  
  ntu_DA->SetBranchStatus("*",0);
  ntu_DA->SetBranchStatus("runId",1);  
  ntu_DA->SetBranchStatus("timeStampHigh",1);
  ntu_DA->SetBranchStatus("PV_n",1);
  ntu_DA->SetBranchStatus("ele1_scLaserCorr",1);
  ntu_DA->SetBranchStatus("ele1_seedLaserAlpha",1);
  ntu_DA->SetBranchStatus("ele1_EOverP",1);
  ntu_DA->SetBranchStatus("ele1_scEta",1);
  ntu_DA->SetBranchStatus("ele1_scPhi",1);
  ntu_DA->SetBranchStatus("ele1_scE",1);
  ntu_DA->SetBranchStatus("ele1_scE_regression",1);
  ntu_DA->SetBranchStatus("ele1_scE",1);
  ntu_DA->SetBranchStatus("ele1_es",1);
  ntu_DA->SetBranchStatus("ele1_tkP",1);
  ntu_DA->SetBranchStatus("ele1_seedIeta",1);
  ntu_DA->SetBranchStatus("ele1_seedIphi",1);
  ntu_DA->SetBranchStatus("ele1_seedIx",1);
  ntu_DA->SetBranchStatus("ele1_seedIy",1);
  ntu_DA->SetBranchStatus("ele1_seedZside",1);
    
  ntu_DA->SetBranchAddress("runId", &runId);  
  ntu_DA->SetBranchAddress("timeStampHigh", &timeStampHigh);
  ntu_DA->SetBranchAddress("PV_n", &PV_n);
  ntu_DA->SetBranchAddress("ele1_scLaserCorr", &scLaserCorr);
  ntu_DA->SetBranchAddress("ele1_seedLaserAlpha", &seedLaserAlpha);
  ntu_DA->SetBranchAddress("ele1_EOverP", &EoP);
  ntu_DA->SetBranchAddress("ele1_scEta", &scEta);
  ntu_DA->SetBranchAddress("ele1_scPhi", &scPhi);
  if( useRegression < 1 )
    ntu_DA->SetBranchAddress("ele1_scE", &scE);
  else
    ntu_DA->SetBranchAddress("ele1_scE_regression", &scE);
  ntu_DA->SetBranchAddress("ele1_scE", &scE);
  ntu_DA->SetBranchAddress("ele1_es", &ES);
  ntu_DA->SetBranchAddress("ele1_tkP", &P);
  ntu_DA->SetBranchAddress("ele1_seedIeta", &seedIeta);
  ntu_DA->SetBranchAddress("ele1_seedIphi", &seedIphi);
  ntu_DA->SetBranchAddress("ele1_seedIx", &seedIx);
  ntu_DA->SetBranchAddress("ele1_seedIy", &seedIy);
  ntu_DA->SetBranchAddress("ele1_seedZside", &seedZside);
  
  
  ntu_MC->SetBranchStatus("*",0);
  ntu_MC->SetBranchStatus("runId",1);
  ntu_MC->SetBranchStatus("PV_n",1);
  ntu_MC->SetBranchStatus("ele1_scEta",1);
  ntu_MC->SetBranchStatus("ele1_EOverP",1);
  ntu_MC->SetBranchStatus("ele1_scE",1);
  ntu_MC->SetBranchStatus("ele1_scE_regression",1);
  ntu_MC->SetBranchStatus("ele1_es",1);
  ntu_MC->SetBranchStatus("ele1_tkP",1);
  ntu_MC->SetBranchStatus("ele1_seedIeta",1);
  ntu_MC->SetBranchStatus("ele1_seedIphi",1);
  ntu_MC->SetBranchStatus("ele1_seedIx",1);
  ntu_MC->SetBranchStatus("ele1_seedIy",1);
  ntu_MC->SetBranchStatus("ele1_seedZside",1);
  
  ntu_MC->SetBranchAddress("runId", &runId);  
  ntu_MC->SetBranchAddress("PV_n", &PV_n);
  ntu_MC->SetBranchAddress("ele1_scEta", &scEta);
  ntu_MC->SetBranchAddress("ele1_EOverP", &EoP);
  if( useRegression < 1 )
    ntu_MC->SetBranchAddress("ele1_scE", &scE);
  else
    ntu_MC->SetBranchAddress("ele1_scE_regression", &scE);
  ntu_MC->SetBranchAddress("ele1_es", &ES);
  ntu_MC->SetBranchAddress("ele1_tkP", &P);
  ntu_MC->SetBranchAddress("ele1_seedIeta", &seedIeta);
  ntu_MC->SetBranchAddress("ele1_seedIphi", &seedIphi);
  ntu_MC->SetBranchAddress("ele1_seedIx", &seedIx);
  ntu_MC->SetBranchAddress("ele1_seedIy", &seedIy);
  ntu_MC->SetBranchAddress("ele1_seedZside", &seedZside);
  
  
  
  
  
  
  //--------------------------------------------------------
  // Define PU correction (to be used if useRegression == 0)
  
  // corr = p0 + p1 * PV_n
  float p0_EB;
  float p1_EB;
  float p0_EE;
  float p1_EE;
  
  if( useRegression == 0 )
  {
    //2012 EB
    p0_EB = 0.9991;
    p1_EB = 0.0001635;
    //2012 EE
    p0_EE = 0.9968;
    p1_EE = 0.001046;
  }
  else
  {
    //2012 EB
    p0_EB = 1.001;
    p1_EB = -0.000143;
    //2012 EE
    p0_EE = 1.00327;
    p1_EE = -0.000432;
  }
  
  float p0 = -1.;
  float p1 = -1.;
  
  if( strcmp(EBEE,"EB") == 0 )
  {
    p0 = p0_EB;
    p1 = p1_EB;
  }
  else
  {
    p0 = p0_EE;
    p1 = p1_EE;
  }
  
  
  
  
  
  
  //---------------------------------
  // Build the reference distribution
  
  std::cout << std::endl;
  std::cout << "***** Build reference for " << EBEE << " *****" << std::endl;
  
  TH1F* h_template = new TH1F("template", "", 2000, 0., 5.);
  
  for(int ientry = 0; ientry < ntu_MC->GetEntries(); ++ientry)
  {
    if( (ientry%100000 == 0) ) std::cout << "reading MC entry " << ientry << "\r" << std::flush;
    ntu_MC->GetEntry(ientry);
    
    // selections
    if( (strcmp(EBEE,"EB") == 0) && (fabs(scEta) > 1.45) )                    continue; // barrel
    if( (strcmp(EBEE,"EE") == 0) && (fabs(scEta) < 1.47 || fabs(scEta)>2.7) ) continue; // endcap

    if( (absEtaMin != -1.) && (absEtaMax != -1.) )
    {
      if( (fabs(scEta) < absEtaMin) || (fabs(scEta) > absEtaMax) ) continue;
    }
    
    if( (IetaMin != -1.) && (IetaMax != -1.) && (IphiMin != -1.) && (IphiMax != -1.) )
    {
      if( (seedIeta < IetaMin) || (seedIeta > IetaMax) ) continue;
      if( (seedIphi < IphiMin) || (seedIphi > IphiMax) ) continue;
    }
    
    // PU correction
    float PUCorr = (p0 + p1*PV_n);
    //std::cout << "p0: " << p0  << "   p1: " << p1 << "   PV_n: " << PV_n << std::endl;
    
    // fill the template histogram
    h_template -> Fill( (scE-ES)/(P-ES) / PUCorr );
  }
  
  std::cout << "Reference built for " << EBEE << " - " << h_template->GetEntries() << " events" << std::endl;
  
  
  
  
  
  
  //---------------------
  // Loop and sort events
  
  std::cout << std::endl;
  std::cout << "***** Sort events and define bins *****" << std::endl;
  
  int nEntries = ntu_DA -> GetEntriesFast(); 
  int nSavePts = 0; 
  std::vector<bool> isSavedEntries(nEntries);
  std::vector<Sorter> sortedEntries;
  std::vector<int> timeStampFirst;
  
  for(int ientry = 0; ientry < nEntries; ++ientry)
  {
    ntu_DA -> GetEntry(ientry);
    isSavedEntries.at(ientry) = false;
    
    // selections
    if( (strcmp(EBEE,"EB") == 0) && (fabs(scEta) > 1.45) )                    continue; // barrel
    if( (strcmp(EBEE,"EE") == 0) && (fabs(scEta) < 1.47 || fabs(scEta)>2.7) ) continue; // endcap
    
    if( (absEtaMin != -1.) && (absEtaMax != -1.) )
    {
      if( (fabs(scEta) < absEtaMin) || (fabs(scEta) > absEtaMax) ) continue;
    }
    
    if( (IetaMin != -1.) && (IetaMax != -1.) && (IphiMin != -1.) && (IphiMax != -1.) )
    {
      if( (seedIeta < IetaMin) || (seedIeta > IetaMax) ) continue;
      if( (seedIphi < IphiMin) || (seedIphi > IphiMax) ) continue;
    }
    
    if( timeStampHigh < t1 ) continue;
    if( timeStampHigh > t2 ) continue;
    
    if( scLaserCorr <= 0. ) continue;
    
    isSavedEntries.at(ientry) = true;
    
    
    // fill sorter
    Sorter dummy;
    dummy.time = timeStampHigh;
    dummy.entry = ientry;
    sortedEntries.push_back(dummy);
    
    ++nSavePts;
  }
  
  // sort events
  std::sort(sortedEntries.begin(),sortedEntries.end(),Sorter());
  std::cout << "Data sorted in " << EBEE << " - " << nSavePts << " events" << std::endl;
  
  std::map<int,int> antiMap;
  for(unsigned int iSaved = 0; iSaved < sortedEntries.size(); ++iSaved)
    antiMap[sortedEntries.at(iSaved).entry] = iSaved;
  
  
  //---------------------
  // Loop and define bins
  
  // "wide" bins - find events with time separation bigger than 1 day
  int nWideBins = 1;
  std::vector<int> wideBinEntryMax;
  int timeStampOld = -1;
  
  wideBinEntryMax.push_back(0);  
  for(int iSaved = 0; iSaved < nSavePts; ++iSaved)
  {
    if( iSaved%100000 == 0 ) std::cout << "reading saved entry " << iSaved << "\r" << std::flush;
    ntu_DA->GetEntry(sortedEntries[iSaved].entry);  
    
    if( iSaved == 0 )
    {
      timeStampOld = timeStampHigh;
      continue;
    }
    
    if( (timeStampHigh-timeStampOld)/3600. > timeLapse )
    {
      ++nWideBins;
      wideBinEntryMax.push_back(iSaved-1);
    }
    
    timeStampOld = timeStampHigh;
  }
  std::cout << std::endl;
  wideBinEntryMax.push_back(nSavePts);
  
  
  // bins with approximatively evtsPerPoint events per bin
  int nBins = 0;
  std::vector<int> binEntryMax;
  
  binEntryMax.push_back(0);
  for(int wideBin = 0; wideBin < nWideBins; ++wideBin)
  {
    int nTempBins = std::max(1,int( (wideBinEntryMax.at(wideBin+1)-wideBinEntryMax.at(wideBin))/evtsPerPoint ));
    int nTempBinEntries = int( (wideBinEntryMax.at(wideBin+1)-wideBinEntryMax.at(wideBin))/nTempBins );
    
    for(int tempBin = 0; tempBin < nTempBins; ++tempBin)
    {
      ++nBins;
      if( tempBin < nTempBins - 1 )
        binEntryMax.push_back( wideBinEntryMax.at(wideBin) + (tempBin+1)*nTempBinEntries );
      else
        binEntryMax.push_back( wideBinEntryMax.at(wideBin+1) );
    }
  }
  
  std::cout << "nBins = " << nBins << std::endl;
  //for(int bin = 0; bin < nBins; ++bin)
  //  std::cout << "bin: " << bin
  //            << "   entry min: " << setw(6) << binEntryMax.at(bin)
  //            << "   entry max: " << setw(6) << binEntryMax.at(bin+1)
  //            << "   events: "    << setw(6) << binEntryMax.at(bin+1)-binEntryMax.at(bin)
  //            << std::endl;
  
  
  
  
  
  
  //---------------------
  // histogram definition
  
  TH1F* h_scOccupancy_eta  = new TH1F("h_scOccupancy_eta","", 298, -2.6, 2.6);
  TH1F* h_scOccupancy_phi  = new TH1F("h_scOccupancy_phi","", 363, -3.1765, 3.159);
  SetHistoStyle(h_scOccupancy_eta);
  SetHistoStyle(h_scOccupancy_phi);
  
  TH2F* h_seedOccupancy_EB  = new TH2F("h_seedOccupancy_EB","",  171, -85., 86., 361,   0.,361.);
  TH2F* h_seedOccupancy_EEp = new TH2F("h_seedOccupancy_EEp","", 101,   0.,101., 100,   0.,101.);
  TH2F* h_seedOccupancy_EEm = new TH2F("h_seedOccupancy_EEm","", 101,   0.,101., 100,   0.,101.);
  SetHistoStyle(h_seedOccupancy_EB);
  SetHistoStyle(h_seedOccupancy_EEp);
  SetHistoStyle(h_seedOccupancy_EEm);
  
  TH1F* h_EoP_spread = new TH1F("h_EoP_spread","",100,yMIN,yMAX);
  TH1F* h_EoC_spread = new TH1F("h_EoC_spread","",100,yMIN,yMAX);
  TH1F* h_EoP_spread_run = new TH1F("h_EoP_spread_run","",100,yMIN,yMAX);
  TH1F* h_EoC_spread_run = new TH1F("h_EoC_spread_run","",100,yMIN,yMAX);
  SetHistoStyle(h_EoP_spread,"EoP");
  SetHistoStyle(h_EoC_spread,"EoC");
  SetHistoStyle(h_EoP_spread_run,"EoP");
  SetHistoStyle(h_EoC_spread_run,"EoC");
  
  TH1F* h_EoP_chi2 = new TH1F("h_EoP_chi2","",50,0.,5.);
  TH1F* h_EoC_chi2 = new TH1F("h_EoC_chi2","",50,0.,5.);
  SetHistoStyle(h_EoP_chi2,"EoP");
  SetHistoStyle(h_EoC_chi2,"EoC");  
  
  TH1F** h_EoP = new TH1F*[nBins];
  TH1F** h_EoC = new TH1F*[nBins];
  TH1F** h_Las = new TH1F*[nBins];
  TH1F** h_Tsp = new TH1F*[nBins];
  TH1F** h_Cvl = new TH1F*[nBins];
  
  for(int i = 0; i < nBins; ++i)
  {
    char histoName[80];
    
    sprintf(histoName, "EoP_%d", i);
    h_EoP[i] = new TH1F(histoName, histoName, 2000, 0., 5.);
    SetHistoStyle(h_EoP[i],"EoP");
    
    sprintf(histoName, "EoC_%d", i);
    h_EoC[i] = new TH1F(histoName, histoName, 2000, 0., 5.);
    SetHistoStyle(h_EoC[i],"EoC");
    
    sprintf(histoName, "Las_%d", i);
    h_Las[i] = new TH1F(histoName, histoName, 500, 0.5, 1.5);
    
    sprintf(histoName, "Tsp_%d", i);
    h_Tsp[i] = new TH1F(histoName, histoName, 500, 0.5, 1.5);
  }
  
  
  // function definition
  TF1** f_EoP = new TF1*[nBins];
  TF1** f_EoC = new TF1*[nBins];
  
  
  // graphs definition
  TGraphAsymmErrors* g_fit   = new TGraphAsymmErrors();
  TGraphAsymmErrors* g_c_fit = new TGraphAsymmErrors();
  
  TGraphAsymmErrors* g_fit_run   = new TGraphAsymmErrors();
  TGraphAsymmErrors* g_c_fit_run = new TGraphAsymmErrors();  
  
  TGraph* g_las = new TGraph();
  
  TGraphErrors* g_LT = new TGraphErrors();
  
  g_fit->GetXaxis()->SetTimeFormat("%d/%m%F1970-01-01 00:00:00");
  g_fit->GetXaxis()->SetTimeDisplay(1);
  g_c_fit->GetXaxis()->SetTimeFormat("%d/%m%F1970-01-01 00:00:00");
  g_c_fit->GetXaxis()->SetTimeDisplay(1);
  g_las->GetXaxis()->SetTimeFormat("%d/%m%F1970-01-01 00:00:00");
  g_las->GetXaxis()->SetTimeDisplay(1);
  g_LT->GetXaxis()->SetTimeFormat("%d/%m%F1970-01-01 00:00:00");
  g_LT->GetXaxis()->SetTimeDisplay(1);
    
  
  
  
  
  
  //------------------------------------
  // loop on the saved and sorted events
  
  std::cout << std::endl;
  std::cout << "***** Fill and fit histograms *****" << std::endl;

  std::vector<int> Entries(nBins);  
  std::vector<double> AveTime(nBins);
  std::vector<int> MinTime(nBins);
  std::vector<int> MaxTime(nBins);
  std::vector<double> AveRun(nBins);    
  std::vector<int> MinRun(nBins);
  std::vector<int> MaxRun(nBins);
  std::vector<double> AveLT(nBins);
  std::vector<double> AveLT2(nBins);
    
  int iSaved = -1;
  for(int ientry = 0; ientry < nEntries; ++ientry)
  {
    if( (ientry%100000 == 0) ) std::cout << "reading entry " << ientry << "\r" << std::flush;
    
    if( isSavedEntries.at(ientry) == false ) continue;
    
    ++iSaved;
    
    int iSaved = antiMap[ientry];
    int bin = -1;
    for(bin = 0; bin < nBins; ++bin)
      if( iSaved >= binEntryMax.at(bin) && iSaved < binEntryMax.at(bin+1) )
	break;
    
    //std::cout << "bin = " << bin << "   iSaved = "<< iSaved << std::endl;
    ntu_DA->GetEntry(ientry);
    
    
    
    Entries[bin] += 1;
    
    if( iSaved == binEntryMax.at(bin)+1 )   MinTime[bin] = timeStampHigh;
    if( iSaved == binEntryMax.at(bin+1)-1 ) MaxTime[bin] = timeStampHigh;
    AveTime[bin] += timeStampHigh;
    
    if( iSaved == binEntryMax.at(bin)+1 )   MinRun[bin] = runId;
    if( iSaved == binEntryMax.at(bin+1)-1 ) MaxRun[bin] = runId;
    AveRun[bin] += runId;
    
    float LT = (-1. / seedLaserAlpha * log(scLaserCorr));
    AveLT[bin] += LT;
    AveLT2[bin] += LT*LT;
    
    // PU correction
    float PUCorr = (p0 + p1*PV_n);
    
    // fill the histograms
    (h_EoP[bin]) -> Fill( (scE-ES)/(P-ES) / scLaserCorr / PUCorr);
    (h_EoC[bin]) -> Fill( (scE-ES)/(P-ES) / PUCorr );
    
    (h_Las[bin]) -> Fill(scLaserCorr);
    (h_Tsp[bin]) -> Fill(1./scLaserCorr);
    
    h_scOccupancy_eta -> Fill(scEta);
    h_scOccupancy_phi -> Fill(scPhi);
    if(seedZside == 0)
      h_seedOccupancy_EB -> Fill(seedIeta,seedIphi);
    if(seedZside > 0)
      h_seedOccupancy_EEp -> Fill(seedIx,seedIy);
    if(seedZside < 0)
      h_seedOccupancy_EEm -> Fill(seedIx,seedIy);
  }
  
  for(int bin = 0; bin < nBins; ++bin)
  {
    AveTime[bin] = 1. * AveTime[bin] / (binEntryMax.at(bin+1)-binEntryMax.at(bin));
    AveRun[bin]  = 1. * AveRun[bin]  / (binEntryMax.at(bin+1)-binEntryMax.at(bin));
    AveLT[bin]   = 1. * AveLT[bin]   / (binEntryMax.at(bin+1)-binEntryMax.at(bin));
    AveLT2[bin]  = 1. * AveLT2[bin]  / (binEntryMax.at(bin+1)-binEntryMax.at(bin));
    //std::cout << date << " " << AveTime[i] << " " << MinTime[i] << " " << MaxTime[i] << std::endl;
  }
  
  
  
  
  
  
  int rebin = 2;
  if( strcmp(EBEE,"EE") == 0 ) rebin *= 2;
  
  h_template -> Rebin(rebin);
  
  
  
  float EoP_scale = 0.;
  float EoP_err = 0.;
  int   EoP_nActiveBins = 0;
  
  float EoC_scale = 0.;
  float EoC_err = 0.;
  int   EoC_nActiveBins = 0;
  
  float LCInv_scale = 0;
  
  std::vector<int> validBins;
  for(int i = 0; i < nBins; ++i)
  {
    bool isValid = true;
    
    h_EoP[i] -> Rebin(rebin);
    h_EoC[i] -> Rebin(rebin);
    
    
    
    //------------------------------------
    // Fill the graph for uncorrected data
    
    // define the fitting function
    // N.B. [0] * ( [1] * f( [1]*(x-[2]) ) )
    
    //o -> cd();
    char convolutionName[50];
    sprintf(convolutionName,"h_convolution_%d",i);
    //h_Cvl[i] = ConvoluteTemplate(std::string(convolutionName),h_template,h_Las[i],32768,-5.,5.);
    h_Cvl[i] = MellinConvolution(std::string(convolutionName),h_template,h_Tsp[i]);
    
    histoFunc* templateHistoFunc = new histoFunc(h_template);
    histoFunc* templateConvolutedHistoFunc = new histoFunc(h_Cvl[i]);
    char funcName[50];

    sprintf(funcName,"f_EoP_%d",i);
    
    if( strcmp(EBEE,"EB") == 0 )
      f_EoP[i] = new TF1(funcName, templateConvolutedHistoFunc, 0.8*(h_Tsp[i]->GetMean()), 1.4*(h_Tsp[i]->GetMean()), 3, "histoFunc");
    else
      f_EoP[i] = new TF1(funcName, templateConvolutedHistoFunc, 0.75*(h_Tsp[i]->GetMean()), 1.5*(h_Tsp[i]->GetMean()), 3, "histoFunc");
    
    f_EoP[i] -> SetParName(0,"Norm"); 
    f_EoP[i] -> SetParName(1,"Scale factor"); 
    f_EoP[i] -> SetLineWidth(1); 
    f_EoP[i] -> SetNpx(10000);
    
    double xNorm = h_EoP[i]->GetEntries()/h_template->GetEntries() *
      h_EoP[i]->GetBinWidth(1)/h_template->GetBinWidth(1); 
    
    f_EoP[i] -> FixParameter(0, xNorm);
    f_EoP[i] -> SetParameter(1, 1.);
    f_EoP[i] -> FixParameter(2, 0.);
    f_EoP[i] -> SetLineColor(kRed+2); 
    
    int fStatus = 0;
    int nTrials = 0;
    TFitResultPtr rp;
    
    rp = h_EoP[i] -> Fit(funcName, "QERLS+");
    while( (fStatus != 0) && (nTrials < 10) )
    {
      rp = h_EoP[i] -> Fit(funcName, "QERLS+");
      fStatus = rp;
      if(fStatus == 0) break;
      ++nTrials;
    }
    
    // fill the graph
    double eee = f_EoP[i]->GetParError(1);
    //float k    = f_EoP[i]->GetParameter(1);
    float k    = f_EoP[i]->GetParameter(1) / h_Tsp[i]->GetMean(); //needed when using mellin's convolution 
    
    if( (h_EoP[i]->GetEntries() > 3) && (fStatus == 0) && (eee > 0.05*h_template->GetRMS()/sqrt(evtsPerPoint)) )
    {
      float date = (float)AveTime[i];
      float dLow = (float)(AveTime[i]-MinTime[i]); 
      float dHig = (float)(MaxTime[i]-AveTime[i]);
      float run = (float)AveRun[i];
      float rLow = (float)(AveRun[i]-MinRun[i]); 
      float rHig = (float)(MaxRun[i]-AveRun[i]);
      
      g_fit -> SetPoint(i,  date , 1./k);
      g_fit -> SetPointError(i, dLow , dHig, eee/k/k, eee/k/k);
      
      g_fit_run -> SetPoint(i,  run , 1./k);
      g_fit_run -> SetPointError(i, rLow , rHig, eee/k/k, eee/k/k);
      
      h_EoP_chi2 -> Fill(f_EoP[i]->GetChisquare()/f_EoP[i]->GetNDF());
      
      EoP_scale += 1./k;
      EoP_err += eee/k/k;
      ++EoP_nActiveBins;
    }
    else
    {
      std::cout << "Fitting uncorrected time bin: " << i << "   Fail status: " << fStatus << "   sigma: " << eee << std::endl;
      isValid = false;
    }  
    
    //----------------------------------
    // Fill the graph for corrected data
    
    // define the fitting function
    // N.B. [0] * ( [1] * f( [1]*(x-[2]) ) )

    sprintf(funcName,"f_EoC_%d",i);
    if( strcmp(EBEE,"EB") == 0 )
      f_EoC[i] = new TF1(funcName, templateHistoFunc, 0.8, 1.4, 3, "histoFunc");
    else
      f_EoC[i] = new TF1(funcName, templateHistoFunc, 0.75, 1.5, 3, "histoFunc");
    f_EoC[i] -> SetParName(0,"Norm"); 
    f_EoC[i] -> SetParName(1,"Scale factor"); 
    f_EoC[i] -> SetLineWidth(1); 
    f_EoC[i] -> SetNpx(10000);
    
    xNorm = h_EoC[i]->GetEntries()/h_template->GetEntries() *
            h_EoC[i]->GetBinWidth(1)/h_template->GetBinWidth(1); 

    f_EoC[i] -> FixParameter(0, xNorm);
    f_EoC[i] -> SetParameter(1, 0.99);
    f_EoC[i] -> FixParameter(2, 0.);
    f_EoC[i] -> SetLineColor(kGreen+2); 
    
    
    rp = h_EoC[i] -> Fit(funcName, "QERLS+");
    fStatus = rp;
    nTrials = 0;
    while( (fStatus != 0) && (nTrials < 10) )
    {
      rp = h_EoC[i] -> Fit(funcName, "QERLS+");
      fStatus = rp;
      if(fStatus == 0) break;
      ++nTrials;
    }
    
    // fill the graph
    k   = f_EoC[i]->GetParameter(1);
    eee = f_EoC[i]->GetParError(1); 
    
    if( (h_EoC[i]->GetEntries() > 10) && (fStatus == 0) && (eee > 0.05*h_template->GetRMS()/sqrt(evtsPerPoint)) )
    {
      float date = (float)AveTime[i]; 
      float dLow = (float)(AveTime[i]-MinTime[i]); 
      float dHig = (float)(MaxTime[i]-AveTime[i]);
      float run = (float)AveRun[i];
      float rLow = (float)(AveRun[i]-MinRun[i]); 
      float rHig = (float)(MaxRun[i]-AveRun[i]);
      
      g_c_fit -> SetPoint(i,  date , 1./k);
      g_c_fit -> SetPointError(i, dLow , dHig , eee/k/k, eee/k/k);
      
      g_c_fit_run -> SetPoint(i,  run , 1./k);
      g_c_fit_run -> SetPointError(i, rLow , rHig, eee/k/k, eee/k/k);
      
      h_EoC_chi2 -> Fill(f_EoC[i]->GetChisquare()/f_EoP[i]->GetNDF());
      
      EoC_scale += 1./k;
      EoC_err += eee/k/k;
      ++EoC_nActiveBins;
    }
    else
    {
      std::cout << "Fitting corrected time bin: " << i << "   Fail status: " << fStatus << "   sigma: " << eee << std::endl;
      isValid = false;
    }
    
    if( isValid == true ) validBins.push_back(i);
  }
  
  EoP_scale /= EoP_nActiveBins;
  EoP_err   /= EoP_nActiveBins;
  
  EoC_scale /= EoC_nActiveBins;
  EoC_err   /= EoC_nActiveBins;
  
  
  
  
  
  
  //----------------------------------------
  // Fill the graph for avg laser correction
  
  //fede
  for(unsigned int itr = 0; itr < validBins.size(); ++itr)
  {  
    int i = validBins.at(itr);
    g_las -> SetPoint(itr, (float)AveTime[i], h_Tsp[i]->GetMean() );
    g_LT  -> SetPoint(itr, (float)AveTime[i], AveLT[i] );
    g_LT  -> SetPointError(itr, 0., sqrt(AveLT2[i]-AveLT[i]*AveLT[i]) / sqrt(Entries[i]) );
        
    LCInv_scale += h_Tsp[i]->GetMean();
  }  
  
  LCInv_scale /= validBins.size();
  
  
  
  
  
  
  //---------------
  // Rescale graphs
  
  float yscale = 1.;
  //float yscale = 1./EoC_scale;
  
  for(unsigned int itr = 0; itr < validBins.size(); ++itr)
  {
    double x,y; 
    g_fit -> GetPoint(itr,x,y); 
    g_fit -> SetPoint(itr,x,y*yscale);
    if ( (x > t1) && (x < t2) ) h_EoP_spread -> Fill(y*yscale);
    
    g_c_fit -> GetPoint(itr,x,y); 
    g_c_fit -> SetPoint(itr,x,y*yscale);
    if ( (x > t1) && (x < t2) ) h_EoC_spread -> Fill(y*yscale);
    
    g_fit_run -> GetPoint(itr,x,y); 
    g_fit_run -> SetPoint(itr,x,y*yscale); 
    if ( (x > t1) && (x < t2) ) h_EoP_spread_run -> Fill(y*yscale);
    
    g_c_fit_run -> GetPoint(itr,x,y); 
    g_c_fit_run -> SetPoint(itr,x,y*yscale);
    if ( (x > t1) && (x < t2) ) h_EoC_spread_run -> Fill(y*yscale);
    
    g_las -> GetPoint(itr,x,y);
    g_las -> SetPoint(itr,x,y*yscale*EoP_scale/LCInv_scale);
  }
  
  TF1 EoC_pol0("EoC_pol0","pol0",t1,t2);
  EoC_pol0.SetLineColor(kGreen+2);
  EoC_pol0.SetLineWidth(2);
  EoC_pol0.SetLineStyle(2);
  g_c_fit -> Fit("EoC_pol0","QNR");
  
  
  
  
  
  
  
  
  //----------------------------
  // Print out global quantities
  
  std::cout << std::endl;
  std::cout << "***** Mean scales and errors *****" << std::endl; 
  std::cout << std::fixed;
  std::cout << std::setprecision(4);
  std::cout << "Mean EoP scale: "  << std::setw(6) << EoP_scale   << "   mean EoP error: " << std::setw(8) << EoP_err << std::endl;
  std::cout << "Mean EoC scale: "  << std::setw(6) << EoC_scale   << "   mean EoC error: " << std::setw(8) << EoC_err << std::endl;
  std::cout << "Mean 1/LC scale: " << std::setw(6) << LCInv_scale << std::endl;
  
  
  
  
  
  
  //-----------------
  // Occupancy plots
  //-----------------
  
  TCanvas* c_scOccupancy = new TCanvas("c_scOccupancy","SC occupancy",0,0,1000,500);
  c_scOccupancy -> Divide(2,1);
  
  c_scOccupancy -> cd(1);
  h_scOccupancy_eta -> GetXaxis() -> SetTitle("sc #eta");
  h_scOccupancy_eta -> GetYaxis() -> SetTitle("events");
  h_scOccupancy_eta -> Draw();
  
  c_scOccupancy -> cd(2);
  h_scOccupancy_phi -> GetXaxis() -> SetTitle("sc #phi");
  h_scOccupancy_phi -> GetYaxis() -> SetTitle("events");
  h_scOccupancy_phi -> Draw();
  
  TCanvas* c_seedOccupancy = new TCanvas("c_seedOccupancy","seed occupancy",0,0,1500,500);
  c_seedOccupancy -> Divide(3,1);
  
  c_seedOccupancy -> cd(1);
  h_seedOccupancy_EB -> GetXaxis() -> SetTitle("seed i#eta");
  h_seedOccupancy_EB -> GetYaxis() -> SetTitle("seed i#phi");
  h_seedOccupancy_EB -> Draw("COLZ");
  
  c_seedOccupancy -> cd(2);
  h_seedOccupancy_EEp -> GetXaxis() -> SetTitle("seed ix");
  h_seedOccupancy_EEp -> GetYaxis() -> SetTitle("seed iy");
  h_seedOccupancy_EEp -> Draw("COLZ");
  
  c_seedOccupancy -> cd(3);
  h_seedOccupancy_EEm -> GetXaxis() -> SetTitle("seed ix");
  h_seedOccupancy_EEm -> GetYaxis() -> SetTitle("seed iy");
  h_seedOccupancy_EEm -> Draw("COLZ");
  
  
  
  //-----------
  // Chi2 plots
  //-----------
  
  TCanvas* c_chi2 = new TCanvas("c_chi2","fit chi2",0,0,500,500);
  c_chi2 -> cd();
  
  h_EoC_chi2 -> GetXaxis() -> SetTitle("#chi^{2}/N_{dof}");
  h_EoC_chi2 -> Draw("");
  gPad -> Update();
    
  TPaveStats* s_EoC = new TPaveStats;
  s_EoC = (TPaveStats*)(h_EoC_chi2->GetListOfFunctions()->FindObject("stats"));
  s_EoC -> SetStatFormat("1.4g");
  s_EoC -> SetTextColor(kGreen+2);
  s_EoC->SetY1NDC(0.59);
  s_EoC->SetY2NDC(0.79);
  s_EoC -> Draw("sames");
  gPad -> Update();
  
  h_EoP_chi2 -> GetXaxis() -> SetTitle("#chi^{2}/N_{dof}");
  h_EoP_chi2 -> Draw("sames");
  gPad -> Update();
  
  TPaveStats* s_EoP = new TPaveStats;
  s_EoP = (TPaveStats*)(h_EoP_chi2->GetListOfFunctions()->FindObject("stats"));
  s_EoP -> SetStatFormat("1.4g");
  s_EoP -> SetTextColor(kRed+2);
  s_EoP->SetY1NDC(0.79);
  s_EoP->SetY2NDC(0.99);
  s_EoP -> Draw("sames");
  gPad -> Update();
  
  
  
  
  
  
  //-------------------
  // Final plot vs date
  //-------------------
  
  TCanvas* cplot = new TCanvas("cplot", "history plot vs date",100,100,1000,500);
  cplot->cd();

  TPad *cLeft  = new TPad("pad_0","pad_0",0.00,0.00,0.75,1.00);
  TPad *cRight = new TPad("pad_1","pad_1",0.75,0.00,1.00,1.00);

  cLeft->SetLeftMargin(0.15); 
  cLeft->SetRightMargin(0.025); 
  cRight->SetLeftMargin(0.025); 

  cLeft->Draw();
  cRight->Draw();

  float tYoffset = 1.0; 
  float labSize = 0.05;
  float labSize2 = 0.06;

  cLeft->cd(); 
  
  cLeft->SetGridx();
  cLeft->SetGridy();
  
  TH1F *hPad = (TH1F*)gPad->DrawFrame(t1,0.9,t2,1.05);
  hPad->GetXaxis()->SetTimeFormat("%d/%m%F1970-01-01 00:00:00");
  hPad->GetXaxis()->SetTimeDisplay(1);
  hPad->GetXaxis() -> SetRangeUser(MinTime[0]-43200,MaxTime[nBins-1]+43200);
  hPad->GetXaxis()->SetTitle("date (day/month)");
  if( strcmp(EBEE,"EB") == 0 )
    hPad->GetYaxis()->SetTitle("Relative E/p scale"); 
  else
    hPad->GetYaxis()->SetTitle("Relative E/p scale"); 
  hPad->GetYaxis()->SetTitleOffset(tYoffset);
  hPad->GetXaxis()->SetLabelSize(labSize);
  hPad->GetXaxis()->SetTitleSize(labSize2);
  hPad->GetYaxis()->SetLabelSize(labSize);
  hPad->GetYaxis()->SetTitleSize(labSize2);
  hPad -> SetMinimum(yMIN);
  hPad -> SetMaximum(yMAX);
  
  // draw history plot
  g_fit -> SetMarkerStyle(24);
  g_fit -> SetMarkerSize(0.7);
  g_fit -> SetMarkerColor(kRed+2);
  g_fit -> SetLineColor(kRed+2);
  g_fit -> Draw("P");
  g_c_fit -> SetMarkerStyle(20);
  g_c_fit -> SetMarkerColor(kGreen+2);
  g_c_fit -> SetLineColor(kGreen+2);
  g_c_fit -> SetMarkerSize(0.7);
  g_c_fit -> Draw("P,same");
  g_las -> SetLineColor(kAzure-2);
  g_las -> SetLineWidth(2);
  g_las -> Draw("L,same");
  
  TLegend* legend = new TLegend(0.60,0.78,0.90,0.94);
  legend -> SetLineColor(kWhite);
  legend -> SetLineWidth(0);
  legend -> SetFillColor(kWhite);
  legend -> SetFillStyle(0);
  legend -> SetTextFont(42);
  legend -> SetTextSize(0.04);
  legend -> AddEntry(g_c_fit,"with LM correction","PL");
  legend -> AddEntry(g_fit,  "without LM correction","PL");
  legend -> AddEntry(g_las,  "1 / LM correction","L");
  legend -> Draw("same");
  
  char latexBuffer[250];
  
  sprintf(latexBuffer,"CMS 2012 Preliminary");
  TLatex* latex = new TLatex(0.18,0.89,latexBuffer);  
  latex -> SetNDC();
  latex -> SetTextFont(62);
  latex -> SetTextSize(0.05);
  latex -> Draw("same");
  
  //sprintf(latexBuffer,"#sqrt{s} = 8 TeV   L = 3.95 fb^{-1}");
  sprintf(latexBuffer,"#sqrt{s} = 8 TeV");
  TLatex* latex2 = new TLatex(0.18,0.84,latexBuffer);  
  latex2 -> SetNDC();
  latex2 -> SetTextFont(42);
  latex2 -> SetTextSize(0.05);
  latex2 -> Draw("same");
  
  if( strcmp(EBEE,"EB") == 0 )
    sprintf(latexBuffer,"ECAL Barrel");
  else
    sprintf(latexBuffer,"ECAL Endcap");
  TLatex* latex3 = new TLatex(0.18,0.19,latexBuffer);
  latex3 -> SetNDC();
  latex3 -> SetTextFont(42);
  latex3 -> SetTextSize(0.05);
  latex3 -> Draw("same");
  
  //sprintf(latexBuffer,"%.2E events",1.*nSavePts);
  //TLatex* latex4 = new TLatex(0.18,0.24,latexBuffer);  
  //latex4 -> SetNDC();
  //latex4 -> SetTextFont(42);
  //latex4 -> SetTextSize(0.04);
  //latex4 -> Draw("same");
  //
  //sprintf(latexBuffer,"%d events/bin - %d bins",evtsPerPoint,nBins);
  //TLatex* latex5 = new TLatex(0.18,0.19,latexBuffer);  
  //latex5 -> SetNDC();
  //latex5 -> SetTextFont(42);
  //latex5 -> SetTextSize(0.04);
  //latex5 -> Draw("same");
  
  
  cRight -> cd();
  
  TPaveStats* s_EoP_spread = new TPaveStats();
  TPaveStats* s_EoC_spread = new TPaveStats();
  
  
  h_EoC_spread -> SetFillStyle(3001);
  h_EoC_spread -> SetFillColor(kGreen+2);
  h_EoC_spread->GetYaxis()->SetLabelSize(0.09);
  h_EoC_spread->GetYaxis()->SetLabelOffset(-0.03);
  h_EoC_spread->GetYaxis()->SetTitleSize(0.08);
  h_EoC_spread->GetYaxis()->SetNdivisions(505);
  h_EoC_spread->GetXaxis()->SetLabelOffset(1000);
  
  h_EoC_spread -> Draw("hbar");
  gPad -> Update();
  
  s_EoC_spread = (TPaveStats*)(h_EoC_spread->GetListOfFunctions()->FindObject("stats"));
  s_EoC_spread -> SetStatFormat("1.4g");
  s_EoC_spread->SetX1NDC(0.06); //new x start position
  s_EoC_spread->SetX2NDC(0.71); //new x end position
  s_EoC_spread->SetY1NDC(0.93); //new x start position
  s_EoC_spread->SetY2NDC(0.84); //new x end position
  s_EoC_spread -> SetOptStat(1100);
  s_EoC_spread ->SetTextColor(kGreen+2);
  s_EoC_spread ->SetTextSize(0.08);
  s_EoC_spread -> Draw("sames");
  
  
  h_EoP_spread -> SetFillStyle(3001);
  h_EoP_spread -> SetFillColor(kRed+2);
  h_EoP_spread -> Draw("hbarsames");
  gPad -> Update();
  s_EoP_spread = (TPaveStats*)(h_EoP_spread->GetListOfFunctions()->FindObject("stats"));
  s_EoP_spread -> SetStatFormat("1.4g");
  s_EoP_spread->SetX1NDC(0.06); //new x start position
  s_EoP_spread->SetX2NDC(0.71); //new x end position
  s_EoP_spread->SetY1NDC(0.83); //new x start position
  s_EoP_spread->SetY2NDC(0.74); //new x end position
  s_EoP_spread ->SetOptStat(1100);
  s_EoP_spread ->SetTextColor(kRed+2);
  s_EoP_spread ->SetTextSize(0.08);
  s_EoP_spread -> Draw("sames");
  
  /*
  h_EoP_spread -> SetFillStyle(3001);
  h_EoP_spread -> SetFillColor(kRed+2);
  h_EoP_spread -> Draw("hbarsame");
  gPad -> Update();
  */
  
  
  
  //------------------
  // Final plot vs run
  //------------------
  
  TCanvas* cplot_run = new TCanvas("cplot_run", "history plot vs run",100,100,1000,500);
  cplot_run->cd();
  
  cLeft  = new TPad("pad_0_run","pad_0_run",0.00,0.00,0.75,1.00);
  cRight = new TPad("pad_1_run","pad_1_run",0.75,0.00,1.00,1.00);

  cLeft->SetLeftMargin(0.15); 
  cLeft->SetRightMargin(0.025); 
  cRight->SetLeftMargin(0.025); 

  cLeft->Draw();
  cRight->Draw();

  tYoffset = 1.5; 
  labSize = 0.04;
  labSize2 = 0.07;

  cLeft->cd(); 

  cLeft->SetGridx();
  cLeft->SetGridy();
  
  hPad = (TH1F*)gPad->DrawFrame(MinRun[0]-1000,0.9,MaxRun[nBins-1]+1000,1.05);
  hPad->GetXaxis()->SetTitle("run");
  if( strcmp(EBEE,"EB") == 0 )
    hPad->GetYaxis()->SetTitle("Relative E/p scale"); 
  else
    hPad->GetYaxis()->SetTitle("Relative E/p scale"); 
  hPad->GetYaxis()->SetTitleOffset(tYoffset);
  hPad->GetXaxis()->SetLabelSize(labSize);
  hPad->GetXaxis()->SetTitleSize(labSize);
  hPad->GetYaxis()->SetLabelSize(labSize);
  hPad->GetYaxis()->SetTitleSize(labSize);
  hPad -> SetMinimum(yMIN);
  hPad -> SetMaximum(yMAX);
  
  // draw history plot
  g_fit_run -> SetMarkerStyle(20);
  g_fit_run -> SetMarkerSize(0.7);
  g_fit_run -> SetMarkerColor(kRed+2);
  g_fit_run -> SetLineColor(kRed+2);
  g_fit_run -> Draw("P");
  g_c_fit_run -> SetMarkerStyle(20);
  g_c_fit_run -> SetMarkerColor(kGreen+2);
  g_c_fit_run -> SetLineColor(kGreen+2);
  g_c_fit_run -> SetMarkerSize(0.7);
  g_c_fit_run -> Draw("P,same");
  
  
  cRight -> cd();
  
  s_EoP_spread = new TPaveStats();
  s_EoC_spread = new TPaveStats();
  
  
  h_EoC_spread_run -> SetFillStyle(3001);
  h_EoC_spread_run -> SetFillColor(kGreen+2);
  h_EoC_spread_run->GetYaxis()->SetLabelSize(labSize2);
  h_EoC_spread_run->GetYaxis()->SetTitleSize(labSize2);
  h_EoC_spread_run->GetYaxis()->SetNdivisions(505);
  h_EoC_spread_run->GetYaxis()->SetLabelOffset(-0.02);
  h_EoC_spread_run->GetXaxis()->SetLabelOffset(1000);

  h_EoC_spread_run -> Draw("hbar");
  gPad -> Update();
  
  s_EoC_spread = (TPaveStats*)(h_EoC_spread_run->GetListOfFunctions()->FindObject("stats"));
  s_EoC_spread ->SetTextColor(kGreen+2);
  s_EoC_spread ->SetTextSize(0.06);
  s_EoC_spread->SetX1NDC(0.49); //new x start position
  s_EoC_spread->SetX2NDC(0.99); //new x end position
  s_EoC_spread->SetY1NDC(0.875); //new x start position
  s_EoC_spread->SetY2NDC(0.990); //new x end position
  s_EoC_spread -> SetOptStat(1100);
  s_EoC_spread -> Draw("sames");

  h_EoP_spread_run -> SetFillStyle(3001);
  h_EoP_spread_run -> SetFillColor(kRed+2);
  h_EoP_spread_run -> Draw("hbarsames");
  gPad -> Update();
  
  s_EoP_spread = (TPaveStats*)(h_EoP_spread_run->GetListOfFunctions()->FindObject("stats"));
  s_EoP_spread->SetX1NDC(0.49); //new x start position
  s_EoP_spread->SetX2NDC(0.99); //new x end position
  s_EoP_spread->SetY1NDC(0.750); //new x start position
  s_EoP_spread->SetY2NDC(0.875); //new x end position
  s_EoP_spread ->SetOptStat(1100);
  s_EoP_spread ->SetTextColor(kRed+2);
  s_EoP_spread ->SetTextSize(0.06);
  s_EoP_spread -> Draw("sames");
  
  
  
  
  
  
  c_chi2 -> Print((folderName+"/"+folderName+"_fitChi2.png").c_str(),"png");
  c_scOccupancy -> Print((folderName+"/"+folderName+"_scOccupancy.png").c_str(),"png");
  c_seedOccupancy -> Print((folderName+"/"+folderName+"_seedOccupancy.png").c_str(),"png");
  cplot -> Print((folderName+"/"+folderName+"_history_vsTime.png").c_str(),"png");
  cplot_run -> Print((folderName+"/"+folderName+"_history_vsRun.png").c_str(),"png");
  
  c_chi2 -> Print((folderName+"/"+folderName+"_fitChi2.pdf").c_str(),"pdf");
  c_scOccupancy -> Print((folderName+"/"+folderName+"_scOccupancy.pdf").c_str(),"pdf");
  c_seedOccupancy -> Print((folderName+"/"+folderName+"_seedOccupancy.pdf").c_str(),"pdf");
  cplot -> Print((folderName+"/"+folderName+"_history_vsTime.pdf").c_str(),"pdf");
  cplot_run -> Print((folderName+"/"+folderName+"_history_vsRun.pdf").c_str(),"pdf");
  
  cplot -> SaveAs((folderName+"/"+folderName+"_history_vsTime.C").c_str());
  cplot_run -> SaveAs((folderName+"/"+folderName+"_history_vsRun.C").c_str());
  
  
  
   o -> cd();
  
   h_template -> Write();

   h_scOccupancy_eta   -> Write();
   h_scOccupancy_phi   -> Write();
   h_seedOccupancy_EB  -> Write(); 
   h_seedOccupancy_EEp -> Write();
   h_seedOccupancy_EEm -> Write();

   g_fit   -> Write("g_fit");
   g_c_fit -> Write("g_c_fit");
   g_fit_run   -> Write("g_fit_run");
   g_c_fit_run -> Write("g_c_fit_run");
   g_las -> Write("g_las");
   g_LT -> Write("g_LT");
   
   h_EoP_chi2 -> Write();
   h_EoC_chi2 -> Write();
  
   //for(int i = 0; i < nBins; ++i)
   //{
   //  h_EoP[i] -> GetXaxis() -> SetTitle("E/p");
   //  h_EoP[i] -> Write();
   //
   //  h_EoC[i] -> GetXaxis() -> SetTitle("E/p");
   //  h_EoC[i] -> Write();
   //
   //  h_Tsp[i] -> Write();
   //
   //  h_Cvl[i] -> Write();
   //}

  o -> Close();
}