10#include <analysis/variables/SpecificKinematicVariables.h>
13#include <analysis/VariableManager/Manager.h>
15#include <analysis/utility/PCmsLabTransform.h>
16#include <analysis/variables/Variables.h>
19#include <analysis/dataobjects/Particle.h>
22#include <framework/logging/Logger.h>
26#include <Math/Vector3D.h>
27#include <Math/Vector4D.h>
28using namespace ROOT::Math;
41 double REC_q2BhSimple(
const Particle* particle)
48 PxPyPzEVector hadron4vec;
50 unsigned n = particle->getNDaughters();
55 for (
unsigned i = 0; i < n; i++) {
56 int absPDG = abs(particle->getDaughter(i)->getPDGCode());
60 hadron4vec += particle->getDaughter(i)->get4Vector();
65 PxPyPzEVector phCMS = T.rotateLabToCms() * hadron4vec;
66 PxPyPzMVector pBCMS(0.0, 0.0, 0.0, particle->getPDGMass());
67 return (pBCMS - phCMS).mag2();
70 double REC_q2Bh(
const Particle* particle)
77 PxPyPzEVector hadron4vec;
79 unsigned n = particle->getNDaughters();
84 for (
unsigned i = 0; i < n; i++) {
85 int absPDG = abs(particle->getDaughter(i)->getPDGCode());
89 hadron4vec += particle->getDaughter(i)->get4Vector();
94 PxPyPzEVector had_cm = T.rotateLabToCms() * hadron4vec;
95 PxPyPzEVector Y_cm = T.rotateLabToCms() * particle->get4Vector();
98 double bmass = particle->getPDGMass();
100 double cos_cone_angle = Variable::cosThetaBetweenParticleAndNominalB(particle);
101 if (abs(cos_cone_angle) > 1) {
103 double q2 = Variable::REC_q2BhSimple(particle);
109 double thetaBY = TMath::ACos(cos_cone_angle);
110 const double E_B = T.getCMSEnergy() / 2.0;
111 const double p_B =
sqrt(E_B * E_B - bmass * bmass);
113 double phi_start = gRandom->Uniform(0, TMath::Pi() / 2);
118 XYZVector zHatY(Y_cm.Vect().Unit());
119 XYZVector yHatY((had_cm.Vect().Cross(zHatY)).Unit());
120 XYZVector xHatY(yHatY.Cross(zHatY));
122 double phi = phi_start;
123 double dphi = TMath::Pi() / 2;
124 PxPyPzEVector static_B(0, 0, 0, bmass);
126 for (
int around_the_cone = 0; around_the_cone < 4; around_the_cone++) {
131 double B0_px_Y_frame = p_B * TMath::Sin(thetaBY) * TMath::Cos(phi);
132 double B0_py_Y_frame = p_B * TMath::Sin(thetaBY) * TMath::Sin(phi);
133 double B0_pz_Y_frame = p_B * TMath::Cos(thetaBY);
139 XYZVector B0_px_Dframe(xHatY);
140 B0_px_Dframe *= B0_px_Y_frame;
141 XYZVector B0_py_Dframe(yHatY);
142 B0_py_Dframe *= B0_py_Y_frame;
143 XYZVector B0_pz_Dframe(zHatY);
144 B0_pz_Dframe *= B0_pz_Y_frame;
147 XYZVector B0_p3_Dframe(B0_px_Dframe + B0_py_Dframe + B0_pz_Dframe);
148 PxPyPzEVector B0_p4_Dframe(B0_p3_Dframe.X(), B0_p3_Dframe.Y(), B0_p3_Dframe.Z(), E_B);
152 double cosThetaB = cos(B0_p3_Dframe.Theta());
153 double sinThetaB2 = (1 - cosThetaB * cosThetaB);
156 double wt = sinThetaB2;
160 PxPyPzEVector had_B0(had_cm);
161 had_B0 = Boost(B0_p4_Dframe.BoostToCM()) * had_B0;
162 q2 += wt * ((static_B - had_B0).M2());
174 double REC_MissM2(
const Particle* particle)
177 PxPyPzEVector rec4vecLAB = particle->get4Vector();
178 PxPyPzEVector rec4vec = T.rotateLabToCms() * rec4vecLAB;
180 double E_beam_cms = T.getCMSEnergy() / 2.0;
182 PxPyPzEVector miss4vec(-rec4vec.px(), -rec4vec.py(), -rec4vec.pz(), E_beam_cms - rec4vec.E());
184 return miss4vec.mag2();
188 VARIABLE_GROUP(
"Specific kinematic variables");
190 REGISTER_VARIABLE(
"recQ2BhSimple", REC_q2BhSimple,
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 ... H_n \\ell \\nu_\\ell`.\n"
193 "The B meson momentum in CMS is assumed to be 0.\n\n",
":math:`[\\text{GeV}/\\text{c}]^2`");
195 REGISTER_VARIABLE(
"recQ2Bh", REC_q2Bh,
196 "Returns the momentum transfer squared, :math:`q^2`, calculated in CMS as :math:`q^2 = (p_B - p_h)^2`, \n"
197 "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"
198 "This calculation uses a weighted average of the B meson around the reco B cone. \n"
199 "Based on diamond frame calculation of :math:`q^2` following the idea presented in https://www.osti.gov/biblio/1442697 \n"
200 "It will switch to use of :b2:var:`recQ2BhSimple` if absolute of :b2:var:`cosThetaBetweenParticleAndNominalB` > 1.\n\n",
201 ":math:`[\\text{GeV}/\\text{c}]^2`");
203 REGISTER_VARIABLE(
"recMissM2", REC_MissM2, R
"DOC(
204 Returns the invariant mass squared of the missing momentum calculated assumings the
205 reco B is at rest and calculating the neutrino (missing) momentum from :math:`p_\nu = p_B - p_{\rm had} - p_{\rm lep}`
207 )DOC", ":math:`[\\text{GeV}/\\text{c}^2]^2`");
static const ChargedStable muon
muon particle
static const double doubleNaN
quiet_NaN
static const ChargedStable electron
electron particle
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.