TVector3 CalculateScatVec(TVector3 Incoming ,TVector3 ScatLab){
  
      //What is quicker passing in same value each time or defining value here each time?
      
      zprime = income.Unit();
      yprime = zlab.Cross(-income);
      yprime = yprime.Unit();
      xprime = yprime.Cross(zprime);    
      xprime = xprime.Unit();
  
  
      RotM[0][0] = xlab.Dot(xprime) ;
      RotM[0][1] = xlab.Dot(yprime);
      RotM[0][2] = xlab.Dot(zprime);
      RotM[1][0] = ylab.Dot(xprime);
      RotM[1][1] = ylab.Dot(yprime) ;
      RotM[1][2] = ylab.Dot(zprime) ;
      RotM[2][0] = zlab.Dot(xprime);
      RotM[2][1] = zlab.Dot(yprime);
      RotM[2][2] = zlab.Dot(zprime);
      
      TVector3 ScatNuc;
      
      ScatNuc(0) = (RotM[0][0]*ScatLab(0) +  RotM[1][0]*ScatLab(1) + RotM[2][0]*ScatLab(2) );
      ScatNuc(1) = (RotM[0][1]*ScatLab(0) +  RotM[1][1]*ScatLab(1) + RotM[2][1]*ScatLab(2) );
      ScatNuc(2) = (RotM[0][2]*ScatLab(0) +  RotM[1][2]*ScatLab(1) + RotM[2][2]*ScatLab(2) );
      
      //std::cout << zprime(0) << " " << zprime(1) << " " << zprime(2) <<std::endl;
      return ScatNuc;
  
}
Esempio n. 2
0
Double_t KVMaterial::GetEffectiveAreaDensity(TVector3& norm,
      TVector3& direction)
{
   // Calculate effective area density of absorber (in g/cm**2) as 'seen' in 'direction', taking into
   // account the arbitrary orientation of the 'norm' normal to the material's surface

   TVector3 n = norm.Unit();
   TVector3 d = direction.Unit();
   //absolute value of scalar product, in case direction is opposite to normal
   Double_t prod = TMath::Abs(n * d);
   return GetAreaDensity() / TMath::Max(prod, 1.e-03);
}
Esempio n. 3
0
int get_tl_efield(TVector3 &p,TVector3 &efield)
{
  //function returns the electric field between two infinite parallel wires
  //efield normalized the jackson way with 1/cm units
  //wires extend in z-direction and are can be offset 
  double e_amp = 1. / 2.0 / M_PI * sqrt(tl_data.C / (EPS0 / M2CM));

  //calculate effective wire position for efield
  TVector3 x1(tl_data.x1, 0, 0);	//real position of first wire in cm
  TVector3 x2(tl_data.x2, 0, 0);	//real position of second wire in cm
  TVector3 l = x1 - x2;
  l *= 1./2;
  double a = sqrt(l.Mag2() - pow(tl_data.rI, 2));	//effective wire half separation in cm
  TVector3 a1 = x1 - l + a*l.Unit();	//effective position of first wire in cm
  TVector3 a2 = x1 - l - a*l.Unit();	//effective position of second wire in cm
 
  //vector from point to wires
  p.SetZ(0);
  TVector3 r1 = p + a1;
  TVector3 r2 = p + a2;
   
  //check for hitting wires 
  int status = 0;
  if ( ( (x1-r1).Mag() < tl_data.rI ) || ( (x2-r2).Mag() < tl_data.rI ) ) {
    cout << "Problem!!! Electron hit a wire! Radius " << p.Mag() << endl;
    status = 1;
  }
  //efield = e_amp * (r1 * 1/r1.Mag2() - r2 * 1/r2.Mag2());
  efield.SetX( e_amp * ( r1.X() / r1.Mag2() - r2.X() / r2.Mag2() ) );
  efield.SetY( e_amp * ( r1.Y() / r1.Mag2() - r2.Y() / r2.Mag2() ) );
  efield.SetZ( 0 );                //only true for TE or TEM modes
  return status;
}
Esempio n. 4
0
double CosThetaStar(TLorentzVector p1, TLorentzVector p2){
	TLorentzVector p = p1 + p2;
	TVector3 theBoost = p.BoostVector();
	TVector3 bostDir;
	if ( theBoost.Mag() != 0 ) bostDir = theBoost.Unit(); // / theBoost.Mag());
	else return -1;
	p1.Boost(-theBoost);
	if (p1.Vect().Mag()!=0) return p1.Vect().Dot(bostDir) / p1.Vect().Mag();
	else return -1;	
}
TVector3 EUTelState::getIncidenceUnitMomentumVectorInLocalFrame(){
	TVector3 pVec =	computeCartesianMomentum();
	TVector3 pVecUnit = pVec.Unit();//Make the vector unit.
    streamlog_out(DEBUG2) << "Momentum in global coordinates  Px,Py,Pz= " << pVec[0]<<","<<pVec[1]<<","<<pVec[2] << std::endl;
	double globalVec[] = { pVecUnit[0],pVecUnit[1],pVecUnit[2] };
	double localVec[3];
	geo::gGeometry().master2LocalVec( getLocation() ,globalVec, localVec );
	TVector3 pVecUnitLocal;
	pVecUnitLocal[0] = localVec[0]; 	pVecUnitLocal[1] = localVec[1]; 	pVecUnitLocal[2] = localVec[2]; 
  streamlog_out(DEBUG2) << "Momentum in local coordinates  Px,Py,Pz= " << pVecUnitLocal[0]<<","<<pVecUnitLocal[1]<<","<<pVecUnitLocal[2]<< std::endl;
	return pVecUnitLocal;
}
Esempio n. 6
0
//________________________________________________________
void KVParticle::SetMomentum(Double_t T, TVector3 dir)
{
   //set momentum with kinetic energy t and unit direction vector d
   //(d is normalised first in case it is not a unit vector)

   Double_t p = (T + M()) * (T + M()) - M2();
   TVector3 pdir;
   TVector3 unit_dir = dir.Unit();
   if (p > 0.) {
      p = (TMath::Sqrt(p));
      pdir = p * unit_dir;
   }
   SetMomentum(pdir);
};
Esempio n. 7
0
void figureOutpiover2(int ptBin, double ptCutLo, double ptCutHi, int massBin, double mCutLo, double mCutHi, int etaBin, double etaCutLo, double etaCutHi) {

    //OPTIONS AND CUTS------------
    bool useBlueBeam = false;
    bool useYellowBeam = true;
    double PI = 3.14159265359;


    if (useBlueBeam && useYellowBeam) {
        cout << "using both beams" << endl;
    }
    if (useBlueBeam && !useYellowBeam) {
        cout << "using blue beam" << endl;
    }
    if (!useBlueBeam && useYellowBeam) {
        cout << "using yellow beam" << endl;
    }


    //PION PAIR CUTS:
    /*
     double ptCutLo = 4;
     double ptCutHi = 10;
     double mCutLo = .4;
     double mCutHi = 1;
     double etaCutLo = -1.4;
     double etaCutHi = 1.4;
     //*/
    //double phiCutLo = -.5;
    //double phiCutHi = .5;

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


    //LOAD LIBS
    cout << "\n";
    gROOT->Macro("StRoot/LoadLibs.C");
    gSystem->Load("pionPair");
    cout << " loading of pionPair library done" << endl;


    //SET UP INPUT FILE
    //TFile* infile = new TFile("/star/u/klandry/ucladisk/2012IFF/all2012dataAll.root");
    //TFile* infile = new TFile("/star/u/klandry/ucladisk/2012IFF/schedOutputWithinRad/allWithRadcut.root");
    TFile* infile = new TFile("/star/u/klandry/ucladisk/2012IFF/schedOutAllDataTry1/allDataTry1.root");





    //SET UP TREE TO RECEIVE INPUT
    pionPair* pair1 = new pionPair();
    TTree* pairTree = infile->Get("pionPairTree");
    pairTree->SetBranchAddress("pionPair", &pair1);


    //SET UP HISTOGRAMS

    //event variable histograms
    TH1D* hInvarM    = new TH1D("invarM","invarM",80,0,2);
    TH1D* hEtaTot	   = new TH1D("etaTot","etaTot",60,-1.5,1.5);
    TH1D* hPhiR      = new TH1D("hPhiR","hPhiR",60,-4,4);
    TH1D* hPhiS      = new TH1D("hPhiS","hPhiS",60,-4,4);
    TH1D* hPhiSR     = new TH1D("hPhiSR","hPhiSR",60,-4,4);
    TH1D* hTheta     = new TH1D("hTheta","hTheta",30,-0.85,4);
    TH1D* hCosTheta  = new TH1D("hCosTheta","hCosTheta",80,-1,1);
    TH1D* hZ         = new TH1D("hZ","hZ",80,0,1);
    TH1D* hPtot      = new TH1D("hPtot","hPtot",80,0,20);
    TH1D* hPtTOT     = new TH1D("hPt","hPt",80,0,15);

    //histos for asym analysis
    double histMin = -PI;
    double histMax =  PI;
    const int binNumber = 16;

    TH1D * hNumberUp   = new TH1D("hNumberUp","hNumberUp",binNumber,histMin,histMax);
    TH1D * hNumberDown = new TH1D("hNumberDown","hNumberDown",binNumber,histMin,histMax);

    TH1D * hDiff  = new TH1D("hNumberSum","hNumberSum",binNumber,histMin,histMax);
    TH1D * hAut = new TH1D("Aut","Aut",binNumber,histMin,histMax);


    //BEAM POLARIZATION

    ifstream polFile;
    polFile.open("/star/u/klandry/ucladisk/2012IFF/BeamPolarization2012.txt");


    map<int, double> polarizationOfFill_Y;
    map<int, double> polErrOfFill_Y;

    map<int, double> polarizationOfFill_B;
    map<int, double> polErrOfFill_B;



    int    fill;
    int    beamE;
    int    startT;
    string plusminus;

    double pAvrgBlue;
    double pErrAvrgBlue;

    double pInitialBlue;
    double pErrInitialBlue;
    double dPdTBlue;
    double dPdTErrBlue;

    double pAvrgYellow;
    double pErrAvrgYellow;

    double pInitialYellow;
    double pErrInitialYellow;
    double dPdTYellow;
    double dPdTErrYellow;

    string header;

    for (int i=0; i<19; i++) {
        polFile >> header;
    }

    while (!polFile.eof())
    {

        polFile >> fill;
        polFile >> beamE;
        polFile >> startT;

        polFile >> pAvrgBlue;
        polFile >> plusminus;
        polFile >> pErrAvrgBlue;

        polFile >> pInitialBlue;
        polFile >> plusminus;
        polFile >> pErrInitialBlue;

        polFile >> dPdTBlue;
        polFile >> plusminus;
        polFile >> dPdTErrBlue;

        polFile >> pAvrgYellow;
        polFile >> plusminus;
        polFile >> pErrAvrgYellow;

        polFile >> pInitialYellow;
        polFile >> plusminus;
        polFile >> pErrInitialYellow;

        polFile >> dPdTYellow;
        polFile >> plusminus;
        polFile >> dPdTErrYellow;


        polarizationOfFill_B[fill] = pAvrgBlue/100.;
        polErrOfFill_B[fill] = pErrAvrgBlue/100.;

        polarizationOfFill_Y[fill] = pAvrgYellow/100.;
        polErrOfFill_Y[fill] = pErrAvrgYellow/100.;



    }

    double avgPolOfBinUp[binNumber];
    double polOfBinSumUp[binNumber];

    double avgPerrorOfBinUp[binNumber];
    double pErrorOfBinUp[binNumber];

    double avgPolOfBinDown[binNumber];
    double polOfBinSumDown[binNumber];

    double avgPerrorOfBinDown[binNumber];
    double pErrorOfBinDown[binNumber];

    for (int i=0; i<binNumber; i++)
    {
        avgPolOfBinUp[i] = 0;
        polOfBinSumUp[i] = 0;

        avgPerrorOfBinUp[i] = 0;
        pErrorOfBinUp[i] = 0;

        avgPolOfBinDown[i] = 0;
        polOfBinSumDown[i] = 0;

        avgPerrorOfBinDown[i] = 0;
        pErrorOfBinDown[i] = 0;

    }


    //   ======================================================================
    //============================================================================
    //START ANALYSIS==============================================================
    //============================================================================
    //   ======================================================================

    cout << pairTree->GetEntries() << endl;

    cout << "\n";
    cout << "<----STARTING ANALYSIS---->" << endl;
    cout << "\n";


    double blueFillNo;
    double yellowFillNo;

    int bin;

    TLorentzVector sum;
    TLorentzVector sumY;
    TLorentzVector sumB;

    TRandom3 r;


    int totalPairsFinal = 0;


    for (int iPair = 0; iPair < pairTree->GetEntries(); iPair++)
    {
        if (iPair%10000 == 0) {
            cout << "processing pair number " << iPair << endl;
        }
        //cout << "processing pair number " << iPair << endl;


        //if (iPair == 80000){break;}

        pairTree->GetEntry(iPair);




        if (pair1->withinRadius(0.05, 0.3))
        {

            bool triggerFired = false;
            bool fromKaon = false;

            StTriggerId trigId = pair1->triggerIds();


            if (trigId.isTrigger(370601) || trigId.isTrigger(370611) || trigId.isTrigger(370621))
            {
                triggerFired = true;
            }

            if (trigId.isTrigger(370501) || trigId.isTrigger(370511) || trigId.isTrigger(370522) || trigId.isTrigger(370531))
            {
                triggerFired = true;
            }


            if (pair1->invarientMass() > .4921 && pair1->invarientMass() < .4990)
            {
                fromKaon = true;
            }



            if (triggerFired)
            {


                blueFillNo   = pair1->runInfo().beamFillNumber(1); //1 = blue beam
                yellowFillNo = pair1->runInfo().beamFillNumber(0); //0 = yellow beam

                //cout << blueFillNo << "  " << yellowFillNo << endl;


                if (polarizationOfFill_B[blueFillNo] == 0 || polarizationOfFill_Y[yellowFillNo] == 0)
                {
                    continue;
                }


                hInvarM->Fill(pair1->invarientMass());

                TVector3 spinVec;


                sum = pair1->piPlusLV() + pair1->piMinusLV();
                sumB = sum; //blue beam.


                //yellow beam must rotate around y axis by pi so the eta cut can be the same for both beams.
                sumY = sum;
                sumY.RotateY(PI);


                double randomSpin = r.Uniform(0, 1);

                int randomSpinBit;

                if (randomSpin >=0 && randomSpin <0.25)  {
                    randomSpinBit = 5;
                }
                if (randomSpin >=0.25 && randomSpin <0.5) {
                    randomSpinBit = 6;
                }
                if (randomSpin >=0.5 && randomSpin <0.75) {
                    randomSpinBit = 9;
                }
                if (randomSpin >=0.75 && randomSpin <1.0) {
                    randomSpinBit = 10;
                }


                //CHECK CUTS
                if (sumB.Pt() > ptCutLo && sumB.Pt() < ptCutHi && sumB.M() > mCutLo && sumB.M() < mCutHi && sumB.Eta() > etaCutLo && sumB.Eta() < etaCutHi && useBlueBeam == true)
                {

                    //BLUE BEAM SPIN UP: spin bin 9 and 10
                    if (pair1->spinBit() == 9 || pair1->spinBit() == 10)
                    {
                        bin = hNumberUp->FindBin(pair1->phiSR('b'));
                        //hNumberUp->Fill(pair1->phiSR('b'));



                        polOfBinSumUp[bin] += polarizationOfFill_B[blueFillNo];
                        pErrorOfBinUp[bin] += polErrOfFill_B[blueFillNo];
                    }

                    //BLUE BEAM SPIN DOWN: spin bin 5 and 6
                    if (pair1->spinBit() == 5 || pair1->spinBit() == 6)
                    {
                        bin = hNumberDown->FindBin(pair1->phiSR('b'));
                        hNumberDown->Fill(pair1->phiSR('b'));

                        polOfBinSumDown[bin] += polarizationOfFill_B[blueFillNo];
                        pErrorOfBinDown[bin] += polErrOfFill_B[blueFillNo];
                    }

                }//end blue cuts

                TVector3 Pa;
                Pa.SetXYZ(0, 0, 1);   //blue is unpolarized beam

                TVector3 Pb;
                Pb.SetXYZ(0, 0, -1);  //yellow is polarized beam


                if (sumY.Pt()>ptCutLo && sumY.Pt() < ptCutHi && sumY.M() > mCutLo && sumY.M() < mCutHi && sumY.Eta() > etaCutLo && sumY.Eta() < etaCutHi && useYellowBeam == true)
                {

                    //YELLOW BEAM SPIN UP: spin bin 6 and 10
                    //if (pair1->spinBit() == 6 || pair1->spinBit() == 10)
                    if (randomSpinBit == 6 || randomSpinBit == 10)

                    {

                        totalPairsFinal++;


                        spinVec.SetXYZ(0, 1, 0);

                        TVector3 Ph = pair1->piPlusLV().Vect() + pair1->piMinusLV().Vect();
                        TVector3 Rh  = pair1->piPlusLV().Vect() - pair1->piMinusLV().Vect();


                        double cosPhi_S = -Pb.Unit().Cross(Ph).Unit() * Pb.Unit().Cross(spinVec).Unit();

                        double cosPhi_R = Ph.Unit().Cross(Pb).Unit() * Ph.Unit().Cross(Rh).Unit();

                        double sinPhi_S = Ph.Cross(spinVec) * Pb.Unit() / (Pb.Unit().Cross(Ph).Mag() * Pb.Unit().Cross(spinVec).Mag());

                        double sinPhi_R = Pb.Cross(Rh) * Ph.Unit() / (Ph.Unit().Cross(Pb).Mag() * Ph.Unit().Cross(Rh).Mag());



                        double sinPhi_S_R = sinPhi_S*cosPhi_R - cosPhi_S*sinPhi_R;

                        double cosPhi_S_R = cosPhi_S*cosPhi_R + sinPhi_S*sinPhi_R;



                        double phi_S_R;

                        if (cosPhi_S_R >= 0)
                        {
                            phi_S_R = asin(sinPhi_S_R);
                        }
                        else if (cosPhi_S_R < 0)
                        {

                            if (sinPhi_S_R >= 0)
                            {
                                phi_S_R = TMath::Pi() - asin(sinPhi_S_R);
                            }
                            if (sinPhi_S_R < 0)
                            {
                                phi_S_R = -TMath::Pi() - asin(sinPhi_S_R);
                            }

                        }

                        //cout <<  "phisr = " << phi_S_R << endl;



                        bin = hNumberUp->FindBin(phi_S_R);
                        hNumberUp->Fill(phi_S_R);

                        polOfBinSumUp[bin] += polarizationOfFill_Y[yellowFillNo];
                        pErrorOfBinUp[bin] += polErrOfFill_Y[yellowFillNo];
                    }
                    //YELLOW BEAM SPIN DOWN: spin bit 5 and 9
                    if (randomSpinBit == 5 || randomSpinBit == 9)
                    {

                        totalPairsFinal++;

                        spinVec.SetXYZ(0, -1, 0);

                        TVector3 Ph = pair1->piPlusLV().Vect() + pair1->piMinusLV().Vect();
                        TVector3 Rh  = pair1->piPlusLV().Vect() - pair1->piMinusLV().Vect();


                        double cosPhi_S = -Pb.Unit().Cross(Ph).Unit() * Pb.Unit().Cross(spinVec).Unit();

                        double cosPhi_R = Ph.Unit().Cross(Pa).Unit() * Ph.Unit().Cross(Rh).Unit();

                        double sinPhi_S = Ph.Cross(spinVec) * Pb.Unit() / (Pb.Unit().Cross(Ph).Mag() * Pb.Unit().Cross(spinVec).Mag());

                        double sinPhi_R = Pa.Cross(Rh) * Ph.Unit() / (Ph.Unit().Cross(Pa).Mag() * Ph.Unit().Cross(Rh).Mag());



                        double sinPhi_S_R = sinPhi_S*cosPhi_R - cosPhi_S*sinPhi_R;

                        double cosPhi_S_R = cosPhi_S*cosPhi_R + sinPhi_S*sinPhi_R;



                        double phi_S_R;

                        if (cosPhi_S_R >= 0)
                        {
                            phi_S_R = asin(sinPhi_S_R);
                        }
                        else if (cosPhi_S_R < 0)
                        {

                            if (sinPhi_S_R >= 0)
                            {
                                phi_S_R = TMath::Pi() - asin(sinPhi_S_R);
                            }
                            if (sinPhi_S_R < 0)
                            {
                                phi_S_R = -TMath::Pi() - asin(sinPhi_S_R);
                            }

                        }

                        //	cout <<  "phisr = " << phi_S_R << endl;


                        bin = hNumberDown->FindBin(phi_S_R);
                        hNumberDown->Fill(phi_S_R);

                        polOfBinSumDown[bin] += polarizationOfFill_Y[yellowFillNo];
                        pErrorOfBinDown[bin] += polErrOfFill_Y[yellowFillNo];
                    }
                }//end yellow cuts





            }//end triger check
        }//end radius check
    }//end pairTree loop


    //CALCULATE ASYMMETRY BIN BY BIN
    cout << "\n";
    cout << "<----CALCULATING ASYMMETRY---->" << endl;
    cout << "\n";
    //*
    for (int ibin=1; ibin<=binNumber; ibin++)
    {

        if (ibin <= binNumber*0.5)
        {
            double nUp   = hNumberUp->GetBinContent(ibin);
            double nUpPi = hNumberUp->GetBinContent(ibin+binNumber*0.5);

            double nDown   = hNumberDown->GetBinContent(ibin);
            double nDownPi = hNumberDown->GetBinContent(ibin+binNumber*0.5);


            cout << nUp << "  " << nUpPi << "  " << nDown << "  " << nDownPi << "  "  << endl;

            int binIndexPi = ibin+binNumber*0.5;

            double avgPolA = (polOfBinSumUp[ibin]+polOfBinSumDown[binIndexPi])/(nUp+nDownPi);
            double avgPolB = (polOfBinSumUp[binIndexPi]+polOfBinSumDown[ibin])/(nUpPi+nDown);

            double realAvgPol = (polOfBinSumUp[ibin]+polOfBinSumDown[binIndexPi]+polOfBinSumUp[binIndexPi]+polOfBinSumDown[ibin])/(nUp+nUpPi+nDown+nDownPi);

        }
        else
        {
            double nUp   = hNumberUp->GetBinContent(ibin);
            double nUpPi = hNumberUp->GetBinContent(ibin-binNumber*0.5);

            double nDown   = hNumberDown->GetBinContent(ibin);
            double nDownPi = hNumberDown->GetBinContent(ibin-binNumber*0.5);

            int binIndexPi = ibin-binNumber*0.5;

            cout << nUp << "  " << nUpPi << "  " << nDown << "  " << nDownPi << "  "  << endl;


            double avgPolA = (polOfBinSumUp[ibin]+polOfBinSumDown[binIndexPi])/(nUp+nDownPi);
            double avgPolB = (polOfBinSumUp[binIndexPi]+polOfBinSumDown[ibin])/(nUpPi+nDown);

            double realAvgPol = (polOfBinSumUp[ibin]+polOfBinSumDown[binIndexPi]+polOfBinSumUp[binIndexPi]+polOfBinSumDown[ibin])/(nUp+nUpPi+nDown+nDownPi);

            double realAvgPolE = (pErrorOfBinUp[ibin]+pErrorOfBinDown[binIndexPi]+pErrorOfBinUp[binIndexPi]+pErrorOfBinDown[ibin])/(nUp+nUpPi+nDown+nDownPi);

        }


        cout << avgPolA << "   " << avgPolB << endl;




        hDiff->SetBinContent(ibin, sqrt(nUp*nDownPi) - sqrt(nDown*nUpPi));

        //hAut->SetBinContent(ibin, (1/avgPolA * sqrt(nUp*nDownPi) - 1/avgPolB * sqrt(nDown*nUpPi)) / (sqrt(nUp*nDownPi) + sqrt(nDown*nUpPi))    );


        hAut->SetBinContent(ibin, 1/realAvgPol * (sqrt(nUp*nDownPi) - sqrt(nDown*nUpPi)) / (sqrt(nUp*nDownPi) + sqrt(nDown*nUpPi))    );




        //error
        if (realAvgPol*pow(sqrt(nUp*nDownPi)+sqrt(nDown*nUpPi), 2) != 0)
        {

            double a = sqrt(nUp*nDownPi);
            double b = sqrt(nUpPi*nDown);


            double firstTerm = realAvgPol**2 * (nUpPi*nDown*(nUp+nDownPi) + nDownPi*nUp*(nUpPi+nDown));

            //double secondTerm = ((nUp*nDownPi)**2 +(nUpPi*nDown)**2 - 2*nUp*nDown*nUpPi*nDownPi)*realAvgPolE**2;

            double secondTerm = 0;


            double binError = 1/realAvgPol**2 * 1/(a+b)**2 * sqrt(firstTerm + secondTerm);


        }
        else
        {
            double binError = 0.01;
            cout << "bin " << ibin << " Has problem with error" << endl;
        }

        hAut->SetBinError(ibin, binError);

    }//end Asym calc

    //*/

    //DRAW HISTOGRAMS

    hInvarM->Draw();

    TCanvas* cNup = new TCanvas();
    hNumberUp->Draw();

    TCanvas* cNdown = new TCanvas();
    hNumberDown->Draw();

    TCanvas* cAut = new TCanvas();
    cAut->SetName("cAut");

    TF1* fitFunc = new TF1("fitFunc","[0]*sin(x)+[1]",-PI,PI);
    //hAut->Fit("fitFunc","R");
    hAut->Draw();

    hAut->GetXaxis()->SetTitle("#phi_{S} - #phi_{R}");

    char title[150];
    sprintf(title, "%.1f < P_{T}^{#pi^{+}#pi^{-}} < %.1f  %.1f < M_{inv}^{#pi^{+}#pi^{-}} < %.1f  %.1f < #eta^{#pi^{+}#pi^{-}} < %.1f", ptCutLo, ptCutHi, mCutLo, mCutHi, etaCutLo, etaCutHi);

    hAut->SetTitle(title);





    //SAVE CANVAS


    stringstream pt;
    stringstream eta;
    stringstream mass;

    string part1 = "_ptBin";
    string part2 = "_massBin";
    string part3 = "_etaBin";

    string ptBinStr;
    string etaBinStr;
    string massBinStr;


    pt << ptBin;

    eta << etaBin;

    mass << massBin;

    if (ptBin == 9) {
        ptBinStr = "All";
    }
    else {
        ptBinStr = pt.str();
    }

    if (massBin == 9) {
        massBinStr = "All";
    }
    else {
        massBinStr = mass.str();
    }

    if (etaBin == 9) {
        etaBinStr = "All";
    }
    else {
        etaBinStr = eta.str();
    }

    cout << "total pairs " << totalPairsFinal << endl;

    string outFileName = "./resultsTesting/piover2issue"+part1+ptBinStr+part2+massBinStr+part3+etaBinStr+".root";
    TFile* outFile = new TFile(outFileName.c_str(),"Recreate");


    cout << "---WRITING FILE---" << endl;
    //cAut->SaveAs(outFileName.c_str());
    hAut->Write();
    hNumberUp->Write();
    hNumberDown->Write();

    cout << "---END---" << endl;
}
Esempio n. 8
0
void RJ_ttbar(){
  setstyle();
	
  //give transverse momenta to CM system in lab frame?
  double PT = 0.1; //In units of sqrt{shat}
	
  //gamma factor associated with 'off-threshold-ness' of tops
  double gamma = 1.2;
	
  //Now, we also have the option to take gamma, event-by-event, 
  //from a more realistic distribution
  //to do this, set 'b_gamma' to true and the rest
  //of the variables below appropriately
  bool b_gamma = true;
  rootS = 13.;
  type = 1; //0 quark-antiquark  1 gluon-gluon
  M = 175./1000.; //TeV units
	
  //Number of toy events to throw
  int N = 1000;

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    LAB->AnalyzeEvent();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
    cout << "TT costheta: " << costhetaTT_top << " " << TT->GetCosDecayAngle() << endl;
    cout << "T1 costheta: " << costhetaT1_top << " " << T1->GetCosDecayAngle() << endl;
    cout << "T2 costheta: " << costhetaT2_top << " " << T2->GetCosDecayAngle() << endl;
    cout << "dphi_T1_T2_top: " << dphi_T1_T2_top << " " << T1->GetDeltaPhiDecayPlanes(T2) << endl;
    cout << "dphi_W_T1_top: " << dphi_W_T1_top << " " << T1->GetDeltaPhiDecayPlanes(W1) << endl;
   
    
    TLorentzVector newB1 = Bjet1->GetFourVector(T1);
    TLorentzVector newB2 = Bjet2->GetFourVector(T2);
    TLorentzVector newL1 = Lep1->GetFourVector(W1);
    TLorentzVector newL2 = Lep2->GetFourVector(W2);
    TLorentzVector newNU1 = Neu1->GetFourVector(W1);
    TLorentzVector newNU2 = Neu2->GetFourVector(W2);
    cout << "Eb1: " << Eb1_top << " " << newB1.E() << endl;
    cout << "Eb2: " << Eb2_top << " " << newB2.E() << endl;
    cout << "El1: " << El1_top << " " << newL1.E() << endl;
    cout << "El2: " << El2_top << " " << newL2.E() << endl;
    cout << "ENU1: " << NU1_top.E() << " " << newNU1.E() << endl;
    cout << "ENU2: " << NU2_top.E() << " " << newNU2.E() << endl;
    
  }
}
Esempio n. 9
0
void testRotation(){
	

	//LOAD LIBS
	cout << "\n";
	gROOT->Macro("StRoot/LoadLibs.C");
	gSystem->Load("pionPair");
	cout << " loading of pionPair library done" << endl;
	
	
	
	
	TFile* infile = new TFile("/star/u/klandry/ucladisk/2012IFF/schedOutputAll/all_0.root");

	
	//SET UP TREE TO RECEIVE INPUT
	pionPair* pair1 = new pionPair();
	TTree* pairTree = infile->Get("pionPairTree");
	pairTree->SetBranchAddress("pionPair", &pair1);

	
	for (int iPair = 0; iPair < pairTree->GetEntries(); iPair++)
	{
		if (iPair%10000 == 0) {cout << "processing pair number " << iPair << endl;}
		//cout << "processing pair number " << iPair << endl;
		
		
		//if (iPair == 661){continue;}
		
		pairTree->GetEntry(iPair);
		
		TVector3 spinVec;
		
		
		if (pair1->withinRadius(0.05, 0.3))
		{
			
			
			int spinB = pair1->spinBit();
			
			if (spinB == 5 || spinB == 9) //yelow down
			{
				spinVec.SetXYZ(0, -1, 0);
			}
			
			if (spinB == 6 || spinB == 10) //yellow up
			{
				spinVec.SetXYZ(0, 1, 0);
			}
			
			if (spinB == 5 || spinB == 6 || spinB == 9 || spinB == 10)
			{
				
				
				
				TVector3 Ph = pair1->piPlusLV().Vect() + pair1->piMinusLV().Vect();
				TVector3 Rh  = pair1->piPlusLV().Vect() - pair1->piMinusLV().Vect();
				
				
				TVector3 Pa;
				Pa.SetXYZ(0, 0, 1);   //blue is unpolarized beam
				
				TVector3 Pb;
				Pb.SetXYZ(0, 0, -1);  //yellow is polarized beam
				
				
				//ROTATE EVERYTHING BY PI AROUND Y AXIS
				
				Ph.RotateY(TMath::Pi());
				Rh.RotateY(TMath::Pi());
				Pa.RotateY(TMath::Pi());
				Pb.RotateY(TMath::Pi());
				
				
			//	cout << Ph << endl;
			//	cout << Rh << endl;
			//	cout << Pa << endl;
			//	cout << Pb << endl;
				
				
				//cout << "\n";
				
				//cout << Ph.Unit().Cross(Pa) << endl;
				//cout << Ph.Unit().Cross(Rh) << endl;
				
				double cosPhi_S = Pb.Unit().Cross(Ph).Unit() * Pb.Unit().Cross(spinVec).Unit();
				
				double cosPhi_R = Ph.Unit().Cross(Pa).Unit() * Ph.Unit().Cross(Rh).Unit();
				
				double sinPhi_S = Ph.Cross(spinVec) * Pb.Unit() / (Pb.Unit().Cross(Ph).Mag() * Pb.Unit().Cross(spinVec).Mag());
				
				double sinPhi_R = Pa.Cross(Rh) * Ph.Unit() / (Ph.Unit().Cross(Pa).Mag() * Ph.Unit().Cross(Rh).Mag());
				
				
				
				double sinPhi_S_R = sinPhi_S*cosPhi_R - cosPhi_S*sinPhi_R;
				
				double cosPhi_S_R = cosPhi_S*cosPhi_R + sinPhi_S*sinPhi_R;
				
				
				
				double phi_S_R;
				
				if (cosPhi_S_R >= 0)
				{
					phi_S_R = asin(sinPhi_S_R);
				}
				else if (cosPhi_S_R < 0)
				{
					
					if (sinPhi_S_R >= 0)
					{
						phi_S_R = TMath::Pi() - asin(sinPhi_S_R);
					}
					if (sinPhi_S_R < 0)
					{
						phi_S_R = -TMath::Pi() - asin(sinPhi_S_R);
					}
					
				}
				
				
				
				cout << "regular Phi_SR = " << pair1->phiSR('y') << "   rotated Phi_SR = " << phi_S_R << endl;
				
			}
			
			
			
			
		}
		
	}
	
	
	
	
	
	
	
}
Esempio n. 10
0
TMatrix EUTelState::computePropagationJacobianFromLocalStateToNextLocalState(TVector3 positionEnd, TVector3 momentumEnd, float arcLength,float nextPlaneID) {
	streamlog_out(DEBUG2) << "-------------------------------EUTelState::computePropagationJacobianFromStateToThisZLocation()-------------------------BEGIN" << std::endl;
	if(arcLength == 0 or arcLength < 0 ){ 
		throw(lcio::Exception( Utility::outputColourString("The arc length is less than or equal to zero. ","RED"))); 
	}
	TMatrixD curvilinearJacobian = geo::gGeometry().getPropagationJacobianCurvilinear(arcLength,getOmega(), computeCartesianMomentum().Unit(),momentumEnd.Unit());
	streamlog_out(DEBUG0)<<"This is the curvilinear jacobian at sensor:" << std::endl; 
	streamlog_message( DEBUG0, curvilinearJacobian.Print();, std::endl; );
Esempio n. 11
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;

}