Beispiel #1
0
inline float kinematics::betaiSystem( TLorentzVector* pa, TLorentzVector* pb, int i)
{
	TLorentzVector pTmp = (*pa)+(*pb);
	float E = pTmp.E();
	if(E<=0.) return -99999999.;

	if     (i==1) return pTmp.Px()/E;
	else if(i==2) return pTmp.Py()/E;
	else if(i==3) return pTmp.Pz()/E;
	else _WARNING("i needs to be 1,2,3 (x,y,z), returning -99999999.");
	return -99999999.;
}
void rochcor2012jan22::momcor_mc( TLorentzVector& mu, float charge, int runopt, float& qter){
  
  //sysdev == num : deviation = num

  float ptmu = mu.Pt();
  float muphi = mu.Phi();
  float mueta = mu.Eta(); // same with mu.Eta() in Root

  float px = mu.Px();
  float py = mu.Py();
  float pz = mu.Pz();
  float e = mu.E();

  int mu_phibin = phibin(muphi);
  int mu_etabin = etabin(mueta);
  
  if(mu_phibin>=0 && mu_etabin>=0){
    
    float Mf = (mcor_bf[mu_phibin][mu_etabin] + mptsys_mc_dm[mu_phibin][mu_etabin]*mcor_bfer[mu_phibin][mu_etabin])/(mpavg[mu_phibin][mu_etabin]+mmavg[mu_phibin][mu_etabin]);
    float Af = ((mcor_ma[mu_phibin][mu_etabin]+mptsys_mc_da[mu_phibin][mu_etabin]*mcor_maer[mu_phibin][mu_etabin]) - Mf*(mpavg[mu_phibin][mu_etabin]-mmavg[mu_phibin][mu_etabin]));     
    
    float cor = 1.0/(1.0 + 2.0*Mf + charge*Af*ptmu);
    
    //for the momentum tuning - eta,phi,Q correction
    px *= cor;
    py *= cor;
    pz *= cor;
    e  *= cor;
    
    float gscler = mgscl_stat;    
    float gscl = (genm_smr/mrecm);
    
    px *= (gscl + gscler_mc_dev*gscler);
    py *= (gscl + gscler_mc_dev*gscler);
    pz *= (gscl + gscler_mc_dev*gscler);
    e  *= (gscl + gscler_mc_dev*gscler);
    
    float momscl = sqrt(px*px + py*py)/ptmu;
    
    float tune = gsf[mu_etabin]*eran.Gaus(1.0,sf[mu_etabin]);
    
    px *= (tune); 
    py *= (tune);  
    pz *= (tune);  
    e  *= (tune);   
    
    qter *= sqrt(momscl*momscl + (1.0-tune)*(1.0-tune));
  }
  
  mu.SetPxPyPzE(px,py,pz,e);
  
}
void Boost_To_Stop_Rest_Frame(TLorentzVector& stop4, TLorentzVector& chargino4, TLorentzVector& b4, TLorentzVector& neutralino4, TLorentzVector& W4, TLorentzVector& up4, TLorentzVector& down4, TLorentzVector& s4)
{
    TVector3 betaV(-stop4.Px()/stop4.Energy(),-stop4.Py()/stop4.Energy(),-stop4.Pz()/stop4.Energy());
    stop4.Boost(betaV);
    chargino4.Boost(betaV);
    b4.Boost(betaV);
    neutralino4.Boost(betaV);
    W4.Boost(betaV);
    up4.Boost(betaV);
    down4.Boost(betaV);
    s4.SetE(chargino4.P()/chargino4.M());
    s4.SetVect(chargino4.Vect().Unit()*chargino4.Gamma());
}
///------------------------------------------------------------------------
/// MEKD::computeKD - compute KD and MEs for the input processes A and B
///------------------------------------------------------------------------
int MEKD::computeKD( TString processA, TString processB,
                     TLorentzVector lept1P, int lept1Id, TLorentzVector lept2P, int lept2Id,
                     TLorentzVector lept3P, int lept3Id, TLorentzVector lept4P, int lept4Id,
                     double& kd, double& me2processA, double& me2processB )
{
	/// Prepare 4-momenta in the required format
	lept1P_i[0] = lept1P.E();
	lept1P_i[1] = lept1P.Px();
	lept1P_i[2] = lept1P.Py();
	lept1P_i[3] = lept1P.Pz();
	
	lept2P_i[0] = lept2P.E();
	lept2P_i[1] = lept2P.Px();
	lept2P_i[2] = lept2P.Py();
	lept2P_i[3] = lept2P.Pz();
	
	lept3P_i[0] = lept3P.E();
	lept3P_i[1] = lept3P.Px();
	lept3P_i[2] = lept3P.Py();
	lept3P_i[3] = lept3P.Pz();
	
	lept4P_i[0] = lept4P.E();
	lept4P_i[1] = lept4P.Px();
	lept4P_i[2] = lept4P.Py();
	lept4P_i[3] = lept4P.Pz();
	
	/// Load internal containers
	four_particle_Ps_i[0] = lept1P_i;
	four_particle_Ps_i[1] = lept2P_i;
	four_particle_Ps_i[2] = lept3P_i;
	four_particle_Ps_i[3] = lept4P_i;
	
	four_particle_IDs_i[0] = lept1Id;
	four_particle_IDs_i[1] = lept2Id;
	four_particle_IDs_i[2] = lept3Id;
	four_particle_IDs_i[3] = lept4Id;
	
	return computeKD( (string) processA.Data(), (string) processB.Data(), four_particle_Ps_i, four_particle_IDs_i, kd, me2processA, me2processB );
}
float GetWeightWjetsPolarizationF0(TLorentzVector _p4W, TLorentzVector _p4lepton,float PercentVariation, bool isWplus){

  LorentzVector p4W, p4lepton;
  p4W.SetPx(_p4W.Px());
  p4W.SetPy(_p4W.Py());
  p4W.SetPz(_p4W.Pz());
  p4W.SetE(_p4W.E());
  p4lepton.SetPx(_p4lepton.Px());
  p4lepton.SetPy(_p4lepton.Py());
  p4lepton.SetPz(_p4lepton.Pz());
  p4lepton.SetE(_p4lepton.E());

  float final_weight=1;

  float cos_theta = WjetPolarizationAngle(p4W,p4lepton);
  //  final_weight  = GetWeight( cos_theta,PercentVariation );
  //final_weight  = GetWeightFLminusFR( cos_theta,PercentVariation,p4W, isWplus );
  final_weight  = GetWeightF0( cos_theta,PercentVariation,p4W,isWplus );
  
  return final_weight;
  
  
}//end of function
///------------------------------------------------------------------------
/// MEKD::computeMEs - compute MEs for a multiple reuse
///------------------------------------------------------------------------
int MEKD::computeMEs( TLorentzVector lept1P, int lept1Id, TLorentzVector lept2P, int lept2Id,
					TLorentzVector lept3P, int lept3Id, TLorentzVector lept4P, int lept4Id )
{
	/// Prepare 4-momenta in the required format
	lept1P_i[0] = lept1P.E();
	lept1P_i[1] = lept1P.Px();
	lept1P_i[2] = lept1P.Py();
	lept1P_i[3] = lept1P.Pz();
	
	lept2P_i[0] = lept2P.E();
	lept2P_i[1] = lept2P.Px();
	lept2P_i[2] = lept2P.Py();
	lept2P_i[3] = lept2P.Pz();
	
	lept3P_i[0] = lept3P.E();
	lept3P_i[1] = lept3P.Px();
	lept3P_i[2] = lept3P.Py();
	lept3P_i[3] = lept3P.Pz();
	
	lept4P_i[0] = lept4P.E();
	lept4P_i[1] = lept4P.Px();
	lept4P_i[2] = lept4P.Py();
	lept4P_i[3] = lept4P.Pz();
	
	/// Load internal containers
	four_particle_Ps_i[0] = lept1P_i;
	four_particle_Ps_i[1] = lept2P_i;
	four_particle_Ps_i[2] = lept3P_i;
	four_particle_Ps_i[3] = lept4P_i;
	
	four_particle_IDs_i[0] = lept1Id;
	four_particle_IDs_i[1] = lept2Id;
	four_particle_IDs_i[2] = lept3Id;
	four_particle_IDs_i[3] = lept4Id;
	
	return computeMEs( four_particle_Ps_i, four_particle_IDs_i );
}
void rochcor2012::momcor_data( TLorentzVector& mu, float charge, int runopt, float& qter){
  
  float ptmu = mu.Pt();

  float muphi = mu.Phi();
  float mueta = mu.Eta(); // same with mu.Eta() in Root

  float px = mu.Px();
  float py = mu.Py();
  float pz = mu.Pz();
  float e = mu.E();
  
  int mu_phibin = phibin(muphi);
  int mu_etabin = etabin(mueta);

  float Mf = 0.0;
  float Af = 0.0;

  if(runopt==0){
    Mf = (dcor_bf[mu_phibin][mu_etabin]+mptsys_da_dm[mu_phibin][mu_etabin]*dcor_bfer[mu_phibin][mu_etabin])/(dpavg[mu_phibin][mu_etabin]+dmavg[mu_phibin][mu_etabin]);
    Af = ((dcor_ma[mu_phibin][mu_etabin]+mptsys_da_da[mu_phibin][mu_etabin]*dcor_maer[mu_phibin][mu_etabin]) - Mf*(dpavg[mu_phibin][mu_etabin]-dmavg[mu_phibin][mu_etabin]));     
  }else if(runopt==1){
    Mf = (dcor_bfD[mu_phibin][mu_etabin]+mptsys_da_dm[mu_phibin][mu_etabin]*dcor_bfDer[mu_phibin][mu_etabin])/(dpavgD[mu_phibin][mu_etabin]+dmavgD[mu_phibin][mu_etabin]);
    Af = ((dcor_maD[mu_phibin][mu_etabin]+mptsys_da_da[mu_phibin][mu_etabin]*dcor_maDer[mu_phibin][mu_etabin]) - Mf*(dpavgD[mu_phibin][mu_etabin]-dmavgD[mu_phibin][mu_etabin]));     
  }
  
  float cor = 1.0/(1.0 + 2.0*Mf + charge*Af*ptmu);
  
  px *= cor;
  py *= cor;
  pz *= cor;
  e  *= cor;
  
  //after Z pt correction
  float gscler = dgscl_stat;
  float gscl = (genm_smr/drecm);
  
  px *= (gscl + gscler_da_dev*gscler);
  py *= (gscl + gscler_da_dev*gscler);
  pz *= (gscl + gscler_da_dev*gscler);
  e  *= (gscl + gscler_da_dev*gscler);
  
  float momscl = sqrt(px*px + py*py)/ptmu;
  qter *= momscl;
  
  mu.SetPxPyPzE(px,py,pz,e);
  
}
TLorentzVector doCalEnergy(double BeamEnergy,
                           TLorentzVector Particle1,
                           TLorentzVector Particle2,
                           double nucleusMass,
                           double Particle2Mass,
                           double Particle3Mass)
{
    double E_Particle1   = Particle1.E();
    double p_Particle1_x = Particle1.Px();
    double p_Particle1_y = Particle1.Py();
    double p_Particle1_z = Particle1.Pz();
    double p_Particle1   = sqrt(TMath::Power(p_Particle1_x,2.0) +
                                    TMath::Power(p_Particle1_y,2.0) +
                                    TMath::Power(p_Particle1_z,2.0));
    double phi   = Particle2.Phi();
    double theta = Particle2.Theta();
    double b     = 2.0 * ( p_Particle1_x * cos(phi) * sin(theta) +
                           p_Particle1_y * sin(phi) * sin(theta) +
                           p_Particle1_z * cos(theta) -
                           BeamEnergy * cos(theta)
                         );
    double c     = p_Particle1 * p_Particle1 + BeamEnergy * BeamEnergy - 2.0 * BeamEnergy * p_Particle1_z;
    double d     = BeamEnergy + nucleusMass - E_Particle1;
    double e     = TMath::Power(Particle3Mass,2.0) - TMath::Power(Particle2Mass,2.0) - d * d + c;
    double Delta = 16.0 * TMath::Power(d,2.0) * (TMath::Power(e,2.0) +
                                                 TMath::Power(b * Particle2Mass,2.0) -
                                                 TMath::Power(d * Particle2Mass * 2.0,2.0));
    
    TLorentzVector NewParticle(0.0,0.0,0.0,0.0);
    if(Delta>0.)
    {
       double sol2     = (2.0 * e * b + sqrt(Delta)) / (2.0 * (4.0 * TMath::Power(d,2.0) - TMath::Power(b,2.0)));
       double newpxcal = sol2 * cos(phi) * sin(theta);
       double newpycal = sol2 * sin(phi) * sin(theta);
       double newpzcal = sol2 * cos(theta);
       double energy   = sqrt(TMath::Power(sol2,2.0) + TMath::Power(Particle2Mass,2.0));
      
       TLorentzVector NewParticle2(newpxcal,newpycal,newpzcal,energy);
       NewParticle = NewParticle2;
    }
  
    return NewParticle;
}
Beispiel #9
0
void rochcor::momcor_data( TLorentzVector& mu, float charge, float sysdev, int runopt){
  
  float ptmu = mu.Pt();

  float muphi = mu.Phi();
  float mueta = mu.Eta(); // same with mu.Eta() in Root

  float px = mu.Px();
  float py = mu.Py();
  float pz = mu.Pz();
  float e = mu.E();
  
  int mu_phibin = phibin(muphi);
  int mu_etabin = etabin(mueta);
  
  //float mptsys1 = sran.Gaus(0.0,sysdev);
  
  float dm = (dcor_bf[mu_phibin][mu_etabin] + mptsys_da_dm[mu_phibin][mu_etabin]*dcor_bfer[mu_phibin][mu_etabin])/dmavg[mu_phibin][mu_etabin];
  float da = dcor_ma[mu_phibin][mu_etabin] + mptsys_da_da[mu_phibin][mu_etabin]*dcor_maer[mu_phibin][mu_etabin];
  
  float cor = 1.0/(1.0 + dm + charge*da*ptmu);
  
  px *= cor;
  py *= cor;
  pz *= cor;
  e  *= cor;
  
  //after Z pt correction
  float gscler = 0.0;
  
  gscler = TMath::Sqrt( TMath::Power(dgscl_stat,2) + TMath::Power(dgscl_syst,2) );
  
  float gscl = (genm_smr/drecm);
  
  px *= (gscl + gscler_da_dev*gscler);
  py *= (gscl + gscler_da_dev*gscler);
  pz *= (gscl + gscler_da_dev*gscler);
  e  *= (gscl + gscler_da_dev*gscler);
  
  mu.SetPxPyPzE(px,py,pz,e);
  
}
//This is the function to determine the interaction point in case of a cylinder (case1), for BDXmini.
//The cylinder is with the axis along y(vertical), center at x=0,y=0,z=ldet, radius is R,height is h
double KinUtils::findInteractionPointCylinder1(const TLorentzVector &chi,double ldet,double h,double R,TVector3 &vin,TVector3 &vout,TVector3 &vhit){

	double tIN,tOUT,t2,t3,t,L;

	double px=chi.Px();
	double py=chi.Py();
	double pz=chi.Pz();

	double delta=pz*pz*ldet*ldet-(pz*pz+px*px)*(ldet*ldet-R*R);
	if (delta<0){
		cout<<"KinUtils::findInteractionPointCylinder1 error, the delta is: "<<delta<<endl;
		return 0;
	}

	//entry point
	tIN = (pz*ldet - sqrt(delta))/(px*px+pz*pz);
	t2 = (pz*ldet + sqrt(delta))/(px*px+pz*pz);

	t3 = (h/2)/py;


	if ((t3>0)&&(t3<t2)&&(t3>tIN)){
		tOUT=t3;
	}else{
		tOUT=t2;
	}

	t=Rand.Uniform(tIN,tOUT);

	vin.SetXYZ(tIN*px,tIN*py,tIN*pz);
	vout.SetXYZ(tOUT*px,tOUT*py,tOUT*pz);

	vhit.SetXYZ(t*px,t*py,t*pz);


	L = (vout - vin).Mag();



	return L;
}
Beispiel #11
0
void DalitzChiSq2::setap3(TLorentzVector vec){
	ap3.v.SetXYZM(vec.Px(),vec.Py(),vec.Pz(),vec.M());
	//em & ep
    	    double cos12 = (ap1.v.Px()*ap2.v.Px() + ap1.v.Py()*ap2.v.Py() + ap1.v.Pz()*ap2.v.Pz())/(ap1.v.P()*ap2.v.P());
    	   //em & gm
   	    double cos23 = (ap2.v.Px()*ap3.v.Px() + ap2.v.Py()*ap3.v.Py() + ap2.v.Pz()*ap3.v.Pz())/(ap3.v.P()*ap2.v.P());
            //ep & gm
            double cos13 = (ap1.v.Px()*ap3.v.Px() + ap1.v.Py()*ap3.v.Py() + ap1.v.Pz()*ap3.v.Pz())/(ap1.v.P()*ap3.v.P());
		
		double beta1 = ap1.v.P()/ap1.v.E();
		double beta2 = ap2.v.P()/ap2.v.E();
	    

	    double z12 = 2*((1/(beta1*beta2)) -cos12);
	    double z23 = 2*((1/beta2)-cos23);
	    double z13 = 2*((1/beta1)-cos13);
	double topterm =   M*M - 2*m_e*m_e - ( z12/(TMath::Sin(ap1.theta) * TMath::Sin(ap2.theta) *ap1.x_m*ap2.x_m));
	double bottomterm = ( (z13/(TMath::Sin(ap1.theta) * ap1.x_m)) + (z23/(TMath::Sin(ap2.theta) * ap2.x_m)) );

	ap3.x_m=topterm/bottomterm;
	
}
bool KinUtils::intersectsCylinder1(const TLorentzVector &chi,double ldet,double h,double R){

	double t1,y;

	double px=chi.Px();
	double py=chi.Py();
	double pz=chi.Pz();

	double delta=pz*pz*ldet*ldet-(pz*pz+px*px)*(ldet*ldet-R*R);
	if (delta<0) return false;

	t1 = (pz*ldet - sqrt(delta))/(px*px+pz*pz); //this is where it enters

	y = t1*py;
	if ((y>h/2)||(y<-h/2)) return false;



	return true;


}
void print_se(TLorentzVector e_vec, TLorentzVector p_vec){
    double_t se = 2.0 * e_vec.E() * (abs(p_vec.Px()) + p_vec.E()) + deut_mass*deut_mass;
    cout << "se: " << se <<endl;
}
void print_vec(TLorentzVector v){
    cout <<"("<< v.Px() << " , " << v.Py() << " , " << v.Pz() << " , " << v.E() << ")" <<endl;
}
Beispiel #15
0
int PHSartre::process_event(PHCompositeNode *topNode) {

  if (verbosity > 1) cout << "PHSartre::process_event - event: " << _eventcount << endl;
  
  bool passedTrigger = false;
  Event *event = NULL;

  TLorentzVector *eIn     = NULL;
  TLorentzVector *pIn     = NULL;
  TLorentzVector *eOut    = NULL;
  TLorentzVector *gamma   = NULL;
  TLorentzVector *vm      = NULL;
  TLorentzVector *PomOut  = NULL;
  TLorentzVector *pOut    = NULL;
  TLorentzVector *vmDecay1 = NULL; 
  TLorentzVector *vmDecay2 = NULL; 
  unsigned int preVMDecaySize = 0; 

  while (!passedTrigger) {
    ++_gencount;

    // Generate a Sartre event
    event = _sartre->generateEvent();
        
    //
    //  If Sartre is run in UPC mode, half of the events needs to be
    //  rotated around and axis perpendicular to z:
    //  (only for symmetric events)
    //
    if(settings->UPC() and settings->A()==settings->UPCA()){
      randomlyReverseBeams(event);
    }
	
    // for sPHENIX/RHIC p+Au
    // (see comments in ReverseBeams)
    // reverse when the proton emits the virtual photon
	
    if(settings->UPC() and settings->A()==197){
      ReverseBeams(event);
    }

    // Set pointers to the parts of the event we will need:

    eIn     = &event->particles[0].p;
    pIn     = &event->particles[1].p;
    eOut    = &event->particles[2].p;
    gamma   = &event->particles[3].p;
    vm      = &event->particles[4].p;
    PomOut  = &event->particles[5].p;
    pOut    = &event->particles[6].p;

    // To allow the triggering to work properly, we need to decay the vector meson here

    preVMDecaySize = event->particles.size(); 

    if(doPerformDecay) {

      if( decay->SetDecay(*vm, 2, daughterMasses) ){
	double weight = decay->Generate(); // weight is always 1 here
	if ( (weight-1) > FLT_EPSILON) {
	  cout << "PHSartre: Warning decay weight != 1, weight = " << weight << endl;
	}
	TLorentzVector *vmDaughter1 = decay->GetDecay(0);
	TLorentzVector *vmDaughter2 = decay->GetDecay(1);

	event->particles[4].status = 2; // set VM status

	Particle vmDC1; 
	vmDC1.index = event->particles.size(); 
	vmDC1.pdgId =  daughterID; 
	vmDC1.status = 1; // final state
	vmDC1.p = *vmDaughter1; 
	vmDC1.parents.push_back(4);	
	event->particles.push_back(vmDC1); 
	vmDecay1 = &event->particles[event->particles.size()-1].p;

	Particle vmDC2; 
	vmDC2.index = event->particles.size(); 
	vmDC2.pdgId =  -daughterID; 
	vmDC2.status = 1; // final state
	vmDC2.p = *vmDaughter2; 
	vmDC2.parents.push_back(4);	
	event->particles.push_back(vmDC2); 
	vmDecay2 = &event->particles[event->particles.size()-1].p;

      }
      else {
	cout << "PHSartre: WARNING: Kinematics of Vector Meson does not allow decay!" << endl;
      }

    }

    // test trigger logic
    
    bool andScoreKeeper = true;
    if (verbosity > 2) {
      cout << "PHSartre::process_event - triggersize: " << _registeredTriggers.size() << endl;
    }

    for (unsigned int tr = 0; tr < _registeredTriggers.size(); tr++) { 
      bool trigResult = _registeredTriggers[tr]->Apply(event);

      if (verbosity > 2) {
	cout << "PHSartre::process_event trigger: "
	     << _registeredTriggers[tr]->GetName() << "  " << trigResult << endl;
      }

      if (_triggersOR && trigResult) {
	passedTrigger = true;
	break;
      } else if (_triggersAND) {
	andScoreKeeper &= trigResult;
      }
      
      if (verbosity > 2 && !passedTrigger) {
	cout << "PHSartre::process_event - failed trigger: "
	     << _registeredTriggers[tr]->GetName() <<  endl;
      }
    }

    if ((andScoreKeeper && _triggersAND) || (_registeredTriggers.size() == 0)) {
      passedTrigger = true;
    }

  }

  // fill HepMC object with event
  
  HepMC::GenEvent *genevent = new HepMC::GenEvent(HepMC::Units::GEV, HepMC::Units::MM);

  // add some information to the event
  genevent->set_event_number(_eventcount);

  // Set the PDF information
  HepMC::PdfInfo pdfinfo;
  pdfinfo.set_scalePDF(event->Q2);
  genevent->set_pdf_info(pdfinfo); 

  // We would also like to save:
  //
  // event->t;
  // event->x;
  // event->y;
  // event->s;
  // event->W;
  // event->xpom;
  // (event->polarization == transverse ? 0 : 1);
  // (event->diffractiveMode == coherent ? 0 : 1);
  // 
  // but there doesn't seem to be a good place to do so 
  // within the HepMC event information?
  //
  // t, W and Q^2 form a minial set of good variables for diffractive events
  // Maybe what I do is record the input particles to the event at the HepMC
  // vertices and reconstruct the kinematics from there? 
  
  // Create HepMC vertices and add final state particles to them

  // First, the emitter(electron)-virtual photon vertex:

  HepMC::GenVertex* egammavtx = new HepMC::GenVertex(CLHEP::HepLorentzVector(0.0,0.0,0.0,0.0));
  genevent->add_vertex(egammavtx); 

  egammavtx->add_particle_in( 
			 new HepMC::GenParticle( CLHEP::HepLorentzVector(eIn->Px(),
									 eIn->Py(),
									 eIn->Pz(),
									 eIn->E()), 
						 event->particles[0].pdgId, 
						 3 ) 
			  );

  HepMC::GenParticle *hgamma =  new HepMC::GenParticle( CLHEP::HepLorentzVector(gamma->Px(),
									 gamma->Py(),
									 gamma->Pz(),
									 gamma->E()), 
						event->particles[3].pdgId, 
						3 ); 

  egammavtx->add_particle_out(hgamma);

  egammavtx->add_particle_out( 
			 new HepMC::GenParticle( CLHEP::HepLorentzVector(eOut->Px(),
									 eOut->Py(),
									 eOut->Pz(),
									 eOut->E()), 
						 event->particles[2].pdgId, 
						 1 ) 
			  );

  // Next, the hadron-pomeron vertex:

  HepMC::GenVertex* ppomvtx = new HepMC::GenVertex(CLHEP::HepLorentzVector(0.0,0.0,0.0,0.0));
  genevent->add_vertex(ppomvtx); 


  ppomvtx->add_particle_in( 
			 new HepMC::GenParticle( CLHEP::HepLorentzVector(pIn->Px(),
									 pIn->Py(),
									 pIn->Pz(),
									 pIn->E()), 
						 event->particles[1].pdgId, 
						 3 ) 
			     );

  HepMC::GenParticle *hPomOut = new HepMC::GenParticle( CLHEP::HepLorentzVector(PomOut->Px(),
									 PomOut->Py(),
									 PomOut->Pz(),
									 PomOut->E()), 
						 event->particles[5].pdgId, 
						 3 ); 

  ppomvtx->add_particle_out(hPomOut); 

  // If this is a nuclear breakup, add in the nuclear fragments
  // Otherwise, add in the outgoing hadron
        
  //If the event is incoherent, and nuclear breakup is enabled, fill the remnants to the tree
  if(settings->enableNuclearBreakup() and event->diffractiveMode == incoherent){
    for(unsigned int iParticle=7; iParticle < preVMDecaySize; iParticle++){
      if(event->particles[iParticle].status == 1) {  // Final-state particle
	const Particle& particle = event->particles[iParticle];	  
	ppomvtx->add_particle_out( 
			       new HepMC::GenParticle( CLHEP::HepLorentzVector(particle.p.Px(),
								 particle.p.Py(),
								 particle.p.Pz(),
								 particle.p.E()), 
						particle.pdgId, 
						1 ) 
				);
      }  
    }  
  }
  else{

    ppomvtx->add_particle_out( 
			      new HepMC::GenParticle( CLHEP::HepLorentzVector(pOut->Px(),
									      pOut->Py(),
									      pOut->Pz(),
									      pOut->E()), 
						      event->particles[6].pdgId, 
						      1 ) 
			       );
  }

  // The Pomeron-Photon vertex

  HepMC::GenVertex* gammapomvtx = new HepMC::GenVertex(CLHEP::HepLorentzVector(0.0,0.0,0.0,0.0));
  genevent->add_vertex(gammapomvtx); 
  
  gammapomvtx->add_particle_in(hgamma); 
  gammapomvtx->add_particle_in(hPomOut); 

  int isVMFinal = 1; 
  if(doPerformDecay) isVMFinal = 2; 

  HepMC::GenParticle *hvm = new HepMC::GenParticle( CLHEP::HepLorentzVector(vm->Px(),
									    vm->Py(),
									    vm->Pz(),
									    vm->E()), 
						   event->particles[4].pdgId, 
						   isVMFinal ) ; 

  gammapomvtx->add_particle_out( hvm );
 
  // Add the VM decay to the event

  if(doPerformDecay) {

    if(vmDecay1 && vmDecay2){

      HepMC::GenVertex* fvtx = new HepMC::GenVertex(CLHEP::HepLorentzVector(0.0,0.0,0.0,0.0));
      genevent->add_vertex(fvtx); 

      fvtx->add_particle_in( hvm ); 

      fvtx->add_particle_out( 
			 new HepMC::GenParticle( CLHEP::HepLorentzVector(vmDecay1->Px(),
							   vmDecay1->Py(),
							   vmDecay1->Pz(),
							   vmDecay1->E()), 
					  daughterID, 
					  1 ) 
			  );
      fvtx->add_particle_out( 
			 new HepMC::GenParticle( CLHEP::HepLorentzVector(vmDecay2->Px(),
							   vmDecay2->Py(),
							   vmDecay2->Pz(),
							   vmDecay2->E()), 
					  -daughterID, 
					  1 ) 
			  );

    }
    else {
      cout << "PHSartre: WARNING: Kinematics of Vector Meson does not allow decay!" << endl;
    }

  }

  // pass HepMC to PHNode
  
  PHHepMCGenEvent * success = hepmc_helper . insert_event(genevent);
  if (!success) {
    cout << "PHSartre::process_event - Failed to add event to HepMC record!" << endl;
    return Fun4AllReturnCodes::ABORTRUN;
  }


  // print outs
  
  if (verbosity > 2) cout << "PHSartre::process_event - FINISHED WHOLE EVENT" << endl;

  ++_eventcount;
  return Fun4AllReturnCodes::EVENT_OK;
}
Beispiel #16
0
void PlotTheta( TString inputfilename, TString outputfilename = "output.root"){
//    infile= new TFile("../PATGrid.SM.10k.root","READ");
    infile = new TFile(inputfilename, "READ");
    tree = (TTree*)infile->Get("Event");
    outputFile = new TFile(outputfilename, "RECREATE");
    outTree = new TTree("MyTree","Untersuchung der RekoObjekte");

    //TH2::SetDefaultSumw2();

    histogram__CosThetaDiff = new TH1D("histogram__CosThetaDiff", "Differenz CosTheta gen-reko", 400, -2, 2);
    histogram__CosTheta_GenReko = new TH2D("histogram__CosTheta_GenReko", "Reko-cos(theta) gegen Gen-cos(theta)", 50, -1, 1, 50, -1, 1);

    histogram__gen_A = new TH2D("histogram__gen_A", "histogram__gen_A", 5, -1, 1, 5, -1, 1);
    histogram__gen_N = new TH2D("histogram__gen_N", "histogram__gen_N", 5, -1, 1, 5, -1, 1);

    histogram__gen_LL = new TH2D("histogram__gen_LL", "histogram__gen_LL", 5, -1, 1, 5, -1, 1);
    histogram__gen_LR = new TH2D("histogram__gen_LR", "histogram__gen_LR", 5, -1, 1, 5, -1, 1);
    histogram__gen_RR = new TH2D("histogram__gen_RR", "histogram__gen_RR", 5, -1, 1, 5, -1, 1);
    histogram__gen_RL = new TH2D("histogram__gen_RL", "histogram__gen_RL", 5, -1, 1, 5, -1, 1);

    histogram__gen_Correlation = new TH2D("histogram__gen_Correlation", "histogram__gen_Correlation", 5, -1, 1, 5, -1, 1);

    histogram__A = new TH2D("histogram__A", "histogram__A", 5, -1, 1, 5, -1, 1);
    histogram__N = new TH2D("histogram__N", "histogram__N", 5, -1, 1, 5, -1, 1);

    histogram__Correlation = new TH2D("histogram__Correlation", "histogram__Correlation", 5, -1, 1, 5, -1, 1);
    histogram__Correlation_L15_B50_T1 = new TH2D("histogram__Correlation_L15_B50_T1", "histogram__Correlation_L15_B50_T1", 5, -1, 1, 5, -1, 1);
    histogram__A_L15_B50_T1 = new TH2D("histogram__A_L15_B50_T1", "histogram__A_L15_B50_T1", 5, -1, 1, 5, -1, 1);
    histogram__N_L15_B50_T1 = new TH2D("histogram__N_L15_B50_T1", "histogram__N_L15_B50_T1", 5, -1, 1, 5, -1, 1);
    histogram__Correlation_L20 = new TH2D("histogram__Correlation_L20", "histogram__Correlation_L20", 5, -1, 1, 5, -1, 1);
    histogram__A_L20 = new TH2D("histogram__A_L20", "histogram__A_L20", 5, -1, 1, 5, -1, 1);
    histogram__N_L20 = new TH2D("histogram__N_L20", "histogram__N_L20", 5, -1, 1, 5, -1, 1);
    histogram__Correlation_L20_B40 = new TH2D("histogram__Correlation_L20_B40", "histogram__Correlation_L20_B40", 5, -1, 1, 5, -1, 1);
    histogram__A_L20_B40 = new TH2D("histogram__A_L20_B40", "histogram__A_L20_B40", 5, -1, 1, 5, -1, 1);
    histogram__N_L20_B40 = new TH2D("histogram__N_L20_B40", "histogram__N_L20_B40", 5, -1, 1, 5, -1, 1);
    
    histogram__Correlation_L20_B30_T1 = new TH2D("histogram__Correlation_L20_B30_T1", "histogram__Correlation_L20_B30_T1", 5, -1, 1, 5, -1, 1);
    histogram__A_L20_B30_T1 = new TH2D("histogram__A_L20_B30_T1", "histogram__A_L20_B30_T1", 5, -1, 1, 5, -1, 1);
    histogram__N_L20_B30_T1 = new TH2D("histogram__N_L20_B30_T1", "histogram__N_L20_B30_T1", 5, -1, 1, 5, -1, 1);

    histogram__Correlation_L20_B40_T1 = new TH2D("histogram__Correlation_L20_B40_T1", "histogram__Correlation_L20_B40_T1", 5, -1, 1, 5, -1, 1);
    histogram__A_L20_B40_T1 = new TH2D("histogram__A_L20_B40_T1", "histogram__A_L20_B40_T1", 5, -1, 1, 5, -1, 1);
    histogram__N_L20_B40_T1 = new TH2D("histogram__N_L20_B40_T1", "histogram__N_L20_B40_T1", 5, -1, 1, 5, -1, 1);
    histogram__Correlation_T1 = new TH2D("histogram__Correlation_T1", "histogram__Correlation_T1", 5, -1, 1, 5, -1, 1);
    histogram__A_T1 = new TH2D("histogram__A_T1", "histogram__A_T1", 5, -1, 1, 5, -1, 1);
    histogram__N_T1 = new TH2D("histogram__N_T1", "histogram__N_T1", 5, -1, 1, 5, -1, 1);



    histogram__CosThetaDiff_TTbarPt = new TH2D("histogram__CosThetaDiff_TTbarPt", "histogram__CosThetaDiff_TTbarPt", 100, 0, 1000, 400, -2, 2);


    histogram__LeptonRelIso = new TH1D("histogram__LeptonRelIso", "histogram__LeptonRelIso", 101, 0, 1.01);


    histogram__semilepton_BLeptonMinus = new TH1D("histogram__semilepton_BLeptonMinus","histogram__semilepton_BLeptonMinus", 200, -1, 1);
    histogram__semilepton_BLeptonPlus = new TH1D("histogram__semilepton_BLeptonPlus","histogram__semilepton_BLeptonPlus", 200, -1, 1);



    histogram_nupx_gen_reco = new TH2D(" histogram_nupx_gen_reco", " histogram_nupx_gen_reco", 600, -300, 300, 600, -300, 300);
    histogram_nupy_gen_reco = new TH2D(" histogram_nupy_gen_reco", " histogram_nupy_gen_reco", 600, -300, 300, 600, -300, 300);
    histogram_nupz_gen_reco = new TH2D(" histogram_nupz_gen_reco", " histogram_nupz_gen_reco", 600, -300, 300, 600, -300, 300);

    histogram_nubpx_gen_reco = new TH2D(" histogram_nubpx_gen_reco", " histogram_nubpx_gen_reco", 600, -300, 300, 600, -300, 300);
    histogram_nubpy_gen_reco = new TH2D(" histogram_nubpy_gen_reco", " histogram_nubpy_gen_reco", 600, -300, 300, 600, -300, 300);
    histogram_nubpz_gen_reco = new TH2D(" histogram_nubpz_gen_reco", " histogram_nubpz_gen_reco", 600, -300, 300, 600, -300, 300);

    outTree->Branch("EventIsGood", &EventIsGood, "Event ist rekonstruiert/I");
    outTree->Branch("numberOfJets", &numberOfJets, "Anzahl der Jets/I");
    outTree->Branch("numberOfGoodJets", &numberOfGoodJets, "Anzahl der guten Jets/I");

    outTree->Branch("CosThetaDiff" ,&CosThetaDiff ,"Differenz im cosTheta Reko zu Gen/D");
    outTree->Branch("CosThetaPlus" ,&CosThetaPlus ,"cosTheta LeptonPlus/D");
    outTree->Branch("CosThetaMinus" ,&CosThetaMinus ,"cosTheta LeptonMinus/D");
    outTree->Branch("RekoCosThetaPlus" ,&RekoCosThetaPlus ,"cosTheta RekoLeptonPlus/D");
    outTree->Branch("RekoCosThetaMinus" ,&RekoCosThetaMinus ,"cosTheta RekoLeptonMinus/D");

    outTree->Branch("CosLeptonAngleD", &CosLeptonAngleD, "CosinusLeptonWinkel D/D");
    outTree->Branch("CosRekoLeptonAngleD", &CosRekoLeptonAngleD, "CosinusRekoLeptonWinkel D/D");

    outTree->Branch("TTbar_Pt", &TTbar_Pt, "Pt des TTbarsystems Generator/D");
    outTree->Branch("RekoTTbar_Pt", &RekoTTbar_Pt, "Pt des TTbarsystems Reko/D");
    outTree->Branch("TTbar_M", &TTbar_M, "Masse des TTbarsystems Generator/D");
    outTree->Branch("RekoTTbar_M", &RekoTTbar_M, "Masse des TTbarsystems Reko/D");
    outTree->Branch("Top_Pt", &Top_Pt, "Pt des Tops Generator/D");
    outTree->Branch("Top_M", &Top_M, "M des Tops Generator/D");
    outTree->Branch("AntiTop_Pt", &AntiTop_Pt, "Pt des AntiTops Generator/D");
    outTree->Branch("AntiTop_M", &AntiTop_M, "M des AntiTops Generator/D");
    outTree->Branch("RekoTop_Pt", &RekoTop_Pt, "Pt des Tops Reko/D");
    outTree->Branch("RekoAntiTop_Pt", &RekoAntiTop_Pt, "Pt des AntiTops Reko/D");
    outTree->Branch("RekoTop_M", &RekoTop_M, "M des Tops Reko/D");
    outTree->Branch("RekoAntiTop_M", &RekoAntiTop_M, "M des AntiTops Reko/D");
    outTree->Branch("Nu_Px", &Nu_Px, "Px des Neutrinos Generator/D");
    outTree->Branch("Nu_Py", &Nu_Py, "Py des Neutrinos Generator/D");
    outTree->Branch("Nu_Pz", &Nu_Pz, "Pz des Neutrinos Generator/D");
    outTree->Branch("AntiNu_Px", &AntiNu_Px, "Px des AntiNeutrinos Generator/D");
    outTree->Branch("AntiNu_Py", &AntiNu_Py, "Py des AntiNeutrinos Generator/D");
    outTree->Branch("AntiNu_Pz", &AntiNu_Pz, "Pz des AntiNeutrinos Generator/D");
    outTree->Branch("RekoNu_Px", &RekoNu_Px, "Px des Neutrinos Reko/D");
    outTree->Branch("RekoNu_Py", &RekoNu_Py, "Py des Neutrinos Reko/D");
    outTree->Branch("RekoNu_Pz", &RekoNu_Pz, "Pz des Neutrinos Reko/D");
    outTree->Branch("RekoAntiNu_Px", &RekoAntiNu_Px, "Px des AntiNeutrinos Reko/D");
    outTree->Branch("RekoAntiNu_Py", &RekoAntiNu_Py, "Py des AntiNeutrinos Reko/D");
    outTree->Branch("RekoAntiNu_Pz", &RekoAntiNu_Pz, "Pz des AntiNeutrinos Reko/D");

    outTree->Branch("BestNu_Px", &BestNu_Px, "Px des Neutrinos Best/D");
    outTree->Branch("BestNu_Py", &BestNu_Py, "Py des Neutrinos Best/D");
    outTree->Branch("BestNu_Pz", &BestNu_Pz, "Pz des Neutrinos Best/D");
    outTree->Branch("BestAntiNu_Px", &BestAntiNu_Px, "Px des AntiNeutrinos Best/D");
    outTree->Branch("BestAntiNu_Py", &BestAntiNu_Py, "Py des AntiNeutrinos Best/D");
    outTree->Branch("BestAntiNu_Pz", &BestAntiNu_Pz, "Pz des AntiNeutrinos Best/D");

    outTree->Branch("Lepton_Pt", &Lepton_Pt, "kleineres Pt der beiden gewaehlten Leptonen/D");
    outTree->Branch("BJet_Et", &BJet_Et,"niedrigieres Et der BJets/D");
    outTree->Branch("BJet_Tag_TrkCount", &BJet_Tag_TrkCount,"niedrigierer BTag der BJets/D");
    outTree->Branch("BJet_Tag_SVsimple", &BJet_Tag_SVsimple,"niedrigierer BTag der BJets/D");
    outTree->Branch("BJet_Tag_SVcomb", &BJet_Tag_SVcomb,"niedrigierer BTag der BJets/D");
    outTree->Branch("BJet_Disc", &BJet_Disc,"niedrigierer Discriminator der BJets/D");
    outTree->Branch("Lepton1_Id", &Lepton1_Id, "PdgId des ersten Leptons/I");
    outTree->Branch("Lepton2_Id", &Lepton2_Id, "PdgId des zweiten Leptons/I");
    outTree->Branch("Lepton_Mass", &Lepton_Mass, "inv. Masse der beiden Leptonen/D");

    outTree->Branch("BJet_Angle", &BJet_Angle, "Winkel bJet zu Quark/D");
    outTree->Branch("BbarJet_Angle", &BbarJet_Angle, "Winkel bbarJet zu Quark/D");
    outTree->Branch("LeptonPlus_Angle", &LeptonPlus_Angle, "Winkel LeptonPlus zu Lepton Gen /D");
    outTree->Branch("LeptonMinus_Angle", &LeptonMinus_Angle, "Winkel LeptonMinus zu Lepton Gen /D");
    outTree->Branch("RekoNu_Angle", &RekoNu_Angle, "Winkel RekoNu zu GenNu/D");
    outTree->Branch("RekoAntiNu_Angle", &RekoAntiNu_Angle, "Winkel RekoAntiNu zu GenAntiNu/D");
    outTree->Branch("BestNu_Angle", &BestNu_Angle, "Winkel BestNu zu GenNu/D");
    outTree->Branch("BestAntiNu_Angle", &BestAntiNu_Angle, "Winkel BestAntiNu zu GenAntiNu/D");


    histogram__gen_Correlation->Sumw2();
    histogram__Correlation->Sumw2();
    histogram__gen_A->Sumw2();
    histogram__A->Sumw2();
    histogram__gen_N->Sumw2();
    histogram__N->Sumw2();


    double PatJetsPx[50];
    double PatJetsPy[50];
    double PatJetsPz[50];
    double PatJetsE[50];
    double PatJetsEt[50];

    double PatLeptonsPx[20];
    double PatLeptonsPy[20];
    double PatLeptonsPz[20];
    double PatLeptonsPt[20];
    double PatLeptonsE[20];
    int PatLeptonsCharge[20];
    int PatLeptonsPdgId[20];
    double PatLeptonsTrkIso[20];
    double PatLeptonsCaloIso[20];

    double PatJetsBTag_TrkCount[50];
    double PatJetsBTag_SVsimple[50];
    double PatJetsBTag_SVcomb[50];
    double PatJetsCharge[50];
    double PatJetsBQuarkDeltaR[50];
    double PatJetsBbarQuarkDeltaR[50];
    
    int numberOfPatMuons;
    int numberOfPatElectrons;
    int numberOfPatLeptons;
    int numberOfPatJets;

    int numberOfLeptons;



    TLorentzVector *pTop;           //FROM TREE
    TLorentzVector *pAntiTop;       //FROM TREE
    TLorentzVector *pLeptonPlus;    //FROM TREE
    TLorentzVector *pLeptonMinus;   //FROM TREE
    TLorentzVector *pBQuark;        //FROM TREE
    TLorentzVector *pBbarQuark;     //FROM TREE
    TLorentzVector* pGenNu;         //FROM TREE
    TLorentzVector* pGenAntiNu;     //FROM TREE

    TLorentzVector *pTTbar;
    TLorentzVector *pTopBoosted;
    TLorentzVector *pAntiTopBoosted;
    TLorentzVector *pLeptonPlusBoosted;
    TLorentzVector *pLeptonMinusBoosted;

    TLorentzVector *pJet[50];

    TLorentzVector *pBJet1;
    TLorentzVector *pBJet2;
    TLorentzVector *pRekoNu1;
    TLorentzVector *pRekoAntiNu1;
    TLorentzVector *pRekoNu2;
    TLorentzVector *pRekoAntiNu2;

    TLorentzVector *pRekoLeptonPlus;
    TLorentzVector *pRekoLeptonMinus;
    TLorentzVector *pBJet;
    TLorentzVector *pBbarJet;
    TLorentzVector *pRekoNu;
    TLorentzVector *pRekoAntiNu;

    TLorentzVector *pBestNu;
    TLorentzVector *pBestAntiNu;
    TLorentzVector *pBestNu2;
    TLorentzVector *pBestAntiNu2;

    TLorentzVector *pRekoTop;
    TLorentzVector *pRekoAntiTop;

    TLorentzVector *pRekoTTbar;
    TLorentzVector *pRekoTopBoosted;
    TLorentzVector *pRekoAntiTopBoosted;
    TLorentzVector *pRekoLeptonPlusBoosted;
    TLorentzVector *pRekoLeptonMinusBoosted;

    TLorentzVector *pNu;
    TLorentzVector *pAntiNu;

    TLorentzVector *pBBoosted;
    TLorentzVector *pBbarBoosted;

    pTop = new TLorentzVector(0,0,0,0);
    pAntiTop = new TLorentzVector(0,0,0,0);
    pLeptonPlus = new TLorentzVector(0,0,0,0);
    pLeptonMinus = new TLorentzVector(0,0,0,0);
    pBQuark = new TLorentzVector(0,0,0,0);
    pBbarQuark = new TLorentzVector(0,0,0,0);
    pGenNu = new TLorentzVector(0,0,0,0);
    pGenAntiNu = new TLorentzVector(0,0,0,0);

    pTTbar = new TLorentzVector(0,0,0,0);
    pTopBoosted = new TLorentzVector(0,0,0,0);
    pAntiTopBoosted = new TLorentzVector(0,0,0,0);
    pLeptonPlusBoosted = new TLorentzVector(0,0,0,0);
    pLeptonMinusBoosted = new TLorentzVector(0,0,0,0);

    pRekoTop = new TLorentzVector(0,0,0,0);
    pRekoAntiTop = new TLorentzVector(0,0,0,0);
    pRekoLeptonPlus = new TLorentzVector(0,0,0,0);
    pRekoLeptonMinus = new TLorentzVector(0,0,0,0);
    pRekoNu = new TLorentzVector(0,0,0,0);
    pRekoAntiNu = new TLorentzVector(0,0,0,0);

    pBestNu = new TLorentzVector(0,0,0,0);
    pBestAntiNu = new TLorentzVector(0,0,0,0);
    pBestNu2 = new TLorentzVector(0,0,0,0);
    pBestAntiNu2 = new TLorentzVector(0,0,0,0);

    pRekoTTbar = new TLorentzVector(0,0,0,0);
    pRekoTopBoosted = new TLorentzVector(0,0,0,0);
    pRekoAntiTopBoosted = new TLorentzVector(0,0,0,0);
    pRekoLeptonPlusBoosted = new TLorentzVector(0,0,0,0);
    pRekoLeptonMinusBoosted = new TLorentzVector(0,0,0,0);    

    pNu = new TLorentzVector(0,0,0,0);
    pAntiNu = new TLorentzVector(0,0,0,0);
    pBJet1 = new TLorentzVector(0,0,0,0);
    pBJet2 = new TLorentzVector(0,0,0,0);
    pRekoNu1 = new TLorentzVector(0,0,0,0);
    pRekoAntiNu1 = new TLorentzVector(0,0,0,0);
    pRekoNu2 = new TLorentzVector(0,0,0,0);
    pRekoAntiNu2 = new TLorentzVector(0,0,0,0);
    pBJet = new TLorentzVector(0,0,0,0);
    pBbarJet = new TLorentzVector(0,0,0,0);

    pBBoosted = new TLorentzVector(0,0,0,0);
    pBbarBoosted = new TLorentzVector(0,0,0,0);

    for(int i=0; i<50;i++) pJet[i] = new TLorentzVector(0,0,0,0);

    double mass_a = 170.0;
    double mass_b = 175.0;
    calc Poly(mass_a, mass_b, outputFile);
    

    tree->SetBranchAddress("pTop",                &pTop);
    tree->SetBranchAddress("pAntiTop",            &pAntiTop);
    tree->SetBranchAddress("pLeptonPlus",         &pLeptonPlus);
    tree->SetBranchAddress("pLeptonMinus",        &pLeptonMinus);
    tree->SetBranchAddress("pBQuark",             &pBQuark);
    tree->SetBranchAddress("pBbarQuark",          &pBbarQuark);

    tree->SetBranchAddress("PatLeptonsPx",           PatLeptonsPx);
    tree->SetBranchAddress("PatLeptonsPy",           PatLeptonsPy);
    tree->SetBranchAddress("PatLeptonsPz",           PatLeptonsPz);
    tree->SetBranchAddress("PatLeptonsPt",           PatLeptonsPt);
    tree->SetBranchAddress("PatLeptonsE",            PatLeptonsE);
    tree->SetBranchAddress("PatLeptonsCharge",       PatLeptonsCharge);
    tree->SetBranchAddress("PatLeptonsPdgId",        PatLeptonsPdgId);
    tree->SetBranchAddress("PatLeptonsTrkIso",       PatLeptonsTrkIso);
    tree->SetBranchAddress("PatLeptonsCaloIso",      PatLeptonsCaloIso);

    tree->SetBranchAddress("PatJetsPx",           PatJetsPx);
    tree->SetBranchAddress("PatJetsPy",           PatJetsPy);
    tree->SetBranchAddress("PatJetsPz",           PatJetsPz);
    tree->SetBranchAddress("PatJetsE",            PatJetsE);
    tree->SetBranchAddress("PatJetsEt",           PatJetsEt);
    
    tree->SetBranchAddress("PatJetsCharge", 	        PatJetsCharge);
    tree->SetBranchAddress("PatJetsBTag_TrkCount",	 	PatJetsBTag_TrkCount);
    tree->SetBranchAddress("PatJetsBTag_SVsimple",	 	PatJetsBTag_SVsimple);
    tree->SetBranchAddress("PatJetsBTag_SVcomb",	 	PatJetsBTag_SVcomb);
    tree->SetBranchAddress("PatJetsBQuarkDeltaR",     PatJetsBQuarkDeltaR);
    tree->SetBranchAddress("PatJetsBbarQuarkDeltaR",  PatJetsBbarQuarkDeltaR);
   
    tree->SetBranchAddress("numberOfPatMuons",	        &numberOfPatMuons);
    tree->SetBranchAddress("numberOfPatElectrons",	&numberOfPatElectrons);
    tree->SetBranchAddress("numberOfPatLeptons",	&numberOfPatLeptons);
    tree->SetBranchAddress("numberOfPatJets",	        &numberOfPatJets);

    tree->SetBranchAddress("numberOfLeptons",	&numberOfLeptons);

    tree->SetBranchAddress("pGenNu",          &pGenNu);
    tree->SetBranchAddress("pGenAntiNu",      &pGenAntiNu);
 
    int nEvents = (int)tree->GetEntries();
    //nEvents = 5000;
    int EventCounter = 0;
    cout << "Anzahl Ereignisse: " << nEvents << endl;
    for(int iEvent=1; iEvent<nEvents;iEvent++){

        tree->GetEntry(iEvent);

        EventCounter++;

  
        if(iEvent%10000 == 1)
        {
            cout << "Event " << iEvent << endl;
        }
        
        EventIsGood = 0;
        
// GENERATOR THETA

        w_A = 0;
        w_N = 0;
        
        *pTTbar=(*pTop+*pAntiTop);
        *pTopBoosted = *pTop;
        *pAntiTopBoosted = *pAntiTop;
        *pLeptonPlusBoosted = *pLeptonPlus;
        *pLeptonMinusBoosted = *pLeptonMinus;
        *pBBoosted = *pBQuark;
        *pBbarBoosted = *pBbarQuark;

        pAntiTopBoosted->Boost(-pTTbar->BoostVector());
        pTopBoosted->Boost(-pTTbar->BoostVector());
        pLeptonPlusBoosted->Boost(-pTop->BoostVector());
        pLeptonMinusBoosted->Boost(-pAntiTop->BoostVector());
        CosThetaPlus = cos(pLeptonPlusBoosted->Angle(pTopBoosted->Vect()));
        CosThetaMinus = cos(pLeptonMinusBoosted->Angle(pAntiTopBoosted->Vect()));

        pBBoosted->Boost(-pTop->BoostVector());
        pBbarBoosted->Boost(-pAntiTop->BoostVector());

        CosLeptonAngleD = cos(pLeptonPlusBoosted->Angle(pLeptonMinusBoosted->Vect()));

        double Nenner = 1 - 0.256*CosThetaPlus*CosThetaMinus;
        
        w_A = (-CosThetaPlus*CosThetaMinus)/Nenner;
        w_N = 1./Nenner;
        
        w_LL = (1-CosThetaPlus*CosThetaMinus-CosThetaPlus+CosThetaMinus)/Nenner;
        w_LR = (1+CosThetaPlus*CosThetaMinus-CosThetaPlus-CosThetaMinus)/Nenner;
        w_RR = (1-CosThetaPlus*CosThetaMinus+CosThetaPlus-CosThetaMinus)/Nenner;
        w_RL = (1+CosThetaPlus*CosThetaMinus+CosThetaPlus+CosThetaMinus)/Nenner;
        
        histogram__gen_A->Fill(CosThetaPlus, CosThetaMinus, w_A);
        histogram__gen_N->Fill(CosThetaPlus, CosThetaMinus, w_N);
        
        histogram__gen_LL->Fill(CosThetaPlus, CosThetaMinus, w_LL);
        histogram__gen_LR->Fill(CosThetaPlus, CosThetaMinus, w_LR);
        histogram__gen_RR->Fill(CosThetaPlus, CosThetaMinus, w_RR);
        histogram__gen_RL->Fill(CosThetaPlus, CosThetaMinus, w_RL);
        
        histogram__gen_Correlation->Fill(CosThetaPlus, CosThetaMinus);

        if(numberOfLeptons == 2) 
        {
            if(pLeptonMinus->Px() != 0) histogram__semilepton_BLeptonMinus->Fill( cos(pLeptonMinusBoosted->Angle(pBBoosted->Vect())) );
            if(pLeptonPlus->Px() != 0) histogram__semilepton_BLeptonPlus->Fill( cos(pLeptonPlusBoosted->Angle(pBbarBoosted->Vect())) );
        }

        numberOfJets = numberOfPatJets;
        if(numberOfPatLeptons>=2 && numberOfPatJets >=2)
        {

            RekoNu_Px = -10000;
            RekoNu_Py= -10000;
            RekoNu_Pz= -10000;
        
            RekoAntiNu_Px= -10000;
            RekoAntiNu_Py= -10000;
            RekoAntiNu_Pz= -10000;

            RekoTop_M = -10;
            RekoAntiTop_M = -10;
            RekoTop_Pt = -10;
            RekoAntiTop_Pt = -10;


            
            // REKO THETA 

            pBJet1->SetPxPyPzE(0.,0.,0.,0.);
            pBJet2->SetPxPyPzE(0.,0.,0.,0.);
            pRekoLeptonPlus->SetPxPyPzE(0.,0.,0.,0.);
            pRekoLeptonMinus->SetPxPyPzE(0.,0.,0.,0.);
            pBJet->SetPxPyPzE(0.,0.,0.,0.);
            pBbarJet->SetPxPyPzE(0.,0.,0.,0.);
            pRekoNu->SetPxPyPzE(0.,0.,0.,-10000.);
            pRekoAntiNu->SetPxPyPzE(0.,0.,0.,-10000.);

            pBestNu->SetPxPyPzE(0.,0.,0.,-10000.);
            pBestAntiNu->SetPxPyPzE(0.,0.,0.,-10000.);
            pRekoNu1->SetPxPyPzE(0.,0.,0.,-10000.);
            pRekoAntiNu1->SetPxPyPzE(0.,0.,0.,-10000.);
            pRekoNu2->SetPxPyPzE(0.,0.,0.,-10000.);
            pRekoAntiNu2->SetPxPyPzE(0.,0.,0.,-10000.);

            int LeptonIndex[20];
            int BTagTrkCountIndex[50];
            int BTagSVsimpleIndex[50];
            int BTagSVcombIndex[50];
            int BJetsEIndex[50];
            int BJetDeltaRIndex[50];
            int BbarJetDeltaRIndex[50];
            TMath::Sort(20,PatLeptonsE,LeptonIndex);
            TMath::Sort(50,PatJetsBTag_TrkCount, BTagTrkCountIndex);
            TMath::Sort(50,PatJetsBTag_SVsimple, BTagSVsimpleIndex);
            TMath::Sort(50,PatJetsBTag_SVcomb, BTagSVcombIndex);
            TMath::Sort(50, PatJetsE, BJetsEIndex);
            TMath::Sort(50, PatJetsBQuarkDeltaR, BJetDeltaRIndex);
            TMath::Sort(50, PatJetsBbarQuarkDeltaR, BbarJetDeltaRIndex);


            // Leptonen auswaehlen
            int OtherLepton = -1;
            for(int j=0; PatLeptonsCharge[LeptonIndex[0]]==PatLeptonsCharge[LeptonIndex[j]] && j<20; j++){
                OtherLepton=j+1;
            }
//            if(PatLeptonsCharge[LeptonIndex[OtherLepton]]==0) std::cout<<"Only Leptons of same Charge in Event " << iEvent << "!!"<<std::endl;

            if(PatLeptonsCharge[LeptonIndex[OtherLepton]]!=0){
                // Leptonen zuordnen
                if(PatLeptonsCharge[LeptonIndex[0]]==-1){	
                    pRekoLeptonMinus->SetPxPyPzE(PatLeptonsPx[LeptonIndex[0]], PatLeptonsPy[LeptonIndex[0]], PatLeptonsPz[LeptonIndex[0]], PatLeptonsE[LeptonIndex[0]] );
                }

                if(PatLeptonsCharge[LeptonIndex[0]]==+1){	
                    pRekoLeptonPlus->SetPxPyPzE(PatLeptonsPx[LeptonIndex[0]], PatLeptonsPy[LeptonIndex[0]], PatLeptonsPz[LeptonIndex[0]], PatLeptonsE[LeptonIndex[0]] );
                }
            
                if(PatLeptonsCharge[LeptonIndex[OtherLepton]]==-1){	
                    pRekoLeptonMinus->SetPxPyPzE(PatLeptonsPx[LeptonIndex[OtherLepton]], PatLeptonsPy[LeptonIndex[OtherLepton]], PatLeptonsPz[LeptonIndex[OtherLepton]],PatLeptonsE[LeptonIndex[OtherLepton]] );
                }
           
                if(PatLeptonsCharge[LeptonIndex[OtherLepton]]==+1){	
                    pRekoLeptonPlus->SetPxPyPzE(PatLeptonsPx[LeptonIndex[OtherLepton]], PatLeptonsPy[LeptonIndex[OtherLepton]], PatLeptonsPz[LeptonIndex[OtherLepton]], PatLeptonsE[LeptonIndex[OtherLepton]] );
                }

                //cout << "Leptonen ausgewaehlt" << endl;

                Lepton_Mass = ((*pRekoLeptonPlus) + (*pRekoLeptonMinus)).M();

                if( TMath::Abs( Lepton_Mass - 90.0 ) > 10 || PatLeptonsPdgId[LeptonIndex[0]] + PatLeptonsPdgId[LeptonIndex[OtherLepton]] !=0 )
                {

                    double JetDisc[50];
                    numberOfGoodJets = 0;
                    for(int j=0; j<50; j++){
                        JetDisc[j] = 0.;
                        if(j<numberOfPatJets){
                            //JetDisc[j] = PatJetsBTag_TrkCount[j] * PatJetsEt[j];
                            if(PatJetsBTag_TrkCount[j]>1. && PatJetsEt[j]>20){
                                pJet[j]->SetPxPyPzE(PatJetsPx[j],PatJetsPy[j],  PatJetsPz[j], PatJetsE[j]);
                                if(TMath::Min(pJet[j]->Angle(pRekoLeptonPlus->Vect()), pJet[j]->Angle(pRekoLeptonMinus->Vect())) >0.1){
                                    numberOfGoodJets++;
                                    JetDisc[j] = PatJetsBTag_TrkCount[j] * PatJetsEt[j];
                                }
                            }
                            if(j<numberOfPatLeptons){
                                histogram__LeptonRelIso->Fill(PatLeptonsPt[j]/(PatLeptonsPt[j]+PatLeptonsTrkIso[j]+PatLeptonsCaloIso[j]));
                            }
                        }
                    }
                    int JetDiscIndex[50];
                    TMath::Sort(50, JetDisc, JetDiscIndex);
                        
                    // Jets auswaehlen
                    // verbesserte Auswahl (BTag*ET)
                    pBJet1->SetPxPyPzE(PatJetsPx[JetDiscIndex[0]],PatJetsPy[JetDiscIndex[0]],PatJetsPz[JetDiscIndex[0]],PatJetsE[JetDiscIndex[0]]);
                    pBJet2->SetPxPyPzE(PatJetsPx[JetDiscIndex[1]],PatJetsPy[JetDiscIndex[1]],PatJetsPz[JetDiscIndex[1]],PatJetsE[JetDiscIndex[1]]);

                    //pBJet1->SetPxPyPzE(PatJetsPx[BTagTrkCountIndex[0]],PatJetsPy[BTagTrkCountIndex[0]],PatJetsPz[BTagTrkCountIndex[0]],PatJetsE[BTagTrkCountIndex[0]]);
                    //pBJet2->SetPxPyPzE(PatJetsPx[BTagTrkCountIndex[1]],PatJetsPy[BTagTrkCountIndex[1]],PatJetsPz[BTagTrkCountIndex[1]],PatJetsE[BTagTrkCountIndex[1]]);
                    
                    
                    //cout << "Jets gewaehlt" << endl;
                    
                    
                    // Neutrinos berechnen 
                    
                    //Generator-Werte setzen fuer Vergleich mit Berechnung
                    pNu->SetPxPyPzE(pGenNu->Px(),pGenNu->Py(),pGenNu->Pz(),pGenNu->E());
                    pAntiNu->SetPxPyPzE(pGenAntiNu->Px(),pGenAntiNu->Py(),pGenAntiNu->Pz(),pGenAntiNu->E());
                    
                    
                    
                    Poly.Init(pRekoLeptonPlus, pRekoLeptonMinus, pBJet1, pBJet2, pNu, pAntiNu); // BJet1 = b, BJet2 = bbar
                    Poly.Solve(170.0,171.0 , iEvent, pRekoNu1, pRekoAntiNu1, pBestNu, pBestAntiNu);
                    
                    Poly.Init(pRekoLeptonPlus, pRekoLeptonMinus, pBJet2, pBJet1, pNu, pAntiNu); // BJet1 = bbar, BJet2 = b
                    Poly.Solve(170.0,171.0 , iEvent, pRekoNu2, pRekoAntiNu2, pBestNu2, pBestAntiNu2);
                    
                    //cout << "Neutrinos berechnet" << endl;
                    
                    
// Abfrage, ob Neutrinoloesung ungleich -10000 !!!
                    if(pRekoAntiNu1->Pz() != -10000 && pRekoAntiNu2->Pz() != -10000){
                        
                        if(TMath::Abs( ((*pRekoLeptonPlus)+(*pRekoNu1)+(*pBJet1)).M() + ((*pRekoLeptonMinus)+(*pRekoAntiNu1)+(*pBJet2)).M() - 2*173.2) < TMath::Abs(((*pRekoLeptonPlus)+(*pRekoNu2)+(*pBJet2)).M() + ((*pRekoLeptonMinus)+(*pRekoAntiNu2)+(*pBJet1)).M() - 2*173.2) ){
                            *pBJet = *pBJet1;
                            *pBbarJet = *pBJet2;
                            *pRekoNu = *pRekoNu1;
                            *pRekoAntiNu = *pRekoAntiNu1;
                        }
                        else {
                            *pBJet = *pBJet2;
                            *pBbarJet = *pBJet1;
                            *pRekoNu = *pRekoNu2;
                            *pRekoAntiNu = *pRekoAntiNu2;
                            *pBestNu = *pBestNu2;
                            *pBestAntiNu = *pBestAntiNu2;
                        }
                    }
                    else if(pRekoAntiNu1->Pz() != -10000){
                        *pBJet = *pBJet1;
                        *pBbarJet = *pBJet2;
                        *pRekoNu = *pRekoNu1;
                        *pRekoAntiNu = *pRekoAntiNu1;
                    }
                    else if(pRekoAntiNu2->Pz() != -10000){
                        *pBJet = *pBJet2;
                        *pBbarJet = *pBJet1;
                        *pRekoNu = *pRekoNu2;
                        *pRekoAntiNu = *pRekoAntiNu2;
                        *pBestNu = *pBestNu2;
                        *pBestAntiNu = *pBestAntiNu2;
                    }
                    else{
                        pRekoNu->SetPxPyPzE(0,0,-10000, 10000);
                        pRekoAntiNu->SetPxPyPzE(0,0,-10000, 10000);
                        pBestNu->SetPxPyPzE(0,0,-10000, 10000);
                        pBestAntiNu->SetPxPyPzE(0,0,-10000, 10000);
                        pBJet->SetPxPyPzE(0,0,-10000, 10000);
                        pBbarJet->SetPxPyPzE(0,0,-10000, 10000);
                    }
                    
                    
                    
                    TTbar_Pt = pTTbar->Pt();
                    TTbar_M = pTTbar->M();
                    
                    Top_Pt = pTop->Pt();
                    AntiTop_Pt = pAntiTop->Pt();
                    Top_M = pTop->M();
                    AntiTop_M = pAntiTop->M();
                    
                    Nu_Px = pNu->Px();
                    Nu_Py = pNu->Py();
                    Nu_Pz = pNu->Pz();
                    
                    AntiNu_Px = pAntiNu->Px();
                    AntiNu_Py = pAntiNu->Py();
                    AntiNu_Pz = pAntiNu->Pz();
                    
                    
                    
                    Lepton_Pt = TMath::Min(pRekoLeptonPlus->Pt(), pRekoLeptonMinus->Pt());
                    BJet_Et = TMath::Min(pBJet->Et(), pBbarJet->Et());
                    BJet_Tag_SVsimple = PatJetsBTag_SVsimple[BTagSVsimpleIndex[1]];
                    BJet_Tag_SVcomb = PatJetsBTag_SVcomb[BTagSVcombIndex[1]];
                    BJet_Tag_TrkCount = PatJetsBTag_TrkCount[BTagTrkCountIndex[1]];
                    BJet_Disc = JetDisc[JetDiscIndex[1]];
                    Lepton1_Id = PatLeptonsPdgId[LeptonIndex[0]];
                    Lepton2_Id = PatLeptonsPdgId[LeptonIndex[OtherLepton]];
                    
                    LeptonPlus_Angle = -10.;
                    LeptonMinus_Angle = -10.;
                    BJet_Angle = -10.;
                    BbarJet_Angle = -10.;
                    RekoNu_Angle = -10.;
                    RekoAntiNu_Angle = -10.;
                    BestNu_Angle = -10.;
                    BestAntiNu_Angle = -10.;
                    
                    //cout << "Werte gesetzt" << endl;
                    
                    if(pRekoAntiNu->Pz() > -10000){

                        histogram_nupx_gen_reco->Fill(pGenNu->Px(), pRekoNu->Px());
                        histogram_nubpx_gen_reco->Fill(pGenAntiNu->Px(), pRekoAntiNu->Px());
                        histogram_nupy_gen_reco->Fill(pGenNu->Py(), pRekoNu->Py());
                        histogram_nubpy_gen_reco->Fill(pGenAntiNu->Py(), pRekoAntiNu->Py());
                        histogram_nupz_gen_reco->Fill(pGenNu->Pz(), pRekoNu->Pz());
                        histogram_nubpz_gen_reco->Fill(pGenAntiNu->Pz(), pRekoAntiNu->Pz());
                        
                        if(pLeptonPlus->E() != 0 && pLeptonMinus->E() != 0 && pBQuark->E() != 0 ){
                            BJet_Angle = pBJet->DeltaR(*pBQuark);
                            BbarJet_Angle = pBbarJet->DeltaR(*pBbarQuark);
                            LeptonPlus_Angle = pRekoLeptonPlus->DeltaR(*pLeptonPlus);
                            LeptonMinus_Angle = pRekoLeptonMinus->DeltaR(*pLeptonMinus);
                            RekoNu_Angle = pRekoNu->DeltaR(*pNu);
                            RekoAntiNu_Angle = pRekoAntiNu->DeltaR(*pAntiNu);
                            BestNu_Angle = pBestNu->DeltaR(*pNu);
                            BestAntiNu_Angle = pBestAntiNu->DeltaR(*pAntiNu);
                        }

                        RekoNu_Px = pRekoNu->Px();
                        RekoNu_Py = pRekoNu->Py();
                        RekoNu_Pz = pRekoNu->Pz();
                        
                        RekoAntiNu_Px = pRekoAntiNu->Px();
                        RekoAntiNu_Py = pRekoAntiNu->Py();
                        RekoAntiNu_Pz = pRekoAntiNu->Pz();
                        
                        BestNu_Px = pBestNu->Px();
                        BestNu_Py = pBestNu->Py();
                        BestNu_Pz = pBestNu->Pz();
                        
                        BestAntiNu_Px = pBestAntiNu->Px();
                        BestAntiNu_Py = pBestAntiNu->Py();
                        BestAntiNu_Pz = pBestAntiNu->Pz(); 
                        
                        if(pRekoLeptonPlus->E()!=0 && pRekoLeptonMinus->E()!=0 && pBJet->E()!=0 && pBbarJet->E()!=0){ 
                            
                            EventIsGood = 1;
                            
                            *pRekoTop = (*pRekoLeptonPlus) + (*pBJet) + (*pRekoNu);
                            *pRekoAntiTop = (*pRekoLeptonMinus) + (*pBbarJet) + (*pRekoAntiNu);
                            *pRekoTTbar = (*pRekoTop) + (*pRekoAntiTop);
                            *pRekoTopBoosted = *pRekoTop;
                            *pRekoAntiTopBoosted = *pRekoAntiTop;
                            *pRekoLeptonPlusBoosted = *pRekoLeptonPlus;
                            *pRekoLeptonMinusBoosted = *pRekoLeptonMinus;
                            pRekoAntiTopBoosted->Boost(-pRekoTTbar->BoostVector());
                            pRekoTopBoosted->Boost(-pRekoTTbar->BoostVector());
                            pRekoLeptonPlusBoosted->Boost(-pRekoTop->BoostVector());
                            pRekoLeptonMinusBoosted->Boost(-pRekoAntiTop->BoostVector());
                            
                            RekoCosThetaPlus = cos(pRekoLeptonPlusBoosted->Angle(pRekoTopBoosted->Vect()));
                            RekoCosThetaMinus = cos(pRekoLeptonMinusBoosted->Angle(pRekoAntiTopBoosted->Vect()));
                            //cout << "Cos(Theta) Gen-Reko: " << CosThetaPlus - RekoCosThetaPlus << endl;
                            
                            CosThetaDiff = RekoCosThetaPlus - CosThetaPlus;

                            CosRekoLeptonAngleD = cos(pRekoLeptonPlusBoosted->Angle(pRekoLeptonMinusBoosted->Vect()));
                            
                            RekoTTbar_Pt = pRekoTTbar->Pt();
                            RekoTTbar_M = pRekoTTbar->M();
                            
                            RekoTop_Pt = pRekoTop->Pt();
                            RekoAntiTop_Pt = pRekoAntiTop->Pt();
                            
                            RekoTop_M = pRekoTop->M();
                            RekoAntiTop_M = pRekoAntiTop->M();
                            
                            
                            
                            histogram__A->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_A);
                            histogram__N->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_N);
                            
                            histogram__Correlation->Fill(RekoCosThetaPlus, RekoCosThetaMinus);
                            
                            histogram__CosThetaDiff->Fill( CosThetaPlus - RekoCosThetaPlus );
                            histogram__CosThetaDiff->Fill( CosThetaMinus - RekoCosThetaMinus );
                            histogram__CosTheta_GenReko->Fill(CosThetaPlus, RekoCosThetaPlus);
                            
                            histogram__CosThetaDiff_TTbarPt->Fill(pTTbar->Pt(), CosThetaPlus - RekoCosThetaPlus);

                            if(BJet_Tag_TrkCount > 1.0){
                                histogram__Correlation_T1->Fill(RekoCosThetaPlus, RekoCosThetaMinus);
                                histogram__A_T1->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_A);
                                histogram__N_T1->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_N);
                            }


                            if(pRekoLeptonPlus->Pt()>15 && pRekoLeptonMinus->Pt()>15 && pBJet->Et()>50 && pBbarJet->Et()>50 && PatJetsBTag_TrkCount[BTagTrkCountIndex[1]]>1 ){
                                histogram__Correlation_L15_B50_T1->Fill(RekoCosThetaPlus, RekoCosThetaMinus);
                                histogram__A_L15_B50_T1->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_A);
                                histogram__N_L15_B50_T1->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_N);

                            }
                            if(pRekoLeptonPlus->Pt()>20 && pRekoLeptonMinus->Pt()>20){
                                    
                                histogram__Correlation_L20->Fill(RekoCosThetaPlus, RekoCosThetaMinus);
                                histogram__A_L20->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_A);
                                histogram__N_L20->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_N);

                                if(pBJet->Et() > 30 && pBbarJet->Et() > 30 && PatJetsBTag_TrkCount[BTagTrkCountIndex[1]] > 1){
                                    histogram__Correlation_L20_B30_T1->Fill(RekoCosThetaPlus, RekoCosThetaMinus);
                                    histogram__A_L20_B30_T1->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_A);
                                    histogram__N_L20_B30_T1->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_N);
                                }
                                    
                                if(pBJet->Et() > 40 && pBbarJet->Et() > 40){
                                    histogram__Correlation_L20_B40->Fill(RekoCosThetaPlus, RekoCosThetaMinus);
                                    histogram__A_L20_B40->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_A);
                                    histogram__N_L20_B40->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_N);
                                        
                                    if(PatJetsBTag_TrkCount[BTagTrkCountIndex[1]] > 1 ){
                                        histogram__Correlation_L20_B40_T1->Fill(RekoCosThetaPlus, RekoCosThetaMinus);
                                        histogram__A_L20_B40_T1->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_A);
                                        histogram__N_L20_B40_T1->Fill(RekoCosThetaPlus, RekoCosThetaMinus, w_N);
                                    }
                                }
                            }
                        } // Leptonen und B != 0
                    } // Neutrino-Pz != -10000
                } // inv. Masse der Leptonen != Z-Masse+-10
            }// abfrage auf 2 Leptonen unterschiedlicher Ladung
            //cout << "Tree wird gefuellt: ";
  
            //cout << " und ist fertig" << endl;
            
        }
        outTree->Fill(); 
    } // EventLoop

    cout << "gezaehlte Ereignisse: " << EventCounter << endl;
    cout << "Rekonstruierte Ereignisse: " << histogram__Correlation->Integral() << endl;
    

    outputFile->cd("");
    outputFile->Write();
    outputFile->Close();
    delete outputFile;
}
Beispiel #17
0
int main(int argc, char* argv[])
{
  TApplication theApp(srcName.Data(), &argc, argv);
//=============================================================================

  if (argc<5) return -1;
  TString sPath = argv[1]; if (sPath.IsNull()) return -1;
  TString sFile = argv[2]; if (sFile.IsNull()) return -1;
  TString sJetR = argv[3]; if (sJetR.IsNull()) return -1;
  TString sSjeR = argv[4]; if (sSjeR.IsNull()) return -1;
//=============================================================================

  sPath.ReplaceAll("#", "/");
//=============================================================================

  double dJetR = -1.;
  if (sJetR=="JetR02") dJetR = 0.2;
  if (sJetR=="JetR03") dJetR = 0.3;
  if (sJetR=="JetR04") dJetR = 0.4;
  if (sJetR=="JetR05") dJetR = 0.5;

  if (dJetR<0.) return -1;
  cout << "Jet R = " << dJetR << endl;
//=============================================================================

  double dSjeR = -1.;
  if (sSjeR=="SjeR01") dSjeR = 0.1;
  if (sSjeR=="SjeR02") dSjeR = 0.2;
  if (sSjeR=="SjeR03") dSjeR = 0.3;
  if (sSjeR=="SjeR04") dSjeR = 0.4;

  if (dSjeR<0.) return -1;
  cout << "Sub-jet R = " << dSjeR << endl;
//=============================================================================

  const double dJetsPtMin  = 0.001;
  const double dCutEtaMax  = 1.6;
  const double dJetEtaMax  = 1.;
  const double dJetAreaRef = TMath::Pi() * dJetR * dJetR;

  fastjet::GhostedAreaSpec areaSpc(dCutEtaMax);
  fastjet::JetDefinition   jetsDef(fastjet::antikt_algorithm, dJetR, fastjet::E_scheme, fastjet::Best);

//fastjet::AreaDefinition  areaDef(fastjet::active_area,areaSpc);
  fastjet::AreaDefinition  areaDef(fastjet::active_area_explicit_ghosts,areaSpc);

//fastjet::JetDefinition   bkgsDef(fastjet::kt_algorithm, 0.2, fastjet::BIpt_scheme, fastjet::Best);
//fastjet::AreaDefinition  aBkgDef(fastjet::active_area_explicit_ghosts, areaSpc);

  fastjet::Selector selectJet = fastjet::SelectorAbsEtaMax(dJetEtaMax);
//fastjet::Selector selectRho = fastjet::SelectorAbsEtaMax(dCutEtaMax-0.2);
//fastjet::Selector selecHard = fastjet::SelectorNHardest(2);
//fastjet::Selector selectBkg = selectRho * (!(selecHard));
//fastjet::JetMedianBackgroundEstimator bkgsEstimator(selectBkg, bkgsDef, aBkgDef);
//fastjet::Subtractor                   bkgSubtractor(&bkgsEstimator);

  fastjet::JetDefinition subjDef(fastjet::kt_algorithm, dSjeR, fastjet::E_scheme, fastjet::Best);
//=============================================================================

  std::vector<fastjet::PseudoJet> fjInput;
  const double dMass = TDatabasePDG::Instance()->GetParticle(211)->Mass();
//=============================================================================

  TList *list = new TList();
  TH1D *hJet = new TH1D("hJet", "", 1000, 0., 1000.); hJet->Sumw2(); list->Add(hJet);

  enum                    {  kJet,   kMje,   kDsz,   kIsm,   kZsm,   kDsr, kVar };
  const TString sHist[] = { "aJet", "aMje", "aDsz", "aIsm", "aZsm", "aDsr" };
  const Int_t      nv[] = {   1000,    150,  120,      150,    150,    500 };
  const Double_t dMin[] = {     0.,     0.,   0.,       0.,     0.,     0. };
  const Double_t dMax[] = {  1000.,   150.,  1.2,     150.,    1.5,     5. };

  THnSparseD *hs = new THnSparseD("hs", "", kVar, nv, dMin, dMax); hs->Sumw2();
  for (Int_t i=0; i<kVar; i++) hs->GetAxis(i)->SetName(sHist[i].Data()); list->Add(hs);
//=============================================================================

  HepMC::IO_GenEvent ascii_in(Form("%s/%s.hepmc",sPath.Data(),sFile.Data()), std::ios::in);
  HepMC::GenEvent *evt = ascii_in.read_next_event();

  while (evt) {
    fjInput.resize(0);

    TLorentzVector vPar;
    for (HepMC::GenEvent::particle_const_iterator p=evt->particles_begin(); p!=evt->particles_end(); ++p) if ((*p)->status()==1) {
      vPar.SetPtEtaPhiM((*p)->momentum().perp(), (*p)->momentum().eta(), (*p)->momentum().phi(), dMass);

      if ((TMath::Abs(vPar.Eta())<dCutEtaMax)) {
        fjInput.push_back(fastjet::PseudoJet(vPar.Px(), vPar.Py(), vPar.Pz(), vPar.E()));
      }
    }
//=============================================================================

    fastjet::ClusterSequenceArea clustSeq(fjInput, jetsDef, areaDef);
    std::vector<fastjet::PseudoJet> includJets = clustSeq.inclusive_jets(dJetsPtMin);
//  std::vector<fastjet::PseudoJet> subtedJets = bkgSubtractor(includJets);
    std::vector<fastjet::PseudoJet> selectJets = selectJet(includJets);
//  std::vector<fastjet::PseudoJet> sortedJets = fastjet::sorted_by_pt(selectJets);

    for (int j=0; j<selectJets.size(); j++) {
      double dJet = selectJets[j].pt();

      hJet->Fill(dJet);
//=============================================================================

      fastjet::Filter trimmer(subjDef, fastjet::SelectorPtFractionMin(0.));
      fastjet::PseudoJet trimmdJet = trimmer(selectJets[j]);
      std::vector<fastjet::PseudoJet> trimmdSj = trimmdJet.pieces();

      double d1sj = -1.; int k1sj = -1;
      double d2sj = -1.; int k2sj = -1;
      for (int i=0; i<trimmdSj.size(); i++) {
        double dIsj = trimmdSj[i].pt(); if (dIsj<0.001) continue;

        if (dIsj>d1sj) {
          d2sj = d1sj; k2sj = k1sj;
          d1sj = dIsj; k1sj = i;
        } else if (dIsj>d2sj) {
          d2sj = dIsj; k2sj = i;
        }
      }

      if ((d1sj>0.) && (d2sj>0.)) {
        TLorentzVector v1sj; v1sj.SetPtEtaPhiM(d1sj, trimmdSj[k1sj].eta(), trimmdSj[k1sj].phi(), trimmdSj[k1sj].m());
        TLorentzVector v2sj; v2sj.SetPtEtaPhiM(d2sj, trimmdSj[k2sj].eta(), trimmdSj[k2sj].phi(), trimmdSj[k2sj].m());
        TLorentzVector vIsj = v1sj + v2sj;

        Double_t dIsm = vIsj.M();
        Double_t dMje = selectJets[j].m();
        Double_t dVar[] = { dJet, dMje, (d1sj-d2sj)/dJet, dIsm, dIsm/dMje, v1sj.DeltaR(v2sj)/2./dJetR };

        hs->Fill(dVar);
      }
    }
//=============================================================================

    delete evt;
    ascii_in >> evt;
  }
//=============================================================================

  TString sXsec = sFile; sXsec.ReplaceAll("out", "xsecs");
  TFile *file = TFile::Open(Form("%s/xsecs/%s.root",sPath.Data(),sXsec.Data()), "READ");
  TH1D *hPtHat        = (TH1D*)file->Get("hPtHat");        hPtHat->SetDirectory(0);
  TH1D *hWeightSum    = (TH1D*)file->Get("hWeightSum");    hWeightSum->SetDirectory(0);
  TProfile *hSigmaGen = (TProfile*)file->Get("hSigmaGen"); hSigmaGen->SetDirectory(0);
  file->Close();
//=============================================================================

  file = TFile::Open(Form("%s.root",sFile.Data()), "NEW");
  hPtHat->Write();
  hWeightSum->Write();
  hSigmaGen->Write();
  list->Write();
  file->Close();
//=============================================================================

  cout << "DONE" << endl;
  return 0;
}
Beispiel #18
0
Bool_t monojet::Process(Long64_t entry)
{
    GetEntry(entry);

    if( entry % 100000 == 0 ) cout << "Processing event number: " << entry << endl;
    //cout << "Processing event number: " << entry << endl;

    // To make the processing fast, apply a very looose selection
    if (((TLorentzVector*)((*metP4)[0]))->Pt() < 40. or jetP4->GetEntries() < 1) return kTRUE;

    //this is the type tree
    tm->SetValue("run",runNum);
    tm->SetValue("event",eventNum);
    tm->SetValue("lumi",lumiNum);

    float dR = 0.;
    TClonesArray *tightLep;
    TClonesArray *cleanJet;
    TClonesArray *cleanTau;

    tightLep = new TClonesArray("TLorentzVector",20);
    cleanJet = new TClonesArray("TLorentzVector",20);
    cleanTau = new TClonesArray("TLorentzVector",20);

    std::vector<bool>  jetMonojetId_clean;
    jetMonojetId_clean.clear();
    std::vector<bool>  jetMonojetIdLoose_clean;
    jetMonojetIdLoose_clean.clear();
    //std::vector<float> jetPuId_clean;
    //jetPuId_clean.clear();

    std::vector<float>  tauId_clean;
    tauId_clean.clear();
    std::vector<float>  tauIso_clean;
    tauIso_clean.clear();

    int n_tightlep = 0;

    // ********* Leptons ********** //
    for(int lepton = 0; lepton < lepP4->GetEntries(); lepton++) {
        TLorentzVector* Lepton = (TLorentzVector*) lepP4->At(lepton);
        // check if this is a tight lep, and check the overlap

        //iso_1 = divide(input_tree.lepIso[0],input_tree.lepP4[0].Pt())
        //if (input_tree.lepTightId[0]==0 or iso_1 > 0.12): continue

        if (Lepton->Pt() > 20. && (*lepTightId)[lepton] > 1) {
            n_tightlep +=1;
            new ( (*tightLep)[tightLep->GetEntriesFast()]) TLorentzVector(Lepton->Px(), Lepton->Py(), Lepton->Pz(), Lepton->Energy());

            //check overlap with jets
            for(int j = 0; j < jetP4->GetEntries(); j++) {
                TLorentzVector* Jet = (TLorentzVector*) jetP4->At(j);
                dR = deltaR(Lepton,Jet);
                if (dR > dR_cut) {
                    new ( (*cleanJet)[cleanJet->GetEntriesFast()]) TLorentzVector(Jet->Px(), Jet->Py(), Jet->Pz(), Jet->Energy());
                    jetMonojetId_clean.push_back((*jetMonojetId)[j]);
                    jetMonojetIdLoose_clean.push_back((*jetMonojetIdLoose)[j]);
                    //jetPuId_clean.push_back((*jetPuId)[j]);
                }
            }
            //check overlap with taus
            for(int tau = 0; tau < tauP4->GetEntries(); tau++) {
                TLorentzVector* Tau = (TLorentzVector*) tauP4->At(tau);
                dR = deltaR(Lepton,Tau);
                if (dR > dR_cut) new ( (*cleanTau)[cleanTau->GetEntriesFast()]) TLorentzVector(Tau->Px(), Tau->Py(), Tau->Pz(), Tau->Energy());
                tauId_clean.push_back((*tauId)[tau]);
                tauIso_clean.push_back((*tauIso)[tau]);
            } // tau overlap
        } // tight lepton selection
    }//lepton loop

    tm->SetValue("n_tightlep",n_tightlep);

    TLorentzVector fakeMET;

    // Z Selection
    TLorentzVector Z;
    if(lepP4->GetEntries() == 2 && n_tightlep > 0) {
        if (((*lepPdgId)[0]+(*lepPdgId)[1])==0 ) {
            Z = *((TLorentzVector*)((*lepP4)[0])) + *((TLorentzVector*)((*lepP4)[1]));
            fakeMET = *((TLorentzVector*)((*metP4)[0])) + Z;
        }
    }

    float MT = 0.0;
    //// W Selection
    if(lepP4->GetEntries() == 1 && n_tightlep == 1) {
        fakeMET = *((TLorentzVector*)((*metP4)[0])) + *((TLorentzVector*)((*lepP4)[0])) ;
        MT = transverseMass( ((TLorentzVector*)((*lepP4)[0]))->Pt(), ((TLorentzVector*)((*lepP4)[0]))->Phi(), ((TLorentzVector*)((*metP4)[0]))->Pt(), ((TLorentzVector*)((*metP4)[0]))->Phi());
    }

    tm->SetValue("mt",MT);

    // ********* Jets ********** //
    for(int jet = 0; jet < jetP4->GetEntries(); jet++) {
        TLorentzVector* Jet = (TLorentzVector*) jetP4->At(jet);
        //cout << (*jetMonojetId)[0] <<endl;
        //cout << Jet->Pt()<<endl;
    }

    // ********* Met ********** //
    // Here try to save all possible met variables
    // and the recoil vectors (for Z and Photon)

    TLorentzVector Recoil(-9999.,-9999.,-9999.,-9999);
    float uPar = -9999. ;
    float uPerp = -9999.;

    if(Z.Pt() > 0) {
        Recoil = *((TLorentzVector*)((*metP4)[0])) + Z;
        Recoil.RotateZ(TMath::Pi());
        Recoil.RotateZ(-Z.Phi());
        if (Z.Phi() > TMath::Pi())  uPar = Recoil.Px() - Z.Pt() ;
        else uPar = Recoil.Px() + Z.Pt();
        uPerp = Recoil.Py();
    }

    tm->SetValue("uperp",uPerp);
    tm->SetValue("upar",uPar);

    // Decide on the type of the event and fill the
    // type tree

    int type_event = -1;


    // forcing all regions to be orthogonal wrt to each other
    if (((TLorentzVector*)((*metP4)[0]))->Pt() > 100. &&
            jetP4->GetEntries() > 0 && lepP4->GetEntries() == 0) type_event=0;
    if (lepP4->GetEntriesFast() == 1) type_event=1; //&& (*lepTightId)[0] == 1) type_event=1;
    if (lepP4->GetEntriesFast() == 2) type_event=2; //&& ((*lepTightId)[0] == 1 || (*lepTightId)[1] == 1 )) type_event=2;

    if (  lepP4->GetEntriesFast() == 2 && type_event!=2 ) std::cout << "WTF??" << std::endl;
    tm->SetValue("event_type",type_event);

    // Now replace all the needed collections based
    // on the type

    if (type_event ==1 || type_event==2)
    {
        jetP4 = cleanJet;
        tauP4 = cleanTau;
        *jetMonojetId = jetMonojetId_clean;
        *jetMonojetIdLoose = jetMonojetIdLoose_clean;
        //*jetPuId = jetPuId_clean;
        *tauId = tauId_clean;
        *tauIso = tauIso_clean;
        *(TLorentzVector*)((*metP4)[0]) = fakeMET;
    }

    // final skim
    if(((TLorentzVector*)((*metP4)[0]))->Pt() < 100.) return kTRUE;

    //re-write the mc weight content to be +1 or -1
    if(mcWeight < 0) mcWeight = -1.0;
    if(mcWeight > 0) mcWeight =  1.0;


    // and fill both trees;
    tm ->TreeFill();
    eventstree->Fill();

    return kTRUE;
}
Beispiel #19
0
int main(int argc, char * argv[])
{
	// load silly ROOT thing
	gROOT->ProcessLine("#include <vector>");
	gROOT->ProcessLine(".L loader.C+");

	// output
	TFile * output_file = new TFile("output_file.root", "RECREATE");

	TTree * jet_tree = new TTree("jet_tree", "jet_tree");
	float jet_pt = 0;
	float jet_eta = 0;
	float jet_phi = 0;
	float jet_m = 0;
	jet_tree->Branch("jet_pt", &jet_pt);
	jet_tree->Branch("jet_eta", &jet_eta);
	jet_tree->Branch("jet_phi", &jet_phi);
	jet_tree->Branch("jet_m", &jet_m);

	TTree * event_tree = new TTree("event_tree", "event_tree");
	int n = 0;
	int us = 0;
	event_tree->Branch("n", &n);
	event_tree->Branch("us", &us);

	// input tracks
	TChain * tree = new TChain("tree");
	tree->Add("mc15_13TeV.301523.RS_G_hh_bbbb_c20_M2000.track_ntuple.root");
	int number_of_events = tree->GetEntries();

	int track_number = 0;
	vector<float> * track_pt = 0;
	vector<float> * track_eta = 0;
	vector<float> * track_phi = 0;
	tree->SetBranchAddress("track_number", &track_number);
	tree->SetBranchAddress("track_pt", &track_pt);
	tree->SetBranchAddress("track_eta", &track_eta);
	tree->SetBranchAddress("track_phi", &track_phi);

	vector<PseudoJet> particles;

	// variables for timing
	struct timeval start;
	struct timeval end;
	struct timeval duration;
//	TH2F * h_timing = new TH2F("timing", "timing; # Tracks; #mus", 1000, 0, 1000, 100, 1, 10000);
//	TH2F * h_log_timing = new TH2F("log_timing", "log_timing; # Tracks; log_{10}(#mus)", 1000, 0, 1000, 100, log10(1), log10(10000));
//	TH2F * h_timing = new TH2F("timing", "timing; # Tracks; #mus", 1000, 0, 1000, 100, 1, 10000);
//	TH2F * h_log_timing = new TH2F("log_timing", "log_timing; # Tracks; log_{10}(#mus)", 1000, 0, 1000, 100, log10(1), log10(10000));
//	TH2F * h_timing = new TH2F("timing", "timing; # Tracks; #mus", 1000, 0, 1000, 100, 1, 10000);
//	TH2F * h_log_timing = new TH2F("log_timing", "log_timing; # Tracks; log_{10}(#mus)", 1000, 0, 1000, 100, log10(1), log10(10000));
	TH2F * h_timing = new TH2F("timing", "timing; # Tracks; #mus", 1000, 0, 1000, 100, 1, 5000);						// N2Tiled
	TH2F * h_log_timing = new TH2F("log_timing", "log_timing; # Tracks; log_{10}(#mus)", 1000, 0, 1000, 100, log10(1), log10(5000));	// N2Tiled

	for (int event = 0; event < number_of_events; event++)
	{
		// print a sexy load bar
		loadBar(event, number_of_events, 100, 50);

		tree->GetEntry(event);

		for (int track = 0; track < track_number; track++)
		{
			TLorentzVector trackLorentzVector;
			trackLorentzVector.SetPtEtaPhiM(track_pt->at(track) / 1000.0, track_eta->at(track), track_phi->at(track), 0);
			particles.push_back(PseudoJet(trackLorentzVector.Px(), trackLorentzVector.Py(), trackLorentzVector.Pz(), trackLorentzVector.E()));
		}

		// get the start time
		gettimeofday(&start, NULL);

		// not vrplugin
		double R = 0.4;
//		JetDefinition jet_def(antikt_vr, R, N3Dumb, E_scheme, 1, 60);
//		JetDefinition jet_def(antikt_vr, R, N2Plain, E_scheme, 1, 60);
		JetDefinition jet_def(antikt_vr, R, N2Tiled, E_scheme, 1, 60);
		ClusterSequence cs(particles, jet_def);
		vector<PseudoJet> jets = sorted_by_pt(cs.inclusive_jets());

		// vrplugin
//		double rho = 60;
//		double min_r = 0;
//		double max_r = 0.4;
//		VariableRPlugin vrplugin(rho, min_r, max_r, VariableRPlugin::AKTLIKE);
//		JetDefinition jet_def_vrplugin(&vrplugin);
//		ClusterSequence cs_vrplugin(particles, jet_def_vrplugin);
//		vector<fastjet::PseudoJet> jets = sorted_by_pt(cs_vrplugin.inclusive_jets());

		// get the final time
		gettimeofday(&end, NULL);

		// get the duration
		timersub(&end, &start, &duration);
		h_timing->Fill(track_number, (long int) duration.tv_sec * 1000000 + (long int) duration.tv_usec);
		h_log_timing->Fill(track_number, log10((long int) duration.tv_sec * 1000000 + (long int) duration.tv_usec));

		n = track_number;
		us = (long int) duration.tv_sec * 1000000 + (long int) duration.tv_usec;

		event_tree->Fill();

		for (int jet = 0; jet < jets.size(); jet++)
		{
//			printf("jets[jet].pt() = %f\n", jets[jet].pt());
//			printf("jets[jet].eta() = %f\n", jets[jet].eta());
//			printf("jets[jet].phi() = %f\n", jets[jet].phi());
//			printf("jets[jet].m() = %f\n", jets[jet].m());
			jet_pt = jets[jet].pt();
			jet_eta = jets[jet].eta();
			jet_phi = jets[jet].phi();
			jet_m = jets[jet].m();

			jet_tree->Fill();
		}

		particles.clear();
	}

	TProfile * pr_timing = h_timing->ProfileX();
	TF1 * f_timing_n2 = new TF1("f_timing_n2", "pol2", 0, 1000);
	TF1 * f_timing_n3 = new TF1("f_timing_n3", "pol3", 0, 1000);
	pr_timing->Fit(f_timing_n2);
	pr_timing->Fit(f_timing_n3);

	TProfile * pr_log_timing = h_log_timing->ProfileX();
	TF1 * f_log_timing = new TF1("f_log_timing", "pol1", 0, 1000);
	pr_log_timing->Fit(f_log_timing);

	output_file->Write();

	h_timing->Write();
	pr_timing->Write();
	f_timing_n2->Write();
	f_timing_n3->Write();

	h_log_timing->Write();
	pr_log_timing->Write();
	f_log_timing->Write();

	delete(jet_tree);
	delete(event_tree);

	return 0;
}
PseudoJet::PseudoJet(TLorentzVector const& vector) :
    fastjet::PseudoJet(vector.Px(), vector.Py(), vector.Pz(), vector.E())
{
    INFO(vector.Px(), px(), vector.Py(), py());
}
Beispiel #21
0
void checkOpenHLT::Loop()
{
  gROOT->SetBatch(true);
  // Apply the default trigger cuts
  defaultTriggerCuts_ = true;

  // gROOT->Reset();
  gStyle->SetOptStat(0);
//   In a ROOT session, you can do:
//      Root > .L checkOpenHLT.C
//      Root > checkOpenHLT t
//      Root > t.GetEntry(12); // Fill t data members with entry number 12
//      Root > t.Show();       // Show values of entry 12
//      Root > t.Show(16);     // Read and show values of entry 16
//      Root > t.Loop();       // Loop on all entries
//

//     This is the loop skeleton where:
//    jentry is the global entry number in the chain
//    ientry is the entry number in the current Tree
//  Note that the argument to GetEntry must be:
//    jentry for TChain::GetEntry
//    ientry for TTree::GetEntry and TBranch::GetEntry
//
//       To read only selected branches, Insert statements like:
// METHOD1:
//    fChain->SetBranchStatus("*",0);  // disable all branches
//    fChain->SetBranchStatus("branchname",1);  // activate branchname
// METHOD2: replace line
//    fChain->GetEntry(jentry);       //read all branches
//by  b_branchname->GetEntry(ientry); //read only this branch
   if (fChain == 0) return;

   fChain->SetBranchStatus("*",0);  // disable all branches
   fChain->SetBranchStatus("NohMuL2NoVtx",1);
   fChain->SetBranchStatus("ohMuL2NoVtxPt",1);
   fChain->SetBranchStatus("ohMuL2NoVtxPhi",1);
   fChain->SetBranchStatus("ohMuL2NoVtxEta",1);
   fChain->SetBranchStatus("ohMuL2NoVtxChg",1);
   fChain->SetBranchStatus("ohMuL2NoVtxPtErr",1);
   fChain->SetBranchStatus("ohMuL2NoVtxDr",1);
   fChain->SetBranchStatus("ohMuL2NoVtxDz",1);
   fChain->SetBranchStatus("ohMuL2NoVtxL1idx",1);
   fChain->SetBranchStatus("ohMuL2NoVtxNhits",1);
   fChain->SetBranchStatus("ohMuL2NoVtxNchambers",1);

   // Setup all histograms
   TFile * outputFile = new TFile("CheckOpenHLT.root", "RECREATE");
   TH1F * numMuons = new TH1F("NumMuons", "Number of muons", 5, 0, 4);
   TH1F * num2Muons = new TH1F("Num2Muons", "Number of muons in events with at least 2", 5, 0, 4);

   TString noCutsName("_NoCuts_");
   TString oneValidHitName("_OneValidHit_");
   TString oneValidChamberName("_OneValidChamber_");
   TString parallelismCutName("_ParallelismCut_");

   prepareAllHistograms(noCutsName, outputFile);
   prepareAllHistograms(oneValidHitName, outputFile);
   prepareAllHistograms(oneValidChamberName, outputFile);
   prepareAllHistograms(parallelismCutName, outputFile);

   Long64_t nentries = fChain->GetEntriesFast();
   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
      Long64_t ientry = LoadTree(jentry);
      if (ientry < 0) break;
      nb = fChain->GetEntry(jentry);
      nbytes += nb;

      if( jentry%100 == 0 ) std::cout << "Analyzing entry number " << jentry << std::endl;
      // std::cout << "Number of L2 NoVtx muons = " << NohMuL2NoVtx << std::endl;

      numMuons->Fill(NohMuL2NoVtx);

      parallelDiff_ = -99.;
      if( NohMuL2NoVtx > 1 ) {
        TLorentzVector firstMuon = fromPtEtaPhiToPxPyPz(ohMuL2NoVtxPt[0], ohMuL2NoVtxEta[0], ohMuL2NoVtxPhi[0]);
        TLorentzVector secondMuon = fromPtEtaPhiToPxPyPz(ohMuL2NoVtxPt[1], ohMuL2NoVtxEta[1], ohMuL2NoVtxPhi[1]);
        double px1 = firstMuon.Px();
        double py1 = firstMuon.Py();
        double pz1 = firstMuon.Pz();
        double px2 = secondMuon.Px();
        double py2 = secondMuon.Py();
        double pz2 = secondMuon.Pz();
        parallelDiff_ = acos((px1*px2 + py1*py2 + pz1*pz2)/sqrt(px1*px1 + py1*py1 + pz1*pz1)/sqrt(px2*px2 + py2*py2 + pz2*pz2));

	num2Muons->Fill(NohMuL2NoVtx);

        // Skip if need to apply the default trigger cuts and they do not pass the pt cut
        // if( defaultTriggerCuts_ && !(NohMuL2NoVtx > 1 && ohMuL2NoVtxPt[0] > 23 && ohMuL2NoVtxPt[1] > 23) ) continue;

        int arraySize = std::min(NohMuL2NoVtx, 4);

        bool selectOnChambers = false;
        bool selectOnParallelism = false;

        bool selectionArray[4];

        // No cuts
        selectionArray[0] = true;
        selectionArray[1] = true;
        selectionArray[2] = true;
        selectionArray[3] = true;
        fillAllHistograms(noCutsName, arraySize, selectionArray);

        // Fill histograms for the > 0 valid hit cut
        applyCuts(arraySize, selectOnChambers, parallelDiff_, selectOnParallelism, selectionArray);
        fillAllHistograms(oneValidHitName, arraySize, selectionArray);

        // One valid chamber cut
        selectOnChambers = true;
        applyCuts(arraySize, selectOnChambers, parallelDiff_, selectOnParallelism, selectionArray);
        fillAllHistograms(oneValidChamberName, arraySize, selectionArray);

        // Anti-parallel cut
        selectOnParallelism = true;
        applyCuts(arraySize, selectOnChambers, parallelDiff_, selectOnParallelism, selectionArray);
        fillAllHistograms(parallelismCutName, arraySize, selectionArray);
      }
      // if (Cut(ientry) < 0) continue;
   }
   saveAllHistograms(noCutsName);
   saveAllHistograms(oneValidHitName);
   saveAllHistograms(oneValidChamberName);
   saveAllHistograms(parallelismCutName);

   outputFile->Write();
}
int main(int argc, char * argv[]) {

	// first argument - config file 
	// second argument - filelist

	using namespace std;

	// **** configuration
	Config cfg(argv[1]);

	const bool isData = cfg.get<bool>("IsData");
	const bool applyGoodRunSelection = cfg.get<bool>("ApplyGoodRunSelection");

	// pile up reweighting
	const bool applyPUreweighting = cfg.get<bool>("ApplyPUreweighting");

	//const bool applyPUreweighting = cfg.get<bool>("ApplyPUreweighting");
	const bool applyLeptonSF = cfg.get<bool>("ApplyLeptonSF");

	// kinematic cuts on muons
	const float ptMuonLowCut   = cfg.get<float>("ptMuonLowCut");
	const float ptMuonHighCut  = cfg.get<float>("ptMuonHighCut");
	const float etaMuonHighCut = cfg.get<float>("etaMuonHighCut");
	const float etaMuonLowCut = cfg.get<float>("etaMuonLowCut");
	const double etaMuonCut     = cfg.get<double>("etaMuonCut");
	const float dxyMuonCut     = cfg.get<float>("dxyMuonCut");
	const float dzMuonCut      = cfg.get<float>("dzMuonCut");
	const float isoMuonCut     = cfg.get<float>("isoMuonCut");
	//const bool  applyTauTauSelection = cfg.get<bool>("ApplyTauTauSelection");
	//const bool  selectZToTauTauMuMu = cfg.get<bool>("SelectZToTauTauMuMu");

	// topological cuts

	// trigger
	const bool applyTrigger = cfg.get<bool>("ApplyTrigger");
	const string muonTriggerName  = cfg.get<string>("MuonTriggerName");
	const string muonFilterName   = cfg.get<string>("MuonFilterName");
	const string muon17FilterName = cfg.get<string>("Muon17FilterName"); 
	const string muon8FilterName = cfg.get<string>("Muon8FilterName"); 
	const string singleMuonFilterName = cfg.get<string>("SingleMuonFilterName");
	const float singleMuonTriggerPtCut = cfg.get<float>("SingleMuonTriggerPtCut");
	const float singleMuonTriggerEtaCut = cfg.get<float>("SingleMuonTriggerEtaCut");


	TString MuonTriggerName(muonTriggerName);
	TString MuonFilterName(muonFilterName);

	TString Muon17FilterName(muon17FilterName);
	TString Muon8FilterName(muon8FilterName);
	TString SingleMuonFilterName(singleMuonFilterName);

	const double leadchargedhadrcand_dz = cfg.get<double>("leadchargedhadrcand_dz");
	const double leadchargedhadrcand_dxy = cfg.get<double>("leadchargedhadrcand_dxy");

	const double etaJetCut   = cfg.get<double>("etaJetCut");
	const double ptJetCut   = cfg.get<double>("ptJetCut");


	// topological cuts
	const float dRleptonsCut   = cfg.get<float>("dRleptonsCut");
	const float dPhileptonsCut = cfg.get<float>("dPhileptonsCut");
	const float DRTrigMatch    = cfg.get<float>("DRTrigMatch"); 
	const double dRleptonsCutmutau   = cfg.get<double>("dRleptonsCutmutau");
	const double dZetaCut       = cfg.get<double>("dZetaCut");
	const double deltaRTrigMatch = cfg.get<double>("DRTrigMatch");
	const bool oppositeSign    = cfg.get<bool>("oppositeSign");
	const bool isIsoR03 = cfg.get<bool>("IsIsoR03");

	// tau
	const double taupt    = cfg.get<double>("taupt");
	const double taueta    = cfg.get<double>("taueta");
	const double decayModeFinding    = cfg.get<double>("decayModeFinding");
	const double   decayModeFindingNewDMs  = cfg.get<double>("decayModeFindingNewDMs");
	const double   againstElectronVLooseMVA5  = cfg.get<double>("againstElectronVLooseMVA5");
	const double   againstMuonTight3  = cfg.get<double>("againstMuonTight3");
	const double   vertexz =  cfg.get<double>("vertexz");
	const double   byCombinedIsolationDeltaBetaCorrRaw3Hits = cfg.get<double>("byCombinedIsolationDeltaBetaCorrRaw3Hits");




	// vertex cuts
	const float ndofVertexCut  = cfg.get<float>("NdofVertexCut");   
	const float zVertexCut     = cfg.get<float>("ZVertexCut");
	const float dVertexCut     = cfg.get<float>("DVertexCut");

	// jet related cuts
	//const float jetEtaCut      = cfg.get<float>("JetEtaCut");
	//const float jetEtaTrkCut   = cfg.get<float>("JetEtaTrkCut");
	//const float jetPtHighCut   = cfg.get<float>("JetPtHighCut");
	//const float jetPtLowCut    = cfg.get<float>("JetPtLowCut");
	//const float dRJetLeptonCut = cfg.get<float>("dRJetLeptonCut");

	// Run range
	const unsigned int RunRangeMin = cfg.get<unsigned int>("RunRangeMin");
	const unsigned int RunRangeMax = cfg.get<unsigned int>("RunRangeMax");

	//
	const string dataBaseDir = cfg.get<string>("DataBaseDir");

	// vertex distributions filenames and histname
	const string vertDataFileName = cfg.get<string>("VertexDataFileName");
	const string vertMcFileName   = cfg.get<string>("VertexMcFileName");
	const string vertHistName     = cfg.get<string>("VertexHistName");

	// lepton scale factors
	const string muonSfDataBarrel = cfg.get<string>("MuonSfDataBarrel");
	const string muonSfDataEndcap = cfg.get<string>("MuonSfDataEndcap");
	const string muonSfMcBarrel = cfg.get<string>("MuonSfMcBarrel");
	const string muonSfMcEndcap = cfg.get<string>("MuonSfMcEndcap");

	const string jsonFile = cfg.get<string>("jsonFile");
	string TrigLeg  ;
	if (!isData) TrigLeg  = cfg.get<string>("Mu17LegMC");
	if (isData) TrigLeg  = cfg.get<string>("Mu18LegData");
  	const string Region  = cfg.get<string>("Region");
  	const string Sign  = cfg.get<string>("Sign");
	
	TString MainTrigger(TrigLeg);
	// **** end of configuration

	string cmsswBase = (getenv ("CMSSW_BASE"));
	string fullPathToJsonFile = cmsswBase + "/src/DesyTauAnalyses/NTupleMaker/test/json/" + jsonFile;

	// Run-lumi selector
	std::vector<Period> periods;  
	if (isData) { // read the good runs 
		std::fstream inputFileStream(fullPathToJsonFile.c_str(), std::ios::in);
		if (inputFileStream.fail() ) {
			std::cout << "Error: cannot find json file " << fullPathToJsonFile << std::endl;
			std::cout << "please check" << std::endl;
			std::cout << "quitting program" << std::endl;
			exit(-1);
		}

		for(std::string s; std::getline(inputFileStream, s); ) {
			periods.push_back(Period());
			std::stringstream ss(s);
			ss >> periods.back();
		}
	}
	char ff[100];

	sprintf(ff,"%s/%s",argv[3],argv[2]);
	// file name and tree name
	std::string rootFileName(argv[2]);
	std::ifstream fileList(ff);
	std::ifstream fileList0(ff);
	std::string ntupleName("makeroottree/AC1B");

	TString era=argv[3];
  	TString TStrName(rootFileName+"_"+Region+"_"+Sign);
	std::cout <<TStrName <<std::endl;  
  	datasetName = rootFileName.c_str();

	TFile * file ;//= new TFile(era+"/"+TStrName+TString(".root"),"update");
  	if (isData) file = new TFile(era+"/"+TStrName+TString("_DataDriven.root"),"update");
  	if (!isData) file = new TFile(era+"/"+TStrName+TString(".root"),"update");
	file->cd("");
	/*
	// file name and tree name
	std::string rootFileName(argv[2]);
	std::ifstream fileList(argv[2]);
	std::ifstream fileList0(argv[2]);
	std::string ntupleName("makeroottree/AC1B");

	TString TStrName(rootFileName);
	TString era=argv[3];
	std::cout <<TStrName <<std::endl;  

	TFile * file = new TFile(TStrName+TString(".root"),"recreate");
	file->cd("");
	*/
	std::string initNtupleName("initroottree/AC1B");
	TH1D * inputEventsH = new TH1D("inputEventsH","",1,-0.5,0.5);
	TH1D * histWeightsH = new TH1D("histWeightsH","",1,-0.5,0.5);
	TH1D * histWeightsSkimmedH = new TH1D("histWeightsSkimmedH","",1,-0.5,0.5);

	// Histograms after selecting unique dimuon pair
	TH1D * massSelH = new TH1D("massSelH","",200,0,200);
	TH1D * metSelH  = new TH1D("metSelH","",200,0,400);

	TH1D * hDiJetmet = new TH1D("hDiJetmet","",200,0,400);
	TH1D * hDiJetmass = new TH1D("hDiJetmass","",500,0,1000);
	TH1D * hHT_ = new TH1D("hHT_","",800,0,1600);
	TH1D * metAll  = new TH1D("metAll","",200,0,400);

	TH1D * muon1PtH = new TH1D("muon1PtH","",200,0,400);
	TH1D * muon2PtH = new TH1D("muon2PtH","",200,0,400);

	TH1F * NumberOfVerticesH = new TH1F("NumberOfVerticesH","",51,-0.5,50.5);


	//*****  create eta histogram with eta ranges associated to their names (eg. endcap, barrel)   ***** //

	TFile * fileDataNVert = new TFile(TString(cmsswBase)+"/src/"+dataBaseDir+"/"+vertDataFileName);
  	TFile * fileMcNVert   = new TFile(TString(cmsswBase)+"/src/"+dataBaseDir+"/"+vertMcFileName);


	TH1D * vertexDataH = (TH1D*)fileDataNVert->Get(TString(vertHistName));
	TH1D * vertexMcH   = (TH1D*)fileMcNVert->Get(TString(vertHistName));

	float normVertexData = vertexDataH->GetSumOfWeights();
	float normVertexMc   = vertexMcH->GetSumOfWeights();

	vertexDataH->Scale(1/normVertexData);
	vertexMcH->Scale(1/normVertexMc);


	PileUp * PUofficial = new PileUp();

	TFile * filePUdistribution_data = new TFile(TString(cmsswBase)+"/src/DesyTauAnalyses/NTupleMaker/data/PileUpDistrib/Data_Pileup_2015D_Nov17.root","read");
	TFile * filePUdistribution_MC = new TFile (TString(cmsswBase)+"/src/DesyTauAnalyses/NTupleMaker/data/PileUpDistrib/MC_Spring15_PU25_Startup.root", "read");
	TH1D * PU_data = (TH1D *)filePUdistribution_data->Get("pileup");
	TH1D * PU_mc = (TH1D *)filePUdistribution_MC->Get("pileup");
	PUofficial->set_h_data(PU_data);
	PUofficial->set_h_MC(PU_mc);


	TFile *f10= new TFile(TString(cmsswBase)+"/src/DesyTauAnalyses/NTupleMaker/data/"+muonSfDataBarrel);  // mu SF barrel data
	TFile *f11 = new TFile(TString(cmsswBase)+"/src/DesyTauAnalyses/NTupleMaker/data/"+muonSfDataEndcap); // mu SF endcap data
	TFile *f12= new TFile(TString(cmsswBase)+"/src/DesyTauAnalyses/NTupleMaker/data/"+muonSfMcBarrel);  // mu SF barrel MC
	TFile *f13 = new TFile(TString(cmsswBase)+"/src/DesyTauAnalyses/NTupleMaker/data/"+muonSfMcEndcap); // mu SF endcap MC 

	TGraphAsymmErrors *hEffBarrelData = (TGraphAsymmErrors*)f10->Get("ZMassBarrel");
	TGraphAsymmErrors *hEffEndcapData = (TGraphAsymmErrors*)f11->Get("ZMassEndcap");
	TGraphAsymmErrors *hEffBarrelMC = (TGraphAsymmErrors*)f12->Get("ZMassBarrel");
	TGraphAsymmErrors *hEffEndcapMC = (TGraphAsymmErrors*)f13->Get("ZMassEndcap");

	double * dataEffBarrel = new double[10];
	double * dataEffEndcap = new double[10];
	double * mcEffBarrel = new double[10];
	double * mcEffEndcap = new double[10];

	dataEffBarrel = hEffBarrelData->GetY();
	dataEffEndcap = hEffEndcapData->GetY();
	mcEffBarrel = hEffBarrelMC->GetY();
	mcEffEndcap = hEffEndcapMC->GetY();
	double Weight=0;
	int nTotalFiles = 0;
	int nominator=-1;int denominator = -1;


	file->cd();
	TH1D * hMT = new TH1D("hMT","",20,0,200);
	TH1D * hMass = new TH1D("hMass","",20,0,200);
	TH1D * hRatioSum = new TH1D("hRatioSum","",10,0,1);
	TH1D * hDPhi = new TH1D("hDPhi","",70,0,3.5);

	int nPtBins = 3;
	//float ptBins[6] = {19,25,30,40,60,1000};
	float ptBins[4] = {19,25,40,1000};


/*
	TString PtBins[5] = {"Pt19to25",
		"Pt25to30",
		"Pt30to40",
		"Pt40to60",
		"PtGt60"};//,		       "Pt100to150",		       "Pt150to200",		        "PtGt200"};
*/
	TString PtBins[3] = {"Pt19to25",
		"Pt25to40",
		"PtGt40"};//,		       "Pt100to150",		       "Pt150to200",		        "PtGt200"};


//int nEtaBins = 3;
int nEtaBins = 1;
int nCuts = 4;
//float etaBins[4] = {0,0.9,1.2,2.4}; 
//float etaBins[3] = {0,1.48,2.4}; 
float etaBins[2] = {0,2.4}; 

TString EtaBins[1] = {
	//"EtaLt0p9",
	//"Eta0p9to1p2",
	//"EtaGt1p2"};
	"EtaLt2p4"};

TString Cuts[4] = {"Ratio","mT","DPhi","All"};
/////first stands for the Eta bin, second array for the cut 
TH1D * FakeRatePtIncLoose[1][4];
TH1D * FakeRatePtIncTight[2][4];


//TH1D * FakeRatePt[3][7];
//TH1D * FakeRateNV[3][7];
//TH1D * FakeRateEta[3][7];


TH1D * etaBinsH = new TH1D("etaBinsH", "etaBinsH", nEtaBins, etaBins);
etaBinsH->Draw();
etaBinsH->GetXaxis()->Set(nEtaBins, etaBins);
for (int i=0; i<nEtaBins; i++){ etaBinsH->GetXaxis()->SetBinLabel(i+1, EtaBins[i]);}


for (int iEta=0; iEta<nEtaBins; ++iEta) {
	for (int iCut=0; iCut<nCuts; ++iCut) {
		FakeRatePtIncLoose[iEta][iCut] = new TH1D("FakeRatePtIncLoose"+EtaBins[iEta]+Cuts[iCut],"",nPtBins,ptBins);
		FakeRatePtIncTight[iEta][iCut] = new TH1D("FakeRatePtIncTight"+EtaBins[iEta]+Cuts[iCut],"",nPtBins,ptBins);

	}

	//for (int iPt=0; iPt<nPtBins; ++iPt) {
	//  FakeRatePt[iEta][iPt] = new TH1D("FakeRatePt"+EtaBins[iEta]+PtBins[iPt],"",100,0,1000);
	//  FakeRateNV[iEta][iPt] = new TH1D("FakeRateNV"+EtaBins[iEta]+PtBins[iPt],"",50,0,50);
	//  FakeRateEta[iEta][iPt] = new TH1D("FakeRateEta"+EtaBins[iEta]+PtBins[iPt],"",80,-4,4);
	// }

}





int nFiles = 0;
int nEvents = 0;
int selEventsAllMuons = 0;
int selEventsIdMuons = 0;
int selEventsIsoMuons = 0;


std::string dummy;
// count number of files --->
while (fileList0 >> dummy) nTotalFiles++;

unsigned int RunMin = 9999999;
unsigned int RunMax = 0;
  ifstream ifs("xsecs");
  string line;

  while(std::getline(ifs, line)) // read one line from ifs
    {

      fact=fact2=1;
      istringstream iss(line); // access line as a stream

      // we only need the first two columns
      string dt,st1,st2;st1="stau2_1";st2="stau5_2";
      iss >> dt >> xs >> fact >> fact2;
      //datasetName = dt.c_str();
      //ifs >> dt >> xs; // no need to read further
      //cout<< " "<<dt<<"  "<<endl;
      //cout<< "For sample ========================"<<dt<<" xsecs is "<<xs<<" XSec "<<XSec<<"  "<<fact<<"  "<<fact2<<endl;
      //if (dt==argv[2]) {
      //if (std::string::npos != dt.find(argv[2])) {
      if (  dt == argv[2]) {
	XSec= xs*fact*fact2;
	cout<<" Found the correct cross section "<<xs<<" for Dataset "<<dt<<" XSec "<<XSec<<endl;
      }
      /*
	if ( argv[2] == st1) {ChiMass=100;mIntermediate=200;}
	else if (argv[2] == st2) {ChiMass=200;mIntermediate=500;}
      */
      if (isData) XSec=1.;
      ChiMass=0.0;
    }

  if (XSec<0&& !isData) {cout<<" Something probably wrong with the xsecs...please check  - the input was "<<argv[2]<<endl;return 0;}
	
  xsecs=XSec;

std::vector<unsigned int> allRuns; allRuns.clear();
vector <unsigned int> run_;
vector <unsigned int> lumi_;
vector <unsigned int> event_;
run_.clear();
lumi_.clear();
event_.clear();

std::vector<Event> EventList;
std::ifstream EventsFile;
TString file_events=argv[4]; //eventlist_csc2015.txt
//EventsFile.open("MET_filters/eventlist_"+file_events+".txt");
EventsFile.open(era+"/"+file_events+".txt");
//cout<<"  limits  int -> "<<std::numeric_limits<int>::max()<<"  long int -> "<<std::numeric_limits<long int>::max()<<"  unsigned int -> "<<std::numeric_limits<unsigned int>::max()<<endl;
cout<<" The file that will be used will be "<<era<<"/"<<file_events<<".txt"<<endl;


while (getline(EventsFile, line))
{
	std::vector<std::string> columns = split(line,':');
	run_.push_back(std::stoi(columns[0]));
	lumi_.push_back(std::stoi(columns[1]));
	event_.push_back(std::stoul(columns[2]));
	/*   Event events_;

	     events_.name     = "Test";
	     events_.run     = std::stoi(columns[0]);
	     events_.lumi   = std::stoi(columns[1]);
	     events_.eventrn = std::stof(columns[2]);

	     EventList.push_back(events_);
	     */
}

cout<<" In total there are "<<run_.size()<< " entries for "<<file_events<<" filter "<<endl;
EventsFile.close();
//----Attention----//
//if(XSec!=1) nTotalFiles=20;
//nTotalFiles=5;

if (argv[4] != NULL  && atoi(argv[4])< nTotalFiles) nTotalFiles=atoi(argv[4]);

cout<<" There are in total "<<nTotalFiles<<endl;
for (int iF=0; iF<nTotalFiles; ++iF) {

	std::string filen;
	fileList >> filen;

	std::cout << "file " << iF+1 << " out of " << nTotalFiles << " filename : " << filen << std::endl;
	TFile * file_ = TFile::Open(TString(filen));

	TH1D * histoInputEvents = NULL;
	histoInputEvents = (TH1D*)file_->Get("makeroottree/nEvents");
	if (histoInputEvents==NULL) continue;
	int NE = int(histoInputEvents->GetEntries());
	for (int iE=0;iE<NE;++iE)
		inputEventsH->Fill(0.);
	std::cout << "      number of input events         = " << NE << std::endl;

	TTree * _inittree = NULL;
	_inittree = (TTree*)file_->Get(TString(initNtupleName));
	if (_inittree==NULL) continue;
	Float_t genweight;
	if (!isData)
		_inittree->SetBranchAddress("genweight",&genweight);
	Long64_t numberOfEntriesInitTree = _inittree->GetEntries();
	std::cout << "      number of entries in Init Tree = " << numberOfEntriesInitTree << std::endl;
	for (Long64_t iEntry=0; iEntry<numberOfEntriesInitTree; iEntry++) {
		_inittree->GetEntry(iEntry);
		if (isData)
			histWeightsH->Fill(0.,1.);
		else
			histWeightsH->Fill(0.,genweight);
	}

	TTree * _tree = NULL;
	_tree = (TTree*)file_->Get(TString(ntupleName));
	if (_tree==NULL) continue;
	Long64_t numberOfEntries = _tree->GetEntries();
	std::cout << "      number of entries in Tree      = " << numberOfEntries << std::endl;
	AC1B analysisTree(_tree);


	// EVENT LOOP //
	for (Long64_t iEntry=0; iEntry<numberOfEntries; iEntry++) { 

		analysisTree.GetEntry(iEntry);
		nEvents++;

		if (nEvents%50000==0) 
			cout << "      processed " << nEvents << " events" << endl; 

		float weight = 1;

		//------------------------------------------------

		if (!isData) 
			weight *=analysisTree.genweight;

		histWeightsSkimmedH->Fill(float(0),weight);

		if (!isData) {/*
			if (applyPUreweighting_vertices) {
				int binNvert = vertexDataH->FindBin(analysisTree.primvertex_count);
				float_t dataNvert = vertexDataH->GetBinContent(binNvert);
				float_t mcNvert = vertexMcH->GetBinContent(binNvert);
				if (mcNvert < 1e-10){mcNvert=1e-10;}
				float_t vertWeight = dataNvert/mcNvert;
				weight *= vertWeight;
				//	  cout << "NVert = " << analysisTree.primvertex_count << "   weight = " << vertWeight << endl;
			}
*/
			if (applyPUreweighting) {

				double Ninteractions = analysisTree.numtruepileupinteractions;
				double PUweight = PUofficial->get_PUweight(Ninteractions);
				weight *= PUweight;
				//PUweightsOfficialH->Fill(PUweight);

			}
/*
			if (applyTauTauSelection) {
				unsigned int nTaus = 0;
				if (analysisTree.gentau_count>0) {
					//	  cout << "Generated taus present" << endl;
					for (unsigned int itau = 0; itau < analysisTree.gentau_count; ++itau) {
						//	    cout << itau << "  : pt = " 
						//		 << analysisTree.gentau_visible_pt[itau] 
						//		 << "   eta = " <<  analysisTree.gentau_visible_eta[itau]
						//		 << "   mother = " << int(analysisTree.gentau_mother[itau]) << endl;
						if (int(analysisTree.gentau_mother[itau])==3) nTaus++;

					}
				}
				bool notTauTau = nTaus < 2;
				//	  std::cout << "nTaus = " << nTaus << std::endl;

				if (selectZToTauTauMuMu&&notTauTau) { 
					//	    std::cout << "Skipping event..." << std::endl;
					//	    cout << endl;
					continue;
				}
				if (!selectZToTauTauMuMu&&!notTauTau) { 
					//	    std::cout << "Skipping event..." << std::endl;
					//	    cout << endl;
					continue;
				}
				//	  cout << endl;
			}*/
		}

		if (isData && applyGoodRunSelection){


			bool lumi = false;
			int n=analysisTree.event_run;
			int lum = analysisTree.event_luminosityblock;
			int nr = analysisTree.event_nr;

			std::string num = std::to_string(n);
			std::string lnum = std::to_string(lum);
			for(const auto& a : periods)
			{

				if ( num.c_str() ==  a.name ) {
					//std::cout<< " Eureka "<<num<<"  "<<a.name<<" ";
					//     std::cout <<"min "<< last->lower << "- max last " << last->bigger << std::endl;

					for(auto b = a.ranges.begin(); b != std::prev(a.ranges.end()); ++b) {

						//	cout<<b->lower<<"  "<<b->bigger<<endl;
						if (lum  >= b->lower && lum <= b->bigger ) lumi = true;
					}
					auto last = std::prev(a.ranges.end());
					//    std::cout <<"min "<< last->lower << "- max last " << last->bigger << std::endl;
					if (  (lum >=last->lower && lum <= last->bigger )) lumi=true;


				}

			}

			if (!lumi) continue;
			bool runbool=false;
			bool lumibool=false;
			bool eventbool=false;
			runbool= std::find(run_.begin(), run_.end(), n) != run_.end();
			lumibool= std::find(lumi_.begin(), lumi_.end(), lum) != lumi_.end();
			eventbool= std::find(event_.begin(), event_.end(), nr) != event_.end();

			if (runbool && lumibool && eventbool) continue;
			//if (lumi ) cout<<"  =============  Found good run"<<"  "<<n<<"  "<<lum<<endl;
			//std::remove("myinputfile");
		}     
		float metall = sqrt(analysisTree.pfmet_ex*analysisTree.pfmet_ex+analysisTree.pfmet_ey*analysisTree.pfmet_ey);
		metAll->Fill(metall,weight);

		if (analysisTree.event_run<RunMin)
			RunMin = analysisTree.event_run;

		if (analysisTree.event_run>RunMax)
			RunMax = analysisTree.event_run;

		//std::cout << " Run : " << analysisTree.event_run << std::endl;

		bool isNewRun = true;
		if (allRuns.size()>0) {
			for (unsigned int iR=0; iR<allRuns.size(); ++iR) {
				if (analysisTree.event_run==allRuns.at(iR)) {
					isNewRun = false;
					break;
				}
			}
		}

		if (isNewRun) 
			allRuns.push_back(analysisTree.event_run);
			unsigned int nMainTrigger = 0;
			bool isMainTrigger = false;

		unsigned int nMuonFilter = 0;

			unsigned int nfilters = analysisTree.run_hltfilters->size();
			//  std::cout << "nfiltres = " << nfilters << std::endl;
			for (unsigned int i=0; i<nfilters; ++i) {
				//	std::cout << "HLT Filter : " << i << " = " << analysisTree.run_hltfilters->at(i) << std::endl;
				TString HLTFilter(analysisTree.run_hltfilters->at(i));
				if (HLTFilter==MainTrigger) {
					nMainTrigger = i;
					isMainTrigger = true;
					nMuonFilter = i;
				}



			}

			if (!isMainTrigger) {
				std::cout << "Fail on main HLT Filter " << MainTrigger << " not found" << std::endl;
				return(-1);
			}



/*

		bool isTriggerMuon = false;
		for (std::map<string,int>::iterator it=analysisTree.hltriggerresults->begin(); it!=analysisTree.hltriggerresults->end(); ++it) {
			TString trigName(it->first);
			if (trigName.Contains(MuonTriggerName)) {
				//	  std::cout << it->first << " : " << it->second << std::endl;
				if (it->second==1)
					isTriggerMuon = true;
			}
		}

		if (applyTrigger && !isTriggerMuon) continue;

		unsigned int nMuonFilter = 0;
		bool isMuonFilter = false;

		unsigned int nMuon17Filter = 0;
		bool isMuon17Filter = false;

		unsigned int nMuon8Filter = 0;
		bool isMuon8Filter = false;

		unsigned int nSingleMuonFilter = 0;
		bool isSingleMuonFilter = false;

		unsigned int nfilters = analysisTree.run_hltfilters->size();
		for (unsigned int i=0; i<nfilters; ++i) {
			TString HLTFilter(analysisTree.run_hltfilters->at(i));
			if (HLTFilter==MuonFilterName) {
				nMuonFilter = i;
				isMuonFilter = true;
			}
			if (HLTFilter==Muon17FilterName) {
				nMuon17Filter = i;
				isMuon17Filter = true;
			}
			if (HLTFilter==Muon8FilterName) {
				nMuon8Filter = i;
				isMuon8Filter = true;
			}
			if (HLTFilter==SingleMuonFilterName) {
				nSingleMuonFilter = i;
				isSingleMuonFilter = true;
			}
		}
		if (!isMuonFilter) {
			cout << "Filter " << MuonFilterName << " not found " << endl;
			exit(-1);
		}
		if (!isMuon17Filter) {
			cout << "Filter " << Muon17FilterName << " not found " << endl;
			exit(-1);
		}
		if (!isMuon8Filter) {
			cout << "Filter " << Muon8FilterName << " not found " << endl;
			exit(-1);
		}
		if (!isSingleMuonFilter) {
			cout << "Filter " << SingleMuonFilterName << " not found " << endl;
			exit(-1);
		}
*/
		// vertex cuts

		if (fabs(analysisTree.primvertex_z)>zVertexCut) continue;
		if (analysisTree.primvertex_ndof<ndofVertexCut) continue;
		float dVertex = (analysisTree.primvertex_x*analysisTree.primvertex_x+
				analysisTree.primvertex_y*analysisTree.primvertex_y);
		if (dVertex>dVertexCut) continue;

		// muon selection

		vector<unsigned int> allMuons; allMuons.clear();
		vector<unsigned int> idMuons; idMuons.clear();
		vector<unsigned int> isoMuons; isoMuons.clear();
		vector<float> isoMuonsValue; isoMuonsValue.clear();
		vector<bool> isMuonPassedIdIso; isMuonPassedIdIso.clear();
		vector<bool> isMuonMatched23Filter; isMuonMatched23Filter.clear();
		vector<bool> isMuonMatched17Filter; isMuonMatched17Filter.clear();
		vector<bool> isMuonMatched8Filter; isMuonMatched8Filter.clear();
		vector<bool> isMuonMatchedSingleMuFilter; isMuonMatchedSingleMuFilter.clear();

		for (unsigned int im = 0; im<analysisTree.muon_count; ++im) {
			allMuons.push_back(im);
			bool muPassed    = true;
			bool mu23Matched = false;
			bool mu17Matched = false;
			bool mu8Matched  = false;
			bool muSingleMatched = false;
			if (analysisTree.muon_pt[im]<5) muPassed = false;
			if (fabs(analysisTree.muon_eta[im])>etaMuonLowCut) muPassed = false;
			if (fabs(analysisTree.muon_dxy[im])>dxyMuonCut) muPassed = false;
			if (fabs(analysisTree.muon_dz[im])>dzMuonCut) muPassed = false;
			if (!analysisTree.muon_isMedium[im]) muPassed = false;
			if (muPassed) idMuons.push_back(im);
			float absIso = analysisTree.muon_r03_sumChargedHadronPt[im];
			float neutralIso = analysisTree.muon_r03_sumNeutralHadronEt[im] + 
				analysisTree.muon_r03_sumPhotonEt[im] - 
				0.5*analysisTree.muon_r03_sumPUPt[im];
			neutralIso = TMath::Max(float(0),neutralIso); 
			absIso += neutralIso;
			float relIso = absIso/analysisTree.muon_pt[im];
			if (relIso>isoMuonCut) muPassed = false;
			if (muPassed && analysisTree.muon_pt[im]>ptMuonLowCut) { 
				isoMuons.push_back(im);
				isoMuonsValue.push_back(relIso);
			}

			isMuonPassedIdIso.push_back(muPassed);


			for (unsigned int iT=0; iT<analysisTree.trigobject_count; ++iT) {
				if (analysisTree.trigobject_filters[iT][nMainTrigger]) { // Mu17 Leg
					double dRtrig = deltaR(analysisTree.muon_eta[im],analysisTree.muon_phi[im],
							analysisTree.trigobject_eta[iT],analysisTree.trigobject_phi[iT]);
					if (dRtrig>deltaRTrigMatch) continue;
					//if (!isData && analysisTree.trigobject_filters[iT][nMainTrigger] && analysisTree.trigobject_pt[iT]>18) 
					isMainTrigger = true;

				}
			}

			if (!isMainTrigger) continue;


/*
			//	cout << "pt:" << analysisTree.muon_pt[im] << "  passed:" << muPassed << endl;
			for (unsigned int iT=0; iT<analysisTree.trigobject_count; ++iT) {
				float dRtrig = deltaR(analysisTree.muon_eta[im],analysisTree.muon_phi[im],
						analysisTree.trigobject_eta[iT],analysisTree.trigobject_phi[iT]);
				if (dRtrig>DRTrigMatch) continue;
				if (analysisTree.trigobject_filters[iT][nMuon17Filter] && analysisTree.trigobject_pt[iT]>23.0) 
					mu23Matched = true;
				if (analysisTree.trigobject_filters[iT][nMuon17Filter] && analysisTree.trigobject_pt[iT]>17.0)
					mu17Matched = true;
				if (analysisTree.trigobject_filters[iT][nSingleMuonFilter] && analysisTree.trigobject_pt[iT]>singleMuonTriggerPtCut)
					muSingleMatched = true;
				if (analysisTree.trigobject_filters[iT][nMuon8Filter] && analysisTree.trigobject_pt[iT]>8.0) 
					mu8Matched = true;

			}
			isMuonMatched23Filter.push_back(mu23Matched);
			isMuonMatched17Filter.push_back(mu17Matched);
			isMuonMatched8Filter.push_back(mu8Matched);
			isMuonMatchedSingleMuFilter.push_back(muSingleMatched);*/
		}


		unsigned int indx1 = 0;
		unsigned int indx2 = 0;
		bool isIsoMuonsPair = false;
		float isoMin = 9999;
		if (isoMuons.size()>0) {
			for (unsigned int im1=0; im1<isoMuons.size(); ++im1) {
				unsigned int index1 = isoMuons[im1];
				bool isMu1matched = false;
				for (unsigned int iT=0; iT<analysisTree.trigobject_count; ++iT) {
					float dRtrig = deltaR(analysisTree.muon_eta[index1],analysisTree.muon_phi[index1],
							analysisTree.trigobject_eta[iT],analysisTree.trigobject_phi[iT]);
					if (dRtrig>DRTrigMatch) continue;
					if (analysisTree.trigobject_filters[iT][nMainTrigger] && 
							analysisTree.muon_pt[index1] > ptMuonHighCut &&
							fabs(analysisTree.muon_eta[index1]) < etaMuonHighCut) 
						isMu1matched = true;
				}
				if (isMu1matched) {
					for (unsigned int iMu=0; iMu<allMuons.size(); ++iMu) {
						unsigned int indexProbe = allMuons[iMu];
						if (index1==indexProbe) continue;
						float q1 = analysisTree.muon_charge[index1];
						float q2 = analysisTree.muon_charge[indexProbe];
						if (q1*q2>0) continue;
						float dR = deltaR(analysisTree.muon_eta[index1],analysisTree.muon_phi[index1],
								analysisTree.muon_eta[indexProbe],analysisTree.muon_phi[indexProbe]);
						if (dR<dRleptonsCut) continue; 
						float dPhi = dPhiFrom2P(analysisTree.muon_px[index1],analysisTree.muon_py[index1],
								analysisTree.muon_px[indexProbe],analysisTree.muon_py[indexProbe]);
						if (dPhi>dPhileptonsCut) continue;
						TLorentzVector muon1; muon1.SetXYZM(analysisTree.muon_px[index1],
								analysisTree.muon_py[index1],
								analysisTree.muon_pz[index1],
								muonMass);
						TLorentzVector muon2; muon2.SetXYZM(analysisTree.muon_px[indexProbe],
								analysisTree.muon_py[indexProbe],
								analysisTree.muon_pz[indexProbe],
								muonMass);


						float mass = (muon1+muon2).M();
					}
				}
				for (unsigned int im2=im1+1; im2<isoMuons.size(); ++im2) {
					unsigned int index2 = isoMuons[im2];
					float q1 = analysisTree.muon_charge[index1];
					float q2 = analysisTree.muon_charge[index2];
					bool isMu2matched = false;
					for (unsigned int iT=0; iT<analysisTree.trigobject_count; ++iT) {
						float dRtrig = deltaR(analysisTree.muon_eta[index2],analysisTree.muon_phi[index2],
								analysisTree.trigobject_eta[iT],analysisTree.trigobject_phi[iT]);
						if (dRtrig>DRTrigMatch) continue;
						if (analysisTree.trigobject_filters[iT][nMainTrigger] && 
								analysisTree.muon_pt[index2] > ptMuonHighCut &&
								fabs(analysisTree.muon_eta[index2]) < etaMuonHighCut) 
							isMu2matched = true;
					}
					bool isPairSelected = q1*q2 > 0;
					if (oppositeSign) isPairSelected = q1*q2 < 0;
					bool isTriggerMatch = (isMu1matched || isMu2matched);
					float dRmumu = deltaR(analysisTree.muon_eta[index1],analysisTree.muon_phi[index1],
							analysisTree.muon_eta[index2],analysisTree.muon_phi[index2]);
					if (isTriggerMatch && isPairSelected && dRmumu>dRleptonsCut) {
						bool sumIso = isoMuonsValue[im1]+isoMuonsValue[im2];
						if (sumIso<isoMin) {
							isIsoMuonsPair = true;
							isoMin = sumIso;
							if (analysisTree.muon_pt[index1]>analysisTree.muon_pt[index2]) {
								indx1 = index1;
								indx2 = index2;
							}
							else {
								indx2 = index1;
								indx1 = index2;
							}
						}
					}
				}
			}
		}
		if (isIsoMuonsPair) {      
			//match to genparticles

			double isoTauMin = 999;
			bool tau_iso = false;
			bool isTight = false;
			bool isLoose = false;
			unsigned tau_loose=-1;
			vector<int> tau; tau.clear();


			for (unsigned  int it = 0; it<analysisTree.tau_count; ++it) {

				if (analysisTree.tau_pt[it] < ptMuonLowCut || fabs(analysisTree.tau_eta[it])> etaMuonCut) continue;
				if (analysisTree.tau_decayModeFindingNewDMs[it]<decayModeFindingNewDMs) continue;
				if ( fabs(analysisTree.tau_leadchargedhadrcand_dz[it])> leadchargedhadrcand_dz) continue;
				double  tauIso = analysisTree.tau_byCombinedIsolationDeltaBetaCorrRaw3Hits[it];

				isLoose  = true;
				tau_loose = int(it);

				if (analysisTree.tau_byMediumCombinedIsolationDeltaBetaCorr3Hits [it]> 0.5  && analysisTree.tau_againstElectronVLooseMVA5[it]>againstElectronVLooseMVA5 
						&& analysisTree.tau_againstMuonTight3[it]>againstMuonTight3) {isTight = true;	  tau_tight = int(it);}




			}


			if (!isLoose) continue;
			TLorentzVector JetsV;

			JetsMV.clear();
			int countjets=0;
			for (unsigned int jet=0; jet<analysisTree.pfjet_count; ++jet) {
				float absJetEta = fabs(analysisTree.pfjet_eta[jet]);

				if (analysisTree.pfjet_pt[jet] < 19) continue;
				if (absJetEta > etaJetCut) continue;
				//if (fabs(analysisTree.pfjet_pt[jet])<ptJetCut) continue;
				bool  looseJetID = looseJetiD(analysisTree,jet);
				if (!looseJetID) continue;	  

				double dRmuJet1 = deltaR(analysisTree.pfjet_eta[jet],analysisTree.pfjet_phi[jet],
						analysisTree.muon_eta[indx1],analysisTree.muon_phi[indx1]);

				if (dRmuJet1 < 0.5) continue;
				double dRmuJet2 = deltaR(analysisTree.pfjet_eta[jet],analysisTree.pfjet_phi[jet],
						analysisTree.muon_eta[indx2],analysisTree.muon_phi[indx2]);

				if (dRmuJet2 < 0.5) continue;

				JetsV.SetPxPyPzE(0.,0.,0.,0.);
				JetsV.SetPxPyPzE(analysisTree.pfjet_px[jet], analysisTree.pfjet_py[jet], analysisTree.pfjet_pz[jet], analysisTree.pfjet_e[jet]);
				JetsMV.push_back(JetsV);	
				countjets++;
			}
			sort(JetsMV.begin(), JetsMV.end(),ComparePt);

			if (countjets ==0) continue;



			double dPhi=-1;double MT=-1 ; double RatioSums=-1;


			double met = sqrt ( analysisTree.pfmet_ex*analysisTree.pfmet_ex + analysisTree.pfmet_ey*analysisTree.pfmet_ey);
			// w = mu+MET
			// ptW - ptJ/ptW+ptJ      
			//
			//

			TLorentzVector muon1; muon1.SetXYZM(analysisTree.muon_px[indx1],
					analysisTree.muon_py[indx1],
					analysisTree.muon_pz[indx1],
					muonMass);
			TLorentzVector muon2; muon2.SetXYZM(analysisTree.muon_px[indx2],
					analysisTree.muon_py[indx2],
					analysisTree.muon_pz[indx2],
					muonMass);
			TLorentzVector DiM = muon1+muon2;

			RatioSums = analysisTree.tau_pt[tau_loose]/DiM.Pt();


			TLorentzVector MetV; 
			MetV.SetPx(analysisTree.pfmet_ex); 
			MetV.SetPy(analysisTree.pfmet_ey);

			TLorentzVector tauV;  tauV.SetPtEtaPhiM(analysisTree.tau_pt[tau_loose], analysisTree.tau_eta[tau_loose], analysisTree.tau_phi[tau_loose], tauMass);

			TLorentzVector DiL = DiM  + tauV;

			//dPhi = dPhiFrom2P( DiM.Px(), DiM.Py(), MetV.Px(),  MetV.Py() );
			dPhi = dPhiFrom2P( DiM.Px(), DiM.Py(), analysisTree.tau_px[tau_loose],analysisTree.tau_py[tau_loose]);
			MT = TMath::Sqrt(2*DiM.Pt()*MetV.Pt()*(1-TMath::Cos(dPhi)));


			hRatioSum->Fill(RatioSums,weight);
			hMT->Fill(MT,weight);
			hMass->Fill(DiM.M(),weight);
			hDPhi->Fill(dPhi, weight);


			//if (tau.size()==0 || !tau_iso ) continue;

			//cout<<"  "<<endl;
			if (isLoose) denominator++;
			if (isTight) nominator++;

			if (isLoose){
				float ptProbe = TMath::Min(float(analysisTree.tau_pt[tau_loose]),float(ptBins[nPtBins]-0.1));
				float absEtaProbe = fabs(analysisTree.tau_eta[tau_loose]);
				int ptBin = binNumber(ptProbe,nPtBins,ptBins);
				if (ptBin<0) continue;
				int etaBin = binNumber(absEtaProbe,nEtaBins,etaBins);
				if (etaBin<0) continue;

				//cout<< "filling here  "<<analysisTree.tau_pt[tau_loose]<<"  "<<ptBin<<"  "<<etaBin<<"  "<<weight<<endl;
				//FakeRatePt[etaBin][ptBin]->Fill(analysisTree.tau_pt[tau_loose],weight);

				bool bRatio = (RatioSums < 1.2  && RatioSums > 0.8);
				bool bMass = (DiM.M() < 120 && DiM.M() > 60);
				if (isLoose){
					if (bRatio) FakeRatePtIncLoose[etaBin][0]->Fill(analysisTree.tau_pt[tau_loose],weight);
					if (bMass && bRatio) FakeRatePtIncLoose[etaBin][1]->Fill(analysisTree.tau_pt[tau_loose],weight);
					if (dPhi > 2.5  && bRatio) FakeRatePtIncLoose[etaBin][2]->Fill(analysisTree.tau_pt[tau_loose],weight);
					if (bMass  && dPhi > 2.5 && bRatio) FakeRatePtIncLoose[etaBin][3]->Fill(analysisTree.tau_pt[tau_loose],weight);

				}

				if (isTight) 

				{	
					if (bRatio) FakeRatePtIncTight[etaBin][0]->Fill(analysisTree.tau_pt[tau_loose],weight);
					if (bMass  && bRatio) FakeRatePtIncTight[etaBin][1]->Fill(analysisTree.tau_pt[tau_loose],weight);
					if (dPhi > 2.5 && bRatio) FakeRatePtIncTight[etaBin][2]->Fill(analysisTree.tau_pt[tau_loose],weight);
					if (bMass  && dPhi > 2.5 && bRatio) FakeRatePtIncTight[etaBin][3]->Fill(analysisTree.tau_pt[tau_loose],weight);

				}

				//FakeRateEta[etaBin][ptBin]->Fill(analysisTree.tau_eta[tau_loose],weight);
				//FakeRateNV[etaBin][ptBin]->Fill(analysisTree.tau_vertexz[tau_loose],weight);

			}
		}
	} // end of file processing (loop over events in one file)
	nFiles++;
	delete _tree;
	file_->Close();
	delete file_;
}
std::cout << std::endl;
int allEvents = int(inputEventsH->GetEntries());
std::cout << "Total number of input events                     = " << allEvents << std::endl;
std::cout << "Total number of events in Tree                   = " << nEvents << std::endl;
std::cout << "Total number of selected events (iso muon pairs) = " << selEventsIsoMuons << std::endl;
std::cout << std::endl;
std::cout << "RunMin = " << RunMin << std::endl;
std::cout << "RunMax = " << RunMax << std::endl;

//cout << "weight used:" << weight << std::endl;

// using object as comp
std::sort (allRuns.begin(), allRuns.end(), myobject);
std::cout << "Runs   :";
for (unsigned int iR=0; iR<allRuns.size(); ++iR)
std::cout << " " << allRuns.at(iR);
std::cout << std::endl;

file->cd();
hxsec->Fill(XSec);
hxsec->Write();
inputEventsH->Write();
histWeightsH->Write();
file->Write();
file->Close();
delete file;

}
int main(int argc, char * argv[]) {

  // first argument - config file 
  // second argument - filelist

  using namespace std;

  // **** configuration
  Config cfg(argv[1]);

  // vertex cuts
  const float ndofVertexCut  = cfg.get<float>("NdofVertexCut");   
  const float zVertexCut     = cfg.get<float>("ZVertexCut");
  const float dVertexCut     = cfg.get<float>("DVertexCut");

  // electron cuta
  const float ptElectronLowCut   = cfg.get<float>("ptElectronLowCut");
  const float ptElectronHighCut  = cfg.get<float>("ptElectronHighCut");
  const float etaElectronCut     = cfg.get<float>("etaElectronCut");
  const float dxyElectronCut     = cfg.get<float>("dxyElectronCut");
  const float dzElectronCut      = cfg.get<float>("dzElectronCut");
  const float isoElectronLowCut  = cfg.get<float>("isoElectronLowCut");
  const float isoElectronHighCut = cfg.get<float>("isoElectronHighCut");
  const bool applyElectronId     = cfg.get<bool>("ApplyElectronId");

  // tau cuts
  const float ptTauLowCut    = cfg.get<float>("ptTauLowCut");
  const float ptTauHighCut   = cfg.get<float>("ptTauHighCut");  
  const float etaTauCut      = cfg.get<float>("etaTauCut");
  const bool applyTauId      = cfg.get<bool>("ApplyTauId");

  // pair selection
  const float dRleptonsCut   = cfg.get<float>("dRleptonsCut");

  // additional lepton veto
  const float ptDiElectronVeto   = cfg.get<float>("ptDiElectronVeto");  
  const float etaDiElectronVeto  = cfg.get<float>("etaDiElectronVeto");
  
  // topological cuts
  const float dZetaCut       = cfg.get<float>("dZetaCut");
  const bool oppositeSign    = cfg.get<bool>("oppositeSign");

  const float deltaRTrigMatch = cfg.get<float>("DRTrigMatch");
  const bool isIsoR03 = cfg.get<bool>("IsIsoR03");
  
  const float jetEtaCut = cfg.get<float>("JetEtaCut");
  const float jetPtLowCut = cfg.get<float>("JetPtLowCut");
  const float jetPtHighCut = cfg.get<float>("JetPtHighCut");
  const float dRJetLeptonCut = cfg.get<float>("dRJetLeptonCut");
  const bool applyJetPfId = cfg.get<bool>("ApplyJetPfId");
  const bool applyJetPuId = cfg.get<bool>("ApplyJetPuId");

  const float bJetEtaCut = cfg.get<float>("bJetEtaCut");
  const float btagCut = cfg.get<float>("btagCut");

  // check overlap
  const bool checkOverlap = cfg.get<bool>("CheckOverlap");
  const bool debug = cfg.get<bool>("debug");
  
  // **** end of configuration

  // file name and tree name
  TString rootFileName(argv[2]);
  std::ifstream fileList(argv[2]);
  std::ifstream fileList0(argv[2]);
  std::string ntupleName("makeroottree/AC1B");

  
  rootFileName += "_et_Sync.root";
  std::cout <<rootFileName <<std::endl;  

  // output fileName with histograms
  TFile * file = new TFile( rootFileName ,"recreate");
  file->cd("");

  TH1F * inputEventsH = new TH1F("inputEventsH","",1,-0.5,0.5);
  TTree * tree = new TTree("TauCheck","TauCheck");
  
  Spring15Tree *otree = new Spring15Tree(tree);

  int nTotalFiles = 0;
  std::string dummy;
  // count number of files --->
  while (fileList0 >> dummy) nTotalFiles++;

  int nEvents = 0;
  int selEvents = 0;
  int nFiles = 0;
  
  vector<int> runList; runList.clear();
  vector<int> eventList; eventList.clear();

  int nonOverlap = 0;

  std::ifstream fileEvents("overlap.txt");
  int Run, Event, Lumi;
  if (checkOverlap) {
    std::cout << "Non-overlapping events ->" << std::endl;
    while (fileEvents >> Run >> Event >> Lumi) {
      runList.push_back(Run);
      eventList.push_back(Event);
      std::cout << Run << ":" << Event << std::endl;
    }
    std::cout << std::endl;
  }
  std::ofstream fileOutput("overlap.out");


  for (int iF=0; iF<nTotalFiles; ++iF) {

    std::string filen;
    fileList >> filen;

    std::cout << "file " << iF+1 << " out of " << nTotalFiles << " filename : " << filen << std::endl;
    TFile * file_ = TFile::Open(TString(filen));
    
    TTree * _tree = NULL;
    _tree = (TTree*)file_->Get(TString(ntupleName));
  
    if (_tree==NULL) continue;
    
    TH1D * histoInputEvents = NULL;
   
    histoInputEvents = (TH1D*)file_->Get("makeroottree/nEvents");
    
    if (histoInputEvents==NULL) continue;
    
    int NE = int(histoInputEvents->GetEntries());
    
    std::cout << "      number of input events    = " << NE << std::endl;
    
    for (int iE=0;iE<NE;++iE)
      inputEventsH->Fill(0.);

    AC1B analysisTree(_tree);
    
    Long64_t numberOfEntries = analysisTree.GetEntries();
    
    std::cout << "      number of entries in Tree = " << numberOfEntries << std::endl;
    
    for (Long64_t iEntry=0; iEntry<numberOfEntries; iEntry++) {       
      analysisTree.GetEntry(iEntry);
      nEvents++;
      
      if (nEvents%10000==0) 
	cout << "      processed " << nEvents << " events" << endl; 

      otree->run = int(analysisTree.event_run);
      otree->lumi = int(analysisTree.event_luminosityblock);
      otree->evt = int(analysisTree.event_nr);

      bool overlapEvent = true;
      for (unsigned int iEvent=0; iEvent<runList.size(); ++iEvent) {
	if (runList.at(iEvent)==otree->run && eventList.at(iEvent)==otree->evt) {
	  overlapEvent = false;	  
	}
      }

      if (overlapEvent&&checkOverlap) continue;
      nonOverlap++;

      if (debug) {
	fileOutput << std::endl;
	fileOutput << "Run = " << otree->run << "   Event = " << otree->evt << std::endl;
      }

      // weights
      otree->mcweight = 0;
      otree->puweight = 0;
      otree->trigweight_1 = 0;
      otree->trigweight_2 = 0;
      otree->idweight_1 = 0;
      otree->idweight_2 = 0;
      otree->isoweight_1 = 0;
      otree->isoweight_2 = 0;
      otree->effweight = 0;
      otree->fakeweight = 0;
      otree->embeddedWeight = 0;
      otree->signalWeight = 0;
      otree->weight = 1;
      
      otree->npv = analysisTree.primvertex_count;
      otree->npu = analysisTree.numpileupinteractions;
      otree->rho = analysisTree.rho;

      // vertex cuts
      if (fabs(analysisTree.primvertex_z)>zVertexCut) continue;
      if (analysisTree.primvertex_ndof<=ndofVertexCut) continue;
      float dVertex = sqrt(analysisTree.primvertex_x*analysisTree.primvertex_x+
			   analysisTree.primvertex_y*analysisTree.primvertex_y);
      if (dVertex>dVertexCut)
	continue;
      
      if (debug)
	fileOutput << "Vertex cuts are passed " << std::endl;

      // electron selection
      vector<int> electrons; electrons.clear();
      if (debug)
	fileOutput << "# electrons = " << analysisTree.electron_count << std::endl;
      for (unsigned int ie = 0; ie<analysisTree.electron_count; ++ie) {
	bool electronMvaId = electronMvaIdTight(analysisTree.electron_superclusterEta[ie],
						analysisTree.electron_mva_id_nontrigPhys14[ie]);
	if (checkOverlap)
	  fileOutput << "  " << ie 
		     << " pt = " << analysisTree.electron_pt[ie] 
		     << " eta = " << analysisTree.electron_eta[ie]
		     << " dxy = " << analysisTree.electron_dxy[ie]
		     << " dz  = " << analysisTree.electron_dz[ie]
		     << " passConv = " << analysisTree.electron_pass_conversion[ie]
		     << " nmisshits = " << int(analysisTree.electron_nmissinginnerhits[ie])
		     << " mvaTight = " << electronMvaId << std::endl;
	if (analysisTree.electron_pt[ie]<ptElectronLowCut) continue;
	if (fabs(analysisTree.electron_eta[ie])>etaElectronCut) continue;
	if (fabs(analysisTree.electron_dxy[ie])>dxyElectronCut) continue;
	if (fabs(analysisTree.electron_dz[ie])>dzElectronCut) continue;
	if (!electronMvaId&&applyElectronId) continue;
	if (!analysisTree.electron_pass_conversion[ie]&&applyElectronId) continue;
	if (analysisTree.electron_nmissinginnerhits[ie]!=0&&applyElectronId) continue;
	electrons.push_back(ie);
      }

      // tau selection
      if (debug)
	fileOutput << "# taus = " << analysisTree.tau_count << std::endl;
      vector<int> taus; taus.clear();
      for (unsigned int it = 0; it<analysisTree.tau_count; ++it) {
	if (debug)
	  fileOutput << "  " << it 
		     << " pt = " << analysisTree.tau_pt[it] 
		     << " eta = " << analysisTree.tau_eta[it]
		     << " decayModeFinding = " << analysisTree.tau_decayModeFinding[it]
		     << " decayModeFindingNewDMs = " << analysisTree.tau_decayModeFindingNewDMs[it]
		     << " tau_vertexz = " << analysisTree.tau_vertexz[it] <<std::endl;
	if (analysisTree.tau_pt[it]<ptTauLowCut) continue;
	if (fabs(analysisTree.tau_eta[it])>etaTauCut) continue;
	if (applyTauId &&
	    analysisTree.tau_decayModeFinding[it] < 0.5 &&
	    analysisTree.tau_decayModeFindingNewDMs[it] < 0.5) continue;
	
	float ctgTheta = analysisTree.tau_pz[it] / sqrt(analysisTree.tau_px[it]*analysisTree.tau_px[it] + analysisTree.tau_py[it]*analysisTree.tau_py[it]);
	float zImpact = analysisTree.tau_vertexz[it] + 130. * ctgTheta;

	if ( zImpact > -1.5 && zImpact < 0.5) continue;
	
	if (analysisTree.tau_vertexz[it]!=analysisTree.primvertex_z) continue;
	taus.push_back(it);
      }

      if (debug) {
	fileOutput << " # selected electron = " << electrons.size() << std::endl;
	fileOutput << " # selected taus = " << taus.size() << std::endl;	
      }
      
      if (electrons.size()==0) continue;
      if (taus.size()==0) continue;

      // selecting muon and tau pair (OS or SS);
      int electronIndex = -1;
      int tauIndex = -1;
      
      float isoEleMin = 1e+10;
      float isoTauMin = 1e+10;      
      for (unsigned int ie=0; ie<electrons.size(); ++ie) {
	bool isTrigEle22 = false;
	bool isTrigEle32 = false;

	unsigned int eIndex  = electrons.at(ie);

	float neutralHadIsoEle = analysisTree.electron_neutralHadIso[ie];
	float photonIsoEle = analysisTree.electron_photonIso[ie];
	float chargedHadIsoEle = analysisTree.electron_chargedHadIso[ie];
	float puIsoEle = analysisTree.electron_puIso[ie];
	if (isIsoR03) {
	  neutralHadIsoEle = analysisTree.electron_r03_sumNeutralHadronEt[ie];
	  photonIsoEle = analysisTree.electron_r03_sumPhotonEt[ie];
	  chargedHadIsoEle = analysisTree.electron_r03_sumChargedHadronPt[ie];
	  puIsoEle = analysisTree.electron_r03_sumPUPt[ie];
	}
	float neutralIsoEle = neutralHadIsoEle + photonIsoEle - 0.5*puIsoEle;
	neutralIsoEle = TMath::Max(float(0),neutralIsoEle); 
	float absIsoEle =  chargedHadIsoEle + neutralIsoEle;
	float relIsoEle = absIsoEle/analysisTree.electron_pt[ie];
	
	if (debug)
	  fileOutput << "Electron " << eIndex << " -> relIso = "<<relIsoEle<<" absIso = "<<absIsoEle<<std::endl;

	for (unsigned int iT=0; iT<analysisTree.trigobject_count; ++iT) {
	  /*if (analysisTree.trigobject_isElectron[iT] ||
	      !analysisTree.trigobject_isMuon[iT] ||
	      analysisTree.trigobject_isTau[iT]) continue;*/
	  
	  float dRtrig = deltaR(analysisTree.electron_eta[eIndex],analysisTree.electron_phi[eIndex],
				analysisTree.trigobject_eta[iT],analysisTree.trigobject_phi[iT]);

	  if (dRtrig < deltaRTrigMatch){
	    if (analysisTree.trigobject_filters[iT][7] && analysisTree.trigobject_filters[iT][8]) // Ele22 Leg
	      isTrigEle22 = true;	      
	    if (analysisTree.trigobject_filters[iT][10]) // Ele32 Leg
	      isTrigEle32 = true;
	  }
	}
	  
	if (debug)
	  fileOutput << "Electron " << eIndex << " -> isTrigEle22 = " << isTrigEle22 << " ; isTrigEle32 = " << isTrigEle32 << std::endl;

	if ((!isTrigEle22) && (!isTrigEle32)) continue;
      
	for (unsigned int it=0; it<taus.size(); ++it) {
	  unsigned int tIndex = taus.at(it);
	  float absIsoTau = analysisTree.tau_byCombinedIsolationDeltaBetaCorrRaw3Hits[tIndex];
	  float relIsoTau = absIsoTau / analysisTree.tau_pt[tIndex];

	  if (debug)
	    fileOutput << "tau" << tIndex << " -> relIso = "<<relIsoTau<<" absIso = "<<absIsoTau<<std::endl;
	  
	  float dR = deltaR(analysisTree.tau_eta[tIndex],analysisTree.tau_phi[tIndex],
			    analysisTree.electron_eta[eIndex],analysisTree.electron_phi[eIndex]);

	  if (debug)
	    fileOutput << "dR(ele,tau) = " << dR << std::endl;

	  if (dR<dRleptonsCut) continue;
	  
	  bool isTrigTau = false;
	  float dRtrig_min = 9999.;
	  
	  for (unsigned int iT=0; iT<analysisTree.trigobject_count; ++iT) {
	    if (debug){
	      if (analysisTree.trigobject_isElectron[iT] && analysisTree.trigobject_isMuon[iT])
		fileOutput<<" trigObj "<<iT<<" both e and mu"<<std::endl;
	      
	      if (analysisTree.trigobject_isMuon[iT] && analysisTree.trigobject_isTau[iT])
		fileOutput<<" trigObj "<<iT<<" both mu and tau"<<std::endl;
	      
	      if (analysisTree.trigobject_isElectron[iT] && analysisTree.trigobject_isTau[iT])
		fileOutput<<" trigObj "<<iT<<" both e and tau"<<std::endl;
	    }
	    
	    if (analysisTree.trigobject_isElectron[iT] ||
		analysisTree.trigobject_isMuon[iT] ||
		!analysisTree.trigobject_isTau[iT]) continue;
	    
	    float dRtrig = deltaR(analysisTree.tau_eta[tIndex],analysisTree.tau_phi[tIndex],
				  analysisTree.trigobject_eta[iT],analysisTree.trigobject_phi[iT]);
	    
	    if (dRtrig < deltaRTrigMatch){
	      if (analysisTree.trigobject_filters[iT][7] && analysisTree.trigobject_filters[iT][8]){
		isTrigTau = true;
		if (dRtrig < dRtrig_min)
		  dRtrig_min = dRtrig;
	      }
	    }
	  }
	  
	  if (debug)
	    fileOutput << "Tau " << it << " -> isTrigTau = " << isTrigTau << " DR="<<dRtrig_min<<std::endl;

	  bool trigMatch = isTrigEle32 || (isTrigEle22 && isTrigTau);

	  if (isTrigEle32 && analysisTree.hltriggerresults_second[4]==false)
	    if (debug)
	      std::cout<<"IsoEle32 Trigger Mismatch"<<std::endl;

	  
	  if (isTrigEle22 && isTrigTau && analysisTree.hltriggerresults_second[1]==false)
	    if (debug)
	      std::cout<<"xEleTau Trigger Mismatch"<<std::endl;
	      
	  if (!trigMatch) continue;
	  
	  bool isKinematicMatch = false;
	  if (isTrigEle32) {
	    if (analysisTree.electron_pt[eIndex]>ptElectronHighCut)
	      isKinematicMatch = true;
	  }	  
	  if (isTrigEle22 && isTrigTau) {
            if (analysisTree.electron_pt[eIndex]>ptElectronLowCut && analysisTree.tau_pt[tIndex]>ptTauHighCut)
              isKinematicMatch = true;
	  }
	  	  
	  if (!isKinematicMatch) continue;
	  
	  bool changePair =  false;
	  
	  if (relIsoEle<isoEleMin) {
	    changePair = true;
	  }
	  else if (fabs(relIsoEle - isoEleMin) < 1.e-5) {
	    if (analysisTree.electron_pt[eIndex] > analysisTree.electron_pt[electronIndex]) {
	      changePair = true;
	    }	    
	    else if (fabs(analysisTree.electron_pt[eIndex] - analysisTree.electron_pt[electronIndex]) < 1.e-5) {
	      if (absIsoTau < isoTauMin) {
		changePair = true;
	      }
	      else if ((absIsoTau - isoTauMin) < 1.e-5){
		if (analysisTree.tau_pt[tIndex] > analysisTree.tau_pt[tauIndex]) {
		  changePair = true;
		}
	      }
	    }
	  }
	  
	  if (changePair){
	    isoEleMin  = relIsoEle;
	    electronIndex = eIndex;
	    isoTauMin = absIsoTau;
	    tauIndex = tIndex;
	  }
	}
      }
    
      if (electronIndex<0) continue;
      if (tauIndex<0) continue;
      
      // filling electron variables
      otree->pt_1 = analysisTree.electron_pt[electronIndex];
      otree->eta_1 = analysisTree.electron_eta[electronIndex];
      otree->phi_1 = analysisTree.electron_phi[electronIndex];
      otree->m_1 = electronMass;
      otree->q_1 = -1;
      if (analysisTree.electron_charge[electronIndex]>0)
        otree->q_1 = 1;
      otree->iso_1 = isoEleMin;
      otree->mva_1 = analysisTree.electron_mva_id_nontrigPhys14[electronIndex];
      otree->d0_1 = analysisTree.electron_dxy[electronIndex];
      otree->dZ_1 = analysisTree.electron_dz[electronIndex];

      otree->byCombinedIsolationDeltaBetaCorrRaw3Hits_1 = 0;
      otree->againstElectronLooseMVA5_1 = 0;
      otree->againstElectronMediumMVA5_1 = 0;
      otree->againstElectronTightMVA5_1 = 0;
      otree->againstElectronVLooseMVA5_1 = 0;
      otree->againstElectronVTightMVA5_1 = 0;
      otree->againstMuonLoose3_1 = 0;
      otree->againstMuonTight3_1 = 0;
      
      // filling tau variables
      otree->pt_2 = analysisTree.tau_pt[tauIndex];
      otree->eta_2 = analysisTree.tau_eta[tauIndex];
      otree->phi_2 = analysisTree.tau_phi[tauIndex];
      otree->q_2 = -1;
      if (analysisTree.tau_charge[tauIndex]>0)
	otree->q_2 = 1;
      otree->mva_2 = log(0);
      otree->d0_2 = analysisTree.tau_dxy[tauIndex];
      otree->dZ_2 = analysisTree.tau_dz[tauIndex];
      otree->iso_2 = analysisTree.tau_byCombinedIsolationDeltaBetaCorrRaw3Hits[tauIndex];
      otree->m_2 = analysisTree.tau_mass[tauIndex];

      otree->byCombinedIsolationDeltaBetaCorrRaw3Hits_2 = analysisTree.tau_byCombinedIsolationDeltaBetaCorrRaw3Hits[tauIndex];
      otree->againstElectronLooseMVA5_2 = analysisTree.tau_againstElectronLooseMVA5[tauIndex];
      otree->againstElectronMediumMVA5_2 = analysisTree.tau_againstElectronMediumMVA5[tauIndex];
      otree->againstElectronTightMVA5_2 = analysisTree.tau_againstElectronTightMVA5[tauIndex];
      otree->againstElectronVLooseMVA5_2 = analysisTree.tau_againstElectronVLooseMVA5[tauIndex];
      otree->againstElectronVTightMVA5_2 = analysisTree.tau_againstElectronVTightMVA5[tauIndex];
      otree->againstMuonLoose3_2 = analysisTree.tau_againstMuonLoose3[tauIndex];
      otree->againstMuonTight3_2 = analysisTree.tau_againstMuonTight3[tauIndex];

      // ditau system
      TLorentzVector electronLV; electronLV.SetXYZM(analysisTree.electron_px[electronIndex],
					    analysisTree.electron_py[electronIndex],
					    analysisTree.electron_pz[electronIndex],
					    electronMass);

      TLorentzVector tauLV; tauLV.SetXYZM(analysisTree.tau_px[tauIndex],
					  analysisTree.tau_py[tauIndex],
					  analysisTree.tau_pz[tauIndex],
					  tauMass);

      TLorentzVector dileptonLV = electronLV + tauLV;

      otree->m_vis = dileptonLV.M();
      otree->pt_tt = dileptonLV.Pt();

      // opposite charge
      otree->os = (otree->q_1 * otree->q_2) < 0.;

      // dimuon veto
      otree->dilepton_veto = 0;

      for (unsigned int ie = 0; ie<analysisTree.electron_count; ++ie) {
	if (analysisTree.electron_pt[ie]<ptDiElectronVeto) continue;
	if (fabs(analysisTree.electron_eta[ie])>etaDiElectronVeto) continue;	
	
	if (fabs(analysisTree.electron_dxy[ie])>dxyElectronCut) continue;
	if (fabs(analysisTree.electron_dz[ie])>dzElectronCut) continue;

	if (otree->q_1 * analysisTree.electron_charge[ie] > 0.) continue;

	float neutralHadIsoEle = analysisTree.electron_neutralHadIso[ie];
	float photonIsoEle = analysisTree.electron_photonIso[ie];
	float chargedHadIsoEle = analysisTree.electron_chargedHadIso[ie];
	float puIsoEle = analysisTree.electron_puIso[ie];
	if (isIsoR03) {
	  neutralHadIsoEle = analysisTree.electron_r03_sumNeutralHadronEt[ie];
	  photonIsoEle = analysisTree.electron_r03_sumPhotonEt[ie];
	  chargedHadIsoEle = analysisTree.electron_r03_sumChargedHadronPt[ie];
	  puIsoEle = analysisTree.electron_r03_sumPUPt[ie];
	}
	float neutralIsoEle = neutralHadIsoEle + photonIsoEle - 0.5*puIsoEle;
	neutralIsoEle = TMath::Max(float(0),neutralIsoEle); 
	float absIsoEle =  chargedHadIsoEle + neutralIsoEle;
	float relIsoEle = absIsoEle/analysisTree.electron_pt[ie];
	
	if(relIsoEle > 0.3) continue;

	float dr = deltaR(analysisTree.electron_eta[ie],analysisTree.electron_phi[ie],
			  otree->eta_1,otree->phi_1);
	if(dr<0.15) continue;

	otree->dilepton_veto = 1;
      }
      
      // extra electron veto
      otree->extraelec_veto = 0;

      // extra muon veto
      otree->extramuon_veto = 0;
      
      // svfit variables
      otree->m_sv = -9999;
      otree->pt_sv = -9999;
      otree->eta_sv = -9999;
      otree->phi_sv = -9999;

      // pfmet variables      
      otree->met = TMath::Sqrt(analysisTree.pfmet_ex*analysisTree.pfmet_ex + analysisTree.pfmet_ey*analysisTree.pfmet_ey);
      otree->metphi = TMath::ATan2(analysisTree.pfmet_ey,analysisTree.pfmet_ex);
      otree->metcov00 = analysisTree.pfmet_sigxx;
      otree->metcov01 = analysisTree.pfmet_sigxy;
      otree->metcov10 = analysisTree.pfmet_sigyx;
      otree->metcov11 = analysisTree.pfmet_sigyy;
      
      // bisector of muon and tau transverse momenta
      float electronUnitX = electronLV.Px()/electronLV.Pt();
      float electronUnitY = electronLV.Py()/electronLV.Pt();
	
      float tauUnitX = tauLV.Px()/tauLV.Pt();
      float tauUnitY = tauLV.Py()/tauLV.Pt();

      float zetaX = electronUnitX + tauUnitX;
      float zetaY = electronUnitY + tauUnitY;
      
      float normZeta = TMath::Sqrt(zetaX*zetaX+zetaY*zetaY);

      zetaX = zetaX/normZeta;
      zetaY = zetaY/normZeta;

      float vectorVisX = electronLV.Px() + tauLV.Px();
      float vectorVisY = electronLV.Py() + tauLV.Py();

      otree->pzetavis  = vectorVisX*zetaX + vectorVisY*zetaY;
      
      // choosing mva met
      unsigned int iMet = 0;
      for (; iMet<analysisTree.mvamet_count; ++iMet) {
	if ((int)analysisTree.mvamet_channel[iMet]==2) break;
      }
      
      if (iMet>=analysisTree.mvamet_count){
	if(debug)
	  fileOutput<<"MVA MET channel ploblems.."<<std::endl;

	otree->mvamet = log(0);
	otree->mvametphi = log(0);
 	otree->mvacov00 = log(0);
	otree->mvacov01 = log(0);
	otree->mvacov10 = log(0);
	otree->mvacov11 = log(0);

	otree->mt_1 = log(0);
	otree->mt_2 = log(0);
	
	otree->pzetamiss = log(0);	
      }
      else {
	float mvamet_x = analysisTree.mvamet_ex[iMet];
	float mvamet_y = analysisTree.mvamet_ey[iMet];
	float mvamet_x2 = mvamet_x * mvamet_x;
	float mvamet_y2 = mvamet_y * mvamet_y;

	otree->mvamet = TMath::Sqrt(mvamet_x2+mvamet_y2);
	otree->mvametphi = TMath::ATan2(mvamet_y,mvamet_x);
	otree->mvacov00 = analysisTree.mvamet_sigxx[iMet];
	otree->mvacov01 = analysisTree.mvamet_sigxy[iMet];
	otree->mvacov10 = analysisTree.mvamet_sigyx[iMet];
	otree->mvacov11 = analysisTree.mvamet_sigyy[iMet];

	// computation of mt
	otree->mt_1 = sqrt(2*otree->pt_1*otree->mvamet*(1.-cos(otree->phi_1-otree->mvametphi)));
	otree->mt_2 = sqrt(2*otree->pt_2*otree->mvamet*(1.-cos(otree->phi_2-otree->mvametphi)));  
	
	// computation of DZeta variable
	otree->pzetamiss = analysisTree.pfmet_ex*zetaX + analysisTree.pfmet_ey*zetaY;
      }

      // counting jets
      vector<unsigned int> jets; jets.clear();
      vector<unsigned int> jetspt20; jetspt20.clear();
      vector<unsigned int> bjets; bjets.clear();

      int indexLeadingJet = -1;
      float ptLeadingJet = -1;

      int indexSubLeadingJet = -1;
      float ptSubLeadingJet = -1;
      
      int indexLeadingBJet = -1;
      float ptLeadingBJet = -1;

      for (unsigned int jet=0; jet<analysisTree.pfjet_count; ++jet) {
	float absJetEta = fabs(analysisTree.pfjet_eta[jet]);
	if (absJetEta>jetEtaCut) continue;

	float jetPt = analysisTree.pfjet_pt[jet];
	if (jetPt<jetPtLowCut) continue;

	float dR1 = deltaR(analysisTree.pfjet_eta[jet],analysisTree.pfjet_phi[jet],
			   otree->eta_1,otree->phi_1);

	float dR2 = deltaR(analysisTree.pfjet_eta[jet],analysisTree.pfjet_phi[jet],
                           otree->eta_2,otree->phi_2);
	
	// pf jet Id
	float energy = analysisTree.pfjet_e[jet];
        float chf = analysisTree.pfjet_chargedhadronicenergy[jet]/energy;
        float nhf = analysisTree.pfjet_neutralhadronicenergy[jet]/energy;
        float phf = analysisTree.pfjet_neutralemenergy[jet]/energy;
        float elf = analysisTree.pfjet_chargedemenergy[jet]/energy;
        float chm = analysisTree.pfjet_chargedmulti[jet];
        float npr = analysisTree.pfjet_chargedmulti[jet] + analysisTree.pfjet_neutralmulti[jet];
	bool isPFJetId = (npr>1 && phf<0.99 && nhf<0.99) && (absJetEta>2.4 || (elf<0.99 && chf>0 && chm>0)); // muon fraction missing

	if(debug)
	  fileOutput<<" jet "<<jet<<": pt="<<analysisTree.pfjet_pt[jet]<<" eta="<<analysisTree.pfjet_eta[jet]
		    <<" dr1="<<dR1<<" dr2="<<dR2<<" npr="<<npr<<" phf="<<phf<<" nhf="<<nhf<<std::endl;

	// apply dR cut
	if (dR1<dRJetLeptonCut) continue;
	if (dR2<dRJetLeptonCut) continue;

	// apply pf jet Id
	if (applyJetPfId&&!isPFJetId) continue;

	// pu jet Id
	if (applyJetPuId&&!puJetIdLoose(analysisTree.pfjet_eta[jet],analysisTree.pfjet_pu_jet_full_mva[jet])) continue;
	
	jetspt20.push_back(jet);

	if (absJetEta<bJetEtaCut && analysisTree.pfjet_btag[jet][6]>btagCut) { // b-jet
	  bjets.push_back(jet);
	  if (jetPt>ptLeadingBJet) {
	    ptLeadingBJet = jetPt;
	    indexLeadingBJet = jet;
	  }
	} 

	if (jetPt<jetPtHighCut) continue;
	
	jets.push_back(jet);

	if(jetPt>ptLeadingJet){
	  ptSubLeadingJet = ptLeadingJet;
	  indexSubLeadingJet = indexLeadingJet;

	  ptLeadingJet = jetPt;
	  indexLeadingJet = jet;
	}
	else if(jetPt>ptSubLeadingJet){
	  ptSubLeadingJet = jetPt;
	  indexSubLeadingJet = jet;
	}	
      }
      
      otree->njets = jets.size();
      otree->njetspt20 = jetspt20.size();
      otree->nbtag = bjets.size();
      
      otree->bpt = -9999;
      otree->beta = -9999;
      otree->bphi = -9999;
      
      if (indexLeadingBJet>=0) {
	otree->bpt = analysisTree.pfjet_pt[indexLeadingBJet];
	otree->beta = analysisTree.pfjet_eta[indexLeadingBJet];
	otree->bphi = analysisTree.pfjet_phi[indexLeadingBJet];
      }
     
      otree->jpt_1 = -9999;
      otree->jeta_1 = -9999;
      otree->jphi_1 = -9999;
      otree->jptraw_1 = -9999;
      otree->jptunc_1 = -9999;
      otree->jmva_1 = -9999;
      otree->jlrm_1 = -9999;
      otree->jctm_1 = -9999;

      if (indexLeadingJet>=0&&indexSubLeadingJet>=0&&indexLeadingJet==indexSubLeadingJet)
	cout << "warning : indexLeadingJet ==indexSubLeadingJet = " << indexSubLeadingJet << endl;

      if (indexLeadingJet>=0) {
	otree->jpt_1 = analysisTree.pfjet_pt[indexLeadingJet];
	otree->jeta_1 = analysisTree.pfjet_eta[indexLeadingJet];
	otree->jphi_1 = analysisTree.pfjet_phi[indexLeadingJet];
	otree->jptraw_1 = analysisTree.pfjet_pt[indexLeadingJet]*analysisTree.pfjet_energycorr[indexLeadingJet];
	otree->jmva_1 = analysisTree.pfjet_pu_jet_full_mva[indexLeadingJet];
      }

      otree->jpt_2 = -9999;
      otree->jeta_2 = -9999;
      otree->jphi_2 = -9999;
      otree->jptraw_2 = -9999;
      otree->jptunc_2 = -9999;
      otree->jmva_2 = -9999;
      otree->jlrm_2 = -9999;
      otree->jctm_2 = -9999;

      if (indexSubLeadingJet>=0) {
	otree->jpt_2 = analysisTree.pfjet_pt[indexSubLeadingJet];
	otree->jeta_2 = analysisTree.pfjet_eta[indexSubLeadingJet];
	otree->jphi_2 = analysisTree.pfjet_phi[indexSubLeadingJet];
	otree->jptraw_2 = analysisTree.pfjet_pt[indexSubLeadingJet]*analysisTree.pfjet_energycorr[indexSubLeadingJet];
	otree->jmva_2 = analysisTree.pfjet_pu_jet_full_mva[indexSubLeadingJet];
      }

      otree->mjj =  -9999;
      otree->jdeta =  -9999;
      otree->njetingap = 0;

      if (indexLeadingJet>=0 && indexSubLeadingJet>=0) {

	TLorentzVector jet1; jet1.SetPxPyPzE(analysisTree.pfjet_px[indexLeadingJet],
					     analysisTree.pfjet_py[indexLeadingJet],
					     analysisTree.pfjet_pz[indexLeadingJet],
					     analysisTree.pfjet_e[indexLeadingJet]);

	TLorentzVector jet2; jet2.SetPxPyPzE(analysisTree.pfjet_px[indexSubLeadingJet],
					     analysisTree.pfjet_py[indexSubLeadingJet],
					     analysisTree.pfjet_pz[indexSubLeadingJet],
					     analysisTree.pfjet_e[indexSubLeadingJet]);

	otree->mjj = (jet1+jet2).M();
	otree->jdeta = abs(analysisTree.pfjet_eta[indexLeadingJet]-
		    analysisTree.pfjet_eta[indexSubLeadingJet]);
 
	float etamax = analysisTree.pfjet_eta[indexLeadingJet];
	float etamin = analysisTree.pfjet_eta[indexSubLeadingJet];
	if (etamax<etamin) {
	  float tmp = etamax;
	  etamax = etamin;
	  etamin = tmp;
	}
	for (unsigned int jet=0; jet<jetspt20.size(); ++jet) {
	  int index = jetspt20.at(jet);
	  float etaX = analysisTree.pfjet_eta[index];
	  if (index!=indexLeadingJet&&index!=indexSubLeadingJet&&etaX>etamin&&etaX<etamax) 
	    otree->njetingap++;
	}
      }
      
      otree->Fill();
      selEvents++;
    } // end of file processing (loop over events in one file)
    nFiles++;
    delete _tree;
    file_->Close();
    delete file_;
  }
  std::cout << std::endl;
  int allEvents = int(inputEventsH->GetEntries());
  std::cout << "Total number of input events    = " << allEvents << std::endl;
  std::cout << "Total number of events in Tree  = " << nEvents << std::endl;
  std::cout << "Total number of selected events = " << selEvents << std::endl;
  std::cout << std::endl;
  
  file->cd("");
  file->Write();
  file->Close();
  delete file;
  
}
Beispiel #24
0
void rochcor_42X::momcor_mc( TLorentzVector& mu, float charge, float sysdev, int runopt){
  
  //sysdev == num : deviation = num

  float ptmu = mu.Pt();
  float muphi = mu.Phi();
  float mueta = mu.Eta(); // same with mu.Eta() in Root

  float px = mu.Px();
  float py = mu.Py();
  float pz = mu.Pz();
  float e = mu.E();

  int mu_phibin = phibin(muphi);
  int mu_etabin = etabin(mueta);

  //float mptsys = sran.Gaus(0.0,sysdev);
  
  float dm = 0.0;
  float da = 0.0;
  
  if(runopt == 0){
    dm = (mcor_bfA[mu_phibin][mu_etabin] + mptsys_mc_dm[mu_phibin][mu_etabin]*mcor_bfAer[mu_phibin][mu_etabin])/mmavgA[mu_phibin][mu_etabin];
    da = mcor_maA[mu_phibin][mu_etabin] + mptsys_mc_da[mu_phibin][mu_etabin]*mcor_maAer[mu_phibin][mu_etabin];
  }else if(runopt == 1){
    dm = (mcor_bfB[mu_phibin][mu_etabin] + mptsys_mc_dm[mu_phibin][mu_etabin]*mcor_bfBer[mu_phibin][mu_etabin])/mmavgB[mu_phibin][mu_etabin];
    da = mcor_maB[mu_phibin][mu_etabin] + mptsys_mc_da[mu_phibin][mu_etabin]*mcor_maBer[mu_phibin][mu_etabin];
  }
  
  float cor = 1.0/(1.0 + dm + charge*da*ptmu);
  
  //for the momentum tuning - eta,phi,Q correction
  px *= cor;
  py *= cor;
  pz *= cor;
  e  *= cor;
  
  float recm = 0.0;
  float drecm = 0.0; 
  float delta = 0.0;
  float sf = 0.0;

  float gscler = 0.0;
  float deltaer = 0.0;
  float sfer = 0.0;
  
  if(runopt==0){
    recm = recmA;
    drecm = drecmA;
    
    delta = deltaA;
    sf = sfA;
    
    gscler = TMath::Sqrt( TMath::Power(mgsclA_stat,2) + TMath::Power(mgsclA_syst,2) );
    deltaer = TMath::Sqrt( TMath::Power(deltaA_stat,2) + TMath::Power(deltaA_syst,2) );
    sfer = TMath::Sqrt( TMath::Power(sfA_stat,2) + TMath::Power(sfA_syst,2) );
  }else if(runopt==1){
    recm = recmB;
    drecm = drecmB;
    
    delta = deltaB;
    sf = sfB;
    
    gscler = TMath::Sqrt( TMath::Power(mgsclB_stat,2) + TMath::Power(mgsclB_syst,2) );
    deltaer = TMath::Sqrt( TMath::Power(deltaB_stat,2) + TMath::Power(deltaB_syst,2) );
    sfer = TMath::Sqrt( TMath::Power(sfB_stat,2) + TMath::Power(sfB_syst,2) );
  }
  
  float tune = 1.0/(1.0 + (delta + sysdev*deltaer)*sqrt(px*px + py*py)*eran.Gaus(1.0,(sf + sysdev*sfer)));
  
  px *= (tune); 
  py *= (tune);  
  pz *= (tune);  
  e  *= (tune);   
      
  float gscl = (genm_smr/recm);
  
  px *= (gscl + sysdev*gscler);
  py *= (gscl + sysdev*gscler);
  pz *= (gscl + sysdev*gscler);
  e  *= (gscl + sysdev*gscler);
  
  mu.SetPxPyPzE(px,py,pz,e);
  
}
Beispiel #25
0
// Copied from http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/CMSSW/TopQuarkAnalysis/SingleTop/src/TopProducer.cc?revision=1.9&view=markup
TLorentzVector getNu4Momentum(const TLorentzVector& TLepton, const TLorentzVector& TMET)
{
  const math::XYZTLorentzVector Lepton(TLepton.Px(), TLepton.Py(), TLepton.Pz(), TLepton.E());
  const math::XYZTLorentzVector MET(TMET.Px(), TMET.Py(), 0., TMET.E());

  double  mW = 80.38;

  //std::vector<math::XYZTLorentzVector> result;
  std::vector<TLorentzVector> result;

  //  double Wmt = sqrt(pow(Lepton.et()+MET.pt(),2) - pow(Lepton.px()+MET.px(),2) - pow(Lepton.py()+MET.py(),2) );
    
  double MisET2 = (MET.px()*MET.px() + MET.py()*MET.py());
  double mu = (mW*mW)/2 + MET.px()*Lepton.px() + MET.py()*Lepton.py();
  double a  = (mu*Lepton.pz())/(Lepton.energy()*Lepton.energy() - Lepton.pz()*Lepton.pz());
  double a2 = TMath::Power(a,2);
  double b  = (TMath::Power(Lepton.energy(),2.)*(MisET2) - TMath::Power(mu,2.))/(TMath::Power(Lepton.energy(),2) - TMath::Power(Lepton.pz(),2));
  double pz1(0),pz2(0),pznu(0);
  int nNuSol(0);

  //math::XYZTLorentzVector p4nu_rec;
  TLorentzVector p4nu_rec;
  math::XYZTLorentzVector p4W_rec;
  math::XYZTLorentzVector p4b_rec;
  math::XYZTLorentzVector p4Top_rec;
  math::XYZTLorentzVector p4lep_rec;

  p4lep_rec.SetPxPyPzE(Lepton.px(),Lepton.py(),Lepton.pz(),Lepton.energy());
  
  //math::XYZTLorentzVector p40_rec(0,0,0,0);

  if(a2-b > 0 ){
    //if(!usePositiveDeltaSolutions_)
    //  {
    //    result.push_back(p40_rec);
    //    return result;
    //  }
    double root = sqrt(a2-b);
    pz1 = a + root;
    pz2 = a - root;
    nNuSol = 2;

    //if(usePzPlusSolutions_)pznu = pz1;    
    //if(usePzMinusSolutions_)pznu = pz2;
    //if(usePzAbsValMinimumSolutions_){
      pznu = pz1;
      if(fabs(pz1)>fabs(pz2)) pznu = pz2;
    //}

    double Enu = sqrt(MisET2 + pznu*pznu);

    p4nu_rec.SetPxPyPzE(MET.px(), MET.py(), pznu, Enu);

    result.push_back(p4nu_rec);

  }
  else{
    //if(!useNegativeDeltaSolutions_){
    //  result.push_back(p40_rec);
    //  return result;
    //}
    //    double xprime = sqrt(mW;

    double ptlep = Lepton.pt(),pxlep=Lepton.px(),pylep=Lepton.py(),metpx=MET.px(),metpy=MET.py();

    double EquationA = 1;
    double EquationB = -3*pylep*mW/(ptlep);
    double EquationC = mW*mW*(2*pylep*pylep)/(ptlep*ptlep)+mW*mW-4*pxlep*pxlep*pxlep*metpx/(ptlep*ptlep)-4*pxlep*pxlep*pylep*metpy/(ptlep*ptlep);
    double EquationD = 4*pxlep*pxlep*mW*metpy/(ptlep)-pylep*mW*mW*mW/ptlep;

    std::vector<long double> solutions = EquationSolve<long double>((long double)EquationA,(long double)EquationB,(long double)EquationC,(long double)EquationD);

    std::vector<long double> solutions2 = EquationSolve<long double>((long double)EquationA,-(long double)EquationB,(long double)EquationC,-(long double)EquationD);

    double deltaMin = 14000*14000;
    double zeroValue = -mW*mW/(4*pxlep); 
    double minPx=0;
    double minPy=0;

    //    std::cout<<"a "<<EquationA << " b " << EquationB  <<" c "<< EquationC <<" d "<< EquationD << std::endl; 
      
    //if(usePxMinusSolutions_){
      for( int i =0; i< (int)solutions.size();++i){
      if(solutions[i]<0 ) continue;
      double p_x = (solutions[i]*solutions[i]-mW*mW)/(4*pxlep); 
      double p_y = ( mW*mW*pylep + 2*pxlep*pylep*p_x -mW*ptlep*solutions[i])/(2*pxlep*pxlep);
      double Delta2 = (p_x-metpx)*(p_x-metpx)+(p_y-metpy)*(p_y-metpy); 

      //      std::cout<<"intermediate solution1 met x "<<metpx << " min px " << p_x  <<" met y "<<metpy <<" min py "<< p_y << std::endl; 

      if(Delta2< deltaMin && Delta2 > 0){deltaMin = Delta2;
      minPx=p_x;
      minPy=p_y;}
      //     std::cout<<"solution1 met x "<<metpx << " min px " << minPx  <<" met y "<<metpy <<" min py "<< minPy << std::endl; 
      }
    //}

    //if(usePxPlusSolutions_){
      for( int i =0; i< (int)solutions2.size();++i){
        if(solutions2[i]<0 ) continue;
        double p_x = (solutions2[i]*solutions2[i]-mW*mW)/(4*pxlep); 
        double p_y = ( mW*mW*pylep + 2*pxlep*pylep*p_x +mW*ptlep*solutions2[i])/(2*pxlep*pxlep);
        double Delta2 = (p_x-metpx)*(p_x-metpx)+(p_y-metpy)*(p_y-metpy); 
        //  std::cout<<"intermediate solution2 met x "<<metpx << " min px " << minPx  <<" met y "<<metpy <<" min py "<< minPy << std::endl; 
        if(Delta2< deltaMin && Delta2 > 0){deltaMin = Delta2;
          minPx=p_x;
          minPy=p_y;
        }
        //        std::cout<<"solution2 met x "<<metpx << " min px " << minPx  <<" met y "<<metpy <<" min py "<< minPy << std::endl; 
      }
    //}

    double pyZeroValue= ( mW*mW*pxlep + 2*pxlep*pylep*zeroValue);
    double delta2ZeroValue= (zeroValue-metpx)*(zeroValue-metpx) + (pyZeroValue-metpy)*(pyZeroValue-metpy);

    if(deltaMin==14000*14000) return TLorentzVector(0,0,0,0);
    //if(deltaMin==14000*14000) return result.front();
    //    else std::cout << " test " << std::endl;

    if(delta2ZeroValue < deltaMin){
      deltaMin = delta2ZeroValue;
      minPx=zeroValue;
      minPy=pyZeroValue;}

    //    std::cout<<" MtW2 from min py and min px "<< sqrt((minPy*minPy+minPx*minPx))*ptlep*2 -2*(pxlep*minPx + pylep*minPy)  <<std::endl;
    ///    ////Y part   

    double mu_Minimum = (mW*mW)/2 + minPx*pxlep + minPy*pylep;
    double a_Minimum  = (mu_Minimum*Lepton.pz())/(Lepton.energy()*Lepton.energy() - Lepton.pz()*Lepton.pz());
    pznu = a_Minimum;

    //if(!useMetForNegativeSolutions_){
      double Enu = sqrt(minPx*minPx+minPy*minPy + pznu*pznu);
      p4nu_rec.SetPxPyPzE(minPx, minPy, pznu , Enu);
    //}
    //else{
    //  pznu = a;
    //  double Enu = sqrt(metpx*metpx+metpy*metpy + pznu*pznu);
    //  p4nu_rec.SetPxPyPzE(metpx, metpy, pznu , Enu);
    //}
    result.push_back(p4nu_rec);
  }
  return result.front();
}
Beispiel #26
0
///
///________________________________________________________________________________
///
Bool_t
UEJetAreaFinder::find( TClonesArray& Input, vector<UEJetWithArea>& _jets )
{
  /// return if no four-vectors are provided
  if ( Input.GetSize() == 0 ) return kFALSE;

  /// prepare input
  std::vector<fastjet::PseudoJet> fjInputs;
  fjInputs.reserve ( Input.GetSize() );

  int iJet( 0 );
  for( int i(0); i < Input.GetSize(); ++i )
    {
      TLorentzVector *v = (TLorentzVector*)Input.At(i);

      if ( TMath::Abs(v->Eta()) > etaRegionInput ) continue;
      if ( v->Pt()              < ptThreshold    ) continue;

      fjInputs.push_back (fastjet::PseudoJet (v->Px(), v->Py(), v->Pz(), v->E()) );
      fjInputs.back().set_user_index(iJet);
      ++iJet;
    }

  /// return if no four-vectors in visible phase space
  if ( fjInputs.size() == 0 ) return kFALSE;
  
  /// print out info on current jet algorithm
  //   cout << endl;
  //   cout << mJetDefinition->description() << endl;
  //   cout << theAreaDefinition->description() << endl;

  /// return if active area is not chosen to be calculated
  if ( ! theAreaDefinition ) return kFALSE;

  //  cout << "fastjet::ClusterSequenceActiveArea* clusterSequence" << endl;
  
  fastjet::ClusterSequenceArea* clusterSequence
    = new fastjet::ClusterSequenceArea (fjInputs, *mJetDefinition, *theAreaDefinition );

  //  cout << "retrieve jets for selected mode" << endl;

  /// retrieve jets for selected mode
  double mJetPtMin( 1. );
  std::vector<fastjet::PseudoJet> jets( clusterSequence->inclusive_jets (mJetPtMin) );
  unsigned int nJets( jets.size() );

  if ( nJets == 0 ) 
    {
      delete clusterSequence;
      return kFALSE;
    }
  //Double_t ptByArea[ nJets ];

  //   int columnwidth( 10 );
  //cout << "found " << jets.size() << " jets" << endl;
  //   cout.width( 5 );
  //   cout << "jet";
  //   cout.width( columnwidth );
  //   cout << "eta";
  //   cout.width( columnwidth );
  //   cout << "phi";
  //   cout.width( columnwidth );
  //   cout << "pT";
  //   cout.width( columnwidth );
  //   cout << "jetArea";
  //   cout.width( 15 );
  //   cout << "pT / jetArea";
  //   cout << endl;
  
  _jets.reserve( nJets );

  vector< fastjet::PseudoJet > sorted_jets ( sorted_by_pt( jets ));
  for ( int i(0); i<nJets; ++i )
    {
      //ptByArea[i] = jets[i].perp()/clusterSequence->area(jets[i]);

      //       cout.width( 5 );
      //       cout << i;
      //       cout.width( columnwidth );
      //       cout << jets[i].eta();
      //       cout.width( columnwidth );
      //       cout << jets[i].phi();
      //       cout.width( columnwidth );
      //       cout << jets[i].perp();
      //       cout.width( columnwidth );
      //       cout << clusterSequence->area(jets[i]);
      //       cout.width( 15 );
      //       cout << ptByArea[i];
      //       cout << endl;

      /// save
      ///
      /// TLorentzVector
      /// area
      /// nconstituents
      
      fastjet::PseudoJet jet( sorted_jets[i] );
      vector< fastjet::PseudoJet > constituents( clusterSequence->constituents(jet) );
      
      TLorentzVector* mom    = new TLorentzVector( jet.px(), jet.py(), jet.pz(), jet.e() );
      double          area   = clusterSequence->area(jet);
      //  double          median = TMath::Median( nJets, ptByArea );
      unsigned int    nconst = constituents.size();
      
      UEJetWithArea* theJet = new UEJetWithArea( *mom, area, nconst);
      //_jets[i] = *theJet;
      _jets.push_back( *theJet );

      delete mom;
      delete theJet;
    }
  delete clusterSequence;

  return kTRUE;
}
Beispiel #27
0
//!PG main function
int 
  selector (TChain * tree, histos & plots, int if_signal)
{
 
 plots.v_hardTAGPt = -99;
 plots.v_softTAGPt = -99;
 plots.v_TAGDProdEta = -99;
 plots.v_TAGDeta = -99;
 plots.v_TAGMinv = -99;
 plots.v_LepLep = -99;
 plots.v_hardLEPPt = -99;
 plots.v_softLEPPt = -99;
 plots.v_LEPDPhi = -99;
 plots.v_LEPDEta = -99;
 plots.v_LEPDR = -99;
 plots.v_LEPMinv = -99;
 plots.v_LEPProdCharge = -99;
 plots.v_hardLEPCharge = -99;
 plots.v_softLEPCharge = -99;
 plots.v_MET = -99;
 
 plots.v_ojets = -99 ;
 plots.v_ojetsCJV = -99 ;
 plots.v_ojetsRegionalCJV = -99 ;
 
 plots.v_ojetsZepp_01 = -99 ;
 plots.v_ojetsZepp_02 = -99 ;
 plots.v_ojetsZepp_03 = -99 ;
 plots.v_ojetsZepp_04 = -99 ;
 plots.v_ojetsZepp_05 = -99 ;
 plots.v_ojetsZepp_06 = -99 ;
 plots.v_ojetsZepp_07 = -99 ;
 plots.v_ojetsZepp_08 = -99 ;
 plots.v_ojetsZepp_09 = -99 ;
 plots.v_ojetsZepp_10 = -99 ;
 plots.v_ojetsZepp_11 = -99 ;
 plots.v_ojetsZepp_12 = -99 ;
 plots.v_ojetsZepp_13 = -99 ;
 plots.v_ojetsZepp_14 = -99 ;
 
 plots.v_decay_Channel_e = -99 ;
 plots.v_decay_Channel_mu = -99 ;
 plots.v_decay_Channel_tau = -99 ;
 
 
 TClonesArray * genParticles = new TClonesArray ("TParticle") ;
 tree->SetBranchAddress ("genParticles", &genParticles) ;
 
 
//  TClonesArray * tagJets = new TClonesArray ("TLorentzVector") ; 
//  tree->SetBranchAddress ("tagJets", &tagJets) ;
 TClonesArray * otherJets_temp = new TClonesArray ("TLorentzVector") ;
 tree->SetBranchAddress (g_KindOfJet.c_str(), &otherJets_temp) ;
//  tree->SetBranchAddress ("otherJets", &otherJets_temp) ;
 
 
 TClonesArray * electrons = new TClonesArray ("TLorentzVector") ;
 tree->SetBranchAddress ("electrons", &electrons) ;
 TClonesArray * muons = new TClonesArray ("TLorentzVector") ;
 tree->SetBranchAddress ("muons", &muons) ;
 TClonesArray * MET = new TClonesArray ("TLorentzVector") ;
 tree->SetBranchAddress ("MET", &MET) ;
 TClonesArray * tracks = new TClonesArray ("TLorentzVector") ;
 tree->SetBranchAddress ("tracks", &tracks) ;
 
 TClonesArray * tagJets = new TClonesArray ("TLorentzVector") ; 
 TClonesArray * otherJets = new TClonesArray ("TLorentzVector") ;
 
  
 int EleId[100];
 float IsolEleSumPt_VBF[100];
 int nEle;
 int EleCharge[30];
 tree->SetBranchAddress ("nEle", &nEle) ;
 tree->SetBranchAddress ("EleId",EleId ) ;
 tree->SetBranchAddress ("IsolEleSumPt_VBF",IsolEleSumPt_VBF ) ;
 tree->SetBranchAddress ("EleCharge",EleCharge ) ;
 
 float IsolMuTr[100];
 int nMu ;
 int MuCharge[30];
 tree->SetBranchAddress ("nMu", &nMu) ;
 tree->SetBranchAddress ("IsolMuTr",IsolMuTr ) ;
 tree->SetBranchAddress ("MuCharge", MuCharge) ;
 

 int IdEvent;
 tree->SetBranchAddress ("IdEvent", &IdEvent) ;
 
 
 int nentries = (int) tree->GetEntries () ;

 
 plots.passedJetAndLepNumberSelections = 0;
 plots.analyzed = 0;
 
 plots.analyzed_ee = 0;
 plots.analyzed_mumu = 0;
 plots.analyzed_tautau = 0;
 plots.analyzed_emu = 0;
 plots.analyzed_etau = 0;
 plots.analyzed_mutau = 0;
  
 plots.passedJetAndLepNumberSelections_ee = 0;
 plots.passedJetAndLepNumberSelections_mumu = 0;
 plots.passedJetAndLepNumberSelections_tautau = 0;
 plots.passedJetAndLepNumberSelections_emu = 0;
 plots.passedJetAndLepNumberSelections_etau = 0;
 plots.passedJetAndLepNumberSelections_mutau = 0;

 
 
 //PG loop over the events
 for (int evt = 0 ; evt < nentries ; ++evt)
 {

  tree->GetEntry (evt) ;
  
  tagJets -> Clear () ;  
  otherJets -> Clear () ;    
  
  
    //---- check if signal ----
  if (if_signal && (IdEvent!=123 && IdEvent!=124)) continue;
  plots.analyzed++;
  
   //!---- MC ----

  if (IdEvent==123 || IdEvent==124) { //---- VBF event ----
   plots.v_decay_Channel_e = 0;
   plots.v_decay_Channel_mu = 0;
   plots.v_decay_Channel_tau = 0;
   for (int iGen = 0; iGen < genParticles->GetEntries() ; ++iGen){
    TParticle* myparticle = (TParticle*) genParticles->At(iGen);
    if (abs(myparticle->GetPdgCode()) == 24) { //---- W
     Int_t mother1 = 0;
     mother1 = myparticle->GetMother(0);
     if (mother1 == 25) { //---- mother is higgs ----
      for (int iDaughter = 0; iDaughter<2; iDaughter++){
       if (abs(myparticle->GetDaughter(iDaughter)) == 11) {//---- W -> e
        plots.v_decay_Channel_e++;
       }
       if (abs(myparticle->GetDaughter(iDaughter)) == 13) {//---- W -> mu    
        plots.v_decay_Channel_mu++;
       }
       if (abs(myparticle->GetDaughter(iDaughter)) == 15) {//---- W -> tau
        plots.v_decay_Channel_tau++;
       }       
      }
     }
    }
   }
  }

  if (plots.v_decay_Channel_e == 2) plots.analyzed_ee++;
  if (plots.v_decay_Channel_mu == 2) plots.analyzed_mumu++;
  if (plots.v_decay_Channel_tau == 2) plots.analyzed_tautau++;
  if (plots.v_decay_Channel_e == 1 && plots.v_decay_Channel_mu == 1) plots.analyzed_emu++;
  if (plots.v_decay_Channel_e == 1 && plots.v_decay_Channel_tau == 1) plots.analyzed_etau++;
  if (plots.v_decay_Channel_mu == 1 && plots.v_decay_Channel_tau == 1) plots.analyzed_mutau++;
  
  
  
  
  
  
  
  int cutId = 0 ;

  plots.increase (cutId++) ; //AM 0 -> total number of events


//   std::cerr << "--- preambolo leptoni " << std::endl;           
  
  std::vector<lepton> leptons ;
            
      //PG pour electrons into leptons collection
      //PG ---------------------------------------

      //PG loop over electrons
  for (int iele = 0; iele < electrons->GetEntries () ; ++iele)
  {
   TLorentzVector * theEle = (TLorentzVector*) (electrons->At (iele)) ;
   lepton dummy (theEle, 0, iele) ;
   leptons.push_back (dummy) ;
  } //PG loop over electrons

      //PG loop over muons
  for (int imu = 0 ; imu < nMu ; ++imu)
  {
   TLorentzVector * theMu = (TLorentzVector*) (muons->At (imu)) ;
   lepton dummy (theMu, 1, imu) ;
   leptons.push_back (dummy) ;
  } //PG loop over muons

//PG this check is not necessary
//PG      if (leptons.size () < 2) continue ;

  
  
//   std::cerr << "--- inizia leptoni " << std::endl;
  
  
      //PG 2 LEPTONS
      //PG ---------

/* 
applied after the leptons choice: 
  in this case it is possible to differentiate the selections depending on the 
  position of each lepton in the pt-sorting.
  the algorithm searches the first two most energetic candidates which satisfy 
  the ID selections required for the first and second lepton respectively.
  
  Then check for channel analysis according to "g_LepLep"
     0 == ee
     1 == mumu
     2 == emu
     3 == mue
  pt ordered
  
*/

  sort (leptons.rbegin (), leptons.rend (), lessThan ()) ;

  lepton primoLEP ;
  lepton secondoLEP ;

  double first_lepton_charge = 0;
  double second_lepton_charge = 0;
  
  int lepton_counter = 0;
  int electron_counter = 0;
  int muon_counter = 0;
    
      //PG find the first lepton
  int ilep = 0 ;
  for ( ; ilep < leptons.size () ; ++ilep)
  {
   if (leptons.at (ilep).m_flav == 0) //PG electron
   {
               //PG iso check
    bool eleIso = (IsolEleSumPt_VBF[leptons.at (ilep).m_index] /  
      leptons.at (ilep).m_kine->Pt () ) < g_IsoElectron ; // 0.2 per il momento
    if (g_ISO1[0] == 1 && eleIso != 1) continue;
              
              //PG eleID check
    int eleID = EleId[leptons.at (ilep).m_index] ;
    if      (g_ID1 == 100 && (eleID/100) != 1) continue;
    else if (g_ID1 == 10  && ((eleID%100)/10) != 1) continue;
    else if (g_ID1 == 1   && (eleID%10) != 1) continue;
    first_lepton_charge = EleCharge[leptons.at (ilep).m_index];
   }
   else //PG muon
   {
              //PG iso check
    bool muIso = (IsolMuTr[leptons.at (ilep).m_index] /  
      leptons.at (ilep).m_kine->Pt () ) < g_IsoMuon ; 
    if (g_ISO1[1] == 1 && muIso != 1) continue;
    first_lepton_charge = MuCharge[leptons.at (ilep).m_index];
   }  
   primoLEP = leptons[ilep] ;
   lepton_counter++;
   if (leptons.at (ilep).m_flav == 0) electron_counter++;
   else muon_counter++;
   break ;
   } //PG find the first lepton

  
      //PG find the second lepton
  bool flag_secondoLEP = false;
  for (++ilep ; ilep < leptons.size () ; ++ilep)
  {
   if (leptons.at (ilep).m_flav == 0) //PG electron
   {
               //PG iso check
    bool eleIso = (IsolEleSumPt_VBF[leptons.at (ilep).m_index] /  
      leptons.at (ilep).m_kine->Pt () ) < g_IsoElectron ; // 0.2 per il momento
    if (g_ISO2[0] == 1 && eleIso != 1) continue;
              
              //PG eleID check
    int eleID = EleId[leptons.at (ilep).m_index] ;
    if      (g_ID2 == 100 && (eleID/100) != 1) continue;
    else if (g_ID2 == 10  && ((eleID%100)/10) != 1) continue;
    else if (g_ID2 == 1   && (eleID%10) != 1) continue;
    second_lepton_charge = EleCharge[leptons.at (ilep).m_index];
   }
   else //PG muon
   {
              //PG iso check
    bool muIso = (IsolMuTr[leptons.at (ilep).m_index] /  
      leptons.at (ilep).m_kine->Pt () ) < g_IsoMuon ; 
    if (g_ISO2[1] == 1 && muIso != 1) continue;
    second_lepton_charge = MuCharge[leptons.at (ilep).m_index];
   }  
   if (!flag_secondoLEP) {
    secondoLEP = leptons[ilep] ;
    flag_secondoLEP = true;
   }
   
   if (leptons.at (ilep).m_kine->Pt () > 0) {
    if (leptons.at (ilep).m_flav == 0) electron_counter++;
    else muon_counter++;
    lepton_counter++;
    }
   
  } //PG find the second lepton

 //---- AM 3 --- 2 leptons after Id      
 if (primoLEP.m_flav == -1 || secondoLEP.m_flav == -1) continue ;
  
 //---- AM 4 check for the two most transverse-energetic leptons have the right flavours
  
 plots.v_numLep = lepton_counter;
 plots.v_numEle = electron_counter;
 plots.v_numMu = muon_counter; 
 
 if (primoLEP.m_flav == 0 && secondoLEP.m_flav == 0) plots.v_LepLep = 0 ;
 if (primoLEP.m_flav == 1 && secondoLEP.m_flav == 1) plots.v_LepLep = 1 ;
 if (primoLEP.m_flav == 0 && secondoLEP.m_flav == 1) plots.v_LepLep = 2 ;
 if (primoLEP.m_flav == 1 && secondoLEP.m_flav == 0) plots.v_LepLep = 3 ;

      
      
 plots.v_hardLEPPt = primoLEP.m_kine->Pt () ; 
   //---- AM 5 pt_min of the most energetic lepton
  
 plots.v_softLEPPt = secondoLEP.m_kine->Pt () ;
   //---- AM 6 pt_min of the least energetic lepton
   
 plots.v_LEPDPhi = deltaPhi (primoLEP.m_kine->Phi (), secondoLEP.m_kine->Phi ()) ;
  //---- AM 7 Delta_phi_min between leptons

 plots.v_LEPDEta = deltaEta (primoLEP.m_kine->Eta (), secondoLEP.m_kine->Eta ()) ;
 plots.v_LEPDR = deltaR (primoLEP.m_kine->Phi (),primoLEP.m_kine->Eta (), secondoLEP.m_kine->Phi (), secondoLEP.m_kine->Eta ()) ;

 
   
  TLorentzVector sumLEP = *(primoLEP.m_kine) + *(secondoLEP.m_kine) ;
  plots.v_LEPMinv = sumLEP.M () ;
  //---- AM 9 MInv_min of leptons
  
  
  plots.v_LEPProdCharge = first_lepton_charge * second_lepton_charge ;
  plots.v_hardLEPCharge = first_lepton_charge ;
  plots.v_softLEPCharge = second_lepton_charge ;
      
  
      //PG MET
      //PG ---

//   std::cerr << "--- finito " << std::endl;
  
  TLorentzVector* met = ((TLorentzVector*) (MET->At(0))) ;
      //correct for muons
  for (int i = 0 ; i < nMu ; i++)
  {
   TLorentzVector * mu_v = (TLorentzVector*) (muons->At (i)) ;
   
   if (mu_v->Pt () > 3)
   {
    met->SetPx (met->Px () - mu_v->Px ()) ;
    met->SetPy (met->Py () - mu_v->Py ()) ;
   }
  }      
  
  plots.v_MET = met->Pt () ;
  
  
 
  

    
    
    
  //---- AM 11 Met_min ----------------> Met correction ?
  
//      if (((TLorentzVector*) (MET->At (0)))->Pt () < g_METMin) continue ; plots.increase (cutId++) ; //PG 10
      
  
  
  
  

      //PG Ztautau vetos
      //PG -------------
      
      //PG the two electrons should not be opposite to each other
//       
//   TVector2 primoLEPT (primoLEP.m_kine->X (), primoLEP.m_kine->Y ()) ;
//   TVector2 secondoLEPT (secondoLEP.m_kine->X (), secondoLEP.m_kine->Y ()) ;
//   TVector2 METT (met->X (), met->Y ()) ;
// 
//   double Sum = METT * primoLEPT + METT * secondoLEPT / (1 + primoLEPT * secondoLEPT) ;
//   double Dif = METT * primoLEPT - METT * secondoLEPT / (1 - primoLEPT * secondoLEPT) ;
//       
//   TVector2 METT1 = 0.5 * (Sum + Dif) * primoLEPT ;
//   TVector2 METT2 = 0.5 * (Sum - Dif) * secondoLEPT ;
//       
//   double ptNu1 = METT1.Mod () / cos (primoLEP.m_kine->Theta ()) ;
//   double ptNu2 = METT2.Mod () / cos (secondoLEP.m_kine->Theta ()) ;

  
  
  
  
  plots.m_tree_selections->Fill();
  plots.passedJetAndLepNumberSelections++;

  if (plots.v_decay_Channel_e == 2) plots.passedJetAndLepNumberSelections_ee++;
  if (plots.v_decay_Channel_mu == 2) plots.passedJetAndLepNumberSelections_mumu++;
  if (plots.v_decay_Channel_tau == 2) plots.passedJetAndLepNumberSelections_tautau++;
  if (plots.v_decay_Channel_e == 1 && plots.v_decay_Channel_mu == 1) plots.passedJetAndLepNumberSelections_emu++;
  if (plots.v_decay_Channel_e == 1 && plots.v_decay_Channel_tau == 1) plots.passedJetAndLepNumberSelections_etau++;
  if (plots.v_decay_Channel_mu == 1 && plots.v_decay_Channel_tau == 1) plots.passedJetAndLepNumberSelections_mutau++;
   
    
 } //PG loop over the events


 plots.m_efficiency->Fill();
 plots.m_efficiency->Write();
 plots.m_tree_selections->Write();

 delete otherJets_temp ;
 delete tagJets  ;  
 delete otherJets  ;
 delete electrons  ;
 delete muons  ;    
 delete MET  ;      
 delete tracks  ;   

 return 0;
  
}
Beispiel #28
0
void selectAntiWm(const TString conf="wm.conf", // input file
              const TString outputDir="."       // output directory
) {
  gBenchmark->Start("selectAntiWm");

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      cout << nsel  << " +/- " << sqrt(nselvar);
      if(isam!=0) cout << " per 1/fb";
      cout << endl;
    }
    outFile->Write();
    outFile->Close();
  }
  delete h_rw;
  delete f_rw;
  delete info;
  delete gen;
  delete genPartArr;
  delete muonArr;
  delete vertexArr;
      
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
   
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << " W -> mu nu" << endl;
  cout << "  pT > " << PT_CUT << endl;
  cout << "  |eta| < " << ETA_CUT << endl;
  cout << endl;
  
  cout << endl;
  cout << "  <> Output saved in " << outputDir << "/" << endl;    
  cout << endl;  
      
  gBenchmark->Show("selectAntiWm"); 
}
int main(int argc, char* argv[])
{
  TApplication theApp(srcName.Data(), &argc, argv);
//=============================================================================

  if (argc<5) return -1;
  TString sPath = argv[1]; if (sPath.IsNull()) return -1;
  TString sFile = argv[2]; if (sFile.IsNull()) return -1;
  TString sJetR = argv[3]; if (sJetR.IsNull()) return -1;
  TString sSjeR = argv[4]; if (sSjeR.IsNull()) return -1;
//=============================================================================

  sPath.ReplaceAll("#", "/");
//=============================================================================

  double dJetR = -1.;
  if (sJetR=="JetR02") dJetR = 0.2;
  if (sJetR=="JetR03") dJetR = 0.3;
  if (sJetR=="JetR04") dJetR = 0.4;
  if (sJetR=="JetR05") dJetR = 0.5;

  if (dJetR<0.) return -1;
  cout << "Jet R = " << dJetR << endl;
//=============================================================================

  double dSjeR = -1.;
  if (sSjeR=="SjeR01") dSjeR = 0.1;
  if (sSjeR=="SjeR02") dSjeR = 0.2;
  if (sSjeR=="SjeR03") dSjeR = 0.3;
  if (sSjeR=="SjeR04") dSjeR = 0.4;

  if (dSjeR<0.) return -1;
  cout << "Sub-jet R = " << dSjeR << endl;
//=============================================================================

  const int multiLHC = 3000;
  const double dJetsPtMin  = 0.001;
  const double dCutEtaMax  = 1.6;
  const double dJetEtaMax  = 1.;
  const double dJetAreaRef = TMath::Pi() * dJetR * dJetR;

  fastjet::GhostedAreaSpec areaSpc(dCutEtaMax);
  fastjet::JetDefinition   jetsDef(fastjet::antikt_algorithm, dJetR, fastjet::BIpt_scheme, fastjet::Best);

//fastjet::AreaDefinition  areaDef(fastjet::active_area,areaSpc);
  fastjet::AreaDefinition  areaDef(fastjet::active_area_explicit_ghosts,areaSpc);

  fastjet::JetDefinition   bkgsDef(fastjet::kt_algorithm, 0.2, fastjet::BIpt_scheme, fastjet::Best);
  fastjet::AreaDefinition  aBkgDef(fastjet::active_area_explicit_ghosts, areaSpc);

  fastjet::Selector selectJet = fastjet::SelectorAbsEtaMax(dJetEtaMax);
  fastjet::Selector selectRho = fastjet::SelectorAbsEtaMax(dCutEtaMax-0.2);
  fastjet::Selector selecHard = fastjet::SelectorNHardest(2);
  fastjet::Selector selectBkg = selectRho * (!(selecHard));
  fastjet::JetMedianBackgroundEstimator bkgsEstimator(selectBkg, bkgsDef, aBkgDef);
//fastjet::Subtractor                   bkgSubtractor(&bkgsEstimator);

  fastjet::JetDefinition subjDef(fastjet::kt_algorithm, dSjeR, fastjet::BIpt_scheme, fastjet::Best);
//=============================================================================

  TRandom3 *r3 = new TRandom3(0);
  TF1 *fBkg = BackgroundSpec();
//=============================================================================

  std::vector<fastjet::PseudoJet> fjInputVac;
  std::vector<fastjet::PseudoJet> fjInputHyd;
//=============================================================================

  TList *list = new TList();
  TH1D *hWeightSum = new TH1D("hWeightSum", "", 1, 0., 1.); list->Add(hWeightSum);


//=============================================================================

  HepMC::IO_GenEvent ascii_in(Form("%s/%s.hepmc",sPath.Data(),sFile.Data()), std::ios::in);
  HepMC::GenEvent *evt = ascii_in.read_next_event();

  while (evt) {
    fjInputVac.resize(0);
    fjInputHyd.resize(0);

    double dXsect  = evt->cross_section()->cross_section() / 1e9;
    double dWeight = evt->weights().back();
    double dNorm = dWeight * dXsect;
    hWeightSum->Fill(0.5, dWeight);

    int iCount = 0;
    TLorentzVector vPseudo;
    for (HepMC::GenEvent::particle_const_iterator p=evt->particles_begin(); p!=evt->particles_end(); ++p) if ((*p)->status()==1) {
      vPseudo.SetPtEtaPhiM((*p)->momentum().perp(), (*p)->momentum().eta(), (*p)->momentum().phi(), 0.);

      if ((TMath::Abs(vPar.Eta())<dCutEtaMax)) {
        fjInputVac.push_back(fastjet::PseudoJet(vPseudo.Px(), vPseudo.Py(), vPseudo.Pz(), vPseudo.E()));
        fjInputVac.back().set_user_info(new UserInfoTrk(false));
        fjInputVac.back().set_user_index(iCount); iCount+=1;
      }
    }
//=============================================================================

    for (int i=0; i<=multiLHC; i++) {
      double dPt = fBkg->GetRandom(fgkPtBkgMin, fgkPtBkgMax); if (dPt<0.001) continue;

      vPseudo.SetPtEtaPhiM(dPt, r3->Uniform(-1.*dCutEtaMax,dCutEtaMax), r3->Uniform(0.,TMath::TwoPi()), 0.);
      fjInputHyd.push_back(fastjet::PseudoJet(vPseudo.Px(), vPseudo.Py(), vPseudo.Pz(), vPseudo.E()));
      fjInputHyd.back().set_user_info(new UserInfoTrk(true));
      fjInputHyd.back().set_user_index(-10);
    }

    fjInputHyd.insert(fjInputHyd.end(), fjInputVac.begin(),fjInputVac.end());
//=============================================================================

    fastjet::ClusterSequenceArea clustSeq(fjInputVac, jetsDef, areaDef);
    std::vector<fastjet::PseudoJet> includJetsPy = clustSeq.inclusive_jets(dJetsPtMin);
//  std::vector<fastjet::PseudoJet> subtedJetsPy = bkgSubtractor(includJetsPy);
    std::vector<fastjet::PseudoJet> selectJetsPy = selectJet(includJetsPy);
//  std::vector<fastjet::PseudoJet> sortedJetsPy = fastjet::sorted_by_pt(selectJetsPy);

    for (int j=0; j<selectJetsPy.size(); j++) {
      SetJetUserInfo(selectJetsPy[j]);
      selectJetsPy[j].set_user_index(j);
    }
//=============================================================================

    bkgsEstimator.set_particles(fjInputHyd);
    double dBkgRhoHd = bkgsEstimator.rho();
    double dBkgRmsHd = bkgsEstimator.sigma();

    fastjet::ClusterSequenceArea clustSeqHd(fjInputHyd, jetsDef, areaDef);
    std::vector<fastjet::PseudoJet> includJetsHd = clustSeqHd.inclusive_jets(dJetsPtMin);
    std::vector<fastjet::PseudoJet> selectJetsHd = selectJet(includJetsHd);

    for (int j=0; j<selectJetsHd.size(); j++) {
      SetJetUserInfo(selectJetsHd[j]);
      selectJetsHd[j].set_user_index(j);
      if (selectJetsHd[j].user_info<UserInfoJet>().IsBkg()) continue;

      for (int i=0; i<selectJetsPy.size(); i++) {
        if (CalcDeltaR(selectJetsHd[j],selectJetsPy[i])>0.8) continue;
        DoTrkMatch(selectJetsHd[j], selectJetsPy[i]);
      }
    }
//=============================================================================

  








    for (int j=0; j<sortedJets.size(); j++) {
      double dJet = sortedJets[j].pt();

      hJet->Fill(dJet, dNorm);
//=============================================================================

      fastjet::Filter trimmer(subjDef, fastjet::SelectorPtFractionMin(0.));
      fastjet::PseudoJet trimmdJet = trimmer(sortedJets[j]);
      std::vector<fastjet::PseudoJet> trimmdSj = trimmdJet.pieces();

      double nIsj = 0.;
      double d1sj = -1.; int k1sj = -1;
      double d2sj = -1.; int k2sj = -1;
      for (int i=0; i<trimmdSj.size(); i++) {
        double dIsj = trimmdSj[i].pt(); if (dIsj<0.001) continue;

        hJetIsj->Fill(dJet, dIsj, dNorm);
        hJetIsz->Fill(dJet, dIsj/dJet, dNorm);

        if (dIsj>d1sj) {
          d2sj = d1sj; k2sj = k1sj;
          d1sj = dIsj; k1sj = i;
        } else if (dIsj>d2sj) {
          d2sj = dIsj; k2sj = i;
        } nIsj += 1.;
      }

      hJetNsj->Fill(dJet, nIsj, dNorm);
      if (d1sj>0.) { hJet1sj->Fill(dJet, d1sj, dNorm); hJet1sz->Fill(dJet, d1sj/dJet, dNorm); }
      if (d2sj>0.) { hJet2sj->Fill(dJet, d2sj, dNorm); hJet2sz->Fill(dJet, d2sj/dJet, dNorm); }

      if ((d1sj>0.) && (d2sj>0.)) {
        TVector3 v1sj; v1sj.SetPtEtaPhi(d1sj, trimmdSj[k1sj].eta(), trimmdSj[k1sj].phi());
        TVector3 v2sj; v2sj.SetPtEtaPhi(d2sj, trimmdSj[k2sj].eta(), trimmdSj[k2sj].phi());

        double dsj = d1sj - d2sj;
        double dsz = dsj / dJet;
        double dsr = v1sj.DeltaR(v2sj) / 2. / dJetR;

        hJetDsj->Fill(dJet, dsj, dNorm);
        hJetDsz->Fill(dJet, dsz, dNorm);
        hJetDsr->Fill(dJet, dsz, dsr, dNorm);
      }
    }
//=============================================================================

    delete evt;
    ascii_in >> evt;
  }
//=============================================================================

  TFile *file = TFile::Open(Form("%s.root",sFile.Data()), "NEW");
  list->Write();
  file->Close();
//=============================================================================

  cout << "DONE" << endl;
  return 0;
}
int main(int argc, char *argv[])
{
  // Declaration of variables
  ExRootConfReader *confReader = 0;
  Delphes *modularDelphes = 0;
  DelphesFactory *factory = 0;
  TObjArray *allParticleOutputArray = 0;
  TObjArray *stableParticleOutputArray = 0;
  TObjArray *partonOutputArray = 0;

  Int_t event;

  TObjArray *inputArray = 0;
  TIterator *inputIterator = 0;
  Candidate *candidate = 0;
  TLorentzVector momentum;

  JetDefinition *definition = 0;
  vector<PseudoJet> inputList, outputList;
  PseudoJet jet;

  gROOT->SetBatch();

  int appargc = 1;
  char appName[] = "ExternalFastJetBasic";
  char *appargv[] = {appName};
  TApplication app(appName, &appargc, appargv);

  if(argc != 2)
  {
    cout << " Usage: " << appName << " config_file" << endl;
    cout << " config_file - configuration file in Tcl format." << endl;
    return 1;
  }

  try
  {
    // Initialization
    confReader = new ExRootConfReader;
    confReader->ReadFile(argv[1]);

    modularDelphes = new Delphes("Delphes");
    modularDelphes->SetConfReader(confReader);

    factory = modularDelphes->GetFactory();

    allParticleOutputArray = modularDelphes->ExportArray("allParticles");
    stableParticleOutputArray = modularDelphes->ExportArray("stableParticles");
    partonOutputArray = modularDelphes->ExportArray("partons");

    modularDelphes->InitTask();

    
    // fastjet definition
    ClusterSequence::print_banner();
    definition = new JetDefinition(antikt_algorithm, 0.5);
    
    // Define your input candidates to fastjet (by default particle-flow objects).
    // If you want pure calorimeter towers change "EFlowMerger/eflow" into "Calorimeter/towers":
     
    inputArray = modularDelphes->ImportArray("EFlowMerger/eflow");
      
    inputIterator = inputArray->MakeIterator();

    // Event loop
    for(event = 0; event < NEVENTS; ++event)
    {
      modularDelphes->Clear();
      
      // convert EVENT input array into Delphes internal format
      ConvertInput(event, factory, allParticleOutputArray, stableParticleOutputArray, partonOutputArray);
      
      // run Delphes reconstruction
      modularDelphes->ProcessTask();

      inputList.clear();
      inputIterator->Reset();
      
      
      // pass delphes candidates to fastjet clustering  
      while((candidate = static_cast<Candidate*>(inputIterator->Next())))
      {
        momentum = candidate->Momentum;
        jet = PseudoJet(momentum.Px(), momentum.Py(), momentum.Pz(), momentum.E());
        inputList.push_back(jet);
      }
     
      // run clustering 
      ClusterSequence sequence(inputList, *definition);
      outputList.clear();
      outputList = sorted_by_pt(sequence.inclusive_jets(0.0));

      // tell the user what was done
      //  - the description of the algorithm used
      //  - show the inclusive jets as
      //      {index, rapidity, phi, pt}
      //----------------------------------------------------------
      cout << "Ran " << definition->description() << endl;

      // label the columns
      printf("%5s %15s %15s %15s\n","jet #", "rapidity", "phi", "pt");

      // print out the details for each jet
      for (unsigned int i = 0; i < outputList.size(); i++) {
        printf("%5u %15.8f %15.8f %15.8f\n",
               i, outputList[i].rap(), outputList[i].phi(),
               outputList[i].perp());
      }
    }

    // Finalization
    modularDelphes->FinishTask();
    delete modularDelphes;
    delete confReader;
    return 0;
  }
  catch(runtime_error &e)
  {
    cerr << "** ERROR: " << e.what() << endl;
    return 1;
  }
}