//=============================================================================
// decay particle
//=============================================================================
void EvtBToDDalitzCPK::decay( EvtParticle * p ) 
{
  if ( _flag == 1 ) {
    // PHSP
    p -> initializePhaseSpace( getNDaug() , getDaugs() ) ;
    vertex ( 0. ) ;
  }
  else if ( _flag == 2 ) {
    // SVS
    p->initializePhaseSpace(getNDaug(),getDaugs());
    
    EvtParticle *v;
    v = p->getDaug(0);
    double massv = v->mass();
    EvtVector4R momv = v->getP4();
    EvtVector4R moms = p->getDaug(1)->getP4();
    double m_parent = p->mass();
    EvtVector4R p4_parent = momv+moms;
    
    double norm=massv/(momv.d3mag()*m_parent);
    p4_parent = norm*p4_parent;
    vertex(0,p4_parent*(v->epsParent(0)));
    vertex(1,p4_parent*(v->epsParent(1)));
    vertex(2,p4_parent*(v->epsParent(2)));
  }
}
Example #2
0
void EvtD0gammaDalitz::decay( EvtParticle* part )
{
  // Check if the D is from a B+- -> D0 K+- decay with the appropriate model.
  EvtParticle* parent = part->getParent(); // If there are no mistakes, should be B+ or B-.
  if (parent != 0 && EvtDecayTable::getInstance()->getDecayFunc( parent )->getName() == "BTODDALITZCPK" )
  {
    EvtId parId = parent->getId();
    if ( ( parId == _BP ) || ( parId == _BM ) ||
         ( parId == _B0 ) || ( parId == _B0B) )
    {
      _bFlavor = parId;
    }
    else
    {
      reportInvalidAndExit();
    }
  }
  else
  {
    reportInvalidAndExit();
  }

  // Read the D decay parameters from the B decay model.
  // Gamma angle in rad.
  double gamma = EvtDecayTable::getInstance()->getDecayFunc( parent )->getArg( 0 );
  // Strong phase in rad.
  double delta = EvtDecayTable::getInstance()->getDecayFunc( parent )->getArg( 1 );
  // Ratio between B->D0K and B->D0barK
  double rB    = EvtDecayTable::getInstance()->getDecayFunc( parent )->getArg( 2 );

  // Same structure for all of these decays.
  part->initializePhaseSpace( getNDaug(), getDaugs() );
  EvtVector4R pA = part->getDaug( _d1 )->getP4();
  EvtVector4R pB = part->getDaug( _d2 )->getP4();
  EvtVector4R pC = part->getDaug( _d3 )->getP4();

  // Squared invariant masses.
  double mSqAB = ( pA + pB ).mass2();
  double mSqAC = ( pA + pC ).mass2();
  double mSqBC = ( pB + pC ).mass2();

  EvtComplex amp( 1.0, 0.0 );

  // Direct and conjugated amplitudes.
  EvtComplex ampDir;
  EvtComplex ampCnj;

  if ( _isKsPiPi )
  {
    // Direct and conjugated Dalitz points.
    EvtDalitzPoint pointDir( _mKs, _mPi, _mPi, mSqAB, mSqBC, mSqAC );
    EvtDalitzPoint pointCnj( _mKs, _mPi, _mPi, mSqAC, mSqBC, mSqAB );

    // Direct and conjugated amplitudes.
    ampDir = dalitzKsPiPi( pointDir );
    ampCnj = dalitzKsPiPi( pointCnj );
  }
  else
  {
    // Direct and conjugated Dalitz points.
    EvtDalitzPoint pointDir( _mKs, _mK, _mK, mSqAB, mSqBC, mSqAC );
    EvtDalitzPoint pointCnj( _mKs, _mK, _mK, mSqAC, mSqBC, mSqAB );

    // Direct and conjugated amplitudes.
    ampDir = dalitzKsKK( pointDir );
    ampCnj = dalitzKsKK( pointCnj );
  }

  if ( _bFlavor == _BP || _bFlavor == _B0 )
  {
    amp = ampCnj + rB * exp( EvtComplex( 0., delta + gamma ) ) * ampDir;
  }
  else
  {
    amp = ampDir + rB * exp( EvtComplex( 0., delta - gamma ) ) * ampCnj;
  }

  vertex( amp );

  return;

}
Example #3
0
void EvtDecayAmp::makeDecay(EvtParticle* p, bool recursive){

  //original default value
  int ntimes=10000;
  
  int more;

  EvtSpinDensity rho;
  double prob,prob_max;

  _amp2.init(p->getId(),getNDaug(),getDaugs());

  do{

    _daugsDecayedByParentModel=false;
    _weight = 1.0;
    decay(p);

    rho=_amp2.getSpinDensity();

    prob=p->getSpinDensityForward().normalizedProb(rho);

    if (prob<0.0) {
      EvtGenReport(EVTGEN_ERROR,"EvtGen")<<"Negative prob:"<<p->getId().getId()
			    <<" "<<p->getChannel()<<endl;

      EvtGenReport(EVTGEN_ERROR,"EvtGen") << "rho_forward:"<<endl;
      EvtGenReport(EVTGEN_ERROR,"EvtGen") << p->getSpinDensityForward();
      EvtGenReport(EVTGEN_ERROR,"EvtGen") << "rho decay:"<<endl;
      EvtGenReport(EVTGEN_ERROR,"EvtGen") << rho <<endl;
    }

    if (prob!=prob) {

      EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "Forward density matrix:"<<endl;
      EvtGenReport(EVTGEN_DEBUG,"EvtGen") << p->getSpinDensityForward();

      EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "Decay density matrix:"<<endl;
      EvtGenReport(EVTGEN_DEBUG,"EvtGen") << rho;

      EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "prob:"<<prob<<endl;
      
      EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "Particle:"
			     <<EvtPDL::name(p->getId()).c_str()<<endl;
      EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "channel        :"<<p->getChannel()<<endl;
      EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "Momentum:" << p->getP4() << " " << p->mass() << endl;
      if( p->getParent()!=0){
	EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "parent:"
			       <<EvtPDL::name(
				p->getParent()->getId()).c_str()<<endl;
	EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "parent channel        :"
			       <<p->getParent()->getChannel()<<endl;

        size_t i;
	EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "parent daughters  :";
        for (i=0;i<p->getParent()->getNDaug();i++){
	  EvtGenReport(EVTGEN_DEBUG,"") << EvtPDL::name(
			    p->getParent()->getDaug(i)->getId()).c_str()
				 << " ";
        }
	EvtGenReport(EVTGEN_DEBUG,"") << endl;

	EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "daughters  :";
        for (size_t i=0;i<p->getNDaug();i++){
	  EvtGenReport(EVTGEN_DEBUG,"") << EvtPDL::name(
			    p->getDaug(i)->getId()).c_str()
				 << " ";
        }
	EvtGenReport(EVTGEN_DEBUG,"") << endl;

	EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "daughter momenta  :" << endl;;
        for (size_t i=0;i<p->getNDaug();i++){
	  EvtGenReport(EVTGEN_DEBUG,"") << p->getDaug(i)->getP4() << " " << p->getDaug(i)->mass();
	  EvtGenReport(EVTGEN_DEBUG,"") << endl;
        }

      }
    }


    prob/=_weight;

    prob_max = getProbMax(prob);
    p->setDecayProb(prob/prob_max);

    more=prob<EvtRandom::Flat(prob_max);
    
    ntimes--;

  }while(ntimes&&more);

  if (ntimes==0){
    EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "Tried accept/reject: 10000" 
			   <<" times, and rejected all the times!"<<endl;
   
    EvtGenReport(EVTGEN_DEBUG,"EvtGen")<<p->getSpinDensityForward()<<endl;
    EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "Is therefore accepting the last event!"<<endl;
    EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "Decay of particle:"<<
      EvtPDL::name(p->getId()).c_str()<<"(channel:"<<
      p->getChannel()<<") with mass "<<p->mass()<<endl;
    
    for(size_t ii=0;ii<p->getNDaug();ii++){
      EvtGenReport(EVTGEN_DEBUG,"EvtGen") <<"Daughter "<<ii<<":"<<
	EvtPDL::name(p->getDaug(ii)->getId()).c_str()<<" with mass "<<
	p->getDaug(ii)->mass()<<endl;
    }				   
  }

  EvtSpinDensity rho_list[10];

  rho_list[0]=p->getSpinDensityForward();

  EvtAmp ampcont;

  if (_amp2._pstates!=1){
    ampcont=_amp2.contract(0,p->getSpinDensityForward());
  }
  else{
    ampcont=_amp2;
  }


  // it may be that the parent decay model has already
  // done the decay - this should be rare and the
  // model better know what it is doing..
  
  if ( !daugsDecayedByParentModel() ){

    if(recursive) {   
    
      for(size_t i=0;i<p->getNDaug();i++){

	rho.setDim(_amp2.dstates[i]);
      
	if (_amp2.dstates[i]==1) {
	  rho.set(0,0,EvtComplex(1.0,0.0));
	}
	else{
	  rho=ampcont.contract(_amp2._dnontrivial[i],_amp2);
	}
	
	if (!rho.check()) {
	  
	  EvtGenReport(EVTGEN_ERROR,"EvtGen") << "-------start error-------"<<endl;
	  EvtGenReport(EVTGEN_ERROR,"EvtGen")<<"forward rho failed Check:"<<
	    EvtPDL::name(p->getId()).c_str()<<" "<<p->getChannel()<<" "<<i<<endl;
	  
	  p->printTree();

	  for (size_t idaug = 0; idaug < p->getNDaug(); idaug++) {
	    EvtParticle* daughter = p->getDaug(idaug);
	    if (daughter != 0) {daughter->printTree();}
	  }

	  EvtParticle* pParent = p->getParent();
	  if (pParent != 0) {
	    EvtGenReport(EVTGEN_ERROR,"EvtGen")<<"Parent:"<<EvtPDL::name(pParent->getId()).c_str()<<endl;

	    EvtParticle* grandParent = pParent->getParent();

	    if (grandParent != 0) {
	      EvtGenReport(EVTGEN_ERROR,"EvtGen")<<"GrandParent:"<<EvtPDL::name(grandParent->getId()).c_str()<<endl;
	    }
	  }

	  EvtGenReport(EVTGEN_ERROR,"EvtGen") << " EvtSpinDensity rho: " << rho;
	  
	  _amp2.dump();

	  for(size_t ii=0;ii<i+1;ii++){
	    EvtGenReport(EVTGEN_ERROR,"EvtGen") << "rho_list[" << ii << "] = " << rho_list[ii];
	  }

	  EvtGenReport(EVTGEN_ERROR,"EvtGen") << "-------Done with error-------"<<endl;  

	}
      
	p->getDaug(i)->setSpinDensityForward(rho);
	p->getDaug(i)->decay();
	
	rho_list[i+1]=p->getDaug(i)->getSpinDensityBackward();
	
	if (_amp2.dstates[i]!=1){
	ampcont=ampcont.contract(_amp2._dnontrivial[i],rho_list[i+1]);
	}
      
	
      }
      
      p->setSpinDensityBackward(_amp2.getBackwardSpinDensity(rho_list));
      
      
      if (!p->getSpinDensityBackward().check()) {
	
	EvtGenReport(EVTGEN_ERROR,"EvtGen")<<"rho_backward failed Check"<<
	  p->getId().getId()<<" "<<p->getChannel()<<endl;
      
	EvtGenReport(EVTGEN_ERROR,"EvtGen") << p->getSpinDensityBackward();
      
      }
    }    
  }


  if (getPHOTOS() || EvtRadCorr::alwaysRadCorr()) {
    int n_daug_orig=p->getNDaug();
    EvtRadCorr::doRadCorr(p);
    int n_daug_new=p->getNDaug();
    for (int i=n_daug_orig;i<n_daug_new;i++){
      p->getDaug(i)->decay();
    }
  }

}
Example #4
0
void EvtBtoXsll::decay( EvtParticle *p ){

  p->makeDaughters(getNDaug(),getDaugs());

  EvtParticle* xhadron = p->getDaug(0);
  EvtParticle* leptonp = p->getDaug(1);
  EvtParticle* leptonn = p->getDaug(2);

  double mass[3];
 
  findMasses( p, getNDaug(), getDaugs(), mass );

  double mB = p->mass();
  double ml = mass[1];
  double pb(0.);

  int im = 0;
  static int nmsg = 0;
  double xhadronMass = -999.0;

  EvtVector4R p4xhadron;
  EvtVector4R p4leptonp;
  EvtVector4R p4leptonn;

  // require the hadronic system has mass greater than that of a Kaon pion pair

  //  while (xhadronMass < 0.6333)
  // the above minimum value of K+pi mass appears to be too close
  // to threshold as far as JETSET is concerned
  // (JETSET gets caught in an infinite loop)
  // so we choose a lightly larger value for the threshold
  while (xhadronMass < _mxmin)
  {
    im++;

    // Apply Fermi motion and determine effective b-quark mass

    // Old BaBar MC parameters
    //    double pf = 0.25;
    //    double ms = 0.2;
    //    double mq = 0.3;

    double mb = 0.0;

    double xbox, ybox;

    while (mb <= 0.0)
    {
      pb = _calcprob->FermiMomentum(_pf);

      // effective b-quark mass
      mb = mB*mB + _mq*_mq - 2.0*mB*sqrt(pb*pb + _mq*_mq);
      if ( mb>0. && sqrt(mb)-_ms  < 2.0*ml ) mb= -10.;
    }
    mb = sqrt(mb);
  
    //    cout << "b-quark momentum = " << pb << " mass = " <<  mb << endl;

    // generate a dilepton invariant mass

    double s    = 0.0;
    double smin = 4.0 * ml * ml;
    double smax = (mb - _ms)*(mb - _ms);

    while (s == 0.0)
      {
      xbox = EvtRandom::Flat(smin, smax);
      ybox = EvtRandom::Flat(_dGdsProbMax);
      double prob= _calcprob->dGdsProb(mb, _ms, ml, xbox);
      if ( !(prob>=0.0) && !(prob<=0.0)) {
	//	EvtGenReport(EVTGEN_INFO,"EvtGen") << "nan from dGdsProb " << prob << " " << mb << " " << _ms << " " << ml << " " << xbox << std::endl;
      }
      if ( ybox < prob ) s=xbox;
      }

    //    cout << "dGdsProb(s) = " << _calcprob->dGdsProb(mb, _ms, ml, s)
    //         << " for s = " << s << endl;

    // two-body decay of b quark at rest into s quark and dilepton pair:
    // b -> s (ll)

    EvtVector4R p4sdilep[2];

    double msdilep[2];
    msdilep[0] = _ms;
    msdilep[1] = sqrt(s);

    EvtGenKine::PhaseSpace(2, msdilep, p4sdilep, mb);

    // generate dilepton decay with the expected asymmetry: (ll) -> l+ l-

    EvtVector4R p4ll[2];

    double mll[2];
    mll[0] = ml;
    mll[1] = ml;

    double tmp = 0.0;

    while (tmp == 0.0)
    {
      // (ll) -> l+ l- decay in dilepton rest frame

      EvtGenKine::PhaseSpace(2, mll, p4ll, msdilep[1]);

      // boost to b-quark rest frame

      p4ll[0] = boostTo(p4ll[0], p4sdilep[1]);
      p4ll[1] = boostTo(p4ll[1], p4sdilep[1]);

      // compute kinematical variable u

      EvtVector4R p4slp = p4sdilep[0] + p4ll[0];
      EvtVector4R p4sln = p4sdilep[0] + p4ll[1];

      double u = p4slp.mass2() - p4sln.mass2();

      ybox = EvtRandom::Flat(_dGdsdupProbMax);

      double prob = _calcprob->dGdsdupProb(mb, _ms, ml, s, u);
      if ( !(prob>=0.0) && !(prob<=0.0)) {
	EvtGenReport(EVTGEN_INFO,"EvtGen") << "nan from dGdsProb " << prob << " " << mb << " " << _ms << " " << ml << " " << s << " " << u << std::endl;
      }
      if (prob > _dGdsdupProbMax && nmsg < 20)
      {
        EvtGenReport(EVTGEN_INFO,"EvtGen") << "d2gdsdup GT d2gdsdup_max:" << prob
             << " " << _dGdsdupProbMax
             << " for s = " << s << " u = " << u << " mb = " << mb << endl;
	         nmsg++;
      }
      if (ybox < prob)
	{
	  tmp = 1.0;
	  //        cout << "dGdsdupProb(s) = " << prob
	  //             << " for u = " << u << endl;
	}
    }


    // assign 4-momenta to valence quarks inside B meson in B rest frame

    double phi   = EvtRandom::Flat( EvtConst::twoPi );
    double costh = EvtRandom::Flat( -1.0, 1.0 );
    double sinth = sqrt(1.0 - costh*costh);

    // b-quark four-momentum in B meson rest frame

    EvtVector4R p4b(sqrt(mb*mb + pb*pb),
                    pb*sinth*sin(phi),
                    pb*sinth*cos(phi),
                    pb*costh);

    // B meson in its rest frame
    //
    //    EvtVector4R p4B(mB, 0.0, 0.0, 0.0);
    //
    // boost B meson to b-quark rest frame
    //
    //    p4B = boostTo(p4B, p4b);
    //
    //    cout << " B meson mass in b-quark rest frame = " << p4B.mass() << endl;

    // boost s, l+ and l- to B meson rest frame

    //    EvtVector4R p4s = boostTo(p4sdilep[0], p4B);
    //    p4leptonp       = boostTo(p4ll[0],     p4B);
    //    p4leptonn       = boostTo(p4ll[1],     p4B);

    EvtVector4R p4s = boostTo(p4sdilep[0], p4b);
    p4leptonp       = boostTo(p4ll[0],     p4b);
    p4leptonn       = boostTo(p4ll[1],     p4b);

    // spectator quark in B meson rest frame

    EvtVector4R p4q( sqrt(pb*pb + _mq*_mq), -p4b.get(1), -p4b.get(2), -p4b.get(3) );

    // hadron system in B meson rest frame

    p4xhadron = p4s + p4q;
    xhadronMass = p4xhadron.mass();

    //    cout << "Xs mass = " << xhadronMass << " trial " << im << endl;
  }

  // initialize the decay products

  xhadron->init(getDaug(0), p4xhadron);

  // For B-bar mesons (i.e. containing a b quark) we have the normal
  // order of leptons
  if ( p->getId() == EvtPDL::getId("anti-B0") ||
       p->getId() == EvtPDL::getId("B-") )
  {
    leptonp->init(getDaug(1), p4leptonp);
    leptonn->init(getDaug(2), p4leptonn);
  }
  // For B mesons (i.e. containing a b-bar quark) we need to flip the
  // role of the positive and negative leptons in order to produce the
  // correct forward-backward asymmetry between the two leptons
  else
  {
    leptonp->init(getDaug(1), p4leptonn);
    leptonn->init(getDaug(2), p4leptonp);
  }

  return ;
}
void EvtPythiaEngine::createDaughterEvtParticles(EvtParticle* theParent) {

    if (theParent == 0) {
        EvtGenReport(EVTGEN_INFO,"EvtGen")<<"Error in EvtPythiaEngine::createDaughterEvtParticles. The parent is null"<<endl;
        return;
    }

    // Get the list of Pythia decay modes defined for this particle id alias.
    // It would be easier to just use the decay channel number that Pythia chose to use
    // for the particle decay, but this is not accessible from the Pythia interface at present.

    int nDaughters = _daugPDGVector.size();
    std::vector<EvtId> daugAliasIdVect(0);

    EvtId particleId = theParent->getId();
    // Check to see if we have an anti-particle. If we do, charge conjugate the particle id to get the
    // Pythia "alias" we can compare with the defined (particle) Pythia modes.
    int PDGId = EvtPDL::getStdHep(particleId);
    int aliasInt = particleId.getAlias();
    int pythiaAliasInt(aliasInt);

    if (PDGId < 0) {
        // We have an anti-particle.
        EvtId conjPartId = EvtPDL::chargeConj(particleId);
        pythiaAliasInt = conjPartId.getAlias();
    }

    std::vector<int> pythiaModes = _pythiaModeMap[pythiaAliasInt];

    // Loop over all available Pythia decay modes and find the channel that matches
    // the daughter ids. Set each daughter id to also use the alias integer.
    // This will then convert the Pythia generated channel to the EvtGen alias defined one.

    std::vector<int>::iterator modeIter;
    bool gotMode(false);

    for (modeIter = pythiaModes.begin(); modeIter != pythiaModes.end(); ++modeIter) {

        // Stop the loop if we have the right decay mode channel
        if (gotMode) {
            break;
        }

        int pythiaModeInt = *modeIter;

        EvtDecayBase* decayModel = EvtDecayTable::getInstance()->findDecayModel(aliasInt, pythiaModeInt);

        if (decayModel != 0) {

            int nModeDaug = decayModel->getNDaug();

            // We need to make sure that the number of daughters match
            if (nDaughters == nModeDaug) {

                int iModeDaug(0);
                for (iModeDaug = 0; iModeDaug < nModeDaug; iModeDaug++) {

                    EvtId daugId = decayModel->getDaug(iModeDaug);
                    int daugPDGId = EvtPDL::getStdHep(daugId);
                    // Pythia has used the right PDG codes for this decay mode, even for conjugate modes
                    int pythiaPDGId = _daugPDGVector[iModeDaug];

                    if (daugPDGId == pythiaPDGId) {
                        daugAliasIdVect.push_back(daugId);
                    }

                } // Loop over EvtGen mode daughters

                int daugAliasSize = daugAliasIdVect.size();
                if (daugAliasSize == nDaughters) {
                    // All daughter Id codes are accounted for. Set the flag to stop the loop.
                    gotMode = true;
                } else {
                    // We do not have the correct daughter ordering. Clear the id vector
                    // and try another mode.
                    daugAliasIdVect.clear();
                }

            } // Same number of daughters

        } // decayModel != 0

    } // Loop over available Pythia modes

    if (gotMode == false) {

        // We did not find a match for the daughter aliases. Just use the normal PDG codes
        // from the Pythia decay result
        int iPyDaug(0);
        for (iPyDaug = 0; iPyDaug < nDaughters; iPyDaug++) {

            int daugPDGCode = _daugPDGVector[iPyDaug];
            EvtId daugPyId = EvtPDL::evtIdFromStdHep(daugPDGCode);
            daugAliasIdVect.push_back(daugPyId);

        }
    }

    // Make the EvtParticle daughters (with correct alias id's). Their 4-momenta are uninitialised.
    theParent->makeDaughters(nDaughters, daugAliasIdVect);

    // Now set the 4-momenta of the daughters.
    int iDaug(0);
    // Can use an iterator here, but we already had to use the vector size...
    for (iDaug = 0; iDaug < nDaughters; iDaug++) {

        EvtParticle* theDaughter = theParent->getDaug(iDaug);

        // Set the correct 4-momentum for each daughter particle.
        if (theDaughter != 0) {
            EvtId theDaugId = daugAliasIdVect[iDaug];
            const EvtVector4R theDaugP4 = _daugP4Vector[iDaug];
            theDaughter->init(theDaugId, theDaugP4);
        }

    }

}
void EvtSVSNONCPEIGEN::decay( EvtParticle *p){

  //added by Lange Jan4,2000
  static EvtId B0=EvtPDL::getId("B0");
  static EvtId B0B=EvtPDL::getId("anti-B0");

  double t;
  EvtId other_b;
  EvtId daugs[2];

  // MB: flip selects the final of the decay
  int flip = ((p->getId() == B0) ? 0 : 1);
  daugs[0]=getDaug(0);
  daugs[1]=getDaug(1);
  p->initializePhaseSpace(2, daugs);

  EvtCPUtil::getInstance()->OtherB(p,t,other_b,0.5);

  EvtComplex amp;
  double dmt2 = (_dm * t) / (2 * EvtConst::c);
  EvtComplex ePlusIPhi(cos(_phickm), sin(_phickm));
  EvtComplex eMinusIPhi(cos(-_phickm), -sin(_phickm));

  // flip == 0 : D-rho+
  // flip == 1 : D+rho-

   if (!flip) {
     if (other_b==B0B){
       // At t=0 we have a B0
       amp = cos(dmt2)*_A_f + eMinusIPhi*EvtComplex(0.0,sin(dmt2))*_Abar_f;
     }
     if (other_b==B0){
       // At t=0 we have a B0bar
       amp = ePlusIPhi*EvtComplex(0.0,sin(dmt2))*_A_f + cos(dmt2)*_Abar_f;
     }
   }
   else{
     if (other_b==B0B){
       // At t=0 we have a B0
       amp = cos(dmt2)*_A_fbar + eMinusIPhi*EvtComplex(0.0,sin(dmt2))*_Abar_fbar;
     }
     if (other_b==B0){
       // At t=0 we have a B0bar
       amp = ePlusIPhi*EvtComplex(0.0,sin(dmt2))*_A_fbar + cos(dmt2)*_Abar_fbar;
     }
   }


  EvtParticle *v;
  v= p->getDaug(0);

  EvtVector4R momv = p->getDaug(0)->getP4();
  EvtVector4R moms = p->getDaug(1)->getP4();
  EvtVector4R p4_parent=momv+moms;

  double norm=momv.mass()/(momv.d3mag()*p->mass());

  vertex(0,amp*norm*p4_parent*(v->epsParent(0)));
  vertex(1,amp*norm*p4_parent*(v->epsParent(1)));
  vertex(2,amp*norm*p4_parent*(v->epsParent(2)));

  return ;
}
void EvtSSD_DirectCP::decay( EvtParticle *p) {

    bool flip = false ;
    EvtId daugs[2];

    // decide it is B or Bbar:
    if ( EvtRandom::Flat(0.,1.) < ( ( 1. - _acp ) / 2. ) ) {
        // it is a B
        if ( EvtPDL::getStdHep( getParentId() ) < 0 ) flip = true ;
    } else {
        // it is a Bbar
        if ( EvtPDL::getStdHep( getParentId() ) > 0 ) flip = true ;
    }

    if ( flip ) {
        if ( ( isB0Mixed( p ) ) || ( isBsMixed( p ) ) ) {
            p->getParent()
            ->setId( EvtPDL::chargeConj( p->getParent()->getId() ) ) ;
            p->setId( EvtPDL::chargeConj( p->getId() ) ) ;
        }
        else {
            p->setId( EvtPDL::chargeConj( p->getId() ) ) ;
        }
    }

    if (!flip) {
        daugs[0]=getDaug(0);
        daugs[1]=getDaug(1);
    }
    else {
        daugs[0]=EvtPDL::chargeConj(getDaug(0));
        daugs[1]=EvtPDL::chargeConj(getDaug(1));
    }

    EvtParticle *d;
    p->initializePhaseSpace(2, daugs);

    EvtVector4R p4_parent=p->getP4Restframe();
    double m_parent=p4_parent.mass();

    EvtSpinType::spintype d2type=EvtPDL::getSpinType(getDaug(1));

    EvtVector4R momv;
    EvtVector4R moms;

    if (d2type==EvtSpinType::SCALAR) {
        d2type=EvtPDL::getSpinType(getDaug(0));
        d= p->getDaug(0);
        momv = d->getP4();
        moms = p->getDaug(1)->getP4();
    }
    else {
        d= p->getDaug(1);
        momv = d->getP4();
        moms = p->getDaug(0)->getP4();
    }

    if (d2type==EvtSpinType::SCALAR) {
        vertex(1.);
    }

    if (d2type==EvtSpinType::VECTOR) {

        double norm=momv.mass()/(momv.d3mag()*p->mass());

        vertex(0,norm*p4_parent*(d->epsParent(0)));
        vertex(1,norm*p4_parent*(d->epsParent(1)));
        vertex(2,norm*p4_parent*(d->epsParent(2)));

    }

    if (d2type==EvtSpinType::TENSOR) {

        double norm=
            d->mass()*d->mass()/(m_parent*d->getP4().d3mag()*d->getP4().d3mag());


        vertex(0,norm*d->epsTensorParent(0).cont1(p4_parent)*p4_parent);
        vertex(1,norm*d->epsTensorParent(1).cont1(p4_parent)*p4_parent);
        vertex(2,norm*d->epsTensorParent(2).cont1(p4_parent)*p4_parent);
        vertex(3,norm*d->epsTensorParent(3).cont1(p4_parent)*p4_parent);
        vertex(4,norm*d->epsTensorParent(4).cont1(p4_parent)*p4_parent);
    }
}
Example #8
0
void EvtVectorIsr::decay( EvtParticle *p ){

  //the elctron mass
  double electMass=EvtPDL::getMeanMass(EvtPDL::getId("e-"));

  static EvtId gammaId=EvtPDL::getId("gamma");

  EvtParticle *phi;
  EvtParticle *gamma;

  //4-mom of the two colinear photons to the decay of the vphoton
  EvtVector4R p4softg1(0.,0.,0.,0.);
  EvtVector4R p4softg2(0.,0.,0.,0.);


  //get pointers to the daughters set
  //get masses/initial phase space - will overwrite the
  //p4s below to get the kinematic distributions correct
  p->initializePhaseSpace(getNDaug(),getDaugs());
  phi=p->getDaug(0);
  gamma=p->getDaug(1);

  //Generate soft colinear photons and the electron and positron energies after emission.
  //based on method of AfkQed and notes of Vladimir Druzhinin.
  //
  //function ckhrad(eb,q2m,r1,r2,e01,e02,f_col)
  //eb:      energy of incoming electrons in CM frame
  //q2m:     minimum invariant mass of the virtual photon after soft colinear photon emission
  //returned arguments
  //e01,e02: energies of e+ and e- after soft colinear photon emission
  //fcol:    weighting factor for Born cross section for use in an accept/reject test.


  double wcm=p->mass();
  double eb=0.5*wcm;

  //TO guarantee the collinear photons are softer than the ISR photon, require q2m > m*wcm
  double q2m=phi->mass()*wcm;
  double f_col(0.);
  double e01(0.);
  double e02(0.);
  double ebeam=eb;
  double wcm_new = wcm;
  double s_new = wcm*wcm;

  double fran = 1.;
  double f = 0;
  int m = 0;
  double largest_f=0;//only used when determining max weight for this vector particle mass
    
  if (!firstorder){
    while (fran > f){
      m++;    
    
      int n=0;
      while (f_col == 0.){
	n++;
	ckhrad(eb,q2m,e01,e02,f_col);
	if (n > 10000){
	  report(Severity::Info,"EvtGen") << "EvtVectorIsr is having problems. Called ckhrad 10000 times.\n";
	  assert(0);
	}
      }
    
      //Effective beam energy after soft photon emission (neglecting electron mass)
      ebeam = sqrt(e01*e02);
      wcm_new = 2*ebeam;
      s_new = wcm_new*wcm_new;
    
      //The Vector mass should never be greater than wcm_new
      if (phi->mass() > wcm_new){
	report(Severity::Info,"EvtGen") << "EvtVectorIsr finds Vector mass="<<phi->mass()<<" > Weff=" << wcm_new<<".  Should not happen\n";
	assert(0);
      }
 
      //Determine Born cross section @ wcm_new for e+e- -> gamma V.  We aren't interested in the absolute normalization
      //Just the functional dependence. Assuming a narrow resonance when determining cs_Born
      double cs_Born = 1.;
      if (EvtPDL::getMaxRange(phi->getId()) > 0.) {
	double x0 = 1 - EvtPDL::getMeanMass(phi->getId())*EvtPDL::getMeanMass(phi->getId())/s_new;
      
	//L = log(s/(electMass*electMass)  
	double L = 2.*log(wcm_new/electMass);
      
	// W(x0) is actually 2*alpha/pi times the following
	double W = (L-1.)*(1. - x0 +0.5*x0*x0);
      
	//Born cross section is actually 12*pi*pi*Gammaee/EvtPDL::getMeanMass(phi->getId()) times the following
	//(we'd need the full W(x0) as well)
	cs_Born = W/s_new;
      }
    
      f = cs_Born*f_col;

      //if fmax was set properly, f should NEVER be larger than fmax
      if (f > fmax && fmax > 0.){
	  report(Severity::Info,"EvtGen") << "EvtVectorIsr finds a problem with fmax, the maximum weight setting\n"
	     << "fmax is the third decay argument in the .dec file. VectorIsr attempts to set it reasonably if it wasn't provided\n"
	     << "To determine a more appropriate value, build GeneratorQAApp, and set the third argument for this decay <0.\n"
	     << "If you haven't been providing the first 2 arguments, set them to be 1. 1.). The program will report\n"
	     << "the largest weight it finds.  You should set fmax to be slightly larger.\n"
	     << "Alternatively try the following values for various vector particles: "
	     << "phi->1.15   J/psi-psi(4415)->0.105\n"
	     << "The current value of f and fmax for " << EvtPDL::name(phi->getId()) << " are " << f << "  " << fmax << "\n"
	     << "Will now assert\n";
	assert(0);
      }
 

      if (fmax > 0.) {
	fran = fmax*EvtRandom::Flat(0.0,1.0);
      }
    
      else {
	//determine max weight for this vector particle mass
	if (f>largest_f) {
	  largest_f = f;
	  report(Severity::Info,"EvtGen")  << m << " " <<  EvtPDL::name(phi->getId()) << " "
	       << "vector_mass " 
	       << " " << EvtPDL::getMeanMass(phi->getId()) << "  fmax should be at least " << largest_f 
	       << ".        f_col cs_B = " << f_col << " " << cs_Born 
	       << std::endl;
	}
	if (m%10000 == 0) {  
	  report(Severity::Info,"EvtGen") << m << " " <<  EvtPDL::name(phi->getId()) << " "
	       << "vector_mass " 
	       << " " << EvtPDL::getMeanMass(phi->getId()) << "  fmax should be at least " << largest_f 
	       << ".        f_col cs_B = " << f_col << " " << cs_Born 
	       << std::endl;
	}
      
	f_col = 0.;
	f = 0.;
	//determine max weight for this vector particle mass
      }
    
      if (m > 100000){
      
	if (fmax > 0.) report(Severity::Info,"EvtGen") << "EvtVectorIsr is having problems. Check the fmax value - the 3rd argument in the .dec file\n"
					     << "Recommended values for various vector particles: "
					     << "phi->1.15   J/psi-psi(4415)->0.105   "
					     << "Upsilon(1S,2S,3S)->0.14\n";
	assert(0);
      }
    }//while (fran > f)
  
  }//if (firstorder)
  
  //Compute parameters for boost to/from the system after colinear radiation

  double bet_l;
  double gam_l;
  double betgam_l;
  
  double csfrmn_new;
  double csbkmn_new;

  if (firstorder){
    bet_l = 0.;
    gam_l = 1.;
    betgam_l = 0.;
    csfrmn_new = csfrmn;
    csbkmn_new = csbkmn;
  } else {  
    double xx       = e02/e01;
    double sq_xx    = sqrt(xx);
    bet_l    = (1.-xx)/(1.+xx);
    gam_l    = (1.+xx)/(2.*sq_xx);
    betgam_l = (1.-xx)/(2.*sq_xx);
  
    //Boost photon cos_theta limits in lab to limits in the system after colinear rad
    csfrmn_new=(csfrmn - bet_l)/(1. - bet_l*csfrmn);
    csbkmn_new=(csbkmn - bet_l)/(1. - bet_l*csbkmn);
  }
 
//    //generate kinematics according to Bonneau-Martin article
//    //Nucl. Phys. B27 (1971) 381-397

  // For backward compatibility with .dec files before SP5, the backward cos limit for
  //the ISR photon is actually given as *minus* the actual limit. Sorry, this wouldn't be
  //my choice.  -Joe

   //gamma momentum in the vpho restframe *after* soft colinear radiation
  double pg = (s_new - phi->mass()*phi->mass())/(2.*wcm_new);


  //calculate the beta of incoming electrons after  colinear rad in the frame where e= and e- have equal momentum
  double beta=electMass/ebeam; //electMass/Ebeam = 1/gamma
  beta=sqrt(1. - beta*beta);   //sqrt (1 - (1/gamma)**2)

  double ymax=log((1.+beta*csfrmn_new)/(1.-beta*csfrmn_new));
  double ymin=log((1.-beta*csbkmn_new)/(1.+beta*csbkmn_new));

  // photon theta distributed as  2*beta/(1-beta**2*cos(theta)**2)
  double y=(ymax-ymin)*EvtRandom::Flat(0.0,1.0) + ymin;
  double cs=exp(y);
  cs=(cs - 1.)/(cs + 1.)/beta;
  double sn=sqrt(1-cs*cs);

  double fi=EvtRandom::Flat(EvtConst::twoPi);

  //four-vector for the phi
  double phi_p0 = sqrt(phi->mass()*phi->mass()+pg*pg);
  double phi_p3 = -pg*cs;


  //boost back to frame before colinear radiation.
  EvtVector4R p4phi(gam_l*phi_p0 + betgam_l*phi_p3,
		    -pg*sn*cos(fi),
		    -pg*sn*sin(fi),
		    betgam_l*phi_p0 + gam_l*phi_p3);

  double isr_p0 = pg;
  double isr_p3 = -phi_p3;
  EvtVector4R p4gamma(gam_l*isr_p0 + betgam_l*isr_p3,
		      -p4phi.get(1),
		      -p4phi.get(2),
		      betgam_l*isr_p0 + gam_l*isr_p3);

  
  //four-vectors of the collinear photons
  if (!firstorder) {
    p4softg1.set(0, eb-e02);    p4softg1.set(3, e02-eb);
    p4softg2.set(0, eb-e01);    p4softg2.set(3, eb-e01);
  }
  
  //save momenta for particles
  phi->init( getDaug(0),p4phi);
  gamma->init( getDaug(1),p4gamma);


  //add the two colinear photons as vphoton daughters
  EvtPhotonParticle *softg1=new EvtPhotonParticle;;
  EvtPhotonParticle *softg2=new EvtPhotonParticle;;
  softg1->init(gammaId,p4softg1);
  softg2->init(gammaId,p4softg2);
  softg1->addDaug(p);
  softg2->addDaug(p);

  //try setting the spin density matrix of the phi
  //get polarization vector for phi in its parents restframe.
  EvtVector4C phi0=phi->epsParent(0);
  EvtVector4C phi1=phi->epsParent(1);
  EvtVector4C phi2=phi->epsParent(2);

  //get polarization vector for a photon in its parents restframe.
  EvtVector4C gamma0=gamma->epsParentPhoton(0);
  EvtVector4C gamma1=gamma->epsParentPhoton(1);

  EvtComplex r1p=phi0*gamma0;
  EvtComplex r2p=phi1*gamma0;
  EvtComplex r3p=phi2*gamma0;


  EvtComplex r1m=phi0*gamma1;
  EvtComplex r2m=phi1*gamma1;
  EvtComplex r3m=phi2*gamma1;

  EvtComplex rho33=r3p*conj(r3p)+r3m*conj(r3m);
  EvtComplex rho22=r2p*conj(r2p)+r2m*conj(r2m);
  EvtComplex rho11=r1p*conj(r1p)+r1m*conj(r1m);

  EvtComplex rho13=r3p*conj(r1p)+r3m*conj(r1m);
  EvtComplex rho12=r2p*conj(r1p)+r2m*conj(r1m);
  EvtComplex rho23=r3p*conj(r2p)+r3m*conj(r2m);

  EvtComplex rho31=conj(rho13);
  EvtComplex rho32=conj(rho23);
  EvtComplex rho21=conj(rho12);


  EvtSpinDensity rho;
  rho.setDim(3);

  rho.set(0,0,rho11);
  rho.set(0,1,rho12);
  rho.set(0,2,rho13);
  rho.set(1,0,rho21);
  rho.set(1,1,rho22);
  rho.set(1,2,rho23);
  rho.set(2,0,rho31);
  rho.set(2,1,rho32);
  rho.set(2,2,rho33);

  setDaughterSpinDensity(0);
  phi->setSpinDensityForward(rho);

  return ;
}