//============================================================================= // 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))); } }
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; }
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(); } } }
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); } }
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 ; }