10 #include <analysis/variables/SpecificKinematicVariables.h>
11 #include <analysis/utility/PCmsLabTransform.h>
12 #include <analysis/variables/Variables.h>
15 #include <analysis/dataobjects/Particle.h>
18 #include <framework/logging/Logger.h>
33 double REC_q2BhSimple(
const Particle* particle)
40 TLorentzVector hadron4vec;
42 unsigned n = particle->getNDaughters();
45 return std::numeric_limits<float>::quiet_NaN();
47 for (
unsigned i = 0; i < n; i++) {
48 int absPDG = abs(particle->getDaughter(i)->getPDGCode());
49 if (absPDG == Const::electron.getPDGCode() || absPDG == Const::muon.getPDGCode() || absPDG == 15)
52 hadron4vec += particle->getDaughter(i)->get4Vector();
57 TLorentzVector phCMS = T.rotateLabToCms() * hadron4vec;
59 pBCMS.SetXYZM(0.0, 0.0, 0.0, particle->getPDGMass());
60 return (pBCMS - phCMS).Mag2();
63 double REC_q2Bh(
const Particle* particle)
70 TLorentzVector hadron4vec;
72 unsigned n = particle->getNDaughters();
75 return std::numeric_limits<float>::quiet_NaN();
77 for (
unsigned i = 0; i < n; i++) {
78 int absPDG = abs(particle->getDaughter(i)->getPDGCode());
79 if (absPDG == Const::electron.getPDGCode() || absPDG == Const::muon.getPDGCode() || absPDG == 15)
82 hadron4vec += particle->getDaughter(i)->get4Vector();
87 TLorentzVector had_cm = T.rotateLabToCms() * hadron4vec;
88 TLorentzVector Y_cm = T.rotateLabToCms() * particle->get4Vector();
91 double bmass = particle->getPDGMass();
93 double cos_cone_angle = Variable::cosThetaBetweenParticleAndNominalB(particle);
94 if (abs(cos_cone_angle) > 1) {
96 double q2 = Variable::REC_q2BhSimple(particle);
102 double thetaBY = TMath::ACos(cos_cone_angle);
103 const double E_B = T.getCMSEnergy() / 2.0;
104 const double p_B = sqrt(E_B * E_B - bmass * bmass);
106 double phi_start = gRandom->Uniform(0, TMath::Pi() / 2);
111 TVector3 zHatY(Y_cm.Vect().Unit());
112 TVector3 yHatY((had_cm.Vect().Cross(zHatY)).Unit());
113 TVector3 xHatY(yHatY.Cross(zHatY));
115 double phi = phi_start;
116 double dphi = TMath::Pi() / 2;
117 TLorentzVector static_B(0, 0, 0, bmass);
119 for (
int around_the_cone = 0; around_the_cone < 4; around_the_cone++) {
124 double B0_px_Y_frame = p_B * TMath::Sin(thetaBY) * TMath::Cos(phi);
125 double B0_py_Y_frame = p_B * TMath::Sin(thetaBY) * TMath::Sin(phi);
126 double B0_pz_Y_frame = p_B * TMath::Cos(thetaBY);
132 TVector3 B0_px_Dframe(xHatY);
133 B0_px_Dframe *= B0_px_Y_frame;
134 TVector3 B0_py_Dframe(yHatY);
135 B0_py_Dframe *= B0_py_Y_frame;
136 TVector3 B0_pz_Dframe(zHatY);
137 B0_pz_Dframe *= B0_pz_Y_frame;
140 TVector3 B0_p3_Dframe(B0_px_Dframe + B0_py_Dframe + B0_pz_Dframe);
141 TLorentzVector B0_p4_Dframe(B0_p3_Dframe, E_B);
145 double cosThetaB = B0_p3_Dframe.CosTheta();
146 double sinThetaB2 = (1 - cosThetaB * cosThetaB);
149 double wt = sinThetaB2;
153 TLorentzVector had_B0(had_cm);
154 had_B0.Boost(-B0_p4_Dframe.BoostVector());
155 q2 += wt * ((static_B - had_B0).M2());
167 double REC_MissM2(
const Particle* particle)
170 TLorentzVector rec4vecLAB = particle->get4Vector();
171 TLorentzVector rec4vec = T.rotateLabToCms() * rec4vecLAB;
173 TLorentzVector miss4vec;
174 double E_beam_cms = T.getCMSEnergy() / 2.0;
176 miss4vec.SetVect(-rec4vec.Vect());
177 miss4vec.SetE(E_beam_cms - rec4vec.Energy());
179 return miss4vec.Mag2();
183 VARIABLE_GROUP(
"Specific kinematic variables");
185 REGISTER_VARIABLE(
"recQ2BhSimple", REC_q2BhSimple,
186 "Returns the momentum transfer squared, :math:`q^2`, calculated in CMS as :math:`q^2 = (p_B - p_h)^2`, \n"
187 "where p_h is the CMS momentum of all hadrons in the decay :math:`B \\to H_1 ... H_n \\ell \\nu_\\ell`.\n"
188 "The B meson momentum in CMS is assumed to be 0.");
190 REGISTER_VARIABLE(
"recQ2Bh", REC_q2Bh,
191 "Returns the momentum transfer squared, :math:`q^2`, calculated in CMS as :math:`q^2 = (p_B - p_h)^2`, \n"
192 "where p_h is the CMS momentum of all hadrons in the decay :math:`B \\to H_1\\dots H_n \\ell \\nu_\\ell`.\n"
193 "This calculation uses a weighted average of the B meson around the reco B cone. \n"
194 "Based on diamond frame calculation of :math:`q^2` following the idea presented in https://www.osti.gov/biblio/1442697 \n"
195 "It will switch to use of :b2:var:`recQ2BhSimple` if absolute of :b2:var:`cosThetaBetweenParticleAndNominalB` > 1.");
197 REGISTER_VARIABLE(
"recMissM2", REC_MissM2,
198 "Returns the invariant mass squared of the missing momentum calculated assumings the"
199 "reco B is at rest and calculating the neutrino (missing) momentum from :math:`p_\\nu = p_B - p_\\mathrm{had} - p_\\mathrm{lep}`");
Abstract base class for different kinds of events.