evtgen is hosted by Hepforge, IPPP Durham
EvtGen  2.0.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
EvtSSDCP.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 
21 #include "EvtGenModels/EvtSSDCP.hh"
22 
23 #include "EvtGenBase/EvtCPUtil.hh"
24 #include "EvtGenBase/EvtConst.hh"
25 #include "EvtGenBase/EvtGenKine.hh"
27 #include "EvtGenBase/EvtPDL.hh"
29 #include "EvtGenBase/EvtPatches.hh"
30 #include "EvtGenBase/EvtRandom.hh"
31 #include "EvtGenBase/EvtReport.hh"
34 
35 #include <stdlib.h>
36 #include <string>
37 using std::endl;
38 
39 std::string EvtSSDCP::getName()
40 {
41  return "SSD_CP";
42 }
43 
45 {
46  return new EvtSSDCP;
47 }
48 
50 {
51  // check that there are 8 or 12 or 14 arguments
52 
53  checkNArg( 14, 12, 8 );
54  checkNDaug( 2 );
55 
58 
59  // Check it is a B0 or B0s
60  if ( ( getParentId() != EvtPDL::getId( "B0" ) ) &&
61  ( getParentId() != EvtPDL::getId( "anti-B0" ) ) &&
62  ( getParentId() != EvtPDL::getId( "B_s0" ) ) &&
63  ( getParentId() != EvtPDL::getId( "anti-B_s0" ) ) ) {
64  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
65  << "EvtSSDCP only decays B0 and B0s" << std::endl;
66  ::abort();
67  }
68 
69  if ( ( !( d1type == EvtSpinType::SCALAR || d2type == EvtSpinType::SCALAR ) ) ||
70  ( !( ( d2type == EvtSpinType::SCALAR ) ||
71  ( d2type == EvtSpinType::VECTOR ) ||
72  ( d2type == EvtSpinType::TENSOR ) ) ) ||
73  ( !( ( d1type == EvtSpinType::SCALAR ) ||
74  ( d1type == EvtSpinType::VECTOR ) ||
75  ( d1type == EvtSpinType::TENSOR ) ) ) ) {
76  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
77  << "EvtSSDCP generator expected "
78  << "one of the daugters to be a scalar, the other either scalar, vector, or tensor, found:"
79  << EvtPDL::name( getDaug( 0 ) ).c_str() << " and "
80  << EvtPDL::name( getDaug( 1 ) ).c_str() << endl;
81  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
82  << "Will terminate execution!" << endl;
83  ::abort();
84  }
85 
86  _dm = getArg( 0 ) / EvtConst::c; //units of 1/mm
87 
88  _dgog = getArg( 1 );
89 
90  _qoverp = getArg( 2 ) * EvtComplex( cos( getArg( 3 ) ), sin( getArg( 3 ) ) );
91  _poverq = 1.0 / _qoverp;
92 
93  _A_f = getArg( 4 ) * EvtComplex( cos( getArg( 5 ) ), sin( getArg( 5 ) ) );
94 
95  _Abar_f = getArg( 6 ) * EvtComplex( cos( getArg( 7 ) ), sin( getArg( 7 ) ) );
96 
97  if ( getNArg() >= 12 ) {
98  _eigenstate = false;
99  _A_fbar = getArg( 8 ) *
100  EvtComplex( cos( getArg( 9 ) ), sin( getArg( 9 ) ) );
101  _Abar_fbar = getArg( 10 ) *
102  EvtComplex( cos( getArg( 11 ) ), sin( getArg( 11 ) ) );
103  } else {
104  //I'm somewhat confused about this. For a CP eigenstate set the
105  //amplitudes to the same. For a non CP eigenstate CPT invariance
106  //is enforced. (ryd)
107  if ( ( getDaug( 0 ) == EvtPDL::chargeConj( getDaug( 0 ) ) &&
108  getDaug( 1 ) == EvtPDL::chargeConj( getDaug( 1 ) ) ) ||
109  ( getDaug( 0 ) == EvtPDL::chargeConj( getDaug( 1 ) ) &&
110  getDaug( 1 ) == EvtPDL::chargeConj( getDaug( 0 ) ) ) ) {
111  _eigenstate = true;
112  } else {
113  _eigenstate = false;
114  _A_fbar = conj( _Abar_f );
115  _Abar_fbar = conj( _A_f );
116  }
117  }
118 
119  //FS: new check for z
120  if ( getNArg() == 14 ) { //FS Set _z parameter if provided else set it 0
121  _z = EvtComplex( getArg( 12 ), getArg( 13 ) );
122  } else {
123  _z = EvtComplex( 0.0, 0.0 );
124  }
125 
126  // FS substituted next 2 lines...
127 
128  //
129  // _gamma=EvtPDL::getctau(EvtPDL::getId("B0")); //units of 1/mm
130  //_dgamma=_gamma*0.5*_dgog;
131  //
132  // ...with:
133 
134  if ( ( getParentId() == EvtPDL::getId( "B0" ) ) ||
135  ( getParentId() == EvtPDL::getId( "anti-B0" ) ) ) {
136  _gamma = 1. / EvtPDL::getctau( EvtPDL::getId( "B0" ) ); //gamma/c (1/mm)
137  } else {
138  _gamma = 1. / EvtPDL::getctau( EvtPDL::getId( "B_s0" ) );
139  }
140 
141  _dgamma = _gamma * _dgog; //dgamma/c (1/mm)
142 
143  if ( verbose() ) {
144  EvtGenReport( EVTGEN_INFO, "EvtGen" )
145  << "SSD_CP will generate CP/CPT violation:" << endl
146  << endl
147  << " " << EvtPDL::name( getParentId() ).c_str() << " --> "
148  << EvtPDL::name( getDaug( 0 ) ).c_str() << " + "
149  << EvtPDL::name( getDaug( 1 ) ).c_str() << endl
150  << endl
151  << "using parameters:" << endl
152  << endl
153  << " delta(m) = " << _dm << " hbar/ps" << endl
154  << "dGamma = " << _dgamma << " ps-1" << endl
155  << " q/p = " << _qoverp << endl
156  << " z = " << _z << endl
157  << " tau = " << 1. / _gamma << " ps" << endl;
158  }
159 }
160 
162 {
163  double theProbMax = abs( _A_f ) * abs( _A_f ) +
164  abs( _Abar_f ) * abs( _Abar_f ) +
165  abs( _A_fbar ) * abs( _A_fbar ) +
166  abs( _Abar_fbar ) * abs( _Abar_fbar );
167 
168  if ( _eigenstate )
169  theProbMax *= 2;
170 
173  if ( d1type == EvtSpinType::TENSOR || d2type == EvtSpinType::TENSOR )
174  theProbMax *= 10;
175 
176  setProbMax( theProbMax );
177 }
178 
180 {
181  static EvtId B0 = EvtPDL::getId( "B0" );
182  static EvtId B0B = EvtPDL::getId( "anti-B0" );
183 
184  static EvtId B0s = EvtPDL::getId( "B_s0" );
185  static EvtId B0Bs = EvtPDL::getId( "anti-B_s0" );
186 
187  double t;
188  EvtId other_b;
189  EvtId daugs[2];
190 
191  int flip = 0;
192  if ( !_eigenstate ) {
193  if ( EvtRandom::Flat( 0.0, 1.0 ) < 0.5 )
194  flip = 1;
195  }
196 
197  if ( !flip ) {
198  daugs[0] = getDaug( 0 );
199  daugs[1] = getDaug( 1 );
200  } else {
201  daugs[0] = EvtPDL::chargeConj( getDaug( 0 ) );
202  daugs[1] = EvtPDL::chargeConj( getDaug( 1 ) );
203  }
204 
205  EvtParticle* d;
206  p->initializePhaseSpace( 2, daugs );
207 
208  EvtComplex amp;
209 
210  EvtCPUtil::getInstance()->OtherB( p, t, other_b, 0.5 ); // t is c*Dt (mm)
211  // EvtIncoherentMixing::OtherB( p , t , other_b , 0.5 ) ;
212 
213  //if (flip) t=-t;
214 
215  //FS We assume DGamma=GammaLow-GammaHeavy and Dm=mHeavy-mLow
216  EvtComplex expH = exp( -EvtComplex( -0.25 * _dgamma * t, 0.5 * _dm * t ) );
217  EvtComplex expL = exp( EvtComplex( -0.25 * _dgamma * t, 0.5 * _dm * t ) );
218  //FS Definition of gp and gm
219  EvtComplex gp = 0.5 * ( expL + expH );
220  EvtComplex gm = 0.5 * ( expL - expH );
221  //FS Calculation os sqrt(1-z^2)
222  EvtComplex sqz = sqrt( abs( 1 - _z * _z ) ) *
223  exp( EvtComplex( 0, arg( 1 - _z * _z ) / 2 ) );
224 
225  //EvtComplex BB=0.5*(expL+expH); // <B0|B0(t)>
226  //EvtComplex barBB=_qoverp*0.5*(expL-expH); // <B0bar|B0(t)>
227  //EvtComplex BbarB=_poverq*0.5*(expL-expH); // <B0|B0bar(t)>
228  //EvtComplex barBbarB=BB; // <B0bar|B0bar(t)>
229  // FS redefinition of these guys... (See BAD #188 eq.35 for ref.)
230  // q/p is taken as in the BaBar Phys. Book (opposite sign wrt ref.)
231  EvtComplex BB = gp + _z * gm; // <B0|B0(t)>
232  EvtComplex barBB = sqz * _qoverp * gm; // <B0bar|B0(t)>
233  EvtComplex BbarB = sqz * _poverq * gm; // <B0|B0bar(t)>
234  EvtComplex barBbarB = gp - _z * gm; // <B0bar|B0bar(t)>
235 
236  if ( !flip ) {
237  if ( other_b == B0B || other_b == B0Bs ) {
238  //at t=0 we have a B0
239  //EvtGenReport(EVTGEN_INFO,"EvtGen") << "B0B"<<endl;
240  amp = BB * _A_f + barBB * _Abar_f;
241  //std::cout << "noflip B0B tag:"<<amp<<std::endl;
242  //amp=0.0;
243  }
244  if ( other_b == B0 || other_b == B0s ) {
245  //EvtGenReport(EVTGEN_INFO,"EvtGen") << "B0"<<endl;
246  amp = BbarB * _A_f + barBbarB * _Abar_f;
247  }
248  } else {
249  if ( other_b == B0 || other_b == B0s ) {
250  amp = BbarB * _A_fbar + barBbarB * _Abar_fbar;
251  //std::cout << "flip B0 tag:"<<amp<<std::endl;
252  //amp=0.0;
253  }
254  if ( other_b == B0B || other_b == B0Bs ) {
255  amp = BB * _A_fbar + barBB * _Abar_fbar;
256  }
257  }
258 
259  EvtVector4R p4_parent = p->getP4Restframe();
260  double m_parent = p4_parent.mass();
261 
263 
264  EvtVector4R momv;
265  EvtVector4R moms;
266 
267  if ( d2type == EvtSpinType::SCALAR ) {
268  d2type = EvtPDL::getSpinType( getDaug( 0 ) );
269  d = p->getDaug( 0 );
270  momv = d->getP4();
271  moms = p->getDaug( 1 )->getP4();
272  } else {
273  d = p->getDaug( 1 );
274  momv = d->getP4();
275  moms = p->getDaug( 0 )->getP4();
276  }
277 
278  if ( d2type == EvtSpinType::SCALAR ) {
279  vertex( amp );
280  }
281 
282  if ( d2type == EvtSpinType::VECTOR ) {
283  double norm = momv.mass() / ( momv.d3mag() * p->mass() );
284 
285  //std::cout << amp << " " << norm << " " << p4_parent << d->getP4()<< std::endl;
286  // std::cout << EvtPDL::name(d->getId()) << " " << EvtPDL::name(p->getDaug(0)->getId()) <<
287  // " 1and2 " << EvtPDL::name(p->getDaug(1)->getId()) << std::endl;
288  //std::cout << d->eps(0) << std::endl;
289  //std::cout << d->epsParent(0) << std::endl;
290  vertex( 0, amp * norm * p4_parent * ( d->epsParent( 0 ) ) );
291  vertex( 1, amp * norm * p4_parent * ( d->epsParent( 1 ) ) );
292  vertex( 2, amp * norm * p4_parent * ( d->epsParent( 2 ) ) );
293  }
294 
295  if ( d2type == EvtSpinType::TENSOR ) {
296  double norm = d->mass() * d->mass() /
297  ( m_parent * d->getP4().d3mag() * d->getP4().d3mag() );
298 
299  vertex( 0, amp * norm * d->epsTensorParent( 0 ).cont1( p4_parent ) *
300  p4_parent );
301  vertex( 1, amp * norm * d->epsTensorParent( 1 ).cont1( p4_parent ) *
302  p4_parent );
303  vertex( 2, amp * norm * d->epsTensorParent( 2 ).cont1( p4_parent ) *
304  p4_parent );
305  vertex( 3, amp * norm * d->epsTensorParent( 3 ).cont1( p4_parent ) *
306  p4_parent );
307  vertex( 4, amp * norm * d->epsTensorParent( 4 ).cont1( p4_parent ) *
308  p4_parent );
309  }
310 
311  return;
312 }
313 
314 std::string EvtSSDCP::getParamName( int i )
315 {
316  switch ( i ) {
317  case 0:
318  return "deltaM";
319  case 1:
320  return "deltaGammaOverGamma";
321  case 2:
322  return "qOverP";
323  case 3:
324  return "qOverPPhase";
325  case 4:
326  return "Af";
327  case 5:
328  return "AfPhase";
329  case 6:
330  return "Abarf";
331  case 7:
332  return "AbarfPhase";
333  case 8:
334  return "Afbar";
335  case 9:
336  return "AfbarPhase";
337  case 10:
338  return "Abarfbar";
339  case 11:
340  return "AbarfbarPhase";
341  case 12:
342  return "Z";
343  case 13:
344  return "ZPhase";
345  default:
346  return "";
347  }
348 }
349 
350 std::string EvtSSDCP::getParamDefault( int i )
351 {
352  switch ( i ) {
353  case 3:
354  return "0.0";
355  case 4:
356  return "1.0";
357  case 5:
358  return "0.0";
359  case 6:
360  return "1.0";
361  case 7:
362  return "0.0";
363  default:
364  return "";
365  }
366 }
virtual EvtTensor4C epsTensorParent(int i) const
EvtDecayBase * clone() override
Definition: EvtSSDCP.cpp:44
EvtComplex _Abar_fbar
Definition: EvtSSDCP.hh:62
EvtComplex _A_fbar
Definition: EvtSSDCP.hh:61
static std::string name(EvtId i)
Definition: EvtPDL.cpp:382
double _dm
Definition: EvtSSDCP.hh:47
double getArg(unsigned int j)
static EvtSpinType::spintype getSpinType(EvtId i)
Definition: EvtPDL.cpp:377
EvtComplex _z
Definition: EvtSSDCP.hh:53
double _gamma
Definition: EvtSSDCP.hh:66
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=0)
Definition: EvtReport.cpp:33
bool _eigenstate
Definition: EvtSSDCP.hh:69
Evt3Rank3C conj(const Evt3Rank3C &t2)
Definition: Evt3Rank3C.cpp:172
double mass() const
Definition: EvtVector4R.cpp:49
static double getctau(EvtId i)
Definition: EvtPDL.cpp:357
EvtVector4C cont1(const EvtVector4C &v4) const
EvtComplex _poverq
Definition: EvtSSDCP.hh:52
void decay(EvtParticle *p) override
Definition: EvtSSDCP.cpp:179
std::string getParamName(int i) override
Definition: EvtSSDCP.cpp:314
void OtherB(EvtParticle *p, double &t, EvtId &otherb)
Definition: EvtCPUtil.cpp:372
EvtComplex _Abar_f
Definition: EvtSSDCP.hh:59
void setProbMax(double prbmx)
Definition: EvtId.hh:27
double _dgog
Definition: EvtSSDCP.hh:49
EvtId getParentId() const
Definition: EvtDecayBase.hh:61
void vertex(const EvtComplex &amp)
Definition: EvtDecayAmp.hh:37
double initializePhaseSpace(unsigned int numdaughter, EvtId *daughters, bool forceResetMasses=false, double poleSize=-1., int whichTwo1=0, int whichTwo2=1)
virtual EvtVector4C epsParent(int i) const
void checkNDaug(int d1, int d2=-1)
static double Flat()
Definition: EvtRandom.cpp:72
void checkNArg(int a1, int a2=-1, int a3=-1, int a4=-1)
static const double c
Definition: EvtConst.hh:30
double abs(const EvtComplex &c)
Definition: EvtComplex.hh:201
void initProbMax() override
Definition: EvtSSDCP.cpp:161
static EvtId getId(const std::string &name)
Definition: EvtPDL.cpp:287
const EvtVector4R & getP4() const
double mass() const
double d3mag() const
EvtComplex exp(const EvtComplex &c)
Definition: EvtComplex.hh:240
static EvtCPUtil * getInstance()
Definition: EvtCPUtil.cpp:43
int verbose() const
Definition: EvtDecayBase.hh:82
EvtParticle * getDaug(int i)
Definition: EvtParticle.cpp:91
EvtComplex _qoverp
Definition: EvtSSDCP.hh:51
EvtComplex _A_f
Definition: EvtSSDCP.hh:58
std::string getName() override
Definition: EvtSSDCP.cpp:39
void init() override
Definition: EvtSSDCP.cpp:49
double _dgamma
Definition: EvtSSDCP.hh:67
double arg(const EvtComplex &c)
Definition: EvtComplex.hh:214
EvtVector4R getP4Restframe() const
int getNArg() const
Definition: EvtDecayBase.hh:68
static EvtId chargeConj(EvtId id)
Definition: EvtPDL.cpp:207
std::string getParamDefault(int i) override
Definition: EvtSSDCP.cpp:350
EvtId getDaug(int i) const
Definition: EvtDecayBase.hh:67