Belle II Software development
EvtYmSToYnSpipiCLEOboost.cc
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: EvtGen/EvtYmSToYnSpipiCLEOboost.h
12//
13// Description: This model is based on matrix element method used by
14// CLEO in Phys.Rev.D76:072001,2007 to model the dipion mass
15// and helicity angle distribution in the decays Y(mS) -> pi pi Y(nS),
16// where m,n are integers and m>n and m<4.
17// This model has two parameters, Re(B/A) and Im(B/A), which
18// are coefficients of the matrix element's terms determined by
19// the CLEO fits.
20//
21// Example:
22//
23// Decay Upsilon(3S)
24// 1.0000 Upsilon pi+ pi- YMSTOYNSPIPICLEOBOOST -2.523 1.189;
25// Enddecay
26// Decay Upsilon(3S)
27// 1.0000 Upsilon(2S) pi+ pi- YMSTOYNSPIPICLEOBOOST -0.395 0.001;
28// Enddecay
29// Decay Upsilon(2S)
30// 1.0000 Upsilon pi+ pi- YMSTOYNSPIPICLEOBOOST -0.753 0.000;
31// Enddecay
32//
33// --> the order of parameters is: Re(B/A) Im(B/A)
34//
35// Modification history:
36//
37// SEKULA Jan. 28, 2008 Module created
38// FULSOM, Bryan May 12 2015 Change boost, L178
39//
40//------------------------------------------------------------------------
41
42
43#include <stdlib.h>
44#include "EvtGenBase/EvtParticle.hh"
45#include "EvtGenBase/EvtGenKine.hh"
46#include "EvtGenBase/EvtPDL.hh"
47#include "EvtGenBase/EvtVector4C.hh"
48#include "EvtGenBase/EvtReport.hh"
49#include "EvtGenBase/EvtRandom.hh"
50#include <generators/evtgen/EvtGenModelRegister.h>
51#include "generators/evtgen/models/EvtYmSToYnSpipiCLEOboost.h"
52#include <string>
53using std::endl;
54
56
57
58EvtYmSToYnSpipiCLEOboost::~EvtYmSToYnSpipiCLEOboost() {}
59
61{
62
63 return "YMSTOYNSPIPICLEOBOOST";
64
65}
66
67
69{
70
71 return new EvtYmSToYnSpipiCLEOboost;
72
73}
74
76{
77
78 static EvtId PIP = EvtPDL::getId("pi+");
79 static EvtId PIM = EvtPDL::getId("pi-");
80 static EvtId PI0 = EvtPDL::getId("pi0");
81
82 // check that there are 2 arguments
83 checkNArg(2);
84 checkNDaug(3);
85
86 checkSpinParent(EvtSpinType::VECTOR);
87 checkSpinDaughter(0, EvtSpinType::VECTOR);
88
89
90
91 if ((!(getDaug(1) == PIP && getDaug(2) == PIM)) &&
92 (!(getDaug(1) == PI0 && getDaug(2) == PI0))) {
93 EvtGenReport(EVTGEN_ERROR, "EvtGen") << "EvtYmSToYnSpipiCLEOboost generator expected "
94 << " pi+ and pi- (or pi0 and pi0) "
95 << "as 2nd and 3rd daughter. " << endl;
96 EvtGenReport(EVTGEN_ERROR, "EvtGen") << "Will terminate execution!" << endl;
97 ::abort();
98 }
99
100}
101
103{
104 setProbMax(2.0);
105}
106
108{
109
110
111 // We want to simulate the following process:
112 //
113 // Y(mS) -> Y(nS) X, X -> pi+ pi- (pi0 pi0)
114 //
115 // The CLEO analysis assumed such an intermediate process
116 // were occurring, and wrote down the matrix element
117 // and its components according to this assumption.
118 //
119 //
120
121
122 double ReB_over_A = getArg(0);
123 double ImB_over_A = getArg(1);
124
125 p->makeDaughters(getNDaug(), getDaugs());
126 EvtParticle* v, *s1, *s2;
127 v = p->getDaug(0);
128 s1 = p->getDaug(1);
129 s2 = p->getDaug(2);
130
131 double m_pi = s1->getP4().mass();
132 double M_mS = p->getP4().mass();
133 double M_nS = v->getP4().mass();
134
135 // // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEOboost") << "M_nS = " << v->getP4().mass() << endl;
136
137 EvtVector4R P_nS;
138 EvtVector4R P_pi1;
139 EvtVector4R P_pi2;
140
141 // Perform a simple accept/reject until we get a configuration of the
142 // dipion system that passes
143 bool acceptX = false;
144
145 while (false == acceptX) {
146
147 // Begin by generating a random X mass between the kinematic
148 // boundaries, 2*m_pi and M(mS) - M(nS)
149
150 double mX = EvtRandom::Flat(2.0 * m_pi, M_mS - M_nS);
151
152 // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEOboost") << "m_X = " << mX << endl;
153
154 // Now create a two-body decay from the Y(mS) in its rest frame
155 // of Y(mS) -> Y(nS) + X
156
157 double masses[30];
158 masses[0] = M_nS;
159 masses[1] = mX;
160
161 EvtVector4R p4[2];
162
163 EvtGenKine::PhaseSpace(2, masses, p4, M_mS);
164
165 P_nS = p4[0];
166 EvtVector4R P_X = p4[1];
167
168 // Now create the four-vectors for the two pions in the X
169 // rest frame, X -> pi pi
170
171 masses[0] = s1->mass();
172 masses[1] = s2->mass();
173
174 EvtGenKine::PhaseSpace(2, masses, p4, P_X.mass());
175
176 // compute cos(theta), the polar helicity angle between a pi+ and
177 // the direction opposite the Y(mS) in the X rest frame. If the pions are pi0s, then
178 // choose the one where cos(theta) = [0:1].
179
180 EvtVector4R P_YmS_X = boostTo(p->getP4Restframe(), P_X);
181 double costheta = - p4[0].dot(P_YmS_X) / (p4[0].d3mag() * P_YmS_X.d3mag());
182 if (EvtPDL::name(s1->getId()) == "pi0") {
183 if (costheta < 0) {
184 costheta = - p4[1].dot(P_YmS_X) / (p4[1].d3mag() * P_YmS_X.d3mag());
185 }
186 }
187 if (EvtPDL::name(s1->getId()) == "pi-") {
188 costheta = - p4[1].dot(P_YmS_X) / (p4[1].d3mag() * P_YmS_X.d3mag());
189 }
190
191 // // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEOboost") << "cos(theta) = " << costheta << endl;
192
193
194
195 // Now boost the pion four vectors into the Y(mS) rest frame
196 P_pi1 = boostTo(p4[0], P_YmS_X);
197 P_pi2 = boostTo(p4[1], P_YmS_X);
198
199 // Use a simple accept-reject to test this dipion system
200
201 // Now compute the components of the matrix-element squared
202 //
203 // 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)
204 //
205 // x=m_pipi^2 and y = cos(theta), and where
206 //
207 // Q(x,y) = (x^2 + 2*m_pi^2)
208 //
209 // E1E2(x,y) = (1/4) * ( (E1 + E2)^2 - (E2 - E1)^2_max * cos(theta)^2 )
210 //
211 // and E1 + E2 = M_mS - M_nS and (E2 - E1)_max is the maximal difference
212 // in the energy of the two pions allowed for a given mX value.
213 //
214
215 double Q = (mX * mX - 2.0 * m_pi * m_pi);
216
217 double deltaEmax =
218 - 2.0 *
219 sqrt(P_nS.get(0) * P_nS.get(0) - M_nS * M_nS) *
220 sqrt(0.25 - pow(m_pi / mX, 2.0));
221
222 double sumE = (M_mS * M_mS - M_nS * M_nS + mX * mX) / (2.0 * M_mS);
223
224 double E1E2 = 0.25 * (pow(sumE, 2.0) - pow(deltaEmax * costheta, 2.0));
225
226 double M2 = Q * Q + (pow(ReB_over_A, 2.0) + pow(ImB_over_A, 2.0)) * E1E2 * E1E2 + 2.0 * ReB_over_A * Q * E1E2;
227
228 // phase space factor
229 //
230 // this is given as d(PS) = C * p(*)_X * p(X)_{pi+} * d(cosTheta) * d(m_X)
231 //
232 // where C is a normalization constant, p(*)_X is the X momentum magnitude in the
233 // Y(mS) rest frame, and p(X)_{pi+} is the pi+/pi0 momentum in the X rest frame
234 //
235
236 double dPS =
237 sqrt((M_mS * M_mS - pow(M_nS + mX, 2.0)) * (M_mS * M_mS - pow(M_nS - mX, 2.0))) * // p(*)_X
238 sqrt(mX * mX - 4 * m_pi * m_pi); // p(X)_{pi}
239
240 // the double-differential decay rate dG/(dcostheta dmX)
241 double dG = M2 * dPS;
242
243 // Throw a uniform random number from 0 --> probMax and do accept/reject on this
244
245 double rnd = EvtRandom::Flat(0.0, getProbMax(0.0));
246
247 if (rnd < dG)
248 acceptX = true;
249
250 }
251
252
253 // initialize the daughters
254 v->init(getDaugs()[0], P_nS);
255 s1->init(getDaugs()[1], P_pi1);
256 s2->init(getDaugs()[2], P_pi2);
257
258 // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEOboost") << "M_nS = " << v->getP4().mass() << endl;
259 // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEOboost") << "m_pi = " << s1->getP4().mass() << endl;
260 // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEOboost") << "m_pi = " << s2->getP4().mass() << endl;
261 // EvtGenReport(EVTGEN_INFO,"EvtYmSToYnSpipiCLEOboost") << "M2 = " << M2 << endl;
262
263 // Pass the polarization of the parent Upsilon
264 EvtVector4C ep0, ep1, ep2;
265
266 ep0 = p->eps(0);
267 ep1 = p->eps(1);
268 ep2 = p->eps(2);
269
270
271 vertex(0, 0, (ep0 * v->epsParent(0).conj()));
272 vertex(0, 1, (ep0 * v->epsParent(1).conj()));
273 vertex(0, 2, (ep0 * v->epsParent(2).conj()));
274
275 vertex(1, 0, (ep1 * v->epsParent(0).conj()));
276 vertex(1, 1, (ep1 * v->epsParent(1).conj()));
277 vertex(1, 2, (ep1 * v->epsParent(2).conj()));
278
279 vertex(2, 0, (ep2 * v->epsParent(0).conj()));
280 vertex(2, 1, (ep2 * v->epsParent(1).conj()));
281 vertex(2, 2, (ep2 * v->epsParent(2).conj()));
282
283
284 return ;
285
286}
287
288
289
290
291
Register Decay model EvtYmSToYnSpipiCLEOboost.
void init()
Initialize standard stream objects
EvtDecayBase * clone()
Clone the decay
void initProbMax()
Initialize standard stream objects for probability function
std::string getName()
Get function Name
void decay(EvtParticle *p)
Member of particle in EvtGen.
#define B2_EVTGEN_REGISTER_MODEL(classname)
Class to register B2_EVTGEN_REGISTER_MODEL.