Belle II Software  release-08-01-10
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>
53 using std::endl;
54 
56 
57 
58 EvtYmSToYnSpipiCLEOboost::~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.
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
#define B2_EVTGEN_REGISTER_MODEL(classname)
Class to register B2_EVTGEN_REGISTER_MODEL.