Belle II Software development
EvtVSSBMixNP.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include "generators/evtgen/EvtGenModelRegister.h"
10#include "generators/evtgen/models/EvtVSSBMixNP.h"
11
12#include "EvtGenBase/EvtConst.hh"
13#include "EvtGenBase/EvtGenKine.hh"
14#include "EvtGenBase/EvtId.hh"
15#include "EvtGenBase/EvtPDL.hh"
16#include "EvtGenBase/EvtParticle.hh"
17#include "EvtGenBase/EvtPatches.hh"
18#include "EvtGenBase/EvtRandom.hh"
19#include "EvtGenBase/EvtReport.hh"
20#include "EvtGenBase/EvtVector4C.hh"
21
22#include <stdlib.h>
23#include <string>
24
27
28using std::endl;
29
31
33{
34 return "VSSBMixNP";
35}
36
37EvtDecayBase* EvtVSSBMixNP::clone()
38{
39 return new EvtVSSBMixNP;
40}
41
43{
44 if (getNArg() > 4)
45 checkNArg(14, 12, 8);
46
47 if (getNArg() < 1) {
48 EvtGenReport(EVTGEN_ERROR, "EvtGen")
49 << "EvtVSSBMix generator expected "
50 << " at least 1 argument (deltam) but found:" << getNArg() << endl;
51 EvtGenReport(EVTGEN_ERROR, "EvtGen")
52 << "Will terminate execution!" << endl;
53 ::abort();
54 }
55 // check that we are asked to produced exactly 2 daughters
56 //4 are allowed if they are aliased..
57 checkNDaug(2, 4);
58
59 if (getNDaug() == 4) {
60 if (getDaug(0) != getDaug(2) || getDaug(1) != getDaug(3)) {
61 EvtGenReport(EVTGEN_ERROR, "EvtGen")
62 << "EvtVSSBMixNP generator allows "
63 << " 4 daughters only if 1=3 and 2=4"
64 << " (but 3 and 4 are aliased " << endl;
65 EvtGenReport(EVTGEN_ERROR, "EvtGen")
66 << "Will terminate execution!" << endl;
67 ::abort();
68 }
69 }
70 // check that we are asked to decay a vector particle into a pair
71 // of scalar particles
72
73 checkSpinParent(EvtSpinType::VECTOR);
74
75 checkSpinDaughter(0, EvtSpinType::SCALAR);
76 checkSpinDaughter(1, EvtSpinType::SCALAR);
77
78 // check that our daughter particles are charge conjugates of each other
79 if (!(EvtPDL::chargeConj(getDaug(0)) == getDaug(1))) {
80 EvtGenReport(EVTGEN_ERROR, "EvtGen")
81 << "EvtVSSBMixNP generator expected daughters "
82 << "to be charge conjugate." << endl
83 << " Found " << EvtPDL::name(getDaug(0)).c_str() << " and "
84 << EvtPDL::name(getDaug(1)).c_str() << endl;
85 EvtGenReport(EVTGEN_ERROR, "EvtGen")
86 << "Will terminate execution!" << endl;
87 ::abort();
88 }
89 // check that both daughter particles have the same lifetime
90 if (EvtPDL::getctau(getDaug(0)) != EvtPDL::getctau(getDaug(1))) {
91 EvtGenReport(EVTGEN_ERROR, "EvtGen")
92 << "EvtVSSBMixNP generator expected daughters "
93 << "to have the same lifetime." << endl
94 << " Found ctau = " << EvtPDL::getctau(getDaug(0))
95 << " mm and " << EvtPDL::getctau(getDaug(1)) << " mm" << endl;
96 EvtGenReport(EVTGEN_ERROR, "EvtGen")
97 << "Will terminate execution!" << endl;
98 ::abort();
99 }
100 // precompute quantities that will be used to generate events
101 // and print out a summary of parameters for this decay
102
103 // mixing frequency in hbar/mm
104 _freq = getArg(0) / EvtConst::c;
105
106 // deltaG
107 double gamma = 1 / EvtPDL::getctau(getDaug(0)); // gamma/c (1/mm)
108 _dGamma = 0.0;
109 if (getNArg() > 1) _dGamma = getArg(1) * gamma;
110
111 // lambda
112 _lambda = 0.0;
113 if (getNArg() > 2) _lambda = getArg(2) * (1 / EvtConst::c);
114 printf("freq %e gamma %e dgamma %e lambda %e\n", _freq, gamma, _dGamma, _lambda);
115 // some printout
116 double dm = 1e-12 * getArg(0); // B0/anti-B0 mass difference in hbar/ps
117 if (verbose()) {
118 EvtGenReport(EVTGEN_INFO, "EvtGen")
119 << "VSS_NP will generate mixing with possible decoherence:"
120 << endl
121 << endl
122 << " " << EvtPDL::name(getParentId()).c_str() << " --> "
123 << EvtPDL::name(getDaug(0)).c_str() << " + "
124 << EvtPDL::name(getDaug(1)).c_str() << endl
125 << endl
126 << "using parameters:" << endl
127 << endl
128 << " delta(m) = " << dm << " hbar/ps" << endl
129 << " dGamma = " << _dGamma << " hbar/mm" << endl
130 << " lambda = " << _lambda << endl
131 << endl;
132 }
133}
134
136{
137 // this value is ok for reasonable values of all the parameters
138 setProbMax(1);
139}
140
141void EvtVSSBMixNP::decay(EvtParticle* p)
142{
143 // generate a final state according to phase space
144
145 if (getNDaug() == 4) {
146 double rndm = EvtRandom::random();
147 EvtId tempDaug[2];
148 if (rndm < 0.5) {
149 tempDaug[0] = getDaug(0);
150 tempDaug[1] = getDaug(3);
151 } else {
152 tempDaug[0] = getDaug(2);
153 tempDaug[1] = getDaug(1);
154 }
155 p->initializePhaseSpace(2, tempDaug);
156 } else { //nominal case.
157 p->initializePhaseSpace(2, getDaugs());
158 }
159
160 EvtParticle* s1 = p->getDaug(0), *s2 = p->getDaug(1);
161
162 //delete any daughters - if there are daughters, they
163 //are from the initialization and will be redone later
164 if (s1->getNDaug() > 0) s1->deleteDaughters();
165 if (s2->getNDaug() > 0) s2->deleteDaughters();
166
167 EvtVector4R p1 = s1->getP4();
168
169 // choose a decay time for each final state particle using the
170 // lifetime (which must be the same for both particles) in pdt.table
171 // and calculate the lifetime difference for this event
172 double t0, t1, tl, tr, dt; //, prob;
173 do {
174 s1->setLifetime();
175 s2->setLifetime();
176 tl = s1->getLifetime();
177 tr = s2->getLifetime(); // in mm
178 dt = tl - tr;
179 t0 = cosh(-0.5 * _dGamma * dt);
180 } while (EvtRandom::random() * 1.0001 > t0);
181 t1 = exp(-_lambda * std::min(tl, tr)) * cos(_freq * dt);
182
183
184 double fl = EvtRandom::random();
185 int flv = 2 * t0 * EvtRandom::random() < t0 - t1;
186 if (getNDaug() == 4) {
187 if (flv) {
188 // same flavor
189 if (fl > 0.5) {
190 s1->setId(getDaug(0));
191 s2->setId(getDaug(2));
192 } else {
193 s1->setId(getDaug(3));
194 s2->setId(getDaug(1));
195 }
196 } else {
197 // opposite flavors
198 if (fl > 0.5) {
199 s1->setId(getDaug(0));
200 s2->setId(getDaug(3));
201 } else {
202 s1->setId(getDaug(2));
203 s2->setId(getDaug(1));
204 }
205 }
206 } else {
207 if (flv) {
208 // same flavor
209 if (fl > 0.5) {
210 s1->setId(getDaug(0));
211 s2->setId(getDaug(0));
212 } else {
213 s1->setId(getDaug(1));
214 s2->setId(getDaug(1));
215 }
216 } else {
217 // opposite flavors
218 if (fl > 0.5) {
219 s1->setId(getDaug(0));
220 s2->setId(getDaug(1));
221 } else {
222 s1->setId(getDaug(1));
223 s2->setId(getDaug(0));
224 }
225 }
226 }
227
228 // store the amplitudes for each parent spin basis state
229 double norm = 1.0 / p1.d3mag();
230 vertex(0, norm * p1 * (p->eps(0)));
231 vertex(1, norm * p1 * (p->eps(1)));
232 vertex(2, norm * p1 * (p->eps(2)));
233
234 return;
235}
236
Routine to decay vector-> scalar scalar with BB-like mixing and decoherence parameter lambda.
EvtDecayBase * clone() override
The function which makes a copy of the model.
void decay(EvtParticle *p) override
The function to calculate a quark decay amplitude.
virtual ~EvtVSSBMixNP()
Destructor.
double _dGamma
delta gamma in hbar/mm
double _freq
mixing frequency in hbar/mm
std::string getName() override
The function which returns the name of the model.
EvtVSSBMixNP()
Constructor.
double _lambda
lambda in hbar/mm
void init() override
The function for an initialization.
void initProbMax() override
The function to sets a maximum probability.
#define B2_EVTGEN_REGISTER_MODEL(classname)
Class to register B2_EVTGEN_REGISTER_MODEL.