Esempio n. 1
0
void AnalysisModuleRunner::begin_in_file(const string & infile){
    std::unique_ptr<TFile> file(TFile::Open(infile.c_str(), "read"));
    if(read_trigger){
        std::map<int, std::vector<std::string>> runid_to_triggernames;
        // find triggernames for all runs in this file:
        TTree * intree = dynamic_cast<TTree*>(file->Get("AnalysisTree"));
        if(!intree) throw runtime_error("Did not find AnalysisTree in input file");
        std::vector<std::string> trigger_names;
        std::vector<std::string> *ptrigger_names = &trigger_names;
        int runid = 0;
        TBranch* runb = 0;
        TBranch* tnb = 0;
        intree->SetBranchAddress("run", &runid, &runb);
        intree->SetBranchAddress("triggerNames", &ptrigger_names, &tnb);
        if(runb==0 || tnb==0){
            throw runtime_error("did not find branches for setting up trigger names");
        }
        int nentries = intree->GetEntries();
        int last_runid = -1;
        for(int i=0; i<nentries; ++i){
            runb->GetEntry(i);
            if(last_runid == runid) continue;
            last_runid = runid;
            assert(runid >= 1);
            tnb->GetEntry(i);
            if(!trigger_names.empty()){
                runid_to_triggernames[runid] = trigger_names;
            }
        }
        LOG_INFO("Found " << runid_to_triggernames.size() << " trigger infos in file '" << infile << "'");
        helper->set_infile_triggernames(move(runid_to_triggernames));
    }
    
}
int PlotSignals(char *filename, int plfrom=0, int plto=100, int same=1) {

  bragg_signal signal;

  TFile *fin=new TFile(filename);
  if (!fin->IsOpen()) {
    std::cout << "file not found! " << std::endl;
    return -1;
  }

  TTree *tree = (TTree*)fin->Get("bragg");
  if (!tree) {
    std::cout << "Bragg tree not found! " << std::endl;
    return -2;
  }

  TBranch *br = tree->GetBranch("signals");
  if (!br) {
    std::cout << "Signal branch not found! " << std::endl;
    return -3;
  }

  br->SetAddress(&signal);
  int nev = br->GetEntries();
  std::cout << "Number of events in file : " << nev << std::endl;

  for (int i=plfrom; i<plto; i++) {
    br->GetEntry(i);
    plotSignal(signal,same);  
  }
  
  return 0;
}
Esempio n. 3
0
void D3PDSelector::loadData(std::string key)
{
  if (m_loaded.find(key) == m_loaded.end())
  {
    TBranch* toload = m_branches.find(key)->second;
    toload->GetEntry(m_curentry);
    m_loaded[key] = true;
  }
}
Esempio n. 4
0
 void tv3Read2() {
   //second read example illustrating how to read one branch only
   TVector3 *v = 0;
   TFile *f = new TFile("v3.root");
   TTree *T = (TTree*)f->Get("T");
   T->SetBranchAddress("v3",&v);
   TBranch *by = T->GetBranch("fY");
   TH1F *h2 = new TH1F("y","y component of TVector3",100,-5,20);
   Int_t nentries = Int_t(T->GetEntries());
   for (Int_t i=0;i<nentries;i++) {
      by->GetEntry(i);
      h2->Fill(v->y());
   }
   h2->Draw();
}
Esempio n. 5
0
void Tree::TreeR(){

	Channel *ch;
	f = new TFile(rootFile.c_str());
	t = (TTree*)f->Get("testTree");
	TBranch *b = t->GetBranch("channel");
	t->SetBranchAddress("channel",&ch,&b);
	Int_t nentries = t->GetEntries();
	for(Int_t i = 0 ; i < nentries ; i++){
		b->GetEntry(i);
		std::cout<<"val : "<<ch->at(1)<<std::endl;
	}


}
Esempio n. 6
0
void Tree::TreeR_V2(std::string bName, int entry){
//TFile *
//   f = TFile::Open(rootFile.c_str(),"READ");
//   if (!f) { return; }
//   f->GetObject("testTree",t);
   Channel *vpx = 0;
   TBranch *bvpx = 0;
   t->SetBranchAddress(bName.c_str(),&vpx,&bvpx);
   Long64_t tentry = t->LoadTree(entry);
   bvpx->GetEntry(tentry);
   for (UInt_t j = 0; j < vpx->size(); ++j) {
         std::cout<<"value : "<<vpx->at(j)<<" , ";         
   }
   std::cout<<std::endl;
   t->ResetBranchAddresses();

}
/*
 * Extract the index of the transmitter from the fibre map
 */
int getFibreIndexTx(TTree *t, char *txswitch) {
  int index = -1;
  int len = t->GetEntries();
  char fromSw[100];
  TBranch *br = t->GetBranch("fromSw");
  
  for (int i = 0; i < len; i++) {
    br->GetEntry(i);
    cout << fromSw <<endl;
    if (strstr(fromSw, txswitch) != NULL) {
      cout << "Found one\n";
      index = i;
      i = len;
    }
  }
  
  return index;
}
Esempio n. 8
0
void h2fast(const char *url , Bool_t draw=kFALSE, Long64_t cachesize=10000000, Int_t learn=1) {
// gEnv->SetValue("TFile.DavixLog", 10);
//  gDebug= 0x02;
   TStopwatch sw;
   TTree* T = NULL;
   sw.Start();
   Long64_t oldb = TFile::GetFileBytesRead();
   TFile *f = TFile::Open(url);
  
   if (!f || f->IsZombie()) {
      printf("File h1big.root does not exist\n");
      exit (-1);
   }
   

//   TTreeCacheUnzip::SetParallelUnzip(TTreeCacheUnzip::kEnable);

   T= (TTree*)f->Get("h42");
   Long64_t nentries = T->GetEntries();
   T->SetCacheSize(cachesize);
   TTreeCache::SetLearnEntries(learn);
   TFileCacheRead *tpf = f->GetCacheRead();
   //tpf->SetEntryRange(0,nentries);
   
   if (draw) T->Draw("rawtr","E33>20");
   else {
      TBranch *brawtr = T->GetBranch("rawtr");
      TBranch *bE33   = T->GetBranch("E33");
      Float_t E33; 
      bE33->SetAddress(&E33);
      for (Long64_t i=0;i<nentries;i++) {
         T->LoadTree(i);
         bE33->GetEntry(i);
         if (E33 > 0) brawtr->GetEntry(i);
      } 
   } 
   if (tpf) tpf->Print();
   printf("Bytes read = %lld\n",TFile::GetFileBytesRead()-oldb);
   printf("Real Time = %7.3f s, CPUtime = %7.3f s\n",sw.RealTime(),sw.CpuTime());
   delete T;
   delete f;
}
Esempio n. 9
0
void CountEvents()
{
   // Variables used to store the data
   Int_t     totalSize = 0;        // Sum of data size (in bytes) of all events
   Int_t     eventSize = 0;        // Size of the current event
   TBranch  *eventSizeBranch = 0;  // Pointer to the event.fEventsize branch

   // open the file
   TFile *f = TFile::Open("http://lcg-heppkg.web.cern.ch/lcg-heppkg/ROOT/eventdata.root");
   if (f == 0) {
      // if we cannot open the file, print an error message and return immediatly
      printf("Error: cannot open http://lcg-heppkg.web.cern.ch/lcg-heppkg/ROOT/eventdata.root!\n");
      return;
   }
   // get a pointer to the tree
   TTree *tree = (TTree *)f->Get("EventTree");
   // To use SetBranchAddress() with simple types (e.g. double, int)
   // instead of objects (e.g. std::vector<Particle>).
   tree->SetMakeClass(1);

   // Connect the branch "fEventSize" with the variable
   // eventSize that we want to contain the data.
   // While we are at it, ask the tree to save the branch
   // in eventSizeBranch
   tree->SetBranchAddress("fEventSize", &eventSize, &eventSizeBranch);

   // First, get the total number of entries
   Long64_t nentries = tree->GetEntries();
   // then loop over all of them
   for (Long64_t i=0;i<nentries;i++) {
      // Load the data for TTree entry number "i" from branch
      // fEventSize into the connected variable (eventSize):
      eventSizeBranch->GetEntry(i);
      totalSize += eventSize;
   }
   Int_t sizeInMB = totalSize/1024/1024;
   printf("Total size of all events: %d MB\n", sizeInMB);
}
void selectEleHZZRun1LegacyPaperIsoGivenIDWithZeeGammaPerFile(const string inputfile,          // input file
                                                const string outputfile,         // output directory
                                                const Bool_t  matchGen = kFALSE, // match to generator muons
                                                Int_t dataType = 0,              // del = 0, sel = 1, mc sig = -1, mc bkg = -2
                                                Int_t DataEraInput = 2
  ) {

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //============================================================================================================== 
  UInt_t DataEra = kDataEra_NONE;
  if (DataEraInput == 1) DataEra = kDataEra_2011_MC;
  if (DataEraInput == 2) DataEra = kDataEra_2012_MC;
  if (DataEraInput == 11) DataEra = kDataEra_2011_Data;
  if (DataEraInput == 12) DataEra = kDataEra_2012_Data;

  //*****************************************************************************************
  //Setup MVA
  //*****************************************************************************************
  EGammaMvaEleEstimator *eleIDMVA = new EGammaMvaEleEstimator();
  vector<string> weightFiles;

  weightFiles.push_back((string(getenv("CMSSW_BASE"))+string("/src/HiggsAna/HZZ4l/data/ElectronIDMVAWeights/Electrons_BDTG_NonTrigV0_Cat1.weights.xml")).c_str());
  weightFiles.push_back((string(getenv("CMSSW_BASE"))+string("/src/HiggsAna/HZZ4l/data/ElectronIDMVAWeights/Electrons_BDTG_NonTrigV0_Cat2.weights.xml")).c_str());
  weightFiles.push_back((string(getenv("CMSSW_BASE"))+string("/src/HiggsAna/HZZ4l/data/ElectronIDMVAWeights/Electrons_BDTG_NonTrigV0_Cat3.weights.xml")).c_str());
  weightFiles.push_back((string(getenv("CMSSW_BASE"))+string("/src/HiggsAna/HZZ4l/data/ElectronIDMVAWeights/Electrons_BDTG_NonTrigV0_Cat4.weights.xml")).c_str());
  weightFiles.push_back((string(getenv("CMSSW_BASE"))+string("/src/HiggsAna/HZZ4l/data/ElectronIDMVAWeights/Electrons_BDTG_NonTrigV0_Cat5.weights.xml")).c_str());
  weightFiles.push_back((string(getenv("CMSSW_BASE"))+string("/src/HiggsAna/HZZ4l/data/ElectronIDMVAWeights/Electrons_BDTG_NonTrigV0_Cat6.weights.xml")).c_str());
  eleIDMVA->initialize( "BDT", EGammaMvaEleEstimator::kNonTrig,  kTRUE, weightFiles);
  

  // mass region
  Double_t massLo = 40;
  Double_t massHi = 200;

  
  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  
  
  Double_t nProbes = 0;
  
  //
  // Set up output ntuple
  //
  TFile *outFile = new TFile(outputfile.c_str(),"RECREATE"); 
  TTree *outTree = new TTree("Events","Events");
  EffData data;
  outTree->Branch("Events",&data.mass,"mass/F:pt:eta:phi:weight:q/I:npv/i:npu:pass:runNum:lumiSec:evtNum:rho/F");

  TFile *infile=0;
  TTree *eventTree=0;
  
  // Data structures to store info from TTrees
  higgsana::TEventInfo *info  = new higgsana::TEventInfo();
  TClonesArray *genparticleArr = new TClonesArray("higgsana::TGenParticle");
  TClonesArray *electronArr = new TClonesArray("higgsana::TElectron");
  TClonesArray *photonArr = new TClonesArray("higgsana::TPhoton");
  TClonesArray *pfcandidateArr = new TClonesArray("higgsana::TPFCandidate");
  TClonesArray *muonArr = new TClonesArray("higgsana::TMuon");

  // Read input file and get the TTrees
  cout << "Processing " << inputfile << "..." << endl;
  infile = TFile::Open(inputfile.c_str(),"read");
  assert(infile);



  //********************************************************
  // Good RunLumi Selection
  //********************************************************
  Bool_t hasJSON = kFALSE;
  mithep::RunLumiRangeMap rlrm;
  if (!matchGen) {
    hasJSON = kTRUE;
    rlrm.AddJSONFile("/afs/cern.ch/work/s/sixie/public/HZZ4l/auxiliar/2012/Cert_Full2012_53X_JSON.txt"); 
  }
    
  eventTree = (TTree*)infile->Get("Events"); assert(eventTree);  
  eventTree->SetBranchAddress("Info",     &info);        TBranch *infoBr     = eventTree->GetBranch("Info");
  eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron");
  eventTree->SetBranchAddress("Photon", &photonArr); TBranch *photonBr = eventTree->GetBranch("Photon");
  eventTree->SetBranchAddress("Muon", &muonArr);         TBranch *muonBr = eventTree->GetBranch("Muon");
  eventTree->SetBranchAddress("PFCandidate", &pfcandidateArr);  TBranch *pfcandidateBr = eventTree->GetBranch("PFCandidate");
  cout << "NEvents = " << eventTree->GetEntries() << endl;

  TBranch *genparticleBr;
  if(matchGen) {
    eventTree->SetBranchAddress("GenParticle", &genparticleArr);
    genparticleBr = eventTree->GetBranch("GenParticle");
  }
    
  Double_t weight = 1;

  // loop over events
  for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
    if (ientry % 100000 == 0) cout << "Processed Event " << ientry << endl;
    infoBr->GetEntry(ientry);
    
    // check for certified runs
    mithep::RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec);      
    if(hasJSON && !rlrm.HasRunLumi(rl)) continue;  

    //***********************************************************
    // Definition of Pileup Energy density
    //***********************************************************
    Double_t rhoEleIso = 0;
    UInt_t EleEAEra = 0;
    if (DataEra == kDataEra_2011_MC) {
        
      if (!(isnan(info->RhoKt6PFJetsForIso25) || 
            isinf(info->RhoKt6PFJetsForIso25))) {
        rhoEleIso = info->RhoKt6PFJetsForIso25;
      }
      EleEAEra = kDataEra_2011_Data;
        
    } else if (DataEra == kDataEra_2012_MC) {
        
      if (!(isnan(info->RhoKt6PFJets) || 
            isinf(info->RhoKt6PFJets))) {
        rhoEleIso = info->RhoKt6PFJets;
      }
      EleEAEra = kDataEra_2012_Data;
    }

    //use only odd numbered events to evaluate efficiency for data. even numbered events were used for training
    //Don't need this for zee gamma
    //if (info->evtNum % 2 == 0 && !matchGen) continue;

    // trigger requirement               
    Bool_t passTrigger = kFALSE;
    if(dataType == 0 ) {
      if ((info->triggerBits & kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50) == kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50) passTrigger = kTRUE;
      if ((info->triggerBits & kHLT_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC8_Mass30) == kHLT_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC8_Mass30) passTrigger = kTRUE;
      if ((info->triggerBits & kHLT_Ele32_CaloIdL_CaloIsoVL_SC17) == kHLT_Ele32_CaloIdL_CaloIsoVL_SC17) passTrigger = kTRUE;
    } else if(dataType == 1 ) {
      if(info->triggerBits & kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50)  continue;
      if(info->triggerBits & kHLT_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC8_Mass30)  continue;
      if(info->triggerBits & kHLT_Ele32_CaloIdL_CaloIsoVL_SC17)                         continue;
 
      if ((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) == kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) passTrigger = kTRUE;
    } else if (dataType < 0) {
      if ((info->triggerBits & kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50) == kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50) passTrigger = kTRUE;
      if ((info->triggerBits & kHLT_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC8_Mass30) == kHLT_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC8_Mass30) passTrigger = kTRUE;
      if ((info->triggerBits & kHLT_Ele32_CaloIdL_CaloIsoVL_SC17) == kHLT_Ele32_CaloIdL_CaloIsoVL_SC17) passTrigger = kTRUE;
      if ((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) == kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) passTrigger = kTRUE;
    }
    if(!passTrigger) continue;     



    // good vertex requirement
    if(!(info->hasGoodPV)) continue;

    electronArr->Clear();
    muonArr->Clear(); 
    pfcandidateArr->Clear(); 
    genparticleArr->Clear(); 
    electronBr->GetEntry(ientry);
    photonBr->GetEntry(ientry);
    muonBr->GetEntry(ientry);
    pfcandidateBr->GetEntry(ientry);
    if(matchGen) {
      genparticleBr->GetEntry(ientry);
    }  


    //********************************************************
    //Loop over TAG electrons
    //********************************************************
    vector<Int_t> probeAlreadyUsed;
    for(Int_t i=0; i<electronArr->GetEntriesFast(); ++i) {
      probeAlreadyUsed.push_back(kFALSE);
    }

    for(Int_t i=0; i<electronArr->GetEntriesFast(); ++i) {

      const higgsana::TElectron *tag = (higgsana::TElectron*)((*electronArr)[i]);
	
      Bool_t TagIsEle = MatchedToStatus1Ele(tag, genparticleArr);

      if(tag->pt          < 20)  continue;
      if(fabs(tag->scEta) > 2.5) continue;
//       if(dataType == 1) {
//         if(tag->pt          < 30)  continue;
//       }

      if (!passCutBasedEleID(tag, ComputeElePFIso04(tag,pfcandidateArr,rhoEleIso,EleEAEra))) continue;

      if(dataType == 0 &&
         !((info->triggerBits & kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50) && (tag->hltMatchBits & kHLTObject_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT)) &&
         !((info->triggerBits & kHLT_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC8_Mass30) && (tag->hltMatchBits & kHLTObject_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT)) &&
         !((info->triggerBits & kHLT_Ele32_CaloIdL_CaloIsoVL_SC17) && (tag->hltMatchBits & kHLTObject_Ele32_CaloIdL_CaloIsoVL)) &&
         !((info->triggerBits & kHLT_Ele32_CaloIdL_CaloIsoVL_SC17) && (tag->hltMatchBits & kHLTObject_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT))         
        )
        continue;
      
      if(dataType == 1 &&
         !((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && (tag->hltMatchBits & kHLTObject_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT)) &&
         !((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && (tag->hltMatchBits & kHLTObject_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT)) &&
         !((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && (tag->hltMatchBits & kHLTObject_Ele52_CaloIdVT_TrkIdT)) &&
         !((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && (tag->hltMatchBits & kHLTObject_Ele65_CaloIdVT_TrkIdT)) &&
         !((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && (tag->hltMatchBits & kHLTObject_Ele80_CaloIdVT_TrkIdT)) &&
         !((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && (tag->hltMatchBits & kHLTObject_Ele27_WP80)) &&
         !((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && (tag->hltMatchBits & kHLTObject_Ele32_WP70))
        ) 
        continue;
        

      const Double_t m = 0.000511;
      TLorentzVector vtag;
      vtag.SetPtEtaPhiM(tag->pt, tag->eta, tag->phi, m);
        
      //Find Photon
      for(Int_t j=0; j<photonArr->GetEntriesFast(); ++j) {
      
        const higgsana::TPhoton *pho = (higgsana::TPhoton*)((*photonArr)[j]);
        TLorentzVector vpho;
        vpho.SetPtEtaPhiM(pho->et, pho->eta, pho->phi, 0);
        
        if (pho->et < 10) continue;
        if (fabs(pho->eta) > 2.5) continue;
    
        if (!passPhotonSimpleCuts(pho)) continue;        

        Bool_t PhotonIsReal = MatchedToStatus1Photon(pho, genparticleArr);

        if (fabs(tag->eta - pho->eta) < 0.15 && higgsana::deltaR( tag->eta, tag->phi, pho->eta, pho->phi) < 0.7) continue;                

        //Find Probes
        for(Int_t k=0; k<electronArr->GetEntriesFast(); ++k) {

          //no duplicates
          if(k==i) continue;    
          if (probeAlreadyUsed[k]) continue;

          const higgsana::TElectron *probe = (higgsana::TElectron*)((*electronArr)[k]);
          if(probe->q == tag->q) continue;
          TLorentzVector vprobe;
          vprobe.SetPtEtaPhiM(probe->pt, probe->eta, probe->phi, m);

          Bool_t ProbeIsEle = MatchedToStatus1Ele(probe, genparticleArr);


          //High Efficiency Pixel Veto
          double minDEta = fmin( fabs(tag->eta - pho->eta) , fabs(probe->eta - pho->eta ));
          double minDPhi = fmin( higgsana::deltaPhi(tag->phi, pho->phi) , higgsana::deltaPhi( probe->phi, pho->phi));
          double minDR = fmin( higgsana::deltaR(tag->eta,tag->phi, pho->eta, pho->phi) , higgsana::deltaR( probe->eta, probe->phi, pho->eta, pho->phi));
          Bool_t passPixelVeto = kTRUE;
          if (fabs(pho->eta) < 1.479) {
            if (minDEta > 0.04 || minDPhi > 0.3) {
              if (pho->hasPixelSeed) passPixelVeto = kFALSE;
            }
          } else {
            if (minDEta > 0.08 || minDPhi > 0.3) {
              if (pho->hasPixelSeed) passPixelVeto = kFALSE;
            }
          }

          //more eegamma selection cuts          
          if (fabs( probe->eta - pho->eta) < 0.15 && higgsana::deltaR( probe->eta, probe->phi, pho->eta, pho->phi) < 0.7) continue;

          //Selection cuts
          if (!((vtag + vpho + vprobe).M() + (vtag+vprobe).M() < 180)) continue;
          if (!((vtag+vprobe).M() > 40)) continue;
          if (!(higgsana::deltaR(probe->eta, probe->phi, pho->eta, pho->phi) < 1.5)) continue;
          if (!passPixelVeto) continue;

          //cut to emulate trigger.
          if (!((vtag+vpho).M() > 50)) continue;


          //optional cuts for tighter selection
          if (dataType == 0 || dataType == 1) {
            if (!(higgsana::deltaR(probe->eta, probe->phi, pho->eta, pho->phi) < 0.7)) continue;
          }
            
          //gen matching for MC
          if (matchGen) {
            if (dataType == -1) {
              if (!(TagIsEle && PhotonIsReal && ProbeIsEle)) continue;
              if (!(higgsana::deltaR(probe->eta, probe->phi, pho->eta, pho->phi) < 0.7)) continue;
            }
            if (dataType == -2) {
              if ((TagIsEle && PhotonIsReal && ProbeIsEle)) continue;
            }
          }

          TLorentzVector vdielectrongamma = vtag + vpho + vprobe;
          if((vdielectrongamma.M()<massLo) || (vdielectrongamma.M()>massHi)) continue;	  	  
 

          //find pfphotons to remove the photon footprint
          vector<const higgsana::TPFCandidate*> photonsToVeto;

          Double_t pfphotonMinDR = 9999;
          const higgsana::TPFCandidate *photonPFCandidate = 0;
          for( uint p=0; p< uint(pfcandidateArr->GetEntries()); ++p ) {
            const higgsana::TPFCandidate *pf = (higgsana::TPFCandidate*)((*pfcandidateArr)[p]);
            if (higgsana::deltaR(pho->eta,pho->phi,pf->eta,pf->phi) < pfphotonMinDR) {
              photonPFCandidate = pf;
              pfphotonMinDR = higgsana::deltaR(pho->eta,pho->phi,pf->eta,pf->phi);
            }
          }
          if (pfphotonMinDR < 0.1) photonsToVeto.push_back(photonPFCandidate);

          for( uint p=0; p< uint(pfcandidateArr->GetEntries()); ++p ) {
            const higgsana::TPFCandidate *pf = (higgsana::TPFCandidate*)((*pfcandidateArr)[p]);
            if (pf->pfType != eGamma) continue;
            if (fabs(pho->eta) < 1.479) {
              if (fabs(pho->eta - pf->eta) < 0.015) {
                photonsToVeto.push_back(pf);
              }
            } else {
              if (higgsana::deltaR(pho->eta,pho->phi,pf->eta,pf->phi) < 0.07) {
                photonsToVeto.push_back(pf);
              }
            }
          }


          //Fill probe
          nProbes++;
          Bool_t passID = (PassEleHZZ4lPreselection(probe) && PassEleHZZ4lRun1LegacyPaperID(probe, eleIDMVA));
          Bool_t passIsolation = PassEleHZZ4lICHEP2012Iso(probe,j,pfcandidateArr,rhoEleIso,EleEAEra,photonsToVeto);
          if (!passID) continue;

          //******************
          //PASS
          //******************
          Bool_t pass = passID && passIsolation;

          // Fill tree
          data.mass   = vdielectrongamma.M();
          data.pt     = probe->pt;
          data.eta    = probe->scEta;
          data.phi    = probe->phi;
          data.weight = weight;
          data.q      = probe->q;
          data.npv    = info->nPV0;
          data.npu    = info->nPUEvents;
          data.pass   = (pass) ? 1 : 0;
          data.rho    = rhoEleIso;

          outTree->Fill();	  
          probeAlreadyUsed[k] = kTRUE;
          
        }


      }


    }
  }

  delete infile;
  infile=0, eventTree=0;      
  delete info;
  delete genparticleArr;
  delete electronArr;
  delete photonArr;
  delete muonArr;
  
     
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
   
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << endl;
  cout << " Number of probes selected: " << nProbes << endl;
  
  outFile->Write();
  outFile->Close();
  delete outFile;
  
  cout << endl;
  cout << "  <> Output saved in " << outputfile << endl;    
  cout << endl;  
      
  gBenchmark->Show("selectEleLHEffTP"); 
}
Esempio n. 11
0
void RunPidGetterQAEff()
{
        
    TString PidFrameworkDir = "/lustre/nyx/cbm/users/klochkov/soft/PidFramework/";
    gSystem->Load( PidFrameworkDir + "build/libPid");  
    
    gStyle->SetOptStat(0000);

    TFile *f2 = new TFile("pid_0.root");    
    TTree *PidTree = (TTree*) f2->Get("PidTree");

    TofPidGetter *getter = new TofPidGetter();
    TBranch *PidGet = PidTree->GetBranch("TofPidGetter");
    PidGet->SetAddress(&getter);

    PidGet->GetEntry(0);
    Float_t ret[3];
        
    TProfile *hEffP  = new  TProfile ("hEffP", "", 100, 0, 10);
    TProfile *hEffPi = new  TProfile ("hEffPi", "", 100, 0, 6);
    TProfile *hEffK  = new  TProfile ("hEffK", "", 100, 0, 5);

    TProfile *hEffPSigma  = new  TProfile ("hEffPSigma", "", 100, 0, 10);
    TProfile *hEffPiSigma = new  TProfile ("hEffPiSigma", "", 100, 0, 6);
    TProfile *hEffKSigma  = new  TProfile ("hEffKSigma", "", 100, 0, 5);

    TProfile2D *hEffPtYP  = new  TProfile2D ("hEffPtYP", "", 100,   -2.5, 2.5, 100, 0, 4);
    TProfile2D *hEffPtYK  = new  TProfile2D ("hEffPtYK", "", 100,   -2.5, 2.5, 100, 0, 4);
    TProfile2D *hEffPtYPi  = new  TProfile2D ("hEffPtYPi", "", 100, -2.5, 2.5, 100, 0, 4);

    TString InTreeFileName = "/lustre/nyx/cbm/users/dblau/cbm/mc/UrQMD/AuAu/10AGeV/sis100_electron/SC_ON/2016_09_01/tree/11111.root";
    TFile *InFile = new TFile(InTreeFileName);    
    TTree *InTree = (TTree*) InFile->Get("fDataTree");
    DataTreeEvent* DTEvent;
    InTree -> SetBranchAddress("DTEvent",&DTEvent);

    int nevents = 100000;//InTree->GetEntries();
    int outputstep = 100;
    std::cout << "Entries = " << nevents << std::endl;

    for (int j=0;j<nevents;j++)
    {
        if ( (j+1) % outputstep == 0) std::cout << j+1 << "/" << nevents <<  "\r" << std::flush;
        InTree->GetEntry(j);
        
        Int_t Nmc[3] = {100,100,100};
        Int_t Ntof[3] = {0,0,0};
        Int_t PdgCode[3] = {2212, 212, 211};
        Double_t sigmas [3] = {0,0,0};
                
        for (int i=0;i<DTEvent->GetNTracks(); i++)
        {
            
            TLorentzVector v;
            
            DataTreeTrack* track = DTEvent -> GetTrack(i);
            DataTreeMCTrack* mctrack = DTEvent -> GetMCTrack(i);
            Double_t p = mctrack->GetPt() * TMath::CosH( mctrack->GetEta() );
            if (track->GetTOFHitId() < 0)
            {
                if (mctrack->GetPdgId() == 2212  )  
                {
                    v.SetPtEtaPhiM (track->GetPt(0), track->GetEta(0), track->GetPhi(0), 0.9386);
                    hEffP->Fill ( p, 0 );
                    hEffPSigma->Fill ( p, 0 );
                    hEffPtYP -> Fill( v.Rapidity() - 1.52, v.Pt(), 0 );
                }
                
                if (mctrack->GetPdgId() == 321  )  
                {
                    v.SetPtEtaPhiM (track->GetPt(0), track->GetEta(0), track->GetPhi(0), 0.5);
                    hEffK->Fill ( p, 0 );
                    hEffKSigma->Fill ( p,  0 ); 
                    hEffPtYK -> Fill( v.Rapidity() - 1.52, v.Pt(), 0 );
                }
                
                if (mctrack->GetPdgId() == 211  )  
                {
                    v.SetPtEtaPhiM (track->GetPt(0), track->GetEta(0), track->GetPhi(0), 0.14);
                    hEffPi->Fill ( p, 0 );
                    hEffPiSigma->Fill ( p,  0);  
                    hEffPtYPi -> Fill( v.Rapidity() - 1.52, v.Pt(),  0 );
                }
                continue;
            }
//             
            DataTreeTOFHit* toftrack = DTEvent -> GetTOFHit(track->GetTOFHitId());
            p = toftrack->GetP();
            Double_t m2 = toftrack->GetMass2 ();
            
            Bool_t cut = toftrack->GetBeta() > 0.1 && ( track->GetChiSq(0)/track->GetNDF(0) < 3 ) && p > 1.0 ;
            if ( !cut ) continue;
            
            getter->GetBayesProbability (m2, p, ret);
            sigmas[0] = getter->GetSigmaProton (m2, p);
            sigmas[1] = getter->GetSigmaKaon (m2, p);
            sigmas[2] = getter->GetSigmaPion (m2, p);
            
    //             std::cout << "pdg = " << mctrack->GetPdgId() << " p = " << p << " Sp = " << sigmas[0] << " Sk = " << sigmas[1]<< " Spi = " << sigmas[2] << std::endl;
            
            if (mctrack->GetPdgId() == 2212  )  
            {
                v.SetPtEtaPhiM (track->GetPt(0), track->GetEta(0), track->GetPhi(0), 0.9386);
                hEffP->Fill ( p, ret[0] > 0.9 );
                hEffPSigma->Fill ( p,  sigmas[0] < 3&& sigmas[1] > 2 && sigmas[2] > 2 );
                hEffPtYP -> Fill( v.Rapidity() - 1.52, v.Pt(),  ret[0] > 0.9 );
            }
            
            if (mctrack->GetPdgId() == 321  )  
            {
                v.SetPtEtaPhiM (track->GetPt(0), track->GetEta(0), track->GetPhi(0), 0.5);
                hEffK->Fill ( p, ret[1] > 0.9 );
                hEffKSigma->Fill ( p,  sigmas[1] < 3&& sigmas[2] > 2 && sigmas[0] > 2 ); 
                hEffPtYK -> Fill(  v.Rapidity() - 1.52, v.Pt(),  ret[1] > 0.9 );
            }
            
            if (mctrack->GetPdgId() == 211  )  
            {
                v.SetPtEtaPhiM (track->GetPt(0), track->GetEta(0), track->GetPhi(0), 0.14);
                hEffPi->Fill ( p, ret[2] > 0.9 );
                hEffPiSigma->Fill ( p, sigmas[2] < 3&& sigmas[0] > 2 && sigmas[1] > 2 );  
                hEffPtYPi -> Fill( v.Rapidity() - 1.52, v.Pt(),  ret[2] > 0.9  );
            }
        }
    }

    hEffP       -> SetMarkerStyle(21);      hEffP       -> SetMarkerColor(kRed);     hEffP       -> SetLineColor(kRed); 
    hEffPi      -> SetMarkerStyle(21);      hEffPi      -> SetMarkerColor(kRed);     hEffPi      -> SetLineColor(kRed); 
    hEffK       -> SetMarkerStyle(21);      hEffK       -> SetMarkerColor(kRed);     hEffK       -> SetLineColor(kRed); 
    hEffPSigma  -> SetMarkerStyle(22);      hEffPSigma  -> SetMarkerColor(kBlue);    hEffPSigma  -> SetLineColor(kBlue);
    hEffPiSigma -> SetMarkerStyle(22);      hEffPiSigma -> SetMarkerColor(kBlue);    hEffPiSigma -> SetLineColor(kBlue);
    hEffKSigma  -> SetMarkerStyle(22);      hEffKSigma  -> SetMarkerColor(kBlue);    hEffKSigma  -> SetLineColor(kBlue);

    hEffP->GetXaxis()->SetTitle( "p, GeV/c" );
    hEffP->GetYaxis()->SetTitle(  "Efficiency"  );    
    hEffP->GetYaxis()->SetRangeUser(0.0, 1.);

    hEffK->GetXaxis()->SetTitle( "p, GeV/c" );
    hEffK->GetYaxis()->SetTitle(  "Efficiency"  );    
    hEffK->GetYaxis()->SetRangeUser(0.0, 1.);

    hEffPi->GetXaxis()->SetTitle( "p, GeV/c" );
    hEffPi->GetYaxis()->SetTitle(  "Efficiency"  );    
    hEffPi->GetYaxis()->SetRangeUser(0.0, 1.);
    
    hEffPtYP->GetYaxis()->SetTitle( "p_{T}, GeV/c" );
    hEffPtYP->GetXaxis()->SetTitle(  "Rapidity"  );
    hEffPtYK->GetYaxis()->SetTitle( "p_{T}, GeV/c" );
    hEffPtYK->GetXaxis()->SetTitle(  "Rapidity"  );
    hEffPtYPi->GetYaxis()->SetTitle( "p_{T}, GeV/c" );
    hEffPtYPi->GetXaxis()->SetTitle(  "Rapidity"  );
    
    TCanvas *c1 = new TCanvas ("c1", "c1", 1400, 700);
    c1->Divide(3,1);

    c1->cd(1);
    hEffP->Draw();
    hEffPSigma->Draw("same");
    c1->cd(2);
    hEffK->Draw();
    hEffKSigma->Draw("same");
    c1->cd(3);
    hEffPi->Draw();
    hEffPiSigma->Draw("same");

//     c1->cd(4);
//     getter->GetProtonSigma()->Draw();
//     getter->GetKaonSigma()->Draw("same");
//     getter->GetPionSigma()->Draw("same");
// 
//     c1->cd(5);
//     getter->GetProtonA()->Draw();
//     getter->GetKaonA()->Draw("same");
//     getter->GetPionA()->Draw("same");
// 
//     c1->cd(6);
//     getter->GetProtonM2()->Draw();
//     getter->GetKaonM2()->Draw("same");
//     getter->GetPionM2()->Draw("same");    
    
    TCanvas *c2 = new TCanvas ("c2", "c2", 1400, 700);
    
    c2->Divide(3,1);
    c2->cd(1);
    hEffPtYP->Draw("colz");

    c2->cd(2);
    hEffPtYK->Draw("colz");
    
    c2->cd(3);
    hEffPtYPi->Draw("colz");
    
   
    c1->SaveAs("Canvas_Eff_p_all.root");
    c1->SaveAs("Canvas_Eff_p_all.C");
    c1->SaveAs("Canvas_Eff_p_all.png");
   
    c2->SaveAs("Canvas_Eff_pT_Y_all.root");
    c2->SaveAs("Canvas_Eff_pT_Y_all.C");
    c2->SaveAs("Canvas_Eff_pT_Y_all.png");
   
}
Esempio n. 12
0
// Main macro function
//--------------------------------------------------------------------------------------------------
void SkimNtuples(const TString input = "skim.input") 
{
  gBenchmark->Start("SkimNtuples");
  
  TString outfilename;          // output of skimming 
  vector<TString> infilenames;  // list input ntuple files to be skimmed
  
  // 
  // parse input file
  //  
  ifstream ifs;
  ifs.open(input.Data()); 
  assert(ifs.is_open());
  string line;
  getline(ifs,line); 
  outfilename = line;
  while(getline(ifs,line)) { infilenames.push_back(line); }
  ifs.close();

  TTree::SetMaxTreeSize(kMaxLong64);
  
  // Don't write TObject part of the objects
  mithep::TEventInfo::Class()->IgnoreTObjectStreamer();
  mithep::TElectron::Class()->IgnoreTObjectStreamer();
  mithep::TDielectron::Class()->IgnoreTObjectStreamer();
  mithep::TMuon::Class()->IgnoreTObjectStreamer();
  mithep::TJet::Class()->IgnoreTObjectStreamer();
  mithep::TPhoton::Class()->IgnoreTObjectStreamer();
  mithep::TVertex::Class()->IgnoreTObjectStreamer();
  
  // Data structures to store info from TTrees
  mithep::TEventInfo *info    = new mithep::TEventInfo();
  TClonesArray *electronArr   = new TClonesArray("mithep::TElectron");
  TClonesArray *dielectronArr = new TClonesArray("mithep::TDielectron");
  TClonesArray *muonArr       = new TClonesArray("mithep::TMuon");
  TClonesArray *pfJetArr      = new TClonesArray("mithep::TJet");
  TClonesArray *photonArr     = new TClonesArray("mithep::TPhoton");
  TClonesArray *pvArr         = new TClonesArray("mithep::TVertex");
  
  UInt_t nInputEvts = 0;
  UInt_t nPassEvts  = 0;
  
  TFile* outfile = new TFile(outfilename, "RECREATE");
  
  //
  // Initialize data trees and structs
  // 
  TTree *outEventTree = new TTree("Events","Events"); 
  outEventTree->Branch("Info",       &info);
  outEventTree->Branch("Electron",   &electronArr);
  outEventTree->Branch("Dielectron", &dielectronArr);
  outEventTree->Branch("Muon",       &muonArr);
  outEventTree->Branch("PFJet",      &pfJetArr);
  outEventTree->Branch("Photon",     &photonArr);
  outEventTree->Branch("PV",         &pvArr);

  for(UInt_t ifile=0; ifile<infilenames.size(); ifile++) {
    cout << "Skimming " << infilenames[ifile] << "..." << endl;
    TFile *infile = new TFile(infilenames[ifile]);
    assert(infile);
    
    TTree *eventTree = (TTree*)infile->Get("Events");
    assert(eventTree);
    
    // Set branch address to structures that will store the info  
    eventTree->SetBranchAddress("Info",       &info);          TBranch *infoBr       = eventTree->GetBranch("Info");
    eventTree->SetBranchAddress("Electron",   &electronArr);   TBranch *electronBr   = eventTree->GetBranch("Electron");
    eventTree->SetBranchAddress("Dielectron", &dielectronArr); TBranch *dielectronBr = eventTree->GetBranch("Dielectron");
    eventTree->SetBranchAddress("Muon",       &muonArr);       TBranch *muonBr       = eventTree->GetBranch("Muon");
    eventTree->SetBranchAddress("PFJet",      &pfJetArr);      TBranch *pfJetBr      = eventTree->GetBranch("PFJet");
    eventTree->SetBranchAddress("Photon",     &photonArr);     TBranch *photonBr     = eventTree->GetBranch("Photon");
    eventTree->SetBranchAddress("PV",         &pvArr);         TBranch *pvBr         = eventTree->GetBranch("PV");
    
    for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { 
      infoBr->GetEntry(ientry);

      electronArr->Clear();   electronBr->GetEntry(ientry);
      dielectronArr->Clear(); dielectronBr->GetEntry(ientry);
      muonArr->Clear();       muonBr->GetEntry(ientry);
      pfJetArr->Clear();      pfJetBr->GetEntry(ientry);
      photonArr->Clear();     photonBr->GetEntry(ientry);
      pvArr->Clear();         pvBr->GetEntry(ientry);
      
      nInputEvts++;
            
      Bool_t keep = kFALSE;

      if(dielectronArr->GetEntriesFast() > 0)
        keep = kTRUE;
  
      if(keep) {
        outEventTree->Fill();
        nPassEvts++;
      }
    }
  }
  
  outfile->Write();
  outfile->Close();
  
  delete info;
  delete electronArr;
  delete dielectronArr;
  delete muonArr;
  delete pfJetArr;
  delete photonArr;
  delete pvArr;
    
  std::cout << outfilename << " created!" << std::endl;
  std::cout << " >>> Events processed: " << nInputEvts << std::endl;
  std::cout << " >>>   Events passing: " << nPassEvts << std::endl;
  
  gBenchmark->Show("SkimNtuples");
}  
Esempio n. 13
0
// Main macro function
//--------------------------------------------------------------------------------------------------
void SkimNtuples(const TString input = "skim.input") 
{
  gBenchmark->Start("SkimNtuples");
  
  TString outfilename;          // output of skimming 
  vector<TString> infilenames;  // list input ntuple files to be skimmed
  TString sample;
  
  // 
  // parse input file
  //  
  ifstream ifs;
  ifs.open(input.Data()); 
  assert(ifs.is_open());
  string line;
  // First line should be DATA or SIGNALMC or BGMC
  getline(ifs,line); 
  sample = line;
  // Second line is the OUTPUT skim file name
  getline(ifs,line); 
  outfilename = line;
  // All subsequent lines are names of INPUT root files
  while(getline(ifs,line)) { infilenames.push_back(line); }
  ifs.close();
  
  bool isGenPresent = true;
  if( sample == "DATA" || sample == "BGMC")
    isGenPresent = false;
  else if( sample == "SIGNALMC" )
    isGenPresent = true;
  else{
    printf("Unknown sample type: use DATA or SIGNALMC or BGMC only in the input configuration file.\n");
    return;
  }
  if( isGenPresent)
    printf("Generator block will be written: signal MC indicated in config file\n");

  TTree::SetMaxTreeSize(kMaxLong64);
  
  // Don't write TObject part of the objects
  mithep::TEventInfo::Class()->IgnoreTObjectStreamer();
  mithep::TGenInfo::Class()->IgnoreTObjectStreamer();
  mithep::TElectron::Class()->IgnoreTObjectStreamer();
  mithep::TDielectron::Class()->IgnoreTObjectStreamer();
  mithep::TMuon::Class()->IgnoreTObjectStreamer();
  mithep::TJet::Class()->IgnoreTObjectStreamer();
  mithep::TPhoton::Class()->IgnoreTObjectStreamer();
  mithep::TVertex::Class()->IgnoreTObjectStreamer();
  
  // Data structures to store info from TTrees
  mithep::TEventInfo *info    = new mithep::TEventInfo();
  mithep::TGenInfo *gen    = new mithep::TGenInfo();
  TClonesArray *electronArr   = new TClonesArray("mithep::TElectron");
  TClonesArray *dielectronArr = new TClonesArray("mithep::TDielectron");
  TClonesArray *muonArr       = new TClonesArray("mithep::TMuon");
  TClonesArray *pfJetArr      = new TClonesArray("mithep::TJet");
  TClonesArray *photonArr     = new TClonesArray("mithep::TPhoton");
  TClonesArray *pvArr         = new TClonesArray("mithep::TVertex");
  
  UInt_t nInputEvts = 0;
  UInt_t nPassEvts  = 0;
  
  TFile* outfile = new TFile(outfilename, "RECREATE");
  
  //
  // Initialize data trees and structs
  // 
  TTree *outEventTree = new TTree("Events","Events"); 
  outEventTree->Branch("Info",       &info);
  if( isGenPresent )
    outEventTree->Branch("Gen",       &gen);
  outEventTree->Branch("Electron",   &electronArr);
  outEventTree->Branch("Dielectron", &dielectronArr);
  outEventTree->Branch("Muon",       &muonArr);
  outEventTree->Branch("PFJet",      &pfJetArr);
  outEventTree->Branch("Photon",     &photonArr);
  outEventTree->Branch("PV",         &pvArr);

  for(UInt_t ifile=0; ifile<infilenames.size(); ifile++) {
    cout << "Skimming " << infilenames[ifile] << "..." << endl;
    TFile *infile = new TFile(infilenames[ifile]);
    assert(infile);
    
    TTree *eventTree = (TTree*)infile->Get("Events");
    assert(eventTree);
    
    // Set branch address to structures that will store the info  
    eventTree->SetBranchAddress("Info",       &info);          TBranch *infoBr       = eventTree->GetBranch("Info");
    TBranch *genBr = 0;
    if(isGenPresent){
      eventTree->SetBranchAddress("Gen" ,       &gen);
      genBr        = eventTree->GetBranch("Gen");
      if( !genBr ){
	printf("MC info is not found in signal MC file\n");
	assert(0);
      }
    }
    eventTree->SetBranchAddress("Electron",   &electronArr);   TBranch *electronBr   = eventTree->GetBranch("Electron");
    eventTree->SetBranchAddress("Dielectron", &dielectronArr); TBranch *dielectronBr = eventTree->GetBranch("Dielectron");
    eventTree->SetBranchAddress("Muon",       &muonArr);       TBranch *muonBr       = eventTree->GetBranch("Muon");
    eventTree->SetBranchAddress("PFJet",      &pfJetArr);      TBranch *pfJetBr      = eventTree->GetBranch("PFJet");
    eventTree->SetBranchAddress("Photon",     &photonArr);     TBranch *photonBr     = eventTree->GetBranch("Photon");
    eventTree->SetBranchAddress("PV",         &pvArr);         TBranch *pvBr         = eventTree->GetBranch("PV");
    
     for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { 
//      for(UInt_t ientry=0; ientry< 100000; ientry++) { // For testing
      infoBr->GetEntry(ientry);
      if( isGenPresent)
	genBr->GetEntry(ientry);

      electronArr->Clear();   
      dielectronArr->Clear(); 
      muonArr->Clear();       
      pfJetArr->Clear();      
      photonArr->Clear();     
      pvArr->Clear();         
      
      nInputEvts++;
            
      Bool_t keep = kFALSE;

      dielectronBr->GetEntry(ientry);

      // Require at least one dielectron
      if(dielectronArr->GetEntriesFast() > 0) {
	// Apply cuts on the dielectron
	int nDielectronsPass = 0;
	for(Int_t i=0; i<dielectronArr->GetEntriesFast(); i++) {
	  mithep::TDielectron *dielectron = (mithep::TDielectron*)((*dielectronArr)[i]);
	  // Require at least one dielectron above 19 GeV and the other above 9 GeV
	  bool etCut = false;
	  if( (dielectron->scEt_1 > 19 && dielectron->scEt_2 > 9) ||
	      (dielectron->scEt_1 > 9 && dielectron->scEt_2 > 19) )
	    etCut = true;
	  // Require at least one dielectron to pass full ID
	  bool idCut = false;
// 	  if( passSmurf(extractElectron(dielectron,1)) ||
// 	      passSmurf(extractElectron(dielectron,2)) )
	  if( DYTools::energy8TeV == 1 ){
	    if( passEGMID2012( DYTools::extractElectron(dielectron,1), WP_MEDIUM, info->rhoLowEta)
		|| passEGMID2012(DYTools::extractElectron(dielectron,2), WP_MEDIUM, info->rhoLowEta) )
	      idCut = true;
	  }else{
	    if( passEGMID2011( DYTools::extractElectron(dielectron,1), WP_MEDIUM, info->rhoLowEta)
		|| passEGMID2011(DYTools::extractElectron(dielectron,2), WP_MEDIUM, info->rhoLowEta) )
	      idCut = true;
	  }
	  if( etCut && idCut )
	    nDielectronsPass++;
	}
	if(nDielectronsPass > 0)
	  keep = kTRUE;
      }
      
      if(keep) {
	// Some of the objects are dropped for skimmed events
// 	electronBr->GetEntry(ientry);
// 	muonBr->GetEntry(ientry);
// 	pfJetBr->GetEntry(ientry);
// 	photonBr->GetEntry(ientry);
// Fill only those branches that we want to write out
	pvBr->GetEntry(ientry);
        nPassEvts++;
      }else{
// Clear branches which we filled to make the pass/fail check,
// but do not want to write out for failed events
	dielectronArr->Clear();
      }

      outEventTree->Fill();

    }
  }
  
  outfile->Write();
  outfile->Close();
  
  delete info;
  delete electronArr;
  delete dielectronArr;
  delete muonArr;
  delete pfJetArr;
  delete photonArr;
  delete pvArr;
    
  std::cout << outfilename << " created!" << std::endl;
  std::cout << " >>> Events processed: " << nInputEvts << std::endl;
  std::cout << " >>>   Events passing: " << nPassEvts << std::endl;
  
  gBenchmark->Show("SkimNtuples");
}  
void selectEleHZZHCP2012IDGivenIsoWithTightTagPerFile(const string inputfile,          // input file
                              const string outputfile,         // output directory
                              const Bool_t  matchGen = kFALSE, // match to generator muons
                              Int_t dataType = 0,              // del = 0, sel = 1, mc = -1
                              Int_t DataEraInput = 2
  ) {
  gBenchmark->Start("selectEleMVAIsoTightGivenID");

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //============================================================================================================== 
  UInt_t DataEra = kDataEra_NONE;
  if (DataEraInput == 1) DataEra = kDataEra_2011_MC;
  if (DataEraInput == 2) DataEra = kDataEra_2012_MC;
  if (DataEraInput == 11) DataEra = kDataEra_2011_Data;
  if (DataEraInput == 12) DataEra = kDataEra_2012_Data;

  //*****************************************************************************************
  //Setup MVA
  //*****************************************************************************************
  EGammaMvaEleEstimator *eleIDMVA = new EGammaMvaEleEstimator();
  vector<string> weightFiles;

  weightFiles.push_back((string(getenv("CMSSW_BASE"))+string("/src/HiggsAna/HZZ4l/data/ElectronIDMVAWeights/Electrons_BDTG_NonTrigV0_Cat1.weights.xml")).c_str());
  weightFiles.push_back((string(getenv("CMSSW_BASE"))+string("/src/HiggsAna/HZZ4l/data/ElectronIDMVAWeights/Electrons_BDTG_NonTrigV0_Cat2.weights.xml")).c_str());
  weightFiles.push_back((string(getenv("CMSSW_BASE"))+string("/src/HiggsAna/HZZ4l/data/ElectronIDMVAWeights/Electrons_BDTG_NonTrigV0_Cat3.weights.xml")).c_str());
  weightFiles.push_back((string(getenv("CMSSW_BASE"))+string("/src/HiggsAna/HZZ4l/data/ElectronIDMVAWeights/Electrons_BDTG_NonTrigV0_Cat4.weights.xml")).c_str());
  weightFiles.push_back((string(getenv("CMSSW_BASE"))+string("/src/HiggsAna/HZZ4l/data/ElectronIDMVAWeights/Electrons_BDTG_NonTrigV0_Cat5.weights.xml")).c_str());
  weightFiles.push_back((string(getenv("CMSSW_BASE"))+string("/src/HiggsAna/HZZ4l/data/ElectronIDMVAWeights/Electrons_BDTG_NonTrigV0_Cat6.weights.xml")).c_str());
  eleIDMVA->initialize( "BDT", EGammaMvaEleEstimator::kNonTrig,  kTRUE, weightFiles);
  

  // mass region
  Double_t massLo = 40;
  Double_t massHi = 200;

  
  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  
  
  Double_t nProbes = 0;
  
  //
  // Set up output ntuple
  //
  TFile *outFile = new TFile(outputfile.c_str(),"RECREATE"); 
  TTree *outTree = new TTree("Events","Events");
  EffData data;
  outTree->Branch("Events",&data.mass,"mass/F:pt:eta:phi:weight:q/I:npv/i:npu:pass:runNum:lumiSec:evtNum:rho/F");

  TFile *infile=0;
  TTree *eventTree=0;
  
  // Data structures to store info from TTrees
  higgsana::TEventInfo *info  = new higgsana::TEventInfo();
  higgsana::TGenInfo *gen     = new higgsana::TGenInfo();
  TClonesArray *electronArr = new TClonesArray("higgsana::TElectron");
  TClonesArray *pfcandidateArr = new TClonesArray("higgsana::TPFCandidate");
  TClonesArray *muonArr = new TClonesArray("higgsana::TMuon");

  // Read input file and get the TTrees
  cout << "Processing " << inputfile << "..." << endl;
  infile = TFile::Open(inputfile.c_str(),"read");
  assert(infile);



  //********************************************************
  // Good RunLumi Selection
  //********************************************************
  Bool_t hasJSON = kFALSE;
  mithep::RunLumiRangeMap rlrm;
  if (!matchGen) {
    hasJSON = kTRUE;
    rlrm.AddJSONFile("/afs/cern.ch/work/s/sixie/public/HZZ4l/auxiliar/2012/Cert_Full2012_53X_JSON.txt"); 
    rlrm.AddJSONFile("/afs/cern.ch/work/s/sixie/public/HZZ4l/auxiliar/2011/2011Combined.json");
  }
    
  eventTree = (TTree*)infile->Get("Events"); assert(eventTree);  
  eventTree->SetBranchAddress("Info",     &info);        TBranch *infoBr     = eventTree->GetBranch("Info");
  eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron");
  eventTree->SetBranchAddress("Muon", &muonArr);         TBranch *muonBr = eventTree->GetBranch("Muon");
  eventTree->SetBranchAddress("PFCandidate", &pfcandidateArr);  TBranch *pfcandidateBr = eventTree->GetBranch("PFCandidate");
  cout << "NEvents = " << eventTree->GetEntries() << endl;

  TBranch *genBr = 0;
  if(matchGen) {
    eventTree->SetBranchAddress("Gen", &gen);
    genBr = eventTree->GetBranch("Gen");
  }
    
  Double_t weight = 1;

  // loop over events
  for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
    if (ientry % 100000 == 0) cout << "Processed Event " << ientry << endl;
    infoBr->GetEntry(ientry);

    // check for certified runs
    mithep::RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec);      
    if(hasJSON && !rlrm.HasRunLumi(rl)) continue;  
 
    //***********************************************************
    // Definition of Pileup Energy density
    //***********************************************************
    Double_t rhoEleIso = 0;
    UInt_t EleEAEra = 0;
    if (DataEra == kDataEra_2011_MC) {
        
      if (!(isnan(info->RhoKt6PFJetsForIso25) || 
            isinf(info->RhoKt6PFJetsForIso25))) {
        rhoEleIso = info->RhoKt6PFJetsForIso25;
      }
      EleEAEra = kDataEra_2011_Data;
        
    } else if (DataEra == kDataEra_2012_MC) {
        
      if (!(isnan(info->RhoKt6PFJets) || 
            isinf(info->RhoKt6PFJets))) {
        rhoEleIso = info->RhoKt6PFJets;
      }
      EleEAEra = kDataEra_2012_Data;
    }

    //use only odd numbered events to evaluate efficiency for data. even numbered events were used for training
    //if (info->evtNum % 2 == 0 && !matchGen) continue;


    // trigger requirement               
    Bool_t passTrigger = kFALSE;
    if(dataType == 0) {
      if ((info->triggerBits & kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50) == kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50) passTrigger = kTRUE;
      if ((info->triggerBits & kHLT_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC8_Mass30) == kHLT_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC8_Mass30) passTrigger = kTRUE;
      if ((info->triggerBits & kHLT_Ele32_CaloIdL_CaloIsoVL_SC17) == kHLT_Ele32_CaloIdL_CaloIsoVL_SC17) passTrigger = kTRUE;
    } else if(dataType == 1) {
      if(DataEraInput == 2) {
        if(info->triggerBits & kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50)  continue;
        if(info->triggerBits & kHLT_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC8_Mass30)  continue;
        if(info->triggerBits & kHLT_Ele32_CaloIdL_CaloIsoVL_SC17)                         continue;
      }
        
      if ((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) == kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) passTrigger = kTRUE;
    }
    if(dataType != -1 && !passTrigger) continue;     
      
    // good vertex requirement
    if(!(info->hasGoodPV)) continue;

    if(matchGen) genBr->GetEntry(ientry);
      
    electronArr->Clear();
    muonArr->Clear(); 
    pfcandidateArr->Clear(); 
    electronBr->GetEntry(ientry);
    muonBr->GetEntry(ientry);
    pfcandidateBr->GetEntry(ientry);

    //********************************************************
    //Low Met Requirement
    //********************************************************
    TVector3 met;        
    if(info->pfMEx!=0 || info->pfMEy!=0) {       
      met.SetXYZ(info->pfMEx, info->pfMEy, 0);
    }
    if (met.Pt() > 25) continue;
      

    //********************************************************
    //Loop over TAG electrons
    //********************************************************
    for(Int_t i=0; i<electronArr->GetEntriesFast(); i++) {

      const higgsana::TElectron *tag = (higgsana::TElectron*)((*electronArr)[i]);
	
      if(matchGen) {
        Bool_t match1 = (higgsana::deltaR(tag->eta, tag->phi, gen->eta_1, gen->phi_1) < 0.5);
        Bool_t match2 = (higgsana::deltaR(tag->eta, tag->phi, gen->eta_2, gen->phi_2) < 0.5);
        if(!match1 && !match2)
          continue;
      }

      if(tag->pt          < 20)  continue;
      if(fabs(tag->scEta) > 2.5) continue;

      if (!PassEleSimpleCutsVeryTight(tag,pfcandidateArr,rhoEleIso,EleEAEra)) continue;

      if(dataType == 0 &&
         !((info->triggerBits & kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50) && (tag->hltMatchBits & kHLTObject_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT)) &&
         !((info->triggerBits & kHLT_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC8_Mass30) && (tag->hltMatchBits & kHLTObject_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT)) &&
         !((info->triggerBits & kHLT_Ele32_CaloIdL_CaloIsoVL_SC17) && (tag->hltMatchBits & kHLTObject_Ele32_CaloIdL_CaloIsoVL)) &&
         !((info->triggerBits & kHLT_Ele32_CaloIdL_CaloIsoVL_SC17) && (tag->hltMatchBits & kHLTObject_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT)) &&
         !((info->triggerBits & kHLT_Ele17_CaloIdL_CaloIsoVL) && (tag->hltMatchBits & kHLTObject_Ele17_CaloIdL_CaloIsoVL)) ) 
        continue;
      
      if (dataType == 1) {
        if(dataType == 1 &&
           !((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && (tag->hltMatchBits & kHLTObject_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && tag->pt > 30) &&
           !((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && (tag->hltMatchBits & kHLTObject_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && tag->pt > 35) &&
           !((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && (tag->hltMatchBits & kHLTObject_Ele52_CaloIdVT_TrkIdT) && tag->pt > 60) &&
           !((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && (tag->hltMatchBits & kHLTObject_Ele27_WP80) && tag->pt > 30) && 
           !((info->triggerBits & kHLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT) && (tag->hltMatchBits & kHLTObject_Ele32_WP70) && tag->pt > 35)  
          )
          continue;       
      }

      const Double_t m = 0.000511;
      TLorentzVector vtag;
      vtag.SetPtEtaPhiM(tag->pt, tag->eta, tag->phi, m);
        
      for(Int_t j=0; j<electronArr->GetEntriesFast(); j++) {
        if(i==j) continue;
	  
        const higgsana::TElectron *probe = (higgsana::TElectron*)((*electronArr)[j]);
        if(probe->q == tag->q) continue;
	  
// 	  if(typev[ifile]==eDiEl &&
// 	     !((info->triggerBits & kHLT_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC8_Mass30) && (probe->hltMatchBits & kHLTObject_SC8)) &&
// 	     !((info->triggerBits & kHLT_Ele17_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC8_Mass30) && (probe->hltMatchBits & kHLTObject_Ele8)) &&
// 	     !((info->triggerBits & kHLT_Ele32_CaloIdL_CaloIsoVL_SC17) && (probe->hltMatchBits & kHLTObject_SC17)))
// 	    continue;
	  
        if(matchGen) {
          Bool_t match1 = (higgsana::deltaR(probe->eta, probe->phi, gen->eta_1, gen->phi_1) < 0.5);
          Bool_t match2 = (higgsana::deltaR(probe->eta, probe->phi, gen->eta_2, gen->phi_2) < 0.5);
          if(!match1 && !match2)
            continue;
        }
	  
        if(fabs(probe->scEta) > 2.5) continue;

        TLorentzVector vprobe;
        vprobe.SetPtEtaPhiM(probe->pt, probe->eta, probe->phi, m);
	  
        TLorentzVector vdielectron = vtag + vprobe;
        if((vdielectron.M()<massLo) || (vdielectron.M()>massHi)) continue;	  	  

        //for probes with pT < 10, require the Ele20_SC4 trigger
        if (probe->pt < 10) {
          if(dataType == 0) {

            if (!((info->triggerBits & kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50) == kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50)) continue;
            if (!((info->triggerBits & kHLT_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT_SC4_Mass50) && (tag->hltMatchBits & kHLTObject_Ele20_CaloIdVT_CaloIsoVT_TrkIdT_TrkIsoVT))) continue;
          }
        }

        nProbes++;

        Bool_t passID = (PassEleHZZ4lPreselection(probe) && PassEleHZZ4lICHEP2012ID(probe, eleIDMVA));
        
        vector<const higgsana::TPFCandidate*> photonsToVeto;
        Bool_t passIsolation = PassEleHZZ4lICHEP2012Iso(probe,j,pfcandidateArr,rhoEleIso,EleEAEra,photonsToVeto);
        if (!passIsolation) continue;

        //******************
        //PASS
        //******************
        Bool_t pass = passID && passIsolation;

        // Fill tree
        data.mass   = vdielectron.M();
        data.pt     = probe->pt;
        data.eta    = probe->scEta;
        data.phi    = probe->phi;
        data.weight = weight;
        data.q      = probe->q;
        data.npv    = info->nPV0;
        data.npu    = info->nPUEvents;
        data.pass   = (pass) ? 1 : 0;
        data.rho    = rhoEleIso;
        data.runNum = info->runNum;
        data.lumiSec = info->lumiSec;
        data.evtNum = info->evtNum;

        outTree->Fill();	  
      }
    }
  }

  delete infile;
  infile=0, eventTree=0;      
  delete info;
  delete gen;
  delete electronArr;
  
     
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
   
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << endl;
  cout << " Number of probes selected: " << nProbes << endl;
  
  outFile->Write();
  outFile->Close();
  delete outFile;
  
  cout << endl;
  cout << "  <> Output saved in " << outputfile << endl;    
  cout << endl;  
      
  gBenchmark->Show("selectEleLHEffTP"); 
}
Esempio n. 15
0
void computeAccSelZeeBinned(const TString conf,            // input file
                            const TString outputDir,        // output directory
			    const Int_t   doPU
) {
  gBenchmark->Start("computeAccSelZeeBinned");

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //============================================================================================================== 

  const Double_t MASS_LOW   = 60;
  const Double_t MASS_HIGH  = 120;
  const Double_t PT_CUT     = 25;
  const Double_t ETA_CUT    = 2.5;
  const Double_t ELE_MASS   = 0.000511;

  const Double_t ETA_BARREL = 1.4442;
  const Double_t ETA_ENDCAP = 1.566;

  const Int_t BOSON_ID  = 23;
  const Int_t LEPTON_ID = 11;
  
  // efficiency files
  const TString dataHLTEffName     = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/MG/eff.root";
  const TString dataHLTEffName_pos = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/MG/eff.root";
  const TString dataHLTEffName_neg = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/MG/eff.root";

  const TString zeeHLTEffName      = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/CT/eff.root";
  const TString zeeHLTEffName_pos  = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/CT/eff.root";
  const TString zeeHLTEffName_neg  = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/CT/eff.root";
  
  const TString dataGsfSelEffName     = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/MG/eff.root";
  const TString dataGsfSelEffName_pos = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/MG/eff.root";
  const TString dataGsfSelEffName_neg = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/MG/eff.root";

  const TString zeeGsfSelEffName      = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/CT/eff.root";
  const TString zeeGsfSelEffName_pos  = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/CT/eff.root";
  const TString zeeGsfSelEffName_neg  = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/CT/eff.root";

  // load pileup reweighting file
  TFile *f_rw = TFile::Open("../Tools/pileup_rw_76X.root", "read");
  TH1D *h_rw = (TH1D*) f_rw->Get("h_rw_golden");


  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  

  vector<TString> fnamev;  // file name per input file
  vector<TString> labelv;  // TLegend label per input file
  vector<Int_t>   colorv;  // plot color per input file
  vector<Int_t>   linev;   // plot line style per input file

  //
  // parse .conf file
  //
  ifstream ifs;
  ifs.open(conf.Data());
  assert(ifs.is_open());
  string line;
  while(getline(ifs,line)) {
    if(line[0]=='#') continue;
    
    string fname;
    Int_t color, linesty;
    stringstream ss(line);
    ss >> fname >> color >> linesty;
    string label = line.substr(line.find('@')+1);
    fnamev.push_back(fname);
    labelv.push_back(label);
    colorv.push_back(color);
    linev.push_back(linesty);
  }
  ifs.close();

  // Create output directory
  gSystem->mkdir(outputDir,kTRUE);
  
  TH2D *h=0;
  
  //
  // HLT efficiency
  //
  cout << "Loading trigger efficiencies..." << endl;

  TFile *dataHLTEffFile_pos = new TFile(dataHLTEffName_pos);
  CEffUser2D dataHLTEff_pos;
  dataHLTEff_pos.loadEff((TH2D*)dataHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *dataHLTEffFile_neg = new TFile(dataHLTEffName_neg);
  CEffUser2D dataHLTEff_neg;
  dataHLTEff_neg.loadEff((TH2D*)dataHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrhEtaPt"));
  
  TFile *zeeHLTEffFile_pos = new TFile(zeeHLTEffName_pos);
  CEffUser2D zeeHLTEff_pos;
  zeeHLTEff_pos.loadEff((TH2D*)zeeHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)zeeHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zeeHLTEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *zeeHLTEffFile_neg = new TFile(zeeHLTEffName_neg);
  CEffUser2D zeeHLTEff_neg;
  zeeHLTEff_neg.loadEff((TH2D*)zeeHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)zeeHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zeeHLTEffFile_neg->Get("hErrhEtaPt"));
  
  h =(TH2D*)dataHLTEffFile_pos->Get("hEffEtaPt");
  TH2D *hHLTErr_pos = new TH2D("hHLTErr_pos", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                                 h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  TH2D *hHLTErr_neg = new TH2D("hHLTErr_neg", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                                 h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  
  //
  // Selection efficiency
  //
  cout << "Loading GSF+selection efficiencies..." << endl;
  
  TFile *dataGsfSelEffFile_pos = new TFile(dataGsfSelEffName_pos);
  CEffUser2D dataGsfSelEff_pos;
  dataGsfSelEff_pos.loadEff((TH2D*)dataGsfSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataGsfSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataGsfSelEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *dataGsfSelEffFile_neg = new TFile(dataGsfSelEffName_neg);
  CEffUser2D dataGsfSelEff_neg;
  dataGsfSelEff_neg.loadEff((TH2D*)dataGsfSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataGsfSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataGsfSelEffFile_neg->Get("hErrhEtaPt"));

  TFile *zeeGsfSelEffFile_pos = new TFile(zeeGsfSelEffName_pos);
  CEffUser2D zeeGsfSelEff_pos;
  zeeGsfSelEff_pos.loadEff((TH2D*)zeeGsfSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)zeeGsfSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zeeGsfSelEffFile_pos->Get("hErrhEtaPt"));

  TFile *zeeGsfSelEffFile_neg = new TFile(zeeGsfSelEffName_neg);
  CEffUser2D zeeGsfSelEff_neg;
  zeeGsfSelEff_neg.loadEff((TH2D*)zeeGsfSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)zeeGsfSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zeeGsfSelEffFile_neg->Get("hErrhEtaPt"));
 
  h =(TH2D*)dataGsfSelEffFile_pos->Get("hEffEtaPt");
  TH2D *hGsfSelErr_pos = new TH2D("hGsfSelErr_pos", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                                       h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  TH2D *hGsfSelErr_neg = new TH2D("hGsfSelErr_neg", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                                       h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  
  // Data structures to store info from TTrees
  baconhep::TEventInfo   *info = new baconhep::TEventInfo();
  baconhep::TGenEventInfo *gen = new baconhep::TGenEventInfo();
  TClonesArray *genPartArr     = new TClonesArray("baconhep::TGenParticle");
  TClonesArray *electronArr    = new TClonesArray("baconhep::TElectron");
  TClonesArray *vertexArr  = new TClonesArray("baconhep::TVertex");

  TFile *infile=0;
  TTree *eventTree=0;
  
  // Variables to store acceptances and uncertainties (per input file)
  vector<Double_t> nEvtsv, nSelv;
  vector<Double_t> nSelCorrv, nSelCorrVarv;
  vector<Double_t> accv, accCorrv;
  vector<Double_t> accErrv, accErrCorrv;

  const baconhep::TTrigger triggerMenu("../../BaconAna/DataFormats/data/HLT_50nsGRun");

  //
  // loop through files
  //
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {  

    // Read input file and get the TTrees
    cout << "Processing " << fnamev[ifile] << " ..." << endl;
    infile = TFile::Open(fnamev[ifile]); 
    assert(infile);

    eventTree = (TTree*)infile->Get("Events"); assert(eventTree);  
    eventTree->SetBranchAddress("Info",              &info); TBranch *infoBr     = eventTree->GetBranch("Info");
    eventTree->SetBranchAddress("GenEvtInfo",         &gen); TBranch *genBr      = eventTree->GetBranch("GenEvtInfo");
    eventTree->SetBranchAddress("GenParticle", &genPartArr); TBranch *genPartBr  = eventTree->GetBranch("GenParticle");
    eventTree->SetBranchAddress("Electron",   &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron");
    eventTree->SetBranchAddress("PV",   &vertexArr); TBranch *vertexBr = eventTree->GetBranch("PV");

    nEvtsv.push_back(0);
    nSelv.push_back(0);
    nSelCorrv.push_back(0);
    nSelCorrVarv.push_back(0);

    //
    // loop over events
    //
    for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
      genBr->GetEntry(ientry);
      genPartArr->Clear(); genPartBr->GetEntry(ientry);
      infoBr->GetEntry(ientry);

      Int_t glepq1=-99;
      Int_t glepq2=-99;

      if (fabs(toolbox::flavor(genPartArr, BOSON_ID))!=LEPTON_ID) continue;
      TLorentzVector *vec=new TLorentzVector(0,0,0,0);
      TLorentzVector *lep1=new TLorentzVector(0,0,0,0);
      TLorentzVector *lep2=new TLorentzVector(0,0,0,0);
      toolbox::fillGen(genPartArr, BOSON_ID, vec, lep1, lep2,&glepq1,&glepq2,1);
      if(vec->M()<MASS_LOW || vec->M()>MASS_HIGH) continue;      
      delete vec; delete lep1; delete lep2;

      vertexArr->Clear();
      vertexBr->GetEntry(ientry);
      double npv  = vertexArr->GetEntries();
      Double_t weight=gen->weight;
      if(doPU>0) weight*=h_rw->GetBinContent(h_rw->FindBin(info->nPUmean));

      nEvtsv[ifile]+=weight;        

      // trigger requirement               
      if (!isEleTrigger(triggerMenu, info->triggerBits, kFALSE)) continue;
      
      // good vertex requirement
      if(!(info->hasGoodPV)) continue;
      
      electronArr->Clear();
      electronBr->GetEntry(ientry);

      for(Int_t i1=0; i1<electronArr->GetEntriesFast(); i1++) {
  	const baconhep::TElectron *ele1 = (baconhep::TElectron*)((*electronArr)[i1]);
	
	// check ECAL gap
	if(fabs(ele1->scEta)>=ETA_BARREL && fabs(ele1->scEta)<=ETA_ENDCAP) continue;
	
	//double ele1_pt = gRandom->Gaus(ele1->pt*getEleScaleCorr(ele1->scEta,0), getEleResCorr(ele1->scEta,0));

	if(ele1->pt	     < PT_CUT && ele1->scEt < PT_CUT)	  continue;  // lepton pT cut
        if(fabs(ele1->scEta) > ETA_CUT && fabs(ele1->eta) > ETA_CUT)	  continue;  // lepton |eta| cut
        if(!passEleID(ele1,info->rhoIso)) continue;  // lepton selection
	//if(!isEleTriggerObj(triggerMenu, ele1->hltMatchBits, kFALSE, kFALSE)) continue;

        TLorentzVector vEle1(0,0,0,0);
	vEle1.SetPtEtaPhiM(ele1->pt, ele1->eta, ele1->phi, ELE_MASS);
	Bool_t isB1 = (fabs(ele1->scEta)<ETA_BARREL) ? kTRUE : kFALSE;

        for(Int_t i2=i1+1; i2<electronArr->GetEntriesFast(); i2++) {          
	  const baconhep::TElectron *ele2 = (baconhep::TElectron*)((*electronArr)[i2]);
	  
	  // check ECAL gap
	  if(fabs(ele2->scEta)>=ETA_BARREL && fabs(ele2->scEta)<=ETA_ENDCAP) continue;
	  //double ele2_pt = gRandom->Gaus(ele2->scEt*getEleScaleCorr(ele2->scEta,0), getEleResCorr(ele2->scEta,0));
	  if(ele1->q == ele2->q)	continue;
          if(ele2->pt        < PT_CUT && ele2->scEt < PT_CUT)    continue;  // lepton pT cut
          if(fabs(ele2->scEta) > ETA_CUT && fabs(ele2->eta) > ETA_CUT)   continue;  // lepton |eta| cut
	  if(!passEleID(ele2,info->rhoIso)) continue;  // lepton selection

          TLorentzVector vEle2(0,0,0,0);
	  vEle2.SetPtEtaPhiM(ele2->pt, ele2->eta, ele2->phi, ELE_MASS);  
          Bool_t isB2 = (fabs(ele2->scEta)<ETA_BARREL) ? kTRUE : kFALSE;

	  if(!isEleTriggerObj(triggerMenu, ele1->hltMatchBits, kFALSE, kFALSE) && !isEleTriggerObj(triggerMenu, ele2->hltMatchBits, kFALSE, kFALSE)) continue;
	  
	  // mass window
          TLorentzVector vDilep = vEle1 + vEle2;
          if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue;
          
          /******** We have a Z candidate! HURRAY! ********/
          Double_t effdata, effmc;
          //Double_t sceta1 = (fabs(ele1->scEta)<2.5) ? ele1->scEta : 0.99*(ele1->scEta);
	  Double_t sceta1 = ele1->scEta;
          //Double_t sceta2 = (fabs(ele2->scEta)<2.5) ? ele2->scEta : 0.99*(ele2->scEta);
    	  Double_t sceta2 = ele2->scEta;

          Double_t corr=1;
	  
	  effdata=1; effmc=1;
          if(ele1->q>0) { 
            effdata *= (1.-dataHLTEff_pos.getEff(sceta1, ele1->scEt));
            effmc   *= (1.-zeeHLTEff_pos.getEff(sceta1, ele1->scEt));
          } else {
            effdata *= (1.-dataHLTEff_neg.getEff(sceta1, ele1->scEt)); 
            effmc   *= (1.-zeeHLTEff_neg.getEff(sceta1, ele1->scEt)); 
          }
          if(ele2->q>0) {
            effdata *= (1.-dataHLTEff_pos.getEff(sceta2, ele2->scEt)); 
            effmc   *= (1.-zeeHLTEff_pos.getEff(sceta2, ele2->scEt));
          } else {
            effdata *= (1.-dataHLTEff_neg.getEff(sceta2, ele2->scEt)); 
            effmc   *= (1.-zeeHLTEff_neg.getEff(sceta2, ele2->scEt));
          }
          effdata = 1.-effdata;
          effmc   = 1.-effmc;
          corr *= effdata/effmc;


          effdata=1; effmc=1;
          if(ele1->q>0) { 
            effdata *= dataGsfSelEff_pos.getEff(sceta1, ele1->scEt); 
            effmc   *= zeeGsfSelEff_pos.getEff(sceta1, ele1->scEt); 
          } else {
            effdata *= dataGsfSelEff_neg.getEff(sceta1, ele1->scEt); 
            effmc   *= zeeGsfSelEff_neg.getEff(sceta1, ele1->scEt); 
          }
          if(ele2->q>0) {
            effdata *= dataGsfSelEff_pos.getEff(sceta2, ele2->scEt); 
            effmc   *= zeeGsfSelEff_pos.getEff(sceta2, ele2->scEt);
          } else {
            effdata *= dataGsfSelEff_neg.getEff(sceta2, ele2->scEt); 
            effmc   *= zeeGsfSelEff_neg.getEff(sceta2, ele2->scEt);
          }
          corr *= effdata/effmc;
	  
	  // scale factor uncertainties
	  if(ele1->q>0) {	    
	    Double_t effdata = dataGsfSelEff_pos.getEff(sceta1, ele1->scEt);
	    Double_t errdata = TMath::Max(dataGsfSelEff_pos.getErrLow(sceta1, ele1->scEt), dataGsfSelEff_pos.getErrHigh(sceta1, ele1->scEt));
            Double_t effmc   = zeeGsfSelEff_pos.getEff(sceta1, ele1->scEt); 
	    Double_t errmc   = TMath::Max(zeeGsfSelEff_pos.getErrLow(sceta1, ele1->scEt), zeeGsfSelEff_pos.getErrHigh(sceta1, ele1->scEt));
	    Double_t errGsfSel = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
	    hGsfSelErr_pos->Fill(sceta1, ele1->scEt, errGsfSel);
	  } else {
	    Double_t effdata = dataGsfSelEff_neg.getEff(sceta1, ele1->scEt);
	    Double_t errdata = TMath::Max(dataGsfSelEff_neg.getErrLow(sceta1, ele1->scEt), dataGsfSelEff_neg.getErrHigh(sceta1, ele1->scEt));
            Double_t effmc   = zeeGsfSelEff_neg.getEff(sceta1, ele1->scEt); 
	    Double_t errmc   = TMath::Max(zeeGsfSelEff_neg.getErrLow(sceta1, ele1->scEt), zeeGsfSelEff_neg.getErrHigh(sceta1, ele1->scEt));
	    Double_t errGsfSel = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
	    hGsfSelErr_neg->Fill(sceta1, ele1->scEt, errGsfSel);
	  }

	  if(ele2->q>0) {	    
	    Double_t effdata = dataHLTEff_pos.getEff(sceta2, ele2->scEt);
	    Double_t errdata = TMath::Max(dataHLTEff_pos.getErrLow(sceta2, ele2->scEt), dataHLTEff_pos.getErrHigh(sceta2, ele2->scEt));
            Double_t effmc   = zeeHLTEff_pos.getEff(sceta2, ele2->scEt); 
	    Double_t errmc   = TMath::Max(zeeHLTEff_pos.getErrLow(sceta2, ele2->scEt), zeeHLTEff_pos.getErrHigh(sceta2, ele2->scEt));
	    Double_t errHLT = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
	    hHLTErr_pos->Fill(sceta2, ele2->scEt, errHLT);
	  } else {
	    Double_t effdata = dataHLTEff_neg.getEff(sceta2, ele2->scEt);
	    Double_t errdata = TMath::Max(dataHLTEff_neg.getErrLow(sceta2, ele2->scEt), dataHLTEff_neg.getErrHigh(sceta2, ele2->scEt));
            Double_t effmc   = zeeHLTEff_neg.getEff(sceta2, ele2->scEt); 
	    Double_t errmc   = TMath::Max(zeeHLTEff_neg.getErrLow(sceta2, ele2->scEt), zeeHLTEff_neg.getErrHigh(sceta2, ele2->scEt));
	    Double_t errHLT = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
	    hHLTErr_neg->Fill(sceta2, ele2->scEt, errHLT);
	  }

	  nSelv[ifile]+=weight;
	  nSelCorrv[ifile]+=weight*corr;
	  nSelCorrVarv[ifile]+=weight*weight*corr*corr;
	}
      }
    }
    
    Double_t var=0;
    for(Int_t iy=0; iy<=hHLTErr_pos->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hHLTErr_pos->GetNbinsX(); ix++) {
	Double_t err=hHLTErr_pos->GetBinContent(ix,iy);
	var+=err*err;
      }
    }
    for(Int_t iy=0; iy<=hHLTErr_neg->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hHLTErr_neg->GetNbinsX(); ix++) {
	Double_t err=hHLTErr_neg->GetBinContent(ix,iy);
	var+=err*err;
      }
    }
    cout << "var1: " << var << endl;
    for(Int_t iy=0; iy<=hGsfSelErr_pos->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hGsfSelErr_pos->GetNbinsX(); ix++) {
	Double_t err=hGsfSelErr_pos->GetBinContent(ix,iy);
	var+=err*err;
      }
    }
    for(Int_t iy=0; iy<=hGsfSelErr_neg->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hGsfSelErr_neg->GetNbinsX(); ix++) {
	Double_t err=hGsfSelErr_neg->GetBinContent(ix,iy);
	var+=err*err;
      }
    }
    cout << "var2: " << var << endl;

    nSelCorrVarv[ifile]+=var;

    // compute acceptances
    std::cout << nEvtsv[ifile] << " " << nSelv[ifile] << std::endl;
    accv.push_back(nSelv[ifile]/nEvtsv[ifile]);         accErrv.push_back(sqrt(accv[ifile]*(1. +accv[ifile])/nEvtsv[ifile]));
    accCorrv.push_back(nSelCorrv[ifile]/nEvtsv[ifile]); accErrCorrv.push_back(accCorrv[ifile]*sqrt((nSelCorrVarv[ifile])/(nSelCorrv[ifile]*nSelCorrv[ifile]) + 1./nEvtsv[ifile]));
    
    delete infile;
    infile=0, eventTree=0;  
  }  
  delete info;
  delete gen;
  delete electronArr;  
    
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
   
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << " Z -> e e" << endl;
  cout << "  Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl;
  cout << "  pT > " << PT_CUT << endl;
  cout << "  |eta| < " << ETA_CUT << endl;
  cout << endl;
  
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
    cout << "   ================================================" << endl;
    cout << "    Label: " << labelv[ifile] << endl;
    cout << "     File: " << fnamev[ifile] << endl;
    cout << endl;
    cout << "    *** Acceptance ***" << endl;
    cout << "          nominal: " << setw(12) << nSelv[ifile]   << " / " << nEvtsv[ifile] << " = " << accv[ifile]   << " +/- " << accErrv[ifile] << endl;
    cout << "     SF corrected: " << accCorrv[ifile] << " +/- " << accErrCorrv[ifile] << endl;
    cout << endl;
  }
  
  char txtfname[100];
  sprintf(txtfname,"%s/binned.txt",outputDir.Data());
  ofstream txtfile;
  txtfile.open(txtfname);
  txtfile << "*" << endl;
  txtfile << "* SUMMARY" << endl;
  txtfile << "*--------------------------------------------------" << endl;
  txtfile << " Z -> e e" << endl;
  txtfile << "  Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl;
  txtfile << "  pT > " << PT_CUT << endl;
  txtfile << "  |eta| < " << ETA_CUT << endl;
  txtfile << endl;
  
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
    txtfile << "   ================================================" << endl;
    txtfile << "    Label: " << labelv[ifile] << endl;
    txtfile << "     File: " << fnamev[ifile] << endl;
    txtfile << endl;
    txtfile << "    *** Acceptance ***" << endl;
    txtfile << "          nominal: " << setw(12) << nSelv[ifile]   << " / " << nEvtsv[ifile] << " = " << accv[ifile]   << " +/- " << accErrv[ifile] << endl;
    txtfile << "     SF corrected: " << accCorrv[ifile] << " +/- " << accErrCorrv[ifile] << endl;
    txtfile << endl;
  }
  txtfile.close();
  
  cout << endl;
  cout << "  <> Output saved in " << outputDir << "/" << endl;    
  cout << endl;  
      
  gBenchmark->Show("computeAccSelZeeBinned"); 
}
void MakeBJetEfficiencyNtuple(const string inputFilename, const string outputFilename, int denominatorType = 0)
{  
  gBenchmark->Start("WWTemplate");

  //*****************************************************************************************
  //Define Data Era
  //*****************************************************************************************
  UInt_t DataEra = kDataEra_NONE;
  DataEra = kDataEra_2012_MC;

  cout << "using DataEra = " << DataEra << endl;


  //*****************************************************************************************
  //Setup Output Tree
  //*****************************************************************************************
  TFile *outputFile = new TFile(outputFilename.c_str(), "RECREATE");
  cmsana::EfficiencyTree *effTree = new cmsana::EfficiencyTree;
  effTree->CreateTree();
  effTree->tree_->SetAutoFlush(0);

  UInt_t NDenominatorsFilled = 0;
  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  
  
  //
  // Access samples and fill histograms
  TTree *eventTree=0;  
   
  // Data structures to store info from TTrees
  cmsana::TEventInfo *info    = new cmsana::TEventInfo();
  TClonesArray *jetArr = new TClonesArray("cmsana::TJet");
  TClonesArray *pfcandidateArr = new TClonesArray("cmsana::TPFCandidate");
  TClonesArray *genparticleArr = new TClonesArray("cmsana::TGenParticle");
  TClonesArray *genjetArr = new TClonesArray("cmsana::TGenJet");

  Int_t NEvents = 0;



  //********************************************************
  // Get Tree
  //********************************************************
  eventTree = getTreeFromFile(inputFilename.c_str(),"Events"); 
  TBranch *infoBr;
  TBranch *jetBr;
  TBranch *pfcandidateBr;
  TBranch *genparticleBr;
  TBranch *genjetBr;
  
  
  //*****************************************************************************************
  //Loop over Data Tree
  //*****************************************************************************************
  // Set branch address to structures that will store the info  
  eventTree->SetBranchAddress("Info",       &info);  infoBr       = eventTree->GetBranch("Info");
  eventTree->SetBranchAddress("PFJet", &jetArr); jetBr  = eventTree->GetBranch("PFJet");
  eventTree->SetBranchAddress("PFCandidate", &pfcandidateArr); pfcandidateBr = eventTree->GetBranch("PFCandidate");
  eventTree->SetBranchAddress("GenParticle", &genparticleArr); genparticleBr = eventTree->GetBranch("GenParticle");
  eventTree->SetBranchAddress("GenJet", &genjetArr); genjetBr = eventTree->GetBranch("GenJet");

  cout << "InputFile " << inputFilename << " --- Total Events : " << eventTree->GetEntries() << endl;
  for(UInt_t ientry=0; ientry < eventTree->GetEntries(); ientry++) {       	
    infoBr->GetEntry(ientry);
		
    if (ientry % 100 == 0) cout << "Event " << ientry << endl;

    Double_t eventweight = info->eventweight;

    //********************************************************
    // Load the branches
    //********************************************************
    jetArr->Clear(); 
    pfcandidateArr->Clear(); 
    genparticleArr->Clear(); 
    genjetArr->Clear(); 
    jetBr->GetEntry(ientry);
    pfcandidateBr->GetEntry(ientry);
    genparticleBr->GetEntry(ientry);
    genjetBr->GetEntry(ientry);
 

    //********************************************************
    // Pileup Energy Density
    //********************************************************
    Double_t rho = info->RhoKt6PFJets;
    UInt_t EAEra = kDataEra_2012_Data;


    if (denominatorType == 0) {
    //********************************************************
    // genjets denominator
    //********************************************************
      for(Int_t k=0; k<genjetArr->GetEntries(); k++) {
        const cmsana::TGenJet *genjet = (cmsana::TGenJet*)((*genjetArr)[k]);

        //some kinematic cuts to save ntupling time
        if (!(genjet->pt > 30)) continue;
        if (!(fabs(genjet->eta) < 2.5)) continue;        

        bool pass = false;
        //Find matching jet
        for(Int_t i=0; i<jetArr->GetEntriesFast(); i++) {
          const cmsana::TJet *jet = (cmsana::TJet*)((*jetArr)[i]);
          if (!(jet->pt > 20)) continue;
          if (!(fabs(jet->eta) < 2.5)) continue;
          
          //match in dR?
          double DR = cmsana::deltaR(jet->eta,jet->phi,genjet->eta,genjet->phi);
          if (!(DR < 0.5)) continue;

          if (!(jet->CombinedSecondaryVertexBJetTagsDisc > 0.679)) continue;
          
          pass = true;
          break;
        }
        
        effTree->weight = eventweight;
        effTree->mass = 0;
        effTree->pt = genjet->pt;
        effTree->eta = genjet->eta;
        effTree->phi = genjet->phi;
        effTree->rho = info->RhoKt6PFJets;
        effTree->q = 0;
        effTree->npv = info->nGoodPV;
        effTree->npu = info->nPU;
        effTree->matchedPdgId = genjet->matchedPdgId;
        effTree->run = info->runNum;
        effTree->lumi = info->lumiSec;
        effTree->event = info->evtNum;
        effTree->pass = pass;

        //***********************
        //Fill Denominator
        //***********************
        NDenominatorsFilled++;
        effTree->tree_->Fill();

      }//loop over genjet denominators
    } //if denominatorType == 0

  } //loop over events
  
  cout << "Total Denominators: " << NDenominatorsFilled << endl;

  delete info;
  delete jetArr;
  delete pfcandidateArr;
  delete genparticleArr;
  delete genjetArr;

  outputFile->Write();
  outputFile->Close();
  
  delete outputFile;
  if (effTree) delete effTree;
} 
void HHToBBGGSelectionCCOneFakePhoton(const string inputfile,          // input file
                       const string outputfile,         // output directory
                       Int_t SampleType = 1
  ) {
  
  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //============================================================================================================== 
  bool printdebug = false;


  //*****************************************************************************************
  //Setup Jet Energy Corrections
  //*****************************************************************************************
  std::vector<cmsana::JetCorrectorParameters> correctionParameters;
  correctionParameters.push_back(cmsana::JetCorrectorParameters( ( getenv("CMSSW_BASE") + string("/src/CMSAna/JetEnergyCorrections/data/GR_R_52_V9_L1FastJet_AK5PF.txt")).c_str()));
  correctionParameters.push_back(cmsana::JetCorrectorParameters( ( getenv("CMSSW_BASE") + string("/src/CMSAna/JetEnergyCorrections/data/GR_R_52_V9_L2Relative_AK5PF.txt")).c_str()));
  correctionParameters.push_back(cmsana::JetCorrectorParameters( ( getenv("CMSSW_BASE") + string("/src/CMSAna/JetEnergyCorrections/data/GR_R_52_V9_L3Absolute_AK5PF.txt")).c_str()));
  cmsana::FactorizedJetCorrector *JetCorrector = new cmsana::FactorizedJetCorrector(correctionParameters);


  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  
  Double_t nEvents = 0;

  
  //*****************************************************************************************
  // Set up output ntuple
  //*****************************************************************************************
  TFile *outFile = new TFile(outputfile.c_str(),"RECREATE"); 
  TH1F *NEvents =  new TH1F("NEvents",";;",1,-0.5,0.5);
  TH1F *N2bjets = new TH1F("N2bjets","Number of Events w/ 2 bjets",1,-0.5,0.5); // Count the number of events that have two real cjets
  TH1F *N4genjets = new TH1F("N4genjets", "Number of Events w/ at 2 bjets and >=2 genjets", 1, -0.5, 0.5); // Count the number of events that have two real bjets + at least two other jets
  TH1F *NPUMean = new TH1F("NPUMean",";NPUMean;Number of Events", 100, -0.5, 99.5);
  cmsana::HHToBBGGEventTree *outputEventTree = new cmsana::HHToBBGGEventTree;
  outputEventTree->CreateTree();


  //*****************************************************************************************
  // Set up input
  //*****************************************************************************************
  TFile *infile=0;
  TTree *eventTree=0;
  
  // Data structures to store info from TTrees
  cmsana::TEventInfo *info  = new cmsana::TEventInfo();
  TClonesArray *genparticleArr = new TClonesArray("cmsana::TGenParticle");
  TClonesArray *genjetArr = new TClonesArray("cmsana::TGenJet");
  TClonesArray *photonArr = new TClonesArray("cmsana::TPhoton");
  TClonesArray *muonArr = new TClonesArray("cmsana::TMuon");
  TClonesArray *electronArr = new TClonesArray("cmsana::TElectron");
  TClonesArray *jetArr = new TClonesArray("cmsana::TJet");
  TClonesArray *pfcandidateArr = new TClonesArray("cmsana::TPFCandidate");

  // Read input file and get the TTrees
  cout << "Processing " << inputfile << "..." << endl;
  infile = TFile::Open(inputfile.c_str(),"read");
  assert(infile);

    
  eventTree = (TTree*)infile->Get("Events"); assert(eventTree);  
  eventTree->SetBranchAddress("Info",     &info);        TBranch *infoBr     = eventTree->GetBranch("Info");
  eventTree->SetBranchAddress("GenParticle", &genparticleArr); TBranch *genparticleBr = eventTree->GetBranch("GenParticle");
  eventTree->SetBranchAddress("GenJet", &genjetArr); TBranch *genjetBr = eventTree->GetBranch("GenJet");
  cout << "NEvents = " << eventTree->GetEntries() << endl;

  // Read efficiency file for Fake Photon Rate
  TFile *glu = TFile::Open("/afs/cern.ch/work/v/vlambert/public/releases/CMSSW_5_3_9_patch3/src/PhotonEfficiencies/Efficiencies/PhotonMistagRate_gluon.root");
  TH2F *gluon_efficiencies = (TH2F*)glu->Get("MistagRate_CSVMedium_PtEta");  // access 2D histogram with efficiency weights for gluons
  TFile *qk = TFile::Open("/afs/cern.ch/work/v/vlambert/public/releases/CMSSW_5_3_9_patch3/src/PhotonEfficiencies/Efficiencies/PhotonMistagRate_quark.root");
  TH2F *quark_efficiencies = (TH2F*)qk->Get("MistagRate_CSVMedium_PtEta");  // access 2D histogram with efficiency weights for quarks
  
  // Efficiencies for charm jets faking bjets
  TFile *file4Weight = TFile::Open("/afs/cern.ch/work/v/vlambert/public/releases/CMSSW_5_3_9_patch3/src/PhotonEfficiencies/Efficiencies/BJetMistagRate_type4_nocuts.root");
  TH2F *type4Weight = (TH2F*)file4Weight->Get("MistagRate_CSVMedium_Pt_Eta");

  // Efficiencies for Photons
  TFile *FakePhoton = TFile::Open("/afs/cern.ch/work/v/vlambert/public/releases/CMSSW_5_3_9_patch3/src/PhotonEfficiencies/Efficiencies/PhotonEfficiency_PromptPhoton.root");
  TH2F *Photon_efficiency = (TH2F*)FakePhoton->Get("Efficiency_PtEta");
  
  // null vector for default four vectors
  cmsana::FourVector null(0.0,0.0,0.0,0.0);

  // loop over events
  for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
    if (ientry % 1000 == 0) cout << "Processed Event " << ientry << endl;
    infoBr->GetEntry(ientry);

    NEvents->Fill(0);
    NPUMean->Fill(info->nPUMean);

    //***********************************************************
    // Definition of Pileup Energy density
    //***********************************************************
    Double_t rho = info->RhoKt6PFJets;

    genparticleArr->Clear(); 
    genjetArr->Clear(); 

    genparticleBr->GetEntry(ientry);
    genjetBr->GetEntry(ientry);

    //***********************************************************
    // Find Gen-Level particles
    //***********************************************************
    const cmsana::TGenParticle *genPhoton1 = 0;
    const cmsana::TGenParticle *genPhoton2 = 0;
    const cmsana::TGenParticle* photon1 = 0;
    const cmsana::TGenParticle *genB1 = 0;
    const cmsana::TGenParticle *genB2 = 0;
    const cmsana::TGenJet* genBJet1 = 0;
    const cmsana::TGenJet* genBJet2 = 0;
    const cmsana::TGenJet* bjet1 = 0;
    const cmsana::TGenJet* bjet2 = 0;
    Float_t FakeRate3 = 0;
    Float_t FakeRate4 = 0;
    for(Int_t i=0; i<genparticleArr->GetEntriesFast(); i++) {
      const cmsana::TGenParticle *p = (cmsana::TGenParticle*)((*genparticleArr)[i]);
//       cout << p->pdgid << " " << p->status << " " << p->pt << " " << p->eta << " " << p->phi 
//            << " | " << p->motherPdgID << "\n";

      if ( SampleType == cmsana::HHToBBGGEventTree::HHToBBGG) {
        if (abs(p->pdgid) == 5 && p->motherPdgID == 25 && p->status == 2) {
          if (!genB1) {
            genB1 = p;
          } else {
            if (!genB2) genB2 = p;
          }
        }
      }
      if ( SampleType == cmsana::HHToBBGGEventTree::ttHgg 
           || SampleType == cmsana::HHToBBGGEventTree::ttbar
        ) {
        if (abs(p->pdgid) == 5 && abs(p->motherPdgID) == 6 && p->status == 2) {
          if (!genB1) {
            genB1 = p;
          } else {
            if (!genB2) genB2 = p;
          }
        }
      }
      if ( SampleType == cmsana::HHToBBGGEventTree::ZHgg 
        ) {
        if (abs(p->pdgid) == 5 && p->motherPdgID == 23 && p->status == 2) {
          if (!genB1) {
            genB1 = p;
          } else {
            if (!genB2) genB2 = p;
          }
        }
      }
      //********************************************************
      // Find Photon
      //********************************************************
      if (abs(p->pdgid) == 22
	  && ( p->motherPdgID == 25 || abs(p->motherPdgID) <= 6 ||
	       (abs(p->motherPdgID) >= 11 && abs(p->motherPdgID) <= 14) ||
	       abs(p->motherPdgID) == 23 || abs(p->motherPdgID) == 24 || 
	       abs(p->motherPdgID) == 21)) {
	if (p->pt < 20) continue;
	if (fabs(p->eta) > 2.5) continue;
	if (!genPhoton1) {
	  genPhoton1 = p;
	  photon1 = p;
	} else {
	  if (!genPhoton2) {
	    if (cmsana::deltaR(p->eta, p->phi, photon1->eta, photon1->phi) < 0.1) continue;   
	    genPhoton2 = p;
	  }
	}
      }
    }
    //********************************************************
    // Assigning charm jets as B jets
    //********************************************************
    for(Int_t gen=0; gen<genjetArr->GetEntriesFast(); gen++) {
      const cmsana::TGenJet *genJ = (cmsana::TGenJet*)((*genjetArr)[gen]);
      if (fabs(genJ->matchedPdgId) == 4) { 
	if (genJ->pt <30) continue;
	if (fabs(genJ->eta) >2.4) continue;
	if (!genBJet1) {
	  genBJet1 = genJ;
	  bjet1 = genJ;
	} else {
	  if (!genBJet2) {
	    genBJet2 = genJ;
	    bjet2 = genJ;
	  }
	}
      }
    }
    // Check for real bjets
    Int_t realB = 0;
    for(Int_t rb=0; rb<genjetArr->GetEntriesFast(); rb++) {
      const cmsana::TGenJet *bcand = (cmsana::TGenJet*)((*genjetArr)[rb]);
      if (fabs(bcand->matchedPdgId) == 5) { 
	if (bcand->pt >20) realB++;
      }
    }
    // Discount all events with more than two photons and real bjets
    if (!genPhoton1) continue;
    if (genPhoton2) continue;
    if (realB !=0) continue;
    // Cut out events without 2 bjets faked by charm jets
    if (!(bjet1 && bjet2)) continue;
    
    // Count the number of events with 2 bjets
    N2bjets->Fill(0);

    //sampleType
    cmsana::HHToBBGGEventTree::SampleType stype = cmsana::HHToBBGGEventTree::none;
    if (SampleType == 0) stype = cmsana::HHToBBGGEventTree::data;
    if (SampleType == 1) stype = cmsana::HHToBBGGEventTree::HHToBBGG;
    if (SampleType == 2) stype = cmsana::HHToBBGGEventTree::ttHgg;
    if (SampleType == 3) stype = cmsana::HHToBBGGEventTree::ZHgg;
    if (SampleType == 4) stype = cmsana::HHToBBGGEventTree::bbHgg;
    if (SampleType == 5) stype = cmsana::HHToBBGGEventTree::ttbar;
    if (SampleType == 6) stype = cmsana::HHToBBGGEventTree::BBGG;
    if (SampleType == 7) stype = cmsana::HHToBBGGEventTree::GGPlusTwoMistag;
    if (SampleType == 8) stype = cmsana::HHToBBGGEventTree::BBPlusTwoFakePhotons;
    if (SampleType == 9) stype = cmsana::HHToBBGGEventTree::CCMistagPlusTwoFakePhotons;
    if (SampleType == 10) stype = cmsana::HHToBBGGEventTree::TwoLightJetsMistagPlusTwoFakePhotons;
    if (SampleType == 11) stype = cmsana::HHToBBGGEventTree::BBJG;
    if (SampleType == 12) stype = cmsana::HHToBBGGEventTree::CCJG;
    if (SampleType == 13) stype = cmsana::HHToBBGGEventTree::JJJG;


    outputEventTree->sampletype = stype;
    outputEventTree->run = info->runNum;
    outputEventTree->lumi = info->lumiSec;
    outputEventTree->event = info->evtNum;
    outputEventTree->npu = info->nPU;
    outputEventTree->rho = info->RhoKt6PFJets;
    outputEventTree->nvtx = info->nGoodPV;

    cmsana::FourVectorM genpho1v;
    cmsana::FourVectorM genpho2v;
    outputEventTree->genpho1 = null;
    outputEventTree->genpho2 = null;
    if (genPhoton1) {
      genpho1v.SetPt(genPhoton1->pt);
      genpho1v.SetEta(genPhoton1->eta);
      genpho1v.SetPhi(genPhoton1->phi);
      genpho1v.SetM(0);
      outputEventTree->genpho1 = genpho1v;
    }
    if (genPhoton2) {
      genpho2v.SetPt(genPhoton2->pt);
      genpho2v.SetEta(genPhoton2->eta);
      genpho2v.SetPhi(genPhoton2->phi);
      genpho2v.SetM(0);   
      outputEventTree->genpho2 = genpho2v;    
    }
        
    cmsana::FourVectorM genb1v;
    cmsana::FourVectorM genb2v;
    outputEventTree->genb1 = null;
    outputEventTree->genb2 = null;
    if (genB1) {
      genb1v.SetPt(genB1->pt);
      genb1v.SetEta(genB1->eta);
      genb1v.SetPhi(genB1->phi);
      genb1v.SetM(0);
      outputEventTree->genb1 = genb1v;
    }
    if (genB2) {
      genb2v.SetPt(genB2->pt);
      genb2v.SetEta(genB2->eta);
      genb2v.SetPhi(genB2->phi);
      genb2v.SetM(0);   
      outputEventTree->genb2 = genb2v;
    }
    
    //Fill the event bjets and genbjets
    cmsana::FourVectorM bjet1v;
    cmsana::FourVectorM bjet2v;
    cmsana::FourVectorM dibjetv;
    outputEventTree->bjet1 = null;      //default 4-vector
    outputEventTree->bjet2 = null;
    outputEventTree->dibjet = null;    
    
    bjet1v.SetPt(bjet1->pt);
    bjet1v.SetEta(bjet1->eta);
    bjet1v.SetPhi(bjet1->phi);
    bjet1v.SetM(bjet1->mass);
    outputEventTree->bjet1 = bjet1v;
    
    bjet2v.SetPt(bjet2->pt);
    bjet2v.SetEta(bjet2->eta);
    bjet2v.SetPhi(bjet2->phi);
    bjet2v.SetM(bjet2->mass);
    outputEventTree->bjet2 = bjet2v;
    
    dibjetv = bjet1v + bjet2v;
    outputEventTree->dibjet = dibjetv;
    
    cmsana::FourVectorM genbjet1v;
    cmsana::FourVectorM genbjet2v;
    outputEventTree->genbjet1 = null;    
    outputEventTree->genbjet2 = null;    
    
    genbjet1v.SetPt(genBJet1->pt);
    genbjet1v.SetEta(genBJet1->eta);
    genbjet1v.SetPhi(genBJet1->phi);
    genbjet1v.SetM(genBJet1->mass);
    outputEventTree->genbjet1 = genbjet1v;
    
    genbjet2v.SetPt(genBJet2->pt);
    genbjet2v.SetEta(genBJet2->eta);
    genbjet2v.SetPhi(genBJet2->phi);
    genbjet2v.SetM(genBJet2->mass);   
    outputEventTree->genbjet2 = genbjet2v; 
    
    // count other genjets
    Int_t addgenjets = 0;
    for(Int_t c=0; c<genjetArr->GetEntriesFast(); c++) {
      const cmsana::TGenJet *counterjet = (cmsana::TGenJet*)((*genjetArr)[c]);
      if (counterjet == genBJet1 || counterjet == genBJet2) continue;
      addgenjets++;
    }
    if (addgenjets > 1) {
      N4genjets->Fill(0);
    }

    //Assign efficiencies for bjets
    FakeRate3 = type4Weight->GetBinContent(type4Weight->FindBin(fmax(fmin(bjet1->pt,119.9),30.1),fmax(fmin(bjet1->eta, 2.39),-2.39)));
    FakeRate4 = type4Weight->GetBinContent(type4Weight->FindBin(fmax(fmin(bjet2->pt,119.9),30.1),fmax(fmin(bjet2->eta, 2.39),-2.39)));
    
    //********************************************************
    // Assign Photons
    //********************************************************

    //Assubg the real photon as photon1
    Float_t photonsPt = 0;
    Float_t FakeRate1 = 0;
    cmsana::FourVectorM photon1v;
    outputEventTree->pho1 = null;  
    //Assign efficiency for photon 1
    FakeRate1 = Photon_efficiency->GetBinContent(Photon_efficiency->FindBin(fmax(fmin(photon1->pt,99.9),20.1),fmax(fmin(photon1->eta, 2.49),-2.49)));
    photon1v.SetPt(photon1->pt);
    photon1v.SetEta(photon1->eta);
    photon1v.SetPhi(photon1->phi);
    photon1v.SetM(0);
    photonsPt+=photon1->pt;
    outputEventTree->pho1 = photon1v;
    
    // Define the second photon
    Float_t FakeRate2 = 0;
    const cmsana::TGenJet* photon2 = 0;
    // Store as photons
    cmsana::FourVectorM photon2v;
    cmsana::FourVectorM diphotonv;
    UInt_t njets = 0;
    UInt_t ncentraljets = 0;
    Float_t goodjetsPt = 0;
    
    //select genjet
    for(Int_t j=0; j<genjetArr->GetEntriesFast(); j++) {
      const cmsana::TGenJet *genjet2 = (cmsana::TGenJet*)((*genjetArr)[j]);
      if (cmsana::deltaR(photon1->eta, photon1->phi, genjet2->eta, genjet2->phi) < 0.5) continue;
      if (genjet2 == genBJet1 || genjet2 == genBJet2) continue;
      if (genjet2->pt < 20) continue;
      if (fabs(genjet2->eta) >2.5) continue;
      
      //Assign these two genjets as fake photons
      outputEventTree->pho2 = null;
      outputEventTree->diphoton = null; 
      FakeRate2 = 0;
      
      //Assign fake rates for photon 2
      if (fabs(genjet2->matchedPdgId) == 21) { // jet corresponds to a gluon
	FakeRate2 = gluon_efficiencies->GetBinContent(gluon_efficiencies->FindBin(fmax(fmin(genjet2->pt,99.9),20.1),fmax(fmin(genjet2->eta, 2.49),-2.49)));
      }
      else { // jet corresponds to a quark
	FakeRate2 = quark_efficiencies->GetBinContent(quark_efficiencies->FindBin(fmax(fmin(genjet2->pt,99.9),20.1),fmax(fmin(genjet2->eta, 2.49),-2.49)));
      }
      photon2 = genjet2;	
      photon2v.SetPt(genjet2->pt);
      photon2v.SetEta(genjet2->eta);
      photon2v.SetPhi(genjet2->phi);
      photon2v.SetM(0);
      photonsPt+=genjet2->pt;
      
      outputEventTree->pho2 = photon2v;
      diphotonv = photon1v + photon2v;
      outputEventTree->diphoton = diphotonv;
      
      // count additional jets
      njets = 0;
      ncentraljets = 0;
      goodjetsPt = 0;
      
      for(Int_t k=0; k<genjetArr->GetEntriesFast(); k++) {
	const cmsana::TGenJet *othergenjet = (cmsana::TGenJet*)((*genjetArr)[k]);
	
	// look only at the genjets that are not bjets or photons
	if (othergenjet == photon2 || othergenjet == genBJet1 ||othergenjet == genBJet2) continue;
	if (cmsana::deltaR(photon1->eta, photon1->phi, othergenjet->eta, othergenjet->phi) < 0.5) continue;
	if (!(othergenjet->pt >30)) continue;
	njets++;
	goodjetsPt += othergenjet->pt;
	if (fabs(othergenjet->eta) < 2.5) ncentraljets++;  
      }
      
      //********************************************************
      //bbgg system
      //********************************************************    
      cmsana::FourVectorM bbggSystemv;
      outputEventTree->bbgg = null;
      if (bjet1 && bjet2 && photon1 && photon2) {
	bbggSystemv = (photon1v + photon2v + bjet1v + bjet2v);
	outputEventTree->bbgg = bbggSystemv;
      }
      
      //********************************************************
      //NJets
      //********************************************************    
      outputEventTree->njets = njets;
      outputEventTree->ncentraljets = ncentraljets;
      
      if (bjet1 && bjet2 && photon1 && photon2 && njets >= 4) printdebug = true;
      
      //********************************************************
      //Count Additional Leptons
      //********************************************************    
      Int_t NLeptons = 0;
      Float_t ElectronsPt = 0;
      Float_t MuonsPt = 0;
      for(Int_t i=0; i<muonArr->GetEntriesFast(); i++) {
	const cmsana::TMuon *mu = (cmsana::TMuon*)((*muonArr)[i]);
	
	if (!(mu->pt > 10)) continue;
	if (!(fabs(mu->eta) < 2.4)) continue;
	
	//pass loose veto cuts
	if (!PassMuonIDVeto(mu)) continue;
	if (!(ComputeMuonPFIsoRings(mu,pfcandidateArr, rho,
				    kDataEra_2012_MC, kPFIso, 0.0, 0.3, false) / mu->pt < 0.2)) continue;
	
	//make sure the lepton doesn't overlap with bjets or photons
	if (bjet1 && cmsana::deltaR(mu->eta, mu->phi, bjet1->eta, bjet1->phi) < 0.5) continue;
	if (bjet2 && cmsana::deltaR(mu->eta, mu->phi, bjet2->eta, bjet2->phi) < 0.5) continue;
	if (photon1 && cmsana::deltaR(mu->eta, mu->phi, photon1->eta, photon1->phi) < 0.3) continue;
	if (photon2 && cmsana::deltaR(mu->eta, mu->phi, photon2->eta, photon2->phi) < 0.3) continue;
	MuonsPt+= mu->pt;
	NLeptons++;
      }
      for(Int_t i=0; i<electronArr->GetEntriesFast(); i++) {
	const cmsana::TElectron *ele = (cmsana::TElectron*)((*electronArr)[i]);
	
	if (!(ele->pt > 20)) continue;
	if (!(fabs(ele->scEta) < 2.5)) continue;
	
	//pass loose veto cuts
	if (!PassEleSimpleCutsVeto( ele, pfcandidateArr, rho,
				    kDataEra_2012_MC, false)) continue;
	
	//make sure the lepton doesn't overlap with bjets or photons
	if (bjet1 && cmsana::deltaR(ele->eta, ele->phi, bjet1->eta, bjet1->phi) < 0.5) continue;
	if (bjet2 && cmsana::deltaR(ele->eta, ele->phi, bjet2->eta, bjet2->phi) < 0.5) continue;
	if (photon1 && cmsana::deltaR(ele->eta, ele->phi, photon1->eta, photon1->phi) < 0.3) continue;
	if (photon2 && cmsana::deltaR(ele->eta, ele->phi, photon2->eta, photon2->phi) < 0.3) continue;
	ElectronsPt+= ele->pt;
	NLeptons++;
      }
      
      outputEventTree->nlep = NLeptons;
      
      //********************************************************
      //Some kinematic variables
      //********************************************************
      outputEventTree->DRgg = -1;
      outputEventTree->DRbb = -1;
      outputEventTree->minDRgb = -1;
      outputEventTree->HT = 0;
      outputEventTree->MET = 0;
      outputEventTree->pfTrackMET = 0;
      if (photon1 && photon2 && bjet1 && bjet2 ) {
	outputEventTree->DRgg = cmsana::deltaR(photon1->eta, photon1->phi, photon2->eta, photon2->phi);
	outputEventTree->DRbb = cmsana::deltaR(bjet1->eta, bjet1->phi, bjet2->eta, bjet2->phi);
	outputEventTree->minDRgb = fmin(fmin(fmin( cmsana::deltaR(photon1->eta, photon1->phi, bjet1->eta, bjet1->phi), 
						   cmsana::deltaR(photon1->eta, photon1->phi, bjet2->eta, bjet2->phi)),
					     cmsana::deltaR(photon2->eta, photon2->phi, bjet1->eta, bjet1->phi)),
					cmsana::deltaR(photon2->eta, photon2->phi, bjet2->eta, bjet2->phi));
      };     
      outputEventTree->HT = photonsPt + goodjetsPt + ElectronsPt + MuonsPt;
      outputEventTree->MET = sqrt( info->pfMEx*info->pfMEx + info->pfMEy*info->pfMEy);
      outputEventTree->pfTrackMET = sqrt( info->pfTrackMEx*info->pfTrackMEx + info->pfTrackMEy*info->pfTrackMEy);
      
      
      outputEventTree->pfmet = sqrt( info->pfMEx*info->pfMEx + info->pfMEy*info->pfMEy);
      
      //********************************************************
      //Fill Output Tree
      //********************************************************
      //Temporary Measure:Reduce Fake-rate by factor of 4 when we use Tight Photon selection instead of Loose
      FakeRate2 = FakeRate2 / 4;

      //reduction from pileup;
      FakeRate1 = FakeRate1 * (0.85/0.95)*(0.85/0.95);
      FakeRate3 = FakeRate3 * (0.10/0.15);
      FakeRate4 = FakeRate4 * (0.10/0.15);
      
      outputEventTree->weight = FakeRate1 * FakeRate2 * FakeRate3 * FakeRate4;
      outputEventTree->tree_->Fill();
      nEvents++;
      
      // Debug for Fake Rates
      //cout<< "weight = " << FakeRate1*FakeRate2*FakeRate3*FakeRate4<<endl;
      if (FakeRate1*FakeRate2*FakeRate3*FakeRate4 ==0) {
	cout<< "FakeRate 1 = "<< FakeRate1 <<endl;
	cout<< "FakeRate 2 = "<< FakeRate2 <<endl;
	cout<< "FakeRate 3 = "<< FakeRate3 <<endl;
	cout<< "FakeRate 4 = "<< FakeRate4 <<endl;
      }
    }
  }
  delete infile;
  infile=0, eventTree=0;      
  delete info;
  delete photonArr;
  delete jetArr;
  delete genparticleArr;
  delete genjetArr;
     
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
 
  outFile->Write();
  outFile->Close();
  delete outFile;
  
  cout << " Number of events selected: " << nEvents << endl;
  cout << endl;
  cout << "  <> Output saved in " << outputfile << endl;    
  cout << endl;  
  
  
}
Esempio n. 18
0
void computeAccSelWe_Charge(const TString conf,       // input file
                     const TString outputDir,  // output directory
		     const Int_t   charge,      // 0 = inclusive, +1 = W+, -1 = W-
		     const Int_t   doPU,
		     const Int_t   doScaleCorr,
		     const Int_t   sigma
) {
  gBenchmark->Start("computeAccSelWe");

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //============================================================================================================== 

  const Double_t PT_CUT     = 25;
  const Double_t ETA_CUT    = 2.5;
  const Double_t ELE_MASS = 0.000511;

  const Double_t ETA_BARREL = 1.4442;
  const Double_t ETA_ENDCAP = 1.566;

  const Double_t VETO_PT   = 10;
  const Double_t VETO_ETA  = 2.5;

  const Double_t ECAL_GAP_LOW  = 1.4442;
  const Double_t ECAL_GAP_HIGH = 1.566;

  const Int_t BOSON_ID  = 24;
  const Int_t LEPTON_ID = 11;
 
  // efficiency files
  TString dataHLTEffName(   "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/MG/eff.root");
  TString zeeHLTEffName(    "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/CT/eff.root");
  TString dataGsfSelEffName("/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/MG/eff.root");
  TString zeeGsfSelEffName( "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/CT/eff.root");
  if(charge==1) {
    dataHLTEffName    = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/MGpositive/eff.root";
    zeeHLTEffName     = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/CTpositive/eff.root"; 
    dataGsfSelEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/MGpositive_FineBin/eff.root";
    zeeGsfSelEffName  = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/CTpositive/eff.root"; 
  }
  if(charge==-1) {
    dataHLTEffName    = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/MGnegative/eff.root";
    zeeHLTEffName     = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/CTnegative/eff.root";
    dataGsfSelEffName = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/MGnegative_FineBin/eff.root";
    zeeGsfSelEffName  = "/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleGsfSelEff/CTnegative/eff.root";
  }

  const TString corrFiles = "../EleScale/76X_16DecRereco_2015_Etunc";

  EnergyScaleCorrection_class eleCorr( corrFiles.Data()); eleCorr.doScale= true; eleCorr.doSmearings =true;

  // load pileup reweighting file
  TFile *f_rw = TFile::Open("../Tools/puWeights_76x.root", "read");
  TH1D *h_rw = (TH1D*) f_rw->Get("puWeights");

  TFile *f_r9 = TFile::Open("../EleScale/transformation.root","read");
  TGraph* gR9EB = (TGraph*) f_r9->Get("transformR90");
  TGraph* gR9EE = (TGraph*) f_r9->Get("transformR91");

  TFile *f_hlt_data;
  TFile *f_hlt_mc;

  if(charge==1){
    f_hlt_data = TFile::Open("/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/Nominal/EleTriggerTF1_Data_Positive.root");
    f_hlt_mc   = TFile::Open("/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/Nominal/EleTriggerTF1_MC_Positive.root");
  }
  if(charge==-1){
    f_hlt_data = TFile::Open("/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/Nominal/EleTriggerTF1_Data_Negative.root");
    f_hlt_mc   = TFile::Open("/afs/cern.ch/work/x/xniu/public/WZXSection/wz-efficiency/EleHLTEff/Nominal/EleTriggerTF1_MC_Negative.root");
  }
 
  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  

  vector<TString> fnamev;  // file name per input file
  vector<TString> labelv;  // TLegend label per input file
  vector<Int_t>   colorv;  // plot color per input file
  vector<Int_t>   linev;   // plot line style per input file

  //
  // parse .conf file
  //
  ifstream ifs;
  ifs.open(conf.Data());
  assert(ifs.is_open());
  string line;
  while(getline(ifs,line)) {
    if(line[0]=='#') continue;
    
    string fname;
    Int_t color, linesty;
    stringstream ss(line);
    ss >> fname >> color >> linesty;
    string label = line.substr(line.find('@')+1);
    fnamev.push_back(fname);
    labelv.push_back(label);
    colorv.push_back(color);
    linev.push_back(linesty);
  }
  ifs.close();

  // Create output directory
  gSystem->mkdir(outputDir,kTRUE);
  
  //
  // Get efficiency
  //
  TFile *dataHLTEffFile = new TFile(dataHLTEffName);
  CEffUser2D dataHLTEff;
  TH2D *hHLTErr=0, *hHLTErrB=0, *hHLTErrE=0;
  if(dataHLTEffName) {
    dataHLTEff.loadEff((TH2D*)dataHLTEffFile->Get("hEffEtaPt"),
                       (TH2D*)dataHLTEffFile->Get("hErrlEtaPt"),
                       (TH2D*)dataHLTEffFile->Get("hErrhEtaPt"));
    
    TH2D* h =(TH2D*)dataHLTEffFile->Get("hEffEtaPt");
    hHLTErr  = new TH2D("hHLTErr", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                      h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
    hHLTErrB = new TH2D("hHLTErrB","",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                      h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
    hHLTErrE = new TH2D("hHLTErrE","",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                      h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  }
  
  TFile *zeeHLTEffFile = new TFile(zeeHLTEffName);
  CEffUser2D zeeHLTEff;
  if(zeeHLTEffName) {
    zeeHLTEff.loadEff((TH2D*)zeeHLTEffFile->Get("hEffEtaPt"),
                      (TH2D*)zeeHLTEffFile->Get("hErrlEtaPt"),
                      (TH2D*)zeeHLTEffFile->Get("hErrhEtaPt"));
  }
  
  TFile *dataGsfSelEffFile = new TFile(dataGsfSelEffName);
  CEffUser2D dataGsfSelEff;
  TH2D *hGsfSelErr=0, *hGsfSelErrB=0, *hGsfSelErrE=0;
  if(dataGsfSelEffName) {
    dataGsfSelEff.loadEff((TH2D*)dataGsfSelEffFile->Get("hEffEtaPt"),
                       (TH2D*)dataGsfSelEffFile->Get("hErrlEtaPt"),
                       (TH2D*)dataGsfSelEffFile->Get("hErrhEtaPt"));
    
    TH2D* h =(TH2D*)dataGsfSelEffFile->Get("hEffEtaPt");
    hGsfSelErr  = new TH2D("hGsfSelErr", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                      h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
    hGsfSelErrB = new TH2D("hGsfSelErrB","",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                      h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
    hGsfSelErrE = new TH2D("hGsfSelErrE","",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                      h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  }
  
  TFile *zeeGsfSelEffFile = new TFile(zeeGsfSelEffName);
  CEffUser2D zeeGsfSelEff;
  if(zeeGsfSelEffName) {
    zeeGsfSelEff.loadEff((TH2D*)zeeGsfSelEffFile->Get("hEffEtaPt"),
                      (TH2D*)zeeGsfSelEffFile->Get("hErrlEtaPt"),
                      (TH2D*)zeeGsfSelEffFile->Get("hErrhEtaPt"));
  }
  
  // Data structures to store info from TTrees
  baconhep::TEventInfo    *info = new baconhep::TEventInfo();
  baconhep::TGenEventInfo *gen  = new baconhep::TGenEventInfo();
  TClonesArray *electronArr = new TClonesArray("baconhep::TElectron");
  TClonesArray *genPartArr  = new TClonesArray("baconhep::TGenParticle");
  TClonesArray *vertexArr  = new TClonesArray("baconhep::TVertex");
  
  TFile *infile=0;
  TTree *eventTree=0;

  // Variables to store acceptances and uncertainties (per input file)
  vector<Double_t> nEvtsv, nSelv, nSelBv, nSelEv;
  vector<Double_t> accv, accBv, accEv;
  vector<Double_t> accErrv, accErrBv, accErrEv;
  vector<Double_t> nSelCorrv, nSelBCorrv, nSelECorrv;
  vector<Double_t> nSelCorrVarv, nSelBCorrVarv, nSelECorrVarv;
  vector<Double_t> accCorrv, accBCorrv, accECorrv;
  vector<Double_t> accErrCorrv, accErrBCorrv, accErrECorrv;

  const baconhep::TTrigger triggerMenu("../../BaconAna/DataFormats/data/HLT_50nsGRun");
 
  // loop through files
  //
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {  

    // Read input file and get the TTrees
    cout << "Processing " << fnamev[ifile] << " ..." << endl;
    infile = TFile::Open(fnamev[ifile]); 
    assert(infile);
  
    eventTree = (TTree*)infile->Get("Events"); assert(eventTree);  
    eventTree->SetBranchAddress("Info",             &info); TBranch *infoBr     = eventTree->GetBranch("Info");
    eventTree->SetBranchAddress("GenEvtInfo",        &gen); TBranch *genBr      = eventTree->GetBranch("GenEvtInfo");
    eventTree->SetBranchAddress("GenParticle",&genPartArr); TBranch *genPartBr  = eventTree->GetBranch("GenParticle");
    eventTree->SetBranchAddress("Electron",  &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron");
    eventTree->SetBranchAddress("PV",   &vertexArr); TBranch *vertexBr = eventTree->GetBranch("PV");

    nEvtsv.push_back(0);
    nSelv.push_back(0);
    nSelBv.push_back(0);
    nSelEv.push_back(0);
    nSelCorrv.push_back(0);
    nSelBCorrv.push_back(0);
    nSelECorrv.push_back(0);
    nSelCorrVarv.push_back(0);
    nSelBCorrVarv.push_back(0);
    nSelECorrVarv.push_back(0);
    
    for(Int_t iy=0; iy<=hHLTErr->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hHLTErr->GetNbinsX(); ix++) {
        hHLTErr ->SetBinContent(ix,iy,0);
        hHLTErrB->SetBinContent(ix,iy,0);
        hHLTErrE->SetBinContent(ix,iy,0);
      }
    }
    for(Int_t iy=0; iy<=hGsfSelErr->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hGsfSelErr->GetNbinsX(); ix++) {
        hGsfSelErr ->SetBinContent(ix,iy,0);
        hGsfSelErrB->SetBinContent(ix,iy,0);
        hGsfSelErrE->SetBinContent(ix,iy,0);
      }
    }

    //
    // loop over events
    //
    for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
//      if(ientry==10000) break;
      infoBr->GetEntry(ientry);
      genBr->GetEntry(ientry);      
      genPartArr->Clear(); genPartBr->GetEntry(ientry);
  
      if (charge==-1 && toolbox::flavor(genPartArr, -BOSON_ID)!=LEPTON_ID) continue;
      if (charge==1 && toolbox::flavor(genPartArr, BOSON_ID)!=-LEPTON_ID) continue;
      if (charge==0 && fabs(toolbox::flavor(genPartArr, BOSON_ID))!=LEPTON_ID) continue;
    
      vertexArr->Clear();
      vertexBr->GetEntry(ientry);
      double npv  = vertexArr->GetEntries();
      Double_t weight=gen->weight;
      if(doPU>0) weight*=h_rw->GetBinContent(h_rw->FindBin(info->nPUmean));

      nEvtsv[ifile]+=weight;
      
      // trigger requirement                
      if (!isEleTrigger(triggerMenu, info->triggerBits, kFALSE)) continue;
      
      // good vertex requirement
      if(!(info->hasGoodPV)) continue;
      
      electronArr->Clear();
      electronBr->GetEntry(ientry);
      Int_t nLooseLep=0;
      const baconhep::TElectron *goodEle=0;
      TLorentzVector vEle(0,0,0,0);
      TLorentzVector vElefinal(0,0,0,0);
      Bool_t passSel=kFALSE;
     
      for(Int_t i=0; i<electronArr->GetEntriesFast(); i++) {
        const baconhep::TElectron *ele = (baconhep::TElectron*)((*electronArr)[i]);
	vEle.SetPtEtaPhiM(ele->pt, ele->eta, ele->phi, ELE_MASS);
	
	//double ele_pt = gRandom->Gaus(ele->scEt*getEleScaleCorr(ele->scEta,0), getEleResCorr(ele->scEta,0));
        //double ele_pt = gRandom->Gaus(ele->scEt*getEleScaleCorr(ele->scEta,0), getEleResCorr(ele->scEta,0));

        // check ECAL gap
//        if(fabs(ele->scEta)>=ETA_BARREL && fabs(ele->scEta)<=ETA_ENDCAP) continue;
	if(fabs(vEle.Eta())>=ECAL_GAP_LOW && fabs(vEle.Eta())<=ECAL_GAP_HIGH) continue;
        if(doScaleCorr && (ele->r9 < 1.)){
            float eleSmear = 0.;

            float eleAbsEta   = fabs(vEle.Eta());
            float eleEt       = vEle.E() / cosh(eleAbsEta);
            bool  eleisBarrel = eleAbsEta < 1.4442;

            float eleR9Prime = ele->r9; // r9 corrections MC only
            if(eleisBarrel){
                      eleR9Prime = gR9EB->Eval(ele->r9);}
            else {
                      eleR9Prime = gR9EE->Eval(ele->r9);
            }

            double eleRamdom = gRandom->Gaus(0,1);
            eleSmear = eleCorr.getSmearingSigma(info->runNum, eleisBarrel, eleR9Prime, eleAbsEta, eleEt, 0., 0.);
            float eleSmearEP = eleCorr.getSmearingSigma(info->runNum, eleisBarrel, eleR9Prime, eleAbsEta, eleEt, 1., 0.);
            float eleSmearEM = eleCorr.getSmearingSigma(info->runNum, eleisBarrel, eleR9Prime, eleAbsEta, eleEt, -1., 0.);

            if(sigma==0){
              (vEle) *= 1. + eleSmear * eleRamdom;
            }else if(sigma==1){
              (vEle) *= 1. + eleSmearEP * eleRamdom;
            }else if(sigma==-1){
              (vEle) *= 1.  + eleSmearEM * eleRamdom;
            }
        }

        
//        if(fabs(ele->scEta) > VETO_ETA) continue;             // loose lepton |eta| cut
//        if(ele->scEt < VETO_PT)  continue;             // loose lepton pT cut
//        if(passEleLooseID(ele,info->rhoIso)) nLooseLep++;     // loose lepton selection
        if(fabs(vEle.Eta())    > VETO_ETA) continue;
        if(vEle.Pt()           < VETO_PT)  continue;
        if(passEleLooseID(ele, vEle, info->rhoIso)) nLooseLep++;

        if(nLooseLep>1) {  // extra lepton veto
          passSel=kFALSE;
          break;
        }

//        if(fabs(ele->scEta) > ETA_CUT && fabs(ele->eta) > ETA_CUT)       continue;  // lepton |eta| cut
//        if(ele->pt < PT_CUT && ele->scEt < PT_CUT)  	     continue;  // lepton pT cut
//        if(!passEleID(ele,info->rhoIso))     continue;  // lepton selection
        if(vEle.Pt()           < PT_CUT)     continue;  // lepton pT cut
        if(fabs(vEle.Eta())    > ETA_CUT)    continue;  // lepton |eta| cut
        if(!passEleID(ele, vEle, info->rhoIso))     continue;  // lepton selection

	if(!isEleTriggerObj(triggerMenu, ele->hltMatchBits, kFALSE, kFALSE)) continue;
        //if(!(ele->hltMatchBits[trigObjHLT])) continue;  // check trigger matching

	if(charge!=0 && ele->q!=charge) continue;  // check charge (if necessary)
        
	passSel=kTRUE;
        goodEle = ele;  
	vElefinal = vEle;
      }
      
      if(passSel) {
        
	/******** We have a W candidate! HURRAY! ********/
        Bool_t isBarrel = (fabs(vElefinal.Eta())<ETA_BARREL) ? kTRUE : kFALSE;

        Double_t corr=1;
        if(dataHLTEffFile && zeeHLTEffFile) {
//          Double_t effdata = dataHLTEff.getEff(vElefinal.Eta(), vElefinal.Pt());
//          Double_t effmc   = zeeHLTEff.getEff(vElefinal.Eta(), vElefinal.Pt());

	  char funcname[20];
	  sprintf(funcname, "fitfcn_%d", getEtaBinLabel(vElefinal.Eta()));
	  TF1 *fdt = (TF1*)f_hlt_data->Get(funcname);
	  TF1 *fmc = (TF1*)f_hlt_mc  ->Get(funcname);
	  Double_t effdata = fdt->Eval(TMath::Min(vElefinal.Pt(),119.0));
	  Double_t effmc   = fmc->Eval(TMath::Min(vElefinal.Pt(),119.0));
	  delete fdt;
	  delete fmc;

	  corr *= effdata/effmc;
        }
        if(dataGsfSelEffFile && zeeGsfSelEffFile) {
          Double_t effdata = dataGsfSelEff.getEff(vElefinal.Eta(), vElefinal.Pt());
          Double_t effmc   = zeeGsfSelEff.getEff(vElefinal.Eta(), vElefinal.Pt());
          corr *= effdata/effmc;
        }

        if(dataHLTEffFile && zeeHLTEffFile) {
          Double_t effdata = dataHLTEff.getEff(vElefinal.Eta(), vElefinal.Pt());
          Double_t effmc   = zeeHLTEff.getEff(vElefinal.Eta(), vElefinal.Pt());
          Double_t errdata = TMath::Max(dataHLTEff.getErrLow(vElefinal.Eta(), vElefinal.Pt()),dataHLTEff.getErrHigh(vElefinal.Eta(), vElefinal.Pt()));
          Double_t errmc   = TMath::Max(zeeHLTEff.getErrLow(vElefinal.Eta(), vElefinal.Pt()), zeeHLTEff.getErrHigh(vElefinal.Eta(), vElefinal.Pt()));
          Double_t err     = corr*sqrt(errdata*errdata/effdata/effdata+errmc*errmc/effmc/effmc);
          hHLTErr->Fill(vElefinal.Eta(),vElefinal.Pt(),err);
          if(isBarrel) hHLTErrB->Fill(vElefinal.Eta(),vElefinal.Pt(),err);
          else         hHLTErrE->Fill(vElefinal.Eta(),vElefinal.Pt(),err);
        }
        if(dataGsfSelEffFile && zeeGsfSelEffFile) {
          Double_t effdata = dataGsfSelEff.getEff(vElefinal.Eta(), vElefinal.Pt());
          Double_t effmc   = zeeGsfSelEff.getEff(vElefinal.Eta(), vElefinal.Pt());
          Double_t errdata = TMath::Max(dataGsfSelEff.getErrLow(vElefinal.Eta(), vElefinal.Pt()),dataGsfSelEff.getErrHigh(vElefinal.Eta(), vElefinal.Pt()));
          Double_t errmc   = TMath::Max(zeeGsfSelEff.getErrLow(vElefinal.Eta(), vElefinal.Pt()), zeeGsfSelEff.getErrHigh(vElefinal.Eta(), vElefinal.Pt()));
          Double_t err     = corr*sqrt(errdata*errdata/effdata/effdata+errmc*errmc/effmc/effmc);
          hGsfSelErr->Fill(vElefinal.Eta(),vElefinal.Pt(),err);
          if(isBarrel) hGsfSelErrB->Fill(vElefinal.Eta(),vElefinal.Pt(),err);
          else         hGsfSelErrE->Fill(vElefinal.Eta(),vElefinal.Pt(),err);
        }
        
	nSelv[ifile]+=weight;
	nSelCorrv[ifile]+=weight*corr;
	nSelCorrVarv[ifile]+=weight*weight*corr*corr;

  	if(isBarrel) { 
	  nSelBv[ifile]+=weight;
	  nSelBCorrv[ifile]+=weight*corr;
	  nSelBCorrVarv[ifile]+=weight*weight*corr*corr;
	  	
	} else { 
	  nSelEv[ifile]+=weight;
	  nSelECorrv[ifile]+=weight*corr;
	  nSelECorrVarv[ifile]+=weight*weight*corr*corr;
	}
      }
    }
    
    Double_t var=0, varB=0, varE=0;
    for(Int_t iy=0; iy<=hHLTErr->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hHLTErr->GetNbinsX(); ix++) {
        Double_t err;
	err=hHLTErr->GetBinContent(ix,iy);  var+=err*err;
        err=hHLTErrB->GetBinContent(ix,iy); varB+=err*err;
        err=hHLTErrE->GetBinContent(ix,iy); varE+=err*err;
      }
    }

    for(Int_t iy=0; iy<=hGsfSelErr->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hGsfSelErr->GetNbinsX(); ix++) {
        Double_t err;
	err=hGsfSelErr->GetBinContent(ix,iy);  var+=err*err;
	err=hGsfSelErrB->GetBinContent(ix,iy); varB+=err*err;
	err=hGsfSelErrE->GetBinContent(ix,iy); varE+=err*err;
      }
    }

    nSelCorrVarv[ifile]+=var;
    nSelBCorrVarv[ifile]+=varB;
    nSelECorrVarv[ifile]+=varE;
    
    // compute acceptances
    accv.push_back(nSelv[ifile]/nEvtsv[ifile]);   accErrv.push_back(sqrt(accv[ifile]*(1.+accv[ifile])/nEvtsv[ifile]));
    accBv.push_back(nSelBv[ifile]/nEvtsv[ifile]); accErrBv.push_back(sqrt(accBv[ifile]*(1.+accBv[ifile])/nEvtsv[ifile]));
    accEv.push_back(nSelEv[ifile]/nEvtsv[ifile]); accErrEv.push_back(sqrt(accEv[ifile]*(1.+accEv[ifile])/nEvtsv[ifile]));
    
    accCorrv.push_back(nSelCorrv[ifile]/nEvtsv[ifile]);   accErrCorrv.push_back(accCorrv[ifile]*sqrt(nSelCorrVarv[ifile]/nSelCorrv[ifile]/nSelCorrv[ifile] + 1./nEvtsv[ifile]));
    accBCorrv.push_back(nSelBCorrv[ifile]/nEvtsv[ifile]); accErrBCorrv.push_back(accBCorrv[ifile]*sqrt(nSelBCorrVarv[ifile]/nSelBCorrv[ifile]/nSelBCorrv[ifile] + 1./nEvtsv[ifile]));
    accECorrv.push_back(nSelECorrv[ifile]/nEvtsv[ifile]); accErrECorrv.push_back(accECorrv[ifile]*sqrt(nSelECorrVarv[ifile]/nSelECorrv[ifile]/nSelECorrv[ifile] + 1./nEvtsv[ifile]));
    
    delete infile;
    infile=0, eventTree=0;  
  }
  delete info;
  delete gen;
  delete electronArr;
  
    
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
   
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  if(charge== 0) cout << " W -> e nu"  << endl;
  if(charge==-1) cout << " W- -> e nu" << endl;
  if(charge== 1) cout << " W+ -> e nu" << endl;
  cout << "  pT > " << PT_CUT << endl;
  cout << "  |eta| < " << ETA_CUT << endl;
  cout << "  Barrel definition: |eta| < " << ETA_BARREL << endl;
  cout << "  Endcap definition: |eta| > " << ETA_ENDCAP << endl;
  cout << endl;
  
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
    cout << "   ================================================" << endl;
    cout << "    Label: " << labelv[ifile] << endl;
    cout << "     File: " << fnamev[ifile] << endl;
    cout << endl;
    cout << "    *** Acceptance ***" << endl;
    cout << "     barrel: " << setw(12) << nSelBv[ifile] << " / " << nEvtsv[ifile] << " = " << accBv[ifile] << " +/- " << accErrBv[ifile];
    cout << "  ==eff corr==> " << accBCorrv[ifile] << " +/- " << accErrBCorrv[ifile] << endl;
    cout << "     endcap: " << setw(12) << nSelEv[ifile] << " / " << nEvtsv[ifile] << " = " << accEv[ifile] << " +/- " << accErrEv[ifile];
    cout << "  ==eff corr==> " << accECorrv[ifile] << " +/- " << accErrECorrv[ifile] << endl;
    cout << "      total: " << setw(12) << nSelv[ifile]  << " / " << nEvtsv[ifile] << " = " << accv[ifile]  << " +/- " << accErrv[ifile];
    cout << "  ==eff corr==> " << accCorrv[ifile]  << " +/- " << accErrCorrv[ifile] << endl;
    cout << endl;
  }
  
  char txtfname[100];
  sprintf(txtfname,"%s/sel.txt",outputDir.Data());
  ofstream txtfile;
  txtfile.open(txtfname);
  txtfile << "*" << endl;
  txtfile << "* SUMMARY" << endl;
  txtfile << "*--------------------------------------------------" << endl;
  if(charge== 0) txtfile << " W -> e nu"  << endl;
  if(charge==-1) txtfile << " W- -> e nu" << endl;
  if(charge== 1) txtfile << " W+ -> e nu" << endl;
  txtfile << "  pT > " << PT_CUT << endl;
  txtfile << "  |eta| < " << ETA_CUT << endl;
  txtfile << "  Barrel definition: |eta| < " << ETA_BARREL << endl;
  txtfile << "  Endcap definition: |eta| > " << ETA_ENDCAP << endl;
  txtfile << endl;
  
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
    txtfile << "   ================================================" << endl;
    txtfile << "    Label: " << labelv[ifile] << endl;
    txtfile << "     File: " << fnamev[ifile] << endl;
    txtfile << endl;
    txtfile << "    *** Acceptance ***" << endl;
    txtfile << "     barrel: " << setw(12) << nSelBv[ifile] << " / " << nEvtsv[ifile] << " = " << accBv[ifile] << " +/- " << accErrBv[ifile];
    txtfile << "  ==eff corr==> " << accBCorrv[ifile] << " +/- " << accErrBCorrv[ifile] << endl;
    txtfile << "     endcap: " << setw(12) << nSelEv[ifile] << " / " << nEvtsv[ifile] << " = " << accEv[ifile] << " +/- " << accErrEv[ifile];
    txtfile << "  ==eff corr==> " << accECorrv[ifile] << " +/- " << accErrECorrv[ifile] << endl;
    txtfile << "      total: " << setw(12) << nSelv[ifile]  << " / " << nEvtsv[ifile] << " = " << accv[ifile]  << " +/- " << accErrv[ifile];
    txtfile << "  ==eff corr==> " << accCorrv[ifile]  << " +/- " << accErrCorrv[ifile] << endl;
    txtfile << endl;
  }
  txtfile.close();  
  
  cout << endl;
  cout << "  <> Output saved in " << outputDir << "/" << endl;    
  cout << endl;  
      
  gBenchmark->Show("computeAccSelWe"); 
}
Esempio n. 19
0
void selectAntiWm(const TString conf="wm.conf", // input file
              const TString outputDir="."       // output directory
) {
  gBenchmark->Start("selectAntiWm");

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //============================================================================================================== 

  const Double_t PT_CUT    = 25;
  const Double_t ETA_CUT   = 2.4;
  const Double_t MUON_MASS = 0.105658369;

  const Double_t VETO_PT   = 10;
  const Double_t VETO_ETA  = 2.4;

  const Int_t BOSON_ID  = 24;
  const Int_t LEPTON_ID = 13;

  // load trigger menu
  const baconhep::TTrigger triggerMenu("../../BaconAna/DataFormats/data/HLT_50nsGRun");

  // load pileup reweighting file
  TFile *f_rw = TFile::Open("../Tools/pileup_weights_2015B.root", "read");
  TH1D *h_rw = (TH1D*) f_rw->Get("npv_rw");

  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  

  vector<TString>  snamev;      // sample name (for output files)  
  vector<CSample*> samplev;     // data/MC samples

  //
  // parse .conf file
  //
  confParse(conf, snamev, samplev);
  const Bool_t hasData = (samplev[0]->fnamev.size()>0);

  // Create output directory
  gSystem->mkdir(outputDir,kTRUE);
  const TString ntupDir = outputDir + TString("/ntuples");
  gSystem->mkdir(ntupDir,kTRUE);
  
  //
  // Declare output ntuple variables
  //
  UInt_t  runNum, lumiSec, evtNum;
  UInt_t  npv, npu;
  UInt_t  id_1, id_2;
  Double_t x_1, x_2, xPDF_1, xPDF_2;
  Double_t scalePDF, weightPDF;
  TLorentzVector *genV=0, *genLep=0;
  Float_t genVPt, genVPhi, genVy, genVMass;
  Float_t genLepPt, genLepPhi;
  Float_t scale1fb, puWeight;
  Float_t met, metPhi, sumEt, mt, u1, u2;
  Float_t tkMet, tkMetPhi, tkSumEt, tkMt, tkU1, tkU2;
  Float_t mvaMet, mvaMetPhi, mvaSumEt, mvaMt, mvaU1, mvaU2;
  Int_t   q;
  TLorentzVector *lep=0;
  ///// muon specific /////
  Float_t trkIso, emIso, hadIso;
  Float_t pfChIso, pfGamIso, pfNeuIso, pfCombIso;
  Float_t d0, dz;
  Float_t muNchi2;
  UInt_t nPixHits, nTkLayers, nValidHits, nMatch, typeBits;
  
  // Data structures to store info from TTrees
  baconhep::TEventInfo *info  = new baconhep::TEventInfo();
  baconhep::TGenEventInfo *gen  = new baconhep::TGenEventInfo();
  TClonesArray *genPartArr = new TClonesArray("baconhep::TGenParticle");
  TClonesArray *muonArr    = new TClonesArray("baconhep::TMuon");
  TClonesArray *vertexArr  = new TClonesArray("baconhep::TVertex");
  
  TFile *infile=0;
  TTree *eventTree=0;
  
  //
  // loop over samples
  //  
  for(UInt_t isam=0; isam<samplev.size(); isam++) {
    
    // Assume data sample is first sample in .conf file
    // If sample is empty (i.e. contains no ntuple files), skip to next sample
    Bool_t isData=kFALSE;
    if(isam==0 && !hasData) continue;
    else if (isam==0) isData=kTRUE;
    
    // Assume signal sample is given name "wm"
    Bool_t isSignal = (snamev[isam].CompareTo("wm",TString::kIgnoreCase)==0);
    // flag to reject W->mnu events when selecting wrong-flavor background events
    Bool_t isWrongFlavor = (snamev[isam].CompareTo("wx",TString::kIgnoreCase)==0);  
    
    CSample* samp = samplev[isam];
  
    //
    // Set up output ntuple
    //
    TString outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.root");
    TFile *outFile = new TFile(outfilename,"RECREATE"); 
    TTree *outTree = new TTree("Events","Events");

    outTree->Branch("runNum",     &runNum,     "runNum/i");     // event run number
    outTree->Branch("lumiSec",    &lumiSec,    "lumiSec/i");    // event lumi section
    outTree->Branch("evtNum",     &evtNum,     "evtNum/i");     // event number
    outTree->Branch("npv",        &npv,        "npv/i");        // number of primary vertices
    outTree->Branch("npu",        &npu,        "npu/i");        // number of in-time PU events (MC)
    outTree->Branch("id_1",       &id_1,       "id_1/i");       // PDF info -- parton ID for parton 1
    outTree->Branch("id_2",       &id_2,       "id_2/i");       // PDF info -- parton ID for parton 2
    outTree->Branch("x_1",        &x_1,        "x_1/d");        // PDF info -- x for parton 1
    outTree->Branch("x_2",        &x_2,        "x_2/d");        // PDF info -- x for parton 2
    outTree->Branch("xPDF_1",     &xPDF_1,     "xPDF_1/d");     // PDF info -- x*F for parton 1
    outTree->Branch("xPDF_2",     &xPDF_2,     "xPDF_2/d");     // PDF info -- x*F for parton 2
    outTree->Branch("scalePDF",   &scalePDF,   "scalePDF/d");   // PDF info -- energy scale of parton interaction
    outTree->Branch("weightPDF",  &weightPDF,  "weightPDF/d");  // PDF info -- PDF weight
    outTree->Branch("genV",       "TLorentzVector", &genV);     // GEN boson 4-vector (signal MC)
    outTree->Branch("genLep",     "TLorentzVector", &genLep);   // GEN lepton 4-vector (signal MC)
    outTree->Branch("genVPt",     &genVPt,     "genVPt/F");     // GEN boson pT (signal MC)
    outTree->Branch("genVPhi",    &genVPhi,    "genVPhi/F");    // GEN boson phi (signal MC)
    outTree->Branch("genVy",      &genVy,      "genVy/F");      // GEN boson rapidity (signal MC)
    outTree->Branch("genVMass",   &genVMass,   "genVMass/F");   // GEN boson mass (signal MC)
    outTree->Branch("genLepPt",   &genLepPt,   "genLepPt/F");   // GEN lepton pT (signal MC)
    outTree->Branch("genLepPhi",  &genLepPhi,  "genLepPhi/F");  // GEN lepton phi (signal MC)
    outTree->Branch("scale1fb",   &scale1fb,   "scale1fb/F");   // event weight per 1/fb (MC)
    outTree->Branch("puWeight",   &puWeight,   "puWeight/F");    // scale factor for pileup reweighting (MC)
    outTree->Branch("met",        &met,        "met/F");        // MET
    outTree->Branch("metPhi",     &metPhi,     "metPhi/F");     // phi(MET)
    outTree->Branch("sumEt",      &sumEt,      "sumEt/F");      // Sum ET
    outTree->Branch("mt",         &mt,         "mt/F");         // transverse mass
    outTree->Branch("u1",         &u1,         "u1/F");         // parallel component of recoil
    outTree->Branch("u2",         &u2,         "u2/F");         // perpendicular component of recoil
    outTree->Branch("tkMet",      &tkMet,      "tkMet/F");      // MET (track MET)
    outTree->Branch("tkMetPhi",   &tkMetPhi,   "tkMetPhi/F");   // phi(MET) (track MET)
    outTree->Branch("tkSumEt",    &tkSumEt,    "tkSumEt/F");    // Sum ET (track MET)
    outTree->Branch("tkMt",       &tkMt,       "tkMt/F");       // transverse mass (track MET)
    outTree->Branch("tkU1",       &tkU1,       "tkU1/F");       // parallel component of recoil (track MET)
    outTree->Branch("tkU2",       &tkU2,       "tkU2/F");       // perpendicular component of recoil (track MET)
    outTree->Branch("mvaMet",     &mvaMet,     "mvaMet/F");     // MVA MET
    outTree->Branch("mvaMetPhi",  &mvaMetPhi,  "mvaMetPhi/F");  // phi(MVA MET)
    outTree->Branch("mvaSumEt",   &mvaSumEt,   "mvaSumEt/F");   // Sum ET (MVA MET)
    outTree->Branch("mvaMt",      &mvaMt,      "mvaMt/F");      // transverse mass (MVA MET)
    outTree->Branch("mvaU1",      &mvaU1,      "mvaU1/F");      // parallel component of recoil (mva MET)
    outTree->Branch("mvaU2",      &mvaU2,      "mvaU2/F");      // perpendicular component of recoil (mva MET)
    outTree->Branch("q",          &q,          "q/I");          // lepton charge
    outTree->Branch("lep",        "TLorentzVector", &lep);      // lepton 4-vector
    ///// muon specific /////
    outTree->Branch("trkIso",     &trkIso,     "trkIso/F");     // track isolation of lepton
    outTree->Branch("emIso",      &emIso,      "emIso/F");      // ECAL isolation of lepton
    outTree->Branch("hadIso",     &hadIso,     "hadIso/F");     // HCAL isolation of lepton
    outTree->Branch("pfChIso",    &pfChIso,    "pfChIso/F");    // PF charged hadron isolation of lepton
    outTree->Branch("pfGamIso",   &pfGamIso,   "pfGamIso/F");   // PF photon isolation of lepton
    outTree->Branch("pfNeuIso",   &pfNeuIso,   "pfNeuIso/F");   // PF neutral hadron isolation of lepton
    outTree->Branch("pfCombIso",  &pfCombIso,  "pfCombIso/F");  // PF combined isolation of lepton
    outTree->Branch("d0",         &d0,         "d0/F");         // transverse impact parameter of lepton
    outTree->Branch("dz",         &dz,         "dz/F");         // longitudinal impact parameter of lepton
    outTree->Branch("muNchi2",    &muNchi2,    "muNchi2/F");    // muon fit normalized chi^2 of lepton
    outTree->Branch("nPixHits",   &nPixHits,   "nPixHits/i");   // number of pixel hits of muon
    outTree->Branch("nTkLayers",  &nTkLayers,  "nTkLayers/i");  // number of tracker layers of muon
    outTree->Branch("nMatch",     &nMatch,     "nMatch/i");     // number of matched segments of muon	 
    outTree->Branch("nValidHits", &nValidHits, "nValidHits/i"); // number of valid muon hits of muon 
    outTree->Branch("typeBits",   &typeBits,   "typeBits/i");   // number of valid muon hits of muon 
    
    //
    // loop through files
    //
    const UInt_t nfiles = samp->fnamev.size();
    for(UInt_t ifile=0; ifile<nfiles; ifile++) {  

      // Read input file and get the TTrees
      cout << "Processing " << samp->fnamev[ifile] << " [xsec = " << samp->xsecv[ifile] << " pb] ... "; cout.flush();
      infile = TFile::Open(samp->fnamev[ifile]); 
      assert(infile);
      
      Bool_t hasJSON = kFALSE;
      baconhep::RunLumiRangeMap rlrm;
      if(samp->jsonv[ifile].CompareTo("NONE")!=0) { 
	hasJSON = kTRUE;
	rlrm.addJSONFile(samp->jsonv[ifile].Data()); 
      }

      eventTree = (TTree*)infile->Get("Events");
      assert(eventTree);
      eventTree->SetBranchAddress("Info", &info);    TBranch *infoBr = eventTree->GetBranch("Info");
      eventTree->SetBranchAddress("Muon", &muonArr); TBranch *muonBr = eventTree->GetBranch("Muon");
      eventTree->SetBranchAddress("PV",   &vertexArr); TBranch *vertexBr = eventTree->GetBranch("PV");
      Bool_t hasGen = eventTree->GetBranchStatus("GenEvtInfo");
      TBranch *genBr=0, *genPartBr=0;
      if(hasGen) {
        eventTree->SetBranchAddress("GenEvtInfo", &gen); genBr = eventTree->GetBranch("GenEvtInfo");
        eventTree->SetBranchAddress("GenParticle",&genPartArr); genPartBr = eventTree->GetBranch("GenParticle");
      }
    
      // Compute MC event weight per 1/fb
      const Double_t xsec = samp->xsecv[ifile];
      Double_t totalWeight=0;

      if (hasGen) {
	TH1D *hall = new TH1D("hall", "", 1,0,1);
	eventTree->Draw("0.5>>hall", "GenEvtInfo->weight");
	totalWeight=hall->Integral();
	delete hall;
	hall=0;
      }

      //
      // loop over events
      //
      Double_t nsel=0, nselvar=0;
      for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
        infoBr->GetEntry(ientry);

	if(ientry%1000000==0) cout << "Processing event " << ientry << ". " << (double)ientry/(double)eventTree->GetEntries()*100 << " percent done with this file." << endl;

        Double_t weight=1;
        if(xsec>0 && totalWeight>0) weight = xsec/totalWeight;
	if(hasGen) {
          genPartArr->Clear();
          genBr->GetEntry(ientry);
          genPartBr->GetEntry(ientry);
	  weight*=gen->weight;
        }

        // veto w -> xv decays for signal and w -> mv for bacground samples (needed for inclusive WToLNu sample)
        if (isWrongFlavor && hasGen && fabs(toolbox::flavor(genPartArr, BOSON_ID))==LEPTON_ID) continue;
	else if (isSignal && hasGen && fabs(toolbox::flavor(genPartArr, BOSON_ID))!=LEPTON_ID) continue;
        
	// check for certified lumi (if applicable)
        baconhep::RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec);      
        if(hasJSON && !rlrm.hasRunLumi(rl)) continue;  

        // trigger requirement               
	if (!isMuonTrigger(triggerMenu, info->triggerBits)) continue;
      
        // good vertex requirement
        if(!(info->hasGoodPV)) continue;

        //
	// SELECTION PROCEDURE:
	//  (1) Look for 1 good muon matched to trigger
	//  (2) Reject event if another muon is present passing looser cuts
	//
	muonArr->Clear();
        muonBr->GetEntry(ientry);

	Int_t nLooseLep=0;
	const baconhep::TMuon *goodMuon=0;
	Bool_t passSel=kFALSE;

        for(Int_t i=0; i<muonArr->GetEntriesFast(); i++) {
          const baconhep::TMuon *mu = (baconhep::TMuon*)((*muonArr)[i]);

          if(fabs(mu->eta) > VETO_PT)  continue; // loose lepton |eta| cut
          if(mu->pt        < VETO_ETA) continue; // loose lepton pT cut
//          if(passMuonLooseID(mu)) nLooseLep++; // loose lepton selection
          if(nLooseLep>1) {  // extra lepton veto
            passSel=kFALSE;
            break;
          }
          
          if(fabs(mu->eta) > ETA_CUT)         continue; // lepton |eta| cut
          if(mu->pt < PT_CUT)                 continue; // lepton pT cut   
          if(!passAntiMuonID(mu))             continue; // lepton anti-selection
          if(!isMuonTriggerObj(triggerMenu, mu->hltMatchBits, kFALSE)) continue;
	  
	  passSel=kTRUE;
	  goodMuon = mu;
	}

	if(passSel) {	  
	  /******** We have a W candidate! HURRAY! ********/
	  nsel+=weight;
          nselvar+=weight*weight;
	  
	  TLorentzVector vLep; 
	  vLep.SetPtEtaPhiM(goodMuon->pt, goodMuon->eta, goodMuon->phi, MUON_MASS);

	  //
	  // Fill tree
	  //
	  runNum   = info->runNum;
	  lumiSec  = info->lumiSec;
	  evtNum   = info->evtNum;
	  
	  vertexArr->Clear();
	  vertexBr->GetEntry(ientry);

	  npv      = vertexArr->GetEntries();
	  npu	   = info->nPUmean;
	  genV      = new TLorentzVector(0,0,0,0);
          genLep    = new TLorentzVector(0,0,0,0);
	  genVPt    = -999;
          genVPhi   = -999;
          genVy     = -999;
          genVMass  = -999;
          u1        = -999;
          u2        = -999;
          tkU1      = -999;
          tkU2      = -999;
	  mvaU1     = -999;
          mvaU2     = -999;
          id_1      = -999;
          id_2      = -999;
          x_1       = -999;
          x_2       = -999;
          xPDF_1    = -999;
          xPDF_2    = -999;
          scalePDF  = -999;
          weightPDF = -999;

	  if(isSignal && hasGen) {
	    TLorentzVector *gvec=new TLorentzVector(0,0,0,0);
            TLorentzVector *glep1=new TLorentzVector(0,0,0,0);
            TLorentzVector *glep2=new TLorentzVector(0,0,0,0);
	    toolbox::fillGen(genPartArr, BOSON_ID, gvec, glep1, glep2,1);

            if (gvec && glep1) {
	      genV      = new TLorentzVector(0,0,0,0);
              genV->SetPtEtaPhiM(gvec->Pt(),gvec->Eta(),gvec->Phi(),gvec->M());
              genLep    = new TLorentzVector(0,0,0,0);
              genLep->SetPtEtaPhiM(glep1->Pt(),glep1->Eta(),glep1->Phi(),glep1->M());
              genVPt    = gvec->Pt();
              genVPhi   = gvec->Phi();
              genVy     = gvec->Rapidity();
              genVMass  = gvec->M();
              genLepPt  = glep1->Pt();
              genLepPhi = glep1->Phi();

	      TVector2 vWPt((genVPt)*cos(genVPhi),(genVPt)*sin(genVPhi));
	      TVector2 vLepPt(vLep.Px(),vLep.Py());
	      
	      TVector2 vMet((info->pfMETC)*cos(info->pfMETCphi), (info->pfMETC)*sin(info->pfMETCphi));
	      TVector2 vU = -1.0*(vMet+vLepPt);
	      u1 = ((vWPt.Px())*(vU.Px()) + (vWPt.Py())*(vU.Py()))/(genVPt);  // u1 = (pT . u)/|pT|
	      u2 = ((vWPt.Px())*(vU.Py()) - (vWPt.Py())*(vU.Px()))/(genVPt);  // u2 = (pT x u)/|pT|

	      TVector2 vTkMet((info->trkMET)*cos(info->trkMETphi), (info->trkMET)*sin(info->trkMETphi));
	      TVector2 vTkU = -1.0*(vTkMet+vLepPt);
	      tkU1 = ((vWPt.Px())*(vTkU.Px()) + (vWPt.Py())*(vTkU.Py()))/(genVPt);  // u1 = (pT . u)/|pT|
	      tkU2 = ((vWPt.Px())*(vTkU.Py()) - (vWPt.Py())*(vTkU.Px()))/(genVPt);  // u2 = (pT x u)/|pT|
	      
	      TVector2 vMvaMet((info->mvaMET)*cos(info->mvaMETphi), (info->mvaMET)*sin(info->mvaMETphi));
	      TVector2 vMvaU = -1.0*(vMvaMet+vLepPt);
	      mvaU1 = ((vWPt.Px())*(vMvaU.Px()) + (vWPt.Py())*(vMvaU.Py()))/(genVPt);  // u1 = (pT . u)/|pT|
	      mvaU2 = ((vWPt.Px())*(vMvaU.Py()) - (vWPt.Py())*(vMvaU.Px()))/(genVPt);  // u2 = (pT x u)/|pT|
          
            }
	    id_1      = gen->id_1;
            id_2      = gen->id_2;
            x_1       = gen->x_1;
            x_2       = gen->x_2;
            xPDF_1    = gen->xPDF_1;
            xPDF_2    = gen->xPDF_2;
            scalePDF  = gen->scalePDF;
            weightPDF = gen->weight;

	    delete gvec;
            delete glep1;
            delete glep2;
            gvec=0; glep1=0; glep2=0;
	  }
	  scale1fb = weight;
	  puWeight = h_rw->GetBinContent(info->nPUmean+1);
	  met	   = info->pfMETC;
	  metPhi   = info->pfMETCphi;
	  sumEt    = 0;
	  mt       = sqrt( 2.0 * (vLep.Pt()) * (info->pfMETC) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->pfMETCphi))) );
	  tkMet    = info->trkMET;
          tkMetPhi = info->trkMETphi;
          tkSumEt  = 0;
          tkMt     = sqrt( 2.0 * (vLep.Pt()) * (info->trkMET) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->trkMETphi))) );
	  mvaMet   = info->mvaMET;
          mvaMetPhi = info->mvaMETphi;
          mvaSumEt  = 0;
          mvaMt     = sqrt( 2.0 * (vLep.Pt()) * (info->mvaMET) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->mvaMETphi))) );
	  q        = goodMuon->q;
	  lep      = &vLep;
	  
	  ///// muon specific /////
	  trkIso     = goodMuon->trkIso;
          emIso      = goodMuon->ecalIso;
          hadIso     = goodMuon->hcalIso;
          pfChIso    = goodMuon->chHadIso;
          pfGamIso   = goodMuon->gammaIso;
          pfNeuIso   = goodMuon->neuHadIso;
          pfCombIso  = goodMuon->chHadIso + TMath::Max(goodMuon->neuHadIso + goodMuon->gammaIso -
						       0.5*(goodMuon->puIso),Double_t(0));
	  d0         = goodMuon->d0;
	  dz         = goodMuon->dz;
	  muNchi2    = goodMuon->muNchi2;
	  nPixHits   = goodMuon->nPixHits;
	  nTkLayers  = goodMuon->nTkLayers;
	  nMatch     = goodMuon->nMatchStn;
	  nValidHits = goodMuon->nValidHits;
	  typeBits   = goodMuon->typeBits;

	  outTree->Fill();
	  delete genV;
	  delete genLep;
	  genV=0, genLep=0, lep=0;
        }
      }
      delete infile;
      infile=0, eventTree=0;    

      cout << nsel  << " +/- " << sqrt(nselvar);
      if(isam!=0) cout << " per 1/fb";
      cout << endl;
    }
    outFile->Write();
    outFile->Close();
  }
  delete h_rw;
  delete f_rw;
  delete info;
  delete gen;
  delete genPartArr;
  delete muonArr;
  delete vertexArr;
      
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
   
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << " W -> mu nu" << endl;
  cout << "  pT > " << PT_CUT << endl;
  cout << "  |eta| < " << ETA_CUT << endl;
  cout << endl;
  
  cout << endl;
  cout << "  <> Output saved in " << outputDir << "/" << endl;    
  cout << endl;  
      
  gBenchmark->Show("selectAntiWm"); 
}
Esempio n. 20
0
// Main macro function
//--------------------------------------------------------------------------------------------------
void NormalizeNtuple(string inputFilename, string datasetName, string outputFilename) 
{
  gBenchmark->Start("NormalizeNtuple");
    
  TTree::SetMaxTreeSize(kMaxLong64);
  
  // Don't write TObject part of the objects
  mithep::TEventInfo::Class()->IgnoreTObjectStreamer();
  mithep::TMuon::Class()->IgnoreTObjectStreamer();
  mithep::TElectron::Class()->IgnoreTObjectStreamer();
  mithep::TJet::Class()->IgnoreTObjectStreamer();
  mithep::TPhoton::Class()->IgnoreTObjectStreamer();

  // Data structures to store info from TTrees
  mithep::TEventInfo *info  = new mithep::TEventInfo();
  TClonesArray *muonArr     = new TClonesArray("mithep::TMuon");
  TClonesArray *electronArr     = new TClonesArray("mithep::TElectron");
  TClonesArray *jetArr    = new TClonesArray("mithep::TJet");
  TClonesArray *photonArr     = new TClonesArray("mithep::TPhoton");

  UInt_t nInputEvts = 0;
  UInt_t nPassEvts  = 0;
  
  TFile* outfile = new TFile(outputFilename.c_str(), "RECREATE");

  //
  // Initialize data trees and structs
  // 
  TTree *outEventTree = new TTree("Events","Events"); 
  outEventTree->Branch("Info",     &info);
  outEventTree->Branch("Muon",     &muonArr);
  outEventTree->Branch("Electron", &electronArr);
  outEventTree->Branch("PFJet",    &jetArr);
  outEventTree->Branch("Photon",   &photonArr);

  TTree *eventTree = getTreeFromFile(inputFilename.c_str(),"Events"); 
   assert(eventTree);
    
  // Set branch address to structures that will store the info  
  eventTree->SetBranchAddress("Info",     &info);        TBranch *infoBr     = eventTree->GetBranch("Info");
  eventTree->SetBranchAddress("Muon",     &muonArr);     TBranch *muonBr     = eventTree->GetBranch("Muon");
  eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron");
  eventTree->SetBranchAddress("PFJet",    &jetArr);      TBranch *jetBr    = eventTree->GetBranch("PFJet");
  eventTree->SetBranchAddress("Photon",    &photonArr);  TBranch *photonBr   = eventTree->GetBranch("Photon");

  Double_t normalizationWeight = getNormalizationWeight(inputFilename, datasetName);

  for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) { 
    infoBr->GetEntry(ientry);
    muonArr->Clear();     muonBr->GetEntry(ientry);
    electronArr->Clear(); electronBr->GetEntry(ientry);
    photonArr->Clear(); photonBr->GetEntry(ientry);
    jetArr->Clear();      jetBr->GetEntry(ientry);
      
    if (ientry % 100000 == 0) cout << "Events: " << ientry << endl;

    nInputEvts++;
     
    info->eventweight = info->eventweight * normalizationWeight;
   outEventTree->Fill();
    nPassEvts++;
  }
  
  outfile->Write();
  outfile->Close();
  
  delete info;
  delete muonArr;
  delete electronArr;
  delete jetArr;
    
  std::cout << outputFilename << " created!" << std::endl;
  std::cout << " >>> Events processed: " << nInputEvts << std::endl;
  std::cout << " >>>   Events passing: " << nPassEvts << std::endl;
  
  gBenchmark->Show("NormalizeNtuple");
}  
Esempio n. 21
0
void selectZmmGen(const TString conf="zmmgen.conf", // input file
                  const TString outputDir="."   // output directory
	          ) {
  gBenchmark->Start("selectZmmGen");

//--------------------------------------------------------------------------------------------------------------
  // Settings 
  //============================================================================================================== 

  const Double_t MASS_LOW  = 40;
  const Double_t MASS_HIGH = 200;
  const Double_t PT_CUT    = 22;
  const Double_t ETA_CUT   = 2.4;
  const Double_t MUON_MASS = 0.105658369;

  const Int_t BOSON_ID  = 23;
  const Int_t LEPTON_ID = 13;

  // load trigger menu                                                                                                  
  const baconhep::TTrigger triggerMenu("../../BaconAna/DataFormats/data/HLT_50nsGRun");

  // load pileup reweighting file  

  TFile *f_rw = TFile::Open("../Tools/pileup_rw_baconDY.root", "read"); 
  
  // for systematics we need 3
  TH1D *h_rw = (TH1D*) f_rw->Get("h_rw_golden");
  TH1D *h_rw_up = (TH1D*) f_rw->Get("h_rw_up_golden");
  TH1D *h_rw_down = (TH1D*) f_rw->Get("h_rw_down_golden"); 

  if (h_rw==NULL) cout<<"WARNIG h_rw == NULL"<<endl;
  if (h_rw_up==NULL) cout<<"WARNIG h_rw == NULL"<<endl;
  if (h_rw_down==NULL) cout<<"WARNIG h_rw == NULL"<<endl;

  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  

  vector<TString>  snamev;      // sample name (for output files)  
  vector<CSample*> samplev;     // data/MC samples

  //
  // parse .conf file
  //
  confParse(conf, snamev, samplev);
 
  // Create output directory
  gSystem->mkdir(outputDir,kTRUE);
  const TString ntupDir = outputDir + TString("/ntuples");
  gSystem->mkdir(ntupDir,kTRUE);

  //
  // Declare output ntuple variables
  //
  UInt_t  runNum, lumiSec, evtNum;
  UInt_t  matchGen;
  UInt_t  npv, npu;
  UInt_t  triggerDec;
  UInt_t  goodPV;
  UInt_t  matchTrigger;
  UInt_t  ngenlep;
  TLorentzVector *genlep1=0, *genlep2=0;
  Int_t   genq1, genq2;
  UInt_t nlep;
  TLorentzVector *lep1=0, *lep2=0;
  Int_t   q1, q2;
  Float_t scale1fbGen,scale1fb,scale1fbUp,scale1fbDown;

  std::vector<float> *lheweight = new std::vector<float>();

 // Data structures to store info from TTrees
  baconhep::TEventInfo *info   = new baconhep::TEventInfo();
  baconhep::TGenEventInfo *gen = new baconhep::TGenEventInfo();
  TClonesArray *genPartArr = new TClonesArray("baconhep::TGenParticle");
  TClonesArray *muonArr    = new TClonesArray("baconhep::TMuon");
  TClonesArray *vertexArr  = new TClonesArray("baconhep::TVertex");
  
  TFile *infile=0;
  TTree *eventTree=0;

  //
  // loop over samples
  //  
  for(UInt_t isam=0; isam<samplev.size(); isam++) {
    
    // Assume signal sample is given name "zmm" - flag to store GEN Z kinematics
    Bool_t isSignal = snamev[isam].Contains("zmm",TString::kIgnoreCase);
    
    // flag to reject Z->mm events when selecting at wrong-flavor background events
    Bool_t isWrongFlavor = (snamev[isam].CompareTo("zxx",TString::kIgnoreCase)==0);
    
    CSample* samp = samplev[isam];

    //
    // Set up output ntuple
    //
    TString outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.raw.root");

    TFile *outFile = new TFile(outfilename,"RECREATE"); 
    TTree *outTree = new TTree("Events","Events");
    outTree->Branch("runNum",     &runNum,     "runNum/i");      // event run number
    outTree->Branch("lumiSec",    &lumiSec,    "lumiSec/i");     // event lumi section
    outTree->Branch("evtNum",     &evtNum,     "evtNum/i");      // event number
    outTree->Branch("matchGen",   &matchGen,   "matchGen/i");    // event has both leptons matched to MC Z->ll
    outTree->Branch("npv",        &npv,        "npv/i");         // number of primary vertices
    outTree->Branch("npu",        &npu,        "npu/i");         // number of in-time PU events (MC)
    outTree->Branch("triggerDec",   &triggerDec,   "triggerDec/i");    // event pass the trigger
    outTree->Branch("goodPV",   &goodPV,   "goodPV/i");    // event has a good PV
    outTree->Branch("matchTrigger",   &matchTrigger,   "matchTrigger/i");    // event has at least one lepton matched to the trigger
    outTree->Branch("ngenlep",     &ngenlep,     "ngenlep/i");      // number of gen leptons
    outTree->Branch("genlep1",   "TLorentzVector",  &genlep1);     // gen lepton1 4-vector
    outTree->Branch("genlep2",   "TLorentzVector",  &genlep2);     // gen lepton2 4-vector
    outTree->Branch("genq1",          &genq1,         "genq1/I");          // charge of lepton1
    outTree->Branch("genq2",          &genq2,         "genq2/I");          // charge of lepton2
    outTree->Branch("nlep",     &nlep,     "nlep/i");      // number of leptons
    outTree->Branch("lep1",       "TLorentzVector",  &lep1);     // lepton1 4-vector
    outTree->Branch("lep2",       "TLorentzVector",  &lep2);     // lepton2 4-vector
    outTree->Branch("q1",          &q1,         "q1/I");          // charge of lepton1
    outTree->Branch("q2",          &q2,         "q2/I");          // charge of lepton2
    outTree->Branch("scale1fbGen",   &scale1fbGen,   "scale1fbGen/F");    // event weight per 1/fb (MC)
    outTree->Branch("scale1fb",   &scale1fb,   "scale1fb/F");    // event weight per 1/fb (MC)
    outTree->Branch("scale1fbUp",    &scale1fbUp,   "scale1fbUp/F");    // event weight per 1/fb (MC)
    outTree->Branch("scale1fbDown",    &scale1fbDown,   "scale1fbDown/F");    // event weight per 1/fb (MC)
    outTree->Branch("lheweight",  &lheweight);

    //
    // loop through files
    //
    const UInt_t nfiles = samp->fnamev.size();
    for(UInt_t ifile=0; ifile<nfiles; ifile++) {  

      // Read input file and get the TTrees
      cout << "Processing " << samp->fnamev[ifile] << " [xsec = " << samp->xsecv[ifile] << " pb] ... " << endl; cout.flush();
      infile = TFile::Open(samp->fnamev[ifile]); 
      assert(infile);
      
      eventTree = (TTree*)infile->Get("Events");
      assert(eventTree);  
      eventTree->SetBranchAddress("Info",     &info);        TBranch *infoBr     = eventTree->GetBranch("Info");
      eventTree->SetBranchAddress("Muon", &muonArr);   TBranch *muonBr = eventTree->GetBranch("Muon");
      eventTree->SetBranchAddress("PV",   &vertexArr); TBranch *vertexBr = eventTree->GetBranch("PV");
      Bool_t hasGen = eventTree->GetBranchStatus("GenEvtInfo");
      TBranch *genBr=0, *genPartBr=0;
      if(hasGen) {
        eventTree->SetBranchAddress("GenEvtInfo", &gen); genBr = eventTree->GetBranch("GenEvtInfo");
	eventTree->SetBranchAddress("GenParticle",&genPartArr); genPartBr = eventTree->GetBranch("GenParticle");
      }

      // Compute MC event weight per 1/fb
      const Double_t xsec = samp->xsecv[ifile];
      Double_t totalWeightGen=0;
      Double_t totalWeight=0;
      Double_t totalWeightUp=0;
      Double_t totalWeightDown=0;
      Double_t puWeight=0;
      Double_t puWeightUp=0;
      Double_t puWeightDown=0;
      if (hasGen) {
	for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
	  infoBr->GetEntry(ientry);
	  genBr->GetEntry(ientry);
	  puWeight = h_rw->GetBinContent(h_rw->FindBin(info->nPUmean));
	  puWeightUp = h_rw_up->GetBinContent(h_rw_up->FindBin(info->nPUmean));
	  puWeightDown = h_rw_down->GetBinContent(h_rw_down->FindBin(info->nPUmean));
	  totalWeightGen+=gen->weight;
	  totalWeight+=gen->weight*puWeight;
	  totalWeightUp+=gen->weight*puWeightUp;
	  totalWeightDown+=gen->weight*puWeightDown;
	}
      }


      //
      // loop over events
      //
      Double_t nsel=0, nselvar=0;
      for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
	infoBr->GetEntry(ientry);

        if(ientry%1000000==0) cout << "Processing event " << ientry << ". " << (double)ientry/(double)eventTree->GetEntries()*100 << " percent done with this file." << endl;

	Double_t weightGen=1;
	Double_t weight=1;
	Double_t weightUp=1;
	Double_t weightDown=1;
	if(xsec>0 && totalWeightGen>0) weightGen = xsec/totalWeightGen;
        if(xsec>0 && totalWeight>0) weight = xsec/totalWeight;
	if(xsec>0 && totalWeightUp>0) weightUp = xsec/totalWeightUp;
	if(xsec>0 && totalWeightDown>0) weightDown = xsec/totalWeightDown;
	if(hasGen) {
	  genPartArr->Clear();
	  genBr->GetEntry(ientry);
	  genPartBr->GetEntry(ientry);
	  puWeight = h_rw->GetBinContent(h_rw->FindBin(info->nPUmean));
	  puWeightUp = h_rw_up->GetBinContent(h_rw_up->FindBin(info->nPUmean));
	  puWeightDown = h_rw_down->GetBinContent(h_rw_down->FindBin(info->nPUmean));
	  weightGen*=gen->weight;
	  weight*=gen->weight*puWeight;
	  weightUp*=gen->weight*puWeightUp;
	  weightDown*=gen->weight*puWeightDown;
	}

	// veto z -> xx decays for signal and z -> mm for bacground samples (needed for inclusive DYToLL sample)
        if (isWrongFlavor && hasGen && fabs(toolbox::flavor(genPartArr, BOSON_ID))==LEPTON_ID) continue;
        else if (isSignal && hasGen && fabs(toolbox::flavor(genPartArr, BOSON_ID))!=LEPTON_ID) continue;
     

	// trigger requirement
	Bool_t passMuTrigger = kFALSE;
	if (isMuonTrigger(triggerMenu, info->triggerBits)) passMuTrigger=kTRUE;
	
        // good vertex requirement
	Bool_t hasGoodPV = kFALSE;
        if((info->hasGoodPV)) hasGoodPV=kTRUE;

	muonArr->Clear();
        muonBr->GetEntry(ientry);

	Int_t n_mu=0;
	TLorentzVector vlep1(0., 0., 0., 0.);
	TLorentzVector vlep2(0., 0., 0., 0.);
	Bool_t hasTriggerMatch = kFALSE;

	for(Int_t i1=0; i1<muonArr->GetEntriesFast(); i1++) {
          const baconhep::TMuon *mu = (baconhep::TMuon*)((*muonArr)[i1]);

	  double Mu_Pt=mu->pt;
	
	  if(Mu_Pt     < PT_CUT)        continue;  // lepton pT cut
	  if(fabs(mu->eta) > ETA_CUT)       continue;  // lepton |eta| cut
	  if(!passMuonID(mu))               continue;  // lepton selection

          if(isMuonTriggerObj(triggerMenu, mu->hltMatchBits, kFALSE)) hasTriggerMatch=kTRUE;
	  
	  if(Mu_Pt>vlep1.Pt())
	    {
	      vlep2=vlep1;
	      vlep1.SetPtEtaPhiM(Mu_Pt, mu->eta, mu->phi, MUON_MASS);
	      q2=q1;
	      q1=mu->q;
	    }
	  else if(Mu_Pt<=vlep1.Pt()&&Mu_Pt>vlep2.Pt())
	    {
	      vlep2.SetPtEtaPhiM(Mu_Pt, mu->eta, mu->phi, MUON_MASS);
	      q2=mu->q;
	    }
	 
	  n_mu++;
	}

	Int_t n_genmu=0;
	Int_t glepq1=-99;
	Int_t glepq2=-99;
	TLorentzVector *gvec=new TLorentzVector(0,0,0,0);
	TLorentzVector *glep1=new TLorentzVector(0,0,0,0);
	TLorentzVector *glep2=new TLorentzVector(0,0,0,0);
	TLorentzVector *gph=new TLorentzVector(0,0,0,0);
	Bool_t hasGenMatch = kFALSE;
	if(isSignal && hasGen) {
	  toolbox::fillGen(genPartArr, BOSON_ID, gvec, glep1, glep2,&glepq1,&glepq2,1);
	  
	  Bool_t match1 = ( ((glep1) && toolbox::deltaR(vlep1.Eta(), vlep1.Phi(), glep1->Eta(), glep1->Phi())<0.5) ||
			    ((glep2) && toolbox::deltaR(vlep1.Eta(), vlep1.Phi(), glep2->Eta(), glep2->Phi())<0.5) );
	      
	  Bool_t match2 = ( ((glep1) && toolbox::deltaR(vlep2.Eta(), vlep2.Phi(), glep1->Eta(), glep1->Phi())<0.5) ||
                                ((glep2) && toolbox::deltaR(vlep2.Eta(), vlep2.Phi(), glep2->Eta(), glep2->Phi())<0.5) );

	  for(Int_t i=0; i<genPartArr->GetEntriesFast(); i++) {
	    const baconhep::TGenParticle* genloop = (baconhep::TGenParticle*) ((*genPartArr)[i]);
	    if(fabs(genloop->pdgId)!=22) continue;
	    gph->SetPtEtaPhiM(genloop->pt, genloop->eta, genloop->phi, genloop->mass);
	    if(toolbox::deltaR(gph->Eta(),gph->Phi(),glep1->Eta(),glep1->Phi())<0.1)
	      {
		glep1->operator+=(*gph);
	      }
	    if(toolbox::deltaR(gph->Eta(),gph->Phi(),glep2->Eta(),glep2->Phi())<0.1)
	      {
		glep2->operator+=(*gph);
	      }
	  }

	  if(glep1->Pt() >= PT_CUT && fabs(glep1->Eta())< ETA_CUT)
	    {
	      genlep1=glep1;
	      genq1=glepq1;
	      n_genmu++;
	    }
	  if(glep2->Pt() >= PT_CUT && fabs(glep2->Eta())< ETA_CUT)
	    {
	      genlep2=glep2;
	      genq2=glepq2;
	      n_genmu++;
	    }
	  
	  if(match1 && match2) hasGenMatch = kTRUE;
	}

	//
	// Fill tree
	//
	runNum   = info->runNum;
	lumiSec  = info->lumiSec;
	evtNum   = info->evtNum;

	if (hasGenMatch) matchGen=1;
	else matchGen=0;
	if (passMuTrigger) triggerDec=1;
	else triggerDec=0;
	if (hasGoodPV) goodPV=1;
	else goodPV=0;
	if (hasTriggerMatch) matchTrigger=1;
	else matchTrigger=0;
	
	vertexArr->Clear();
	vertexBr->GetEntry(ientry);
	
	npv      = vertexArr->GetEntries();
	npu      = info->nPUmean;
	scale1fbGen = weightGen;
	scale1fb = weight;
	scale1fbUp = weightUp;
	scale1fbDown = weightDown;

	lheweight->clear();
	for (int j = 0; j<=110; j++)
	  {
	    lheweight->push_back(gen->lheweight[j]);
	  }

	ngenlep=n_genmu;

	nlep=n_mu;
	lep1=&vlep1;
        lep2=&vlep2;
	
	nsel+=weight;
	nselvar+=weight*weight;

	outTree->Fill();

	delete gvec;
	delete glep1;
	delete glep2;
	delete gph;
	lep1=0, lep2=0;
	genlep1=0, genlep2=0;
      }
      delete infile;
      infile=0, eventTree=0;    
      
      cout << nsel  << " +/- " << sqrt(nselvar);
      cout << endl;
    }
    outFile->Write();
    outFile->Close(); 
  }
  delete h_rw;
  delete h_rw_up;
  delete h_rw_down;
  delete f_rw;
  delete info;
  delete gen;
  delete genPartArr;
  delete muonArr;
  delete vertexArr;
    
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
  
  cout << endl;
  cout << "  <> Output saved in " << outputDir << "/" << endl;    
  cout << endl;  
      
  gBenchmark->Show("selectZmmGen"); 
}
void HHToBBGGSelectionMistags(const string inputfile,          // input file
                              const string outputfile,         // output directory
                              Int_t SampleType = 7,
                              Bool_t applyExtrapWeightTo140PU = kFALSE
  ) {
  
  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //============================================================================================================== 
  bool printdebug = false;

  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  
  Double_t nEvents = 0;
  Double_t nEventsTwoRealPho = 0;
  
  //*****************************************************************************************
  // Set up output ntuple
  //*****************************************************************************************
  TFile *outFile = new TFile(outputfile.c_str(),"RECREATE"); 
  TH1F *NEvents =  new TH1F("NEvents",";;",1,-0.5,0.5);
  //edit
  TH1F *NEventsTwoRealPho =  new TH1F("NEventsTwoRealPho",";;",1,-0.5,0.5);
  TH1F *NPUMean = new TH1F("NPUMean",";NPUMean;Number of Events", 100, -0.5, 99.5);
  cmsana::HHToBBGGEventTree *outputEventTree = new cmsana::HHToBBGGEventTree;
  outputEventTree->CreateTree();


  //*****************************************************************************************
  // Set up input
  //*****************************************************************************************
  TFile *infile=0;
  TTree *eventTree=0;
  
  // Data structures to store info from TTrees
  cmsana::TEventInfo *info  = new cmsana::TEventInfo();
  TClonesArray *genparticleArr = new TClonesArray("cmsana::TGenParticle");
  TClonesArray *genjetArr = new TClonesArray("cmsana::TGenJet");

  TFile *BJetMistagRateLightJetsFile = TFile::Open("/afs/cern.ch/work/s/sixie/public/releases/analysis/CMSSW_5_3_9_patch3/src/CMSAna/HHToBBGG/data/BTaggingEfficiency_LightJetsMistagRate.root");
  TFile *BJetMistagRateCharmJetsFile = TFile::Open("/afs/cern.ch/work/s/sixie/public/releases/analysis/CMSSW_5_3_9_patch3/src/CMSAna/HHToBBGG/data/BTaggingEfficiency_CharmJetsMistagRate.root");
  TFile *PhotonEfficiencyFile = TFile::Open("/afs/cern.ch/work/s/sixie/public/releases/analysis/CMSSW_5_3_9_patch3/src/CMSAna/HHToBBGG/data/PhotonEfficiency_PromptPhoton.root");
  TH2F *BJetMistagRateLightJetsHist = (TH2F*)BJetMistagRateLightJetsFile->Get("MistagRate_CSVMedium_Pt_Eta");
  TH2F *BJetMistagRateCharmJetsHist = (TH2F*)BJetMistagRateCharmJetsFile->Get("MistagRate_CSVMedium_Pt_Eta");
  TH2F *PhotonEfficiencyHist = (TH2F*)PhotonEfficiencyFile->Get("Efficiency_PtEta");
  TH2F *bjet1FakeRateHist = 0;
  TH2F *bjet2FakeRateHist = 0;
  double bjet1Eff = 0;
  double bjet2Eff = 0;

  // Read input file and get the TTrees
  cout << "Processing " << inputfile << "..." << endl;
  infile = TFile::Open(inputfile.c_str(),"read");
  assert(infile);

    
  eventTree = (TTree*)infile->Get("Events"); assert(eventTree);  
  eventTree->SetBranchAddress("Info", &info); TBranch *infoBr = eventTree->GetBranch("Info");
  eventTree->SetBranchAddress("GenParticle", &genparticleArr); TBranch *genparticleBr = eventTree->GetBranch("GenParticle");
  eventTree->SetBranchAddress("GenJet", &genjetArr); TBranch *genjetBr = eventTree->GetBranch("GenJet");
  cout << "NEvents = " << eventTree->GetEntries() << endl;

  
  Double_t weight = 1;

  // null vector for default four vectors
  cmsana::FourVector null(0.0,0.0,0.0,0.0);

  // loop over events
  for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
    if (ientry % 1000 == 0) cout << "Processed Event " << ientry << endl;
    infoBr->GetEntry(ientry);

    NEvents->Fill(0);
    NEventsTwoRealPho->Fill(0);
    NPUMean->Fill(info->nPUMean);

    //***********************************************************
    // Definition of Pileup Energy density
    //***********************************************************
    Double_t rho = info->RhoKt6PFJets;

    genparticleArr->Clear();
    genjetArr->Clear(); 

    genparticleBr->GetEntry(ientry);
    genjetBr->GetEntry(ientry);

    double tmpHT = 0;

    //***********************************************************
    // Find Gen-Level particles
    //***********************************************************
    const cmsana::TGenParticle *genPhoton1 = 0;
    const cmsana::TGenParticle *genPhoton2 = 0;
    for(Int_t i=0; i<genparticleArr->GetEntriesFast(); i++) {
      const cmsana::TGenParticle *p = (cmsana::TGenParticle*)((*genparticleArr)[i]);

      //***********************************************************
      // Find Gen Photons
      //***********************************************************
      if ( SampleType == cmsana::HHToBBGGEventTree::GGPlusTwoMistag) {
        if (p->pdgid == 22 && ( p->motherPdgID == 21 || (abs(p->motherPdgID) >= 1 && abs(p->motherPdgID) <= 6) ) ) {
          if (!genPhoton1) {
            genPhoton1 = p;
          } else if (!genPhoton2) {
            genPhoton2 = p;
          }
        }
      }

    }
    
    //sampleType
    cmsana::HHToBBGGEventTree::SampleType stype = cmsana::HHToBBGGEventTree::none;
    if (SampleType == 7) stype = cmsana::HHToBBGGEventTree::GGPlusTwoMistag;

    outputEventTree->sampletype = stype;
    outputEventTree->run = info->runNum;
    outputEventTree->lumi = info->lumiSec;
    outputEventTree->event = info->evtNum;
    outputEventTree->npu = info->nPU;
    outputEventTree->rho = info->RhoKt6PFJets;
    outputEventTree->nvtx = info->nGoodPV;

    cmsana::FourVectorM genpho1v;
    cmsana::FourVectorM genpho2v;
    outputEventTree->genpho1 = null;
    outputEventTree->genpho2 = null;
    if (genPhoton1) {
      genpho1v.SetPt(genPhoton1->pt);
      genpho1v.SetEta(genPhoton1->eta);
      genpho1v.SetPhi(genPhoton1->phi);
      genpho1v.SetM(0);
      outputEventTree->genpho1 = genpho1v;
    }
    if (genPhoton2) {
      genpho2v.SetPt(genPhoton2->pt);
      genpho2v.SetEta(genPhoton2->eta);
      genpho2v.SetPhi(genPhoton2->phi);
      genpho2v.SetM(0);   
      outputEventTree->genpho2 = genpho2v;    
    }

    cmsana::FourVectorM genb1v;
    cmsana::FourVectorM genb2v;
    outputEventTree->genb1 = null;
    outputEventTree->genb2 = null;

    //****************************************************************
    // Loop over genjets to make collection of eligible denominators
    //****************************************************************   
    UInt_t njets = 0;
    UInt_t ncentraljets = 0;
    vector<const cmsana::TGenJet*> goodBJets;
    for(Int_t i=0; i<genjetArr->GetEntriesFast(); i++) {
      const cmsana::TGenJet *genjet = (cmsana::TGenJet*)((*genjetArr)[i]);

      bool passBJetCuts = true;
//       if ( !(genPhoton1 && genPhoton2) ) passBJetCuts = false; //Si: not sure this is useful

      //***************************************************
      //bjet cuts
      //***************************************************
      if (!(genjet->pt > 30)) passBJetCuts = false;
      if (!(fabs(genjet->eta) < 2.4)) passBJetCuts = false;
      if (passBJetCuts) {      
        //save good bjets
        goodBJets.push_back((cmsana::TGenJet*)genjet->Clone()); //new object created
      }

      //***************************************************
      //jet counting
      //***************************************************
      if (genjet->pt > 30) {
        tmpHT += genjet->pt;
        njets++;
        if (fabs(genjet->eta) < 2.5) ncentraljets++;
      }
    }


    //***************************************************
    //No real bjets in this sample
    //***************************************************
    cmsana::FourVectorM genbjet1v;
    cmsana::FourVectorM genbjet2v;
    outputEventTree->genbjet1 = null;    
    outputEventTree->genbjet2 = null;    
    
    
    //***************************************************
    //selected photons
    //***************************************************
    const cmsana::TGenParticle *photon1 = 0;
    const cmsana::TGenParticle *photon2 = 0;

    if (genPhoton1) photon1 = genPhoton1;
    if (genPhoton2) photon2 = genPhoton2;

    cmsana::FourVectorM photon1v;
    cmsana::FourVectorM photon2v;
    cmsana::FourVectorM diphotonv;
    double pho1eff = 0;
    double pho2eff = 0;
    outputEventTree->pho1 = null;      //default 4-vector
    outputEventTree->pho2 = null;
    outputEventTree->diphoton = null;    

    if (photon1) {
      photon1v.SetPt(photon1->pt);
      photon1v.SetEta(photon1->eta);
      photon1v.SetPhi(photon1->phi);
      photon1v.SetM(0);
      outputEventTree->pho1 = photon1v;
      pho1eff = PhotonEfficiencyHist->GetBinContent(PhotonEfficiencyHist->FindFixBin(fmax(fmin(photon1->pt,99.9),0.01),
                                                                    fmax(fmin(photon1->eta,2.49),-2.49)));
    } 

    if (photon2) {
      photon2v.SetPt(photon2->pt);
      photon2v.SetEta(photon2->eta);
      photon2v.SetPhi(photon2->phi);
      photon2v.SetM(0);
      outputEventTree->pho2 = photon2v;
      pho2eff = PhotonEfficiencyHist->GetBinContent(PhotonEfficiencyHist->FindFixBin(fmax(fmin(photon2->pt,99.9),0.01),
                                                                    fmax(fmin(photon2->eta,2.49),-2.49)));
    }
    
    if (photon1 && photon2) {
      diphotonv = photon1v + photon2v;
      outputEventTree->diphoton = diphotonv;
    }
    
    if (photon1) tmpHT += photon1->pt;
    if (photon2) tmpHT += photon2->pt;

    //cout << " Number of good BJets: " << goodBJets.size() << endl;

    //***************************************************************************************************************
    // now that I have all the possible goodBJets, loop through them and choose two pairwise unique goodBJets to
    // promote to bjet1 and bjet2 and store this event into the tree (don't forget to weight the event)
    //
    //***************************************************************************************************************
    //Select all pairwise goodBJets (i.e. possible bjets)
    //***************************************************************************************************************
    if (goodBJets.size() > 1) {
      for (UInt_t i=0; i<goodBJets.size()-1; i++) {
        for (UInt_t j=i+1; j<goodBJets.size(); j++) {
          const cmsana::TGenJet* bjet1 = 0;
          const cmsana::TGenJet* bjet2 = 0;
          bjet1 = goodBJets[i];
          bjet2 = goodBJets[j];
          if (bjet2->pt > bjet1->pt) {
            const cmsana::TGenJet* tmp = bjet2;
            bjet2 = bjet1;
            bjet1 = tmp;
          }

          //**************************************************
          //skip any jet pairs that have real b jets
          //**************************************************
          if ( abs(bjet1->matchedPdgId) == 5 || abs(bjet2->matchedPdgId) == 5) continue;

          //**************************************************
          //assign mistag rates for light jets and charm
          //**************************************************          
          if ( abs(bjet1->matchedPdgId) == 4) bjet1FakeRateHist = BJetMistagRateCharmJetsHist;
          else bjet1FakeRateHist = BJetMistagRateLightJetsHist;
          if ( abs(bjet2->matchedPdgId) == 4) bjet2FakeRateHist = BJetMistagRateCharmJetsHist;
          else bjet2FakeRateHist = BJetMistagRateLightJetsHist;
          bjet1Eff = bjet1FakeRateHist->GetBinContent(bjet1FakeRateHist->FindBin(fmax(fmin(bjet1->pt,119.9),0.01),fmax(fmin(bjet1->eta,2.49),-2.49)));
          bjet2Eff = bjet2FakeRateHist->GetBinContent(bjet2FakeRateHist->FindBin(fmax(fmin(bjet1->pt,119.9),0.01),fmax(fmin(bjet1->eta,2.49),-2.49)));
      
          cmsana::FourVectorM bjet1v;
          cmsana::FourVectorM bjet2v;
          cmsana::FourVectorM dibjetv;
          outputEventTree->bjet1 = null;      //default 4-vector
          outputEventTree->bjet2 = null;
          outputEventTree->dibjet = null;    
      
          if (bjet1) {
            bjet1v.SetPt(bjet1->pt);
            bjet1v.SetEta(bjet1->eta);
            bjet1v.SetPhi(bjet1->phi);
            bjet1v.SetM(bjet1->mass);
      
            outputEventTree->bjet1 = bjet1v;
          }
      
          if (bjet2) {
            bjet2v.SetPt(bjet2->pt);
            bjet2v.SetEta(bjet2->eta);
            bjet2v.SetPhi(bjet2->phi);
            bjet2v.SetM(bjet2->mass);
            outputEventTree->bjet2 = bjet2v;
          }

          if (bjet1 && bjet2) {
            dibjetv = bjet1v + bjet2v;
            outputEventTree->dibjet = dibjetv;
          }

          //********************************************************
          //bbgg system
          //********************************************************    
          cmsana::FourVectorM bbggSystemv;
          outputEventTree->bbgg = null;
          if (bjet1 && bjet2 && photon1 && photon2) {
            bbggSystemv = (photon1v + photon2v + bjet1v + bjet2v);
            outputEventTree->bbgg = bbggSystemv;
          }
      
      
      
          //********************************************************
          //NJets
          //********************************************************    
          outputEventTree->njets = njets;
          outputEventTree->ncentraljets = ncentraljets;      
          outputEventTree->nlep = 0;

          //********************************************************
          //Some kinematic variables
          //********************************************************
          outputEventTree->DRgg = -1;
          outputEventTree->DRbb = -1;
          outputEventTree->minDRgb = -1;
          if (photon1 && photon2 && bjet1 && bjet2 ) {
            outputEventTree->DRgg = cmsana::deltaR(photon1->eta, photon1->phi, photon2->eta, photon2->phi);
            outputEventTree->DRbb = cmsana::deltaR(bjet1->eta, bjet1->phi, bjet2->eta, bjet2->phi);
            outputEventTree->minDRgb = fmin(fmin(fmin( cmsana::deltaR(photon1->eta, photon1->phi, bjet1->eta, bjet1->phi), 
                                                       cmsana::deltaR(photon1->eta, photon1->phi, bjet2->eta, bjet2->phi)),
                                                 cmsana::deltaR(photon2->eta, photon2->phi, bjet1->eta, bjet1->phi)),
                                            cmsana::deltaR(photon2->eta, photon2->phi, bjet2->eta, bjet2->phi));      
          }
      
          outputEventTree->pfmet = 0;
          outputEventTree->pfTrackMET = 0;          
          outputEventTree->HT = tmpHT;
          
          //Note: currently not computing HT. we may add it later.

          //*******************************************************
          //Apply mistag and photon selection efficiencies
          //*******************************************************
          outputEventTree->weight = bjet1Eff * bjet2Eff * pho1eff * pho2eff;

          //************************************
          //Extrapolation to 140 Pileup
          //************************************
          double pho1EffScalingForPU140 = 1.0;
          double pho2EffScalingForPU140 = 1.0;
          double bjet1EffScalingForPU140 = 1.0;
          double bjet2EffScalingForPU140 = 1.0;
          pho1EffScalingForPU140 = (0.85/0.95)*(0.85/0.95);
          pho2EffScalingForPU140 = (0.85/0.95)*(0.85/0.95);

          //Don't do extrapolation for mistag rate at this point in time
//           if ( abs(bjet1->matchedPdgId) == 4) {
//             bjet1EffScalingForPU140 = 0.15/0.10;
//           } else {
//             bjet1EffScalingForPU140 = 0.03/0.015;
//           }
//           if ( abs(bjet2->matchedPdgId) == 4) {
//             bjet2EffScalingForPU140 = 0.15/0.10;
//           } else {
//             bjet2EffScalingForPU140 = 0.03/0.015;
//           }

          if (applyExtrapWeightTo140PU) {
            outputEventTree->weight = outputEventTree->weight * pho1EffScalingForPU140*pho2EffScalingForPU140*bjet1EffScalingForPU140*bjet2EffScalingForPU140;
          }


          //********************************************************
          //Fill Output Tree
          //********************************************************
          outputEventTree->tree_->Fill();
          nEventsTwoRealPho++;
        }
      }
    }


    //********************************************************
    //Clean up Memory
    //********************************************************
    for (uint k=0; k<goodBJets.size(); ++k) {
      if (goodBJets[k]) delete goodBJets[k];
    }
    nEvents++;

  } //loop over all events


  delete infile;
  infile=0, eventTree=0;      
  delete info;
  delete genparticleArr;
  delete genjetArr;
  
     
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
   
  
  outFile->Write();
  outFile->Close();
  delete outFile;
  
  cout << " Number of events selected: " << nEvents << endl;
  cout << endl;
  cout << " Number of events with two real photons: " << nEventsTwoRealPho << endl;
  cout << endl;
  cout << "  <> Output saved in " << outputfile << endl;    
  cout << endl;  
      

}
Esempio n. 23
0
rdEEevent(int neve=300,  TString Tname0="/star/u/eemcdb/dataFeb11/run00006.eeTree", int flag=0, float Emax=40.) {
    TString Tname0="../sim2003/mc_eve2";
    gSystem->Load("StRoot/StEEmcUtil/EEevent/libEEevent.so");

    //  gStyle->SetPalette(1,0);
    gStyle->SetOptStat(111111);

    TString Tname;
    Tname=Tname0;

    printf("read upto %d events from file=%s.root\n",neve,Tname.Data());
    TFile *f = new TFile(Tname+".root");
    assert(f->IsOpen());
    TTree *t4 = (TTree*)f->Get("EEtree");
    assert(t4);
    // create a pointer to an event object. This will be used
    // to read the branch values.
    EEeventDst *event = new EEeventDst();

    //if (gROOT->IsBatch()) return;  new TBrowser();  t4->StartViewer();  return;
    TBranch *br = t4->GetBranch("EEdst");
    br->SetAddress(&event);
    Int_t nevent = (Int_t)t4->GetEntries();
    for (Int_t ie=0; ie<nevent; ie++) {
        if(ie>=neve) break;
        printf("\niEve=%d  ---------- \n",ie);
        int i;

        //read this branch only
        br->GetEntry(ie);
        event->print();

        int nSec=event->Sec->GetEntries();
        printf("%d sectors with data\n",nSec);

        int is;
        for(is=0; is<nSec; is++) {
            EEsectorDst *sec=(EEsectorDst*)event->Sec->At(is);
            //      sec->print();
            TClonesArray *hitA=sec->getTwHits();
            assert(hitA);
            int ih;
            for(ih=0; ih<hitA->GetEntries(); ih++) {
                char sub;
                int eta;
                float ener;
                EEtwHitDst *hit=(EEtwHitDst*)hitA->At(ih);
                hit->get(sub,eta,ener);
                if(ie<5) printf("    ih=%d sec=%d sub=%c etaBin=%d ener=%f\n",ih, sec->getID(), sub, eta,ener);
                //	hit->print();
            }

        }


    }

#if 0

    // allocate memory for needed branches
    TClonesArray *secA=new TClonesArray("EEsectorDst",1000);
    TBranch *BRsec = t4->GetBranch("Sec");   // set the branch address
    BRsec->SetAddress(&secA);

    int eveID=0;
    TBranch *BRid = t4->GetBranch("ID");
    BRid->SetAddress(&eveID);

    Int_t nevent = (Int_t)t4->GetEntries();
    printf("Total events in TTree=%d\n",nevent);


    // ...........  LOOP OVER EVENTS ............

    for (Int_t ie=0; ie<nevent; ie++) {
        if(ie>=neve) break;
        int i;

        //read this branch only
        BRid->GetEntry(ie);
        BRsec->GetEntry(ie);

        if(ie%1==0) printf("\n\iEve=%d  nSec=%d with data \n",ie,secA->GetEntries());

        //    if(ie%1==0) printf("\n\iEve=%d eveID=%d, eveType=%d, nSec=%d with data :\n",ie,eveID,eveType,secA->GetEntries());
        if(ie%1==0) printf("\n\iEve=%d eveID=%d, nSec=%d with data :\n",ie,eveID,secA->GetEntries());


        int is;
        for(is=0; is<secA->GetEntries(); is++) {
            EEsectorDst *sec=(EEsectorDst*)secA->At(is);
            if(ie<1) sec->print();

            TClonesArray *hitA;
            int ih;

            TClonesArray *hitAA[]= {sec->getPre1Hits(),sec->getPre2Hits(),sec->getTwHits(),sec->getPostHits(),sec->getSmdUHits(),sec->getSmdVHits()};
            int iz;
            for(iz=0; iz<4; iz++) { // over tower/pre/post
                hitA=hitAA[iz];
                if(ie<1)    printf("  sectorID=%d  iz=%d nHit=%d :\n",sec->getID(),iz,hitA->GetEntries());
            }// end of loop over pre1/2/Tw/Post


            for(iz=4; iz<6; iz++) { // over SMD U/V
                hitA=hitAA[iz];
                if(ie<1) printf("  sectorID=%d  iz=%d nHit=%d :\n",sec->getID(),iz,hitA->GetEntries());
                for(ih=0; ih<hitA->GetEntries(); ih++) {
                    EEsmdHitDst *hit2=(EEsmdHitDst*)hitA->At(ih);
                    int strip;
                    float ener;
                    hit2->get(strip,ener);
                    if(ie<1) printf("    ih=%d strip=%d etaBin=%d ener=%f\n",ih, sec->getID(), strip,ener);
                    hit->print();
                }
            }// end of loop over pre1/2/Tw/Post


        }// end of loop over sector

    }
#endif
    printf("\n\nTotal events in B TTree=%d\n",nevent);


}
Esempio n. 24
0
void selectWe(const TString conf="we.conf", // input file
              const TString outputDir=".",  // output directory
              const Bool_t  doScaleCorr=0   // apply energy scale corrections?
             ) {
    gBenchmark->Start("selectWe");

    //--------------------------------------------------------------------------------------------------------------
    // Settings
    //==============================================================================================================

    const Double_t PT_CUT   = 25;
    const Double_t ETA_CUT  = 2.5;
    const Double_t ELE_MASS = 0.000511;

    const Double_t VETO_PT   = 10;
    const Double_t VETO_ETA  = 2.5;

    const Double_t ECAL_GAP_LOW  = 1.4442;
    const Double_t ECAL_GAP_HIGH = 1.566;

    const Double_t escaleNbins  = 2;
    const Double_t escaleEta[]  = { 1.4442, 2.5   };
    const Double_t escaleCorr[] = { 0.992,  1.009 };

    const Int_t BOSON_ID  = 24;
    const Int_t LEPTON_ID = 11;

    // load trigger menu
    const baconhep::TTrigger triggerMenu("../../BaconAna/DataFormats/data/HLT_50nsGRun");

    // load pileup reweighting file
    TFile *f_rw = TFile::Open("../Tools/pileup_rw_Golden.root", "read");
    TH1D *h_rw = (TH1D*) f_rw->Get("h_rw_golden");
    TH1D *h_rw_up = (TH1D*) f_rw->Get("h_rw_up_golden");
    TH1D *h_rw_down = (TH1D*) f_rw->Get("h_rw_down_golden");

    //--------------------------------------------------------------------------------------------------------------
    // Main analysis code
    //==============================================================================================================

    vector<TString>  snamev;      // sample name (for output files)
    vector<CSample*> samplev;     // data/MC samples

    //
    // parse .conf file
    //
    confParse(conf, snamev, samplev);
    const Bool_t hasData = (samplev[0]->fnamev.size()>0);

    // Create output directory
    gSystem->mkdir(outputDir,kTRUE);
    const TString ntupDir = outputDir + TString("/ntuples");
    gSystem->mkdir(ntupDir,kTRUE);

    //
    // Declare output ntuple variables
    //
    UInt_t  runNum, lumiSec, evtNum;
    UInt_t  npv, npu;
    UInt_t  id_1, id_2;
    Double_t x_1, x_2, xPDF_1, xPDF_2;
    Double_t scalePDF, weightPDF;
    TLorentzVector *genV=0, *genLep=0;
    Float_t genVPt, genVPhi, genVy, genVMass;
    Float_t genLepPt, genLepPhi;
    Float_t scale1fb, puWeight, puWeightUp, puWeightDown;
    Float_t met, metPhi, sumEt, mt, u1, u2;
    Float_t tkMet, tkMetPhi, tkSumEt, tkMt, tkU1, tkU2;
    Float_t mvaMet, mvaMetPhi, mvaSumEt, mvaMt, mvaU1, mvaU2;
    Float_t puppiMet, puppiMetPhi, puppiSumEt, puppiMt, puppiU1, puppiU2;
    Int_t   q;
    TLorentzVector *lep=0;
    Int_t lepID;
    ///// electron specific /////
    Float_t trkIso, emIso, hadIso;
    Float_t pfChIso, pfGamIso, pfNeuIso, pfCombIso;
    Float_t sigieie, hovere, eoverp, fbrem, ecalE;
    Float_t dphi, deta;
    Float_t d0, dz;
    UInt_t  isConv, nexphits, typeBits;
    TLorentzVector *sc=0;

    // Data structures to store info from TTrees
    baconhep::TEventInfo *info   = new baconhep::TEventInfo();
    baconhep::TGenEventInfo *gen = new baconhep::TGenEventInfo();
    TClonesArray *genPartArr     = new TClonesArray("baconhep::TGenParticle");
    TClonesArray *electronArr    = new TClonesArray("baconhep::TElectron");
    TClonesArray *scArr          = new TClonesArray("baconhep::TPhoton");
    TClonesArray *vertexArr      = new TClonesArray("baconhep::TVertex");

    TFile *infile=0;
    TTree *eventTree=0;

    //
    // loop over samples
    //
    for(UInt_t isam=0; isam<samplev.size(); isam++) {

        // Assume data sample is first sample in .conf file
        // If sample is empty (i.e. contains no ntuple files), skip to next sample
        Bool_t isData=kFALSE;
        if(isam==0 && !hasData) continue;
        else if (isam==0) isData=kTRUE;

        // Assume signal sample is given name "we" -- flag to store GEN W kinematics
        Bool_t isSignal = (snamev[isam].CompareTo("we",TString::kIgnoreCase)==0);
        // flag to reject W->enu events when selecting at wrong-flavor background events
        Bool_t isWrongFlavor = (snamev[isam].CompareTo("wx",TString::kIgnoreCase)==0);

        CSample* samp = samplev[isam];

        //
        // Set up output ntuple
        //
        TString outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.root");
        if(isam!=0 && !doScaleCorr) outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.raw.root");
        TFile *outFile = new TFile(outfilename,"RECREATE");
        TTree *outTree = new TTree("Events","Events");

        outTree->Branch("runNum",     &runNum,     "runNum/i");      // event run number
        outTree->Branch("lumiSec",    &lumiSec,    "lumiSec/i");     // event lumi section
        outTree->Branch("evtNum",     &evtNum,     "evtNum/i");      // event number
        outTree->Branch("npv",        &npv,        "npv/i");         // number of primary vertices
        outTree->Branch("npu",        &npu,        "npu/i");         // number of in-time PU events (MC)
        outTree->Branch("id_1",       &id_1,       "id_1/i");        // PDF info -- parton ID for parton 1
        outTree->Branch("id_2",       &id_2,       "id_2/i");        // PDF info -- parton ID for parton 2
        outTree->Branch("x_1",        &x_1,        "x_1/d");         // PDF info -- x for parton 1
        outTree->Branch("x_2",        &x_2,        "x_2/d");         // PDF info -- x for parton 2
        outTree->Branch("xPDF_1",     &xPDF_1,     "xPDF_1/d");      // PDF info -- x*F for parton 1
        outTree->Branch("xPDF_2",     &xPDF_2,     "xPDF_2/d");      // PDF info -- x*F for parton 2
        outTree->Branch("scalePDF",   &scalePDF,   "scalePDF/d");    // PDF info -- energy scale of parton interaction
        outTree->Branch("weightPDF",  &weightPDF,  "weightPDF/d");   // PDF info -- PDF weight
        outTree->Branch("genV",      "TLorentzVector", &genV);       // GEN boson 4-vector (signal MC)
        outTree->Branch("genLep",    "TLorentzVector", &genLep);     // GEN lepton 4-vector (signal MC)
        outTree->Branch("genVPt",     &genVPt,     "genVPt/F");      // GEN boson pT (signal MC)
        outTree->Branch("genVPhi",    &genVPhi,    "genVPhi/F");     // GEN boson phi (signal MC)
        outTree->Branch("genVy",      &genVy,      "genVy/F");       // GEN boson rapidity (signal MC)
        outTree->Branch("genVMass",   &genVMass,   "genVMass/F");    // GEN boson mass (signal MC)
        outTree->Branch("genLepPt",   &genLepPt,   "genLepPt/F");    // GEN lepton pT (signal MC)
        outTree->Branch("genLepPhi",  &genLepPhi,  "genLepPhi/F");   // GEN lepton phi (signal MC)
        outTree->Branch("scale1fb",   &scale1fb,   "scale1fb/F");    // event weight per 1/fb (MC)
        outTree->Branch("puWeight",   &puWeight,   "puWeight/F");    // scale factor for pileup reweighting (MC)
        outTree->Branch("puWeightUp",    &puWeightUp,   "puWeightUp/F");    // scale factor for pileup reweighting (MC)
        outTree->Branch("puWeightDown",    &puWeightDown,   "puWeightDown/F");    // scale factor for pileup reweighting (MC)
        outTree->Branch("met",        &met,        "met/F");         // MET
        outTree->Branch("metPhi",     &metPhi,     "metPhi/F");      // phi(MET)
        outTree->Branch("sumEt",      &sumEt,      "sumEt/F");       // Sum ET
        outTree->Branch("mt",         &mt,         "mt/F");          // transverse mass
        outTree->Branch("u1",         &u1,         "u1/F");          // parallel component of recoil
        outTree->Branch("u2",         &u2,         "u2/F");          // perpendicular component of recoil
        outTree->Branch("tkMet",      &tkMet,      "tkMet/F");       // MET (track MET)
        outTree->Branch("tkMetPhi",   &tkMetPhi,   "tkMetPhi/F");    // phi(MET) (track MET)
        outTree->Branch("tkSumEt",    &tkSumEt,    "tkSumEt/F");     // Sum ET (track MET)
        outTree->Branch("tkMt",       &tkMt,       "tkMt/F");        // transverse mass (track MET)
        outTree->Branch("tkU1",       &tkU1,       "tkU1/F");        // parallel component of recoil (track MET)
        outTree->Branch("tkU2",       &tkU2,       "tkU2/F");        // perpendicular component of recoil (track MET)
        outTree->Branch("mvaMet",     &mvaMet,     "mvaMet/F");      // MVA MET
        outTree->Branch("mvaMetPhi",  &mvaMetPhi,  "mvaMetPhi/F");   // phi(MVA MET)
        outTree->Branch("mvaSumEt",   &mvaSumEt,   "mvaSumEt/F");    // Sum ET (mva MET)
        outTree->Branch("mvaMt",      &mvaMt,      "mvaMt/F");       // transverse mass (mva MET)
        outTree->Branch("mvaU1",      &mvaU1,      "mvaU1/F");       // parallel component of recoil (mva MET)
        outTree->Branch("mvaU2",      &mvaU2,      "mvaU2/F");       // perpendicular component of recoil (mva MET)
        outTree->Branch("puppiMet",    &puppiMet,   "puppiMet/F");      // Puppi MET
        outTree->Branch("puppiMetPhi", &puppiMetPhi,"puppiMetPhi/F");   // phi(Puppi MET)
        outTree->Branch("puppiSumEt",  &puppiSumEt, "puppiSumEt/F");    // Sum ET (Puppi MET)
        outTree->Branch("puppiU1",     &puppiU1,    "puppiU1/F");       // parallel component of recoil (Puppi MET)
        outTree->Branch("puppiU2",     &puppiU2,    "puppiU2/F");       // perpendicular component of recoil (Puppi MET)
        outTree->Branch("q",          &q,          "q/I");           // lepton charge
        outTree->Branch("lep",       "TLorentzVector", &lep);        // lepton 4-vector
        outTree->Branch("lepID",      &lepID,      "lepID/I");       // lepton PDG ID
        ///// electron specific /////
        outTree->Branch("trkIso",     &trkIso,     "trkIso/F");      // track isolation of tag lepton
        outTree->Branch("emIso",      &emIso,      "emIso/F");       // ECAL isolation of tag lepton
        outTree->Branch("hadIso",     &hadIso,     "hadIso/F");      // HCAL isolation of tag lepton
        outTree->Branch("pfChIso",    &pfChIso,    "pfChIso/F");     // PF charged hadron isolation of lepton
        outTree->Branch("pfGamIso",   &pfGamIso,   "pfGamIso/F");    // PF photon isolation of lepton
        outTree->Branch("pfNeuIso",   &pfNeuIso,   "pfNeuIso/F");    // PF neutral hadron isolation of lepton
        outTree->Branch("pfCombIso",  &pfCombIso,  "pfCombIso/F");   // PF combined isolation of electron
        outTree->Branch("sigieie",    &sigieie,    "sigieie/F");     // sigma-ieta-ieta of electron
        outTree->Branch("hovere",     &hovere,     "hovere/F");      // H/E of electron
        outTree->Branch("eoverp",     &eoverp,     "eoverp/F");      // E/p of electron
        outTree->Branch("fbrem",      &fbrem,      "fbrem/F");       // brem fraction of electron
        outTree->Branch("dphi",       &dphi,       "dphi/F");        // GSF track - ECAL dphi of electron
        outTree->Branch("deta",       &deta,       "deta/F");        // GSF track - ECAL deta of electron
        outTree->Branch("ecalE",      &ecalE,      "ecalE/F");       // ECAL energy of electron
        outTree->Branch("d0",         &d0,         "d0/F");          // transverse impact parameter of electron
        outTree->Branch("dz",         &dz,         "dz/F");          // longitudinal impact parameter of electron
        outTree->Branch("isConv",     &isConv,     "isConv/i");      // conversion filter flag of electron
        outTree->Branch("nexphits",   &nexphits,   "nexphits/i");    // number of missing expected inner hits of electron
        outTree->Branch("typeBits",   &typeBits,   "typeBits/i");    // electron type of electron
        outTree->Branch("sc",        "TLorentzVector", &sc);         // supercluster 4-vector

        //
        // loop through files
        //
        const UInt_t nfiles = samp->fnamev.size();
        for(UInt_t ifile=0; ifile<nfiles; ifile++) {

            // Read input file and get the TTrees
            cout << "Processing " << samp->fnamev[ifile] << " [xsec = " << samp->xsecv[ifile] << " pb] ... ";
            cout.flush();
            infile = TFile::Open(samp->fnamev[ifile]);
            assert(infile);

            Bool_t hasJSON = kFALSE;
            baconhep::RunLumiRangeMap rlrm;
            if(samp->jsonv[ifile].CompareTo("NONE")!=0) {
                hasJSON = kTRUE;
                rlrm.addJSONFile(samp->jsonv[ifile].Data());
            }

            eventTree = (TTree*)infile->Get("Events");
            assert(eventTree);
            eventTree->SetBranchAddress("Info",     &info);
            TBranch *infoBr     = eventTree->GetBranch("Info");
            eventTree->SetBranchAddress("Electron", &electronArr);
            TBranch *electronBr = eventTree->GetBranch("Electron");
            eventTree->SetBranchAddress("PV",   &vertexArr);
            TBranch *vertexBr = eventTree->GetBranch("PV");

            Bool_t hasGen = eventTree->GetBranchStatus("GenEvtInfo");
            TBranch *genBr=0, *genPartBr=0;
            if(hasGen) {
                eventTree->SetBranchAddress("GenEvtInfo", &gen);
                genBr = eventTree->GetBranch("GenEvtInfo");
                eventTree->SetBranchAddress("GenParticle",&genPartArr);
                genPartBr = eventTree->GetBranch("GenParticle");
            }

            // Compute MC event weight per 1/fb
            const Double_t xsec = samp->xsecv[ifile];
            Double_t totalWeight=0;

            if (hasGen) {
                TH1D *hall = new TH1D("hall", "", 1,0,1);
                eventTree->Draw("0.5>>hall", "GenEvtInfo->weight");
                totalWeight=hall->Integral();
                delete hall;
                hall=0;
            }

            //
            // loop over events
            //
            Double_t nsel=0, nselvar=0;
            for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
                infoBr->GetEntry(ientry);

                if(ientry%1000000==0) cout << "Processing event " << ientry << ". " << (double)ientry/(double)eventTree->GetEntries()*100 << " percent done with this file." << endl;

                Double_t weight=1;
                if(xsec>0 && totalWeight>0) weight = xsec/totalWeight;
                if(hasGen) {
                    genPartArr->Clear();
                    genBr->GetEntry(ientry);
                    genPartBr->GetEntry(ientry);
                    weight*=gen->weight;
                }

                // veto w -> xv decays for signal and w -> ev for bacground samples (needed for inclusive WToLNu sample)
                if (isWrongFlavor && hasGen && fabs(toolbox::flavor(genPartArr, BOSON_ID))==LEPTON_ID) continue;
                else if (isSignal && hasGen && fabs(toolbox::flavor(genPartArr, BOSON_ID))!=LEPTON_ID) continue;

                // check for certified lumi (if applicable)
                baconhep::RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec);
                if(hasJSON && !rlrm.hasRunLumi(rl)) continue;

                // trigger requirement
                if (!isEleTrigger(triggerMenu, info->triggerBits, isData)) continue;

                // good vertex requirement
                if(!(info->hasGoodPV)) continue;

                //
                // SELECTION PROCEDURE:
                //  (1) Look for 1 good electron matched to trigger
                //  (2) Reject event if another electron is present passing looser cuts
                //
                electronArr->Clear();
                electronBr->GetEntry(ientry);

                Int_t nLooseLep=0;
                const baconhep::TElectron *goodEle=0;
                Bool_t passSel=kFALSE;

                for(Int_t i=0; i<electronArr->GetEntriesFast(); i++) {
                    const baconhep::TElectron *ele = (baconhep::TElectron*)((*electronArr)[i]);

                    // check ECAL gap
                    if(fabs(ele->scEta)>=ECAL_GAP_LOW && fabs(ele->scEta)<=ECAL_GAP_HIGH) continue;

                    // apply scale and resolution corrections to MC
                    Double_t elescEt_corr = ele->scEt;
                    if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0)
                        elescEt_corr = gRandom->Gaus(ele->scEt*getEleScaleCorr(ele->scEta,0),getEleResCorr(ele->scEta,0));

                    if(fabs(ele->scEta)   > VETO_ETA) continue;        // loose lepton |eta| cut
                    if(elescEt_corr       < VETO_PT)  continue;        // loose lepton pT cut
                    if(passEleLooseID(ele,info->rhoIso)) nLooseLep++;  // loose lepton selection
                    if(nLooseLep>1) {  // extra lepton veto
                        passSel=kFALSE;
                        break;
                    }

                    if(fabs(ele->scEta)   > ETA_CUT)     continue;  // lepton |eta| cut
                    if(elescEt_corr       < PT_CUT)      continue;  // lepton pT cut
                    if(!passEleID(ele,info->rhoIso))     continue;  // lepton selection
                    if(!isEleTriggerObj(triggerMenu, ele->hltMatchBits, kFALSE, isData)) continue;

                    passSel=kTRUE;
                    goodEle = ele;
                }

                if(passSel) {

                    //******* We have a W candidate! HURRAY! ********
                    nsel+=weight;
                    nselvar+=weight*weight;

                    // apply scale and resolution corrections to MC
                    Double_t goodElept_corr = goodEle->pt;
                    if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0)
                        goodElept_corr = gRandom->Gaus(goodEle->pt*getEleScaleCorr(goodEle->scEta,0),getEleResCorr(goodEle->scEta,0));

                    TLorentzVector vLep(0,0,0,0);
                    TLorentzVector vSC(0,0,0,0);
                    // apply scale and resolution corrections to MC
                    if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0) {
                        vLep.SetPtEtaPhiM(goodElept_corr, goodEle->eta, goodEle->phi, ELE_MASS);
                        vSC.SetPtEtaPhiM(gRandom->Gaus(goodEle->scEt*getEleScaleCorr(goodEle->scEta,0),getEleResCorr(goodEle->scEta,0)), goodEle->scEta, goodEle->scPhi, ELE_MASS);
                    } else {
                        vLep.SetPtEtaPhiM(goodEle->pt,goodEle->eta,goodEle->phi,ELE_MASS);
                        vSC.SetPtEtaPhiM(goodEle->scEt,goodEle->scEta,goodEle->scPhi,ELE_MASS);
                    }

                    //
                    // Fill tree
                    //
                    runNum    = info->runNum;
                    lumiSec   = info->lumiSec;
                    evtNum    = info->evtNum;

                    vertexArr->Clear();
                    vertexBr->GetEntry(ientry);

                    npv      = vertexArr->GetEntries();
                    npu	    = info->nPUmean;
                    genV      = new TLorentzVector(0,0,0,0);
                    genLep    = new TLorentzVector(0,0,0,0);
                    genVPt    = -999;
                    genVPhi   = -999;
                    genVy     = -999;
                    genVMass  = -999;
                    genLepPt  = -999;
                    genLepPhi = -999;
                    u1        = -999;
                    u2        = -999;
                    tkU1      = -999;
                    tkU2      = -999;
                    mvaU1     = -999;
                    mvaU2     = -999;
                    puppiU1     = -999;
                    puppiU2     = -999;
                    id_1      = -999;
                    id_2      = -999;
                    x_1       = -999;
                    x_2       = -999;
                    xPDF_1    = -999;
                    xPDF_2    = -999;
                    scalePDF  = -999;
                    weightPDF = -999;

                    if(isSignal && hasGen) {
                        TLorentzVector *gvec=new TLorentzVector(0,0,0,0);
                        TLorentzVector *glep1=new TLorentzVector(0,0,0,0);
                        TLorentzVector *glep2=new TLorentzVector(0,0,0,0);
                        toolbox::fillGen(genPartArr, BOSON_ID, gvec, glep1, glep2,1);

                        if (gvec && glep1) {
                            genV      = new TLorentzVector(0,0,0,0);
                            genV->SetPtEtaPhiM(gvec->Pt(),gvec->Eta(),gvec->Phi(),gvec->M());
                            genLep    = new TLorentzVector(0,0,0,0);
                            genLep->SetPtEtaPhiM(glep1->Pt(),glep1->Eta(),glep1->Phi(),glep1->M());
                            genVPt    = gvec->Pt();
                            genVPhi   = gvec->Phi();
                            genVy     = gvec->Rapidity();
                            genVMass  = gvec->M();
                            genLepPt  = glep1->Pt();
                            genLepPhi = glep1->Phi();

                            TVector2 vWPt((genVPt)*cos(genVPhi),(genVPt)*sin(genVPhi));
                            TVector2 vLepPt(vLep.Px(),vLep.Py());

                            TVector2 vMet((info->pfMETC)*cos(info->pfMETCphi), (info->pfMETC)*sin(info->pfMETCphi));
                            TVector2 vU = -1.0*(vMet+vLepPt);
                            u1 = ((vWPt.Px())*(vU.Px()) + (vWPt.Py())*(vU.Py()))/(genVPt);  // u1 = (pT . u)/|pT|
                            u2 = ((vWPt.Px())*(vU.Py()) - (vWPt.Py())*(vU.Px()))/(genVPt);  // u2 = (pT x u)/|pT|

                            TVector2 vTkMet((info->trkMET)*cos(info->trkMETphi), (info->trkMET)*sin(info->trkMETphi));
                            TVector2 vTkU = -1.0*(vTkMet+vLepPt);
                            tkU1 = ((vWPt.Px())*(vTkU.Px()) + (vWPt.Py())*(vTkU.Py()))/(genVPt);  // u1 = (pT . u)/|pT|
                            tkU2 = ((vWPt.Px())*(vTkU.Py()) - (vWPt.Py())*(vTkU.Px()))/(genVPt);  // u2 = (pT x u)/|pT|

                            TVector2 vMvaMet((info->mvaMET)*cos(info->mvaMETphi), (info->mvaMET)*sin(info->mvaMETphi));
                            TVector2 vMvaU = -1.0*(vMvaMet+vLepPt);
                            mvaU1 = ((vWPt.Px())*(vMvaU.Px()) + (vWPt.Py())*(vMvaU.Py()))/(genVPt);  // u1 = (pT . u)/|pT|
                            mvaU2 = ((vWPt.Px())*(vMvaU.Py()) - (vWPt.Py())*(vMvaU.Px()))/(genVPt);  // u2 = (pT x u)/|pT|

                            TVector2 vPuppiMet((info->puppET)*cos(info->puppETphi), (info->puppET)*sin(info->puppETphi));
                            TVector2 vPuppiU = -1.0*(vPuppiMet+vLepPt);
                            puppiU1 = ((vWPt.Px())*(vPuppiU.Px()) + (vWPt.Py())*(vPuppiU.Py()))/(genVPt);  // u1 = (pT . u)/|pT|
                            puppiU2 = ((vWPt.Px())*(vPuppiU.Py()) - (vWPt.Py())*(vPuppiU.Px()))/(genVPt);  // u2 = (pT x u)/|pT|

                        }
                        id_1      = gen->id_1;
                        id_2      = gen->id_2;
                        x_1       = gen->x_1;
                        x_2       = gen->x_2;
                        xPDF_1    = gen->xPDF_1;
                        xPDF_2    = gen->xPDF_2;
                        scalePDF  = gen->scalePDF;
                        weightPDF = gen->weight;

                        delete gvec;
                        delete glep1;
                        delete glep2;
                        gvec=0;
                        glep1=0;
                        glep2=0;
                    }
                    scale1fb = weight;
                    puWeight = h_rw->GetBinContent(h_rw->FindBin(npu));
                    puWeightUp = h_rw_up->GetBinContent(h_rw_up->FindBin(npu));
                    puWeightDown = h_rw_down->GetBinContent(h_rw_down->FindBin(npu));
                    met	   = info->pfMETC;
                    metPhi   = info->pfMETCphi;
                    sumEt    = 0;
                    mt       = sqrt( 2.0 * (vLep.Pt()) * (info->pfMETC) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->pfMETCphi))) );
                    tkMet	   = info->trkMET;
                    tkMetPhi = info->trkMETphi;
                    tkSumEt  = 0;
                    tkMt     = sqrt( 2.0 * (vLep.Pt()) * (info->trkMET) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->trkMETphi))) );
                    mvaMet   = info->mvaMET;
                    mvaMetPhi = info->mvaMETphi;
                    mvaSumEt  = 0;
                    mvaMt     = sqrt( 2.0 * (vLep.Pt()) * (info->mvaMET) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->mvaMETphi))) );
// 	  TVector2 vLepPt(vLep.Px(),vLep.Py());
// 	  TVector2 vPuppi((info->puppET)*cos(info->puppETphi), (info->puppET)*sin(info->puppETphi));
// 	  TVector2 vpp; vpp=vPuppi-vLepPt;
                    puppiMet   = info->puppET;
                    puppiMetPhi = info->puppETphi;
                    puppiSumEt  = 0;
                    puppiMt     = sqrt( 2.0 * (vLep.Pt()) * (info->puppET) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->puppETphi))) );
                    q        = goodEle->q;
                    lep      = &vLep;

                    ///// electron specific /////
                    sc       = &vSC;
                    trkIso    = goodEle->trkIso;
                    emIso     = goodEle->ecalIso;
                    hadIso    = goodEle->hcalIso;
                    pfChIso   = goodEle->chHadIso;
                    pfGamIso  = goodEle->gammaIso;
                    pfNeuIso  = goodEle->neuHadIso;
                    pfCombIso = goodEle->chHadIso + TMath::Max(goodEle->neuHadIso + goodEle->gammaIso -
                                (info->rhoIso)*getEffAreaEl(goodEle->scEta), 0.);
                    sigieie   = goodEle->sieie;
                    hovere    = goodEle->hovere;
                    eoverp    = goodEle->eoverp;
                    fbrem     = goodEle->fbrem;
                    dphi      = goodEle->dPhiIn;
                    deta      = goodEle->dEtaIn;
                    ecalE     = goodEle->ecalEnergy;
                    d0        = goodEle->d0;
                    dz        = goodEle->dz;
                    isConv    = goodEle->isConv;
                    nexphits  = goodEle->nMissingHits;
                    typeBits  = goodEle->typeBits;

                    outTree->Fill();
                    delete genV;
                    delete genLep;
                    genV=0, genLep=0, lep=0, sc=0;
                }
            }
            delete infile;
            infile=0, eventTree=0;

            cout << nsel  << " +/- " << sqrt(nselvar);
            if(isam!=0) cout << " per 1/pb";
            cout << endl;
        }
        outFile->Write();
        outFile->Close();
    }
    delete h_rw;
    delete h_rw_up;
    delete h_rw_down;
    delete f_rw;
    delete info;
    delete gen;
    delete genPartArr;
    delete electronArr;
    delete vertexArr;

    //--------------------------------------------------------------------------------------------------------------
    // Output
    //==============================================================================================================

    cout << "*" << endl;
    cout << "* SUMMARY" << endl;
    cout << "*--------------------------------------------------" << endl;
    cout << " W -> e nu" << endl;
    cout << "  pT > " << PT_CUT << endl;
    cout << "  |eta| < " << ETA_CUT << endl;
    if(doScaleCorr)
        cout << "  *** Scale corrections applied ***" << endl;
    cout << endl;

    cout << endl;
    cout << "  <> Output saved in " << outputDir << "/" << endl;
    cout << endl;

    gBenchmark->Show("selectWe");
}
Esempio n. 25
0
void Plotter_sbatb2(){

  
  Int_t mA=248;
  TString strmA = "248";
  Int_t mH=500;
  TString strmH = "500";

  gStyle->SetOptStat(0);
  gStyle->SetOptTitle(0);

  gStyle->SetPadLeftMargin(0.1191275);
  gStyle->SetPadRightMargin(0.05944056);
  gStyle->SetPadTopMargin(0.05944056);
  gStyle->SetPadBottomMargin(0.1206294);

  gStyle->SetTitleSize(0.04, "XYZ");
  gStyle->SetTitleXOffset(1.1);
  gStyle->SetTitleYOffset(1.45);
  gStyle->SetPalette(1);
  gStyle->SetNdivisions(505);
  gStyle->SetLabelSize(0.04,"XYZ");



  // Getting the limits from combine root files 

  TString file_path_sig1 = "/home/fynu/amertens/storage/CMSSW/CMSSW_6_1_1/src/HiggsAnalysis/CombinedLimit/python/v1_MH_"+strmH+"_Asymptotic_Unblind_Combined_/higgsCombineTest.Asymptotic.mA"+strmA+".root";

  Double_t limit;

  TGraph2D* myTGraph_ratio = new TGraph2D(10);
  myTGraph_ratio->SetName("Ratio CMSSW/Delphes");
  myTGraph_ratio->SetTitle("Ratio CMSSW/Delphes");
  myTGraph_ratio->SetPoint(0,35,142,0.411);
  myTGraph_ratio->SetPoint(1,10,200,0.838);
  myTGraph_ratio->SetPoint(2,110,200,0.796);
  myTGraph_ratio->SetPoint(3,30,329,0.826);
  myTGraph_ratio->SetPoint(4,70,329,0.897);
  myTGraph_ratio->SetPoint(5,70,575,0.955);
  myTGraph_ratio->SetPoint(6,70,875,0.907);
  myTGraph_ratio->SetPoint(7,142,329,0.925);
  myTGraph_ratio->SetPoint(8,142,875,0.927);
  myTGraph_ratio->SetPoint(9,378,575,0.891);
  myTGraph_ratio->SetPoint(10,378,875,0.911);
  myTGraph_ratio->SetPoint(11,575,875,0.890);
  myTGraph_ratio->SetPoint(12,761,875,0.849);
  myTGraph_ratio->SetPoint(13,50,1200,0.9);
  myTGraph_ratio->SetPoint(14,1200,1200,0.85);

  Double_t ratio = myTGraph_ratio->Interpolate(mA,mH);

  pathDelphesEff = "/home/fynu/amertens/storage/THDM/eff_v1/"+strmH+"_"+strmA+".root";
  DelphesFile = TFile(pathDelphesEff);
  TGraph2D* myG2D = DelphesFile.Get("Graph2D");
  Double_t eff = myG2D->Interpolate(int(mA),int(mH));

  Double_t lumi = 19.7;
  cout << "efficiency : " << eff << " ratio : " << ratio << endl;
  Double_t LumiEff = eff*ratio*lumi;

  TFile* f_Sig1 = new TFile(file_path_sig1);
  TTree* tree_Sig1 = (TTree*) f_Sig1->Get("limit");

  TBranch *branch  = tree_Sig1->GetBranch("limit");
  branch->SetAddress(&limit);

  branch->GetEntry(5);
  Double_t limit_obs = limit /(0.067*LumiEff);
  branch->GetEntry(0);
  Double_t limit_m2 = limit /(0.067*LumiEff);
  branch->GetEntry(1);
  Double_t limit_m1 = limit /(0.067*LumiEff);
  branch->GetEntry(2);
  Double_t limit_exp = limit /(0.067*LumiEff);
  branch->GetEntry(3);
  Double_t limit_p1 = limit /(0.067*LumiEff);
  branch->GetEntry(4);
  Double_t limit_p2 = limit /(0.067*LumiEff);

  // Limit vs TanBeta cosba
  TString Xsec_path = "/home/fynu/amertens/Delphes/delphes/condor/xsec_H_ZA_ll_bb_tautau_tanb_cosba_"+strmH+"_"+strmA+".root";
  TFile *f4 = new TFile(Xsec_path);
  TCanvas* C_tbcba = new TCanvas("C_tbcba","C_tbcba",600,600);

  gPad->SetGrid();

  C_tbcba->SetLogy(true);
  //C_tbcba->SetRightMargin(0.17);

  TH2D* h_tbcba = f4->Get("h_HZbbXsec");

  TGraph* g_obs = getContourFilledX(h_tbcba, C_tbcba, 3, 1,3645, limit_obs);
  TGraph* g_exp = getContourFilledX(h_tbcba, C_tbcba, 3, 7,0, limit_exp);


  Double_t contours[6];
  contours[0] = limit_m2;
  contours[1] = limit_m1;
  contours[2] = limit_exp;
  contours[3] = limit_p1;
  contours[4] = limit_p2;
  h_tbcba->SetContour(5, contours);

  TH2D* finalPlot_tbcba = h_tbcba;

  Int_t colors[] = {kYellow, kGreen, kGreen, kYellow, kWhite}; // #colors >= #levels - 1
  gStyle->SetPalette((sizeof(colors)/sizeof(Int_t)), colors);

  DrawThis();

  finalPlot_tbcba->Draw("cont list same");

  cout << "limits : " << limit_m2 << endl;
  cout << "limits : " << limit_m1 << endl;
  cout << "limits : " << limit_exp << endl;
  cout << "limits : " << limit_p1 << endl;
  cout << "limits : " << limit_p2 << endl;

  cout << "limits obs : " << limit_obs << endl;

   

//  TGraph* g_obs = getContourFilledX(finalPlot_tbcba, C_tbcba, 3, 1,3004, limit_obs);
//  TGraph* g_exp = getContourFilledX(finalPlot_tbcba, C_tbcba, 3, 7,4000, limit_exp);

  g_obs->Draw("CL F same");
  g_exp->Draw("CL F same");

  DrawMasses("M_{H} = 330 GeV", "M_{A} = 100 GeV");

  TGraph* g_yellow = new TGraph();
  g_yellow->SetFillColor(kYellow);
  TGraph* g_green = new TGraph();
  g_green->SetFillColor(kGreen);



  TLegend* leg = new TLegend(0.7,0.5,0.9,0.7);
  //leg->SetHeader("#splitline{THDM type II}{#splitline{M_{H} = 378}{M_{A} = 216}}");
  leg->SetLineColor(0);
  leg->SetFillColor(0);
  leg->AddEntry(g_obs,"Obs. Excl.","F");
  leg->AddEntry(g_exp,"Exp. Excl.","l");  
  leg->AddEntry(g_green,"1-sigma","F");
  leg->AddEntry(g_yellow,"2-sigma","F");
  leg->Draw();

  gPad->RedrawAxis("g"); // for "grid lines"

}
void computeAccSelZmmBinned_PileupSys(const TString conf,      // input file
			    const TString inputDir,
                            const TString outputDir,  // output directory
			    const Int_t   doPU,
			    const TString PUtype
) {
  gBenchmark->Start("computeAccSelZmmBinned");

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //============================================================================================================== 

  const Double_t MASS_LOW   = 60;
  const Double_t MASS_HIGH  = 120;
  const Double_t PT_CUT     = 25;
  const Double_t ETA_CUT    = 2.4;
  const Double_t MUON_MASS  = 0.105658369;

  const Int_t BOSON_ID  = 23;
  const Int_t LEPTON_ID = 13;
  
  // efficiency files
  const TString dataHLTEffName_pos = inputDir + "MuHLTEff/MGpositive/eff.root";
  const TString dataHLTEffName_neg = inputDir + "MuHLTEff/MGnegative/eff.root";
  const TString zmmHLTEffName_pos  = inputDir + "MuHLTEff/CTpositive/eff.root";
  const TString zmmHLTEffName_neg  = inputDir + "MuHLTEff/CTnegative/eff.root";

  const TString dataSelEffName_pos = inputDir + "MuSITEff/MGpositive_FineBin/eff.root";
  const TString dataSelEffName_neg = inputDir + "MuSITEff/MGnegative_FineBin/eff.root";
  const TString zmmSelEffName_pos  = inputDir + "MuSITEff/CTpositive/eff.root";
  const TString zmmSelEffName_neg  = inputDir + "MuSITEff/CTnegative/eff.root";

  const TString dataTrkEffName_pos = inputDir + "MuSITEff/MGpositive_FineBin/eff.root";
  const TString dataTrkEffName_neg = inputDir + "MuSITEff/MGnegative_FineBin/eff.root";
  const TString zmmTrkEffName_pos  = inputDir + "MuSITEff/CTpositive/eff.root";
  const TString zmmTrkEffName_neg  = inputDir + "MuSITEff/CTnegative/eff.root";

  const TString dataStaEffName_pos = inputDir + "MuStaEff/MGpositive/eff.root";
  const TString dataStaEffName_neg = inputDir + "MuStaEff/MGnegative/eff.root";
  const TString zmmStaEffName_pos  = inputDir + "MuStaEff/CTpositive/eff.root";
  const TString zmmStaEffName_neg  = inputDir + "MuStaEff/CTnegative/eff.root";
  
  // load pileup reweighting file
  TFile *f_rw = TFile::Open("../Tools/puWeights_76x.root", "read");
  TH1D *h_rw = (TH1D*) f_rw->Get(PUtype.Data());
 
  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  

  vector<TString> fnamev;  // file name per input file
  vector<TString> labelv;  // TLegend label per input file
  vector<Int_t>   colorv;  // plot color per input file
  vector<Int_t>   linev;   // plot line style per input file

  //
  // parse .conf file
  //
  ifstream ifs;
  ifs.open(conf.Data());
  assert(ifs.is_open());
  string line;
  while(getline(ifs,line)) {
    if(line[0]=='#') continue;
    
    string fname;
    Int_t color, linesty;
    stringstream ss(line);
    ss >> fname >> color >> linesty;
    string label = line.substr(line.find('@')+1);
    fnamev.push_back(fname);
    labelv.push_back(label);
    colorv.push_back(color);
    linev.push_back(linesty);
  }
  ifs.close();

  // Create output directory
  gSystem->mkdir(outputDir,kTRUE);  

  TH2D *h=0;

  //
  // HLT efficiency
  //
  cout << "Loading trigger efficiencies..." << endl;
  
  TFile *dataHLTEffFile_pos = new TFile(dataHLTEffName_pos);
  CEffUser2D dataHLTEff_pos;
  dataHLTEff_pos.loadEff((TH2D*)dataHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *dataHLTEffFile_neg = new TFile(dataHLTEffName_neg);
  CEffUser2D dataHLTEff_neg;
  dataHLTEff_neg.loadEff((TH2D*)dataHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrhEtaPt"));
    
  TFile *zmmHLTEffFile_pos = new TFile(zmmHLTEffName_pos);
  CEffUser2D zmmHLTEff_pos;
  zmmHLTEff_pos.loadEff((TH2D*)zmmHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)zmmHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zmmHLTEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *zmmHLTEffFile_neg = new TFile(zmmHLTEffName_neg);
  CEffUser2D zmmHLTEff_neg;
  zmmHLTEff_neg.loadEff((TH2D*)zmmHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)zmmHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zmmHLTEffFile_neg->Get("hErrhEtaPt"));

  h =(TH2D*)dataHLTEffFile_pos->Get("hEffEtaPt");
  TH2D *hHLTErr_pos = new TH2D("hHLTErr_pos", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
			       h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  TH2D *hHLTErr_neg = new TH2D("hHLTErr_neg", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
			       h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  
  //
  // Selection efficiency
  //
  cout << "Loading selection efficiencies..." << endl;
  
  TFile *dataSelEffFile_pos = new TFile(dataSelEffName_pos);
  CEffUser2D dataSelEff_pos;
  dataSelEff_pos.loadEff((TH2D*)dataSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataSelEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *dataSelEffFile_neg = new TFile(dataSelEffName_neg);
  CEffUser2D dataSelEff_neg;
  dataSelEff_neg.loadEff((TH2D*)dataSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataSelEffFile_neg->Get("hErrhEtaPt"));
  
  TFile *zmmSelEffFile_pos = new TFile(zmmSelEffName_pos);
  CEffUser2D zmmSelEff_pos;
  zmmSelEff_pos.loadEff((TH2D*)zmmSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)zmmSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zmmSelEffFile_pos->Get("hErrhEtaPt"));

  TFile *zmmSelEffFile_neg = new TFile(zmmSelEffName_neg);
  CEffUser2D zmmSelEff_neg;
  zmmSelEff_neg.loadEff((TH2D*)zmmSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)zmmSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zmmSelEffFile_neg->Get("hErrhEtaPt"));

  h =(TH2D*)dataSelEffFile_pos->Get("hEffEtaPt");
  TH2D *hSelErr_pos = new TH2D("hSelErr_pos", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
			       h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  TH2D *hSelErr_neg = new TH2D("hSelErr_neg", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
			       h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());

  //
  // Standalone efficiency
  //
  cout << "Loading standalone efficiencies..." << endl;
  
  TFile *dataStaEffFile_pos = new TFile(dataStaEffName_pos);
  CEffUser2D dataStaEff_pos;
  dataStaEff_pos.loadEff((TH2D*)dataStaEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataStaEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataStaEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *dataStaEffFile_neg = new TFile(dataStaEffName_neg);
  CEffUser2D dataStaEff_neg;
  dataStaEff_neg.loadEff((TH2D*)dataStaEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataStaEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataStaEffFile_neg->Get("hErrhEtaPt"));
  
  TFile *zmmStaEffFile_pos = new TFile(zmmStaEffName_pos);
  CEffUser2D zmmStaEff_pos;
  zmmStaEff_pos.loadEff((TH2D*)zmmStaEffFile_pos->Get("hEffEtaPt"), (TH2D*)zmmStaEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zmmStaEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *zmmStaEffFile_neg = new TFile(zmmStaEffName_neg);
  CEffUser2D zmmStaEff_neg;
  zmmStaEff_neg.loadEff((TH2D*)zmmStaEffFile_neg->Get("hEffEtaPt"), (TH2D*)zmmStaEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zmmStaEffFile_neg->Get("hErrhEtaPt"));

  h =(TH2D*)dataStaEffFile_pos->Get("hEffEtaPt");
  TH2D *hStaErr_pos = new TH2D("hStaErr_pos", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
			       h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  TH2D *hStaErr_neg = new TH2D("hStaErr_neg", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
			       h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());

  //
  // Tracker efficiency
  //
  cout << "Loading track efficiencies..." << endl;
  
  TFile *dataTrkEffFile_pos = new TFile(dataTrkEffName_pos);
  CEffUser2D dataTrkEff_pos;
  dataTrkEff_pos.loadEff((TH2D*)dataTrkEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataTrkEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataTrkEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *dataTrkEffFile_neg = new TFile(dataTrkEffName_neg);
  CEffUser2D dataTrkEff_neg;
  dataTrkEff_neg.loadEff((TH2D*)dataTrkEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataTrkEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataTrkEffFile_neg->Get("hErrhEtaPt"));
  
  TFile *zmmTrkEffFile_pos = new TFile(zmmTrkEffName_pos);
  CEffUser2D zmmTrkEff_pos;
  zmmTrkEff_pos.loadEff((TH2D*)zmmTrkEffFile_pos->Get("hEffEtaPt"), (TH2D*)zmmTrkEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zmmTrkEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *zmmTrkEffFile_neg = new TFile(zmmTrkEffName_neg);
  CEffUser2D zmmTrkEff_neg;
  zmmTrkEff_neg.loadEff((TH2D*)zmmTrkEffFile_neg->Get("hEffEtaPt"), (TH2D*)zmmTrkEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zmmTrkEffFile_neg->Get("hErrhEtaPt"));

  h =(TH2D*)dataTrkEffFile_pos->Get("hEffEtaPt");
  TH2D *hTrkErr_pos = new TH2D("hTrkErr_pos", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
			       h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  TH2D *hTrkErr_neg = new TH2D("hTrkErr_neg", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
			       h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());

  // Data structures to store info from TTrees
  baconhep::TEventInfo *info   = new baconhep::TEventInfo();
  baconhep::TGenEventInfo *gen = new baconhep::TGenEventInfo();
  TClonesArray *genPartArr     = new TClonesArray("baconhep::TGenParticle");
  TClonesArray *muonArr        = new TClonesArray("baconhep::TMuon");
  TClonesArray *vertexArr  = new TClonesArray("baconhep::TVertex");
  
  TFile *infile=0;
  TTree *eventTree=0;
   
  // Variables to store acceptances and uncertainties (per input file)
  vector<Double_t> nEvtsv, nSelv;
  vector<Double_t> nSelCorrv, nSelCorrVarv;
  vector<Double_t> accv, accCorrv;
  vector<Double_t> accErrv, accErrCorrv;

  const baconhep::TTrigger triggerMenu("../../BaconAna/DataFormats/data/HLT_50nsGRun");
  
  //
  // loop through files
  //
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {  

    // Read input file and get the TTrees
    cout << "Processing " << fnamev[ifile] << " ..." << endl;
    infile = TFile::Open(fnamev[ifile]); 
    assert(infile);
  
    eventTree = (TTree*)infile->Get("Events"); assert(eventTree);  
    eventTree->SetBranchAddress("Info",             &info); TBranch *infoBr = eventTree->GetBranch("Info");
    eventTree->SetBranchAddress("GenEvtInfo",        &gen); TBranch *genBr  = eventTree->GetBranch("GenEvtInfo");
    eventTree->SetBranchAddress("GenParticle",&genPartArr); TBranch* genPartBr = eventTree->GetBranch("GenParticle");
    eventTree->SetBranchAddress("Muon",          &muonArr); TBranch *muonBr = eventTree->GetBranch("Muon");   
    eventTree->SetBranchAddress("PV",   &vertexArr); TBranch *vertexBr = eventTree->GetBranch("PV");

    nEvtsv.push_back(0);
    nSelv.push_back(0);
    nSelCorrv.push_back(0);
    nSelCorrVarv.push_back(0);

    //
    // loop over events
    //      
    for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
      genBr->GetEntry(ientry);
      genPartArr->Clear(); genPartBr->GetEntry(ientry);
      infoBr->GetEntry(ientry);

      Int_t glepq1=-99;
      Int_t glepq2=-99;

      if (fabs(toolbox::flavor(genPartArr, BOSON_ID))!=LEPTON_ID) continue;
      TLorentzVector *vec=new TLorentzVector(0,0,0,0);
      TLorentzVector *lep1=new TLorentzVector(0,0,0,0);
      TLorentzVector *lep2=new TLorentzVector(0,0,0,0);
      toolbox::fillGen(genPartArr, BOSON_ID, vec, lep1, lep2,&glepq1,&glepq2,1);
      if(vec->M()<MASS_LOW || vec->M()>MASS_HIGH) continue;
      delete vec; delete lep1; delete lep2;

      vertexArr->Clear();
      vertexBr->GetEntry(ientry);
      double npv  = vertexArr->GetEntries();
      Double_t weight=gen->weight;
      if(doPU>0) weight*=h_rw->GetBinContent(h_rw->FindBin(info->nPUmean));

      nEvtsv[ifile]+=weight;
      
      // trigger requirement               
      if (!isMuonTrigger(triggerMenu, info->triggerBits)) continue;

      // good vertex requirement
      if(!(info->hasGoodPV)) continue;
    
      muonArr->Clear();
      muonBr->GetEntry(ientry);

      for(Int_t i1=0; i1<muonArr->GetEntriesFast(); i1++) {
  	const baconhep::TMuon *mu1 = (baconhep::TMuon*)((*muonArr)[i1]);

        if(mu1->pt	  < PT_CUT)  continue;  // lepton pT cut
        if(fabs(mu1->eta) > ETA_CUT) continue;  // lepton |eta| cut
        if(!passMuonID(mu1))	     continue;  // lepton selection
	
	TLorentzVector vMu1(0,0,0,0);
	vMu1.SetPtEtaPhiM(mu1->pt, mu1->eta, mu1->phi, MUON_MASS);

        for(Int_t i2=i1+1; i2<muonArr->GetEntriesFast(); i2++) {
          const baconhep::TMuon *mu2 = (baconhep::TMuon*)((*muonArr)[i2]);
        
          if(mu1->q == mu2->q)	       continue;  // opposite charge requirement
          if(mu2->pt        < PT_CUT)  continue;  // lepton pT cut
          if(fabs(mu2->eta) > ETA_CUT) continue;  // lepton |eta| cut
	  if(!passMuonID(mu2))	       continue;  // lepton selection

          TLorentzVector vMu2(0,0,0,0);
	  vMu2.SetPtEtaPhiM(mu2->pt, mu2->eta, mu2->phi, MUON_MASS);  

          // trigger match
	  if(!isMuonTriggerObj(triggerMenu, mu1->hltMatchBits, kFALSE) && !isMuonTriggerObj(triggerMenu, mu2->hltMatchBits, kFALSE)) continue;
	  
	  // mass window
          TLorentzVector vDilep = vMu1 + vMu2;
          if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue;
          
          /******** We have a Z candidate! HURRAY! ********/
          Double_t effdata, effmc;
	  Double_t corr=1;
	  
	  effdata=1; effmc=1;    
          if(mu1->q>0) { 
            effdata *= (1.-dataHLTEff_pos.getEff(mu1->eta, mu1->pt)); 
            effmc   *= (1.-zmmHLTEff_pos.getEff(mu1->eta, mu1->pt)); 
          } else {
            effdata *= (1.-dataHLTEff_neg.getEff(mu1->eta, mu1->pt)); 
            effmc   *= (1.-zmmHLTEff_neg.getEff(mu1->eta, mu1->pt)); 
          }
          if(mu2->q>0) {
            effdata *= (1.-dataHLTEff_pos.getEff(mu2->eta, mu2->pt)); 
            effmc   *= (1.-zmmHLTEff_pos.getEff(mu2->eta, mu2->pt));
          } else {
            effdata *= (1.-dataHLTEff_neg.getEff(mu2->eta, mu2->pt)); 
            effmc   *= (1.-zmmHLTEff_neg.getEff(mu2->eta, mu2->pt));
          }
          effdata = 1.-effdata;
          effmc   = 1.-effmc;
          corr *= effdata/effmc;
    
          effdata=1; effmc=1;
          if(mu1->q>0) { 
            effdata *= dataSelEff_pos.getEff(mu1->eta, mu1->pt); 
            effmc   *= zmmSelEff_pos.getEff(mu1->eta, mu1->pt); 
          } else {
            effdata *= dataSelEff_neg.getEff(mu1->eta, mu1->pt); 
            effmc   *= zmmSelEff_neg.getEff(mu1->eta, mu1->pt); 
          }
          if(mu2->q>0) {
            effdata *= dataSelEff_pos.getEff(mu2->eta, mu2->pt); 
            effmc   *= zmmSelEff_pos.getEff(mu2->eta, mu2->pt);
          } else {
            effdata *= dataSelEff_neg.getEff(mu2->eta, mu2->pt); 
            effmc   *= zmmSelEff_neg.getEff(mu2->eta, mu2->pt);
          }
          corr *= effdata/effmc;
    
          effdata=1; effmc=1;
          if(mu1->q>0) { 
            effdata *= dataStaEff_pos.getEff(mu1->eta, mu1->pt); 
            effmc   *= zmmStaEff_pos.getEff(mu1->eta, mu1->pt); 
          } else {
            effdata *= dataStaEff_neg.getEff(mu1->eta, mu1->pt); 
            effmc   *= zmmStaEff_neg.getEff(mu1->eta, mu1->pt); 
          }
          if(mu2->q>0) {
            effdata *= dataStaEff_pos.getEff(mu2->eta, mu2->pt); 
            effmc   *= zmmStaEff_pos.getEff(mu2->eta, mu2->pt);
          } else {
            effdata *= dataStaEff_neg.getEff(mu2->eta, mu2->pt); 
            effmc   *= zmmStaEff_neg.getEff(mu2->eta, mu2->pt);
          }
          corr *= effdata/effmc;
    
          effdata=1; effmc=1;
          if(mu1->q>0) { 
            effdata *= dataTrkEff_pos.getEff(mu1->eta, mu1->pt); 
            effmc   *= zmmTrkEff_pos.getEff(mu1->eta, mu1->pt); 
          } else {
            effdata *= dataTrkEff_neg.getEff(mu1->eta, mu1->pt); 
            effmc   *= zmmTrkEff_neg.getEff(mu1->eta, mu1->pt); 
          }
          if(mu2->q>0) {
            effdata *= dataTrkEff_pos.getEff(mu2->eta, mu2->pt); 
            effmc   *= zmmTrkEff_pos.getEff(mu2->eta, mu2->pt);
          } else {
            effdata *= dataTrkEff_neg.getEff(mu2->eta, mu2->pt); 
            effmc   *= zmmTrkEff_neg.getEff(mu2->eta, mu2->pt);
          }
          //corr *= effdata/effmc;
	  
	  // scale factor uncertainties                                                                                                                                         
	  // TRACKER
          if(mu1->q>0) {
            Double_t effdata = dataTrkEff_pos.getEff(mu1->eta, mu1->pt);
            Double_t errdata = TMath::Max(dataTrkEff_pos.getErrLow(mu1->eta, mu1->pt), dataTrkEff_pos.getErrHigh(mu1->eta, mu1->pt));
            Double_t effmc   = zmmTrkEff_pos.getEff(mu1->eta, mu1->pt);
            Double_t errmc   = TMath::Max(zmmTrkEff_pos.getErrLow(mu1->eta, mu1->pt), zmmTrkEff_pos.getErrHigh(mu1->eta, mu1->pt));
            Double_t errTrk = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hTrkErr_pos->Fill(mu1->eta, mu1->pt, errTrk);
          } else {
            Double_t effdata = dataTrkEff_neg.getEff(mu1->eta, mu1->pt);
            Double_t errdata = TMath::Max(dataTrkEff_neg.getErrLow(mu1->eta, mu1->pt), dataTrkEff_neg.getErrHigh(mu1->eta, mu1->pt));
            Double_t effmc   = zmmTrkEff_neg.getEff(mu1->eta, mu1->pt);
            Double_t errmc   = TMath::Max(zmmTrkEff_neg.getErrLow(mu1->eta, mu1->pt), zmmTrkEff_neg.getErrHigh(mu1->eta, mu1->pt));
            Double_t errTrk = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hTrkErr_neg->Fill(mu1->eta, mu1->pt, errTrk);
          }

          if(mu2->q>0) {
            Double_t effdata = dataTrkEff_pos.getEff(mu2->eta, mu2->pt);
            Double_t errdata = TMath::Max(dataTrkEff_pos.getErrLow(mu2->eta, mu2->pt), dataTrkEff_pos.getErrHigh(mu2->eta, mu2->pt));
            Double_t effmc   = zmmTrkEff_pos.getEff(mu2->eta, mu2->pt);
            Double_t errmc   = TMath::Max(zmmTrkEff_pos.getErrLow(mu2->eta, mu2->pt), zmmTrkEff_pos.getErrHigh(mu2->eta, mu2->pt));
            Double_t errTrk = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
	    /*   if(mu2->eta>1.2 && mu2->eta<2.1) 
	      {
		errTrk=0.0013;
		}*/
            hTrkErr_pos->Fill(mu2->eta, mu2->pt, errTrk);
          } else {
            Double_t effdata = dataTrkEff_neg.getEff(mu2->eta, mu2->pt);
            Double_t errdata = TMath::Max(dataTrkEff_neg.getErrLow(mu2->eta, mu2->pt), dataTrkEff_neg.getErrHigh(mu2->eta, mu2->pt));
            Double_t effmc   = zmmTrkEff_neg.getEff(mu2->eta, mu2->pt);
            Double_t errmc   = TMath::Max(zmmTrkEff_neg.getErrLow(mu2->eta, mu2->pt), zmmTrkEff_neg.getErrHigh(mu2->eta, mu2->pt));
            Double_t errTrk = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
	    /*  if(mu2->eta>1.2 && mu2->eta<2.1) 
	      {
		errTrk=0.0013;
	      }
	      hTrkErr_neg->Fill(mu2->eta, mu2->pt, errTrk);*/
          }
	  // STANDALONE
          if(mu1->q>0) {
            Double_t effdata = dataStaEff_pos.getEff(mu1->eta, mu1->pt);
            Double_t errdata = TMath::Max(dataStaEff_pos.getErrLow(mu1->eta, mu1->pt), dataStaEff_pos.getErrHigh(mu1->eta, mu1->pt));
            Double_t effmc   = zmmStaEff_pos.getEff(mu1->eta, mu1->pt);
            Double_t errmc   = TMath::Max(zmmStaEff_pos.getErrLow(mu1->eta, mu1->pt), zmmStaEff_pos.getErrHigh(mu1->eta, mu1->pt));
            Double_t errSta = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hStaErr_pos->Fill(mu1->eta, mu1->pt, errSta);
          } else {
            Double_t effdata = dataStaEff_neg.getEff(mu1->eta, mu1->pt);
            Double_t errdata = TMath::Max(dataStaEff_neg.getErrLow(mu1->eta, mu1->pt), dataStaEff_neg.getErrHigh(mu1->eta, mu1->pt));
            Double_t effmc   = zmmStaEff_neg.getEff(mu1->eta, mu1->pt);
            Double_t errmc   = TMath::Max(zmmStaEff_neg.getErrLow(mu1->eta, mu1->pt), zmmStaEff_neg.getErrHigh(mu1->eta, mu1->pt));
            Double_t errSta = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hStaErr_neg->Fill(mu1->eta, mu1->pt, errSta);
          }

          if(mu2->q>0) {
            Double_t effdata = dataStaEff_pos.getEff(mu2->eta, mu2->pt);
            Double_t errdata = TMath::Max(dataStaEff_pos.getErrLow(mu2->eta, mu2->pt), dataStaEff_pos.getErrHigh(mu2->eta, mu2->pt));
            Double_t effmc   = zmmStaEff_pos.getEff(mu2->eta, mu2->pt);
            Double_t errmc   = TMath::Max(zmmStaEff_pos.getErrLow(mu2->eta, mu2->pt), zmmStaEff_pos.getErrHigh(mu2->eta, mu2->pt));
            Double_t errSta = ((effdata/effmc))*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hStaErr_pos->Fill(mu2->eta, mu2->pt, errSta);
          } else {
            Double_t effdata = dataStaEff_neg.getEff(mu2->eta, mu2->pt);
            Double_t errdata = TMath::Max(dataStaEff_neg.getErrLow(mu2->eta, mu2->pt), dataStaEff_neg.getErrHigh(mu2->eta, mu2->pt));
            Double_t effmc   = zmmStaEff_neg.getEff(mu2->eta, mu2->pt);
            Double_t errmc   = TMath::Max(zmmStaEff_neg.getErrLow(mu2->eta, mu2->pt), zmmStaEff_neg.getErrHigh(mu2->eta, mu2->pt));
            Double_t errSta = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hStaErr_neg->Fill(mu2->eta, mu2->pt, errSta);
	  }

	  // SELECTION
          if(mu1->q>0) {
            Double_t effdata = dataSelEff_pos.getEff(mu1->eta, mu1->pt);
            Double_t errdata = TMath::Max(dataSelEff_pos.getErrLow(mu1->eta, mu1->pt), dataSelEff_pos.getErrHigh(mu1->eta, mu1->pt));
            Double_t effmc   = zmmSelEff_pos.getEff(mu1->eta, mu1->pt);
            Double_t errmc   = TMath::Max(zmmSelEff_pos.getErrLow(mu1->eta, mu1->pt), zmmSelEff_pos.getErrHigh(mu1->eta, mu1->pt));
            Double_t errSel = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hSelErr_pos->Fill(mu1->eta, mu1->pt, errSel);
          } else {
            Double_t effdata = dataSelEff_neg.getEff(mu1->eta, mu1->pt);
            Double_t errdata = TMath::Max(dataSelEff_neg.getErrLow(mu1->eta, mu1->pt), dataSelEff_neg.getErrHigh(mu1->eta, mu1->pt));
            Double_t effmc   = zmmSelEff_neg.getEff(mu1->eta, mu1->pt);
            Double_t errmc   = TMath::Max(zmmSelEff_neg.getErrLow(mu1->eta, mu1->pt), zmmSelEff_neg.getErrHigh(mu1->eta, mu1->pt));
            Double_t errSel = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hSelErr_neg->Fill(mu1->eta, mu1->pt, errSel);
          }

          if(mu2->q>0) {
            Double_t effdata = dataSelEff_pos.getEff(mu2->eta, mu2->pt);
            Double_t errdata = TMath::Max(dataSelEff_pos.getErrLow(mu2->eta, mu2->pt), dataSelEff_pos.getErrHigh(mu2->eta, mu2->pt));
            Double_t effmc   = zmmSelEff_pos.getEff(mu2->eta, mu2->pt);
            Double_t errmc   = TMath::Max(zmmSelEff_pos.getErrLow(mu2->eta, mu2->pt), zmmSelEff_pos.getErrHigh(mu2->eta, mu2->pt));
            Double_t errSel = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hSelErr_pos->Fill(mu2->eta, mu2->pt, errSel);
          } else {
            Double_t effdata = dataSelEff_neg.getEff(mu2->eta, mu2->pt);
            Double_t errdata = TMath::Max(dataSelEff_neg.getErrLow(mu2->eta, mu2->pt), dataSelEff_neg.getErrHigh(mu2->eta, mu2->pt));
            Double_t effmc   = zmmSelEff_neg.getEff(mu2->eta, mu2->pt);
            Double_t errmc   = TMath::Max(zmmSelEff_neg.getErrLow(mu2->eta, mu2->pt), zmmSelEff_neg.getErrHigh(mu2->eta, mu2->pt));
            Double_t errSel = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hSelErr_neg->Fill(mu2->eta, mu2->pt, errSel);
	  }

	  //HLT
          if(mu1->q>0) {
            Double_t effdata = dataHLTEff_pos.getEff(mu1->eta, mu1->pt);
            Double_t errdata = TMath::Max(dataHLTEff_pos.getErrLow(mu1->eta, mu1->pt), dataHLTEff_pos.getErrHigh(mu1->eta, mu1->pt));
            Double_t effmc   = zmmHLTEff_pos.getEff(mu1->eta, mu1->pt);
            Double_t errmc   = TMath::Max(zmmHLTEff_pos.getErrLow(mu1->eta, mu1->pt), zmmHLTEff_pos.getErrHigh(mu1->eta, mu1->pt));
            Double_t errHLT = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hHLTErr_pos->Fill(mu1->eta, mu1->pt, errHLT);
          } else {
            Double_t effdata = dataHLTEff_neg.getEff(mu1->eta, mu1->pt);
            Double_t errdata = TMath::Max(dataHLTEff_neg.getErrLow(mu1->eta, mu1->pt), dataHLTEff_neg.getErrHigh(mu1->eta, mu1->pt));
            Double_t effmc   = zmmHLTEff_neg.getEff(mu1->eta, mu1->pt);
            Double_t errmc   = TMath::Max(zmmHLTEff_neg.getErrLow(mu1->eta, mu1->pt), zmmHLTEff_neg.getErrHigh(mu1->eta, mu1->pt));
            Double_t errHLT = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hHLTErr_neg->Fill(mu1->eta, mu1->pt, errHLT);
          }

          if(mu2->q>0) {
            Double_t effdata = dataHLTEff_pos.getEff(mu2->eta, mu2->pt);
            Double_t errdata = TMath::Max(dataHLTEff_pos.getErrLow(mu2->eta, mu2->pt), dataHLTEff_pos.getErrHigh(mu2->eta, mu2->pt));
            Double_t effmc   = zmmHLTEff_pos.getEff(mu2->eta, mu2->pt);
            Double_t errmc   = TMath::Max(zmmHLTEff_pos.getErrLow(mu2->eta, mu2->pt), zmmHLTEff_pos.getErrHigh(mu2->eta, mu2->pt));
            Double_t errHLT = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hHLTErr_pos->Fill(mu2->eta, mu2->pt, errHLT);
          } else {
            Double_t effdata = dataHLTEff_neg.getEff(mu2->eta, mu2->pt);
            Double_t errdata = TMath::Max(dataHLTEff_neg.getErrLow(mu2->eta, mu2->pt), dataHLTEff_neg.getErrHigh(mu2->eta, mu2->pt));
            Double_t effmc   = zmmHLTEff_neg.getEff(mu2->eta, mu2->pt);
            Double_t errmc   = TMath::Max(zmmHLTEff_neg.getErrLow(mu2->eta, mu2->pt), zmmHLTEff_neg.getErrHigh(mu2->eta, mu2->pt));
            Double_t errHLT = (effdata/effmc)*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
            hHLTErr_neg->Fill(mu2->eta, mu2->pt, errHLT);
          }
	  
	  nSelv[ifile]    +=weight;
	  nSelCorrv[ifile]+=weight*corr;
	  nSelCorrVarv[ifile]+=weight*weight*corr*corr;
        }
      }      
    }

    Double_t var=0;
    for(Int_t iy=0; iy<=hHLTErr_pos->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hHLTErr_pos->GetNbinsX(); ix++) {
        Double_t err=hHLTErr_pos->GetBinContent(ix,iy);
        var+=err*err;
      }
    }
    for(Int_t iy=0; iy<=hHLTErr_neg->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hHLTErr_neg->GetNbinsX(); ix++) {
        Double_t err=hHLTErr_neg->GetBinContent(ix,iy);
        var+=err*err;
      }
    }
    for(Int_t iy=0; iy<=hSelErr_pos->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hSelErr_pos->GetNbinsX(); ix++) {
        Double_t err=hSelErr_pos->GetBinContent(ix,iy);
        var+=err*err;
      }
    }
    for(Int_t iy=0; iy<=hSelErr_neg->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hSelErr_neg->GetNbinsX(); ix++) {
        Double_t err=hSelErr_neg->GetBinContent(ix,iy);
        var+=err*err;
      }
    }
    for(Int_t iy=0; iy<=hTrkErr_pos->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hTrkErr_pos->GetNbinsX(); ix++) {
        Double_t err=hTrkErr_pos->GetBinContent(ix,iy);
        //var+=err*err;
	var+=0.0;
      }
    }
    for(Int_t iy=0; iy<=hTrkErr_neg->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hTrkErr_neg->GetNbinsX(); ix++) {
        Double_t err=hTrkErr_neg->GetBinContent(ix,iy);
	var+=0.0;
        //var+=err*err;
      }
    }
    for(Int_t iy=0; iy<=hStaErr_pos->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hStaErr_pos->GetNbinsX(); ix++) {
        Double_t err=hStaErr_pos->GetBinContent(ix,iy);
	var+=err*err;
      }
    }
    for(Int_t iy=0; iy<=hStaErr_neg->GetNbinsY(); iy++) {
      for(Int_t ix=0; ix<=hStaErr_neg->GetNbinsX(); ix++) {
        Double_t err=hStaErr_neg->GetBinContent(ix,iy);
	var+=err*err;
      }
    }

    nSelCorrVarv[ifile]+=var;

    // compute acceptances
    accv.push_back(nSelv[ifile]/nEvtsv[ifile]);     accErrv.push_back(accv[ifile]*sqrt((1.+accv[ifile])/nEvtsv[ifile]));
    accCorrv.push_back(nSelCorrv[ifile]/nEvtsv[ifile]); accErrCorrv.push_back(accCorrv[ifile]*sqrt((nSelCorrVarv[ifile])/(nSelCorrv[ifile]*nSelCorrv[ifile]) + 1./nEvtsv[ifile]));
    
    delete infile;
    infile=0, eventTree=0;  
  }  
  delete info;
  delete gen;
  delete muonArr;

    
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================    
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << " Z -> mu mu" << endl;
  cout << "  Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl;
  cout << "  pT > " << PT_CUT << endl;
  cout << "  |eta| < " << ETA_CUT << endl;
  cout << endl;
  
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
    cout << "   ================================================" << endl;
    cout << "    Label: " << labelv[ifile] << endl;
    cout << "     File: " << fnamev[ifile] << endl;
    cout << endl;
    cout << "    *** Acceptance ***" << endl;
    cout << "          nominal: " << setw(12) << nSelv[ifile]   << " / " << nEvtsv[ifile] << " = " << accv[ifile]   << " +/- " << accErrv[ifile] << endl;
    cout << "     SF corrected: " << accCorrv[ifile] << " +/- " << accErrCorrv[ifile] << endl;
    cout << endl;
  }
  
  char txtfname[100];
  sprintf(txtfname,"%s/binned.txt",outputDir.Data());
  ofstream txtfile;
  txtfile.open(txtfname);
  txtfile << "*" << endl;
  txtfile << "* SUMMARY" << endl;
  txtfile << "*--------------------------------------------------" << endl;
  txtfile << " Z -> mu mu" << endl;
  txtfile << "  Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl;
  txtfile << "  pT > " << PT_CUT << endl;
  txtfile << "  |eta| < " << ETA_CUT << endl;
  txtfile << endl;
  
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
    txtfile << "   ================================================" << endl;
    txtfile << "    Label: " << labelv[ifile] << endl;
    txtfile << "     File: " << fnamev[ifile] << endl;
    txtfile << endl;
    txtfile << "    *** Acceptance ***" << endl;
    txtfile << "          nominal: " << setw(12) << nSelv[ifile]   << " / " << nEvtsv[ifile] << " = " << accv[ifile]   << " +/- " << accErrv[ifile] << endl;
    txtfile << "     SF corrected: " << accCorrv[ifile] << " +/- " << accErrCorrv[ifile] << endl;
    txtfile << endl;
  }
  txtfile.close();
  
  cout << endl;
  cout << "  <> Output saved in " << outputDir << "/" << endl;    
  cout << endl;  
      
  gBenchmark->Show("computeAccSelZmmBinned"); 
}
Esempio n. 27
0
void computeAccSelZmmBinned(const TString conf,      // input file
                            const TString outputDir  // output directory
                           ) {
    gBenchmark->Start("computeAccSelZmmBinned");

    //--------------------------------------------------------------------------------------------------------------
    // Settings
    //==============================================================================================================

    const Double_t MASS_LOW   = 60;
    const Double_t MASS_HIGH  = 120;
    const Double_t PT_CUT     = 25;
    const Double_t ETA_CUT    = 2.1;
    const Double_t MUON_MASS  = 0.105658369;

    // efficiency files
    const TString dataHLTEffName_pos = "../Efficiency/May23_MuHLTEff_pos/analysis/eff.root";
    const TString dataHLTEffName_neg = "../Efficiency/May23_MuHLTEff_neg/analysis/eff.root";
    const TString zmmHLTEffName_pos  = "../Efficiency/Zmm_MuHLTEff_pos/analysis/eff.root";
    const TString zmmHLTEffName_neg  = "../Efficiency/Zmm_MuHLTEff_neg/analysis/eff.root";

    const TString dataSelEffName_pos = "../Efficiency/May23_MuSelEff_pos/analysis/eff.root";
    const TString dataSelEffName_neg = "../Efficiency/May23_MuSelEff_neg/analysis/eff.root";
    const TString zmmSelEffName_pos  = "../Efficiency/Zmm_MuSelEff_pos/analysis/eff.root";
    const TString zmmSelEffName_neg  = "../Efficiency/Zmm_MuSelEff_neg/analysis/eff.root";

    const TString dataTrkEffName_pos = "../Efficiency/May23_MuTrkEff_pos/analysis/eff.root";
    const TString dataTrkEffName_neg = "../Efficiency/May23_MuTrkEff_neg/analysis/eff.root";
    const TString zmmTrkEffName_pos  = "../Efficiency/Zmm_MuTrkEff_pos/analysis/eff.root";
    const TString zmmTrkEffName_neg  = "../Efficiency/Zmm_MuTrkEff_neg/analysis/eff.root";

    const TString dataStaEffName_pos = "../Efficiency/May23_MuStaEff_iso_pos/analysis/eff.root";
    const TString dataStaEffName_neg = "../Efficiency/May23_MuStaEff_iso_neg/analysis/eff.root";
    const TString zmmStaEffName_pos  = "../Efficiency/Zmm_MuStaEff_iso_pos/analysis/eff.root";
    const TString zmmStaEffName_neg  = "../Efficiency/Zmm_MuStaEff_iso_neg/analysis/eff.root";


    //--------------------------------------------------------------------------------------------------------------
    // Main analysis code
    //==============================================================================================================

    vector<TString> fnamev;  // file name per input file
    vector<TString> labelv;  // TLegend label per input file
    vector<Int_t>   colorv;  // plot color per input file
    vector<Int_t>   linev;   // plot line style per input file

    //
    // parse .conf file
    //
    ifstream ifs;
    ifs.open(conf.Data());
    assert(ifs.is_open());
    string line;
    while(getline(ifs,line)) {
        if(line[0]=='#') continue;

        string fname;
        Int_t color, linesty;
        stringstream ss(line);
        ss >> fname >> color >> linesty;
        string label = line.substr(line.find('@')+1);
        fnamev.push_back(fname);
        labelv.push_back(label);
        colorv.push_back(color);
        linev.push_back(linesty);
    }
    ifs.close();

    // Create output directory
    gSystem->mkdir(outputDir,kTRUE);


    //
    // HLT efficiency
    //
    cout << "Loading trigger efficiencies..." << endl;

    TFile *dataHLTEffFile_pos = new TFile(dataHLTEffName_pos);
    CEffUser2D dataHLTEff_pos;
    dataHLTEff_pos.loadEff((TH2D*)dataHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrhEtaPt"));

    TFile *dataHLTEffFile_neg = new TFile(dataHLTEffName_neg);
    CEffUser2D dataHLTEff_neg;
    dataHLTEff_neg.loadEff((TH2D*)dataHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrhEtaPt"));

    TFile *zmmHLTEffFile_pos = new TFile(zmmHLTEffName_pos);
    CEffUser2D zmmHLTEff_pos;
    zmmHLTEff_pos.loadEff((TH2D*)zmmHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)zmmHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zmmHLTEffFile_pos->Get("hErrhEtaPt"));

    TFile *zmmHLTEffFile_neg = new TFile(zmmHLTEffName_neg);
    CEffUser2D zmmHLTEff_neg;
    zmmHLTEff_neg.loadEff((TH2D*)zmmHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)zmmHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zmmHLTEffFile_neg->Get("hErrhEtaPt"));

    //
    // Selection efficiency
    //
    cout << "Loading selection efficiencies..." << endl;

    TFile *dataSelEffFile_pos = new TFile(dataSelEffName_pos);
    CEffUser2D dataSelEff_pos;
    dataSelEff_pos.loadEff((TH2D*)dataSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataSelEffFile_pos->Get("hErrhEtaPt"));

    TFile *dataSelEffFile_neg = new TFile(dataSelEffName_neg);
    CEffUser2D dataSelEff_neg;
    dataSelEff_neg.loadEff((TH2D*)dataSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataSelEffFile_neg->Get("hErrhEtaPt"));

    TFile *zmmSelEffFile_pos = new TFile(zmmSelEffName_pos);
    CEffUser2D zmmSelEff_pos;
    zmmSelEff_pos.loadEff((TH2D*)zmmSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)zmmSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zmmSelEffFile_pos->Get("hErrhEtaPt"));

    TFile *zmmSelEffFile_neg = new TFile(zmmSelEffName_neg);
    CEffUser2D zmmSelEff_neg;
    zmmSelEff_neg.loadEff((TH2D*)zmmSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)zmmSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zmmSelEffFile_neg->Get("hErrhEtaPt"));

    //
    // Standalone efficiency
    //
    cout << "Loading standalone efficiencies..." << endl;

    TFile *dataStaEffFile_pos = new TFile(dataStaEffName_pos);
    CEffUser2D dataStaEff_pos;
    dataStaEff_pos.loadEff((TH2D*)dataStaEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataStaEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataStaEffFile_pos->Get("hErrhEtaPt"));

    TFile *dataStaEffFile_neg = new TFile(dataStaEffName_neg);
    CEffUser2D dataStaEff_neg;
    dataStaEff_neg.loadEff((TH2D*)dataStaEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataStaEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataStaEffFile_neg->Get("hErrhEtaPt"));

    TFile *zmmStaEffFile_pos = new TFile(zmmStaEffName_pos);
    CEffUser2D zmmStaEff_pos;
    zmmStaEff_pos.loadEff((TH2D*)zmmStaEffFile_pos->Get("hEffEtaPt"), (TH2D*)zmmStaEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zmmStaEffFile_pos->Get("hErrhEtaPt"));

    TFile *zmmStaEffFile_neg = new TFile(zmmStaEffName_neg);
    CEffUser2D zmmStaEff_neg;
    zmmStaEff_neg.loadEff((TH2D*)zmmStaEffFile_neg->Get("hEffEtaPt"), (TH2D*)zmmStaEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zmmStaEffFile_neg->Get("hErrhEtaPt"));

    //
    // Tracker efficiency
    //
    cout << "Loading track efficiencies..." << endl;

    TFile *dataTrkEffFile_pos = new TFile(dataTrkEffName_pos);
    CEffUser2D dataTrkEff_pos;
    dataTrkEff_pos.loadEff((TH2D*)dataTrkEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataTrkEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataTrkEffFile_pos->Get("hErrhEtaPt"));

    TFile *dataTrkEffFile_neg = new TFile(dataTrkEffName_neg);
    CEffUser2D dataTrkEff_neg;
    dataTrkEff_neg.loadEff((TH2D*)dataTrkEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataTrkEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataTrkEffFile_neg->Get("hErrhEtaPt"));

    TFile *zmmTrkEffFile_pos = new TFile(zmmTrkEffName_pos);
    CEffUser2D zmmTrkEff_pos;
    zmmTrkEff_pos.loadEff((TH2D*)zmmTrkEffFile_pos->Get("hEffEtaPt"), (TH2D*)zmmTrkEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zmmTrkEffFile_pos->Get("hErrhEtaPt"));

    TFile *zmmTrkEffFile_neg = new TFile(zmmTrkEffName_neg);
    CEffUser2D zmmTrkEff_neg;
    zmmTrkEff_neg.loadEff((TH2D*)zmmTrkEffFile_neg->Get("hEffEtaPt"), (TH2D*)zmmTrkEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zmmTrkEffFile_neg->Get("hErrhEtaPt"));


    // Data structures to store info from TTrees
    mithep::TEventInfo *info = new mithep::TEventInfo();
    mithep::TGenInfo   *gen  = new mithep::TGenInfo();
    TClonesArray *muonArr    = new TClonesArray("mithep::TMuon");

    TFile *infile=0;
    TTree *eventTree=0;

    // Variables to store acceptances and uncertainties (per input file)
    vector<Double_t> nEvtsv, nSelv, nSelCorrv;
    vector<Double_t> accv, accCorrv;
    vector<Double_t> accErrv, accCorrErrv;

    //
    // loop through files
    //
    for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {

        // Read input file and get the TTrees
        cout << "Processing " << fnamev[ifile] << " ..." << endl;
        infile = new TFile(fnamev[ifile]);
        assert(infile);

        eventTree = (TTree*)infile->Get("Events");
        assert(eventTree);
        eventTree->SetBranchAddress("Info", &info);
        TBranch *infoBr = eventTree->GetBranch("Info");
        eventTree->SetBranchAddress("Gen",  &gen);
        TBranch *genBr  = eventTree->GetBranch("Gen");
        eventTree->SetBranchAddress("Muon", &muonArr);
        TBranch *muonBr = eventTree->GetBranch("Muon");

        nEvtsv.push_back(0);
        nSelv.push_back(0);
        nSelCorrv.push_back(0);

        //
        // loop over events
        //
        for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
            genBr->GetEntry(ientry);
            if(gen->vmass<MASS_LOW || gen->vmass>MASS_HIGH) continue;

            infoBr->GetEntry(ientry);

            Double_t weight=1;
            nEvtsv[ifile]+=weight;

            // trigger requirement
            ULong_t trigger = kHLT_Mu15_eta2p1;
            ULong_t trigObj = kHLT_Mu15_eta2p1_MuObj;
            if(!(info->triggerBits & trigger)) continue;

            // good vertex requirement
            if(!(info->hasGoodPV)) continue;

            muonArr->Clear();
            muonBr->GetEntry(ientry);
            for(Int_t i1=0; i1<muonArr->GetEntriesFast(); i1++) {
                const mithep::TMuon *mu1 = (mithep::TMuon*)((*muonArr)[i1]);

                if(mu1->pt	  < PT_CUT)  continue;  // lepton pT cut
                if(fabs(mu1->eta) > ETA_CUT) continue;  // lepton |eta| cut
                if(!passMuonID(mu1))	     continue;  // lepton selection

                LorentzVector vMu1(mu1->pt, mu1->eta, mu1->phi, MUON_MASS);

                for(Int_t i2=i1+1; i2<muonArr->GetEntriesFast(); i2++) {
                    const mithep::TMuon *mu2 = (mithep::TMuon*)((*muonArr)[i2]);

                    if(mu1->q == mu2->q)	       continue;  // opposite charge requirement
                    if(mu2->pt        < PT_CUT)  continue;  // lepton pT cut
                    if(fabs(mu2->eta) > ETA_CUT) continue;  // lepton |eta| cut
                    if(!passMuonID(mu2))	       continue;  // lepton selection

                    LorentzVector vMu2(mu2->pt, mu2->eta, mu2->phi, MUON_MASS);

                    // trigger match
                    if(!(mu1->hltMatchBits & trigObj) && !(mu2->hltMatchBits & trigObj)) continue;

                    // mass window
                    LorentzVector vDilep = vMu1 + vMu2;
                    if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue;


                    /******** We have a Z candidate! HURRAY! ********/

                    Double_t effdata, effmc;
                    Double_t corr=1;

                    effdata=1;
                    effmc=1;
                    if(mu1->q>0) {
                        effdata *= (1.-dataHLTEff_pos.getEff(mu1->eta, mu1->pt));
                        effmc   *= (1.-zmmHLTEff_pos.getEff(mu1->eta, mu1->pt));
                    } else {
                        effdata *= (1.-dataHLTEff_neg.getEff(mu1->eta, mu1->pt));
                        effmc   *= (1.-zmmHLTEff_neg.getEff(mu1->eta, mu1->pt));
                    }
                    if(mu2->q>0) {
                        effdata *= (1.-dataHLTEff_pos.getEff(mu2->eta, mu2->pt));
                        effmc   *= (1.-zmmHLTEff_pos.getEff(mu2->eta, mu2->pt));
                    } else {
                        effdata *= (1.-dataHLTEff_neg.getEff(mu2->eta, mu2->pt));
                        effmc   *= (1.-zmmHLTEff_neg.getEff(mu2->eta, mu2->pt));
                    }
                    effdata = 1.-effdata;
                    effmc   = 1.-effmc;
                    corr *= effdata/effmc;

                    effdata=1;
                    effmc=1;
                    if(mu1->q>0) {
                        effdata *= dataSelEff_pos.getEff(mu1->eta, mu1->pt);
                        effmc   *= zmmSelEff_pos.getEff(mu1->eta, mu1->pt);
                    } else {
                        effdata *= dataSelEff_neg.getEff(mu1->eta, mu1->pt);
                        effmc   *= zmmSelEff_neg.getEff(mu1->eta, mu1->pt);
                    }
                    if(mu2->q>0) {
                        effdata *= dataSelEff_pos.getEff(mu2->eta, mu2->pt);
                        effmc   *= zmmSelEff_pos.getEff(mu2->eta, mu2->pt);
                    } else {
                        effdata *= dataSelEff_neg.getEff(mu2->eta, mu2->pt);
                        effmc   *= zmmSelEff_neg.getEff(mu2->eta, mu2->pt);
                    }
                    corr *= effdata/effmc;

                    effdata=1;
                    effmc=1;
                    if(mu1->q>0) {
                        effdata *= dataStaEff_pos.getEff(fabs(mu1->eta), mu1->pt);
                        effmc   *= zmmStaEff_pos.getEff(fabs(mu1->eta), mu1->pt);
                    } else {
                        effdata *= dataStaEff_neg.getEff(fabs(mu1->eta), mu1->pt);
                        effmc   *= zmmStaEff_neg.getEff(fabs(mu1->eta), mu1->pt);
                    }
                    if(mu2->q>0) {
                        effdata *= dataStaEff_pos.getEff(fabs(mu2->eta), mu2->pt);
                        effmc   *= zmmStaEff_pos.getEff(fabs(mu2->eta), mu2->pt);
                    } else {
                        effdata *= dataStaEff_neg.getEff(fabs(mu2->eta), mu2->pt);
                        effmc   *= zmmStaEff_neg.getEff(fabs(mu2->eta), mu2->pt);
                    }
                    corr *= effdata/effmc;

                    effdata=1;
                    effmc=1;
                    if(mu1->q>0) {
                        effdata *= dataTrkEff_pos.getEff(fabs(mu1->eta), mu1->pt);
                        effmc   *= zmmTrkEff_pos.getEff(fabs(mu1->eta), mu1->pt);
                    } else {
                        effdata *= dataTrkEff_neg.getEff(fabs(mu1->eta), mu1->pt);
                        effmc   *= zmmTrkEff_neg.getEff(fabs(mu1->eta), mu1->pt);
                    }
                    if(mu2->q>0) {
                        effdata *= dataTrkEff_pos.getEff(fabs(mu2->eta), mu2->pt);
                        effmc   *= zmmTrkEff_pos.getEff(fabs(mu2->eta), mu2->pt);
                    } else {
                        effdata *= dataTrkEff_neg.getEff(fabs(mu2->eta), mu2->pt);
                        effmc   *= zmmTrkEff_neg.getEff(fabs(mu2->eta), mu2->pt);
                    }
                    corr *= effdata/effmc;

                    nSelv[ifile]    +=weight;
                    nSelCorrv[ifile]+=weight*corr;
                }
            }
        }

        // compute acceptances
        accv.push_back(nSelv[ifile]/nEvtsv[ifile]);
        accErrv.push_back(accv[ifile]*sqrt((1.-accv[ifile])/nEvtsv[ifile]));
        accCorrv.push_back(nSelCorrv[ifile]/nEvtsv[ifile]);
        accCorrErrv.push_back(accCorrv[ifile]*sqrt((1.-accCorrv[ifile])/nEvtsv[ifile]));

        delete infile;
        infile=0, eventTree=0;
    }
    delete info;
    delete gen;
    delete muonArr;


    //--------------------------------------------------------------------------------------------------------------
    // Output
    //==============================================================================================================
    cout << "*" << endl;
    cout << "* SUMMARY" << endl;
    cout << "*--------------------------------------------------" << endl;
    cout << " Z -> mu mu" << endl;
    cout << "  Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl;
    cout << "  pT > " << PT_CUT << endl;
    cout << "  |eta| < " << ETA_CUT << endl;
    cout << endl;

    for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
        cout << "   ================================================" << endl;
        cout << "    Label: " << labelv[ifile] << endl;
        cout << "     File: " << fnamev[ifile] << endl;
        cout << endl;
        cout << "    *** Acceptance ***" << endl;
        cout << "          nominal: " << setw(12) << nSelv[ifile]   << " / " << nEvtsv[ifile] << " = " << accv[ifile]   << " +/- " << accErrv[ifile] << endl;
        cout << "     SF corrected: " << accCorrv[ifile] << " +/- " << accCorrErrv[ifile] << endl;
        cout << endl;
    }

    char txtfname[100];
    sprintf(txtfname,"%s/binned.txt",outputDir.Data());
    ofstream txtfile;
    txtfile.open(txtfname);
    txtfile << "*" << endl;
    txtfile << "* SUMMARY" << endl;
    txtfile << "*--------------------------------------------------" << endl;
    txtfile << " Z -> mu mu" << endl;
    txtfile << "  Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl;
    txtfile << "  pT > " << PT_CUT << endl;
    txtfile << "  |eta| < " << ETA_CUT << endl;
    txtfile << endl;

    for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
        txtfile << "   ================================================" << endl;
        txtfile << "    Label: " << labelv[ifile] << endl;
        txtfile << "     File: " << fnamev[ifile] << endl;
        txtfile << endl;
        txtfile << "    *** Acceptance ***" << endl;
        txtfile << "          nominal: " << setw(12) << nSelv[ifile]   << " / " << nEvtsv[ifile] << " = " << accv[ifile]   << " +/- " << accErrv[ifile] << endl;
        txtfile << "     SF corrected: " << accCorrv[ifile] << " +/- " << accCorrErrv[ifile] << endl;
        txtfile << endl;
    }
    txtfile.close();

    cout << endl;
    cout << "  <> Output saved in " << outputDir << "/" << endl;
    cout << endl;

    gBenchmark->Show("computeAccSelZmmBinned");
}
Esempio n. 28
0
void LaserCalib(TTreeSRedirector & cstream, TTree * chain, Float_t tmin, Float_t tmax, Float_t fraction){
  ///

  const Double_t kMaxDelta=10;
  AliTPCParamSR param;
  param.Update();
  TFile fce("TPCsignal.root");
  TTree   * treece =(TTree*)fce.Get("Signalce");
  if (chain) treece=chain;
  //
  TBranch * brsector  = treece->GetBranch("Sector");
  TBranch * brpad     = treece->GetBranch("Pad");
  TBranch * brrow     = treece->GetBranch("Row");
  TBranch * brTimeStamp = treece->GetBranch("TimeStamp");
  //
  TBranch * brtime    = treece->GetBranch("Time");
  TBranch * brrms     = treece->GetBranch("RMS06");
  TBranch * brmax     = treece->GetBranch("Max");
  TBranch * brsum     = treece->GetBranch("Qsum");

  Int_t sector, pad, row=0;
  Double_t time=0, rms=0, qMax=0, qSum=0;
  UInt_t  timeStamp=0;
  brsector->SetAddress(&sector);
  brrow->SetAddress(&row);
  brpad->SetAddress(&pad);
  brTimeStamp->SetAddress(&timeStamp);
  
  brtime->SetAddress(&time);
  brrms->SetAddress(&rms);
  brmax->SetAddress(&qMax);
  brsum->SetAddress(&qSum);


  brsector->GetEntry(0);
  //
  Int_t firstSector  = sector;
  Int_t lastSector   = sector;
  Int_t fentry = 0;
  Int_t lentry = 0;
  //
  // find time offset for differnt events
  //
  Int_t count = 0;
  Double_t padTimes[500000];
  TRobustEstimator restim;
  Double_t meanS[72], sigmaS[72];
  Int_t   firstS[72], lastS[72];
  Double_t   sectorsID[72];
  for (Int_t isector=0;isector<72; isector++){
    firstS[isector]=-1; 
    lastS[isector] =-1;
  };
  TH1F  hisT("hisT","hisT",100,tmin,tmax);
  treece->Draw("Time>>hisT","");
  Float_t cbin = hisT.GetBinCenter(hisT.GetMaximumBin());

  for (Int_t ientry=0; ientry<treece->GetEntriesFast(); ientry++){
    treece->GetEvent(ientry);
    //
    if (sector!=lastSector && sector==firstSector){
      //if (sector!=lastSector){
      lentry = ientry;
      TTimeStamp stamp(timeStamp);
      stamp.Print();
      printf("\nEvent\t%d\tFirst\t%d\tLast\t%d\t%d\n",count, fentry, lentry, lentry-fentry);
      //
      //
      Int_t ngood=0;      
      for (Int_t ientry2=fentry; ientry2<lentry; ientry2++){
	//	brtime->GetEvent(ientry2);
	//  brsector->GetEvent(ientry2);
	treece->GetEvent(ientry2);
	if (time>tmin&&time<tmax && TMath::Abs(time-cbin)<kMaxDelta){
	  padTimes[ngood]=time;
	  ngood++;	
	  if (firstS[sector]<0)  firstS[sector]= ngood;
	  if (firstS[sector]>=0) lastS[sector] = ngood;
	}	
      }
      //
      //
      Double_t mean,sigma;
      restim.EvaluateUni(ngood,padTimes,mean, sigma,int(float(ngood)*fraction));
      printf("Event\t%d\t%f\t%f\n",count, mean, sigma);
      for (Int_t isector=0; isector<72; isector++){
	sectorsID[isector]=sector;
	if (firstS[isector]>=0 &&lastS[isector]>=0 && lastS[isector]>firstS[isector] ){
	  Int_t ngoodS = lastS[isector]-firstS[isector];
	  restim.EvaluateUni(ngoodS, &padTimes[firstS[isector]],meanS[isector], 
			     sigmaS[isector],int(float(ngoodS)*fraction));
	}
      }
      TGraph  graphM(72,sectorsID,meanS);
      TGraph  graphS(72,sectorsID,sigmaS);
      cstream<<"TimeS"<<
	"CBin="<<cbin<<
	"Event="<<count<<
	"GM="<<&graphM<<
	"GS="<<&graphS<<
	"\n";
      

      for (Int_t ientry2=fentry; ientry2<lentry-1; ientry2++){
	treece->GetEvent(ientry2);
	Double_t x      = param.GetPadRowRadii(sector,row);
	Int_t    maxpad = AliTPCROC::Instance()->GetNPads(sector,row);
	Double_t y = (pad - 2.5 - 0.5*maxpad)*param.GetPadPitchWidth(sector);
	Double_t alpha = TMath::DegToRad()*(10.+20.*(sector%18));	
	Double_t gx = x*TMath::Cos(alpha)-y*TMath::Sin(alpha);
	Double_t gy = y*TMath::Cos(alpha)+x*TMath::Sin(alpha);
	
	Int_t npadS = lastS[sector]-firstS[sector];
	cstream<<"Time"<<
	  "Event="<<count<<
	  "TimeStamp="<<timeStamp<<
	  "CBin="<<cbin<<
	  "x="<<x<<
	  "y="<<y<<
	  "gx="<<gx<<
	  "gy="<<gy<<
	  "Sector="<<sector<<
	  "Row="<<row<<
	  "Pad="<<pad<<
	  "Time="<<time<<
	  "RMS="<<rms<<
	  "Time0="<<mean<<
	  "Sigma0="<<sigma<< 
	  "TimeS0="<<meanS[sector]<<
	  "SigmaS0="<<sigmaS[sector]<<
	  "npad0="<<ngood<<
	  "npadS="<<npadS<<
	  "Max="<<qMax<<
	  "Sum="<<qSum<<
	  "\n";
      }
      treece->GetEvent(ientry);
      fentry = ientry;
      count++;      
      for (Int_t isector=0;isector<72; isector++){
	firstS[isector]=-1; 
	lastS[isector] =-1;
      }
    }
    lastSector=sector;
  }
}
Esempio n. 29
0
void selectWe(const TString conf,        // input file
              const TString outputDir,   // output directory
	      const Bool_t  doScaleCorr  // apply energy scale corrections?
) {
  gBenchmark->Start("selectWe");

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //============================================================================================================== 

  const Double_t PT_CUT   = 20;
  const Double_t ETA_CUT  = 2.5;
  const Double_t ELE_MASS = 0.000511;
  
  const Double_t ECAL_GAP_LOW  = 1.4442;
  const Double_t ECAL_GAP_HIGH = 1.566;
  
  const Double_t escaleNbins  = 6;
  const Double_t escaleEta[]  = { 0.4,     0.8,     1.2,     1.4442,  2,        2.5 };
  const Double_t escaleCorr[] = { 1.00284, 1.00479, 1.00734, 1.00851, 1.00001,  0.982898 };
  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  

  vector<TString>  snamev;      // sample name (for output files)  
  vector<CSample*> samplev;     // data/MC samples

  //
  // parse .conf file
  //
  confParse(conf, snamev, samplev);
  const Bool_t hasData = (samplev[0]->fnamev.size()>0);

  // Create output directory
  gSystem->mkdir(outputDir,kTRUE);
  const TString ntupDir = outputDir + TString("/ntuples");
  gSystem->mkdir(ntupDir,kTRUE);
  
  //
  // Declare output ntuple variables
  //
  UInt_t  runNum, lumiSec, evtNum;
  UInt_t  npv, npu;
  Float_t genVPt, genVPhi, genVy, genVMass;
  Float_t genLepPt, genLepPhi;
  Float_t scale1fb;
  Float_t met, metPhi, sumEt, mt, u1, u2;
  Int_t   q;
  LorentzVector *lep=0;
  ///// electron specific /////
  Float_t trkIso, emIso, hadIso;
  Float_t pfChIso, pfGamIso, pfNeuIso, pfCombIso;
  Float_t sigieie, hovere, eoverp, fbrem, ecalE;
  Float_t dphi, deta;
  Float_t d0, dz;
  UInt_t  isConv, nexphits, typeBits;
  LorentzVector *sc=0;
  
  // Data structures to store info from TTrees
  mithep::TEventInfo *info  = new mithep::TEventInfo();
  mithep::TGenInfo   *gen   = new mithep::TGenInfo();
  TClonesArray *electronArr = new TClonesArray("mithep::TElectron");
  TClonesArray *pvArr       = new TClonesArray("mithep::TVertex");
  
  TFile *infile=0;
  TTree *eventTree=0;
  
  //
  // loop over samples
  //  
  for(UInt_t isam=0; isam<samplev.size(); isam++) {
    
    // Assume data sample is first sample in .conf file
    // If sample is empty (i.e. contains no ntuple files), skip to next sample
    if(isam==0 && !hasData) continue;
  
    CSample* samp = samplev[isam];
  
    //
    // Set up output ntuple
    //
    TString outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.root");
    if(isam==0 && !doScaleCorr) outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.raw.root");
    TFile *outFile = new TFile(outfilename,"RECREATE"); 
    TTree *outTree = new TTree("Events","Events");

    outTree->Branch("runNum",   &runNum,   "runNum/i");     // event run number
    outTree->Branch("lumiSec",  &lumiSec,  "lumiSec/i");    // event lumi section
    outTree->Branch("evtNum",   &evtNum,   "evtNum/i");     // event number
    outTree->Branch("npv",      &npv,      "npv/i");        // number of primary vertices
    outTree->Branch("npu",      &npu,      "npu/i");        // number of in-time PU events (MC)
    outTree->Branch("genVPt",   &genVPt,   "genVPt/F");     // GEN boson pT (signal MC)
    outTree->Branch("genVPhi",  &genVPhi,  "genVPhi/F");    // GEN boson phi (signal MC)
    outTree->Branch("genVy",    &genVy,    "genVy/F");      // GEN boson rapidity (signal MC)
    outTree->Branch("genVMass", &genVMass, "genVMass/F");   // GEN boson mass (signal MC)
    outTree->Branch("genLepPt", &genLepPt, "genLepPt/F");   // GEN lepton pT (signal MC)
    outTree->Branch("genLepPhi",&genLepPhi,"genLepPhi/F");  // GEN lepton phi (signal MC)
    outTree->Branch("scale1fb", &scale1fb, "scale1fb/F");   // event weight per 1/fb (MC)
    outTree->Branch("met",      &met,      "met/F");        // MET
    outTree->Branch("metPhi",   &metPhi,   "metPhi/F");     // phi(MET)
    outTree->Branch("sumEt",    &sumEt,    "sumEt/F");      // Sum ET
    outTree->Branch("mt",       &mt,       "mt/F");         // transverse mass
    outTree->Branch("u1",       &u1,       "u1/F");         // parallel component of recoil
    outTree->Branch("u2",       &u2,       "u2/F");         // perpendicular component of recoil
    outTree->Branch("q",        &q,        "q/I");          // lepton charge
    outTree->Branch("lep", "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &lep);  // lepton 4-vector
    ///// electron specific /////
    outTree->Branch("trkIso",    &trkIso,    "trkIso/F");     // track isolation of tag lepton
    outTree->Branch("emIso",     &emIso,     "emIso/F");      // ECAL isolation of tag lepton
    outTree->Branch("hadIso",    &hadIso,    "hadIso/F");     // HCAL isolation of tag lepton
    outTree->Branch("pfChIso",   &pfChIso,   "pfChIso/F");    // PF charged hadron isolation of lepton
    outTree->Branch("pfGamIso",  &pfGamIso,  "pfGamIso/F");   // PF photon isolation of lepton
    outTree->Branch("pfNeuIso",  &pfNeuIso,  "pfNeuIso/F");   // PF neutral hadron isolation of lepton
    outTree->Branch("pfCombIso", &pfCombIso, "pfCombIso/F");  // PF combined isolation of electron
    outTree->Branch("sigieie",   &sigieie,   "sigieie/F");    // sigma-ieta-ieta of electron
    outTree->Branch("hovere",    &hovere,    "hovere/F");     // H/E of electron
    outTree->Branch("eoverp",    &eoverp,    "eoverp/F");     // E/p of electron
    outTree->Branch("fbrem",     &fbrem,     "fbrem/F");      // brem fraction of electron
    outTree->Branch("dphi",      &dphi,	     "dphi/F");       // GSF track - ECAL dphi of electron
    outTree->Branch("deta",      &deta,      "deta/F");       // GSF track - ECAL deta of electron
    outTree->Branch("ecalE",     &ecalE,     "ecalE/F");      // ECAL energy of electron
    outTree->Branch("d0",        &d0,        "d0/F");         // transverse impact parameter of electron
    outTree->Branch("dz",        &dz,        "dz/F");         // longitudinal impact parameter of electron
    outTree->Branch("isConv",    &isConv,    "isConv/i");     // conversion filter flag of electron
    outTree->Branch("nexphits",  &nexphits,  "nexphits/i");   // number of missing expected inner hits of electron
    outTree->Branch("typeBits",  &typeBits,  "typeBits/i");   // electron type of electron
    outTree->Branch("sc",  "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &sc);   // electron Supercluster 4-vector
    
    //
    // loop through files
    //
    const UInt_t nfiles = samp->fnamev.size();
    for(UInt_t ifile=0; ifile<nfiles; ifile++) {  

      // Read input file and get the TTrees
      cout << "Processing " << samp->fnamev[ifile] << " [xsec = " << samp->xsecv[ifile] << " pb] ... "; cout.flush();      
      infile = new TFile(samp->fnamev[ifile]); 
      assert(infile);

      Bool_t hasJSON = kFALSE;
      mithep::RunLumiRangeMap rlrm;
      if(samp->jsonv[ifile].CompareTo("NONE")!=0) { 
        hasJSON = kTRUE;
        rlrm.AddJSONFile(samp->jsonv[ifile].Data()); 
      }
  
      eventTree = (TTree*)infile->Get("Events");
      assert(eventTree);  
      eventTree->SetBranchAddress("Info",     &info);        TBranch *infoBr     = eventTree->GetBranch("Info");
      eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron");
      eventTree->SetBranchAddress("PV",       &pvArr);       TBranch *pvBr       = eventTree->GetBranch("PV");
      Bool_t hasGen = eventTree->GetBranchStatus("Gen");
      TBranch *genBr=0;
      if(hasGen) {
        eventTree->SetBranchAddress("Gen", &gen);
	genBr = eventTree->GetBranch("Gen");
      }
    
      // Compute MC event weight per 1/fb
      Double_t weight = 1;
      const Double_t xsec = samp->xsecv[ifile];
      if(xsec>0) weight = 1000.*xsec/(Double_t)eventTree->GetEntries();     

      //
      // loop over events
      //
      Double_t nsel=0, nselvar=0;
      for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
        infoBr->GetEntry(ientry);
	
	if(genBr) genBr->GetEntry(ientry);
     
        // check for certified lumi (if applicable)
        mithep::RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec);      
        if(hasJSON && !rlrm.HasRunLumi(rl)) continue;  

        // trigger requirement               
        ULong64_t trigger = kHLT_Ele22_CaloIdL_CaloIsoVL;
	ULong64_t trigObj = kHLT_Ele22_CaloIdL_CaloIsoVL_EleObj;   
        if(!(info->triggerBits & trigger)) continue;      
      
        // good vertex requirement
        if(!(info->hasGoodPV)) continue;
        pvArr->Clear();
        pvBr->GetEntry(ientry);
      
        //
	// SELECTION PROCEDURE:
	//  (1) Look for 1 good electron matched to trigger
	//  (2) Reject event if another electron is present passing looser cuts
	//
	electronArr->Clear();
        electronBr->GetEntry(ientry);
	Int_t nLooseLep=0;
	const mithep::TElectron *goodEle=0;
	Bool_t passSel=kFALSE;	
        for(Int_t i=0; i<electronArr->GetEntriesFast(); i++) {
          const mithep::TElectron *ele = (mithep::TElectron*)((*electronArr)[i]);
	  
	  // check ECAL gap
	  if(fabs(ele->scEta)>=ECAL_GAP_LOW && fabs(ele->scEta)<=ECAL_GAP_HIGH) continue;
	  
	  Double_t escale=1;
	  if(doScaleCorr && isam==0) {
	    for(UInt_t ieta=0; ieta<escaleNbins; ieta++) {
	      if(fabs(ele->scEta)<escaleEta[ieta]) {
	        escale = escaleCorr[ieta];
		break;
	      }
	    }
	  }
	  
	  if(fabs(ele->scEta)   > 2.5) continue;                // loose lepton |eta| cut
          if(escale*(ele->scEt) < 20)  continue;                // loose lepton pT cut
          if(passEleLooseID(ele,info->rhoLowEta)) nLooseLep++;  // loose lepton selection
          if(nLooseLep>1) {  // extra lepton veto
            passSel=kFALSE;
            break;
          }
          
          if(fabs(ele->scEta)   > ETA_CUT)    continue;  // lepton |eta| cut
          if(escale*(ele->scEt) < PT_CUT)     continue;  // lepton pT cut
          if(!passEleID(ele,info->rhoLowEta)) continue;  // lepton selection
          if(!(ele->hltMatchBits & trigObj))  continue;  // check trigger matching
	  
	  passSel=kTRUE;
	  goodEle = ele;  
	}
	
	if(passSel) {
	  
	  /******** We have a W candidate! HURRAY! ********/
	    
	  nsel+=weight;
          nselvar+=weight*weight;
	  
	  Double_t escale=1;
	  if(doScaleCorr && isam==0) {
	    for(UInt_t ieta=0; ieta<escaleNbins; ieta++) {
	      if(fabs(goodEle->scEta)<escaleEta[ieta]) {
	        escale = escaleCorr[ieta];
		break;
	      }
	    }
	  }
	  
	  LorentzVector vLep(escale*(goodEle->pt), goodEle->eta, goodEle->phi, ELE_MASS);  
	  LorentzVector vSC(escale*(goodEle->scEt), goodEle->scEta, goodEle->scPhi, ELE_MASS); 	  
	  
	  //
	  // Fill tree
	  //
	  runNum   = info->runNum;
	  lumiSec  = info->lumiSec;
	  evtNum   = info->evtNum;
	  npv	   = pvArr->GetEntriesFast();
	  npu	   = info->nPU;
	  genVPt   = 0;
	  genVPhi  = 0;
	  genVy    = 0;
	  genVMass = 0;
	  genLepPt = 0;
	  genLepPhi= 0;
	  u1       = 0;
	  u2       = 0;
	  if(hasGen) {
	    genVPt   = gen->vpt;
            genVPhi  = gen->vphi;
	    genVy    = gen->vy;
	    genVMass = gen->vmass;
	    TVector2 vWPt((gen->vpt)*cos(gen->vphi),(gen->vpt)*sin(gen->vphi));
	    TVector2 vLepPt(vLep.Px(),vLep.Py());      
            TVector2 vMet((info->pfMET)*cos(info->pfMETphi), (info->pfMET)*sin(info->pfMETphi));        
            TVector2 vU = -1.0*(vMet+vLepPt);
            u1 = ((vWPt.Px())*(vU.Px()) + (vWPt.Py())*(vU.Py()))/(gen->vpt);  // u1 = (pT . u)/|pT|
            u2 = ((vWPt.Px())*(vU.Py()) - (vWPt.Py())*(vU.Px()))/(gen->vpt);  // u2 = (pT x u)/|pT|
	    
	    if(abs(gen->id_1)==EGenType::kElectron) { genLepPt = gen->vpt_1; genLepPhi = gen->vphi_1; }
	    if(abs(gen->id_2)==EGenType::kElectron) { genLepPt = gen->vpt_2; genLepPhi = gen->vphi_2; }
	  }
	  scale1fb = weight;
	  met	   = info->pfMET;
	  metPhi   = info->pfMETphi;
	  sumEt    = info->pfSumET;
	  mt       = sqrt( 2.0 * (vLep.Pt()) * (info->pfMET) * (1.0-cos(toolbox::deltaPhi(vLep.Phi(),info->pfMETphi))) );
	  q        = goodEle->q;	  
	  lep      = &vLep;	  
	  
	  ///// electron specific /////
	  sc	    = &vSC;
	  trkIso    = goodEle->trkIso03;
	  emIso     = goodEle->emIso03;
	  hadIso    = goodEle->hadIso03;
	  pfChIso   = goodEle->pfChIso03;
	  pfGamIso  = goodEle->pfGamIso03;
	  pfNeuIso  = goodEle->pfNeuIso03;	
	  pfCombIso = goodEle->pfChIso03 + TMath::Max(goodEle->pfNeuIso03 + goodEle->pfGamIso03 - (info->rhoLowEta)*getEffArea(goodEle->scEta), 0.);
	  sigieie   = goodEle->sigiEtaiEta;
	  hovere    = goodEle->HoverE;
	  eoverp    = goodEle->EoverP;
	  fbrem     = goodEle->fBrem;
	  dphi      = goodEle->deltaPhiIn;
	  deta      = goodEle->deltaEtaIn;
	  d0        = goodEle->d0;
	  dz        = goodEle->dz;
	  isConv    = goodEle->isConv;
	  nexphits  = goodEle->nExpHitsInner;
	  typeBits  = goodEle->typeBits;
	   
	  outTree->Fill();
        }
      }
      delete infile;
      infile=0, eventTree=0;    

      cout << nsel  << " +/- " << sqrt(nselvar);
      if(isam!=0) cout << " per 1/fb";
      cout << endl;
    }
    outFile->Write();
    outFile->Close();
  }
  delete info;
  delete gen;
  delete electronArr;
  delete pvArr;
  
    
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
   
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << " W -> e nu" << endl;
  cout << "  pT > " << PT_CUT << endl;
  cout << "  |eta| < " << ETA_CUT << endl;
  if(doScaleCorr)
    cout << "  *** Scale corrections applied ***" << endl;
  cout << endl;

  cout << endl;
  cout << "  <> Output saved in " << outputDir << "/" << endl;    
  cout << endl;  
      
  gBenchmark->Show("selectWe"); 
}
Esempio n. 30
0
void getXsecExtended(const TString mc_input, int debugMode=0, bool useFEWZ=true, int fineGrid=0)
{
  // check whether it is a calculation
  if (mc_input.Contains("_DebugRun_")) {
    std::cout << "getXsec: _DebugRun_ detected. Terminating the script\n";
    return;
  }

  if (debugMode==1) std::cout << "\n\n\tDEBUG MODE is ON\n\n";
  if (debugMode==-1) std::cout << "\n\n\tPLOT ONLY MODE is ON\n\n";
  std::cout << "DYTools::analysisTag=" << DYTools::analysisTag << "\n";

  if (DYTools::study2D && fineGrid) {
    std::cout << "fineGrid=1 is allowed only for study2D=0\n";
    return;
  }

  // normal calculation

  gBenchmark->Start("getXsec");

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //==============================================================================================================
  
  //Bool_t doSave  = false;    // save plots?
  TString format = "png";   // output file format
  MCInputFileMgr_t inpMgr;
  TString fineGridStr;
  if (fineGrid==1) fineGridStr="fineGrid_";
  else if (fineGrid==2) fineGridStr="summer2011Grid_";
  else if (fineGrid==3) fineGridStr="summer2011specGrid_";
  
  Double_t massLow  = DYTools::massBinLimits[0];
  Double_t massHigh = DYTools::massBinLimits[DYTools::nMassBins];

  // fine grid: 0, 1, 2, ..., (fineGrid_1GeVstop-1), fineGrid_1GeVstop, fineGrid_1GeVstop+fineGridLargerStep, fineGrid_1GeVstop+2*fineGridLargerStep, ..., 1500
  //
  double fineGrid_1GeVstop=200.;
  double fineGrid_LargerStep=20.;

  int locMassBinCount=DYTools::nMassBins;
  double *massRangeEdges=NULL;
  if (!fineGrid) {
    massRangeEdges=new double[locMassBinCount+1];
    for (int i=0; i<=DYTools::nMassBins; ++i) {
      massRangeEdges[i]=DYTools::massBinLimits[i];
    }
  }
  else if (fineGrid==1) {
    // 1GeV grid
    locMassBinCount=int(fineGrid_1GeVstop-massLow+1e-3);
    std::cout << "1GeV grid size=" << locMassBinCount << "\n";
    // fineGrid_LargerStep
    double upperRange= (massHigh-fineGrid_1GeVstop);
    double upperCount= upperRange/fineGrid_LargerStep + 1e-3;
    if (upperCount - trunc(upperCount) > 1e-3) {
      std::cout << "(upperCount -1e-3)=" << (upperCount -1e-3) << "\n";
      std::cout << "should be integer value\n";
      return;
    }
    locMassBinCount += int(upperCount);
    std::cout << "mass grid[" << locMassBinCount << "]\n";

    massRangeEdges=new double[locMassBinCount+1];
    double m=massLow, dm=1;
    int count=0;
    while (m<=massHigh) {
      massRangeEdges[count]=m;
      if (1) {
	if (m<massHigh) std::cout << "count=" << count << ", massRange=" << m << " .. " << (m+dm) << "\n";
	else std::cout << "last edge=" << m << "\n";
      }
      count++;
      m+=dm;
      if (m==fineGrid_1GeVstop) dm=fineGrid_LargerStep;
    }
  }
  else if (fineGrid==2) {
    const int nMassBinTh=518;
    Double_t mxl = 14.0;
    locMassBinCount=nMassBinTh;
    massRangeEdges=new double[nMassBinTh+1];

    for(int iTh=0; iTh<=nMassBinTh; iTh++){
      // mass limits
      if     ( iTh >=   0 && iTh <  11 ) {mxl += 1.0;}
      else if( iTh >=  11 && iTh <  18 ) {mxl += 5.0;}
      else if( iTh >=  18 && iTh < 118 ) {mxl += 1.0;}
      else if( iTh >= 118 && iTh < 340 ) {mxl += 2.0;}
      else if( iTh >= 340 && iTh < nMassBinTh)   {mxl += 5.0; }
      else if( iTh == nMassBinTh)                {mxl = 1500; }
      massRangeEdges[iTh]=mxl;
    }
  }
  else if (fineGrid==3) {
    const int nMassBinTh=518;
    Double_t mxl = 14.0;
    locMassBinCount=nMassBinTh;
    massRangeEdges=new double[nMassBinTh+1];

    int iTh_new=0, tmpCounter=0;
    for(int iTh=0; iTh<=nMassBinTh; iTh++, iTh_new++){
      // mass limits
      if     ( iTh >=   0 && iTh <  11 ) {mxl += 1.0;}
      else if( iTh >=  11 && iTh <  18 ) {mxl += 5.0;}
      else if( iTh >=  18 && iTh < 118 ) {mxl += 1.0;}
      else if( iTh >= 118 && iTh < 340 ) {
	if (iTh>=139) {
	  std::cout << "iTh=" << iTh << ", current mxl=" << mxl << " +2\n";
	  if (iTh==139) tmpCounter=10;
	  tmpCounter--;
	  if (tmpCounter>0) iTh_new--;
	  else if (tmpCounter==0) {
	    tmpCounter=10;
	    std::cout << "iTh=" << iTh << ", iTh_new=" << iTh_new << ", current mxl=" << mxl << " +10\n";
	  }
	}
	mxl += 2.0;
      }
      else if( iTh >= 340 && iTh < nMassBinTh)   {
	std::cout << "iTh=" << iTh << ", current mxl=" << mxl << " +5\n";
	if (iTh<342) iTh_new--;
	else {
	  if ((iTh-342)%4>0) iTh_new--;
	  else std::cout << "iTh=" << iTh << ", iTh_new=" << iTh_new << ", current mxl=" << mxl << " +10\n";
	}
	mxl += 5.0; 
      }
      else if( iTh == nMassBinTh)                {mxl = 1500; }
      massRangeEdges[iTh_new]=mxl;
    }
    massRangeEdges[iTh_new-2]=1500.;
    std::cout << "iTh_new=" << iTh_new << "\n";
    locMassBinCount=iTh_new-2;
  }

  TVectorD massGrid(locMassBinCount+1);
  for (int i=0; i<=locMassBinCount; ++i) massGrid[i]=massRangeEdges[i];
  TH1F hMassIdx("h_massIdx","h_massIdx",locMassBinCount-1,massRangeEdges);
  //delete massRangeEdges;

  if (0) {
    printHisto(&hMassIdx);
    if (0) {
      for (int i=0; i<int(massHigh); ++i) {
	double m=i+0.5;
	std::cout << "i=" << i << ", m=" << m << ", idx=" << (hMassIdx.FindBin(m)-1) << "\n";
      }
    }
    return;
  }

  //std::cout << "massHigh=" << massHigh << "\n";
  //std::cout << "locMassBinCount=" << locMassBinCount << "\n";

  if (!inpMgr.Load(mc_input)) {
    return;
  }
  
  //--------------------------------------------------------------------------------------------------------------
  // Main code 
  //==============================================================================================================
  
  //  
  // Set up histograms
  //

  //vector<TH1D*> hZMassv;
  
  Double_t   nZv = 0;

  TMatrixD nEvents (locMassBinCount,DYTools::nYBinsMax);    // number of weigthed events
  TMatrixD nEventsDET (locMassBinCount,DYTools::nYBinsMax); // number of weighted events in the detector acceptance
  TMatrixD nEventsDETrecoPostIdx (locMassBinCount,DYTools::nYBinsMax);    // number of weigthed events
  TMatrixD w2Events (locMassBinCount,DYTools::nYBinsMax);
  TMatrixD w2EventsDET (locMassBinCount,DYTools::nYBinsMax);
  TMatrixD w2EventsDETrecoPostIdx (locMassBinCount,DYTools::nYBinsMax);
  Double_t nZpeak=0, w2Zpeak=0;
  double nZpeakDET=0, w2ZpeakDET=0;
  double nZpeakDETrecoPostIdx=0, w2ZpeakDETrecoPostIdx=0;

  nEvents = 0;
  w2Events = 0;
  nEventsDET = 0;
  w2EventsDET  = 0;
  nEventsDETrecoPostIdx = 0;
  w2EventsDETrecoPostIdx  = 0;

  //char hname[100];
  //for(UInt_t ifile = 0; ifile<fnamev.size(); ifile++) {
  //  sprintf(hname,"hZMass_%i",ifile); hZMassv.push_back(new TH1F(hname,"",500,0,500)); hZMassv[ifile]->Sumw2();
  //}

  // 
  // Read weights from a file
  //
  const bool useFewzWeights = useFEWZ;
  const bool cutZPT100 = true;
  FEWZ_t fewz(useFewzWeights,cutZPT100);
  if (useFewzWeights && !fewz.isInitialized()) {
    std::cout << "failed to prepare FEWZ correction\n";
    throw 2;
  }

  //
  // Access samples and fill histograms
  //  
  TFile *infile=0;
  TTree *eventTree=0;  
    
  // Data structures to store info from TTrees
  mithep::TGenInfo *gen  = new mithep::TGenInfo();

  // loop over samples  
  double lumi0=0;
  if (debugMode!=-1) {
  for(UInt_t ifile=0; ifile<inpMgr.fileNames().size(); ifile++) {
  
    // Read input file
    cout << "Processing " << inpMgr.fileName(ifile) << "..." << endl;
    infile = new TFile(inpMgr.fileName(ifile));
    assert(infile);

    // Get the TTrees
    eventTree = (TTree*)infile->Get("Events"); assert(eventTree);

    // Find weight for events for this file
    // The first file in the list comes with weight 1,
    // all subsequent ones are normalized to xsection and luminosity
    double lumi  = eventTree->GetEntries()/inpMgr.xsec(ifile);
    if (ifile==0) lumi0=lumi;
    double scale = lumi0/lumi;
    std::cout << "       -> sample weight is " << scale << endl;

    // Set branch address to structures that will store the info  
    eventTree->SetBranchAddress("Gen",&gen);
    TBranch *genBr = eventTree->GetBranch("Gen");
 
    // loop over events    
    nZv += scale * eventTree->GetEntries();

    for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
      if (debugMode && (ientry>100000)) break;

      genBr->GetEntry(ientry);
      if (ientry%1000000==0) printProgress("ientry=",ientry,eventTree->GetEntriesFast());

      double massPreFsr = gen->vmass;   // pre-FSR
      double yPreFsr = gen->vy;    // pre-FSR
      double massPostFsr = gen->mass;   // post-FSR
      double yPostFsr = gen->y;    // post-FSR

      if ((massPreFsr < massLow) || (massPreFsr > massHigh)) continue;
      if ((fabs(yPreFsr) < DYTools::yRangeMin) || 
	  (fabs(yPreFsr) > DYTools::yRangeMax)) continue;

      int ibinMassPreFsr=-1, ibinYPreFsr=-1;
      int ibinMassPostFsr=-1, ibinYPostFsr=-1;

      if (!fineGrid) {
	ibinMassPreFsr = DYTools::findMassBin(massPreFsr);
	ibinMassPostFsr= DYTools::findMassBin(massPostFsr);
	ibinYPreFsr = DYTools::findAbsYBin(ibinMassPreFsr, yPreFsr);
	ibinYPostFsr= DYTools::findAbsYBin(ibinMassPostFsr, yPostFsr);
      }
      else {
	ibinMassPreFsr=hMassIdx.FindBin(massPreFsr)-1;
	ibinMassPostFsr=hMassIdx.FindBin(massPostFsr)-1;
	ibinYPreFsr=0;
	ibinYPostFsr=0;
	//printf("massPreFsr=%8.4lf, idx=%3d;  massPostFsr=%8.4lf, idx=%3d\n", massPreFsr,ibinMassPreFsr, massPostFsr,ibinMassPostFsr);
      }

      // We are only interested in the events, reconstructed with 
      // good mass and rapidity 
      if (ibinMassPreFsr==-1 || 
	  ibinMassPreFsr>=locMassBinCount || 
	  ibinYPreFsr==-1) {
	printf(".. skipping mass=%6.4lf, y=%6.4lf. ibinMass=%d, ibinY=%d\n",massPreFsr,yPreFsr,ibinMassPreFsr,ibinYPreFsr);
	continue;
      }

      // Find FEWZ-powheg reweighting factor 
      // that depends on pre-FSR Z/gamma* rapidity, pt, and mass
      double fewz_weight = 1.0;

      if(useFewzWeights) {
	fewz_weight=fewz.getWeight(gen->vmass,gen->vpt,gen->vy);
      }

      //std::cout << "weight=scale*gen->weight*fewz: " << scale << " * " << gen->weight << " * " << fewz_weight << "\n";
      double fullWeight = scale * gen->weight * fewz_weight;
      nEvents(ibinMassPreFsr,ibinYPreFsr) += fullWeight;
      w2Events(ibinMassPreFsr,ibinYPreFsr) += fullWeight*fullWeight;

      // Pre-FSR cross section
      if( DYTools::goodEtPair(gen->vpt_1, gen->vpt_2) &&
	  DYTools::goodEtaPair(gen->veta_1, gen->veta_2) ) {
	nEventsDET(ibinMassPreFsr,ibinYPreFsr) += fullWeight;
	w2EventsDET(ibinMassPreFsr,ibinYPreFsr) += fullWeight*fullWeight;
      }

      // Post-FSR cross section
      if(  (ibinMassPostFsr!=-1) && (ibinYPostFsr!=-1) &&
	   DYTools::goodEtPair(gen->pt_1, gen->pt_2) &&
	   DYTools::goodEtaPair(gen->eta_1, gen->eta_2) ) {
	nEventsDETrecoPostIdx(ibinMassPostFsr,ibinYPostFsr) += fullWeight;
	w2EventsDETrecoPostIdx(ibinMassPostFsr,ibinYPostFsr) += fullWeight*fullWeight;
      }
    }
    delete infile;
    infile=0, eventTree=0;
  }
  delete gen;

  // Determine Z-peak event count
  for (int i=0; i<locMassBinCount; i++) {
    int isZpeak=0;
    // bin idx is (i+1)
    if ((hMassIdx.GetBinLowEdge(i+1)>=60-1e-3) 
	&& (hMassIdx.GetBinLowEdge(i+1+1)<=120+1e-3)) isZpeak=1;
    if (isZpeak) {
      int yiMax=(fineGrid) ? 1:DYTools::nYBins[i];
      for (int yi=0; yi<yiMax; ++yi) {
	nZpeak += nEvents(i,yi);
	w2Zpeak += w2Events(i,yi);
	nZpeakDET += nEventsDET(i,yi);
	w2ZpeakDET += w2EventsDET(i,yi);
	nZpeakDETrecoPostIdx += nEventsDETrecoPostIdx(i,yi);
	w2ZpeakDETrecoPostIdx += w2EventsDETrecoPostIdx(i,yi);
      }
    }
  }
  std::cout << "\n";
  std::cout << "nZpeak=" << nZpeak << ", w2Zpeak=" << w2Zpeak << "\n";
  std::cout << "nZpeakDET=" << nZpeakDET << ", w2ZpeakDET=" << w2ZpeakDET << "\n";
  std::cout << "nZpeakDETrecoPostIdx=" << nZpeakDETrecoPostIdx << ", w2ZpeakDETrecoPostIdx=" << w2ZpeakDETrecoPostIdx << "\n";
  std::cout << "\n";


  if (nZpeak==0) {
    std::cout << "no events in the Z-peak region\n";
    return ;
  }
  } // if (debugMode!=-1)


  // Containers of the normalized event counts
  TMatrixD nEventsNorm (locMassBinCount,DYTools::nYBinsMax);    // number of weigthed events, normalized to Z-peak
  TMatrixD nEventsDETNorm (locMassBinCount,DYTools::nYBinsMax); // number of weighted events in the detector acceptance, normalized to Z-peak
  TMatrixD nEventsDETrecoPostIdxNorm (locMassBinCount,DYTools::nYBinsMax); // number of weighted events in the detector acceptance, normalized to Z-peak
  TMatrixD nEventsNormErr (locMassBinCount,DYTools::nYBinsMax);
  TMatrixD nEventsDETNormErr (locMassBinCount,DYTools::nYBinsMax);
  TMatrixD nEventsDETrecoPostIdxNormErr (locMassBinCount,DYTools::nYBinsMax);

  TMatrixD nEventsErr (locMassBinCount,DYTools::nYBinsMax);
  TMatrixD nEventsDETErr (locMassBinCount,DYTools::nYBinsMax);
  TMatrixD nEventsDETrecoPostIdxErr (locMassBinCount,DYTools::nYBinsMax);

  nEventsNorm=0;
  nEventsDETNorm=0;
  nEventsDETrecoPostIdxNorm=0;
  nEventsNormErr=0;
  nEventsDETNormErr=0;
  nEventsDETrecoPostIdxNormErr=0;

  nEventsErr=0;
  nEventsDETErr=0;

  if (debugMode!=-1) {
  for(int i=0; i<locMassBinCount; i++) {
    int yiMax=(fineGrid) ? 1:DYTools::nYBins[i];
    for (int j=0; j<yiMax; j++) {
      nEventsErr(i,j)=sqrt(w2Events(i,j));
      nEventsDETErr(i,j)=sqrt(w2EventsDET(i,j));
      nEventsDETrecoPostIdxErr(i,j)=sqrt(w2EventsDETrecoPostIdx(i,j));

      nEventsNorm(i,j) = nEvents(i,j)/nZpeak;
      nEventsNormErr(i,j) = 
	getErrorOnRatio(nEvents(i,j),nEventsErr(i,j),
			nZpeak, sqrt(w2Zpeak));

      nEventsDETNorm(i,j) = nEventsDET(i,j)/nZpeakDET;
      nEventsDETNormErr(i,j) =
	getErrorOnRatio(nEventsDET(i,j),nEventsDETErr(i,j),
			nZpeakDET, sqrt(w2ZpeakDET));

      nEventsDETrecoPostIdxNorm(i,j) = nEventsDETrecoPostIdx(i,j)/nZpeakDETrecoPostIdx;
      nEventsDETrecoPostIdxNormErr(i,j) =
	getErrorOnRatio(nEventsDETrecoPostIdx(i,j),nEventsDETrecoPostIdxErr(i,j),
			nZpeakDETrecoPostIdx, sqrt(w2ZpeakDETrecoPostIdx));
    }
  }
  }



  TString outFile= TString("../root_files/xSecThExt_");
  //outFile.Append("2MCfiles_");
  if (!useFewzWeights) outFile.Append("noFEWZ_");
  if (fineGridStr.Length()) outFile.Append(fineGridStr);
  if (debugMode==1) outFile.Append("debug_");
  outFile.Append( DYTools::analysisTag + TString("_tmp.root") );


  TVectorD rapidityGrid(massGrid.GetNoElements()-1);
  rapidityGrid=1;

  if (debugMode!=-1) {
    TFile thFile(outFile,"recreate");
    massGrid.Write("massBinEdges");
    if (fineGrid) rapidityGrid.Write("rapidityBinCount");
    nEvents.Write("nGenEvents");
    nEventsErr.Write("nGenEventsErr");
    nEventsDET.Write("nGenEventsDET");
    nEventsDETErr.Write("nGenEventsDETErr");
    nEventsDETrecoPostIdx.Write("nGenEventsDETrecoPostIdx");
    nEventsDETrecoPostIdxErr.Write("nGenEventsDETRecoPostIdxErr");
    nEventsNorm.Write("nGenEventsNorm");
    nEventsNormErr.Write("nGenEventsNormErr");
    nEventsDETNorm.Write("nGenEventsDETNorm");
    nEventsDETNormErr.Write("nGenEventsDETNormErr");
    nEventsDETrecoPostIdxNorm.Write("nGenEventsDETrecoPostIdxNorm");
    nEventsDETrecoPostIdxNormErr.Write("nGenEventsDETrecoPostIdxNormErr");
    TVectorD zPeakInfo(6);
    zPeakInfo(0)=nZpeak; zPeakInfo(1)=sqrt(w2Zpeak);
    zPeakInfo(2)=nZpeakDET; zPeakInfo(3)=sqrt(w2ZpeakDET);
    zPeakInfo(4)=nZpeakDETrecoPostIdx; zPeakInfo(5)=sqrt(w2ZpeakDETrecoPostIdx);
    zPeakInfo.Write("zPeakCountAndErr");
    thFile.Close();
    std::cout << "file <" << outFile << "> created\n";
  }
  else {
    TFile thFile(outFile);
    nEvents.Read("nGenEvents");
    nEventsErr.Read("nGenEventsErr");
    nEventsDET.Read("nGenEventsDET");
    nEventsDETErr.Read("nGenEventsDETErr");
    nEventsDETrecoPostIdx.Read("nGenEventsDETrecoPostIdx");
    nEventsDETrecoPostIdxErr.Read("nGenEventsDETRecoPostIdxErr");
    nEventsNorm.Read("nGenEventsNorm");
    nEventsNormErr.Read("nGenEventsNormErr");
    nEventsDETNorm.Read("nGenEventsDETNorm");
    nEventsDETNormErr.Read("nGenEventsDETNormErr");
    nEventsDETrecoPostIdxNorm.Read("nGenEventsDETrecoPostIdxNorm");
    nEventsDETrecoPostIdxNormErr.Read("nGenEventsDETrecoPostIdxNormErr");
    TVectorD zPeakInfo(6);
    zPeakInfo.Read("zPeakCountAndErr");
    thFile.Close();
    
    nZpeak=zPeakInfo[0]; w2Zpeak=SQR(zPeakInfo[1]);
    nZpeakDET=zPeakInfo[2]; w2ZpeakDET=SQR(zPeakInfo[3]);
    nZpeakDETrecoPostIdx=zPeakInfo[4]; w2ZpeakDETrecoPostIdx=SQR(zPeakInfo[5]);
    std::cout << "file <" << outFile << "> loaded\n";
  }

  //--------------------------------------------------------------------------------------------------------------
  // Make plots 
  //==============================================================================================================  
  CPlot::sOutDir="plots" + DYTools::analysisTag;

  TString fileNamePlots=outFile;
  fileNamePlots.ReplaceAll("_tmp.root","_plots_tmp.root");
  TFile *filePlots=new TFile(fileNamePlots,"recreate");
  if (!filePlots) {
    std::cout << "failed to create file <" << fileNamePlots << ">\n";
    throw 2;
  }
  // string buffers
  //char ylabel[50];   // y-axis label


  if (DYTools::study2D) {
    TString c2Dname="canvXsectTh_2D";
    if (useFewzWeights) c2Dname.Append("_FEWZ");
    TCanvas *c2D = MakeCanvas(c2Dname,c2Dname,600,600+300*DYTools::study2D);
    std::vector<TH1F*> hXsecV;
    std::vector<CPlot*> cpV;
    hXsecV.reserve(DYTools::nMassBins);
    cpV.reserve(DYTools::nMassBins);
    for (int iM=0; iM<DYTools::nMassBins; ++iM) {
      double massMin=DYTools::massBinLimits[iM];
      double massMax=DYTools::massBinLimits[iM+1];
      CPlot *cp=new CPlot(Form("cpMass%2.0lf_%2.0lf",massMin,massMax),
			  "","|Y|","counts");
      cpV.push_back(cp);
      hXsecV.push_back( plotXsec2D("xsec",iM,nEvents,nEventsErr,cp,kBlack,1) );
    }
    c2D->Divide(2,3);
    for (int ipad=1; ipad<=6; ++ipad) {
      cpV[ipad]->Draw(c2D,false,"png",ipad);
    }
    c2D->Update();
    SaveCanvas(c2D,c2Dname);
  }

  {
    TString canvName=TString("canvXsectTh_") + fineGridStr + TString("1D");
    if (useFewzWeights) canvName.Append("_FEWZ");
    TCanvas *c1D = MakeCanvas(canvName,canvName,600,600);
    CPlot *cp=new CPlot("cplot_1D","","M_{ee} (GeV)","counts");
    TH1F *hXsec= plotXsec1D("xsec1D",nEvents,nEventsErr,cp,kBlue, fineGrid);
    hXsec->SetDirectory(0);
    cp->SetLogx();
    cp->Draw(c1D,false,"png");
    c1D->Update();
    SaveCanvas(c1D,canvName);
  }
	
  {
    TString canvName=TString("canvXsectThNorm_") + fineGridStr + TString("1D");
    if (useFewzWeights) canvName.Append("_FEWZ");
    TCanvas *c1D = MakeCanvas(canvName,canvName,600,600);
    CPlot *cp=new CPlot("cplotNorm_1D","","M_{ee} (GeV)","normalized counts");
    TH1F *hXsec= plotXsec1D("xsec1D",nEventsNorm,nEventsNormErr,cp,kBlue, fineGrid);
    hXsec->SetDirectory(0);
    cp->SetLogx();
    cp->Draw(c1D,false,"png");
    c1D->Update();
    SaveCanvas(c1D,canvName);
  }
	
  /* 

 // Z mass
  sprintf(ylabel,"a.u. / %.1f GeV/c^{2}",hZMassv[0]->GetBinWidth(1));
  CPlot plotZMass1("zmass1","","m(Z) [GeV/c^{2}]",ylabel);
  for(UInt_t i=0; i<fnamev.size(); i++) { 
    plotZMass1.AddHist1D(hZMassv[i],labelv[i],"hist",colorv[i],linev[i]); 
  }
  plotZMass1.SetLogy();
  plotZMass1.Draw(c);
  SaveCanvas(c, "zmass1");

  PlotMatrixVariousBinning(accv, "acceptance", "LEGO2",filePlots);
  filePlots->Close();
  if (DYTools::study2D==0)
    Plot1D(accv,accErrv,"acceptance1D","acceptance");
  //delete filePlots;
  
  */
  //--------------------------------------------------------------------------------------------------------------
  // Summary print out
  //==============================================================================================================

  if (!fineGrid) {
    const int printSystErr=0;
    TMatrixD zeroErr=nEventsErr; zeroErr=0;
    printYields("nGenEvents", nEvents,nEventsErr,zeroErr, printSystErr);
    printYields("nGenEventsDET", nEventsDET,nEventsDETErr,zeroErr, printSystErr);
    printYields("nGenEventsDETrecoPostIdx",nEventsDETrecoPostIdx,nEventsDETrecoPostIdxErr, zeroErr,printSystErr);
  }

  gBenchmark->Show("getXsec");
}