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