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