LCOV - code coverage report
Current view: top level - TEvtGen/EvtGen/EvtGenModels - EvtYmSToYnSpipiCLEO.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 87 0.0 %
Date: 2016-06-14 17:26:59 Functions: 0 8 0.0 %

          Line data    Source code
       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           0 : EvtYmSToYnSpipiCLEO::~EvtYmSToYnSpipiCLEO() {}
      56             : 
      57             : std::string EvtYmSToYnSpipiCLEO::getName(){
      58             : 
      59           0 :   return "YMSTOYNSPIPICLEO";     
      60             : 
      61             : }
      62             : 
      63             : 
      64             : EvtDecayBase* EvtYmSToYnSpipiCLEO::clone(){
      65             : 
      66           0 :   return new EvtYmSToYnSpipiCLEO;
      67             : 
      68           0 : }
      69             : 
      70             : void EvtYmSToYnSpipiCLEO::init(){
      71             : 
      72           0 :   static EvtId PIP=EvtPDL::getId("pi+");
      73           0 :   static EvtId PIM=EvtPDL::getId("pi-");
      74           0 :   static EvtId PI0=EvtPDL::getId("pi0");
      75             : 
      76             :   // check that there are 2 arguments
      77           0 :   checkNArg(2);
      78           0 :   checkNDaug(3);
      79             : 
      80           0 :   checkSpinParent(EvtSpinType::VECTOR);
      81           0 :   checkSpinDaughter(0,EvtSpinType::VECTOR);
      82             : 
      83             : 
      84             : 
      85           0 :   if ((!(getDaug(1)==PIP&&getDaug(2)==PIM))&&
      86           0 :       (!(getDaug(1)==PI0&&getDaug(2)==PI0))) {
      87           0 :     report(Severity::Error,"EvtGen") << "EvtYmSToYnSpipiCLEO generator expected "
      88           0 :                            << " pi+ and pi- (or pi0 and pi0) "
      89           0 :                            << "as 2nd and 3rd daughter. "<<endl;
      90           0 :     report(Severity::Error,"EvtGen") << "Will terminate execution!"<<endl;
      91           0 :     ::abort();
      92             :   }
      93             : 
      94           0 : }
      95             : 
      96             : void EvtYmSToYnSpipiCLEO::initProbMax() {
      97           0 :   setProbMax(2.0);
      98           0 : }      
      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           0 :   double ReB_over_A = getArg(0);
     115           0 :   double ImB_over_A = getArg(1);
     116             : 
     117           0 :   p->makeDaughters(getNDaug(),getDaugs());
     118             :   EvtParticle *v,*s1,*s2;
     119           0 :   v=p->getDaug(0);
     120           0 :   s1=p->getDaug(1);
     121           0 :   s2=p->getDaug(2);
     122             : 
     123           0 :   double m_pi = s1->getP4().mass();
     124           0 :   double M_mS = p->getP4().mass();
     125           0 :   double M_nS = v->getP4().mass();
     126             : 
     127             : // //   report(Severity::Info,"EvtYmSToYnSpipiCLEO")  << "M_nS = " << v->getP4().mass() << endl;
     128             : 
     129           0 :   EvtVector4R P_nS;
     130           0 :   EvtVector4R P_pi1;
     131           0 :   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           0 :   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           0 :       double mX = EvtRandom::Flat(2.0 * m_pi, M_mS-M_nS);
     144             : 
     145             :       //   report(Severity::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           0 :       double masses[2];
     151           0 :       masses[0] = M_nS;
     152           0 :       masses[1] = mX;
     153             : 
     154           0 :       EvtVector4R p4[2];
     155             : 
     156           0 :       EvtGenKine::PhaseSpace( 2, masses, p4, M_mS );
     157             : 
     158           0 :       P_nS = p4[0];
     159           0 :       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           0 :       masses[0] = s1->mass();
     165           0 :       masses[1] = s2->mass();
     166             : 
     167           0 :       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           0 :       EvtVector4R P_YmS_X = boostTo(p->getP4(), P_X);
     174           0 :       double costheta = - p4[0].dot(P_YmS_X)/(p4[0].d3mag()*P_YmS_X.d3mag());
     175           0 :       if (EvtPDL::name(s1->getId()) == "pi0") {
     176           0 :         if (costheta < 0) {
     177           0 :           costheta = - p4[1].dot(P_YmS_X)/(p4[1].d3mag()*P_YmS_X.d3mag());
     178           0 :         }
     179             :       }
     180           0 :       if (EvtPDL::name(s1->getId()) == "pi-") {
     181           0 :         costheta = - p4[1].dot(P_YmS_X)/(p4[1].d3mag()*P_YmS_X.d3mag());
     182           0 :       }
     183             :   
     184             :       // //   report(Severity::Info,"EvtYmSToYnSpipiCLEO")  << "cos(theta) = " << costheta << endl;
     185             :     
     186             :     
     187             : 
     188             :       // Now boost the pion four vectors into the Y(mS) rest frame
     189           0 :       P_pi1 = boostTo(p4[0],P_YmS_X);
     190           0 :       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           0 :       double Q    = (mX*mX - 2.0 * m_pi * m_pi);
     209             : 
     210             :       double deltaEmax = 
     211           0 :         - 2.0 * 
     212           0 :         sqrt( P_nS.get(0)*P_nS.get(0) - M_nS*M_nS ) *
     213           0 :         sqrt( 0.25 - pow(m_pi/mX,2.0));
     214             : 
     215           0 :       double sumE = (M_mS*M_mS - M_nS*M_nS + mX*mX)/(2.0 * M_mS);
     216             : 
     217           0 :       double E1E2 = 0.25 * ( pow(sumE, 2.0) - pow( deltaEmax * costheta, 2.0) );
     218             : 
     219           0 :       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           0 :         sqrt( (M_mS*M_mS - pow(M_nS + mX,2.0)) * (M_mS*M_mS - pow(M_nS - mX,2.0)) ) * // p(*)_X
     231           0 :         sqrt(mX*mX - 4*m_pi*m_pi); // p(X)_{pi}
     232             : 
     233             :       // the double-differential decay rate dG/(dcostheta dmX)
     234           0 :       double dG = M2 * dPS;
     235             : 
     236             :       // Throw a uniform random number from 0 --> probMax and do accept/reject on this
     237             :       
     238           0 :       double rnd = EvtRandom::Flat(0.0,getProbMax(0.0));
     239             : 
     240           0 :       if (rnd < dG)
     241           0 :         acceptX = true;
     242             : 
     243           0 :     }
     244             : 
     245             : 
     246             :   // initialize the daughters
     247           0 :   v->init(  getDaugs()[0], P_nS);
     248           0 :   s1->init( getDaugs()[1], P_pi1);
     249           0 :   s2->init( getDaugs()[2], P_pi2); 
     250             : 
     251             : //   report(Severity::Info,"EvtYmSToYnSpipiCLEO")  << "M_nS = " << v->getP4().mass() << endl;
     252             : //   report(Severity::Info,"EvtYmSToYnSpipiCLEO")  << "m_pi = " << s1->getP4().mass() << endl;
     253             : //   report(Severity::Info,"EvtYmSToYnSpipiCLEO")  << "m_pi = " << s2->getP4().mass() << endl;
     254             : //   report(Severity::Info,"EvtYmSToYnSpipiCLEO")  << "M2 = "   << M2 << endl;
     255             :   
     256             :   // Pass the polarization of the parent Upsilon
     257           0 :   EvtVector4C ep0,ep1,ep2;  
     258             :   
     259           0 :   ep0=p->eps(0);
     260           0 :   ep1=p->eps(1);
     261           0 :   ep2=p->eps(2);
     262             : 
     263             : 
     264           0 :   vertex(0,0,(ep0*v->epsParent(0).conj()));
     265           0 :   vertex(0,1,(ep0*v->epsParent(1).conj()));
     266           0 :   vertex(0,2,(ep0*v->epsParent(2).conj()));
     267             :   
     268           0 :   vertex(1,0,(ep1*v->epsParent(0).conj()));
     269           0 :   vertex(1,1,(ep1*v->epsParent(1).conj()));
     270           0 :   vertex(1,2,(ep1*v->epsParent(2).conj()));
     271             :   
     272           0 :   vertex(2,0,(ep2*v->epsParent(0).conj()));
     273           0 :   vertex(2,1,(ep2*v->epsParent(1).conj()));
     274           0 :   vertex(2,2,(ep2*v->epsParent(2).conj()));
     275             : 
     276             : 
     277             :   return ;
     278             : 
     279           0 : }
     280             : 
     281             : 
     282             : 
     283             : 

Generated by: LCOV version 1.11