EvtGen 2.2.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
Loading...
Searching...
No Matches
EvtBtoXsll.cpp
Go to the documentation of this file.
1
2/***********************************************************************
3* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
4* *
5* This file is part of EvtGen. *
6* *
7* EvtGen is free software: you can redistribute it and/or modify *
8* it under the terms of the GNU General Public License as published by *
9* the Free Software Foundation, either version 3 of the License, or *
10* (at your option) any later version. *
11* *
12* EvtGen is distributed in the hope that it will be useful, *
13* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15* GNU General Public License for more details. *
16* *
17* You should have received a copy of the GNU General Public License *
18* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
19***********************************************************************/
20
22
25#include "EvtGenBase/EvtId.hh"
26#include "EvtGenBase/EvtPDL.hh"
30
33
34#include <stdlib.h>
35using std::endl;
36
37std::string EvtBtoXsll::getName() const
38{
39 return "BTOXSLL";
40}
41
43{
44 return new EvtBtoXsll;
45}
46
48{
49 // check that there are no arguments
50
51 checkNArg( 0, 4, 5 );
52
53 checkNDaug( 3 );
54
55 // Check that the two leptons are the same type
56
57 EvtId lepton1type = getDaug( 1 );
58 EvtId lepton2type = getDaug( 2 );
59
60 int etyp = 0;
61 int mutyp = 0;
62 int tautyp = 0;
63 if ( lepton1type == EvtPDL::getId( "e+" ) ||
64 lepton1type == EvtPDL::getId( "e-" ) ) {
65 etyp++;
66 }
67 if ( lepton2type == EvtPDL::getId( "e+" ) ||
68 lepton2type == EvtPDL::getId( "e-" ) ) {
69 etyp++;
70 }
71 if ( lepton1type == EvtPDL::getId( "mu+" ) ||
72 lepton1type == EvtPDL::getId( "mu-" ) ) {
73 mutyp++;
74 }
75 if ( lepton2type == EvtPDL::getId( "mu+" ) ||
76 lepton2type == EvtPDL::getId( "mu-" ) ) {
77 mutyp++;
78 }
79 if ( lepton1type == EvtPDL::getId( "tau+" ) ||
80 lepton1type == EvtPDL::getId( "tau-" ) ) {
81 tautyp++;
82 }
83 if ( lepton2type == EvtPDL::getId( "tau+" ) ||
84 lepton2type == EvtPDL::getId( "tau-" ) ) {
85 tautyp++;
86 }
87
88 if ( etyp != 2 && mutyp != 2 && tautyp != 2 ) {
89 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
90 << "Expect two leptons of the same type in EvtBtoXsll.cc\n";
91 ::abort();
92 }
93
94 // Check that the second and third entries are leptons with positive
95 // and negative charge, respectively
96
97 int lpos = 0;
98 int lneg = 0;
99 if ( lepton1type == EvtPDL::getId( "e+" ) ||
100 lepton1type == EvtPDL::getId( "mu+" ) ||
101 lepton1type == EvtPDL::getId( "tau+" ) ) {
102 lpos++;
103 }
104 if ( lepton2type == EvtPDL::getId( "e-" ) ||
105 lepton2type == EvtPDL::getId( "mu-" ) ||
106 lepton2type == EvtPDL::getId( "tau-" ) ) {
107 lneg++;
108 }
109
110 if ( lpos != 1 || lneg != 1 ) {
111 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
112 << "Expect 2nd and 3rd particles to be positive and negative leptons in EvtBtoXsll.cc\n";
113 ::abort();
114 }
115
116 m_mb = 4.8;
117 m_ms = 0.2;
118 m_mq = 0.;
119 m_pf = 0.41;
120 m_mxmin = 1.1;
121 if ( getNArg() == 4 ) {
122 // b-quark mass
123 m_mb = getArg( 0 );
124 // s-quark mass
125 m_ms = getArg( 1 );
126 // spectator quark mass
127 m_mq = getArg( 2 );
128 // Fermi motion parameter
129 m_pf = getArg( 3 );
130 }
131 if ( getNArg() == 5 ) {
132 m_mxmin = getArg( 4 );
133 }
134
135 m_calcprob = std::make_unique<EvtBtoXsllUtil>();
136
137 double ml = EvtPDL::getMeanMass( getDaug( 1 ) );
138
139 // determine the maximum probability density from dGdsProb
140
141 int i, j;
142 int nsteps = 100;
143 double s = 0.0;
144 double smin = 4.0 * ml * ml;
145 double smax = ( m_mb - m_ms ) * ( m_mb - m_ms );
146 double probMax = -10000.0;
147 double sProbMax = -10.0;
148 double uProbMax = -10.0;
149
150 for ( i = 0; i < nsteps; i++ ) {
151 s = smin + ( i + 0.002 ) * ( smax - smin ) / (double)nsteps;
152 double prob = m_calcprob->dGdsProb( m_mb, m_ms, ml, s );
153 if ( prob > probMax ) {
154 sProbMax = s;
155 probMax = prob;
156 }
157 }
158
159 m_dGdsProbMax = probMax;
160
161 if ( verbose() ) {
162 EvtGenReport( EVTGEN_INFO, "EvtGen" )
163 << "dGdsProbMax = " << probMax << " for s = " << sProbMax << endl;
164 }
165
166 // determine the maximum probability density from dGdsdupProb
167
168 probMax = -10000.0;
169 sProbMax = -10.0;
170
171 for ( i = 0; i < nsteps; i++ ) {
172 s = smin + ( i + 0.002 ) * ( smax - smin ) / (double)nsteps;
173 double umax = sqrt( ( s - ( m_mb + m_ms ) * ( m_mb + m_ms ) ) *
174 ( s - ( m_mb - m_ms ) * ( m_mb - m_ms ) ) );
175 for ( j = 0; j < nsteps; j++ ) {
176 double u = -umax + ( j + 0.002 ) * ( 2.0 * umax ) / (double)nsteps;
177 double prob = m_calcprob->dGdsdupProb( m_mb, m_ms, ml, s, u );
178 if ( prob > probMax ) {
179 sProbMax = s;
180 uProbMax = u;
181 probMax = prob;
182 }
183 }
184 }
185
186 m_dGdsdupProbMax = 2.0 * probMax;
187
188 if ( verbose() ) {
189 EvtGenReport( EVTGEN_INFO, "EvtGen" )
190 << "dGdsdupProbMax = " << probMax << " for s = " << sProbMax
191 << " and u = " << uProbMax << endl;
192 }
193}
194
196{
197 noProbMax();
198}
199
201{
203
204 EvtParticle* xhadron = p->getDaug( 0 );
205 EvtParticle* leptonp = p->getDaug( 1 );
206 EvtParticle* leptonn = p->getDaug( 2 );
207
208 double mass[3];
209
210 findMasses( p, getNDaug(), getDaugs(), mass );
211
212 double mB = p->mass();
213 double ml = mass[1];
214 double pb( 0. );
215
216 static thread_local int nmsg = 0;
217
218 double xhadronMass = -999.0;
219
220 EvtVector4R p4xhadron;
221 EvtVector4R p4leptonp;
222 EvtVector4R p4leptonn;
223
224 // require the hadronic system has mass greater than that of a Kaon pion pair
225
226 // while (xhadronMass < 0.6333)
227 // the above minimum value of K+pi mass appears to be too close
228 // to threshold as far as JETSET is concerned
229 // (JETSET gets caught in an infinite loop)
230 // so we choose a lightly larger value for the threshold
231 while ( xhadronMass < m_mxmin ) {
232 // Apply Fermi motion and determine effective b-quark mass
233
234 // Old BaBar MC parameters
235 // double pf = 0.25;
236 // double ms = 0.2;
237 // double mq = 0.3;
238
239 double mb = 0.0;
240
241 double xbox, ybox;
242
243 while ( mb <= 0.0 ) {
244 pb = m_calcprob->FermiMomentum( m_pf );
245
246 // effective b-quark mass
247 mb = mB * mB + m_mq * m_mq - 2.0 * mB * sqrt( pb * pb + m_mq * m_mq );
248 if ( mb > 0. && sqrt( mb ) - m_ms < 2.0 * ml )
249 mb = -10.;
250 }
251 mb = sqrt( mb );
252
253 // cout << "b-quark momentum = " << pb << " mass = " << mb << endl;
254
255 // generate a dilepton invariant mass
256
257 double s = 0.0;
258 double smin = 4.0 * ml * ml;
259 double smax = ( mb - m_ms ) * ( mb - m_ms );
260
261 while ( s == 0.0 ) {
262 xbox = EvtRandom::Flat( smin, smax );
264 double prob = m_calcprob->dGdsProb( mb, m_ms, ml, xbox );
265 if ( !( prob >= 0.0 ) && !( prob <= 0.0 ) ) {
266 // EvtGenReport(EVTGEN_INFO,"EvtGen") << "nan from dGdsProb " << prob << " " << mb << " " << m_ms << " " << ml << " " << xbox << std::endl;
267 }
268 if ( ybox < prob )
269 s = xbox;
270 }
271
272 // cout << "dGdsProb(s) = " << m_calcprob->dGdsProb(mb, m_ms, ml, s)
273 // << " for s = " << s << endl;
274
275 // two-body decay of b quark at rest into s quark and dilepton pair:
276 // b -> s (ll)
277
278 EvtVector4R p4sdilep[2];
279
280 double msdilep[2];
281 msdilep[0] = m_ms;
282 msdilep[1] = sqrt( s );
283
284 EvtGenKine::PhaseSpace( 2, msdilep, p4sdilep, mb );
285
286 // generate dilepton decay with the expected asymmetry: (ll) -> l+ l-
287
288 EvtVector4R p4ll[2];
289
290 double mll[2];
291 mll[0] = ml;
292 mll[1] = ml;
293
294 double tmp = 0.0;
295
296 while ( tmp == 0.0 ) {
297 // (ll) -> l+ l- decay in dilepton rest frame
298
299 EvtGenKine::PhaseSpace( 2, mll, p4ll, msdilep[1] );
300
301 // boost to b-quark rest frame
302
303 p4ll[0] = boostTo( p4ll[0], p4sdilep[1] );
304 p4ll[1] = boostTo( p4ll[1], p4sdilep[1] );
305
306 // compute kinematical variable u
307
308 EvtVector4R p4slp = p4sdilep[0] + p4ll[0];
309 EvtVector4R p4sln = p4sdilep[0] + p4ll[1];
310
311 double u = p4slp.mass2() - p4sln.mass2();
312
314
315 double prob = m_calcprob->dGdsdupProb( mb, m_ms, ml, s, u );
316 if ( !( prob >= 0.0 ) && !( prob <= 0.0 ) ) {
317 EvtGenReport( EVTGEN_INFO, "EvtGen" )
318 << "nan from dGdsProb " << prob << " " << mb << " " << m_ms
319 << " " << ml << " " << s << " " << u << std::endl;
320 }
321 if ( prob > m_dGdsdupProbMax && nmsg < 20 ) {
322 EvtGenReport( EVTGEN_INFO, "EvtGen" )
323 << "d2gdsdup GT d2gdsdup_max:" << prob << " "
324 << m_dGdsdupProbMax << " for s = " << s << " u = " << u
325 << " mb = " << mb << endl;
326 nmsg++;
327 }
328 if ( ybox < prob ) {
329 tmp = 1.0;
330 // cout << "dGdsdupProb(s) = " << prob
331 // << " for u = " << u << endl;
332 }
333 }
334
335 // assign 4-momenta to valence quarks inside B meson in B rest frame
336
337 double phi = EvtRandom::Flat( EvtConst::twoPi );
338 double costh = EvtRandom::Flat( -1.0, 1.0 );
339 double sinth = sqrt( 1.0 - costh * costh );
340
341 // b-quark four-momentum in B meson rest frame
342
343 EvtVector4R p4b( sqrt( mb * mb + pb * pb ), pb * sinth * sin( phi ),
344 pb * sinth * cos( phi ), pb * costh );
345
346 // B meson in its rest frame
347 //
348 // EvtVector4R p4B(mB, 0.0, 0.0, 0.0);
349 //
350 // boost B meson to b-quark rest frame
351 //
352 // p4B = boostTo(p4B, p4b);
353 //
354 // cout << " B meson mass in b-quark rest frame = " << p4B.mass() << endl;
355
356 // boost s, l+ and l- to B meson rest frame
357
358 // EvtVector4R p4s = boostTo(p4sdilep[0], p4B);
359 // p4leptonp = boostTo(p4ll[0], p4B);
360 // p4leptonn = boostTo(p4ll[1], p4B);
361
362 EvtVector4R p4s = boostTo( p4sdilep[0], p4b );
363 p4leptonp = boostTo( p4ll[0], p4b );
364 p4leptonn = boostTo( p4ll[1], p4b );
365
366 // spectator quark in B meson rest frame
367
368 EvtVector4R p4q( sqrt( pb * pb + m_mq * m_mq ), -p4b.get( 1 ),
369 -p4b.get( 2 ), -p4b.get( 3 ) );
370
371 // hadron system in B meson rest frame
372
373 p4xhadron = p4s + p4q;
374 xhadronMass = p4xhadron.mass();
375 }
376
377 // initialize the decay products
378
379 xhadron->init( getDaug( 0 ), p4xhadron );
380
381 // For B-bar mesons (i.e. containing a b quark) we have the normal
382 // order of leptons
383 if ( p->getId() == EvtPDL::getId( "anti-B0" ) ||
384 p->getId() == EvtPDL::getId( "B-" ) ) {
385 leptonp->init( getDaug( 1 ), p4leptonp );
386 leptonn->init( getDaug( 2 ), p4leptonn );
387 }
388 // For B mesons (i.e. containing a b-bar quark) we need to flip the
389 // role of the positive and negative leptons in order to produce the
390 // correct forward-backward asymmetry between the two leptons
391 else {
392 leptonp->init( getDaug( 1 ), p4leptonn );
393 leptonn->init( getDaug( 2 ), p4leptonp );
394 }
395
396 return;
397}
EvtRaritaSchwinger boostTo(const EvtRaritaSchwinger &rs, const EvtVector4R p4)
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=nullptr)
Definition EvtReport.cpp:32
@ EVTGEN_INFO
Definition EvtReport.hh:52
@ EVTGEN_ERROR
Definition EvtReport.hh:49
double m_ms
Definition EvtBtoXsll.hh:57
double m_dGdsdupProbMax
Definition EvtBtoXsll.hh:55
void init() override
void initProbMax() override
std::unique_ptr< EvtBtoXsllUtil > m_calcprob
Definition EvtBtoXsll.hh:53
double m_dGdsProbMax
Definition EvtBtoXsll.hh:54
double m_mxmin
Definition EvtBtoXsll.hh:60
double m_pf
Definition EvtBtoXsll.hh:59
void decay(EvtParticle *p) override
double m_mq
Definition EvtBtoXsll.hh:58
double m_mb
Definition EvtBtoXsll.hh:56
EvtDecayBase * clone() const override
std::string getName() const override
static const double twoPi
Definition EvtConst.hh:27
EvtDecayBase()=default
int getNDaug() const
int getNArg() const
double getArg(unsigned int j)
static void findMasses(EvtParticle *p, int ndaugs, const EvtId daugs[10], double masses[10])
bool verbose() const
EvtId getDaug(int i) const
void checkNDaug(int d1, int d2=-1)
void checkNArg(int a1, int a2=-1, int a3=-1, int a4=-1)
const EvtId * getDaugs() const
static double PhaseSpace(int ndaug, double mass[30], EvtVector4R p4[30], double mp)
Definition EvtId.hh:27
static double getMeanMass(EvtId i)
Definition EvtPDL.cpp:306
static EvtId getId(const std::string &name)
Definition EvtPDL.cpp:283
virtual void init(EvtId part_n, const EvtVector4R &p4)=0
EvtId getId() const
EvtParticle * getDaug(const int i)
double mass() const
void makeDaughters(size_t ndaug, const EvtId *id)
static double Flat()
Definition EvtRandom.cpp:95
double mass() const
double get(int i) const
double mass2() const