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.
EvtVSSBMixCPT.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 
23 #include "EvtGenBase/EvtConst.hh"
24 #include "EvtGenBase/EvtGenKine.hh"
25 #include "EvtGenBase/EvtId.hh"
26 #include "EvtGenBase/EvtPDL.hh"
28 #include "EvtGenBase/EvtPatches.hh"
29 #include "EvtGenBase/EvtRandom.hh"
30 #include "EvtGenBase/EvtReport.hh"
32 
33 #include <stdlib.h>
34 #include <string>
35 using std::endl;
36 
38 {
39  return "VSS_BMIX";
40 }
41 
43 {
44  return new EvtVSSBMixCPT;
45 }
46 
48 {
49  if ( getNArg() > 4 )
50  checkNArg( 14, 12, 8 );
51 
52  if ( getNArg() < 1 ) {
53  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
54  << "EvtVSSBMix generator expected "
55  << " at least 1 argument (deltam) but found:" << getNArg() << endl;
56  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
57  << "Will terminate execution!" << endl;
58  ::abort();
59  }
60  // check that we are asked to produced exactly 2 daughters
61  //4 are allowed if they are aliased..
62  checkNDaug( 2, 4 );
63 
64  if ( getNDaug() == 4 ) {
65  if ( getDaug( 0 ) != getDaug( 2 ) || getDaug( 1 ) != getDaug( 3 ) ) {
66  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
67  << "EvtVSSBMixCPT generator allows "
68  << " 4 daughters only if 1=3 and 2=4"
69  << " (but 3 and 4 are aliased " << endl;
70  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
71  << "Will terminate execution!" << endl;
72  ::abort();
73  }
74  }
75  // check that we are asked to decay a vector particle into a pair
76  // of scalar particles
77 
79 
82 
83  // check that our daughter particles are charge conjugates of each other
84  if ( !( EvtPDL::chargeConj( getDaug( 0 ) ) == getDaug( 1 ) ) ) {
85  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
86  << "EvtVSSBMixCPT generator expected daughters "
87  << "to be charge conjugate." << endl
88  << " Found " << EvtPDL::name( getDaug( 0 ) ).c_str() << " and "
89  << EvtPDL::name( getDaug( 1 ) ).c_str() << endl;
90  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
91  << "Will terminate execution!" << endl;
92  ::abort();
93  }
94  // check that both daughter particles have the same lifetime
95  if ( EvtPDL::getctau( getDaug( 0 ) ) != EvtPDL::getctau( getDaug( 1 ) ) ) {
96  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
97  << "EvtVSSBMixCPT generator expected daughters "
98  << "to have the same lifetime." << endl
99  << " Found ctau = " << EvtPDL::getctau( getDaug( 0 ) )
100  << " mm and " << EvtPDL::getctau( getDaug( 1 ) ) << " mm" << endl;
101  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
102  << "Will terminate execution!" << endl;
103  ::abort();
104  }
105  // precompute quantities that will be used to generate events
106  // and print out a summary of parameters for this decay
107 
108  // mixing frequency in hbar/mm
109  _freq = getArg( 0 ) / EvtConst::c;
110 
111  // deltaG
112  double gamma = 1 / EvtPDL::getctau( getDaug( 0 ) ); // gamma/c (1/mm)
113  _dGamma = 0.0;
114  double dgog = 0.0;
115  if ( getNArg() > 1 ) {
116  dgog = getArg( 1 );
117  _dGamma = dgog * gamma;
118  }
119  // q/p
120  _qoverp = EvtComplex( 1.0, 0.0 );
121  if ( getNArg() > 2 ) {
122  _qoverp = EvtComplex( getArg( 2 ), 0.0 );
123  }
124  if ( getNArg() > 3 ) {
125  _qoverp = getArg( 2 ) *
126  EvtComplex( cos( getArg( 3 ) ), sin( getArg( 3 ) ) );
127  }
128  _poverq = 1.0 / _qoverp;
129 
130  // decay amplitudes
131  _A_f = EvtComplex( 1.0, 0.0 );
132  _Abar_f = EvtComplex( 0.0, 0.0 );
133  _A_fbar = _Abar_f; // CPT conservation
134  _Abar_fbar = _A_f; // CPT conservation
135  if ( getNArg() > 4 ) {
136  _A_f = getArg( 4 ) *
137  EvtComplex( cos( getArg( 5 ) ),
138  sin( getArg( 5 ) ) ); // this allows for DCSD
139  _Abar_f = getArg( 6 ) *
140  EvtComplex( cos( getArg( 7 ) ),
141  sin( getArg( 7 ) ) ); // this allows for DCSD
142  if ( getNArg() > 8 ) {
143  // CPT violation in decay
144  _A_fbar = getArg( 8 ) *
145  EvtComplex( cos( getArg( 9 ) ), sin( getArg( 9 ) ) );
146  _Abar_fbar = getArg( 10 ) *
147  EvtComplex( cos( getArg( 11 ) ), sin( getArg( 11 ) ) );
148  } else {
149  // CPT conservation in decay
150  _A_fbar = _Abar_f;
151  _Abar_fbar = _A_f;
152  }
153  }
154 
155  // CPT violation in mixing
156  _z = EvtComplex( 0.0, 0.0 );
157  if ( getNArg() > 12 ) {
158  _z = EvtComplex( getArg( 12 ), getArg( 13 ) );
159  }
160 
161  // some printout
162  double tau = 1e12 * EvtPDL::getctau( getDaug( 0 ) ) / EvtConst::c; // in ps
163  double dm = 1e-12 * getArg( 0 ); // B0/anti-B0 mass difference in hbar/ps
164  double x = dm * tau;
165  double y = dgog * 0.5; //y=dgamma/(2*gamma)
166  double qop2 = abs( _qoverp * _qoverp );
167  _chib0_b0bar = qop2 * ( x * x + y * y ) /
168  ( qop2 * ( x * x + y * y ) + 2 + x * x -
169  y * y ); // does not include CPT in mixing
170  _chib0bar_b0 = ( 1 / qop2 ) * ( x * x + y * y ) /
171  ( ( 1 / qop2 ) * ( x * x + y * y ) + 2 + x * x -
172  y * y ); // does not include CPT in mixing
173 
174  if ( verbose() ) {
175  EvtGenReport( EVTGEN_INFO, "EvtGen" )
176  << "VSS_BMIXCPT will generate mixing and CPT/CP effects in mixing:"
177  << endl
178  << endl
179  << " " << EvtPDL::name( getParentId() ).c_str() << " --> "
180  << EvtPDL::name( getDaug( 0 ) ).c_str() << " + "
181  << EvtPDL::name( getDaug( 1 ) ).c_str() << endl
182  << endl
183  << "using parameters:" << endl
184  << endl
185  << " delta(m) = " << dm << " hbar/ps" << endl
186  << " _freq = " << _freq << " hbar/mm" << endl
187  << " dgog = " << dgog << endl
188  << " dGamma = " << _dGamma << " hbar/mm" << endl
189  << " q/p = " << _qoverp << endl
190  << " z = " << _z << endl
191  << " tau = " << tau << " ps" << endl
192  << " x = " << x << endl
193  << " chi(B0->B0bar) = " << _chib0_b0bar << endl
194  << " chi(B0bar->B0) = " << _chib0bar_b0 << endl
195  << " Af = " << _A_f << endl
196  << " Abarf = " << _Abar_f << endl
197  << " Afbar = " << _A_fbar << endl
198  << " Abarfbar = " << _Abar_fbar << endl
199  << endl;
200  }
201 }
202 
204 {
205  // this value is ok for reasonable values of all the parameters
206  setProbMax( 4.0 );
207 }
208 
210 {
211  static EvtId B0 = EvtPDL::getId( "B0" );
212  static EvtId B0B = EvtPDL::getId( "anti-B0" );
213 
214  // generate a final state according to phase space
215 
216  double rndm = EvtRandom::random();
217 
218  if ( getNDaug() == 4 ) {
219  EvtId tempDaug[2];
220 
221  if ( rndm < 0.5 ) {
222  tempDaug[0] = getDaug( 0 );
223  tempDaug[1] = getDaug( 3 );
224  } else {
225  tempDaug[0] = getDaug( 2 );
226  tempDaug[1] = getDaug( 1 );
227  }
228 
229  p->initializePhaseSpace( 2, tempDaug );
230  } else { //nominal case.
231  p->initializePhaseSpace( 2, getDaugs() );
232  }
233 
234  EvtParticle *s1, *s2;
235 
236  s1 = p->getDaug( 0 );
237  s2 = p->getDaug( 1 );
238  //delete any daughters - if there are daughters, they
239  //are from the initialization and will be redone later
240  if ( s1->getNDaug() > 0 ) {
241  s1->deleteDaughters();
242  }
243  if ( s2->getNDaug() > 0 ) {
244  s2->deleteDaughters();
245  }
246 
247  EvtVector4R p1 = s1->getP4();
248  EvtVector4R p2 = s2->getP4();
249 
250  // throw a random number to decide if this final state should be mixed
251  rndm = EvtRandom::random();
252  int mixed = ( rndm < 0.5 ) ? 1 : 0;
253 
254  // if this decay is mixed, choose one of the 2 possible final states
255  // with equal probability (re-using the same random number)
256  if ( mixed == 1 ) {
257  EvtId mixedId = ( rndm < 0.25 ) ? getDaug( 0 ) : getDaug( 1 );
258  EvtId mixedId2 = mixedId;
259  if ( getNDaug() == 4 && rndm < 0.25 )
260  mixedId2 = getDaug( 2 );
261  if ( getNDaug() == 4 && rndm > 0.25 )
262  mixedId2 = getDaug( 3 );
263  s1->init( mixedId, p1 );
264  s2->init( mixedId2, p2 );
265  }
266 
267  // if this decay is unmixed, choose one of the 2 possible final states
268  // with equal probability (re-using the same random number)
269  if ( mixed == 0 ) {
270  EvtId unmixedId = ( rndm < 0.75 ) ? getDaug( 0 ) : getDaug( 1 );
271  EvtId unmixedId2 = ( rndm < 0.75 ) ? getDaug( 1 ) : getDaug( 0 );
272  if ( getNDaug() == 4 && rndm < 0.75 )
273  unmixedId2 = getDaug( 3 );
274  if ( getNDaug() == 4 && rndm > 0.75 )
275  unmixedId2 = getDaug( 2 );
276  s1->init( unmixedId, p1 );
277  s2->init( unmixedId2, p2 );
278  }
279 
280  // choose a decay time for each final state particle using the
281  // lifetime (which must be the same for both particles) in pdt.table
282  // and calculate the lifetime difference for this event
283  s1->setLifetime();
284  s2->setLifetime();
285  double dct = s1->getLifetime() - s2->getLifetime(); // in mm
286 
287  // Convention: _dGamma=GammaLight-GammaHeavy
288  EvtComplex exp1( -0.25 * _dGamma * dct, 0.5 * _freq * dct );
289 
290  /*
291  //Find the flavor of the B that decayed first.
292  EvtId firstDec = (dct > 0 ) ? s2->getId() : s1->getId();
293 
294  //This tags the flavor of the other particle at that time.
295  EvtId stateAtDeltaTeq0 = ( firstDec==B0 ) ? B0B : B0;
296  */
297  EvtId stateAtDeltaTeq0 = ( s2->getId() == B0 ) ? B0B : B0;
298 
299  // calculate the oscillation amplitude, based on wether this event is mixed or not
300  EvtComplex osc_amp;
301 
302  //define some useful functions: (see BAD #188 eq. 39 for ref.)
303  EvtComplex gp = 0.5 * ( exp( -1.0 * exp1 ) + exp( exp1 ) );
304  EvtComplex gm = 0.5 * ( exp( -1.0 * exp1 ) - exp( exp1 ) );
305  EvtComplex sqz = sqrt( abs( 1 - _z * _z ) ) *
306  exp( EvtComplex( 0, arg( 1 - _z * _z ) / 2 ) );
307 
308  EvtComplex BB = gp + _z * gm; // <B0|B0(t)>
309  EvtComplex barBB = -sqz * _qoverp * gm; // <B0bar|B0(t)>
310  EvtComplex BbarB = -sqz * _poverq * gm; // <B0|B0bar(t)>
311  EvtComplex barBbarB = gp - _z * gm; // <B0bar|B0bar(t)>
312 
313  //
314  if ( !mixed && stateAtDeltaTeq0 == B0 ) {
315  osc_amp = BB * _A_f + barBB * _Abar_f;
316  }
317  if ( !mixed && stateAtDeltaTeq0 == B0B ) {
318  osc_amp = barBbarB * _Abar_fbar + BbarB * _A_fbar;
319  }
320 
321  if ( mixed && stateAtDeltaTeq0 == B0 ) {
322  osc_amp = barBB * _Abar_fbar + BB * _A_fbar;
323  }
324  if ( mixed && stateAtDeltaTeq0 == B0B ) {
325  osc_amp = BbarB * _A_f + barBbarB * _Abar_f;
326  }
327 
328  // store the amplitudes for each parent spin basis state
329  double norm = 1.0 / p1.d3mag();
330  vertex( 0, norm * osc_amp * p1 * ( p->eps( 0 ) ) );
331  vertex( 1, norm * osc_amp * p1 * ( p->eps( 1 ) ) );
332  vertex( 2, norm * osc_amp * p1 * ( p->eps( 2 ) ) );
333 
334  return;
335 }
336 
337 std::string EvtVSSBMixCPT::getParamName( int i )
338 {
339  switch ( i ) {
340  case 0:
341  return "deltaM";
342  case 1:
343  return "deltaGammaOverGamma";
344  case 2:
345  return "qOverP";
346  case 3:
347  return "qOverPPhase";
348  case 4:
349  return "Af";
350  case 5:
351  return "AfPhase";
352  case 6:
353  return "Abarf";
354  case 7:
355  return "AbarfPhase";
356  case 8:
357  return "Afbar";
358  case 9:
359  return "AfbarPhase";
360  case 10:
361  return "Abarfbar";
362  case 11:
363  return "AbarfbarPhase";
364  case 12:
365  return "Z";
366  case 13:
367  return "ZPhase";
368  default:
369  return "";
370  }
371 }
372 
373 std::string EvtVSSBMixCPT::getParamDefault( int i )
374 {
375  switch ( i ) {
376  case 3:
377  return "0.0";
378  case 4:
379  return "1.0";
380  case 5:
381  return "0.0";
382  case 6:
383  return "1.0";
384  case 7:
385  return "0.0";
386  default:
387  return "";
388  }
389 }
EvtComplex _poverq
double _chib0bar_b0
std::string getParamName(int i) override
static std::string name(EvtId i)
Definition: EvtPDL.cpp:382
double _chib0_b0bar
virtual EvtVector4C eps(int i) const
double getArg(unsigned int j)
EvtComplex _Abar_fbar
static double random()
Definition: EvtRandom.cpp:42
void decay(EvtParticle *p) override
EvtComplex _Abar_f
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=0)
Definition: EvtReport.cpp:33
virtual void init(EvtId part_n, const EvtVector4R &p4)=0
static double getctau(EvtId i)
Definition: EvtPDL.cpp:357
EvtId getId() const
EvtComplex _qoverp
void setLifetime(double tau)
EvtId * getDaugs()
Definition: EvtDecayBase.hh:66
void setProbMax(double prbmx)
Definition: EvtId.hh:27
size_t getNDaug() const
EvtId getParentId() const
Definition: EvtDecayBase.hh:61
void vertex(const EvtComplex &amp)
Definition: EvtDecayAmp.hh:37
void init() override
EvtComplex _z
double initializePhaseSpace(unsigned int numdaughter, EvtId *daughters, bool forceResetMasses=false, double poleSize=-1., int whichTwo1=0, int whichTwo2=1)
void deleteDaughters(bool keepChannel=false)
void checkNDaug(int d1, int d2=-1)
void checkSpinParent(EvtSpinType::spintype sp)
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
static EvtId getId(const std::string &name)
Definition: EvtPDL.cpp:287
const EvtVector4R & getP4() const
void checkSpinDaughter(int d1, EvtSpinType::spintype sp)
double d3mag() const
int getNDaug() const
Definition: EvtDecayBase.hh:65
EvtComplex exp(const EvtComplex &c)
Definition: EvtComplex.hh:240
double getLifetime()
void initProbMax() override
int verbose() const
Definition: EvtDecayBase.hh:82
EvtParticle * getDaug(int i)
Definition: EvtParticle.cpp:91
std::string getParamDefault(int i) override
double arg(const EvtComplex &c)
Definition: EvtComplex.hh:214
int getNArg() const
Definition: EvtDecayBase.hh:68
static EvtId chargeConj(EvtId id)
Definition: EvtPDL.cpp:207
EvtComplex _A_fbar
std::string getName() override
EvtComplex _A_f
EvtDecayBase * clone() override
EvtId getDaug(int i) const
Definition: EvtDecayBase.hh:67