コード例 #1
0
ファイル: radiation.c プロジェクト: project8/adiP8
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;
}
コード例 #2
0
ファイル: eventDirGenerator.C プロジェクト: nichol77/monte
int getSurfacePoint(TVector3 intPos, TVector3 &intDir, TVector3 &surfPos) {
    Double_t b=intDir.X()*intPos.X() + intDir.Y()*intPos.Y() + intDir.Z()*intPos.Z();
    Double_t c = intPos.X()*intPos.X() + intPos.Y()*intPos.Y() + intPos.Z()*intPos.Z() - rEarth*rEarth;
    if(b*b < c)
        return 0;


    Double_t l1=-1*b + TMath::Sqrt(b*b - c);
    Double_t l2=-1*b - TMath::Sqrt(b*b - c);


    if(intPos.Mag2()> rEarth*rEarth) {
        //Start outside take l1
        //return 0;
        //    cout << "Outside:\t" << l1 << "\t" << l2 << endl;
        intDir*=-1;
        l1*=-1;
        surfPos.SetX(intPos.X() + l1*intDir.X());
        surfPos.SetY(intPos.Y() + l1*intDir.Y());
        surfPos.SetZ(intPos.Z() + l1*intDir.Z());
        //    cout << surfPos.Mag() << endl;
    }
    else {
        //Start inside take l2
        //    cout << "Inside:\t" << l1 << "\t" << l2 <<  endl;
        //    cout << l2 << endl;
        //    return 0;
        surfPos.SetX(intPos.X() + l2*intDir.X());
        surfPos.SetY(intPos.Y() + l2*intDir.Y());
        surfPos.SetZ(intPos.Z() + l2*intDir.Z());
        //    cout << surfPos.Mag() << endl;
    }

    return 1;
}
コード例 #3
0
ファイル: PCalTools.hpp プロジェクト: hengne/d0wmass
  static TVector3 floorXYZ(double zvtx, double physeta, double physphi) {
    // Function to calculate detector position when particle is extrapolated
    // to 3rd layer of em calorimeter.

    // Note that we assume an x,y vertex position of zero.
    // Also, the x,y cal shifts are not implemented...yet.

    TVector3 v;
    
    double phi = physphi;  
    double eta = physeta;
    double theta = PTools::etaToTheta(eta);
    double ztmp = zvtx + CC_3R/TMath::Tan(theta);
    
    if( TMath::Abs(ztmp) >= EC_DIV ){ // in EC
      (eta>=0) ? v.SetZ(EC_3Z_SOUTH) : v.SetZ(EC_3Z_NORTH);
      v.SetX( (v.Z()-zvtx) * TMath::Tan(theta) * TMath::Cos(phi));
      v.SetY( (v.Z()-zvtx) * TMath::Tan(theta) * TMath::Sin(phi));
      
    }
    else{ // in CC
      v.SetZ(ztmp);
      v.SetX( CC_3R * TMath::Cos(phi));
      v.SetY( CC_3R * TMath::Sin(phi));
      
    }
    
    return v;
  }
コード例 #4
0
ファイル: radiation.c プロジェクト: project8/adiP8
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;
}
コード例 #5
0
ファイル: PCalTools.hpp プロジェクト: hengne/d0wmass
  static TVector3 toGlobal(const TVector3 &local){

    TVector3 global = local;

    if(TMath::Abs(local.Z()) < EC_DIV){ //CC
      global.SetX(global.X()+CC_XSHIFT);
      global.SetY(global.Y()+CC_YSHIFT);
      global.SetZ(global.Z()+CC_ZSHIFT);
    }else{
      if (local.Z() < 0) global.SetX(local.X()+EC_XSHIFT_NORTH);
      global.SetZ( (local.Z()>0) ? EC_3Z_SOUTH : EC_3Z_NORTH );
    }

    return global;
  }
コード例 #6
0
ファイル: PCalTools.hpp プロジェクト: hengne/d0wmass
  static TVector3 toLocal(const TVector3 &global){

    TVector3 local = global;

    if(TMath::Abs(global.Z()) < EC_DIV){ //CC
      local.SetX(local.X()-CC_XSHIFT);
      local.SetY(local.Y()-CC_YSHIFT);
      local.SetZ(local.Z()-CC_ZSHIFT);
    }else{
      if (global.Z() < 0) local.SetX(local.X()-EC_XSHIFT_NORTH);
      local.SetZ( (global.Z()>0) ? EC_3Z : -EC_3Z );
    }

    return local;
  }
コード例 #7
0
// This is the deltaphi between the di-lepton system and the Higgs
// boost in the approximate Higgs rest frame, or R-FRAME
// L1 and L2 are the 4-vectors for the 2 hemispheres, or in you case,
// the two leptons - setting mass to 0 should be fine
// MET is the MET 3 vector (don't forget to set the z-component of
// MET to 0)
// This function will do the correct Lorentz transformations of the 
// leptons for you
double HWWKinematics::CalcDoubleDphiRFRAME(){
  // first calculate pt-corrected MR
  float mymrnew = CalcMRNEW();
  
  TVector3 BL = L1.Vect()+L2.Vect();
  BL.SetX(0.0);
  BL.SetY(0.0);
  BL = (1./(L1.P()+L2.P()))*BL;
  L1.Boost(-BL);
  L2.Boost(-BL);
  
  //Next, calculate the transverse Lorentz transformation
  TVector3 B = L1.Vect()+L2.Vect()+MET;
  B.SetZ(0.0);
  B = (-1./(sqrt(4.*mymrnew*mymrnew+B.Dot(B))))*B;
  
  L1.Boost(B);
  L2.Boost(B);
  
  // Now, calculate the delta phi
  // between di-lepton axis and boost
  // in new reference frame
  
  return B.DeltaPhi(L1.Vect()+L2.Vect());
  
}
コード例 #8
0
// This is the pt corrected delta phi between the 2 leptons
// P and L2 are the 4-vectors for the 2 hemispheres, or in you case,
// the two leptons - setting mass to 0 should be fine
// MET is the MET 3 vector (don't forget to set the z-component of
// MET to 0)
// This function will do the correct Lorentz transformations of the 
// leptons for you
double HWWKinematics::CalcDeltaPhiRFRAME(){
  // first calculate pt-corrected MR
  float mymrnew = CalcMRNEW();
  
  // Now, boost lepton system to rest in z
  // (approximate accounting for longitudinal boost)
  TVector3 BL = L1.Vect()+L2.Vect();
  BL.SetX(0.0);
  BL.SetY(0.0);
  BL = (1./(L1.P()+L2.P()))*BL;
  L1.Boost(-BL);
  L2.Boost(-BL);
  
  // Next, calculate the transverse Lorentz transformation
  // to go to Higgs approximate rest frame
  TVector3 B = L1.Vect()+L2.Vect()+MET;
  B.SetZ(0.0);
  B = (-1./(sqrt(4.*mymrnew*mymrnew+B.Dot(B))))*B;
  
  L1.Boost(B);
  L2.Boost(B);
  
  //Now, re-calculate the delta phi
  // in the new reference frame:
  return L1.DeltaPhi(L2);
  
}
コード例 #9
0
ファイル: radiation.c プロジェクト: project8/adiP8
double coeff_of_t(TVector3 &efield, TVector3 &vel, int dir)
{
  //returns A C(t), the coefficient of each waveguide mode in +x-direction
  // in units of C*Ohm/s or volts
  efield.SetZ( dir * efield.Z() );//only effect TM modes
  return Echarge * tl_data.Zw / 2 * ( efield * vel ) / US2S;
}
コード例 #10
0
ファイル: radiation.c プロジェクト: project8/adiP8
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;
}
コード例 #11
0
// M is the MET 3 vector (don't forget to set the z-component of
// MET to 0)
double HWWKinematics::CalcMRNEW(TLorentzVector P, TLorentzVector Q, TVector3 M){
 TVector3 vI = M+P.Vect()+Q.Vect();
 vI.SetZ(0.0);
 double PpQ = CalcMR(P,Q); //Note - this calls the old MR function
 double vptx = (P+Q).Px();
 double vpty = (P+Q).Py();
 TVector3 vpt;
 vpt.SetXYZ(vptx,vpty,0.0);

 float MR2 = 0.5*(PpQ*PpQ-vpt.Dot(vI)+PpQ*sqrt(PpQ*PpQ+vI.Dot(vI)-2.*vI.Dot(vpt)));

 return sqrt(MR2);

}
コード例 #12
0
// This is the pt corrected MR - here, we assume the pt
// of the Higgs is (MET+Pt+Qt);
// L1 and L2 are the 4-vectors for the 2 hemispheres, or in you case,
// the two leptons - setting mass to 0 should be fine
// MET is the MET 3 vector (don't forget to set the z-component of
// MET to 0)
// Also, 2 times this variable should give you the Higgs mass
double HWWKinematics::CalcMRNEW(){
  TVector3 vI = MET+L1.Vect()+L2.Vect();
  vI.SetZ(0.0);
  double L1pL2 = CalcMR(); //Note - this calls the old MR function
  double vptx = (L1+L2).Px();
  double vpty = (L1+L2).Py();
  TVector3 vpt;
  vpt.SetXYZ(vptx,vpty,0.0);
  
  float MR2 = 0.5*(L1pL2*L1pL2-vpt.Dot(vI)+L1pL2*sqrt(L1pL2*L1pL2+vI.Dot(vI)-2.*vI.Dot(vpt)));
  
  return sqrt(MR2);
  
}
コード例 #13
0
// This is the pt corrected delta phi between the 2 mega-jets
// P and Q are the 4-vectors for the 2 hemispheres 
// M is the MET 3 vector (don't forget to set the z-component of
// MET to 0)
// This function will do the correct Lorentz transformations of the 
// leptons for you
double HWWKinematics::CalcDeltaPhiNEW(TLorentzVector P, TLorentzVector Q, TVector3 M){
    // first calculate pt-corrected MR
 float mymrnew = CalcMRNEW(L1,L2,MET);

    //Next, calculate the transverse Lorentz transformation
 TVector3 B = P.Vect()+Q.Vect()+MET;
 B.SetZ(0.0);
 B = (-1./(sqrt(4.*mymrnew*mymrnew+B.Dot(B))))*B;

 P.Boost(B);
 Q.Boost(B);

    //Now, re-calculate the delta phi
    // in the new reference frame:

 return P.DeltaPhi(Q);

}
コード例 #14
0
double HWWKinematics::CalcUnboostedMTR(TLorentzVector P, TLorentzVector Q, TVector3 M){
    // first calculate pt-corrected MR
 float mymrnew = CalcMRNEW(L1,L2,MET);

    //Next, calculate the transverse Lorentz transformation
 TVector3 B = P.Vect()+Q.Vect()+MET;
 B.SetZ(0.0);
 B = (-1./(sqrt(4.*mymrnew*mymrnew+B.Dot(B))))*B;

 P.Boost(B);
 Q.Boost(B);

    //Now, re-calculate MTR in the new reference frame:
 float mymtrnew = CalcMTRNEW(P, Q);

    //R is now just the ratio of mymrnew and mymtrnew;

 return mymtrnew;
}
コード例 #15
0
ファイル: radiation.c プロジェクト: project8/adiP8
int get_sq_wg_efield(TVector3 &pos, TVector3 &efield)
{
  //function returns the TE_10 efield inside an infinite square waveguide 
  //centered at x=0, y=0 (not with corner at origin as is standard)
  //efield normalized the jackson way with 1/cm units
  //waveguide extends in z-direction
  // wavelength of 27 GHz radiation is 1.1 cm
  double e_amp = sqrt(2 / tl_data.x1 / tl_data.y1);
  int status = 0;

  if ((pos.X() > tl_data.x1 / 2.) || (pos.X() < -tl_data.x1 / 2.)) {
    cout << "Problem!!! Electron hit a wall in x-dir! " << endl;
    status = 1;
  }
  if ((pos.Y() > tl_data.y1 / 2.) || (pos.Y() < -tl_data.y1 / 2.)) {
    cout << "Problem!!! Electron hit a wall in y-dir! " << endl;
    status = 1;
  }
  efield.SetX( 0 );
  efield.SetY( e_amp * sin(M_PI * (pos.X() + tl_data.x1 / 2.) / tl_data.x1) );
  efield.SetZ( 0 );                //is true for TE mode
  return status;
}
コード例 #16
0
ファイル: radiation.c プロジェクト: project8/adiP8
int get_pp_efield(TVector3 &p, TVector3 &efield)
{
  //function returns the electric field between two parallel plates 
  //amplitude corrected for capacitance of finite width strips
  //not valid outside plates
  //efield normalized the jackson way with 1/cm units
  //strips extend in y- and z- directions, so the field is in the x-direction
  double e_amp = sqrt(1 / (tl_data.n * tl_data.l * (tl_data.x2 - tl_data.x1)));
  //factor of sqrt(n=1.8) lower than ideal capacitor 
  int status = 0;

  if ((p.X() < tl_data.x1) || (p.X() > tl_data.x2)) {
    cout << "Problem!!! Electron hit a plate! " << endl;
    status = 1;
  }
  if ((p.Y() < -tl_data.l / 2) || (p.Y() > tl_data.l / 2)) {
    cout << "Problem!!! Electron outside plates! " << endl;
    status = 1;
  }
  efield.SetX( e_amp );
  efield.SetY( 0 );
  efield.SetZ( 0 );                //only true for TE or TEM modes
  return status;
}
コード例 #17
0
void example_Hp_to_HggWlnu(const std::string& output_name =
			   "output_Hp_to_HggWlnu.root"){
 
  // set particle masses and widths
  double mH   = 125.; 
  double mW   = 80.385; // GeV, PDG 2016
  double wW   = 2.085;
  
  std::vector<double> mHp; // vary charged Higgs mass
  mHp.push_back(300.);
  mHp.push_back(500.);
  mHp.push_back(750.);
  mHp.push_back(1000.);
  mHp.push_back(1500.);
  
  // Number of events to generate (per H+ mass)
  int Ngen = 10000;
  
  /////////////////////////////////////////////////////////////////////////////////////////
  g_Log << LogInfo << "Initializing generator frames and tree..." << LogEnd;
  /////////////////////////////////////////////////////////////////////////////////////////
  ppLabGenFrame         LAB_Gen("LAB_Gen","LAB");
  DecayGenFrame         Hp_Gen("Hp_Gen","H^{ +}");
  DecayGenFrame         H_Gen("H_Gen","h^{ 0}");
  ResonanceGenFrame     W_Gen("W_Gen","W^{ +}");
  VisibleGenFrame       G1_Gen("G1_Gen","#gamma_{1}");
  VisibleGenFrame       G2_Gen("G2_Gen","#gamma_{2}");
  VisibleGenFrame       L_Gen("L_Gen","#it{l}^{ +}");
  InvisibleGenFrame     NU_Gen("NU_Gen","#nu");

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

  LAB_Gen.SetChildFrame(Hp_Gen);
  Hp_Gen.AddChildFrame(H_Gen);
  Hp_Gen.AddChildFrame(W_Gen);
  H_Gen.AddChildFrame(G1_Gen);
  H_Gen.AddChildFrame(G2_Gen);
  W_Gen.AddChildFrame(L_Gen);
  W_Gen.AddChildFrame(NU_Gen);

  if(LAB_Gen.InitializeTree())
    g_Log << LogInfo << "...Successfully initialized generator tree" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing generator tree" << LogEnd;

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

  if(mHp.size() < 1) return;
  
  // set neutral and charged Higgs mass 
  Hp_Gen.SetMass(mHp[0]);              H_Gen.SetMass(mH);         
  // set W mass and width
  W_Gen.SetMass(mW);                   W_Gen.SetWidth(wW);

  // set photon/lepton pT and eta cuts
  L_Gen.SetPtCut(15.);                 L_Gen.SetEtaCut(2.5);
  G1_Gen.SetPtCut(20.);                G1_Gen.SetEtaCut(3.);
  G2_Gen.SetPtCut(20.);                G2_Gen.SetEtaCut(3.);  

  if(LAB_Gen.InitializeAnalysis())
    g_Log << LogInfo << "...Successfully initialized generator analysis" << std::endl << LogEnd;
  else
    g_Log << LogError << "...Failed initializing generator analysis" << LogEnd;
  /////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////////////////////////////
  g_Log << LogInfo << "Initializing reconstruction frames and trees..." << LogEnd;
  /////////////////////////////////////////////////////////////////////////////////////////
  LabRecoFrame       LAB("LAB","LAB");
  DecayRecoFrame     Hp("Hp","H^{ +}");
  DecayRecoFrame     H("H","h^{ 0}");
  DecayRecoFrame     W("W","W^{ +}");
  VisibleRecoFrame   G1("G1","#gamma_{1}");
  VisibleRecoFrame   G2("G2","#gamma_{2}");
  VisibleRecoFrame   L("L","#it{l}^{ +}");
  InvisibleRecoFrame NU("NU","#nu");

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

  LAB.SetChildFrame(Hp);
  Hp.AddChildFrame(H);
  Hp.AddChildFrame(W);
  H.AddChildFrame(G1);
  H.AddChildFrame(G2);
  W.AddChildFrame(L);
  W.AddChildFrame(NU);

  if(LAB.InitializeTree())
    g_Log << LogInfo << "...Successfully initialized reconstruction trees" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing reconstruction trees" << LogEnd;

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

  // Invisible Group
  InvisibleGroup INV("INV","#nu Jigsaws");
  INV.AddFrame(NU);     

  // Set neutrino masses to zero
  SetMassInvJigsaw NuM("NuM","M_{#nu} = 0"); 
  INV.AddJigsaw(NuM);                        

  // Set neutrino rapidity to that of visible particles
  SetRapidityInvJigsaw NuR("NuR","#eta_{#nu} = #eta_{#gamma#gamma#it{l}}");
  INV.AddJigsaw(NuR);
  NuR.AddVisibleFrames(Hp.GetListVisibleFrames());

  if(LAB.InitializeAnalysis())
    g_Log << LogInfo << "...Successfully initialized analyses" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing analyses" << LogEnd;

  /////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////

  TreePlot* treePlot = new TreePlot("TreePlot","TreePlot");
 
  treePlot->SetTree(LAB_Gen);
  treePlot->Draw("GenTree", "Generator Tree", true);

  treePlot->SetTree(LAB);
  treePlot->Draw("RecoTree", "Reconstruction Tree");

  //-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//
  
  // Declare observables for histogram booking
  std::string plot_title = "pp #rightarrow H^{ +} #rightarrow h^{ 0}(#gamma #gamma ) W(#it{l} #nu)";
  HistPlot* histPlot   = new HistPlot("HistPlot", plot_title);

  RFList<const HistPlotCategory> cat_list;
  int Nmass = mHp.size();
  for(int m = 0; m < Nmass; m++){
    char smass[50], scat[50];
    sprintf(scat, "MHp%.0f", mHp[m]);
    sprintf(smass, "m_{H^{ +}} = %.0f", mHp[m]);
    cat_list += histPlot->GetNewCategory(scat, smass);
  }

  const HistPlotCategory& cat_Hp  = histPlot->GetNewCategory("HprodHp", "h^{ 0} prod. frame = H^{ +}");
  const HistPlotCategory& cat_LAB = histPlot->GetNewCategory("HprodLAB", "h^{ 0} prod. frame = LAB");
  
  const HistPlotVar& MHp    = histPlot->GetNewVar("MHp", "M_{H^{ +}}", 0., 2400., "[GeV]");
  const HistPlotVar& MHpN   = histPlot->GetNewVar("MHpN", "M_{H^{ +}} / m_{H^{ +}}^{true}", 0.7, 1.05);
  const HistPlotVar& MWN    = histPlot->GetNewVar("MWN", "M_{W} / m_{W}^{true}", 0., 2.);
  const HistPlotVar& cosHp  = histPlot->GetNewVar("cosHp","cos #theta_{H^{ +}}", -1., 1.);
  const HistPlotVar& cosW   = histPlot->GetNewVar("cosW","cos #theta_{W}", -1., 1.);
  const HistPlotVar& cosH   = histPlot->GetNewVar("cosH","cos #theta_{h^{ 0}}", -1., 1.);
  const HistPlotVar& DcosHp = histPlot->GetNewVar("DcosHp","#theta_{H^{ +}} - #theta_{H^{ +}}^{true}", -1., 1.);
  const HistPlotVar& DcosW  = histPlot->GetNewVar("DcosW","#theta_{W} - #theta_{W}^{true}", -1., 1.);
  const HistPlotVar& DcosH  = histPlot->GetNewVar("DcosW","#theta_{h^{ 0}} - #theta_{h^{ 0}}^{true}", -1., 1.);

  histPlot->AddPlot(DcosH,  cat_list);
  histPlot->AddPlot(DcosW,  cat_list);
  histPlot->AddPlot(DcosHp, cat_list);
  histPlot->AddPlot(MWN,  cat_list);
  histPlot->AddPlot(MHpN, cat_list);
  histPlot->AddPlot(MHp,  cat_list);
  histPlot->AddPlot(MWN,    MHpN,   cat_list[2]);
  histPlot->AddPlot(DcosW, MWN,  cat_list[2]);
  histPlot->AddPlot(DcosHp, MHpN, cat_list[2]);
  histPlot->AddPlot(DcosHp, DcosW,  cat_list[2]);
  histPlot->AddPlot(DcosH,  MHpN,   cat_list[2]);
  
  histPlot->AddPlot(DcosH,  cat_Hp+cat_LAB);

  /////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////

  for(int m = 0; m < Nmass; m++){
    g_Log << LogInfo << "Generating events for H^{+} mass = " << mHp[m] << LogEnd;

    Hp_Gen.SetMass(mHp[m]);
    LAB_Gen.InitializeAnalysis();
  
    for(int igen = 0; igen < Ngen; igen++){
      if(igen%((std::max(Ngen,10))/10) == 0)
	g_Log << LogInfo << "Generating event " << igen << " of " << Ngen << LogEnd;
      
      // generate event
      LAB_Gen.ClearEvent();                            // clear the gen tree

      LAB_Gen.SetPToverM(gRandom->Rndm());             // give charged Higgs some Pt
      
      LAB_Gen.AnalyzeEvent();                          // generate a new event

      TVector3 MET = LAB_Gen.GetInvisibleMomentum();   // Get the MET from gen tree
      MET.SetZ(0.);
    
      // analyze event 
      LAB.ClearEvent();                                   // clear the reco tree
    
      L.SetLabFrameFourVector(L_Gen.GetFourVector());     // Set lepton 4-vec
      G1.SetLabFrameFourVector(G1_Gen.GetFourVector());   // Set photons' 4-vec
      G2.SetLabFrameFourVector(G2_Gen.GetFourVector());   
      INV.SetLabFrameThreeVector(MET);                    // Set the MET in reco tree
    
      LAB.AnalyzeEvent();                                 //analyze the event

      // Generator-level observables
      double MHpgen = Hp_Gen.GetMass();
      double MWgen  = W_Gen.GetMass();
      double cosHpgen = Hp_Gen.GetCosDecayAngle();
      double cosHgen  = H_Gen.GetCosDecayAngle();
      double cosWgen  = W_Gen.GetCosDecayAngle();

      // Reconstructed observables
      MHp    = Hp.GetMass();
      MHpN   = Hp.GetMass()/MHpgen;
      MWN    = W.GetMass()/MWgen;
      cosHp  = Hp.GetCosDecayAngle();
      cosH   = H.GetCosDecayAngle();
      cosW   = W.GetCosDecayAngle();
      DcosHp = asin(sqrt(1.-cosHp*cosHp)*cosHpgen-sqrt(1.-cosHpgen*cosHpgen)*cosHp);
      DcosH  = asin(sqrt(1.-cosH*cosH)*cosHgen-sqrt(1.-cosHgen*cosHgen)*cosH);
      DcosW  = asin(sqrt(1.-cosW*cosW)*cosWgen-sqrt(1.-cosWgen*cosWgen)*cosW);

      histPlot->Fill(cat_list[m]);

      if(m == 0){
	histPlot->Fill(cat_Hp);
	
	TVector3 Hboost = H.GetFourVector().BoostVector();
	TLorentzVector vP_G1 = G1.GetFourVector();
	vP_G1.Boost(-Hboost);
	cosH   = -vP_G1.Vect().Unit().Dot(Hboost.Unit());
	DcosH  = asin(sqrt(1.-cosH*cosH)*cosHgen-sqrt(1.-cosHgen*cosHgen)*cosH);

	histPlot->Fill(cat_LAB);
      }
    }

    LAB_Gen.PrintGeneratorEfficiency();
  }

  histPlot->Draw();
  
  TFile fout(output_name.c_str(),"RECREATE");
  fout.Close();
  histPlot->WriteOutput(output_name);
  histPlot->WriteHist(output_name);
  treePlot->WriteOutput(output_name);

  g_Log << LogInfo << "Finished" << LogEnd;

}
コード例 #18
0
void example_ttbar_to_bWlnubWlnu(const std::string output_name =
				 "output_ttbar_to_bWlnubWlnu.root"){

  double mT = 173.21; // GeV, PDG 2016
  double mW = 80.385;
  double mB = 4.18;
  double mL = 0.106;
  double mN = 0.;

  // number of events to generate
  int Ngen = 100000;

  /////////////////////////////////////////////////////////////////////////////////////////
  g_Log << LogInfo << "Initializing generator frames and tree..." << LogEnd;
  /////////////////////////////////////////////////////////////////////////////////////////
  ppLabGenFrame     LAB_Gen("LAB_Gen","LAB");
  DecayGenFrame     TT_Gen("TT_Gen","t #bar{t}");
  DecayGenFrame     Ta_Gen("Ta_Gen","t_{a}");
  DecayGenFrame     Tb_Gen("Tb_Gen","t_{b}");
  DecayGenFrame     Wa_Gen("Wa_Gen","W_{a}");
  DecayGenFrame     Wb_Gen("Wb_Gen","W_{b}");
  VisibleGenFrame   Ba_Gen("Ba_Gen","b_{a}");
  VisibleGenFrame   La_Gen("La_Gen","#it{l}_{a}");
  InvisibleGenFrame Na_Gen("Na_Gen","#nu_{a}");
  VisibleGenFrame   Bb_Gen("Bb_Gen","b_{b}");
  VisibleGenFrame   Lb_Gen("Lb_Gen","#it{l}_{b}");
  InvisibleGenFrame Nb_Gen("Nb_Gen","#nu_{b}");

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

  LAB_Gen.SetChildFrame(TT_Gen);
  TT_Gen.AddChildFrame(Ta_Gen);
  TT_Gen.AddChildFrame(Tb_Gen);
  Ta_Gen.AddChildFrame(Ba_Gen);
  Ta_Gen.AddChildFrame(Wa_Gen);
  Tb_Gen.AddChildFrame(Bb_Gen);
  Tb_Gen.AddChildFrame(Wb_Gen);
  Wa_Gen.AddChildFrame(La_Gen);
  Wa_Gen.AddChildFrame(Na_Gen);
  Wb_Gen.AddChildFrame(Lb_Gen);
  Wb_Gen.AddChildFrame(Nb_Gen);

  if(LAB_Gen.InitializeTree())
    g_Log << LogInfo << "...Successfully initialized generator tree" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing generator tree" << LogEnd;							        
  
  //-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//

  // non-resonant ttbar production
  TT_Gen.SetVariableMass();
  // set top masses
  Ta_Gen.SetMass(mT);            Tb_Gen.SetMass(mT);
  // set W masses
  Wa_Gen.SetMass(mW);            Wb_Gen.SetMass(mW);
  // set B masses
  Ba_Gen.SetMass(mB);            Bb_Gen.SetMass(mB);
  // set : masses
  La_Gen.SetMass(mL);            Lb_Gen.SetMass(mL);
  // set neutrino masses
  Na_Gen.SetMass(mN);            Nb_Gen.SetMass(mN);

  // set b-jet/lepton pT/eta cuts
  Ba_Gen.SetPtCut(20.);          Bb_Gen.SetPtCut(20.);
  Ba_Gen.SetEtaCut(2.5);         Bb_Gen.SetEtaCut(2.5);
  La_Gen.SetPtCut(15.);          Lb_Gen.SetPtCut(15.);
  La_Gen.SetEtaCut(2.5);         Lb_Gen.SetEtaCut(2.5);

  if(LAB_Gen.InitializeAnalysis())
    g_Log << LogInfo << "...Successfully initialized generator analysis" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing generator analysis" << LogEnd;
  /////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////								    
  /////////////////////////////////////////////////////////////////////////////////////////
  g_Log << LogInfo << "Initializing reconstruction frames and trees..." << LogEnd;
  /////////////////////////////////////////////////////////////////////////////////////////
  LabRecoFrame       LAB_R1("LAB_R1","LAB");      LabRecoFrame       LAB_R2("LAB_R2","LAB");
  DecayRecoFrame     TT_R1("TT_R1","t #bar{t}");  DecayRecoFrame     TT_R2("TT_R2","t #bar{t}");
  DecayRecoFrame     Ta_R1("Ta_R1","t_{a}");      DecayRecoFrame     Ta_R2("Ta_R2","t_{a}");
  DecayRecoFrame     Tb_R1("Tb_R1","t_{b}");      DecayRecoFrame     Tb_R2("Tb_R2","t_{b}");
  DecayRecoFrame     Wa_R1("Wa_R1","W_{a}");      DecayRecoFrame     Wa_R2("Wa_R2","W_{a}");
  DecayRecoFrame     Wb_R1("Wb_R1","W_{b}");      DecayRecoFrame     Wb_R2("Wb_R2","W_{b}");
  VisibleRecoFrame   Ba_R1("Ba_R1","b_{a}");      VisibleRecoFrame   Ba_R2("Ba_R2","b_{a}");
  VisibleRecoFrame   La_R1("La_R1","#it{l}_{a}"); VisibleRecoFrame   La_R2("La_R2","#it{l}_{a}");
  InvisibleRecoFrame Na_R1("Na_R1","#nu_{a}");    InvisibleRecoFrame Na_R2("Na_R2","#nu_{a}");
  VisibleRecoFrame   Bb_R1("Bb_R1","b_{b}");      VisibleRecoFrame   Bb_R2("Bb_R2","b_{b}");
  VisibleRecoFrame   Lb_R1("Lb_R1","#it{l}_{b}"); VisibleRecoFrame   Lb_R2("Lb_R2","#it{l}_{b}");
  InvisibleRecoFrame Nb_R1("Nb_R1","#nu_{b}");    InvisibleRecoFrame Nb_R2("Nb_R2","#nu_{b}");

  LabRecoFrame       LAB_R3("LAB_R3","LAB");      LabRecoFrame       LAB_R4("LAB_R4","LAB");
  DecayRecoFrame     TT_R3("TT_R3","t #bar{t}");  DecayRecoFrame     TT_R4("TT_R4","t #bar{t}");
  DecayRecoFrame     Ta_R3("Ta_R3","t_{a}");      DecayRecoFrame     Ta_R4("Ta_R4","t_{a}");
  DecayRecoFrame     Tb_R3("Tb_R3","t_{b}");      DecayRecoFrame     Tb_R4("Tb_R4","t_{b}");
  DecayRecoFrame     Wa_R3("Wa_R3","W_{a}");      DecayRecoFrame     Wa_R4("Wa_R4","W_{a}");
  DecayRecoFrame     Wb_R3("Wb_R3","W_{b}");      DecayRecoFrame     Wb_R4("Wb_R4","W_{b}");
  VisibleRecoFrame   Ba_R3("Ba_R3","b_{a}");      VisibleRecoFrame   Ba_R4("Ba_R4","b_{a}");
  VisibleRecoFrame   La_R3("La_R3","#it{l}_{a}"); VisibleRecoFrame   La_R4("La_R4","#it{l}_{a}");
  InvisibleRecoFrame Na_R3("Na_R3","#nu_{a}");    InvisibleRecoFrame Na_R4("Na_R4","#nu_{a}");
  VisibleRecoFrame   Bb_R3("Bb_R3","b_{b}");      VisibleRecoFrame   Bb_R4("Bb_R4","b_{b}");
  VisibleRecoFrame   Lb_R3("Lb_R3","#it{l}_{b}"); VisibleRecoFrame   Lb_R4("Lb_R4","#it{l}_{b}");
  InvisibleRecoFrame Nb_R3("Nb_R3","#nu_{b}");    InvisibleRecoFrame Nb_R4("Nb_R4","#nu_{b}");

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

  LAB_R1.SetChildFrame(TT_R1);                    LAB_R2.SetChildFrame(TT_R2);
  TT_R1.AddChildFrame(Ta_R1);                     TT_R2.AddChildFrame(Ta_R2);
  TT_R1.AddChildFrame(Tb_R1);                     TT_R2.AddChildFrame(Tb_R2);
  Ta_R1.AddChildFrame(Ba_R1);                     Ta_R2.AddChildFrame(Ba_R2);
  Ta_R1.AddChildFrame(Wa_R1);                     Ta_R2.AddChildFrame(Wa_R2);
  Tb_R1.AddChildFrame(Bb_R1);                     Tb_R2.AddChildFrame(Bb_R2);
  Tb_R1.AddChildFrame(Wb_R1);                     Tb_R2.AddChildFrame(Wb_R2);
  Wa_R1.AddChildFrame(La_R1);                     Wa_R2.AddChildFrame(La_R2);
  Wa_R1.AddChildFrame(Na_R1);                     Wa_R2.AddChildFrame(Na_R2);
  Wb_R1.AddChildFrame(Lb_R1);                     Wb_R2.AddChildFrame(Lb_R2);
  Wb_R1.AddChildFrame(Nb_R1);                     Wb_R2.AddChildFrame(Nb_R2);

  LAB_R3.SetChildFrame(TT_R3);                    LAB_R4.SetChildFrame(TT_R4);
  TT_R3.AddChildFrame(Ta_R3);                     TT_R4.AddChildFrame(Ta_R4);
  TT_R3.AddChildFrame(Tb_R3);                     TT_R4.AddChildFrame(Tb_R4);
  Ta_R3.AddChildFrame(Ba_R3);                     Ta_R4.AddChildFrame(Ba_R4);
  Ta_R3.AddChildFrame(Wa_R3);                     Ta_R4.AddChildFrame(Wa_R4);
  Tb_R3.AddChildFrame(Bb_R3);                     Tb_R4.AddChildFrame(Bb_R4);
  Tb_R3.AddChildFrame(Wb_R3);                     Tb_R4.AddChildFrame(Wb_R4);
  Wa_R3.AddChildFrame(La_R3);                     Wa_R4.AddChildFrame(La_R4);
  Wa_R3.AddChildFrame(Na_R3);                     Wa_R4.AddChildFrame(Na_R4);
  Wb_R3.AddChildFrame(Lb_R3);                     Wb_R4.AddChildFrame(Lb_R4);
  Wb_R3.AddChildFrame(Nb_R3);                     Wb_R4.AddChildFrame(Nb_R4);

  if(LAB_R1.InitializeTree() && LAB_R2.InitializeTree() && 
     LAB_R3.InitializeTree() && LAB_R4.InitializeTree())
    g_Log << LogInfo << "...Successfully initialized reconstruction trees" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing reconstruction trees" << LogEnd;
 
  //-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//

  //////////////////////// define Groups for reconstruction trees ////////////////////////
  std::string group_name;

  // Invisible Group
  group_name = "#splitline{#nu #nu Jigsaws for}{min M_{top} , M_{top}^{ a} = M_{top}^{ b}}";
  InvisibleGroup INV_R1("INV_R1", group_name);
  INV_R1.AddFrame(Na_R1);
  INV_R1.AddFrame(Nb_R1);
  // Combinatoric Group for b's
  CombinatoricGroup B_R1("VIS_R1","b-jet Jigsaws");
  B_R1.AddFrame(Ba_R1);
  B_R1.AddFrame(Bb_R1);
  // b-jet frames must have at least one element
  B_R1.SetNElementsForFrame(Ba_R1, 1);
  B_R1.SetNElementsForFrame(Bb_R1, 1);

  group_name = "#splitline{#nu #nu Jigsaws for}{min M_{W}, M_{W}^{ a} = M_{W}^{ b}}";
  InvisibleGroup INV_R2("INV_R2", group_name);
  INV_R2.AddFrame(Na_R2);
  INV_R2.AddFrame(Nb_R2);
  CombinatoricGroup B_R2("VIS_R2","b-jet Jigsaws");
  B_R2.AddFrame(Ba_R2);
  B_R2.AddFrame(Bb_R2);
  B_R2.SetNElementsForFrame(Ba_R2, 1);
  B_R2.SetNElementsForFrame(Bb_R2, 1);

  group_name = "#splitline{#nu #nu Jigsaws for}{min M_{top a}^{2}+ M_{top b}^{2}}";
  InvisibleGroup INV_R3("INV_R3", group_name);
  INV_R3.AddFrame(Na_R3);
  INV_R3.AddFrame(Nb_R3);
  CombinatoricGroup B_R3("VIS_R3","b-jet Jigsaws");
  B_R3.AddFrame(Ba_R3);
  B_R3.AddFrame(Bb_R3);
  B_R3.SetNElementsForFrame(Ba_R3, 1);
  B_R3.SetNElementsForFrame(Bb_R3, 1);

  group_name = "#splitline{#nu #nu Jigsaws for}{min (M_{top a}- M_{top b})^{2}}";
  InvisibleGroup INV_R4("INV_R4", group_name);
  INV_R4.AddFrame(Na_R4);
  INV_R4.AddFrame(Nb_R4);
  CombinatoricGroup B_R4("VIS_R4","b-jet Jigsaws");
  B_R4.AddFrame(Ba_R4);
  B_R4.AddFrame(Bb_R4);
  B_R4.SetNElementsForFrame(Ba_R4, 1);
  B_R4.SetNElementsForFrame(Bb_R4, 1);

  //////////////////////// define Jigsaws for reconstruction trees ////////////////////////
  std::string jigsaw_name;

  // Minimize equal top masses neutrino jigsaws
  jigsaw_name = "M_{#nu#nu} = f(m_{b#it{l}b#it{l}} , m_{b#it{l}}^{ a} , m_{b#it{l}}^{ b})";
  SetMassInvJigsaw NuNuM_R1("NuNuM_R1", jigsaw_name);
  INV_R1.AddJigsaw(NuNuM_R1);

  jigsaw_name = "#eta_{#nu#nu} = #eta_{b #it{l} b #it{l}}";
  SetRapidityInvJigsaw NuNuR_R1("NuNuR_R1", jigsaw_name);
  INV_R1.AddJigsaw(NuNuR_R1);
  NuNuR_R1.AddVisibleFrames(La_R1+Ba_R1+Lb_R1+Bb_R1);

  jigsaw_name = "min M_{top}, M_{top}^{ a} = M_{top}^{ b}";
  ContraBoostInvJigsaw MinMt_R1("MinMt_R1", jigsaw_name);
  INV_R1.AddJigsaw(MinMt_R1);
  MinMt_R1.AddVisibleFrames(La_R1+Ba_R1, 0);
  MinMt_R1.AddVisibleFrames(Lb_R1+Bb_R1, 1);
  MinMt_R1.AddInvisibleFrame(Na_R1, 0);
  MinMt_R1.AddInvisibleFrame(Nb_R1, 1);

  // Minimize equal W masses neutrino jigsaws
  jigsaw_name = "M_{#nu#nu} = f(m_{#it{l}#it{l}} , m_{#it{l}}^{ a} , m_{#it{l}}^{ b})";
  SetMassInvJigsaw NuNuM_R2("NuNuM_R2", jigsaw_name);
  INV_R2.AddJigsaw(NuNuM_R2);

  jigsaw_name = "#eta_{#nu#nu} = #eta_{b #it{l} b #it{l}}";
  SetRapidityInvJigsaw NuNuR_R2("NuNuR_R2", jigsaw_name);
  INV_R2.AddJigsaw(NuNuR_R2);
  NuNuR_R2.AddVisibleFrames(La_R2+Ba_R2+Lb_R2+Bb_R2);

  jigsaw_name = "min M_{W}, M_{W}^{ a} = M_{W}^{ b}";
  ContraBoostInvJigsaw MinMW_R2("MinMW_R2", jigsaw_name);
  INV_R2.AddJigsaw(MinMW_R2);
  MinMW_R2.AddVisibleFrame(La_R2, 0);
  MinMW_R2.AddVisibleFrame(Lb_R2, 1);
  MinMW_R2.AddInvisibleFrame(Na_R2, 0);
  MinMW_R2.AddInvisibleFrame(Nb_R2, 1);

  // Minimize sum Mt^2 jigsaws
  jigsaw_name = "M_{#nu#nu} = f(m_{#it{l}#it{l}} , m_{#it{l}}^{ a} , m_{#it{l}}^{ b})";
  SetMassInvJigsaw NuNuM_R3("NuNuM_R3", jigsaw_name);
  INV_R3.AddJigsaw(NuNuM_R3);

  jigsaw_name = "#eta_{#nu#nu} = #eta_{b #it{l} b #it{l}}";
  SetRapidityInvJigsaw NuNuR_R3("NuNuR_R3", jigsaw_name);
  INV_R3.AddJigsaw(NuNuR_R3);
  NuNuR_R3.AddVisibleFrames(LAB_R3.GetListVisibleFrames());

  jigsaw_name = "min #Sigma M_{top}^{2}";
  MinMassesSqInvJigsaw MinMt_R3("MinMt_R3", jigsaw_name, 2);
  INV_R3.AddJigsaw(MinMt_R3);
  MinMt_R3.AddInvisibleFrame(Na_R3, 0);
  MinMt_R3.AddInvisibleFrame(Nb_R3, 1);
  MinMt_R3.AddVisibleFrames(La_R3+Ba_R3, 0);
  MinMt_R3.AddVisibleFrames(Lb_R3+Bb_R3, 1);
  MinMt_R3.AddMassFrame(La_R3, 0);
  MinMt_R3.AddMassFrame(Lb_R3, 1);

  // Minimize difference Mt jigsaws
  jigsaw_name = "M_{#nu#nu} = f(m_{#it{l}#it{l}} , m_{#it{l}}^{ a} , m_{#it{l}}^{ b})";
  SetMassInvJigsaw NuNuM_R4("NuNuM_R4", jigsaw_name);
  INV_R4.AddJigsaw(NuNuM_R4);

  jigsaw_name = "#eta_{#nu#nu} = #eta_{b #it{l} b #it{l}}";
  SetRapidityInvJigsaw NuNuR_R4("NuNuR_R4", jigsaw_name);
  INV_R4.AddJigsaw(NuNuR_R4);
  NuNuR_R4.AddVisibleFrames(LAB_R4.GetListVisibleFrames());

  jigsaw_name = "min ( M_{top a}- M_{top b} )^{2}";
  MinMassDiffInvJigsaw MinDeltaMt_R4("MinDeltaMt_R4", jigsaw_name, 2);
  INV_R4.AddJigsaw(MinDeltaMt_R4);
  MinDeltaMt_R4.AddInvisibleFrame(Na_R4, 0);
  MinDeltaMt_R4.AddInvisibleFrame(Nb_R4, 1);
  MinDeltaMt_R4.AddVisibleFrames(La_R4+Ba_R4, 0);
  MinDeltaMt_R4.AddVisibleFrames(Lb_R4+Bb_R4, 1);
  MinDeltaMt_R4.AddMassFrame(La_R4, 0);
  MinDeltaMt_R4.AddMassFrame(Lb_R4, 1);

  // b-jet combinatoric jigsaws for all trees
  jigsaw_name = "Minimize M(b #it{l} )_{a} , M(b #it{l} )_{b}";

  MinMassesCombJigsaw MinBL_R1("MinBL_R1", jigsaw_name);
  B_R1.AddJigsaw(MinBL_R1);
  MinBL_R1.AddFrames(La_R1+Ba_R1,0);
  MinBL_R1.AddFrames(Lb_R1+Bb_R1,1);

  MinMassesCombJigsaw MinBL_R2("MinBL_R2", jigsaw_name);
  B_R2.AddJigsaw(MinBL_R2);
  MinBL_R2.AddFrames(La_R2+Ba_R2,0);
  MinBL_R2.AddFrames(Lb_R2+Bb_R2,1);

  MinMassesCombJigsaw MinBL_R3("MinBL_R3", jigsaw_name);
  B_R3.AddJigsaw(MinBL_R3);
  MinBL_R3.AddFrames(La_R3+Ba_R3,0);
  MinBL_R3.AddFrames(Lb_R3+Bb_R3,1);

  MinMassesCombJigsaw MinBL_R4("MinBL_R4", jigsaw_name);
  B_R4.AddJigsaw(MinBL_R4);
  MinBL_R4.AddFrames(La_R4+Ba_R4,0);
  MinBL_R4.AddFrames(Lb_R4+Bb_R4,1);

  if(LAB_R1.InitializeAnalysis() && LAB_R2.InitializeAnalysis() && 
     LAB_R3.InitializeAnalysis() && LAB_R4.InitializeAnalysis())
    g_Log << LogInfo << "...Successfully initialized analysis" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing analysis" << LogEnd;	

  /////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////

  TreePlot* treePlot = new TreePlot("TreePlot","TreePlot");
 
  treePlot->SetTree(LAB_Gen);
  treePlot->Draw("GenTree", "Generator Tree", true);
  
  treePlot->SetTree(LAB_R1);
  treePlot->Draw("RecoTree", "Reconstruction Tree");

  treePlot->SetTree(B_R1);
  treePlot->Draw("VisTree", "b-jet Jigsaws", true);

  treePlot->SetTree(INV_R1);
  treePlot->Draw("InvTree_R1", "Inivisibl Jigsaws", true);

  treePlot->SetTree(INV_R2);
  treePlot->Draw("InvTree_R2", "Inivisibl Jigsaws", true);

  treePlot->SetTree(INV_R3);
  treePlot->Draw("InvTree_R3", "Inivisibl Jigsaws", true);

  treePlot->SetTree(INV_R4);
  treePlot->Draw("InvTree_R4", "Inivisibl Jigsaws", true);

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

  HistPlot* histPlot = new HistPlot("HistPlot", "t #bar{t} #rightarrow b W(#it{l} #nu) b W(#it{l} #nu)");

  const HistPlotCategory& cat_Gen = histPlot->GetNewCategory("Gen",  "Generator");
  const HistPlotCategory& cat_R1  = histPlot->GetNewCategory("Reco1", "M_{top}^{ a} = M_{top}^{ b} Reco");
  const HistPlotCategory& cat_R2  = histPlot->GetNewCategory("Reco2", "M_{W}^{ a} = M_{W}^{ b} Reco");
  const HistPlotCategory& cat_R3  = histPlot->GetNewCategory("Reco3", "min #Sigma M_{top}^{ 2} Reco");
  const HistPlotCategory& cat_R4  = histPlot->GetNewCategory("Reco4", "min #Delta M_{top} Reco");

  const HistPlotVar& Mtt    = histPlot->GetNewVar("Mtt", "M_{t #bar{t}} / m_{t #bar{t}}", 0., 2.);
  const HistPlotVar& Eb_ta  = histPlot->GetNewVar("Eb_ta", "E_{b a}^{top a} / E_{b a}^{top a gen}", 0., 2.);
  const HistPlotVar& Eb_tb  = histPlot->GetNewVar("Eb_tb", "E_{b b}^{top b} / E_{b b}^{top b gen}", 0., 2.);
  const HistPlotVar& El_Wa  = histPlot->GetNewVar("El_Wa", "E_{#it{l} a}^{W a} / E_{#it{l} a}^{W a gen}", 0., 2.);
  const HistPlotVar& El_Wb  = histPlot->GetNewVar("El_Wb", "E_{#it{l} b}^{W b} / E_{#it{l} b}^{W b gen}", 0., 2.);
  const HistPlotVar& costt  = histPlot->GetNewVar("costt","cos #theta_{t #bar{t}}", -1., 1.);
  const HistPlotVar& costa  = histPlot->GetNewVar("costa","cos #theta_{top a}", -1., 1.);
  const HistPlotVar& costb  = histPlot->GetNewVar("costb","cos #theta_{top b}", -1., 1.);
  const HistPlotVar& cosWa  = histPlot->GetNewVar("cosWa","cos #theta_{W a}", -1., 1.);
  const HistPlotVar& cosWb  = histPlot->GetNewVar("cosWb","cos #theta_{W b}", -1., 1.);
  const HistPlotVar& Dcostt = histPlot->GetNewVar("Dcostt","#theta_{t #bar{t}} - #theta_{t #bar{t}}^{gen}", 
						  -acos(-1.)/2., acos(-1.)/2.);
  const HistPlotVar& Dcosta = histPlot->GetNewVar("Dcosta","#theta_{top a} - #theta_{top a}^{gen}", 
						  -acos(-1.)/2., acos(-1.)/2.);
  const HistPlotVar& Dcostb = histPlot->GetNewVar("Dcostb","#theta_{top b} - #theta_{top b}^{gen}", 
						  -acos(-1.)/2., acos(-1.)/2.);
  const HistPlotVar& DcosWa = histPlot->GetNewVar("DcosWa","#theta_{W a} - #theta_{W a}^{gen}", 
						  -acos(-1.)/2., acos(-1.)/2.);
  const HistPlotVar& DcosWb = histPlot->GetNewVar("DcosWb","#theta_{W b} - #theta_{W b}^{gen}", 
						  -acos(-1.)/2., acos(-1.)/2.);

  histPlot->AddPlot(Mtt,   cat_R1+cat_R2+cat_R3+cat_R4);
  histPlot->AddPlot(Eb_ta, cat_R1+cat_R2+cat_R3+cat_R4);
  histPlot->AddPlot(El_Wa, cat_R1+cat_R2+cat_R3+cat_R4);
  histPlot->AddPlot(Dcostt, cat_R1+cat_R2+cat_R3+cat_R4);
  histPlot->AddPlot(Dcosta, cat_R1+cat_R2+cat_R3+cat_R4);
  histPlot->AddPlot(DcosWa, cat_R1+cat_R2+cat_R3+cat_R4);

  histPlot->AddPlot(Mtt, Eb_ta, cat_R4);
  histPlot->AddPlot(Mtt, El_Wa, cat_R4);
  histPlot->AddPlot(Eb_ta, Eb_tb, cat_R4);
  histPlot->AddPlot(El_Wa, El_Wb, cat_R4);
  histPlot->AddPlot(Eb_ta, El_Wa, cat_R4);
  histPlot->AddPlot(Eb_ta, El_Wb, cat_R4);
  histPlot->AddPlot(Dcostt, Mtt,  cat_R4);
  histPlot->AddPlot(Dcosta, Eb_ta, cat_R4);
  histPlot->AddPlot(DcosWa, El_Wa, cat_R4);
  histPlot->AddPlot(Dcostt, Dcosta, cat_R4);
  histPlot->AddPlot(Dcosta, Dcostb, cat_R4);
  histPlot->AddPlot(DcosWa, DcosWb, cat_R4);
  histPlot->AddPlot(Dcosta, DcosWa, cat_R4);

  /////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////

  for(int igen = 0; igen < Ngen; igen++){
    if(igen%((std::max(Ngen,10))/10) == 0)
      g_Log << LogInfo << "Generating event " << igen << " of " << Ngen << LogEnd;

    // generate event
    LAB_Gen.ClearEvent();                             // clear the gen tree
  
    LAB_Gen.AnalyzeEvent();                           // generate a new event

    // analyze event three different ways
    TVector3 MET = LAB_Gen.GetInvisibleMomentum();    // Get the MET from gen tree
    MET.SetZ(0.);

    LAB_R1.ClearEvent();   
    LAB_R2.ClearEvent(); 
    LAB_R3.ClearEvent(); 
    LAB_R4.ClearEvent(); 
             
    INV_R1.SetLabFrameThreeVector(MET); 
    INV_R2.SetLabFrameThreeVector(MET); 
    INV_R3.SetLabFrameThreeVector(MET);
    INV_R4.SetLabFrameThreeVector(MET);

    La_R1.SetLabFrameFourVector(La_Gen.GetFourVector());
    Lb_R1.SetLabFrameFourVector(Lb_Gen.GetFourVector());
    La_R2.SetLabFrameFourVector(La_Gen.GetFourVector());
    Lb_R2.SetLabFrameFourVector(Lb_Gen.GetFourVector());
    La_R3.SetLabFrameFourVector(La_Gen.GetFourVector());
    Lb_R3.SetLabFrameFourVector(Lb_Gen.GetFourVector());
    La_R4.SetLabFrameFourVector(La_Gen.GetFourVector());
    Lb_R4.SetLabFrameFourVector(Lb_Gen.GetFourVector());

    std::vector<RFKey> B_R1_ID; // ID for tracking jets in tree
    B_R1_ID.push_back(B_R1.AddLabFrameFourVector(Ba_Gen.GetFourVector()));
    B_R1_ID.push_back(B_R1.AddLabFrameFourVector(Bb_Gen.GetFourVector()));
    B_R2.AddLabFrameFourVector(Ba_Gen.GetFourVector());
    B_R2.AddLabFrameFourVector(Bb_Gen.GetFourVector());
    B_R3.AddLabFrameFourVector(Ba_Gen.GetFourVector());
    B_R3.AddLabFrameFourVector(Bb_Gen.GetFourVector());
    B_R4.AddLabFrameFourVector(Ba_Gen.GetFourVector());
    B_R4.AddLabFrameFourVector(Bb_Gen.GetFourVector());
   
    LAB_R1.AnalyzeEvent(); // analyze the event
    LAB_R2.AnalyzeEvent();     
    LAB_R3.AnalyzeEvent(); 
    LAB_R4.AnalyzeEvent(); 

    //////////////////////////////////////
    // Observable Calculations
    //////////////////////////////////////

    double Mttgen   = TT_Gen.GetMass();
    double Eb_tagen = Ba_Gen.GetFourVector(Ta_Gen).E();
    double Eb_tbgen = Bb_Gen.GetFourVector(Tb_Gen).E();
    double El_Wagen = La_Gen.GetFourVector(Wa_Gen).E();
    double El_Wbgen = Lb_Gen.GetFourVector(Wb_Gen).E();
    double costtgen = TT_Gen.GetCosDecayAngle();
    double costagen = Ta_Gen.GetCosDecayAngle();
    double costbgen = Tb_Gen.GetCosDecayAngle();
    double cosWagen = Wa_Gen.GetCosDecayAngle();
    double cosWbgen = Wb_Gen.GetCosDecayAngle();

    Mtt = TT_R1.GetMass()/Mttgen;
    // Mta = Ta_R1.GetMass();
    // Mtb = Tb_R1.GetMass();
    // MWa = Wa_R1.GetMass();
    // MWb = Wb_R1.GetMass();
    Eb_ta = Ba_R1.GetFourVector(Ta_R1).E()/Eb_tagen;
    Eb_tb = Bb_R1.GetFourVector(Tb_R1).E()/Eb_tbgen;
    El_Wa = La_R1.GetFourVector(Wa_R1).E()/El_Wagen;
    El_Wb = Lb_R1.GetFourVector(Wb_R1).E()/El_Wbgen;
    costt = TT_R1.GetCosDecayAngle();
    costa = Ta_R1.GetCosDecayAngle();
    costb = Tb_R1.GetCosDecayAngle();
    cosWa = Wa_R1.GetCosDecayAngle();
    cosWb = Wb_R1.GetCosDecayAngle();
    Dcostt = asin(sqrt(1.-costt*costt)*costtgen-sqrt(1.-costtgen*costtgen)*costt);
    Dcosta = asin(sqrt(1.-costa*costa)*costagen-sqrt(1.-costagen*costagen)*costa);
    Dcostb = asin(sqrt(1.-costb*costb)*costbgen-sqrt(1.-costbgen*costbgen)*costb);
    DcosWa = asin(sqrt(1.-cosWa*cosWa)*cosWagen-sqrt(1.-cosWagen*cosWagen)*cosWa);
    DcosWb = asin(sqrt(1.-cosWb*cosWb)*cosWbgen-sqrt(1.-cosWbgen*cosWbgen)*cosWb);

    histPlot->Fill(cat_R1);

    Mtt = TT_R2.GetMass()/Mttgen;
    // Mta = Ta_R2.GetMass();
    // Mtb = Tb_R2.GetMass();
    // MWa = Wa_R2.GetMass();
    // MWb = Wb_R2.GetMass();
    Eb_ta = Ba_R2.GetFourVector(Ta_R2).E()/Eb_tagen;
    Eb_tb = Bb_R2.GetFourVector(Tb_R2).E()/Eb_tbgen;
    El_Wa = La_R2.GetFourVector(Wa_R2).E()/El_Wagen;
    El_Wb = Lb_R2.GetFourVector(Wb_R2).E()/El_Wbgen;
    costt = TT_R2.GetCosDecayAngle();
    costa = Ta_R2.GetCosDecayAngle();
    costb = Tb_R2.GetCosDecayAngle();
    cosWa = Wa_R2.GetCosDecayAngle();
    cosWb = Wb_R2.GetCosDecayAngle();
    Dcostt = asin(sqrt(1.-costt*costt)*costtgen-sqrt(1.-costtgen*costtgen)*costt);
    Dcosta = asin(sqrt(1.-costa*costa)*costagen-sqrt(1.-costagen*costagen)*costa);
    Dcostb = asin(sqrt(1.-costb*costb)*costbgen-sqrt(1.-costbgen*costbgen)*costb);
    DcosWa = asin(sqrt(1.-cosWa*cosWa)*cosWagen-sqrt(1.-cosWagen*cosWagen)*cosWa);
    DcosWb = asin(sqrt(1.-cosWb*cosWb)*cosWbgen-sqrt(1.-cosWbgen*cosWbgen)*cosWb);

    histPlot->Fill(cat_R2);

    Mtt = TT_R3.GetMass()/Mttgen;
    // Mta = Ta_R3.GetMass();
    // Mtb = Tb_R3.GetMass();
    // MWa = Wa_R3.GetMass();
    // MWb = Wb_R3.GetMass();
    Eb_ta = Ba_R3.GetFourVector(Ta_R3).E()/Eb_tagen;
    Eb_tb = Bb_R3.GetFourVector(Tb_R3).E()/Eb_tbgen;
    El_Wa = La_R3.GetFourVector(Wa_R3).E()/El_Wagen;
    El_Wb = Lb_R3.GetFourVector(Wb_R3).E()/El_Wbgen;
    costt = TT_R3.GetCosDecayAngle();
    costa = Ta_R3.GetCosDecayAngle();
    costb = Tb_R3.GetCosDecayAngle();
    cosWa = Wa_R3.GetCosDecayAngle();
    cosWb = Wb_R3.GetCosDecayAngle();
    Dcostt = asin(sqrt(1.-costt*costt)*costtgen-sqrt(1.-costtgen*costtgen)*costt);
    Dcosta = asin(sqrt(1.-costa*costa)*costagen-sqrt(1.-costagen*costagen)*costa);
    Dcostb = asin(sqrt(1.-costb*costb)*costbgen-sqrt(1.-costbgen*costbgen)*costb);
    DcosWa = asin(sqrt(1.-cosWa*cosWa)*cosWagen-sqrt(1.-cosWagen*cosWagen)*cosWa);
    DcosWb = asin(sqrt(1.-cosWb*cosWb)*cosWbgen-sqrt(1.-cosWbgen*cosWbgen)*cosWb);

    histPlot->Fill(cat_R3);

    Mtt = TT_R4.GetMass()/Mttgen;
    // Mta = Ta_R4.GetMass();
    // Mtb = Tb_R4.GetMass();
    // MWa = Wa_R4.GetMass();
    // MWb = Wb_R4.GetMass();
    Eb_ta = Ba_R4.GetFourVector(Ta_R4).E()/Eb_tagen;
    Eb_tb = Bb_R4.GetFourVector(Tb_R4).E()/Eb_tbgen;
    El_Wa = La_R4.GetFourVector(Wa_R4).E()/El_Wagen;
    El_Wb = Lb_R4.GetFourVector(Wb_R4).E()/El_Wbgen;
    costt = TT_R4.GetCosDecayAngle();
    costa = Ta_R4.GetCosDecayAngle();
    costb = Tb_R4.GetCosDecayAngle();
    cosWa = Wa_R4.GetCosDecayAngle();
    cosWb = Wb_R4.GetCosDecayAngle();
    Dcostt = asin(sqrt(1.-costt*costt)*costtgen-sqrt(1.-costtgen*costtgen)*costt);
    Dcosta = asin(sqrt(1.-costa*costa)*costagen-sqrt(1.-costagen*costagen)*costa);
    Dcostb = asin(sqrt(1.-costb*costb)*costbgen-sqrt(1.-costbgen*costbgen)*costb);
    DcosWa = asin(sqrt(1.-cosWa*cosWa)*cosWagen-sqrt(1.-cosWagen*cosWagen)*cosWa);
    DcosWb = asin(sqrt(1.-cosWb*cosWb)*cosWbgen-sqrt(1.-cosWbgen*cosWbgen)*cosWb);

    histPlot->Fill(cat_R4);

  }

  histPlot->Draw();

  LAB_Gen.PrintGeneratorEfficiency();

  TFile fout(output_name.c_str(),"RECREATE");
  fout.Close();
  histPlot->WriteOutput(output_name);
  histPlot->WriteHist(output_name);
  treePlot->WriteOutput(output_name);

  g_Log << LogInfo << "Finished" << LogEnd;
}
コード例 #19
0
ファイル: example_Wlnu.C プロジェクト: dguest/RestFrames
void example_Wlnu(const std::string& output_name = "output_Wlnu.root"){

  double mW = 80.385; // GeV, PDG 2016
  double wW = 2.085;
  
  // Number of events to generate
  int Ngen = 100000;

  /////////////////////////////////////////////////////////////////////////////////////////
  g_Log << LogInfo << "Initializing generator frames and tree..." << LogEnd;
  /////////////////////////////////////////////////////////////////////////////////////////
  LabGenFrame       LAB_Gen("LAB_Gen","LAB");
  ResonanceGenFrame W_Gen("W_Gen","W");
  VisibleGenFrame   L_Gen("L_Gen","#it{l}");
  InvisibleGenFrame NU_Gen("NU_Gen","#nu");

  //-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//
  
  LAB_Gen.SetChildFrame(W_Gen);
  W_Gen.AddChildFrame(L_Gen);
  W_Gen.AddChildFrame(NU_Gen);
 
  if(LAB_Gen.InitializeTree())
    g_Log << LogInfo << "...Successfully initialized generator tree" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing generator tree" << LogEnd;

  //-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//
                
  // set W pole mass and width
  W_Gen.SetMass(mW);                   W_Gen.SetWidth(wW);

  // set lepton pT and eta cuts
  L_Gen.SetPtCut(20.);                 L_Gen.SetEtaCut(2.5);  

  if(LAB_Gen.InitializeAnalysis())
    g_Log << LogInfo << "...Successfully initialized generator analysis" << std::endl << LogEnd;
  else
    g_Log << LogError << "...Failed initializing generator analysis" << LogEnd;
  /////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////////////////////////////
  g_Log << LogInfo << "Initializing reconstruction frames and trees..." << LogEnd;
  /////////////////////////////////////////////////////////////////////////////////////////
  LabRecoFrame       LAB("LAB","LAB");
  DecayRecoFrame     W("W","W");
  VisibleRecoFrame   L("L","#it{l}");
  InvisibleRecoFrame NU("NU","#nu");

  //-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//
  
  LAB.SetChildFrame(W);
  W.AddChildFrame(L);
  W.AddChildFrame(NU);

  if(LAB.InitializeTree())
    g_Log << LogInfo << "...Successfully initialized reconstruction trees" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing reconstruction trees" << LogEnd;

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

  // Now we add invisible jigsaws
  InvisibleGroup INV("INV","Neutrino Jigsaws");
  INV.AddFrame(NU);

  // Set the neutrino mass
  SetMassInvJigsaw MassJigsaw("MassJigsaw","m_{#nu} = 0");
  INV.AddJigsaw(MassJigsaw);

  // Set the neutrino rapidity
  SetRapidityInvJigsaw RapidityJigsaw("RapidityJigsaw","#eta_{#nu} = #eta_{#it{l}}");
  INV.AddJigsaw(RapidityJigsaw);
  RapidityJigsaw.AddVisibleFrame(L);

  if(LAB.InitializeAnalysis())
    g_Log << LogInfo << "...Successfully initialized analyses" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing analyses" << LogEnd;
  
  /////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////
  
  TreePlot* tree_plot = new TreePlot("TreePlot","TreePlot");
 
  // generator tree
  tree_plot->SetTree(LAB_Gen);
  tree_plot->Draw("GenTree", "Generator Tree", true);

  // reconstruction tree
  tree_plot->SetTree(LAB);
  tree_plot->Draw("RecoTree", "Reconstruction Tree");

  // Invisible Jigsaws tree 
  tree_plot->SetTree(INV);
  tree_plot->Draw("InvTree", "InvisibleJigsaws", true);

  //-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//
  
  // Declare observables for histogram booking
  HistPlot* hist_plot = new HistPlot("HistPlot","W #rightarrow #it{l} #nu");

  const HistPlotVar& MW     = hist_plot->GetNewVar("MW", "M_{W}", 30., 120., "[GeV]");
  const HistPlotVar& cosW   = hist_plot->GetNewVar("cosW","cos #phi_{W}", -1., 1.);
  const HistPlotVar& dphiW  = hist_plot->GetNewVar("dphiW", "#Delta #phi_{W}", 0., 2.*acos(-1.));
  const HistPlotVar& DcosW  = hist_plot->GetNewVar("DcosW","#phi_{W} - #phi_{W}^{true}", -0.5, 0.5);
  const HistPlotVar& DdphiW = hist_plot->GetNewVar("DdphiW","#Delta #phi_{W} - #Delta #phi_{W}^{true}", -0.5, 0.5);
  const HistPlotVar& pTWoMW = hist_plot->GetNewVar("pTW","p_{T}^{W} / m_{W}",0.,1.);

  const HistPlotCategory& cat_Gen  = hist_plot->GetNewCategory("Reco", "Generator");
  const HistPlotCategory& cat_Reco = hist_plot->GetNewCategory("Reco", "Reconstruction");
  
  hist_plot->AddPlot(DcosW,  cat_Reco);
  hist_plot->AddPlot(DdphiW, cat_Reco);
  hist_plot->AddPlot(MW,     cat_Gen+cat_Reco);
  hist_plot->AddPlot(DcosW,  MW, cat_Reco);
  hist_plot->AddPlot(DdphiW, MW, cat_Reco);
  hist_plot->AddPlot(MW,     pTWoMW, cat_Reco);
  hist_plot->AddPlot(DcosW,  pTWoMW, cat_Reco);
  hist_plot->AddPlot(DdphiW, pTWoMW, cat_Reco);

  for(int igen = 0; igen < Ngen; igen++){
    if(igen%((std::max(Ngen,10))/10) == 0)
      g_Log << LogInfo << "Generating event " << igen << " of " << Ngen << LogEnd;

    // generate event
    LAB_Gen.ClearEvent();                                // clear the gen tree

    pTWoMW = gRandom->Rndm();
    LAB_Gen.SetPToverM(pTWoMW);                          // give the W some Pt
    double PzW = mW*(2.*gRandom->Rndm()-1.);
    LAB_Gen.SetLongitudinalMomentum(PzW);                // give the W some Pz
     
    LAB_Gen.AnalyzeEvent();                              // generate a new event

    // analyze event
    LAB.ClearEvent();                               // clear the reco tree
      
    L.SetLabFrameFourVector(L_Gen.GetFourVector()); // Set lepton 4-vec
      
    TVector3 MET = LAB_Gen.GetInvisibleMomentum();       // Get the MET from gen tree
    MET.SetZ(0.);
    INV.SetLabFrameThreeVector(MET);                     // Set the MET in reco tree
      
    LAB.AnalyzeEvent();                             // analyze the event

    // generator-level observables
    MW    = W_Gen.GetMass();
    cosW  = cos(W_Gen.GetDeltaPhiDecayAngle());
    dphiW = LAB_Gen.GetDeltaPhiDecayPlanes(W_Gen);

    hist_plot->Fill(cat_Gen);

    // calculate observables
    MW    = W.GetMass();
    cosW  = cos(W.GetDeltaPhiDecayAngle());
    dphiW = LAB.GetDeltaPhiDecayPlanes(W);
      
    double cosWgen  = cos(W_Gen.GetDeltaPhiDecayAngle());
    double dphiWgen = LAB_Gen.GetDeltaPhiDecayPlanes(W_Gen);
    DcosW  = asin(sqrt(1.-cosW*cosW)*cosWgen-sqrt(1.-cosWgen*cosWgen)*cosW);
    DdphiW = asin(sin(dphiW-dphiWgen));

    hist_plot->Fill(cat_Reco);
  }
 
  hist_plot->Draw();

  TFile fout(output_name.c_str(),"RECREATE");
  fout.Close();
  hist_plot->WriteOutput(output_name);
  hist_plot->WriteHist(output_name);
  tree_plot->WriteOutput(output_name);

}
コード例 #20
0
ファイル: RJ_ttbar.C プロジェクト: rsmith54/RestFramesCMT
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;
    
  }
}
コード例 #21
0
void example_top_to_bWlnu(const std::string& output_name =
			 "output_top_to_bWlnu.root"){
 
  // set particle masses and widths
  double mtop = 173.21; // GeV, PDG 2016
  double wtop = 1.41;
  double mW   = 80.385;
  double wW   = 2.085;
  
  // Number of events to generate
  int Ngen = 100000;
  
  /////////////////////////////////////////////////////////////////////////////////////////
  g_Log << LogInfo << "Initializing generator frames and tree..." << LogEnd;
  /////////////////////////////////////////////////////////////////////////////////////////
  ppLabGenFrame         LAB_Gen("LAB_Gen","LAB");
  ResonanceGenFrame     T_Gen("T_Gen","t");
  ResonanceGenFrame     W_Gen("W_Gen","W");
  VisibleGenFrame       B_Gen("B_Gen","b");
  VisibleGenFrame       L_Gen("L_Gen","#it{l}");
  InvisibleGenFrame     NU_Gen("NU_Gen","#nu");

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

  LAB_Gen.SetChildFrame(T_Gen);
  T_Gen.AddChildFrame(B_Gen);
  T_Gen.AddChildFrame(W_Gen);
  W_Gen.AddChildFrame(L_Gen);
  W_Gen.AddChildFrame(NU_Gen);

  if(LAB_Gen.InitializeTree())
    g_Log << LogInfo << "...Successfully initialized generator tree" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing generator tree" << LogEnd;

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

  // set top mass and width
  T_Gen.SetMass(mtop);                 T_Gen.SetWidth(wtop);
  // set W mass and width
  W_Gen.SetMass(mW);                   W_Gen.SetWidth(wW);

  // set b-jet/lepton pT and eta cuts
  L_Gen.SetPtCut(20.);                 L_Gen.SetEtaCut(2.5);
  B_Gen.SetPtCut(20.);                 B_Gen.SetEtaCut(2.5);  

  if(LAB_Gen.InitializeAnalysis())
    g_Log << LogInfo << "...Successfully initialized generator analysis" << std::endl << LogEnd;
  else
    g_Log << LogError << "...Failed initializing generator analysis" << LogEnd;
  /////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////////////////////////////
  g_Log << LogInfo << "Initializing reconstruction frames and trees..." << LogEnd;
  /////////////////////////////////////////////////////////////////////////////////////////
  LabRecoFrame       LAB_Mt("LAB_Mt","LAB"); LabRecoFrame       LAB_MW("LAB_MW","LAB");
  DecayRecoFrame     T_Mt("T_Mt","t");       DecayRecoFrame     T_MW("T_MW","t");
  DecayRecoFrame     W_Mt("W_Mt","W");       DecayRecoFrame     W_MW("W_MW","W");
  VisibleRecoFrame   B_Mt("B_Mt","b");       VisibleRecoFrame   B_MW("B_MW","b");
  VisibleRecoFrame   L_Mt("L_Mt","#it{l}");  VisibleRecoFrame   L_MW("L_MW","#it{l}");
  InvisibleRecoFrame NU_Mt("NU_Mt","#nu");   InvisibleRecoFrame NU_MW("NU_MW","#nu");

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

  LAB_Mt.SetChildFrame(T_Mt);                LAB_MW.SetChildFrame(T_MW);
  T_Mt.AddChildFrame(B_Mt);                  T_MW.AddChildFrame(B_MW);
  T_Mt.AddChildFrame(W_Mt);                  T_MW.AddChildFrame(W_MW);
  W_Mt.AddChildFrame(L_Mt);                  W_MW.AddChildFrame(L_MW);
  W_Mt.AddChildFrame(NU_Mt);                 W_MW.AddChildFrame(NU_MW);

  if(LAB_Mt.InitializeTree() && LAB_MW.InitializeTree())
    g_Log << LogInfo << "...Successfully initialized reconstruction trees" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing reconstruction trees" << LogEnd;

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

  // Invisible Groups
  InvisibleGroup INV_Mt("INV_Mt","#nu Jigsaws");
  INV_Mt.AddFrame(NU_Mt);     
  InvisibleGroup INV_MW("INV_MW","#nu Jigsaws");
  INV_MW.AddFrame(NU_MW);

  // Set neutrino masses to zero
  SetMassInvJigsaw NuM_Mt("NuM_Mt","M_{#nu} = 0"); 
  INV_Mt.AddJigsaw(NuM_Mt);                        
  SetMassInvJigsaw NuM_MW("NuM_MW","M_{#nu} = 0");
  INV_MW.AddJigsaw(NuM_MW);

  // Set neutrino rapidity to that of visible particles
  SetRapidityInvJigsaw NuR_Mt("NuR_Mt","#eta_{#nu} = #eta_{b+#it{l}}");
  INV_Mt.AddJigsaw(NuR_Mt);
  NuR_Mt.AddVisibleFrame(L_Mt);
  NuR_Mt.AddVisibleFrame(B_Mt);
  SetRapidityInvJigsaw NuR_MW("NuR_MW","#eta_{#nu} = #eta_{#it{l}}");
  INV_MW.AddJigsaw(NuR_MW);
  NuR_MW.AddVisibleFrame(L_MW);

  if(LAB_Mt.InitializeAnalysis() && LAB_MW.InitializeAnalysis())
    g_Log << LogInfo << "...Successfully initialized analyses" << LogEnd;
  else
    g_Log << LogError << "...Failed initializing analyses" << LogEnd;

  /////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////

  TreePlot* treePlot = new TreePlot("TreePlot","TreePlot");
 
  treePlot->SetTree(LAB_Gen);
  treePlot->Draw("GenTree", "Generator Tree", true);

  treePlot->SetTree(LAB_Mt);
  treePlot->Draw("RecoTree", "Reconstruction Tree");

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

  // Declare observables for histogram booking
  HistPlot* histPlot   = new HistPlot("HistPlot","pp #rightarrow t #rightarrow W(#it{l} #nu) b");

  const HistPlotCategory& cat_Gen   = histPlot->GetNewCategory("Gen", "Generator");
  const HistPlotCategory& cat_minMt = histPlot->GetNewCategory("minMt", "min M_{t} Reco");
  const HistPlotCategory& cat_minMW = histPlot->GetNewCategory("minMW", "min M_{W} Reco");

  const HistPlotVar& Mt     = histPlot->GetNewVar("Mt", "M_{t}", 0., 280., "[GeV]");
  const HistPlotVar& MW     = histPlot->GetNewVar("MW", "M_{W}", 0., 150., "[GeV]");
  const HistPlotVar& pTtoMt = histPlot->GetNewVar("pTtoMt","p_{T}^{top} / m_{top}", 0., 1.);
  const HistPlotVar& cosT   = histPlot->GetNewVar("cosT","cos #theta_{t}", -1., 1.);
  const HistPlotVar& cosW   = histPlot->GetNewVar("cosW","cos #theta_{W}", -1., 1.);
  const HistPlotVar& dphiT  = histPlot->GetNewVar("dphiT", "#Delta #phi_{t}", 0., 2.*acos(-1.));
  const HistPlotVar& dphiW  = histPlot->GetNewVar("dphiW", "#Delta #phi_{W}", 0., 2.*acos(-1.));
  const HistPlotVar& DcosT  = histPlot->GetNewVar("DcosT","#theta_{t} - #theta_{t}^{gen}", -1., 1.);
  const HistPlotVar& DcosW  = histPlot->GetNewVar("DcosW","#theta_{W} - #theta_{W}^{gen}", -1., 1.);
  const HistPlotVar& DdphiT = histPlot->GetNewVar("DdphiT","#Delta #phi_{t} - #Delta #phi_{t}^{gen}", -1., 1.);
  const HistPlotVar& DdphiW = histPlot->GetNewVar("DdphiW","#Delta #phi_{W} - #Delta #phi_{W}^{gen}", -1., 1.);

  histPlot->AddPlot(DcosT,  cat_minMt+cat_minMW);
  histPlot->AddPlot(DcosW,  cat_minMt+cat_minMW);
  histPlot->AddPlot(DdphiT, cat_minMt+cat_minMW);
  histPlot->AddPlot(DdphiW, cat_minMt+cat_minMW);
  histPlot->AddPlot(MW,     cat_minMt+cat_minMW+cat_Gen);
  histPlot->AddPlot(Mt,     cat_minMt+cat_minMW+cat_Gen);
  histPlot->AddPlot(Mt, MW, cat_minMt+cat_minMW+cat_Gen);
  histPlot->AddPlot(Mt, pTtoMt, cat_minMt+cat_minMW);
  histPlot->AddPlot(MW, pTtoMt, cat_minMt+cat_minMW);
  histPlot->AddPlot(DcosW,  MW, cat_minMt+cat_minMW);
  histPlot->AddPlot(DcosT,  Mt, cat_minMt+cat_minMW);
  histPlot->AddPlot(Mt, pTtoMt, cat_minMt+cat_minMW);
  histPlot->AddPlot(MW, pTtoMt, cat_minMt+cat_minMW);
  histPlot->AddPlot(DcosT, DcosW, cat_minMt+cat_minMW);
 

  /////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////

  for(int igen = 0; igen < Ngen; igen++){
    if(igen%((std::max(Ngen,10))/10) == 0)
      g_Log << LogInfo << "Generating event " << igen << " of " << Ngen << LogEnd;

    // generate event
    LAB_Gen.ClearEvent();                            // clear the gen tree

    pTtoMt = gRandom->Rndm();                        // give the Top some Pt
    LAB_Gen.SetPToverM(pTtoMt); 
  
    LAB_Gen.AnalyzeEvent();                          // generate a new event

    TVector3 MET = LAB_Gen.GetInvisibleMomentum();   // Get the MET from gen tree
    MET.SetZ(0.);
    
    // analyze event one way
    LAB_Mt.ClearEvent();                               // clear the reco tree
    
    L_Mt.SetLabFrameFourVector(L_Gen.GetFourVector()); // Set lepton 4-vec
    B_Mt.SetLabFrameFourVector(B_Gen.GetFourVector()); // Set b-jet 4-vec
    INV_Mt.SetLabFrameThreeVector(MET);                // Set the MET in reco tree
    
    LAB_Mt.AnalyzeEvent();                             //analyze the event

    // analyze event another way
    LAB_MW.ClearEvent();                               // clear the reco tree
    
    L_MW.SetLabFrameFourVector(L_Gen.GetFourVector()); // Set lepton 4-vec
    B_MW.SetLabFrameFourVector(B_Gen.GetFourVector()); // Set b-jet 4-vec
    INV_MW.SetLabFrameThreeVector(MET);                // Set the MET in reco tree
    
    LAB_MW.AnalyzeEvent();                             //analyze the event

    // Generator-level observables
    double MTgen = T_Gen.GetMass();
    double cosTgen  = T_Gen.GetCosDecayAngle();
    double dphiTgen = LAB_Gen.GetDeltaPhiDecayPlanes(T_Gen);
    double MWgen = W_Gen.GetMass();
    double cosWgen  = W_Gen.GetCosDecayAngle();
    double dphiWgen = T_Gen.GetDeltaPhiDecayPlanes(W_Gen);

    Mt = MTgen;
    MW = MWgen;
    histPlot->Fill(cat_Gen);

    // minMt observables
    Mt     = T_Mt.GetMass();
    cosT   = T_Mt.GetCosDecayAngle();
    dphiT  = LAB_Mt.GetDeltaPhiDecayPlanes(T_Mt);
    MW     = W_Mt.GetMass();
    cosW   = W_Mt.GetCosDecayAngle();
    dphiW  = T_Mt.GetDeltaPhiDecayPlanes(W_Mt);
    DcosT  = asin(sqrt(1.-cosT*cosT)*cosTgen-sqrt(1.-cosTgen*cosTgen)*cosT);
    DdphiT = asin(sin(dphiT-dphiTgen));
    DcosW  = asin(sqrt(1.-cosW*cosW)*cosWgen-sqrt(1.-cosWgen*cosWgen)*cosW);
    DdphiW = asin(sin(dphiW-dphiWgen));

    histPlot->Fill(cat_minMt);

    // minMW observables
    Mt     = T_MW.GetMass();
    cosT   = T_MW.GetCosDecayAngle();
    dphiT  = LAB_MW.GetDeltaPhiDecayPlanes(T_MW);
    MW     = W_MW.GetMass();
    cosW   = W_MW.GetCosDecayAngle();
    dphiW  = T_MW.GetDeltaPhiDecayPlanes(W_MW);
    DcosT  = asin(sqrt(1.-cosT*cosT)*cosTgen-sqrt(1.-cosTgen*cosTgen)*cosT);
    DdphiT = asin(sin(dphiT-dphiTgen));
    DcosW  = asin(sqrt(1.-cosW*cosW)*cosWgen-sqrt(1.-cosWgen*cosWgen)*cosW);
    DdphiW = asin(sin(dphiW-dphiWgen));

    histPlot->Fill(cat_minMW);
  }

  histPlot->Draw();

  LAB_Gen.PrintGeneratorEfficiency();
  
  TFile fout(output_name.c_str(),"RECREATE");
  fout.Close();
  histPlot->WriteOutput(output_name);
  histPlot->WriteHist(output_name);
  treePlot->WriteOutput(output_name);

  g_Log << LogInfo << "Finished" << LogEnd;

}