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
EvtSSD_DirectCP.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
26#include "EvtGenBase/EvtPDL.hh"
33
34#include <stdlib.h>
35#include <string>
36
37std::string EvtSSD_DirectCP::getName() const
38{
39 return "SSD_DirectCP";
40}
41
43{
44 return new EvtSSD_DirectCP;
45}
46
48{
49 // check that there is 1 argument and 2-body decay
50
51 checkNArg( 1 );
52 checkNDaug( 2 );
53
56
57 if ( ( !( d1type == EvtSpinType::SCALAR || d2type == EvtSpinType::SCALAR ) ) ||
58 ( !( ( d2type == EvtSpinType::SCALAR ) ||
59 ( d2type == EvtSpinType::VECTOR ) ||
60 ( d2type == EvtSpinType::TENSOR ) ) ) ||
61 ( !( ( d1type == EvtSpinType::SCALAR ) ||
62 ( d1type == EvtSpinType::VECTOR ) ||
63 ( d1type == EvtSpinType::TENSOR ) ) ) ) {
64 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
65 << "EvtSSD_DirectCP generator expected "
66 << "one of the daugters to be a scalar, "
67 << "the other either scalar, vector, or tensor, "
68 << "found:" << EvtPDL::name( getDaug( 0 ) ).c_str() << " and "
69 << EvtPDL::name( getDaug( 1 ) ).c_str() << std::endl;
70 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
71 << "Will terminate execution!" << std::endl;
72 ::abort();
73 }
74
75 m_acp = getArg( 0 ); // A_CP defined as A_CP = (BR(fbar)-BR(f))/(BR(fbar)+BR(f))
76}
77
79{
80 double theProbMax = 1.;
81
84
85 if ( d1type != EvtSpinType::SCALAR || d2type != EvtSpinType::SCALAR ) {
86 // Create a scalar parent at rest and initialize it
87 // Use noLifeTime() cludge to avoid generating random numbers
88
89 EvtScalarParticle parent{};
90 parent.noLifeTime();
91 parent.init( getParentId(),
92 EvtVector4R( EvtPDL::getMass( getParentId() ), 0, 0, 0 ) );
94
95 // Create daughters and initialize amplitude
96 EvtAmp amp;
97 EvtId daughters[2] = { getDaug( 0 ), getDaug( 1 ) };
98 amp.init( getParentId(), 2, daughters );
99 parent.makeDaughters( 2, daughters );
100
101 const int scalarDaughterIndex = d1type == EvtSpinType::SCALAR ? 0 : 1;
102 const int nonScalarDaughterIndex = d1type == EvtSpinType::SCALAR ? 1 : 0;
103
104 EvtParticle* scalarDaughter = parent.getDaug( scalarDaughterIndex );
105 EvtParticle* nonScalarDaughter = parent.getDaug( nonScalarDaughterIndex );
106
107 scalarDaughter->noLifeTime();
108 nonScalarDaughter->noLifeTime();
109
110 EvtSpinDensity rho;
111 rho.setDiag( parent.getSpinStates() );
112
113 // Momentum of daughters in parent's frame
114 const double parentMass = EvtPDL::getMass( getParentId() );
115 const double sdMass = EvtPDL::getMass( getDaug( scalarDaughterIndex ) );
116 const double ndMass = EvtPDL::getMass( getDaug( nonScalarDaughterIndex ) );
117 const double pstar =
118 sqrt( pow( parentMass, 2 ) - pow( ( sdMass + ndMass ), 2 ) ) *
119 sqrt( pow( parentMass, 2 ) - pow( ( ndMass - sdMass ), 2 ) ) /
120 ( 2 * parentMass );
121
122 EvtVector4R p4_sd, p4_nd;
123
124 const int nsteps = 16;
125
126 double prob_max = 0;
127 double theta_max = 0;
128
129 for ( int i = 0; i <= nsteps; i++ ) {
130 const double theta = i * EvtConst::pi / nsteps;
131
132 p4_sd.set( sqrt( pow( pstar, 2 ) + pow( sdMass, 2 ) ), 0,
133 +pstar * sin( theta ), +pstar * cos( theta ) );
134
135 p4_nd.set( sqrt( pow( pstar, 2 ) + pow( ndMass, 2 ) ), 0,
136 -pstar * sin( theta ), -pstar * cos( theta ) );
137
138 scalarDaughter->init( getDaug( scalarDaughterIndex ), p4_sd );
139 nonScalarDaughter->init( getDaug( nonScalarDaughterIndex ), p4_nd );
140
141 calcAmp( parent, amp );
142
143 const double i_prob = rho.normalizedProb( amp.getSpinDensity() );
144
145 if ( i_prob > prob_max ) {
146 prob_max = i_prob;
147 theta_max = theta;
148 }
149 }
150
151 EvtGenReport( EVTGEN_INFO, "EvtGen" )
152 << " - probability " << prob_max
153 << " found at theta = " << theta_max << std::endl;
154 theProbMax *= 1.01 * prob_max;
155 }
156
157 setProbMax( theProbMax );
158
159 EvtGenReport( EVTGEN_INFO, "EvtGen" )
160 << " EvtSSD_DirectCP - set up maximum probability to " << theProbMax
161 << std::endl;
162}
163
165{
166 bool flip = false;
167 EvtId daugs[2];
168
169 // decide it is B or Bbar:
170 if ( EvtRandom::Flat( 0., 1. ) < ( ( 1. - m_acp ) / 2. ) ) {
171 // it is a B
172 if ( EvtPDL::getStdHep( getParentId() ) < 0 )
173 flip = true;
174 } else {
175 // it is a Bbar
176 if ( EvtPDL::getStdHep( getParentId() ) > 0 )
177 flip = true;
178 }
179
180 if ( flip ) {
181 if ( ( isB0Mixed( *parent ) ) || ( isBsMixed( *parent ) ) ) {
182 parent->getParent()->setId(
183 EvtPDL::chargeConj( parent->getParent()->getId() ) );
184 parent->setId( EvtPDL::chargeConj( parent->getId() ) );
185 } else {
186 parent->setId( EvtPDL::chargeConj( parent->getId() ) );
187 }
188 daugs[0] = EvtPDL::chargeConj( getDaug( 0 ) );
189 daugs[1] = EvtPDL::chargeConj( getDaug( 1 ) );
190 } else {
191 daugs[0] = getDaug( 0 );
192 daugs[1] = getDaug( 1 );
193 }
194
195 parent->initializePhaseSpace( 2, daugs );
196
197 calcAmp( *parent, m_amp2 );
198}
199
201{
202 if ( !( p.getParent() ) )
203 return false;
204
205 static const EvtId B0 = EvtPDL::getId( "B0" );
206 static const EvtId B0B = EvtPDL::getId( "anti-B0" );
207
208 if ( ( p.getId() != B0 ) && ( p.getId() != B0B ) )
209 return false;
210
211 if ( ( p.getParent()->getId() == B0 ) || ( p.getParent()->getId() == B0B ) )
212 return true;
213
214 return false;
215}
216
218{
219 if ( !( p.getParent() ) )
220 return false;
221
222 static const EvtId BS0 = EvtPDL::getId( "B_s0" );
223 static const EvtId BSB = EvtPDL::getId( "anti-B_s0" );
224
225 if ( ( p.getId() != BS0 ) && ( p.getId() != BSB ) )
226 return false;
227
228 if ( ( p.getParent()->getId() == BS0 ) || ( p.getParent()->getId() == BSB ) )
229 return true;
230
231 return false;
232}
233
235{
236 switch ( i ) {
237 case 0:
238 return "ACP";
239 default:
240 return "";
241 }
242}
243
244void EvtSSD_DirectCP::calcAmp( const EvtParticle& parent, EvtAmp& amp ) const
245{
247 parent.getDaug( 0 )->getId() );
249 parent.getDaug( 1 )->getId() );
250
251 if ( d1type == EvtSpinType::SCALAR && d2type == EvtSpinType::SCALAR ) {
252 amp.vertex( 1. );
253 return;
254 }
255
256 const EvtVector4R p4_parent = parent.getP4Restframe();
257
258 const int nonScalarDaughterIndex = d1type == EvtSpinType::SCALAR ? 1 : 0;
259
260 const EvtParticle& daughter = *parent.getDaug( nonScalarDaughterIndex );
261
262 const EvtSpinType::spintype nonScalarType = EvtPDL::getSpinType(
263 daughter.getId() );
264
265 if ( nonScalarType == EvtSpinType::VECTOR ) {
266 const EvtVector4R momv = daughter.getP4();
267 const double norm = momv.mass() / ( momv.d3mag() * parent.mass() );
268
269 amp.vertex( 0, norm * p4_parent * ( daughter.epsParent( 0 ) ) );
270 amp.vertex( 1, norm * p4_parent * ( daughter.epsParent( 1 ) ) );
271 amp.vertex( 2, norm * p4_parent * ( daughter.epsParent( 2 ) ) );
272
273 }
274
275 // This is for the EvtSpinType::TENSOR case.
276 else {
277 const double norm = daughter.mass() * daughter.mass() /
278 ( p4_parent.mass() * daughter.getP4().d3mag() *
279 daughter.getP4().d3mag() );
280
281 amp.vertex( 0, norm * daughter.epsTensorParent( 0 ).cont1( p4_parent ) *
282 p4_parent );
283 amp.vertex( 1, norm * daughter.epsTensorParent( 1 ).cont1( p4_parent ) *
284 p4_parent );
285 amp.vertex( 2, norm * daughter.epsTensorParent( 2 ).cont1( p4_parent ) *
286 p4_parent );
287 amp.vertex( 3, norm * daughter.epsTensorParent( 3 ).cont1( p4_parent ) *
288 p4_parent );
289 amp.vertex( 4, norm * daughter.epsTensorParent( 4 ).cont1( p4_parent ) *
290 p4_parent );
291 }
292}
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
void vertex(const EvtComplex &amp)
Definition EvtAmp.cpp:453
EvtSpinDensity getSpinDensity() const
Definition EvtAmp.cpp:141
void init(EvtId p, int ndaug, const EvtId *daug)
Definition EvtAmp.cpp:67
static const double pi
Definition EvtConst.hh:26
EvtAmp m_amp2
EvtDecayBase()=default
double getArg(unsigned int j)
void setProbMax(double prbmx)
EvtId getParentId() 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)
Definition EvtId.hh:27
static EvtSpinType::spintype getSpinType(EvtId i)
Definition EvtPDL.cpp:371
static int getStdHep(EvtId id)
Definition EvtPDL.cpp:356
static double getMass(EvtId i)
Definition EvtPDL.cpp:311
static std::string name(EvtId i)
Definition EvtPDL.cpp:376
static EvtId chargeConj(EvtId id)
Definition EvtPDL.cpp:201
static EvtId getId(const std::string &name)
Definition EvtPDL.cpp:283
void noLifeTime()
virtual EvtVector4C epsParent(int i) const
virtual void init(EvtId part_n, const EvtVector4R &p4)=0
virtual EvtTensor4C epsTensorParent(int i) const
double initializePhaseSpace(size_t numdaughter, const EvtId *daughters, bool forceResetMasses=false, double poleSize=-1., int whichTwo1=0, int whichTwo2=1)
EvtId getId() const
EvtVector4R getP4Restframe() const
int getSpinStates() const
void setDiagonalSpinDensity()
const EvtVector4R & getP4() const
EvtParticle * getDaug(const int i)
double mass() const
void setId(EvtId id)
EvtParticle * getParent() const
void makeDaughters(size_t ndaug, const EvtId *id)
static double Flat()
Definition EvtRandom.cpp:95
std::string getName() const override
void calcAmp(const EvtParticle &parent, EvtAmp &amp) const
bool isB0Mixed(const EvtParticle &p)
bool isBsMixed(const EvtParticle &p)
void decay(EvtParticle *p) override
std::string getParamName(int i) override
void initProbMax() override
void init() override
EvtDecayBase * clone() const override
void init(EvtId part_n, double e, double px, double py, double pz)
double normalizedProb(const EvtSpinDensity &d)
void setDiag(int n)
EvtVector4C cont1(const EvtVector4C &v4) const
double mass() const
double d3mag() const
void set(int i, double d)