void genAnalysis(
 Int_t period = 1
 ){

  TString filesPath  = "/scratch5/ceballos/ntuples_noweights/";
  Double_t lumi = 0.0715;
  if(period == 1) lumi = 2.2;

  //*******************************************************
  //Input Files
  //*******************************************************
  vector<TString> infilenamev;  
  vector<Int_t> infilecatv;  

  TString puPath = "";
  if      (period==0){
  puPath = "/home/ceballos/cms/cmssw/042/CMSSW_7_4_6/src/MitAnalysisRunII/data/puWeights_13TeV_50ns.root";
  //infilenamev.push_back(Form("%sdata_AOD_50ns.root",filesPath.Data()));														  infilecatv.push_back(0);
  infilenamev.push_back(Form("%sWWTo2L2Nu_13TeV-powheg+RunIISpring15DR74-Asympt50ns_MCRUN2_74_V9A-v2+AODSIM.root",filesPath.Data()));						  infilecatv.push_back(1);
  //infilenamev.push_back(Form("%sDYJetsToLL_M-10to50_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt50ns_MCRUN2_74_V9A-v1+AODSIM.root",filesPath.Data()));	  infilecatv.push_back(2);
  //infilenamev.push_back(Form("%sDYJetsToLL_M-50_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt50ns_MCRUN2_74_V9A-v2+AODSIM.root",filesPath.Data()));  	  infilecatv.push_back(2);
  //infilenamev.push_back(Form("%sTTTo2L2Nu_13TeV-powheg+RunIISpring15DR74-Asympt50ns_MCRUN2_74_V9A-v2+AODSIM.root",filesPath.Data()));						  infilecatv.push_back(3);
  //infilenamev.push_back(Form("%sST_tW_antitop_5f_inclusiveDecays_13TeV-powheg-pythia8_TuneCUETP8M1+RunIISpring15DR74-Asympt50ns_MCRUN2_74_V9A-v2+AODSIM.root",filesPath.Data())); infilecatv.push_back(3);
  //infilenamev.push_back(Form("%sWZ_TuneCUETP8M1_13TeV-pythia8+RunIISpring15DR74-Asympt50ns_MCRUN2_74_V9A-v2+AODSIM.root",filesPath.Data()));					  infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sZZ_TuneCUETP8M1_13TeV-pythia8+RunIISpring15DR74-Asympt50ns_MCRUN2_74_V9A-v2+AODSIM.root",filesPath.Data()));					  infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sWJetsToLNu_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt50ns_MCRUN2_74_V9A-v1+AODSIM.root",filesPath.Data()));		  infilecatv.push_back(5);
  }
  else if(period==1){
  puPath = "/home/ceballos/cms/cmssw/042/CMSSW_7_4_6/src/MitAnalysisRunII/data/puWeights_13TeV_25ns.root";
  //infilenamev.push_back(Form("%sdata_AOD_25ns.root",filesPath.Data()));														  infilecatv.push_back(0);
  infilenamev.push_back(Form("%sWWTo2L2Nu_13TeV-powheg+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));						  infilecatv.push_back(1);
  //infilenamev.push_back(Form("%sDYJetsToLL_M-10to50_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));	  //infilecatv.push_back(2);
  //infilenamev.push_back(Form("%sDYJetsToLL_M-50_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v3+AODSIM.root",filesPath.Data()));  	          //infilecatv.push_back(2);
  //infilenamev.push_back(Form("%sTTTo2L2Nu_13TeV-powheg+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));						  infilecatv.push_back(3);
  //infilenamev.push_back(Form("%sST_tW_top_5f_//inclusiveDecays_13TeV-powheg-pythia8_TuneCUETP8M1+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));      //infilecatv.push_back(3);
  //infilenamev.push_back(Form("%sST_tW_antitop_5f_//inclusiveDecays_13TeV-powheg-pythia8_TuneCUETP8M1+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));  //infilecatv.push_back(3);
  //infilenamev.push_back(Form("%sZZTo2L2Nu_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));					  //infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sZZTo2L2Q_13TeV_amcatnloFXFX_madsp//in_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		          //infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sZZTo4L_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));					  //infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sWZTo1L1Nu2Q_13TeV_amcatnloFXFX_madsp//in_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			  //infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sWZTo2L2Q_13TeV_amcatnloFXFX_madsp//in_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v2+AODSIM.root",filesPath.Data()));			  //infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sWZTo3LNu_TuneCUETP8M1_13TeV-powheg-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			  //infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sWZZ_TuneCUETP8M1_13TeV-amcatnlo-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));				  //infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sTTWJetsToLNu_TuneCUETP8M1_13TeV-amcatnloFXFX-madsp//in-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));	  //infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sTTWJetsToQQ_TuneCUETP8M1_13TeV-amcatnloFXFX-madsp//in-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));	  //infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sTTZToLLNuNu_M-10_TuneCUETP8M1_13TeV-amcatnlo-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		  //infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sTTZToQQ_TuneCUETP8M1_13TeV-amcatnlo-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		          //infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sTTGJets_TuneCUETP8M1_13TeV-amcatnloFXFX-madsp//in-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		  //infilecatv.push_back(4);
  //infilenamev.push_back(Form("%sWJetsToLNu_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		  //infilecatv.push_back(5);
  //infilenamev.push_back(Form("%sWGToLNuG_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));                     //infilecatv.push_back(6);
  //infilenamev.push_back(Form("%sGluGluHToWWTo2L2Nu_M125_13TeV_amcatnloFXFX_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		  //infilecatv.push_back(7);
  //infilenamev.push_back(Form("%sVBFHToWWTo2L2Nu_M125_13TeV_powheg_JHUgen_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		          //infilecatv.push_back(7);
  //infilenamev.push_back(Form("%sHWm//inusJ_HToWW_M125_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		                  //infilecatv.push_back(7);
  //infilenamev.push_back(Form("%sHWplusJ_HToWW_M125_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		                  //infilecatv.push_back(7);
  //infilenamev.push_back(Form("%sHZJ_HToWW_M125_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		                  //infilecatv.push_back(7);
  //infilenamev.push_back(Form("%sGluGluZH_HToWW_M125_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		                  //infilecatv.push_back(7);
  //infilenamev.push_back(Form("%sGluGluHToTauTau_M125_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		                  //infilecatv.push_back(7);
  //infilenamev.push_back(Form("%sVBFHToTauTau_M125_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		                  //infilecatv.push_back(7);
  //infilenamev.push_back(Form("%sWplusHToTauTau_M125_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		                  //infilecatv.push_back(7);
  //infilenamev.push_back(Form("%sWm//inusHToTauTau_M125_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		                  //infilecatv.push_back(7);
  //infilenamev.push_back(Form("%sttHJetToNonbb_M125_13TeV_amcatnloFXFX_madsp//in_pythia8_mWCutfix+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));      //infilecatv.push_back(7);
  }
  else {assert(0);}
  
  //infilenamev.clear();infilecatv.clear();
  //infilenamev.push_back(Form("/scratch5/ceballos/test/test.root"));   infilecatv.push_back(1);

  if(infilenamev.size() != infilecatv.size()) assert(0);

  Float_t fMVACut[4][4];
  InitializeJetIdCuts(fMVACut);
 
  TFile *fPUFile = TFile::Open(Form("%s",puPath.Data()));
  TH1D *fhDPU = (TH1D*)(fPUFile->Get("puWeights"));
  assert(fhDPU);
  fhDPU->SetDirectory(0);
  delete fPUFile;

  double xmin = 0.0;
  double xmax = 1.0;
  int nBinPlot      = 200;
  double xminPlot   = 0.0;
  double xmaxPlot   = 200.0;
  const int allPlots = 160;
  TH1D* histo[allPlots];

  for(int thePlot=0; thePlot<allPlots; thePlot++){
    if     (thePlot >=  0 && thePlot <= 39) {nBinPlot =  20; xminPlot = 0.0; xmaxPlot = 100.0;}
    else if(thePlot >= 40 && thePlot <= 79) {nBinPlot =   5; xminPlot = 0.0; xmaxPlot =   2.5;}
    else if(thePlot >= 80 && thePlot <= 80) {nBinPlot =   5; xminPlot =-0.5; xmaxPlot =   4.5;}
    else if(thePlot >= 81 && thePlot <= 90) {nBinPlot = 100; xminPlot = 0.0; xmaxPlot =   1.0;}
    else if(thePlot >=100 && thePlot <=109) {nBinPlot =  50; xminPlot = 0.0; xmaxPlot = 100.0;}
    else if(thePlot >=110 && thePlot <=119) {nBinPlot =  50; xminPlot = 0.0; xmaxPlot =   5.0;}
    else if(thePlot >=120 && thePlot <=129) {nBinPlot =  50; xminPlot = 0.0; xmaxPlot = 100.0;}
    else if(thePlot >=130 && thePlot <=139) {nBinPlot =  50; xminPlot = 0.0; xmaxPlot =   5.0;}
    else if(thePlot >=140 && thePlot <=149) {nBinPlot =  50; xminPlot = 0.0; xmaxPlot = 100.0;}
    else if(thePlot >=150 && thePlot <=159) {nBinPlot =  50; xminPlot = 0.0; xmaxPlot =   5.0;}
    TH1D* histos = new TH1D("histos", "histos", nBinPlot, xminPlot, xmaxPlot);
    histos->Sumw2();
    histo[thePlot] = (TH1D*) histos->Clone(Form("histo%d",thePlot));
    histos->Clear();
  }

  //*******************************************************
  // Chain Loop
  //*******************************************************
  for(UInt_t ifile=0; ifile<infilenamev.size(); ifile++) {

    TFile the_input_file(infilenamev[ifile]);
    TTree *the_input_tree = (TTree*)the_input_file.FindObjectAny("events");
    //TTree *the_input_all  = (TTree*)the_input_file.FindObjectAny("all");

    BareEvent eventEvent;
    eventEvent.setBranchAddresses(the_input_tree);

    BareJets eventJets;
    eventJets.setBranchAddresses(the_input_tree);

    BareLeptons eventLeptons;
    eventLeptons.setBranchAddresses(the_input_tree);

    BareTaus eventTaus;
    eventTaus.setBranchAddresses(the_input_tree);

    BareMet eventMet;
    eventMet.SetExtend();
    eventMet.setBranchAddresses(the_input_tree);

    BareTrigger eventTrigger;
    eventTrigger.setBranchAddresses(the_input_tree);

    BareVertex eventVertex;
    eventVertex.setBranchAddresses(the_input_tree);

    BareMonteCarlo eventMonteCarlo;
    eventMonteCarlo.setBranchAddresses(the_input_tree);

    TNamed *triggerNames = (TNamed*)the_input_file.FindObjectAny("triggerNames");
    char **tokens;
    size_t numtokens;
    tokens = strsplit(triggerNames->GetTitle(), ",", &numtokens);
    if(infilecatv[ifile] == 0){
      for (int i = 0; i < (int)numtokens; i++) {
        printf("triggerNames(%2d): \"%s\"\n",(int)i,tokens[i]);
      }
    }
    else {
      printf("sampleNames(%d): %s\n",ifile,infilenamev[ifile].Data());
    }

    double isoCut;
    for (int i=0; i<int(the_input_tree->GetEntries()/1.); ++i) {
      the_input_tree->GetEntry(i);
      if(i%100000==0) printf("event %d out of %d\n",i,(int)the_input_tree->GetEntries());

      double totalWeight = 1;//eventMonteCarlo.mcWeight*lumi;

      vector<bool> isGenDupl; int nGoodGenLeptons = 0;
      for(int ngen0=0; ngen0<eventMonteCarlo.p4->GetEntriesFast(); ngen0++) {
        isGenDupl.push_back(0);
	if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen0]) != 11 &&
	   TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen0]) != 13) isGenDupl[ngen0] = 1;
	if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen0]) != 11 &&
	   TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen0]) != 13) continue;
        for(int ngen1=ngen0+1; ngen1<eventMonteCarlo.p4->GetEntriesFast(); ngen1++) {
          if(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen0])->DeltaR(*((TLorentzVector*)(*eventMonteCarlo.p4)[ngen1])) < 0.02) {
	    isGenDupl[ngen0] = 1;
	    break;
	  }
        }
	if(isGenDupl[ngen0] == 0) nGoodGenLeptons++;
      }
      histo[80]->Fill((double)nGoodGenLeptons,totalWeight);
      
      for(int ngen=0; ngen<eventMonteCarlo.p4->GetEntriesFast(); ngen++) {
	if(isGenDupl[ngen] == 1) continue;
        if(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Pt() <= 10) continue;
	if(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Eta()) >= 2.5) continue;

	int nCount = 0;
	if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen])==11) nCount = 10;
	histo[nCount+ 0]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Pt(),99.999),totalWeight);
	histo[nCount+40]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Eta()),totalWeight);

        int whichRecoLepton = -1;
        for(int nlep=0; nlep<eventLeptons.p4->GetEntriesFast(); nlep++) {
          if(TMath::Abs((int)(*eventLeptons.pdgId)[nlep]) == TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen]) &&
	    ((TLorentzVector*)(*eventLeptons.p4)[nlep])->DeltaR(*((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])) < 0.1) {
	    whichRecoLepton = nlep;
	    break;
	  }
	}
	if(whichRecoLepton >= 0) {
	  if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen])==13) histo[81]->Fill(TMath::Min((double)(*eventLeptons.iso)   [whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt(),0.999),totalWeight);
	  if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen])==11) histo[82]->Fill(TMath::Min((double)(*eventLeptons.iso)   [whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt(),0.999),totalWeight);
	  if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen])==13) histo[83]->Fill(TMath::Min((double)(*eventLeptons.chIso) [whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt(),0.999),totalWeight);
	  if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen])==11) histo[84]->Fill(TMath::Min((double)(*eventLeptons.chIso) [whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt(),0.999),totalWeight);
	  if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen])==13) histo[85]->Fill(TMath::Min((double)(*eventLeptons.nhIso) [whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt(),0.999),totalWeight);
	  if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen])==11) histo[86]->Fill(TMath::Min((double)(*eventLeptons.nhIso) [whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt(),0.999),totalWeight);
	  if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen])==13) histo[87]->Fill(TMath::Min((double)(*eventLeptons.phoIso)[whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt(),0.999),totalWeight);
	  if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen])==11) histo[88]->Fill(TMath::Min((double)(*eventLeptons.phoIso)[whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt(),0.999),totalWeight);
	  if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen])==13) histo[89]->Fill(TMath::Min((double)(*eventLeptons.puIso) [whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt(),0.999),totalWeight);
	  if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen])==11) histo[90]->Fill(TMath::Min((double)(*eventLeptons.puIso) [whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt(),0.999),totalWeight);

	  if(((int)(*eventLeptons.selBits)[whichRecoLepton] & BareLeptons::LepBaseline) == BareLeptons::LepBaseline) { 
	    histo[nCount+ 1]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Pt(),99.999),totalWeight);
   	    histo[nCount+41]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Eta()),totalWeight);
	  }

          isoCut = 0.12;
	  if(TMath::Abs((int)(*eventLeptons.pdgId)[whichRecoLepton]) == 11) isoCut = (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Eta()) ? 0.1260 : 0.1440);
	  if(((int)(*eventLeptons.selBits)[whichRecoLepton] & BareLeptons::LepVeto) == BareLeptons::LepVeto 
	  && (double)(*eventLeptons.iso)[whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt() < isoCut) {
	    histo[nCount+ 2]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Pt(),99.999),totalWeight);
   	    histo[nCount+42]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Eta()),totalWeight);
	  }

	  if(((int)(*eventLeptons.selBits)[whichRecoLepton] & BareLeptons::LepFake) == BareLeptons::LepFake) {
	    histo[nCount+ 3]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Pt(),99.999),totalWeight);
   	    histo[nCount+43]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Eta()),totalWeight);
	  }

          isoCut = 0.12;
	  if(TMath::Abs((int)(*eventLeptons.pdgId)[whichRecoLepton]) == 11) isoCut = (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Eta()) ? 0.0893 : 0.1210);
	  if(((int)(*eventLeptons.selBits)[whichRecoLepton] & BareLeptons::LepLoose) == BareLeptons::LepLoose 
	  && (double)(*eventLeptons.iso)[whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt() < isoCut) {
	    histo[nCount+ 4]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Pt(),99.999),totalWeight);
   	    histo[nCount+44]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Eta()),totalWeight);
	  }

          isoCut = 0.12;
	  if(TMath::Abs((int)(*eventLeptons.pdgId)[whichRecoLepton]) == 11) isoCut = (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Eta()) ? 0.0766 : 0.0678);
	  if(((int)(*eventLeptons.selBits)[whichRecoLepton] & BareLeptons::LepMedium) == BareLeptons::LepMedium 
	  && (double)(*eventLeptons.iso)[whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt() < isoCut) {
	    histo[nCount+ 5]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Pt(),99.999),totalWeight);
   	    histo[nCount+45]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Eta()),totalWeight);
	  }

          isoCut = 0.12;
	  if(TMath::Abs((int)(*eventLeptons.pdgId)[whichRecoLepton]) == 11) isoCut = (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Eta()) ? 0.0354 : 0.0646);
	  if(((int)(*eventLeptons.selBits)[whichRecoLepton] & BareLeptons::LepTight) == BareLeptons::LepTight 
	  && (double)(*eventLeptons.iso)[whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt() < isoCut) {
	    histo[nCount+ 6]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Pt(),99.999),totalWeight);
   	    histo[nCount+46]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Eta()),totalWeight);
	  }

	  if(((int)(*eventLeptons.selBits)[whichRecoLepton] & BareLeptons::LepSoftIP) == BareLeptons::LepSoftIP) {
	    histo[nCount+ 7]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Pt(),99.999),totalWeight);
   	    histo[nCount+47]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Eta()),totalWeight);
	  }

          isoCut = 0.12;
	  if(TMath::Abs((int)(*eventLeptons.pdgId)[whichRecoLepton]) == 11) isoCut = (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Eta()) ? 0.0766 : 0.0678);
	  if(((int)(*eventLeptons.selBits)[whichRecoLepton] & BareLeptons::LepMediumIP) == BareLeptons::LepMediumIP 
	  && (double)(*eventLeptons.iso)[whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt() < isoCut) {
	    histo[nCount+ 8]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Pt(),99.999),totalWeight);
   	    histo[nCount+48]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Eta()),totalWeight);
	  }

          isoCut = 0.12;
	  if(TMath::Abs((int)(*eventLeptons.pdgId)[whichRecoLepton]) == 11) isoCut = (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Eta()) ? 0.0354 : 0.0646);
	  if(((int)(*eventLeptons.selBits)[whichRecoLepton] & BareLeptons::LepTightIP) == BareLeptons::LepTightIP 
	  && (double)(*eventLeptons.iso)[whichRecoLepton]/((TLorentzVector*)(*eventLeptons.p4)[whichRecoLepton])->Pt() < isoCut) {
	    histo[nCount+ 9]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Pt(),99.999),totalWeight);
   	    histo[nCount+49]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Eta()),totalWeight);
	  }
	}
      } // end loop over gen leptons


      for(int nlep=0; nlep<eventLeptons.p4->GetEntriesFast(); nlep++) {
	int nCount = 20;
	if(TMath::Abs((int)(*eventLeptons.pdgId)[nlep])==11) nCount = 30;
        int whichGenLepton = -1;
        for(int ngen=0; ngen<eventMonteCarlo.p4->GetEntriesFast(); ngen++) {
	  if(isGenDupl[ngen] == 1) continue;
          if(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Pt() <= 10) continue;
	  if(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])->Eta()) >= 2.5) continue;
          if(TMath::Abs((int)(*eventLeptons.pdgId)[nlep]) == TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen]) &&
	    ((TLorentzVector*)(*eventLeptons.p4)[nlep])->DeltaR(*((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])) < 0.1) {
	    whichGenLepton = nlep;
	    break;
	  }
	}

	if(whichGenLepton == -1) {
	  histo[nCount+ 0]->Fill(TMath::Min(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt(),99.999),totalWeight);
   	  histo[nCount+40]->Fill(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),totalWeight);

	  if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepBaseline) == BareLeptons::LepBaseline) { 
	    histo[nCount+ 1]->Fill(TMath::Min(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt(),99.999),totalWeight);
   	    histo[nCount+41]->Fill(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),totalWeight);
	  }

          isoCut = 0.12;
	  if(TMath::Abs((int)(*eventLeptons.pdgId)[nlep]) == 11) isoCut = (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()) ? 0.1260 : 0.1440);
	  if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepVeto) == BareLeptons::LepVeto 
	  && (double)(*eventLeptons.iso)[nlep]/((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt() < isoCut) {
	    histo[nCount+ 2]->Fill(TMath::Min(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt(),99.999),totalWeight);
   	    histo[nCount+42]->Fill(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),totalWeight);
	  }

	  if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepFake) == BareLeptons::LepFake) {
	    histo[nCount+ 3]->Fill(TMath::Min(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt(),99.999),totalWeight);
   	    histo[nCount+43]->Fill(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),totalWeight);
	  }

          isoCut = 0.12;
	  if(TMath::Abs((int)(*eventLeptons.pdgId)[nlep]) == 11) isoCut = (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()) ? 0.0893 : 0.1210);
	  if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepLoose) == BareLeptons::LepLoose 
	  && (double)(*eventLeptons.iso)[nlep]/((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt() < isoCut) {
	    histo[nCount+ 4]->Fill(TMath::Min(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt(),99.999),totalWeight);
   	    histo[nCount+44]->Fill(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),totalWeight);
	  }

          isoCut = 0.12;
	  if(TMath::Abs((int)(*eventLeptons.pdgId)[nlep]) == 11) isoCut = (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()) ? 0.0766 : 0.0678);
	  if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepMedium) == BareLeptons::LepMedium 
	  && (double)(*eventLeptons.iso)[nlep]/((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt() < isoCut) {
	    histo[nCount+ 5]->Fill(TMath::Min(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt(),99.999),totalWeight);
   	    histo[nCount+45]->Fill(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),totalWeight);
	  }

          isoCut = 0.12;
	  if(TMath::Abs((int)(*eventLeptons.pdgId)[nlep]) == 11) isoCut = (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()) ? 0.0354 : 0.0646);
	  if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepTight) == BareLeptons::LepTight 
	  && (double)(*eventLeptons.iso)[nlep]/((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt() < isoCut) {
	    histo[nCount+ 6]->Fill(TMath::Min(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt(),99.999),totalWeight);
   	    histo[nCount+46]->Fill(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),totalWeight);
	  }

	  if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepSoftIP) == BareLeptons::LepSoftIP) {
	    histo[nCount+ 7]->Fill(TMath::Min(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt(),99.999),totalWeight);
   	    histo[nCount+47]->Fill(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),totalWeight);
	  }

          isoCut = 0.12;
	  if(TMath::Abs((int)(*eventLeptons.pdgId)[nlep]) == 11) isoCut = (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()) ? 0.0766 : 0.0678);
	  if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepMediumIP) == BareLeptons::LepMediumIP 
	  && (double)(*eventLeptons.iso)[nlep]/((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt() < isoCut) {
	    histo[nCount+ 8]->Fill(TMath::Min(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt(),99.999),totalWeight);
   	    histo[nCount+48]->Fill(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),totalWeight);
	  }

          isoCut = 0.12;
	  if(TMath::Abs((int)(*eventLeptons.pdgId)[nlep]) == 11) isoCut = (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()) ? 0.0354 : 0.0646);
	  if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepTightIP) == BareLeptons::LepTightIP 
	  && (double)(*eventLeptons.iso)[nlep]/((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt() < isoCut) {
	    histo[nCount+ 9]->Fill(TMath::Min(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt(),99.999),totalWeight);
   	    histo[nCount+49]->Fill(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),totalWeight);
	  }
	}

      } // end loop over reco leptons

      vector<int> idLep;
      for(int nlep=0; nlep<eventLeptons.p4->GetEntriesFast(); nlep++) {
        if(selectIdIsoCut("medium",TMath::Abs((int)(*eventLeptons.pdgId)[nlep]),TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt()),
	   TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),(double)(*eventLeptons.iso)[nlep],(int)(*eventLeptons.selBits)[nlep]))
	                                                                                               {idLep.push_back(nlep);}
        else if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepFake)  == BareLeptons::LepFake ) {idLep.push_back(nlep);}
      }

      vector<int> idGenJet;
      for(int ngenj=0; ngenj<eventMonteCarlo.jetP4->GetEntriesFast(); ngenj++) {
        Bool_t isGenLepton = kFALSE;
        for(int ngenl=0; ngenl<eventMonteCarlo.p4->GetEntriesFast(); ngenl++) {
	if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngenl]) != 12 &&
	   TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngenl]) != 14 &&
	   TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngenl]) != 16 &&
	   TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngenl]) != 11 &&
	   TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngenl]) != 13) continue;
          if(((TLorentzVector*)(*eventMonteCarlo.jetP4)[ngenj])->DeltaR(*((TLorentzVector*)(*eventMonteCarlo.p4)[ngenl])) < 0.3) isGenLepton = kTRUE;
        }
        if(isGenLepton == kTRUE) continue;
        if(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.jetP4)[ngenj])->Eta()) >= 5) continue;
        idGenJet.push_back(ngenj);
      }

      vector<int> idJet;
      vector<int> idMVAJet;
      for(int nj=0; nj<eventJets.p4->GetEntriesFast(); nj++){
        if(((TLorentzVector*)(*eventJets.p4)[nj])->Pt() < 10) continue;
        Bool_t isLepton = kFALSE;
        for(unsigned int nl=0; nl<idLep.size(); nl++){
          if(((TLorentzVector*)(*eventJets.p4)[nj])->DeltaR(*((TLorentzVector*)(*eventLeptons.p4)[idLep[nl]])) < 0.3) isLepton = kTRUE;
	}
	if(isLepton == kTRUE) continue;

        if(((TLorentzVector*)(*eventJets.p4)[nj])->Pt() < 30) continue;        
	idJet.push_back(nj);

        bool passId = passJetId(fMVACut, (float)(*eventJets.puId)[nj], ((TLorentzVector*)(*eventJets.p4)[nj])->Pt(), TMath::Abs(((TLorentzVector*)(*eventJets.p4)[nj])->Eta()));
        if(passId == false) continue;        
	idMVAJet.push_back(nj);
      }

      for(unsigned int ngenj=0; ngenj<idGenJet.size(); ngenj++) {
	int nCount = 100;
	if(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->Eta()) < 2.5)
	histo[nCount+ 0]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->Pt(),99.999),totalWeight);
	if(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->Pt() > 30)
	histo[nCount+10]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->Eta()),totalWeight);
	
	bool isRecoJet = kFALSE;
        for(unsigned int nj=0; nj<idJet.size(); nj++){
          if(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->DeltaR(*((TLorentzVector*)(*eventJets.p4)[idJet[nj]])) < 0.4) isRecoJet = kTRUE;
        }
        if(isRecoJet == kTRUE) {
	  if(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->Eta()) < 2.5)
	  histo[nCount+ 1]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->Pt(),99.999),totalWeight);
	  if(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->Pt() > 30)
	  histo[nCount+11]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->Eta()),totalWeight);
	}

        isRecoJet = kFALSE;
        for(unsigned int nj=0; nj<idMVAJet.size(); nj++){
          if(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->DeltaR(*((TLorentzVector*)(*eventJets.p4)[idMVAJet[nj]])) < 0.4) isRecoJet = kTRUE;
        }
        if(isRecoJet == kTRUE) {
	  if(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->Eta()) < 2.5)
	  histo[nCount+ 2]->Fill(TMath::Min(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->Pt(),99.999),totalWeight);
	  if(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->Pt() > 30)
	  histo[nCount+12]->Fill(TMath::Abs(((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])->Eta()),totalWeight);
	}
      }

      for(unsigned int nj=0; nj<idJet.size(); nj++) {
	int nCount = 120;
	if(TMath::Abs(((TLorentzVector*)(*eventJets.p4)[idJet[nj]])->Eta()) < 2.5)
	histo[nCount+ 0]->Fill(TMath::Min(((TLorentzVector*)(*eventJets.p4)[idJet[nj]])->Pt(),99.999),totalWeight);
	if(((TLorentzVector*)(*eventJets.p4)[idJet[nj]])->Pt() > 30)
	histo[nCount+10]->Fill(TMath::Abs(((TLorentzVector*)(*eventJets.p4)[idJet[nj]])->Eta()),totalWeight);
	
	bool isGenJet = kFALSE;
        for(unsigned int ngenj=0; ngenj<idGenJet.size(); ngenj++){
          if(((TLorentzVector*)(*eventJets.p4)[idJet[nj]])->DeltaR(*((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])) < 0.4) isGenJet = kTRUE;
        }
        if(isGenJet == kFALSE) {
  	  if(TMath::Abs(((TLorentzVector*)(*eventJets.p4)[idJet[nj]])->Eta()) < 2.5)
  	  histo[nCount+ 1]->Fill(TMath::Min(((TLorentzVector*)(*eventJets.p4)[idJet[nj]])->Pt(),99.999),totalWeight);
	  if(((TLorentzVector*)(*eventJets.p4)[idJet[nj]])->Pt() > 30)
	  histo[nCount+11]->Fill(TMath::Abs(((TLorentzVector*)(*eventJets.p4)[idJet[nj]])->Eta()),totalWeight);
	}
      }

      for(unsigned int nj=0; nj<idMVAJet.size(); nj++) {
	int nCount = 140;
        if(TMath::Abs(((TLorentzVector*)(*eventJets.p4)[idMVAJet[nj]])->Eta()) < 2.5)
	histo[nCount+ 0]->Fill(TMath::Min(((TLorentzVector*)(*eventJets.p4)[idMVAJet[nj]])->Pt(),99.999),totalWeight);
	if(((TLorentzVector*)(*eventJets.p4)[idMVAJet[nj]])->Pt() > 30)
	histo[nCount+10]->Fill(TMath::Abs(((TLorentzVector*)(*eventJets.p4)[idMVAJet[nj]])->Eta()),totalWeight);
	
	bool isGenJet = kFALSE;
        for(unsigned int ngenj=0; ngenj<idGenJet.size(); ngenj++){
          if(((TLorentzVector*)(*eventJets.p4)[idMVAJet[nj]])->DeltaR(*((TLorentzVector*)(*eventMonteCarlo.jetP4)[idGenJet[ngenj]])) < 0.4) isGenJet = kTRUE;
        }
        if(isGenJet == kFALSE) {
  	  if(TMath::Abs(((TLorentzVector*)(*eventJets.p4)[idMVAJet[nj]])->Eta()) < 2.5)
  	  histo[nCount+ 1]->Fill(TMath::Min(((TLorentzVector*)(*eventJets.p4)[idMVAJet[nj]])->Pt(),99.999),totalWeight);
	  if(((TLorentzVector*)(*eventJets.p4)[idMVAJet[nj]])->Pt() > 30)
	  histo[nCount+11]->Fill(TMath::Abs(((TLorentzVector*)(*eventJets.p4)[idMVAJet[nj]])->Eta()),totalWeight);
	}
      }
    } // end of loop
  } // end of chain

  for(int np= 1; np<10; np++) histo[np]->Divide(histo[ 0]);
  for(int np=11; np<20; np++) histo[np]->Divide(histo[10]);
  for(int np=21; np<30; np++) histo[np]->Divide(histo[20]);
  for(int np=31; np<40; np++) histo[np]->Divide(histo[30]);
  for(int np=41; np<50; np++) histo[np]->Divide(histo[40]);
  for(int np=51; np<60; np++) histo[np]->Divide(histo[50]);
  for(int np=61; np<70; np++) histo[np]->Divide(histo[60]);
  for(int np=71; np<80; np++) histo[np]->Divide(histo[70]);
  for(int np=80; np<=90; np++) histo[np]->Scale(1./histo[np]->GetSumOfWeights());
  for(int np=101; np<110; np++) histo[np]->Divide(histo[100]);
  for(int np=111; np<120; np++) histo[np]->Divide(histo[110]);
  for(int np=121; np<130; np++) histo[np]->Divide(histo[120]);
  for(int np=131; np<140; np++) histo[np]->Divide(histo[130]);
  for(int np=141; np<150; np++) histo[np]->Divide(histo[140]);
  for(int np=151; np<160; np++) histo[np]->Divide(histo[150]);
  char output[200];
  sprintf(output,"histo_geneff.root");	  
  TFile* outFilePlotsNote = new TFile(output,"recreate");
  outFilePlotsNote->cd();
  for(int np=0; np<160; np++) histo[np]->Write();
  outFilePlotsNote->Close();
}
void QCDAnalysis(
 Int_t nsel = 0,
 Int_t typeSel = 4,
 Int_t applyPrescale = 1,
 TString typeLepSel = "medium"
 ){

  Int_t period = 1;
  TString filesPath  = "/scratch5/ceballos/ntuples_weights/qcd_";
  Double_t lumi = 0.0715;
  if(period == 1) lumi = 2.2;

  Double_t prescale[5];

  double denFRDA[5][5] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  double numFRDA[5][5] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  double denFRBG[5][5] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  double numFRBG[5][5] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

  //*******************************************************
  //Input Files
  //*******************************************************
  vector<TString> infilenamev;  
  vector<Int_t> infilecatv;  

  TString puPath = "";
  if     (period==0){
  }
  else if(period==1){
  if     (typeSel == 11) {prescale[0]=0.00000;prescale[1]=0.00859;prescale[2]=0.00520;prescale[3]=0.00750;prescale[4]=0.00956;}
  else if(typeSel == 13) {prescale[0]=0.00250;prescale[1]=0.07087;prescale[2]=0.09861;prescale[3]=0.09744;prescale[4]=0.09616;}
  puPath = "/home/ceballos/cms/cmssw/042/CMSSW_7_4_6/src/MitAnalysisRunII/data/puWeights_13TeV_25ns.root";
  infilenamev.push_back(Form("%sdata_AOD_Run2015C1_25ns.root",filesPath.Data())); 												  infilecatv.push_back(0);
  infilenamev.push_back(Form("%sdata_AOD_Run2015D3_25ns.root",filesPath.Data())); 												  infilecatv.push_back(0);
  infilenamev.push_back(Form("%sdata_AOD_Run2015D4_25ns.root",filesPath.Data())); 												  infilecatv.push_back(0);
  infilenamev.push_back(Form("%sWWTo2L2Nu_13TeV-powheg+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));					          infilecatv.push_back(1);
  infilenamev.push_back(Form("%sGluGluWWTo2L2Nu_MCFM_13TeV+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));                                          infilecatv.push_back(1);
  infilenamev.push_back(Form("%sDYJetsToLL_M-10to50_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));         infilecatv.push_back(2);
  infilenamev.push_back(Form("%sDYJetsToLL_M-50_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v3+AODSIM.root",filesPath.Data()));	          infilecatv.push_back(2);
  infilenamev.push_back(Form("%sTT_TuneCUETP8M1_13TeV-powheg-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v2+AODSIM.root",filesPath.Data()));				  infilecatv.push_back(3); // tt->X (not tt->2l)
  infilenamev.push_back(Form("%sST_tW_top_5f_inclusiveDecays_13TeV-powheg-pythia8_TuneCUETP8M1+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));      infilecatv.push_back(3);
  infilenamev.push_back(Form("%sST_tW_antitop_5f_inclusiveDecays_13TeV-powheg-pythia8_TuneCUETP8M1+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));  infilecatv.push_back(3);
  infilenamev.push_back(Form("%sZZTo2L2Nu_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));				          infilecatv.push_back(4);
  infilenamev.push_back(Form("%sZZTo2L2Q_13TeV_amcatnloFXFX_madspin_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		          infilecatv.push_back(4);
  infilenamev.push_back(Form("%sZZTo4L_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));				          infilecatv.push_back(4);
  infilenamev.push_back(Form("%sGluGluToZZTo2e2mu_BackgroundOnly_13TeV_MCFM+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			  infilecatv.push_back(4);
  infilenamev.push_back(Form("%sGluGluToZZTo2e2tau_BackgroundOnly_13TeV_MCFM+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			  infilecatv.push_back(4);
  infilenamev.push_back(Form("%sGluGluToZZTo2mu2tau_BackgroundOnly_13TeV_MCFM+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			  infilecatv.push_back(4);
  infilenamev.push_back(Form("%sGluGluToZZTo4e_BackgroundOnly_13TeV_MCFM+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));  			  infilecatv.push_back(4);
  infilenamev.push_back(Form("%sGluGluToZZTo4mu_BackgroundOnly_13TeV_MCFM+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data())); 			  infilecatv.push_back(4);
  infilenamev.push_back(Form("%sGluGluToZZTo4tau_BackgroundOnly_13TeV_MCFM+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			  infilecatv.push_back(4);
  infilenamev.push_back(Form("%sWZTo1L1Nu2Q_13TeV_amcatnloFXFX_madspin_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		          infilecatv.push_back(4);
  infilenamev.push_back(Form("%sWZTo2L2Q_13TeV_amcatnloFXFX_madspin_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v2+AODSIM.root",filesPath.Data()));		          infilecatv.push_back(4);
  infilenamev.push_back(Form("%sWZTo3LNu_TuneCUETP8M1_13TeV-powheg-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));                          infilecatv.push_back(4);
  infilenamev.push_back(Form("%sWWZ_TuneCUETP8M1_13TeV-amcatnlo-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			          infilecatv.push_back(4);
  infilenamev.push_back(Form("%sWZZ_TuneCUETP8M1_13TeV-amcatnlo-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			          infilecatv.push_back(4);
  infilenamev.push_back(Form("%sZZZ_TuneCUETP8M1_13TeV-amcatnlo-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v2+AODSIM.root",filesPath.Data()));			          infilecatv.push_back(4);
  infilenamev.push_back(Form("%sTTWJetsToLNu_TuneCUETP8M1_13TeV-amcatnloFXFX-madspin-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));        infilecatv.push_back(4);
  infilenamev.push_back(Form("%sTTWJetsToQQ_TuneCUETP8M1_13TeV-amcatnloFXFX-madspin-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));         infilecatv.push_back(4);
  infilenamev.push_back(Form("%sTTZToLLNuNu_M-10_TuneCUETP8M1_13TeV-amcatnlo-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));	          infilecatv.push_back(4);
  infilenamev.push_back(Form("%sTTZToQQ_TuneCUETP8M1_13TeV-amcatnlo-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		          infilecatv.push_back(4);
  infilenamev.push_back(Form("%sTTGJets_TuneCUETP8M1_13TeV-amcatnloFXFX-madspin-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));	          infilecatv.push_back(4);
  infilenamev.push_back(Form("%sWJetsToLNu_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));	          infilecatv.push_back(5);
  infilenamev.push_back(Form("%sWGToLNuG_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));  		  infilecatv.push_back(6);
  //infilenamev.push_back(Form("%sZGTo2LG_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));		          infilecatv.push_back(6);
  infilenamev.push_back(Form("%sGluGluHToWWTo2L2Nu_M125_13TeV_powheg_JHUgen_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v3+AODSIM.root",filesPath.Data()));	          infilecatv.push_back(7);
  infilenamev.push_back(Form("%sVBFHToWWTo2L2Nu_M125_13TeV_powheg_JHUgen_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));  	          infilecatv.push_back(7);
  infilenamev.push_back(Form("%sGluGluHToTauTau_M125_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data())); 		          infilecatv.push_back(7);
  infilenamev.push_back(Form("%sVBFHToTauTau_M125_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			          infilecatv.push_back(7);
  /////infilenamev.push_back(Form("%sVHToNonbb_M125_13TeV_amcatnloFXFX_madspin_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data())); 		  infilecatv.push_back(7);
  /////infilenamev.push_back(Form("%sttHJetToNonbb_M125_13TeV_amcatnloFXFX_madspin_pythia8_mWCutfix+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data())); infilecatv.push_back(7);
  }

  //infilenamev.push_back(Form("nero.root"));     infilecatv.push_back(0);

  if(infilenamev.size() != infilecatv.size()) assert(0);

  Float_t fMVACut[4][4];
  InitializeJetIdCuts(fMVACut);
 
  TFile *fPUFile = TFile::Open(Form("%s",puPath.Data()));
  TH1D *fhDPU = (TH1D*)(fPUFile->Get("puWeights"));
  assert(fhDPU);
  fhDPU->SetDirectory(0);
  delete fPUFile;

  double xmin = 0.0;
  double xmax = 1.0;
  int nBinPlot      = 200;
  double xminPlot   = 0.0;
  double xmaxPlot   = 200.0;
  const int allPlots = 11;
  const int histBins = 8;
  TH1D* histo[allPlots][histBins];

  for(int thePlot=0; thePlot<allPlots; thePlot++){
    if     (thePlot >=  0 && thePlot <=  5) {nBinPlot = 200; xminPlot = 0.0; xmaxPlot = 200.0;}
    else if(thePlot >=  6 && thePlot <=  6) {nBinPlot =   7; xminPlot =-0.5; xmaxPlot =   6.5;}
    else if(thePlot >=  7 && thePlot <=  7) {nBinPlot =  40; xminPlot = 0.0; xmaxPlot =  40.0;}
    else if(thePlot >=  8 && thePlot <=  8) {nBinPlot =  40; xminPlot =-0.5; xmaxPlot =  39.5;}
    else if(thePlot >=  9 && thePlot <=  9) {nBinPlot =  50; xminPlot = 0.0; xmaxPlot =  50.0;}
    else if(thePlot >= 10 && thePlot <= 10) {nBinPlot =  50; xminPlot = 0.0; xmaxPlot =   2.5;}
    TH1D* histos = new TH1D("histos", "histos", nBinPlot, xminPlot, xmaxPlot);
    histos->Sumw2();
    for(int i=0; i<histBins; i++) histo[thePlot][i] = (TH1D*) histos->Clone(Form("histo%d",i));
    histos->Clear();
  }

  //*******************************************************
  // Chain Loop
  //*******************************************************
  for(UInt_t ifile=0; ifile<infilenamev.size(); ifile++) {

    TFile the_input_file(infilenamev[ifile]);
    TTree *the_input_tree = (TTree*)the_input_file.FindObjectAny("events");
    //TTree *the_input_all  = (TTree*)the_input_file.FindObjectAny("all");

    BareMonteCarlo eventMonteCarlo;
    eventMonteCarlo.setBranchAddresses(the_input_tree);

    BareEvent eventEvent;
    eventEvent.setBranchAddresses(the_input_tree);

    BareJets eventJets;
    eventJets.setBranchAddresses(the_input_tree);

    BareLeptons eventLeptons;
    eventLeptons.setBranchAddresses(the_input_tree);

    BareTaus eventTaus;
    eventTaus.setBranchAddresses(the_input_tree);

    BareMet eventMet;
    eventMet.SetExtend();
    eventMet.setBranchAddresses(the_input_tree);

    BareTrigger eventTrigger;
    eventTrigger.setBranchAddresses(the_input_tree);

    BareVertex eventVertex;
    eventVertex.setBranchAddresses(the_input_tree);

    TNamed *triggerNames = (TNamed*)the_input_file.FindObjectAny("triggerNames");
    char **tokens;
    size_t numtokens;
    tokens = strsplit(triggerNames->GetTitle(), ",", &numtokens);
    if(infilecatv[ifile] == 0){
      for (int i = 0; i < (int)numtokens; i++) {
        printf("triggerNames(%2d): \"%s\"\n",(int)i,tokens[i]);
      }
    }
    else {
      printf("sampleNames(%d): %s\n",ifile,infilenamev[ifile].Data());
    }

    Int_t nPassTrigger[12] = {0,0,0,0,0,0,0,0,0,0,0,0};

    Int_t nPassCuts[10] = {0,0,0,0,0,0,0,0,0,0};
    double theMCPrescale = mcPrescale;
    if(infilecatv[ifile] == 0) theMCPrescale = 1.0;
    for (int i=0; i<int(the_input_tree->GetEntries()/theMCPrescale); ++i) {
      the_input_tree->GetEntry(i);
      if(i%100000==0) printf("event %d out of %d\n",i,(int)the_input_tree->GetEntries());

      if(typeSel != 11 && typeSel != 13) assert(0);

      Bool_t passFilter = kFALSE;
      Bool_t passTrigger = kFALSE;
      for (int nt = 0; nt < (int)numtokens; nt++) {
	if(typeSel == 11 &&
          (strcmp(tokens[nt],"HLT_Ele12_CaloIdL_TrackIdL_IsoVL_PFJet30_v*") == 0 ||
           strcmp(tokens[nt],"HLT_Ele18_CaloIdL_TrackIdL_IsoVL_PFJet30_v*") == 0 ||
           strcmp(tokens[nt],"HLT_Ele23_CaloIdL_TrackIdL_IsoVL_PFJet30_v*") == 0 ||
           strcmp(tokens[nt],"HLT_Ele33_CaloIdL_TrackIdL_IsoVL_PFJet30_v*") == 0) &&
	  (*eventTrigger.triggerFired)[nt] == 1) passTrigger = kTRUE;
	if(typeSel == 13 &&
	  (strcmp(tokens[nt],"HLT_Mu8_TrkIsoVVL_v*")  == 0 ||              
	   strcmp(tokens[nt],"HLT_Mu17_TrkIsoVVL_v*") == 0 ||              
	   strcmp(tokens[nt],"HLT_Mu24_TrkIsoVVL_v*") == 0 ||              
	   strcmp(tokens[nt],"HLT_Mu34_TrkIsoVVL_v*") == 0) &&           
	  (*eventTrigger.triggerFired)[nt] == 1) passTrigger = kTRUE;
      }
      if(passTrigger == kTRUE &&
         eventLeptons.p4->GetEntriesFast() >= 1 &&
         ((TLorentzVector*)(*eventLeptons.p4)[0])->Pt() > 10 && 
	 (double)((TLorentzVector*)(*eventMet.p4)[0])->Pt() < 30.0) passFilter = kTRUE;

      if(passTrigger == kTRUE) nPassCuts[0]++;
      if(passFilter  == kTRUE) nPassCuts[1]++;
      if(passFilter == kFALSE) continue;

      Bool_t passSel = kFALSE;
      TLorentzVector dilep;double deltaPhiDileptonMet = -999.0; double mtW = -999.0;
      vector<int> idLep; vector<int> idTight;
      for(int nlep=0; nlep<eventLeptons.p4->GetEntriesFast(); nlep++) {
        if(selectIdIsoCut(typeLepSel.Data(),TMath::Abs((int)(*eventLeptons.pdgId)[nlep]),TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt()),
	   TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),(double)(*eventLeptons.iso)[nlep],(int)(*eventLeptons.selBits)[nlep]))
	                                                                                               {idTight.push_back(1); idLep.push_back(nlep);}
        else if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepFake)  == BareLeptons::LepFake ) {idTight.push_back(0); idLep.push_back(nlep);}
      }

      vector<int> isGenLep;
      for(unsigned nl=0; nl<idLep.size(); nl++){
        bool isGenLepton = false;
        for(int ngen=0; ngen<eventMonteCarlo.p4->GetEntriesFast(); ngen++) {
          if(TMath::Abs((int)(*eventLeptons.pdgId)[idLep[nl]]) == TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen]) &&
	    ((TLorentzVector*)(*eventLeptons.p4)[idLep[nl]])->DeltaR(*((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])) < 0.1) {
	    isGenLepton = true;
	    break;
	  }
	}
	if(isGenLepton == true) isGenLep.push_back(nl);
      }
      
      vector<int> idJet20,idJet30;
      for(int nj=0; nj<eventJets.p4->GetEntriesFast(); nj++){
        if(((TLorentzVector*)(*eventJets.p4)[nj])->Pt() < 10) continue;
        bool passId = passJetId(fMVACut, (float)(*eventJets.puId)[nj], ((TLorentzVector*)(*eventJets.p4)[nj])->Pt(), TMath::Abs(((TLorentzVector*)(*eventJets.p4)[nj])->Eta()));
        //if(passId == false) continue;        

        Bool_t isLepton = kFALSE;
        for(unsigned int nl=0; nl<idLep.size(); nl++){
          if(((TLorentzVector*)(*eventJets.p4)[nj])->DeltaR(*((TLorentzVector*)(*eventLeptons.p4)[idLep[nl]])) < 0.3) isLepton = kTRUE;
	}
	if(isLepton == kTRUE) continue;

        if(((TLorentzVector*)(*eventJets.p4)[nj])->Pt() > 20)  idJet20.push_back(nj);
        if(((TLorentzVector*)(*eventJets.p4)[nj])->Pt() > 30)  idJet30.push_back(nj);
      }

      if     (nsel == 0){ // Z->ll
        if(idLep.size() == 2) nPassCuts[2]++;
	if(idLep.size() == 2 &&
     	  ((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() > 10 && 
     	  ((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Pt() > 10) nPassCuts[3]++;
        if(idLep.size() == 2 &&
     	  ((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() > 10 && 
     	  ((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Pt() > 10 &&
          (int)(*eventLeptons.pdgId)[idLep[0]]*(int)(*eventLeptons.pdgId)[idLep[1]] < 0 &&
	  TMath::Abs((int)(*eventLeptons.pdgId)[idLep[0]]) == TMath::Abs((int)(*eventLeptons.pdgId)[idLep[1]]) &&
	  TMath::Abs((int)(*eventLeptons.pdgId)[idLep[0]]) == typeSel &&
	 (infilecatv[ifile] == 0 || isGenLep.size() == 2)) {
          nPassCuts[4]++;
          dilep = ( ( *(TLorentzVector*)(eventLeptons.p4->At(idLep[0])) ) + ( *(TLorentzVector*)(eventLeptons.p4->At(idLep[1])) ) ); 
          if(TMath::Abs(dilep.M()-91.1876)<15.0) passSel = kTRUE;	
	}
      }
      else if(nsel == 1){ // fake
        if(idLep.size() == 1) nPassCuts[2]++;
	if(idLep.size() == 1 &&
     	  ((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() > 10) nPassCuts[3]++;
        if(idLep.size() == 1 &&
     	  ((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() > 10 &&
	  ((typeSel == 11 && idJet30.size() >= 1) ||(typeSel == 13 && idJet20.size() >= 1)) &&
	  TMath::Abs((int)(*eventLeptons.pdgId)[idLep[0]]) == typeSel &&
	 (infilecatv[ifile] == 0 || isGenLep.size() == 1)) {
          dilep = ( *(TLorentzVector*)(eventLeptons.p4->At(idLep[0])) );
          nPassCuts[4]++;
          deltaPhiDileptonMet = TMath::Abs(dilep.DeltaPhi(*((TLorentzVector*)(*eventMet.p4)[0])));
          mtW = TMath::Sqrt(2.0*dilep.Pt()*((TLorentzVector*)(*eventMet.p4)[0])->Pt()*(1.0 - cos(deltaPhiDileptonMet)));
	  if(mtW < 20) passSel = kTRUE;
	}
      }
      else if(nsel == 2){ // W->ln
        if(idLep.size() == 1 && idTight[0] == 1) nPassCuts[2]++;
	if(idLep.size() == 1 && idTight[0] == 1 &&
     	  ((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() > 10) nPassCuts[3]++;
        if(idLep.size() == 1 && idTight[0] == 1 &&
     	  ((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() > 10 &&
	  TMath::Abs((int)(*eventLeptons.pdgId)[idLep[0]]) == typeSel &&
	 (infilecatv[ifile] == 0 || isGenLep.size() == 1)) {
          dilep = ( *(TLorentzVector*)(eventLeptons.p4->At(idLep[0])) );
          nPassCuts[4]++;
          deltaPhiDileptonMet = TMath::Abs(dilep.DeltaPhi(*((TLorentzVector*)(*eventMet.p4)[0])));
          mtW = TMath::Sqrt(2.0*dilep.Pt()*((TLorentzVector*)(*eventMet.p4)[0])->Pt()*(1.0 - cos(deltaPhiDileptonMet)));
	  if(mtW > 50) passSel = kTRUE;
	}
      }

      if(passSel == kTRUE) nPassCuts[5]++;
      if(passSel == kFALSE) continue;

      if(mtW < 0){
        deltaPhiDileptonMet = TMath::Abs(dilep.DeltaPhi(*((TLorentzVector*)(*eventMet.p4)[0])));
        mtW = TMath::Sqrt(2.0*dilep.Pt()*((TLorentzVector*)(*eventMet.p4)[0])->Pt()*(1.0 - cos(deltaPhiDileptonMet)));
      }

      double mcWeight = eventMonteCarlo.mcWeight;
      if(infilecatv[ifile] == 0) mcWeight = 1.0;
      double theLumi = lumi; if(infilecatv[ifile] == 0) theLumi = 1.0;
      double puWeight = nPUScaleFactor(fhDPU, (double)eventVertex.npv); if(infilecatv[ifile] == 0) puWeight = 1.0;
      double effSF = 1.0;
      if(infilecatv[ifile] != 0){
        for(unsigned int nl=0; nl<idLep.size(); nl++){
          effSF = effSF * effScaleFactor(((TLorentzVector*)(*eventLeptons.p4)[idLep[nl]])->Pt(),TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[nl]])->Eta()),TMath::Abs((int)(*eventLeptons.pdgId)[idLep[nl]]),period,typeLepSel);
        }
      }
      
      int iPt = -1;
      if     (((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() < 15){
        iPt = 0;
      }
      else if(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() < 20){
        iPt = 1;
      }
      else if(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() < 25){
        iPt = 2;
      }
      else if(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() < 30){
        iPt = 3;
      }
      else {
        iPt = 4;
      }
      int iEta = -1;
      if     (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Eta()) < 0.5){
         iEta = 0;
      }
      else if(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Eta()) < 1.0){
         iEta = 1;
      }
      else if(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Eta()) < 1.5){
         iEta = 2;
      }
      else if(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Eta()) < 2.0){
         iEta = 3;
      }
      else {
         iEta = 4;
      }
      if(nsel == 0) iEta = 0;

      double thePrescale = 1.0;
      if(infilecatv[ifile] != 0 && applyPrescale == 1) thePrescale = prescale[iPt];

      double totalWeight = mcWeight*theLumi*puWeight*effSF*thePrescale*theMCPrescale;

      if(infilecatv[ifile] == 0) {
                            denFRDA[iPt][iEta] = denFRDA[iPt][iEta] + totalWeight;
        if(idTight[0] == 1) numFRDA[iPt][iEta] = numFRDA[iPt][iEta] + totalWeight;
      }
      else {
                            denFRBG[iPt][iEta] = denFRBG[iPt][iEta] + totalWeight;
        if(idTight[0] == 1) numFRBG[iPt][iEta] = numFRBG[iPt][iEta] + totalWeight;
      }

      for(int thePlot=0; thePlot<allPlots; thePlot++){
        double theVar = 0.0;
        if     (thePlot ==  0) theVar = TMath::Min(dilep.M(),199.999);
        else if(thePlot ==  1) theVar = TMath::Min((double)((TLorentzVector*)(*eventMet.p4)[0])->Pt(),199.999);
        else if(thePlot ==  2) theVar = TMath::Min((double)eventMet.metNoMu->Pt(),199.999);
        else if(thePlot ==  3) theVar = TMath::Min((double)((TLorentzVector*)(*eventMet.p4)[0])->Pt(),199.999);
        else if(thePlot ==  4) theVar = TMath::Min(dilep.Pt(),199.999);
        else if(thePlot ==  5) theVar = TMath::Min(mtW,199.999);
        else if(thePlot ==  6) theVar = TMath::Min((double)0.0,6.499);
        else if(thePlot ==  7) theVar = TMath::Min((double)eventEvent.rho,39.999);
        else if(thePlot ==  8) theVar = TMath::Min((double)eventVertex.npv,39.499);
        else if(thePlot ==  9) theVar = TMath::Min(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt(),49.999);
        else if(thePlot == 10) theVar = TMath::Min(TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Eta()),2.499);
        histo[thePlot][infilecatv[ifile]]->Fill(theVar,totalWeight);
      }

    }

    printf("eff_cuts: ");
    for(int nc=0; nc<6; nc++){
      double nminusone = the_input_tree->GetEntries();
      if(nc>0) nminusone = nPassCuts[nc-1];
      printf("(%d): %8.5f(%8.5f) | ",nc,100*(double)nPassCuts[nc]/the_input_tree->GetEntries(),100*(double)nPassCuts[nc]/nminusone);
    }
    printf("\n");
  } // end of chain

  for(int nc=0; nc<8; nc++){
    printf("(%d): %5.2f | ",nc,histo[0][nc]->GetSumOfWeights());
  }
  double sumTot[2] = {0.,0.};
  printf("totalMC: %5.2f\n",histo[0][1]->GetSumOfWeights()+histo[0][2]->GetSumOfWeights()+histo[0][3]->GetSumOfWeights()+
                            histo[0][4]->GetSumOfWeights()+histo[0][5]->GetSumOfWeights()+histo[0][6]->GetSumOfWeights()+histo[0][7]->GetSumOfWeights());
  for(int iEta=0; iEta<5; iEta++){
    for(int iPt=0; iPt<5; iPt++){
      sumTot[0] = sumTot[0] + denFRDA[iPt][iEta];
      sumTot[1] = sumTot[1] + denFRBG[iPt][iEta];
      printf("(%d,%d): (%6.1f-%6.1f)/(%6.1f-%6.1f)=%4.3f | ",iPt,iEta,numFRDA[iPt][iEta],numFRBG[iPt][iEta] , denFRDA[iPt][iEta],denFRBG[iPt][iEta],
                                                                     (numFRDA[iPt][iEta]-numFRBG[iPt][iEta])/(denFRDA[iPt][iEta]-denFRBG[iPt][iEta]));
      if(iPt==4) printf("\n");
    }
  }
  printf("sumTot(da/bg) = %f / %f = %f\n",sumTot[0],sumTot[1],sumTot[0]/sumTot[1]);
  if(nsel == 0){
    for(int iEta=0; iEta<5; iEta++){
      for(int iPt=0; iPt<5; iPt++){
        printf("(%d,%d): (%6.1f)/(%6.1f)=%7.5f | ",iPt,iEta,denFRDA[iPt][iEta],denFRBG[iPt][iEta],denFRDA[iPt][iEta]/denFRBG[iPt][iEta]);
        if(iPt==4) printf("\n");
      }
    }
  }
  else {
    for(int iEta=0; iEta<5; iEta++){
      for(int iPt=0; iPt<5; iPt++){
        printf("(%d,%d): (%6.1f)/(%6.1f)=%4.3f | ",iPt,iEta,numFRDA[iPt][iEta] , denFRDA[iPt][iEta],
                                                           (numFRDA[iPt][iEta])/(denFRDA[iPt][iEta]));
        if(iPt==4) printf("\n");
      }
    }
  }

  if(typeSel == 11) printf("double fake_rate_e[%d][%d] = {\n",5,5);
  else              printf("double fake_rate_m[%d][%d] = {\n",5,5);
  for(int iEta=0; iEta<5; iEta++){
    for(int iPt=0; iPt<5; iPt++){
      printf("%4.3f",TMath::Abs((numFRDA[iPt][iEta]-numFRBG[iPt][iEta])/(denFRDA[iPt][iEta]-denFRBG[iPt][iEta])));
      if(iPt!=4||iEta!=4) printf(",");
      if(iPt==4) printf("\n");
    }
  }
  printf("};\n");
  
  for(int thePlot=0; thePlot<allPlots; thePlot++){
    char output[200];
    sprintf(output,"histo_fake_%d_%d_%d.root",thePlot,nsel,typeSel);	  
    TFile* outFilePlotsNote = new TFile(output,"recreate");
    outFilePlotsNote->cd();
    for(int np=0; np<histBins; np++) histo[thePlot][np]->Write();
    outFilePlotsNote->Close();
  }

}
void computeDYBkgScaleFactor(Int_t period = 1, Double_t MassZCut = 15){

  TString filesPath  = "/scratch5/ceballos/ntuples_weights/met_";
  Double_t lumi = 0.0715;
  if(period == 1) lumi = 2.2;

  float dymva_= -999.;
  unsigned int nlep_= -1;
  unsigned int njets_= -1;

  //*******************************************************
  //Input Files
  //*******************************************************
  vector<TString> infilenamev;  
  vector<Int_t> infilecatv;  

  TString puPath = "";
  if      (period==0){
  puPath = "/home/ceballos/cms/cmssw/042/CMSSW_7_4_6/src/MitAnalysisRunII/data/puWeights_13TeV_50ns.root";
  infilenamev.push_back(Form("%sdata_AOD_50ns.root",filesPath.Data()));														  infilecatv.push_back(0);
  infilenamev.push_back(Form("%sDYJetsToLL_M-10to50_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt50ns_MCRUN2_74_V9A-v1+AODSIM.root",filesPath.Data()));	  infilecatv.push_back(1);
  infilenamev.push_back(Form("%sDYJetsToLL_M-50_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt50ns_MCRUN2_74_V9A-v2+AODSIM.root",filesPath.Data()));  	  infilecatv.push_back(1);
  infilenamev.push_back(Form("%sWZ_TuneCUETP8M1_13TeV-pythia8+RunIISpring15DR74-Asympt50ns_MCRUN2_74_V9A-v2+AODSIM.root",filesPath.Data()));					  infilecatv.push_back(2);
  infilenamev.push_back(Form("%sZZ_TuneCUETP8M1_13TeV-pythia8+RunIISpring15DR74-Asympt50ns_MCRUN2_74_V9A-v2+AODSIM.root",filesPath.Data()));					  infilecatv.push_back(2);
  assert(0);
  }
  else if(period==1){
  puPath = "/home/ceballos/cms/cmssw/042/CMSSW_7_4_6/src/MitAnalysisRunII/data/puWeights_13TeV_25ns.root";
  infilenamev.push_back(Form("%sdata_AOD_Run2015C1_25ns.root",filesPath.Data()));												  infilecatv.push_back(0);
  infilenamev.push_back(Form("%sdata_AOD_Run2015D3_25ns.root",filesPath.Data()));												infilecatv.push_back(0);
  infilenamev.push_back(Form("%sdata_AOD_Run2015D4_25ns.root",filesPath.Data()));												infilecatv.push_back(0);
  infilenamev.push_back(Form("%sDYJetsToLL_M-10to50_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));	infilecatv.push_back(1);
  infilenamev.push_back(Form("%sDYJetsToLL_M-50_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v3+AODSIM.root",filesPath.Data()));		  infilecatv.push_back(1);
  infilenamev.push_back(Form("%sZZTo2L2Nu_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));					infilecatv.push_back(2);
  infilenamev.push_back(Form("%sZZTo2L2Q_13TeV_amcatnloFXFX_madspin_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			infilecatv.push_back(2);
  infilenamev.push_back(Form("%sZZTo4L_13TeV_powheg_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));					infilecatv.push_back(2);
  infilenamev.push_back(Form("%sGluGluToZZTo2e2mu_BackgroundOnly_13TeV_MCFM+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			infilecatv.push_back(2);
  infilenamev.push_back(Form("%sGluGluToZZTo2e2tau_BackgroundOnly_13TeV_MCFM+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			infilecatv.push_back(2);
  infilenamev.push_back(Form("%sGluGluToZZTo2mu2tau_BackgroundOnly_13TeV_MCFM+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			infilecatv.push_back(2);
  infilenamev.push_back(Form("%sGluGluToZZTo4e_BackgroundOnly_13TeV_MCFM+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));  			infilecatv.push_back(2);
  infilenamev.push_back(Form("%sGluGluToZZTo4mu_BackgroundOnly_13TeV_MCFM+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data())); 			infilecatv.push_back(2);
  infilenamev.push_back(Form("%sGluGluToZZTo4tau_BackgroundOnly_13TeV_MCFM+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			infilecatv.push_back(2);
  infilenamev.push_back(Form("%sWZTo1L1Nu2Q_13TeV_amcatnloFXFX_madspin_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			infilecatv.push_back(2);
  infilenamev.push_back(Form("%sWZTo2L2Q_13TeV_amcatnloFXFX_madspin_pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v2+AODSIM.root",filesPath.Data()));			infilecatv.push_back(2);
  infilenamev.push_back(Form("%sWZTo3LNu_TuneCUETP8M1_13TeV-powheg-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));			infilecatv.push_back(2);
  }
  else {assert(0);}

  if(infilenamev.size() != infilecatv.size()) assert(0);

  const Double_t mZ = 91.1876;
  
  const Int_t nbins = 4;  
  Float_t bins[nbins+1];

  const Int_t nmass = 3;
  const Double_t mH[nmass]     = {0, 125, 200};  
  bool useRFromData[3] = {1, 1, 1};

  //*******************************************************
  //Yields and  histograms
  //*******************************************************
  vector<Double_t> nin_kee_data, nin_kmm_data;
  
  vector<vector<TH1D*> > hNin_ree_mc,   hNout_ree_mc,   hNin_rmm_mc,   hNout_rmm_mc;
  vector<vector<TH1D*> > hNin_ree_da,   hNout_ree_da,   hNin_rmm_da,   hNout_rmm_da;

  vector<vector<Double_t> > nin_ee_dy, nout_ee_dy, nin_ee_vz, nout_ee_vz, nin_ee_data;  
  vector<vector<Double_t> > nin_mm_dy, nout_mm_dy, nin_mm_vz, nout_mm_vz, nin_mm_data;
  vector<vector<Double_t> > varin_ee_dy, varout_ee_dy, varin_ee_vz, varout_ee_vz;
  vector<vector<Double_t> > varin_mm_dy, varout_mm_dy, varin_mm_vz, varout_mm_vz;
  vector<vector<Double_t> > nin_em_data;

  
  for(UInt_t jetIndex = 0; jetIndex < 3; ++jetIndex) {
    Double_t tmp_nin_kee_data=0, tmp_nin_kmm_data=0;
    vector<TH1D*> tmp_hNin_ree_mc,   tmp_hNout_ree_mc,   tmp_hNin_rmm_mc,   tmp_hNout_rmm_mc;
    vector<TH1D*> tmp_hNin_ree_da,   tmp_hNout_ree_da,   tmp_hNin_rmm_da,   tmp_hNout_rmm_da;
    
    vector<Double_t> tmp_nin_ee_dy, tmp_nout_ee_dy, tmp_nin_ee_vz, tmp_nout_ee_vz, tmp_nin_ee_data;  
    vector<Double_t> tmp_nin_mm_dy, tmp_nout_mm_dy, tmp_nin_mm_vz, tmp_nout_mm_vz, tmp_nin_mm_data;
    vector<Double_t> tmp_varin_ee_dy, tmp_varout_ee_dy, tmp_varin_ee_vz, tmp_varout_ee_vz;
    vector<Double_t> tmp_varin_mm_dy, tmp_varout_mm_dy, tmp_varin_mm_vz, tmp_varout_mm_vz;
    vector<Double_t> tmp_nin_em_data;

    char hname[50];
    for(Int_t imass=0; imass<nmass; imass++) {
      if     (useDYMVA == kTRUE){
        if     (jetIndex == 0){
	  bins[0] = -0.20; bins[1] =  0.10; bins[2] = +0.20; bins[3] =  0.30; bins[4] = 1.0; 
	}
	else if(jetIndex == 1){
	  bins[0] = -0.20; bins[1] = +0.10; bins[2] = +0.20; bins[3] =  0.30; bins[4] = 1.0; 
	}
	else if(jetIndex == 2){
	  bins[0] = -0.20; bins[1] = +0.10; bins[2] = +0.20; bins[3] =  0.30; bins[4] = 1.0; 
	}
      } else {
	bins[0] = 20; bins[1] = 25; bins[2] = 35; bins[3] =  45; bins[4] = 70; 
      }

      sprintf(hname,"hNin_%iJet_ree_mc_m%i",Int_t(jetIndex),(Int_t)mH[imass]);  tmp_hNin_ree_mc.push_back(new TH1D(hname,"",nbins,bins));  tmp_hNin_ree_mc[imass]->Sumw2();
      sprintf(hname,"hNout_%iJet_ree_mc_m%i",Int_t(jetIndex),(Int_t)mH[imass]); tmp_hNout_ree_mc.push_back(new TH1D(hname,"",nbins,bins)); tmp_hNout_ree_mc[imass]->Sumw2();
      sprintf(hname,"hNin_%iJet_rmm_mc_m%i",Int_t(jetIndex),(Int_t)mH[imass]);  tmp_hNin_rmm_mc.push_back(new TH1D(hname,"",nbins,bins));  tmp_hNin_rmm_mc[imass]->Sumw2();
      sprintf(hname,"hNout_%iJet_rmm_mc_m%i",Int_t(jetIndex),(Int_t)mH[imass]); tmp_hNout_rmm_mc.push_back(new TH1D(hname,"",nbins,bins)); tmp_hNout_rmm_mc[imass]->Sumw2();
      
      sprintf(hname,"hNin_%iJet_ree_da_m%i",Int_t(jetIndex),(Int_t)mH[imass]);  tmp_hNin_ree_da.push_back(new TH1D(hname,"",nbins,bins));  tmp_hNin_ree_da[imass]->Sumw2();
      sprintf(hname,"hNout_%iJet_ree_da_m%i",Int_t(jetIndex),(Int_t)mH[imass]); tmp_hNout_ree_da.push_back(new TH1D(hname,"",nbins,bins)); tmp_hNout_ree_da[imass]->Sumw2();
      sprintf(hname,"hNin_%iJet_rmm_da_m%i",Int_t(jetIndex),(Int_t)mH[imass]);  tmp_hNin_rmm_da.push_back(new TH1D(hname,"",nbins,bins));  tmp_hNin_rmm_da[imass]->Sumw2();
      sprintf(hname,"hNout_%iJet_rmm_da_m%i",Int_t(jetIndex),(Int_t)mH[imass]); tmp_hNout_rmm_da.push_back(new TH1D(hname,"",nbins,bins)); tmp_hNout_rmm_da[imass]->Sumw2();
      
      tmp_nin_ee_dy.push_back(0), tmp_nout_ee_dy.push_back(0), tmp_nin_ee_vz.push_back(0), tmp_nout_ee_vz.push_back(0), tmp_nin_ee_data.push_back(0);
      tmp_nin_mm_dy.push_back(0), tmp_nout_mm_dy.push_back(0), tmp_nin_mm_vz.push_back(0), tmp_nout_mm_vz.push_back(0), tmp_nin_mm_data.push_back(0);
      tmp_varin_ee_dy.push_back(0), tmp_varout_ee_dy.push_back(0), tmp_varin_ee_vz.push_back(0), tmp_varout_ee_vz.push_back(0);    
      tmp_varin_mm_dy.push_back(0), tmp_varout_mm_dy.push_back(0), tmp_varin_mm_vz.push_back(0), tmp_varout_mm_vz.push_back(0);
      tmp_nin_em_data.push_back(0);
     }

    nin_kee_data.push_back(tmp_nin_kee_data);
    nin_kmm_data.push_back(tmp_nin_kmm_data);

    hNin_ree_mc.push_back(tmp_hNin_ree_mc); 
    hNout_ree_mc.push_back(tmp_hNout_ree_mc); 
    hNin_rmm_mc.push_back(tmp_hNin_rmm_mc); 
    hNout_rmm_mc.push_back(tmp_hNout_rmm_mc);

    hNin_ree_da.push_back(tmp_hNin_ree_da); 
    hNout_ree_da.push_back(tmp_hNout_ree_da); 
    hNin_rmm_da.push_back(tmp_hNin_rmm_da); 
    hNout_rmm_da.push_back(tmp_hNout_rmm_da);

    nin_ee_dy.push_back(tmp_nin_ee_dy);
    nout_ee_dy.push_back(tmp_nout_ee_dy);
    nin_ee_vz.push_back(tmp_nin_ee_vz);
    nout_ee_vz.push_back(tmp_nout_ee_vz);
    nin_ee_data.push_back(tmp_nin_ee_data);
    nin_mm_dy.push_back(tmp_nin_mm_dy);
    nout_mm_dy.push_back(tmp_nout_mm_dy);
    nin_mm_vz.push_back(tmp_nin_mm_vz);
    nout_mm_vz.push_back(tmp_nout_mm_vz);
    nin_mm_data.push_back(tmp_nin_mm_data);
    varin_ee_dy.push_back(tmp_varin_ee_dy);
    varout_ee_dy.push_back(tmp_varout_ee_dy);
    varin_ee_vz.push_back(tmp_varin_ee_vz);
    varout_ee_vz.push_back(tmp_varout_ee_vz);
    varin_mm_dy.push_back(tmp_varin_mm_dy);
    varout_mm_dy.push_back(tmp_varout_mm_dy);
    varin_mm_vz.push_back(tmp_varin_mm_vz);
    varout_mm_vz.push_back(tmp_varout_mm_vz);
    nin_em_data.push_back(tmp_nin_em_data);
  }
  //*******************************************************
  //Systematic Error on VZ Normalization
  //*******************************************************
  const Double_t vzNormSystematic = 0.10;

  Float_t fMVACut[4][4];
  InitializeJetIdCuts(fMVACut);
 
  TFile *fPUFile = TFile::Open(Form("%s",puPath.Data()));
  TH1D *fhDPU = (TH1D*)(fPUFile->Get("puWeights"));
  assert(fhDPU);
  fhDPU->SetDirectory(0);
  delete fPUFile;

  //*******************************************************
  // Chain Loop
  //*******************************************************
  for(UInt_t ifile=0; ifile<infilenamev.size(); ifile++) {

    TFile the_input_file(infilenamev[ifile]);
    TTree *the_input_tree = (TTree*)the_input_file.FindObjectAny("events");
    //TTree *the_input_all  = (TTree*)the_input_file.FindObjectAny("all");

    BareMonteCarlo eventMonteCarlo;
    eventMonteCarlo.setBranchAddresses(the_input_tree);

    BareEvent eventEvent;
    eventEvent.setBranchAddresses(the_input_tree);

    BareJets eventJets;
    eventJets.setBranchAddresses(the_input_tree);

    BareLeptons eventLeptons;
    eventLeptons.setBranchAddresses(the_input_tree);

    BareTaus eventTaus;
    eventTaus.setBranchAddresses(the_input_tree);

    BareMet eventMet;
    eventMet.SetExtend();
    eventMet.setBranchAddresses(the_input_tree);

    BareTrigger eventTrigger;
    eventTrigger.setBranchAddresses(the_input_tree);

    BareVertex eventVertex;
    eventVertex.setBranchAddresses(the_input_tree);

    if(useDYMVA == true){
      the_input_tree->SetBranchAddress("dymva", &dymva_);
      the_input_tree->SetBranchAddress("nlep", &nlep_ );
      the_input_tree->SetBranchAddress("njets", &njets_);
    }

    TNamed *triggerNames = (TNamed*)the_input_file.FindObjectAny("triggerNames");
    char **tokens;
    size_t numtokens;
    tokens = strsplit(triggerNames->GetTitle(), ",", &numtokens);
    if(infilecatv[ifile] == 0){
      for (int i = 0; i < (int)numtokens; i++) {
        printf("triggerNames(%2d): \"%s\"\n",(int)i,tokens[i]);
      }
    }

    double theMCPrescale = mcPrescale;
    if(infilecatv[ifile] == 0) theMCPrescale = 1.0;
    for (int i=0; i<int(the_input_tree->GetEntries()/theMCPrescale); ++i) {
      the_input_tree->GetEntry(i);
      if(i%100000==0) printf("event %d out of %d\n",i,(int)the_input_tree->GetEntries());

      Bool_t passFilter[6] = {kFALSE,kFALSE,kFALSE,kFALSE,kFALSE,kFALSE};
      vector<int> idLep; vector<int> idTight; vector<int> idSoft; unsigned int goodIsTight = 0;
      for(int nlep=0; nlep<eventLeptons.p4->GetEntriesFast(); nlep++) {
        if(selectIdIsoCut(typeLepSel.Data(),TMath::Abs((int)(*eventLeptons.pdgId)[nlep]),TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt()),
	   TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),(double)(*eventLeptons.iso)[nlep],(int)(*eventLeptons.selBits)[nlep]))
	                                                                                               {idTight.push_back(1); idLep.push_back(nlep); goodIsTight++;}
        else if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepFake)  == BareLeptons::LepFake ) {idTight.push_back(0); idLep.push_back(nlep);}
        else if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepSoftIP)== BareLeptons::LepSoftIP){idSoft.push_back(nlep);}
      }
      if(idLep.size()!=idTight.size()) assert(0);
      if(idLep.size()==2) passFilter[0] = kTRUE;
      if(passFilter[0] == kFALSE) continue;

      if(idLep.size() >= 2 &&
     	 ((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() > 20 && 
     	 ((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Pt() > 20) passFilter[1] = kTRUE;
      for (int nt = 0; nt <(int)numtokens; nt++) {
        if((*eventTrigger.triggerFired)[nt] == 0) continue;
        if((strcmp(tokens[nt],"HLT_Mu8_TrkIsoVVL_Ele17_CaloIdL_TrackIdL_IsoVL_v*")  == 0) ||
           (strcmp(tokens[nt],"HLT_Mu8_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL_v*")  == 0) ||
           (strcmp(tokens[nt],"HLT_Mu17_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL_v*") == 0) ||
           (strcmp(tokens[nt],"HLT_Mu23_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL_v*") == 0) ||
           (strcmp(tokens[nt],"HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ_v*") 	    == 0) ||
           (strcmp(tokens[nt],"HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL_DZ_v*")	    == 0) ||
           (strcmp(tokens[nt],"HLT_IsoMu27_v*") 				    == 0) ||
           (strcmp(tokens[nt],"HLT_IsoMu20_v*") 				    == 0) ||
           (strcmp(tokens[nt],"HLT_IsoTkMu20_v*")				    == 0) ||
           (strcmp(tokens[nt],"HLT_Ele17_Ele12_CaloIdL_TrackIdL_IsoVL_DZ_v*")	    == 0) ||
           (strcmp(tokens[nt],"HLT_Ele23_WPLoose_Gsf_v*")			    == 0) ||
           (strcmp(tokens[nt],"HLT_Ele22_eta2p1_WP75_Gsf_v*")			    == 0) ||
           (strcmp(tokens[nt],"HLT_Ele27_WPLoose_Gsf_v*")			    == 0) ||
           (strcmp(tokens[nt],"HLT_Ele27_WP85_Gsf_v*")  			    == 0)
           ) passFilter[2] = kTRUE;
      }

      if(passFilter[1] == kFALSE) continue;
      if(passFilter[2] == kFALSE) continue;

      if(goodIsTight == idTight.size()) passFilter[3] = kTRUE;
      if(passFilter[3] == kFALSE) continue;

      passFilter[4] = ((int)(*eventLeptons.pdgId)[idLep[0]]*(int)(*eventLeptons.pdgId)[idLep[1]] < 0);
      if(passFilter[4] == kFALSE) continue;

      TLorentzVector dilep(( ( *(TLorentzVector*)(eventLeptons.p4->At(idLep[0])) ) + ( *(TLorentzVector*)(eventLeptons.p4->At(idLep[1])) ) )); 

      double dPhiLepMETMin = 999.;
      for(unsigned nl=0; nl<idLep.size(); nl++){
        if(dPhiLepMETMin > TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[nl]])->DeltaPhi(*((TLorentzVector*)(*eventMet.p4)[0]))))
           dPhiLepMETMin = TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[nl]])->DeltaPhi(*((TLorentzVector*)(*eventMet.p4)[0])));      
      }
      double minMET  = TMath::Min(((TLorentzVector*)(*eventMet.p4)[0])->Pt(),(double)eventMet.trackMet->Pt());
      double minPMET = TMath::Min(((TLorentzVector*)(*eventMet.p4)[0])->Pt(),(double)eventMet.trackMet->Pt());
      if(dPhiLepMETMin < TMath::Pi()/2) minPMET = minPMET * sin(dPhiLepMETMin);

      unsigned int nJets = 0;
      bool isBtag = kFALSE;
      double bDiscrMax = 0.0;
      double dPhiJetMET = -1.0;
      double dPhiJetDiLep = -1.0;
      for(int nj=0; nj<eventJets.p4->GetEntriesFast(); nj++){
        if(((TLorentzVector*)(*eventJets.p4)[nj])->Pt() < 10) continue;
        bool passId = passJetId(fMVACut, (float)(*eventJets.puId)[nj], ((TLorentzVector*)(*eventJets.p4)[nj])->Pt(), TMath::Abs(((TLorentzVector*)(*eventJets.p4)[nj])->Eta()));
        //if(passId == false) continue;        

        Bool_t isLepton = kFALSE;
        for(unsigned int nl=0; nl<idLep.size(); nl++){
          if(((TLorentzVector*)(*eventJets.p4)[nj])->DeltaR(*((TLorentzVector*)(*eventLeptons.p4)[idLep[nl]])) < 0.3) isLepton = kTRUE;
	}
	if(isLepton == kTRUE) continue;

        if(dPhiJetMET   == -1) dPhiJetMET   = TMath::Abs(((TLorentzVector*)(*eventJets.p4)[nj])->DeltaPhi(*((TLorentzVector*)(*eventMet.p4)[0])))*180./TMath::Pi();
        if(dPhiJetDiLep == -1) dPhiJetDiLep = TMath::Abs(dilep.DeltaPhi(*((TLorentzVector*)(*eventJets.p4)[nj])))*180./TMath::Pi();

	if(((TLorentzVector*)(*eventJets.p4)[nj])->Pt() > 15 && 
	   (float)(*eventJets.bDiscr)[nj] > bDiscrMax) bDiscrMax = (float)(*eventJets.bDiscr)[nj];

        if(((TLorentzVector*)(*eventJets.p4)[nj])->Pt() < 30) continue;

        nJets++;
      }

      if(useDYMVA == true){
        if(nlep_ != idLep.size()) {printf("PROBLEM nlep %d != %d\n",(int)nlep_,(int)idLep.size()); assert(1); return;}
        if(njets_ != nJets) {printf("PROBLEM njet %d != %d\n",(int)njets_,nJets); assert(1); return;}
      }

      if(nJets <= 2) passFilter[5] = kTRUE;  	    
      if(passFilter[5] == kFALSE) continue;

      Int_t typeLep = 2;
      if     (TMath::Abs((int)(*eventLeptons.pdgId)[idLep[0]])==13&&TMath::Abs((int)(*eventLeptons.pdgId)[idLep[1]])==13) typeLep = 0;
      else if(TMath::Abs((int)(*eventLeptons.pdgId)[idLep[0]])==11&&TMath::Abs((int)(*eventLeptons.pdgId)[idLep[1]])==11) typeLep = 1;

      if(infilecatv[ifile] == 0 && TMath::Abs(dilep.M()-mZ)<MassZCut) {
        if(typeLep == 0) nin_kmm_data[nJets]++;
        if(typeLep == 1) nin_kee_data[nJets]++;
      }

      if(minPMET <= 20) continue;
      double varMet = minPMET;
      if(varMet>=70) varMet=69;
      if(useDYMVA == kTRUE) {
        varMet = dymva_;
      }

      double theLumi = lumi; if(infilecatv[ifile] == 0) theLumi = 1.0;
      double puWeight = nPUScaleFactor(fhDPU, (double)eventVertex.npv); if(infilecatv[ifile] == 0) puWeight = 1.0;
      double effSF = 1.0;

      if(infilecatv[ifile] != 0){
        effSF = effScaleFactor(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt(),TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Eta()),TMath::Abs((int)(*eventLeptons.pdgId)[idLep[0]]),period,typeLepSel.Data())*
                effScaleFactor(((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Pt(),TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Eta()),TMath::Abs((int)(*eventLeptons.pdgId)[idLep[1]]),period,typeLepSel.Data());
      }

      double totalWeight = eventMonteCarlo.mcWeight*theLumi*puWeight*effSF*theMCPrescale;

      vector<bool> isGenDupl;
      for(int ngen0=0; ngen0<eventMonteCarlo.p4->GetEntriesFast(); ngen0++) {
        isGenDupl.push_back(0);
	if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen0]) != 11 &&
	   TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen0]) != 13) isGenDupl[ngen0] = 1;
	if(TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen0]) != 11 &&
	   TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen0]) != 13) continue;
        for(int ngen1=ngen0+1; ngen1<eventMonteCarlo.p4->GetEntriesFast(); ngen1++) {
          if(((TLorentzVector*)(*eventMonteCarlo.p4)[ngen0])->DeltaR(*((TLorentzVector*)(*eventMonteCarlo.p4)[ngen1])) < 0.02) {
	    isGenDupl[ngen0] = 1;
	    break;
	  }
        }
      }
      vector<int> isGenLep; unsigned int goodIsGenLep = 0;
      for(unsigned nl=0; nl<idLep.size(); nl++){
        bool isGenLepton = false;
        for(int ngen=0; ngen<eventMonteCarlo.p4->GetEntriesFast(); ngen++) {
	  if(isGenDupl[ngen] == 1) continue;
          if(TMath::Abs((int)(*eventLeptons.pdgId)[idLep[nl]]) == TMath::Abs((int)(*eventMonteCarlo.pdgId)[ngen]) &&
	    ((TLorentzVector*)(*eventLeptons.p4)[idLep[nl]])->DeltaR(*((TLorentzVector*)(*eventMonteCarlo.p4)[ngen])) < 0.1) {
	    isGenLepton = true;
	    break;
	  }
	}
	if(isGenLepton == true) {isGenLep.push_back(1); goodIsGenLep++;}
	else                    {isGenLep.push_back(0);}
      }
      if(infilecatv[ifile] != 0 && goodIsGenLep != isGenLep.size()) totalWeight = 0.0;

      //loop over analyses
      for(Int_t imass=0; imass<nmass; imass++) {
        // MET related cuts need to be applied after the Rout/in computation
        double theCutMassHigh = 1000.;
	if(dilep.Pt() <= 45.0) continue;
        if(bDiscrMax > 0.605 || idSoft.size() != 0) continue;
	if(dilep.M() <= 12.0) continue;

        if(infilecatv[ifile] == 1){ // Z MC
	  if     (TMath::Abs(dilep.M()-mZ)<MassZCut) {
	    if     (typeLep == 1) {
              hNin_ree_mc[nJets][imass]->Fill(varMet,totalWeight);		 
            }
	    else if(typeLep == 0) {
              hNin_rmm_mc[nJets][imass]->Fill(varMet,totalWeight);		     
            }
          } 
	  else if(TMath::Abs(dilep.M()-mZ) >= 15 && dilep.M() < theCutMassHigh) {
	    if     (typeLep == 1) {
              hNout_ree_mc[nJets][imass]->Fill(varMet,totalWeight);  
            }
	    else if(typeLep == 0) {
              hNout_rmm_mc[nJets][imass]->Fill(varMet,totalWeight);
            }
          }
        }
 
        double theDataWeight = 0.0;
        if     (infilecatv[ifile] == 0 && (typeLep == 0 || typeLep == 1)) theDataWeight =  1.0;
	else if(infilecatv[ifile] == 0					) theDataWeight = -1.0;

	// In reality ee == ee+mm for data
	if(theDataWeight != 0.0){
	  if     (TMath::Abs(dilep.M()-mZ)<MassZCut) {
            hNin_ree_da[nJets][imass]->Fill(varMet,theDataWeight);		
          } 
	  else if(TMath::Abs(dilep.M()-mZ) >= 15 && dilep.M() < theCutMassHigh) {
            hNout_ree_da[nJets][imass]->Fill(varMet,theDataWeight);     
          }
        }

	bool passMET = varMet > 45;
	if(useDYMVA == kTRUE) passMET = dymva_ > 0.3;
	if(passMET == kFALSE) continue;

        if(infilecatv[ifile] == 1){ // Z MC
	  if     (TMath::Abs(dilep.M()-mZ)<MassZCut) {
	    if     (typeLep == 1) { 
	      nin_ee_dy[nJets][imass]+=totalWeight; 
	      varin_ee_dy[nJets][imass]+=totalWeight*totalWeight; 
	    }	
	    else if(typeLep == 0) { 
	      nin_mm_dy[nJets][imass]+=totalWeight; 
	      varin_mm_dy[nJets][imass]+=totalWeight*totalWeight;
	    }

           } 
	   else if(TMath::Abs(dilep.M()-mZ) >= 15 && dilep.M() < theCutMassHigh) {
	    if     (typeLep == 1) {
	      nout_ee_dy[nJets][imass]+=totalWeight; 
	      varout_ee_dy[nJets][imass]+=totalWeight*totalWeight;
	    }  
	    else if(typeLep == 0) {
	      nout_mm_dy[nJets][imass]+=totalWeight;
	      varout_mm_dy[nJets][imass]+=totalWeight*totalWeight;
	    }
          }
        }

        //In Z peak region
	if(TMath::Abs(dilep.M()-mZ)<MassZCut) {

          if(typeLep == 1) {
            if(infilecatv[ifile] == 0) { 
              nin_ee_data[nJets][imass]++; 
            }
            if(infilecatv[ifile] == 2)  {
              nin_ee_vz[nJets][imass]+=totalWeight;
              varin_ee_vz[nJets][imass]+=totalWeight*totalWeight;
            }
          }
	
          if(typeLep == 0) {
            if(infilecatv[ifile] == 0) { 
              nin_mm_data[nJets][imass]++;
            }	
            if(infilecatv[ifile] == 2) {
              nin_mm_vz[nJets][imass]+=totalWeight;
              varin_mm_vz[nJets][imass]+=totalWeight*totalWeight;
            }		   
          }

	  if(infilecatv[ifile] == 0 && typeLep == 2) {
            nin_em_data[nJets][imass]++; 
          }

        } 
        // Out of Z peak region
        else if(TMath::Abs(dilep.M()-mZ) >= 15 && dilep.M() < theCutMassHigh) {

	  if(typeLep == 0) {
            if (infilecatv[ifile] == 2) {
              nout_ee_vz[nJets][imass]+=totalWeight;
              varout_ee_vz[nJets][imass]+=totalWeight*totalWeight;
            }
	  }
	
	  if(typeLep == 1) {
            if (infilecatv[ifile] == 2) {
              nout_mm_vz[nJets][imass]+=totalWeight;
              varout_mm_vz[nJets][imass]+=totalWeight*totalWeight;
            }
	  }
        }

      }
    }
  } // end of chain

  //--------------------------------------------------------------------------------------------------------------
  // Summary print out
  //============================================================================================================== 
  char DYEstimateTableName[200];
  sprintf(DYEstimateTableName,"DYEstimateTable.txt");
  ofstream fout(DYEstimateTableName);

  vector<vector<Double_t> > DYBkgScaleFactorHiggsSelection;
  vector<vector<Double_t> > DYBkgScaleFactorHiggsSelectionErr;
  vector<Double_t> DYBkgScaleFactorWWPreselection;
  vector<Double_t> DYBkgScaleFactorWWPreselectionErr;

  for(UInt_t jetIndex = 0; jetIndex < 3; ++jetIndex) {
    
    vector<Double_t> tmpDYBkgScaleFactorHiggsSelection;
    vector<Double_t> tmpDYBkgScaleFactorHiggsSelectionErr;
    Double_t tmpDYBkgScaleFactorWWPreselection;
    Double_t tmpDYBkgScaleFactorWWPreselectionErr;

    fout << "************************************************************************\n";
    fout << jetIndex << "-Jet Bin DY Bkg Scale Factor Computation\n";
    fout << "************************************************************************\n";

    Double_t k    = sqrt(nin_kee_data[jetIndex]/nin_kmm_data[jetIndex]);
    Double_t kerr = 0.5*k*sqrt(1.0/nin_kee_data[jetIndex] + 1.0/nin_kmm_data[jetIndex]);
    char buffer[200];
  
    fout << "Electron to muon efficiency ratio is " << k << " +/- " << kerr << endl;

    fout << endl;
    fout << jetIndex << "-jet bin summary:" << endl;
    fout << setw(4) << "sel" << "   ";
    fout << setw(25) << "R_out/in       ";
    fout << setw(15) << "mm/em/ee";
    fout << setw(20) << "N_in (OF,VZ sub)";
    fout << setw(20) << "N_in (data/MC)";
    fout << setw(20) << "   N_out data   ";
    fout << setw(20) << "N_out MC  ";
    fout << setw(20) << "N_out (data/MC)" << endl;


    for(Int_t imass=0; imass<nmass; imass++) {
      fout << setw(4) << mH[imass] << "   ";
    
      //
      // compute Routin from MC
      //

      Int_t MetBinToComputeRoutin = nbins-1;

      Double_t nout_ee   = 0;
      Double_t errout_ee = 0;
      Double_t nout_mm   = 0;
      Double_t errout_mm = 0;
      Double_t nout_ll   = 0;
      Double_t errout_ll = 0;      
      Double_t nin_ee   = 0;
      Double_t errin_ee = 0;
      Double_t nin_mm   = 0;
      Double_t errin_mm = 0;
      Double_t nin_ll   = 0;
      Double_t errin_ll = 0;      
      Double_t Ree        = 0;
      Double_t ReeErrStat = 0;
      Double_t ReeErrSyst = 0;      
      Double_t Rmm        = 0;
      Double_t RmmErrStat = 0;
      Double_t RmmErrSyst = 0;
      Double_t Rll = 0;
      Double_t RllErrStat = 0;
      Double_t RllErrSyst = 0;

      if(useRFromData[jetIndex] == false){
	nout_ee   = hNout_ree_mc[jetIndex][imass]->GetBinContent(MetBinToComputeRoutin);
	errout_ee = hNout_ree_mc[jetIndex][imass]->GetBinError(MetBinToComputeRoutin);
	nout_mm   = hNout_rmm_mc[jetIndex][imass]->GetBinContent(MetBinToComputeRoutin);
	errout_mm = hNout_rmm_mc[jetIndex][imass]->GetBinError(MetBinToComputeRoutin);
	nout_ll   = nout_ee+nout_mm;
	errout_ll = sqrt(errout_ee*errout_ee + errout_mm*errout_mm);

	nin_ee   = hNin_ree_mc[jetIndex][imass]->GetBinContent(MetBinToComputeRoutin);
	errin_ee = hNin_ree_mc[jetIndex][imass]->GetBinError(MetBinToComputeRoutin);
	nin_mm   = hNin_rmm_mc[jetIndex][imass]->GetBinContent(MetBinToComputeRoutin);
	errin_mm = hNin_rmm_mc[jetIndex][imass]->GetBinError(MetBinToComputeRoutin);
	nin_ll   = nin_ee+nin_mm;
	errin_ll = sqrt(errin_ee*errin_ee + errin_mm*errin_mm);

	Ree        = nout_ee/nin_ee;
	ReeErrStat = Ree*sqrt(errin_ee*errin_ee/nin_ee/nin_ee + errout_ee*errout_ee/nout_ee/nout_ee);
	ReeErrSyst = computeSyst(hNout_ree_mc[jetIndex][imass],hNin_ree_mc[jetIndex][imass], MetBinToComputeRoutin, 0.4);    

	Rmm        = nout_mm/nin_mm;
	RmmErrStat = Rmm*sqrt(errin_mm*errin_mm/nin_mm/nin_mm + errout_mm*errout_mm/nout_mm/nout_mm);
	RmmErrSyst = computeSyst(hNout_rmm_mc[jetIndex][imass],hNin_rmm_mc[jetIndex][imass], MetBinToComputeRoutin, 0.4);

	TH1D *hout = (TH1D*)hNout_ree_mc[jetIndex][imass]->Clone("hout");
	hout->Add(hNout_rmm_mc[jetIndex][imass]);
	TH1D *hin = (TH1D*)hNin_ree_mc[jetIndex][imass]->Clone("hin");
	hin->Add(hNin_rmm_mc[jetIndex][imass]);
	Rll        = nout_ll/nin_ll;
	RllErrStat = Rll*sqrt(errin_ll*errin_ll/nin_ll/nin_ll + errout_ll*errout_ll/nout_ll/nout_ll);
	RllErrSyst = computeSyst(hout,hin, MetBinToComputeRoutin, 0.4);

	delete hout;
	delete hin;
      } else {
	nout_ll   = hNout_ree_da[jetIndex][imass]->GetBinContent(MetBinToComputeRoutin);
	errout_ll = hNout_ree_da[jetIndex][imass]->GetBinError(MetBinToComputeRoutin);

	nin_ll   = hNin_ree_da[jetIndex][imass]->GetBinContent(MetBinToComputeRoutin);
	errin_ll = hNin_ree_da[jetIndex][imass]->GetBinError(MetBinToComputeRoutin);

	TH1D *hout = (TH1D*)hNout_ree_da[jetIndex][imass]->Clone("hout");
	TH1D *hin = (TH1D*)hNin_ree_da[jetIndex][imass]->Clone("hin");

	Rll        = nout_ll/nin_ll;
	RllErrStat = Rll*sqrt(errin_ll*errin_ll/nin_ll/nin_ll + errout_ll*errout_ll/nout_ll/nout_ll);
	Double_t rErrorMax = 100000.4;
	cout << "M: " << mH[imass] << endl;
	RllErrSyst = computeSyst(hout,hin,MetBinToComputeRoutin,rErrorMax,true,true);
	delete hout;
	delete hin;
      }

      if(Rll <= 0) {Rll = 0.10; RllErrStat = 0.10; RllErrSyst = 0.10;}
      // DO NOT ALLOW FOR MORE THAN 100% uncertainty
      if(RllErrSyst > 1.0*Rll) RllErrSyst = 1.0*Rll;
      // DO NOT ALLOW FOR LESS THAN 30% uncertainty
      if(RllErrSyst < 0.3*Rll) RllErrSyst = 0.3*Rll;

      sprintf(buffer,"%.2f +/- %.2f +/- %.2f",Rll,RllErrStat,RllErrSyst);
//     sprintf(buffer,"%.3f +/- %.3f +/- %.3f",Ree,ReeErrStat,ReeErrSyst);
//     sprintf(buffer,"%.3f +/- %.3f +/- %.3f",Rmm,RmmErrStat,RmmErrSyst);
      fout << setw(25) << buffer; 

      //
      // raw in-yields in data
      //
      sprintf(buffer,"%i/%i/%i",Int_t(nin_mm_data[jetIndex][imass]), Int_t(nin_em_data[jetIndex][imass]), Int_t(nin_ee_data[jetIndex][imass]));
      fout << setw(15) << buffer;

      //
      // in-yields in data after OF and VZ subtraction
      //
      Double_t nof = nin_em_data[jetIndex][imass];
      Double_t nin_ee_sub, err_ee_sub,nin_mm_sub,err_mm_sub,nin_ll_sub,err_ll_sub;

      //use Opposite Flavor data for bkg subtraction
      nin_ee_sub = nin_ee_data[jetIndex][imass] - 0.5*k*nof - nin_ee_vz[jetIndex][imass];
      err_ee_sub = sqrt(nin_ee_data[jetIndex][imass] + 0.5*0.5*k*k*nof*nof*(kerr*kerr/k/k + 1.0/nof) + varin_ee_vz[jetIndex][imass] + pow(nin_ee_vz[jetIndex][imass]*vzNormSystematic,2) );
      nin_mm_sub = nin_mm_data[jetIndex][imass] - 0.5/k*nof - nin_mm_vz[jetIndex][imass];
      err_mm_sub = sqrt(nin_mm_data[jetIndex][imass] + 0.5*0.5/k/k*nof*nof*(kerr*kerr/k/k + 1.0/nof) + varin_mm_vz[jetIndex][imass] + pow(nin_mm_vz[jetIndex][imass]*vzNormSystematic,2));
      nin_ll_sub = nin_ee_sub + nin_mm_sub;
      err_ll_sub = sqrt(nin_mm_data[jetIndex][imass] + nin_ee_data[jetIndex][imass] 
        			 + 0.5*0.5*( (k+1.0/k)*(k+1.0/k)*nof*nof*kerr*kerr + (k+1.0/k)*(k+1.0/k)*nof ) 
        			 + varin_mm_vz[jetIndex][imass] + varin_ee_vz[jetIndex][imass] + pow((nin_ee_vz[jetIndex][imass]+nin_mm_vz[jetIndex][imass])*vzNormSystematic,2));
      if(nin_ee_sub <= 0) nin_ee_sub = 1;
      if(nin_mm_sub <= 0) nin_mm_sub = 1;
      if(nin_ll_sub <= 0) nin_ll_sub = 1;

      sprintf(buffer,"  %.2f +/- %.2f : %.2f : %.2f + %.2f  ",nin_ll_sub,err_ll_sub, 0.5*k*nof + 0.5/k*nof, nin_ee_vz[jetIndex][imass], nin_mm_vz[jetIndex][imass]);
      fout << setw(20) << buffer;
    
      //
      // in-yield data/MC scale factor
      //

      Double_t sfin_ee     = nin_ee_sub/nin_ee_dy[jetIndex][imass];
      Double_t sfin_ee_err = sfin_ee*sqrt(err_ee_sub*err_ee_sub/nin_ee_sub/nin_ee_sub + (varin_ee_dy[jetIndex][imass])*(varin_ee_dy[jetIndex][imass])/(nin_ee_dy[jetIndex][imass])/(nin_ee_dy[jetIndex][imass]));
      Double_t sfin_mm     = nin_mm_sub/nin_mm_dy[jetIndex][imass];
      Double_t sfin_mm_err = sfin_mm*sqrt(err_mm_sub*err_mm_sub/nin_mm_sub/nin_mm_sub + (varin_mm_dy[jetIndex][imass])*(varin_mm_dy[jetIndex][imass])/(nin_mm_dy[jetIndex][imass])/(nin_mm_dy[jetIndex][imass]));
      Double_t sfin_ll     = nin_ll_sub/(nin_ee_dy[jetIndex][imass]+nin_mm_dy[jetIndex][imass]);
//       Double_t sfin_ll_err = sfin_ll*sqrt(err_ll_sub*err_ll_sub/nin_ll_sub/nin_ll_sub 
//                                           + (varin_ee_dy[jetIndex][imass]+varin_mm_dy[jetIndex][imass])*(varin_ee_dy[jetIndex][imass]+varin_mm_dy[jetIndex][imass])/(nin_ee_dy[jetIndex][imass]+nin_mm_dy[jetIndex][imass])/(nin_ee_dy[jetIndex][imass]+nin_mm_dy[jetIndex][imass]));
      Double_t sfin_ll_err = sfin_ll*sqrt(err_ll_sub*err_ll_sub/nin_ll_sub/nin_ll_sub 
                                          + (varin_ee_dy[jetIndex][imass]+varin_mm_dy[jetIndex][imass])/(nin_ee_dy[jetIndex][imass]+nin_mm_dy[jetIndex][imass])/(nin_ee_dy[jetIndex][imass]+nin_mm_dy[jetIndex][imass]));
   
      sprintf(buffer,"%.2f +/- %.2f",sfin_ll,sfin_ll_err);
//    sprintf(buffer,"%.2f +/- %.2f",sfin_ee,sfin_ee_err);
//    sprintf(buffer,"%.2f +/- %.2f",sfin_mm,sfin_mm_err);
      fout << setw(20) << buffer;
    
      //
      // out-yield prediction
      //
      Double_t nout_ee_pre = Ree*nin_ee_sub;
      Double_t nout_ee_sta = nout_ee_pre*sqrt(ReeErrStat*ReeErrStat/Ree/Ree + err_ee_sub*err_ee_sub/nin_ee_sub/nin_ee_sub);
      Double_t nout_ee_sys = nout_ee_pre*ReeErrSyst/Ree;
      Double_t nout_ee_err = sqrt(nout_ee_sys*nout_ee_sys + nout_ee_sta*nout_ee_sta);
      Double_t nout_mm_pre = Rmm*nin_mm_sub;
      Double_t nout_mm_sta = nout_mm_pre*sqrt(RmmErrStat*RmmErrStat/Rmm/Rmm + err_mm_sub*err_mm_sub/nin_mm_sub/nin_mm_sub);
      Double_t nout_mm_sys = nout_mm_pre*RmmErrSyst/Rmm;
      Double_t nout_mm_err = sqrt(nout_mm_sys*nout_mm_sys + nout_mm_sta*nout_mm_sta);
      Double_t nout_ll_pre = Rll*nin_ll_sub;
      Double_t nout_ll_sta = nout_ll_pre*sqrt((RllErrStat*RllErrStat)/Rll/Rll + err_ll_sub*err_ll_sub/nin_ll_sub/nin_ll_sub);
      Double_t nout_ll_sys = nout_ll_pre*RllErrSyst/Rll;
      Double_t nout_ll_err = sqrt(nout_ll_sys*nout_ll_sys + nout_ll_sta*nout_ll_sta);

      sprintf(buffer,"%.2f +/- %.2f +/- %.2f",nout_ll_pre,nout_ll_sta,nout_ll_sys);
//    sprintf(buffer,"%.2f +/- %.2f +/- %.2f",nout_ee_pre,nout_ee_sta,nout_ee_sys);
//    sprintf(buffer,"%.2f +/- %.2f +/- %.2f",nout_mm_pre,nout_mm_sta,nout_mm_sys);
      fout << "   " << setw(20) << buffer;
    
      //
      // out-yield in MC
      //
      printf("SSS %f %f %f\n",nout_ee_dy[jetIndex][imass]+nout_mm_dy[jetIndex][imass],nout_ee_dy[jetIndex][imass],nout_mm_dy[jetIndex][imass]);
      sprintf(buffer,"%.2f +/- %.2f",nout_ee_dy[jetIndex][imass]+nout_mm_dy[jetIndex][imass],sqrt(varout_ee_dy[jetIndex][imass] + varout_mm_dy[jetIndex][imass]));
//    sprintf(buffer,"%.2f +/- %.2f",nout_ee_dy[jetIndex][imass],sqrt(varout_ee_dy[jetIndex][imass]));
//    sprintf(buffer,"%.2f +/- %.2f",nout_mm_dy[jetIndex][imass],sqrt(varout_mm_dy[jetIndex][imass]));
      fout << setw(20) << buffer;
    
      //
      // out-yield data/MC scale factor
      //
      Double_t sfout_ee     = nout_ee_pre/nout_ee_dy[jetIndex][imass];
      Double_t sfout_ee_err = sfout_ee*sqrt(nout_ee_err*nout_ee_err/nout_ee_pre/nout_ee_pre );
      Double_t sfout_mm     = nout_mm_pre/nout_mm_dy[jetIndex][imass];
      Double_t sfout_mm_err = sfout_mm*sqrt(nout_mm_err*nout_mm_err/nout_mm_pre/nout_mm_pre );
      Double_t sfout_ll     = nout_ll_pre/(nout_ee_dy[jetIndex][imass]+nout_mm_dy[jetIndex][imass]);
      Double_t sfout_ll_err = sfout_ll*sqrt(nout_ll_err*nout_ll_err/nout_ll_pre/nout_ll_pre);
    
      sprintf(buffer,"%.2f +/- %.2f",sfout_ll,sfout_ll_err);
//    sprintf(buffer,"%.2f +/- %.2f",sfout_ee,sfout_ee_err);
//    sprintf(buffer,"%.2f +/- %.2f",sfout_mm,sfout_mm_err);
      fout << setw(20) << buffer;        
      fout << endl;
      if (imass == 0) {
        tmpDYBkgScaleFactorWWPreselection    = sfout_ll;
        tmpDYBkgScaleFactorWWPreselectionErr = sfout_ll_err;
      } else {
        // BIG CHANGE, we quote
        //tmpDYBkgScaleFactorHiggsSelection.push_back(sfout_ll);
        //tmpDYBkgScaleFactorHiggsSelectionErr.push_back(sfout_ll_err);
        tmpDYBkgScaleFactorHiggsSelection.push_back(nout_ll_pre);
        tmpDYBkgScaleFactorHiggsSelectionErr.push_back(sqrt(nout_ll_sta*nout_ll_sta+nout_ll_sys*nout_ll_sys));
      }
    }

    DYBkgScaleFactorHiggsSelection.push_back(tmpDYBkgScaleFactorHiggsSelection);
    DYBkgScaleFactorHiggsSelectionErr.push_back(tmpDYBkgScaleFactorHiggsSelectionErr);
    DYBkgScaleFactorWWPreselection.push_back(tmpDYBkgScaleFactorWWPreselection);
    DYBkgScaleFactorWWPreselectionErr.push_back(tmpDYBkgScaleFactorWWPreselectionErr);
  }

  fout.close();


  //***************************************************************************
  // Generate DY Scale Factor and Systematics Code for card creation
  //***************************************************************************
  char DYBkgScaleFactorsName[200];
  sprintf(DYBkgScaleFactorsName,"DYBkgScaleFactors.h");
  ofstream outf(DYBkgScaleFactorsName);

  outf << "static Double_t DYBkgScaleFactor(Int_t mH, Int_t jetBin) {" << endl;
  
  outf << "  Int_t mHiggs[" << nmass-1 << "] = {";
  for (UInt_t i = 0; i < nmass-1 ; ++i) {
    outf << mH[i+1];
    if (i < nmass-1-1) outf << ",";    
  }
  outf << "};" << endl;

  outf << "  Double_t DYBkgScaleFactorWWPreselection[3] = { " 
       << DYBkgScaleFactorWWPreselection[0] << ", "
       << DYBkgScaleFactorWWPreselection[1] << ", "
       << DYBkgScaleFactorWWPreselection[2] << " "
       << " };" << endl;

  outf << "  Double_t DYBkgScaleFactorHiggsSelection[3][" << nmass-1 << "] = { " << endl;
  outf << "    { ";
  for (UInt_t i = 0; i < nmass-1 ; ++i) {
    outf << DYBkgScaleFactorHiggsSelection[0][i];    
    if (i < nmass-1-1) outf << ",";
  }
  outf << "}," << endl;
  outf << "    { ";
  for (UInt_t i = 0; i < nmass-1 ; ++i) {
    outf << DYBkgScaleFactorHiggsSelection[1][i];    
    if (i < nmass-1-1) outf << ",";
  }
  outf << "}," << endl;
  outf << "    { ";
  for (UInt_t i = 0; i < nmass-1 ; ++i) {
    outf << DYBkgScaleFactorHiggsSelection[2][i];    
    if (i < nmass-1-1) outf << ",";
  }
  outf << "} };" << endl;

  outf << "  if(mH == 0) return DYBkgScaleFactorWWPreselection[jetBin];" << endl;
  
  outf << "  Int_t massIndex = -1;" << endl;
  outf << "  for (UInt_t m=0; m < " << nmass-1 << " ; ++m) {" << endl;
  outf << "    if (mH == mHiggs[m]) massIndex = m;" << endl;
  outf << "  }" << endl;
  outf << "  if (massIndex >= 0) {" << endl;  
  outf << "    return DYBkgScaleFactorHiggsSelection[jetBin][massIndex];" << endl;
  outf << "  } else {" << endl;
  outf << "    return DYBkgScaleFactorWWPreselection[jetBin];" << endl;
  
  outf << "  }" << endl;
  outf << "}" << endl;
  outf << endl;


  outf << "static Double_t DYBkgScaleFactorKappa(Int_t mH, Int_t jetBin) {" << endl;
  
  outf << "  Int_t mHiggs[" << nmass-1 << "] = {";
  for (UInt_t i = 0; i < nmass-1 ; ++i) {
    outf << mH[i+1];
    if (i < nmass-1-1) outf << ",";    
  }
  outf << "};" << endl;

  outf << "  Double_t DYBkgScaleFactorWWPreselectionKappa[3] = { " 
       << (1.0 + DYBkgScaleFactorWWPreselectionErr[0]/DYBkgScaleFactorWWPreselection[0]) << ", "
       << (1.0 + DYBkgScaleFactorWWPreselectionErr[1]/DYBkgScaleFactorWWPreselection[1]) << ", "
       << (1.0 + DYBkgScaleFactorWWPreselectionErr[2]/DYBkgScaleFactorWWPreselection[2]) << " "
       << " };" << endl;

  outf << "  Double_t DYBkgScaleFactorHiggsSelectionKappa[3][" << nmass-1 << "] = { " << endl;
  outf << "    { ";
  for (UInt_t i = 0; i < nmass-1 ; ++i) {
    outf << (1.0 + DYBkgScaleFactorHiggsSelectionErr[0][i] / DYBkgScaleFactorHiggsSelection[0][i]);
    if (i < nmass-1-1) outf << ",";
  }
  outf << "}," << endl;
  outf << "    { ";
  for (UInt_t i = 0; i < nmass-1 ; ++i) {
    outf << (1.0 + DYBkgScaleFactorHiggsSelectionErr[1][i] / DYBkgScaleFactorHiggsSelection[1][i]);
    if (i < nmass-1-1) outf << ",";
  }
  outf << "}," << endl;
  outf << "    { ";
  for (UInt_t i = 0; i < nmass-1 ; ++i) {
    outf << (1.0 + DYBkgScaleFactorHiggsSelectionErr[2][i] / DYBkgScaleFactorHiggsSelection[2][i]);
    if (i < nmass-1-1) outf << ",";
  }
  outf << "} };" << endl;

  outf << "  if(mH == 0) return DYBkgScaleFactorWWPreselectionKappa[jetBin];" << endl;
  
  outf << "  Int_t massIndex = -1;" << endl;
  outf << "  for (UInt_t m=0; m < " << nmass-1 << " ; ++m) {" << endl;
  outf << "    if (mH == mHiggs[m]) massIndex = m;" << endl;
  outf << "  }" << endl;
  outf << "  if (massIndex >= 0) {" << endl;  
  outf << "    return DYBkgScaleFactorHiggsSelectionKappa[jetBin][massIndex];" << endl;
  outf << "  } else {" << endl;
  outf << "    return DYBkgScaleFactorWWPreselectionKappa[jetBin];" << endl;
  
  outf << "  }" << endl;
  outf << "}" << endl;
  outf << endl;

  outf.close();
}
void ZllAnalysis(TString typeLepSel = "default"){

  TString filesPath  = "/scratch5/ceballos/ntuples_weights_74x/";
  Double_t lumi = 0.0715;
  if(period == 1) lumi = 2.263;

  //*******************************************************
  //Input Files
  //*******************************************************
  vector<TString> infilenamev;  
  vector<Int_t> infilecatv;  

  TString puPath = "";
  if     (period==1){
  puPath = "/home/ceballos/cms/cmssw/042/CMSSW_7_4_6/src/MitAnalysisRunII/data/74x/puWeights_13TeV_25ns.root";
  infilenamev.push_back(Form("%sdata_AOD_Run2015C1_25ns.root",filesPath.Data())); 												  infilecatv.push_back(0);
  infilenamev.push_back(Form("%sdata_AOD_Run2015D3_25ns.root",filesPath.Data())); 												  infilecatv.push_back(0);
  infilenamev.push_back(Form("%sdata_AOD_Run2015D4_25ns.root",filesPath.Data())); 												  infilecatv.push_back(0);
  infilenamev.push_back(Form("%sDYJetsToLL_M-10to50_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v1+AODSIM.root",filesPath.Data()));	  infilecatv.push_back(1);
  infilenamev.push_back(Form("%sDYJetsToLL_M-50_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8+RunIISpring15DR74-Asympt25ns_MCRUN2_74_V9-v3+AODSIM.root",filesPath.Data()));  	          infilecatv.push_back(1);
  }
  else {assert(0);}

  if(infilenamev.size() != infilecatv.size()) assert(0);

  Float_t fMVACut[4][4];
  InitializeJetIdCuts(fMVACut);
 
  TFile *fPUFile = TFile::Open(Form("%s",puPath.Data()));
  TH1D *fhDPU = (TH1D*)(fPUFile->Get("puWeights"));
  assert(fhDPU);
  fhDPU->SetDirectory(0);
  delete fPUFile;

  const int ptBins = 5;
  const int etaBins = 2;

  double yields[2][ptBins][etaBins][ptBins][etaBins][3],yieldsE[2][ptBins][etaBins][ptBins][etaBins][3];
  for (int ch=0; ch<2; ch++){
    for (int pt0=0; pt0<ptBins; pt0++){
      for (int eta0=0; eta0<etaBins; eta0++){
        for (int pt1=0; pt1<ptBins; pt1++){
          for (int eta1=0; eta1<etaBins; eta1++){
            for (int nlep=0; nlep<3; nlep++){
              yields[ch][pt0][eta0][pt1][eta1][nlep] = 0; yieldsE[ch][pt0][eta0][pt1][eta1][nlep] = 0;
            }
          }
        }
      }
    }
  }
  double yieldsTotal[2][3],yieldsTotal20[2][3];
  for (int ch=0; ch<2; ch++){
    for (int nlep=0; nlep<3; nlep++){
      yieldsTotal[ch][nlep] = 0;
      yieldsTotal20[ch][nlep] = 0;
    }
  }
  //*******************************************************
  // Chain Loop
  //*******************************************************
  for(UInt_t ifile=0; ifile<infilenamev.size(); ifile++) {

    TFile the_input_file(infilenamev[ifile]);
    TTree *the_input_tree = (TTree*)the_input_file.FindObjectAny("events");
    //TTree *the_input_all  = (TTree*)the_input_file.FindObjectAny("all");

    BareMonteCarlo eventMonteCarlo;
    eventMonteCarlo.setBranchAddresses(the_input_tree);

    BareEvent eventEvent;
    eventEvent.setBranchAddresses(the_input_tree);

    BareJets eventJets;
    eventJets.setBranchAddresses(the_input_tree);

    BareLeptons eventLeptons;
    eventLeptons.setBranchAddresses(the_input_tree);

    BareTaus eventTaus;
    eventTaus.setBranchAddresses(the_input_tree);

    BareMet eventMet;
    eventMet.SetExtend();
    eventMet.setBranchAddresses(the_input_tree);

    BareTrigger eventTrigger;
    eventTrigger.setBranchAddresses(the_input_tree);

    BareVertex eventVertex;
    eventVertex.setBranchAddresses(the_input_tree);

    TNamed *triggerNames = (TNamed*)the_input_file.FindObjectAny("triggerNames");
    char **tokens;
    size_t numtokens;
    tokens = strsplit(triggerNames->GetTitle(), ",", &numtokens);
    if(infilecatv[ifile] == 0){
      for (int i = 0; i < (int)numtokens; i++) {
        printf("triggerNames(%2d): \"%s\"\n",(int)i,tokens[i]);
      }
    }

    int MAX = the_input_tree->GetEntries();
    //if(infilecatv[ifile] == 1) MAX = MAX/10.;
    for (int i=0; i<MAX; ++i) {
      the_input_tree->GetEntry(i);
      if(i%100000==0) printf("event %d out of %d\n",i,(int)the_input_tree->GetEntries());

      Bool_t passFilter[6] = {kFALSE,kFALSE,kFALSE,kFALSE,kFALSE,kFALSE};
      if(eventLeptons.p4->GetEntriesFast() >= 2 &&
     	 ((TLorentzVector*)(*eventLeptons.p4)[0])->Pt() > 20 && 
     	 ((TLorentzVector*)(*eventLeptons.p4)[1])->Pt() > 10) passFilter[0] = kTRUE;
      for (int nt = 0; nt <(int)numtokens; nt++) {
        if((*eventTrigger.triggerFired)[nt] == 0) continue;
        if((strcmp(tokens[nt],"HLT_Mu8_TrkIsoVVL_Ele17_CaloIdL_TrackIdL_IsoVL_v*")  == 0) ||
           (strcmp(tokens[nt],"HLT_Mu8_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL_v*")  == 0) ||
           (strcmp(tokens[nt],"HLT_Mu17_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL_v*") == 0) ||
           (strcmp(tokens[nt],"HLT_Mu23_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL_v*") == 0) ||
           (strcmp(tokens[nt],"HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ_v*") 	    == 0) ||
           (strcmp(tokens[nt],"HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL_DZ_v*")	    == 0) ||
           (strcmp(tokens[nt],"HLT_IsoMu27_v*") 				    == 0) ||
           (strcmp(tokens[nt],"HLT_IsoMu20_v*") 				    == 0) ||
           (strcmp(tokens[nt],"HLT_IsoTkMu20_v*")				    == 0) ||
           (strcmp(tokens[nt],"HLT_Ele17_Ele12_CaloIdL_TrackIdL_IsoVL_DZ_v*")	    == 0) ||
           (strcmp(tokens[nt],"HLT_Ele23_WPLoose_Gsf_v*")			    == 0) ||
           (strcmp(tokens[nt],"HLT_Ele22_eta2p1_WP75_Gsf_v*")			    == 0) ||
           (strcmp(tokens[nt],"HLT_Ele27_WPLoose_Gsf_v*")			    == 0) ||
           (strcmp(tokens[nt],"HLT_Ele27_WP85_Gsf_v*")  			    == 0)
           ) passFilter[1] = kTRUE;
      }

      if(passFilter[0] == kFALSE) continue;
      if(passFilter[1] == kFALSE) continue;

      vector<int> idLep; vector<int> idTight;
      for(int nlep=0; nlep<eventLeptons.p4->GetEntriesFast(); nlep++) {
        if(selectIdIsoCut(typeLepSel.Data(),TMath::Abs((int)(*eventLeptons.pdgId)[nlep]),TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Pt()),
	   TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[nlep])->Eta()),(double)(*eventLeptons.iso)[nlep],(int)(*eventLeptons.selBits)[nlep]))
	                                                                                               {idTight.push_back(1); idLep.push_back(nlep);}
        else if(((int)(*eventLeptons.selBits)[nlep] & BareLeptons::LepFake)  == BareLeptons::LepFake ) {idTight.push_back(0); idLep.push_back(nlep);}
      }
      if(idLep.size()==2) passFilter[2] = kTRUE;
      if(passFilter[2] == kFALSE) continue;

      if(idTight[0]==1&&idTight[1]==1) passFilter[3] = kTRUE;
      if(passFilter[3] == kFALSE) continue;
      if(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() <= 20 ||
         ((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Pt() <= 10) continue;

      passFilter[4] = ((int)(*eventLeptons.pdgId)[idLep[0]]*(int)(*eventLeptons.pdgId)[idLep[1]] < 0);
      if(passFilter[4] == kFALSE) continue;

      TLorentzVector dilep(( ( *(TLorentzVector*)(eventLeptons.p4->At(idLep[0])) ) + ( *(TLorentzVector*)(eventLeptons.p4->At(idLep[1])) ) )); 

      if(TMath::Abs(dilep.M()-91.1876)<15.0) passFilter[5] = kTRUE;  	    
      if(passFilter[5] == kFALSE) continue;

      int iPt[2] = {-1, -1};
      if     (((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() < 15) iPt[0] = 0;
      else if(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() < 20) iPt[0] = 1;
      else if(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() < 25) iPt[0] = 2;
      else if(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt() < 30) iPt[0] = 3;
      else                                                                iPt[0] = 4;
      if     (((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Pt() < 15) iPt[1] = 0;
      else if(((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Pt() < 20) iPt[1] = 1;
      else if(((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Pt() < 25) iPt[1] = 2;
      else if(((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Pt() < 30) iPt[1] = 3;
      else                                                                iPt[1] = 4;

      int iEta[2] = {-1, -1};
      if     (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Eta()) < 1.5) iEta[0] = 0;
      else                                                                              iEta[0] = 1;
      if     (TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Eta()) < 1.5) iEta[1] = 0;
      else                                                                              iEta[1] = 1;

      Int_t typeLep = 2;
      if     (TMath::Abs((int)(*eventLeptons.pdgId)[idLep[0]])==13&&TMath::Abs((int)(*eventLeptons.pdgId)[idLep[1]])==13) typeLep = 0;
      else if(TMath::Abs((int)(*eventLeptons.pdgId)[idLep[0]])==11&&TMath::Abs((int)(*eventLeptons.pdgId)[idLep[1]])==11) typeLep = 1;

      double theLumi = lumi; if(infilecatv[ifile] == 0) theLumi = 1.0;
      double puWeight = nPUScaleFactor(fhDPU, (double)eventVertex.npv); if(infilecatv[ifile] == 0) puWeight = 1.0;
      //double puWeight = 1.0; if(infilecatv[ifile] != 0) puWeight = weightTruePileupFall15_74X((double)eventMonteCarlo.puTrueInt);
      double effSF = 1.0;

      if(infilecatv[ifile] != 0){
        effSF = effScaleFactor(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Pt(),TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[0]])->Eta()),TMath::Abs((int)(*eventLeptons.pdgId)[idLep[0]]),period,typeLepSel.Data())*
                effScaleFactor(((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Pt(),TMath::Abs(((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Eta()),TMath::Abs((int)(*eventLeptons.pdgId)[idLep[1]]),period,typeLepSel.Data());
        effSF=1; // SF efficiency == 1!
      }

      double mcWeight = eventMonteCarlo.mcWeight;
      if(infilecatv[ifile] == 0) mcWeight = 1.0;
      double totalWeight = mcWeight*theLumi*puWeight*effSF;
   
      yields [infilecatv[ifile]][iPt[0]][iEta[0]][iPt[1]][iEta[1]][typeLep] =  yields[infilecatv[ifile]][iPt[0]][iEta[0]][iPt[1]][iEta[1]][typeLep] + totalWeight;

      yieldsE[infilecatv[ifile]][iPt[0]][iEta[0]][iPt[1]][iEta[1]][typeLep] = yieldsE[infilecatv[ifile]][iPt[0]][iEta[0]][iPt[1]][iEta[1]][typeLep] + totalWeight * totalWeight;

      yieldsTotal[infilecatv[ifile]][typeLep]   = yieldsTotal  [infilecatv[ifile]][typeLep] + totalWeight;
      if(((TLorentzVector*)(*eventLeptons.p4)[idLep[1]])->Pt() > 20)
      yieldsTotal20[infilecatv[ifile]][typeLep] = yieldsTotal20[infilecatv[ifile]][typeLep] + totalWeight;
    }
  } // end of chain

  double kFactor[2] = {1., 1.};
  for (int ch=0; ch<2; ch++){
    kFactor[ch] = (yieldsTotal[ch][0]/yieldsTotal[ch][1]+yieldsTotal[ch][1]/yieldsTotal[ch][0])*0.5;
  }
  printf("kFactors data/MC: %f %f\n",kFactor[0],kFactor[1]);

  for (int pt0=0; pt0<ptBins; pt0++){
    for (int eta0=0; eta0<etaBins; eta0++){
      for (int pt1=0; pt1<ptBins; pt1++){
        for (int eta1=0; eta1<etaBins; eta1++){
	  if(pt0>=pt1)
          printf("yield %1d %1d %1d %1d: %6.1f %6.1f %6.1f - %6.1f %6.1f %6.1f\n",pt0,eta0,pt1,eta1,yields[0][pt0][eta0][pt1][eta1][0],yields[0][pt0][eta0][pt1][eta1][1],yields[0][pt0][eta0][pt1][eta1][2],yields[1][pt0][eta0][pt1][eta1][0],yields[1][pt0][eta0][pt1][eta1][1],yields[1][pt0][eta0][pt1][eta1][2]);
        }         
      }
    }
  }

  printf("yieldTotal:   %8.1f %8.1f %8.1f - %8.1f %8.1f %8.1f\n",yieldsTotal  [0][0],yieldsTotal  [0][1],yieldsTotal  [0][2],yieldsTotal  [1][0],yieldsTotal  [1][1],yieldsTotal  [1][2]);
  printf("yieldTotal20: %8.1f %8.1f %8.1f - %8.1f %8.1f %8.1f\n",yieldsTotal20[0][0],yieldsTotal20[0][1],yieldsTotal20[0][2],yieldsTotal20[1][0],yieldsTotal20[1][1],yieldsTotal20[1][2]);

  for (int pt0=0; pt0<ptBins; pt0++){
    for (int eta0=0; eta0<etaBins; eta0++){
      for (int pt1=0; pt1<ptBins; pt1++){
        for (int eta1=0; eta1<etaBins; eta1++){
	  if(pt0>=pt1)
          printf("yield %1d %1d %1d %1d: %6.4f +/- %6.4f - %6.4f +/- %6.4f\n",pt0,eta0,pt1,eta1,(yields[0][pt0][eta0][pt1][eta1][0]-yields[0][pt0][eta0][pt1][eta1][2]*kFactor[0])/(yields[1][pt0][eta0][pt1][eta1][0]-yields[1][pt0][eta0][pt1][eta1][2]*kFactor[1]),
                                                                                                                              sqrt(yieldsE[0][pt0][eta0][pt1][eta1][0])*kFactor[0]/(yields[1][pt0][eta0][pt1][eta1][0]-yields[1][pt0][eta0][pt1][eta1][2]*kFactor[1]),
                                                                                                (yields[0][pt0][eta0][pt1][eta1][1]-yields[0][pt0][eta0][pt1][eta1][2]*kFactor[0])/(yields[1][pt0][eta0][pt1][eta1][1]-yields[1][pt0][eta0][pt1][eta1][2]*kFactor[1]),
                                                                                                                              sqrt(yieldsE[0][pt0][eta0][pt1][eta1][0])*kFactor[0]/(yields[1][pt0][eta0][pt1][eta1][1]-yields[1][pt0][eta0][pt1][eta1][2]*kFactor[1]));
        }
      }
    }
  }
}