示例#1
0
bool CTransferRules::initFromTxtFile(vfs::tReadableFile* pFile)
{
	if(pFile && pFile->openRead())
	{
		vfs::COpenReadFile rfile(pFile);
		std::string sBuffer;
		vfs::UInt32 line_counter = 0;
		vfs::CReadLine rl(*pFile);
		while(rl.getLine(sBuffer))
		{
			line_counter++;
			// very simple parsing : key = value
			if(!sBuffer.empty())
			{
				// remove leading white spaces
				::size_t iStart = sBuffer.find_first_not_of(" \t",0);
				char first = sBuffer.at(iStart);
				switch(first)
				{
				case '!':
				case ';':
				case '#':
					// comment -> do nothing
					break;
				default:
					::size_t iEnd = sBuffer.find_first_of(" \t", iStart);
					if(iEnd != std::string::npos)
					{
						SRule rule;
						std::string action = sBuffer.substr(iStart, iEnd - iStart);
						if( vfs::StrCmp::Equal(action, "deny") )
						{
							rule.action = CTransferRules::DENY;
						}
						else if( vfs::StrCmp::Equal(action, "accept") )
						{
							rule.action = CTransferRules::ACCEPT;
						}
						else
						{
							std::wstring trybuffer = L"Invalid UTF-8 character in string";
							VFS_IGNOREEXCEPTION( trybuffer = vfs::String(sBuffer).c_wcs(), "" ); /* just make sure we don't break off when string conversion fails */
							std::wstringstream wss;
							wss << L"Unknown action in file \"" << pFile->getPath().c_wcs()
								<< L", line " << line_counter << " : " << vfs::String(sBuffer).c_wcs();
							SGP_THROW(wss.str().c_str());
						}
						try
						{
							rule.pattern = vfs::Path(vfs::trimString(sBuffer, iEnd, sBuffer.length()));
						}
						catch(vfs::Exception& ex)
						{
							std::wstringstream wss;
							wss << L"Could not convert string, invalid utf8 encoding in file \"" << pFile->getPath().c_wcs()
								<< L"\", line "  << line_counter;
							SGP_RETHROW(wss.str().c_str(), ex);
						}
						m_listRules.push_back(rule);
					}
					break;
				}; // end switch
			} // end if (empty)
		} // end while(!eof)
		return true;
	}
	return false;
}
示例#2
0
QString SGMSettings::SGMDatabaseFilename() const{
	QReadLocker rl(&mutex_);
	return SGMDatabaseFilename_;
}
示例#3
0
map<BinaryData, shared_ptr<BtcWallet> > WalletGroup::getWalletMap(void) const
{
   ReadWriteLock::ReadLock rl(lock_);
   return wallets_;
}
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"); 
}
示例#5
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");
}
示例#6
0
文件: mpt.c 项目: ryanSie/Advantech
int
mpt_get_state(mpt_adap_t *adap)
{
	return rl(DOORBELL) & MPI_IOC_STATE_MASK;
}
示例#7
0
void HwwDYBkgEstimate(const string inputFilename, Double_t mHiggs,
                 const string Label) 
{  
  gBenchmark->Start("WWTemplate");

  
  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //==============================================================================================================
  
  Double_t lumi = 35.5;              // luminosity (pb^-1)
  Int_t ChargeSelection = 0;
//   ChargeSelection = 1;
    
  Double_t fPtMaxLowerCut;
  Double_t fPtMinLowerCut;
  Double_t fDileptonMassUpperCut;
  Double_t fDeltaPhiCut;

  Double_t fHiggsMass = mHiggs;

  //Configure Higgs Mass Dependant Cuts
  if (fHiggsMass == 120) { fPtMaxLowerCut = 20.0;        fPtMinLowerCut = 20.0; 
                           fDileptonMassUpperCut = 40.0; fDeltaPhiCut = 60.0;
  }
  if (fHiggsMass == 130) { fPtMaxLowerCut = 25.0;        fPtMinLowerCut = 20.0;
                           fDileptonMassUpperCut = 45.0; fDeltaPhiCut = 60.0;
  }
  if (fHiggsMass == 140) { fPtMaxLowerCut = 25.0;        fPtMinLowerCut = 20.0;
                           fDileptonMassUpperCut = 45.0; fDeltaPhiCut = 60.0;
  }
  if (fHiggsMass == 150) { fPtMaxLowerCut = 27.0;        fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 50.0; fDeltaPhiCut = 60.0;
  }
  if (fHiggsMass == 160) { fPtMaxLowerCut = 30.0;        fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 50.0; fDeltaPhiCut = 60.0;
  }
  if (fHiggsMass == 170) { fPtMaxLowerCut = 34.0;        fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 50.0; fDeltaPhiCut = 60.0;
  }
  if (fHiggsMass == 180) { fPtMaxLowerCut = 36.0;        fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 60.0; fDeltaPhiCut = 70.0;
  }
  if (fHiggsMass == 190) { fPtMaxLowerCut = 38.0;        fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 80.0; fDeltaPhiCut = 90.0;
  }
  if (fHiggsMass == 200) { fPtMaxLowerCut = 40.0;        fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 90.0; fDeltaPhiCut = 100.0;
  }
  if (fHiggsMass == 210) { fPtMaxLowerCut = 44.0;         fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 110.0; fDeltaPhiCut = 110.0;
  }
  if (fHiggsMass == 220) { fPtMaxLowerCut = 48.0;         fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 120.0; fDeltaPhiCut = 120.0;
  }
  if (fHiggsMass == 230) { fPtMaxLowerCut = 52.0;         fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 130.0; fDeltaPhiCut = 130.0;
  }
  if (fHiggsMass == 250) { fPtMaxLowerCut = 55.0;         fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 150.0; fDeltaPhiCut = 140.0;
  }
  if (fHiggsMass == 300) { fPtMaxLowerCut = 70.0;         fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 200.0; fDeltaPhiCut = 175.0;
  }
  if (fHiggsMass == 350) { fPtMaxLowerCut = 80.0;         fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 250.0; fDeltaPhiCut = 175.0;
  }
  if (fHiggsMass == 400) { fPtMaxLowerCut = 90.0;         fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 300.0; fDeltaPhiCut = 175.0;
  }
  if (fHiggsMass == 450) { fPtMaxLowerCut = 110.0;        fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 350.0; fDeltaPhiCut = 175.0;
  }
  if (fHiggsMass == 500) { fPtMaxLowerCut = 120.0;        fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 400.0; fDeltaPhiCut = 175.0;
  }
  if (fHiggsMass == 550) { fPtMaxLowerCut = 130.0;        fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 450.0; fDeltaPhiCut = 175.0;
  }
  if (fHiggsMass == 600) { fPtMaxLowerCut = 140.0;        fPtMinLowerCut = 25.0;
                           fDileptonMassUpperCut = 500.0; fDeltaPhiCut = 175.0;
  }


  //--------------------------------------------------------------------------------------------------------------
  // Histograms
  //==============================================================================================================  
  TH1D *DileptonMass_allOtherCuts_ee = new TH1D("DileptonMass_allOtherCuts_ee", ";Mass_{ll};Number of Events",150,0.,300.);
  TH1D *DileptonMass_allOtherCuts_emu = new TH1D("DileptonMass_allOtherCuts_emu", ";Mass_{ll};Number of Events",150,0.,300.);
  TH1D *DileptonMass_allOtherCuts_mumu = new TH1D("DileptonMass_allOtherCuts_mumu", ";Mass_{ll};Number of Events",150,0.,300.);
  TH1D *DileptonMass_allOtherCutsExceptMetCut_ee = new TH1D("DileptonMass_allOtherCutsExceptMetCut_ee", ";Mass_{ll};Number of Events",150,0.,300.);
  TH1D *DileptonMass_allOtherCutsExceptMetCut_emu = new TH1D("DileptonMass_allOtherCutsExceptMetCut_emu", ";Mass_{ll};Number of Events",150,0.,300.);
  TH1D *DileptonMass_allOtherCutsExceptMetCut_mumu = new TH1D("DileptonMass_allOtherCutsExceptMetCut_mumu", ";Mass_{ll};Number of Events",150,0.,300.);

  Double_t NEventsIn_BeforeMetCut_ee = 0;
  Double_t NEventsIn_BeforeMetCut_em = 0;
  Double_t NEventsIn_BeforeMetCut_mm = 0;
  Double_t NEventsOut_BeforeMetCut_ee = 0;
  Double_t NEventsOut_BeforeMetCut_em = 0;
  Double_t NEventsOut_BeforeMetCut_mm = 0;
  Double_t NEventsIn_AfterMetCut_ee = 0;
  Double_t NEventsIn_AfterMetCut_em = 0;
  Double_t NEventsIn_AfterMetCut_mm = 0;
  Double_t NEventsOut_AfterMetCut_ee = 0;
  Double_t NEventsOut_AfterMetCut_em = 0;
  Double_t NEventsOut_AfterMetCut_mm = 0;


  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  
  
  //
  // Access samples and fill histograms
  TFile *inputFile=0;
  TTree *eventTree=0;  
   
  // Data structures to store info from TTrees
  mithep::TEventInfo *info    = new mithep::TEventInfo();
  TClonesArray *electronArr = new TClonesArray("mithep::TElectron");
  TClonesArray *muonArr = new TClonesArray("mithep::TMuon");
  TClonesArray *jetArr = new TClonesArray("mithep::TJet");
  
  //********************************************************
  // Good RunLumi Selection
  //********************************************************
  Bool_t hasJSON = kTRUE;
  mithep::RunLumiRangeMap rlrm;
//   rlrm.AddJSONFile("Cert_TopOct22_Merged_135821-148058_allPVT.txt"); 
   rlrm.AddJSONFile("Cert_136033-149442_7TeV_Dec22ReReco_Collisions10_JSON_v3.txt"); 
   hasJSON = kFALSE;

  //********************************************************
  // Get Tree
  //********************************************************
  eventTree = getTreeFromFile(inputFilename.c_str(),"Events"); 
  TBranch *infoBr;
  TBranch *electronBr;
  TBranch *muonBr;
  TBranch *jetBr;


  //*****************************************************************************************
  //Loop over muon Data Tree
  //*****************************************************************************************
  // Set branch address to structures that will store the info  
  eventTree->SetBranchAddress("Info",       &info);      infoBr       = eventTree->GetBranch("Info");
  eventTree->SetBranchAddress("Electron", &electronArr); electronBr = eventTree->GetBranch("Electron");
  eventTree->SetBranchAddress("Muon", &muonArr);         muonBr = eventTree->GetBranch("Muon");
  eventTree->SetBranchAddress("PFJet", &jetArr);         jetBr = eventTree->GetBranch("PFJet");
  
  for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {       	
    infoBr->GetEntry(ientry);
    if (ientry % 100000 == 0) cout << "Event " << ientry << endl;
		
    mithep::RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec);      
    if(hasJSON && !rlrm.HasRunLumi(rl)) continue;  // not certified run? Skip to next event...
     
    //for the skimmed input, I already required the HLT bits.
    //    if (!passHLT(info->triggerBits, info->runNum, kTRUE)) continue;

    //********************************************************
    // Load the branches
    //********************************************************
    electronArr->Clear(); 
    muonArr->Clear(); 
    jetArr->Clear(); 
    electronBr->GetEntry(ientry);
    muonBr->GetEntry(ientry);
    jetBr->GetEntry(ientry);

    //event weight
    Double_t eventweight = info->eventweight * lumi;

    //********************************************************
    // TcMet
    //********************************************************
    TVector3 met;        
    if(info->tcMEx!=0 || info->tcMEy!=0) {       
      met.SetXYZ(info->tcMEx, info->tcMEy, 0);
    }

    //********************************************************
    // TcMet
    //********************************************************

    Int_t NSoftMuons = 0;
    Int_t NLeptons = 0;
    vector<Int_t> leptonType;
    vector<Int_t> leptonIndex;
    vector<Double_t> leptonPt;
    vector<Double_t> leptonEta;
    vector<Double_t> leptonPhi;
    vector<Int_t> leptonCharge;

    Int_t NJets = 0;
    const mithep::TJet *leadingJet = 0;
    
    for(Int_t i=0; i<muonArr->GetEntries(); i++) {
      const mithep::TMuon *mu = (mithep::TMuon*)((*muonArr)[i]);      
      if ( (0==0)
           &&
           passMuonCuts(mu)
           &&
           fabs(mu->eta) < 2.4
           && 
           mu->pt > 10.0
        ) {
        leptonPt.push_back(mu->pt);
        leptonEta.push_back(mu->eta);
        leptonPhi.push_back(mu->phi);
        leptonType.push_back(13);
        leptonIndex.push_back(i);  
        leptonCharge.push_back(mu->q);
      }
    }
    //soft muons
    for(Int_t i=0; i<muonArr->GetEntries(); i++) {
      const mithep::TMuon *mu = (mithep::TMuon*)((*muonArr)[i]);
      Bool_t isCleanMuon = kFALSE;
      for (int k=0; k<leptonPt.size(); ++k) {
        if ( leptonType[k] == 13 
             && mithep::MathUtils::DeltaR(mu->phi, mu->eta, leptonPhi[k],leptonEta[k]) < 0.1
          ) {
          isCleanMuon = kTRUE; 
          break;
        }
      }
      if ( mu->pt > 3.0
           && (mu->qualityBits & kTMLastStationAngTight)
           && mu->nTkHits > 10
           && fabs(mu->d0) < 0.2
           && (mu->typeBits & kTracker)
           && !isCleanMuon
        ) {
        NSoftMuons++;
      }
    }
    for(Int_t i=0; i<electronArr->GetEntries(); i++) {
      const mithep::TElectron *ele = (mithep::TElectron*)((*electronArr)[i]);
      Bool_t isMuonOverlap = kFALSE;
      for (int k=0; k<leptonPt.size(); ++k) {
        if ( leptonType[k] == 13 
             && mithep::MathUtils::DeltaR(ele->phi, ele->eta, leptonPhi[k],leptonEta[k]) < 0.1
          ) {
          isMuonOverlap = kTRUE; 
          break;
        }        
      }

      if ( (0==0)
           && 
           passElectronCuts(ele)
           &&
           fabs(ele->eta) < 2.5
           && 
           ele->pt > 10.0
           &&
           !isMuonOverlap
        ) {
        leptonPt.push_back(ele->pt);
        leptonEta.push_back(ele->eta);
        leptonPhi.push_back(ele->phi);
        leptonType.push_back(11);
        leptonIndex.push_back(i);
        leptonCharge.push_back(ele->q);
      }
    }


    //sort leptons
    Int_t tempType;
    Int_t tempIndex;
    Double_t tempPt;
    Double_t tempEta;
    Double_t tempPhi;
    Int_t tempCharge;
    for (int l=0; l<leptonIndex.size(); l++) {
      for (int k=0; k < leptonIndex.size() - 1; k++) {
        if (leptonPt[k+1] > leptonPt[k]) {
          tempType = leptonType[k];
          tempIndex = leptonIndex[k];
          tempPt = leptonPt[k];
          tempEta = leptonEta[k];
          tempPhi = leptonPhi[k];
          tempCharge = leptonCharge[k];
          
          leptonType[k] = leptonType[k+1];
          leptonIndex[k] = leptonIndex[k+1];
          leptonPt[k] = leptonPt[k+1];
          leptonEta[k] = leptonEta[k+1];
          leptonPhi[k] = leptonPhi[k+1];
          leptonCharge[k] = leptonCharge[k+1];

          leptonType[k+1] = tempType;
          leptonIndex[k+1] = tempIndex;
          leptonPt[k+1] = tempPt;
          leptonEta[k+1] = tempEta;
          leptonPhi[k+1] = tempPhi;
          leptonCharge[k+1] = tempCharge;
          
        }
      }
    }

    double maxBtag = -99999;
    for(Int_t i=0; i<jetArr->GetEntries(); i++) {
      const mithep::TJet *jet = (mithep::TJet*)((*jetArr)[i]);

      Bool_t leptonOverlap = kFALSE;
      for (int k=0; k<leptonPt.size(); ++k) {
        if (mithep::MathUtils::DeltaR(jet->phi, jet->eta, leptonPhi[k],leptonEta[k]) < 0.3) {
          leptonOverlap = kTRUE;
        }
      }

      if (!leptonOverlap) {
        if (jet->pt > 25 && fabs(jet->eta) < 5.0 ) {
          if (!leadingJet || jet->pt > leadingJet->pt) {
            leadingJet = jet;
          }
          NJets++;
        } else {
          if (jet->TrackCountingHighEffBJetTagsDisc > maxBtag ) maxBtag = jet->TrackCountingHighEffBJetTagsDisc;
        }
      }
    }


    //******************************************************************************
    //dilepton preselection
    //******************************************************************************
    if (leptonPt.size() < 2) continue;
    if (!(leptonPt[0] > 20.0 && leptonPt[1] > 10.0)) continue;

    for(int i = 0; i < leptonPt.size(); ++i) {
      for(int j = i+1; j < leptonPt.size(); ++j) {

        //require opposite sign
        if ((ChargeSelection == 0 && leptonCharge[i] == leptonCharge[j]) || (ChargeSelection == 1 && leptonCharge[0] != leptonCharge[j])) continue;


        Int_t finalState = -1;
        if (leptonType[i] == 11 && leptonType[j] == 11) {
          finalState = 0;
        } else if (leptonType[i] == 13 && leptonType[j] == 13) {
          finalState = 1;
        } else if (leptonType[i] == 11 && leptonType[j] == 13) {
          finalState = 2;
        } else if (leptonType[i] == 13 && leptonType[j] == 11) {
          finalState = 3;
        }


        //***********************************************************************************************
        //|Z_vert-Z_l| maximum
        //***********************************************************************************************
        double zDiffMax = 0.0;
       
        double dz_i = 0;
        if (leptonType[0] == 11) {
          dz_i = ((mithep::TElectron*)((*electronArr)[leptonIndex[i]]))->dz;
        } else {
          dz_i = ((mithep::TMuon*)((*muonArr)[leptonIndex[i]]))->dz;
        }
        if (dz_i > zDiffMax) zDiffMax = dz_i;
    
        double dz_j;
        if (leptonType[j] == 11) {
          dz_j = ((mithep::TElectron*)((*electronArr)[leptonIndex[j]]))->dz;
        } else {
          dz_j = ((mithep::TMuon*)((*muonArr)[leptonIndex[j]]))->dz;
        }
        if (dz_j > zDiffMax) zDiffMax = dz_j;
        //szDiffMax = fabs(dz_i - dz_j);

        //******************************************************************************
        //construct event variables
        //******************************************************************************
        mithep::FourVectorM lepton1;
        mithep::FourVectorM lepton2;
        if (leptonType[i] == 11) {
          lepton1.SetCoordinates(leptonPt[i], leptonEta[i], leptonPhi[i], 0.51099892e-3 );
        } else {
          lepton1.SetCoordinates(leptonPt[i], leptonEta[i], leptonPhi[i], 105.658369e-3 );
        }
        if (leptonType[j] == 11) {
          lepton2.SetCoordinates(leptonPt[j], leptonEta[j], leptonPhi[j], 0.51099892e-3 );
        } else {
          lepton2.SetCoordinates(leptonPt[j], leptonEta[j], leptonPhi[j], 105.658369e-3 );
        }
        mithep::FourVectorM dilepton = lepton1+lepton2;

        double deltaPhiLeptons = mithep::MathUtils::DeltaPhi(lepton1.Phi(), 
                                                             lepton2.Phi())* 180.0 / TMath::Pi();    
        double deltaPhiDileptonMet = mithep::MathUtils::DeltaPhi(met.Phi(), 
                                                                 dilepton.Phi())*180.0 / TMath::Pi();    
        double mtHiggs = TMath::Sqrt(2.0*dilepton.Pt() * met.Phi()*
                                     (1.0 - cos(deltaPhiDileptonMet * TMath::Pi() / 180.0)));

        //angle between MET and closest lepton
        double deltaPhiMetLepton[2] = {mithep::MathUtils::DeltaPhi(met.Phi(), lepton1.Phi()),
                                       mithep::MathUtils::DeltaPhi(met.Phi(), lepton2.Phi())};
  
        double mTW[2] = {TMath::Sqrt(2.0*lepton1.Pt()*met.Pt()*
                                     (1.0 - cos(deltaPhiMetLepton[0]))),
                         TMath::Sqrt(2.0*lepton2.Pt()*met.Pt()*
                                     (1.0 - cos(deltaPhiMetLepton[1])))};

        double minDeltaPhiMetLepton = (deltaPhiMetLepton[0] < deltaPhiMetLepton[1])?
          deltaPhiMetLepton[0]:deltaPhiMetLepton[1];

        double METdeltaPhilEt = met.Pt();
        if(minDeltaPhiMetLepton < TMath::Pi()/2.)
          METdeltaPhilEt = METdeltaPhilEt * sin(minDeltaPhiMetLepton);

    
        //*********************************************************************************************
        //Define Cuts
        //*********************************************************************************************
        const int nCuts = 14;
        bool passCut[nCuts] = {false, false, false, false, false, false, false, false, false, false,
                               false, false, false, false};
  
        if(lepton1.Pt() >  20.0 &&
           lepton2.Pt() >= 10.0) passCut[0] = true;

        if(zDiffMax < 1.0)                    passCut[1] = true;
  
        if(met.Pt()    > 20.0)               passCut[2] = true;
  
        if(dilepton.M() > 12.0)            passCut[3] = true;
   
        if (finalState == 0 || finalState == 1){ // mumu/ee
          if(fabs(dilepton.M()-91.1876)   > 15.0)   passCut[4] = true;
          if(METdeltaPhilEt > 35) passCut[5] = true;
        }
        else if(finalState == 2 ||finalState == 3 ) { // emu
          passCut[4] = true;
          if(METdeltaPhilEt > 35) passCut[5] = true;
        }

        if(NJets     < 1)              passCut[6] = true;
        
        if (NSoftMuons == 0 )      passCut[7] = true;

        if (!(leptonPt.size() >= 3 && leptonPt[2] > 10.0)) passCut[8] = true;

        if(maxBtag < 2.1)                     passCut[9] = true;

        if (lepton1.Pt() > fPtMaxLowerCut) passCut[10] = true;
        if (lepton2.Pt() > fPtMinLowerCut) passCut[11] = true;
        if (dilepton.M() < fDileptonMassUpperCut)   passCut[12] = true;
        if (deltaPhiLeptons < fDeltaPhiCut) passCut[13] = true;

        //*********************************************************************************************
        //Make Selection Histograms. Number of events passing each level of cut
        //*********************************************************************************************  
        bool passAllCuts = true;
        for(int c=0; c<nCuts; c++) passAllCuts = passAllCuts & passCut[c];
    
  
        //*****************************************************************************************
        //Make Histograms Before Met Cut
        //*****************************************************************************************
        if (passCut[0] && passCut[1] && passCut[3] && passCut[6] &&passCut[7] && passCut[8] && passCut[9] 
//             && passCut[10] && passCut[11] && passCut[13] 
          ) {

          if (finalState == 0) {
            DileptonMass_allOtherCutsExceptMetCut_ee->Fill(dilepton.M());
            if(fabs(dilepton.M()-91.1876)   > 15.0) {
              NEventsOut_BeforeMetCut_ee++;
            } else {
              NEventsIn_BeforeMetCut_ee++;
            }

          } else if (finalState == 1) {
            DileptonMass_allOtherCutsExceptMetCut_mumu->Fill(dilepton.M());
            if(fabs(dilepton.M()-91.1876)   > 15.0) {
              NEventsOut_BeforeMetCut_mm++;
            } else {
              NEventsIn_BeforeMetCut_mm++;
            }

          } else {
            DileptonMass_allOtherCutsExceptMetCut_emu->Fill(dilepton.M());
            if(fabs(dilepton.M()-91.1876)   > 15.0) {
              NEventsOut_BeforeMetCut_em++;
            } else {
              NEventsIn_BeforeMetCut_em++;
            }
          }        
        }

        //*****************************************************************************************
        //Make Histograms  
        //*****************************************************************************************
        if (passCut[0] && passCut[1] && passCut[2] && passCut[3] && passCut[5] &&passCut[6] &&passCut[7] && passCut[8] && passCut[9] 
//             && passCut[10] && passCut[11] && passCut[13] 
          ) {

          if (finalState == 0) {
            DileptonMass_allOtherCuts_ee->Fill(dilepton.M());
            if(fabs(dilepton.M()-91.1876)   > 15.0) {
              NEventsOut_AfterMetCut_ee++;
            } else {
              NEventsIn_AfterMetCut_ee++;
              cout << info->runNum << " " << info->lumiSec << " " << info->evtNum << " : " << dilepton.M() << " " 
                   << finalState << " : " << lepton1.Pt() << " " << lepton1.Eta() << " " << lepton1.Phi() << " : " 
                   << " : " << lepton2.Pt() << " " << lepton2.Eta() << " " << lepton2.Phi() << " \n" ;
            }
          } else if (finalState == 1) {
            DileptonMass_allOtherCuts_mumu->Fill(dilepton.M());
            if(fabs(dilepton.M()-91.1876)   > 15.0) {
              NEventsOut_AfterMetCut_mm++;
            } else {
              NEventsIn_AfterMetCut_mm++;
              cout << info->runNum << " " << info->lumiSec << " " << info->evtNum << " : " << dilepton.M() << " " 
                   << finalState << " : " << lepton1.Pt() << " " << lepton1.Eta() << " " << lepton1.Phi() << " : " 
                   << " : " << lepton2.Pt() << " " << lepton2.Eta() << " " << lepton2.Phi() << " \n" ;
            }
          } else {
            DileptonMass_allOtherCuts_emu->Fill(dilepton.M());
            if(fabs(dilepton.M()-91.1876)   > 15.0) {
              NEventsOut_AfterMetCut_em++;
            } else {
              NEventsIn_AfterMetCut_em++;
              cout << info->runNum << " " << info->lumiSec << " " << info->evtNum << " : " << dilepton.M() << " " 
                   << finalState << " : " << lepton1.Pt() << " " << lepton1.Eta() << " " << lepton1.Phi() << " : " 
                   << " : " << lepton2.Pt() << " " << lepton2.Eta() << " " << lepton2.Phi() << " \n" ;
            }
          }        
        }



      }
    }
  

  } //end loop over data     



  delete info;
  delete electronArr;
  delete muonArr;
  delete jetArr;


  //--------------------------------------------------------------------------------------------------------------
  // Make plots
  //==============================================================================================================
  TCanvas *cv = new TCanvas("cv","cv", 800,600);

  //--------------------------------------------------------------------------------------------------------------
  // Summary print out
  //============================================================================================================== 



  cout << "Before Met Cut\n";
  cout << "Number of Events in Z window : (ee) " << NEventsIn_BeforeMetCut_ee << " (mm) " << NEventsIn_BeforeMetCut_mm << endl;
  cout << "Number of Events out of Z window : (ee) " << NEventsOut_BeforeMetCut_ee << " (mm) " << NEventsOut_BeforeMetCut_mm << endl;
  cout << "Ratio Out/In : (ee) " << NEventsOut_BeforeMetCut_ee / NEventsIn_BeforeMetCut_ee << " (mm) "
       << NEventsOut_BeforeMetCut_mm / NEventsIn_BeforeMetCut_mm << endl; 


  cout << "After Met Cut\n";
  cout << "Number of Events in Z window : (ee) " << NEventsIn_AfterMetCut_ee << " (mm) " 
       << NEventsIn_AfterMetCut_mm << " (em) " << NEventsIn_AfterMetCut_em << endl;
  cout << "Number of Events out of Z window : (ee) " << NEventsOut_AfterMetCut_ee << " (mm) " 
       << NEventsOut_AfterMetCut_mm << " (em) " << NEventsOut_AfterMetCut_em << endl;








  //--------------------------------------------------------------------------------------------------------------
  // Save Histograms;
  //============================================================================================================== 
  TFile *file = new TFile("HwwSelectionPlots.root", "RECREATE");
  
  
  file->WriteTObject(DileptonMass_allOtherCuts_ee ,DileptonMass_allOtherCuts_ee->GetName(), "WriteDelete");
  file->WriteTObject(DileptonMass_allOtherCuts_mumu ,DileptonMass_allOtherCuts_mumu->GetName(), "WriteDelete");
  file->WriteTObject(DileptonMass_allOtherCuts_emu ,DileptonMass_allOtherCuts_emu->GetName(), "WriteDelete");

  file->WriteTObject(DileptonMass_allOtherCutsExceptMetCut_ee ,DileptonMass_allOtherCutsExceptMetCut_ee->GetName(), "WriteDelete");
  file->WriteTObject(DileptonMass_allOtherCutsExceptMetCut_mumu ,DileptonMass_allOtherCutsExceptMetCut_mumu->GetName(), "WriteDelete");
  file->WriteTObject(DileptonMass_allOtherCutsExceptMetCut_emu ,DileptonMass_allOtherCutsExceptMetCut_emu->GetName(), "WriteDelete");
  file->Close();
  delete file;

        
  gBenchmark->Show("WWTemplate");       
} 
示例#8
0
void selectZmm(const TString conf="zmm.conf", // input file
               const TString outputDir=".",   // output directory
	       const Bool_t  doScaleCorr=0,    // apply energy scale corrections
	       const Bool_t  doPU=0
) {
  gBenchmark->Start("selectZmm");

  //--------------------------------------------------------------------------------------------------------------
  // 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/puWeights_76x.root", "read");

  TH1D *h_rw = (TH1D*) f_rw->Get("puWeights");
  TH1D *h_rw_up = (TH1D*) f_rw->Get("puWeightsUp");
  TH1D *h_rw_down = (TH1D*) f_rw->Get("puWeightsDown");


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

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

  enum { eMuMu2HLT=1, eMuMu1HLT1L1, eMuMu1HLT, eMuMuNoSel, eMuSta, eMuTrk };  // event category enum
  
  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  matchGen;
  UInt_t  category;
  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;
  Float_t genVPt, genVPhi, genVy, genVMass;
  Float_t genWeight, PUWeight;
  Float_t scale1fb,scale1fbUp,scale1fbDown;
  Float_t met, metPhi, sumEt, u1, u2;
  Float_t tkMet, tkMetPhi, tkSumEt, tkU1, tkU2;
  Float_t mvaMet, mvaMetPhi, mvaSumEt, mvaU1, mvaU2;
  Float_t puppiMet, puppiMetPhi, puppiSumEt, puppiU1, puppiU2;
  Int_t   q1, q2;
  TLorentzVector *dilep=0, *lep1=0, *lep2=0;
  ///// muon specific /////
  Float_t trkIso1, emIso1, hadIso1, trkIso2, emIso2, hadIso2;
  Float_t pfChIso1, pfGamIso1, pfNeuIso1, pfCombIso1, pfChIso2, pfGamIso2, pfNeuIso2, pfCombIso2;
  Float_t d01, dz1, d02, dz2;
  Float_t muNchi21,  muNchi22;
  UInt_t nPixHits1, nTkLayers1, nPixHits2, nTkLayers2;
  UInt_t nValidHits1, nMatch1, nValidHits2, nMatch2;
  UInt_t typeBits1, typeBits2;
  TLorentzVector *sta1=0, *sta2=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 *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 "zmm" - flag to store GEN Z kinematics
    Bool_t isSignal = (snamev[isam].CompareTo("zmm",TString::kIgnoreCase)==0);
    // 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.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("matchGen",    &matchGen,   "matchGen/i");    // event has both leptons matched to MC Z->ll
    outTree->Branch("category",    &category,   "category/i");    // dilepton category
    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("npv",         &npv,        "npv/i");         // number of primary vertices
    outTree->Branch("npu",         &npu,        "npu/i");         // number of in-time PU events (MC)
    outTree->Branch("genV",        "TLorentzVector",  &genV);     // GEN boson 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("genWeight",   &genWeight,  "genWeight/F");
    outTree->Branch("PUWeight",    &PUWeight,   "PUWeight/F");
    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("met",         &met,        "met/F");         // MET
    outTree->Branch("metPhi",      &metPhi,     "metPhi/F");      // phi(MET)
    outTree->Branch("sumEt",       &sumEt,      "sumEt/F");       // Sum ET
    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("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("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("q1",          &q1,         "q1/I");          // charge of tag lepton
    outTree->Branch("q2",          &q2,         "q2/I");          // charge of probe lepton
    outTree->Branch("dilep",       "TLorentzVector", &dilep);     // di-lepton 4-vector
    outTree->Branch("lep1",        "TLorentzVector", &lep1);      // tag lepton 4-vector
    outTree->Branch("lep2",        "TLorentzVector", &lep2);      // probe lepton 4-vector
    ///// muon specific /////
    outTree->Branch("trkIso1",     &trkIso1,     "trkIso1/F");       // track isolation of tag lepton
    outTree->Branch("trkIso2",     &trkIso2,     "trkIso2/F");       // track isolation of probe lepton
    outTree->Branch("emIso1",      &emIso1,      "emIso1/F");        // ECAL isolation of tag lepton
    outTree->Branch("emIso2",      &emIso2,      "emIso2/F");        // ECAL isolation of probe lepton
    outTree->Branch("hadIso1",     &hadIso1,     "hadIso1/F");       // HCAL isolation of tag lepton
    outTree->Branch("hadIso2",     &hadIso2,     "hadIso2/F");       // HCAL isolation of probe lepton
    outTree->Branch("pfChIso1",    &pfChIso1,    "pfChIso1/F");      // PF charged hadron isolation of tag lepton
    outTree->Branch("pfChIso2",    &pfChIso2,    "pfChIso2/F");      // PF charged hadron isolation of probe lepton
    outTree->Branch("pfGamIso1",   &pfGamIso1,   "pfGamIso1/F");     // PF photon isolation of tag lepton
    outTree->Branch("pfGamIso2",   &pfGamIso2,   "pfGamIso2/F");     // PF photon isolation of probe lepton
    outTree->Branch("pfNeuIso1",   &pfNeuIso1,   "pfNeuIso1/F");     // PF neutral hadron isolation of tag lepton
    outTree->Branch("pfNeuIso2",   &pfNeuIso2,   "pfNeuIso2/F");     // PF neutral hadron isolation of probe lepton
    outTree->Branch("pfCombIso1",  &pfCombIso1,  "pfCombIso1/F");    // PF combined isolation of tag lepton
    outTree->Branch("pfCombIso2",  &pfCombIso2,  "pfCombIso2/F");    // PF combined isolation of probe lepton    
    outTree->Branch("d01",         &d01,         "d01/F");           // transverse impact parameter of tag lepton
    outTree->Branch("d02",         &d02,         "d02/F");           // transverse impact parameter of probe lepton	 
    outTree->Branch("dz1",         &dz1,         "dz1/F");           // longitudinal impact parameter of tag lepton
    outTree->Branch("dz2",         &dz2,         "dz2/F");           // longitudinal impact parameter of probe lepton	 
    outTree->Branch("muNchi21",    &muNchi21,    "muNchi21/F");      // muon fit normalized chi^2 of tag lepton
    outTree->Branch("muNchi22",    &muNchi22,    "muNchi22/F");      // muon fit normalized chi^2 of probe lepton
    outTree->Branch("nPixHits1",   &nPixHits1,	 "nPixHits1/i");     // number of pixel hits of tag muon
    outTree->Branch("nPixHits2",   &nPixHits2,	 "nPixHits2/i");     // number of pixel hits of probe muon
    outTree->Branch("nTkLayers1",  &nTkLayers1,  "nTkLayers1/i");    // number of tracker layers of tag muon
    outTree->Branch("nTkLayers2",  &nTkLayers2,  "nTkLayers2/i");    // number of tracker layers of probe muon
    outTree->Branch("nMatch1",     &nMatch1,	 "nMatch1/i");       // number of matched segments of tag muon
    outTree->Branch("nMatch2",     &nMatch2,	 "nMatch2/i");       // number of matched segments of probe muon 
    outTree->Branch("nValidHits1", &nValidHits1, "nValidHits1/i");   // number of valid muon hits of tag muon
    outTree->Branch("nValidHits2", &nValidHits2, "nValidHits2/i");   // number of valid muon hits of probe muon
    outTree->Branch("typeBits1",   &typeBits1,   "typeBits1/i");     // muon type of tag muon
    outTree->Branch("typeBits2",   &typeBits2,   "typeBits2/i");     // muon type of probe muon
    outTree->Branch("sta1",        "TLorentzVector", &sta1);         // tag standalone muon 4-vector
    outTree->Branch("sta2",        "TLorentzVector", &sta2);         // probe standalone muon 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);
      if (samp->fnamev[ifile] == "/dev/null") 
	      {
	     	cout <<"-> Ignoring null input "<<endl; 
		continue;
	      }


      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;
      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 = doPU ? h_rw->GetBinContent(h_rw->FindBin(info->nPUmean)) : 1.;
	  puWeightUp = doPU ? h_rw_up->GetBinContent(h_rw_up->FindBin(info->nPUmean)) : 1.;
	  puWeightDown = doPU ? h_rw_down->GetBinContent(h_rw_down->FindBin(info->nPUmean)) : 1.;
	  totalWeight+=gen->weight*puWeight;
	  totalWeightUp+=gen->weight*puWeightUp;
	  totalWeightDown+=gen->weight*puWeightDown;
	}
      }
      else if (not isData){
	for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
	  puWeight = doPU ? h_rw->GetBinContent(h_rw->FindBin(info->nPUmean)) : 1.;
	  puWeightUp = doPU ? h_rw_up->GetBinContent(h_rw_up->FindBin(info->nPUmean)) : 1.;
	  puWeightDown = doPU ? h_rw_down->GetBinContent(h_rw_down->FindBin(info->nPUmean)) : 1.;
	  totalWeight+= 1.0*puWeight;
	  totalWeightUp+= 1.0*puWeightUp;
	  totalWeightDown+= 1.0*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 weight=1;
	Double_t weightUp=1;
	Double_t weightDown=1;
    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 = doPU ? h_rw->GetBinContent(h_rw->FindBin(info->nPUmean)) : 1.;
	  puWeightUp = doPU ? h_rw_up->GetBinContent(h_rw_up->FindBin(info->nPUmean)) : 1.;
	  puWeightDown = doPU ? h_rw_down->GetBinContent(h_rw_down->FindBin(info->nPUmean)) : 1.;
	  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;
     
        // 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;

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

	TLorentzVector vTag(0,0,0,0);
	TLorentzVector vTagSta(0,0,0,0);
	Double_t tagPt=0;
	Double_t Pt1=0;
	Double_t Pt2=0;
	Int_t itag=-1;
	
        for(Int_t i1=0; i1<muonArr->GetEntriesFast(); i1++) {
          const baconhep::TMuon *tag = (baconhep::TMuon*)((*muonArr)[i1]);

          // apply scale and resolution corrections to MC
          Double_t tagpt_corr = tag->pt;
          if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0)
            tagpt_corr = gRandom->Gaus(tag->pt*getMuScaleCorr(tag->eta,0),getMuResCorr(tag->eta,0));
	
	  if(tagpt_corr     < PT_CUT)        continue;  // lepton pT cut
	  if(fabs(tag->eta) > ETA_CUT)       continue;  // lepton |eta| cut
	  if(!passMuonID(tag))               continue;  // lepton selection

	  double Mu_Pt=0;
	  if(doScaleCorr) {
	    Mu_Pt=gRandom->Gaus(tag->pt*getMuScaleCorr(tag->eta,0),getMuResCorr(tag->eta,0));
	  }
	  else
	    {
	      Mu_Pt=tag->pt;
	    }

	  if(Mu_Pt>Pt1)
	    {
	      Pt2=Pt1;
	      Pt1=Mu_Pt;
	    }
	  else if(Mu_Pt>Pt2&&Mu_Pt<Pt1)
	    {
	      Pt2=Mu_Pt;
	    }

          if(!isMuonTriggerObj(triggerMenu, tag->hltMatchBits, kFALSE)) continue;

	  if(Mu_Pt<tagPt) continue;

	  tagPt=Mu_Pt;
	  itag=i1;
        
          // apply scale and resolution corrections to MC
          if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0) {
            vTag.SetPtEtaPhiM(tagpt_corr,tag->eta,tag->phi,MUON_MASS);
            vTagSta.SetPtEtaPhiM(gRandom->Gaus(tag->staPt*getMuScaleCorr(tag->eta,0),getMuResCorr(tag->eta,0)),tag->staEta,tag->staPhi,MUON_MASS);
          } else {
            vTag.SetPtEtaPhiM(tag->pt,tag->eta,tag->phi,MUON_MASS);
            vTagSta.SetPtEtaPhiM(tag->staPt,tag->staEta,tag->staPhi,MUON_MASS);
          }

	  trkIso1     = tag->trkIso;
	  emIso1      = tag->ecalIso;	    
	  hadIso1     = tag->hcalIso;
	  pfChIso1    = tag->chHadIso;
	  pfGamIso1   = tag->gammaIso;
	  pfNeuIso1   = tag->neuHadIso;
	  pfCombIso1  = tag->chHadIso + TMath::Max(tag->neuHadIso + tag->gammaIso - 
						   0.5*(tag->puIso),Double_t(0));
	  d01         = tag->d0;
	  dz1         = tag->dz;
	  muNchi21    = tag->muNchi2;
	  nPixHits1   = tag->nPixHits;
	  nTkLayers1  = tag->nTkLayers;
	  nMatch1     = tag->nMatchStn;
	  nValidHits1 = tag->nValidHits;
	  typeBits1   = tag->typeBits;
	  q1 = tag->q;
	}

	if(tagPt<Pt2) continue;

	TLorentzVector vProbe(0,0,0,0); TLorentzVector vProbeSta(0,0,0,0);
	Double_t probePt=0;
	Int_t passID=false;
	UInt_t icat=0;

	for(Int_t i2=0; i2<muonArr->GetEntriesFast(); i2++) {
	  if(itag==i2) continue;
	  const baconhep::TMuon *probe = (baconhep::TMuon*)((*muonArr)[i2]);
	  

	  // apply scale and resolution corrections to MC
	  Double_t probept_corr = probe->pt;
	  if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0)
	    probept_corr = gRandom->Gaus(probe->pt*getMuScaleCorr(probe->eta,0),getMuResCorr(probe->eta,0));

	  if(probept_corr     < PT_CUT)  continue;  // lepton pT cut
	  if(fabs(probe->eta) > ETA_CUT) continue;  // lepton |eta| cut

	  double Mu_Pt=probept_corr;
  
	  if(passID&&passMuonID(probe)&&Mu_Pt<probePt) continue;
	  if(passID&&!passMuonID(probe)) continue;
	  if(!passID&&!passMuonID(probe)&&Mu_Pt<probePt) continue;

	  if(!passID&&passMuonID(probe)) passID=true;

	  probePt=Mu_Pt;

	  // apply scale and resolution corrections to MC
	  if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0) {
	    vProbe.SetPtEtaPhiM(probept_corr,probe->eta,probe->phi,MUON_MASS);
	    if(probe->typeBits & baconhep::EMuType::kStandalone)
	      vProbeSta.SetPtEtaPhiM(gRandom->Gaus(probe->staPt*getMuScaleCorr(probe->eta,0),getMuResCorr(probe->eta,0)),probe->staEta,probe->staPhi,MUON_MASS);
	  } else {
	    vProbe.SetPtEtaPhiM(probe->pt,probe->eta,probe->phi,MUON_MASS);
	    if(probe->typeBits & baconhep::EMuType::kStandalone)
	      vProbeSta.SetPtEtaPhiM(probe->staPt,probe->staEta,probe->staPhi,MUON_MASS);
	  }

	  trkIso2     = probe->trkIso;
	  emIso2      = probe->ecalIso;
	  hadIso2     = probe->hcalIso;
	  pfChIso2    = probe->chHadIso;
	  pfGamIso2   = probe->gammaIso;
	  pfNeuIso2   = probe->neuHadIso;
	  pfCombIso2  = probe->chHadIso + TMath::Max(probe->neuHadIso + probe->gammaIso - 
						     0.5*(probe->puIso),Double_t(0));
	  d02         = probe->d0;
	  dz2         = probe->dz;
	  muNchi22    = probe->muNchi2;
	  nPixHits2   = probe->nPixHits;
	  nTkLayers2  = probe->nTkLayers;
	  nMatch2     = probe->nMatchStn;
	  nValidHits2 = probe->nValidHits;
	  typeBits2   = probe->typeBits;
	  q2 = probe->q;

	  // determine event category
	  if(passMuonID(probe)) {
	    if(isMuonTriggerObj(triggerMenu, probe->hltMatchBits, kFALSE)) {
	      icat=eMuMu2HLT;
	    }
	    else if(isMuonTriggerObj(triggerMenu, probe->hltMatchBits, kTRUE)) {
	      icat=eMuMu1HLT1L1;
	  }
	    else {
	      icat=eMuMu1HLT;
	    }
	  }
	  else if(probe->typeBits & baconhep::EMuType::kGlobal) { icat=eMuMuNoSel; }
	  else if(probe->typeBits & baconhep::EMuType::kStandalone) { icat=eMuSta; }
	  else if(probe->nTkLayers>=6 && probe->nPixHits>=1)        { icat=eMuTrk; }
	}
	
	if(q1 == q2)         continue;  // opposite charge requirement
	    
	// mass window
	TLorentzVector vDilep = vTag + vProbe;
	if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue;
	
	if(icat==0) continue;
	
	/******** We have a Z candidate! HURRAY! ********/
	nsel+=weight;
	nselvar+=weight*weight;
	
	// Perform matching of dileptons to GEN leptons from Z decay

	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(vTag.Eta(), vTag.Phi(), glep1->Eta(), glep1->Phi())<0.5) ||
			    ((glep2) && toolbox::deltaR(vTag.Eta(), vTag.Phi(), glep2->Eta(), glep2->Phi())<0.5) );
	  
	  Bool_t match2 = ( ((glep1) && toolbox::deltaR(vProbe.Eta(), vProbe.Phi(), glep1->Eta(), glep1->Phi())<0.5) ||
			    ((glep2) && toolbox::deltaR(vProbe.Eta(), vProbe.Phi(), glep2->Eta(), glep2->Phi())<0.5) );

	  if(match1 && match2) {
	    hasGenMatch = kTRUE;
	    if (gvec!=0) {
	      genV=new TLorentzVector(0,0,0,0);
	      genV->SetPtEtaPhiM(gvec->Pt(), gvec->Eta(), gvec->Phi(), gvec->M());
	      genVPt   = gvec->Pt();
	      genVPhi  = gvec->Phi();
	      genVy    = gvec->Rapidity();
	      genVMass = gvec->M();
	    }
	    else {
	      TLorentzVector tvec=*glep1+*glep2;
	      genV=new TLorentzVector(0,0,0,0);
	      genV->SetPtEtaPhiM(tvec.Pt(), tvec.Eta(), tvec.Phi(), tvec.M());
	      genVPt   = tvec.Pt();
	      genVPhi  = tvec.Phi();
	      genVy    = tvec.Rapidity();
	      genVMass = tvec.M();
	    }
	    delete gvec;
	    delete glep1;
	    delete glep2;
	    glep1=0; glep2=0; gvec=0;
	  }
	  else {
	    genV     = new TLorentzVector(0,0,0,0); 
	    genVPt   = -999;
	    genVPhi  = -999;
	    genVy    = -999;
	    genVMass = -999;
	  }
	}
	
	if (hasGen) {
	  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;
	}
	else {
	  id_1      = -999;
	  id_2      = -999;
	  x_1       = -999;
	  x_2       = -999;
	  xPDF_1    = -999;
	  xPDF_2    = -999;
	  scalePDF  = -999;
	  weightPDF = -999;
	}
	
	//
	// Fill tree
	//
	runNum   = info->runNum;
	lumiSec  = info->lumiSec;
	evtNum   = info->evtNum;
	
	if (hasGenMatch) matchGen=1;
	else matchGen=0;
	
	category = icat;
	
	vertexArr->Clear();
	vertexBr->GetEntry(ientry);
	
	npv      = vertexArr->GetEntries();
	npu      = info->nPUmean;
	genWeight= hasGen ? gen->weight: 1.;
	PUWeight = puWeight;
	scale1fb = weight;
	scale1fbUp = weightUp;
	scale1fbDown = weightDown;
	met      = info->pfMETC;
	metPhi   = info->pfMETCphi;
	sumEt    = 0;
	tkMet    = info->trkMET;
	tkMetPhi = info->trkMETphi;
	tkSumEt  = 0;
	mvaMet   = info->mvaMET;
	mvaMetPhi = info->mvaMETphi;
	mvaSumEt = 0;
	TVector2 vZPt((vDilep.Pt())*cos(vDilep.Phi()),(vDilep.Pt())*sin(vDilep.Phi()));

        puppiMet = info->puppET;
        puppiMetPhi = info->puppETphi;
	puppiSumEt = 0;
	lep1     = &vTag;
	lep2     = &vProbe;
	dilep    = &vDilep;
	sta1        = &vTagSta;
	sta2        = &vProbeSta;
	
	TVector2 vMet((info->pfMETC)*cos(info->pfMETCphi), (info->pfMETC)*sin(info->pfMETCphi));
	TVector2 vU = -1.0*(vMet+vZPt);
	u1 = ((vDilep.Px())*(vU.Px()) + (vDilep.Py())*(vU.Py()))/(vDilep.Pt());  // u1 = (pT . u)/|pT|
	u2 = ((vDilep.Px())*(vU.Py()) - (vDilep.Py())*(vU.Px()))/(vDilep.Pt());  // u2 = (pT x u)/|pT|
	
	TVector2 vTkMet((info->trkMET)*cos(info->trkMETphi), (info->trkMET)*sin(info->trkMETphi));
	TVector2 vTkU = -1.0*(vTkMet+vZPt);
	tkU1 = ((vDilep.Px())*(vTkU.Px()) + (vDilep.Py())*(vTkU.Py()))/(vDilep.Pt());  // u1 = (pT . u)/|pT|
	tkU2 = ((vDilep.Px())*(vTkU.Py()) - (vDilep.Py())*(vTkU.Px()))/(vDilep.Pt());  // u2 = (pT x u)/|pT|
	
	TVector2 vMvaMet((info->mvaMET)*cos(info->mvaMETphi), (info->mvaMET)*sin(info->mvaMETphi));
	TVector2 vMvaU = -1.0*(vMvaMet+vZPt);
	mvaU1 = ((vDilep.Px())*(vMvaU.Px()) + (vDilep.Py())*(vMvaU.Py()))/(vDilep.Pt());  // u1 = (pT . u)/|pT|
	mvaU2 = ((vDilep.Px())*(vMvaU.Py()) - (vDilep.Py())*(vMvaU.Px()))/(vDilep.Pt());  // u2 = (pT x u)/|pT|
        
        TVector2 vPuppiMet((info->puppET)*cos(info->puppETphi), (info->puppET)*sin(info->puppETphi));
	TVector2 vPuppiU = -1.0*(vPuppiMet+vZPt);
	puppiU1 = ((vDilep.Px())*(vPuppiU.Px()) + (vDilep.Py())*(vPuppiU.Py()))/(vDilep.Pt());  // u1 = (pT . u)/|pT|
	puppiU2 = ((vDilep.Px())*(vPuppiU.Py()) - (vDilep.Py())*(vPuppiU.Px()))/(vDilep.Pt());  // u2 = (pT x u)/|pT|
	
        outTree->Fill();
	delete genV;
	genV=0, dilep=0, lep1=0, lep2=0, sta1=0, sta2=0;
      }
      delete infile;
      infile=0, eventTree=0;    
      
      cout << nsel  << " +/- " << sqrt(nselvar);
      if(!isData) cout << " per 1/fb";
      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 << "* 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;
  
  cout << endl;
  cout << "  <> Output saved in " << outputDir << "/" << endl;    
  cout << endl;  
      
  gBenchmark->Show("selectZmm"); 
}
void MakeZmumuGammaEventNtuples(const string inputfile,    // input file
		const string outputfile,   // output file
		const Bool_t  matchGen = kFALSE, // match to generator
		const string PUReweightFile = "",
		Int_t PDType = 0,
		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;


  double eventWeight = 1;
//53X MC
//   if (PDType == -1) eventWeight = 10000 * 1177.6*3 / 30391580.0; //mll50
//   if (PDType == -2) eventWeight = 10000 * 3969.61*3.0*0.0498327*1.45 / 1700850.0 ; //mll1050
//52X MC
  if (PDType == -1) eventWeight = 10000 * 1177.6*3 / 26821030.0; //mll50
  if (PDType == -2) eventWeight = 10000 * 3969.61*3.0*0.0498327*1.45 / 6046518.0 ; //mll1050

  //********************************************************
  // Pileup Reweighting
  //********************************************************
  TFile *fPUFile = 0;
  if (PUReweightFile != "") {
    fPUFile = TFile::Open(PUReweightFile.c_str());
  }
  TH1D *fhDPU = 0;
  if (fPUFile) fhDPU = (TH1D*)(fPUFile->Get("puWeights"));
  if(fhDPU) fhDPU->SetDirectory(0);
  if (fPUFile) delete fPUFile;


  //********************************************************
  // Good RunLumi Selection
  //********************************************************
  Bool_t applyGoodLumi = kTRUE;
  if (matchGen) applyGoodLumi = kFALSE;
  mithep::RunLumiRangeMap rlrm;
  rlrm.AddJSONFile("/afs/cern.ch/work/s/sixie/public/HZGamma/auxiliar/Cert_190456-196531_8TeV_29Jun2012ReReco_Collisions12_JSON.txt"); 
  rlrm.AddJSONFile("/afs/cern.ch/work/s/sixie/public/HZGamma/auxiliar/Cert_190782-190949_8TeV_29Jun2012ReReco-recover_Collisions12_JSON.txt");
  rlrm.AddJSONFile("/afs/cern.ch/work/s/sixie/public/HZGamma/auxiliar/Cert_Full2012_53X_JSON.txt");


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

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

  Double_t nEvents = 0;

  //*****************************************************************************************
  // Set up output ntuple
  //*****************************************************************************************
  TFile *outFile = new TFile(outputfile.c_str(),"RECREATE"); 

  citana::ZmumuGammaEventTree *zmumuGammaEventTree = new citana::ZmumuGammaEventTree;
  zmumuGammaEventTree->CreateTree();
  //   zeeEventTree->tree_->SetAutoFlush(0);


  //*****************************************************************************************
  // Read Input File
  //*****************************************************************************************
  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 *genparticleArr = new TClonesArray("higgsana::TGenParticle");
  TClonesArray *muonArr = new TClonesArray("higgsana::TMuon");
  TClonesArray *photonArr = new TClonesArray("higgsana::TPhoton");

  // 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("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron");
  eventTree->SetBranchAddress("Muon", &muonArr);         TBranch *muonBr = eventTree->GetBranch("Muon");
  eventTree->SetBranchAddress("Photon", &photonArr);     TBranch *photonBr = eventTree->GetBranch("Photon");
  eventTree->SetBranchAddress("PFCandidate", &pfcandidateArr);  TBranch *pfcandidateBr = eventTree->GetBranch("PFCandidate");
  cout << "NEvents = " << eventTree->GetEntries() << endl;

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


  // 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(applyGoodLumi && !rlrm.HasRunLumi(rl)) continue;  

    //***********************************************************
    // Definition of Pileup Energy density
    //***********************************************************
    Double_t rhoMuonIso = 0;
    Double_t rhoEleIso = 0;
    Double_t rhoPhoIso = 0;
    UInt_t MuonEAEra = 0;
    UInt_t EleEAEra = 0;
    UInt_t PhoEAEra = 0;

    if (DataEra == kDataEra_2011_MC) {
     
      if (!(isnan(info->RhoKt6PFJetsForIso25) || 
            isinf(info->RhoKt6PFJetsForIso25))) {
        rhoMuonIso = info->RhoKt6PFJetsForIso25;
        rhoEleIso = info->RhoKt6PFJetsForIso25;
        rhoPhoIso = info->RhoKt6PFJetsForIso25;
      }
      MuonEAEra = kDataEra_2011_Data;
      EleEAEra = kDataEra_2011_Data;
      PhoEAEra = kDataEra_2011_Data;
    } else if (DataEra == kDataEra_2012_MC) {

      if (!(isnan(info->RhoKt6PFJetsCentralNeutral) || 
            isinf(info->RhoKt6PFJetsCentralNeutral))) {
        rhoMuonIso = info->RhoKt6PFJetsCentralNeutral;
      }

      if (!(isnan(info->RhoKt6PFJets) || 
            isinf(info->RhoKt6PFJets))) {
        rhoEleIso = info->RhoKt6PFJets;
        rhoPhoIso = info->RhoKt6PFJets;
      }

      MuonEAEra = kDataEra_2012_Data;
      EleEAEra = kDataEra_2012_Data;
      PhoEAEra = kDataEra_2012_Data;
    }

    //***********************************************************
    // Pileup Weight
    //***********************************************************
    double npuWeight = 1;
    if (fhDPU) {
      double mynpu = TMath::Min((double)info->nPUEvents,34.999);
      Int_t npuxbin = fhDPU->GetXaxis()->FindBin(mynpu);
      npuWeight = fhDPU->GetBinContent(npuxbin);
    }


    // trigger requirement               
    Bool_t passTrigger = kFALSE;
    UInt_t triggerBits = 0;
    if(PDType == 0) {
      if ( (info->triggerBits & kHLT_DoubleMu7) == kHLT_DoubleMu7 ) {
	passTrigger = kTRUE;
      }
      if ( (info->triggerBits & kHLT_Mu13_Mu8) == kHLT_Mu13_Mu8 ) {
	passTrigger = kTRUE;
      }
      if ( (info->triggerBits & kHLT_Mu17_Mu8) == kHLT_Mu17_Mu8 ) {
	passTrigger = kTRUE;
      }
    } else if(PDType == 1) {

      //if it's from single ele PD, then remove overlap by vetoing double ele triggers
      if ((info->triggerBits & kHLT_DoubleMu7) == kHLT_DoubleMu7)  continue;
      if ((info->triggerBits & kHLT_Mu13_Mu8) == kHLT_Mu13_Mu8)  continue;
      if ((info->triggerBits & kHLT_Mu17_Mu8) == kHLT_Mu17_Mu8)  continue;

      if ( (info->triggerBits & kHLT_IsoMu24) == kHLT_IsoMu24 ) {
	passTrigger = kTRUE;
      }

    }

//     if( PDType != -1 && PDType != -2 &&  !passTrigger) continue;     
     
    // good vertex requirement
    if(!(info->hasGoodPV)) continue;

    if(matchGen) genparticleBr->GetEntry(ientry);
      

    electronArr->Clear();
    muonArr->Clear(); 
    photonArr->Clear(); 
    pfcandidateArr->Clear(); 
    electronBr->GetEntry(ientry);
    muonBr->GetEntry(ientry);
    photonBr->GetEntry(ientry);
    pfcandidateBr->GetEntry(ientry);

    //********************************************************
    //Loop over muons
    //********************************************************
//     Int_t Muon1Index = -1;
//     Int_t Muon2Index = -1;
//     Double_t Muon1Pt = -1;
//     Double_t Muon2Pt = -1;
//     Double_t Mass = 0;

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

      if(fabs(mu1->eta) > 2.4) continue;
      if (!PassMuonHZGammaID(mu1, (DataEra == kDataEra_2011_MC) )) continue;
      if (! (ComputeMuonPFIsoRings(mu1, pfcandidateArr, rhoMuonIso,MuonEAEra, kPFChargedIso, 0.0, 0.4) / mu1->pt < 0.2)) continue;

//       cout << "mu: " << mu1->pt << " " << mu1->eta << " " << mu1->phi << " : " << Bool_t((mu1->typeBits & kGlobal) == kGlobal) << " " << mu1->PassPFId << " " << mu1->muNchi2 << " " << mu1->nValidHits << " " << mu1->nMatch << " " << mu1->d0 << " " << mu1->dz << " " << mu1->nPixHits << " " << mu1->trkLayers << " " << PassMuonHZGammaID(mu1, (DataEra == kDataEra_2011_MC) )  << endl;

      //make four vector for muon1
      TLorentzVector vmu1;
      vmu1.SetPtEtaPhiM(mu1->pt, mu1->eta, mu1->phi, MUONMASS);

      for(Int_t j=i+1; j<muonArr->GetEntriesFast(); j++) {

	const higgsana::TMuon *mu2 = (higgsana::TMuon*)((*muonArr)[j]);

	if(fabs(mu2->eta) > 2.4) continue;
        if (!PassMuonHZGammaID(mu2, (DataEra == kDataEra_2011_MC) )) continue;
        if (! (ComputeMuonPFIsoRings(mu2, pfcandidateArr, rhoMuonIso,MuonEAEra, kPFChargedIso, 0.0, 0.4) / mu2->pt < 0.2)) continue;

	//charge requirement
	if(mu2->q == mu1->q) continue;

	//pt cuts
	if (!(mu1->pt > 10 || mu2->pt > 10)) continue;
	if (!(mu1->pt > 10 && mu2->pt > 10)) continue;


	TLorentzVector vmu2;
	vmu2.SetPtEtaPhiM(mu2->pt, mu2->eta, mu2->phi, MUONMASS);

 	TLorentzVector vdimuon = vmu1 + vmu2;

        for(Int_t p=0; p<photonArr->GetEntriesFast(); ++p) {
          
          const higgsana::TPhoton *pho = (higgsana::TPhoton*)((*photonArr)[p]);
          
//           cout << "Photon: " << pho->energyRegressionHgg2012/cosh(pho->eta) << " " << pho->eta << " " << pho->phi << " : " 
//                << PassPhotonHZGammaID(pho, (DataEra == kDataEra_2011_MC)) << endl;

          if (!(pho->energyRegressionHgg2012/cosh(pho->eta) > 10)) continue;
          if (!(fabs(pho->scEta) < 2.5)) continue;
          if ( fabs(pho->scEta) > 1.4442 && fabs(pho->scEta) < 1.566) continue;
          //noisy photon removal
          if (pho->scEta > -1.78 && pho->scEta < -1.75 && pho->scPhi > 1.36 && pho->scPhi < 1.39) continue;
          
          if (!PassPhotonHZGammaID(pho, (DataEra == kDataEra_2011_MC))) {
            continue;
          }
          
          //ignore this for now. no iso applied.
//           if (!PassPhotonHZGammaIso( pho, pfcandidateArr, rhoPhoIso,PhoEAEra)) {
//             continue;
//           }

          TLorentzVector vpho;
          //Use SC Energy
          //vpho.SetPtEtaPhiM(pho->et, pho->eta, pho->phi, 0);
          //Use regression energy
          vpho.SetPtEtaPhiM(pho->energyRegressionHgg2012/cosh(pho->eta) , pho->eta, pho->phi, 0);

         //******************************************************************
          //find matching gen leptons
          //******************************************************************
    
          const higgsana::TGenParticle *genMu1 = 0;
          const higgsana::TGenParticle *genMu2 = 0;
          const higgsana::TGenParticle *genPhoton = 0;
          for(Int_t k=0; k<genparticleArr->GetEntries(); k++) {
            const higgsana::TGenParticle *gen = (higgsana::TGenParticle*)((*genparticleArr)[k]);
            if (gen->status == 1 && (abs(gen->pdgid) == 13 ) ) {

              //find gen mu1
              if (higgsana::deltaR(gen->eta, gen->phi, mu1->eta, mu1->phi) < 0.1) {
                if (!genMu1 || higgsana::deltaR(gen->eta, gen->phi, mu1->eta, mu1->phi) < higgsana::deltaR(genMu1->eta, genMu1->phi, mu1->eta, mu1->phi)) {
                  genMu1 = gen;
                }
              }

              //find gen mu2
              if (higgsana::deltaR(gen->eta, gen->phi, mu2->eta, mu2->phi) < 0.1) {
                if (!genMu2 || higgsana::deltaR(gen->eta, gen->phi, mu2->eta, mu2->phi) < higgsana::deltaR(genMu2->eta, genMu2->phi, mu2->eta, mu2->phi)) {
                  genMu2 = gen;
                }
              }
            } //end if muon

            //find photon
            if (gen->status == 1 && (abs(gen->pdgid) == 22 ) ) {
              if (higgsana::deltaR(gen->eta, gen->phi, pho->eta, pho->phi) < 0.1) {
                if (!genPhoton || higgsana::deltaR(gen->eta, gen->phi, pho->eta, pho->phi) < higgsana::deltaR(genPhoton->eta, genPhoton->phi, pho->eta, pho->phi)) {
                  genPhoton = gen;
                }
              }
            }
          }

          //******************
          //Fill ZmumuGamma Event
          //******************
//           cout << "Trigger: " 
//                << Bool_t ( (info->triggerBits & kHLT_DoubleMu7) == kHLT_DoubleMu7 ) << " " 
//                << Bool_t( (info->triggerBits & kHLT_Mu13_Mu8) == kHLT_Mu13_Mu8 ) << " "
//                << Bool_t( (info->triggerBits & kHLT_Mu17_Mu8) == kHLT_Mu17_Mu8 ) << " "
//                << Bool_t( (info->triggerBits &  kHLT_Mu17_TkMu8) ==  kHLT_Mu17_TkMu8 ) << " "
//                << " : " << passTrigger
//                << endl;


          zmumuGammaEventTree->fWeight = npuWeight * eventWeight;
          zmumuGammaEventTree->fRunNumber = info->runNum;
          zmumuGammaEventTree->fLumiSectionNumber = info->lumiSec;
          zmumuGammaEventTree->fEventNumber = info->evtNum;
          zmumuGammaEventTree->fNPU = info->nPUEvents;
          zmumuGammaEventTree->fRho = rhoEleIso; 
          zmumuGammaEventTree->fNVertices = info->nPV0; 
          zmumuGammaEventTree->fMass = (vmu1+vmu2+vpho).M();
          zmumuGammaEventTree->fDileptonMass = (vmu1+vmu2).M();
          zmumuGammaEventTree->fPhotonPt = vpho.Pt(); 
          zmumuGammaEventTree->fPhotonEta = vpho.Eta(); 
          zmumuGammaEventTree->fPhotonPhi = vpho.Phi(); 
          zmumuGammaEventTree->fPhotonR9 = pho->R9; 
          zmumuGammaEventTree->fPhotonIsEB = (fabs(pho->scEta) < 1.566); 
          zmumuGammaEventTree->fPhotonHoE = pho->HoESingleTower; 
          zmumuGammaEventTree->fSCEt = pho->scEt; 
          zmumuGammaEventTree->fSCE = pho->scEt*cosh(pho->scEta); 
          zmumuGammaEventTree->fSCRawE = pho->scEt*cosh(pho->scEta);  
          zmumuGammaEventTree->fSCEta = pho->scEta; 
          zmumuGammaEventTree->fSCEtaWidth = 0; //for cluster correction calculations only
          zmumuGammaEventTree->fSCPhiWidth = 0; //for cluster correction calculations only
          zmumuGammaEventTree->fPhoToTrackDeltaR = 0; // do we need this? //old CiC selection ele veto
          zmumuGammaEventTree->fPhoPassElectronVeto = pho->passConversionSafeEleVeto; 
          zmumuGammaEventTree->fPhoHasMatchedConversion = 0;  //do we need this? no.
          zmumuGammaEventTree->fPhoHasPixelMatch = pho->hasPixelSeed; 
          zmumuGammaEventTree->fPhoSigmaIEtaIEta = pho->sigiEtaiEta; 
          zmumuGammaEventTree->fPhoTrackIso = pho->trkIso03Hollow; 
          zmumuGammaEventTree->fPhoEcalIso = pho->emIso03; 
          zmumuGammaEventTree->fPhoHcalIso = pho->hadIso03; 
          zmumuGammaEventTree->fPhoPdgId = 0;  //what's this used for? use deltaR circle. then use closest pt particle within circle. 0.1. mostly used to identify if it's a real photon or not.
          zmumuGammaEventTree->fPhoCrackCorr = 0; //part of cluster corrections.
          zmumuGammaEventTree->fMu1Pt = mu1->pt; 
          zmumuGammaEventTree->fMu1Eta = mu1->eta; 
          zmumuGammaEventTree->fMu1Phi = mu1->phi; 
          zmumuGammaEventTree->fMu1Charge = mu1->q; 
          zmumuGammaEventTree->fMu1TrackChi2 = 0; //do we need this? useful to see kinks in muons, but not needed for now
          zmumuGammaEventTree->fMu1TrackNormalizedChi2 = mu1->tkNchi2; 
          zmumuGammaEventTree->fMu1DeltaR = higgsana::deltaR(pho->eta, pho->phi, mu1->eta, mu1->phi); 
          zmumuGammaEventTree->fMu1CalEnergyEm = mu1->EmEnergy; //not used
          zmumuGammaEventTree->fMu1CalEnergyEmMax = 0; //what's this? not used
          zmumuGammaEventTree->fMu1CalEnergyEmHad = 0; //what's this? not used
          zmumuGammaEventTree->fMu2Pt = mu2->pt; 
          zmumuGammaEventTree->fMu2Eta= mu2->eta; 
          zmumuGammaEventTree->fMu2Phi = mu2->phi; 
          zmumuGammaEventTree->fMu2Charge = mu2->q; 
          zmumuGammaEventTree->fMu2TrackChi2 = 0;  //do we need this?
          zmumuGammaEventTree->fMu2TrackNormalizedChi2 = mu2->tkNchi2; 
          zmumuGammaEventTree->fMu2DeltaR = higgsana::deltaR(pho->eta, pho->phi, mu2->eta, mu2->phi);  
          zmumuGammaEventTree->fMu2CalEnergyEm = mu2->EmEnergy; //not used
          zmumuGammaEventTree->fMu2CalEnergyEmMax = 0; //what's this?
          zmumuGammaEventTree->fMu2CalEnergyEmHad = 0; //what's this?

          zmumuGammaEventTree->fMinDeltaEta = fmin( fabs(mu1->eta - pho->eta), fabs(mu2->eta - pho->eta) );
          zmumuGammaEventTree->fMinDeltaR = fmin(higgsana::deltaR(mu1->eta, mu1->phi, pho->eta, pho->phi),higgsana::deltaR(mu2->eta, mu2->phi, pho->eta, pho->phi));
          zmumuGammaEventTree->fMinDeltaPhi = fmin(higgsana::deltaPhi(mu1->phi, pho->phi),higgsana::deltaPhi(mu2->phi, pho->phi));
          zmumuGammaEventTree->fkRatio = 0; //what's that? photon energy calculated from on-shell z assumption to reconstructed photon energy
          zmumuGammaEventTree->fPreshowerE = 0; //also for cluster corrections

          if (genMu1) {
            zmumuGammaEventTree->fGenMu1Pt = genMu1->pt; 
            zmumuGammaEventTree->fGenMu1Eta = genMu1->eta; 
            zmumuGammaEventTree->fGenMu1Phi = genMu1->phi; 
          }
          if (genMu2) {
            zmumuGammaEventTree->fGenMu2Pt = genMu2->pt; 
            zmumuGammaEventTree->fGenMu2Eta = genMu2->eta; 
            zmumuGammaEventTree->fGenMu2Phi = genMu2->phi;
          }

          if (genPhoton) {
            zmumuGammaEventTree->fGenPhoE = genPhoton->pt * cosh(genPhoton->eta);  
            zmumuGammaEventTree->fGenPhoEt = genPhoton->pt; 
            zmumuGammaEventTree->fGenPhoEta = genPhoton->eta; 
            zmumuGammaEventTree->fGenPhoPhi = genPhoton->phi; 
            zmumuGammaEventTree->fGenPhoMotherPdgId = genPhoton->motherPdgID; 

            if (fabs(genPhoton->motherPdgID) == 13) {
              zmumuGammaEventTree->fIsFSR = kTRUE;
            } else {
              zmumuGammaEventTree->fIsFSR = kFALSE;
            }
            if ( (fabs(genPhoton->motherPdgID) >= 1 &&  fabs(genPhoton->motherPdgID) <= 6) ||  fabs(genPhoton->motherPdgID) == 21)  {
              zmumuGammaEventTree->fIsISR = kTRUE;
            } else {
              zmumuGammaEventTree->fIsISR = kFALSE;
            }
          }

          //Do we need these? Don't need them for now
          zmumuGammaEventTree->fPhoIEtaX = 0;       
          zmumuGammaEventTree->fPhoIPhiY = 0; 
          zmumuGammaEventTree->fMuNearIEtaX = 0; 
          zmumuGammaEventTree->fMuNearIPhiY = 0; 
          zmumuGammaEventTree->fMuNearIsEB = 0; 
          zmumuGammaEventTree->fMuNearIndex = 0; 

          zmumuGammaEventTree->tree_->Fill();
          if ((vmu1+vmu2).M() > 50 && (vmu1+vmu2+vpho).M() > 75 && (vmu1+vmu2+vpho).M() < 105 && (vmu1+vmu2).M()+(vmu1+vmu2+vpho).M() < 180) {
            nEvents++;
          }


        } //loop over photon

      } //loop over 2nd muon
    } //loop over first muon

  } //loop over events


    // Cleaning up the evaluators
  delete infile;
  infile=0, eventTree=0;    

  delete info;
  delete gen;
  delete muonArr;


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

  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << endl;
  cout << " Number of events selected: " << nEvents << endl;

  outFile->Write();
  outFile->Close();
  delete outFile;

  cout << endl;
  cout << "  <> Output saved in " << outputfile << endl;    
  cout << endl;  

}
示例#10
0
qint64 QUsbHid::bytesToWrite() const
{
    QReadLocker rl(bytesToWriteLock);
    return _bytesToWrite;
}
示例#11
0
void selectZee(const TString conf="zee.conf", // input file
               const TString outputDir=".",   // output directory
	       const Bool_t  doScaleCorr=0    // apply energy scale corrections?
) {
  gBenchmark->Start("selectZee");

  //--------------------------------------------------------------------------------------------------------------
  // 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.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  = 2;
  const Double_t escaleEta[]  = { 1.4442, 2.5   };
  const Double_t escaleCorr[] = { 0.992,  1.009 };

  const Int_t BOSON_ID  = 23;
  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_76X.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 
  //==============================================================================================================  

  enum { eEleEle2HLT=1, eEleEle1HLT1L1, eEleEle1HLT, eEleEleNoSel, eEleSC };  // event category enum
  
  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  matchGen;
  UInt_t  category;
  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;
  Float_t genVPt, genVPhi, genVy, genVMass;
  Float_t genWeight, PUWeight;
  Float_t scale1fb,scale1fbUp,scale1fbDown;
  Float_t met, metPhi, sumEt, u1, u2;
  Float_t tkMet, tkMetPhi, tkSumEt, tkU1, tkU2;
  Float_t mvaMet, mvaMetPhi, mvaSumEt, mvaU1, mvaU2;
  Float_t puppiMet, puppiMetPhi, puppiSumEt, puppiU1, puppiU2;
  Int_t   q1, q2;
  TLorentzVector *dilep=0, *lep1=0, *lep2=0;
  ///// electron specific /////
  Float_t trkIso1, emIso1, hadIso1, trkIso2, emIso2, hadIso2;
  Float_t pfChIso1, pfGamIso1, pfNeuIso1, pfCombIso1, pfChIso2, pfGamIso2, pfNeuIso2, pfCombIso2;
  Float_t sigieie1, hovere1, eoverp1, fbrem1, ecalE1, sigieie2, hovere2, eoverp2, fbrem2, ecalE2;
  Float_t dphi1, deta1, dphi2, deta2;
  Float_t d01, dz1, d02, dz2;
  UInt_t  isConv1, nexphits1, typeBits1, isConv2, nexphits2, typeBits2; 
  TLorentzVector *sc1=0, *sc2=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 "zee" - flag to store GEN Z kinematics
    Bool_t isSignal = (snamev[isam].CompareTo("zee",TString::kIgnoreCase)==0);  
    // flag to reject Z->ee 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.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("matchGen",   &matchGen,   "matchGen/i");    // event has both leptons matched to MC Z->ll
    outTree->Branch("category",   &category,   "category/i");    // dilepton category
    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("npv",        &npv,        "npv/i");         // number of primary vertices
    outTree->Branch("npu",        &npu,        "npu/i");         // number of in-time PU events (MC)
    outTree->Branch("genV",      "TLorentzVector",  &genV);      // GEN boson 4-vector
    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("genWeight",   &genWeight,  "genWeight/F");
    outTree->Branch("PUWeight",    &PUWeight,   "PUWeight/F");
    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("met",        &met,        "met/F");         // MET
    outTree->Branch("metPhi",     &metPhi,     "metPhi/F");      // phi(MET)
    outTree->Branch("sumEt",      &sumEt,      "sumEt/F");       // Sum ET
    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("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("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("q1",         &q1,         "q1/I");          // charge of tag lepton
    outTree->Branch("q2",         &q2,         "q2/I");          // charge of probe lepton
    outTree->Branch("dilep",      "TLorentzVector",  &dilep);    // di-lepton 4-vector
    outTree->Branch("lep1",       "TLorentzVector",  &lep1);     // tag lepton 4-vector
    outTree->Branch("lep2",       "TLorentzVector",  &lep2);     // probe lepton 4-vector
    ///// electron specific /////
    outTree->Branch("trkIso1",    &trkIso1,    "trkIso1/F");     // track isolation of tag lepton
    outTree->Branch("trkIso2",    &trkIso2,    "trkIso2/F");     // track isolation of probe lepton
    outTree->Branch("emIso1",     &emIso1,     "emIso1/F");      // ECAL isolation of tag lepton
    outTree->Branch("emIso2",     &emIso2,     "emIso2/F");      // ECAL isolation of probe lepton
    outTree->Branch("hadIso1",    &hadIso1,    "hadIso1/F");     // HCAL isolation of tag lepton
    outTree->Branch("hadIso2",    &hadIso2,    "hadIso2/F");     // HCAL isolation of probe lepton
    outTree->Branch("pfChIso1",   &pfChIso1,   "pfChIso1/F");    // PF charged hadron isolation of tag lepton
    outTree->Branch("pfChIso2",   &pfChIso2,   "pfChIso2/F");    // PF charged hadron isolation of probe lepton
    outTree->Branch("pfGamIso1",  &pfGamIso1,  "pfGamIso1/F");   // PF photon isolation of tag lepton
    outTree->Branch("pfGamIso2",  &pfGamIso2,  "pfGamIso2/F");   // PF photon isolation of probe lepton
    outTree->Branch("pfNeuIso1",  &pfNeuIso1,  "pfNeuIso1/F");   // PF neutral hadron isolation of tag lepton
    outTree->Branch("pfNeuIso2",  &pfNeuIso2,  "pfNeuIso2/F");   // PF neutral hadron isolation of probe lepton
    outTree->Branch("pfCombIso1", &pfCombIso1, "pfCombIso1/F");  // PF combine isolation of tag lepton
    outTree->Branch("pfCombIso2", &pfCombIso2, "pfCombIso2/F");  // PF combined isolation of probe lepton    
    outTree->Branch("sigieie1",   &sigieie1,   "sigieie1/F");    // sigma-ieta-ieta of tag
    outTree->Branch("sigieie2",   &sigieie2,   "sigieie2/F");    // sigma-ieta-ieta of probe
    outTree->Branch("hovere1",    &hovere1,    "hovere1/F");     // H/E of tag
    outTree->Branch("hovere2",    &hovere2,    "hovere2/F");     // H/E of probe
    outTree->Branch("eoverp1",    &eoverp1,    "eoverp1/F");     // E/p of tag
    outTree->Branch("eoverp2",    &eoverp2,    "eoverp2/F");     // E/p of probe	 
    outTree->Branch("fbrem1",     &fbrem1,     "fbrem1/F");      // brem fraction of tag
    outTree->Branch("fbrem2",     &fbrem2,     "fbrem2/F");      // brem fraction of probe
    outTree->Branch("dphi1",      &dphi1,      "dphi1/F");       // GSF track - ECAL dphi of tag
    outTree->Branch("dphi2",      &dphi2,      "dphi2/F");       // GSF track - ECAL dphi of probe 	
    outTree->Branch("deta1",      &deta1,      "deta1/F");       // GSF track - ECAL deta of tag
    outTree->Branch("deta2",      &deta2,      "deta2/F");       // GSF track - ECAL deta of probe
    outTree->Branch("ecalE1",     &ecalE1,     "ecalE1/F");      // ECAL energy of tag
    outTree->Branch("ecalE2",     &ecalE2,     "ecalE2/F");      // ECAL energy of probe
    outTree->Branch("d01",        &d01,        "d01/F");	 // transverse impact parameter of tag
    outTree->Branch("d02",        &d02,        "d02/F");	 // transverse impact parameter of probe	  
    outTree->Branch("dz1",        &dz1,        "dz1/F");	 // longitudinal impact parameter of tag
    outTree->Branch("dz2",        &dz2,        "dz2/F");	 // longitudinal impact parameter of probe
    outTree->Branch("isConv1",    &isConv1,    "isConv1/i");     // conversion filter flag of tag lepton
    outTree->Branch("isConv2",    &isConv2,    "isConv2/i");     // conversion filter flag of probe lepton
    outTree->Branch("nexphits1",  &nexphits1,  "nexphits1/i");   // number of missing expected inner hits of tag lepton
    outTree->Branch("nexphits2",  &nexphits2,  "nexphits2/i");   // number of missing expected inner hits of probe lepton
    outTree->Branch("typeBits1",  &typeBits1,  "typeBits1/i");   // electron type of tag lepton
    outTree->Branch("typeBits2",  &typeBits2,  "typeBits2/i");   // electron type of probe lepton
    outTree->Branch("sc1",       "TLorentzVector",  &sc1);       // tag supercluster 4-vector
    outTree->Branch("sc2",       "TLorentzVector",  &sc2);       // probe 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] ... " << endl; 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("Photon",   &scArr);       TBranch *scBr       = eventTree->GetBranch("Photon");
      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;
      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));
	  totalWeight+=gen->weight*puWeight;
	  totalWeightUp+=gen->weight*puWeightUp;
	  totalWeightDown+=gen->weight*puWeightDown;
	}
      }
      else if (not isData){
	for(UInt_t ientry=0; ientry<eventTree->GetEntries(); 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));
	  totalWeight+= 1.0*puWeight;
	  totalWeightUp+= 1.0*puWeightUp;
	  totalWeightDown+= 1.0*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 weight=1;
	Double_t weightUp=1;
	Double_t weightDown=1;
        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));
	  weight*=gen->weight*puWeight;
	  weightUp*=gen->weight*puWeightUp;
	  weightDown*=gen->weight*puWeightDown;
	}
	
	// veto z -> xx decays for signal and z -> ee 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;

        // 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;

	electronArr->Clear();
        electronBr->GetEntry(ientry);
	scArr->Clear();
	scBr->GetEntry(ientry);

	TLorentzVector vTag(0,0,0,0);
	TLorentzVector vTagSC(0,0,0,0);
	Double_t tagPt=0;
	Double_t Pt1=0;
	Double_t Pt2=0;
	Int_t itag=-1;
	Int_t tagscID=-1;
		
	for(Int_t i1=0; i1<electronArr->GetEntriesFast(); i1++) {
          const baconhep::TElectron *tag = (baconhep::TElectron*)((*electronArr)[i1]);
	  
	  // check ECAL gap
	  if(fabs(tag->scEta)>=ECAL_GAP_LOW && fabs(tag->scEta)<=ECAL_GAP_HIGH) continue;
	  
          // apply scale and resolution corrections to MC
          Double_t tagscEt_corr = tag->scEt;
          if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0)
            tagscEt_corr = gRandom->Gaus(tag->scEt*getEleScaleCorr(tag->scEta,0),getEleResCorr(tag->scEta,0));
	  
	  if(tagscEt_corr        < PT_CUT)     continue;  // lepton pT cut
	  if(fabs(tag->scEta)    > ETA_CUT)    continue;  // lepton |eta| cut
	  if(!passEleID(tag,info->rhoIso))     continue;  // lepton selection
	
	  double El_Pt=0;
	  if(doScaleCorr) {
	    El_Pt=gRandom->Gaus(tag->pt*getEleScaleCorr(tag->scEta,0),getEleResCorr(tag->scEta,0));
	  }
	  else
	    {
	      El_Pt=tag->pt;
	    }

	  if(El_Pt>Pt1)
	    {
	      Pt2=Pt1;
	      Pt1=El_Pt;
	    }
	  else if(El_Pt>Pt2&&El_Pt<Pt1)
	    {
	      Pt2=El_Pt;
	    }

	  if(!isEleTriggerObj(triggerMenu, tag->hltMatchBits, kFALSE, isData)) continue;
	  
	  if(El_Pt<tagPt) continue;
	  
	  tagPt=El_Pt;
	  itag=i1;
	  tagscID=tag->scID;

	  // apply scale and resolution corrections to MC
          if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0) {
            vTag.SetPtEtaPhiM(El_Pt, tag->eta, tag->phi, ELE_MASS);
            vTagSC.SetPtEtaPhiM(tagscEt_corr, tag->scEta, tag->scPhi, ELE_MASS);
          } else {
  	    vTag.SetPtEtaPhiM(tag->pt, tag->eta, tag->phi, ELE_MASS);
	    vTagSC.SetPtEtaPhiM(tag->scEt, tag->scEta, tag->scPhi, ELE_MASS);
          }

	  trkIso1    = tag->trkIso;
	  emIso1     = tag->ecalIso;
	  hadIso1    = tag->hcalIso;
	  pfChIso1   = tag->chHadIso;
	  pfGamIso1  = tag->gammaIso;	    
	  pfNeuIso1  = tag->neuHadIso;
	  pfCombIso1 = tag->chHadIso + TMath::Max(tag->neuHadIso + tag->gammaIso - (info->rhoIso)*getEffAreaEl(tag->scEta), 0.);
	  sigieie1   = tag->sieie;
	  hovere1    = tag->hovere;
	  eoverp1    = tag->eoverp;
	  fbrem1     = tag->fbrem;
	  dphi1      = tag->dPhiIn;
	  deta1      = tag->dEtaIn;
	  ecalE1     = tag->ecalEnergy;
	  d01        = tag->d0;
	  dz1        = tag->dz;
	  isConv1    = tag->isConv;
	  nexphits1  = tag->nMissingHits;
	  typeBits1  = tag->typeBits;
	  q1         = tag->q;

	}

	if(tagPt<Pt2) continue;

	TLorentzVector vProbe(0,0,0,0); TLorentzVector vProbeSC(0,0,0,0);
	Double_t probePt=0;
	Int_t iprobe=-1;
	Int_t passID=false;
	UInt_t icat=0;
	
	const baconhep::TElectron *eleProbe=0;

	for(Int_t j=0; j<scArr->GetEntriesFast(); j++) {
	  const baconhep::TPhoton *scProbe = (baconhep::TPhoton*)((*scArr)[j]);
	  
	  if(scProbe->scID == tagscID) continue;

	  // check ECAL gap
	  if(fabs(scProbe->eta)>=ECAL_GAP_LOW && fabs(scProbe->eta)<=ECAL_GAP_HIGH) continue;
	  
	  // apply scale and resolution corrections to MC
	  Double_t scProbept_corr = scProbe->pt;
	  if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0)
	    scProbept_corr = gRandom->Gaus(scProbe->pt*getEleScaleCorr(scProbe->eta,0),getEleResCorr(scProbe->eta,0));
	  
	  if(scProbept_corr        < PT_CUT)  continue;  // Supercluster ET cut ("pt" = corrected by PV position)
	  if(fabs(scProbe->eta)  > ETA_CUT) continue;  // Supercluster |eta| cuts

	  for(Int_t i2=0; i2<electronArr->GetEntriesFast(); i2++) {
	    if(itag==i2) continue;
	    const baconhep::TElectron *ele = (baconhep::TElectron*)((*electronArr)[i2]);
	    if(!(ele->typeBits & baconhep::EEleType::kEcalDriven)) continue;
	    if(scProbe->scID==ele->scID) { 
	      eleProbe = ele; 
	      iprobe   = i2;
	      break; 
	    }
	  }

	  double El_Pt=0;
	  if(doScaleCorr&&eleProbe) {
	    El_Pt=gRandom->Gaus(eleProbe->pt*getEleScaleCorr(scProbe->eta,0),getEleResCorr(scProbe->eta,0));
	  }
	  else if(!doScaleCorr&&eleProbe)
	    {
	      El_Pt=eleProbe->pt;
	    }
	  else
	    {
	      El_Pt=scProbept_corr;
	    }

	  if(passID&&eleProbe&&passEleID(eleProbe,info->rhoIso)&&El_Pt<probePt) continue;
	  if(passID&&eleProbe&&!passEleID(eleProbe,info->rhoIso)) continue;
	  if(passID&&!eleProbe) continue;
	  if(!passID&&eleProbe&&!passEleID(eleProbe,info->rhoIso)&&El_Pt<probePt) continue;
	  if(!passID&&!eleProbe&&El_Pt<probePt) continue;
	  if(!passID&&eleProbe&&passEleID(eleProbe,info->rhoIso)) passID=true;

	  probePt=El_Pt;

	  // apply scale and resolution corrections to MC
	  if(doScaleCorr && snamev[isam].CompareTo("data",TString::kIgnoreCase)!=0) {
	    vProbe.SetPtEtaPhiM((eleProbe) ? gRandom->Gaus(eleProbe->pt*getEleScaleCorr(scProbe->eta,0),getEleResCorr(scProbe->eta,0)) : scProbept_corr,
				(eleProbe) ? eleProbe->eta : scProbe->eta,
				(eleProbe) ? eleProbe->phi : scProbe->phi,
				ELE_MASS);
	    vProbeSC.SetPtEtaPhiM((eleProbe) ? gRandom->Gaus(eleProbe->scEt*getEleScaleCorr(scProbe->eta,0),getEleResCorr(scProbe->eta,0)) : gRandom->Gaus(scProbe->pt*getEleScaleCorr(scProbe->eta,0),getEleResCorr(scProbe->eta,0)),
				  scProbe->eta, scProbe->phi, ELE_MASS);
	  } else {
	    vProbe.SetPtEtaPhiM((eleProbe) ? eleProbe->pt : scProbe->pt,
				(eleProbe) ? eleProbe->eta : scProbe->eta,
				(eleProbe) ? eleProbe->phi : scProbe->phi,
				ELE_MASS);
	    vProbeSC.SetPtEtaPhiM((eleProbe) ? eleProbe->scEt : scProbe->pt,
				  scProbe->eta, scProbe->phi, ELE_MASS);
	  }

	  trkIso2    = (eleProbe) ? eleProbe->trkIso        : -1;
	  emIso2     = (eleProbe) ? eleProbe->ecalIso       : -1;
	  hadIso2    = (eleProbe) ? eleProbe->hcalIso       : -1;
	  pfChIso2   = (eleProbe) ? eleProbe->chHadIso      : -1;
	  pfGamIso2  = (eleProbe) ? eleProbe->gammaIso      : -1;
	  pfNeuIso2  = (eleProbe) ? eleProbe->neuHadIso     : -1;	    
	  pfCombIso2 = (eleProbe) ? 
	    eleProbe->chHadIso + TMath::Max(eleProbe->neuHadIso + eleProbe->gammaIso - 
					    (info->rhoIso)*getEffAreaEl(eleProbe->scEta), 0.) :  -1;
	  sigieie2   = (eleProbe) ? eleProbe->sieie         : scProbe->sieie;
	  hovere2    = (eleProbe) ? eleProbe->hovere        : scProbe->hovere;
	  eoverp2    = (eleProbe) ? eleProbe->eoverp        : -1;
	  fbrem2     = (eleProbe) ? eleProbe->fbrem         : -1;
	  dphi2      = (eleProbe) ? eleProbe->dPhiIn        : -999;
	  deta2      = (eleProbe) ? eleProbe->dEtaIn        : -999;
	  ecalE2     = (eleProbe) ? eleProbe->ecalEnergy    : -999;
	  d02        = (eleProbe) ? eleProbe->d0            : -999;
	  dz2        = (eleProbe) ? eleProbe->dz            : -999;
	  isConv2    = (eleProbe) ? eleProbe->isConv        : 0;
	  nexphits2  = (eleProbe) ? eleProbe->nMissingHits  : 0;
	  typeBits2  = (eleProbe) ? eleProbe->typeBits      : 0;
	  q2         = (eleProbe) ? eleProbe->q : -q1;

	  // determine event category
	  if(eleProbe) {
	    if(passEleID(eleProbe,info->rhoIso)) {
	      
	      if(isEleTriggerObj(triggerMenu, eleProbe->hltMatchBits, kFALSE, isData)) {
		icat=eEleEle2HLT;  
	      } 
	      else if(isEleTriggerObj(triggerMenu, eleProbe->hltMatchBits, kTRUE, isData)) {
		icat=eEleEle1HLT1L1; 
	      }
	      else { icat=eEleEle1HLT; }
	    }
	    else { icat=eEleEleNoSel; } 
	  } 
	  else { icat=eEleSC; }
	  
	}

	if(q1 == q2)         continue;  // opposite charge requirement

	// mass window
	TLorentzVector vDilep = vTag + vProbe;
	if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue;

	if(icat==0) continue;

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

	// Perform matching of dileptons to GEN leptons from Z decay

	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(vTag.Eta(), vTag.Phi(), glep1->Eta(), glep1->Phi())<0.3) || 
			    ((glep2) && toolbox::deltaR(vTag.Eta(), vTag.Phi(), glep2->Eta(), glep2->Phi())<0.3) );
	  
	  Bool_t match2 = ( ((glep1) && toolbox::deltaR(vProbe.Eta(), vProbe.Phi(), glep1->Eta(), glep1->Phi())<0.3) || 
			    ((glep2) && toolbox::deltaR(vProbe.Eta(), vProbe.Phi(), glep2->Eta(), glep2->Phi())<0.3) );
	  
	  if(match1 && match2) {
	    hasGenMatch = kTRUE;
	    if (gvec!=0) {
	      genV=new TLorentzVector(0,0,0,0);
	      genV->SetPtEtaPhiM(gvec->Pt(), gvec->Eta(), gvec->Phi(), gvec->M());
	      genVPt   = gvec->Pt();
	      genVPhi  = gvec->Phi();
	      genVy    = gvec->Rapidity();
	      genVMass = gvec->M();
	    }
	    else {
	      TLorentzVector tvec=*glep1+*glep2;
	      genV=new TLorentzVector(0,0,0,0);
	      genV->SetPtEtaPhiM(tvec.Pt(), tvec.Eta(), tvec.Phi(), tvec.M());
	      genVPt   = tvec.Pt();
	      genVPhi  = tvec.Phi();
	      genVy    = tvec.Rapidity();
	      genVMass = tvec.M();
	    }
	    delete gvec;
	    delete glep1;
	    delete glep2;
	    glep1=0; glep2=0; gvec=0;
	  }
	  else {
	    genV     = new TLorentzVector(0,0,0,0);
	    genVPt   = -999;
	    genVPhi  = -999;
	    genVy    = -999;
	    genVMass = -999;
	  }
	}
	
	if (hasGen) {
	  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;
	}
	else {
	  id_1      = -999;
	  id_2      = -999;
	  x_1       = -999;
	  x_2       = -999;
	  xPDF_1    = -999;
	  xPDF_2    = -999;
	  scalePDF  = -999;
	  weightPDF = -999;
	  }

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

	if (hasGenMatch) matchGen=1;
	else matchGen=0;

	category = icat;

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

	npv      = vertexArr->GetEntries();
	npu      = info->nPUmean;
        genWeight= hasGen ? gen->weight: 1.;
        PUWeight = puWeight;
	scale1fb = weight;
	scale1fbUp = weightUp;
	scale1fbDown = weightDown;
	met      = info->pfMETC;
	metPhi   = info->pfMETCphi;
	sumEt    = 0;
	tkMet    = info->trkMET;
	tkMetPhi = info->trkMETphi;
	tkSumEt  = 0;
	mvaMet   = info->mvaMET;
	mvaMetPhi = info->mvaMETphi; 
	mvaSumEt = 0;
	TVector2 vZPt((vDilep.Pt())*cos(vDilep.Phi()),(vDilep.Pt())*sin(vDilep.Phi()));

	puppiMet = info->puppET;
        puppiMetPhi = info->puppETphi;
	puppiSumEt = 0;
	lep1     = &vTag;
	lep2     = &vProbe;
	dilep    = &vDilep;
	sc1        = &vTagSC;
	sc2        = &vProbeSC;

	TVector2 vMet((info->pfMETC)*cos(info->pfMETCphi), (info->pfMETC)*sin(info->pfMETCphi));
	TVector2 vU = -1.0*(vMet+vZPt);
	u1 = ((vDilep.Px())*(vU.Px()) + (vDilep.Py())*(vU.Py()))/(vDilep.Pt());  // u1 = (pT . u)/|pT|
	u2 = ((vDilep.Px())*(vU.Py()) - (vDilep.Py())*(vU.Px()))/(vDilep.Pt());  // u2 = (pT x u)/|pT|
	
	TVector2 vTkMet((info->trkMET)*cos(info->trkMETphi), (info->trkMET)*sin(info->trkMETphi));        
	TVector2 vTkU = -1.0*(vTkMet+vZPt);
	tkU1 = ((vDilep.Px())*(vTkU.Px()) + (vDilep.Py())*(vTkU.Py()))/(vDilep.Pt());  // u1 = (pT . u)/|pT|
	tkU2 = ((vDilep.Px())*(vTkU.Py()) - (vDilep.Py())*(vTkU.Px()))/(vDilep.Pt());  // u2 = (pT x u)/|pT|
	
	TVector2 vMvaMet((info->mvaMET)*cos(info->mvaMETphi), (info->mvaMET)*sin(info->mvaMETphi));
	TVector2 vMvaU = -1.0*(vMvaMet+vZPt);
	mvaU1 = ((vDilep.Px())*(vMvaU.Px()) + (vDilep.Py())*(vMvaU.Py()))/(vDilep.Pt());  // u1 = (pT . u)/|pT|
	mvaU2 = ((vDilep.Px())*(vMvaU.Py()) - (vDilep.Py())*(vMvaU.Px()))/(vDilep.Pt());  // u2 = (pT x u)/|pT|
        
	TVector2 vPuppiMet((info->puppET)*cos(info->puppETphi), (info->puppET)*sin(info->puppETphi));
	TVector2 vPuppiU = -1.0*(vPuppiMet+vZPt);
	puppiU1 = ((vDilep.Px())*(vPuppiU.Px()) + (vDilep.Py())*(vPuppiU.Py()))/(vDilep.Pt());  // u1 = (pT . u)/|pT|
	puppiU2 = ((vDilep.Px())*(vPuppiU.Py()) - (vDilep.Py())*(vPuppiU.Px()))/(vDilep.Pt());  // u2 = (pT x u)/|pT|

	outTree->Fill();
	delete genV;
	genV=0, dilep=0, lep1=0, lep2=0, sc1=0, sc2=0;
      }
      delete infile;
      infile=0, eventTree=0;    
      
      cout << nsel  << " +/- " << sqrt(nselvar);
      if(!isData) cout << " per 1/fb";
      cout << endl;
    }
    outFile->Write();
    outFile->Close(); 
  }
  delete h_rw;
  delete f_rw;
  delete info;
  delete gen;
  delete genPartArr;
  delete electronArr;
  delete scArr;
  delete vertexArr;
    
  //--------------------------------------------------------------------------------------------------------------
  // 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;
  
  cout << endl;
  cout << "  <> Output saved in " << outputDir << "/" << endl;    
  cout << endl;  
      
  gBenchmark->Show("selectZee"); 
}
示例#12
0
qint64 QUsbHid::bytesAvailable() const
{
    QReadLocker rl(readBufferLock);
    return readBuffer.length();
}
示例#13
0
const QString& KstIfaceImpl::generateScalar(const QString& name, double value) {
  KstScalarPtr s = new KstScalar(name, value);
  KstReadLocker rl(s);
  s->setOrphan(true);
  return s->tagName();
}
示例#14
0
void WalletGroup::reset()
{
   ReadWriteLock::ReadLock rl(lock_);
   for (const auto& wlt : values(wallets_))
      wlt->reset();
}
示例#15
0
文件: mpt.c 项目: ryanSie/Advantech
int
mpt_directdownload(mpt_adap_t *adap)
{
	U16						 deviceId = adap->device_id;
	U32						 mask = adap->diagmem_size - 1;
	MpiFwHeader_t			*fwHeader;
	U32						*image;
	U32						 addr;
	U32						 size;
	U32						 data;
	int						 t;

	wl(WRITE_SEQUENCE, MPI_WRSEQ_KEY_VALUE_MASK);
	wl(WRITE_SEQUENCE, MPI_WRSEQ_1ST_KEY_VALUE);
	wl(WRITE_SEQUENCE, MPI_WRSEQ_2ND_KEY_VALUE);
	wl(WRITE_SEQUENCE, MPI_WRSEQ_3RD_KEY_VALUE);
	wl(WRITE_SEQUENCE, MPI_WRSEQ_4TH_KEY_VALUE);
	wl(WRITE_SEQUENCE, MPI_WRSEQ_5TH_KEY_VALUE);

	wl(DIAGNOSTIC, MPI_DIAG_DISABLE_ARM);
	DELAY(100);

	/*  If FlashBadSig is set, the download doesn't seem to work if we reset
	 *  the chip here.
	 *
	 *  If FlashBadSig isn't set, the download doesn't seem to work if we
	 *  don't reset the chip here.
	 */
	data = rl(DIAGNOSTIC);
	if (!(data & MPI_DIAG_FLASH_BAD_SIG))
	{
		wl(DIAGNOSTIC, MPI_DIAG_DISABLE_ARM | MPI_DIAG_RESET_ADAPTER);
		DELAY(100);

		wl(WRITE_SEQUENCE, MPI_WRSEQ_KEY_VALUE_MASK);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_1ST_KEY_VALUE);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_2ND_KEY_VALUE);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_3RD_KEY_VALUE);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_4TH_KEY_VALUE);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_5TH_KEY_VALUE);
	}

	wl(DIAGNOSTIC, MPI_DIAG_DISABLE_ARM | MPI_DIAG_MEM_ENABLE);

	addr = 0x50004;
	rldiag(addr, data);
	data &= ~0x80000000;
	wldiag(addr, data);

	if (deviceId == MPI_MANUFACTPAGE_DEVICEID_FC929)
	{
		addr = 0x51004;
		rldiag(addr, data);
		data &= ~0x80000000;
		wldiag(addr, data);
	}

	if (rl(DIAGNOSTIC) & MPI_DIAG_FLASH_BAD_SIG)
	{
		addr = 0x40000;
		rldiag(addr, data);
		data |= 0x40000000;
		wldiag(addr, data);
	}

	fwHeader = (MpiFwHeader_t *)adap->fw_image;

	image = (U32 *)fwHeader;

	addr = fwHeader->LoadStartAddress;
	size = fwHeader->ImageSize;

	while (size)
	{
		data = *image++;

		wldiag(addr, data);

		addr += 4;
		size -= 4;
	}

	addr = fwHeader->IopResetRegAddr;
	data = fwHeader->IopResetVectorValue;

	wldiag(addr, data);

	addr = 0x40000;
	rldiag(addr, data);
	data |= 0x40000000;
	wldiag(addr, data);

	wl(DIAGNOSTIC, 0);
	DELAY(100);

	t = mpt_wait_for_ready(adap);

	if (wFlag)
		fprintf(logFile, "%s:  Firmware Direct Download:  %s\n",
				adap->name, t ? "PASS" : "FAIL");

	if (t)
		return 1;

	printf("\n%s: DirectDownload failed!\n", adap->name);
	return 0;
}
示例#16
0
const QString& KstIfaceImpl::generateVector(const QString& name, double from, double to, int points) {
  KstVectorPtr v = new KstSVector(from, to, points, name);
  KST::addVectorToList(v);
  KstReadLocker rl(v);
  return v->tagName();
}
示例#17
0
文件: mpt.c 项目: ryanSie/Advantech
int
mpt_get_doorbell(mpt_adap_t *adap)
{
	return rl(DOORBELL);
}
示例#18
0
QString AMSettings::publicDataFolder() const
{
	QReadLocker rl(&mutex_);
	return publicDataFolder_;
}
示例#19
0
文件: mpt.c 项目: ryanSie/Advantech
/*
 * mpt_stop - stop the IOC (reset it).
 */
int
mpt_stop(mpt_adap_t *adap, int wait)
{
	time_t	 limit = time(NULL) + 10;

//	printf("mpt_stop called\n");

#if EFI
	if (adap->disconnected == FALSE && wait == TRUE)
	{
		EFI_PCI_IO_PROTOCOL		*pci_io;

		if (adap->loaddevice == TRUE)
		{
			printf("This chip controls the device that this utility was loaded from.\n");
			printf("After this command, the load device cannot be accessed again\n");
			printf("to open files, until this utility has been exited and restarted.\n\n");
		}

		if (!EFI_ERROR(BS->DisconnectController(adap->handle, NULL, NULL)))
		{
			adap->disconnected = TRUE;
			pci_io = adap->pci_io;
			pci_io->Attributes(pci_io, EfiPciIoAttributeOperationEnable,
							   EFI_PCI_IO_ATTRIBUTE_IO |
							   EFI_PCI_IO_ATTRIBUTE_MEMORY |
							   EFI_PCI_IO_ATTRIBUTE_BUS_MASTER |
							   EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE, NULL);
		}

		if (adap->partner_adap)
		{
			if (!EFI_ERROR(BS->DisconnectController(adap->partner_adap->handle, NULL, NULL)))
			{
				adap->partner_adap->disconnected = TRUE;
				pci_io = adap->partner_adap->pci_io;
				pci_io->Attributes(pci_io, EfiPciIoAttributeOperationEnable,
								   EFI_PCI_IO_ATTRIBUTE_IO |
								   EFI_PCI_IO_ATTRIBUTE_MEMORY |
								   EFI_PCI_IO_ATTRIBUTE_BUS_MASTER |
								   EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE, NULL);
			}
		}
	}
#endif

	adap->interrupt_mask = MPI_HIM_RIM | MPI_HIM_DIM;
	wl(HOST_INTERRUPT_MASK, adap->interrupt_mask);

	/*
	 * Reset the chip.
	 */
	if (adap->device_id == MPI_MANUFACTPAGE_DEVICEID_FC909)
	{
		rl(FC909_BUG);    /* work around FC909 bug */
	}

	if (!(rl(DIAGNOSTIC) & MPI_DIAG_DRWE))
	{
		wl(WRITE_SEQUENCE, MPI_WRSEQ_KEY_VALUE_MASK);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_1ST_KEY_VALUE);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_2ND_KEY_VALUE);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_3RD_KEY_VALUE);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_4TH_KEY_VALUE);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_5TH_KEY_VALUE);
	}

	if (!(rl(DIAGNOSTIC) & MPI_DIAG_RESET_HISTORY) ||
		((rl(DOORBELL) & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_RESET &&
		 (rl(DOORBELL) & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_READY))
	{
		if (adap->device_id == MPI_MANUFACTPAGE_DEVID_SAS1078)
		{
			wl(SAS1078_RESET, 0x7);
		}
		else
		{
			wl(DIAGNOSTIC, MPI_DIAG_RESET_ADAPTER);
		}
		DELAY(1000);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_KEY_VALUE_MASK);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_1ST_KEY_VALUE);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_2ND_KEY_VALUE);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_3RD_KEY_VALUE);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_4TH_KEY_VALUE);
		wl(WRITE_SEQUENCE, MPI_WRSEQ_5TH_KEY_VALUE);
	}

	wl(DIAGNOSTIC, 0);

	if (wait == FALSE)
	{
		while (time(NULL) < limit)
		{
			if (rl(DOORBELL) & MPI_IOC_STATE_MASK)
				break;
			if (rl(DIAGNOSTIC) & MPI_DIAG_DISABLE_ARM)
				break;
			DELAY(100);
		}

		return 1;
	}

	if (rl(DIAGNOSTIC) & MPI_DIAG_RESET_ADAPTER)
	{
		printf("\n%s: Failed to clear RESET ADAPTER\n", adap->name);
		if (wFlag)
			fprintf(logFile, "%s:  Failed to clear RESET ADAPTER\n",
					adap->name);
		adap->restart_needed = TRUE;
		return 0;
	}

	adap->bootloader = FALSE;

	if (mpt_wait_for_ready(adap))
		return 1;

	if (mpt_fwdownloadboot(adap))
		return 1;

	if ((rl(DOORBELL) & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_RESET)
	{
		adap->restart_needed = FALSE;

		printf("\n%s: Failed to leave the RESET state\n", adap->name);
		if (wFlag)
			fprintf(logFile, "%s:  Failed to leave the RESET state\n",
					adap->name);
	}
	else
	{
		adap->restart_needed = TRUE;

		printf("\n%s: Failed to reset properly\n", adap->name);
		if (wFlag)
			fprintf(logFile, "%s:  Failed to reset properly\n",
					adap->name);
	}

	return 0;
}
示例#20
0
QString AMSettings::publicDatabaseFilename() const
{
	QReadLocker rl(&mutex_);
	return publicDatabaseFilename_;
}
示例#21
0
文件: mr.cpp 项目: jayridge/mongo
            bool run(const char *dbname, BSONObj& cmd, string& errmsg, BSONObjBuilder& result, bool fromRepl ){
                Timer t;
                Client::GodScope cg;
                Client& client = cc();
                CurOp * op = client.curop();

                MRSetup mr( nsToDatabase( dbname ) , cmd );

                log(1) << "mr ns: " << mr.ns << endl;
                
                if ( ! db.exists( mr.ns ) ){
                    errmsg = "ns doesn't exist";
                    return false;
                }
                
                bool shouldHaveData = false;
                
                long long num = 0;
                long long inReduce = 0;
                
                BSONObjBuilder countsBuilder;
                BSONObjBuilder timingBuilder;
                try {
                    
                    MRState state( mr );
                    state.scope->injectNative( "emit" , fast_emit );
                    
                    MRTL * mrtl = new MRTL( state );
                    _tlmr.reset( mrtl );

                    ProgressMeter & pm = op->setMessage( "m/r: (1/3) emit phase" , db.count( mr.ns , mr.filter ) );
                    long long mapTime = 0;
                    {
                        readlock lock( mr.ns );
                        Client::Context ctx( mr.ns );
                        
                        auto_ptr<Cursor> temp = QueryPlanSet(mr.ns.c_str() , mr.filter , BSONObj() ).getBestGuess()->newCursor();
                        auto_ptr<ClientCursor> cursor( new ClientCursor( QueryOption_NoCursorTimeout , temp , mr.ns.c_str() ) );

                        if ( ! mr.filter.isEmpty() )
                            cursor->matcher.reset( new CoveredIndexMatcher( mr.filter , cursor->indexKeyPattern() ) );
                        
                        Timer mt;
                        while ( cursor->ok() ){
                            
                            if ( ! cursor->currentMatches() ){
                                cursor->advance();
                                continue;
                            }
                            
                            BSONObj o = cursor->current(); 
                            cursor->advance();
                            
                            if ( mr.verbose ) mt.reset();
                            
                            state.scope->setThis( &o );
                            if ( state.scope->invoke( state.map , state.setup.mapparams , 0 , true ) )
                                throw UserException( 9014, (string)"map invoke failed: " + state.scope->getError() );
                            
                            if ( mr.verbose ) mapTime += mt.micros();
                            
                            num++;
                            if ( num % 100 == 0 ){
                                ClientCursor::YieldLock yield = cursor->yieldHold();
                                Timer t;
                                mrtl->checkSize();
                                inReduce += t.micros();
                                
                                if ( ! yield.stillOk() ){
                                    cursor.release();
                                    break;
                                }

                                killCurrentOp.checkForInterrupt();
                            }
                            pm.hit();
                            
                            if ( mr.limit && num >= mr.limit )
                                break;
                        }
                    }
                    pm.finished();
                    
                    killCurrentOp.checkForInterrupt();

                    countsBuilder.appendNumber( "input" , num );
                    countsBuilder.appendNumber( "emit" , mrtl->numEmits );
                    if ( mrtl->numEmits )
                        shouldHaveData = true;
                    
                    timingBuilder.append( "mapTime" , mapTime / 1000 );
                    timingBuilder.append( "emitLoop" , t.millis() );
                    
                    // final reduce
                    op->setMessage( "m/r: (2/3) final reduce in memory" );
                    mrtl->reduceInMemory();
                    mrtl->dump();
                    
                    BSONObj sortKey = BSON( "0" << 1 );
                    db.ensureIndex( mr.incLong , sortKey );
                    
                    {
                        writelock lock( mr.tempLong.c_str() );
                        Client::Context ctx( mr.tempLong.c_str() );
                        assert( userCreateNS( mr.tempLong.c_str() , BSONObj() , errmsg , mr.replicate ) );
                    }


                    {
                        readlock rl(mr.incLong.c_str());
                        Client::Context ctx( mr.incLong );
                        
                        BSONObj prev;
                        BSONList all;
                        
                        pm = op->setMessage( "m/r: (3/3) final reduce to collection" , db.count( mr.incLong ) );

                        auto_ptr<Cursor> temp = QueryPlanSet(mr.incLong.c_str() , BSONObj() , sortKey ).getBestGuess()->newCursor();
                        auto_ptr<ClientCursor> cursor( new ClientCursor( QueryOption_NoCursorTimeout , temp , mr.incLong.c_str() ) );
                        
                        while ( cursor->ok() ){
                            BSONObj o = cursor->current().getOwned();
                            cursor->advance();
                            
                            pm.hit();
                            
                            if ( o.woSortOrder( prev , sortKey ) == 0 ){
                                all.push_back( o );
                                if ( pm.hits() % 1000 == 0 ){
                                    if ( ! cursor->yield() ){
                                        cursor.release();
                                        break;
                                    } 
                                    killCurrentOp.checkForInterrupt();
                                }
                                continue;
                            }
                        
                            ClientCursor::YieldLock yield = cursor->yieldHold();
                                
                            state.finalReduce( all );
                            
                            all.clear();
                            prev = o;
                            all.push_back( o );

                            if ( ! yield.stillOk() ){
                                cursor.release();
                                break;
                            }
                            
                            killCurrentOp.checkForInterrupt();
                        }

                        {
                            dbtemprelease tl;
                            state.finalReduce( all );
                        }

                        pm.finished();
                    }

                    _tlmr.reset( 0 );
                }
                catch ( ... ){
                    log() << "mr failed, removing collection" << endl;
                    db.dropCollection( mr.tempLong );
                    db.dropCollection( mr.incLong );
                    throw;
                }
                
                long long finalCount = 0;
                {
                    dblock lock;
                    db.dropCollection( mr.incLong );
                
                    finalCount = mr.renameIfNeeded( db );
                }

                timingBuilder.append( "total" , t.millis() );
                
                result.append( "result" , mr.finalShort );
                result.append( "timeMillis" , t.millis() );
                countsBuilder.appendNumber( "output" , finalCount );
                if ( mr.verbose ) result.append( "timing" , timingBuilder.obj() );
                result.append( "counts" , countsBuilder.obj() );

                if ( finalCount == 0 && shouldHaveData ){
                    result.append( "cmd" , cmd );
                    errmsg = "there were emits but no data!";
                    return false;
                }

                return true;
            }
示例#22
0
QString AMSettings::fileLoaderPluginsFolder() const
{
	QReadLocker rl(&mutex_);
	return fileLoaderPluginsFolder_;
}
void selectEleHZZHCP2012IsoGivenIDWithTightTagPerFile(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 (!passID) 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;
        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"); 
}
示例#24
0
QString AMSettings::analysisBlockPluginsFolder() const
{
	QReadLocker rl(&mutex_);
	return analysisBlockPluginsFolder_;
}
示例#25
0
QString SGMSettings::SGMDataFolder() const{
	QReadLocker rl(&mutex_);
	return SGMDataFolder_;
}
示例#26
0
double
safe_svm_evaluator(GRNModel& m, GRNModel& nm, const std::list<std::string>& testingSet,
                   uint32_t numGenes, uint32_t numArrays)
{
  int pipes[2];
  pid_t pid;

  pipe(pipes);
  if ((pid = fork()) == 0)
  {
    close(pipes[0]);

    ResultListener rl(numGenes, numArrays);

    m.trainSVMs();

    m.testSVMs(testingSet, rl);
    printf("Model training done.\n");
    double x = 0.0;
    write(pipes[1], &x, sizeof(double));

    nm.trainSVMs();

    nm.testSVMs(testingSet, rl);
    
    double result = rl.log2pval();
    printf("Null model training done; log_2 p %g\n", result);
    write(pipes[1], &result, sizeof(double));

    exit(0);
  }
  else
  {
    close(pipes[1]);

    struct timeval tv;
    // Give it 120 seconds (for each result, 4 min total)...
    tv.tv_sec = 500;
    tv.tv_usec = 0;
    fd_set s;
    FD_ZERO(&s);
    FD_SET(pipes[0], &s);
    double result;
    if (select(pipes[0] + 1, &s, NULL, &s, &tv) <= 0)
    {
      printf("Timeout on model; killing process.\n");
      kill(pid, SIGKILL);
      result = 0;
    }
    else
    {
      if (read(pipes[0], &result, sizeof(double) + 1) != sizeof(double))
      {
        printf("Read error on model.\n");
        result = 0;
      }
      else
      {
        tv.tv_sec = 500;
        tv.tv_usec = 0;
        FD_SET(pipes[0], &s);
        if (select(pipes[0] + 1, &s, NULL, &s, &tv) <= 0)
        {
          printf("Timeout on null model.\n");
          kill(pid, SIGKILL);
          result = 0;
        }
        else if (read(pipes[0], &result, sizeof(double) + 1) != sizeof(double))
        {
          printf("Read error on null model.\n");
          result = 0;
        }
      }
    }
    close(pipes[0]);
    int status;
    wait(&status);

    printf("Returning result: %g\n", result);

    return result;
  }
  return 0;
}
示例#27
0
void WalletGroup::merge()
{
   ReadWriteLock::ReadLock rl(lock_);
   for (auto& wlt : values(wallets_))
      wlt->merge();
}
示例#28
0
文件: mpt.c 项目: ryanSie/Advantech
void
mpt_interrupt(mpt_adap_t *adap)
{
	U32					 context;
	U32					 reply_ba;
	MPIDefaultReply_t	*reply;
	U32					 doorbell;
	int					 state;

//	printf("mpt_interrupt called\n");

	if (adap->hrsm_capable)
	{
		if (adap->hrsm_value == adap->shared->hrsm_value)
			return;
		adap->hrsm_value = adap->shared->hrsm_value;
	}

	doorbell = rl(DOORBELL);
	state = doorbell & MPI_IOC_STATE_MASK;
	if (state != MPI_IOC_STATE_OPERATIONAL)
	{
		if (state == MPI_IOC_STATE_FAULT)
		{
			printf("%s: MPT Firmware Fault, code %04x\n",
				   adap->name, doorbell & MPI_DOORBELL_DATA_MASK);
			if (wFlag)
				fprintf(logFile, "%s:  MPT Firmware Fault, code %04x\n",
						adap->name, doorbell & MPI_DOORBELL_DATA_MASK);
		}
		adap->restart_needed = TRUE;
	}

	while ((context = rl(REPLY_QUEUE)) != 0xffffffff)
	{
		if (context & MPI_CONTEXT_REPLY_A_BIT)
		{
			reply_ba = context << 1;
			reply = (MPIDefaultReply_t *)((U8 *)adap->shared + reply_ba - (U32)adap->shared_ba);
			if (mpt_handle_reply(adap, reply, reply_ba))
				wl(REPLY_QUEUE, reply_ba);
			continue;
		}
		if (context == PASS_THRU_CONTEXT)
		{
			if (adap->command_active == TRUE)
			{
				SCSIIORequest_t		*scsiReq = (SCSIIORequest_t *)adap->shared->message;
				SCSIIOReply_t		*scsiRep = (SCSIIOReply_t *)adap->shared->data;

				adap->command_active = FALSE;
				bzero(scsiRep, sizeof(*scsiRep));

				scsiRep->Function		= scsiReq->Function;
				scsiRep->MsgLength		= sizeof *scsiRep / 4;
				scsiRep->Bus			= scsiReq->Bus;
				scsiRep->TargetID		= scsiReq->TargetID;
				scsiRep->CDBLength		= scsiReq->CDBLength;
				scsiRep->IOCStatus		= MPI_IOCSTATUS_SUCCESS;
				scsiRep->SCSIStatus		= MPI_SCSI_STATUS_SUCCESS;
				scsiRep->TransferCount	= scsiReq->DataLength;
			}
			continue;
		}
		printf("%s: Invalid reply, Context = %08x\n", adap->name, reply);
	}
}
示例#29
0
bool WalletGroup::hasID(const BinaryData& ID) const
{
   ReadWriteLock::ReadLock rl(lock_);
   return wallets_.find(ID) != wallets_.end();
}
示例#30
0
        bool run(const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
            
            _runCalled = true;

            long long start = Listener::getElapsedTimeMillis();
            BSONObjBuilder timeBuilder(256);

            const ClientBasic* myClientBasic = ClientBasic::getCurrent();
            AuthorizationSession* authSession = myClientBasic->getAuthorizationSession();
            
            // --- basic fields that are global

            result.append("host", prettyHostName() );
            result.append("version", versionString);
            result.append("process",cmdLine.binaryName);
            result.append("pid", ProcessId::getCurrent().asLongLong());
            result.append("uptime",(double) (time(0)-cmdLine.started));
            result.append("uptimeMillis", (long long)(curTimeMillis64()-_started));
            result.append("uptimeEstimate",(double) (start/1000));
            result.appendDate( "localTime" , jsTime() );

            timeBuilder.appendNumber( "after basic" , Listener::getElapsedTimeMillis() - start );
            
            // --- all sections
            
            for ( SectionMap::const_iterator i = _sections->begin(); i != _sections->end(); ++i ) {
                ServerStatusSection* section = i->second;
                
                std::vector<Privilege> requiredPrivileges;
                section->addRequiredPrivileges(&requiredPrivileges);
                if (!authSession->checkAuthForPrivileges(requiredPrivileges).isOK())
                    continue;

                bool include = section->includeByDefault();
                
                BSONElement e = cmdObj[section->getSectionName()];
                if ( e.type() ) {
                    include = e.trueValue();
                }
                
                if ( ! include )
                    continue;
                
                BSONObj data = section->generateSection(e);
                if ( data.isEmpty() )
                    continue;

                result.append( section->getSectionName(), data );
                timeBuilder.appendNumber( static_cast<string>(str::stream() << "after " << section->getSectionName()), 
                                          Listener::getElapsedTimeMillis() - start );
            }

            // --- counters
            bool includeMetricTree = MetricTree::theMetricTree != NULL;
            if ( cmdObj["metrics"].type() && !cmdObj["metrics"].trueValue() )
                includeMetricTree = false;

            if ( includeMetricTree ) {
                MetricTree::theMetricTree->appendTo( result );
            }

            // --- some hard coded global things hard to pull out

            {
                RamLog::LineIterator rl(RamLog::get("warnings"));
                if (rl.lastWrite() >= time(0)-(10*60)){  // only show warnings from last 10 minutes
                    BSONArrayBuilder arr(result.subarrayStart("warnings"));
                    while (rl.more()) {
                        arr.append(rl.next());
                    }
                    arr.done();
                }
            }

            timeBuilder.appendNumber( "at end" , Listener::getElapsedTimeMillis() - start );
            if ( Listener::getElapsedTimeMillis() - start > 1000 ) {
                BSONObj t = timeBuilder.obj();
                log() << "serverStatus was very slow: " << t << endl;
                result.append( "timing" , t );
            }

            return true;
        }