diff --git a/EvtGenModels/EvtEtaLLPiPi.hh b/EvtGenModels/EvtEtaLLPiPi.hh new file mode 100644 --- /dev/null +++ b/EvtGenModels/EvtEtaLLPiPi.hh @@ -0,0 +1,81 @@ + +/*********************************************************************** +* Copyright 1998-2020 CERN for the benefit of the EvtGen authors * +* * +* This file is part of EvtGen. * +* * +* EvtGen is free software: you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation, either version 3 of the License, or * +* (at your option) any later version. * +* * +* EvtGen is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with EvtGen. If not, see . * +***********************************************************************/ + +#ifndef EVT_ETALLPIPI_HH +#define EVT_ETALLPIPI_HH + +#include "EvtGenBase/EvtDecayProb.hh" +#include + +class EvtParticle; + +class EvtEtaLLPiPi : public EvtDecayProb { +public: + + EvtEtaLLPiPi(); + + void init() override; + void initProbMax() override; + + std::string getName() override; + EvtDecayBase *clone() override; + + void decay( EvtParticle *p ) override; + +private: + + void updateMassPars( double mLep, double mPi ); + + double rhoWidth( double s, double m ) const; + + double F0( double sLL, double sPiPi ) const; + + double lambda( double a, double b, double c ) const; + + double ampSquared( EvtParticle *p ) const; + + double m_alpha; + double m_eSq; + double m_fPi; + double m_f8; + double m_f0; + double m_thetaMix; + double m_mixSq; + double m_c1; + double m_c2; + double m_c3; + double m_par1; + double m_parLL; + double m_parPiPi; + + double m_rhoMass; + double m_rhoMassSq; + double m_rhoGamma; + + double m_lepMass; + double m_lepMassSq; + double m_piMass; + double m_piMassSq; + double m_4LepMassSq; + double m_4PiMassSq; + +}; + +#endif diff --git a/History.txt b/History.txt --- a/History.txt +++ b/History.txt @@ -4,6 +4,15 @@ // //=========================================================================== +21st Aug 2020 John Back + Add EvtEtaLLPiPi model for eta' -> l l pi pi decays (l = e or mu), + courtesy of Aleksei Luchinsky (LHCb). + +15th May 2020 Michal Kreps + Add EvtThreeBodyPhsp (rectangular Dalitz plot selection) and + EvtPhspDecaytimeCut (minimum decay time requirement) models. + Fix initialisation of constants in EvtBTo3hCP model. + R02-00-00------------------------------------------------------------------- 24th Apr 2020 Michal Kreps Update particle properties file evt.pdl to 2019 version of RPP by PDG. diff --git a/src/EvtGenModels/EvtEtaLLPiPi.cpp b/src/EvtGenModels/EvtEtaLLPiPi.cpp new file mode 100644 --- /dev/null +++ b/src/EvtGenModels/EvtEtaLLPiPi.cpp @@ -0,0 +1,250 @@ + +/*********************************************************************** +* Copyright 1998-2020 CERN for the benefit of the EvtGen authors * +* * +* This file is part of EvtGen. * +* * +* EvtGen is free software: you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation, either version 3 of the License, or * +* (at your option) any later version. * +* * +* EvtGen is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with EvtGen. If not, see . * +***********************************************************************/ + +#include "EvtGenModels/EvtEtaLLPiPi.hh" + +#include "EvtGenBase/EvtConst.hh" +#include "EvtGenBase/EvtId.hh" +#include "EvtGenBase/EvtKine.hh" +#include "EvtGenBase/EvtParticle.hh" +#include "EvtGenBase/EvtPDL.hh" +#include "EvtGenBase/EvtSpinType.hh" +#include "EvtGenBase/EvtVector4R.hh" + +#include + +EvtEtaLLPiPi::EvtEtaLLPiPi() : + m_alpha( 1.0 / 137.0 ), + m_eSq( 4.0 * EvtConst::pi * m_alpha ), + m_fPi( 0.0924 ), + m_f8( 1.3 * m_fPi ), + m_f0( 1.04 * m_fPi ), + m_thetaMix( 20.0 * EvtConst::pi / 180.0 ), + m_mixSq( 0.0 ), + m_c1( 1.0 ), + m_c2( 0.0 ), + m_c3( m_c1 - m_c2 ), // Eq 9 + m_par1( 1.0 - ( 3.0 * ( m_c1 - m_c2 + m_c3 ) / 4.0 ) ), + m_parLL( 3.0 * ( m_c1 - m_c2 - m_c3 ) / 4.0 ), + m_parPiPi( 3.0 * m_c3 / 2.0 ), + m_rhoMass( 0.775 ), // updated in init() + m_rhoMassSq( m_rhoMass * m_rhoMass ), + m_rhoGamma( 0.149 ), // updated in init() + m_lepMass( 0.106 ), // modified in updateMassPars() + m_lepMassSq ( m_lepMass * m_lepMass ), + m_piMass( 0.140 ), // modified in updateMassPars() + m_piMassSq( m_piMass * m_piMass ), + m_4LepMassSq( 4.0 * m_lepMassSq ), + m_4PiMassSq( 4.0 * m_piMassSq ) +{ + // eta' -> mu+ mu- pi+ pi- or e+ e- pi+ pi- + // From Zhang Zhen-Yu et al, Chinese Phys. C 36, p926, 2012 +} + +void EvtEtaLLPiPi::init() { + + // Check for 0 or 1 (maxProb) arguments + checkNArg( 0, 1 ); + + // Check particle types + checkSpinParent( EvtSpinType::SCALAR ); + checkSpinDaughter( 0, EvtSpinType::DIRAC ); + checkSpinDaughter( 1, EvtSpinType::DIRAC ); + checkSpinDaughter( 2, EvtSpinType::SCALAR ); + checkSpinDaughter( 3, EvtSpinType::SCALAR ); + + // Mass and width of rho0 from particle properties file + m_rhoMass = EvtPDL::getMeanMass( EvtPDL::getId("rho0") ); + m_rhoMassSq = m_rhoMass * m_rhoMass; + m_rhoGamma = EvtPDL::getWidth( EvtPDL::getId( "rho0" ) ); + + // Mixing parameter squared, using Eq 6 + const double denom = 8.0 * pow( EvtConst::pi * m_fPi, 2 ); + const double factor = m_eSq / ( denom * denom * 3.0 ); + const double fTerm8 = sin( m_thetaMix ) / m_f8; + const double fTerm0 = 2.0 * sqrt( 2.0 ) * cos( m_thetaMix ) / m_f0; + m_mixSq = factor * pow( fTerm8 + fTerm0, 2 ); + +} + +void EvtEtaLLPiPi::initProbMax() { + + if ( getNArg() == 1 ) { + setProbMax( getArg( 0 ) ); + + } else { + + int lepId = getDaug(0).getId(); + if ( lepId == EvtPDL::getId( "e-" ).getId() || + lepId == EvtPDL::getId( "e+" ).getId() ) { + setProbMax( 27500.0 ); + + } else if ( lepId == EvtPDL::getId( "mu-" ).getId() || + lepId == EvtPDL::getId( "mu+" ).getId() ) { + setProbMax( 20.0 ); + } + + } + +} + +std::string EvtEtaLLPiPi::getName() { + return "ETA_LLPIPI"; +} + +EvtDecayBase *EvtEtaLLPiPi::clone() { + return new EvtEtaLLPiPi(); +} + +void EvtEtaLLPiPi::decay( EvtParticle *p ) { + + p->initializePhaseSpace( getNDaug(), getDaugs() ); + + const double mLep = p->getDaug( 0 )->mass(); + const double mPi = p->getDaug( 2 )->mass(); + + updateMassPars( mLep, mPi ); + + const double prob = ampSquared( p ); + setProb( prob ); + +} + +void EvtEtaLLPiPi::updateMassPars( double mLep, double mPi ) { + + // Update mass parameters used in various functions + m_lepMass = mLep; + m_lepMassSq = mLep*mLep; + m_4LepMassSq = 4.0*m_lepMassSq; + + m_piMass = mPi; + m_piMassSq = mPi*mPi; + m_4PiMassSq = 4.0*m_piMassSq; + +} + +double EvtEtaLLPiPi::rhoWidth( double s, double m ) const { + + // Define width of rho using modified vector meson dynamics, Eq 8 + double gamma( 0.0 ); + + if ( s >= m_4PiMassSq ) { + + const double mSq = m*m; + const double num = 1.0 - ( 4.0 * mSq / s ); + const double denom = 1.0 - ( 4.0 * mSq / m_rhoMassSq ); + const double ratio = denom > 0.0 ? num/denom : 0.0; + gamma = m_rhoGamma * ( s / m_rhoMassSq ) * pow ( ratio, 1.5 ); + + } + + return gamma; +} + +double EvtEtaLLPiPi::F0( double sLL, double sPiPi ) const { + + // Equation 7 + double ampSq( 0.0 ); + + const double rhoWidthL = rhoWidth( sLL, m_lepMass ); + const double rhoWidthPi = rhoWidth( sPiPi, m_piMass ); + + const double mSqDiffL = m_rhoMassSq - sLL; + const double mRhoWidthL = m_rhoMass * rhoWidthL; + + const double mSqDiffPi = m_rhoMassSq - sPiPi; + const double mRhoWidthPi = m_rhoMass * rhoWidthPi; + + const double denomLL = mSqDiffL * mSqDiffL + mRhoWidthL * mRhoWidthL; + const double denomPiPi = mSqDiffPi * mSqDiffPi + mRhoWidthPi * mRhoWidthPi; + + if ( denomLL > 0.0 && denomPiPi > 0.0 ) { + + const double mRho4 = m_rhoMassSq * m_rhoMassSq; + const double denomProd = denomLL * denomPiPi; + + double realAmp = m_par1 + m_parLL * ( m_rhoMassSq * mSqDiffL / denomLL ); + realAmp += m_parPiPi * mRho4 *( ( mSqDiffPi * mSqDiffL ) - mRhoWidthL * mRhoWidthPi ) / denomProd; + + double imagAmp = m_parLL * ( m_rhoMassSq * mRhoWidthL / denomLL ); + imagAmp += m_parPiPi * mRho4 * ( mRhoWidthPi * mSqDiffL + mRhoWidthL * mSqDiffPi ) / denomProd; + + ampSq = realAmp * realAmp + imagAmp * imagAmp; + + } + + return ampSq; + +} + +double EvtEtaLLPiPi::lambda( double a, double b, double c ) const { + + const double sumSq = a * a + b * b + c * c; + const double prod = a * b + b * c + c * a; + const double L = sumSq - 2.0 * prod; + return L; + +} + +double EvtEtaLLPiPi::ampSquared( EvtParticle *p ) const { + + // Equation 3 + const double zeroProb( 0.0 ); + + // Mass of eta' meson + const double mEta = p->mass(); + + const EvtVector4R pL1 = p->getDaug(0)->getP4(); + const EvtVector4R pL2 = p->getDaug(1)->getP4(); + const EvtVector4R pPi1 = p->getDaug(2)->getP4(); + const EvtVector4R pPi2 = p->getDaug(3)->getP4(); + + const EvtVector4R pLL = pL1 + pL2; + const double sLL = pLL.mass2(); + const EvtVector4R pPiPi = pPi1 + pPi2; + const double sPiPi = pPiPi.mass2(); + + if ( sLL < 1e-4 || sPiPi < m_4PiMassSq || sLL < m_4LepMassSq ) { + // To avoid negative square roots etc + return zeroProb; + } + + // Angles theta_p, theta_k and phi defined in Fig 1 + const EvtVector4R pSum = pLL + pPiPi; + // Helicity angle of first lepton + const double cosThp = -EvtDecayAngle( pSum, pLL, pL1 ); + const double sinThp = sqrt( 1.0 - cosThp * cosThp ); + // Helicity angle of first pion + const double cosThk = -EvtDecayAngle( pSum, pPiPi, pPi2 ); + const double sinThk = sqrt( 1.0 - cosThk * cosThk ); + // Angle between the dilepton and dipion decay planes + const double phi = EvtDecayAngleChi( pSum, pL1, pL2, pPi1, pPi2 ); + const double sinPhi = sin( phi ); + + const double betaLL = sqrt( 1.0 - ( m_4LepMassSq / sLL ) ); + const double betaPiPi = sqrt( 1.0 - ( m_4PiMassSq / sPiPi ) ); + + const double betaProd = ( 1.0 - pow( betaLL * sinThp * sinPhi, 2) ) * sPiPi * pow( betaPiPi * sinThk, 2 ); + const double L = lambda( mEta*mEta, sLL, sPiPi ); + const double ampSq = m_eSq * F0( sLL, sPiPi ) * m_mixSq * L * betaProd / ( 8.0 * sLL ); + + return ampSq; + +} diff --git a/src/EvtGenModels/EvtModelReg.cpp b/src/EvtGenModels/EvtModelReg.cpp --- a/src/EvtGenModels/EvtModelReg.cpp +++ b/src/EvtGenModels/EvtModelReg.cpp @@ -160,6 +160,7 @@ #include "EvtGenModels/EvtbsToLLLL.hh" #include "EvtGenModels/EvtbsToLLLLHyperCP.hh" #include "EvtGenModels/EvtThreeBodyPhsp.hh" +#include "EvtGenModels/EvtEtaLLPiPi.hh" #include #include @@ -341,4 +342,5 @@ modelist.registerModel( new EvtPsi2JpsiPiPi ); modelist.registerModel( new EvtThreeBodyPhsp ); + modelist.registerModel( new EvtEtaLLPiPi ); }