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
EvtYmSToYnSpipiCLEO.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
24#include "EvtGenBase/EvtPDL.hh"
30
31#include <stdlib.h>
32#include <string>
33using std::endl;
34
36{
37 return "YMSTOYNSPIPICLEO";
38}
39
44
46{
47 static const EvtId PIP = EvtPDL::getId( "pi+" );
48 static const EvtId PIM = EvtPDL::getId( "pi-" );
49 static const EvtId PI0 = EvtPDL::getId( "pi0" );
50
51 // check that there are 2 arguments
52 checkNArg( 2 );
53 checkNDaug( 3 );
54
57
58 if ( ( !( getDaug( 1 ) == PIP && getDaug( 2 ) == PIM ) ) &&
59 ( !( getDaug( 1 ) == PI0 && getDaug( 2 ) == PI0 ) ) ) {
60 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
61 << "EvtYmSToYnSpipiCLEO generator expected "
62 << " pi+ and pi- (or pi0 and pi0) "
63 << "as 2nd and 3rd daughter. " << endl;
64 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
65 << "Will terminate execution!" << endl;
66 ::abort();
67 }
68}
69
74
76{
77 // We want to simulate the following process:
78 //
79 // Y(mS) -> Y(nS) X, X -> pi+ pi- (pi0 pi0)
80 //
81 // The CLEO analysis assumed such an intermediate process
82 // were occurring, and wrote down the matrix element
83 // and its components according to this assumption.
84 //
85 //
86
87 double ReB_over_A = getArg( 0 );
88 double ImB_over_A = getArg( 1 );
89
91 EvtParticle *v, *s1, *s2;
92 v = p->getDaug( 0 );
93 s1 = p->getDaug( 1 );
94 s2 = p->getDaug( 2 );
95
96 double m_pi = s1->getP4().mass();
97 double M_mS = p->getP4().mass();
98 double M_nS = v->getP4().mass();
99
100 // // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEO") << "M_nS = " << v->getP4().mass() << endl;
101
102 EvtVector4R P_nS;
103 EvtVector4R P_pi1;
104 EvtVector4R P_pi2;
105
106 // Perform a simple accept/reject until we get a configuration of the
107 // dipion system that passes
108 bool acceptX = false;
109
110 while ( false == acceptX ) {
111 // Begin by generating a random X mass between the kinematic
112 // boundaries, 2*m_pi and M(mS) - M(nS)
113
114 double mX = EvtRandom::Flat( 2.0 * m_pi, M_mS - M_nS );
115
116 // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEO") << "m_X = " << mX << endl;
117
118 // Now create a two-body decay from the Y(mS) in its rest frame
119 // of Y(mS) -> Y(nS) + X
120
121 double masses[2];
122 masses[0] = M_nS;
123 masses[1] = mX;
124
125 EvtVector4R p4[2];
126
127 EvtGenKine::PhaseSpace( 2, masses, p4, M_mS );
128
129 P_nS = p4[0];
130 EvtVector4R P_X = p4[1];
131
132 // Now create the four-vectors for the two pions in the X
133 // rest frame, X -> pi pi
134
135 masses[0] = s1->mass();
136 masses[1] = s2->mass();
137
138 EvtGenKine::PhaseSpace( 2, masses, p4, P_X.mass() );
139
140 // compute cos(theta), the polar helicity angle between a pi+ and
141 // the direction opposite the Y(mS) in the X rest frame. If the pions are pi0s, then
142 // choose the one where cos(theta) = [0:1].
143
144 EvtVector4R P_YmS_X = boostTo( p->getP4(), P_X );
145 double costheta = -p4[0].dot( P_YmS_X ) /
146 ( p4[0].d3mag() * P_YmS_X.d3mag() );
147 if ( EvtPDL::name( s1->getId() ) == "pi0" ) {
148 if ( costheta < 0 ) {
149 costheta = -p4[1].dot( P_YmS_X ) /
150 ( p4[1].d3mag() * P_YmS_X.d3mag() );
151 }
152 }
153 if ( EvtPDL::name( s1->getId() ) == "pi-" ) {
154 costheta = -p4[1].dot( P_YmS_X ) /
155 ( p4[1].d3mag() * P_YmS_X.d3mag() );
156 }
157
158 // // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEO") << "cos(theta) = " << costheta << endl;
159
160 // Now boost the pion four vectors into the Y(mS) rest frame
161 P_pi1 = boostTo( p4[0], P_YmS_X );
162 P_pi2 = boostTo( p4[1], P_YmS_X );
163
164 // Use a simple accept-reject to test this dipion system
165
166 // Now compute the components of the matrix-element squared
167 //
168 // M(x,y)^2 = Q(x,y)^2 + |B/A|^2 * E1E2(x,y)^2 + 2*Re(B/A)*Q(x,y)*E1E2(x,y)
169 //
170 // x=m_pipi^2 and y = cos(theta), and where
171 //
172 // Q(x,y) = (x^2 + 2*m_pi^2)
173 //
174 // E1E2(x,y) = (1/4) * ( (E1 + E2)^2 - (E2 - E1)^2_max * cos(theta)^2 )
175 //
176 // and E1 + E2 = M_mS - M_nS and (E2 - E1)_max is the maximal difference
177 // in the energy of the two pions allowed for a given mX value.
178 //
179
180 double Q = ( mX * mX - 2.0 * m_pi * m_pi );
181
182 double deltaEmax = -2.0 *
183 sqrt( P_nS.get( 0 ) * P_nS.get( 0 ) - M_nS * M_nS ) *
184 sqrt( 0.25 - pow( m_pi / mX, 2.0 ) );
185
186 double sumE = ( M_mS * M_mS - M_nS * M_nS + mX * mX ) / ( 2.0 * M_mS );
187
188 double E1E2 = 0.25 *
189 ( pow( sumE, 2.0 ) - pow( deltaEmax * costheta, 2.0 ) );
190
191 double M2 = Q * Q +
192 ( pow( ReB_over_A, 2.0 ) + pow( ImB_over_A, 2.0 ) ) * E1E2 *
193 E1E2 +
194 2.0 * ReB_over_A * Q * E1E2;
195
196 // phase space factor
197 //
198 // this is given as d(PS) = C * p(*)_X * p(X)_{pi+} * d(cosTheta) * d(m_X)
199 //
200 // where C is a normalization constant, p(*)_X is the X momentum magnitude in the
201 // Y(mS) rest frame, and p(X)_{pi+} is the pi+/pi0 momentum in the X rest frame
202 //
203
204 double dPS = sqrt( ( M_mS * M_mS - pow( M_nS + mX, 2.0 ) ) *
205 ( M_mS * M_mS - pow( M_nS - mX, 2.0 ) ) ) * // p(*)_X
206 sqrt( mX * mX - 4 * m_pi * m_pi ); // p(X)_{pi}
207
208 // the double-differential decay rate dG/(dcostheta dmX)
209 double dG = M2 * dPS;
210
211 // Throw a uniform random number from 0 --> probMax and do accept/reject on this
212
213 double rnd = EvtRandom::Flat( 0.0, getProbMax( 0.0 ) );
214
215 if ( rnd < dG )
216 acceptX = true;
217 }
218
219 // initialize the daughters
220 v->init( getDaugs()[0], P_nS );
221 s1->init( getDaugs()[1], P_pi1 );
222 s2->init( getDaugs()[2], P_pi2 );
223
224 // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEO") << "M_nS = " << v->getP4().mass() << endl;
225 // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEO") << "m_pi = " << s1->getP4().mass() << endl;
226 // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEO") << "m_pi = " << s2->getP4().mass() << endl;
227 // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEO") << "M2 = " << M2 << endl;
228
229 // Pass the polarization of the parent Upsilon
230 EvtVector4C ep0, ep1, ep2;
231
232 ep0 = p->eps( 0 );
233 ep1 = p->eps( 1 );
234 ep2 = p->eps( 2 );
235
236 vertex( 0, 0, ( ep0 * v->epsParent( 0 ).conj() ) );
237 vertex( 0, 1, ( ep0 * v->epsParent( 1 ).conj() ) );
238 vertex( 0, 2, ( ep0 * v->epsParent( 2 ).conj() ) );
239
240 vertex( 1, 0, ( ep1 * v->epsParent( 0 ).conj() ) );
241 vertex( 1, 1, ( ep1 * v->epsParent( 1 ).conj() ) );
242 vertex( 1, 2, ( ep1 * v->epsParent( 2 ).conj() ) );
243
244 vertex( 2, 0, ( ep2 * v->epsParent( 0 ).conj() ) );
245 vertex( 2, 1, ( ep2 * v->epsParent( 1 ).conj() ) );
246 vertex( 2, 2, ( ep2 * v->epsParent( 2 ).conj() ) );
247
248 return;
249}
EvtRaritaSchwinger boostTo(const EvtRaritaSchwinger &rs, const EvtVector4R p4)
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=nullptr)
Definition EvtReport.cpp:32
@ EVTGEN_ERROR
Definition EvtReport.hh:49
void vertex(const EvtComplex &amp)
void checkSpinDaughter(int d1, EvtSpinType::spintype sp)
EvtDecayBase()=default
int getNDaug() const
void checkSpinParent(EvtSpinType::spintype sp)
double getArg(unsigned int j)
void setProbMax(double prbmx)
EvtId getDaug(int i) const
double getProbMax(double prob)
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 std::string name(EvtId i)
Definition EvtPDL.cpp:376
static EvtId getId(const std::string &name)
Definition EvtPDL.cpp:283
virtual EvtVector4C epsParent(int i) const
virtual void init(EvtId part_n, const EvtVector4R &p4)=0
EvtId getId() const
const EvtVector4R & getP4() const
EvtParticle * getDaug(const int i)
double mass() const
virtual EvtVector4C eps(int i) const
void makeDaughters(size_t ndaug, const EvtId *id)
static double Flat()
Definition EvtRandom.cpp:95
EvtVector4C conj() const
double dot(const EvtVector4R &v2) const
double mass() const
double get(int i) const
double d3mag() const
std::string getName() const override
EvtDecayBase * clone() const override
void decay(EvtParticle *p) override