BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
EvtCPUtil.cc
Go to the documentation of this file.
1//--------------------------------------------------------------------------
2//
3// Environment:
4// This software is part of the EvtGen package developed jointly
5// for the BaBar and CLEO collaborations. If you use all or part
6// of it, please give an appropriate acknowledgement.
7//
8// Copyright Information: See EvtGen/COPYRIGHT
9// Copyright (C) 1998 Caltech, UCSB
10//
11// Module: EvtCPUtil.cc
12//
13// Description: Utilities needed for generation of CP violating
14// decays.
15//
16// Modification history:
17//
18// RYD March 24, 1998 Module created
19//
20//------------------------------------------------------------------------
21//
22#include "EvtCPUtil.hh"
23#include "EvtConst.hh"
24#include "EvtPDL.hh"
25#include "EvtParticle.hh"
26#include "EvtPatches.hh"
27#include "EvtRandom.hh"
28#include "EvtReport.hh"
29#include "EvtScalarParticle.hh"
30#include "EvtSymTable.hh"
31
32#include <assert.h>
33#include <stdlib.h>
34using std::endl;
35
36// added two functions for finding the fraction of B0 tags for decays into
37// both CP eigenstates and non-CP eigenstates -- NK, Jan. 27th, 1998
38
39void EvtCPUtil::fractB0CP( EvtComplex Af, EvtComplex Abarf, double deltam, double beta,
40 double& fract ) {
41 // this function returns the number of B0 tags for decays into CP-eigenstates
42 //(the "probB0" in the new EvtOtherB)
43
44 // double gamma_B = EvtPDL::getWidth(B0);
45 // double xd = deltam/gamma_B;
46 // double xd = 0.65;
47 double ratio = 1 / ( 1 + 0.65 * 0.65 );
48
49 EvtComplex rf, rbarf;
50
51 rf = EvtComplex( cos( 2.0 * beta ), sin( 2.0 * beta ) ) * Abarf / Af;
52 rbarf = EvtComplex( 1.0 ) / rf;
53
54 double A2 = real( Af ) * real( Af ) + imag( Af ) * imag( Af );
55 double Abar2 = real( Abarf ) * real( Abarf ) + imag( Abarf ) * imag( Abarf );
56
57 double rf2 = real( rf ) * real( rf ) + imag( rf ) * imag( rf );
58 double rbarf2 = real( rbarf ) * real( rbarf ) + imag( rbarf ) * imag( rbarf );
59
60 fract = ( Abar2 * ( 1 + rbarf2 + ( 1 - rbarf2 ) * ratio ) ) /
61 ( Abar2 * ( 1 + rbarf2 + ( 1 - rbarf2 ) * ratio ) +
62 A2 * ( 1 + rf2 + ( 1 - rf2 ) * ratio ) );
63 return;
64}
66 EvtComplex Abarfbar, double deltam, double beta, int flip,
67 double& fract ) {
68
69 // this function returns the number of B0 tags for decays into non-CP eigenstates
70 //(the "probB0" in the new EvtOtherB)
71 // this needs more thought...
72
73 // double gamma_B = EvtPDL::getWidth(B0);
74 // report(INFO,"EvtGen") << "gamma " << gamma_B<< endl;
75 // double xd = deltam/gamma_B;
76
77 // why is the width of B0 0 in PDL??
78
79 double xd = 0.65;
80 double gamma_B = deltam / xd;
81 double IAf, IAfbar, IAbarf, IAbarfbar;
82 EvtComplex rf, rfbar, rbarf, rbarfbar;
83 double rf2, rfbar2, rbarf2, rbarfbar2;
84 double Af2, Afbar2, Abarf2, Abarfbar2;
85
86 rf = EvtComplex( cos( 2.0 * beta ), sin( 2.0 * beta ) ) * Abarf / Af;
87 rfbar = EvtComplex( cos( 2.0 * beta ), sin( 2.0 * beta ) ) * Abarfbar / Afbar;
88 rbarf = EvtComplex( cos( -2.0 * beta ), sin( -2.0 * beta ) ) * Af / Abarf;
89 rbarfbar = EvtComplex( cos( -2.0 * beta ), sin( -2.0 * beta ) ) * Afbar / Abarfbar;
90
91 rf2 = real( rf ) * real( rf ) + imag( rf ) * imag( rf );
92 rfbar2 = real( rfbar ) * real( rfbar ) + imag( rfbar ) * imag( rfbar );
93 rbarf2 = real( rbarf ) * real( rbarf ) + imag( rbarf ) * imag( rbarf );
94 rbarfbar2 = real( rbarfbar ) * real( rbarfbar ) + imag( rbarfbar ) * imag( rbarfbar );
95
96 Af2 = real( Af ) * real( Af ) + imag( Af ) * imag( Af );
97 Afbar2 = real( Afbar ) * real( Afbar ) + imag( Afbar ) * imag( Afbar );
98 Abarf2 = real( Abarf ) * real( Abarf ) + imag( Abarf ) * imag( Abarf );
99 Abarfbar2 = real( Abarfbar ) * real( Abarfbar ) + imag( Abarfbar ) * imag( Abarfbar );
100
101 //
102 // IAf = integral(gamma(B0->f)), etc.
103 //
104
105 IAf = ( Af2 / ( 2 * gamma_B ) ) * ( 1 + rf2 + ( 1 - rf2 ) / ( 1 + xd * xd ) );
106 IAfbar = ( Afbar2 / ( 2 * gamma_B ) ) * ( 1 + rfbar2 + ( 1 - rfbar2 ) / ( 1 + xd * xd ) );
107 IAbarf = ( Abarf2 / ( 2 * gamma_B ) ) * ( 1 + rbarf2 + ( 1 - rbarf2 ) / ( 1 + xd * xd ) );
108 IAbarfbar = ( Abarfbar2 / ( 2 * gamma_B ) ) *
109 ( 1 + rbarfbar2 + ( 1 - rbarfbar2 ) / ( 1 + xd * xd ) );
110
111 // flip specifies the relative fraction of fbar events
112
113 fract = IAbarf / ( IAbarf + IAf ) + flip * IAbarfbar / ( IAfbar + IAbarfbar );
114
115 return;
116}
117
118void EvtCPUtil::OtherB( EvtParticle* p, double& t, EvtId& otherb, double probB0 ) {
119
120 // Can not call this recursively!!!
121 static int entryCount = 0;
122 entryCount++;
123
124 // added by Lange Jan4,2000
125 static EvtId B0B = EvtPDL::getId( "anti-B0" );
126 static EvtId B0 = EvtPDL::getId( "B0" );
127
128 int isB0 = EvtRandom::Flat( 0.0, 1.0 ) < probB0;
129
130 int idaug;
131
132 p->setLifetime();
133
134 // now get the time between the decay of this B and the other B!
135
136 EvtParticle* parent = p->getParent();
137
138 EvtParticle* other;
139
140 if ( parent == 0 )
141 {
142 // report(ERROR,"EvtGen") <<
143 // "Warning CP violation with B having no parent!"<<endl;
144 p->setLifetime();
145 t = p->getLifetime();
146 if ( p->getId() == B0 ) otherb = B0B;
147 if ( p->getId() == B0B ) otherb = B0;
148 entryCount--;
149 return;
150 }
151 else
152 {
153 if ( parent->getDaug( 0 ) != p )
154 {
155 other = parent->getDaug( 0 );
156 idaug = 0;
157 }
158 else
159 {
160 other = parent->getDaug( 1 );
161 idaug = 1;
162 }
163 }
164
165 if ( parent != 0 )
166 {
167
168 // if (entryCount>1){
169 // report(INFO,"EvtGen") << "Double CP decay:"<<entryCount<<endl;
170 // }
171
172 // kludge!! Lange Mar21, 2003
173 // if the other B is an alias... don't change the flavor..
174 if ( other->getId().isAlias() )
175 {
176 OtherB( p, t, otherb );
177 entryCount--;
178 return;
179 }
180
181 if ( entryCount == 1 )
182 {
183
184 EvtVector4R p_init = other->getP4();
185 // int decayed=other->getNDaug()>0;
186 bool decayed = other->isDecayed();
187
188 other->deleteTree();
189
190 EvtScalarParticle* scalar_part;
191
192 scalar_part = new EvtScalarParticle;
193 if ( isB0 ) { scalar_part->init( B0, p_init ); }
194 else { scalar_part->init( B0B, p_init ); }
195 other = (EvtParticle*)scalar_part;
196 // other->set_type(EvtSpinType::SCALAR);
197 other->setDiagonalSpinDensity();
198
199 parent->insertDaugPtr( idaug, other );
200
201 if ( decayed )
202 {
203 // report(INFO,"EvtGen") << "In CP Util calling decay \n";
204 other->decay();
205 }
206 }
207
208 otherb = other->getId();
209
210 other->setLifetime();
211 t = p->getLifetime() - other->getLifetime();
212
213 otherb = other->getId();
214 }
215 else
216 {
217 report( INFO, "EvtGen" ) << "We have an error here!!!!" << endl;
218 otherb = EvtId( -1, -1 );
219 }
220
221 entryCount--;
222 return;
223}
224
225void EvtCPUtil::OtherB( EvtParticle* p, double& t, EvtId& otherb ) {
226
227 static EvtId BSB = EvtPDL::getId( "anti-B_s0" );
228 static EvtId BS0 = EvtPDL::getId( "B_s0" );
229 static EvtId B0B = EvtPDL::getId( "anti-B0" );
230 static EvtId B0 = EvtPDL::getId( "B0" );
231 static EvtId UPS4 = EvtPDL::getId( "Upsilon(4S)" );
232
233 if ( p->getId() == BS0 || p->getId() == BSB )
234 {
235 static double ctauL = EvtPDL::getctau( EvtPDL::getId( "B_s0L" ) );
236 static double ctauH = EvtPDL::getctau( EvtPDL::getId( "B_s0H" ) );
237 static double ctau = ctauL < ctauH ? ctauH : ctauL;
238 t = -log( EvtRandom::Flat() ) * ctau;
239 EvtParticle* parent = p->getParent();
240 if ( parent != 0 && ( parent->getId() == BS0 || parent->getId() == BSB ) )
241 {
242 if ( parent->getId() == BS0 ) otherb = BSB;
243 if ( parent->getId() == BSB ) otherb = BS0;
244 parent->setLifetime( t );
245 return;
246 }
247 if ( p->getId() == BS0 ) otherb = BSB;
248 if ( p->getId() == BSB ) otherb = BS0;
249 p->setLifetime( t );
250 return;
251 }
252
253 p->setLifetime();
254
255 // now get the time between the decay of this B and the other B!
256
257 EvtParticle* parent = p->getParent();
258
259 if ( parent == 0 || parent->getId() != UPS4 )
260 {
261 // report(ERROR,"EvtGen") <<
262 // "Warning CP violation with B having no parent!"<<endl;
263 t = p->getLifetime();
264 if ( p->getId() == B0 ) otherb = B0B;
265 if ( p->getId() == B0B ) otherb = B0;
266 if ( p->getId() == BS0 ) otherb = BSB;
267 if ( p->getId() == BSB ) otherb = BS0;
268 return;
269 }
270 else
271 {
272 if ( parent->getDaug( 0 ) != p )
273 {
274 otherb = parent->getDaug( 0 )->getId();
275 parent->getDaug( 0 )->setLifetime();
276 t = p->getLifetime() - parent->getDaug( 0 )->getLifetime();
277 }
278 else
279 {
280 otherb = parent->getDaug( 1 )->getId();
281 parent->getDaug( 1 )->setLifetime();
282 t = p->getLifetime() - parent->getDaug( 1 )->getLifetime();
283 }
284 }
285
286 return;
287}
288
289void EvtCPUtil::incoherentMix( const EvtId id, double& t, int& mix ) {
290
291 int stdHepNum = EvtPDL::getStdHep( id );
292 stdHepNum = abs( stdHepNum );
293
294 EvtId partId = EvtPDL::evtIdFromStdHep( stdHepNum );
295
296 std::string partName = EvtPDL::name( partId );
297 std::string hname = partName + std::string( "H" );
298 std::string lname = partName + std::string( "L" );
299
300 EvtId lId = EvtPDL::getId( lname );
301 EvtId hId = EvtPDL::getId( hname );
302
303 double ctauL = EvtPDL::getctau( lId );
304 double ctauH = EvtPDL::getctau( hId );
305 double ctau = 0.5 * ( ctauL + ctauH );
306 double y = ( ctauH - ctauL ) / ctau;
307
308 // need to figure out how to get these parameters into the code...
309
310 std::string qoverpParmName = std::string( "qoverp_incohMix_" ) + partName;
311 std::string mdParmName = std::string( "dm_incohMix_" ) + partName;
312 int ierr;
313 double qoverp = atof( EvtSymTable::Get( qoverpParmName, ierr ).c_str() );
314 double x = atof( EvtSymTable::Get( mdParmName, ierr ).c_str() ) * ctau / EvtConst::c;
315 double fac;
316
317 if ( id == partId ) { fac = 1.0 / ( qoverp * qoverp ); }
318 else { fac = qoverp * qoverp; }
319
320 double mixprob = ( x * x + y * y ) / ( x * x + y * y + fac * ( 2 + x * x - y * y ) );
321
322 int mixsign;
323
324 mixsign = ( mixprob > EvtRandom::Flat( 0.0, 1.0 ) ) ? -1 : 1;
325
326 double prob;
327
328 do {
329 t = -log( EvtRandom::Flat() ) * ctauL;
330 prob = 1 + exp( y * t / ctau ) + mixsign * 2 * exp( 0.5 * y * t / ctau ) * cos( x * t );
331 } while ( prob < 4 * EvtRandom::Flat() );
332
333 mix = 0;
334
335 if ( mixsign == -1 ) mix = 1;
336
337 return;
338}
double imag(const EvtComplex &c)
EvtComplex exp(const EvtComplex &c)
ostream & report(Severity severity, const char *facility)
Definition EvtReport.cc:34
@ INFO
Definition EvtReport.hh:52
static void fractB0nonCP(EvtComplex Af, EvtComplex Abarf, EvtComplex Afbar, EvtComplex Abarfbar, double deltam, double beta, int flip, double &fract)
Definition EvtCPUtil.cc:65
static void fractB0CP(EvtComplex Af, EvtComplex Abarf, double deltam, double beta, double &fract)
Definition EvtCPUtil.cc:39
static void incoherentMix(const EvtId id, double &t, int &mix)
Definition EvtCPUtil.cc:289
static void OtherB(EvtParticle *p, double &t, EvtId &otherb)
Definition EvtCPUtil.cc:225
static const double c
Definition EvtConst.hh:31
Definition EvtId.hh:27
static int getStdHep(EvtId id)
Definition EvtPDL.hh:61
static EvtId evtIdFromStdHep(int stdhep)
Definition EvtPDL.cc:232
static std::string name(EvtId i)
Definition EvtPDL.hh:70
static EvtId getId(const std::string &name)
Definition EvtPDL.cc:272
static double getctau(EvtId i)
Definition EvtPDL.hh:60
void insertDaugPtr(int idaug, EvtParticle *partptr)
EvtId getId() const
EvtParticle * getParent()
double getLifetime()
void setLifetime(double tau)
EvtParticle * getDaug(int i)
static double Flat()
Definition EvtRandom.cc:69
static double Flat(double min, double max)
Definition EvtRandom.cc:55
void init(EvtId part_n, double e, double px, double py, double pz)
static std::string Get(const std::string &name, int &ierr)
int t()
Definition t.c:1