TVectorD EUTelState::getStateVec() const { 
	streamlog_out( DEBUG1 ) << "EUTelState::getTrackStateVec()------------------------BEGIN" << std::endl;
	TVector3 momentum =	computeCartesianMomentum();
	TVectorD stateVec(5);
	const float lambda = asin(momentum[2]/(momentum.Mag()));//This will be in radians.
	const float phi = asin(momentum[1]/(momentum.Mag())*cos(lambda));


	stateVec[0] = getOmega();
	stateVec[1] = getIntersectionLocalXZ();
	stateVec[2] = getIntersectionLocalYZ(); 
	stateVec[3] = getPosition()[0]; 
	stateVec[4] = getPosition()[1];
			
//	if ( streamlog_level(DEBUG0) ){
//		streamlog_out( DEBUG0 ) << "Track state:" << std::endl;
//		stateVec.Print();
//	}
	if(stateVec[0] == INFINITY or stateVec[0] == NAN ){
		throw(lcio::Exception( Utility::outputColourString("Passing a state vector where curvature is not defined","RED"))); 
	}

	streamlog_out( DEBUG1 ) << "EUTelState::getTrackStateVec()------------------------END" << std::endl;
 	return stateVec;
}
Beispiel #2
0
// // //
double analysisClass::visPzeta( unsigned int iMuR, unsigned int iTauR ){
  TVector3 muT; TVector3 tauT; TVector3 unitmuT; TVector3 unittauT; TVector3 unitbisecT; TVector3 MET;
  muT.SetPtEtaPhi(  muPtcorr(iMuR),    0, MuonPhi->at(iMuR)    );
  tauT.SetPtEtaPhi( tauPtcorr(iTauR), 0, HPSTauPhi->at(iTauR) );
  unitmuT=muT*(1./muT.Mag());  unittauT=tauT*(1./tauT.Mag());
  unitbisecT=(unitmuT+unittauT)*(1./((unitmuT+unittauT).Mag()));
  MET.SetPtEtaPhi( METcorr("Pt"), 0, METcorr("Phi")  );
  double pZetaVis;
  pZetaVis = unitbisecT.Dot( (muT+tauT)     );
  return pZetaVis;
}
  //returns a projection onto the 2D plane 
  TVector3 Projection(TVector3 jaxis){
    //Find the projection of a jet onto this subspace

    if(v1.Mag() == 0) { scalar1 = 0; }   else { scalar1 = jaxis.Dot(v1)/(v1.Dot(v1)); } 
    if(v2.Mag() == 0) { scalar2 = 0; }   else { scalar2 = jaxis.Dot(v2)/(v2.Dot(v2)); } 
    v1 = scalar1*v1;
    v2 = scalar2*v2;
    proj(0) = v1(0) + v2(0);
    proj(1) = v1(1) + v2(1);
    proj(2) = v1(2) + v2(2); 
    
    return proj;
  }//end of projection
Beispiel #4
0
int get_tl_efield(TVector3 &p,TVector3 &efield)
{
  //function returns the electric field between two infinite parallel wires
  //efield normalized the jackson way with 1/cm units
  //wires extend in z-direction and are can be offset 
  double e_amp = 1. / 2.0 / M_PI * sqrt(tl_data.C / (EPS0 / M2CM));

  //calculate effective wire position for efield
  TVector3 x1(tl_data.x1, 0, 0);	//real position of first wire in cm
  TVector3 x2(tl_data.x2, 0, 0);	//real position of second wire in cm
  TVector3 l = x1 - x2;
  l *= 1./2;
  double a = sqrt(l.Mag2() - pow(tl_data.rI, 2));	//effective wire half separation in cm
  TVector3 a1 = x1 - l + a*l.Unit();	//effective position of first wire in cm
  TVector3 a2 = x1 - l - a*l.Unit();	//effective position of second wire in cm
 
  //vector from point to wires
  p.SetZ(0);
  TVector3 r1 = p + a1;
  TVector3 r2 = p + a2;
   
  //check for hitting wires 
  int status = 0;
  if ( ( (x1-r1).Mag() < tl_data.rI ) || ( (x2-r2).Mag() < tl_data.rI ) ) {
    cout << "Problem!!! Electron hit a wire! Radius " << p.Mag() << endl;
    status = 1;
  }
  //efield = e_amp * (r1 * 1/r1.Mag2() - r2 * 1/r2.Mag2());
  efield.SetX( e_amp * ( r1.X() / r1.Mag2() - r2.X() / r2.Mag2() ) );
  efield.SetY( e_amp * ( r1.Y() / r1.Mag2() - r2.Y() / r2.Mag2() ) );
  efield.SetZ( 0 );                //only true for TE or TEM modes
  return status;
}
Beispiel #5
0
int get_circ_wg_efield_vert(TVector3 &pos, TVector3 &efield)
{
  //returns the TE_11 efield inside an infinite circ. waveguide 
  //efield normalized the jackson way with 1/cm units
  //waveguide extends in x-direction
  // wavelength of 27 GHz radiation is 1.1 cm
  double p11 = 1.841;            //1st zero of the derivate of bessel function
  //k11 is angular wavenumber for cutoff frequency for TE11
  double k11 = p11 / tl_data.rO;
  //convert position to cylindrical
  pos.SetZ(0);
  double radius = pos.Mag();
  double phi = pos.Phi();//azimuthal position
  //double phi = acos(pos.Y()/radius);//azimuthal position, see definition of phase
  double J1 = TMath::BesselJ1(k11 * radius);//this term cancels in dot product w/ vel
  double Jp = TMath::BesselJ0(k11 * radius) - TMath::BesselJ1(k11 * radius) / k11 / radius;
  double e_amp = 1.63303/tl_data.rO;//cm
  int status = 0;

  if (radius > tl_data.rO) {
    cout << "Problem!!! Electron hit a wall! At radius " << radius << endl;
    status = 1;
  }
  efield.SetX(e_amp * (J1 / k11 / radius * cos(phi) * sin(phi) - Jp * sin(phi) * cos(phi)));
  efield.SetY(e_amp * (J1 / k11 / radius * sin(phi) * sin(phi) + Jp * cos(phi) * cos(phi)));
  efield.SetZ(0);                //only true for TE mode
  if (radius == 0) {
    Jp = 1.0/2; 
    phi = 0;
    efield.SetX(e_amp * (1. / 2 * cos(phi) * sin(phi) - Jp * sin(phi) * cos(phi)));
    efield.SetY(e_amp * (1. / 2 * sin(phi) * sin(phi) + Jp * cos(phi) * cos(phi)));
  }
  return status;
}
Beispiel #6
0
//_____________________________________________________________________________
void THaSpectrometer::LabToTransport( const TVector3& vertex, 
				      const TVector3& pvect,
				      TVector3& tvertex, Double_t* ray ) const
{
  // Convert lab coordinates to TRANSPORT coordinates in the spectrometer
  // coordinate system.
  // Inputs:
  //  vertex:  Reaction point in lab system
  //  pvect:   Momentum vector in lab
  // Outputs:
  //  tvertex: The vertex point in the TRANSPORT system, without any
  //           coordinate projections applied
  //  ray:     The TRANSPORT ray according to TRANSPORT conventions.
  //           This is an array of size 6 with elements x, tan(theta),
  //           y, tan(y), z, and delta.
  //           z is set to 0, and accordingly x and y are the TRANSPORT 
  //           coordinates in the z=0 plane. delta is computed with respect 
  //           to the present spectrometer's central momentum.
  //           Units are the same as of the input vectors.

  tvertex = fToTraRot * ( vertex - fPointingOffset );
  TVector3 pt = fToTraRot * pvect;
  if( pt.Z() != 0.0 ) {
    ray[1] = pt.X() / pt.Z();
    ray[3] = pt.Y() / pt.Z();
    // In the "ray", project the vertex to z=0
    ray[0] = tvertex.X() - tvertex.Z() * ray[1];
    ray[2] = tvertex.Y() - tvertex.Z() * ray[3];
  } else
    ray[0] = ray[1] = ray[2] = ray[3] = 0.0;
  
  ray[4] = 0.0;   // By definition for this ray, TRANSPORT z=0
  ray[5] = pt.Mag() / fPcentral - 1.0;
}
Beispiel #7
0
//________________________________________________________
void KVParticle::SetRandomMomentum(Double_t T, Double_t thmin,
                                   Double_t thmax, Double_t phmin,
                                   Double_t phmax, Option_t* opt)
{
   //Give randomly directed momentum to particle with kinetic energy T
   //Direction will be between (thmin,thmax) [degrees] limits in polar angle,
   //and (phmin,phmax) [degrees] limits in azimuthal angle.
   //
   //If opt = "" or "isotropic" (default) : direction is isotropically distributed over the solid angle
   //If opt = "random"                    : direction is randomly distributed over solid angle
   //
   //Based on KVPosition::GetRandomDirection().

   Double_t p = (T + M()) * (T + M()) - M2();
   if (p > 0.)
      p = (TMath::Sqrt(p));     // calculate momentum
   else
      p = 0.;

   TVector3 dir;
   KVPosition pos(thmin, thmax, phmin, phmax);
   dir = pos.GetRandomDirection(opt);   // get isotropic unit vector dir
   if (p && dir.Mag())
      dir.SetMag(p);            // set magnitude of vector to momentum required
   SetMomentum(dir);            // set momentum 4-vector
}
Beispiel #8
0
int get_coax_efield(TVector3 &p, TVector3 &efield)
{
  //function returns the electric field inside an infinite coaxial cable 
  //efield normalized the jackson way with 1/cm units
  //cable extend in z-direction 
  double e_amp = 1 / sqrt(2.0 * M_PI * log(tl_data.rO / tl_data.rI));
  int status = 0;

  p.SetZ(0);
  if (p.Mag() < tl_data.rI || p.Mag() > tl_data.rO) {
    cout << "Problem!!! Electron hit the cable! " << endl;
    status = 1;
  }
  efield.SetX( e_amp * p.X() / p.Mag2() );
  efield.SetY( e_amp * p.Y() / p.Mag2() );
  efield.SetZ( 0 );                //only true for TE or TEM modes
  return status;
}
Beispiel #9
0
// // //
double analysisClass::deltaPzeta( unsigned int iMuR, unsigned int iTauR ){
  TVector3 muT; TVector3 tauT; TVector3 unitmuT; TVector3 unittauT; TVector3 unitbisecT; TVector3 MET;
  muT.SetPtEtaPhi(  muPtcorr(iMuR),    0, MuonPhi->at(iMuR)    );
  tauT.SetPtEtaPhi( tauPtcorr(iTauR), 0, HPSTauPhi->at(iTauR) );
  unitmuT=muT*(1./muT.Mag());  unittauT=tauT*(1./tauT.Mag());
  unitbisecT=(unitmuT+unittauT)*(1./((unitmuT+unittauT).Mag()));
  MET.SetPtEtaPhi( METcorr("Pt"), 0, METcorr("Phi")  );
  double pZeta;  double pZetaVis;
  pZeta    = unitbisecT.Dot( (muT+tauT+MET) );
  pZetaVis = unitbisecT.Dot( (muT+tauT)     );
  /*std::cout<<" TauMag, MuMag: "<<unitmuT.Mag()<<" "<<unittauT.Mag()<<std::endl;
  std::cout<<"  Mu-bisec: "<<muT.DeltaPhi(unitbisecT)<<std::endl;
  std::cout<<" Tau-bisec: "<<tauT.DeltaPhi(unitbisecT)<<std::endl;
  std::cout<<"    Tau-Mu: "<<tauT.DeltaPhi(muT)<<std::endl;
  std::cout<<"(pZeta-1.5*pZetaVis): "<<(pZeta-1.5*pZetaVis)<<std::endl;
  std::cout<<std::endl;*/
  return (pZeta-1.5*pZetaVis);
}
Beispiel #10
0
double CosThetaStar(TLorentzVector p1, TLorentzVector p2){
	TLorentzVector p = p1 + p2;
	TVector3 theBoost = p.BoostVector();
	TVector3 bostDir;
	if ( theBoost.Mag() != 0 ) bostDir = theBoost.Unit(); // / theBoost.Mag());
	else return -1;
	p1.Boost(-theBoost);
	if (p1.Vect().Mag()!=0) return p1.Vect().Dot(bostDir) / p1.Vect().Mag();
	else return -1;	
}
Beispiel #11
0
Double_t LineLength(Double_t alpha, TVector3 CircleCenter,
		    Double_t CircleRadius, TVector3 LineStart) {                   

  Double_t yend = CircleRadius*1.1;
  Double_t xend = yend*TMath::Tan(TMath::DegToRad()*alpha);
  TVector3 LineEnd(xend, yend, 0);
  TVector3 rend = LineCrossesCircle(CircleCenter, CircleRadius, LineStart, LineEnd);
  if (rend != LineStart) {
    TVector3 llen = rend - LineStart;
    return llen.Mag();
  }
  return 0;
} 
//find
int EUTelState::findIntersectionWithCertainID(int nextSensorID, float intersectionPoint[], TVector3& momentumAtIntersection, float& arcLength ){
	streamlog_out(DEBUG5) << "-EUTelState::findIntersectionWithCertainID---------------------------BEGIN" << std::endl;
	TVector3 pVec = computeCartesianMomentum();
	streamlog_out(DEBUG5) << "Momentum (Global): " << pVec[0]<<","<<pVec[1]<<","<<pVec[2]<<","<<" Position (local): "<<getPosition()[0]<<","<<getPosition()[1]<<","<<getPosition()[2]<< std::endl;
	if(pVec.Mag() == 0){
		throw(lcio::Exception( Utility::outputColourString("The momentum is 0","RED"))); 
	}
	double posLocal[] =  {getPosition()[0],getPosition()[1],getPosition()[2] };
	double temp[] = {0.,0.,0.};
	geo::gGeometry().local2Master(getLocation() , posLocal, temp);//IMPORTANT:For strip sensors this will make the hit strip look like a pixel at (Xstriplocal,somevalue,somevalue).
	float posGlobal[] = { static_cast<float>(temp[0]), static_cast<float>(temp[1]), static_cast<float>(temp[2]) };
	int sensorID = geo::gGeometry().findIntersectionWithCertainID(posGlobal[0] ,  posGlobal[1] , posGlobal[2], pVec[0],pVec[1],pVec[2], getBeamCharge(), nextSensorID, intersectionPoint, momentumAtIntersection, arcLength ); 
	streamlog_out(DEBUG5) << "-EUTelState::findIntersectionWithCertainID--------------------------END" << std::endl;
	return sensorID;
}
//This sets the LOCAL frame intersection. Not the curvilinear frames intersection
void EUTelState::setLocalXZAndYZIntersectionAndCurvatureUsingGlobalMomentum(TVector3 momentumIn){
	streamlog_out(DEBUG5) << "EUTelState::setLocalXZAndYZIntersectionAndCurvatureUsingGlobalMomentum--------------------------BEGIN" << std::endl;

	//set the beam energy and curvature
	setBeamEnergy(momentumIn.Mag());
	initialiseCurvature();//You must set beam charge before you call this.
	//Now calculate the momentum in LOCAL coordinates.
	const double momentum[]	= {momentumIn[0], momentumIn[1],momentumIn[2]};//Need this since geometry works with const doubles not floats 
	double localMomentum [3];
	geo::gGeometry().master2LocalVec(getLocation(), momentum, localMomentum );
	//In the LOCAL coordinates this is just dx/dz and dy/dz in the LOCAL frame
	streamlog_out(DEBUG5) << "The local momentum (x,y,z) is: "<< localMomentum[0]<<","<< localMomentum[1] <<"," <<localMomentum[2] << std::endl;
	setIntersectionLocalXZ(localMomentum[0]/localMomentum[2]);
	setIntersectionLocalYZ(localMomentum[1]/localMomentum[2]);
	streamlog_out(DEBUG5) << "The XZ tilt is: "<< getIntersectionLocalXZ()<<" The YZ tilt is: "<<  getIntersectionLocalYZ()<< std::endl;
	streamlog_out(DEBUG5) << "EUTelState::setLocalXZAndYZIntersectionAndCurvatureUsingGlobalMomentum--------------------------END" << std::endl;
}
Beispiel #14
0
//find
bool EUTelState::findIntersectionWithCertainID(int nextSensorID, float intersectionPoint[], TVector3& momentumAtIntersection, float& arcLength, int& newNextPlaneID )
{
	TVector3 pVec = getMomGlobal();

	//TODO: better exception
	if(pVec.Mag() == 0)
	{
		throw(lcio::Exception( "The momentum is 0")); 
	}

	double posLocal[] =  {getPosition()[0],getPosition()[1],getPosition()[2] };
	double temp[] = {0.,0.,0.};

	//IMPORTANT:For strip sensors this will make the hit strip look like a pixel at (Xstriplocal,somevalue,somevalue).
	geo::gGeometry().local2Master(getLocation() , posLocal, temp);
    int charge = -1;
	float posGlobal[] = { static_cast<float>(temp[0]), static_cast<float>(temp[1]), static_cast<float>(temp[2]) };
	return  EUTelNav::findIntersectionWithCertainID(	posGlobal[0], posGlobal[1], posGlobal[2], 
								pVec[0], pVec[1], pVec[2], charge,
								nextSensorID, intersectionPoint, 
								momentumAtIntersection, arcLength, newNextPlaneID); 
}
//_________________________________________________________________
void KVRelativeVelocity::Fill(KVNucleus* cc)
{

//
// Filling method
//
//
// Use the FillVar(val) or the FillVar(val,w) method to increment the quantity
// of the global variable.
// The weight w is evaluated from the properties of the KVNucleus passed as an
// argument.
//
// For example, to evaluate the mean charge of all fragments,
// you may proceed as follows:
//
// FillVar(c->GetZ());
//
// Another example: to evaluate the mean parallel velocity weighted by the charge
// of the nucleus:
//
// FillVar(c->GetV().Z(),c->GetZ());
//
   if (!heaviest) {
      heaviest = new TList;
      heaviest->SetOwner(kFALSE);
      heaviest->Add(cc);
   }
   else {
      for (Int_t ii = 0; ii < heaviest->GetEntries(); ii += 1) {
         TVector3 ww = cc->BoostVector() - ((KVNucleus*)heaviest->At(ii))->BoostVector();
         FillVar(ww.Mag());
      }
      heaviest->Add(cc);
   }

}
Beispiel #16
0
//This is the function for MTR from the inclusive analysis
//it goes in the numerator when calculating 'R' such that:
// R = MTR/MR
// P and Q are the 4-vectors for the 2 hemispheres, or in you case,
// the two leptons - setting mass to 0 should be fine
// M is the MET 3 vector (don't forget to set the z-component of
// MET to 0)
double HWWKinematics::CalcMTR(TLorentzVector P, TLorentzVector Q, TVector3 M){
 float MTR = sqrt((M.Mag()*(P.Pt()+Q.Pt())-(P+Q).Vect().Dot(M))/2.);
 return MTR;
}
Beispiel #17
0
void RJ_ttbar(){
  setstyle();
	
  //give transverse momenta to CM system in lab frame?
  double PT = 0.1; //In units of sqrt{shat}
	
  //gamma factor associated with 'off-threshold-ness' of tops
  double gamma = 1.2;
	
  //Now, we also have the option to take gamma, event-by-event, 
  //from a more realistic distribution
  //to do this, set 'b_gamma' to true and the rest
  //of the variables below appropriately
  bool b_gamma = true;
  rootS = 13.;
  type = 1; //0 quark-antiquark  1 gluon-gluon
  M = 175./1000.; //TeV units
	
  //Number of toy events to throw
  int N = 1000;

  //
  // Generate fake events taking flat ME's for all decay angles
  //
	
  //here, we set up the stuff for dynamic gamma
  TH1D *h_gamma = (TH1D*) new TH1D("newgamma","newgamma",500,1.0,10.0);
  if(b_gamma){
    cout << "generating gamma distribution" << endl;
    for(int ibin = 1; ibin <= 500; ibin++){
      double g = h_gamma->GetBinCenter(ibin);
      double entry = Calc_dsigma_dgamma(g);
    
      if(entry > 0.)
	h_gamma->SetBinContent(ibin, entry);
    }
    cout << "done" << endl;
  }
  
  //////////////////////////////////////////////////////////////
  // Setup rest frames code
  //////////////////////////////////////////////////////////////
  cout << " Initialize lists of visible, invisible particles and intermediate states " << endl;
  RLabFrame* LAB = new RLabFrame("LAB","lab");
  RDecayFrame* TT = new RDecayFrame("TT","t #bar{t}");
  RDecayFrame* T1 = new RDecayFrame("T1","t_{a}");
  RDecayFrame* T2 = new RDecayFrame("T2","t_{b}");
  RVisibleFrame* Bjet1 = new RVisibleFrame("B1","b_{a}");
  RVisibleFrame* Bjet2 = new RVisibleFrame("B2","b_{b}");
  RDecayFrame* W1 = new RDecayFrame("W1","W_{a}");
  RDecayFrame* W2 = new RDecayFrame("W2","W_{b}");
  RVisibleFrame* Lep1 = new RVisibleFrame("L1","#it{l}_{a}");
  RVisibleFrame* Lep2 = new RVisibleFrame("L2","#it{l}_{b}");
  RInvisibleFrame* Neu1 = new RInvisibleFrame("NU1","#nu_{a}");
  RInvisibleFrame* Neu2 = new RInvisibleFrame("NU2","#nu_{b}");

  cout << " Define invisible and combinatoric groups " << endl;
  InvisibleGroup INV("INV","Invisible State Jigsaws");
  INV.AddFrame(Neu1);
  INV.AddFrame(Neu2);

  CombinatoricGroup BTAGS("BTAGS","B-tagged jet Jigsaws");
  BTAGS.AddFrame(Bjet1);
  BTAGS.SetNElementsForFrame(Bjet1,1,true);
  BTAGS.AddFrame(Bjet2);
  BTAGS.SetNElementsForFrame(Bjet2,1,true);

  cout << " Build decay tree " << endl;
  LAB->SetChildFrame(TT);

  TT->AddChildFrame(T1);
  TT->AddChildFrame(T2);
  
  T1->AddChildFrame(Bjet1);
  T1->AddChildFrame(W1);
  T2->AddChildFrame(Bjet2);
  T2->AddChildFrame(W2);
  
  W1->AddChildFrame(Lep1);
  W1->AddChildFrame(Neu1);
  W2->AddChildFrame(Lep2);
  W2->AddChildFrame(Neu2);


  //check that tree topology is consistent
  cout << "Is consistent topology: " << LAB->InitializeTree() << endl; 

  cout << "Initializing jigsaw rules" << endl; 

  InvisibleMassJigsaw MinMassJigsaw("MINMASS_JIGSAW", "Invisible system mass Jigsaw");
  INV.AddJigsaw(MinMassJigsaw);

  InvisibleRapidityJigsaw RapidityJigsaw("RAPIDITY_JIGSAW", "Invisible system rapidity Jigsaw");
  INV.AddJigsaw(RapidityJigsaw);
  RapidityJigsaw.AddVisibleFrame((LAB->GetListVisibleFrames()));
  
  
  ContraBoostInvariantJigsaw TopJigsaw("TOP_JIGSAW","Contraboost invariant Jigsaw");
  INV.AddJigsaw(TopJigsaw);
  TopJigsaw.AddVisibleFrame((T1->GetListVisibleFrames()), 0);
  TopJigsaw.AddVisibleFrame((T2->GetListVisibleFrames()), 1);
  TopJigsaw.AddInvisibleFrame((T1->GetListInvisibleFrames()), 0);
  TopJigsaw.AddInvisibleFrame((T2->GetListInvisibleFrames()), 1);

  MinimizeMassesCombinatoricJigsaw BLJigsaw("BL_JIGSAW","Minimize m_{b#it{l}}'s Jigsaw");
  BTAGS.AddJigsaw(BLJigsaw);
  BLJigsaw.AddFrame(Bjet1,0);
  BLJigsaw.AddFrame(Lep1,0);
  BLJigsaw.AddFrame(Bjet2,1);
  BLJigsaw.AddFrame(Lep2,1);

  cout << "Initializing the tree for analysis : " << LAB->InitializeAnalysis() << endl; 

  //draw tree with jigsaws
  FramePlot* jigsaw_plot = new FramePlot("tree","Decay Tree");
  jigsaw_plot->AddFrameTree(LAB);
  jigsaw_plot->AddJigsaw(TopJigsaw);
  jigsaw_plot->AddJigsaw(BLJigsaw);
  jigsaw_plot->DrawFramePlot();
	
  for(int i = 0; i < N; i++){
    if(b_gamma){
      gamma = h_gamma->GetRandom();
    }
   	
    //////////////////////////////////////////////////////////////
    // BEGIN CODE TO generate toy GEN LEVEL events
    //////////////////////////////////////////////////////////////
    double Mt1 = 175.;
    double MW1 = 80.;
    double Mt2 = 175.;
    double MW2 = 80.;
		
    double Mnu1 = 0.;
    double Mnu2 = 0.;
		
    GetLepTopHem(0, Mt1, MW1, 5., 0.005, Mnu1);
    GetLepTopHem(1, Mt2, MW2, 5., 0.005, Mnu2);
		
    double EB1 = (Mt1*Mt1 - MW1*MW1)/(2.*Mt1);
    double EB2 = (Mt2*Mt2 - MW2*MW2)/(2.*Mt2);
		
    double EVIS1 = (Mt1*Mt1 - Mnu1*Mnu1)/(Mt1);
    double EVIS2 = (Mt2*Mt2 - Mnu2*Mnu2)/(Mt2);
		
    double EW1 = (Mt1*Mt1 + MW1*MW1)/(2.*Mt1);
    double EW2 = (Mt2*Mt2 + MW2*MW2)/(2.*Mt2);
		
    double EL1 = (MW1*MW1-Mnu1*Mnu1)/(2.*MW1);
    double EL2 = (MW2*MW2-Mnu2*Mnu2)/(2.*MW2);
		
    double gamma1 = EW1/MW1;
    double gamma2 = EW2/MW2;
    double beta1 = 1.;
    double beta2 = 1.;
		
    //put them in the lab frame
    BoostToLabFrame(gamma);
		
    // effective gamma factor for parents in CM frame
    double g_eff = (P[0]+P[1]).M()/(2.*sqrt(P[0].M()*P[1].M()));
		
    PtBoost(PT);
    //////////////////////////////////////////////////////////////
    // END CODE TO generate toy GEN LEVEL event
    //////////////////////////////////////////////////////////////
        
    //////////////////////////////////////////////////////////////
    // BEGIN CODE TO analyze GEN LEVEL events
    //////////////////////////////////////////////////////////////
    
    //////////////////////////////////////////////////////////////
    // First, we calculate approximate neutrino 4-vectors
    // in W frames using two different strategies
    //////////////////////////////////////////////////////////////
        
    TLorentzVector NU1_top, NU2_top, NU1_W, NU2_W;
      
    //
    // first, we will assign 4-vectos in the lab frame for
    // NU1_top and NU2_top by drawing a contraboost invariant symmetry 
    // between the two BL systems and neutrinos. 
    // Here, the tops are assumed to have the same boost factor in TT 
    // rest frame.
    //
    for(;;){
      // get MET in lab frame 
      TVector3 MET = (vMiss[0]+vMiss[1]).Vect();
      MET.SetZ(0.0);
      // get b-quarks in lab frame
      TLorentzVector B1, B2;
      B1 = C_2[0];
      B2 = C_2[1];
      // get leptons in lab frame
      TLorentzVector L1, L2;
      L1 = C_1_1[0];
      L2 = C_1_1[1];
      //
      // We separate the objects into decay hemispheres
      // practice we will need to assign BL pairs according to
      // metric (see commented below)
      //
      
      TLorentzVector VISTOT = B1+L1+B2+L2;
      TVector3 boostTOT = VISTOT.BoostVector();
      B1.Boost(-boostTOT);
      B2.Boost(-boostTOT);
      L1.Boost(-boostTOT);
      L2.Boost(-boostTOT);
      if( (B1+L2).P() > (B1+L1).P() ){
	TLorentzVector temp = B1;
	B1 = B2;
	B2 = temp;
      }
      B1.Boost(boostTOT);
      B2.Boost(boostTOT);
      L1.Boost(boostTOT);
      L2.Boost(boostTOT);

      //
      // visible hemispheres of top decays
      //
      TLorentzVector H1 = (B1+L1);
      TLorentzVector H2 = (B2+L2);

      //
      // We will now attempt to travel through approximations of each of the rest frames 
      // of interest, beginning in the lab frame and ending in the TT rest frame, where
      // we will specify the neutrino 4-momenta according to a contraboost invariant 
      // symmetry between the visible and invisible decay products of the two tops
      //
      
      //
      // first, we boost from the lab frame to intermediate 'CMz' frame
      // i.e. with the visible hemispheres' vectoral sum zero
      //
      TVector3 BL = H1.Vect()+H2.Vect();
      BL.SetX(0.0);
      BL.SetY(0.0);
      BL = (1./(H1.E()+H2.E()))*BL;
		
      B1.Boost(-BL);
      L1.Boost(-BL);
      B2.Boost(-BL);
      L2.Boost(-BL);
      H1.Boost(-BL);
      H2.Boost(-BL);
		 
      //
      // Now, we need to 'guess' the invariant mass of the weakly interacting system
      // as a Lorentz-invariant quantity which is a function of the visible system
      // masses, and large enough to accomodate the contraboost invariant 
      // solution we will use in the following TT CM frame. This allows us to write down
      // the transverse part of the boost from lab to TT CM frame.
      //
      
      double Minv2 = (H1+H2).M2() - 4.*H1.M()*H2.M();
      //double Minv2 = (H1+H2).M2() - 4.*min(H1.M2(),H2.M2());

      //
      // transverse momentum of total TT system in lab frame
      // NOTE: (H1+H2).Pz() == 0 due to previous longitudinal boost
      //
      TVector3 PT = MET+(H1+H2).Vect();
      double Einv2 = MET.Mag2() + Minv2;
      PT.SetZ(0.0); // redundant
      //
      // transverse boost from 'CMz' frame to TT CM frame
      //
      TVector3 BT = (1./( (H1+H2).E() + sqrt(Einv2) ))*PT;
      B1.Boost(-BT);
      L1.Boost(-BT);
      B2.Boost(-BT);
      L2.Boost(-BT);
      H1.Boost(-BT);
      H2.Boost(-BT);
      
      //
      // Now, in TT CM approx frame we will make a contraboost invariant choise for the assymmetric boost, then specifying 
      // neutrino 4-vectors
      // 
      //
      // contra-boost invariant quantities (for this boost)
      //
      double m1 = H1.M();
      double m2 = H2.M();
      double MC2 = 2.*( H1.E()*H2.E() + H1.Vect().Dot(H2.Vect()) );
     
      //
      // contra-boost invariant coefficients
      //
      double k1 = m1*m1-m2*m2 + MC2 - 2.*m1*m2;
      double k2 = m2*m2-m1*m1 + MC2 - 2.*m1*m2;

      double N = ( fabs(k1*m1*m1 - k2*m2*m2) - 0.5*fabs(k2-k1)*MC2 + 0.5*(k1+k2)*sqrt(MC2*MC2-4.*m1*m1*m2*m2) )/(k1*k1*m1*m1+k2*k2*m2*m2+k1*k2*MC2);

      double c1 = 0.5*(1.+N*k1);
      double c2 = 0.5*(1.+N*k2);

      //c1 = 1;
      //c2 = 1;
		
      // 
      // adjust coefficients such that di-neutrino invariant mass is equal to the Lorentz-invariant value we chose earlier,
      // maintaining a contra-boost invariant ratio
      //
      double A = ( H1.E()+H2.E() + sqrt( (H1.E()+H2.E())*(H1.E()+H2.E()) -(H1+H2).M2() + Minv2 ))/(c1*H1.E()+c2*H2.E())/2.;

      c1 *= A;
      c2 *= A;
                
      double Enu1 = (c1-1.)*H1.E() + c2*H2.E();
      double Enu2 = c1*H1.E() + (c2-1.)*H2.E();
      TVector3 pnu1 = (c1-1.)*H1.Vect() - c2*H2.Vect();
      TVector3 pnu2 = (c2-1.)*H2.Vect() - c1*H1.Vect();

      //
      // define neutrino 4-vectors
      //
      NU1_top.SetPxPyPzE(pnu1.X(),pnu1.Y(),pnu1.Z(),Enu1);
      NU2_top.SetPxPyPzE(pnu2.X(),pnu2.Y(),pnu2.Z(),Enu2);

      //
      // now, transform neutrinos back into lab frame
      //
      NU1_top.Boost(BT);
      NU2_top.Boost(BT);
      NU1_top.Boost(BL);
      NU2_top.Boost(BL);
            
      break;
    }
		
    //
    // Next, we will assign 4-vectos in the lab frame for
    // NU1_W and NU2_W by drawing a contraboost invariant symmetry 
    // between the two L systems and neutrinos. 
    // Here, the W's are assumed to have the same boost factor in the WW  
    // rest frame.
    //
    for(;;){
      TVector3 MET = (vMiss[0]+vMiss[1]).Vect();
      MET.SetZ(0.0);
      //get b-quarks in lab frame
      TLorentzVector B1, B2;
      B1 = C_2[0];
      B2 = C_2[1];
      //get leptons in lab frame
      TLorentzVector L1, L2;
      L1 = C_1_1[0];
      L2 = C_1_1[1];
      //
      // We separate the objects into decay hemispheres
      // practice we will need to assign BL pairs according to
      // metric (see commented below)
      //
      TLorentzVector VISTOT = B1+L1+B2+L2;
      TVector3 boostTOT = VISTOT.BoostVector();
      B1.Boost(-boostTOT);
      B2.Boost(-boostTOT);
      L1.Boost(-boostTOT);
      L2.Boost(-boostTOT);
      if( (B1+L2).P() > (B1+L1).P() ){
	TLorentzVector temp = B1;
	B1 = B2;
	B2 = temp;
      }
      B1.Boost(boostTOT);
      B2.Boost(boostTOT);
      L1.Boost(boostTOT);
      L2.Boost(boostTOT);
      //
      // visible hemispheres of top decays
      //
      TLorentzVector H1 = (B1+L1);
      TLorentzVector H2 = (B2+L2);
            
      //
      // We will now attempt to travel through approximations of each of the rest frames 
      // of interest, beginning in the lab frame and ending in the WW rest frame, where
      // we will specify the neutrino 4-momenta according to a contraboost invariant 
      // symmetry between the visible and invisible decay products of the two W's
      //
      
      //
      // first, we boost from the lab frame to intermediate 'CMz' frame
      // i.e. with the visible hemispheres' vectoral sum zero
      //
      TVector3 BL = H1.Vect()+H2.Vect();
      BL.SetX(0.0);
      BL.SetY(0.0);
      BL = (1./(H1.E()+H2.E()))*BL;
            
      B1.Boost(-BL);
      L1.Boost(-BL);
      B2.Boost(-BL);
      L2.Boost(-BL);
      H1.Boost(-BL);
      H2.Boost(-BL);
            
      //
      // Now, we need to 'guess' the invariant mass of the weakly interacting system
      // as a Lorentz-invariant quantity which is a function of the visible system
      // masses, and large enough to accomodate the contraboost invariant 
      // solution we will use in the following WW CM frame. This allows us to write down
      // the transverse part of the boost from lab to WW CM frame.
      //
      double Minv2 = (L1+L2).M2();
      TVector3 PT = MET+(L1+L2).Vect();
      double Einv2 = MET.Mag2() + Minv2;
     
      TVector3 BT = (1./( (L1+L2).E() + sqrt(Einv2) ))*PT;
      L1.Boost(-BT);
      L2.Boost(-BT);
      //
      // Now, in WW CM approx frame we will make a contraboost invariant choise for the assymmetric boost, then specifying 
      // neutrino 4-vectors
      // 
      //
      // contra-boost invariant coefficients are both 1, scaling factor to fix di-neutrino invariant mass
      // is 1, since (L1+L2).M2() = Minv2
      //
      double c = ( L1.E()+L2.E() + sqrt( (L1.E()+L2.E())*(L1.E()+L2.E()) -(L1+L2).M2() + Minv2 ))/(L1.E()+L2.E())/2.; //obviously redundant
            
      double Enu1 = (c-1.)*L1.E() + c*L2.E();
      double Enu2 = c*L1.E() + (c-1.)*L2.E();
      TVector3 pnu1 = (c-1.)*L1.Vect() - c*L2.Vect();
      TVector3 pnu2 = (c-1.)*L2.Vect() - c*L1.Vect();
            
      //define neutrino 4-vectors
      NU1_W.SetPxPyPzE(pnu1.X(),pnu1.Y(),pnu1.Z(),Enu1);
      NU2_W.SetPxPyPzE(pnu2.X(),pnu2.Y(),pnu2.Z(),Enu2);
            
      //now, go back to lab frame
      NU1_W.Boost(BT);
      NU2_W.Boost(BT);
      NU1_W.Boost(BL);
      NU2_W.Boost(BL);
            
      break;
    }
    //
    // Now we have our guess for the neutrino 4-vectors in the lab frame
    // using two different approaches (top or W symmetry, NUi_top and NUi_W
    // 4-vectors, respectively), along with the 'truth' values.
    // We will now go through all of the relevant reference frames in our approximate 
    // reconstructions and in truth simultaenously to calculate observables
    //
    TLorentzVector B1, B2;
    B1 = C_2[0];
    B2 = C_2[1];
    //get leptons in lab frame
    TLorentzVector L1, L2;
    L1 = C_1_1[0];
    L2 = C_1_1[1];
    //get truth neutrinos in lab frame
    TLorentzVector NU1, NU2;
    NU1 = C_1_2[0];
    NU2 = C_1_2[1];

    TVector3 MET = (vMiss[0]+vMiss[1]).Vect();
    MET.SetZ(0.0);

    INV.ClearEvent();
    BTAGS.ClearEvent();

    Lep1->SetLabFrameFourVector(L1);
    Lep2->SetLabFrameFourVector(L2);
    GroupElementID B1_ID = BTAGS.AddLabFrameFourVector(B1);
    GroupElementID B2_ID = BTAGS.AddLabFrameFourVector(B2);
    INV.SetLabFrameThreeVector(MET);

    LAB->AnalyzeEvent();

    //
    // Now we have two different sets of neutrino guesses in lab frame - define matching visible particles
    //
    TLorentzVector B1_top = B1;
    TLorentzVector B2_top = B2;
    TLorentzVector L1_top = L1;
    TLorentzVector L2_top = L2;
    TLorentzVector B1_W = B1;
    TLorentzVector B2_W = B2;
    TLorentzVector L1_W = L1;
    TLorentzVector L2_W = L2;
    //
    // We separate the objects into decay hemispheres
    // practice we will need to assign BL pairs according to
    // metric for 'reconstructed' events (see commented below)
    //
    
      TLorentzVector VISTOT_top = B1_top+L1_top+B2_top+L2_top;
      TVector3 boostTOT_top = VISTOT_top.BoostVector();
      B1_top.Boost(-boostTOT_top);
      B2_top.Boost(-boostTOT_top);
      L1_top.Boost(-boostTOT_top);
      L2_top.Boost(-boostTOT_top);
      if( (B1_top+L2_top).P() > (B1_top+L1_top).P() ){
	TLorentzVector temp = B1_top;
	B1_top = B2_top;
	B2_top = temp;
      }
      B1_top.Boost(boostTOT_top);
      B2_top.Boost(boostTOT_top);
      L1_top.Boost(boostTOT_top);
      L2_top.Boost(boostTOT_top);

      /*
      if( (B1_W+L1_W).M2()+(B2_W+L2_W).M2() > (B1_W+L2_W).M2()+(B2_W+L1_W).M2() ){
	TLorentzVector temp = L1_W;
	L1_W = L2_W;
	L2_W = temp;
      }
    */
    //
    // visible hemispheres of top decays
    //
    TLorentzVector H1 = L1+B1+NU1;
    TLorentzVector H2 = L2+B2+NU2;
    TLorentzVector H1_top = L1_top+B1_top+NU1_top;
    TLorentzVector H2_top = L2_top+B2_top+NU2_top;
    TLorentzVector H1_W = L1+B1+NU1_W;
    TLorentzVector H2_W = L2+B2+NU2_W;
    
    
    cout << "TT mass: " << (H1_top+H2_top).M() << " " << TT->GetMass() << endl;
    cout << "T1 mass: " << H1_top.M() << " " << T1->GetMass() << endl;
    cout << "T2 mass: " << H2_top.M() << " " << T2->GetMass() << endl;
    cout << "W1 mass: " << (L1_top+NU1_top).M() << " " << W1->GetMass() << endl;
    cout << "W2 mass: " << (L2_top+NU2_top).M() << " " << W2->GetMass() << endl;
    cout << "NU1 mass: " << NU1_top.M() << " " << Neu1->GetMass() << endl;
    cout << "NU2 mass: " << NU2_top.M() << " " << Neu2->GetMass() << endl;
    cout << "MET: " << (Neu1->GetFourVector(LAB)+Neu2->GetFourVector(LAB)).Pt() << " " << MET.Mag() << endl;
    
    /*
    cout << "TT mass: " << (H1_W+H2_W).M() << " " << TT->GetMass() << endl;
    cout << "T1 mass: " << H1_W.M() << " " << T1->GetMass() << endl;
    cout << "T2 mass: " << H2_W.M() << " " << T2->GetMass() << endl;
    cout << "W1 mass: " << (L1+NU1_W).M() << " " << W1->GetMass() << endl;
    cout << "W2 mass: " << (L2+NU2_W).M() << " " << W2->GetMass() << endl;
    cout << "NU1 mass: " << NU1_W.M() << " " << Neu1->GetMass() << endl;
    cout << "NU2 mass: " << NU2_W.M() << " " << Neu2->GetMass() << endl;
    */
    //
    // In the lab frame - let's move now to the ttbar CM frame
    // boosts
    //
    TVector3 BltoCM = (H1+H2).BoostVector();
    TVector3 BltoCM_top = (H1_top+H2_top).BoostVector();
    TVector3 BltoCM_W = (H1_W+H2_W).BoostVector();

    H1.Boost(-BltoCM);
    H2.Boost(-BltoCM);
    L1.Boost(-BltoCM);
    L2.Boost(-BltoCM);
    NU1.Boost(-BltoCM);
    NU2.Boost(-BltoCM);
    B1.Boost(-BltoCM);
    B2.Boost(-BltoCM);
    H1_top.Boost(-BltoCM_top);
    H2_top.Boost(-BltoCM_top);
    L1_top.Boost(-BltoCM_top);
    L2_top.Boost(-BltoCM_top);
    B1_top.Boost(-BltoCM_top);
    B2_top.Boost(-BltoCM_top);
    NU1_top.Boost(-BltoCM_top);
    NU2_top.Boost(-BltoCM_top);
    H1_W.Boost(-BltoCM_W);
    H2_W.Boost(-BltoCM_W);
    L1_W.Boost(-BltoCM_W);
    L2_W.Boost(-BltoCM_W);
    B1_W.Boost(-BltoCM_W);
    B2_W.Boost(-BltoCM_W);
    NU1_W.Boost(-BltoCM_W);
    NU2_W.Boost(-BltoCM_W);

    //
    // angles in the TT CM frames, approximate and true
    //
    double costhetaTT = H1.Vect().Unit().Dot( BltoCM.Unit() );
    double dphiTT = fabs(H1.Vect().DeltaPhi( BltoCM ));
    double dphiM  = fabs( (B1+B2+L1+L2).Vect().DeltaPhi( BltoCM ));
    double costhetaTT_top = fabs( H1_top.Vect().Unit().Dot( BltoCM_top.Unit() ));
    double dphiTT_top = fabs(H1_top.Vect().DeltaPhi( BltoCM_top ));
    double dphiM_top  = fabs( (B1_top+B2_top+L1_top+L2_top).Vect().DeltaPhi( BltoCM_top ));
    double costhetaTT_W = fabs( H1_W.Vect().Unit().Dot( BltoCM_W.Unit() ));
    double dphiTT_W = fabs(H1_W.Vect().DeltaPhi( BltoCM_W ));
    double dphiM_W  = fabs( (B1_W+B2_W+L1_W+L2_W).Vect().DeltaPhi( BltoCM_W ));
    //scale
    double MTT = (H1+H2).M();
    double MTT_top = (H1_top+H2_top).M();
    double MTT_W = (H1_W+H2_W).M();
    
    // vector normal to decay plane of CM frame (for later azimuthal angles)
    TVector3 vNORM_CM_T1 = B1.Vect().Cross((L1+NU1).Vect());
    TVector3 vNORM_CM_T2 = B2.Vect().Cross((L2+NU2).Vect());
    double dphi_T1_T2 = vNORM_CM_T1.Angle(vNORM_CM_T2);
    double dot_dphi_T1_T2 = B1.Vect().Dot(vNORM_CM_T2);
    if(dot_dphi_T1_T2 < 0.0 && dphi_T1_T2 > 0.0){
      dphi_T1_T2 = TMath::Pi()*2. - dphi_T1_T2;
    }
    TVector3 vNORM_CM_T1_top = B1_top.Vect().Cross((L1_top+NU1_top).Vect());
    TVector3 vNORM_CM_T2_top = B2_top.Vect().Cross((L2_top+NU2_top).Vect());
    double dphi_T1_T2_top = vNORM_CM_T1_top.Angle(vNORM_CM_T2_top);
    double dot_dphi_T1_T2_top = B1_top.Vect().Dot(vNORM_CM_T2_top);
    if(dot_dphi_T1_T2_top < 0.0 && dphi_T1_T2_top > 0.0){
      dphi_T1_T2_top = TMath::Pi()*2. - dphi_T1_T2_top;
    }
    TVector3 vNORM_CM_T1_W = B1_W.Vect().Cross((L1_W+NU1_W).Vect());
    TVector3 vNORM_CM_T2_W = B2_W.Vect().Cross((L2_W+NU2_W).Vect());
    double dphi_T1_T2_W = vNORM_CM_T1_W.Angle(vNORM_CM_T2_W);
    double dot_dphi_T1_T2_W = B1.Vect().Dot(vNORM_CM_T2_W);
    if(dot_dphi_T1_T2_W < 0.0 && dphi_T1_T2_W > 0.0){
      dphi_T1_T2_W = TMath::Pi()*2. - dphi_T1_T2_W;
    }
    
    double ddphi_T1_T2_top = sin(dphi_T1_T2_top-dphi_T1_T2);
    double ddphi_T1_T2_W = sin(dphi_T1_T2_W-dphi_T1_T2);

    //
    // To the next frames!!!!
    // now, to 'top' CM frame approxs and truth
    //
    TVector3 BCMtoT1 = H1.BoostVector();
    TVector3 BCMtoT2 = H2.BoostVector();
    TVector3 BCMtoT1_top = H1_top.BoostVector();
    TVector3 BCMtoT2_top = H2_top.BoostVector();
    TVector3 BCMtoT1_W = H1_W.BoostVector();
    TVector3 BCMtoT2_W = H2_W.BoostVector();

    B1.Boost(-BCMtoT1);
    B2.Boost(-BCMtoT2);
    L1.Boost(-BCMtoT1);
    L2.Boost(-BCMtoT2);
    NU1.Boost(-BCMtoT1);
    NU2.Boost(-BCMtoT2);
    B1_top.Boost(-BCMtoT1_top);
    B2_top.Boost(-BCMtoT2_top);
    L1_top.Boost(-BCMtoT1_top);
    L2_top.Boost(-BCMtoT2_top);
    NU1_top.Boost(-BCMtoT1_top);
    NU2_top.Boost(-BCMtoT2_top);
    B1_W.Boost(-BCMtoT1_W);
    B2_W.Boost(-BCMtoT2_W);
    L1_W.Boost(-BCMtoT1_W);
    L2_W.Boost(-BCMtoT2_W);
    NU1_W.Boost(-BCMtoT1_W);
    NU2_W.Boost(-BCMtoT2_W);

    cout <<  W1->GetFourVector(T1).E() << " " << (L1_top+NU1_top).E() << endl;
    cout <<  W2->GetFourVector(T2).E() << " " << (L2_top+NU2_top).E() << endl;

    //
    // decay angles in top frames
    //
    double costhetaT1 = B1.Vect().Unit().Dot(BCMtoT1.Unit());
    double costhetaT2 = B2.Vect().Unit().Dot(BCMtoT2.Unit());
    double costhetaT1_top = B1_top.Vect().Unit().Dot(BCMtoT1_top.Unit());
    double costhetaT2_top = B2_top.Vect().Unit().Dot(BCMtoT2_top.Unit());
    double costhetaT1_W = B1_W.Vect().Unit().Dot(BCMtoT1_W.Unit());
    double costhetaT2_W = B2_W.Vect().Unit().Dot(BCMtoT2_W.Unit());
    double dcosthetaT1_top = costhetaT1_top*sqrt(1.-costhetaT1*costhetaT1)-costhetaT1*sqrt(1.-costhetaT1_top*costhetaT1_top);
    double dcosthetaT2_top = costhetaT2_top*sqrt(1.-costhetaT2*costhetaT2)-costhetaT2*sqrt(1.-costhetaT2_top*costhetaT2_top);
    double dcosthetaT1_W = costhetaT1_W*sqrt(1.-costhetaT1*costhetaT1)-costhetaT1*sqrt(1.-costhetaT1_W*costhetaT1_W);
    double dcosthetaT2_W = costhetaT2_W*sqrt(1.-costhetaT2*costhetaT2)-costhetaT2*sqrt(1.-costhetaT2_W*costhetaT2_W);

    //vectors normal to decay planes of T frames
    TVector3 vNORM_T1_B = B1.Vect().Cross(BCMtoT1);
    TVector3 vNORM_T2_B = B2.Vect().Cross(BCMtoT2);
    TVector3 vNORM_T1_B_top = B1_top.Vect().Cross(BCMtoT1_top);
    TVector3 vNORM_T2_B_top = B2_top.Vect().Cross(BCMtoT2_top);
    TVector3 vNORM_T1_B_W = B1_W.Vect().Cross(BCMtoT1_W);
    TVector3 vNORM_T2_B_W = B2_W.Vect().Cross(BCMtoT2_W);
    //vectors normal to W decay planes in T frames
    TVector3 vNORM_T1_W = L1.Vect().Cross(NU1.Vect());
    TVector3 vNORM_T2_W = L2.Vect().Cross(NU2.Vect());
    TVector3 vNORM_T1_W_top = L1_top.Vect().Cross(NU1_top.Vect());
    TVector3 vNORM_T2_W_top = L2_top.Vect().Cross(NU2_top.Vect());
    TVector3 vNORM_T1_W_W = L1_W.Vect().Cross(NU1_W.Vect());
    TVector3 vNORM_T2_W_W = L2_W.Vect().Cross(NU2_W.Vect());

    double dphi_W_T1 = vNORM_T1_W.Angle(vNORM_T1_B);
    double dphi_W_T2 = vNORM_T2_W.Angle(vNORM_T2_B);
    double dot_dphi_W_T1 = L1.Vect().Dot(vNORM_T1_B);
    double dot_dphi_W_T2 = L2.Vect().Dot(vNORM_T2_B);
    if(dot_dphi_W_T1 < 0.0 && dphi_W_T1 > 0.0){
      dphi_W_T1 = TMath::Pi()*2. - dphi_W_T1;
    }
    if(dot_dphi_W_T2 < 0.0 && dphi_W_T2 > 0.0){
      dphi_W_T2 = TMath::Pi()*2. - dphi_W_T2;
    }
    double dphi_W_T1_top = vNORM_T1_W_top.Angle(vNORM_T1_B_top);
    double dphi_W_T2_top = vNORM_T2_W_top.Angle(vNORM_T2_B_top);
    double dot_dphi_W_T1_top = L1_top.Vect().Dot(vNORM_T1_B_top);
    double dot_dphi_W_T2_top = L2_top.Vect().Dot(vNORM_T2_B_top);
    if(dot_dphi_W_T1_top < 0.0 && dphi_W_T1_top > 0.0){
      dphi_W_T1_top = TMath::Pi()*2. - dphi_W_T1_top;
    }
    if(dot_dphi_W_T2_top < 0.0 && dphi_W_T2_top > 0.0){
      dphi_W_T2_top = TMath::Pi()*2. - dphi_W_T2_top;
    }
    double dphi_W_T1_W = vNORM_T1_W_W.Angle(vNORM_T1_B_W);
    double dphi_W_T2_W = vNORM_T2_W_W.Angle(vNORM_T2_B_W);
    double dot_dphi_W_T1_W = L1_W.Vect().Dot(vNORM_T1_B_W);
    double dot_dphi_W_T2_W = L2_W.Vect().Dot(vNORM_T2_B_W);
    if(dot_dphi_W_T1_W < 0.0 && dphi_W_T1_W > 0.0){
      dphi_W_T1_W = TMath::Pi()*2. - dphi_W_T1_W;
    }
    if(dot_dphi_W_T2_W < 0.0 && dphi_W_T2_W > 0.0){
      dphi_W_T2_W = TMath::Pi()*2. - dphi_W_T2_W;
    }

    //
    // differences between true and reco azimuthal angles
    //
    double ddphi_W_T1_top = sin(dphi_W_T1_top-dphi_W_T1);
    double ddphi_W_T2_top = sin(dphi_W_T2_top-dphi_W_T2);
    double ddphi_W_T1_W = sin(dphi_W_T1_W-dphi_W_T1);
    double ddphi_W_T2_W = sin(dphi_W_T2_W-dphi_W_T2);
    
    //
    // gamma for asymmetric boost
    //
    double gammaT = 1./pow( (1.-BCMtoT1.Mag2())*(1.-BCMtoT2.Mag2()),1./4. );
    double gammaT_top = 1./sqrt(1.-BCMtoT1_top.Mag2());
    double gammaT_W = 1./pow( (1.-BCMtoT1_W.Mag2())*(1.-BCMtoT2_W.Mag2()),1./4. );
    //
    // scale variables
    //
    double MT1 = H1.M();
    double MT2 = H2.M();
    double MT_top = H1_top.M();
    double MT1_W = H1_W.M();
    double MT2_W = H2_W.M();
  
    double Eb1 = B1.E();
    double Eb2 = B2.E();
    double Eb1_top = B1_top.E();
    double Eb2_top = B2_top.E();
    double Eb1_W = B1_W.E();
    double Eb2_W = B2_W.E();

    //
    // Heading to the last frames!!!!!
    // from the T rest frames to the W rest frames
    //
    TVector3 BTtoW1 = (L1+NU1).BoostVector();
    TVector3 BTtoW2 = (L2+NU2).BoostVector();
    TVector3 BTtoW1_top = (L1_top+NU1_top).BoostVector();
    TVector3 BTtoW2_top = (L2_top+NU2_top).BoostVector();
    TVector3 BTtoW1_W = (L1_W+NU1_W).BoostVector();
    TVector3 BTtoW2_W = (L2_W+NU2_W).BoostVector();

    L1.Boost(-BTtoW1);
    NU1.Boost(-BTtoW1);
    L2.Boost(-BTtoW2);
    NU2.Boost(-BTtoW2);
    L1_top.Boost(-BTtoW1_top);
    NU1_top.Boost(-BTtoW1_top);
    L2_top.Boost(-BTtoW2_top);
    NU2_top.Boost(-BTtoW2_top);
    L1_W.Boost(-BTtoW1_W);
    NU1_W.Boost(-BTtoW1_W);
    L2_W.Boost(-BTtoW2_W);
    NU2_W.Boost(-BTtoW2_W);

    //
    // scales in the W rest frame
    //
    double El1 = L1.E();
    double El2 = L2.E();
    double El1_top = L1_top.E();
    double El2_top = L2_top.E();
    double El1_W = L1_W.E();
    double El2_W = L2_W.E();
    
    //calculate some angles
    double costhetaW1 = L1.Vect().Unit().Dot(BTtoW1.Unit());
    double costhetaW2 = L2.Vect().Unit().Dot(BTtoW2.Unit());
    double costhetaW1_top = L1_top.Vect().Unit().Dot(BTtoW1_top.Unit());
    double costhetaW2_top = L2_top.Vect().Unit().Dot(BTtoW2_top.Unit());
    double costhetaW1_W = L1_W.Vect().Unit().Dot(BTtoW1_W.Unit());
    double costhetaW2_W = L2_W.Vect().Unit().Dot(BTtoW2_W.Unit());
    double dcosthetaW1_top = costhetaW1*sqrt(1.-costhetaW1_top*costhetaW1_top) - costhetaW1_top*sqrt(1.-costhetaW1*costhetaW1);
    double dcosthetaW2_top = costhetaW2*sqrt(1.-costhetaW2_top*costhetaW2_top) - costhetaW2_top*sqrt(1.-costhetaW2*costhetaW2);
    double dcosthetaW1_W = costhetaW1*sqrt(1.-costhetaW1_W*costhetaW1_W) - costhetaW1_W*sqrt(1.-costhetaW1*costhetaW1);
    double dcosthetaW2_W = costhetaW2*sqrt(1.-costhetaW2_W*costhetaW2_W) - costhetaW2_W*sqrt(1.-costhetaW2*costhetaW2);

    // define different scale sensitive ratios
    double El1Eb1_top = El1_top/(El1_top+Eb1_top);
    double El1Eb1_W = El1_W/(El1_W+Eb1_W);
    double El1Eb2_top = El1_top/(El1_top+Eb2_top);
    double El1Eb2_W = El1_W/(El1_W+Eb2_W);

    
    cout << "TT costheta: " << costhetaTT_top << " " << TT->GetCosDecayAngle() << endl;
    cout << "T1 costheta: " << costhetaT1_top << " " << T1->GetCosDecayAngle() << endl;
    cout << "T2 costheta: " << costhetaT2_top << " " << T2->GetCosDecayAngle() << endl;
    cout << "dphi_T1_T2_top: " << dphi_T1_T2_top << " " << T1->GetDeltaPhiDecayPlanes(T2) << endl;
    cout << "dphi_W_T1_top: " << dphi_W_T1_top << " " << T1->GetDeltaPhiDecayPlanes(W1) << endl;
   
    
    TLorentzVector newB1 = Bjet1->GetFourVector(T1);
    TLorentzVector newB2 = Bjet2->GetFourVector(T2);
    TLorentzVector newL1 = Lep1->GetFourVector(W1);
    TLorentzVector newL2 = Lep2->GetFourVector(W2);
    TLorentzVector newNU1 = Neu1->GetFourVector(W1);
    TLorentzVector newNU2 = Neu2->GetFourVector(W2);
    cout << "Eb1: " << Eb1_top << " " << newB1.E() << endl;
    cout << "Eb2: " << Eb2_top << " " << newB2.E() << endl;
    cout << "El1: " << El1_top << " " << newL1.E() << endl;
    cout << "El2: " << El2_top << " " << newL2.E() << endl;
    cout << "ENU1: " << NU1_top.E() << " " << newNU1.E() << endl;
    cout << "ENU2: " << NU2_top.E() << " " << newNU2.E() << endl;
    
  }
}
Beispiel #18
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.1;
  const double dJetEtaMax  = 2.;
  const double dCutEtaMax  = 2.6;

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

  fastjet::Selector selectJet = fastjet::SelectorAbsEtaMax(dJetEtaMax);
  fastjet::JetDefinition subjDef(fastjet::kt_algorithm, dSjeR, fastjet::BIpt_scheme, fastjet::Best);
//=============================================================================

  std::vector<fastjet::PseudoJet> fjInput;
//=============================================================================

  TFile *file = TFile::Open(Form("%s.root",sFile.Data()), "NEW");
  TList *list = new TList();

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

  TH2D *hTrkPtEta = new TH2D("hTrkPtEta", "", 1000, 0., 500., 60, -3., 3.); hTrkPtEta->Sumw2(); list->Add(hTrkPtEta);
  TH2D *hTrkPtPhi = new TH2D("hTrkPtPhi", "", 1000, 0., 500., 20, -1., 1.); hTrkPtPhi->Sumw2(); list->Add(hTrkPtPhi);

  TH2D *hJetPtNsj = new TH2D("hJetPtNsj", "", 1000, 0., 1000., 100, -0.5, 99.5); hJetPtNsj->Sumw2(); list->Add(hJetPtNsj);


  TH2D *hJetPtEta = new TH2D("hJetPtEta", "", 1000, 0., 1000., 60, -3., 3.); hJetPtEta->Sumw2(); list->Add(hJetPtEta);
  TH2D *hJetPtPhi = new TH2D("hJetPtPhi", "", 1000, 0., 1000., 20, -1., 1.); hJetPtPhi->Sumw2(); list->Add(hJetPtPhi);

  TH2D *hLjePtEta = new TH2D("hLjePtEta", "", 1000, 0., 1000., 60, -3., 3.); hLjePtEta->Sumw2(); list->Add(hLjePtEta);
  TH2D *hLjePtPhi = new TH2D("hLjePtPhi", "", 1000, 0., 1000., 20, -1., 1.); hLjePtPhi->Sumw2(); list->Add(hLjePtPhi);

  TH2D *hNjePtEta = new TH2D("hNjePtEta", "", 1000, 0., 1000., 60, -3., 3.); hNjePtEta->Sumw2(); list->Add(hNjePtEta);
  TH2D *hNjePtPhi = new TH2D("hNjePtPhi", "", 1000, 0., 1000., 20, -1., 1.); hNjePtPhi->Sumw2(); list->Add(hNjePtPhi);


  TH2D *hJe2PtEta = new TH2D("hJe2PtEta", "", 1000, 0., 1000., 60, -3., 3.); hJe2PtEta->Sumw2(); list->Add(hJe2PtEta);
  TH2D *hJe2PtPhi = new TH2D("hJe2PtPhi", "", 1000, 0., 1000., 20, -1., 1.); hJe2PtPhi->Sumw2(); list->Add(hJe2PtPhi);

  TH2D *hLj2PtEta = new TH2D("hLj2PtEta", "", 1000, 0., 1000., 60, -3., 3.); hLj2PtEta->Sumw2(); list->Add(hLj2PtEta);
  TH2D *hLj2PtPhi = new TH2D("hLj2PtPhi", "", 1000, 0., 1000., 20, -1., 1.); hLj2PtPhi->Sumw2(); list->Add(hLj2PtPhi);

  TH2D *hNj2PtEta = new TH2D("hNj2PtEta", "", 1000, 0., 1000., 60, -3., 3.); hNj2PtEta->Sumw2(); list->Add(hNj2PtEta);
  TH2D *hNj2PtPhi = new TH2D("hNj2PtPhi", "", 1000, 0., 1000., 20, -1., 1.); hNj2PtPhi->Sumw2(); list->Add(hNj2PtPhi);
//=============================================================================

  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);
    double dWeight = evt->weights().back();
    double dXsect  = evt->cross_section()->cross_section() / 1e9;
    double dNorm   = dWeight * dXsect;
    hWeightSum->Fill(0.5, dWeight);

    TVector3 vTrk;
    for (HepMC::GenEvent::particle_const_iterator p=evt->particles_begin(); p!=evt->particles_end(); ++p) if ((*p)->status()==1) {
      double dTrkPt  = (*p)->momentum().perp(); if (dTrkPt<0.5) continue;
      double dTrkEta = (*p)->momentum().eta();  if (TMath::Abs(dTrkEta)>dCutEtaMax) continue;
      double dTrkPhi = (*p)->momentum().phi();  vTrk.SetPtEtaPhi(dTrkPt, dTrkEta, dTrkPhi);
      double dTrkCos = TMath::Cos(dTrkPhi); if (dTrkCos==1.) dTrkCos = 1. - 1e-6;

      fjInput.push_back(fastjet::PseudoJet(vTrk.Px(), vTrk.Py(), vTrk.Pz(), vTrk.Mag()));

      hTrkPtEta->Fill(dTrkPt, dTrkEta, dNorm);
      hTrkPtPhi->Fill(dTrkPt, dTrkCos, dNorm);
    }
//=============================================================================

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

    for (int j=0; j<sortedJets.size(); j++) {
      double dJetPt  = sortedJets[j].pt();
      double dJetEta = sortedJets[j].eta();
      double dJetPhi = sortedJets[j].phi();
      double dJetCos = TMath::Cos(dJetPhi);
      if (dJetCos==1.) dJetCos = 1. - 1e-6;

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

      int nSje = 0;
      for (int i=0; i<trimmdSj.size(); i++) if (trimmdSj[i].pt()>0.1) { nSje += 1; }
      hJetPtNsj->Fill(dJetPt, nSje, dNorm);

      hJetPtEta->Fill(dJetPt, dJetEta, dNorm); hJetPtPhi->Fill(dJetPt, dJetCos, dNorm);
      if (j==0) { hLjePtEta->Fill(dJetPt, dJetEta, dNorm); hLjePtPhi->Fill(dJetPt, dJetCos, dNorm); }
      if (j==1) { hNjePtEta->Fill(dJetPt, dJetEta, dNorm); hNjePtPhi->Fill(dJetPt, dJetCos, dNorm); }

      if (nSje>=2) {
        hJe2PtEta->Fill(dJetPt, dJetEta, dNorm); hJe2PtPhi->Fill(dJetPt, dJetCos, dNorm);
        if (j==0) { hLj2PtEta->Fill(dJetPt, dJetEta, dNorm); hLj2PtPhi->Fill(dJetPt, dJetCos, dNorm); }
        if (j==1) { hNj2PtEta->Fill(dJetPt, dJetEta, dNorm); hNj2PtPhi->Fill(dJetPt, dJetCos, dNorm); }
      }
    }
//=============================================================================

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

  file->cd(); list->Write(); file->Close();
//=============================================================================

  cout << "DONE" << endl;
//=============================================================================

  return 0;
}
Beispiel #19
0
void algo_test() {
  
  // Vector A starts at (0.0,0.5,0.5) and points along (1,1,1) (too simple ?)
  // Vector B starts at (2,1,1) and points along (0.5, 0.5, 4)
  TVector3 dir_a(1.0,1.0,1.0);  // (1.0,1.0,1.0)
  TVector3 dir_b(0.5, 0.5, 4.0); // (0.5, 0.5, 4.0) 

  TVector3 unit_a = dir_a.Unit();
  TVector3 unit_b = dir_b.Unit();

  // check for parallel vectors and bow out if they are
  TVector3 cross = unit_a.Cross(unit_b);
  // account for floats
  if (cross.Mag() < 0.01)  {
    cout << "These vectors seem to be parallel, there won't be a vertex !" << endl; 
    exit(0);
  }


  TVector3 start_a(0.0, 0.5, 0.5);  
  TVector3 start_b(2.0, 1.0, 1.0); 
  TVector3 start_diff = start_a - start_b;

  float ta = ( -(start_diff*unit_a) + (start_diff *  unit_b) * (unit_a * unit_b) )/ 
    ( 1.0 - ( (unit_a * unit_b) *  (unit_a * unit_b)) );
  float tb =   ( (start_diff*unit_b) - (start_diff *  unit_a) * (unit_a * unit_b) )/ 
    ( 1.0 - ( (unit_a * unit_b) *  (unit_a * unit_b)) );

  TVector3 close_a = start_a + (ta *  unit_a);
  TVector3 close_b = start_b + (tb * unit_b);
  
  // now what I really want to store as a vertex is the middle of the Vector going from close_a to close_b
  

  cout << "Closest point on Vector A = " << close_a.X() << ", " << close_a.Y() << " ," << close_a.Z() << endl;
  cout << "Closest point on Vector B = " << close_b.X() << ", " << close_b.Y() << " ," << close_b.Z() << endl;

  TVector3 from_a_to_b = close_b - close_a;
  // conceptually that's more of a point than a vector
  TVector3 vertex = close_a + 0.5 * from_a_to_b;
  cout << "The vertex is here:  " << vertex.X() << ", " <<  vertex.Y() << ", " <<  vertex.Z() << endl;

  // now try this with the find_vertex function
  line_vec line_a(start_a, start_a+dir_a);
  line_vec line_b(start_b, start_b+dir_b);
  
  TVector3 vertex_again = find_vertex(line_a, line_b);
  

  // test the clustering algorithm
  TVector3 vec_a(1.0, 1.0, 1.0);
  TVector3 vec_b(2.0, 2.0, 2.0);
  TVector3 vec_c(3.0, 3.0, 3.0);
  TVector3 vec_a1(1.1, 1.0, 1.0);
  TVector3 vec_b1(2.1, 2.0, 2.0);
  TVector3 vec_c1(3.1, 3.0, 3.0);
  TVector3 vec_a2(1.1, 1.2, 1.0);
  TVector3 vec_b2(2.1, 2.2, 2.0);
  TVector3 vec_c2(3.1, 3.0, 3.2);
  TVector3 vec_a3(3.1, 1.2, 1.0);
  TVector3 vec_b3(3.1, 2.3, 2.0);
  TVector3 vec_c3(3.4, 3.4, 3.4);
  TVector3 vec_a4(2.1, 2.2, 2.0);
  TVector3 vec_b4(2.1, 2.3, 2.0);
  TVector3 vec_c4(2.4, 2.4, 2.4);

  vector<TVector3> points;
  points.push_back(vec_a);  points.push_back(vec_b);  points.push_back(vec_c);
  points.push_back(vec_a1);  points.push_back(vec_b1);  points.push_back(vec_c1);
  points.push_back(vec_a2);  points.push_back(vec_b2);  points.push_back(vec_c2);
  points.push_back(vec_a3);  points.push_back(vec_b3);  points.push_back(vec_c3);
  points.push_back(vec_a4);  points.push_back(vec_b4);  points.push_back(vec_c4);

  vector<TVector3> good_points = find_cluster(points, 1.0);
  cout << good_points.size() << endl;
  TVector3 vertex_av = vertex_ave(good_points);
  cout << "Cluster average: " << vertex_av.X() << " " << vertex_av.Y() << " " << vertex_av.Z() << endl; 


  vector<TVector3> test_ave;
  test_ave.push_back(vec_a);
  test_ave.push_back(vec_b);
  test_ave.push_back(vec_c);
  TVector3 av = vertex_ave(test_ave);
  cout << "vertex_ave test: " <<  av.X() << " " << av.Y() << " " << av.Z() << endl; 


  // Line defined by two points - how far is the third point away ?
  TVector3 point_one(1.0, 1.0, 1.0);
  TVector3 point_two(2.0, 1.0, 1.0);
  TVector3 point_three(1.5, 1.5, 1.0);
  TVector3 point_four(1.5, 1.0, 1.0);
  TVector3 point_five(3.0, 1.7, 1.0);
  // thanks to Wolfram Alpha
  // line is x1, x2, point is x0
  // x = cross prduct
  // d = |(x2 - x1) x (x1 - x0)| / | x2-x1 |

  Float_t d1 =  ((point_two - point_one).Cross(point_one - point_three)).Mag() /
    (point_two - point_one).Mag();
  cout << "d1: " << d1 << endl;
  Float_t d2 =  ((point_two - point_one).Cross(point_one - point_four)).Mag() /
      (point_two - point_one).Mag();
  cout << "d2: " << d2 << endl;
  Float_t d3 =  ((point_two - point_one).Cross(point_one - point_five)).Mag() /
    (point_two - point_one).Mag();
  cout << "d3: " << d3 << endl;


}
TH1F* AnalyzeDs1pToDstKs(TChain* fChain,TString DATAorMC,Int_t MatterOrAntiMatter,TString Mode,TString NtupleDir,Int_t WhichCuts){

  Int_t test;
  
  //
  Bool_t TruthMatch=false;
  if(DATAorMC=="MC")TruthMatch=true;
 
  // Declaration of leave types
  Float_t beamSX;
  Float_t beamSY;
  Float_t beamSZ;

  Int_t   nDs1p;
  Float_t Ds1pChi2[400];  
  Float_t Ds1pMass[400];  
  Float_t Ds1pcosth[400];  
  Float_t Ds1pcosthCM[400];  
  Float_t Ds1pp3CM[400];  
  Float_t Ds1pphiCM[400];  
  Int_t   Ds1pLund[400];  
  Int_t   Ds1pMCIdx[400];  
  Int_t   Ds1pd1Lund[400];  
  Int_t   Ds1pd1Idx[400];  
  Int_t   Ds1pd2Lund[400];  
  Int_t   Ds1pd2Idx[400];  
  Float_t Ds1pVtxx[500];  
  Float_t Ds1pVtxy[500];  
  Float_t Ds1pVtxz[500];     

  Int_t   nKs;
  Float_t KsMass[400]; 
  Float_t Ksp3CM[400]; 
  Int_t   KsLund[400]; 
  Int_t   Ksd1Lund[400]; 
  Int_t   Ksd1Idx[400]; 
  Int_t   Ksd2Lund[400]; 
  Int_t   Ksd2Idx[400];  
  Int_t   KsMCIdx[400];
  Float_t KsChi2[400];
  Int_t   KsnDof[400];
  Float_t KsVtxx[500]; 
  Float_t KsVtxy[500]; 
  Float_t KsVtxz[500]; 
  Float_t Kscosth[500]; 
  Float_t Ksphi[500]; 

  Int_t   nDstar;
  Float_t DstarMass[400];  
  Float_t DstarMassErr[400];  
  Float_t Dstarcosth[400];  
  Float_t Dstarp3[400];  
  Float_t Dstarp3CM[400];  
  Int_t   DstarLund[400];  
  Int_t   Dstard1Lund[400];  
  Int_t   Dstard1Idx[400];  
  Int_t   Dstard2Lund[400];  
  Int_t   Dstard2Idx[400];    
  Int_t   DstarMCIdx[400];
 
  Int_t   nD0;
  Float_t D0Mass[400];  
  Float_t D0MassErr[400];  
  Float_t D0p3CM[400];  
  Int_t   D0Lund[400];  
  Int_t   D0d1Lund[400];  
  Int_t   D0d1Idx[400];  
  Int_t   D0d2Lund[400];  
  Int_t   D0d2Idx[400];   
  Int_t   D0d3Lund[400];  
  Int_t   D0d3Idx[400];
  Int_t   D0d4Lund[400];     
  Int_t   D0d4Idx[400];
  Int_t   D0MCIdx[400];
  Float_t D0Chi2[400];
  Int_t   D0nDof[400];

  Int_t   nPi;
  Float_t Pip3[400];  
  Int_t   PiLund[400];   
  Int_t   PiMCIdx[400];
  Int_t   PiTrkIdx[400];
  Int_t   PiSelectorsMap[400];
  
  Int_t   nK;
  Float_t Kp3[400]; 
  Int_t   KLund[400]; 
  Int_t   KMCIdx[400];
  Int_t   KTrkIdx[400];

  Int_t   nPi0;
  Float_t Pi0Mass[400];
  Float_t Pi0p3[400];  
  Int_t   Pi0Lund[400];  
  Int_t   Pi0MCIdx[400];
  Int_t   Pi0d1Lund[400];
  Int_t   Pi0d1Idx[400];

  Float_t GammaECal[400];
  Int_t   GammaMCIdx[400];
  Int_t   GammaLund[400];

  Int_t TRKnSvt[400];
  Int_t TRKLund[400];
  

  ////MC block
  Int_t mcLen;
  Int_t mcLund[400];
  Int_t mothIdx[400];
  Int_t dauLen[400];
  Int_t dauIdx[400];
  Float_t mcmass[400]; 
  Float_t mccosth[400];
  Float_t mcp3[400];
  Float_t mccosthCM[400];
  Float_t mcp3CM[400]; 


 

  //////My derived variables
  Float_t D0Probab;
  Float_t KsProbab;
  Float_t KsCosine;  
  TVector3 Ksp3Direction;
  TVector3 KsFlightDirection;

  Int_t MCDs1pCounterPerEvent=0;
  Int_t MCDs1pCounterTotal=0;
  Int_t RecoDs1pCounterTotal=0;


  Int_t   Ds1pIdx;
  Int_t   DstarIdx;
  Int_t   KsIdx;
  Int_t   D0Idx;
  Int_t   PiIdx;
  Int_t   SlowPiIdx;
  Int_t   KIdx;
  Int_t   Pi0Idx;
  Int_t   GammaIdx;  
  Int_t   PitrkIdx;
  Int_t   SlowPitrkIdx;
  Int_t   KsPi1Idx;
  Int_t   KsPi2Idx;
  Int_t   KsPi1trkIdx;
  Int_t   KsPi2trkIdx;

  //TChain* fChain=DstToD0PiChain(firstfile,lastfile, DATAorMC,Mode, ModeSubDir);
  if(fChain==NULL){
    cout<<"No chain."<<endl;
    return NULL;
  }
  fChain->SetBranchAddress("beamSX",&beamSX);
  fChain->SetBranchAddress("beamSY",&beamSY);
  fChain->SetBranchAddress("beamSZ",&beamSZ);

  fChain->SetBranchAddress("nDs1p",&nDs1p);
  fChain->SetBranchAddress("Ds1pMass",Ds1pMass);
  fChain->SetBranchAddress("Ds1pcosthCM",Ds1pcosthCM);
  fChain->SetBranchAddress("Ds1pp3CM",Ds1pp3CM);
  fChain->SetBranchAddress("Ds1pLund",Ds1pLund); 
  fChain->SetBranchAddress("Ds1pd1Lund",Ds1pd1Lund);
  fChain->SetBranchAddress("Ds1pd1Idx",Ds1pd1Idx);
  fChain->SetBranchAddress("Ds1pd2Lund",Ds1pd2Lund);
  fChain->SetBranchAddress("Ds1pd2Idx",Ds1pd2Idx);
  fChain->SetBranchAddress("Ds1pVtxx",Ds1pVtxx);
  fChain->SetBranchAddress("Ds1pVtxy",Ds1pVtxy);
  fChain->SetBranchAddress("Ds1pVtxz",Ds1pVtxz);


  fChain->SetBranchAddress("nKs",&nKs);
  fChain->SetBranchAddress("KsMass",KsMass);
  fChain->SetBranchAddress("Ksp3CM",Ksp3CM);  
  fChain->SetBranchAddress("KsLund",KsLund);
  fChain->SetBranchAddress("Ksd1Lund",Ksd1Lund);
  fChain->SetBranchAddress("Ksd1Idx",Ksd1Idx);
  fChain->SetBranchAddress("Ksd2Lund",Ksd2Lund);
  fChain->SetBranchAddress("Ksd2Idx",Ksd2Idx);
  fChain->SetBranchAddress("KsChi2",KsChi2);
  fChain->SetBranchAddress("KsnDof",KsnDof);
  fChain->SetBranchAddress("KsMCIdx",KsMCIdx);
  fChain->SetBranchAddress("KsVtxx",KsVtxx);
  fChain->SetBranchAddress("KsVtxy",KsVtxy);
  fChain->SetBranchAddress("KsVtxz",KsVtxz);
  fChain->SetBranchAddress("Kscosth",Kscosth);
  fChain->SetBranchAddress("Ksphi",Ksphi);


  fChain->SetBranchAddress("nDstar",&nDstar);
  fChain->SetBranchAddress("DstarMass",DstarMass);
  fChain->SetBranchAddress("DstarLund",DstarLund);
  fChain->SetBranchAddress("Dstard1Lund",Dstard1Lund);
  fChain->SetBranchAddress("Dstard1Idx",Dstard1Idx);
  fChain->SetBranchAddress("Dstard2Lund",Dstard2Lund);
  fChain->SetBranchAddress("Dstard2Idx",Dstard2Idx);

  fChain->SetBranchAddress("nD0",&nD0);
  fChain->SetBranchAddress("D0Mass",D0Mass);
  fChain->SetBranchAddress("D0p3CM",D0p3CM);  
  fChain->SetBranchAddress("D0Lund",D0Lund);
  fChain->SetBranchAddress("D0d1Lund",D0d1Lund);
  fChain->SetBranchAddress("D0d1Idx",D0d1Idx);
  fChain->SetBranchAddress("D0d2Lund",D0d2Lund);
  fChain->SetBranchAddress("D0d2Idx",D0d2Idx);
  fChain->SetBranchAddress("D0Chi2",D0Chi2);
  fChain->SetBranchAddress("D0nDof",D0nDof);

  fChain->SetBranchAddress("nPi",&nPi);
  fChain->SetBranchAddress("Pip3",Pip3);
  fChain->SetBranchAddress("PiLund",PiLund);
  fChain->SetBranchAddress("PiTrkIdx",PiTrkIdx);

  fChain->SetBranchAddress("nK",&nK);
  fChain->SetBranchAddress("Kp3",Kp3);
  fChain->SetBranchAddress("KLund",KLund);
  fChain->SetBranchAddress("KTrkIdx",KTrkIdx);

  fChain->SetBranchAddress("TRKnSvt",TRKnSvt);
  fChain->SetBranchAddress("TRKLund",TRKLund);
  fChain->SetBranchAddress("piSelectorsMap",PiSelectorsMap);

 
  if(Mode=="D0ToKPiPi0"){
    fChain->SetBranchAddress("D0d3Lund",D0d3Lund);
    fChain->SetBranchAddress("D0d3Idx",D0d3Idx);
    fChain->SetBranchAddress("nPi0",&nPi0);
    fChain->SetBranchAddress("Pi0Mass",Pi0Mass);
    fChain->SetBranchAddress("Pi0p3",Pi0p3);
    fChain->SetBranchAddress("Pi0Lund",Pi0Lund);
    fChain->SetBranchAddress("Pi0d1Lund",Pi0d1Lund);
    fChain->SetBranchAddress("Pi0d1Idx",Pi0d1Idx);
    fChain->SetBranchAddress("GammaLund",GammaLund);
    fChain->SetBranchAddress("GammaECal",GammaECal);
 
    if(TruthMatch){
      fChain->SetBranchAddress("Pi0MCIdx",Pi0MCIdx);    
      fChain->SetBranchAddress("GammaMCIdx", GammaMCIdx);
   
    }

  }
  if(Mode=="D0ToK3Pi"){
    fChain->SetBranchAddress("D0d3Lund",D0d3Lund);
    fChain->SetBranchAddress("D0d3Idx",D0d3Idx);
    fChain->SetBranchAddress("D0d4Lund",D0d4Lund);
    fChain->SetBranchAddress("D0d4Idx",D0d4Idx);
  }

  if(TruthMatch){
    fChain->SetBranchAddress("Ds1pMCIdx",Ds1pMCIdx);
    fChain->SetBranchAddress("DstarMCIdx",DstarMCIdx);
    fChain->SetBranchAddress("D0MCIdx",D0MCIdx);
    fChain->SetBranchAddress("KMCIdx",KMCIdx);
    fChain->SetBranchAddress("PiMCIdx",PiMCIdx);
    fChain->SetBranchAddress("mcLund",mcLund);
    fChain->SetBranchAddress("mcLen",&mcLen);
    fChain->SetBranchAddress("mcp3",mcp3);
    fChain->SetBranchAddress("mccosth",mccosth);
    fChain->SetBranchAddress("mcp3CM",mcp3CM);
    fChain->SetBranchAddress("mccosthCM",mccosthCM); 
  }
  
 
  //Histosgrams
  Float_t DstarMassWindow=.090;  
  Float_t D0MassWindow=.090;
  Float_t KsMassWindow=.030;
  Int_t NMassBins=62;
  Float_t Ds1pMassLo=2.470;  
  Float_t Ds1pMassHi=2.600;  
  Int_t NDs1pMassBins=70;


  //////Cuts
  ///Loose
  Float_t D0p3CMCut=0.;
  Float_t D0ProbabCut=0.;
  Float_t KsProbabCut=0.;
  Float_t KsCosineCut=0.;

  ///Define Signal Region
  Float_t Ds1pMassCutLo=0.;
  Float_t Ds1pMassCutHi=0.;
  Float_t Ds1pMassResolution=0.;
  //////////////
  

  if(Mode=="D0ToKPi"){
    //loose
    if(WhichCuts==1){       
      D0p3CMCut=2.4; 
      D0ProbabCut=5e-3; 
      KsProbabCut=5e-3; 
      KsCosineCut=0; 
    }
    Ds1pMassResolution=.009;
    Ds1pMassCutLo=Ds1pPDGMass-4*Ds1pMassResolution;
    Ds1pMassCutHi=Ds1pPDGMass+4*Ds1pMassResolution;

  }
  if(Mode=="D0ToKPiPi0"){
    //loose
    if(WhichCuts==1){       
      D0p3CMCut=2.2; 
      D0ProbabCut=5e-3; 
      KsProbabCut=5e-3; 
      KsCosineCut=0; 
    }
    Ds1pMassResolution=.013;
    Ds1pMassCutLo=Ds1pPDGMass-4*Ds1pMassResolution;
    Ds1pMassCutHi=Ds1pPDGMass+4*Ds1pMassResolution;

  }

  if(Mode=="D0ToK3Pi"){
    //loose
    if(WhichCuts==1){       
      D0p3CMCut=2.2; 
      D0ProbabCut=5e-3; 
      KsProbabCut=5e-3; 
      KsCosineCut=0; 
    }
    Ds1pMassResolution=.006;
    Ds1pMassCutLo=Ds1pPDGMass-4*Ds1pMassResolution;
    Ds1pMassCutHi=Ds1pPDGMass+4*Ds1pMassResolution;

  }
  

  //////////////  
  //BeamPlots  
  TH1F HBeamRadius;
  SetHistoXY(&HBeamRadius,"Beam R",100,0,.5,"R (cm)","Entries/50#mu m");
  
  TH1F HBeamZ;
  SetHistoXY(&HBeamZ,"Beam Z",100,-4.,4.,"Z (cm)","Entries/1mm");
   
  ////Kaon
  TH1F HKMomentum;
  SetHistoXY(&HKMomentum,"K Momentum ",80,0,8,"p (GeV/c)","Entries/100MeV");

  TH1F HKMomentumTruthMatched;
  SetHistoXY(&HKMomentumTruthMatched,"K Momentum ",80,0,8,"p (GeV/c)","Entries/100MeV");
  
  /////pion 
  TH1F HPiMomentum;
  SetHistoXY(&HPiMomentum," Pion Momentum ",80,0,8,"p (GeV/c)","Entries/100MeV");

  TH1F HPiMomentumTruthMatched;
  SetHistoXY(&HPiMomentumTruthMatched," Pion Momentum ",80,0,8,"p (GeV/c)","Entries/100MeV");

  ///////////Mode dependent histos
  ////////////Mode=="D0ToKPiPi0"
  ////Gamma
  TH1F HGammaEnergy;
  SetHistoXY(&HGammaEnergy,"Gamma Energy",30,0,1.2,"calor. energy (GeV/c^{2})","Entries/40MeV");

  TH1F HGammaEnergyTruthMatched;
  SetHistoXY(&HGammaEnergyTruthMatched,"Gamma Energy",30,0,1.2,"calor. energy (GeV/c^{2})","Entries/40MeV");
  
  ////Pi0 
  TH1F HPi0MassPreCuts;
  SetHistoXY(&HPi0MassPreCuts,"Pi0 Mass After Cuts ",120,.075,.195," mass (GeV/c^{2})","Entries/1MeV");

  TH1F HPi0Mass;
  SetHistoXY(&HPi0Mass,"Pi0 Mass After Cuts ",120,.075,.195," mass (GeV/c^{2})","Entries/1MeV");

  TH1F HPi0MassTruthMatched;
  SetHistoXY(&HPi0MassTruthMatched,"Pi0 Mass After Cuts ",120,.075,.195," mass (GeV/c^{2})","Entries/1MeV");
  
 
  /////D0 
  TH1F HD0p3CM;
  SetHistoXY(&HD0p3CM,"D0 CM Momentum ",80,0,8,"p* (GeV/c)","Entries/100MeV");

  TH1F HD0MassPreCuts;
  SetHistoXY(&HD0MassPreCuts,"D0 Mass Before Cuts",NMassBins,D0PDGMass-D0MassWindow-.001,D0PDGMass+D0MassWindow+.001,"D0 Cand. Mass (GeV/c^{2})","Entries/1MeV");

  TH1F HD0Mass;
  SetHistoXY(&HD0Mass,"D0 Mass After Cuts ",NMassBins,D0PDGMass-D0MassWindow-.001,D0PDGMass+D0MassWindow+.001,"D0 Cand. Mass (GeV/c^{2})","Entries/1MeV");

  TH1F HD0MassTruthMatched;
  SetHistoXY(&HD0MassTruthMatched,"D0 Mass After Cuts ",NMassBins,D0PDGMass-D0MassWindow-.001,D0PDGMass+D0MassWindow+.001,"D0 Cand. Mass (GeV/c^{2})","Entries/1MeV");

  TH1F HD0Probab;
  SetHisto(&HD0Probab,"D0 Vtx Probab ",200,-8,0,"log(p(#chi^{2}))");


  //slow pion
  TH1F HSlowPiMomentum;
  SetHistoXY(&HSlowPiMomentum,"Slow Pion Momentum ",30,0,1.2,"p (GeV/c)","Entries/40MeV");

  TH1F HSlowPiMomentumTruthMatched;
  SetHistoXY(&HSlowPiMomentumTruthMatched,"Slow Pion Momentum ",30,0,1.2,"p (GeV/c)","Entries/40MeV");

  ////Dstar
  TH1F HDstarMassPreCuts;
  SetHistoXY(&HDstarMassPreCuts,"D* Mass Before Cuts",NMassBins,DstarPDGMass-DstarMassWindow-.001,DstarPDGMass+DstarMassWindow+.001,"D* Cand. Mass (GeV/c^{2})","Entries/1MeV");
  HDstarMassPreCuts.SetLineColor(1);

  TH1F HDstarMass;
  SetHistoXY(&HDstarMass,"D* Mass After Cuts",NMassBins,DstarPDGMass-DstarMassWindow-.001,DstarPDGMass+DstarMassWindow+.001,"D* Cand. Mass (GeV/c^{2})","Entries/1MeV");
  HDstarMass.SetLineColor(1);
  
  TH1F HDstarMassTruthMatched;
  SetHistoXY(&HDstarMassTruthMatched,"D* Mass After Cuts and Truth Matched",NMassBins,DstarPDGMass-DstarMassWindow-.001,DstarPDGMass+DstarMassWindow+.001,"D* Cand. Mass (GeV/c^{2})","Entries/1MeV");
  HDstarMassTruthMatched.SetLineColor(1);

  TH1F HMassDiff;
  SetHistoXY(&HMassDiff,"#Delta M After Cuts",300,.139,.160,"D* Cand. Mass - D0 Cand. Mass (GeV/c^{2})","Entries/.1MeV");  


  /////pion1 
  TH1F HPi1Momentum;
  SetHistoXY(&HPi1Momentum," Pion1 Momentum ",100,0,2,"p (GeV/c)","Entries/20MeV");

  TH1F HPi1MomentumTruthMatched;
  SetHistoXY(&HPi1MomentumTruthMatched," Pion1 Momentum ",100,0,2,"p (GeV/c)","Entries/20MeV");

  /////Ks 
  TH1F HKsp3CM;
  SetHistoXY(&HKsp3CM,"Ks CM Momentum ",80,0,8,"p* (GeV/c)","Entries/100MeV");

  TH1F HKsMassPreCuts;
  SetHistoXY(&HKsMassPreCuts,"Ks Mass Before Cuts",NMassBins,K0PDGMass-KsMassWindow-.001,K0PDGMass+KsMassWindow+.001,"Ks Cand. Mass (GeV/c^{2})","Entries/1MeV");

  TH1F HKsMass;
  SetHistoXY(&HKsMass,"Ks Mass After Cuts ",NMassBins,K0PDGMass-KsMassWindow-.001,K0PDGMass+KsMassWindow+.001,"Ks Cand. Mass (GeV/c^{2})","Entries/1MeV");

  TH1F HKsMassTruthMatched;
  SetHistoXY(&HKsMassTruthMatched,"Ks Mass After Cuts ",NMassBins,K0PDGMass-KsMassWindow-.001,K0PDGMass+KsMassWindow+.001,"Ks Cand. Mass (GeV/c^{2})","Entries/1MeV");

  TH1F HKsCosine;
  SetHistoXY(&HKsCosine,"Ks Direction",100,-1.00001,1.00001,"cos(#theta)","Entries/.02");

  TH1F HKsProbab;
  SetHisto(&HKsProbab,"Ks Vtx Probab ",200,-8,0,"log(p(#chi^{2}))");

 
  ////Ds1p
  TH1F HDs1pMassPreCuts;
  SetHistoXY(&HDs1pMassPreCuts,"D'_{s1} Mass Before Cuts",NDs1pMassBins,Ds1pMassLo,Ds1pMassHi,"Ds1p Cand. Mass (GeV/c^{2})","Entries/1MeV");
  HDs1pMassPreCuts.SetLineColor(1);

  TH1F HDs1pMassPID;
  SetHistoXY(&HDs1pMassPID,"D'_{s1} Mass After Cuts",NDs1pMassBins,Ds1pMassLo,Ds1pMassHi,"Ds1p Cand. Mass (GeV/c^{2})","Entries/1MeV");
  HDs1pMassPID.SetLineColor(1);

  TH1F HDs1pMass;
  SetHistoXY(&HDs1pMass,"D'_{s1} Mass After Cuts",NDs1pMassBins,Ds1pMassLo,Ds1pMassHi,"Ds1p Cand. Mass (GeV/c^{2})","Entries/1MeV");
  HDs1pMass.SetLineColor(1);
  
  TH1F HDs1pMassSignal;
  SetHistoXY(&HDs1pMassSignal,"D'_{s1} Mass After Cuts",NDs1pMassBins,Ds1pMassLo,Ds1pMassHi,"Ds1p Cand. Mass (GeV/c^{2})","Entries/1MeV");
  HDs1pMassSignal.SetLineColor(1);

  TH1F HDs1pMassTruthMatched;
  SetHistoXY(&HDs1pMassTruthMatched,"D'_{s1} Mass After Cuts and Truth Matched",NDs1pMassBins,Ds1pMassLo,Ds1pMassHi,"Ds1p Cand. Mass (GeV/c^{2})","Entries/1MeV");
  HDs1pMassTruthMatched.SetLineColor(1);

  
  Float_t Ds1pp3CMmax=8;
  Float_t Ds1pp3CMmin=0;
  Int_t Ds1pp3CMNbins=80;
  if(TruthMatch){
    Ds1pp3CMmax=5;
    Ds1pp3CMmin=0;
    Ds1pp3CMNbins=50;
  }
  
  TH1F HDs1pp3CMPreCuts;
  SetHistoXY(&HDs1pp3CMPreCuts,"D's1 CM Momentum ",Ds1pp3CMNbins,Ds1pp3CMmin,Ds1pp3CMmax,"p* (GeV/c)","Entries/100MeV");

  TH1F HDs1pp3CM;
  SetHistoXY(&HDs1pp3CM,"D's1 CM Momentum ",Ds1pp3CMNbins,Ds1pp3CMmin,Ds1pp3CMmax,"p* (GeV/c)","Entries/100MeV");

  TH1F HDs1pp3CMPIDCut;
  SetHistoXY(&HDs1pp3CMPIDCut,"D's1 CM Momentum ",Ds1pp3CMNbins,Ds1pp3CMmin,Ds1pp3CMmax,"p* (GeV/c)","Entries/100MeV");
  HDs1pp3CMPIDCut.SetLineColor(2);

  TH1F HDs1pp3CMPIDCutD0PCut;
  SetHistoXY(&HDs1pp3CMPIDCutD0PCut,"D's1 CM Momentum ",Ds1pp3CMNbins,Ds1pp3CMmin,Ds1pp3CMmax,"p* (GeV/c)","Entries/100MeV");
  HDs1pp3CMPIDCutD0PCut.SetLineColor(3);

  TH1F HDs1pp3CMPIDCutD0PCutDeltaMCut;
  SetHistoXY(&HDs1pp3CMPIDCutD0PCutDeltaMCut,"D's1 CM Momentum ",Ds1pp3CMNbins,Ds1pp3CMmin,Ds1pp3CMmax,"p* (GeV/c)","Entries/100MeV");
  HDs1pp3CMPIDCutD0PCutDeltaMCut.SetLineColor(4);

  TH1F HDs1pp3CMPIDCutD0PCutDeltaMCutD0Probab;
  SetHistoXY(&HDs1pp3CMPIDCutD0PCutDeltaMCutD0Probab,"D's1 CM Momentum ",Ds1pp3CMNbins,Ds1pp3CMmin,Ds1pp3CMmax,"p* (GeV/c)","Entries/100MeV");
  HDs1pp3CMPIDCutD0PCutDeltaMCutD0Probab.SetLineColor(6);    


  TH1F HDs1pcosthCMPreCuts;
  SetHistoXY(&HDs1pcosthCMPreCuts,"D's1 Angular Distribution  ",100,-1,1,"cos(#theta)*","Entries/.02");

  TH1F HDs1pcosthCM;
  SetHistoXY(&HDs1pcosthCM,"D's1 Angular Distribution  ",100,-1,1,"cos(#theta)*","Entries/.02");

  TH1F HDs1pcosthCMPIDCut;
  SetHistoXY(&HDs1pcosthCMPIDCut,"D's1 Angular Distribution  ",100,-1,1,"cos(#theta)*","Entries/.02");
  HDs1pcosthCMPIDCut.SetLineColor(2);

  TH1F HDs1pcosthCMPIDCutD0PCut;
  SetHistoXY(&HDs1pcosthCMPIDCutD0PCut,"D's1 Angular Distribution  ",100,-1,1,"cos(#theta)*","Entries/.02");
  HDs1pcosthCMPIDCutD0PCut.SetLineColor(3);

  TH1F HDs1pcosthCMPIDCutD0PCutDeltaMCut;
  SetHistoXY(&HDs1pcosthCMPIDCutD0PCutDeltaMCut,"D's1 Angular Distribution  ",100,-1,1,"cos(#theta)*","Entries/.02");
  HDs1pcosthCMPIDCutD0PCutDeltaMCut.SetLineColor(4);

  TH1F HDs1pcosthCMPIDCutD0PCutDeltaMCutD0Probab;
  SetHistoXY(&HDs1pcosthCMPIDCutD0PCutDeltaMCutD0Probab,"D's1 Angular Distribution  ",100,-1,1,"cos(#theta)*","Entries/.02");
  HDs1pcosthCMPIDCutD0PCutDeltaMCutD0Probab.SetLineColor(6);
    
  TH2F H2Ds1pCMPvsTheta;
  SetHisto2D(&H2Ds1pCMPvsTheta," #theta* vs  p* ",Ds1pp3CMNbins,Ds1pp3CMmin,Ds1pp3CMmax,"p* (GeV/c)",100,-1,1,"cos(#theta)*","entries/(.01x100MeV)");


  /////////MC 
  TH1F HMCDs1pMass;
  SetHistoXY(&HMCDs1pMass,"MC D's1 Mass",NDs1pMassBins,Ds1pMassLo,Ds1pMassHi,"Ds1p Cand. Mass (GeV/c^{2})","Entries/1MeV");

  TH1F HMCDs1pp3CM;
  SetHistoXY(&HMCDs1pp3CM,"MC D's1 Momentum ",Ds1pp3CMNbins,Ds1pp3CMmin,Ds1pp3CMmax,"p* (GeV/c)","Entries/100MeV");

  TH1F HMCDs1pcosthCM;
  SetHistoXY(&HMCDs1pcosthCM,"MC D's1 Angular Distribution ",100,-1,1,"cos(#theta)*","Entries/.02");
  
  TH2F H2MCDs1pCMPvsTheta;
  SetHisto2D(&H2MCDs1pCMPvsTheta,"MC  #theta* vs p* ",Ds1pp3CMNbins,Ds1pp3CMmin,Ds1pp3CMmax,"p* (GeV/c)",100,-1,1,"cos(#theta*)","entries/(.02x100MeV)");


  TH1F HMCNDs1p;
  SetHistoXY(&HMCNDs1p,"MC Number of D's1 Generated",10,-.5,10.5,"nDs1p/event","Counts");
 
  //check particle id 
  TH1F HLundCheck;SetHisto(&HLundCheck,"Lund Id Check",15,-.5,14.5,"ParticleLund - LundExp");

  ////////+++++++++Important
  // Dstard1=D0,Dstard2=Pi;D0d1=K;D0d2=Pi
  //Lunds:

    
  
  //Start the event loop;
  Int_t eventid=0;
  while(fChain->GetEntry(eventid,0)>0){   
    eventid++;
    if(eventid%5000==0)cout<<eventid<<" Events done."<<endl;    
           
    HBeamRadius.Fill(sqrt( beamSX*beamSX + beamSY*beamSY));
    HBeamZ.Fill(beamSZ);     
         
    if(nDs1p>400){cout<<"Too many cands at event"<<eventid<<endl;continue;}
    ///Loop over the reconstructed
    Ds1pIdx=-1;
    while( Ds1pIdx< nDs1p-1){
      Ds1pIdx++;

      ////For Monte Carlo decide to analyze matter or antimatter
      if(!(Ds1pLund[Ds1pIdx]==MatterOrAntiMatter*myDs1pLund || MatterOrAntiMatter==0))continue;

      //Check that Im using proper indexes
      if(Mode=="D0ToKPi"||Mode=="D0ToK3Pi"){
	KsIdx=Ds1pd2Idx[Ds1pIdx];  
	KsPi1Idx=Ksd1Idx[KsIdx];
	KsPi2Idx=Ksd2Idx[KsIdx];    
	DstarIdx=Ds1pd1Idx[Ds1pIdx];
	SlowPiIdx=Dstard2Idx[DstarIdx];
	D0Idx=Dstard1Idx[DstarIdx];
	PiIdx=D0d2Idx[D0Idx];
	KIdx=D0d1Idx[D0Idx];

	PitrkIdx=PiTrkIdx[PiIdx];
	SlowPitrkIdx=PiTrkIdx[SlowPiIdx];
	KsPi1trkIdx=PiTrkIdx[KsPi1Idx];
	KsPi2trkIdx=PiTrkIdx[KsPi2Idx];

	if(abs(Dstard1Lund[DstarIdx]-D0Lund[D0Idx])>0)HLundCheck.Fill(1);
	else if(abs(Dstard2Lund[DstarIdx]-PiLund[SlowPiIdx])>0)HLundCheck.Fill(2);
	else if(abs(D0d1Lund[D0Idx]-KLund[KIdx])>0)HLundCheck.Fill(3);
	else if(abs(D0d2Lund[D0Idx]-PiLund[PiIdx])>0)HLundCheck.Fill(4);
	else if(abs(TRKLund[SlowPitrkIdx]-PiLund[SlowPiIdx])>0)HLundCheck.Fill(5);
	else if(abs(TRKLund[PitrkIdx]-PiLund[PiIdx])>0)HLundCheck.Fill(6);
	else if(abs(Ds1pd1Lund[Ds1pIdx]-DstarLund[DstarIdx])>0)HLundCheck.Fill(7);
	else if(abs(Ds1pd2Lund[Ds1pIdx]-KsLund[KsIdx])>0)HLundCheck.Fill(8);
	else if(abs(TRKLund[KsPi1trkIdx]-PiLund[KsPi1Idx])>0)HLundCheck.Fill(9);
	else if(abs(TRKLund[KsPi2trkIdx]-PiLund[KsPi2Idx])>0)HLundCheck.Fill(10);
	else if(abs(Ksd1Lund[KsIdx]-PiLund[KsPi1Idx])>0)HLundCheck.Fill(11);
	else if(abs(Ksd2Lund[KsIdx]-PiLund[KsPi2Idx])>0)HLundCheck.Fill(12);	
	else HLundCheck.Fill(0);
      }      


      if(Mode=="D0ToKPiPi0"){
	KsIdx=Ds1pd2Idx[Ds1pIdx]; 
	KsPi1Idx=Ksd1Idx[KsIdx];
	KsPi2Idx=Ksd2Idx[KsIdx]; 
	DstarIdx=Ds1pd1Idx[Ds1pIdx];
   	SlowPiIdx=Dstard2Idx[DstarIdx];
	D0Idx=Dstard1Idx[DstarIdx];
	PiIdx=D0d2Idx[D0Idx];
	KIdx=D0d1Idx[D0Idx];
	Pi0Idx=D0d3Idx[D0Idx];
	GammaIdx=Pi0d1Idx[Pi0Idx];

	PitrkIdx=PiTrkIdx[PiIdx];
	SlowPitrkIdx=PiTrkIdx[SlowPiIdx];
	KsPi1trkIdx=PiTrkIdx[KsPi1Idx];
	KsPi2trkIdx=PiTrkIdx[KsPi2Idx];


	if(abs(Dstard1Lund[DstarIdx]-D0Lund[D0Idx])>0)HLundCheck.Fill(1);
	else if(abs(Dstard2Lund[DstarIdx]-PiLund[SlowPiIdx])>0)HLundCheck.Fill(2);
	else if(abs(D0d1Lund[D0Idx]-KLund[KIdx])>0)HLundCheck.Fill(3);
	else if(abs(D0d2Lund[D0Idx]-PiLund[PiIdx])>0)HLundCheck.Fill(4);
	else if(abs(TRKLund[SlowPitrkIdx]-PiLund[SlowPiIdx])>0)HLundCheck.Fill(5);
	else if(abs(TRKLund[PitrkIdx]-PiLund[PiIdx])>0)HLundCheck.Fill(6);
	else if(abs(Ds1pd1Lund[Ds1pIdx]-DstarLund[DstarIdx])>0)HLundCheck.Fill(7);
	else if(abs(Ds1pd2Lund[Ds1pIdx]-KsLund[KsIdx])>0)HLundCheck.Fill(8);
	else if(abs(TRKLund[KsPi1trkIdx]-PiLund[KsPi1Idx])>0)HLundCheck.Fill(9);
	else if(abs(TRKLund[KsPi2trkIdx]-PiLund[KsPi2Idx])>0)HLundCheck.Fill(10);
	else if(abs(Ksd1Lund[KsIdx]-PiLund[KsPi1Idx])>0)HLundCheck.Fill(11);
	else if(abs(Ksd2Lund[KsIdx]-PiLund[KsPi2Idx])>0)HLundCheck.Fill(12);
	else if(abs(D0d3Lund[D0Idx]-Pi0Lund[Pi0Idx])>0)HLundCheck.Fill(13);
	else if(abs(Pi0d1Lund[Pi0Idx]-GammaLund[GammaIdx])>0)HLundCheck.Fill(14);	
	else HLundCheck.Fill(0);

      }


      ///compute some quantities
      D0Probab=TMath::Prob(D0Chi2[D0Idx],D0nDof[D0Idx]);     
      KsProbab=TMath::Prob(KsChi2[D0Idx],KsnDof[D0Idx]);     
         
      Ksp3Direction.SetXYZ(sin(acos(Kscosth[KsIdx]))*cos(Ksphi[KIdx]),
			   sin(acos(Kscosth[KsIdx]))*sin(Ksphi[KIdx]),
			   Kscosth[KsIdx]); 
      KsFlightDirection.SetXYZ(KsVtxx[KsIdx]-Ds1pVtxx[Ds1pIdx],
			       KsVtxy[KsIdx]-Ds1pVtxy[Ds1pIdx],
			       KsVtxz[KsIdx]-Ds1pVtxz[Ds1pIdx]);
      KsCosine=Ksp3Direction*KsFlightDirection/KsFlightDirection.Mag();

      ///Fill Distributions  
      if(Mode=="D0ToKPiPi0"){        
	HPi0MassPreCuts.Fill(Pi0Mass[Pi0Idx]);  
      }

      HD0p3CM.Fill(D0p3CM[D0Idx]);
      HD0MassPreCuts.Fill(D0Mass[D0Idx]);
      HD0Probab.Fill(log(D0Probab));

      HDstarMassPreCuts.Fill(DstarMass[DstarIdx]);   

      HKsMassPreCuts.Fill(KsMass[KsIdx]);
      HKsProbab.Fill(log(KsProbab));
      HKsCosine.Fill(KsCosine);

      HDs1pMassPreCuts.Fill(Ds1pMass[Ds1pIdx]);  


      //Apply Cuts       
      //     if((PiSelectorsMap[KsPi1trkIdx] & (1<<4) ) != 0 && (PiSelectorsMap[KsPi2trkIdx] & (1<<4) ) != 0){
      //	HDs1pMassPID.Fill(Ds1pMass[Ds1pIdx]);

      if(D0p3CM[D0Idx] > D0p3CMCut){
	if(D0Probab > D0ProbabCut){
	  if(KsProbab > KsProbabCut && KsCosine>KsCosineCut){

	    HDs1pMass.Fill(Ds1pMass[Ds1pIdx]);

	    ///Fill histograms only for the signal region of Ds1p
	    if(Ds1pMassCutLo<Ds1pMass[Ds1pIdx]&&Ds1pMass[Ds1pIdx]<Ds1pMassCutHi){

	      HDs1pMassSignal.Fill(Ds1pMass[Ds1pIdx]);
	      if(Ds1pMCIdx[Ds1pIdx]>0){
		HDs1pMassTruthMatched.Fill(Ds1pMass[Ds1pIdx]); 	
		HDs1pp3CM.Fill(Ds1pp3CM[Ds1pIdx]); 
		HDs1pcosthCM.Fill(Ds1pcosthCM[Ds1pIdx]); 		  
		H2Ds1pCMPvsTheta.Fill(Ds1pp3CM[Ds1pIdx],Ds1pcosthCM[Ds1pIdx]);	
	      }	  
	  
	      HKsMass.Fill(KsMass[KsIdx]);	   
	      if(KsMCIdx[KsIdx]>0){
		HKsMassTruthMatched.Fill(KsMass[KsIdx]); 		
	      }
	  
	      HPi1Momentum.Fill(Pip3[KsPi1Idx]);
	      if(PiMCIdx[KsPi1Idx]>0)
		HPi1MomentumTruthMatched.Fill(Pip3[KsPi1Idx]);	

	      HDstarMass.Fill(DstarMass[DstarIdx]); 		  
	      if(DstarMCIdx[DstarIdx]>0){
		HDstarMassTruthMatched.Fill(DstarMass[DstarIdx]); 		
	      }	  
	      HMassDiff.Fill(DstarMass[DstarIdx]-D0Mass[D0Idx]);   

	  
	      HD0Mass.Fill(D0Mass[D0Idx]); 
	      if(D0MCIdx[D0Idx]>0)
		HD0MassTruthMatched.Fill(D0Mass[D0Idx]); 

	      HSlowPiMomentum.Fill(Pip3[SlowPiIdx]);	
	      if(PiMCIdx[SlowPiIdx]>0)
		HSlowPiMomentumTruthMatched.Fill(Pip3[SlowPiIdx]);	    

	      HKMomentum.Fill(Kp3[KIdx]);
	      if(KMCIdx[KIdx]>0)
		HKMomentumTruthMatched.Fill(Kp3[KIdx]);

	      HPiMomentum.Fill(Pip3[PiIdx]);
	      if(PiMCIdx[PiIdx]>0)
		HPiMomentumTruthMatched.Fill(Pip3[PiIdx]);	

	      if(Mode=="D0ToKPiPi0"){ 
		HGammaEnergy.Fill(GammaECal[GammaIdx]);
		if(GammaMCIdx[GammaIdx]>0)
		  HGammaEnergyTruthMatched.Fill(GammaECal[GammaIdx]);

		HPi0Mass.Fill(Pi0Mass[Pi0Idx]);
		if(Pi0MCIdx[Pi0Idx]>0)
		  HPi0MassTruthMatched.Fill(Pi0Mass[Pi0Idx]);
	      }
	 

	      RecoDs1pCounterTotal++;
	    }//signal region
	  }//Ks Cuts
	}//D0Probab Cut     
      }//D0 p* cut  
      
    }//Ds1p loop
	 

    //now loop over MC    
    MCDs1pCounterPerEvent=0; 
    Int_t mcid=-1;
    while(mcid<mcLen){
      mcid++;

      if(mcLund[mcid]==MatterOrAntiMatter*myDs1pLund){
	MCDs1pCounterPerEvent++; 
	MCDs1pCounterTotal++;
		
	HMCDs1pMass.Fill(mcmass[mcid]);
	HMCDs1pp3CM.Fill(mcp3CM[mcid]); 
	HMCDs1pcosthCM.Fill(mccosthCM[mcid]); 	
	H2MCDs1pCMPvsTheta.Fill(mcp3CM[mcid],mccosthCM[mcid]);
      }
    }
    HMCNDs1p.Fill(MCDs1pCounterPerEvent);
        
  }

  //print summary
  cout<<"--------Summary-------"<<endl;
  cout<<"Total events="<<eventid<<endl;
  cout<<"Total Generated="<<MCDs1pCounterTotal<<" Reconstructed="<<RecoDs1pCounterTotal<<endl;
  cout<<"--------End Summary---"<<endl;

 
  ////Save histograms
  TString filename;
  filename=NtupleDir+"/"+"Plots.ps";
  TCanvas Canvas(filename,filename);
  Canvas.Print(filename+"[");

  TLine cutline;
  cutline.SetLineColor(2);

  //beam
  Canvas.Clear();
  HBeamRadius.Draw();
  Canvas.Print(filename);
  Canvas.Clear();
  HBeamZ.Draw();
  Canvas.Print(filename);    

  ///The Kaon 
  Canvas.Clear();
  HKMomentum.Draw();
  Canvas.Print(filename);
  TH1F* HKMomentumTruthDifference=(TH1F*)HKMomentum.Clone();
  HKMomentumTruthDifference->Add(&HKMomentumTruthMatched,-1.);
  HKMomentumTruthDifference->SetTitle("Truth Difference");
  HKMomentumTruthDifference->Draw();
  Canvas.Print(filename);

  //ThePion
  Canvas.Clear();
  HPiMomentum.Draw();
  Canvas.Print(filename);
  Canvas.Clear();
  TH1F* HPiMomentumTruthDifference=(TH1F*)HPiMomentum.Clone();
  HPiMomentumTruthDifference->Add(&HPiMomentumTruthMatched,-1.);
  HPiMomentumTruthDifference->SetTitle("Truth Difference");
  HPiMomentumTruthDifference->Draw();
  Canvas.Print(filename);

  
  if(Mode=="D0ToKPiPi0"){ 
    ///Gamma
    Canvas.Clear();
    HGammaEnergy.Draw();
    Canvas.Print(filename);
    Canvas.Clear();
    TH1F* HGammaEnergyTruthDifference=(TH1F*)HGammaEnergy.Clone();
    HGammaEnergyTruthDifference->Add(&HGammaEnergyTruthMatched,-1.);
    HGammaEnergyTruthDifference->SetTitle("Truth Difference");
    HGammaEnergyTruthDifference->Draw();
    Canvas.Print(filename);

    //The Pi0
    Canvas.Clear();
    HPi0MassPreCuts.GetYaxis()->SetRangeUser(0,1.05*HPi0MassPreCuts.GetMaximum());
    HPi0MassPreCuts.Draw();
    HPi0Mass.Draw("same");
    Canvas.Print(filename);
    Canvas.Clear();
    TH1F* HPi0MassTruthDifference=(TH1F*)HPi0Mass.Clone();
    HPi0MassTruthDifference->Add(&HPi0MassTruthMatched,-1.);
    HPi0MassTruthDifference->SetTitle("Truth Difference");
    HPi0MassTruthDifference->Draw();
    Canvas.Print(filename);

  }

  //The D0 
  Canvas.Clear();
  HD0p3CM.Draw();
  cutline.DrawLine(D0p3CMCut,0,D0p3CMCut, HD0p3CM.GetMaximum());
  Canvas.Print(filename);
  Canvas.Clear();
  HD0MassPreCuts.GetYaxis()->SetRangeUser(0,1.05*HD0MassPreCuts.GetMaximum());
  HD0MassPreCuts.Draw();
  HD0Mass.Draw("same");
  Canvas.Print(filename);
  Canvas.Clear();
  TH1F* HD0MassTruthDifference=(TH1F*)HD0Mass.Clone();
  HD0MassTruthDifference->Add(&HD0MassTruthMatched,-1.);
  HD0MassTruthDifference->SetTitle("Truth Difference");
  HD0MassTruthDifference->Draw();
  Canvas.Print(filename);

  ///The Slow Pion
  Canvas.Clear();
  HSlowPiMomentum.Draw();
  Canvas.Print(filename);
  Canvas.Clear();
  TH1F* HSlowPiMomentumTruthDifference=(TH1F*)HSlowPiMomentum.Clone();
  HSlowPiMomentumTruthDifference->Add(&HSlowPiMomentumTruthMatched,-1.);
  HSlowPiMomentumTruthDifference->SetTitle("Truth Difference");
  HSlowPiMomentumTruthDifference->Draw();
  Canvas.Print(filename);


  ///The Dstar
  Canvas.Clear();
  HDstarMassPreCuts.GetYaxis()->SetRangeUser(0,1.05*HDstarMassPreCuts.GetMaximum());
  HDstarMassPreCuts.Draw();
  HDstarMass.Draw("same");
  //HDstarMassTruthMatched.Draw("same");
  Canvas.Print(filename); 
  Canvas.Clear();
  TH1F* HDstarMassTruthDifference=(TH1F*)HDstarMass.Clone();
  HDstarMassTruthDifference->Add(&HDstarMassTruthMatched,-1.);
  HDstarMassTruthDifference->SetTitle("Truth Difference");
  HDstarMassTruthDifference->Draw();
  Canvas.Print(filename);
  Canvas.Clear();
  HMassDiff.Draw();
  Canvas.Print(filename);


  //Pi1 and Pi2
  Canvas.Clear();
  HPi1Momentum.Draw();
  Canvas.Print(filename);
  Canvas.Clear();
  TH1F* HPi1MomentumTruthDifference=(TH1F*)HPi1Momentum.Clone();
  HPi1MomentumTruthDifference->Add(&HPi1MomentumTruthMatched,-1.);
  HPi1MomentumTruthDifference->SetTitle("Truth Difference");
  HPi1MomentumTruthDifference->Draw();
  Canvas.Print(filename);


  //Ks  
  Canvas.Clear();
  HKsProbab.Draw();
  Canvas.Print(filename); 
  Canvas.Clear();
  Canvas.SetLogy(1);
  HKsCosine.Draw();
  Canvas.Print(filename); 
  Canvas.SetLogy(0);
  Canvas.Clear();
  HKsMassPreCuts.GetYaxis()->SetRangeUser(0,1.05*HKsMassPreCuts.GetMaximum());
  HKsMassPreCuts.Draw();
  HKsMass.Draw("same");  
  //HKsMassTruthMatched.Draw("same");
  Canvas.Print(filename); 
  Canvas.Clear();
  TH1F* HKsMassTruthDifference=(TH1F*)HKsMass.Clone();
  HKsMassTruthDifference->Add(&HKsMassTruthMatched,-1.);
  HKsMassTruthDifference->SetTitle("Truth Difference");
  HKsMassTruthDifference->Draw();
  Canvas.Print(filename);


  //Ds1p
  Canvas.Clear();
  HDs1pMassPreCuts.GetYaxis()->SetRangeUser(0,1.05*HDs1pMassPreCuts.GetMaximum());
  HDs1pMassPreCuts.Draw();
  HDs1pMassPID.Draw("same");  
  HDs1pMass.Draw("same");
  cutline.DrawLine(Ds1pMassCutLo,0,Ds1pMassCutLo,HDs1pMass.GetMaximum());
  cutline.DrawLine(Ds1pMassCutHi,0,Ds1pMassCutHi,HDs1pMass.GetMaximum());  
  Canvas.Print(filename); 
  Canvas.Clear();
  Canvas.Divide(2,2);
  Canvas.cd(1);
  HDs1pMassSignal.Draw();
  HDs1pMassTruthMatched.Draw("same");
  Canvas.cd(2);
  TH1F* HDs1pMassTruthDifference=(TH1F*)HDs1pMassSignal.Clone();
  HDs1pMassTruthDifference->Add(&HDs1pMassTruthMatched,-1.);
  HDs1pMassTruthDifference->SetTitle("Truth Difference");
  HDs1pMassTruthDifference->Draw();
  Canvas.cd(3);
  TH1F* HDs1pMassTruthRatio=(TH1F*)HDs1pMassTruthMatched.Clone();
  HDs1pMassTruthRatio->Divide(&HDs1pMassSignal);
  HDs1pMassTruthRatio->SetTitle("Truth Ratio"); 
  HDs1pMassTruthRatio->GetYaxis()->SetTitle("TruthMatched/Reconstructed");
  HDs1pMassTruthRatio->Draw();
  Canvas.Print(filename);


  Canvas.Clear();
  if(TruthMatch){
    HMCDs1pp3CM.GetYaxis()->SetRangeUser(0,1.05*HMCDs1pp3CM.GetMaximum());
    HMCDs1pp3CM.Draw();  
    HDs1pp3CMPreCuts.Draw("same");
  }else {
    HDs1pp3CMPreCuts.GetYaxis()->SetRangeUser(1,1.05*HDs1pp3CMPreCuts.GetMaximum());
    HDs1pp3CMPreCuts.Draw();
  }       
  HDs1pp3CMPIDCut.Draw("same");
  HDs1pp3CMPIDCutD0PCut.Draw("same");
  HDs1pp3CMPIDCutD0PCutDeltaMCut.Draw("same");
  HDs1pp3CMPIDCutD0PCutDeltaMCutD0Probab.Draw("same");
  HDs1pp3CM.Draw("same");
  Canvas.Print(filename);

  //For bins were MC is less than 100 set efficiency to 0
  for(Int_t bin=0;bin<=HMCDs1pp3CM.GetNbinsX();bin++)
    if(HMCDs1pp3CM.GetBinContent(bin)<100)
      HMCDs1pp3CM.SetBinContent(bin,1e30);  

  Canvas.Clear();  
  TH1F HDs1pp3CMEfficiency0=*(TH1F*)HDs1pp3CMPreCuts.Clone();
  HDs1pp3CMEfficiency0.Divide(&HMCDs1pp3CM);
  HDs1pp3CMEfficiency0.SetTitle("CM Momentum Efficiency");
  HDs1pp3CMEfficiency0.GetYaxis()
    //->SetRangeUser(0,1.05*HDs1pp3CMEfficiency0.GetBinContent(HDs1pp3CMEfficiency0.GetMaximumBin()));
    ->SetRangeUser(0,1);
  HDs1pp3CMEfficiency0.Draw();
//   TH1F HDs1pp3CMEfficiency1=*(TH1F*)HDs1pp3CMPIDCut.Clone();
//   HDs1pp3CMEfficiency1.Divide(&HMCDs1pp3CM);
//   HDs1pp3CMEfficiency1.Draw("same");
//   TH1F HDs1pp3CMEfficiency2=*(TH1F*)HDs1pp3CMPIDCutD0PCut.Clone();
//   HDs1pp3CMEfficiency2.Divide(&HMCDs1pp3CM);
//   HDs1pp3CMEfficiency2.Draw("same");
//   TH1F HDs1pp3CMEfficiency3=*(TH1F*)HDs1pp3CMPIDCutD0PCutDeltaMCut.Clone();
//   HDs1pp3CMEfficiency3.Divide(&HMCDs1pp3CM);
//   HDs1pp3CMEfficiency3.Draw("same");
//   TH1F HDs1pp3CMEfficiency4=*(TH1F*)HDs1pp3CMPIDCutD0PCutDeltaMCutD0Probab.Clone();
//   HDs1pp3CMEfficiency4.Divide(&HMCDs1pp3CM);
//   HDs1pp3CMEfficiency4.Draw("same");  
  TH1F HDs1pp3CMEfficiencyFinal=*(TH1F*)HDs1pp3CM.Clone();
  HDs1pp3CMEfficiencyFinal.Divide(&HMCDs1pp3CM);  
  HDs1pp3CMEfficiencyFinal.Draw("same");
  Canvas.Print(filename);
  
  Canvas.Clear();
  if(TruthMatch){
    HMCDs1pcosthCM.GetYaxis()->SetRangeUser(0,1.05*HMCDs1pcosthCM.GetMaximum());
    HMCDs1pcosthCM.Draw();  
    HDs1pcosthCMPreCuts.Draw("same");
  }else {
    HDs1pcosthCMPreCuts.GetYaxis()->SetRangeUser(1,1.05*HDs1pcosthCMPreCuts.GetMaximum());
    HDs1pcosthCMPreCuts.Draw();
  }       
//   HDs1pcosthCMPIDCut.Draw("same");
//   HDs1pcosthCMPIDCutD0PCut.Draw("same");
//   HDs1pcosthCMPIDCutD0PCutDeltaMCut.Draw("same");
//   HDs1pcosthCMPIDCutD0PCutDeltaMCutD0Probab.Draw("same");
  HDs1pcosthCM.Draw("same");
  Canvas.Print(filename);
  
  Canvas.Clear();  
  TH1F HDs1pcosthCMEfficiency0=*(TH1F*)HDs1pcosthCMPreCuts.Clone();
  HDs1pcosthCMEfficiency0.Divide(&HMCDs1pcosthCM);
  HDs1pcosthCMEfficiency0.SetTitle("Angular Efficiency");
  HDs1pcosthCMEfficiency0.GetYaxis()
    //->SetRangeUser(0,1.05*HDs1pcosthCMEfficiency0.GetBinContent(HDs1pcosthCMEfficiency0.GetMaximumBin()));
    ->SetRangeUser(0,1);
  HDs1pcosthCMEfficiency0.Draw();
//   TH1F HDs1pcosthCMEfficiency1=*(TH1F*)HDs1pcosthCMPIDCut.Clone();
//   HDs1pcosthCMEfficiency1.Divide(&HMCDs1pcosthCM);
//   HDs1pcosthCMEfficiency1.Draw("same");
//   TH1F HDs1pcosthCMEfficiency2=*(TH1F*)HDs1pcosthCMPIDCutD0PCut.Clone();
//   HDs1pcosthCMEfficiency2.Divide(&HMCDs1pcosthCM);
//   HDs1pcosthCMEfficiency2.Draw("same");
//   TH1F HDs1pcosthCMEfficiency3=*(TH1F*)HDs1pcosthCMPIDCutD0PCutDeltaMCut.Clone();
//   HDs1pcosthCMEfficiency3.Divide(&HMCDs1pcosthCM);
//   HDs1pcosthCMEfficiency3.Draw("same");
//   TH1F HDs1pcosthCMEfficiency4=*(TH1F*)HDs1pcosthCMPIDCutD0PCutDeltaMCutD0Probab.Clone();
//   HDs1pcosthCMEfficiency4.Divide(&HMCDs1pcosthCM);
//   HDs1pcosthCMEfficiency4.Draw("same");  
  TH1F HDs1pcosthCMEfficiencyFinal=*(TH1F*)HDs1pcosthCM.Clone();
  HDs1pcosthCMEfficiencyFinal.Divide(&HMCDs1pcosthCM);  
  HDs1pcosthCMEfficiencyFinal.Draw("same");
  Canvas.Print(filename);

  Canvas.Clear();
  H2Ds1pCMPvsTheta.Draw("colz");
  Canvas.Print(filename);
  Canvas.Clear();
  H2MCDs1pCMPvsTheta.Draw("colz");
  Canvas.Print(filename);
  Canvas.Clear();
  //For bins were MC is less than 5 set efficiency to 0
  for(Int_t binx=0;binx<=H2MCDs1pCMPvsTheta.GetNbinsX();binx++)
    for(Int_t biny=0;biny<=H2MCDs1pCMPvsTheta.GetNbinsY();biny++)
      if(H2MCDs1pCMPvsTheta.GetBinContent(binx,biny)<20)
	H2MCDs1pCMPvsTheta.SetBinContent(binx,biny,1e30); 

  TH2F H2Ds1pPvsThetaEfficiency=*(TH2F*)H2Ds1pCMPvsTheta.Clone();
  H2Ds1pPvsThetaEfficiency.Divide(&H2MCDs1pCMPvsTheta);
  H2Ds1pPvsThetaEfficiency.SetTitle("D* Efficiency");
  H2Ds1pPvsThetaEfficiency.GetZaxis()->SetTitle("efficiency");
  H2Ds1pPvsThetaEfficiency.SetTitleOffset(.68,"Z");
  H2Ds1pPvsThetaEfficiency.SetStats(kFALSE);
  H2Ds1pPvsThetaEfficiency.Draw("colz");
  Canvas.Print(filename);





  ///Make plot of TruthMatched vs particle: 
  Float_t KTruthRatio=0;
  Float_t PiTruthRatio=0;
  Float_t GammaTruthRatio=0;
  Float_t Pi0TruthRatio=0;
  Float_t D0TruthRatio=0;
  Float_t SlowPiTruthRatio=0;
  Float_t DstarTruthRatio=0;
  Float_t Pi1TruthRatio=0;
  Float_t KsTruthRatio=0;
  Float_t Ds1pTruthRatio=0;

  if(HKMomentum.Integral()>0) KTruthRatio=HKMomentumTruthMatched.Integral()/HKMomentum.Integral();
  if(HPiMomentum.Integral()>0) PiTruthRatio=HPiMomentumTruthMatched.Integral()/HPiMomentum.Integral();
  if(HGammaEnergy.Integral()>0) GammaTruthRatio=HPiMomentumTruthMatched.Integral()/HPiMomentum.Integral();
  if(HPi0Mass.Integral()>0) Pi0TruthRatio=HPi0MassTruthMatched.Integral()/HPi0Mass.Integral();
  if(HD0Mass.Integral()>0) D0TruthRatio=HD0MassTruthMatched.Integral()/HD0Mass.Integral();
  if(HSlowPiMomentum.Integral()>0) SlowPiTruthRatio=HSlowPiMomentumTruthMatched.Integral()/HSlowPiMomentum.Integral();
  if(HDstarMass.Integral()>0) DstarTruthRatio=HDstarMassTruthMatched.Integral()/HDstarMass.Integral();
  if(HPi1Momentum.Integral()>0) Pi1TruthRatio=HPi1MomentumTruthMatched.Integral()/HPi1Momentum.Integral();
  if(HKsMass.Integral()>0) KsTruthRatio=HKsMassTruthMatched.Integral()/HKsMass.Integral();
  if(HDs1pMass.Integral()>0) Ds1pTruthRatio=HDs1pMassTruthMatched.Integral()/HDs1pMassSignal.Integral();
  

  TH1F HTruthRatioVsParticle;
  SetHistoXY(&HTruthRatioVsParticle,"Truth Match Ratios",10,.5,10.5,"Particle Type","TruthMatched/Reconstructed");
  HTruthRatioVsParticle.SetBinContent(1,KTruthRatio);
  HTruthRatioVsParticle.SetBinContent(2,PiTruthRatio);
  HTruthRatioVsParticle.SetBinContent(3,GammaTruthRatio);
  HTruthRatioVsParticle.SetBinContent(4,Pi0TruthRatio); 
  HTruthRatioVsParticle.SetBinContent(5,D0TruthRatio);
  HTruthRatioVsParticle.SetBinContent(6,SlowPiTruthRatio);
  HTruthRatioVsParticle.SetBinContent(7,DstarTruthRatio); 
  HTruthRatioVsParticle.SetBinContent(8,PiTruthRatio);   
  HTruthRatioVsParticle.SetBinContent(9,KsTruthRatio); 
  HTruthRatioVsParticle.SetBinContent(10,Ds1pTruthRatio); 
  HTruthRatioVsParticle.GetYaxis()->SetRangeUser(0,1);
  HTruthRatioVsParticle.SetStats(kFALSE);
  HTruthRatioVsParticle.SetBarWidth(.9);
  
  TText text;
  text.SetTextSize(.03);

  Canvas.Clear();
  HTruthRatioVsParticle.Draw("b");
  text.DrawText(1-.2,.1,"K");
  text.DrawText(2-.2,.1,"Pi");
  text.DrawText(3-.4,.1,"Gamma");
  text.DrawText(4-.2,.1,"Pi0");
  text.DrawText(5-.2,.1,"D0");
  text.DrawText(6-.4,.1,"SlowPi");
  text.DrawText(7-.2,.1,"D*");
  text.DrawText(8-.2,.1,"Pi1");
  text.DrawText(9-.2,.1,"Ks");
  text.DrawText(10-.2,.1,"Ds1");
  text.DrawText(1-.35,KTruthRatio*.9,TString("")+long(100*KTruthRatio)+"."+long(1000*KTruthRatio)%10+"%");
  text.DrawText(2-.35,PiTruthRatio*.9,TString("")+long(100*PiTruthRatio)+"."+long(1000*PiTruthRatio)%10+"%");
  text.DrawText(3-.35,GammaTruthRatio*.9,TString("")+long(100*GammaTruthRatio)+"."+long(1000*GammaTruthRatio)%10+"%");
  text.DrawText(4-.35,Pi0TruthRatio*.9,TString("")+long(100*Pi0TruthRatio)+"."+long(1000*Pi0TruthRatio)%10+"%");
  text.DrawText(5-.35,D0TruthRatio*.9,TString("")+long(100*D0TruthRatio)+"."+long(1000*D0TruthRatio)%10+"%");
  text.DrawText(6-.35,SlowPiTruthRatio*.9,TString("")+long(100*SlowPiTruthRatio)+"."+long(1000*SlowPiTruthRatio)%10+"%");
  text.DrawText(7-.35,DstarTruthRatio*.9,TString("")+long(100*DstarTruthRatio)+"."+long(1000*DstarTruthRatio)%10+"%");
  text.DrawText(8-.35,Pi1TruthRatio*.9,TString("")+long(100*Pi1TruthRatio)+"."+long(1000*Pi1TruthRatio)%10+"%");
  text.DrawText(9-.35,KsTruthRatio*.9,TString("")+long(100*KsTruthRatio)+"."+long(1000*KsTruthRatio)%10+"%");
  text.DrawText(10-.35,Ds1pTruthRatio*.9,TString("")+long(100*Ds1pTruthRatio)+"."+long(1000*Ds1pTruthRatio)%10+"%");
  Canvas.Print(filename);

  Canvas.Clear(); 
  HLundCheck.SetBarOffset(0);
  HLundCheck.SetBarWidth(.05);
  HLundCheck.Draw();
  Canvas.Print(filename);
   

  Canvas.Print(filename+"]");  
  return (TH1F*) HMassDiff.Clone(); 
}
Beispiel #21
0
Bool_t Selector_p3pi::Process(Long64_t entry)
{
   // The Process() function is called for each entry in the tree (or possibly
   // keyed object in the case of PROOF) to be processed. The entry argument
   // specifies which entry in the currently loaded tree is to be processed.
   // It can be passed to either Selector_p3pi::GetEntry() or TBranch::GetEntry()
   // to read either all or the required parts of the data. When processing
   // keyed objects with PROOF, the object is already loaded and is available
   // via the fObject pointer.
   //
   // This function should contain the "body" of the analysis. It can contain
   // simple or elaborate selection criteria, run algorithms on the data
   // of the event and typically fill histograms.
   //
   // The processing can be stopped by calling Abort().
   //
   // Use fStatus to set the return value of TTree::Process().
   //
   // The return value is currently not used.

	GetEntry(entry);

	/********************************************* SETUP UNIQUENESS TRACKING ********************************************/

	//PREVENT-DOUBLE COUNTING WHEN HISTOGRAMMING
		//Sometimes, some content is the exact same between one combo and the next
			//e.g. maybe two combos have different beam particles, but the same data for the final-state
		//When histogramming, you don't want to double-count when this happens: artificially inflates your signal (or background)
		//So, for each quantity you histogram, keep track of what particles you used (for a given combo)
			//Use the combo-independent particle indices (i.e. the indices to "ChargedHypo," "NeutralShower," and/or "Beam"
		//Then for each combo, just compare to what you used before, and make sure it's unique

	//In general: Could have multiple particles with the same PID: Use a set (easier, faster to search)
	//In general: Multiple PIDs, so multiple sets: Contain within a map
	//Multiple combos: Contain maps within a set (easier, faster to search)
	set<map<Particle_t, set<Int_t> > > locUsedSoFar_Pi0Mass; 
	set<map<Particle_t, set<Int_t> > > locUsedSoFar_MissingMass;
	set<map<Particle_t, set<Int_t> > > locUsedSoFar_OmegaMass;
	set<Int_t> locUsedSoFar_BeamEnergy;
	set<Int_t> locUsedSoFar_MandelstamT;
	set<set<Int_t> > locUsedSoFar_ExtraPi0;
	bool locNumExtraTracksFilledFlag = false;

	/************************************************* LOOP OVER COMBOS *************************************************/

	//Loop over combos
	int locNumSurvivingCombos = 0;
	for(UInt_t loc_i = 0; loc_i < NumCombos; ++loc_i)
	{
		// Is used to mark when combos are cut
		if(IsComboCut[loc_i]) // Is false initially
			continue; // Combo has been cut previously

		/***************************************** READ/SETUP DATA FOR THIS COMBO ****************************************/

		// Particle info is split between combo-dependent and combo-independent
		// For combo-dependent (e.g. PID, kinfit p4), use the branches starting with the particle name (<Name>)
			// e.g. PiPlus__P4_KinFit
		// For combo-independent (e.g. measured p4, dE/dx, etc.), use the branches starting with either: 
			// "ChargedHypo," "NeutralShower," or "Beam"
			// However, these are arrays. The array index that you need is given by the branches:
			// "<Name>__ChargedIndex," "<Name>__ShowerIndex," or "ComboBeam__BeamIndex"
		// If using charged PIDs for which hypos are not created by default (e.g. e+, e-), beware! (pi+/-, k+/-, and p are fine)
			// The energy in the "P4_Measured" will be computed with a different mass than the one you're using
			// So you'll need to recompute it yourself.  However, the "P4_KinFit" will be fine. 

		// Get particle indices: These point from combo-particle to combo-independent data
		Int_t locPhoton1Index = Photon1__ShowerIndex[loc_i];
		Int_t locPhoton2Index = Photon2__ShowerIndex[loc_i];
		Int_t locPiPlusIndex = PiPlus__ChargedIndex[loc_i];
		Int_t locPiMinusIndex = PiMinus__ChargedIndex[loc_i];
		Int_t locProtonIndex = Proton__ChargedIndex[loc_i];
		Int_t locBeamIndex = ComboBeam__BeamIndex[loc_i];

		// Get Measured Neutral P4's: Combo-dependent (P4 defined by combo-dependent vertex position)
		TLorentzVector& locPhoton1P4_Measured = *((TLorentzVector*)Photon1__P4_Measured->At(loc_i));
		TLorentzVector& locPhoton2P4_Measured = *((TLorentzVector*)Photon2__P4_Measured->At(loc_i));

		// Get KinFit Neutral P4's: Combo-dependent
		TLorentzVector& locPhoton1P4_KinFit = *((TLorentzVector*)Photon1__P4_KinFit->At(loc_i));
		TLorentzVector& locPhoton2P4_KinFit = *((TLorentzVector*)Photon2__P4_KinFit->At(loc_i));

		// Get Measured Charged P4's: Combo-independent
		TLorentzVector& locPiPlusP4_Measured = *((TLorentzVector*)ChargedHypo__P4_Measured->At(locPiPlusIndex));
		TLorentzVector& locPiMinusP4_Measured = *((TLorentzVector*)ChargedHypo__P4_Measured->At(locPiMinusIndex));
		TLorentzVector& locProtonP4_Measured = *((TLorentzVector*)ChargedHypo__P4_Measured->At(locProtonIndex));

		// Get KinFit Charged P4's: Combo-dependent
		TLorentzVector& locPiPlusP4_KinFit = *((TLorentzVector*)PiPlus__P4_KinFit->At(loc_i));
		TLorentzVector& locPiMinusP4_KinFit = *((TLorentzVector*)PiMinus__P4_KinFit->At(loc_i));
		TLorentzVector& locProtonP4_KinFit = *((TLorentzVector*)Proton__P4_KinFit->At(loc_i));

		// Get Measured Beam P4: Combo-independent
		TLorentzVector& locBeamP4_Measured = *((TLorentzVector*)Beam__P4_Measured->At(locBeamIndex));

		// Get KinFit Beam P4: Combo-dependent
		TLorentzVector& locBeamP4_KinFit = *((TLorentzVector*)ComboBeam__P4_KinFit->At(locBeamIndex));

		// Combine 4-vectors
		TLorentzVector locPi0P4_Measured = locPhoton1P4_Measured + locPhoton2P4_Measured;
		TLorentzVector locPi0P4_KinFit = locPhoton1P4_KinFit + locPhoton2P4_KinFit;

		TLorentzVector locOmegaP4_Measured = locPiPlusP4_Measured + locPiMinusP4_Measured + locPi0P4_Measured;
		TLorentzVector locOmegaP4_KinFit = locPiPlusP4_KinFit + locPiMinusP4_KinFit + locPi0P4_KinFit;

		TLorentzVector locFinalStateP4_Measured = locOmegaP4_Measured + locProtonP4_Measured;
		TLorentzVector locFinalStateP4_KinFit = locOmegaP4_KinFit + locProtonP4_KinFit;

		TLorentzVector locInitialStateP4_Measured = locBeamP4_Measured + dTargetP4;
		TLorentzVector locInitialStateP4_KinFit = locBeamP4_KinFit + dTargetP4;

		TLorentzVector locMissingP4_Measured = locInitialStateP4_Measured - locFinalStateP4_Measured;

		/****************************************************** PI0 ******************************************************/

		//Mass
		double locPi0Mass_Measured = locPi0P4_Measured.M();
		double locPi0Mass_KinFit = locPi0P4_KinFit.M();

		//Build the map of particles used for the pi0 mass
		map<Particle_t, set<Int_t> > locUsedThisCombo_Pi0Mass;
		locUsedThisCombo_Pi0Mass[Gamma].insert(locPhoton1Index);
		locUsedThisCombo_Pi0Mass[Gamma].insert(locPhoton2Index);

		//compare to what's been used so far
		if(locUsedSoFar_Pi0Mass.find(locUsedThisCombo_Pi0Mass) == locUsedSoFar_Pi0Mass.end())
		{
			//unique pi0 combo: histogram it, and register this combo of particles
			dHist_Pi0Mass_Measured->Fill(locPi0Mass_Measured);
			dHist_Pi0Mass_KinFit->Fill(locPi0Mass_KinFit);
			locUsedSoFar_Pi0Mass.insert(locUsedThisCombo_Pi0Mass);
		}

		//Cut pi0 mass (+/- 3 sigma)
//		if((locPi0Mass_Measured < 0.0775209) || (locPi0Mass_Measured > 0.188047))
//			continue; //could also mark combo as cut, then save cut results to a new TTree
		if((locPi0Mass_KinFit < 0.102284) || (locPi0Mass_KinFit > 0.167278))
			continue; //could also mark combo as cut, then save cut results to a new TTree

		/********************************************* MISSING MASS SQUARED **********************************************/

		//Missing Mass Squared
		double locMissingMassSquared = locMissingP4_Measured.M2();

		//Build the map of particles used for the missing mass
			//For beam: Don't want to group with final-state photons. Instead use "Unknown" PID (not ideal, but it's easy). 
		map<Particle_t, set<Int_t> > locUsedThisCombo_MissingMass;
		locUsedThisCombo_MissingMass[Gamma] = locUsedThisCombo_Pi0Mass[Gamma];
		locUsedThisCombo_MissingMass[PiPlus].insert(locPiPlusIndex);
		locUsedThisCombo_MissingMass[PiMinus].insert(locPiMinusIndex);
		locUsedThisCombo_MissingMass[Proton].insert(locProtonIndex);
		locUsedThisCombo_MissingMass[Unknown].insert(locBeamIndex); //beam

		//compare to what's been used so far
		if(locUsedSoFar_MissingMass.find(locUsedThisCombo_MissingMass) == locUsedSoFar_MissingMass.end())
		{
			//unique missing mass combo: histogram it, and register this combo of particles
			dHist_MissingMassSquared->Fill(locMissingMassSquared);
			locUsedSoFar_MissingMass.insert(locUsedThisCombo_MissingMass);
		}

		//Cut
		if((locMissingMassSquared < -0.007) || (locMissingMassSquared > 0.005))
			continue; //could also mark combo as cut, then save cut results to a new TTree

		/***************************************************** OMEGA *****************************************************/

		//Mass
		double locOmegaMass_Measured = locOmegaP4_Measured.M();
		double locOmegaMass_KinFit = locOmegaP4_KinFit.M();

		//Build the map of particles used for the omega mass
		map<Particle_t, set<Int_t> > locUsedThisCombo_OmegaMass;
		locUsedThisCombo_OmegaMass[Gamma] = locUsedThisCombo_Pi0Mass[Gamma];
		locUsedThisCombo_OmegaMass[PiPlus].insert(locPiPlusIndex);
		locUsedThisCombo_OmegaMass[PiMinus].insert(locPiMinusIndex);

		//compare to what's been used so far
		bool locOmegaUniqueFlag = false; //will check later for asymmetry
		if(locUsedSoFar_OmegaMass.find(locUsedThisCombo_OmegaMass) == locUsedSoFar_OmegaMass.end())
		{
			//unique missing mass combo: histogram it, and register this combo of particles
			locOmegaUniqueFlag = true;
			dHist_OmegaMass_Measured->Fill(locOmegaMass_Measured);
			dHist_OmegaMass_KinFit->Fill(locOmegaMass_KinFit);
			locUsedSoFar_OmegaMass.insert(locUsedThisCombo_OmegaMass);
		}

		//Cut
		if((locOmegaMass_KinFit < 0.72) || (locOmegaMass_KinFit > 0.84))
			continue; //could also mark combo as cut, then save cut results to a new TTree

		/************************************************ BEAM ENERGY, T *************************************************/

		//Histogram beam energy (if haven't already)
		if(locUsedSoFar_BeamEnergy.find(locBeamIndex) == locUsedSoFar_BeamEnergy.end())
		{
			dHist_BeamEnergy->Fill(locBeamP4_KinFit.E());
			locUsedSoFar_BeamEnergy.insert(locBeamIndex);
		}
		if((locBeamP4_KinFit.E() < 2.5) || (locBeamP4_KinFit.E() > 3.0))
			continue; //could also mark combo as cut, then save cut results to a new TTree

		double locT = (locProtonP4_KinFit - dTargetP4).Mag2();
		if(locUsedSoFar_MandelstamT.find(locProtonIndex) == locUsedSoFar_MandelstamT.end())
		{
			dHist_MandelstamT->Fill(locT);
			locUsedSoFar_MandelstamT.insert(locProtonIndex);
		}

		if((fabs(locT) < 0.02) || (fabs(locT) > 0.3))
			continue;

		/*********************************************** EXTRA PARTICLES *************************************************/

		//loop through all hypotheses, find how many physical tracks there are
		set<Int_t> locFoundTrackIDs; //keep track of unique track ids
		for(size_t loc_j = 0; loc_j < NumChargedHypos; ++loc_j)
			locFoundTrackIDs.insert(ChargedHypo__TrackID[loc_j]);

		int locNumExtraTracks = locFoundTrackIDs.size() - 3; //proton, pi+, pi- used
		//Fill the histogram if it hasn't already been filled for this event (quantity is combo-independent)
		if(!locNumExtraTracksFilledFlag)
		{
			dHist_NumExtraTracks->Fill(locNumExtraTracks);
			locNumExtraTracksFilledFlag = true;
		}

		//cut, requiring no extra tracks in the event
		if(locNumExtraTracks > 0)
			continue;

		//Loop through showers, see if there are any additional pi0s
		TVector3 locProductionVertex = ((TLorentzVector*)ComboBeam__X4_Measured->At(loc_i))->Vect();
		for(Int_t loc_j = 0; loc_j < Int_t(NumNeutralShowers); ++loc_j)
		{
			if((loc_j == locPhoton1Index) || (loc_j == locPhoton2Index))
				continue; //don't choose a shower that's already in the combo

			//Construct extra photon 1 p4
			TLorentzVector& locShower1X4 = *((TLorentzVector*)NeutralShower__X4_Shower->At(loc_j));
			double locShower1Energy = (NeutralShower__Energy_BCAL[loc_j] > 0.0) ? NeutralShower__Energy_BCAL[loc_j] : NeutralShower__Energy_FCAL[loc_j];
			TVector3 locExtraPhoton1P3 = locShower1X4.Vect() - locProductionVertex;
			locExtraPhoton1P3.SetMag(locShower1Energy);
			TLorentzVector locExtraPhoton1P4(locExtraPhoton1P3, locShower1Energy);

			//need 2 photons for a pi0
			for(Int_t loc_k = loc_j + 1; loc_k < Int_t(NumNeutralShowers); ++loc_k)
			{
				if((loc_k == locPhoton1Index) || (loc_k == locPhoton2Index))
					continue; //don't choose a shower that's already in the combo

				//Construct extra photon 2 p4
				TLorentzVector& locShower2X4 = *((TLorentzVector*)NeutralShower__X4_Shower->At(loc_k));
				double locShower2Energy = (NeutralShower__Energy_BCAL[loc_k] > 0.0) ? NeutralShower__Energy_BCAL[loc_k] : NeutralShower__Energy_FCAL[loc_k];
				TVector3 locExtraPhoton2P3 = locShower2X4.Vect() - locProductionVertex;
				locExtraPhoton2P3.SetMag(locShower2Energy);
				TLorentzVector locExtraPhoton2P4(locExtraPhoton2P3, locShower2Energy);

				TLorentzVector locExtraPi0P4 = locExtraPhoton1P4 + locExtraPhoton2P4;
				double locExtraPi0Mass = locExtraPi0P4.M();

				//see if this combo has been histogrammed yet
				set<Int_t> locUsedThisCombo_ExtraPi0;
				locUsedThisCombo_ExtraPi0.insert(loc_j);
				locUsedThisCombo_ExtraPi0.insert(loc_k);
				if(locUsedSoFar_ExtraPi0.find(locUsedThisCombo_ExtraPi0) == locUsedSoFar_ExtraPi0.end())
				{
					//it has not: histogram and register
					dHist_ExtraPi0InvariantMass->Fill(locExtraPi0Mass);
					locUsedSoFar_ExtraPi0.insert(locUsedThisCombo_ExtraPi0);
				}
			}
		}

		++locNumSurvivingCombos;
		if(locNumSurvivingCombos > 1)
			cout << "# combos = " << locNumSurvivingCombos << endl;

		/************************************************ OMEGA ASYMMETRY ************************************************/

		//Polarization plane:
			//Beam is in the lab z-direction
			//(FYI) Circularly polarized photon beam: Polarization rotates through the plane perpendicular to the direction of the photon: The XY Plane
			//The polarization vector is perpendicular to the direction of the photon
			//Linearly polarized photon beam: Polarization is confined to a plane along the direction of the photon
				//Plane defined by z-direction & some angle phi. Thus, polarization vector defined by phi.
				//PARA: Polarization plane parallel to the floor: The XZ plane. Polarization Vector = +/- x-axis
				//PERP: Polarization plane perpendicular to the floor: The YZ plane. Polarization Vector = +/- y-axis
			//Here: Assume that the beam polarization plane is parallel to the floor (Run 3185) (xz plane, choose +x-axis)

		//Production CM frame: The center-of-mass frame of the production step. Here: g, p -> omega, p
			//In general, the beam energy is measured more accurately than the combination of all of the final-state particles
			//So define the production CM frame using the initial state
		TVector3 locBoostVector_ProdCM = -1.0*(locInitialStateP4_KinFit.BoostVector()); //negative due to coordinate system convention

		//boost beam & proton to production CM frame
		TLorentzVector locBeamP4_ProdCM(locBeamP4_KinFit);
		locBeamP4_ProdCM.Boost(locBoostVector_ProdCM);
		TLorentzVector locProtonP4_ProdCM(locProtonP4_KinFit);
		locProtonP4_ProdCM.Boost(locBoostVector_ProdCM);

		//Production plane:
			//The production plane is the plane containing the produced particles. Here: Defined by the proton and the omega
			//However, when you boost to the production CM frame, the production plane is no longer well defined: the particles are back-to-back
			//So, by convention, define the production plane in the production CM frame by the beam and the vector meson.

		//Production CM frame axes: "HELICITY SYSTEM"
			//The z-axis is defined as the direction of the meson (omega): z = Omega
			//The y-axis is defined by the vector cross product: y = Beam X Omega
			//The x-axis is defined by the vector cross product: x = y cross z
			//However, the proton momentum is in general better known than the omega momentum, so use it instead (they are back-to-back)
				//z = -1 * Proton
				//y = -1 * (Beam X Proton)
				//x = y cross z
			//Thus the production plane in the production frame is the XZ plane, and the normal vector is the Y-axis

		//Define production CM frame helicity axes
		TVector3 locHelicityZAxis_ProdCM = -1.0*locProtonP4_ProdCM.Vect().Unit();
		TVector3 locHelicityYAxis_ProdCM = -1.0*locBeamP4_ProdCM.Vect().Cross(locProtonP4_ProdCM.Vect()).Unit();
		TVector3 locHelicityXAxis_ProdCM = locHelicityYAxis_ProdCM.Cross(locHelicityZAxis_ProdCM).Unit();

		//Since the beam is in PARA configuration (Run 3185), the polarization vector is along the lab x-axis
			//Since the boost is in the z-direction, this vector is the same in the production CM frame
		TVector3 locPolUnit(1.0, 0.0, 0.0);

		//In the production CM frame, locPHI is the angle between the polarization vector and the production plane
		double locCosPHI = locBeamP4_ProdCM.Vect().Unit().Dot(locPolUnit.Cross(locHelicityYAxis_ProdCM));
		double locPHI = acos(locCosPHI); //reports phi between 0 and pi: sign ambiguity
		//Resolve the sign ambiguity
		double locSinPHI = locPolUnit.Dot(locHelicityYAxis_ProdCM);
		if(locSinPHI < 0.0)
			locPHI *= -1.0;

		//Now, we need the theta, phi angles between the omega decay plane and the production plane
		//The omega decay plane is defined by decay products in the omega CM frame
			//2 particles (vectors) define a plane.  
			//However, to conserve momentum, the third particle cannot be out of that plane (so must also be in it)
			//So, use the pi+ and the pi- to define the plane (pi0 measurement has less resolution)
		//By the way, for rho decays, the theta & phi angles are those of the pi+ in the rho CM frame, with respect to the helicity axes

		//boost pi+/- to omega CM frame
		TVector3 locBoostVector_OmegaCM = -1.0*(locOmegaP4_KinFit.BoostVector()); //negative due to coordinate system convention
		TLorentzVector locBeamP4_OmegaCM(locBeamP4_KinFit);
		locBeamP4_OmegaCM.Boost(locBoostVector_OmegaCM);
		TLorentzVector locProtonP4_OmegaCM(locProtonP4_KinFit);
		locProtonP4_OmegaCM.Boost(locBoostVector_OmegaCM);
		TLorentzVector locPiPlusP4_OmegaCM(locPiPlusP4_KinFit);
		locPiPlusP4_OmegaCM.Boost(locBoostVector_OmegaCM);
		TLorentzVector locPiMinusP4_OmegaCM(locPiMinusP4_KinFit);
		locPiMinusP4_OmegaCM.Boost(locBoostVector_OmegaCM);

		//Define omega CM frame helicity axes
			//These are defined the same way as before, but with the boost, the direction of the x & y axes has changed
		TVector3 locHelicityZAxis_OmegaCM = -1.0*locProtonP4_OmegaCM.Vect().Unit();
		TVector3 locHelicityYAxis_OmegaCM = -1.0*locBeamP4_OmegaCM.Vect().Cross(locProtonP4_OmegaCM.Vect()).Unit();
		TVector3 locHelicityXAxis_OmegaCM = locHelicityYAxis_OmegaCM.Cross(locHelicityZAxis_OmegaCM).Unit();

		//Compute the normal vector to the omega decay plane (pi+ x pi-)
		TVector3 locOmegaNormal = (locPiPlusP4_OmegaCM.Vect().Cross(locPiMinusP4_OmegaCM.Vect()));

		//Compute the theta angle to the omega decay plane
		double locCosTheta = locOmegaNormal.Dot(locHelicityZAxis_OmegaCM)/locOmegaNormal.Mag();
		double lcoTheta = acos(locCosTheta);

		//Compute the phi angle to the omega decay plane
		TVector3 locZCrossOmegaNormal = locHelicityZAxis_OmegaCM.Cross(locOmegaNormal);
		double locZCrossOmegaNormalMag = locZCrossOmegaNormal.Mag();
		double locCosPhi = locHelicityYAxis_OmegaCM.Dot(locZCrossOmegaNormal)/locZCrossOmegaNormalMag;
		double locPhi = acos(locCosPhi); //reports phi between 0 and pi: sign ambiguity
		//Resolve the sign ambiguity
		double locSinPhi = -1.0*locHelicityXAxis_OmegaCM.Dot(locZCrossOmegaNormal)/locZCrossOmegaNormalMag;
		if(locSinPhi < 0.0)
			locPhi *= -1.0;

		//Compute the "psi" angle: works at forward angles
		double locPsi = locPhi - locPHI;
		while(locPsi < -1.0*TMath::Pi())
			locPsi += 2.0*TMath::Pi();
		while(locPsi > TMath::Pi())
			locPsi -= 2.0*TMath::Pi();

		//result is defined by omega, only histogram if omega is unique
		if(locOmegaUniqueFlag)
		{
			dHist_OmegaPsi->Fill(180.0*locPsi/TMath::Pi());
			dHist_OmegaCosTheta->Fill(locCosTheta);
		}
	} //end combo loop

   return kTRUE;
}
Beispiel #22
0
void compare_wls1(TString filename="../p15m_nwls/wcsim.root",TString histoname="p15m_nwls", Int_t *flag, TString rootfile = "temp.root") {

    TFile *file1;
    if (*flag!=0) {
        //file1 = new TFile(rootfile,"Update");
        file1 = new TFile(rootfile,"RECREATE");
    } else {
        file1 = new TFile(rootfile,"RECREATE");
    }
    TString filename1;
    filename1 = histoname + "_digi";
    TTree *T = new TTree(filename1,filename1);
    T->SetDirectory(file1);
    Double_t diginpe,digitime,cor_digitime,digitheta,dis_digihit;
    Int_t neve;

    Double_t mom;
    Double_t pos_x,pos_y,pos_z;
    Double_t dir_x,dir_y,dir_z;
    Double_t tube_x,tube_y,tube_z;
    Double_t totankdis;
    Double_t vertex[3],dir[3];

    Double_t tube_pos[3];

    T->Branch("digi_eve",&neve,"data/I");
    T->Branch("diginpe",&diginpe,"data/D");
    T->Branch("digitime",&digitime,"data/D");
    T->Branch("cor_digitime",&cor_digitime,"data/D");
    T->Branch("digitheta",&digitheta,"data/D");
    T->Branch("dis_dighit",&dis_digihit,"data/D");

    T->Branch("mom",&mom,"data/D");
    T->Branch("totankdis",&totankdis,"data/D");
    T->Branch("pos_x",&vertex[0],"data/D");
    T->Branch("pos_y",&vertex[1],"data/D");
    T->Branch("pos_z",&vertex[2],"data/D");

    T->Branch("dir_x",&dir[0],"data/D");
    T->Branch("dir_y",&dir[1],"data/D");
    T->Branch("dir_z",&dir[2],"data/D");

    T->Branch("tube_x",&tube_pos[0],"data/D");
    T->Branch("tube_y",&tube_pos[1],"data/D");
    T->Branch("tube_z",&tube_pos[2],"data/D");

    filename1 = histoname + "_hit";
    TTree *t1 = new TTree(filename1,filename1);
    t1->SetDirectory(file1);

    Double_t wavelength, truetime, corr_time,theta,distance,index;
    Int_t qe_flag,parentid,tubeid,totalpe;

    Int_t ntracks;

    t1->Branch("ntracks",&ntracks,"data/I");
    t1->Branch("neve",&neve,"data/I");
    t1->Branch("wavelength",&wavelength,"data/D");
    t1->Branch("truetime",&truetime,"data/D");
    t1->Branch("corr_time",&corr_time,"data/D");
    t1->Branch("theta",&theta,"data/D");
    t1->Branch("distance",&distance,"data/D");
    t1->Branch("index",&index,"data/D");

    t1->Branch("mom",&mom,"data/D");
    t1->Branch("totankdis",&totankdis,"data/D");
    t1->Branch("pos_x",&vertex[0],"data/D");
    t1->Branch("pos_y",&vertex[1],"data/D");
    t1->Branch("pos_z",&vertex[2],"data/D");

    t1->Branch("dir_x",&dir[0],"data/D");
    t1->Branch("dir_y",&dir[1],"data/D");
    t1->Branch("dir_z",&dir[2],"data/D");

    t1->Branch("tube_x",&tube_pos[0],"data/D");
    t1->Branch("tube_y",&tube_pos[1],"data/D");
    t1->Branch("tube_z",&tube_pos[2],"data/D");

    // t1->Branch("pos_x",&pos_x,"data/D");
//   t1->Branch("pos_y",&pos_y,"data/D");
//   t1->Branch("pos_z",&pos_z,"data/D");

//   t1->Branch("dir_x",&dir_x,"data/D");
//   t1->Branch("dir_y",&dir_y,"data/D");
//   t1->Branch("dir_z",&dir_z,"data/D");

//   t1->Branch("tube_x",&tube_x,"data/D");
//   t1->Branch("tube_y",&tube_y,"data/D");
//   t1->Branch("tube_z",&tube_z,"data/D");

    t1->Branch("qe_flag",&qe_flag,"data/I");
    t1->Branch("parentid",&parentid,"data/I");
    t1->Branch("tubeid",&tubeid,"data/I");
    t1->Branch("totalpe",&totalpe,"data/I");


    TFile *file = new TFile(filename);
    TTree  *wcsimT = file->Get("wcsimT");
    WCSimRootEvent *wcsimrootsuperevent = new WCSimRootEvent();
    wcsimT->SetBranchAddress("wcsimrootevent",&wcsimrootsuperevent);
    wcsimT->GetBranch("wcsimrootevent")->SetAutoDelete(kTRUE);



    TTree *gtree = file->Get("wcsimGeoT");
    WCSimRootGeom *wcsimrootgeom = new WCSimRootGeom();
    gbranch = gtree->GetBranch("wcsimrootgeom");
    gbranch->SetAddress(&wcsimrootgeom);
    gtree->GetEntry(0);

    WCSimRootPMT *pmt;

    Double_t pmt_pos[500000][3];

    for (Int_t i=0; i!=wcsimrootgeom->GetWCNumPMT(); i++) {
        pmt_pos[i][0] = (wcsimrootgeom->GetPMT(i)).GetPosition(0);
        pmt_pos[i][1] = (wcsimrootgeom->GetPMT(i)).GetPosition(1);
        pmt_pos[i][2] = (wcsimrootgeom->GetPMT(i)).GetPosition(2);
    }

    //in terms of wavelength (total NPE) real hit
    filename1 = histoname + "_total_wl";
    TH1F *hqx = new TH1F(filename1,filename1,600,200,800);

    //NPE in each event sum over digi hit
    filename1 = histoname + "_total_npe";
    TH1F *hqx2 = new TH1F(filename1,filename1,1000,0.,10000);

    //digitized hit time
    filename1 = histoname + "_digitime";
    TH1F *hqx1 = new TH1F(filename1,filename1,500,900,1400);

    //corrected digitized hit time
    filename1 = histoname + "_cor_digitime";
    TH1F *hqx4 = new TH1F(filename1,filename1,1000,400,1400);

    //digitized hit angle
    filename1 = histoname + "_digitheta";
    TH1F *hqx5 = new TH1F(filename1,filename1,180,0,180);



    //TH2F *h1 = new TH2F("h1","h1",100,1000,20000,100,90000,140000);

    Double_t index = 1.333;



    neve = *flag;

    cout << histoname << "\t" << wcsimT->GetEntries() << endl;
    for (Int_t j=0; j!=wcsimT->GetEntries(); j++) {
        //for (Int_t j=0;j!=90;j++){
        // cout << j << endl;
        wcsimT->GetEvent(j);
        neve ++;

        WCSimRootTrigger *wcsimrootevent = wcsimrootsuperevent->GetTrigger(0);
        temp = (TClonesArray*)wcsimrootevent->GetTracks();

        Int_t ntrack =  wcsimrootevent->GetNtrack();
        //cout << ntrack << endl;
        ntracks = ntrack;

        mom = ((WCSimRootTrack*)temp->At(ntrack-1))->GetP();
        //get the vertex information
        vertex[0] = ((WCSimRootTrack*)temp->At(ntrack-1))->GetStart(0);
        vertex[1] = ((WCSimRootTrack*)temp->At(ntrack-1))->GetStart(1);
        vertex[2] = ((WCSimRootTrack*)temp->At(ntrack-1))->GetStart(2);

        //get position information
        dir[0] = ((WCSimRootTrack*)temp->At(ntrack-1))->GetDir(0);
        dir[1] = ((WCSimRootTrack*)temp->At(ntrack-1))->GetDir(1);
        dir[2] = ((WCSimRootTrack*)temp->At(ntrack-1))->GetDir(2);

        totankdis=ToTankDistance(vertex,dir);

        TVector3 vertex3(vertex[0],vertex[1],vertex[2]);
        TVector3 dir3(dir[0],dir[1],dir[2]);


        //loop through digi hit
        int max = wcsimrootevent->GetNcherenkovdigihits();

        double sum = 0;

        for (int i=0; i<max; i++) {
            // cout << max << "\t" << i << endl;
            WCSimRootCherenkovDigiHit *cDigiHit = ((WCSimRootCherenkovDigiHit*)wcsimrootevent->GetCherenkovDigiHits()->At(i));
            hqx1->Fill(cDigiHit->GetT());
            tube_pos[0] =  pmt_pos[(cDigiHit->GetTubeId()-1)][0];
            tube_pos[1] =  pmt_pos[(cDigiHit->GetTubeId()-1)][1];
            tube_pos[2] =  pmt_pos[(cDigiHit->GetTubeId()-1)][2];

            TVector3 hit3(tube_pos[0],tube_pos[1],tube_pos[2]);
            TVector3 dis = hit3-vertex3;

            diginpe = cDigiHit->GetQ();
            digitime = cDigiHit->GetT();
            cor_digitime = digitime-dis.Mag()/299792458.*1.333*1.e7;
            digitheta = dis.Angle(dir3)/3.1415926*180.;
            dis_digihit = dis.Mag();


            hqx4->Fill(cor_digitime,diginpe);
            hqx5->Fill(digitheta,diginpe);
            sum += diginpe;

            T->Fill();
        }
        hqx2->Fill(sum);


        //loop through real hit



        //loop through PMT hit first
        max = wcsimrootevent-> GetNcherenkovhits();
        //cout << max << endl;
        if (max ==0) {
            t1->Fill();
        }
        for (int i=0; i<max; i++) {
            WCSimRootCherenkovHit* wcsimrootcherenkovhit =
                dynamic_cast<WCSimRootCherenkovHit*>((wcsimrootevent->GetCherenkovHits())->At(i));

            totalpe = wcsimrootcherenkovhit->GetTotalPe(1);
            tubeid = wcsimrootcherenkovhit->GetTubeID() ;

            //loop through hit time etc
            for (int k=0; k<totalpe; k++) {
                TObject *element2 = (wcsimrootevent->GetCherenkovHitTimes())->
                                    At(wcsimrootcherenkovhit->GetTotalPe(0)+k);
                WCSimRootCherenkovHitTime *wcsimrootcherenkovhittime
                    = dynamic_cast<WCSimRootCherenkovHitTime*>(element2);

                wavelength =wcsimrootcherenkovhittime->GetWavelength();
                qe_flag = wcsimrootcherenkovhittime->GetQe_flag();
                truetime = wcsimrootcherenkovhittime->GetTruetime();
                parentid = wcsimrootcherenkovhittime->GetParentID();

                pos_x = wcsimrootcherenkovhittime->GetPosX() ;
                pos_y = wcsimrootcherenkovhittime->GetPosY() ;
                pos_z = wcsimrootcherenkovhittime->GetPosZ() ;
                dir_x = wcsimrootcherenkovhittime->GetDirX() ;
                dir_y = wcsimrootcherenkovhittime->GetDirY() ;
                dir_z = wcsimrootcherenkovhittime->GetDirZ() ;

                tube_pos[0] =  pmt_pos[tubeid-1][0];
                tube_pos[1] =  pmt_pos[tubeid-1][1];
                tube_pos[2] =  pmt_pos[tubeid-1][2];

                tube_x = tube_pos[0];
                tube_y = tube_pos[1];
                tube_z = tube_pos[2];



                TVector3 hit3(tube_pos[0],tube_pos[1],tube_pos[2]);
                TVector3 dis = hit3-vertex3;

                distance = dis.Mag();
                theta = dis.Angle(dir3)/3.1415926*180.;
                //index = index(wavelength);
                index = 1.34;
                corr_time = truetime - distance/299792458.*1e7*index;

                if (qe_flag==1) {
                    hqx->Fill(wavelength);
                }

                t1->Fill();
            }
        }



    }

    if (flag==1) {
        hqx->SetDirectory(file1);
        hqx2->SetDirectory(file1);
        hqx1->SetDirectory(file1);
        hqx4->SetDirectory(file1);
        hqx5->SetDirectory(file1);
        file1->Write();
        file1->Close();
    } else {
        hqx->SetDirectory(file1);
        hqx2->SetDirectory(file1);
        hqx1->SetDirectory(file1);
        hqx4->SetDirectory(file1);
        hqx5->SetDirectory(file1);
        file1->Write();
        file1->Close();
    }

    *flag = neve;

}
Beispiel #23
0
void testlor::Loop()
{
//   In a ROOT session, you can do:
//      Root > .L testlor.C
//      Root > testlor 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

//Set-up Code
	if (fChain == 0) return;

	Long64_t nentries = fChain->GetEntriesFast();

	Long64_t nbytes = 0, nb = 0;
	int pions=0,kaons=0,ksTOpi=0,i=0,j=0;
	int ipart1,ipart2,a,b;
	Double_t ppion[kMaxentry];
	Double_t npion[kMaxentry];
	Double_t p[kMaxentry];
	double prop=0;
	Double_t pp,E,KSmass;
   	TLorentzVector q[kMaxentry];//pinakas tupou tlorentz
	TLorentzVector w,v; 
	TVector3 l;
	
	TH1D *pzhist=new TH1D("pz","pz histogram",120,-12,12);
	TH1D *pthist=new TH1D("pt","pt histogram",50,0,1.5);
	TH1D *kshist=new TH1D("KSmass","KSmasss",120,0.2,0.8);
	TH1D *kshist2=new TH1D("KSmass","KSmasss",120,0.,5);
	TH1D *pseudohist=new TH1D("Pseudorapidity","Pseudorapidity",120,-15,15);
	
	cout << "Number of events = " << nentries << endl;
	
   //event loop
	for (Long64_t jentry=0; jentry<nentries;jentry++) {//nentries
		Long64_t ientry = LoadTree(jentry);
		if (ientry < 0) break;
		nb = fChain->GetEntry(jentry);   nbytes += nb;
		cout << " event # " << jentry << ",  #particles " <<  entry_ << endl;
		// if (Cut(ientry) < 0) continue;

		//particle loop
		for (int ipart = 0; ipart < entry_ ; ipart++) {
			w.SetPx(entry_pSave_xx[ipart]);
			w.SetPy(entry_pSave_yy[ipart]);
			w.SetPz(entry_pSave_zz[ipart]);
			w.SetE(entry_pSave_tt[ipart]);
			q[ipart]=w;
			l=q[ipart].Vect();
			//~ cout<<"pseudorapidity="<<l.PseudoRapidity()<<endl;
			p[ipart]=l.Mag();
			cout<<"p="<<l.Mag()<<endl;//P!
			//~ cout<<"m="<<q[ipart].M()<<endl;//m?not right
			//~ cout<<"pt="<<q[ipart].Perp()<<endl;//PT!
			//~ cout <<"i="<<ipart<< "\tpdgID = " << entry_idSave[ipart]<<",\t Daughter1="<<entry_idSave[entry_daughter1Save[ipart]]<<",\tDaughter2="<<entry_idSave[entry_daughter2Save[ipart]]<<"\tEnergy="<<entry_pSave_tt[ipart]<<endl;
		
			//pions vs kaons
			if(((TMath::Abs(entry_idSave[ipart]))==(211))||(entry_idSave[ipart]==(111))) {
				pions++;
			} 	
			else if((entry_idSave[ipart]==130)||
				((TMath::Abs(entry_idSave[ipart]))==(321))||(entry_idSave[ipart]==310)
				||((TMath::Abs(entry_idSave[ipart]))==(311))||((TMath::Abs(entry_idSave[ipart]))==(323))
				||((TMath::Abs(entry_idSave[ipart]))==(313)) ) {
				kaons++; 
			}
			
			
			//Ks->pions
			if((entry_idSave[ipart]==310)&&(((entry_idSave[entry_daughter1Save[ipart]]==(211))&&(entry_idSave[entry_daughter2Save[ipart]]==(-1)*(211)))
			||((entry_idSave[entry_daughter1Save[ipart]]==(-1)*(211))&&(entry_idSave[entry_daughter2Save[ipart]]==(211))) )){
				
				ipart1[ksTOpi]=entry_daughter1Save[ipart];
		        ipart2[ksTOpi]=entry_daughter2Save[ipart];
		        cout<<"ipart1="<<ipart1<<"\t ipart2="<<ipart2<<endl;
				ksTOpi++;
				cout<<"ksTOpi="<<ksTOpi<<endl;
				
			}//end of ks->pions if
				
			if(entry_idSave[ipart]==211){
				ppion[i]=ipart;
				i++;}
				
			if(entry_idSave[ipart]==(-1)*(211)){
				npion[j]=ipart;
				j++;}
			
			
			//Fill Histograms
			pzhist->Fill(entry_pSave_zz[ipart]);
			pthist->Fill(q[ipart].Perp());
			pseudohist->Fill(l.PseudoRapidity()); 		
		
		}//end of particle loop
      
		
		//Ksmass 
		for(int n=0;n<i;n++){
			a=ppion[n];
			for(int m=0;m<j;m++){
				b=npion[m];
				v=q[a]+q[b];
				//~ TVector3 y=v.Vect();
				//~ pp=y.Mag();
				//~ E=v.E();
				KSmass=v.M();
				kshist2->Fill(KSmass);
					
			}//end of npion loop
		}//end of ppion loop
				
		//KStoPI
		for(int count=0;count<ksTOpi;count++){
			v=q[ipart1[ksTOpi]]+q[ipart2[ksTOpi]];
			//~ l=v.Vect();
			//~ pp=l.Mag();
			//~ E=v.E();
			KSmass=v.M();
			kshist->Fill(KSmass);
		}//end of ksTOpi loop
			
		i=0;
		j=0;
		ksTOpi=0;
		
	if(kaons!=0){
		prop=prop+((double)kaons)/((double)pions);
		}
		
	
	}//end of event loop
   
	//Wrap-up code
	TCanvas* k1 = new TCanvas("c1","Pythia8Ana",800,800);
	k1->Divide(1, 3);

	k1->cd(1);
	kshist->Draw();
	kshist->GetXaxis()->SetTitle("mass [GeV/c^2]");
	kshist->GetYaxis()->SetTitle("Number of events");

	k1->cd(2);
	kshist2->Draw();
	kshist2->GetXaxis()->SetTitle("mass [GeV/c^2]");
	kshist2->GetYaxis()->SetTitle("Number of events");



	//~ 
	//~ k1->cd(2);
	//~ pseudohist->Draw();
	//~ pseudohist->GetXaxis()->SetTitle("pseudorapidity");
	//~ pseudohist->GetYaxis()->SetTitle("Number of events");



	k1->cd(3);
	pthist->Draw();
	pthist->GetXaxis()->SetTitle("pt [GeV/c]");
	pthist->GetYaxis()->SetTitle("Number of events");

	cout<<"Ebeam1="<<entry_pSave_tt[1]<<"[GeV], Ebeam2="<<entry_pSave_tt[2]<<"[GeV]"<<endl;
	cout<<"Mass1= "<<entry_mSave[1]<<"  Mass2="<<entry_mSave[2]<<endl;
	cout<<"Kaons="<<prop/nentries<<"Pions"<<endl;
	cout<<"kaons="<<kaons<<", Pions="<<pions<<endl;
	cout<<"event found, ipart1="<<ipart1<<"\t ipart2="<<ipart2<<endl;
	cout<<"ipart1="<<ipart1<<endl;
	cout<<"p["<<ipart1<<"]="<<p[ipart1]<<endl;

}//End of Loop method
Beispiel #24
0
KVFAZIABlock::KVFAZIABlock() : TGeoVolumeAssembly("STRUCT_BLOCK")
{
   // Default constructor

   SetMedium(gGeoManager->GetMedium("Vacuum"));//to avoid warnings about STRUCT_BLOCK has dummy medium

   KVMaterial mat_si("Si");
   TGeoMedium *Silicon = mat_si.GetGeoMedium();

   KVMaterial mat_csi("CsI");
   TGeoMedium *CesiumIodide = mat_csi.GetGeoMedium();

   KVMaterial mat_plomb("Lead");
   TGeoMedium *Plomb = mat_plomb.GetGeoMedium();

   TGeoVolumeAssembly* quartet = gGeoManager->MakeVolumeAssembly("STRUCT_QUARTET");
   quartet->SetMedium(gGeoManager->GetMedium("Vacuum"));//to avoid warnings about STRUCT_QUARTET has dummy medium

   TGeoVolume* si = 0;
   TGeoVolume* csi = 0;

   Double_t distance_si2_si1 = 0.220;
   Double_t distance_csi_si2 = 0.434;

   Double_t side_si = 2;
   Double_t side_csi_front = 2.050;
   Double_t side_csi_back = 2.272;

   Double_t inter_si = 0.24;

   Double_t thick_si1 = 300 * KVUnits::um;
   Double_t thick_si2 = 500 * KVUnits::um;
   Double_t thick_csi = 10;

   Double_t adjust_csi = 0.0165;

   Int_t ndet = 1;;
   TGeoTranslation* tr = 0;

   Double_t shift = side_si / 2 + inter_si / 2;
   //printf("%lf\n", shift);

   Double_t coefx[4] = { -1., -1., 1., 1.};
   Double_t coefy[4] = {1., -1., -1., 1.};

   for (Int_t nt = 1; nt <= 4; nt += 1) {

      shift = side_si / 2 + inter_si / 2;

      si = gGeoManager->MakeBox(Form("DET_SI1-T%d", nt), Silicon, side_si / 2, side_si / 2, thick_si1 / 2.);
      tr = new TGeoTranslation(coefx[nt - 1]*shift, coefy[nt - 1]*shift, thick_si1 / 2.);

      quartet->AddNode(si, ndet++, tr);
      ((TGeoNodeMatrix*)quartet->GetNodes()->Last())->SetName(Form("DET_SI1-T%d", nt));

      si = gGeoManager->MakeBox(Form("DET_SI2-T%d", nt), Silicon, side_si / 2, side_si / 2, thick_si2 / 2.);
      tr = new TGeoTranslation(coefx[nt - 1]*shift, coefy[nt - 1]*shift, thick_si2 / 2. + distance_si2_si1);
      quartet->AddNode(si, ndet++, tr);
      ((TGeoNodeMatrix*)quartet->GetNodes()->Last())->SetName(Form("DET_SI2-T%d", nt));

      shift = side_si / 2 + inter_si / 2 + adjust_csi;

      csi = gGeoManager->MakeTrd2(Form("DET_CSI-T%d", nt), CesiumIodide, side_csi_front / 2, side_csi_back / 2, side_csi_front / 2, side_csi_back / 2, thick_csi / 2.);
      tr = new TGeoTranslation(coefx[nt - 1]*shift, coefy[nt - 1]*shift, thick_csi / 2. + distance_csi_si2);
      quartet->AddNode(csi, ndet++, tr);
      ((TGeoNodeMatrix*)quartet->GetNodes()->Last())->SetName(Form("DET_CSI-T%d", nt));

   }

   Int_t nbl = 1;
   TGeoVolume* blindage = 0;
//Double_t thick_bld = thick_si1+distance_si2_si1+thick_si2;
   /* l'epaisseur du si1 est compris dans la distance_si2_si1 */
   Double_t thick_bld = distance_si2_si1 + thick_si2;
   Double_t shift_bld = (side_si + inter_si) / 2.;
///Croix inter quartet
//
// Separation des 4 télescopes
//
//
   blindage = gGeoManager->MakeBox("DEADZONE_BLINDAGE_1", Plomb, inter_si / 2, (side_si + inter_si / 2), thick_bld / 2.);
   //printf("%s\n", blindage->GetMaterial()->GetTitle());
   tr = new TGeoTranslation(0, 0, thick_bld / 2.);
   quartet->AddNode(blindage, nbl++, tr);

   blindage = gGeoManager->MakeBox("DEADZONE_BLINDAGE_2", Plomb, (side_si / 2), inter_si / 2, thick_bld / 2.);
   tr = new TGeoTranslation(-1 * shift_bld, 0, thick_bld / 2.);
   quartet->AddNode(blindage, nbl++, tr);
   tr = new TGeoTranslation(+1 * shift_bld, 0, thick_bld / 2.);
   quartet->AddNode(blindage, nbl++, tr);

///Contour de l ensemble du quartet
//
//Délimiation des bords exterieurs
//
//
   shift_bld = (side_si + inter_si);

   blindage = gGeoManager->MakeBox("DEADZONE_BLINDAGE_3", Plomb, (side_si + inter_si / 2), inter_si / 2, thick_bld / 2.);
   tr = new TGeoTranslation(0, shift_bld, thick_bld / 2.);
   quartet->AddNode(blindage, nbl++, tr);
   tr = new TGeoTranslation(0, -1 * shift_bld, thick_bld / 2.);
   quartet->AddNode(blindage, nbl++, tr);
///
   blindage = gGeoManager->MakeBox("DEADZONE_BLINDAGE_4", Plomb, inter_si / 2, (side_si + inter_si * 1.5), thick_bld / 2.);
   tr = new TGeoTranslation(shift_bld, 0, thick_bld / 2.);
   quartet->AddNode(blindage, nbl++, tr);
   tr = new TGeoTranslation(-1 * shift_bld, 0, thick_bld / 2.);
   quartet->AddNode(blindage, nbl++, tr);

   fTotSidWBlind = 4 * side_si + 5 * inter_si;
//Coordonnées extraite des côtes données par Yvan M.
//vecteur pointant le milieu d un quartet
//X=-2.231625
//Y=-2.230525
//Z=99.950350
// Mag=100.000139
// Theta=1.808104
// Phi = -135.014124
   TVector3* placement = new TVector3(-2.231625, -2.230525, 99.950350);
   TVector3* Centre = new TVector3();

   TGeoRotation rot1, rot2;
   TGeoTranslation trans;
   TGeoTranslation invZtrans(0, 0, -100);

   TGeoHMatrix h;
   TGeoHMatrix* ph = 0;

//Boucle sur les 4 quartets d un block
   Double_t tx[4] = {1, -1, -1, 1};
   Double_t ty[4] = {1, 1, -1, -1};

   Double_t theta = 0;
   Double_t phi = 0;
   Double_t trans_z = 0;

   for (Int_t nq = 1; nq <= 4; nq += 1) {

      Centre->SetXYZ(placement->X()*tx[nq - 1], placement->Y()*ty[nq - 1], placement->Z());

      theta = Centre->Theta() * TMath::RadToDeg();
      phi = Centre->Phi() * TMath::RadToDeg();

      trans_z = Centre->Mag() + thick_si1 / 2.;

      rot2.SetAngles(phi + 90., theta, 0.);
      rot1.SetAngles(-1.*phi, 0., 0.);
      trans.SetDz(trans_z);

      h = invZtrans * rot2 * trans * rot1;
      ph = new TGeoHMatrix(h);

      AddNode(quartet, nq, ph);
   }
}
Beispiel #25
0
void readTrigger()
{
  TLorentzVector eplus[50], eminus[50];
  TLorentzVector momentum,  momentum_pair;
  TVector3 mom;
  Float_t px, py, pz;
  Int_t pdg;
  Int_t nplus=0, nminus=0, njpsi=0; 

  TH1F *hEl = new TH1F("hEl","number of electrons", 10,0,10);
  TH1F *hPtel = new TH1F("hPtel"," dN/dPt ",100,0,4);
  TH1F *hPel = new TH1F("hPel"," dN/dP ",100,0,30);
   
 
  // Load basic libraries


  gROOT->LoadMacro("$VMCWORKDIR/gconfig/basiclibs.C");
  basiclibs();
  gSystem->Load("libPhysics");
  
  gSystem->Load("libGeoBase");
  gSystem->Load("libParBase");
  gSystem->Load("libBase");
  gSystem->Load("libCbmBase");
  gSystem->Load("libCbmData");
  gSystem->Load("libJpsi.so");

  Char_t fileName[100];
  Int_t fNevents = 0;
  Int_t fElectronEvents=0; 
  for (Int_t ifile=0; ifile<1; ifile++)
    {
      TFile *f1 = new TFile(Form("jpsitrigger.25gev.pure.0000.root",ifile));
      TTree* t1 =(TTree*) f1->Get("cbmsim");
      TFolder *fd1 =(TFolder*)  f1->Get("cbmout");

      TClonesArray* fJpsi = (TClonesArray*)fd1->FindObjectAny("CbmJpsiTriggerElectron");
      t1->SetBranchAddress("CbmJpsiTriggerElectron",&fJpsi);
      
      
      Int_t nevent = t1->GetEntries();
      cout<<nevent<<endl;
      nplus=0; nminus=0;
      for(Int_t i=0; i<nevent; i++)
	{
	  nplus = 0;  
	  nminus = 0;
	  fNevents++;
	  t1->GetEntry(i);
	  Int_t nel = fJpsi->GetEntries();
	  for ( Int_t iel=0; iel<nel; iel++)
	    { 
	      CbmJpsiTriggerElectron *jel = (CbmJpsiTriggerElectron*)fJpsi->At(iel);
	      mom = jel->GetMomentum();
	      hPel->Fill(mom.Mag());
	      hPtel->Fill(mom.Pt());
	      if (mom.Pt() < 1.2) continue;
	      momentum.SetVectM(mom,0.000511);
	      pdg = jel -> GetPdg();
	      Double_t ann = jel -> GetAnn();
	      Double_t like = jel -> GetLike();
	      Double_t wkn = jel -> GetWkn();
	      Double_t ran = gRandom->Rndm();
	        if(ann > 0.8 ) 
		{
		  eplus[nplus]=momentum; 
		  nplus++;
		  eplus[nplus].SetXYZT(0,0,0,0);

		}	
	    }
	  hEl->Fill(nplus);
	
	  if ( nplus>1 )   fElectronEvents++;  
    } // event loop
 
      f1->Close();
    }

  cout<< " ElectronEvents "<< fElectronEvents<<endl;
 TFile *fmass = new TFile("jpsiTrigger.hist.root","RECREATE");
 
  hEl->Scale(1./Float_t (fNevents));
  hEl->Write();
  hPel->Scale(1./Float_t (fNevents ));
  hPel->Write();
  hPtel->Scale(1./Float_t (fNevents));
  hPtel->Write();
}
Beispiel #26
0
void NewVariables(){

  const double protonmass = 938.272013; //MeV
  const double pionmass = 139.57018; //MeV
  const double kaonmass = 493.677; //MeV
  //const double muonmass = 105.6583715; //MeV

  TStopwatch *clock = new TStopwatch();
  clock->Start(1);

  double p_PT, p_ETA, p_PHI;
  double K_PT, K_ETA, K_PHI;
  double pi_PT, pi_ETA, pi_PHI;
  double Xb_OWNPV_X, Xb_OWNPV_Y, Xb_OWNPV_Z;
  double Xb_ENDVERTEX_X, Xb_ENDVERTEX_Y, Xb_ENDVERTEX_Z;
  double Xb_PT, Xb_ETA, Xb_PHI, Xb_M;
  double Xc_PT, Xc_ETA, Xc_PHI, Xc_M;
  float Added_H_PT[200], Added_H_ETA[200], Added_H_PHI[200];
  int Added_n_Particles;

  gErrorIgnoreLevel = kError;
  TFile *fSLBS = new TFile("/auto/data/mstahl/SLBaryonSpectroscopy/SLBaryonSpectroscopyStrp21.root","read");
  TTree *Xic_tree = (TTree*)gDirectory->Get("Xib02XicMuNu/Xic2pKpi/DecayTree");
  gErrorIgnoreLevel = kPrint;
  Xic_tree->SetBranchStatus("*",0); //disable all branches
  //now switch on the ones we need (saves a lot of time)  
  Xic_tree->SetBranchStatus("Xib_M",1);
  Xic_tree->SetBranchStatus("Xib_PT",1);
  Xic_tree->SetBranchStatus("Xib_ETA",1);
  Xic_tree->SetBranchStatus("Xib_PHI",1);
  Xic_tree->SetBranchStatus("Xib_OWNPV_X",1);
  Xic_tree->SetBranchStatus("Xib_OWNPV_Y",1);
  Xic_tree->SetBranchStatus("Xib_OWNPV_Z",1);
  Xic_tree->SetBranchStatus("Xib_ENDVERTEX_X",1);
  Xic_tree->SetBranchStatus("Xib_ENDVERTEX_Y",1);
  Xic_tree->SetBranchStatus("Xib_ENDVERTEX_Z",1);

  Xic_tree->SetBranchStatus("Xic_M",1);
  Xic_tree->SetBranchStatus("Xic_PT",1);
  Xic_tree->SetBranchStatus("Xic_ETA",1);
  Xic_tree->SetBranchStatus("Xic_PHI",1);

  Xic_tree->SetBranchStatus("Added_n_Particles",1);
  Xic_tree->SetBranchStatus("Added_H_PT",1);
  Xic_tree->SetBranchStatus("Added_H_ETA",1);
  Xic_tree->SetBranchStatus("Added_H_PHI",1);

  Xic_tree->SetBranchStatus("p_PT",1);
  Xic_tree->SetBranchStatus("p_ETA",1);
  Xic_tree->SetBranchStatus("p_PHI",1);
  Xic_tree->SetBranchStatus("K_PT",1);
  Xic_tree->SetBranchStatus("K_ETA",1);
  Xic_tree->SetBranchStatus("K_PHI",1);
  Xic_tree->SetBranchStatus("pi_PT",1);
  Xic_tree->SetBranchStatus("pi_ETA",1);
  Xic_tree->SetBranchStatus("pi_PHI",1);

  //set the branch addresses
  Xic_tree->SetBranchAddress("Xib_M",&Xb_M);
  Xic_tree->SetBranchAddress("Xib_PT",&Xb_PT);
  Xic_tree->SetBranchAddress("Xib_ETA",&Xb_ETA);
  Xic_tree->SetBranchAddress("Xib_PHI",&Xb_PHI);
  Xic_tree->SetBranchAddress("Xib_OWNPV_X",&Xb_OWNPV_X);
  Xic_tree->SetBranchAddress("Xib_OWNPV_Y",&Xb_OWNPV_Y);
  Xic_tree->SetBranchAddress("Xib_OWNPV_Z",&Xb_OWNPV_Z);
  Xic_tree->SetBranchAddress("Xib_ENDVERTEX_X",&Xb_ENDVERTEX_X);
  Xic_tree->SetBranchAddress("Xib_ENDVERTEX_Y",&Xb_ENDVERTEX_Y);
  Xic_tree->SetBranchAddress("Xib_ENDVERTEX_Z",&Xb_ENDVERTEX_Z);

  Xic_tree->SetBranchAddress("Xic_M",&Xc_M);
  Xic_tree->SetBranchAddress("Xic_PT",&Xc_PT);
  Xic_tree->SetBranchAddress("Xic_ETA",&Xc_ETA);
  Xic_tree->SetBranchAddress("Xic_PHI",&Xc_PHI);

  Xic_tree->SetBranchAddress("Added_n_Particles",&Added_n_Particles);
  Xic_tree->SetBranchAddress("Added_H_PT",&Added_H_PT);
  Xic_tree->SetBranchAddress("Added_H_ETA",&Added_H_ETA);
  Xic_tree->SetBranchAddress("Added_H_PHI",&Added_H_PHI);

  Xic_tree->SetBranchAddress("p_PT",&p_PT);
  Xic_tree->SetBranchAddress("p_ETA",&p_ETA);
  Xic_tree->SetBranchAddress("p_PHI",&p_PHI);
  Xic_tree->SetBranchAddress("K_PT",&K_PT);
  Xic_tree->SetBranchAddress("K_ETA",&K_ETA);
  Xic_tree->SetBranchAddress("K_PHI",&K_PHI);
  Xic_tree->SetBranchAddress("pi_PT",&pi_PT);
  Xic_tree->SetBranchAddress("pi_ETA",&pi_ETA);
  Xic_tree->SetBranchAddress("pi_PHI",&pi_PHI);
  //SLBS_tree->AddBranchToCache("*");
  //SLBS_tree->LoadBaskets(1000000000);//Load baskets up to 1 GB to memory

  double Xb_CorrM, p_beta, K_beta, pi_beta;
  float Xcpi_CosTheta[200],XcK_CosTheta[200],Xcp_CosTheta[200];
  double p_as_piKpi_M, p_as_KKpi_M, pK_as_pipi_M, pK_as_ppi_M, pKpi_as_K_M, pKpi_as_p_M;

  TFile *f1 = new TFile("/auto/data/mstahl/SLBaryonSpectroscopy/SLBaryonSpectroscopyStrp21_friend.root","RECREATE");
  //f1->mkdir("Xib02XicMuNu/Xic2pKpi");
  //f1->cd("Xib02XicMuNu/Xic2pKpi");
  TTree added_Xic_tree("Xic2pKpi","Xic2pKpi");

  added_Xic_tree.Branch("Xib_CorrM", &Xb_CorrM, "Xib_CorrM/D");
  added_Xic_tree.Branch("p_beta", &p_beta, "p_beta/D");
  added_Xic_tree.Branch("K_beta", &K_beta, "K_beta/D");
  added_Xic_tree.Branch("pi_beta", &pi_beta, "pi_beta/D");
  added_Xic_tree.Branch("Added_n_Particles", &Added_n_Particles, "Added_n_Particles/I");
  added_Xic_tree.Branch("Xcpi_CosTheta", &Xcpi_CosTheta, "Xcpi_CosTheta[Added_n_Particles]/F");
  added_Xic_tree.Branch("XcK_CosTheta", &XcK_CosTheta, "XcK_CosTheta[Added_n_Particles]/F");
  added_Xic_tree.Branch("Xcp_CosTheta", &Xcp_CosTheta, "Xcp_CosTheta[Added_n_Particles]/F");
  added_Xic_tree.Branch("p_as_piKpi_M", &p_as_piKpi_M, "p_as_piKpi_M/D");
  added_Xic_tree.Branch("p_as_KKpi_M", &p_as_KKpi_M, "p_as_KKpi_M/D");
  added_Xic_tree.Branch("pK_as_pipi_M", &pK_as_pipi_M, "pK_as_pipi_M/D");
  added_Xic_tree.Branch("pK_as_ppi_M", &pK_as_ppi_M, "pK_as_ppi_M/D");
  added_Xic_tree.Branch("pKpi_as_K_M", &pKpi_as_K_M, "pKpi_as_K_M/D");
  added_Xic_tree.Branch("pKpi_as_p_M", &pKpi_as_p_M, "pKpi_as_p_M/D");

  UInt_t Xic_nevents = Xic_tree->GetEntries();
  cout << "Entries in Xic tree: " << Xic_nevents << endl;

  for (UInt_t evt = 0; evt < Xic_nevents;evt++) {
    Xic_tree->GetEntry(evt);

    TVector3 dir(Xb_ENDVERTEX_X-Xb_OWNPV_X,Xb_ENDVERTEX_Y-Xb_OWNPV_Y,Xb_ENDVERTEX_Z-Xb_OWNPV_Z);
    TVector3 mom;
    mom.SetPtEtaPhi(Xb_PT,Xb_ETA,Xb_PHI);
    double dmag2 = dir.Mag2();
    double ptprime = 0;
    if ( 0 == dmag2 ) ptprime = mom.Mag();
    else ptprime = (mom - dir * ( mom.Dot( dir ) / dmag2 )).Mag() ;
    Xb_CorrM = sqrt(Xb_M*Xb_M + ptprime*ptprime) + ptprime;

    TLorentzVector Xb;
    Xb.SetPtEtaPhiM(Xb_PT,Xb_ETA,Xb_PHI,Xb_CorrM);
    TLorentzVector Xc;
    Xc.SetPtEtaPhiM(Xc_PT,Xc_ETA,Xc_PHI,Xc_M);
    for(int i = 0; i < Added_n_Particles; i++){
      TLorentzVector Hpi;
      Hpi.SetPtEtaPhiM(Added_H_PT[i],Added_H_ETA[i],Added_H_PHI[i],pionmass);
      TLorentzVector HK;
      HK.SetPtEtaPhiM(Added_H_PT[i],Added_H_ETA[i],Added_H_PHI[i],kaonmass);
      TLorentzVector Hp;
      Hp.SetPtEtaPhiM(Added_H_PT[i],Added_H_ETA[i],Added_H_PHI[i],protonmass);
      TLorentzVector Xcpi = Hpi + Xc;
      TLorentzVector XcK = HK + Xc;
      TLorentzVector Xcp = Hp + Xc;
      Xcpi.Boost(-Xb.BoostVector());
      Xcpi_CosTheta[i] = cos(Xcpi.Angle(Xb.Vect()));
      XcK.Boost(-Xb.BoostVector());
      XcK_CosTheta[i] = cos(XcK.Angle(Xb.Vect()));
      Xcp.Boost(-Xb.BoostVector());
      Xcp_CosTheta[i] = cos(Xcp.Angle(Xb.Vect()));
    }

    TLorentzVector proton;
    proton.SetPtEtaPhiM(p_PT,p_ETA,p_PHI,protonmass);
    TLorentzVector kaon;
    kaon.SetPtEtaPhiM(K_PT,K_ETA,K_PHI,kaonmass);
    TLorentzVector pion;
    pion.SetPtEtaPhiM(pi_PT,pi_ETA,pi_PHI,pionmass);

    p_beta  = (-proton.P()+kaon.P()+pion.P())/(proton.P()+kaon.P()+pion.P());
    K_beta  = ( proton.P()-kaon.P()+pion.P())/(proton.P()+kaon.P()+pion.P());
    pi_beta = ( proton.P()+kaon.P()-pion.P())/(proton.P()+kaon.P()+pion.P());

    TLorentzVector p_as_pi;
    p_as_pi.SetVectM(proton.Vect(),pionmass);
    TLorentzVector p_as_K;
    p_as_K.SetVectM(proton.Vect(),kaonmass);

    TLorentzVector K_as_pi;
    K_as_pi.SetVectM(kaon.Vect(),pionmass);
    TLorentzVector K_as_p;
    K_as_p.SetVectM(kaon.Vect(),protonmass);

    TLorentzVector pi_as_K;
    pi_as_K.SetVectM(pion.Vect(),kaonmass);
    TLorentzVector pi_as_p;
    pi_as_p.SetVectM(pion.Vect(),protonmass);

    p_as_piKpi_M = (p_as_pi + kaon + pion).M();
    p_as_KKpi_M = (p_as_K + kaon + pion).M();

    pK_as_pipi_M = (proton + K_as_pi + pion).M();
    pK_as_ppi_M = (proton + K_as_p + pion).M();

    pKpi_as_K_M = (proton + kaon + pi_as_K).M();
    pKpi_as_p_M = (proton + kaon + pi_as_p).M();

    added_Xic_tree.Fill();

  }

  Xic_tree->SetDirectory(0);
  added_Xic_tree.Write();

  fSLBS->cd();
  TTree *Xic0_tree = (TTree*)gDirectory->Get("Xib2Xic0MuNu/Xic02pKKpi/DecayTree");

  double p_P, SSK1_P, SSK2_P, pi_P;
  double SSK1_PT, SSK2_PT, SSK1_ETA, SSK2_ETA, SSK1_PHI, SSK2_PHI;

  Xic0_tree->SetBranchStatus("*",0); //disable all branches
  //now switch on the ones we need (saves a lot of time)
  Xic0_tree->SetBranchStatus("Xib_M",1);
  Xic0_tree->SetBranchStatus("Xib_PT",1);
  Xic0_tree->SetBranchStatus("Xib_ETA",1);
  Xic0_tree->SetBranchStatus("Xib_PHI",1);
  Xic0_tree->SetBranchStatus("Xib_OWNPV_X",1);
  Xic0_tree->SetBranchStatus("Xib_OWNPV_Y",1);
  Xic0_tree->SetBranchStatus("Xib_OWNPV_Z",1);
  Xic0_tree->SetBranchStatus("Xib_ENDVERTEX_X",1);
  Xic0_tree->SetBranchStatus("Xib_ENDVERTEX_Y",1);
  Xic0_tree->SetBranchStatus("Xib_ENDVERTEX_Z",1);

  Xic0_tree->SetBranchStatus("Xic_M",1);
  Xic0_tree->SetBranchStatus("Xic_PT",1);
  Xic0_tree->SetBranchStatus("Xic_ETA",1);
  Xic0_tree->SetBranchStatus("Xic_PHI",1);

  Xic0_tree->SetBranchStatus("Added_n_Particles",1);
  Xic0_tree->SetBranchStatus("Added_H_PT",1);
  Xic0_tree->SetBranchStatus("Added_H_ETA",1);
  Xic0_tree->SetBranchStatus("Added_H_PHI",1);

  Xic0_tree->SetBranchStatus("p_P",1);
  Xic0_tree->SetBranchStatus("SSK1_P",1);
  Xic0_tree->SetBranchStatus("SSK2_P",1);
  Xic0_tree->SetBranchStatus("pi_P",1);

  Xic0_tree->SetBranchStatus("p_PT",1);
  Xic0_tree->SetBranchStatus("p_ETA",1);
  Xic0_tree->SetBranchStatus("p_PHI",1);
  Xic0_tree->SetBranchStatus("SSK1_PT",1);
  Xic0_tree->SetBranchStatus("SSK1_ETA",1);
  Xic0_tree->SetBranchStatus("SSK1_PHI",1);
  Xic0_tree->SetBranchStatus("SSK2_PT",1);
  Xic0_tree->SetBranchStatus("SSK2_ETA",1);
  Xic0_tree->SetBranchStatus("SSK2_PHI",1);
  Xic0_tree->SetBranchStatus("pi_PT",1);
  Xic0_tree->SetBranchStatus("pi_ETA",1);
  Xic0_tree->SetBranchStatus("pi_PHI",1);

  //set the branch addresses
  Xic0_tree->SetBranchAddress("Xib_M",&Xb_M);
  Xic0_tree->SetBranchAddress("Xib_PT",&Xb_PT);
  Xic0_tree->SetBranchAddress("Xib_ETA",&Xb_ETA);
  Xic0_tree->SetBranchAddress("Xib_PHI",&Xb_PHI);
  Xic0_tree->SetBranchAddress("Xib_OWNPV_X",&Xb_OWNPV_X);
  Xic0_tree->SetBranchAddress("Xib_OWNPV_Y",&Xb_OWNPV_Y);
  Xic0_tree->SetBranchAddress("Xib_OWNPV_Z",&Xb_OWNPV_Z);
  Xic0_tree->SetBranchAddress("Xib_ENDVERTEX_X",&Xb_ENDVERTEX_X);
  Xic0_tree->SetBranchAddress("Xib_ENDVERTEX_Y",&Xb_ENDVERTEX_Y);
  Xic0_tree->SetBranchAddress("Xib_ENDVERTEX_Z",&Xb_ENDVERTEX_Z);

  Xic0_tree->SetBranchAddress("Xic_M",&Xc_M);
  Xic0_tree->SetBranchAddress("Xic_PT",&Xc_PT);
  Xic0_tree->SetBranchAddress("Xic_ETA",&Xc_ETA);
  Xic0_tree->SetBranchAddress("Xic_PHI",&Xc_PHI);

  Xic0_tree->SetBranchAddress("Added_n_Particles",&Added_n_Particles);
  Xic0_tree->SetBranchAddress("Added_H_PT",&Added_H_PT);
  Xic0_tree->SetBranchAddress("Added_H_ETA",&Added_H_ETA);
  Xic0_tree->SetBranchAddress("Added_H_PHI",&Added_H_PHI);

  Xic0_tree->SetBranchAddress("p_P",&p_P);
  Xic0_tree->SetBranchAddress("SSK1_P",&SSK1_P);
  Xic0_tree->SetBranchAddress("SSK2_P",&SSK2_P);
  Xic0_tree->SetBranchAddress("pi_P",&pi_P);

  Xic0_tree->SetBranchAddress("p_PT",&p_PT);
  Xic0_tree->SetBranchAddress("SSK1_PT",&SSK1_PT);
  Xic0_tree->SetBranchAddress("SSK2_PT",&SSK2_PT);
  Xic0_tree->SetBranchAddress("pi_PT",&pi_PT);
  Xic0_tree->SetBranchAddress("p_ETA",&p_ETA);
  Xic0_tree->SetBranchAddress("SSK1_ETA",&SSK1_ETA);
  Xic0_tree->SetBranchAddress("SSK2_ETA",&SSK2_ETA);
  Xic0_tree->SetBranchAddress("pi_ETA",&pi_ETA);
  Xic0_tree->SetBranchAddress("p_PHI",&p_PHI);
  Xic0_tree->SetBranchAddress("SSK1_PHI",&SSK1_PHI);
  Xic0_tree->SetBranchAddress("SSK2_PHI",&SSK2_PHI);
  Xic0_tree->SetBranchAddress("pi_PHI",&pi_PHI);


  double SSK1_beta, SSK2_beta;

  f1->cd();
  //f1->mkdir("Xib2Xic0MuNu/Xic02pKKpi");
  //f1->cd("Xib2Xic0MuNu/Xic02pKKpi");
  TTree added_Xic0_tree("Xic02pKKpi","Xic02pKKpi");

  added_Xic0_tree.Branch("Xib_CorrM", &Xb_CorrM, "Xib_CorrM/D");
  added_Xic0_tree.Branch("p_beta", &p_beta, "p_beta/D");
  added_Xic0_tree.Branch("SSK1_beta", &SSK1_beta, "SSK1_beta/D");
  added_Xic0_tree.Branch("SSK2_beta", &SSK2_beta, "SSK2_beta/D");
  added_Xic0_tree.Branch("pi_beta", &pi_beta, "pi_beta/D");
  added_Xic0_tree.Branch("Added_n_Particles", &Added_n_Particles, "Added_n_Particles/I");
  added_Xic0_tree.Branch("Xcpi_CosTheta", &Xcpi_CosTheta, "Xcpi_CosTheta[Added_n_Particles]/F");
  added_Xic0_tree.Branch("XcK_CosTheta", &XcK_CosTheta, "XcK_CosTheta[Added_n_Particles]/F");
  added_Xic0_tree.Branch("Xcp_CosTheta", &Xcp_CosTheta, "Xcp_CosTheta[Added_n_Particles]/F");
  added_Xic0_tree.Branch("p_as_piKKpi_M", &p_as_piKpi_M, "p_as_piKKpi_M/D");
  added_Xic0_tree.Branch("p_as_KKKpi_M", &p_as_KKpi_M, "p_as_KKKpi_M/D");

  UInt_t Xic0_nevents = Xic0_tree->GetEntries();
  cout << "Entries in Xic0 tree: " << Xic0_nevents << endl;

  for (UInt_t evt = 0; evt < Xic0_nevents;evt++) {
    Xic0_tree->GetEntry(evt);

    TVector3 dir(Xb_ENDVERTEX_X-Xb_OWNPV_X,Xb_ENDVERTEX_Y-Xb_OWNPV_Y,Xb_ENDVERTEX_Z-Xb_OWNPV_Z);
    TVector3 mom;
    mom.SetPtEtaPhi(Xb_PT,Xb_ETA,Xb_PHI);
    double dmag2 = dir.Mag2();
    double ptprime = 0;
    if ( 0 == dmag2 ) ptprime = mom.Mag();
    else ptprime = (mom - dir * ( mom.Dot( dir ) / dmag2 )).Mag() ;
    Xb_CorrM = sqrt(Xb_M*Xb_M + ptprime*ptprime) + ptprime;

    TLorentzVector Xb;
    Xb.SetPtEtaPhiM(Xb_PT,Xb_ETA,Xb_PHI,Xb_CorrM);
    TLorentzVector Xc;
    Xc.SetPtEtaPhiM(Xc_PT,Xc_ETA,Xc_PHI,Xc_M);
    for(int i = 0; i < Added_n_Particles; i++){
      TLorentzVector Hpi;
      Hpi.SetPtEtaPhiM(Added_H_PT[i],Added_H_ETA[i],Added_H_PHI[i],pionmass);
      TLorentzVector HK;
      HK.SetPtEtaPhiM(Added_H_PT[i],Added_H_ETA[i],Added_H_PHI[i],kaonmass);
      TLorentzVector Hp;
      Hp.SetPtEtaPhiM(Added_H_PT[i],Added_H_ETA[i],Added_H_PHI[i],protonmass);
      TLorentzVector Xcpi = Hpi + Xc;
      TLorentzVector XcK = HK + Xc;
      TLorentzVector Xcp = Hp + Xc;
      Xcpi.Boost(-Xb.BoostVector());
      Xcpi_CosTheta[i] = cos(Xcpi.Angle(Xb.Vect()));
      XcK.Boost(-Xb.BoostVector());
      XcK_CosTheta[i] = cos(XcK.Angle(Xb.Vect()));
      Xcp.Boost(-Xb.BoostVector());
      Xcp_CosTheta[i] = cos(Xcp.Angle(Xb.Vect()));
    }
    p_beta    = (-p_P+SSK1_P+SSK2_P+pi_P)/(p_P+SSK1_P+SSK2_P+pi_P);
    SSK1_beta = ( p_P-SSK1_P+SSK2_P+pi_P)/(p_P+SSK1_P+SSK2_P+pi_P);
    SSK2_beta = ( p_P+SSK1_P-SSK2_P+pi_P)/(p_P+SSK1_P+SSK2_P+pi_P);
    pi_beta   = ( p_P+SSK1_P+SSK2_P-pi_P)/(p_P+SSK1_P+SSK2_P+pi_P);

    TLorentzVector proton;
    proton.SetPtEtaPhiM(p_PT,p_ETA,p_PHI,protonmass);
    TLorentzVector kaon1;
    kaon1.SetPtEtaPhiM(SSK1_PT,SSK1_ETA,SSK1_PHI,kaonmass);
    TLorentzVector kaon2;
    kaon2.SetPtEtaPhiM(SSK2_PT,SSK2_ETA,SSK2_PHI,kaonmass);
    TLorentzVector pion;
    pion.SetPtEtaPhiM(pi_PT,pi_ETA,pi_PHI,pionmass);

    TLorentzVector p_as_pi;
    p_as_pi.SetVectM(proton.Vect(),pionmass);
    TLorentzVector p_as_K;
    p_as_K.SetVectM(proton.Vect(),kaonmass);

    p_as_piKpi_M = (p_as_pi + kaon1 + kaon2 + pion).M();
    p_as_KKpi_M = (p_as_K + kaon1 + kaon2 + pion).M();

    added_Xic0_tree.Fill();

  }

  added_Xic0_tree.Write();

  fSLBS->cd();
  TTree *Omegac_tree = (TTree*)gDirectory->Get("Omegab2Omegac0MuNu/Omegac2pKKpi/DecayTree");

  Omegac_tree->SetBranchStatus("*",0); //disable all branches
  //now switch on the ones we need (saves a lot of time)
  Omegac_tree->SetBranchStatus("Omegab_M",1);
  Omegac_tree->SetBranchStatus("Omegab_PT",1);
  Omegac_tree->SetBranchStatus("Omegab_ETA",1);
  Omegac_tree->SetBranchStatus("Omegab_PHI",1);
  Omegac_tree->SetBranchStatus("Omegab_OWNPV_X",1);
  Omegac_tree->SetBranchStatus("Omegab_OWNPV_Y",1);
  Omegac_tree->SetBranchStatus("Omegab_OWNPV_Z",1);
  Omegac_tree->SetBranchStatus("Omegab_ENDVERTEX_X",1);
  Omegac_tree->SetBranchStatus("Omegab_ENDVERTEX_Y",1);
  Omegac_tree->SetBranchStatus("Omegab_ENDVERTEX_Z",1);

  Omegac_tree->SetBranchStatus("Omegac_M",1);
  Omegac_tree->SetBranchStatus("Omegac_PT",1);
  Omegac_tree->SetBranchStatus("Omegac_ETA",1);
  Omegac_tree->SetBranchStatus("Omegac_PHI",1);

  Omegac_tree->SetBranchStatus("Added_n_Particles",1);
  Omegac_tree->SetBranchStatus("Added_H_PT",1);
  Omegac_tree->SetBranchStatus("Added_H_ETA",1);
  Omegac_tree->SetBranchStatus("Added_H_PHI",1);

  Omegac_tree->SetBranchStatus("p_P",1);
  Omegac_tree->SetBranchStatus("SSK1_P",1);
  Omegac_tree->SetBranchStatus("SSK2_P",1);
  Omegac_tree->SetBranchStatus("pi_P",1);

  //set the branch addresses
  Omegac_tree->SetBranchAddress("Omegab_M",&Xb_M);
  Omegac_tree->SetBranchAddress("Omegab_PT",&Xb_PT);
  Omegac_tree->SetBranchAddress("Omegab_ETA",&Xb_ETA);
  Omegac_tree->SetBranchAddress("Omegab_PHI",&Xb_PHI);
  Omegac_tree->SetBranchAddress("Omegab_OWNPV_X",&Xb_OWNPV_X);
  Omegac_tree->SetBranchAddress("Omegab_OWNPV_Y",&Xb_OWNPV_Y);
  Omegac_tree->SetBranchAddress("Omegab_OWNPV_Z",&Xb_OWNPV_Z);
  Omegac_tree->SetBranchAddress("Omegab_ENDVERTEX_X",&Xb_ENDVERTEX_X);
  Omegac_tree->SetBranchAddress("Omegab_ENDVERTEX_Y",&Xb_ENDVERTEX_Y);
  Omegac_tree->SetBranchAddress("Omegab_ENDVERTEX_Z",&Xb_ENDVERTEX_Z);

  Omegac_tree->SetBranchAddress("Omegac_M",&Xc_M);
  Omegac_tree->SetBranchAddress("Omegac_PT",&Xc_PT);
  Omegac_tree->SetBranchAddress("Omegac_ETA",&Xc_ETA);
  Omegac_tree->SetBranchAddress("Omegac_PHI",&Xc_PHI);

  Omegac_tree->SetBranchAddress("Added_n_Particles",&Added_n_Particles);
  Omegac_tree->SetBranchAddress("Added_H_PT",&Added_H_PT);
  Omegac_tree->SetBranchAddress("Added_H_ETA",&Added_H_ETA);
  Omegac_tree->SetBranchAddress("Added_H_PHI",&Added_H_PHI);

  Omegac_tree->SetBranchAddress("p_P",&p_P);
  Omegac_tree->SetBranchAddress("SSK1_P",&SSK1_P);
  Omegac_tree->SetBranchAddress("SSK2_P",&SSK2_P);
  Omegac_tree->SetBranchAddress("pi_P",&pi_P);

  f1->cd();
  //f1->mkdir("Omegab2Omegac0MuNu/Omegac2pKKpi");
  //f1->cd("Omegab2Omegac0MuNu/Omegac2pKKpi");
  TTree added_Omegac_tree("Omegac2pKKpi","Omegac2pKKpi");

  added_Omegac_tree.Branch("Omegab_CorrM", &Xb_CorrM, "Omegab_CorrM/D");
  added_Omegac_tree.Branch("p_beta", &p_beta, "p_beta/D");
  added_Omegac_tree.Branch("SSK1_beta", &SSK1_beta, "SSK1_beta/D");
  added_Omegac_tree.Branch("SSK2_beta", &SSK2_beta, "SSK2_beta/D");
  added_Omegac_tree.Branch("pi_beta", &pi_beta, "pi_beta/D");
  added_Omegac_tree.Branch("Added_n_Particles", &Added_n_Particles, "Added_n_Particles/I");
  added_Omegac_tree.Branch("Xcpi_CosTheta", &Xcpi_CosTheta, "Xcpi_CosTheta[Added_n_Particles]/F");
  added_Omegac_tree.Branch("XcK_CosTheta", &XcK_CosTheta, "XcK_CosTheta[Added_n_Particles]/F");
  added_Omegac_tree.Branch("Xcp_CosTheta", &Xcp_CosTheta, "Xcp_CosTheta[Added_n_Particles]/F");

  UInt_t Omegac_nevents = Omegac_tree->GetEntries();
  cout << "Entries in Omegac tree: " << Omegac_nevents << endl;

  for (UInt_t evt = 0; evt < Omegac_nevents;evt++) {
    Omegac_tree->GetEntry(evt);

    TVector3 dir(Xb_ENDVERTEX_X-Xb_OWNPV_X,Xb_ENDVERTEX_Y-Xb_OWNPV_Y,Xb_ENDVERTEX_Z-Xb_OWNPV_Z);
    TVector3 mom;
    mom.SetPtEtaPhi(Xb_PT,Xb_ETA,Xb_PHI);
    double dmag2 = dir.Mag2();
    double ptprime = 0;
    if ( 0 == dmag2 ) ptprime = mom.Mag();
    else ptprime = (mom - dir * ( mom.Dot( dir ) / dmag2 )).Mag() ;
    Xb_CorrM = sqrt(Xb_M*Xb_M + ptprime*ptprime) + ptprime;

    TLorentzVector Xb;
    Xb.SetPtEtaPhiM(Xb_PT,Xb_ETA,Xb_PHI,Xb_CorrM);
    TLorentzVector Xc;
    Xc.SetPtEtaPhiM(Xc_PT,Xc_ETA,Xc_PHI,Xc_M);
    for(int i = 0; i < Added_n_Particles; i++){
      TLorentzVector Hpi;
      Hpi.SetPtEtaPhiM(Added_H_PT[i],Added_H_ETA[i],Added_H_PHI[i],pionmass);
      TLorentzVector HK;
      HK.SetPtEtaPhiM(Added_H_PT[i],Added_H_ETA[i],Added_H_PHI[i],kaonmass);
      TLorentzVector Hp;
      Hp.SetPtEtaPhiM(Added_H_PT[i],Added_H_ETA[i],Added_H_PHI[i],protonmass);
      TLorentzVector Xcpi = Hpi + Xc;
      TLorentzVector XcK = HK + Xc;
      TLorentzVector Xcp = Hp + Xc;
      Xcpi.Boost(-Xb.BoostVector());
      Xcpi_CosTheta[i] = cos(Xcpi.Angle(Xb.Vect()));
      XcK.Boost(-Xb.BoostVector());
      XcK_CosTheta[i] = cos(XcK.Angle(Xb.Vect()));
      Xcp.Boost(-Xb.BoostVector());
      Xcp_CosTheta[i] = cos(Xcp.Angle(Xb.Vect()));
    }
    p_beta    = (-p_P+SSK1_P+SSK2_P+pi_P)/(p_P+SSK1_P+SSK2_P+pi_P);
    SSK1_beta = ( p_P-SSK1_P+SSK2_P+pi_P)/(p_P+SSK1_P+SSK2_P+pi_P);
    SSK2_beta = ( p_P+SSK1_P-SSK2_P+pi_P)/(p_P+SSK1_P+SSK2_P+pi_P);
    pi_beta   = ( p_P+SSK1_P+SSK2_P-pi_P)/(p_P+SSK1_P+SSK2_P+pi_P);

    added_Omegac_tree.Fill();

  }

  added_Omegac_tree.Write();

  clock->Stop();clock->Print();delete clock;
  return;
}
Beispiel #27
0
Track::Track(const TVector3& p3, double charge, const std::shared_ptr<Path> path, uint32_t index, char subtype)
    : m_id(IdCoder::makeId(index, IdCoder::ItemType::kTrack, subtype, p3.Mag())),
      m_p3(p3),
      m_charge(charge),
      m_path(path) {}
void analysisClass::Loop()
{
  std::cout << "analysisClass::Loop() begins" <<std::endl; 

  if (fChain == 0) return;

  //////////book histos here


  int   Nbins_METSumET = 500;
  float Max_METSumET = 500;

  //calomet
  TH1F *h_calometPt   = new TH1F ("h_calometPt","h_calometPt",Nbins_METSumET,0,Max_METSumET);
  TH1F *h_calometPxy   = new TH1F ("h_calometPxy","h_calometPxy",Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_caloSumet   = new TH1F ("h_caloSumet","h_caloSumet",Nbins_METSumET,0,Max_METSumET);
  TH1F *h_caloMetOSumet   = new TH1F ("h_caloMetOSumet","h_caloMetOSumet",50,0,1.);

  h_calometPt->Sumw2();
  h_calometPxy->Sumw2();
  h_caloSumet->Sumw2();
  h_caloMetOSumet->Sumw2();

  //calomet in dijets (loose)
  TH1F *h_dijetLoose_calometPt   = new TH1F ("h_dijetLoose_calometPt","h_dijetLoose_calometPt",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetLoose_calometPxy   = new TH1F ("h_dijetLoose_calometPxy","h_dijetLoose_calometPxy",0.5*Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_dijetLoose_caloSumet   = new TH1F ("h_dijetLoose_caloSumet","h_dijetLoose_caloSumet",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetLoose_caloMetOSumet   = new TH1F ("h_dijetLoose_caloMetOSumet","h_dijetLoose_caloMetOSumet",50,0,1.);

  h_dijetLoose_calometPt->Sumw2();
  h_dijetLoose_calometPxy->Sumw2();
  h_dijetLoose_caloSumet->Sumw2();
  h_dijetLoose_caloMetOSumet->Sumw2();

  //calomet in dijets (tight)
  TH1F *h_dijetTight_calometPt   = new TH1F ("h_dijetTight_calometPt","h_dijetTight_calometPt",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetTight_calometPxy   = new TH1F ("h_dijetTight_calometPxy","h_dijetTight_calometPxy",0.5*Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_dijetTight_caloSumet   = new TH1F ("h_dijetTight_caloSumet","h_dijetTight_caloSumet",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetTight_caloMetOSumet   = new TH1F ("h_dijetTight_caloMetOSumet","h_dijetTight_caloMetOSumet",50,0,1.);

  h_dijetTight_calometPt->Sumw2();
  h_dijetTight_calometPxy->Sumw2();
  h_dijetTight_caloSumet->Sumw2();
  h_dijetTight_caloMetOSumet->Sumw2();

  //tcmet
  TH1F *h_tcmetPt   = new TH1F ("h_tcmetPt","h_tcmetPt",Nbins_METSumET,0,Max_METSumET);
  TH1F *h_tcmetPxy   = new TH1F ("h_tcmetPxy","h_tcmetPxy",Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_tcSumet   = new TH1F ("h_tcSumet","h_tcSumet",Nbins_METSumET,0,Max_METSumET);
  TH1F *h_tcMetOSumet   = new TH1F ("h_tcMetOSumet","h_tcMetOSumet",50,0,1.);

  h_tcmetPt->Sumw2();
  h_tcmetPxy->Sumw2();
  h_tcSumet->Sumw2();
  h_tcMetOSumet->Sumw2();

  //tcmet in dijet (loose)
  TH1F *h_dijetLoose_tcmetPt   = new TH1F ("h_dijetLoose_tcmetPt","h_dijetLoose_tcmetPt",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetLoose_tcmetPxy   = new TH1F ("h_dijetLoose_tcmetPxy","h_dijetLoose_tcmetPxy",0.5*Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_dijetLoose_tcSumet   = new TH1F ("h_dijetLoose_tcSumet","h_dijetLoose_tcSumet",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetLoose_tcMetOSumet   = new TH1F ("h_dijetLoose_tcMetOSumet","h_dijetLoose_tcMetOSumet",50,0,1.);

  h_dijetLoose_tcmetPt->Sumw2();
  h_dijetLoose_tcmetPxy->Sumw2();
  h_dijetLoose_tcSumet->Sumw2();
  h_dijetLoose_tcMetOSumet->Sumw2();

  //tcmet in dijet (tight)
  TH1F *h_dijetTight_tcmetPt   = new TH1F ("h_dijetTight_tcmetPt","h_dijetTight_tcmetPt",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetTight_tcmetPxy   = new TH1F ("h_dijetTight_tcmetPxy","h_dijetTight_tcmetPxy",0.5*Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_dijetTight_tcSumet   = new TH1F ("h_dijetTight_tcSumet","h_dijetTight_tcSumet",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetTight_tcMetOSumet   = new TH1F ("h_dijetTight_tcMetOSumet","h_dijetTight_tcMetOSumet",50,0,1.);

  h_dijetTight_tcmetPt->Sumw2();
  h_dijetTight_tcmetPxy->Sumw2();
  h_dijetTight_tcSumet->Sumw2();
  h_dijetTight_tcMetOSumet->Sumw2();

  //pfmet
  TH1F *h_pfmetPt   = new TH1F ("h_pfmetPt","h_pfmetPt",Nbins_METSumET,0,Max_METSumET);
  TH1F *h_pfmetPxy   = new TH1F ("h_pfmetPxy","h_pfmetPxy",Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_pfSumet   = new TH1F ("h_pfSumet","h_pfSumet",Nbins_METSumET,0,Max_METSumET);
  TH1F *h_pfMetOSumet   = new TH1F ("h_pfMetOSumet","h_pfMetOSumet",50,0,1.);

  h_pfmetPt->Sumw2();
  h_pfmetPxy->Sumw2();
  h_pfSumet->Sumw2();
  h_pfMetOSumet->Sumw2();

  //pfmet in dijet (loose)
  TH1F *h_dijetLoose_pfmetPt   = new TH1F ("h_dijetLoose_pfmetPt","h_dijetLoose_pfmetPt",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetLoose_pfmetPxy   = new TH1F ("h_dijetLoose_pfmetPxy","h_dijetLoose_pfmetPxy",0.5*Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_dijetLoose_pfSumet   = new TH1F ("h_dijetLoose_pfSumet","h_dijetLoose_pfSumet",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetLoose_pfMetOSumet   = new TH1F ("h_dijetLoose_pfMetOSumet","h_dijetLoose_pfMetOSumet",50,0,1.);

  h_dijetLoose_pfmetPt->Sumw2();
  h_dijetLoose_pfmetPxy->Sumw2();
  h_dijetLoose_pfSumet->Sumw2();
  h_dijetLoose_pfMetOSumet->Sumw2();

  //pfmet in dijet (tight)
  TH1F *h_dijetTight_pfmetPt   = new TH1F ("h_dijetTight_pfmetPt","h_dijetTight_pfmetPt",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetTight_pfmetPxy   = new TH1F ("h_dijetTight_pfmetPxy","h_dijetTight_pfmetPxy",0.5*Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_dijetTight_pfSumet   = new TH1F ("h_dijetTight_pfSumet","h_dijetTight_pfSumet",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetTight_pfMetOSumet   = new TH1F ("h_dijetTight_pfMetOSumet","h_dijetTight_pfMetOSumet",50,0,1.);

  h_dijetTight_pfmetPt->Sumw2();
  h_dijetTight_pfmetPxy->Sumw2();
  h_dijetTight_pfSumet->Sumw2();
  h_dijetTight_pfMetOSumet->Sumw2();

  //Vertex
  TH1F *h_AllVertexZ    = new TH1F ("h_AllVertexZ","h_AllVertexZ",100,-100,100);
  TH1F *h_AllVertexChi2 = new TH1F ("h_AllVertexChi2","h_AllVertexChi",100,0,100);
  TH1F *h_AllVertexNDOF = new TH1F ("h_AllVertexNDOF","h_AllVertexNDOF",50,0,50);
  TH1F *h_AllVertexChi2_0_NDOF = new TH1F ("h_AllVertexChi2_0_NDOF","h_AllVertexChi2_0_NDOF",200,0,40);
  TH1F *h_AllVertexNtrk = new TH1F ("h_AllVertexNtrk","h_AllVertexNtrk",50,0,50);
  TH1F *h_AllNVertex    = new TH1F ("h_AllNVertex","h_AllNVertex",50,0,50);
  TH1F *h_VertexSumpt   = new TH1F ("h_VertexSumpt","h_VertexSumpt",200,0,200);
  TH1F *h_VertexSumptW5 = new TH1F ("h_VertexSumptW5","h_VertexSumptW5",200,0,200);

  h_AllVertexZ->Sumw2();
  h_AllVertexChi2->Sumw2(); 
  h_AllVertexNDOF->Sumw2(); 
  h_AllVertexChi2_0_NDOF->Sumw2();
  h_AllVertexNtrk->Sumw2(); 
  h_AllNVertex->Sumw2();
  h_VertexSumpt->Sumw2(); 
  h_VertexSumptW5->Sumw2(); 

  /////////initialize variables
  float HFEnergyCut = getPreCutValue1("HFEnergyCut");

  //////////////////////////////
  ///// Goood Run List  ////////
  //////////////////////////////
  int goodruns[] = {123596, 123615, 123732, 123815, 123818,
                    123908, 124008, 124009, 124020, 124022,
                    124023, 124024, 124025, 124027, 124030/*,
							    124120*/};
                   //124120 at 2360 GeV

   int goodLSmin[] = {2, 70, 62, 8, 2,
                      2, 1, 1, 12, 66,
                      38, 2, 5, 24, 2/*,
				       1*/};

   int goodLSmax[] = {9999, 9999, 109, 9999, 42,
                      12, 1, 68, 94, 179,
                      9999, 83, 13, 9999, 9999/*,
						9999*/};


  // For S9/S1 flagging
  double slopes[] = {0.0171519,0.0245339,0.0311146,0.0384983,0.0530911,0.0608012,0.0789118,0.084833,0.0998253,0.118896,0.0913756,0.0589927};

  Long64_t nentries = fChain->GetEntriesFast();
  std::cout << "analysisClass::Loop(): nentries = " << nentries << std::endl; 

  Long64_t nb = 0;

  for (Long64_t jentry=0; jentry<nentries;jentry++) 
    //for (Long64_t jentry=0; jentry<2000;jentry++) 
    {
      Long64_t ientry = LoadTree(jentry);
      if (ientry < 0) break;
      //       if(jentry>300000) break;
      nb = fChain->GetEntry(jentry); 
      
      if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl; 
      ////////////////////// User's code starts here ///////////////////////
      

      //## Check if the run is in the list of good runs
      int pass_GoodRunList = 0;
      if(isData==1)
        {
          for (int i = 0; i < sizeof(goodruns)/sizeof(int) ; i++) {
            if (goodruns[i] == run && ls >= goodLSmin[i] && ls <= goodLSmax[i]) {
              pass_GoodRunList = 1;
              break;
            }
          }
        }
      else if(isData == 0)
        {
          pass_GoodRunList = 1;
        }

      //#####################
      //## Trigger selection
      //#####################

      int pass_BPTX              = 0;
      int pass_BSC_MB            = 0;
      int pass_BSC_BeamHaloVeto  = 0;
      int pass_PhysicsBit        = 0;

      //## pass_BPTX - Two beams crossing at CMS (only Data)
      if(isData==1)
	{
	  if(l1techbits->at(0)==1)
	    pass_BPTX = 1;
	}
      else if(isData==0)
	pass_BPTX = 1;
      
      //## pass_BSC_MB - BSC MinBias triggers firing (both Data and MC)
      if( l1techbits->at(40)==1 || l1techbits->at(41)==1 ) 
	pass_BSC_MB = 1;
      
      //## pass_BSC_BeamHaloVeto - Veto on BSC Beam Halo Triggers firing
      if(isData==1)
	{
	  pass_BSC_BeamHaloVeto = 1;
	  if( l1techbits->at(36) == 1 || l1techbits->at(37) == 1 || l1techbits->at(38) == 1 || l1techbits->at(39) == 1 )
	    pass_BSC_BeamHaloVeto = 0;
	}
      else if(isData == 0)
	pass_BSC_BeamHaloVeto = 1;

      //## pass_PhysicsBit - HLT Physics Declared bit set 
      if(isData==1)
	{
	  if(hltbits->at(116)==1)
	    pass_PhysicsBit = 1;
	}
      else if(isData == 0)
	pass_PhysicsBit = 1;

      //#####################
      //## Reco-based filters
      //#####################

      //pass_HFEnergyCut
      int pass_HFEnergyCut = 0;
      int pass_HFEnergyCut_Plus = 0;
      int pass_HFEnergyCut_Minus = 0;
      
      for (int i = 0; i<int(CaloTowersEmEt->size()); i++)
	{

	  if( fabs(CaloTowersIeta->at(i)) > 29 ) //HF only
	    {
	 
	      TVector3 * towerL = new TVector3;
	      TVector3 * towerS = new TVector3;
	      towerL->SetPtEtaPhi(CaloTowersEmEt->at(i)+0.5*CaloTowersHadEt->at(i), CaloTowersEta->at(i), CaloTowersPhi->at(i));
	      towerS->SetPtEtaPhi(0.5*CaloTowersHadEt->at(i), CaloTowersEta->at(i), CaloTowersPhi->at(i));

	      // energy on plus side	    
	      if( CaloTowersIeta->at(i) > 0 && ( towerL->Mag() + towerS->Mag() ) > HFEnergyCut )
		{
		  pass_HFEnergyCut_Plus=1;		  
		  if( pass_HFEnergyCut_Plus == 1 && pass_HFEnergyCut_Minus == 1 )
		    {
		      pass_HFEnergyCut = 1;
		      break;
		    }
		}

	      // energy on minus side	    
	      if( CaloTowersIeta->at(i) < 0 && ( towerL->Mag() + towerS->Mag() ) > HFEnergyCut )
		{
		  pass_HFEnergyCut_Minus=1;
		  if( pass_HFEnergyCut_Plus == 1 && pass_HFEnergyCut_Minus == 1 )
		    {
		      pass_HFEnergyCut = 1;
		      break;
		    }
		}
			
	      delete towerL;
	      delete towerS;
	
	    }//end loop over calotowers in HF

	}//end loop over calotowers
      

      //pass_GoodVertex 
      //https://twiki.cern.ch/twiki/bin/viewauth/CMS/TRKPromptFeedBack#Event_and_track_selection_recipe
      int pass_GoodVertex = 0;

      if(vertexZ->size() == 0) pass_GoodVertex = 0;
      for (int ii=0; ii<vertexZ->size(); ii++)
	if( vertexChi2->at(ii) != 0. && vertexNDF->at(ii) != 0 && vertexNDF->at(ii) >= 5 && fabs(vertexZ->at(ii)) <= 15. )
	  {
	    pass_GoodVertex = 1;
	    break;
	  }
      
      //## pass_MonsterTRKEventVeto - "Monster Events" Tracker Filter
      //see https://twiki.cern.ch/twiki/bin/viewauth/CMS/TRKPromptFeedBack#Event_and_track_selection_recipe
      int pass_MonsterTRKEventVeto = 0;

      int num_good_tracks = 0;
      float fraction      = 0.;
      float thresh        = 0.25;
	 
      if(tracksPt->size()<=10)
	{
	  pass_MonsterTRKEventVeto = 1;
	}//<=10 tracks	    
      else if(tracksPt->size()>10)
	{
	  for (int ii=0; ii<tracksPt->size(); ii++)
	    {
	      int trackFlags = tracksQuality->at(ii);
	      int highPurityFlag = 3;
	      if( ( trackFlags & 1 << highPurityFlag) > 0)
		{
		  num_good_tracks++;		      
		  fraction = (float)num_good_tracks / (float)tracksPt->size();
		  
		  if( fraction > thresh ) 
		    pass_MonsterTRKEventVeto = 1;
		}
	    }
	}//>10 tracks	    

      //## pass_HFPMTHitVeto - Reject anomalous events in HF due to PMT hits - 
      int pass_HFPMTHitVeto_tcMET   = 1;

      //masked towers
      // HF(37,67,1): STATUS = 0x8040
      // HF(29,67,1): STATUS = 0x40
      // HF(35,67,1): STATUS = 0x8040
      // HF(29,67,2): STATUS = 0x40
      // HF(30,67,2): STATUS = 0x8040
      // HF(32,67,2): STATUS = 0x8040
      // HF(36,67,2): STATUS = 0x8040
      // HF(38,67,2): STATUS = 0x8040

      for (int i = 0; i<int(CaloTowersEmEt->size()); i++)
	{
	  if( fabs(CaloTowersIeta->at(i)) > 29 ) //HF only
	    {
	      TVector3 * towerL = new TVector3;
	      TVector3 * towerS = new TVector3;
	      towerL->SetPtEtaPhi(CaloTowersEmEt->at(i)+0.5*CaloTowersHadEt->at(i), CaloTowersEta->at(i), CaloTowersPhi->at(i));
	      towerS->SetPtEtaPhi(0.5*CaloTowersHadEt->at(i), CaloTowersEta->at(i), CaloTowersPhi->at(i));

	      //tower masked
	      int isLongMasked=0;
	      int isShortMasked=0;
	      if( CaloTowersIeta->at(i) == 37 && CaloTowersIphi->at(i) == 67)
		isLongMasked = 1;
	      if( CaloTowersIeta->at(i) == 29 && CaloTowersIphi->at(i) == 67)
		isLongMasked = 1;
	      if( CaloTowersIeta->at(i) == 35 && CaloTowersIphi->at(i) == 67)
		isLongMasked = 1;

	      if( CaloTowersIeta->at(i) == 29 && CaloTowersIphi->at(i) == 67)
		isShortMasked = 1;
	      if( CaloTowersIeta->at(i) == 30 && CaloTowersIphi->at(i) == 67)
		isShortMasked = 1;
	      if( CaloTowersIeta->at(i) == 32 && CaloTowersIphi->at(i) == 67)
		isShortMasked = 1;
	      if( CaloTowersIeta->at(i) == 36 && CaloTowersIphi->at(i) == 67)
		isShortMasked = 1;
	      if( CaloTowersIeta->at(i) == 38 && CaloTowersIphi->at(i) == 67)
		isShortMasked = 1;

	      //-- a la tcMET		
	      float ET_cut_tcMET      = 5; 
	      float Rplus_cut_tcMET   = 0.99; 
	      float Rminus_cut_tcMET  = 0.8; 
	      Float_t ratio_tcMET     = -1.5;	      
	      if(  ( CaloTowersEmEt->at(i) + CaloTowersHadEt->at(i) ) > ET_cut_tcMET 
		   && isShortMasked==0 && isLongMasked==0 )
		{		
		  ratio_tcMET = ( fabs(towerL->Mag()) - fabs(towerS->Mag()) ) 
		    / ( fabs(towerL->Mag()) + fabs(towerS->Mag()) );

		  if( ratio_tcMET < -Rminus_cut_tcMET || ratio_tcMET > Rplus_cut_tcMET )
		    pass_HFPMTHitVeto_tcMET = 0; 
		}
	      delete towerL;
	      delete towerS;
	    }
	}


 //## pass_HFPMTHitVeto from 2010 HCAL DPG studies - Reject anomalous events in HF due to PMT hits - 
      int pass_HFPMTHitVeto_S9S1   = 1;
      int pass_HFPMTHitVeto_PET   = 1;

      for (int i = 0; i<int(PMTnoiseRecHitET->size()); i++)
	{
	  
	  bool isPMThit = false;
	  double energy = PMTnoiseRecHitEnergy->at(i);
	  double ET = PMTnoiseRecHitET->at(i);
	  double partenergy = PMTnoiseRecHitPartEnergy->at(i);
	  double sum4Long = PMTnoiseRecHitSum4Long->at(i);
	  double sum4Short = PMTnoiseRecHitSum4Short->at(i);
	  int ieta = PMTnoiseRecHitIeta->at(i);
	  int iphi = PMTnoiseRecHitIphi->at(i);
	  double phi = ((2*3.14159)/72) * iphi;
	  if(abs(ieta)>39) phi = ((2*3.14159)/72) * (iphi+1);
	  int depth = PMTnoiseRecHitDepth->at(i);

	  //skip the RecHit if it's just a pedestal noise
	  if( (depth==1 && energy<1.2) || (depth==2 && energy<1.8) ) continue;
               
	  //--> NOTE : all crystals has been removed in 2010 --> check if there is some channel with black tape on the window
	  //masked towers
	  // HF(37,67,1): STATUS = 0x8040
	  // HF(29,67,1): STATUS = 0x40
	  // HF(35,67,1): STATUS = 0x8040
	  // HF(29,67,2): STATUS = 0x40
	  // HF(30,67,2): STATUS = 0x8040
	  // HF(32,67,2): STATUS = 0x8040
	  // HF(36,67,2): STATUS = 0x8040
	  // HF(38,67,2): STATUS = 0x8040

	  //tower masked
	  int isLongMasked=0;
	  int isShortMasked=0;
	  if( (ieta==37 || ieta==29 || ieta==35) && iphi==67)
	    isLongMasked = 1;

	  if( (ieta==29 || ieta==30 || ieta==32 || ieta==36 || ieta==38) && iphi==67)
	    isShortMasked = 1;
               
	  //skip the RecHit if it's in the tower with crystals mounted
	  if( isLongMasked==1 || isShortMasked==1 ) continue;
               
	  //R = L-S/L+S
	  double R = PMTnoiseRecHitRValue->at(i);
               
	  //S9/S1
	  double S9oS1 = ( partenergy + sum4Long + sum4Short ) / energy;
               
	  // For S9/S1 flagging
	  double slope = (0.3084-0.02577*abs(ieta)+0.0005351*ieta*ieta);
	  if( abs(ieta)>39 ) slope = slopes[abs(ieta)-30];
	  double intercept = -slope*log((162.4-10.19*abs(ieta)+0.21*ieta*ieta));
                
	  //## identify HF spikes

	  //long fibers
	  if( depth==1 ) 
	    {

	      //PET
	      if( energy>(162.4-10.19*abs(ieta)+0.21*ieta*ieta) && R>0.98 ) 
		{ 
		  isPMThit = true;
		  pass_HFPMTHitVeto_PET = 0;
		}
	      
	      //S9/S1
	      if( abs(ieta)==29 && ( energy>(162.4-10.19*abs(ieta)+0.21*ieta*ieta) && R>0.98 ) ) //special case (as PET)
		{ 
		  isPMThit = true;
		  pass_HFPMTHitVeto_S9S1 = 0;		  
		}
	      else if( abs(ieta)>29 && ( energy>(162.4-10.19*abs(ieta)+0.21*ieta*ieta) && S9oS1<(intercept+slope*log(energy)) ) )
		{ 
		  isPMThit = true;
		  pass_HFPMTHitVeto_S9S1 = 0;		  
		}
	      
	    }
	  //short fibers (same cut, PET-based, for both PET and S9/S1 flags)
	  else if( depth==2 && energy>(129.9-6.61*abs(ieta)+0.1153*ieta*ieta) && R<-0.98 ) 
	    {
	      isPMThit = true;
	      pass_HFPMTHitVeto_PET = 0;
	      pass_HFPMTHitVeto_S9S1 = 0;
	    }
	  
	}//end loop over HF rechits




      //ECAL spikes EB
      int pass_ECALSpikesVeto_tcMET = 1;

      for (int ii=0; ii<ECALnoiseECalEBSeedEnergy->size(); ii++)
	{

	  //-- seed crystal info --
	  float seedEnergy = ECALnoiseECalEBSeedEnergy->at(ii);
	  float seedet = ECALnoiseECalEBSeedEnergy->at(ii) / cosh(ECALnoiseECalEBSeedEta->at(ii));
	  float seedex = seedet * cos( ECALnoiseECalEBSeedPhi->at(ii) );
	  float seedey = seedet * sin( ECALnoiseECalEBSeedPhi->at(ii) );
	  float seedeta = ECALnoiseECalEBSeedEta->at(ii);
	  float seedphi = ECALnoiseECalEBSeedPhi->at(ii);

	  //S4/S1 vs ET (a la tcMET)
	  float S4_tcMET = 0.;
	  S4_tcMET = ECALnoiseECalEBSeedERight->at(ii) 
	    + ECALnoiseECalEBSeedELeft->at(ii)
	    + ECALnoiseECalEBSeedETop->at(ii)
	    + ECALnoiseECalEBSeedEBottom->at(ii);

	  float S4_tcMEToverS1 = S4_tcMET / seedEnergy;

	  if(seedet > 5. && S4_tcMEToverS1 < 0.05)
	    pass_ECALSpikesVeto_tcMET = 0;
	}

      //############################
      //## Calculate Reco Quantities 
      //############################

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

      // Set the evaluation of the cuts to false and clear the variable values and filled status
      resetCuts();

      // Set the value of the variableNames listed in the cutFile to their current value
      fillVariableWithValue("pass_GoodRunList", pass_GoodRunList);
      fillVariableWithValue("pass_BPTX", pass_BPTX);
      fillVariableWithValue("pass_BSC_MB", pass_BSC_MB);
      fillVariableWithValue("pass_BSC_BeamHaloVeto", pass_BSC_BeamHaloVeto);
      fillVariableWithValue("pass_PhysicsBit", pass_PhysicsBit);
      fillVariableWithValue("pass_GoodVertex", pass_GoodVertex);
      fillVariableWithValue("pass_MonsterTRKEventVeto", pass_MonsterTRKEventVeto);
      fillVariableWithValue("pass_HFEnergyCut", pass_HFEnergyCut);

      fillVariableWithValue("pass_ECALSpikesVeto_tcMET", pass_ECALSpikesVeto_tcMET);
      fillVariableWithValue("pass_HFPMTHitVeto_tcMET", pass_HFPMTHitVeto_tcMET);

      //HF cleaning - S9/S1 and PET - HCAL DPG 2010
      fillVariableWithValue("pass_HFPMTHitVeto_S9S1", pass_HFPMTHitVeto_S9S1);
      fillVariableWithValue("pass_HFPMTHitVeto_PET", pass_HFPMTHitVeto_PET);

      // Evaluate cuts (but do not apply them)
      evaluateCuts();

      //###########################
      //## Start filling histograms
      //###########################


      if( passedAllPreviousCuts("pass_GoodVertex") )
	{
	  //Vertex
	  h_AllNVertex->Fill(vertexZ->size());
	  for (int ii=0; ii<vertexZ->size(); ii++)
	    {
	      if(vertexNTracksW5->at(ii)==0)
		continue;

	      h_AllVertexZ->Fill(vertexZ->at(ii));
	      h_AllVertexChi2->Fill(vertexChi2->at(ii));
	      h_AllVertexNDOF->Fill(vertexNDF->at(ii));
	      h_AllVertexNtrk->Fill(vertexNTracks->at(ii));
	      if(vertexNDF->at(ii)!=0)
		h_AllVertexChi2_0_NDOF->Fill( vertexChi2->at(ii) / vertexNDF->at(ii) );
	      
	      h_VertexSumpt->Fill(vertexSumPt->at(ii));
	      h_VertexSumptW5->Fill(vertexSumPtW5->at(ii));
	    }
	}
      
      if( passedCut("0") && pass_HFPMTHitVeto_tcMET == 1 && pass_ECALSpikesVeto_tcMET == 1 )
	{
	  //#########################
	  //## inclusive MET
	  //#########################
	  h_calometPt->Fill( calometPt->at(0) );
	  h_calometPxy->Fill( calometPx->at(0) ); 
	  h_calometPxy->Fill( calometPy->at(0) ); 
	  h_caloSumet->Fill( calometSumEt->at(0) ); 
	  h_caloMetOSumet->Fill( calometPt->at(0) / calometSumEt->at(0) ); 

	  h_tcmetPt->Fill( tcmetPt->at(0) );
	  h_tcmetPxy->Fill( tcmetPx->at(0) ); 
	  h_tcmetPxy->Fill( tcmetPy->at(0) ); 
	  h_tcSumet->Fill( tcmetSumEt->at(0) ); 
	  h_tcMetOSumet->Fill( tcmetPt->at(0) / tcmetSumEt->at(0) ); 

	  h_pfmetPt->Fill( pfmetPt->at(0) );
	  h_pfmetPxy->Fill( pfmetPx->at(0) ); 
	  h_pfmetPxy->Fill( pfmetPy->at(0) ); 
	  h_pfSumet->Fill( pfmetSumEt->at(0) ); 
	  h_pfMetOSumet->Fill( pfmetPt->at(0) / pfmetSumEt->at(0) ); 

	  ///////////////////////////////////////
	  ///////// Print High MET events////////
	  ///////////////////////////////////////
	  if(isData==1)
	    if( calometPt->at(0) > 20 || tcmetPt->at(0) > 20 || pfmetPt->at(0) > 20. )
	      {
		cout << "event: " << event << " " 
		     << "ls: " << ls << " "
		     << "run: " << run << "  "
		     << "--  calometPt->at(0) : " <<  calometPt->at(0) << " "
		     << "--  tcmetPt->at(0) : "   <<  tcmetPt->at(0)   <<" "
		     << "--  pfmetPt->at(0) : "   <<  pfmetPt->at(0)   <<" "
		     << endl;
	      }

	  if(isData==1)
	    if( calometSumEt->at(0) > 50 || tcmetSumEt->at(0) > 100 || pfmetSumEt->at(0) > 100 )
	      {
		cout << "event: " << event << " " 
		     << "ls: " << ls << " "
		     << "run: " << run << "  "
		     << "--  calometSumEt->at(0) : " <<  calometSumEt->at(0) << " "
		     << "--  tcmetSumEt->at(0) : "   <<  tcmetSumEt->at(0) << " "
		     << "--  pfmetSumEt->at(0) : "   <<  pfmetSumEt->at(0) << " "
		     << endl;
	      }
	  
	  //##########################
	  //## MET in dijets (ak5)
	  //##########################
	  
	  bool makeJetCorr = true;

	  // cut values
	  double endcapeta =2.6;
	  double endcapeta_dijet =3.0;
	  double cut_CaloDiJetDeltaPhi_min = 2.10;

	  // minimum pt cuts (depending on jet corrections)
	  double ptMin;
	  double ptMinDijet;
	  if (makeJetCorr==true) 
	    {
	      ptMin=15.;
	      ptMinDijet=10.;
	    }
	  if (makeJetCorr==false) 
	    {
	      ptMin=7.;
	      ptMinDijet=5.;
	    }

	  int index_jet1 = -10;
	  int index_jet2 = -10;
	  double mypt1=-10;
	  double mypt2=-10;

	  std::vector<TLorentzVector> vPtEtaPhiE;
	  if(!vPtEtaPhiE.empty()){ vPtEtaPhiE.clear(); }
	  
	  // --------------------DiJets---------------------------------------------------------------------   
	  // JET CORRECTION
	  // --------------------
	  double jcScale0;
	  double jcScale1;

	  //dijet
	  if(int(ak5JetpT->size())>=2)
	    {
	      for (int j = 0; j<int(ak5JetpT->size()); j++)
		{
		  //check if jet is among hardest two
		  //as jets are ordered in uncorrected pT: needs to be done only for corrected jets
		  if(makeJetCorr == true) {
		    if((ak5JetscaleL2L3->at(j)*ak5JetpT->at(j))>mypt1){
		      mypt2=mypt1;
		      index_jet2=index_jet1;
		      mypt1=ak5JetscaleL2L3->at(j)*ak5JetpT->at(j);
		      index_jet1=j;
		    }else if((ak5JetscaleL2L3->at(j)*ak5JetpT->at(j))>mypt2){
		      mypt2=ak5JetscaleL2L3->at(j)*ak5JetpT->at(j);
		      index_jet2=j;
		    }
		  }
		}

	      if((index_jet2==-10)||(index_jet1==-10))
		{
		  cout<<"index should be set ERROR: "<<index_jet2<<"/"<<index_jet1<<endl;
		}
	      // both passed pT and eta cuts
	      if(makeJetCorr == true) 
		{
		  jcScale0 = ak5JetscaleL2L3->at(index_jet1);
		  jcScale1 = ak5JetscaleL2L3->at(index_jet2);
		}
	      else 
		{
		  index_jet1 =  0;
		  index_jet2 =  1;
		  jcScale0    = 1;
		  jcScale1    = 1;
		}
	      
	      if( fabs(ak5JetEta->at(index_jet1)) < endcapeta_dijet && 
		  ( ak5JetpT->at(index_jet1) * jcScale0 ) > ptMinDijet && 
		  fabs( ak5JetEta->at(index_jet2) ) < endcapeta_dijet && 
		  ( ak5JetpT->at(index_jet2) * jcScale1 ) > ptMinDijet )
		{ 
		  // dphi
		double dphi = DeltaPhi(ak5JetPhi->at(index_jet1), ak5JetPhi->at(index_jet2) );
		
		if ( dphi > cut_CaloDiJetDeltaPhi_min ) 
		  {
		    // both passed jet ID loose
		    if(
		       JetIdloose(ak5JetJIDresEMF->at(index_jet1),ak5JetJIDfHPD->at(index_jet1),ak5JetJIDn90Hits->at(index_jet1),ak5JetEta->at(index_jet1)) &&
		       JetIdloose(ak5JetJIDresEMF->at(index_jet2),ak5JetJIDfHPD->at(index_jet2),ak5JetJIDn90Hits->at(index_jet2),ak5JetEta->at(index_jet2)))
		      {
			h_dijetLoose_calometPt->Fill( calometPt->at(0) );
			h_dijetLoose_calometPxy->Fill( calometPx->at(0) ); 
			h_dijetLoose_calometPxy->Fill( calometPy->at(0) ); 
			h_dijetLoose_caloSumet->Fill( calometSumEt->at(0) ); 
			h_dijetLoose_caloMetOSumet->Fill( calometPt->at(0) / calometSumEt->at(0) ); 

			h_dijetLoose_tcmetPt->Fill( tcmetPt->at(0) );
			h_dijetLoose_tcmetPxy->Fill( tcmetPx->at(0) ); 
			h_dijetLoose_tcmetPxy->Fill( tcmetPy->at(0) ); 
			h_dijetLoose_tcSumet->Fill( tcmetSumEt->at(0) ); 
			h_dijetLoose_tcMetOSumet->Fill( tcmetPt->at(0) / tcmetSumEt->at(0) ); 

			h_dijetLoose_pfmetPt->Fill( pfmetPt->at(0) );
			h_dijetLoose_pfmetPxy->Fill( pfmetPx->at(0) ); 
			h_dijetLoose_pfmetPxy->Fill( pfmetPy->at(0) ); 
			h_dijetLoose_pfSumet->Fill( pfmetSumEt->at(0) ); 
			h_dijetLoose_pfMetOSumet->Fill( pfmetPt->at(0) / pfmetSumEt->at(0) ); 
			
			// both passed jet ID tight
			if(
			   JetIdtight(ak5JetJIDresEMF->at(index_jet1),ak5JetJIDfHPD->at(index_jet1),ak5JetJIDfRBX->at(index_jet1),ak5JetJIDn90Hits->at(index_jet1),ak5JetEta->at(index_jet1)) &&
			   JetIdtight(ak5JetJIDresEMF->at(index_jet2),ak5JetJIDfHPD->at(index_jet2),ak5JetJIDfRBX->at(index_jet2),ak5JetJIDn90Hits->at(index_jet2),ak5JetEta->at(index_jet2)))
			  {
			    h_dijetTight_calometPt->Fill( calometPt->at(0) );
			    h_dijetTight_calometPxy->Fill( calometPx->at(0) ); 
			    h_dijetTight_calometPxy->Fill( calometPy->at(0) ); 
			    h_dijetTight_caloSumet->Fill( calometSumEt->at(0) ); 
			    h_dijetTight_caloMetOSumet->Fill( calometPt->at(0) / calometSumEt->at(0) ); 

			    h_dijetTight_tcmetPt->Fill( tcmetPt->at(0) );
			    h_dijetTight_tcmetPxy->Fill( tcmetPx->at(0) ); 
			    h_dijetTight_tcmetPxy->Fill( tcmetPy->at(0) ); 
			    h_dijetTight_tcSumet->Fill( tcmetSumEt->at(0) ); 
			    h_dijetTight_tcMetOSumet->Fill( tcmetPt->at(0) / tcmetSumEt->at(0) ); 
			    
			    h_dijetTight_pfmetPt->Fill( pfmetPt->at(0) );
			    h_dijetTight_pfmetPxy->Fill( pfmetPx->at(0) ); 
			    h_dijetTight_pfmetPxy->Fill( pfmetPy->at(0) ); 
			    h_dijetTight_pfSumet->Fill( pfmetSumEt->at(0) ); 
			    h_dijetTight_pfMetOSumet->Fill( pfmetPt->at(0) / pfmetSumEt->at(0) ); 
			  }
		      }
		  }//dphi cut
		}//eta/pt cuts on dijets
	    }//di jets >= 2 jets
	  
	  //##########################
	}//-------------- passed cuts "0"
      
      ////////////////////// User's code ends here ///////////////////////
    } // End loop over events

  //////////write histos 

  //## 1D histograms

  //calomet
  h_calometPt->Write(); 
  h_calometPxy->Write(); 
  h_caloSumet->Write(); 
  h_caloMetOSumet->Write();
  
  //tcmet
  h_tcmetPt->Write(); 
  h_tcmetPxy->Write(); 
  h_tcSumet->Write(); 
  h_tcMetOSumet->Write();

  //pfmet
  h_pfmetPt->Write(); 
  h_pfmetPxy->Write(); 
  h_pfSumet->Write(); 
  h_pfMetOSumet->Write();

  //Dijets (loose)
  h_dijetLoose_calometPt->Write(); 
  h_dijetLoose_calometPxy->Write(); 
  h_dijetLoose_caloSumet->Write(); 
  h_dijetLoose_caloMetOSumet->Write(); 
 
  h_dijetLoose_tcmetPt->Write(); 
  h_dijetLoose_tcmetPxy->Write(); 
  h_dijetLoose_tcSumet->Write();
  h_dijetLoose_tcMetOSumet->Write(); 
		    
  h_dijetLoose_pfmetPt->Write(); 
  h_dijetLoose_pfmetPxy->Write(); 
  h_dijetLoose_pfSumet->Write(); 
  h_dijetLoose_pfMetOSumet->Write(); 

  //Dijets (tight)
  h_dijetTight_calometPt->Write(); 
  h_dijetTight_calometPxy->Write(); 
  h_dijetTight_caloSumet->Write(); 
  h_dijetTight_caloMetOSumet->Write(); 
  
  h_dijetTight_tcmetPt->Write(); 
  h_dijetTight_tcmetPxy->Write(); 
  h_dijetTight_tcSumet->Write(); 
  h_dijetTight_tcMetOSumet->Write(); 
		    
  h_dijetTight_pfmetPt->Write(); 
  h_dijetTight_pfmetPxy->Write(); 
  h_dijetTight_pfSumet->Write(); 
  h_dijetTight_pfMetOSumet->Write(); 

  //Vertex
  h_AllVertexZ->Write();
  h_AllVertexChi2->Write(); 
  h_AllVertexNDOF->Write(); 
  h_AllVertexChi2_0_NDOF->Write();
  h_AllVertexNtrk->Write(); 
  h_AllNVertex->Write();
  h_VertexSumpt->Write(); 
  h_VertexSumptW5->Write(); 

  //## 2D histograms

  std::cout << "analysisClass::Loop() ends" <<std::endl; 
}
int main( int argc, const char *argv[] )
{

	double momentum  = 0.2;
	double theta 	  = 0.5*M_PI;
	double phi  	  = 0.00;
	double 	     M  = 10.0;
	double 	Energy  = sqrt(momentum*momentum+M*M);
	double 	    m1  = 0.0000;
	double 	    m2  = 0.0000;
	double 	    m3  = 0.0000;

//	double x1 = 0.5;
//	double x2 = 0.2;
//	double x3 = 0.4;
//	double x4 = 0.3342;
//	double x5 = 0.75;
//

	double x1 = 0.50;
	double x2 = 0.00;
	double x3 = 0.00;
	double x4 = 0.00;
	double x5 = 0.00;

	{
	std::cout << "test_PhaseSpaceTools " << std::endl;

	TLorentzVector p1;
	TLorentzVector p2;
	TLorentzVector p3;

	TVector3 v1;

	double costheta1 = 2*x2-1;
	double sintheta1 = sqrt(1-costheta1*costheta1);
	double 	   phi1 = 2*M_PI*x3;
	double sqrt_s23  = x1*(M-m1-m2-m3) + m1+m2;

	double costheta23 = 2*x4-1;
	double sintheta23 = sqrt(1-costheta23*costheta23);
	double 	   phi23 = 2*M_PI*x5;

	double      s = M*M;
	double m1_sqr = m1*m1;
	double m2_sqr = m2*m2;
	double m3_sqr = m3*m3;
	double 	 s23 = sqrt_s23*sqrt_s23;

	double    pmag  = TwoBodyFunc::p    (s, m1_sqr, s23);
	double beta1    = TwoBodyFunc::beta (s, m1_sqr, s23);
	double 	 E1    = TwoBodyFunc::E    (M, m1_sqr, s23);
	double 	 E23   = TwoBodyFunc::E    (M, s23, m1_sqr);

	p1.SetPxPyPzE(pmag*sintheta1*cos(phi1),pmag*sintheta1*sin(phi1),pmag*costheta1,E1);

	TVector3 v;
	v = -p1.Vect();
	v.SetMag(v.Mag()/E23);

	double    p2mag  = TwoBodyFunc::p    (s23, m2_sqr, m3_sqr);
	double    	 E2  = TwoBodyFunc::E    (sqrt_s23, m2_sqr, m3_sqr);
	double    	 E3  = TwoBodyFunc::E    (sqrt_s23, m3_sqr, m2_sqr);

	p2.SetPxPyPzE(p2mag*sintheta23*cos(phi23),p2mag*sintheta23*sin(phi23),p2mag*costheta23,E2);
	p3.SetPxPyPzE(-p2mag*sintheta23*cos(phi23),-p2mag*sintheta23*sin(phi23),-p2mag*costheta23,E3);

	std::cout << "p1:" << std::endl;
	displayTLorentzVector(&p1);

	std::cout << "p2 and p3 in the 23 rest frame:" << std::endl;

	std::cout << "p2:" << std::endl;
	displayTLorentzVector(&p2);

	std::cout << "p3:" << std::endl;
	displayTLorentzVector(&p3);

	p2.Boost(v);
	p3.Boost(v);


	std::cout << "All in the lab frame:" << std::endl;

	std::cout << "p1:" << std::endl;
	displayTLorentzVector(&p1);

	std::cout << "p2:" << std::endl;
	displayTLorentzVector(&p2);

	std::cout << "p3:" << std::endl;
	displayTLorentzVector(&p3);

	TLorentzVector sum;
	sum = p1 + p2 + p3;

	std::cout << "sum in the lab frame:" << std::endl;
	displayTLorentzVector(&sum);

	}

	{

	printf("######################################\n");
	printf("### --- TwoBudyFunc utils TEST --- ###\n");
	printf("######################################\n");

	double M_test      = 5.0;
	double m1_sqr_test = 3.0;
	double m2_sqr_test = 1.0;

	double E = TwoBodyFunc::E (M_test, m1_sqr_test, m2_sqr_test);

	printf("M_test: %.2f\n", M_test);
	printf("m1_sqr_test: %.2f\n", m1_sqr_test);
	printf("m2_sqr_test: %.2f\n", m2_sqr_test);
	printf("TwoBodyFunc::E (M_test, m1_sqr_test, m2_sqr_test): %.2f\n", E);

	}

	{

	printf("\n");
	printf("########################################\n");
	printf("### --- ThreeBodyDecayClass TEST --- ###\n");
	printf("########################################\n");
	printf("\n");
	// ThreeBodyDecay class
   ThreeBodyDecay tau(M, m1, m2, m3);
	tau.SetMotherMPThetaPhi(M,momentum,theta,phi);
	tau.SetBitBoostBack(true);


	tau.SetPhaseSpace(x1, x2, x3, x4, x5);
	TLorentzVector *P = tau.P;
	TLorentzVector *p1 = tau.p[0];
	TLorentzVector *p2 = tau.p[1];
	TLorentzVector *p3 = tau.p[2];
  	double amp = P->Dot( (*p3) ) * p1->Dot( (*p2) );
	tau.DisplayAll();

//	printf("\ns23_min: %.2f", );

	double weight = tau.GetPhaseSpaceWeight(x1, x2, x3, x4, x5);
	std::cout << "PSWeight: " << weight << std::endl;
	std::cout << "amp: " << amp << std::endl;

	std::cout << "P:" << std::endl;
	displayTLorentzVector(P);

	std::cout << "p1:" << std::endl;
	displayTLorentzVector(p1);
	std::cout << "p2:" << std::endl;
	displayTLorentzVector(p2);
	std::cout << "p3:" << std::endl;
	displayTLorentzVector(p3);

	TLorentzVector sum = (*p1) + (*p2) + (*p3);
	std::cout << "p1+p2+p3:" << std::endl;
	displayTLorentzVector(&sum);
	}

}
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::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::antikt_algorithm, dSjeR, fastjet::BIpt_scheme, fastjet::Best);
//=============================================================================

  std::vector<fastjet::PseudoJet> fjInput;
//=============================================================================

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

  TH1D *hJet = new TH1D("hJet", "", 1000, 0., 1000.); hJet->Sumw2(); list->Add(hJet);
  TH2D *hJetNsj = new TH2D("hJetNsj", "", 1000, 0., 1000., 101, -0.5, 100.5); hJetNsj->Sumw2(); list->Add(hJetNsj);

  TH2D *hJetIsj = new TH2D("hJetIsj", "", 1000, 0., 1000., 1000, 0., 1000.); hJetIsj->Sumw2(); list->Add(hJetIsj);
  TH2D *hJet1sj = new TH2D("hJet1sj", "", 1000, 0., 1000., 1000, 0., 1000.); hJet1sj->Sumw2(); list->Add(hJet1sj);
  TH2D *hJet2sj = new TH2D("hJet2sj", "", 1000, 0., 1000., 1000, 0., 1000.); hJet2sj->Sumw2(); list->Add(hJet2sj);
  TH2D *hJetDsj = new TH2D("hJetDsj", "", 1000, 0., 1000., 1000, 0., 1000.); hJetDsj->Sumw2(); list->Add(hJetDsj);

  TH2D *hJetIsz = new TH2D("hJetIsz", "", 1000, 0., 1000., 120, 0., 1.2); hJetIsz->Sumw2(); list->Add(hJetIsz);
  TH2D *hJet1sz = new TH2D("hJet1sz", "", 1000, 0., 1000., 120, 0., 1.2); hJet1sz->Sumw2(); list->Add(hJet1sz);
  TH2D *hJet2sz = new TH2D("hJet2sz", "", 1000, 0., 1000., 120, 0., 1.2); hJet2sz->Sumw2(); list->Add(hJet2sz);
  TH2D *hJetDsz = new TH2D("hJetDsz", "", 1000, 0., 1000., 120, 0., 1.2); hJetDsz->Sumw2(); list->Add(hJetDsz);
//=============================================================================

  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);
    double dXsect  = evt->cross_section()->cross_section() / 1e9;
    double dWeight = evt->weights().back();
    double dNorm = dWeight * dXsect;
    hWeightSum->Fill(0.5, dWeight);

    TVector3 vPar;
    for (HepMC::GenEvent::particle_const_iterator p=evt->particles_begin(); p!=evt->particles_end(); ++p) if ((*p)->status()==1) {
      vPar.SetXYZ((*p)->momentum().px(), (*p)->momentum().py(), (*p)->momentum().pz());

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

    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, dNorm);
//=============================================================================

      fastjet::Filter trimmer(subjDef, fastjet::SelectorPtFractionMin(0.));
      fastjet::PseudoJet trimmdJet = trimmer(selectJets[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.)) {
        double dsj = d1sj - d2sj;
        double dsz = dsj / dJet;

        hJetDsj->Fill(dJet, dsj, dNorm);
        hJetDsz->Fill(dJet, dsz, 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;
}