Rivet analyses
Polarization of ϕ, D*+ and B* mesons at LEP1
Experiment: OPAL (LEP)
Inspire ID: 440103
Status: VALIDATED
Authors: - Peter Richardson
References: - Z.Phys. C74 (1997) 437-449
Beams: e- e+
Beam energies: (45.6, 45.6)GeV
Run details: - e+e- to hadrons
Measurement of the polarization of ϕ, D*+ and B* mesons at LEP1.
Source
code:OPAL_1997_I440103.cc
// -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/Beam.hh"
#include "Rivet/Projections/ChargedFinalState.hh"
#include "Rivet/Projections/FinalState.hh"
#include "Rivet/Projections/Thrust.hh"
#include "Rivet/Projections/UnstableParticles.hh"
#define I_KNOW_THE_INITIAL_QUARKS_PROJECTION_IS_DODGY_BUT_NEED_TO_USE_IT
#include "Rivet/Projections/InitialQuarks.hh"
namespace Rivet {
/// @brief phi D* and B* polarization
class OPAL_1997_I440103 : public Analysis {
public:
/// Constructor
RIVET_DEFAULT_ANALYSIS_CTOR(OPAL_1997_I440103);
/// @name Analysis methods
/// @{
/// Book histograms and initialise projections before the run
void init() {
// Initialise and register projections
declare(Beam(), "Beams");
declare(Thrust(FinalState()), "Thrust");
declare(ChargedFinalState(), "FS");
declare(InitialQuarks(), "IQF");
declare(UnstableParticles(), "UFS");
// Book histograms
// B*
book(_h_B, 8, 1, 1);
book(_h_B2, "/TMP/c_theta_B", 20, -1., 1.);
// phi
book(_h_phi_ctheta, 5, 1, 1);
book(_h_phi_ctheta2, "/TMP/c_theta_phi2", 20, -1., 1.);
book(_h_phi_ctheta3, "/TMP/c_theta_phi3", 20, -1., 1.);
book(_h_phi_ctheta4, "/TMP/c_theta_phi4", 20, -1., 1.);
book(_h_phi_alpha, 5, 1, 2);
book(_h_phi_alpha2, "/TMP/alpha_phi2", 20, 0., 0.5 * M_PI);
book(_h_phi_alpha3, "/TMP/alpha_phi3", 20, 0., 0.5 * M_PI);
book(_h_phi_alpha4, "/TMP/alpha_phi4", 20, 0., 0.5 * M_PI);
book(_h_phi_beta, 5, 1, 3);
book(_h_phi_beta2, "/TMP/beta_phi2", 20, 0., 0.5 * M_PI);
book(_h_phi_beta3, "/TMP/beta_phi3", 20, 0., 0.5 * M_PI);
book(_h_phi_beta4, "/TMP/beta_phi4", 20, 0., 0.5 * M_PI);
book(_c_phi_cos_plus, "/TMP/c_phi_cos_plus1");
book(_c_phi_cos_neg, "/TMP/c_phi_cos_neg1");
book(_c_phi_sin_plus, "/TMP/c_phi_sin_plus1");
book(_c_phi_sin_neg, "/TMP/c_phi_sin_neg1");
book(_c_phi_cos_plus2, "/TMP/c_phi_cos_plus2");
book(_c_phi_cos_neg2, "/TMP/c_phi_cos_neg2");
book(_c_phi_sin_plus2, "/TMP/c_phi_sin_plus2");
book(_c_phi_sin_neg2, "/TMP/c_phi_sin_neg2");
book(_c_phi_cos_plus3, "/TMP/c_phi_cos_plus3");
book(_c_phi_cos_neg3, "/TMP/c_phi_cos_neg3");
book(_c_phi_sin_plus3, "/TMP/c_phi_sin_plus3");
book(_c_phi_sin_neg3, "/TMP/c_phi_sin_neg3");
// D*
book(_h_DS_ctheta, 6, 1, 1);
book(_h_DS_ctheta2, "/TMP/c_theta_DS2", 20, -1., 1.);
book(_h_DS_alpha, 7, 1, 1);
book(_h_DS_alpha2, "/TMP/alpha_DS2", 20, 0., 0.5 * M_PI);
}
/// Perform the per-event analysis
void analyze(const Event& event) {
// First, veto on leptonic events by requiring at least 4 charged FS particles
const FinalState& fs = apply<FinalState>(event, "FS");
const size_t numParticles = fs.particles().size();
// Even if we only generate hadronic events, we still need a cut on numCharged >= 2.
if (numParticles < 2) {
MSG_DEBUG("Failed leptonic event cut");
vetoEvent;
}
MSG_DEBUG("Passed leptonic event cut");
// Get beams and average beam momentum
const ParticlePair& beams = apply<Beam>(event, "Beams").beams();
const double meanBeamMom = (beams.first.p3().mod() + beams.second.p3().mod()) / 2.0;
MSG_DEBUG("Avg beam momentum = " << meanBeamMom);
Vector3 axis;
if (beams.first.pid() > 0)
axis = beams.first.momentum().p3().unit();
else
axis = beams.second.momentum().p3().unit();
// thrust, to define an axis
const Thrust& thrust = apply<Thrust>(event, "Thrust");
int flavour = 0;
const InitialQuarks& iqf = apply<InitialQuarks>(event, "IQF");
// If we only have two quarks (qqbar), just take the flavour.
// If we have more than two quarks, look for the highest energetic q-qbar pair.
/// @todo Yuck... does this *really* have to be quark-based?!?
if (iqf.particles().size() == 2) {
flavour = iqf.particles().front().abspid();
}
else {
map<int, double> quarkmap;
for (const Particle& p : iqf.particles()) {
if (quarkmap[p.pid()] < p.E()) {
quarkmap[p.pid()] = p.E();
}
}
double maxenergy = 0.;
for (int i = 1; i <= 5; ++i) {
if (quarkmap[i] + quarkmap[-i] > maxenergy) {
flavour = i;
}
}
}
// loop over the particles
for (const Particle& p : apply<UnstableParticles>(event, "UFS")
.particles(Cuts::abspid == 513 or Cuts::abspid == 523 or Cuts::pid == 333
or Cuts::abspid == 413)) {
int sign = p.pid() / p.abspid();
Particle decay;
if (p.children().size() != 2) continue;
// B*
if (p.abspid() == 513 or p.abspid() == 523) {
int mid = p.abspid() - 2;
if (p.children()[0].pid() == sign * mid && p.children()[1].pid() == 22) {
decay = p.children()[1];
}
else if (p.children()[1].pid() == sign * mid && p.children()[0].pid() == 22) {
decay = p.children()[0];
}
else {
continue;
}
}
// phi
else if (p.pid() == 333) {
// cut x_E > 0.7
double xE = p.momentum().E() / meanBeamMom;
if (xE < 0.7) continue;
if (p.children()[0].pid() == 321 && p.children()[1].pid() == -321) {
decay = p.children()[0];
}
else if (p.children()[1].pid() == 321 && p.children()[0].pid() == -321) {
decay = p.children()[1];
}
else {
continue;
}
}
// D*
else if (p.abspid() == 413) {
double xE = p.momentum().E() / meanBeamMom;
if (xE < 0.5 || flavour != 4) continue;
if (p.children()[0].pid() == sign * 421 && p.children()[1].pid() == sign * 211) {
decay = p.children()[1];
}
else if (p.children()[1].pid() == sign * 421 && p.children()[0].pid() == sign * 211) {
decay = p.children()[0];
}
else {
continue;
}
}
LorentzTransform boost = LorentzTransform::mkFrameTransformFromBeta(p.momentum().betaVec());
Vector3 e1z = p.p3().unit();
FourMomentum pp = boost.transform(decay.momentum());
Vector3 axis1 = boost.transform(decay.momentum()).p3().unit();
double ctheta = e1z.dot(axis1);
if (p.abspid() == 513 or p.abspid() == 523) {
_h_B->fill(ctheta);
_h_B2->fill(ctheta);
}
// D*
else if (p.abspid() == 413) {
// y and z axis
Vector3 e1y = e1z.cross(axis).unit();
Vector3 e1x = e1y.cross(e1z).unit();
// helicity beam axis, all phis
// cos theta_H
_h_DS_ctheta->fill(ctheta);
_h_DS_ctheta2->fill(ctheta);
// alpha
double phi = atan2(e1y.dot(axis1), e1x.dot(axis1));
double alpha = abs(abs(phi) - 0.5 * M_PI);
_h_DS_alpha->fill(alpha);
_h_DS_alpha2->fill(alpha);
}
else if (p.pid() == 333) {
// y and z axis
Vector3 e1y = e1z.cross(axis).unit();
Vector3 e1x = e1y.cross(e1z).unit();
// helicity beam axis, all phis
// cos theta_H
_h_phi_ctheta->fill(abs(ctheta));
_h_phi_ctheta2->fill(ctheta);
// alpha and beta
double phi = atan2(e1y.dot(axis1), e1x.dot(axis1));
double alpha = abs(abs(phi) - 0.5 * M_PI);
double beta = abs(abs(phi + 0.25 * M_PI) - 0.5 * M_PI);
_h_phi_alpha->fill(alpha);
_h_phi_alpha2->fill(alpha);
_h_phi_beta->fill(beta);
_h_phi_beta2->fill(beta);
/// counters for asymmetries
double sin2H = 2. * ctheta * sqrt(1. - sqr(ctheta));
if (sin2H * cos(phi) > 0.)
_c_phi_cos_plus->fill();
else
_c_phi_cos_neg->fill();
if (sin2H * sin(phi) > 0.)
_c_phi_sin_plus->fill();
else
_c_phi_sin_neg->fill();
// whether or not is a primary hadron
Particle parent = p.parents()[0];
if (parent.children().size() == 1 && parent.abspid() == p.abspid()) parent = parent.parents()[0];
bool primary = !PID::isHadron(parent.pid());
if (primary) {
// cos theta_H
_h_phi_ctheta3->fill(ctheta);
// alpha and beta
_h_phi_alpha3->fill(alpha);
_h_phi_beta3->fill(beta);
/// counters for asymmetries
if (sin2H * cos(phi) > 0.)
_c_phi_cos_plus2->fill();
else
_c_phi_cos_neg2->fill();
if (sin2H * sin(phi) > 0.)
_c_phi_sin_plus2->fill();
else
_c_phi_sin_neg2->fill();
}
// pT w.r.t thrust axis
double pT = sqrt(sqr(thrust.thrustMajorAxis().dot(p.momentum().p3()))
+ sqr(thrust.thrustMinorAxis().dot(p.momentum().p3())));
// helicity-quark frame
if (pT > 1.2) {
// cos theta H
_h_phi_ctheta4->fill(ctheta);
Vector3 axis2;
if (p.momentum().p3().dot(thrust.thrustAxis()) >= 0.) {
axis2 = thrust.thrustAxis();
}
else {
axis2 = -thrust.thrustAxis();
}
Vector3 e2y = e1z.cross(axis2).unit();
Vector3 e2x = e2y.cross(e1z).unit();
// alpha and beta
double phi = atan2(e2y.dot(axis1), e2x.dot(axis1));
double alpha = abs(abs(phi) - 0.5 * M_PI);
double beta = abs(abs(phi + 0.25 * M_PI) - 0.5 * M_PI);
_h_phi_alpha4->fill(alpha);
_h_phi_beta4->fill(beta);
/// counters for asymmetries
double sin2H = 2. * ctheta * sqrt(1. - sqr(ctheta));
if (sin2H * cos(phi) > 0.)
_c_phi_cos_plus3->fill();
else
_c_phi_cos_neg3->fill();
if (sin2H * sin(phi) > 0.)
_c_phi_sin_plus3->fill();
else
_c_phi_sin_neg3->fill();
}
}
}
}
pair<double, double> calcRho(Histo1DPtr hist, unsigned int mode) {
if (hist->numEntries() == 0.) return make_pair(0., 0.);
double sum1(0.), sum2(0.);
for (const auto& bin : hist->bins()) {
double Oi = bin.sumW();
if (Oi == 0.) continue;
double ai(0.), bi(0.);
if (mode == 0) {
ai = 0.25 * (-bin.xMin() * (3. - sqr(bin.xMin())) + bin.xMax() * (3. - sqr(bin.xMax())));
bi = -0.75 * (-bin.xMin() * (1. - sqr(bin.xMin())) + bin.xMax() * (1. - sqr(bin.xMax())));
}
else if (mode == 1) {
ai = 0.125 * (-bin.xMin() * (3. + sqr(bin.xMin())) + bin.xMax() * (3. + sqr(bin.xMax())));
bi = 0.375 * (-bin.xMin() * (1. - sqr(bin.xMin())) + bin.xMax() * (1. - sqr(bin.xMax())));
}
else if (mode == 2) {
ai = -2. * (bin.xMin() - bin.xMax()) / M_PI;
bi = -2. * (sin(2. * bin.xMin()) - sin(2. * bin.xMax())) / M_PI;
}
double Ei = bin.errW();
sum1 += sqr(bi / Ei);
sum2 += bi / sqr(Ei) * (Oi - ai);
}
return make_pair(sum2 / sum1, sqrt(1. / sum1));
}
/// Normalise histograms etc., after the run
void finalize() {
// B*
normalize(_h_B, 1., false);
normalize(_h_B2);
pair<double, double> rho = calcRho(_h_B2, 1);
BinnedEstimatePtr<string> h_rhoB;
book(h_rhoB, 4, 1, 1);
h_rhoB->bin(1).set(rho.first, rho.second);
// D*
normalize(_h_DS_ctheta);
normalize(_h_DS_ctheta2);
rho = calcRho(_h_DS_ctheta2, 1);
BinnedEstimatePtr<string> h_rhoD;
book(h_rhoD, 3, 1, 1);
h_rhoD->bin(1).set(rho.first, rho.second);
normalize(_h_DS_alpha);
normalize(_h_DS_alpha2);
BinnedEstimatePtr<string> h_reRho_D;
book(h_reRho_D, 3, 1, 2);
rho = calcRho(_h_DS_alpha2, 2);
h_reRho_D->bin(1).set(rho.first, rho.second);
// phi
// rho00
normalize(_h_phi_ctheta);
normalize(_h_phi_ctheta2);
normalize(_h_phi_ctheta3);
normalize(_h_phi_ctheta4);
BinnedEstimatePtr<string> hrho_phi;
book(hrho_phi, 1, 1, 1);
rho = calcRho(_h_phi_ctheta2, 0);
hrho_phi->bin(1).set(rho.first, rho.second);
rho = calcRho(_h_phi_ctheta3, 0);
hrho_phi->bin(2).set(rho.first, rho.second);
rho = calcRho(_h_phi_ctheta4, 0);
hrho_phi->bin(3).set(rho.first, rho.second);
// Re rho
normalize(_h_phi_alpha);
normalize(_h_phi_alpha2);
normalize(_h_phi_alpha3);
normalize(_h_phi_alpha4);
BinnedEstimatePtr<string> hreRho_phi;
book(hreRho_phi, 1, 1, 2);
rho = calcRho(_h_phi_alpha2, 2);
hreRho_phi->bin(1).set(rho.first, rho.second);
rho = calcRho(_h_phi_alpha3, 2);
hreRho_phi->bin(2).set(rho.first, rho.second);
rho = calcRho(_h_phi_alpha4, 2);
hreRho_phi->bin(3).set(rho.first, rho.second);
// Im rho
normalize(_h_phi_beta);
normalize(_h_phi_beta2);
normalize(_h_phi_beta3);
normalize(_h_phi_beta4);
BinnedEstimatePtr<string> himRho_phi;
book(himRho_phi, 1, 1, 3);
rho = calcRho(_h_phi_beta2, 2);
himRho_phi->bin(1).set(rho.first, rho.second);
rho = calcRho(_h_phi_beta3, 2);
himRho_phi->bin(2).set(rho.first, rho.second);
rho = calcRho(_h_phi_beta4, 2);
himRho_phi->bin(3).set(rho.first, rho.second);
// real diff
Estimate0D temp = ((*_c_phi_cos_plus - *_c_phi_cos_neg) / (*_c_phi_cos_plus + *_c_phi_cos_neg));
Estimate0D temp2 = ((*_c_phi_cos_plus2 - *_c_phi_cos_neg2) / (*_c_phi_cos_plus2 + *_c_phi_cos_neg2));
Estimate0D temp3 = ((*_c_phi_cos_plus3 - *_c_phi_cos_neg3) / (*_c_phi_cos_plus3 + *_c_phi_cos_neg3));
BinnedEstimatePtr<string> hreDiff_phi;
book(hreDiff_phi, 1, 1, 4);
hreDiff_phi->bin(1) = temp;
hreDiff_phi->bin(2) = temp2;
hreDiff_phi->bin(3) = temp3;
// im diff
temp = ((*_c_phi_sin_plus - *_c_phi_sin_neg) / (*_c_phi_sin_plus + *_c_phi_sin_neg));
temp2 = ((*_c_phi_sin_plus2 - *_c_phi_sin_neg2) / (*_c_phi_sin_plus2 + *_c_phi_sin_neg2));
temp3 = ((*_c_phi_sin_plus3 - *_c_phi_sin_neg3) / (*_c_phi_sin_plus3 + *_c_phi_sin_neg3));
BinnedEstimatePtr<string> himDiff_phi;
book(himDiff_phi, 1, 1, 5);
himDiff_phi->bin(1) = temp;
himDiff_phi->bin(2) = temp2;
himDiff_phi->bin(3) = temp3;
}
/// @}
/// @name Histograms
/// @{
Histo1DPtr _h_B, _h_B2;
Histo1DPtr _h_phi_ctheta, _h_phi_ctheta2, _h_phi_ctheta3, _h_phi_ctheta4;
Histo1DPtr _h_phi_alpha, _h_phi_alpha2, _h_phi_alpha3, _h_phi_alpha4;
Histo1DPtr _h_phi_beta, _h_phi_beta2, _h_phi_beta3, _h_phi_beta4;
CounterPtr _c_phi_cos_plus, _c_phi_cos_neg, _c_phi_cos_plus2, _c_phi_cos_neg2, _c_phi_cos_plus3,
_c_phi_cos_neg3;
CounterPtr _c_phi_sin_plus, _c_phi_sin_neg, _c_phi_sin_plus2, _c_phi_sin_neg2, _c_phi_sin_plus3,
_c_phi_sin_neg3;
Histo1DPtr _h_DS_ctheta, _h_DS_ctheta2;
Histo1DPtr _h_DS_alpha, _h_DS_alpha2;
/// @}
};
RIVET_DECLARE_PLUGIN(OPAL_1997_I440103);
}