diff --git a/EvtGen/EvtGen.hh b/EvtGen/EvtGen.hh index 673bdd1..e57b367 100644 --- a/EvtGen/EvtGen.hh +++ b/EvtGen/EvtGen.hh @@ -1,73 +1,73 @@ /*********************************************************************** * 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 EVTGEN_HH #define EVTGEN_HH #include "EvtGenBase/EvtPDL.hh" -#include #include +#include class EvtParticle; class EvtRandomEngine; class EvtVector4R; class EvtStdHep; class EvtSpinDensity; class EvtAbsRadCorr; class EvtDecayBase; class EvtHepMCEvent; class EvtGen { public: EvtGen( const std::string& decayName, const std::string& pdtTableName, EvtRandomEngine* randomEngine = nullptr, EvtAbsRadCorr* isrEngine = nullptr, const std::list* extraModels = nullptr, int mixingType = 1, bool useXml = false ); EvtGen( const std::string& decayName, std::istream& pdtTableData, EvtRandomEngine* randomEngine = nullptr, EvtAbsRadCorr* isrEngine = nullptr, const std::list* extraModels = nullptr, int mixingType = 1, bool useXml = false ); ~EvtGen(); void readUDecay( const std::string& udecay_name, bool useXml = false ); EvtHepMCEvent* generateDecay( int PDGid, EvtVector4R refFrameP4, EvtVector4R translation, EvtSpinDensity* spinDensity = nullptr ); void generateDecay( EvtParticle* p ); private: void initialize( const std::string& decayName, std::istream& pdtTable, EvtRandomEngine* randomEngine = nullptr, EvtAbsRadCorr* isrEngine = nullptr, const std::list* extraModels = nullptr, int mixingType = 1, bool useXml = false ); EvtPDL _pdl; int _mixingType; }; #endif diff --git a/EvtGenBase/EvtDecayProb.hh b/EvtGenBase/EvtDecayProb.hh index 6937eb8..6b11568 100644 --- a/EvtGenBase/EvtDecayProb.hh +++ b/EvtGenBase/EvtDecayProb.hh @@ -1,41 +1,41 @@ /*********************************************************************** * 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 EvtDecayProb_HH #define EvtDecayProb_HH #include "EvtGenBase/EvtDecayBase.hh" class EvtParticle; class EvtDecayProb : public EvtDecayBase { public: void makeDecay( EvtParticle* p, bool recursive = true ) override; void setProb( double prob ) { _prob = prob; } double getProb() { return _prob; } inline void setWeight( double weight ) { _weight = weight; } private: - double _prob {1.0}; - double _weight {1.0}; + double _prob{ 1.0 }; + double _weight{ 1.0 }; }; #endif diff --git a/EvtGenBase/EvtDiLog.hh b/EvtGenBase/EvtDiLog.hh index 9cdf49c..350bf74 100644 --- a/EvtGenBase/EvtDiLog.hh +++ b/EvtGenBase/EvtDiLog.hh @@ -1,51 +1,51 @@ /*********************************************************************** * 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 EVTGENBASE_EVTDILOG_HH #define EVTGENBASE_EVTDILOG_HH 1 // Include files /** @namespace EvtDiLog EvtDiLog.hh EvtGenBase/EvtDiLog.hh * Dilogarithm function (replaces CERNLIB DDILOG) * * @author Patrick Robbe * @date 2007-01-23 */ namespace EvtDiLog { double DiLog( double x ); // constants for computation static const double Z1 = 1.; static const double HF = Z1 / 2.; static const double PI = 3.14159265358979324; static const double PI3 = PI * PI / 3.; static const double PI6 = PI * PI / 6.; static const double PI12 = PI * PI / 12.; static const double C[20] = { 0.42996693560813697, 0.40975987533077105, -0.01858843665014592, 0.00145751084062268, -0.00014304184442340, 0.00001588415541880, -0.00000190784959387, 0.00000024195180854, -0.00000003193341274, 0.00000000434545063, -0.00000000060578480, 0.00000000008612098, -0.00000000001244332, 0.00000000000182256, -0.00000000000027007, 0.00000000000004042, -0.00000000000000610, 0.00000000000000093, - -0.00000000000000014, 0.00000000000000002}; + -0.00000000000000014, 0.00000000000000002 }; } // namespace EvtDiLog #endif // EVTGENBASE_EVTDILOG_HH diff --git a/EvtGenBase/EvtPDL.hh b/EvtGenBase/EvtPDL.hh index e4cd500..0d4e50d 100644 --- a/EvtGenBase/EvtPDL.hh +++ b/EvtGenBase/EvtPDL.hh @@ -1,100 +1,100 @@ /*********************************************************************** * 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 EVTPDL_HH #define EVTPDL_HH #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtPartProp.hh" #include "EvtGenBase/EvtSpinType.hh" #include "EvtGenBase/EvtStringHash.hh" +#include #include -#include #include -#include +#include const int SPIN_NAME_LENGTH = 100; class EvtPDL final { public: EvtPDL(); void read( const std::string& fname ); void readPDT( std::istream& data ); static double getMeanMass( EvtId i ); static double getMass( EvtId i ); static double getRandMass( EvtId i, EvtId* parId, int nDaug, EvtId* dauId, EvtId* othDaugId, double maxMass, double* dauMasses ); static double getMassProb( EvtId i, double mass, double massPar, int nDaug, double* massDau ); static double getMaxMass( EvtId i ); static double getMinMass( EvtId i ); //the number we got from PDT static double getMaxRange( EvtId i ); static double getWidth( EvtId i ); static double getctau( EvtId i ); static int getStdHep( EvtId id ); static int getLundKC( EvtId id ); // Function to retrieve EvtId from PythiaID static EvtId evtIdFromLundKC( int pythiaId ); static EvtId evtIdFromStdHep( int stdhep ); static EvtId chargeConj( EvtId id ); static int chg3( EvtId i ); static EvtSpinType::spintype getSpinType( EvtId i ); static EvtId getId( const std::string& name ); static std::string name( EvtId i ); static void alias( EvtId num, const std::string& newname ); static void aliasChgConj( EvtId a, EvtId abar ); static size_t entries(); static EvtId getEntry( int i ); static void reSetMass( EvtId i, double mass ); static void reSetWidth( EvtId i, double width ); static void reSetMassMin( EvtId i, double mass ); static void reSetMassMax( EvtId i, double mass ); static void reSetBlatt( EvtId i, double blatt ); static void reSetBlattBirth( EvtId i, double blatt ); static void includeBirthFactor( EvtId i, bool yesno ); static void includeDecayFactor( EvtId i, bool yesno ); static void changeLS( EvtId i, std::string& newLS ); static void setPWForDecay( EvtId i, int spin, EvtId d1, EvtId d2 ); static void setPWForBirthL( EvtId i, int spin, EvtId par, EvtId othD ); private: void setUpConstsPdt(); static unsigned int _firstAlias; static int _nentries; static std::vector& partlist() { static std::vector s_partlist; return s_partlist; } static std::map _particleNameLookup; }; // EvtPDL.h #endif diff --git a/EvtGenBase/EvtSpinAmp.hh b/EvtGenBase/EvtSpinAmp.hh index 671f49f..e6681b6 100644 --- a/EvtGenBase/EvtSpinAmp.hh +++ b/EvtGenBase/EvtSpinAmp.hh @@ -1,110 +1,110 @@ /*********************************************************************** * 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 __EVTSPINAMP_HH__ #define __EVTSPINAMP_HH__ #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtSpinType.hh" #include using std::vector; #include class EvtSpinAmp; EvtSpinAmp operator*( const EvtComplex&, const EvtSpinAmp& ); EvtSpinAmp operator*( const EvtSpinAmp&, const EvtComplex& ); EvtSpinAmp operator/( const EvtSpinAmp&, const EvtComplex& ); class EvtSpinAmp { friend EvtSpinAmp operator*( const EvtComplex&, const EvtSpinAmp& ); friend EvtSpinAmp operator*( const EvtSpinAmp&, const EvtComplex& ); friend EvtSpinAmp operator/( const EvtSpinAmp&, const EvtComplex& ); friend std::ostream& operator<<( std::ostream&, const EvtSpinAmp& ); public: EvtSpinAmp(){}; EvtSpinAmp( const vector& ); EvtSpinAmp( const vector&, const EvtComplex& ); EvtSpinAmp( const vector&, const vector& ); EvtSpinAmp( const EvtSpinAmp& ); ~EvtSpinAmp(){}; // Input to the index functions are twice the magnetic quantum number EvtComplex& operator()( const vector& ); const EvtComplex& operator()( const vector& ) const; EvtComplex& operator()( int, ... ); const EvtComplex& operator()( int, ... ) const; EvtSpinAmp& operator=( const EvtSpinAmp& ); EvtSpinAmp operator+( const EvtSpinAmp& ) const; EvtSpinAmp& operator+=( const EvtSpinAmp& ); EvtSpinAmp operator-( const EvtSpinAmp& ) const; EvtSpinAmp& operator-=( const EvtSpinAmp& ); // Direct Product - EvtSpinAmp operator*(const EvtSpinAmp&)const; + EvtSpinAmp operator*( const EvtSpinAmp& ) const; EvtSpinAmp& operator*=( const EvtSpinAmp& ); EvtSpinAmp& operator*=( const EvtComplex& ); EvtSpinAmp& operator/=( const EvtComplex& ); // Contraction of amplitudes void intcont( size_t, size_t ); void extcont( const EvtSpinAmp&, int, int ); // assign this value to every member in the container void assign( const EvtComplex& val ) { _elem.assign( _elem.size(), val ); } // get the order of the container size_t rank() const { return _twospin.size(); } // get the dimension vector of the container const vector& dims() const { return _twospin; } // set the elements and the dimensions of the vector - useful for something // things eventough it is usually not the cleanest solution void addspin( int twospin ) { _twospin.push_back( twospin ); } void setelem( const vector& elem ) { _elem = elem; } bool iterate( vector& index ) const; vector iterinit() const; bool allowed( const vector& index ) const; bool iterateallowed( vector& index ) const; vector iterallowedinit() const; private: void checkindexargs( const vector& index ) const; void checktwospin( const vector& twospin ) const; int findtrueindex( const vector& index ) const; vector calctwospin( const vector& type ) const; vector _type; vector _twospin; vector _elem; }; #endif // __EVTSPINAMP__ diff --git a/EvtGenModels/EvtBTo3hCP.hh b/EvtGenModels/EvtBTo3hCP.hh index 22523cd..1f8ea7d 100644 --- a/EvtGenModels/EvtBTo3hCP.hh +++ b/EvtGenModels/EvtBTo3hCP.hh @@ -1,120 +1,119 @@ /*********************************************************************** * 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 EVTBTO3HCP_HH #define EVTBTO3HCP_HH #include "EvtGenBase/EvtDecayAmp.hh" #include "EvtGenBase/EvtVector4R.hh" class EvtParticle; class EvtBTo3hCP { public: - void EvtKpipi( double alpha, double beta, int iset, EvtVector4R& p_K_plus, EvtVector4R& p_pi_minus, EvtVector4R& p_gamma_1, EvtVector4R& p_gamma_2, double& Real_B0, double& Imag_B0, double& Real_B0bar, double& Imag_B0bar ); void Evt3pi( double alpha, int iset, EvtVector4R& p_K_plus, EvtVector4R& p_pi_minus, EvtVector4R& p_gamma_1, EvtVector4R& p_gamma_2, double& Real_B0, double& Imag_B0, double& Real_B0bar, double& Imag_B0bar ); void Evt3piMPP( double alpha, int iset, EvtVector4R& p_p1, EvtVector4R& p_p2, EvtVector4R& p_p3, double& Real_B0, double& Imag_B0, double& Real_B0bar, double& Imag_B0bar ); void Evt3piP00( double alpha, int iset, EvtVector4R& p_p1, EvtVector4R& p_p1_gamma1, EvtVector4R& p_p1_gamma2, EvtVector4R& p_p2_gamma1, EvtVector4R& p_p2_gamma2, double& Real_B0, double& Imag_B0, double& Real_B0bar, double& Imag_B0bar ); private: void setConstants( double balpha, double bbeta ); int computeKpipi( EvtVector4R& p1, EvtVector4R& p2, EvtVector4R& p3, double& real_B0, double& imag_B0, double& real_B0bar, double& imag_B0bar, int set ); int compute3pi( EvtVector4R& p1, EvtVector4R& p2, EvtVector4R& p3, double& real_B0, double& imag_B0, double& real_B0bar, double& imag_B0bar, int set ); int compute3piMPP( EvtVector4R& p1, EvtVector4R& p2, EvtVector4R& p3, double& real_B0, double& imag_B0, double& real_B0bar, double& imag_B0bar, int set ); int compute3piP00( EvtVector4R& p1, EvtVector4R& p2, EvtVector4R& p3, double& real_B0, double& imag_B0, double& real_B0bar, double& imag_B0bar, int set ); // Modes are : 0 = Kpipi, 1 = 3pi, 2 = MPP, 3 = P00 void firstStep( EvtVector4R& p1, EvtVector4R& p2, EvtVector4R& p3, int mode ); void generateSqMasses_Kpipi( double& m12, double& m13, double& m23, double MB2, double m1sq, double m2sq, double m3sq ); void generateSqMasses_3pi( double& m12, double& m13, double& m23, double MB2, double m1sq, double m2sq, double m3sq ); void generateSqMasses_3piMPP( double& m12, double& m13, double& m23, double MB2, double m1sq, double m2sq, double m3sq ); void generateSqMasses_3piP00( double& m12, double& m13, double& m23, double MB2, double m1sq, double m2sq, double m3sq ); void rotation( EvtVector4R& p, int newRot ); void gammaGamma( EvtVector4R& p, EvtVector4R& pgamma1, EvtVector4R& pgamma2 ); EvtComplex BreitWigner( EvtVector4R& p1, EvtVector4R& p2, EvtVector4R& p3, int& ierr, double Mass = 0, double Width = 0 ); EvtComplex EvtRBW( double s, double Am2, double Gam, double Am2Min ); EvtComplex EvtCRhoF_W( double s ); EvtComplex EvtcBW_KS( double s, double Am2, double Gam ); EvtComplex EvtcBW_GS( double s, double Am2, double Gam ); double d( double AmRho2 ); double k( double s ); double Evtfs( double s, double AmRho2, double GamRho ); double h( double s ); double dh_ds( double s ); EvtComplex Mat_S1, Mat_S2, Mat_S3, Mat_S4, Mat_S5, Nat_S1, Nat_S2, Nat_S3, Nat_S4, Nat_S5, MatKstarp, MatKstar0, MatKrho, NatKstarp, NatKstar0, NatKrho; double alphaCP = 1.365; double betaCP = 0.362; - double MA2 = 27.927981186; - double MB2 = 27.929242450; + double MA2 = 27.927981186; + double MB2 = 27.929242450; double MC2 = 28.153482608; double pi = 3.141592653; double Mass_rho = 0.770; double Gam_rho = 0.150; double M_B = 5.2794; double M_pip = 0.13957; double M_pim = 0.13957; double M_pi0 = 0.134976; double M_Kp = 0.49368; double Mass_Kstarp = 0.8916; double Mass_Kstar0 = 0.8961; double Gam_Kstarp = 0.0498; double Gam_Kstar0 = 0.0505; double rotMatrix[3][3]; double factor_max = 1; }; #endif diff --git a/EvtGenModels/EvtFlatSqDalitz.hh b/EvtGenModels/EvtFlatSqDalitz.hh index 5b34be1..fc332ab 100644 --- a/EvtGenModels/EvtFlatSqDalitz.hh +++ b/EvtGenModels/EvtFlatSqDalitz.hh @@ -1,49 +1,48 @@ /*********************************************************************** * 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 EVTFLATSQDALITZ_HH #define EVTFLATSQDALITZ_HH #include "EvtGenBase/EvtDecayIncoherent.hh" class EvtParticle; // Description: B->3 body flat in square dalitz vairiables // the square dalitz is the plane m12 theta12 class EvtFlatSqDalitz : public EvtDecayIncoherent { public: - std::string getName() override; EvtDecayBase* clone() override; void init() override; void initProbMax() override; void decay( EvtParticle* p ) override; private: double m_mPrimeMin{ 0. }; double m_mPrimeMax{ 1. }; double m_thetaPrimeMin{ 0. }; double m_thetaPrimeMax{ 1. }; }; #endif diff --git a/EvtGenModels/EvtFourBodyPhsp.hh b/EvtGenModels/EvtFourBodyPhsp.hh index 767b831..f21cb37 100644 --- a/EvtGenModels/EvtFourBodyPhsp.hh +++ b/EvtGenModels/EvtFourBodyPhsp.hh @@ -1,92 +1,92 @@ /*********************************************************************** * 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 EVTFOURBODYPHSP_HH #define EVTFOURBODYPHSP_HH -#include +#include "EvtGenBase/EvtDecayProb.hh" + #include #include - -#include "EvtGenBase/EvtDecayProb.hh" +#include class EvtParticle; class EvtFourBodyPhsp : public EvtDecayProb { public: enum Shape { rectangle = 1, trapezoid = 2, pentagon = 3, variable = 4 }; std::string getName() override; EvtDecayBase* clone() override; void init() override; void initProbMax() override; void decay( EvtParticle* parent ) override; private: std::array phspFactor( const double mM, const double m12, const double m34, std::array& daughters ) const; Shape determineBoundaryShape( const double m12Min, const double m12Max, const double m34Max, const double mMother ) const; std::pair generatePairMasses( const double m12Min, const double m12Max, const double m34Min, const double m34Max, const double mMother, const EvtFourBodyPhsp::Shape shape ) const; std::pair generateRectangle( const double m12Min, const double m12Max, const double m34Min, const double m34Max ) const; std::pair generateTrapezoid( const double m12Min, const double m12Max, const double m34Min, const double mMother ) const; std::array m_daughterMasses{ -1, -1, -1, -1 }; double m_m12Min; double m_m12Max; double m_m34Min; double m_m34Max; double m_trapNorm; double m_trapCoeff1; double m_trapCoeff2; double m_pentagonSplit; double m_pentagonFraction; Shape m_boundaryShape; - bool m_stableMother{true}; - bool m_stableDaughters{true}; - bool m_fixedBoundary{true}; + bool m_stableMother{ true }; + bool m_stableDaughters{ true }; + bool m_fixedBoundary{ true }; }; #endif diff --git a/EvtGenModels/EvtRareLbToLllFFBase.hh b/EvtGenModels/EvtRareLbToLllFFBase.hh index f4c9739..afe03fd 100644 --- a/EvtGenModels/EvtRareLbToLllFFBase.hh +++ b/EvtGenModels/EvtRareLbToLllFFBase.hh @@ -1,72 +1,74 @@ /*********************************************************************** * Copyright 1998-2022 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 EVTRARELBTOLLLFFBASE_HH #define EVTRARELBTOLLLFFBASE_HH 1 // Include files /** @class * * * @author Michal Kreps * @date 2014-10-20 */ #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtParticle.hh" #include #include class EvtRareLbToLllFFBase { public: class FormFactors { public: FormFactors(); virtual ~FormFactors(){}; void areZero(); double F_[4]; double G_[4]; double FT_[4]; double GT_[4]; }; virtual void init() = 0; virtual void getFF( const EvtParticle& parent, const EvtParticle& lambda, EvtRareLbToLllFFBase::FormFactors& FF ) const = 0; bool isNatural( const EvtParticle& lambda ) const; EvtRareLbToLllFFBase(); virtual ~EvtRareLbToLllFFBase(){}; protected: - double calculateVdotV( const EvtParticle& parent, const EvtParticle& lambda ) const; - double calculateVdotV( const EvtParticle&, const EvtParticle&, double qsq ) const; + double calculateVdotV( const EvtParticle& parent, + const EvtParticle& lambda ) const; + double calculateVdotV( const EvtParticle&, const EvtParticle&, + double qsq ) const; EvtIdSet natural_; }; #endif diff --git a/src/EvtGenBase/EvtHepMCEvent.cpp b/src/EvtGenBase/EvtHepMCEvent.cpp index 045d0f4..c80e14b 100644 --- a/src/EvtGenBase/EvtHepMCEvent.cpp +++ b/src/EvtGenBase/EvtHepMCEvent.cpp @@ -1,195 +1,195 @@ /*********************************************************************** * 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 "EvtGenBase/EvtHepMCEvent.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" EvtHepMCEvent::EvtHepMCEvent() : _theEvent( nullptr ), _translation( 0.0, 0.0, 0.0, 0.0 ) { } EvtHepMCEvent::~EvtHepMCEvent() { this->deleteEvent(); } void EvtHepMCEvent::deleteEvent() { if ( _theEvent != nullptr ) { _theEvent->clear(); delete _theEvent; _theEvent = nullptr; } } void EvtHepMCEvent::constructEvent( EvtParticle* baseParticle ) { EvtVector4R origin( 0.0, 0.0, 0.0, 0.0 ); this->constructEvent( baseParticle, origin ); } void EvtHepMCEvent::constructEvent( EvtParticle* baseParticle, EvtVector4R& translation ) { // This class does not take ownership of the base particle pointer. // Rather, it uses the base particle to construct the event. this->deleteEvent(); if ( baseParticle == nullptr ) { return; } _theEvent = new GenEvent( Units::GEV, Units::MM ); _translation = translation; // Use the recursive function addVertex to add a vertex with incoming/outgoing // particles. Adds a new vertex for any EvtParticles with decay daughters. // All particles are in the rest frame of the base particle ("lab frame"). GenParticlePtr hepMCGenParticle = this->createGenParticle( baseParticle, EvtHepMCEvent::LAB ); this->addVertex( baseParticle, hepMCGenParticle ); } GenParticlePtr EvtHepMCEvent::createGenParticle( EvtParticle* theParticle, int frameType ) { // Create an HepMC GenParticle, with the 4-momenta in the frame given by the frameType integer - GenParticlePtr genParticle{nullptr}; + GenParticlePtr genParticle{ nullptr }; if ( theParticle != nullptr ) { // Set the particle status integer to either stable or decayed int status( EvtHepMCEvent::STABLE ); int nDaug = theParticle->getNDaug(); if ( nDaug > 0 ) { status = EvtHepMCEvent::DECAYED; } // Get the 4-momentum (E, px, py, pz) for the EvtParticle. EvtVector4R p4( 0.0, 0.0, 0.0, 0.0 ); if ( frameType == EvtHepMCEvent::RESTFRAME ) { p4 = theParticle->getP4Restframe(); } else if ( frameType == EvtHepMCEvent::LAB ) { p4 = theParticle->getP4Lab(); } else { p4 = theParticle->getP4(); } // Convert this to the HepMC 4-momentum double E = p4.get( 0 ); double px = p4.get( 1 ); double py = p4.get( 2 ); double pz = p4.get( 3 ); FourVector hepMC_p4( px, py, pz, E ); // Get the particle PDG integer id int PDGInt = EvtPDL::getStdHep( theParticle->getId() ); genParticle = newGenParticlePtr( hepMC_p4, PDGInt, status ); } return genParticle; } void EvtHepMCEvent::addVertex( EvtParticle* inEvtParticle, GenParticlePtr inGenParticle ) { // This is a recursive function that adds GenVertices to the GenEvent for // the incoming EvtParticle and its daughters. We use two separate // pointers for the EvtParticle and GenParticle information: the former // to obtain the PDGId, 4-momenta, daughter and vertex positions, the latter to // set the incoming particle to the vertex. Note that the outgoing particle for // one vertex might be the incoming particle for another vertex - this needs to // be the same GenParticle pointer, hence the reason for using it as a 2nd argument // in this function. if ( _theEvent == nullptr || inEvtParticle == nullptr || inGenParticle == nullptr ) { return; } // Create the decay vertex FourVector vtxCoord = this->getVertexCoord( inEvtParticle ); GenVertexPtr theVertex = newGenVertexPtr( vtxCoord ); // Add the vertex to the event _theEvent->add_vertex( theVertex ); // Set the incoming particle theVertex->add_particle_in( inGenParticle ); // Set the outgoing particles (decay products) int nDaug = inEvtParticle->getNDaug(); int iDaug( 0 ); // Loop over the daughters for ( iDaug = 0; iDaug < nDaug; iDaug++ ) { EvtParticle* evtDaughter = inEvtParticle->getDaug( iDaug ); GenParticlePtr genDaughter = this->createGenParticle( evtDaughter, EvtHepMCEvent::LAB ); if ( genDaughter != nullptr ) { // Add a new GenParticle (outgoing) particle daughter to the vertex theVertex->add_particle_out( genDaughter ); // Find out if the daughter also has decay products. // If so, recursively run this function again. int nDaugProducts = evtDaughter->getNDaug(); if ( nDaugProducts > 0 ) { // Recursively process daughter particles and add their vertices to the event this->addVertex( evtDaughter, genDaughter ); } // Have daughter products } // hepMCDaughter != 0 } // Loop over daughters } FourVector EvtHepMCEvent::getVertexCoord( EvtParticle* theParticle ) { FourVector vertexCoord( 0.0, 0.0, 0.0, 0.0 ); if ( theParticle != nullptr && theParticle->getNDaug() != 0 ) { // Get the position (t,x,y,z) of the EvtParticle, offset by the translation vector. // This position will be the point where the particle decays. So we ask // the position of the (1st) daughter particle. EvtParticle* daugParticle = theParticle->getDaug( 0 ); if ( daugParticle != nullptr ) { EvtVector4R vtxPosition = daugParticle->get4Pos() + _translation; // Create the HepMC 4 vector of the position (x,y,z,t) vertexCoord.setX( vtxPosition.get( 1 ) ); vertexCoord.setY( vtxPosition.get( 2 ) ); vertexCoord.setZ( vtxPosition.get( 3 ) ); vertexCoord.setT( vtxPosition.get( 0 ) ); } } return vertexCoord; } diff --git a/src/EvtGenBase/EvtMTree.cpp b/src/EvtGenBase/EvtMTree.cpp index c3f8642..e77a143 100644 --- a/src/EvtGenBase/EvtMTree.cpp +++ b/src/EvtGenBase/EvtMTree.cpp @@ -1,471 +1,470 @@ /*********************************************************************** * 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 "EvtGenBase/EvtMTree.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtKine.hh" #include "EvtGenBase/EvtMBreitWigner.hh" #include "EvtGenBase/EvtMHelAmp.hh" #include "EvtGenBase/EvtMTrivialLS.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtReport.hh" #include #include #include using std::endl; EvtMTree::EvtMTree( const EvtId* idtbl, unsigned int ndaug ) { for ( size_t i = 0; i < ndaug; ++i ) { _lbltbl.push_back( EvtPDL::name( idtbl[i] ) ); } } EvtMTree::~EvtMTree() { for ( size_t i = 0; i < _root.size(); ++i ) delete _root[i]; } bool EvtMTree::parsecheck( char arg, const string& chars ) { bool ret = false; for ( size_t i = 0; i < chars.size(); ++i ) { ret = ret || ( chars[i] == arg ); } return ret; } vector EvtMTree::makeparticles( const string& strid ) { vector particles; vector labels; for ( size_t i = 0; i < _lbltbl.size(); ++i ) { if ( _lbltbl[i] == strid ) labels.push_back( i ); } if ( labels.size() == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Error unknown particle label " << strid << endl; ::abort(); } for ( size_t i = 0; i < labels.size(); ++i ) particles.push_back( new EvtMParticle( labels[i], EvtPDL::getId( strid ) ) ); return particles; } EvtMRes* EvtMTree::makeresonance( const EvtId& id, const string& ls, const vector& lsarg, const string& type, const vector& amps, const vector& children ) { EvtMRes* resonance = nullptr; EvtMLineShape* lineshape = nullptr; if ( ls == "BREITWIGNER" ) { lineshape = new EvtMBreitWigner( id, lsarg ); } else if ( ls == "TRIVIAL" ) { lineshape = new EvtMTrivialLS( id, lsarg ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Lineshape " << lineshape << " not recognized." << endl; ::abort(); } if ( type == "HELAMP" ) { resonance = new EvtMHelAmp( id, lineshape, children, amps ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Model " << type << " not recognized." << endl; ::abort(); } lineshape->setres( resonance ); return resonance; } void EvtMTree::parseerror( bool flag, ptype& c_iter, ptype& c_begin, ptype& c_end ) { if ( !flag ) return; string error; while ( c_begin != c_end ) { if ( c_begin == c_iter ) { error += '_'; error += *c_begin; error += '_'; } else error += *c_begin; ++c_begin; } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Parse error at: " << error << endl; ::abort(); } string EvtMTree::parseId( ptype& c_iter, ptype& c_begin, ptype& c_end ) { string strid; while ( c_iter != c_end ) { parseerror( parsecheck( *c_iter, ")[]," ), c_iter, c_begin, c_end ); if ( *c_iter == '(' ) { ++c_iter; return strid; } strid += *c_iter; ++c_iter; } return strid; } string EvtMTree::parseKey( ptype& c_iter, ptype& c_begin, ptype& c_end ) { string key; while ( *c_iter != ',' ) { parseerror( c_iter == c_end || parsecheck( *c_iter, "()[]" ), c_iter, c_begin, c_end ); key += *c_iter; ++c_iter; } ++c_iter; parseerror( c_iter == c_end, c_iter, c_begin, c_end ); return key; } vector EvtMTree::parseArg( ptype& c_iter, ptype& c_begin, ptype& c_end ) { vector arg; if ( *c_iter != '[' ) return arg; ++c_iter; string temp; while ( true ) { parseerror( c_iter == c_end || parsecheck( *c_iter, "[()" ), c_iter, c_begin, c_end ); if ( *c_iter == ']' ) { ++c_iter; if ( temp.size() > 0 ) arg.push_back( temp ); break; } if ( *c_iter == ',' ) { arg.push_back( temp ); temp.clear(); ++c_iter; continue; } temp += *c_iter; ++c_iter; } parseerror( c_iter == c_end || *c_iter != ',', c_iter, c_begin, c_end ); ++c_iter; return arg; } vector EvtMTree::parseAmps( ptype& c_iter, ptype& c_begin, ptype& c_end ) { vector parg = parseArg( c_iter, c_begin, c_end ); parseerror( parg.size() == 0, c_iter, c_begin, c_end ); // Get parametrization amplitudes vector::iterator amp_iter = parg.begin(); vector::iterator amp_end = parg.end(); vector amps; while ( amp_iter != amp_end ) { const char* nptr; char* endptr = nullptr; double amp = 0.0, phase = 0.0; nptr = ( *amp_iter ).c_str(); amp = strtod( nptr, &endptr ); parseerror( nptr == endptr, c_iter, c_begin, c_end ); ++amp_iter; parseerror( amp_iter == amp_end, c_iter, c_begin, c_end ); nptr = ( *amp_iter ).c_str(); phase = strtod( nptr, &endptr ); parseerror( nptr == endptr, c_iter, c_begin, c_end ); amps.push_back( amp * exp( EvtComplex( 0.0, phase ) ) ); ++amp_iter; } return amps; } vector EvtMTree::duplicate( const vector& list ) const { vector newlist; for ( size_t i = 0; i < list.size(); ++i ) newlist.push_back( list[i]->duplicate() ); return newlist; } // XXX Warning it is unsafe to use cl1 after a call to this function XXX vector> EvtMTree::unionChildren( const string& nodestr, vector>& cl1 ) { vector cl2 = parsenode( nodestr, false ); vector> cl; if ( cl1.size() == 0 ) { for ( size_t i = 0; i < cl2.size(); ++i ) { vector temp( 1, cl2[i] ); cl.push_back( temp ); } return cl; } for ( size_t i = 0; i < cl1.size(); ++i ) { for ( size_t j = 0; j < cl2.size(); ++j ) { vector temp; temp = duplicate( cl1[i] ); temp.push_back( cl2[j]->duplicate() ); cl.push_back( temp ); } } for ( size_t i = 0; i < cl1.size(); ++i ) for ( size_t j = 0; j < cl1[i].size(); ++j ) delete cl1[i][j]; for ( size_t i = 0; i < cl2.size(); ++i ) delete ( cl2[i] ); return cl; } vector> EvtMTree::parseChildren( ptype& c_iter, ptype& c_begin, ptype& c_end ) { bool test = true; int pcount = 0; string nodestr; vector> children; parseerror( c_iter == c_end || *c_iter != '[', c_iter, c_begin, c_end ); ++c_iter; while ( test ) { parseerror( c_iter == c_end || pcount < 0, c_iter, c_begin, c_end ); switch ( *c_iter ) { case ')': --pcount; nodestr += *c_iter; break; case '(': ++pcount; nodestr += *c_iter; break; case ']': if ( pcount == 0 ) { children = unionChildren( nodestr, children ); test = false; } else { nodestr += *c_iter; } break; case ',': if ( pcount == 0 ) { children = unionChildren( nodestr, children ); nodestr.clear(); } else { nodestr += *c_iter; } break; default: nodestr += *c_iter; break; } ++c_iter; } return children; } vector EvtMTree::parsenode( const string& args, bool rootnode ) { ptype c_iter, c_begin, c_end; c_iter = c_begin = args.begin(); c_end = args.end(); string strid = parseId( c_iter, c_begin, c_end ); // Case 1: Particle if ( c_iter == c_end ) return makeparticles( strid ); // Case 2: Resonance - parse further EvtId id = EvtPDL::getId( strid ); parseerror( EvtId( -1, -1 ) == id, c_iter, c_begin, c_end ); string ls; vector lsarg; if ( rootnode ) { ls = "TRIVIAL"; } else { // Get lineshape (e.g. BREITWIGNER) ls = parseKey( c_iter, c_begin, c_end ); lsarg = parseArg( c_iter, c_begin, c_end ); } // Get resonance parametrization type (e.g. HELAMP) string type = parseKey( c_iter, c_begin, c_end ); vector amps = parseAmps( c_iter, c_begin, c_end ); // Children vector> children = parseChildren( c_iter, c_begin, c_end ); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << children.size() << endl; vector resonances; for ( size_t i = 0; i < children.size(); ++i ) { resonances.push_back( makeresonance( id, ls, lsarg, type, amps, children[i] ) ); } parseerror( c_iter == c_end || *c_iter != ')', c_iter, c_begin, c_end ); return resonances; } bool EvtMTree::validTree( const EvtMNode* root ) const { vector res = root->getresonance(); vector check( res.size(), false ); for ( size_t i = 0; i < res.size(); ++i ) { check[res[i]] = true; } bool ret = true; for ( size_t i = 0; i < check.size(); ++i ) { ret = ret && check[i]; } // Function appears to check child integer indices, but this fails if they are // not always the first and second ones, so just return true for all cases ret = true; return ret; - } void EvtMTree::addtree( const string& str ) { // vector roots = parsenode( str, true ); // Edit previous line to allow the creation of node resonances: vector roots = parsenode( str, false ); _norm = 0; for ( size_t i = 0; i < roots.size(); ++i ) { if ( validTree( roots[i] ) ) { _root.push_back( roots[i] ); _norm = _norm + 1; } else delete roots[i]; } _norm = 1.0 / sqrt( _norm ); } EvtSpinAmp EvtMTree::getrotation( EvtParticle* p ) const { // Set up the rotation matrix for the root particle (for now) EvtSpinDensity sd = p->rotateToHelicityBasis(); EvtSpinType::spintype type = EvtPDL::getSpinType( _root[0]->getid() ); int twospin = EvtSpinType::getSpin2( type ); vector types( 2, type ); EvtSpinAmp rot( types, EvtComplex( 0.0, 0.0 ) ); vector index = rot.iterallowedinit(); do { rot( index ) = sd.get( ( index[0] + twospin ) / 2, ( index[1] + twospin ) / 2 ); } while ( rot.iterateallowed( index ) ); return rot; } EvtSpinAmp EvtMTree::amplitude( EvtParticle* p ) const { vector product; for ( size_t i = 0; i < p->getNDaug(); ++i ) product.push_back( p->getDaug( i )->getP4Lab() ); if ( _root.size() == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "No decay tree present." << endl; ::abort(); } EvtSpinAmp amp = _root[0]->amplitude( product ); for ( size_t i = 1; i < _root.size(); ++i ) { // Assume that helicity amplitude is returned amp += _root[i]->amplitude( product ); } amp = _norm * amp; //ryd return amp; // Do Rotation to Proper Frame EvtSpinAmp newamp = getrotation( p ); newamp.extcont( amp, 1, 0 ); return newamp; } diff --git a/src/EvtGenBase/EvtNonresonantAmp.cpp b/src/EvtGenBase/EvtNonresonantAmp.cpp index 1b554ec..c5ad8db 100644 --- a/src/EvtGenBase/EvtNonresonantAmp.cpp +++ b/src/EvtGenBase/EvtNonresonantAmp.cpp @@ -1,99 +1,99 @@ /*********************************************************************** * 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 "EvtGenBase/EvtNonresonantAmp.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtCyclic3.hh" #include "EvtGenBase/EvtDalitzCoord.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtdFunction.hh" #include #include #include using EvtCyclic3::Index; using EvtCyclic3::Pair; using std::endl; EvtNonresonantAmp::EvtNonresonantAmp( EvtDalitzPlot* dp, EvtPto3PAmp::NumType type, EvtCyclic3::Pair pair1, double par1, EvtCyclic3::Pair pair2, double par2, EvtSpinType::spintype spin ) : EvtAmplitude(), - _dalitzSpace{dp}, + _dalitzSpace{ dp }, _type( type ), _pair1( pair1 ), _pair2( pair2 ), _par1( par1 ), _par2( par2 ), _spin( spin ) { } EvtComplex EvtNonresonantAmp::amplitude( const EvtDalitzPoint& dalitzPoint ) const { // flat model if ( _type == EvtPto3PAmp::NONRES ) { return 1; } // "linear model" (prop. to m^2) else if ( _type == EvtPto3PAmp::NONRES_LIN ) { return dalitzPoint.q( _pair1 ); } // Chen-Chua-Soni else if ( _type == EvtPto3PAmp::NONRES_CCS ) { double s = dalitzPoint.q( _pair1 ); double smin = _dalitzSpace->qAbsMin( _pair1 ); return sqrt( s - smin ) / ( s * log( s * _par1 ) ); } // exp{par*m^2) (Belle model, Garmash et al, PRD71) else if ( _type == EvtPto3PAmp::NONRES_EXP ) { return exp( _par1 * dalitzPoint.q( _pair1 ) ); } // exp(par1*m12^2 + par2*m13^2) (Belle model, Garmash et al, PRD71) else if ( _type == EvtPto3PAmp::NONRES_EXP_ADD ) { return exp( _par1 * dalitzPoint.q( _pair1 ) + _par2 * dalitzPoint.q( _pair2 ) ); } // Laura model (P.Harrison et al, BAD806) else if ( _type == EvtPto3PAmp::NONRES_LAURA ) { double m = sqrt( dalitzPoint.q( _pair1 ) ); double mmin = sqrt( _dalitzSpace->qAbsMin( _pair1 ) ); double dm = m - mmin; assert( dm > 0 ); double cosTh = 1; int ispin = EvtSpinType::getSpin2( _spin ); if ( ispin > 0 ) { cosTh = dalitzPoint.cosTh( EvtCyclic3::next( _pair1 ), _pair1 ); if ( ispin > 2 ) cosTh *= cosTh; } return pow( dm, _par1 ) * exp( dm * _par2 ) * cosTh; } return 0; } diff --git a/src/EvtGenBase/EvtSemiLeptonicBaryonAmp.cpp b/src/EvtGenBase/EvtSemiLeptonicBaryonAmp.cpp index b8c5220..f43468b 100644 --- a/src/EvtGenBase/EvtSemiLeptonicBaryonAmp.cpp +++ b/src/EvtGenBase/EvtSemiLeptonicBaryonAmp.cpp @@ -1,788 +1,788 @@ /*********************************************************************** * 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 "EvtGenBase/EvtSemiLeptonicBaryonAmp.hh" #include "EvtGenBase/EvtAmp.hh" #include "EvtGenBase/EvtDiracParticle.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGammaMatrix.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRaritaSchwinger.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSemiLeptonicFF.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include using std::endl; void EvtSemiLeptonicBaryonAmp::CalcAmp( EvtParticle* parent, EvtAmp& amp, EvtSemiLeptonicFF* FormFactors ) { static EvtId EM = EvtPDL::getId( "e-" ); static EvtId MUM = EvtPDL::getId( "mu-" ); static EvtId TAUM = EvtPDL::getId( "tau-" ); static EvtId EP = EvtPDL::getId( "e+" ); static EvtId MUP = EvtPDL::getId( "mu+" ); static EvtId TAUP = EvtPDL::getId( "tau+" ); //Add the lepton and neutrino 4 momenta to find q2 EvtVector4R q = parent->getDaug( 1 )->getP4() + parent->getDaug( 2 )->getP4(); double q2 = ( q.mass2() ); double f1v, f1a, f2v, f2a; double m_meson = parent->getDaug( 0 )->mass(); FormFactors->getbaryonff( parent->getId(), parent->getDaug( 0 )->getId(), q2, m_meson, &f1v, &f1a, &f2v, &f2a ); EvtVector4R p4b; p4b.set( parent->mass(), 0.0, 0.0, 0.0 ); EvtVector4C temp_00_term1; EvtVector4C temp_00_term2; EvtVector4C temp_01_term1; EvtVector4C temp_01_term2; EvtVector4C temp_10_term1; EvtVector4C temp_10_term2; EvtVector4C temp_11_term1; EvtVector4C temp_11_term2; EvtDiracSpinor p0 = parent->sp( 0 ); EvtDiracSpinor p1 = parent->sp( 1 ); EvtDiracSpinor d0 = parent->getDaug( 0 )->spParent( 0 ); EvtDiracSpinor d1 = parent->getDaug( 0 )->spParent( 1 ); temp_00_term1.set( 0, f1v * ( d0 * ( EvtGammaMatrix::g0() * p0 ) ) ); temp_00_term2.set( 0, f1a * ( d0 * ( ( EvtGammaMatrix::g0() * EvtGammaMatrix::g5() ) * p0 ) ) ); temp_01_term1.set( 0, f1v * ( d0 * ( EvtGammaMatrix::g0() * p1 ) ) ); temp_01_term2.set( 0, f1a * ( d0 * ( ( EvtGammaMatrix::g0() * EvtGammaMatrix::g5() ) * p1 ) ) ); temp_10_term1.set( 0, f1v * ( d1 * ( EvtGammaMatrix::g0() * p0 ) ) ); temp_10_term2.set( 0, f1a * ( d1 * ( ( EvtGammaMatrix::g0() * EvtGammaMatrix::g5() ) * p0 ) ) ); temp_11_term1.set( 0, f1v * ( d1 * ( EvtGammaMatrix::g0() * p1 ) ) ); temp_11_term2.set( 0, f1a * ( d1 * ( ( EvtGammaMatrix::g0() * EvtGammaMatrix::g5() ) * p1 ) ) ); temp_00_term1.set( 1, f1v * ( d0 * ( EvtGammaMatrix::g1() * p0 ) ) ); temp_00_term2.set( 1, f1a * ( d0 * ( ( EvtGammaMatrix::g1() * EvtGammaMatrix::g5() ) * p0 ) ) ); temp_01_term1.set( 1, f1v * ( d0 * ( EvtGammaMatrix::g1() * p1 ) ) ); temp_01_term2.set( 1, f1a * ( d0 * ( ( EvtGammaMatrix::g1() * EvtGammaMatrix::g5() ) * p1 ) ) ); temp_10_term1.set( 1, f1v * ( d1 * ( EvtGammaMatrix::g1() * p0 ) ) ); temp_10_term2.set( 1, f1a * ( d1 * ( ( EvtGammaMatrix::g1() * EvtGammaMatrix::g5() ) * p0 ) ) ); temp_11_term1.set( 1, f1v * ( d1 * ( EvtGammaMatrix::g1() * p1 ) ) ); temp_11_term2.set( 1, f1a * ( d1 * ( ( EvtGammaMatrix::g1() * EvtGammaMatrix::g5() ) * p1 ) ) ); temp_00_term1.set( 2, f1v * ( d0 * ( EvtGammaMatrix::g2() * p0 ) ) ); temp_00_term2.set( 2, f1a * ( d0 * ( ( EvtGammaMatrix::g2() * EvtGammaMatrix::g5() ) * p0 ) ) ); temp_01_term1.set( 2, f1v * ( d0 * ( EvtGammaMatrix::g2() * p1 ) ) ); temp_01_term2.set( 2, f1a * ( d0 * ( ( EvtGammaMatrix::g2() * EvtGammaMatrix::g5() ) * p1 ) ) ); temp_10_term1.set( 2, f1v * ( d1 * ( EvtGammaMatrix::g2() * p0 ) ) ); temp_10_term2.set( 2, f1a * ( d1 * ( ( EvtGammaMatrix::g2() * EvtGammaMatrix::g5() ) * p0 ) ) ); temp_11_term1.set( 2, f1v * ( d1 * ( EvtGammaMatrix::g2() * p1 ) ) ); temp_11_term2.set( 2, f1a * ( d1 * ( ( EvtGammaMatrix::g2() * EvtGammaMatrix::g5() ) * p1 ) ) ); temp_00_term1.set( 3, f1v * ( d0 * ( EvtGammaMatrix::g3() * p0 ) ) ); temp_00_term2.set( 3, f1a * ( d0 * ( ( EvtGammaMatrix::g3() * EvtGammaMatrix::g5() ) * p0 ) ) ); temp_01_term1.set( 3, f1v * ( d0 * ( EvtGammaMatrix::g3() * p1 ) ) ); temp_01_term2.set( 3, f1a * ( d0 * ( ( EvtGammaMatrix::g3() * EvtGammaMatrix::g5() ) * p1 ) ) ); temp_10_term1.set( 3, f1v * ( d1 * ( EvtGammaMatrix::g3() * p0 ) ) ); temp_10_term2.set( 3, f1a * ( d1 * ( ( EvtGammaMatrix::g3() * EvtGammaMatrix::g5() ) * p0 ) ) ); temp_11_term1.set( 3, f1v * ( d1 * ( EvtGammaMatrix::g3() * p1 ) ) ); temp_11_term2.set( 3, f1a * ( d1 * ( ( EvtGammaMatrix::g3() * EvtGammaMatrix::g5() ) * p1 ) ) ); EvtVector4C l1, l2; EvtId l_num = parent->getDaug( 1 )->getId(); if ( l_num == EM || l_num == MUM || l_num == TAUM ) { l1 = EvtLeptonVACurrent( parent->getDaug( 1 )->spParent( 0 ), parent->getDaug( 2 )->spParentNeutrino() ); l2 = EvtLeptonVACurrent( parent->getDaug( 1 )->spParent( 1 ), parent->getDaug( 2 )->spParentNeutrino() ); } else { if ( l_num == EP || l_num == MUP || l_num == TAUP ) { l1 = EvtLeptonVACurrent( parent->getDaug( 2 )->spParentNeutrino(), parent->getDaug( 1 )->spParent( 0 ) ); l2 = EvtLeptonVACurrent( parent->getDaug( 2 )->spParentNeutrino(), parent->getDaug( 1 )->spParent( 1 ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Wrong lepton number" << endl; } } amp.vertex( 0, 0, 0, l1.cont( temp_00_term1 + temp_00_term2 ) ); amp.vertex( 0, 0, 1, l2.cont( temp_00_term1 + temp_00_term2 ) ); amp.vertex( 0, 1, 0, l1.cont( temp_01_term1 + temp_01_term2 ) ); amp.vertex( 0, 1, 1, l2.cont( temp_01_term1 + temp_01_term2 ) ); amp.vertex( 1, 0, 0, l1.cont( temp_10_term1 + temp_10_term2 ) ); amp.vertex( 1, 0, 1, l2.cont( temp_10_term1 + temp_10_term2 ) ); amp.vertex( 1, 1, 0, l1.cont( temp_11_term1 + temp_11_term2 ) ); amp.vertex( 1, 1, 1, l2.cont( temp_11_term1 + temp_11_term2 ) ); return; } double EvtSemiLeptonicBaryonAmp::CalcMaxProb( EvtId parent, EvtId baryon, EvtId lepton, EvtId nudaug, EvtSemiLeptonicFF* FormFactors, EvtComplex r00, EvtComplex r01, EvtComplex r10, EvtComplex r11 ) { //This routine takes the arguements parent, baryon, and lepton //number, and a form factor model, and returns a maximum //probability for this semileptonic form factor model. A //brute force method is used. The 2D cos theta lepton and //q2 phase space is probed. //Start by declaring a particle at rest. //It only makes sense to have a scalar parent. For now. //This should be generalized later. // EvtScalarParticle *scalar_part; // scalar_part=new EvtScalarParticle; EvtDiracParticle* dirac_part; EvtParticle* root_part; dirac_part = new EvtDiracParticle; //cludge to avoid generating random numbers! // scalar_part->noLifeTime(); dirac_part->noLifeTime(); EvtVector4R p_init; p_init.set( EvtPDL::getMass( parent ), 0.0, 0.0, 0.0 ); // scalar_part->init(parent,p_init); // root_part=(EvtParticle *)scalar_part; // root_part->set_type(EvtSpinType::SCALAR); dirac_part->init( parent, p_init ); root_part = (EvtParticle*)dirac_part; root_part->setDiagonalSpinDensity(); EvtParticle *daughter, *lep, *trino; EvtAmp amp; EvtId listdaug[3]; listdaug[0] = baryon; listdaug[1] = lepton; listdaug[2] = nudaug; amp.init( parent, 3, listdaug ); root_part->makeDaughters( 3, listdaug ); daughter = root_part->getDaug( 0 ); lep = root_part->getDaug( 1 ); trino = root_part->getDaug( 2 ); //cludge to avoid generating random numbers! daughter->noLifeTime(); lep->noLifeTime(); trino->noLifeTime(); //Initial particle is unpolarized, well it is a scalar so it is //trivial EvtSpinDensity rho; rho.setDiag( root_part->getSpinStates() ); double mass[3]; double m = root_part->mass(); EvtVector4R p4baryon, p4lepton, p4nu, p4w; double q2max; double q2, elepton, plepton; int i, j; double erho, prho, costl; double maxfoundprob = 0.0; double prob = -10.0; int massiter; for ( massiter = 0; massiter < 3; massiter++ ) { mass[0] = EvtPDL::getMass( baryon ); mass[1] = EvtPDL::getMass( lepton ); mass[2] = EvtPDL::getMass( nudaug ); if ( massiter == 1 ) { mass[0] = EvtPDL::getMinMass( baryon ); } if ( massiter == 2 ) { mass[0] = EvtPDL::getMaxMass( baryon ); } q2max = ( m - mass[0] ) * ( m - mass[0] ); //loop over q2 for ( i = 0; i < 25; i++ ) { q2 = ( ( i + 0.5 ) * q2max ) / 25.0; erho = ( m * m + mass[0] * mass[0] - q2 ) / ( 2.0 * m ); prho = sqrt( erho * erho - mass[0] * mass[0] ); p4baryon.set( erho, 0.0, 0.0, -1.0 * prho ); p4w.set( m - erho, 0.0, 0.0, prho ); //This is in the W rest frame elepton = ( q2 + mass[1] * mass[1] ) / ( 2.0 * sqrt( q2 ) ); plepton = sqrt( elepton * elepton - mass[1] * mass[1] ); double probctl[3]; for ( j = 0; j < 3; j++ ) { costl = 0.99 * ( j - 1.0 ); //These are in the W rest frame. Need to boost out into //the B frame. p4lepton.set( elepton, 0.0, plepton * sqrt( 1.0 - costl * costl ), plepton * costl ); p4nu.set( plepton, 0.0, -1.0 * plepton * sqrt( 1.0 - costl * costl ), -1.0 * plepton * costl ); EvtVector4R boost( ( m - erho ), 0.0, 0.0, 1.0 * prho ); p4lepton = boostTo( p4lepton, boost ); p4nu = boostTo( p4nu, boost ); //Now initialize the daughters... daughter->init( baryon, p4baryon ); lep->init( lepton, p4lepton ); trino->init( nudaug, p4nu ); CalcAmp( root_part, amp, FormFactors, r00, r01, r10, r11 ); //Now find the probability at this q2 and cos theta lepton point //and compare to maxfoundprob. //Do a little magic to get the probability!! prob = rho.normalizedProb( amp.getSpinDensity() ); probctl[j] = prob; } //probclt contains prob at ctl=-1,0,1. //prob=a+b*ctl+c*ctl^2 double a = probctl[1]; double b = 0.5 * ( probctl[2] - probctl[0] ); double c = 0.5 * ( probctl[2] + probctl[0] ) - probctl[1]; prob = probctl[0]; if ( probctl[1] > prob ) prob = probctl[1]; if ( probctl[2] > prob ) prob = probctl[2]; if ( fabs( c ) > 1e-20 ) { double ctlx = -0.5 * b / c; if ( fabs( ctlx ) < 1.0 ) { double probtmp = a + b * ctlx + c * ctlx * ctlx; if ( probtmp > prob ) prob = probtmp; } } //EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "prob,probctl:"< maxfoundprob ) { maxfoundprob = prob; } } if ( EvtPDL::getWidth( baryon ) <= 0.0 ) { //if the particle is narrow dont bother with changing the mass. massiter = 4; } } root_part->deleteTree(); maxfoundprob *= 1.1; return maxfoundprob; } void EvtSemiLeptonicBaryonAmp::CalcAmp( EvtParticle* parent, EvtAmp& amp, EvtSemiLeptonicFF* FormFactors, EvtComplex r00, EvtComplex r01, EvtComplex r10, EvtComplex r11 ) { // Leptons static EvtId EM = EvtPDL::getId( "e-" ); static EvtId MUM = EvtPDL::getId( "mu-" ); static EvtId TAUM = EvtPDL::getId( "tau-" ); // Anti-Leptons static EvtId EP = EvtPDL::getId( "e+" ); static EvtId MUP = EvtPDL::getId( "mu+" ); static EvtId TAUP = EvtPDL::getId( "tau+" ); // Baryons static EvtId LAMCP = EvtPDL::getId( "Lambda_c+" ); static EvtId LAMC1P = EvtPDL::getId( "Lambda_c(2593)+" ); static EvtId LAMC2P = EvtPDL::getId( "Lambda_c(2625)+" ); static EvtId LAMB = EvtPDL::getId( "Lambda_b0" ); // Anti-Baryons static EvtId LAMCM = EvtPDL::getId( "anti-Lambda_c-" ); static EvtId LAMC1M = EvtPDL::getId( "anti-Lambda_c(2593)-" ); static EvtId LAMC2M = EvtPDL::getId( "anti-Lambda_c(2625)-" ); static EvtId LAMBB = EvtPDL::getId( "anti-Lambda_b0" ); // Set the spin density matrix of the parent baryon EvtSpinDensity rho; rho.setDim( 2 ); rho.set( 0, 0, r00 ); rho.set( 0, 1, r01 ); rho.set( 1, 0, r10 ); rho.set( 1, 1, r11 ); EvtVector4R vector4P = parent->getP4Lab(); double pmag = vector4P.d3mag(); double cosTheta = pmag > 0.0 ? vector4P.get( 3 ) / pmag : 0.0; double theta = acos( cosTheta ); double phi = atan2( vector4P.get( 2 ), vector4P.get( 1 ) ); parent->setSpinDensityForwardHelicityBasis( rho, phi, theta, 0.0 ); //parent->setSpinDensityForward(rho); // Set the four momentum of the parent baryon in it's rest frame EvtVector4R p4b; p4b.set( parent->mass(), 0.0, 0.0, 0.0 ); // Get the four momentum of the daughter baryon in the parent's rest frame EvtVector4R p4daught = parent->getDaug( 0 )->getP4(); // Add the lepton and neutrino 4 momenta to find q (q^2) EvtVector4R q = parent->getDaug( 1 )->getP4() + parent->getDaug( 2 )->getP4(); double q2 = q.mass2(); EvtId l_num = parent->getDaug( 1 )->getId(); EvtId bar_num = parent->getDaug( 0 )->getId(); EvtId par_num = parent->getId(); double baryonmass = parent->getDaug( 0 )->mass(); // Handle spin-1/2 daughter baryon Dirac spinor cases if ( EvtPDL::getSpinType( parent->getDaug( 0 )->getId() ) == EvtSpinType::DIRAC ) { // Set the form factors double f1, f2, f3, g1, g2, g3; FormFactors->getdiracff( par_num, bar_num, q2, baryonmass, &f1, &f2, &f3, &g1, &g2, &g3 ); - const double form_fact[6] = {f1, f2, f3, g1, g2, g3}; + const double form_fact[6] = { f1, f2, f3, g1, g2, g3 }; EvtVector4C b11, b12, b21, b22, l1, l2; // Lepton Current if ( l_num == EM || l_num == MUM || l_num == TAUM ) { l1 = EvtLeptonVACurrent( parent->getDaug( 1 )->spParent( 0 ), parent->getDaug( 2 )->spParentNeutrino() ); l2 = EvtLeptonVACurrent( parent->getDaug( 1 )->spParent( 1 ), parent->getDaug( 2 )->spParentNeutrino() ); } else if ( l_num == EP || l_num == MUP || l_num == TAUP ) { l1 = EvtLeptonVACurrent( parent->getDaug( 2 )->spParentNeutrino(), parent->getDaug( 1 )->spParent( 0 ) ); l2 = EvtLeptonVACurrent( parent->getDaug( 2 )->spParentNeutrino(), parent->getDaug( 1 )->spParent( 1 ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Wrong lepton number \n"; ::abort(); } // Baryon current // Flag for particle/anti-particle parent, daughter with same/opp. parity // pflag = 0 => particle, same parity parent, daughter // pflag = 1 => particle, opp. parity parent, daughter // pflag = 2 => anti-particle, same parity parent, daughter // pflag = 3 => anti-particle, opp. parity parent, daughter int pflag = 0; // Handle 1/2+ -> 1/2+ first if ( ( par_num == LAMB && bar_num == LAMCP ) || ( par_num == LAMBB && bar_num == LAMCM ) ) { // Set particle/anti-particle flag if ( bar_num == LAMCP ) pflag = 0; else if ( bar_num == LAMCM ) pflag = 2; b11 = EvtBaryonVACurrent( parent->getDaug( 0 )->spParent( 0 ), parent->sp( 0 ), p4b, p4daught, form_fact, pflag ); b21 = EvtBaryonVACurrent( parent->getDaug( 0 )->spParent( 0 ), parent->sp( 1 ), p4b, p4daught, form_fact, pflag ); b12 = EvtBaryonVACurrent( parent->getDaug( 0 )->spParent( 1 ), parent->sp( 0 ), p4b, p4daught, form_fact, pflag ); b22 = EvtBaryonVACurrent( parent->getDaug( 0 )->spParent( 1 ), parent->sp( 1 ), p4b, p4daught, form_fact, pflag ); } // Handle 1/2+ -> 1/2- second else if ( ( par_num == LAMB && bar_num == LAMC1P ) || ( par_num == LAMBB && bar_num == LAMC1M ) ) { // Set particle/anti-particle flag if ( bar_num == LAMC1P ) pflag = 1; else if ( bar_num == LAMC1M ) pflag = 3; b11 = EvtBaryonVACurrent( ( parent->getDaug( 0 )->spParent( 0 ) ), ( EvtGammaMatrix::g5() * parent->sp( 0 ) ), p4b, p4daught, form_fact, pflag ); b21 = EvtBaryonVACurrent( ( parent->getDaug( 0 )->spParent( 0 ) ), ( EvtGammaMatrix::g5() * parent->sp( 1 ) ), p4b, p4daught, form_fact, pflag ); b12 = EvtBaryonVACurrent( ( parent->getDaug( 0 )->spParent( 1 ) ), ( EvtGammaMatrix::g5() * parent->sp( 0 ) ), p4b, p4daught, form_fact, pflag ); b22 = EvtBaryonVACurrent( ( parent->getDaug( 0 )->spParent( 1 ) ), ( EvtGammaMatrix::g5() * parent->sp( 1 ) ), p4b, p4daught, form_fact, pflag ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Dirac semilep. baryon current " << "not implemented for this decay sequence." << std::endl; ::abort(); } amp.vertex( 0, 0, 0, l1 * b11 ); amp.vertex( 0, 0, 1, l2 * b11 ); amp.vertex( 1, 0, 0, l1 * b21 ); amp.vertex( 1, 0, 1, l2 * b21 ); amp.vertex( 0, 1, 0, l1 * b12 ); amp.vertex( 0, 1, 1, l2 * b12 ); amp.vertex( 1, 1, 0, l1 * b22 ); amp.vertex( 1, 1, 1, l2 * b22 ); } // Need special handling for the spin-3/2 daughter baryon // Rarita-Schwinger spinor cases else if ( EvtPDL::getSpinType( parent->getDaug( 0 )->getId() ) == EvtSpinType::RARITASCHWINGER ) { // Set the form factors double f1, f2, f3, f4, g1, g2, g3, g4; FormFactors->getraritaff( par_num, bar_num, q2, baryonmass, &f1, &f2, &f3, &f4, &g1, &g2, &g3, &g4 ); - const double form_fact[8] = {f1, f2, f3, f4, g1, g2, g3, g4}; + const double form_fact[8] = { f1, f2, f3, f4, g1, g2, g3, g4 }; EvtId l_num = parent->getDaug( 1 )->getId(); EvtVector4C b11, b12, b21, b22, b13, b23, b14, b24, l1, l2; // Lepton Current if ( l_num == EM || l_num == MUM || l_num == TAUM ) { // Lepton Current l1 = EvtLeptonVACurrent( parent->getDaug( 1 )->spParent( 0 ), parent->getDaug( 2 )->spParentNeutrino() ); l2 = EvtLeptonVACurrent( parent->getDaug( 1 )->spParent( 1 ), parent->getDaug( 2 )->spParentNeutrino() ); } else if ( l_num == EP || l_num == MUP || l_num == TAUP ) { l1 = EvtLeptonVACurrent( parent->getDaug( 2 )->spParentNeutrino(), parent->getDaug( 1 )->spParent( 0 ) ); l2 = EvtLeptonVACurrent( parent->getDaug( 2 )->spParentNeutrino(), parent->getDaug( 1 )->spParent( 1 ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Wrong lepton number \n"; } // Baryon Current // Declare particle, anti-particle flag, same/opp. parity // pflag = 0 => particle // pflag = 1 => anti-particle int pflag = 0; // Handle cases of 1/2+ -> 3/2- if ( par_num == LAMB && bar_num == LAMC2P ) { // Set flag for particle case pflag = 0; } else if ( par_num == LAMBB && bar_num == LAMC2M ) { // Set flag for anti-particle case pflag = 1; } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Rarita-Schwinger semilep. baryon current " << "not implemented for this decay sequence." << std::endl; ::abort(); } // Baryon current b11 = EvtBaryonVARaritaCurrent( parent->getDaug( 0 )->spRSParent( 0 ), parent->sp( 0 ), p4b, p4daught, form_fact, pflag ); b21 = EvtBaryonVARaritaCurrent( parent->getDaug( 0 )->spRSParent( 0 ), parent->sp( 1 ), p4b, p4daught, form_fact, pflag ); b12 = EvtBaryonVARaritaCurrent( parent->getDaug( 0 )->spRSParent( 1 ), parent->sp( 0 ), p4b, p4daught, form_fact, pflag ); b22 = EvtBaryonVARaritaCurrent( parent->getDaug( 0 )->spRSParent( 1 ), parent->sp( 1 ), p4b, p4daught, form_fact, pflag ); b13 = EvtBaryonVARaritaCurrent( parent->getDaug( 0 )->spRSParent( 2 ), parent->sp( 0 ), p4b, p4daught, form_fact, pflag ); b23 = EvtBaryonVARaritaCurrent( parent->getDaug( 0 )->spRSParent( 2 ), parent->sp( 1 ), p4b, p4daught, form_fact, pflag ); b14 = EvtBaryonVARaritaCurrent( parent->getDaug( 0 )->spRSParent( 3 ), parent->sp( 0 ), p4b, p4daught, form_fact, pflag ); b24 = EvtBaryonVARaritaCurrent( parent->getDaug( 0 )->spRSParent( 3 ), parent->sp( 1 ), p4b, p4daught, form_fact, pflag ); amp.vertex( 0, 0, 0, l1 * b11 ); amp.vertex( 0, 0, 1, l2 * b11 ); amp.vertex( 1, 0, 0, l1 * b21 ); amp.vertex( 1, 0, 1, l2 * b21 ); amp.vertex( 0, 1, 0, l1 * b12 ); amp.vertex( 0, 1, 1, l2 * b12 ); amp.vertex( 1, 1, 0, l1 * b22 ); amp.vertex( 1, 1, 1, l2 * b22 ); amp.vertex( 0, 2, 0, l1 * b13 ); amp.vertex( 0, 2, 1, l2 * b13 ); amp.vertex( 1, 2, 0, l1 * b23 ); amp.vertex( 1, 2, 1, l2 * b23 ); amp.vertex( 0, 3, 0, l1 * b14 ); amp.vertex( 0, 3, 1, l2 * b14 ); amp.vertex( 1, 3, 0, l1 * b24 ); amp.vertex( 1, 3, 1, l2 * b24 ); } } EvtVector4C EvtSemiLeptonicBaryonAmp::EvtBaryonVACurrent( const EvtDiracSpinor& Bf, const EvtDiracSpinor& Bi, EvtVector4R parent, EvtVector4R daught, const double* ff, int pflag ) { // flag == 0 => particle, same parity // flag == 1 => particle, opposite parity // flag == 2 => anti-particle, same parity // flag == 3 => anti-particle, opposite parity // particle EvtComplex cv = EvtComplex( 1.0, 0. ); EvtComplex ca = EvtComplex( 1.0, 0. ); EvtComplex cg0 = EvtComplex( 1.0, 0. ); EvtComplex cg5 = EvtComplex( 1.0, 0. ); // antiparticle- same parity parent & daughter if ( pflag == 2 ) { cv = EvtComplex( -1.0, 0. ); ca = EvtComplex( 1.0, 0. ); cg0 = EvtComplex( 1.0, 0.0 ); cg5 = EvtComplex( 0.0, -1.0 ); } // antiparticle- opposite parity parent & daughter else if ( pflag == 3 ) { cv = EvtComplex( 1.0, 0. ); ca = EvtComplex( -1.0, 0. ); cg0 = EvtComplex( 0.0, -1.0 ); cg5 = EvtComplex( 1.0, 0.0 ); } EvtVector4C t[6]; // Term 1 = \bar{u}(p',s')*(F_1(q^2)*\gamma_{mu})*u(p,s) t[0] = cv * EvtLeptonVCurrent( Bf, Bi ); // Term 2 = \bar{u}(p',s')*(F_2(q^2)*(p_{mu}/m_{\Lambda_Q}))*u(p,s) t[1] = cg0 * EvtLeptonSCurrent( Bf, Bi ) * ( parent / parent.mass() ); // Term 3 = \bar{u}(p',s')*(F_3(q^2)*(p'_{mu}/m_{\Lambda_q}))*u(p,s) t[2] = cg0 * EvtLeptonSCurrent( Bf, Bi ) * ( daught / daught.mass() ); // Term 4 = \bar{u}(p',s')*(G_1(q^2)*\gamma_{mu}*\gamma_5)*u(p,s) t[3] = ca * EvtLeptonACurrent( Bf, Bi ); // Term 5 = \bar{u}(p',s')*(G_2(q^2)*(p_{mu}/m_{\Lambda_Q})*\gamma_5)*u(p,s) t[4] = cg5 * EvtLeptonPCurrent( Bf, Bi ) * ( parent / parent.mass() ); // Term 6 = \bar{u}(p',s')*(G_3(q^2)*(p'_{mu}/m_{\Lambda_q})*\gamma_5)*u(p,s) t[5] = cg5 * EvtLeptonPCurrent( Bf, Bi ) * ( daught / daught.mass() ); // Sum the individual terms EvtVector4C current = ( ff[0] * t[0] + ff[1] * t[1] + ff[2] * t[2] - ff[3] * t[3] - ff[4] * t[4] - ff[5] * t[5] ); return current; } EvtVector4C EvtSemiLeptonicBaryonAmp::EvtBaryonVARaritaCurrent( const EvtRaritaSchwinger& Bf, const EvtDiracSpinor& Bi, EvtVector4R parent, EvtVector4R daught, const double* ff, int pflag ) { // flag == 0 => particle // flag == 1 => anti-particle // particle EvtComplex cv = EvtComplex( 1.0, 0. ); EvtComplex ca = EvtComplex( 1.0, 0. ); EvtComplex cg0 = EvtComplex( 1.0, 0. ); EvtComplex cg5 = EvtComplex( 1.0, 0. ); // antiparticle if ( pflag == 1 ) { cv = EvtComplex( -1.0, 0. ); ca = EvtComplex( 1.0, 0. ); cg0 = EvtComplex( 1.0, 0.0 ); cg5 = EvtComplex( 0.0, -1.0 ); } EvtVector4C t[8]; EvtTensor4C id; id.setdiag( 1.0, 1.0, 1.0, 1.0 ); EvtDiracSpinor tmp; for ( int i = 0; i < 4; i++ ) { tmp.set_spinor( i, Bf.getVector( i ) * parent ); } EvtVector4C v1, v2; for ( int i = 0; i < 4; i++ ) { v1.set( i, EvtLeptonSCurrent( Bf.getSpinor( i ), Bi ) ); v2.set( i, EvtLeptonPCurrent( Bf.getSpinor( i ), Bi ) ); } // Term 1 = \bar{u}^{\alpha}(p',s')*(p_{\alpha}/m_{\Lambda_Q})*(F_1(q^2)*\gamma_{mu})*u(p,s) t[0] = ( cv / parent.mass() ) * EvtLeptonVCurrent( tmp, Bi ); // Term 2 // = \bar{u}^{\alpha}(p',s')*(p_{\alpha}/m_{\Lambda_Q})*(F_2(q^2)*(p_{mu}/m_{\Lambda_Q}))*u(p,s) t[1] = ( ( cg0 / parent.mass() ) * EvtLeptonSCurrent( tmp, Bi ) ) * ( parent / parent.mass() ); // Term 3 // = \bar{u}^{\alpha}(p',s')*(p_{\alpha}/m_{\Lambda_Q})*(F_3(q^2)*(p'_{mu}/m_{\Lambda_q}))*u(p,s) t[2] = ( ( cg0 / parent.mass() ) * EvtLeptonSCurrent( tmp, Bi ) ) * ( daught / daught.mass() ); // Term 4 = \bar{u}^{\alpha}(p',s')*(F_4(q^2)*g_{\alpha,\mu})*u(p,s) t[3] = cg0 * ( id.cont2( v1 ) ); // Term 5 // = \bar{u}^{\alpha}(p',s')*(p_{\alpha}/m_{\Lambda_Q})*(G_1(q^2)*\gamma_{mu}*\gamma_5)*u(p,s) t[4] = ( ca / parent.mass() ) * EvtLeptonACurrent( tmp, Bi ); // Term 6 // = \bar{u}^{\alpha}(p',s')*(p_{\alpha}/m_{\Lambda_Q}) // *(G_2(q^2)*(p_{mu}/m_{\Lambda_Q})*\gamma_5)*u(p,s) t[5] = ( ( cg5 / parent.mass() ) * EvtLeptonPCurrent( tmp, Bi ) ) * ( parent / parent.mass() ); // Term 7 // = \bar{u}^{\alpha}(p',s')*(p_{\alpha}/m_{\Lambda_Q}) // *(G_3(q^2)*(p'_{mu}/m_{\Lambda_q})*\gamma_5)*u(p,s) t[6] = ( ( cg5 / parent.mass() ) * EvtLeptonPCurrent( tmp, Bi ) ) * ( daught / daught.mass() ); // Term 8 = \bar{u}^{\alpha}(p',s')*(G_4(q^2)*g_{\alpha,\mu}*\gamma_5))*u(p,s) t[7] = cg5 * ( id.cont2( v2 ) ); // Sum the individual terms EvtVector4C current = ( ff[0] * t[0] + ff[1] * t[1] + ff[2] * t[2] + ff[3] * t[3] - ff[4] * t[4] - ff[5] * t[5] - ff[6] * t[6] - ff[7] * t[7] ); return current; } diff --git a/src/EvtGenModels/EvtBBScalar.cpp b/src/EvtGenModels/EvtBBScalar.cpp index 3706b63..082ad24 100644 --- a/src/EvtGenModels/EvtBBScalar.cpp +++ b/src/EvtGenModels/EvtBBScalar.cpp @@ -1,497 +1,497 @@ /*********************************************************************** * 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/EvtBBScalar.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGammaMatrix.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtSpinType.hh" #include "EvtGenBase/EvtTensor4C.hh" #include using namespace std; const float pi = 3.14159; const EvtComplex EvtBBScalar::I = EvtComplex( 0, 1 ); const EvtComplex EvtBBScalar::V_ub = EvtComplex( 3.67e-3 * cos( 60 / 180 * pi ), 3.67e-3 * cos( 60 / 180 * pi ) ); const EvtComplex EvtBBScalar::V_us_star = EvtComplex( 0.22, 0 ); const EvtComplex EvtBBScalar::a1 = EvtComplex( 1.05, 0 ); const EvtComplex EvtBBScalar::V_tb = EvtComplex( 0.99915, 0 ); const EvtComplex EvtBBScalar::V_ts_star = EvtComplex( -0.04029 - 0.000813 * cos( 60 / 180 * pi ), -0.000813 * cos( 60 / 180 * pi ) ); const EvtComplex EvtBBScalar::a4 = EvtComplex( -387.3e-4, -121e-4 ); const EvtComplex EvtBBScalar::a6 = EvtComplex( -555.3e-4, -121e-4 ); -const double EvtBBScalar::x[] = {420.96, -10485.50, 100639.97, -433916.61, - 613780.15}; -const double EvtBBScalar::y[] = {292.62, -735.73}; +const double EvtBBScalar::x[] = { 420.96, -10485.50, 100639.97, -433916.61, + 613780.15 }; +const double EvtBBScalar::y[] = { 292.62, -735.73 }; const double EvtBBScalar::m_s = 0.120; const double EvtBBScalar::m_u = 0.029 * 0.120; const double EvtBBScalar::m_b = 4.88; EvtBBScalar::EvtBBScalar() : EvtDecayAmp(), _massRatio( 0 ), _baryonMassSum( 0 ) { FormFactor dummy; dummy.value = 0.36; dummy.sigma1 = 0.43; dummy.sigma2 = 0.0; dummy.mV = 5.42; _f1Map.insert( make_pair( string( "K" ), dummy ) ); dummy.sigma1 = 0.70; dummy.sigma2 = 0.27; _f0Map.insert( make_pair( string( "K" ), dummy ) ); dummy.value = 0.29; dummy.sigma1 = 0.48; dummy.sigma2 = 0.0; dummy.mV = 5.32; _f1Map.insert( make_pair( string( "pi" ), dummy ) ); dummy.sigma1 = 0.76; dummy.sigma2 = 0.28; _f0Map.insert( make_pair( string( "pi" ), dummy ) ); } std::string EvtBBScalar::getName() { return "B_TO_2BARYON_SCALAR"; } EvtBBScalar* EvtBBScalar::clone() { return new EvtBBScalar; } void EvtBBScalar::setKnownBaryonTypes( const EvtId& baryon ) { int baryonId = EvtPDL::getStdHep( baryon ); if ( EvtPDL::getStdHep( EvtPDL::getId( "Lambda0" ) ) == baryonId or EvtPDL::getStdHep( EvtPDL::getId( "anti-Lambda0" ) ) == baryonId ) { _baryonCombination.set( Lambda ); } else if ( EvtPDL::getStdHep( EvtPDL::getId( "p+" ) ) == baryonId or EvtPDL::getStdHep( EvtPDL::getId( "anti-p-" ) ) == baryonId ) { _baryonCombination.set( Proton ); } else if ( EvtPDL::getStdHep( EvtPDL::getId( "n0" ) ) == baryonId or EvtPDL::getStdHep( EvtPDL::getId( "anti-n0" ) ) == baryonId ) { _baryonCombination.set( Neutron ); } else if ( EvtPDL::getStdHep( EvtPDL::getId( "Sigma0" ) ) == baryonId or EvtPDL::getStdHep( EvtPDL::getId( "anti-Sigma0" ) ) == baryonId ) { _baryonCombination.set( Sigma0 ); } else if ( EvtPDL::getStdHep( EvtPDL::getId( "Sigma-" ) ) == baryonId or EvtPDL::getStdHep( EvtPDL::getId( "anti-Sigma+" ) ) == baryonId ) { _baryonCombination.set( Sigma_minus ); } else if ( EvtPDL::getStdHep( EvtPDL::getId( "Xi0" ) ) == baryonId or EvtPDL::getStdHep( EvtPDL::getId( "anti-Xi0" ) ) == baryonId ) { _baryonCombination.set( Xi0 ); } else if ( EvtPDL::getStdHep( EvtPDL::getId( "Xi-" ) ) == baryonId or EvtPDL::getStdHep( EvtPDL::getId( "anti-Xi+" ) ) == baryonId ) { _baryonCombination.set( Xi_minus ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtBBScalar::init: Don't know what to do with this type as the first or second baryon\n"; exit( 2 ); } } double EvtBBScalar::baryonF1F2( double t ) const { // check for known form factors for combination of baryons if ( _baryonCombination.test( Lambda ) and _baryonCombination.test( Proton ) ) { return -sqrt( 1.5 ) * G_p( t ); } else if ( _baryonCombination.test( Sigma0 ) and _baryonCombination.test( Proton ) ) { return -sqrt( 0.5 ) * ( G_p( t ) + 2 * G_n( t ) ); } else if ( _baryonCombination.test( Sigma_minus ) and _baryonCombination.test( Neutron ) ) { return -G_p( t ) - 2 * G_n( t ); } else if ( _baryonCombination.test( Xi0 ) and _baryonCombination.test( Sigma_minus ) ) { return G_p( t ) - G_n( t ); } else if ( _baryonCombination.test( Xi_minus ) and _baryonCombination.test( Sigma0 ) ) { return sqrt( 0.5 ) * ( G_p( t ) - G_n( t ) ); } else if ( _baryonCombination.test( Xi_minus ) and _baryonCombination.test( Lambda ) ) { return sqrt( 1.5 ) * ( G_p( t ) + G_n( t ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtBBScalar::baryonF1F2: Don't know what to do with this type as the first or second baryon\n"; exit( 2 ); } } double EvtBBScalar::formFactorFit( double t, const vector& params ) const { static const double gamma = 2.148; static const double Lambda_0 = 0.3; double result = 0; for ( size_t i = 0; i < params.size(); ++i ) { result += params[i] / pow( t, static_cast( i + 1 ) ); } return result * pow( log( t / pow( Lambda_0, 2 ) ), -gamma ); } double EvtBBScalar::G_p( double t ) const { const vector v_x( x, x + 5 ); return formFactorFit( t, v_x ); } double EvtBBScalar::G_n( double t ) const { const vector v_y( y, y + 2 ); return -formFactorFit( t, v_y ); } double EvtBBScalar::baryon_gA( double t ) const { // check for known form factors for combination of baryons if ( _baryonCombination.test( Lambda ) and _baryonCombination.test( Proton ) ) { return -1 / sqrt( 6. ) * ( D_A( t ) + 3 * F_A( t ) ); } else if ( _baryonCombination.test( Sigma0 ) and _baryonCombination.test( Proton ) ) { return 1 / sqrt( 2. ) * ( D_A( t ) - F_A( t ) ); } else if ( _baryonCombination.test( Sigma_minus ) and _baryonCombination.test( Neutron ) ) { return D_A( t ) - F_A( t ); } else if ( _baryonCombination.test( Xi0 ) and _baryonCombination.test( Sigma_minus ) ) { return D_A( t ) + F_A( t ); } else if ( _baryonCombination.test( Xi_minus ) and _baryonCombination.test( Sigma0 ) ) { return 1 / sqrt( 2. ) * ( D_A( t ) + F_A( t ) ); } else if ( _baryonCombination.test( Xi_minus ) and _baryonCombination.test( Lambda ) ) { return -1 / sqrt( 6. ) * ( D_A( t ) - 3 * F_A( t ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtBBScalar::baryon_gA: Don't know what to do with this type as the first or second baryon\n"; exit( 2 ); } } double EvtBBScalar::baryon_gP( double t ) const { // check for known form factors for combination of baryons if ( _baryonCombination.test( Lambda ) and _baryonCombination.test( Proton ) ) { return -1 / sqrt( 6. ) * ( D_P( t ) + 3 * F_P( t ) ); } else if ( _baryonCombination.test( Sigma0 ) and _baryonCombination.test( Proton ) ) { return 1 / sqrt( 2. ) * ( D_P( t ) - F_P( t ) ); } else if ( _baryonCombination.test( Sigma_minus ) and _baryonCombination.test( Neutron ) ) { return D_P( t ) - F_P( t ); } else if ( _baryonCombination.test( Xi0 ) and _baryonCombination.test( Sigma_minus ) ) { return D_P( t ) + F_P( t ); } else if ( _baryonCombination.test( Xi_minus ) and _baryonCombination.test( Sigma0 ) ) { return 1 / sqrt( 2. ) * ( D_P( t ) + F_P( t ) ); } else if ( _baryonCombination.test( Xi_minus ) and _baryonCombination.test( Lambda ) ) { return -1 / sqrt( 6. ) * ( D_P( t ) - 3 * F_P( t ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtBBScalar::baryon_gP: Don't know what to do with this type as the first or second baryon\n"; exit( 2 ); } } double EvtBBScalar::baryon_fS( double t ) const { // check for known form factors for combination of baryons if ( _baryonCombination.test( Lambda ) and _baryonCombination.test( Proton ) ) { return -1 / sqrt( 6. ) * ( D_S( t ) + 3 * F_S( t ) ); } else if ( _baryonCombination.test( Sigma0 ) and _baryonCombination.test( Proton ) ) { return 1 / sqrt( 2. ) * ( D_S( t ) - F_S( t ) ); } else if ( _baryonCombination.test( Sigma_minus ) and _baryonCombination.test( Neutron ) ) { return D_S( t ) - F_S( t ); } else if ( _baryonCombination.test( Xi0 ) and _baryonCombination.test( Sigma_minus ) ) { return D_S( t ) + F_S( t ); } else if ( _baryonCombination.test( Xi_minus ) and _baryonCombination.test( Sigma0 ) ) { return 1 / sqrt( 2. ) * ( D_S( t ) + F_S( t ) ); } else if ( _baryonCombination.test( Xi_minus ) and _baryonCombination.test( Lambda ) ) { return -1 / sqrt( 6. ) * ( D_S( t ) - 3 * F_S( t ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtBBScalar::baryon_fS: Don't know what to do with this type as the first or second baryon\n"; exit( 2 ); } } double EvtBBScalar::D_A( double t ) const { - const double d_tilde[] = {x[0] - 1.5 * y[0], -478}; + const double d_tilde[] = { x[0] - 1.5 * y[0], -478 }; const vector v_d_tilde( d_tilde, d_tilde + 2 ); return formFactorFit( t, v_d_tilde ); } double EvtBBScalar::F_A( double t ) const { - const double f_tilde[] = {2. / 3 * x[0] + 0.5 * y[0], -478}; + const double f_tilde[] = { 2. / 3 * x[0] + 0.5 * y[0], -478 }; const vector v_f_tilde( f_tilde, f_tilde + 2 ); return formFactorFit( t, v_f_tilde ); } double EvtBBScalar::D_P( double t ) const { - const double d_bar[] = {1.5 * y[0] * _massRatio, /*-952*/ 0}; + const double d_bar[] = { 1.5 * y[0] * _massRatio, /*-952*/ 0 }; const vector v_d_bar( d_bar, d_bar + 2 ); return formFactorFit( t, v_d_bar ); } double EvtBBScalar::F_P( double t ) const { - const double f_bar[] = {( x[0] - 0.5 * y[0] ) * _massRatio, /*-952*/ 0}; + const double f_bar[] = { ( x[0] - 0.5 * y[0] ) * _massRatio, /*-952*/ 0 }; const vector v_f_bar( f_bar, f_bar + 2 ); return formFactorFit( t, v_f_bar ); } double EvtBBScalar::D_S( double t ) const { return -1.5 * _massRatio * G_n( t ); } double EvtBBScalar::F_S( double t ) const { return ( G_p( t ) + 0.5 * G_n( t ) ) * _massRatio; } double EvtBBScalar::baryon_hA( double t ) const { return ( 1 / _massRatio * baryon_gP( t ) - baryon_gA( t ) ) * pow( _baryonMassSum, 2 ) / t; } void EvtBBScalar::init() { // no arguments, daughter lambda p_bar pi // charge conservation is checked by base class checkNArg( 0 ); checkNDaug( 3 ); checkSpinParent( EvtSpinType::SCALAR ); checkSpinDaughter( 0, EvtSpinType::DIRAC ); checkSpinDaughter( 1, EvtSpinType::DIRAC ); checkSpinDaughter( 2, EvtSpinType::SCALAR ); EvtId baryon1 = getDaug( 0 ); EvtId baryon2 = getDaug( 1 ); EvtId scalar = getDaug( 2 ); int scalarId = EvtPDL::getStdHep( scalar ); // Different form factors for the B-pi or B-K transition. if ( scalarId == EvtPDL::getStdHep( EvtPDL::getId( "pi+" ) ) or scalarId == EvtPDL::getStdHep( EvtPDL::getId( "pi-" ) ) or scalarId == EvtPDL::getStdHep( EvtPDL::getId( "pi0" ) ) ) { _scalarType = "pi"; } else if ( scalarId == EvtPDL::getStdHep( EvtPDL::getId( "K+" ) ) or scalarId == EvtPDL::getStdHep( EvtPDL::getId( "K-" ) ) or scalarId == EvtPDL::getStdHep( EvtPDL::getId( "K0" ) ) or scalarId == EvtPDL::getStdHep( EvtPDL::getId( "anti-K0" ) ) ) { _scalarType = "K"; } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtBBScalar::init: Can only deal with Kaons or pions as the third particle\n" << "\tFound: " << scalarId << endl; exit( 2 ); } // check for known particles setKnownBaryonTypes( baryon1 ); setKnownBaryonTypes( baryon2 ); double mass1 = EvtPDL::getMass( baryon1 ); double mass2 = EvtPDL::getMass( baryon2 ); // This whole model deals only with baryons that differ in s-u if ( mass1 > mass2 ) _massRatio = ( mass1 - mass2 ) / ( m_s - m_u ); else _massRatio = ( mass2 - mass1 ) / ( m_s - m_u ); _baryonMassSum = mass1 + mass2; } // initialize phasespace and calculate the amplitude void EvtBBScalar::decay( EvtParticle* p ) { p->initializePhaseSpace( getNDaug(), getDaugs() ); EvtVector4R B_Momentum = p->getP4Lab(); EvtDiracParticle* theLambda = dynamic_cast( p->getDaug( 0 ) ); EvtDiracParticle* theAntiP = dynamic_cast( p->getDaug( 1 ) ); EvtScalarParticle* theScalar = dynamic_cast( p->getDaug( 2 ) ); EvtVector4R scalarMomentum = theScalar->getP4Lab(); // The amplitude consists of three matrix elements. These will be calculated one by one here. // loop over all possible spin states for ( int i = 0; i < 2; ++i ) { EvtDiracSpinor lambdaPol = theLambda->spParent( i ); for ( int j = 0; j < 2; ++j ) { EvtDiracSpinor antiP_Pol = theAntiP->spParent( j ); EvtVector4C theAmplitudePartA = amp_A( B_Momentum, scalarMomentum ); EvtComplex amplitude; for ( int index = 0; index < 4; ++index ) { amplitude += theAmplitudePartA.get( index ) * ( const_B * amp_B( theLambda, lambdaPol, theAntiP, antiP_Pol, index ) + const_C * amp_C( theLambda, lambdaPol, theAntiP, antiP_Pol, index ) ); } vertex( i, j, amplitude ); } } } void EvtBBScalar::initProbMax() { // setProbMax(1); setProbMax( 0.2 ); // found by trial and error } // Form factor f1 for B-pi transition double EvtBBScalar::B_pi_f1( double t ) const { FormFactor f = _f1Map[_scalarType]; double mv2 = f.mV * f.mV; return f.value / ( ( 1 - t / mv2 ) * ( 1 - f.sigma1 * t / mv2 + f.sigma2 * t * t / mv2 / mv2 ) ); } // Form factor f0 for B-pi transition double EvtBBScalar::B_pi_f0( double t ) const { FormFactor f = _f0Map[_scalarType]; double mv2 = f.mV * f.mV; return f.value / ( 1 - f.sigma1 * t / mv2 + f.sigma2 * t * t / mv2 / mv2 ); } // constants of the B and C parts of the amplitude const EvtComplex EvtBBScalar::const_B = V_ub * V_us_star * a1 - V_tb * V_ts_star * a4; const EvtComplex EvtBBScalar::const_C = 2 * a6 * V_tb * V_ts_star; // part A of the amplitude, see hep-ph/0204185 const EvtVector4C EvtBBScalar::amp_A( const EvtVector4R& p4B, const EvtVector4R& p4Scalar ) { double mB2 = p4B.mass2(); double mScalar2 = p4Scalar.mass2(); double t = ( p4B - p4Scalar ).mass2(); return ( ( p4B + p4Scalar ) - ( mB2 - mScalar2 ) / t * ( p4B - p4Scalar ) ) * B_pi_f1( t ) + ( mB2 - mScalar2 ) / t * ( p4B - p4Scalar ) * B_pi_f0( t ); } // part B of the amplitude, Vector and Axial Vector parts const EvtComplex EvtBBScalar::amp_B( const EvtDiracParticle* baryon1, const EvtDiracSpinor& b1Pol, const EvtDiracParticle* baryon2, const EvtDiracSpinor& b2Pol, int index ) { return amp_B_vectorPart( baryon1, b1Pol, baryon2, b2Pol, index ) - amp_B_axialPart( baryon1, b1Pol, baryon2, b2Pol, index ); } const EvtComplex EvtBBScalar::amp_B_vectorPart( const EvtDiracParticle* baryon1, const EvtDiracSpinor& b1Pol, const EvtDiracParticle* baryon2, const EvtDiracSpinor& b2Pol, int index ) { double t = ( baryon1->getP4Lab() + baryon2->getP4Lab() ).mass2(); EvtGammaMatrix gamma; for ( int i = 0; i < 4; ++i ) { gamma += EvtTensor4C::g().get( index, i ) * EvtGammaMatrix::g( i ); } // The F2 contribution that is written out in the paper is neglected here. // see hep-ph/0204185 EvtDiracSpinor A = EvtComplex( baryonF1F2( t ) ) * b2Pol; EvtDiracSpinor Adjb1Pol = b1Pol.adjoint(); EvtDiracSpinor gammaA = gamma * A; return Adjb1Pol * gammaA; // return b1Pol.adjoint()*(gamma*(EvtComplex(baryonF1F2(t))*b2Pol)); } const EvtComplex EvtBBScalar::amp_B_axialPart( const EvtDiracParticle* baryon1, const EvtDiracSpinor& b1Pol, const EvtDiracParticle* baryon2, const EvtDiracSpinor& b2Pol, int index ) { EvtGammaMatrix gamma; for ( int i = 0; i < 4; ++i ) { gamma += EvtTensor4C::g().get( index, i ) * EvtGammaMatrix::g( i ); } double t = ( baryon1->getP4Lab() + baryon2->getP4Lab() ).mass2(); double mSum = baryon1->mass() + baryon2->mass(); EvtVector4C momentum_upper = ( baryon1->getP4Lab() + baryon2->getP4Lab() ); EvtVector4C momentum; for ( int mu = 0; mu < 0; ++mu ) { EvtComplex dummy; for ( int i = 0; i < 4; ++i ) { dummy += EvtTensor4C::g().get( index, i ) * momentum_upper.get( i ); } momentum.set( mu, dummy ); } return b1Pol.adjoint() * ( ( ( baryon_gA( t ) * gamma + EvtGammaMatrix::id() * baryon_hA( t ) / mSum * momentum.get( index ) ) * EvtGammaMatrix::g5() ) * b2Pol ); } // part C of the amplitude, Scalar and Pseudoscalar parts const EvtComplex EvtBBScalar::amp_C( const EvtDiracParticle* baryon1, const EvtDiracSpinor& b1Pol, const EvtDiracParticle* baryon2, const EvtDiracSpinor& b2Pol, int index ) { EvtVector4C baryonSumP4_upper = baryon1->getP4Lab() + baryon2->getP4Lab(); EvtVector4C baryonSumP4; for ( int mu = 0; mu < 4; ++mu ) { EvtComplex dummy; for ( int i = 0; i < 4; ++i ) { dummy += EvtTensor4C::g().get( mu, i ) * baryonSumP4_upper.get( i ); } baryonSumP4.set( mu, dummy ); } double t = ( baryon1->getP4Lab() + baryon2->getP4Lab() ).mass2(); return baryonSumP4.get( index ) / ( m_b - m_u ) * ( amp_C_scalarPart( b1Pol, b2Pol, t ) + amp_C_pseudoscalarPart( b1Pol, b2Pol, t ) ); } const EvtComplex EvtBBScalar::amp_C_scalarPart( const EvtDiracSpinor& b1Pol, const EvtDiracSpinor& b2Pol, double t ) { return baryon_fS( t ) * b1Pol.adjoint() * b2Pol; } const EvtComplex EvtBBScalar::amp_C_pseudoscalarPart( const EvtDiracSpinor& b1Pol, const EvtDiracSpinor& b2Pol, double t ) { return baryon_gP( t ) * b1Pol.adjoint() * ( EvtGammaMatrix::g5() * b2Pol ); } diff --git a/src/EvtGenModels/EvtBTo3hCP.cpp b/src/EvtGenModels/EvtBTo3hCP.cpp index ca8432a..1e18498 100644 --- a/src/EvtGenModels/EvtBTo3hCP.cpp +++ b/src/EvtGenModels/EvtBTo3hCP.cpp @@ -1,1224 +1,1223 @@ /*********************************************************************** * 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/EvtBTo3hCP.hh" #include "EvtGenBase/EvtCPUtil.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtVector4R.hh" #include #include #include #define square( x ) ( ( x ) * ( x ) ) /* * MK - 25/Aug/2016 * The code bellow is not necessarilly well writen as it is 1-to-1 rewrite * from FORTRAN code (which is spread over 4 different source codes in not * fully obvious way). Once it is rewriten and giving correct results, I * will think how to give it more proper structure (mainly by checking what * is duplicated and how to simplify it). */ void EvtBTo3hCP::setConstants( double balpha, double bbeta ) { alphaCP = balpha; double calpha = cos( alphaCP ); double salpha = sin( alphaCP ); betaCP = bbeta; double cbeta = cos( betaCP ); double sbeta = sin( betaCP ); MA2 = square( M_B ) + square( M_pip ) + square( M_pi0 ) + square( M_pi0 ); MB2 = square( M_B ) + square( M_pip ) + square( M_pim ) + square( M_pi0 ); MC2 = square( M_B ) + square( M_Kp ) + square( M_pim ) + square( M_pi0 ); double StrongPhase = 0; EvtComplex StrongExp( cos( StrongPhase ), sin( StrongPhase ) ); EvtComplex Mat_Tp0( calpha, -salpha ); Mat_Tp0 *= 1.09; EvtComplex Mat_Tm0( calpha, -salpha ); Mat_Tm0 *= 1.09; EvtComplex Mat_T0p( calpha, -salpha ); Mat_T0p *= 0.66; EvtComplex Mat_T0m( calpha, -salpha ); Mat_T0m *= 0.66; EvtComplex Mat_Tpm( calpha, -salpha ); Mat_Tpm *= 1.00; EvtComplex Mat_Tmp( calpha, -salpha ); Mat_Tmp *= 0.47; EvtComplex Mat_Ppm( cos( -0.5 ), sin( -0.5 ) ); Mat_Ppm *= -0.2; EvtComplex Mat_Pmp( cos( 2. ), sin( 2. ) ); Mat_Pmp *= 0.15; EvtComplex Mat_P1 = 0.5 * ( Mat_Ppm - Mat_Pmp ); EvtComplex Mat_P0 = 0.5 * ( Mat_Ppm + Mat_Pmp ); EvtComplex Nat_Tp0( calpha, salpha ); Nat_Tp0 *= 1.09; EvtComplex Nat_Tm0( calpha, salpha ); Nat_Tm0 *= 1.09; EvtComplex Nat_T0p( calpha, salpha ); Nat_T0p *= 0.66; EvtComplex Nat_T0m( calpha, salpha ); Nat_T0m *= 0.66; EvtComplex Nat_Tpm( calpha, salpha ); Nat_Tpm *= 1.00; EvtComplex Nat_Tmp( calpha, salpha ); Nat_Tmp *= 0.47; EvtComplex Nat_P1 = Mat_P1; EvtComplex Nat_P0 = Mat_P0; Mat_Tpm = StrongExp * Mat_Tpm; Nat_Tpm = StrongExp * Nat_Tpm; Mat_S1 = Mat_Tp0 + 2. * Mat_P1; Mat_S2 = Mat_T0p - 2. * Mat_P1; Mat_S3 = Mat_Tpm + Mat_P1 + Mat_P0; Mat_S4 = Mat_Tmp - Mat_P1 + Mat_P0; Mat_S5 = -Mat_Tpm - Mat_Tmp + Mat_Tp0 + Mat_T0p - 2. * Mat_P0; Nat_S1 = Nat_Tp0 + 2. * Nat_P1; Nat_S2 = Nat_T0p - 2. * Nat_P1; Nat_S3 = Nat_Tpm + Nat_P1 + Nat_P0; Nat_S4 = Nat_Tmp - Nat_P1 + Nat_P0; Nat_S5 = -Nat_Tpm - Nat_Tmp + Nat_Tp0 + Nat_T0p - 2. * Nat_P0; // B0 -->-- K*+ pi- Amplitudes (Trees + Penguins) MatKstarp = EvtComplex( calpha, -salpha ) * EvtComplex( 0.220, 0. ) + EvtComplex( cbeta, sbeta ) * EvtComplex( -1.200, 0. ); // B0 -->-- K*0 pi0 Amplitudes (Trees + Penguins) MatKstar0 = EvtComplex( calpha, -salpha ) * EvtComplex( 0.015, 0. ) + EvtComplex( cbeta, sbeta ) * EvtComplex( 0.850, 0. ); // B0 -->-- K+ rho- Amplitudes (Trees + Penguins) MatKrho = EvtComplex( calpha, -salpha ) * EvtComplex( 0.130, 0. ) + EvtComplex( cbeta, sbeta ) * EvtComplex( 0.160, 0. ); // B0bar -->-- K*+ pi- Amplitudes (Trees + Penguins) NatKstarp = EvtComplex( 0., 0. ); // B0bar -->-- K*0 pi0 Amplitudes (Trees + Penguins) NatKstar0 = EvtComplex( 0., 0. ); // B0bar -->-- K+ rho- Amplitudes (Trees + Penguins) NatKrho = EvtComplex( 0., 0. ); - } void EvtBTo3hCP::Evt3pi( double alpha, int iset, EvtVector4R& p_pi_plus, EvtVector4R& p_pi_minus, EvtVector4R& p_gamma_1, EvtVector4R& p_gamma_2, double& Real_B0, double& Imag_B0, double& Real_B0bar, double& Imag_B0bar ) { EvtVector4R p_p2; double AB0, AB0bar, Ainter, R1, R2; double factor; int ierr = 0; // Ghm : beta is not needed for this generation - put a default value setConstants( alpha, 0.362 ); if ( iset == 0 ) { p_pi_plus.set( M_pip, 0, 0, 0 ); p_p2.set( M_pi0, 0, 0, 0 ); p_pi_minus.set( M_pim, 0, 0, 0 ); do { firstStep( p_pi_plus, p_p2, p_pi_minus, 1 ); ierr = compute3pi( p_pi_plus, p_p2, p_pi_minus, Real_B0, Imag_B0, Real_B0bar, Imag_B0bar, iset ); } while ( ierr != 0 ); } else if ( iset < 0 ) { p_p2 = p_gamma_1 + p_gamma_2; ierr = compute3pi( p_pi_plus, p_p2, p_pi_minus, Real_B0, Imag_B0, Real_B0bar, Imag_B0bar, iset ); if ( ierr != 0 ) { std::cout << "Provided kinematics is not physical\n"; std::cout << "Program will stop\n"; exit( 1 ); } } else // iset > 0 { factor_max = 0; int endLoop = iset; for ( int i = 0; i < endLoop; ++i ) { p_pi_plus.set( M_pip, 0, 0, 0 ); p_p2.set( M_pi0, 0, 0, 0 ); p_pi_minus.set( M_pim, 0, 0, 0 ); firstStep( p_pi_plus, p_p2, p_pi_minus, 1 ); ierr = compute3pi( p_pi_plus, p_p2, p_pi_minus, Real_B0, Imag_B0, Real_B0bar, Imag_B0bar, iset ); if ( ierr != 0 ) { continue; } AB0 = square( Real_B0 ) + square( Imag_B0 ); AB0bar = square( Real_B0bar ) + square( Imag_B0bar ); Ainter = Real_B0 * Imag_B0bar - Imag_B0 * Real_B0bar; R1 = ( AB0 - AB0bar ) / ( AB0 + AB0bar ); R2 = ( 2.0 * Ainter ) / ( AB0 + AB0bar ); factor = ( 1.0 + sqrt( square( R1 ) + square( R2 ) ) ) * ( AB0 + AB0bar ) / 2.0; if ( factor > factor_max ) factor_max = factor; } factor_max = 1.0 / std::sqrt( factor_max ); } Real_B0 *= factor_max; Imag_B0 *= factor_max; Real_B0bar *= factor_max; Imag_B0bar *= factor_max; if ( iset < 0 ) { return; } rotation( p_pi_plus, 1 ); rotation( p_p2, 0 ); rotation( p_pi_minus, 0 ); gammaGamma( p_p2, p_gamma_1, p_gamma_2 ); } void EvtBTo3hCP::Evt3piMPP( double alpha, int iset, EvtVector4R& p_p1, EvtVector4R& p_p2, EvtVector4R& p_p3, double& Real_B0, double& Imag_B0, double& Real_B0bar, double& Imag_B0bar ) { double ABp, ABm; int ierr = 0; // Ghm : beta is not needed for this generation - put a default value setConstants( alpha, 0.362 ); if ( iset == 0 ) { p_p1.set( M_pim, 0, 0, 0 ); p_p2.set( M_pip, 0, 0, 0 ); p_p3.set( M_pip, 0, 0, 0 ); do { firstStep( p_p1, p_p2, p_p3, 2 ); ierr = compute3piMPP( p_p1, p_p2, p_p3, Real_B0, Imag_B0, Real_B0bar, Imag_B0bar, iset ); } while ( ierr != 0 ); } else if ( iset < 0 ) { ierr = compute3piMPP( p_p1, p_p2, p_p3, Real_B0, Imag_B0, Real_B0bar, Imag_B0bar, iset ); if ( ierr != 0 ) { std::cout << "Provided kinematics is not physical\n"; std::cout << "Program will stop\n"; exit( 1 ); } } else // iset > 0 { factor_max = 0; int endLoop = iset; for ( int i = 0; i < endLoop; ++i ) { p_p1.set( M_pim, 0, 0, 0 ); p_p2.set( M_pip, 0, 0, 0 ); p_p3.set( M_pip, 0, 0, 0 ); firstStep( p_p1, p_p2, p_p3, 2 ); ierr = compute3piMPP( p_p1, p_p2, p_p3, Real_B0, Imag_B0, Real_B0bar, Imag_B0bar, iset ); if ( ierr != 0 ) { continue; } ABp = square( Real_B0 ) + square( Imag_B0 ); ABm = square( Real_B0bar ) + square( Imag_B0bar ); if ( ABp > factor_max ) factor_max = ABp; if ( ABm > factor_max ) factor_max = ABm; } factor_max = 1.0 / std::sqrt( factor_max ); } Real_B0 *= factor_max; Imag_B0 *= factor_max; Real_B0bar *= factor_max; Imag_B0bar *= factor_max; if ( iset < 0 ) { return; } rotation( p_p1, 1 ); rotation( p_p2, 0 ); rotation( p_p3, 0 ); } void EvtBTo3hCP::Evt3piP00( double alpha, int iset, EvtVector4R& p_p1, EvtVector4R& p_p1_gamma1, EvtVector4R& p_p1_gamma2, EvtVector4R& p_p2_gamma1, EvtVector4R& p_p2_gamma2, double& Real_B0, double& Imag_B0, double& Real_B0bar, double& Imag_B0bar ) { double ABp, ABm; EvtVector4R p_p2, p_p3; int ierr = 0; // Ghm : beta is not needed for this generation - put a default value setConstants( alpha, 0.362 ); if ( iset == 0 ) { p_p1.set( M_pip, 0, 0, 0 ); p_p2.set( M_pi0, 0, 0, 0 ); p_p3.set( M_pi0, 0, 0, 0 ); do { firstStep( p_p1, p_p2, p_p3, 3 ); ierr = compute3piP00( p_p1, p_p2, p_p3, Real_B0, Imag_B0, Real_B0bar, Imag_B0bar, iset ); } while ( ierr != 0 ); } else if ( iset < 0 ) { p_p2 = p_p1_gamma1 + p_p1_gamma2; p_p3 = p_p2_gamma1 + p_p2_gamma2; ierr = compute3piP00( p_p1, p_p2, p_p3, Real_B0, Imag_B0, Real_B0bar, Imag_B0bar, iset ); if ( ierr != 0 ) { std::cout << "Provided kinematics is not physical\n"; std::cout << "Program will stop\n"; exit( 1 ); } } else // iset > 0 { factor_max = 0; int endLoop = iset; for ( int i = 0; i < endLoop; ++i ) { p_p1.set( M_pip, 0, 0, 0 ); p_p2.set( M_pi0, 0, 0, 0 ); p_p3.set( M_pi0, 0, 0, 0 ); firstStep( p_p1, p_p2, p_p3, 3 ); ierr = compute3piP00( p_p1, p_p2, p_p3, Real_B0, Imag_B0, Real_B0bar, Imag_B0bar, iset ); if ( ierr != 0 ) { continue; } ABp = square( Real_B0 ) + square( Imag_B0 ); ABm = square( Real_B0bar ) + square( Imag_B0bar ); if ( ABp > factor_max ) factor_max = ABp; if ( ABm > factor_max ) factor_max = ABm; } factor_max = 1.0 / std::sqrt( factor_max ); } Real_B0 *= factor_max; Imag_B0 *= factor_max; Real_B0bar *= factor_max; Imag_B0bar *= factor_max; if ( iset < 0 ) { return; } rotation( p_p1, 1 ); rotation( p_p2, 0 ); rotation( p_p3, 0 ); gammaGamma( p_p2, p_p1_gamma1, p_p1_gamma2 ); gammaGamma( p_p3, p_p2_gamma1, p_p2_gamma2 ); } void EvtBTo3hCP::EvtKpipi( double alpha, double beta, int iset, EvtVector4R& p_K_plus, EvtVector4R& p_pi_minus, EvtVector4R& p_gamma_1, EvtVector4R& p_gamma_2, double& Real_B0, double& Imag_B0, double& Real_B0bar, double& Imag_B0bar ) { EvtVector4R p_p3; double ABp, ABm; int ierr = 0; setConstants( alpha, beta ); if ( iset == 0 ) { p_K_plus.set( M_Kp, 0, 0, 0 ); p_pi_minus.set( M_pim, 0, 0, 0 ); p_p3.set( M_pi0, 0, 0, 0 ); do { firstStep( p_K_plus, p_pi_minus, p_p3, 0 ); ierr = computeKpipi( p_K_plus, p_pi_minus, p_p3, Real_B0, Imag_B0, Real_B0bar, Imag_B0bar, iset ); } while ( ierr != 0 ); } else if ( iset < 0 ) { p_p3 = p_gamma_1 + p_gamma_2; ierr = computeKpipi( p_K_plus, p_pi_minus, p_p3, Real_B0, Imag_B0, Real_B0bar, Imag_B0bar, iset ); if ( ierr != 0 ) { std::cout << "Provided kinematics is not physical\n"; std::cout << "Program will stop\n"; exit( 1 ); } } else // iset > 0 { factor_max = 0; int endLoop = iset; for ( int i = 0; i < endLoop; ++i ) { p_K_plus.set( M_Kp, 0, 0, 0 ); p_pi_minus.set( M_pim, 0, 0, 0 ); p_p3.set( M_pi0, 0, 0, 0 ); firstStep( p_K_plus, p_pi_minus, p_p3, 0 ); ierr = computeKpipi( p_K_plus, p_pi_minus, p_p3, Real_B0, Imag_B0, Real_B0bar, Imag_B0bar, iset ); if ( ierr != 0 ) { continue; } ABp = square( Real_B0 ) + square( Imag_B0 ); ABm = square( Real_B0bar ) + square( Imag_B0bar ); if ( ABp > factor_max ) { factor_max = ABp; } if ( ABm > factor_max ) { factor_max = ABm; } } factor_max = 1.0 / std::sqrt( factor_max ); } Real_B0 *= factor_max; Imag_B0 *= factor_max; Real_B0bar *= factor_max; Imag_B0bar *= factor_max; if ( iset < 0 ) { return; } rotation( p_K_plus, 1 ); rotation( p_pi_minus, 0 ); rotation( p_p3, 0 ); gammaGamma( p_p3, p_gamma_1, p_gamma_2 ); } void EvtBTo3hCP::firstStep( EvtVector4R& p1, EvtVector4R& p2, EvtVector4R& p3, int mode ) { const double m1sq = p1.mass2(); const double m2sq = p2.mass2(); const double m3sq = p3.mass2(); double min_m12, min_m13, min_m23; double max_m12 = square( M_B ); double max_m13 = square( M_B ); double max_m23 = square( M_B ); if ( mode == 0 ) { min_m12 = m1sq + m2sq + 2 * sqrt( m1sq * m2sq ); min_m13 = m1sq + m3sq + 2 * sqrt( m1sq * m3sq ); min_m23 = m2sq + m3sq + 2 * sqrt( m2sq * m3sq ); } else { min_m12 = m1sq + m2sq; min_m13 = m1sq + m3sq; min_m23 = m2sq + m3sq; } bool eventOK; double m13, m12, m23; double E1; double E2; double E3; double p1mom; double p2mom; double p3mom; double cost13; double cost12; double cost23; eventOK = false; do { switch ( mode ) { case 0: generateSqMasses_Kpipi( m12, m13, m23, MC2, m1sq, m2sq, m3sq ); break; case 1: generateSqMasses_3pi( m12, m13, m23, MB2, m1sq, m2sq, m3sq ); break; case 2: generateSqMasses_3piMPP( m12, m13, m23, MB2, m1sq, m2sq, m3sq ); break; case 3: generateSqMasses_3piP00( m12, m13, m23, MA2, m1sq, m2sq, m3sq ); break; default: break; } // Check whether event is physical if ( ( m23 < min_m23 ) || ( m23 > max_m23 ) ) continue; if ( ( m13 < min_m13 ) || ( m13 > max_m13 ) ) continue; if ( ( m12 < min_m12 ) || ( m12 > max_m12 ) ) continue; // Now check the cosines of the angles E1 = ( square( M_B ) + m1sq - m23 ) / ( 2. * M_B ); E2 = ( square( M_B ) + m2sq - m13 ) / ( 2. * M_B ); E3 = ( square( M_B ) + m3sq - m12 ) / ( 2. * M_B ); p1mom = square( E1 ) - m1sq; p2mom = square( E2 ) - m2sq; p3mom = square( E3 ) - m3sq; if ( p1mom < 0 || p2mom < 0 || p3mom < 0 ) { // std::cout<<"Momenta magnitude negative\n"; continue; } p1mom = sqrt( p1mom ); p2mom = sqrt( p2mom ); p3mom = sqrt( p3mom ); cost13 = ( 2. * E1 * E3 + m1sq + m3sq - m13 ) / ( 2. * p1mom * p3mom ); cost12 = ( 2. * E1 * E2 + m1sq + m2sq - m12 ) / ( 2. * p1mom * p2mom ); cost23 = ( 2. * E2 * E3 + m2sq + m3sq - m23 ) / ( 2. * p2mom * p3mom ); if ( cost13 < -1. || cost13 > 1. || cost12 < -1. || cost12 > 1. || cost23 < -1. || cost23 > 1. ) { continue; } eventOK = true; } while ( eventOK == false ); // Now is time to fill 4-vectors p3.set( E3, 0, 0, p3mom ); p1.set( E1, p1mom * sqrt( 1 - square( cost13 ) ), 0, p1mom * cost13 ); p2.set( 0, E2 ); for ( int i = 1; i < 4; ++i ) { p2.set( i, -p1.get( i ) - p3.get( i ) ); } if ( p1.get( 0 ) < p1.d3mag() ) { std::cout << "Unphysical p1 generated: " << p1 << std::endl; } if ( p2.get( 0 ) < p2.d3mag() ) { std::cout << "Unphysical p2 generated: " << p2 << std::endl; } if ( p3.get( 0 ) < p3.d3mag() ) { std::cout << "Unphysical p3 generated: " << p3 << std::endl; } double testMB2 = MB2; switch ( mode ) { case 0: testMB2 = MC2; break; case 1: case 2: testMB2 = MB2; break; case 3: testMB2 = MA2; break; } if ( fabs( m12 + m13 + m23 - testMB2 ) > 1e-4 ) { std::cout << "Unphysical event generated: " << m12 << " " << m13 << " " << m23 << std::endl; } } void EvtBTo3hCP::generateSqMasses_Kpipi( double& m12, double& m13, double& m23, double MB2, double m1sq, double m2sq, double m3sq ) { /* C There is two ways of generating the events: C The first one used a pole-compensation method to generate the C events efficiently taking into account the poles due to the C Breit-Wigners of the rho s. It is activated by setting C Phase_Space to .false. C The second one generates events according to phase space. It is C inneficient but allows the exploration of the full Dalitz plot C in an uniform way. It was found to be usefull fopr some peculiar C applications. It is activated by setting C Phase_space to .true. C Note that in that case, the generation is no longer correct. */ static bool phaseSpace = false; double max_m12 = square( M_B ); double min_m12 = m1sq + m2sq + 2 * sqrt( m1sq * m2sq ); double max_m13 = square( M_B ); double min_m13 = m1sq + m3sq + 2 * sqrt( m1sq * m3sq ); double max_m23 = square( M_B ); double min_m23 = m2sq + m3sq + 2 * sqrt( m2sq * m3sq ); double z = 3. * EvtRandom::Flat(); if ( z < 1. ) // K*+ { if ( phaseSpace ) { m13 = EvtRandom::Flat() * ( max_m13 - min_m13 ) + min_m13; } else { double y = EvtRandom::Flat() * pi - pi / 2; double x = std::tan( y ); double mass = x * Gam_Kstarp / 2. + Mass_Kstarp; m13 = square( mass ); } m12 = EvtRandom::Flat() * ( max_m12 - min_m12 ) + min_m12; m23 = MB2 - m12 - m13; } else if ( z < 2. ) // K*0 { if ( phaseSpace ) { m12 = EvtRandom::Flat() * ( max_m12 - min_m12 ) + min_m12; } else { double y = EvtRandom::Flat() * pi - pi / 2; double x = std::tan( y ); double mass = x * Gam_Kstar0 / 2. + Mass_Kstar0; m12 = square( mass ); } m13 = EvtRandom::Flat() * ( max_m13 - min_m13 ) + min_m13; m23 = MB2 - m12 - m13; } else // rho- { if ( phaseSpace ) { m23 = EvtRandom::Flat() * ( max_m23 - min_m23 ) + min_m23; } else { double y = EvtRandom::Flat() * pi - pi / 2; double x = std::tan( y ); double mass = x * Gam_rho / 2. + Mass_rho; m23 = square( mass ); } m13 = EvtRandom::Flat() * ( max_m13 - min_m13 ) + min_m13; m12 = MB2 - m23 - m13; } } void EvtBTo3hCP::generateSqMasses_3pi( double& m12, double& m13, double& m23, double MB2, double m1sq, double m2sq, double m3sq ) { /* C There is two ways of generating the events: C The first one used a pole-compensation method to generate the C events efficiently taking into account the poles due to the C Breit-Wigners of the rho s. It is activated by setting C Phase_Space to .false. C The second one generates events according to phase space. It is C inneficient but allows the exploration of the full Dalitz plot C in an uniform way. It was found to be usefull fopr some peculiar C applications. It is activated by setting C Phase_space to .true. C Note that in that case, the generation is no longer correct. */ static bool phaseSpace = false; double max_m12 = square( M_B ); double min_m12 = m1sq + m2sq; double max_m13 = square( M_B ); double min_m13 = m1sq + m3sq; double max_m23 = square( M_B ); double min_m23 = m2sq + m3sq; double mass = 0; if ( !phaseSpace ) { double y = EvtRandom::Flat() * pi - pi / 2; double x = std::tan( y ); mass = x * Gam_rho / 2. + Mass_rho; } double z = 3. * EvtRandom::Flat(); if ( z < 1. ) { if ( phaseSpace ) { m12 = EvtRandom::Flat() * ( max_m12 - min_m12 ) + min_m12; } else { m12 = square( mass ); } m13 = EvtRandom::Flat() * ( max_m13 - min_m13 ) + min_m13; m23 = MB2 - m12 - m13; } else if ( z < 2. ) { if ( phaseSpace ) { m13 = EvtRandom::Flat() * ( max_m13 - min_m13 ) + min_m13; } else { m13 = square( mass ); } m12 = EvtRandom::Flat() * ( max_m12 - min_m12 ) + min_m12; m23 = MB2 - m12 - m13; } else { if ( phaseSpace ) { m23 = EvtRandom::Flat() * ( max_m23 - min_m23 ) + min_m23; } else { m23 = square( mass ); } m12 = EvtRandom::Flat() * ( max_m12 - min_m12 ) + min_m12; m13 = MB2 - m12 - m23; } } void EvtBTo3hCP::generateSqMasses_3piMPP( double& m12, double& m13, double& m23, double MB2, double m1sq, double m2sq, double m3sq ) { /* C There is two ways of generating the events: C The first one used a pole-compensation method to generate the C events efficiently taking into account the poles due to the C Breit-Wigners of the rho s. It is activated by setting C Phase_Space to .false. C The second one generates events according to phase space. It is C inneficient but allows the exploration of the full Dalitz plot C in an uniform way. It was found to be usefull fopr some peculiar C applications. It is activated by setting C Phase_space to .true. C Note that in that case, the generation is no longer correct. */ static bool phaseSpace = false; double max_m12 = square( M_B ); double min_m12 = m1sq + m2sq; double max_m13 = square( M_B ); double min_m13 = m1sq + m3sq; double mass = 0; if ( !phaseSpace ) { double y = EvtRandom::Flat() * pi - pi / 2; double x = std::tan( y ); mass = x * Gam_rho / 2. + Mass_rho; } double z = EvtRandom::Flat(); if ( z < 0.5 ) { if ( phaseSpace ) { m12 = EvtRandom::Flat() * ( max_m12 - min_m12 ) + min_m12; } else { m12 = square( mass ); } m13 = EvtRandom::Flat() * ( max_m13 - min_m13 ) + min_m13; m23 = MB2 - m12 - m13; } else { if ( phaseSpace ) { m13 = EvtRandom::Flat() * ( max_m13 - min_m13 ) + min_m13; } else { m13 = square( mass ); } m12 = EvtRandom::Flat() * ( max_m12 - min_m12 ) + min_m12; m23 = MB2 - m12 - m13; } } void EvtBTo3hCP::generateSqMasses_3piP00( double& m12, double& m13, double& m23, double MB2, double m1sq, double m2sq, double m3sq ) { /* C There is two ways of generating the events: C The first one used a pole-compensation method to generate the C events efficiently taking into account the poles due to the C Breit-Wigners of the rho s. It is activated by setting C Phase_Space to .false. C The second one generates events according to phase space. It is C inneficient but allows the exploration of the full Dalitz plot C in an uniform way. It was found to be usefull fopr some peculiar C applications. It is activated by setting C Phase_space to .true. C Note that in that case, the generation is no longer correct. */ static bool phaseSpace = false; double max_m12 = square( M_B ); double min_m12 = m1sq + m2sq; double max_m13 = square( M_B ); double min_m13 = m1sq + m3sq; double mass = 0; if ( !phaseSpace ) { double y = EvtRandom::Flat() * pi - pi / 2; double x = std::tan( y ); mass = x * Gam_rho / 2. + Mass_rho; } double z = EvtRandom::Flat(); if ( z < 0.5 ) { if ( phaseSpace ) { m12 = EvtRandom::Flat() * ( max_m12 - min_m12 ) + min_m12; } else { m12 = square( mass ); } m13 = EvtRandom::Flat() * ( max_m13 - min_m13 ) + min_m13; m23 = MB2 - m12 - m13; } else { if ( phaseSpace ) { m13 = EvtRandom::Flat() * ( max_m13 - min_m13 ) + min_m13; } else { m13 = square( mass ); } m12 = EvtRandom::Flat() * ( max_m12 - min_m12 ) + min_m12; m23 = MB2 - m12 - m13; } } int EvtBTo3hCP::compute3pi( EvtVector4R& p1, EvtVector4R& p2, EvtVector4R& p3, double& real_B0, double& imag_B0, double& real_B0bar, double& imag_B0bar, int iset ) { int ierr = 0; double m12 = ( p1 + p2 ).mass(); double m13 = ( p1 + p3 ).mass(); double m23 = ( p2 + p3 ).mass(); double W12 = 1. / ( ( square( Mass_rho - m12 ) + square( Gam_rho / 2. ) ) * m12 ); double W13 = 1. / ( ( square( Mass_rho - m13 ) + square( Gam_rho / 2. ) ) * m13 ); double W23 = 1. / ( ( square( Mass_rho - m23 ) + square( Gam_rho / 2. ) ) * m23 ); double Wtot = 1.; if ( iset >= 0 ) { Wtot = 1. / sqrt( W12 + W13 + W23 ); } EvtComplex Mat_rhop = BreitWigner( p1, p2, p3, ierr ); EvtComplex Mat_rhom = BreitWigner( p2, p3, p1, ierr ); EvtComplex Mat_rho0 = BreitWigner( p1, p3, p2, ierr ); EvtComplex Mat_1 = Mat_S3 * Mat_rhop; EvtComplex Mat_2 = Mat_S4 * Mat_rhom; EvtComplex Mat_3 = Mat_S5 * Mat_rho0 * 0.5; EvtComplex MatBp = ( Mat_1 + Mat_2 + Mat_3 ) * Wtot; Mat_1 = Nat_S3 * Mat_rhom; Mat_2 = Nat_S4 * Mat_rhop; Mat_3 = Nat_S5 * Mat_rho0 * 0.5; EvtComplex MatBm = ( Mat_1 + Mat_2 + Mat_3 ) * Wtot; real_B0 = real( MatBp ); imag_B0 = imag( MatBp ); real_B0bar = real( MatBm ); imag_B0bar = imag( MatBm ); return ierr; } int EvtBTo3hCP::compute3piMPP( EvtVector4R& p1, EvtVector4R& p2, EvtVector4R& p3, double& real_B0, double& imag_B0, double& real_B0bar, double& imag_B0bar, int iset ) { int ierr = 0; const double ASHQ = sqrt( 2. ); double m12 = ( p1 + p2 ).mass(); double m13 = ( p1 + p3 ).mass(); double W12 = 1. / ( ( square( Mass_rho - m12 ) + square( Gam_rho / 2. ) ) * m12 ); double W13 = 1. / ( ( square( Mass_rho - m13 ) + square( Gam_rho / 2. ) ) * m13 ); double Wtot = 1.; if ( iset >= 0 ) { Wtot = 1. / sqrt( W12 + W13 ); } EvtComplex Mat_rhop = BreitWigner( p1, p2, p3, ierr ) + BreitWigner( p1, p3, p2, ierr ); EvtComplex MatBp = Mat_S2 * Mat_rhop * Wtot * ASHQ; EvtComplex MatBm = Nat_S2 * Mat_rhop * Wtot * ASHQ; real_B0 = real( MatBp ); imag_B0 = imag( MatBp ); real_B0bar = real( MatBm ); imag_B0bar = imag( MatBm ); return ierr; } int EvtBTo3hCP::compute3piP00( EvtVector4R& p1, EvtVector4R& p2, EvtVector4R& p3, double& real_B0, double& imag_B0, double& real_B0bar, double& imag_B0bar, int iset ) { int ierr = 0; const double ASHQ = sqrt( 2. ); double m12 = ( p1 + p2 ).mass(); double m13 = ( p1 + p3 ).mass(); double W12 = 1. / ( ( square( Mass_rho - m12 ) + square( Gam_rho / 2. ) ) * m12 ); double W13 = 1. / ( ( square( Mass_rho - m13 ) + square( Gam_rho / 2. ) ) * m13 ); double Wtot = 1.; if ( iset >= 0 ) { Wtot = 1. / sqrt( W12 + W13 ); } EvtComplex Mat_rhop = BreitWigner( p1, p2, p3, ierr ) + BreitWigner( p1, p3, p2, ierr ); EvtComplex MatBp = Mat_S1 * Mat_rhop * Wtot * ASHQ; EvtComplex MatBm = Nat_S1 * Mat_rhop * Wtot * ASHQ; real_B0 = real( MatBp ); imag_B0 = imag( MatBp ); real_B0bar = real( MatBm ); imag_B0bar = imag( MatBm ); return ierr; } int EvtBTo3hCP::computeKpipi( EvtVector4R& p1, EvtVector4R& p2, EvtVector4R& p3, double& real_B0, double& imag_B0, double& real_B0bar, double& imag_B0bar, int iset ) { int ierr = 0; double m12 = ( p1 + p2 ).mass(); double m13 = ( p1 + p3 ).mass(); double m23 = ( p2 + p3 ).mass(); double W12 = 1. / ( ( square( Mass_Kstar0 - m12 ) + square( Gam_Kstar0 / 2. ) ) * m12 ); double W13 = 1. / ( ( square( Mass_Kstarp - m13 ) + square( Gam_Kstarp / 2. ) ) * m13 ); double W23 = 1. / ( ( square( Mass_rho - m23 ) + square( Gam_rho / 2. ) ) * m23 ); double Wtot = 1.; if ( iset >= 0 ) { Wtot = 1. / sqrt( W12 + W13 + W23 ); } EvtComplex BW13 = BreitWigner( p1, p3, p2, ierr, Mass_Kstarp, Gam_Kstarp ); if ( ierr != 0 ) return ierr; EvtComplex BW12 = BreitWigner( p1, p2, p3, ierr, Mass_Kstar0, Gam_Kstar0 ); if ( ierr != 0 ) return ierr; /* If the rho is to be treated on the same footing as K* ==> use the line below EvtComplex BW23=BreitWigner(p2, p3, p1, ierr, Mass_Rho, Gam_Rho); */ EvtComplex BW23 = BreitWigner( p2, p3, p1, ierr ); if ( ierr != 0 ) return ierr; // Build up amplitudes EvtComplex MatB0 = MatKstarp * BW13 + MatKstar0 * BW12 + MatKrho * BW23; EvtComplex MatB0bar = NatKstarp * BW13 + NatKstar0 * BW12 + NatKrho * BW23; real_B0 = real( MatB0 ) * Wtot; imag_B0 = imag( MatB0 ) * Wtot; real_B0bar = real( MatB0bar ) * Wtot; imag_B0bar = imag( MatB0bar ) * Wtot; return ierr; } void EvtBTo3hCP::rotation( EvtVector4R& p, int newRot ) { if ( newRot ) { double phi2 = EvtRandom::Flat() * 2. * pi; double phi3 = EvtRandom::Flat() * 2. * pi; double c1 = 2. * EvtRandom::Flat() - 1.; double c2 = cos( phi2 ); double c3 = cos( phi3 ); double s1 = sqrt( 1. - square( c1 ) ); double s2 = sin( phi2 ); double s3 = sin( phi3 ); rotMatrix[0][0] = c1; rotMatrix[0][1] = s1 * c3; rotMatrix[0][2] = s1 * s3; rotMatrix[1][0] = -s1 * c2; rotMatrix[1][1] = c1 * c2 * c3 - s2 * s3; rotMatrix[1][2] = c1 * c2 * s3 + s2 * c3; rotMatrix[2][0] = s1 * s2; rotMatrix[2][1] = -c1 * s2 * c3 - c2 * s3; rotMatrix[2][2] = -c1 * s2 * s3 + c2 * c3; } double mom[3]; for ( int i = 1; i < 4; ++i ) { mom[i - 1] = p.get( i ); p.set( i, 0 ); } for ( int i = 0; i < 3; ++i ) { for ( int j = 0; j < 3; ++j ) { p.set( i + 1, p.get( i + 1 ) + rotMatrix[i][j] * mom[j] ); } } } void EvtBTo3hCP::gammaGamma( EvtVector4R& p, EvtVector4R& pgamma1, EvtVector4R& pgamma2 ) { double EGammaCmsPi0 = sqrt( p.mass2() ) / 2.; double cosThetaRot = EvtRandom::Flat() * 2. - 1.; double sinThetaRot = sqrt( 1. - square( cosThetaRot ) ); double PhiRot = EvtRandom::Flat() * 2. * pi; pgamma1.set( 1, EGammaCmsPi0 * sinThetaRot * cos( PhiRot ) ); pgamma1.set( 2, EGammaCmsPi0 * sinThetaRot * sin( PhiRot ) ); pgamma1.set( 3, EGammaCmsPi0 * cosThetaRot ); pgamma1.set( 0, EGammaCmsPi0 ); for ( int i = 1; i < 4; ++i ) { pgamma2.set( i, -pgamma1.get( i ) ); } pgamma2.set( 0, pgamma1.get( 0 ) ); pgamma1.applyBoostTo( p ); pgamma2.applyBoostTo( p ); } EvtComplex EvtBTo3hCP::BreitWigner( EvtVector4R& p1, EvtVector4R& p2, EvtVector4R& p3, int& ierr, double Mass, double Width ) { bool pipiMode = true; if ( Mass > 1e-5 ) { pipiMode = false; } bool relatBW = true; bool aleph = true; EvtComplex result( 0, 0 ); ierr = 0; double m12 = ( p1 + p2 ).mass(); double e12 = ( p1 + p2 ).get( 0 ); double argu = 1. - square( m12 ) / square( e12 ); double beta = 0; if ( argu > 0 ) { beta = sqrt( argu ); } else { std::cout << "Abnormal beta ! Argu = " << argu << std::endl; argu = 0; } double gamma = e12 / m12; double m13sq = ( p1 + p3 ).mass2(); double costet = ( 2. * p1.get( 0 ) * p3.get( 0 ) - m13sq + p1.mass2() + p3.mass2() ) / ( 2. * p1.d3mag() * p3.d3mag() ); double p1z = p1.d3mag() * costet; double p1zcms12 = gamma * ( p1z + beta * p1.get( 0 ) ); double e1cms12 = gamma * ( p1.get( 0 ) + beta * p1z ); double p1cms12 = sqrt( square( e1cms12 ) - p1.mass2() ); double coscms = p1zcms12 / p1cms12; if ( pipiMode ) { if ( aleph ) { double m12_2 = square( m12 ); result = coscms * EvtCRhoF_W( m12_2 ); } else { double factor = 2 * ( square( Mass_rho - m12 ) + square( 0.5 * Gam_rho ) ); factor = coscms * Gam_rho / factor; double numReal = ( Mass_rho - m12 ) * factor; double numImg = 0.5 * Gam_rho * factor; result = EvtComplex( numReal, numImg ); } } else { if ( relatBW ) { double Am2Min = p1.mass2() + p2.mass2() + 2 * p1.mass() * p2.mass(); result = coscms * EvtRBW( square( m12 ), square( Mass ), Width, Am2Min ); } else { double factor = 2 * ( square( Mass - m12 ) + square( 0.5 * Width ) ); factor = coscms * Width / factor; double numReal = ( Mass - m12 ) * factor; double numImg = 0.5 * Width * factor; result = EvtComplex( numReal, numImg ); } } return result; } EvtComplex EvtBTo3hCP::EvtCRhoF_W( double s ) { const bool kuhn_santa = true; // type of Breit-Wigner formula // double lambda = 1.0; double AmRho, GamRho, AmRhoP, GamRhoP, beta, AmRhoPP, GamRhoPP, gamma; if ( kuhn_santa ) { //...rho(770) AmRho = 0.7734; GamRho = 0.1477; //...rho(1450) AmRhoP = 1.465; GamRhoP = 0.696; beta = -0.229; //...rho(1700) AmRhoPP = 1.760; GamRhoPP = 0.215; gamma = 0.075; } else { //...rho(770) AmRho = 0.7757; GamRho = 0.1508; //...rho(1450) AmRhoP = 1.448; GamRhoP = 0.503; beta = -0.161; //...rho(1700) AmRhoPP = 1.757; GamRhoPP = 0.237; gamma = 0.076; } EvtComplex result( 0, 0 ); if ( kuhn_santa ) { result = ( EvtcBW_KS( s, square( AmRho ), GamRho ) + //!...BW-rho( 770) EvtcBW_KS( s, square( AmRhoP ), GamRhoP ) * ( beta ) + //!...BW-rho(1450) EvtcBW_KS( s, square( AmRhoPP ), GamRhoPP ) * ( gamma ) ) / //!...BW-rho(1700) ( 1. + beta + gamma ); } else { result = ( EvtcBW_GS( s, square( AmRho ), GamRho ) + EvtcBW_GS( s, square( AmRhoP ), GamRhoP ) * ( beta ) + EvtcBW_GS( s, square( AmRhoPP ), GamRhoPP ) * ( gamma ) ) / ( 1. + beta + gamma ); } return result; } EvtComplex EvtBTo3hCP::EvtRBW( double s, double Am2, double Gam, double Am2Min ) { EvtComplex result( 0, 0 ); if ( s < Am2Min ) { return result; } double tmp = ( ( s - Am2Min ) / ( Am2 - Am2Min ) ); double G = Gam * ( Am2 / s ) * sqrt( square( tmp ) * tmp ); double D = square( Am2 - s ) + s * square( G ); double X = Am2 * ( Am2 - s ); double Y = Am2 * sqrt( s ) * G; result = EvtComplex( X / D, Y / D ); return result; } EvtComplex EvtBTo3hCP::EvtcBW_KS( double s, double Am2, double Gam ) { EvtComplex result( 0, 0 ); const double AmPi2 = square( 0.13956995 ); return EvtRBW( s, Am2, Gam, 4. * AmPi2 ); } EvtComplex EvtBTo3hCP::EvtcBW_GS( double s, double Am2, double Gam ) { EvtComplex result( 0, 0 ); const double AmPi2 = square( 0.13956995 ); if ( s < 4. * AmPi2 ) { return result; } double tmp = ( ( s - 4. * AmPi2 ) / ( Am2 - 4. * AmPi2 ) ); double G = Gam * ( Am2 / s ) * sqrt( square( tmp ) * tmp ); double z1 = Am2 - s + Evtfs( s, Am2, Gam ); double z2 = sqrt( s ) * G; double z3 = Am2 + d( Am2 ) * Gam * sqrt( Am2 ); double X = z3 * z1; double Y = z3 * z2; double N = square( z1 ) + square( z2 ); result = EvtComplex( X / N, Y / N ); return result; } double EvtBTo3hCP::d( double AmRho2 ) { const double lpi = 3.141593; const double AmPi = 0.13956995; const double AmPi2 = square( AmPi ); double AmRho = sqrt( AmRho2 ); double k_AmRho2 = k( AmRho2 ); double result = 3. / lpi * AmPi2 / square( k_AmRho2 ) * log( ( AmRho + 2. * k_AmRho2 ) / ( 2. * AmPi ) ) + AmRho / ( 2. * pi * k_AmRho2 ) - AmPi2 * AmRho / ( pi * ( square( k_AmRho2 ) * k_AmRho2 ) ); return result; } double EvtBTo3hCP::k( double s ) { const double AmPi2 = square( 0.13956995 ); return 0.5 * sqrt( s - 4. * AmPi2 ); } double EvtBTo3hCP::Evtfs( double s, double AmRho2, double GamRho ) { double k_s = k( s ); double k_Am2 = k( AmRho2 ); return GamRho * AmRho2 / ( square( k_Am2 ) * k_Am2 ) * ( square( k_s ) * ( h( s ) - h( AmRho2 ) ) + ( AmRho2 - s ) * square( k_Am2 ) * dh_ds( AmRho2 ) ); } double EvtBTo3hCP::h( double s ) { const double pi = 3.141593; const double AmPi = 0.13956995; double sqrts = sqrt( s ); double k_s = k( s ); return 2. / pi * ( k_s / sqrts ) * log( ( sqrts + 2. * k_s ) / ( 2. * AmPi ) ); } double EvtBTo3hCP::dh_ds( double s ) { const double pi = 3.141593; return h( s ) * ( 1. / ( 8. * square( k( s ) ) ) - 1. / ( 2 * s ) ) + 1. / ( 2. * pi * s ); } diff --git a/src/EvtGenModels/EvtBsMuMuKK.cpp b/src/EvtGenModels/EvtBsMuMuKK.cpp index 3c793ea..e4747fe 100644 --- a/src/EvtGenModels/EvtBsMuMuKK.cpp +++ b/src/EvtGenModels/EvtBsMuMuKK.cpp @@ -1,682 +1,682 @@ /*********************************************************************** * 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/EvtBsMuMuKK.hh" #include "EvtGenBase/EvtCPUtil.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtVector3R.hh" #include "EvtGenBase/EvtVector4C.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenBase/EvtdFunction.hh" const double pi = EvtConst::pi; const EvtComplex I = EvtComplex( 0.0, 1.0 ); const double sq2 = sqrt( 2.0 ); std::string EvtBsMuMuKK::getName() { return "BS_MUMUKK"; } EvtDecayBase* EvtBsMuMuKK::clone() { return new EvtBsMuMuKK; } void EvtBsMuMuKK::init() { // DecFile parameters checkNArg( 37 ); // Non-resonant S wave f_S_NR = getArg( 0 ); delta_S_NR = getArg( 1 ); phis_S_NR = getArg( 2 ); lambda_S_NR_abs = getArg( 3 ); // f0 (S wave) f_f0 = getArg( 4 ); delta_f0 = getArg( 5 ); phis_f0 = getArg( 6 ); lambda_f0_abs = getArg( 7 ); // phi (P wave) f_phi = getArg( 8 ); f_phi_0 = getArg( 9 ); delta_phi_0 = getArg( 10 ); phis_phi_0 = getArg( 11 ); lambda_phi_0_abs = getArg( 12 ); f_phi_perp = getArg( 13 ); delta_phi_perp = pi - getArg( 14 ); phis_phi_perp = getArg( 15 ); lambda_phi_perp_abs = getArg( 16 ); delta_phi_par = pi - getArg( 17 ); phis_phi_par = getArg( 18 ); lambda_phi_par_abs = getArg( 19 ); // f2' (D wave) f_f2p_0 = getArg( 20 ); delta_f2p_0 = getArg( 21 ); phis_f2p_0 = getArg( 22 ); lambda_f2p_0_abs = getArg( 23 ); f_f2p_perp = getArg( 24 ); delta_f2p_perp = pi - getArg( 25 ); phis_f2p_perp = getArg( 26 ); lambda_f2p_perp_abs = getArg( 27 ); delta_f2p_par = pi - getArg( 28 ); phis_f2p_par = getArg( 29 ); lambda_f2p_par_abs = getArg( 30 ); // Time dependence Gamma = getArg( 31 ); deltaGamma = getArg( 32 ); deltaMs = getArg( 33 ); // mKK window Mf0 = getArg( 34 ); kin_lower_limit = getArg( 35 ); // the minimum is approx 2.03*MKp kin_upper_limit = getArg( 36 ); // PDG masses MBs = EvtPDL::getMass( EvtPDL::getId( "B_s0" ) ); MJpsi = EvtPDL::getMeanMass( EvtPDL::getId( "J/psi" ) ); Mphi = EvtPDL::getMeanMass( EvtPDL::getId( "phi" ) ); Mf2p = EvtPDL::getMeanMass( EvtPDL::getId( "f'_2" ) ); MKp = EvtPDL::getMass( EvtPDL::getId( "K+" ) ); MKm = EvtPDL::getMass( EvtPDL::getId( "K-" ) ); MK0 = EvtPDL::getMass( EvtPDL::getId( "K0" ) ); Mpip = EvtPDL::getMass( EvtPDL::getId( "pi+" ) ); Mpi0 = EvtPDL::getMass( EvtPDL::getId( "pi0" ) ); Mmu = EvtPDL::getMass( EvtPDL::getId( "mu+" ) ); double MBsSq = MBs * MBs; // Amplitudes and other time parameters A_S_NR = sqrt( f_S_NR ); A_f0 = sqrt( f_f0 ); A_phi_0 = sqrt( f_phi_0 * f_phi ); A_phi_perp = sqrt( f_phi_perp * f_phi ); // Use fabs to make sure subtractions are >= 0, since subtracting 0 from 0 can give -0 A_phi_par = sqrt( fabs( f_phi - A_phi_perp * A_phi_perp - A_phi_0 * A_phi_0 ) ); f_f2p = fabs( 1.0 - f_S_NR - f_f0 - f_phi ); A_f2p_0 = sqrt( f_f2p_0 * f_f2p ); A_f2p_perp = sqrt( f_f2p_perp * f_f2p ); A_f2p_par = sqrt( fabs( f_f2p - A_f2p_perp * A_f2p_perp - A_f2p_0 * A_f2p_0 ) ); ctau = 1.0 / Gamma; Gamma0phi = EvtPDL::getWidth( EvtPDL::getId( "phi" ) ); Gamma0f2p = EvtPDL::getWidth( EvtPDL::getId( "f'_2" ) ); kin_middle = 0.5 * ( kin_upper_limit + kin_lower_limit ); int_const_NR = sqrt( Integral( 1.0, 1.0, 0, 1, 1.0, kin_lower_limit, kin_upper_limit, 0 ) ); int_Flatte_f0 = sqrt( Integral( 1.0, Mf0, 0, 1, 1.0, kin_lower_limit, kin_upper_limit, 1 ) ); p30Kp_mid_CMS = sqrt( ( pow( kin_middle, 2 ) - pow( MKp + MKm, 2 ) ) * ( pow( kin_middle, 2 ) - pow( MKp - MKm, 2 ) ) ) / ( 2.0 * kin_middle ); p30Kp_ll_CMS = sqrt( ( pow( kin_lower_limit, 2 ) - pow( MKp + MKm, 2 ) ) * ( pow( kin_lower_limit, 2 ) - pow( MKp - MKm, 2 ) ) ) / ( 2.0 * kin_lower_limit ); p30Kp_phi_CMS = sqrt( ( Mphi * Mphi - pow( MKp + MKm, 2 ) ) * ( Mphi * Mphi - pow( MKp - MKm, 2 ) ) ) / ( 2.0 * Mphi ); p30Kp_f2p_CMS = sqrt( ( Mf2p * Mf2p - pow( MKp + MKm, 2 ) ) * ( Mf2p * Mf2p - pow( MKp - MKm, 2 ) ) ) / ( 2.0 * Mf2p ); p30Jpsi_mid_CMS = sqrt( ( MBsSq - pow( kin_middle + MJpsi, 2 ) ) * ( MBsSq - pow( kin_middle - MJpsi, 2 ) ) ) / ( 2.0 * MBs ); p30Jpsi_ll_CMS = sqrt( ( MBsSq - pow( kin_lower_limit + MJpsi, 2 ) ) * ( MBsSq - pow( kin_lower_limit - MJpsi, 2 ) ) ) / ( 2.0 * MBs ); p30Jpsi_phi_CMS = sqrt( ( MBsSq - pow( Mphi + MJpsi, 2 ) ) * ( MBsSq - pow( Mphi - MJpsi, 2 ) ) ) / ( 2.0 * MBs ); p30Jpsi_f2p_CMS = sqrt( ( MBsSq - pow( Mf2p + MJpsi, 2 ) ) * ( MBsSq - pow( Mf2p - MJpsi, 2 ) ) ) / ( 2.0 * MBs ); int_BW_phi = sqrt( Integral( Gamma0phi, Mphi, 1, 0, p30Kp_phi_CMS, kin_lower_limit, kin_upper_limit, 2 ) ); int_BW_f2p = sqrt( Integral( Gamma0f2p, Mf2p, 2, 1, p30Kp_f2p_CMS, kin_lower_limit, kin_upper_limit, 2 ) ); // 4 daughters checkNDaug( 4 ); // Spin-0 parent checkSpinParent( EvtSpinType::SCALAR ); // B_s0 (anti-B_s0) // Daughters checkSpinDaughter( 0, EvtSpinType::DIRAC ); // mu+ (mu-) checkSpinDaughter( 1, EvtSpinType::DIRAC ); // mu- (mu+) checkSpinDaughter( 2, EvtSpinType::SCALAR ); // K+ (K-) checkSpinDaughter( 3, EvtSpinType::SCALAR ); // K- (K+) // B_s0 parent (Parent must be B_s0 or anti-B_s0) const EvtId p = getParentId(); if ( p != EvtPDL::getId( "B_s0" ) && p != EvtPDL::getId( "anti-B_s0" ) ) { assert( 0 ); } // Daughter types and ordering (should be mu+-, mu-+, K+-, K-+) const EvtId d1 = getDaug( 0 ); const EvtId d2 = getDaug( 1 ); const EvtId d3 = getDaug( 2 ); const EvtId d4 = getDaug( 3 ); if ( !( ( d1 == EvtPDL::getId( "mu+" ) || d1 == EvtPDL::getId( "mu-" ) ) && ( d2 == EvtPDL::getId( "mu-" ) || d2 == EvtPDL::getId( "mu+" ) ) && ( d3 == EvtPDL::getId( "K+" ) || d3 == EvtPDL::getId( "K-" ) ) && ( d4 == EvtPDL::getId( "K-" ) || d4 == EvtPDL::getId( "K+" ) ) ) ) { assert( 0 ); } } // Get ProbMax void EvtBsMuMuKK::initProbMax() { const EvtComplex term11 = sqrt( p30Jpsi_f2p_CMS * p30Kp_f2p_CMS ); const EvtComplex term12 = X_J( 2, p30Kp_f2p_CMS, 0 ) * X_J( 1, p30Jpsi_f2p_CMS, 1 ) * p30Kp_f2p_CMS * p30Kp_f2p_CMS * p30Jpsi_f2p_CMS * ( A_f2p_0 + 0.3 * A_f2p_perp + 0.3 * A_f2p_par ); const EvtComplex term13 = f_f2p * Breit_Wigner( Gamma0f2p, Mf2p, Mf2p, 2, p30Kp_f2p_CMS, p30Kp_f2p_CMS ) / int_BW_f2p; const EvtComplex term21 = sqrt( p30Jpsi_phi_CMS * p30Kp_phi_CMS ); const EvtComplex term22 = X_J( 1, p30Kp_phi_CMS, 0 ) * p30Kp_phi_CMS * ( 0.65 * A_phi_0 + 0.6 * A_phi_perp + 0.6 * A_phi_par ); const EvtComplex term23 = f_phi * Breit_Wigner( Gamma0phi, Mphi, Mphi, 1, p30Kp_phi_CMS, p30Kp_phi_CMS ) / int_BW_phi; const EvtComplex term31 = sqrt( p30Jpsi_ll_CMS * p30Kp_ll_CMS ); const EvtComplex term32 = X_J( 1, p30Jpsi_ll_CMS, 1 ) * p30Jpsi_ll_CMS; const EvtComplex term33 = f_f0 * Flatte( Mf0, kin_lower_limit ) / int_Flatte_f0; const EvtComplex term41 = sqrt( p30Jpsi_mid_CMS * p30Kp_mid_CMS ); const EvtComplex term42 = X_J( 1, p30Jpsi_mid_CMS, 1 ) * p30Jpsi_mid_CMS; const EvtComplex term43 = 1.2 * f_S_NR / int_const_NR; const EvtComplex hm = term11 * term12 * term13 + term21 * term22 * term23 + term31 * term32 * term33 + term41 * term42 * term43; // Increase by 10% setProbMax( 0.5 * abs2( hm ) * 1.1 ); } // Decay function void EvtBsMuMuKK::decay( EvtParticle* p ) { EvtId other_b; double time( 0.0 ); EvtCPUtil::getInstance()->OtherB( p, time, other_b ); time = -log( EvtRandom::Flat() ) * ctau; // This overrules the ctau made in OtherB if ( EvtCPUtil::getInstance()->isBsMixed( p ) ) { p->getParent()->setLifetime( time * EvtConst::c / 1e12 ); // units: mm } else { p->setLifetime( time * EvtConst::c / 1e12 ); // units: mm } double DGtime = 0.25 * deltaGamma * time; double DMtime = 0.5 * deltaMs * time; double mt = exp( -DGtime ); double pt = exp( +DGtime ); double cDMt = cos( DMtime ); double sDMt = sin( DMtime ); EvtComplex termplus = EvtComplex( cDMt, sDMt ); EvtComplex terminus = EvtComplex( cDMt, -sDMt ); EvtComplex gplus = 0.5 * ( mt * termplus + pt * terminus ); EvtComplex gminus = 0.5 * ( mt * termplus - pt * terminus ); EvtId BSB = EvtPDL::getId( "anti-B_s0" ); // Flavour: first assume B_s0, otherwise choose anti-B_s0 int q( 1 ); if ( other_b == BSB ) { q = -1; } p->setAttribute( "q", q ); // Amplitudes EvtComplex a_S_NR = AmpTime( q, gplus, gminus, delta_S_NR, lambda_S_NR_abs, A_S_NR, phis_S_NR, -1 ); EvtComplex a_f0 = AmpTime( q, gplus, gminus, delta_f0, lambda_f0_abs, A_f0, phis_f0, -1 ); EvtComplex a0_phi = AmpTime( q, gplus, gminus, delta_phi_0, lambda_phi_0_abs, A_phi_0, phis_phi_0, 1 ); EvtComplex aperp_phi = AmpTime( q, gplus, gminus, delta_phi_perp, lambda_phi_perp_abs, A_phi_perp, phis_phi_perp, -1 ); EvtComplex apar_phi = AmpTime( q, gplus, gminus, delta_phi_par, lambda_phi_par_abs, A_phi_par, phis_phi_par, 1 ); EvtComplex a0_f2p = AmpTime( q, gplus, gminus, delta_f2p_0, lambda_f2p_0_abs, A_f2p_0, phis_f2p_0, -1 ); EvtComplex aperp_f2p = AmpTime( q, gplus, gminus, delta_f2p_perp, lambda_f2p_perp_abs, A_f2p_perp, phis_f2p_perp, 1 ); EvtComplex apar_f2p = AmpTime( q, gplus, gminus, delta_f2p_par, lambda_f2p_par_abs, A_f2p_par, phis_f2p_par, -1 ); // Generate 4-momenta double mKK = EvtRandom::Flat( kin_lower_limit, kin_upper_limit ); - double mass[10] = {MJpsi, mKK, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; - double Kmass[10] = {MKp, MKm, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; - double muMass[10] = {Mmu, Mmu, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + double mass[10] = { MJpsi, mKK, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + double Kmass[10] = { MKp, MKm, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + double muMass[10] = { Mmu, Mmu, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; EvtVector4R mypV[2], mypK[2], mypmu[2]; EvtGenKine::PhaseSpace( 2, mass, mypV, MBs ); EvtGenKine::PhaseSpace( 2, Kmass, mypK, mKK ); EvtGenKine::PhaseSpace( 2, muMass, mypmu, MJpsi ); EvtVector4R p4mup = boostTo( mypmu[0], mypV[0] ); EvtVector4R p4mum = boostTo( mypmu[1], mypV[0] ); EvtVector4R p4Kp = boostTo( mypK[0], mypV[1] ); EvtVector4R p4Km = boostTo( mypK[1], mypV[1] ); p->makeDaughters( getNDaug(), getDaugs() ); EvtParticle* thisparticle; EvtParticle *muplus, *muminus, *Kplus, *Kminus; // Check particle ID for ( int k = 0; k <= 3; k++ ) { thisparticle = p->getDaug( k ); EvtId pId = thisparticle->getId(); if ( pId == EvtPDL::getId( "mu+" ) ) { muplus = thisparticle; muplus->init( getDaug( k ), p4mup ); } else if ( pId == EvtPDL::getId( "mu-" ) ) { muminus = thisparticle; muminus->init( getDaug( k ), p4mum ); } else if ( pId == EvtPDL::getId( "K+" ) ) { Kplus = thisparticle; Kplus->init( getDaug( k ), p4Kp ); } else if ( pId == EvtPDL::getId( "K-" ) ) { Kminus = thisparticle; Kminus->init( getDaug( k ), p4Km ); } } EvtVector4R p4KK = p4Kp + p4Km; EvtVector4R p4mumu = p4mup + p4mum; EvtVector4R p4Bs = p4mumu + p4KK; double p4KK_mass2 = p4KK.mass2(); double p4KK_mass = p4KK.mass(); double p4Bs_mass2 = p4Bs.mass2(); double p4Bs_mass = p4Bs.mass(); // Kp momentum in the KK CMS double p3Kp_KK_CMS = sqrt( ( p4KK_mass2 - pow( MKp + MKm, 2 ) ) * ( p4KK_mass2 - pow( MKp - MKm, 2 ) ) ) / ( 2.0 * p4KK_mass ); // J/psi momentum in the KK CMS double p3Jpsi_KK_CMS = sqrt( ( p4Bs_mass2 - pow( p4KK_mass + MJpsi, 2 ) ) * ( p4Bs_mass2 - pow( p4KK_mass - MJpsi, 2 ) ) ) / ( 2.0 * p4Bs_mass ); // Mass lineshapes // Non-resonant S wave EvtComplex P_NR = 1.0 / int_const_NR; // f0 Flatte EvtComplex F_f0 = Flatte( Mf0, p4KK_mass ) / int_Flatte_f0; // phi Breit Wigner EvtComplex BW_phi = Breit_Wigner( Gamma0phi, Mphi, p4KK_mass, 1, p30Kp_phi_CMS, p3Kp_KK_CMS ) / int_BW_phi; // f2' Breit Wigner EvtComplex BW_f2p = Breit_Wigner( Gamma0f2p, Mf2p, p4KK_mass, 1, p30Kp_f2p_CMS, p3Kp_KK_CMS ) / int_BW_f2p; // Barrier factors: Always taking the lowest Bs L double X_KK_0 = 1.0; double X_KK_1 = X_J( 1, p3Kp_KK_CMS, 0 ); double X_KK_2 = X_J( 2, p3Kp_KK_CMS, 0 ); double X_NR_Jpsi_1 = X_J( 1, p3Jpsi_KK_CMS, 1 ); double X_f0_Jpsi_1 = X_J( 1, p3Jpsi_KK_CMS, 1 ); double X_phi_Jpsi_0 = 1.0; double X_f2p_Jpsi_1 = X_J( 1, p3Jpsi_KK_CMS, 1 ); // Birth momentum factors: pow(p3(K+),LR)* pow(p3(J/psi),LB) double f_PHSP = sqrt( p3Jpsi_KK_CMS * p3Kp_KK_CMS ); double f_BMF_NR = p3Jpsi_KK_CMS; double f_BMF_f0 = p3Jpsi_KK_CMS; double f_BMF_phi = p3Kp_KK_CMS; double f_BMF_f2p = p3Kp_KK_CMS * p3Kp_KK_CMS * p3Jpsi_KK_CMS; // Angular distribution and sum over KK states double CosK = EvtDecayAngle( p4Bs, p4KK, p4Kp ); double CosMu = EvtDecayAngle( p4Bs, p4mumu, p4mup ); double chi = EvtDecayAngleChi( p4Bs, p4mup, p4mum, p4Kp, p4Km ); // Build helicity amplitudes // phi EvtComplex H0_phi = a0_phi; EvtComplex Hp_phi = ( apar_phi + aperp_phi ) / sq2; EvtComplex Hm_phi = ( apar_phi - aperp_phi ) / sq2; // f2p EvtComplex H0_f2p = a0_f2p; EvtComplex Hp_f2p = ( apar_f2p + aperp_f2p ) / sq2; EvtComplex Hm_f2p = ( apar_f2p - aperp_f2p ) / sq2; // muon polarization +1 EvtComplex swaveangdist1 = AngularDist( 0, 0, 1, CosK, CosMu, chi ); // KK Spin-0 NR EvtComplex mp_hS_NR = a_S_NR * swaveangdist1; EvtComplex Amp_p_NR = P_NR * X_KK_0 * X_NR_Jpsi_1 * f_BMF_NR * mp_hS_NR; // KK Spin-0 f0 EvtComplex mp_h_f0 = a_f0 * swaveangdist1; EvtComplex Amp_p_f0 = F_f0 * X_KK_0 * X_f0_Jpsi_1 * f_BMF_f0 * mp_h_f0; // KK Spin-1 EvtComplex mp_h0_phi = H0_phi * AngularDist( 1, 0, 1, CosK, CosMu, chi ); EvtComplex mp_hp_phi = Hp_phi * AngularDist( 1, 1, 1, CosK, CosMu, chi ); EvtComplex mp_hm_phi = Hm_phi * AngularDist( 1, -1, 1, CosK, CosMu, chi ); EvtComplex Amp_p_phi = BW_phi * X_KK_1 * X_phi_Jpsi_0 * f_BMF_phi * ( mp_h0_phi + mp_hp_phi + mp_hm_phi ); // KK Spin-2 EvtComplex mp_h0_f2p = H0_f2p * AngularDist( 2, 0, 1, CosK, CosMu, chi ); EvtComplex mp_hp_f2p = Hp_f2p * AngularDist( 2, 1, 1, CosK, CosMu, chi ); EvtComplex mp_hm_f2p = Hm_f2p * AngularDist( 2, -1, 1, CosK, CosMu, chi ); EvtComplex Amp_p_f2p = BW_f2p * X_KK_2 * X_f2p_Jpsi_1 * f_BMF_f2p * ( mp_h0_f2p + mp_hp_f2p + mp_hm_f2p ); // muon polarization -1 EvtComplex swaveangdist2 = AngularDist( 0, 0, -1, CosK, CosMu, chi ); // KK Spin-0 NR EvtComplex mm_hS_NR = a_S_NR * swaveangdist2; EvtComplex Amp_m_NR = P_NR * X_KK_0 * X_NR_Jpsi_1 * f_BMF_NR * mm_hS_NR; // KK Spin-0 EvtComplex mm_h_f0 = a_f0 * swaveangdist2; EvtComplex Amp_m_f0 = F_f0 * X_KK_0 * X_f0_Jpsi_1 * f_BMF_f0 * mm_h_f0; // KK Spin-1 EvtComplex mm_h0_phi = H0_phi * AngularDist( 1, 0, -1, CosK, CosMu, chi ); EvtComplex mm_hp_phi = Hp_phi * AngularDist( 1, +1, -1, CosK, CosMu, chi ); EvtComplex mm_hm_phi = Hm_phi * AngularDist( 1, -1, -1, CosK, CosMu, chi ); EvtComplex Amp_m_phi = BW_phi * X_KK_1 * X_phi_Jpsi_0 * f_BMF_phi * ( mm_h0_phi + mm_hp_phi + mm_hm_phi ); // KK Spin-2 EvtComplex mm_h0_f2p = H0_f2p * AngularDist( 2, 0, -1, CosK, CosMu, chi ); EvtComplex mm_hp_f2p = Hp_f2p * AngularDist( 2, 1, -1, CosK, CosMu, chi ); EvtComplex mm_hm_f2p = Hm_f2p * AngularDist( 2, -1, -1, CosK, CosMu, chi ); EvtComplex Amp_m_f2p = BW_f2p * X_KK_2 * X_f2p_Jpsi_1 * f_BMF_f2p * ( mm_h0_f2p + mm_hp_f2p + mm_hm_f2p ); // Total amplitudes EvtComplex Amp_tot_plus = f_PHSP * ( Amp_p_NR + Amp_p_f0 + Amp_p_phi + Amp_p_f2p ); EvtComplex Amp_tot_minus = f_PHSP * ( Amp_m_NR + Amp_m_f0 + Amp_m_phi + Amp_m_f2p ); vertex( 0, 0, 0.0 ); vertex( 0, 1, Amp_tot_plus ); vertex( 1, 0, Amp_tot_minus ); vertex( 1, 1, 0.0 ); } // Rho function EvtComplex EvtBsMuMuKK::GetRho( const double m0, const double m ) const { double rho_sq = 1.0 - ( 4.0 * m0 * m0 / ( m * m ) ); EvtComplex rho; if ( rho_sq > 0.0 ) { rho = EvtComplex( sqrt( rho_sq ), 0.0 ); } else { rho = EvtComplex( 0.0, sqrt( -rho_sq ) ); } return rho; } // Flatte function EvtComplex EvtBsMuMuKK::Flatte( const double m0, const double m ) const { double gpipi = 0.167; double gKK = 3.05 * gpipi; EvtComplex term1 = ( 2.0 * GetRho( Mpip, m ) + GetRho( Mpi0, m ) ) / 3.0; EvtComplex term2 = ( GetRho( MKp, m ) + GetRho( MK0, m ) ) / 2.0; EvtComplex w = gpipi * term1 + gKK * term2; EvtComplex Flatte_0 = 1.0 / ( m0 * m0 - m * m - I * m0 * w ); return Flatte_0; } // Breit-Wigner function EvtComplex EvtBsMuMuKK::Breit_Wigner( const double Gamma0, const double m0, const double m, const int J, const double q0, const double q ) const { double X_J_q0_sq = pow( X_J( J, q0, 0 ), 2 ); double X_J_q_sq = pow( X_J( J, q, 0 ), 2 ); double Gamma = Gamma0 * pow( q / q0, 2 * J + 1 ) * ( m0 / m ) * ( X_J_q_sq / X_J_q0_sq ); return 1.0 / ( m0 * m0 - m * m - I * m0 * Gamma ); } // Integral double EvtBsMuMuKK::Integral( const double Gamma0, const double m0, const int JR, const int JB, const double q0, const double M_KK_ll, const double M_KK_ul, const int fcntype ) const { int bins = 1000; double bin_width = ( M_KK_ul - M_KK_ll ) / static_cast( bins ); EvtComplex integral( 0.0, 0.0 ); double sumMKpKm2 = pow( MKp + MKm, 2 ); double diffMKpKm2 = pow( MKp - MKm, 2 ); double MBs2 = pow( MBs, 2 ); for ( int i = 0; i < bins; i++ ) { double M_KK_i = M_KK_ll + static_cast( i ) * bin_width; double M_KK_f = M_KK_ll + static_cast( i + 1 ) * bin_width; double M_KK_i_sq = M_KK_i * M_KK_i; double M_KK_f_sq = M_KK_f * M_KK_f; double p3Kp_KK_CMS_i = sqrt( ( M_KK_i_sq - sumMKpKm2 ) * ( M_KK_i_sq - diffMKpKm2 ) ) / ( 2.0 * M_KK_i ); double p3Kp_KK_CMS_f = sqrt( ( M_KK_f_sq - sumMKpKm2 ) * ( M_KK_f_sq - diffMKpKm2 ) ) / ( 2.0 * M_KK_f ); double p3Jpsi_Bs_CMS_i = sqrt( ( MBs2 - pow( M_KK_i + MJpsi, 2 ) ) * ( MBs2 - pow( M_KK_i - MJpsi, 2 ) ) ) / ( 2.0 * MBs ); double p3Jpsi_Bs_CMS_f = sqrt( ( MBs2 - pow( M_KK_f + MJpsi, 2 ) ) * ( MBs2 - pow( M_KK_f - MJpsi, 2 ) ) ) / ( 2.0 * MBs ); double f_PHSP_i = sqrt( p3Kp_KK_CMS_i * p3Jpsi_Bs_CMS_i ); double f_PHSP_f = sqrt( p3Kp_KK_CMS_f * p3Jpsi_Bs_CMS_f ); double f_MBF_KK_i = pow( p3Kp_KK_CMS_i, JR ); double f_MBF_KK_f = pow( p3Kp_KK_CMS_f, JR ); double f_MBF_Bs_i = pow( p3Jpsi_Bs_CMS_i, JB ); double f_MBF_Bs_f = pow( p3Jpsi_Bs_CMS_f, JB ); double X_JR_i = X_J( JR, p3Kp_KK_CMS_i, 0 ); double X_JR_f = X_J( JR, p3Kp_KK_CMS_f, 0 ); double X_JB_i = X_J( JB, p3Jpsi_Bs_CMS_i, 1 ); double X_JB_f = X_J( JB, p3Jpsi_Bs_CMS_f, 1 ); EvtComplex fcn_i( 1.0, 0.0 ), fcn_f( 1.0, 0.0 ); if ( fcntype == 1 ) { fcn_i = Flatte( m0, M_KK_i ); fcn_f = Flatte( m0, M_KK_f ); } else if ( fcntype == 2 ) { fcn_i = Breit_Wigner( Gamma0, m0, M_KK_i, JR, q0, p3Kp_KK_CMS_i ); fcn_f = Breit_Wigner( Gamma0, m0, M_KK_f, JR, q0, p3Kp_KK_CMS_f ); } EvtComplex a_i = f_PHSP_i * f_MBF_KK_i * f_MBF_Bs_i * X_JR_i * X_JB_i * fcn_i; EvtComplex a_st_i = conj( a_i ); EvtComplex a_f = f_PHSP_f * f_MBF_KK_f * f_MBF_Bs_f * X_JR_f * X_JB_f * fcn_f; EvtComplex a_st_f = conj( a_f ); integral += 0.5 * bin_width * ( a_i * a_st_i + a_f * a_st_f ); } return sqrt( abs2( integral ) ); } // Blatt-Weisskopf barrier factors double EvtBsMuMuKK::X_J( const int J, const double q, const int isB ) const { double r_BW = 1.0; if ( isB == 0 ) { r_BW = 1.5; } else if ( isB == 1 ) { r_BW = 5.0; } double zsq = pow( r_BW * q, 2 ); double X_J( 1.0 ); if ( J == 1 ) { X_J = sqrt( 1.0 / ( 1.0 + zsq ) ); } else if ( J == 2 ) { X_J = sqrt( 1.0 / ( zsq * zsq + 3.0 * zsq + 9.0 ) ); } return X_J; } // EvtGen d matrix: Input is 2J instead of J etc double EvtBsMuMuKK::Wignerd( const int J, const int l, const int alpha, const double theta ) const { return EvtdFunction::d( 2 * J, 2 * l, 2 * alpha, theta ); } // J spin of KK, l spin proj of J/psi, alpha dimuon spin EvtComplex EvtBsMuMuKK::AngularDist( const int J, const int l, const int alpha, const double cK, const double cL, const double chi ) const { double thetaL = acos( cL ); double thetaK = acos( cK ); EvtComplex out = 0.5 * sqrt( ( 2 * J + 1 ) / pi ) * exp( EvtComplex( 0, -l * chi ) ); out *= Wignerd( 1, l, alpha, thetaL ) * Wignerd( J, -l, 0, thetaK ); return out; } // Time-dependent amplitude calculation EvtComplex EvtBsMuMuKK::AmpTime( const int q, const EvtComplex& gplus, const EvtComplex& gminus, const double delta, const double lambda_abs, const double Amp, const double phis, const int eta ) const { EvtComplex amp_time = Amp * EvtComplex( cos( -delta ), sin( -delta ) ); double qphis = q * phis; amp_time *= ( gplus + eta * pow( lambda_abs, -1.0 * q ) * EvtComplex( cos( qphis ), sin( qphis ) ) * gminus ); if ( q == 1 ) { amp_time *= eta; } return amp_time; } diff --git a/src/EvtGenModels/EvtBtoKD3P.cpp b/src/EvtGenModels/EvtBtoKD3P.cpp index 2c42907..55b4ecd 100644 --- a/src/EvtGenModels/EvtBtoKD3P.cpp +++ b/src/EvtGenModels/EvtBtoKD3P.cpp @@ -1,228 +1,228 @@ /*********************************************************************** * 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/EvtBtoKD3P.hh" #include "EvtGenBase/EvtCyclic3.hh" #include "EvtGenBase/EvtDalitzPoint.hh" #include "EvtGenBase/EvtDecayTable.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenModels/EvtPto3P.hh" #include using std::endl; //------------------------------------------------------------------ EvtDecayBase* EvtBtoKD3P::clone() { return new EvtBtoKD3P(); } //------------------------------------------------------------------ std::string EvtBtoKD3P::getName() { return "BTOKD3P"; } //------------------------------------------------------------------ void EvtBtoKD3P::init() { checkNArg( 2 ); // r, phase checkNDaug( 3 ); // K, D0(allowed), D0(suppressed). // The last two daughters are really one particle // check that the mother and all daughters are scalars: checkSpinParent( EvtSpinType::SCALAR ); checkSpinDaughter( 0, EvtSpinType::SCALAR ); checkSpinDaughter( 1, EvtSpinType::SCALAR ); checkSpinDaughter( 2, EvtSpinType::SCALAR ); // Check that the B dtr types are K D D: // get the parameters: _r = getArg( 0 ); double phase = getArg( 1 ); _exp = EvtComplex( cos( phase ), sin( phase ) ); } //------------------------------------------------------------------ void EvtBtoKD3P::initProbMax() { setProbMax( 1 ); // this is later changed in decay() } //------------------------------------------------------------------ void EvtBtoKD3P::decay( EvtParticle* p ) { // tell the subclass that we decay the daughter: _daugsDecayedByParentModel = true; // the K is the 1st daughter of the B EvtParticle. // The decay mode of the allowed D (the one produced in b->c decay) is 2nd // The decay mode of the suppressed D (the one produced in b->u decay) is 3rd const int KIND = 0; const int D1IND = 1; const int D2IND = 2; // generate kinematics of daughters (K and D): - EvtId tempDaug[2] = {getDaug( KIND ), getDaug( D1IND )}; + EvtId tempDaug[2] = { getDaug( KIND ), getDaug( D1IND ) }; p->initializePhaseSpace( 2, tempDaug ); // Get the D daughter particle and the decay models of the allowed // and suppressed D modes: EvtParticle* theD = p->getDaug( D1IND ); EvtPto3P* model1 = (EvtPto3P*)( EvtDecayTable::getInstance()->getDecayFunc( theD ) ); // For the suppressed mode, re-initialize theD as the suppressed D alias. // First set the id, then re-initialize (since it matches the expected id) theD->setId( getDaug( D2IND ) ); theD->init( getDaug( D2IND ), theD->getP4() ); EvtPto3P* model2 = (EvtPto3P*)( EvtDecayTable::getInstance()->getDecayFunc( theD ) ); // on the first call: if ( false == _decayedOnce ) { _decayedOnce = true; // store the D decay model pointers: _model1 = model1; _model2 = model2; // check the decay models of the first 2 daughters and that they // have the same final states: std::string name1 = model1->getName(); std::string name2 = model2->getName(); if ( name1 != "PTO3P" ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "D daughters of EvtBtoKD3P decay must decay via the \"PTO3P\" model" << endl << " but found to decay via " << name1.c_str() << " or " << name2.c_str() << ". Will terminate execution!" << endl; assert( 0 ); } EvtId* daugs1 = model1->getDaugs(); EvtId* daugs2 = model2->getDaugs(); bool idMatch = true; int d; for ( d = 0; d < 2; ++d ) { if ( daugs1[d] != daugs2[d] ) { idMatch = false; } } if ( false == idMatch ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "D daughters of EvtBtoKD3P decay must decay to the same final state" << endl << " particles in the same order (not CP-conjugate order)," << endl << " but they were found to decay to" << endl; for ( d = 0; d < model1->getNDaug(); ++d ) { EvtGenReport( EVTGEN_ERROR, "" ) << " " << EvtPDL::name( daugs1[d] ).c_str() << " "; } EvtGenReport( EVTGEN_ERROR, "" ) << endl; for ( d = 0; d < model1->getNDaug(); ++d ) { EvtGenReport( EVTGEN_ERROR, "" ) << " " << EvtPDL::name( daugs2[d] ).c_str() << " "; } EvtGenReport( EVTGEN_ERROR, "" ) << endl << ". Will terminate execution!" << endl; assert( 0 ); } // estimate the probmax. Need to know the probmax's of the 2 // models for this: setProbMax( model1->getProbMax( 0 ) + _r * _r * model2->getProbMax( 0 ) + 2 * _r * sqrt( model1->getProbMax( 0 ) * model2->getProbMax( 0 ) ) ); } // end of things to do on the first call // make sure the models haven't changed since the first call: if ( _model1 != model1 || _model2 != model2 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "D daughters of EvtBtoKD3P decay should have only 1 decay modes, " << endl << " but a new decay mode was found after the first call" << endl << " Will terminate execution!" << endl; assert( 0 ); } // Reset the D id to the 1st D theD->setId( getDaug( D1IND ) ); theD->init( getDaug( D1IND ), theD->getP4() ); // get the cover function for each of the models and add them up. // They are summed with coefficients 1 because we are willing to // take a small inefficiency (~50%) in order to ensure that the // cover function is large enough without getting into complications // associated with the smallness of _r: EvtPdfSum* pc1 = model1->getPC(); EvtPdfSum* pc2 = model2->getPC(); EvtPdfSum pc; pc.addTerm( 1.0, *pc1 ); pc.addTerm( 1.0, *pc2 ); // from this combined cover function, generate the Dalitz point: EvtDalitzPoint x = pc.randomPoint(); // get the aptitude for each of the models on this point and add them up: EvtComplex amp1 = model1->amplNonCP( x ); EvtComplex amp2 = model2->amplNonCP( x ); EvtComplex amp = amp1 + amp2 * _r * _exp; // get the value of the cover function for this point and set the // relative amplitude for this decay: double comp = sqrt( pc.evaluate( x ) ); vertex( amp / comp ); // Make the daughters of theD: bool massTreeOK = theD->generateMassTree(); if ( massTreeOK == false ) { return; } // Now generate the p4's of the daughters of theD: std::vector v = model2->initDaughters( x ); if ( v.size() != theD->getNDaug() ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Number of daughters " << theD->getNDaug() << " != " << "Momentum vector size " << v.size() << endl << " Terminating execution." << endl; assert( 0 ); } // Apply the new p4's to the daughters: for ( unsigned int i = 0; i < theD->getNDaug(); ++i ) { theD->getDaug( i )->init( model2->getDaugs()[i], v[i] ); } } diff --git a/src/EvtGenModels/EvtBtoXsgammaFermiUtil.cpp b/src/EvtGenModels/EvtBtoXsgammaFermiUtil.cpp index b0d382c..efa2b0b 100644 --- a/src/EvtGenModels/EvtBtoXsgammaFermiUtil.cpp +++ b/src/EvtGenModels/EvtBtoXsgammaFermiUtil.cpp @@ -1,237 +1,237 @@ /*********************************************************************** * 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/EvtBtoXsgammaFermiUtil.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenModels/EvtBtoXsgammaRootFinder.hh" #include "EvtGenModels/EvtItgFunction.hh" #include "EvtGenModels/EvtItgTwoCoeffFcn.hh" #include #include using std::endl; double EvtBtoXsgammaFermiUtil::FermiExpFunc( double y, const std::vector& coeffs ) { //coeffs: 1 = lambdabar, 2 = a, 3 = lam1, 4 = norm // EvtGenReport(EVTGEN_INFO,"EvtGen")<& coeffs ) { //coeffs: 1 = lambdabar, 2 = a, 3 = c, 4 = norm return ( pow( 1. - ( y / coeffs[1] ), coeffs[2] ) * exp( -pow( coeffs[3], 2. ) * pow( 1. - ( y / coeffs[1] ), 2. ) ) ) / coeffs[4]; } double EvtBtoXsgammaFermiUtil::FermiGaussFuncRoot( double lambdabar, double lam1, double mb, std::vector& gammaCoeffs ) { - std::vector coeffs1 = {0.2, lambdabar, 0.0}; - std::vector coeffs2 = {0.2, lambdabar, -lam1 / 3.}; + std::vector coeffs1 = { 0.2, lambdabar, 0.0 }; + std::vector coeffs2 = { 0.2, lambdabar, -lam1 / 3. }; - auto lhFunc = EvtItgTwoCoeffFcn{&FermiGaussRootFcnA, -mb, lambdabar, - coeffs1, gammaCoeffs}; - auto rhFunc = EvtItgTwoCoeffFcn{&FermiGaussRootFcnB, -mb, lambdabar, - coeffs2, gammaCoeffs}; + auto lhFunc = EvtItgTwoCoeffFcn{ &FermiGaussRootFcnA, -mb, lambdabar, + coeffs1, gammaCoeffs }; + auto rhFunc = EvtItgTwoCoeffFcn{ &FermiGaussRootFcnB, -mb, lambdabar, + coeffs2, gammaCoeffs }; auto rootFinder = EvtBtoXsgammaRootFinder{}; return rootFinder.GetGaussIntegFcnRoot( &lhFunc, &rhFunc, 1.0e-4, 1.0e-4, 40, 40, -mb, lambdabar, 0.2, 0.4, 1.0e-6 ); } double EvtBtoXsgammaFermiUtil::FermiGaussRootFcnA( double y, const std::vector& coeffs1, const std::vector& coeffs2 ) { //coeffs1: 0=ap, 1=lambdabar, coeffs2=gamma function coeffs double cp = Gamma( ( 2.0 + coeffs1[0] ) / 2., coeffs2 ) / Gamma( ( 1.0 + coeffs1[0] ) / 2., coeffs2 ); return ( y * y ) * pow( ( 1. - ( y / coeffs1[1] ) ), coeffs1[0] ) * exp( -pow( cp, 2 ) * pow( ( 1. - ( y / coeffs1[1] ) ), 2. ) ); } double EvtBtoXsgammaFermiUtil::FermiGaussRootFcnB( double y, const std::vector& coeffs1, const std::vector& coeffs2 ) { //coeffs1: 0=ap, 1=lambdabar, coeffs2=gamma function coeffs double cp = Gamma( ( 2.0 + coeffs1[0] ) / 2., coeffs2 ) / Gamma( ( 1.0 + coeffs1[0] ) / 2., coeffs2 ); return pow( ( 1. - ( y / coeffs1[1] ) ), coeffs1[0] ) * exp( -pow( cp, 2 ) * pow( ( 1. - ( y / coeffs1[1] ) ), 2. ) ); } double EvtBtoXsgammaFermiUtil::Gamma( double z, const std::vector& coeffs ) { //Lifted from Numerical Recipies in C double x, y, tmp, ser; int j; y = z; x = z; tmp = x + 5.5; tmp = tmp - ( x + 0.5 ) * log( tmp ); ser = 1.000000000190015; for ( j = 0; j < 6; j++ ) { y = y + 1.0; ser = ser + coeffs[j] / y; } return exp( -tmp + log( 2.5066282746310005 * ser / x ) ); } double EvtBtoXsgammaFermiUtil::BesselK1( double x ) { //Lifted from Numerical Recipies in C : Returns the modified Bessel //function K_1(x) for positive real x if ( x < 0.0 ) EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "x is negative !" << endl; double y, ans; if ( x <= 2.0 ) { y = x * x / 4.0; ans = ( log( x / 2.0 ) * BesselI1( x ) ) + ( 1.0 / x ) * ( 1.0 + y * ( 0.15443144 + y * ( -0.67278579 + y * ( -0.18156897 + y * ( -0.1919402e-1 + y * ( -0.110404e-2 + y * ( -0.4686e-4 ) ) ) ) ) ) ); } else { y = 2.0 / x; ans = ( exp( -x ) / sqrt( x ) ) * ( 1.25331414 + y * ( 0.23498619 + y * ( -0.3655620e-1 + y * ( 0.1504268e-1 + y * ( -0.780353e-2 + y * ( 0.325614e-2 + y * ( -0.68245e-3 ) ) ) ) ) ) ); } return ans; } double EvtBtoXsgammaFermiUtil::BesselI1( double x ) { //Lifted from Numerical Recipies in C : Returns the modified Bessel //function I_1(x) for any real x double ax, ans; double y; ax = fabs( x ); if ( ax < 3.75 ) { y = x / 3.75; y *= y; ans = ax * ( 0.5 + y * ( 0.87890594 + y * ( 0.51498869 + y * ( 0.15084934 + y * ( 0.2658733e-1 + y * ( 0.301532e-2 + y * 0.32411e-3 ) ) ) ) ) ); } else { y = 3.75 / ax; ans = 0.2282967e-1 + y * ( -0.2895312e-1 + y * ( 0.1787654e-1 - y * 0.420059e-2 ) ); ans = 0.398914228 + y * ( -0.3988024e-1 + y * ( -0.362018e-2 + y * ( 0.163801e-2 + y * ( -0.1031555e-1 + y * ans ) ) ) ); ans *= ( exp( ax ) / sqrt( ax ) ); } return x < 0.0 ? -ans : ans; } double EvtBtoXsgammaFermiUtil::FermiRomanFuncRoot( double lambdabar, double lam1 ) { - auto lhFunc = EvtItgFunction{&FermiRomanRootFcnA, -1.e-6, 1.e6}; + auto lhFunc = EvtItgFunction{ &FermiRomanRootFcnA, -1.e-6, 1.e6 }; auto rootFinder = EvtBtoXsgammaRootFinder{}; double rhSide = 1.0 - ( lam1 / ( 3.0 * lambdabar * lambdabar ) ); double rho = rootFinder.GetRootSingleFunc( &lhFunc, rhSide, 0.1, 0.4, 1.0e-6 ); //rho=0.250353; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "rho/2 " << rho / 2. << " bessel " << BesselK1( rho / 2. ) << endl; double pF = lambdabar * sqrt( EvtConst::pi ) / ( rho * exp( rho / 2. ) * BesselK1( rho / 2. ) ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "rho " << rho << " pf " << pF << endl; return rho; } double EvtBtoXsgammaFermiUtil::FermiRomanRootFcnA( double y ) { return EvtConst::pi * ( 2. + y ) * pow( y, -2. ) * exp( -y ) * pow( BesselK1( y / 2. ), -2. ); } double EvtBtoXsgammaFermiUtil::FermiRomanFunc( double y, const std::vector& coeffs ) { if ( y == ( coeffs[1] - coeffs[2] ) ) y = 0.99999999 * ( coeffs[1] - coeffs[2] ); //coeffs: 1 = mB, 2=mb, 3=rho, 4=lambdabar, 5=norm double pF = coeffs[4] * sqrt( EvtConst::pi ) / ( coeffs[3] * exp( coeffs[3] / 2. ) * BesselK1( coeffs[3] / 2. ) ); // EvtGenReport(EVTGEN_INFO,"EvtGen")<<" pf "<. * ***********************************************************************/ #include "EvtGenModels/EvtBtoXsgammaKagan.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenModels/EvtBtoXsgamma.hh" #include "EvtGenModels/EvtBtoXsgammaFermiUtil.hh" #include "EvtGenModels/EvtItgAbsIntegrator.hh" #include "EvtGenModels/EvtItgFourCoeffFcn.hh" #include "EvtGenModels/EvtItgFunction.hh" #include "EvtGenModels/EvtItgPtrFunction.hh" #include "EvtGenModels/EvtItgSimpsonIntegrator.hh" #include "EvtGenModels/EvtItgThreeCoeffFcn.hh" #include "EvtGenModels/EvtItgTwoCoeffFcn.hh" #include #include #include using std::endl; using std::fstream; bool EvtBtoXsgammaKagan::bbprod = false; double EvtBtoXsgammaKagan::intervalMH = 0; void EvtBtoXsgammaKagan::init( int nArg, double* args ) { if ( ( nArg ) > 12 || ( nArg > 1 && nArg < 10 ) || nArg == 11 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtBtoXsgamma generator model " << "EvtBtoXsgammaKagan expected " << "either 1(default config) or " << "10 (default mass range) or " << "12 (user range) arguments but found: " << nArg << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( nArg == 1 ) { bbprod = true; getDefaultHadronicMass(); } else { bbprod = false; computeHadronicMass( nArg, args ); } double mHminLimit = 0.6373; double mHmaxLimit = 4.5; if ( nArg > 10 ) { _mHmin = args[10]; _mHmax = args[11]; if ( _mHmin > _mHmax ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Minimum hadronic mass exceeds maximum " << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( _mHmin < mHminLimit ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Minimum hadronic mass below K pi threshold" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Resetting to K pi threshold" << endl; _mHmin = mHminLimit; } if ( _mHmax > mHmaxLimit ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Maximum hadronic mass above 4.5 GeV/c^2" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Resetting to 4.5 GeV/c^2" << endl; _mHmax = mHmaxLimit; } } else { _mHmin = mHminLimit; // usually just above K pi threshold for Xsd/u _mHmax = mHmaxLimit; } } void EvtBtoXsgammaKagan::getDefaultHadronicMass() { - massHad = {0, 0.0625995, 0.125199, 0.187798, 0.250398, 0.312997, - 0.375597, 0.438196, 0.500796, 0.563395, 0.625995, 0.688594, - 0.751194, 0.813793, 0.876392, 0.938992, 1.00159, 1.06419, - 1.12679, 1.18939, 1.25199, 1.31459, 1.37719, 1.43979, - 1.50239, 1.56499, 1.62759, 1.69019, 1.75278, 1.81538, - 1.87798, 1.94058, 2.00318, 2.06578, 2.12838, 2.19098, - 2.25358, 2.31618, 2.37878, 2.44138, 2.50398, 2.56658, - 2.62918, 2.69178, 2.75438, 2.81698, 2.87958, 2.94217, - 3.00477, 3.06737, 3.12997, 3.19257, 3.25517, 3.31777, - 3.38037, 3.44297, 3.50557, 3.56817, 3.63077, 3.69337, - 3.75597, 3.81857, 3.88117, 3.94377, 4.00637, 4.06896, - 4.13156, 4.19416, 4.25676, 4.31936, 4.38196, 4.44456, - 4.50716, 4.56976, 4.63236, 4.69496, 4.75756, 4.82016, - 4.88276, 4.94536, 5.00796}; - brHad = {0, 1.03244e-09, 3.0239e-08, 1.99815e-07, 7.29392e-07, - 1.93129e-06, 4.17806e-06, 7.86021e-06, 1.33421e-05, 2.09196e-05, - 3.07815e-05, 4.29854e-05, 5.74406e-05, 7.3906e-05, 9.2003e-05, - 0.000111223, 0.000130977, 0.000150618, 0.000169483, 0.000186934, - 0.000202392, 0.000215366, 0.000225491, 0.000232496, 0.000236274, - 0.000236835, 0.000234313, 0.000228942, 0.000221042, 0.000210994, - 0.000199215, 0.000186137, 0.000172194, 0.000157775, 0.000143255, - 0.000128952, 0.000115133, 0.000102012, 8.97451e-05, 7.84384e-05, - 6.81519e-05, 5.89048e-05, 5.06851e-05, 4.34515e-05, 3.71506e-05, - 3.1702e-05, 2.70124e-05, 2.30588e-05, 1.96951e-05, 1.68596e-05, - 1.44909e-05, 1.25102e-05, 1.08596e-05, 9.48476e-06, 8.34013e-06, - 7.38477e-06, 6.58627e-06, 5.91541e-06, 5.35022e-06, 4.87047e-06, - 4.46249e-06, 4.11032e-06, 3.80543e-06, 3.54051e-06, 3.30967e-06, - 3.10848e-06, 2.93254e-06, 2.78369e-06, 2.65823e-06, 2.55747e-06, - 2.51068e-06, 2.57179e-06, 2.74684e-06, 3.02719e-06, 3.41182e-06, - 3.91387e-06, 4.56248e-06, 5.40862e-06, 6.53915e-06, 8.10867e-06, - 1.04167e-05}; + massHad = { 0, 0.0625995, 0.125199, 0.187798, 0.250398, 0.312997, + 0.375597, 0.438196, 0.500796, 0.563395, 0.625995, 0.688594, + 0.751194, 0.813793, 0.876392, 0.938992, 1.00159, 1.06419, + 1.12679, 1.18939, 1.25199, 1.31459, 1.37719, 1.43979, + 1.50239, 1.56499, 1.62759, 1.69019, 1.75278, 1.81538, + 1.87798, 1.94058, 2.00318, 2.06578, 2.12838, 2.19098, + 2.25358, 2.31618, 2.37878, 2.44138, 2.50398, 2.56658, + 2.62918, 2.69178, 2.75438, 2.81698, 2.87958, 2.94217, + 3.00477, 3.06737, 3.12997, 3.19257, 3.25517, 3.31777, + 3.38037, 3.44297, 3.50557, 3.56817, 3.63077, 3.69337, + 3.75597, 3.81857, 3.88117, 3.94377, 4.00637, 4.06896, + 4.13156, 4.19416, 4.25676, 4.31936, 4.38196, 4.44456, + 4.50716, 4.56976, 4.63236, 4.69496, 4.75756, 4.82016, + 4.88276, 4.94536, 5.00796 }; + brHad = { 0, 1.03244e-09, 3.0239e-08, 1.99815e-07, 7.29392e-07, + 1.93129e-06, 4.17806e-06, 7.86021e-06, 1.33421e-05, 2.09196e-05, + 3.07815e-05, 4.29854e-05, 5.74406e-05, 7.3906e-05, 9.2003e-05, + 0.000111223, 0.000130977, 0.000150618, 0.000169483, 0.000186934, + 0.000202392, 0.000215366, 0.000225491, 0.000232496, 0.000236274, + 0.000236835, 0.000234313, 0.000228942, 0.000221042, 0.000210994, + 0.000199215, 0.000186137, 0.000172194, 0.000157775, 0.000143255, + 0.000128952, 0.000115133, 0.000102012, 8.97451e-05, 7.84384e-05, + 6.81519e-05, 5.89048e-05, 5.06851e-05, 4.34515e-05, 3.71506e-05, + 3.1702e-05, 2.70124e-05, 2.30588e-05, 1.96951e-05, 1.68596e-05, + 1.44909e-05, 1.25102e-05, 1.08596e-05, 9.48476e-06, 8.34013e-06, + 7.38477e-06, 6.58627e-06, 5.91541e-06, 5.35022e-06, 4.87047e-06, + 4.46249e-06, 4.11032e-06, 3.80543e-06, 3.54051e-06, 3.30967e-06, + 3.10848e-06, 2.93254e-06, 2.78369e-06, 2.65823e-06, 2.55747e-06, + 2.51068e-06, 2.57179e-06, 2.74684e-06, 3.02719e-06, 3.41182e-06, + 3.91387e-06, 4.56248e-06, 5.40862e-06, 6.53915e-06, 8.10867e-06, + 1.04167e-05 }; massHad.resize( 81 ); brHad.resize( 81 ); intervalMH = 80; } void EvtBtoXsgammaKagan::computeHadronicMass( int /*nArg*/, double* args ) { //Input parameters int fermiFunction = (int)args[1]; _mB = args[2]; _mb = args[3]; _mu = args[4]; _lam1 = args[5]; _delta = args[6]; _z = args[7]; _nIntervalS = args[8]; _nIntervalmH = args[9]; std::vector mHVect( int( _nIntervalmH + 1.0 ) ); massHad.clear(); massHad.resize( int( _nIntervalmH + 1.0 ) ); brHad.clear(); brHad.resize( int( _nIntervalmH + 1.0 ) ); intervalMH = _nIntervalmH; //Going to have to add a new entry into the data file - takes ages... EvtGenReport( EVTGEN_WARNING, "EvtGen" ) << "EvtBtoXsgammaKagan: calculating new hadronic mass spectra. This takes a while..." << endl; //Now need to compute the mHVect vector for //the current parameters //A few more parameters double _mubar = _mu; _mW = 80.33; _mt = 175.0; _alpha = 1. / 137.036; _lambdabar = _mB - _mb; _kappabar = 3.382 - 4.14 * ( sqrt( _z ) - 0.29 ); _fz = Fz( _z ); _rer8 = ( 44. / 9. ) - ( 8. / 27. ) * pow( EvtConst::pi, 2. ); _r7 = ( -10. / 3. ) - ( 8. / 9. ) * pow( EvtConst::pi, 2. ); _rer2 = -4.092 + 12.78 * ( sqrt( _z ) - .29 ); _gam77 = 32. / 3.; _gam27 = 416. / 81.; _gam87 = -32. / 9.; _lam2 = .12; _beta0 = 23. / 3.; _beta1 = 116. / 3.; _alphasmZ = .118; _mZ = 91.187; _ms = _mb / 50.; double eGammaMin = 0.5 * _mB * ( 1. - _delta ); double eGammaMax = 0.5 * _mB; double yMin = 2. * eGammaMin / _mB; double yMax = 2. * eGammaMax / _mB; double _CKMrat = 0.976; double Nsl = 1.0; //Calculate alpha the various scales _alphasmW = CalcAlphaS( _mW ); _alphasmt = CalcAlphaS( _mt ); _alphasmu = CalcAlphaS( _mu ); _alphasmubar = CalcAlphaS( _mubar ); //Calculate the Wilson Coefficients and Delta _etamu = _alphasmW / _alphasmu; _kSLemmu = ( 12. / 23. ) * ( ( 1. / _etamu ) - 1. ); CalcWilsonCoeffs(); CalcDelta(); //Build s22 and s27 vector - saves time because double //integration is required otherwise std::vector s22Coeffs( int( _nIntervalS + 1.0 ) ); std::vector s27Coeffs( int( _nIntervalS + 1.0 ) ); std::vector s28Coeffs( int( _nIntervalS + 1.0 ) ); double dy = ( yMax - yMin ) / _nIntervalS; double yp = yMin; std::vector sCoeffs( 1 ); sCoeffs[0] = _z; //Define s22 and s27 functions - auto mys22Func = EvtItgPtrFunction{&s22Func, 0., yMax + 0.1, sCoeffs}; - auto mys27Func = EvtItgPtrFunction{&s27Func, 0., yMax + 0.1, sCoeffs}; + auto mys22Func = EvtItgPtrFunction{ &s22Func, 0., yMax + 0.1, sCoeffs }; + auto mys27Func = EvtItgPtrFunction{ &s27Func, 0., yMax + 0.1, sCoeffs }; //Use a simpson integrator - auto mys22Simp = EvtItgSimpsonIntegrator{mys22Func, 1.0e-4, 20}; - auto mys27Simp = EvtItgSimpsonIntegrator{mys27Func, 1.0e-4, 50}; + auto mys22Simp = EvtItgSimpsonIntegrator{ mys22Func, 1.0e-4, 20 }; + auto mys27Simp = EvtItgSimpsonIntegrator{ mys27Func, 1.0e-4, 50 }; int i; for ( i = 0; i < int( _nIntervalS + 1.0 ); i++ ) { s22Coeffs[i] = ( 16. / 27. ) * mys22Simp.evaluate( 1.0e-20, yp ); s27Coeffs[i] = ( -8. / 9. ) * _z * mys27Simp.evaluate( 1.0e-20, yp ); s28Coeffs[i] = -s27Coeffs[i] / 3.; yp = yp + dy; } //Define functions and vectors used to calculate mHVect. Each function takes a set //of vectors which are used as the function coefficients std::vector FermiCoeffs( 6 ); std::vector varCoeffs( 3 ); std::vector DeltaCoeffs( 1 ); std::vector s88Coeffs( 2 ); std::vector sInitCoeffs( 3 ); varCoeffs[0] = _mB; varCoeffs[1] = _mb; varCoeffs[2] = 0.; DeltaCoeffs[0] = _alphasmu; s88Coeffs[0] = _mb; s88Coeffs[1] = _ms; sInitCoeffs[0] = _nIntervalS; sInitCoeffs[1] = yMin; sInitCoeffs[2] = yMax; FermiCoeffs[0] = fermiFunction; FermiCoeffs[1] = 0.0; FermiCoeffs[2] = 0.0; FermiCoeffs[3] = 0.0; FermiCoeffs[4] = 0.0; FermiCoeffs[5] = 0.0; //Coefficients for gamma function std::vector gammaCoeffs( 6 ); gammaCoeffs[0] = 76.18009172947146; gammaCoeffs[1] = -86.50532032941677; gammaCoeffs[2] = 24.01409824083091; gammaCoeffs[3] = -1.231739572450155; gammaCoeffs[4] = 0.1208650973866179e-2; gammaCoeffs[5] = -0.5395239384953e-5; //Calculate quantities for the fermi function to be used //Distinguish among the different shape functions if ( fermiFunction == 1 ) { FermiCoeffs[1] = _lambdabar; FermiCoeffs[2] = ( -3. * pow( _lambdabar, 2. ) / _lam1 ) - 1.; FermiCoeffs[3] = _lam1; FermiCoeffs[4] = 1.0; auto myNormFunc = std::make_unique( &EvtBtoXsgammaFermiUtil::FermiExpFunc, -_mb, _mB - _mb, FermiCoeffs ); auto myNormSimp = std::make_unique( *myNormFunc, 1.0e-4, 40 ); FermiCoeffs[4] = myNormSimp->normalisation(); } else if ( fermiFunction == 2 ) { double a = EvtBtoXsgammaFermiUtil::FermiGaussFuncRoot( _lambdabar, _lam1, _mb, gammaCoeffs ); FermiCoeffs[1] = _lambdabar; FermiCoeffs[2] = a; FermiCoeffs[3] = EvtBtoXsgammaFermiUtil::Gamma( ( 2.0 + a ) / 2., gammaCoeffs ) / EvtBtoXsgammaFermiUtil::Gamma( ( 1.0 + a ) / 2., gammaCoeffs ); FermiCoeffs[4] = 1.0; auto myNormFunc = std::make_unique( &EvtBtoXsgammaFermiUtil::FermiGaussFunc, -_mb, _mB - _mb, FermiCoeffs ); auto myNormSimp = std::make_unique( *myNormFunc, 1.0e-4, 40 ); FermiCoeffs[4] = myNormSimp->normalisation(); } else if ( fermiFunction == 3 ) { double rho = EvtBtoXsgammaFermiUtil::FermiRomanFuncRoot( _lambdabar, _lam1 ); FermiCoeffs[1] = _mB; FermiCoeffs[2] = _mb; FermiCoeffs[3] = rho; FermiCoeffs[4] = _lambdabar; FermiCoeffs[5] = 1.0; auto myNormFunc = std::make_unique( &EvtBtoXsgammaFermiUtil::FermiRomanFunc, -_mb, _mB - _mb, FermiCoeffs ); auto myNormSimp = std::make_unique( *myNormFunc, 1.0e-4, 40 ); FermiCoeffs[5] = myNormSimp->normalisation(); } //Define functions - auto myDeltaFermiFunc = EvtItgThreeCoeffFcn{&DeltaFermiFunc, -_mb, - _mB - _mb, FermiCoeffs, - varCoeffs, DeltaCoeffs}; - auto mys88FermiFunc = EvtItgThreeCoeffFcn{&s88FermiFunc, -_mb, - _mB - _mb, FermiCoeffs, - varCoeffs, s88Coeffs}; - auto mys77FermiFunc = EvtItgTwoCoeffFcn{&s77FermiFunc, -_mb, _mB - _mb, - FermiCoeffs, varCoeffs}; - auto mys78FermiFunc = EvtItgTwoCoeffFcn{&s78FermiFunc, -_mb, _mB - _mb, - FermiCoeffs, varCoeffs}; - auto mys22FermiFunc = EvtItgFourCoeffFcn{&sFermiFunc, -_mb, - _mB - _mb, FermiCoeffs, - varCoeffs, sInitCoeffs, - s22Coeffs}; - auto mys27FermiFunc = EvtItgFourCoeffFcn{&sFermiFunc, -_mb, - _mB - _mb, FermiCoeffs, - varCoeffs, sInitCoeffs, - s27Coeffs}; - auto mys28FermiFunc = EvtItgFourCoeffFcn{&sFermiFunc, -_mb, - _mB - _mb, FermiCoeffs, - varCoeffs, sInitCoeffs, - s28Coeffs}; + auto myDeltaFermiFunc = EvtItgThreeCoeffFcn{ &DeltaFermiFunc, -_mb, + _mB - _mb, FermiCoeffs, + varCoeffs, DeltaCoeffs }; + auto mys88FermiFunc = EvtItgThreeCoeffFcn{ &s88FermiFunc, -_mb, + _mB - _mb, FermiCoeffs, + varCoeffs, s88Coeffs }; + auto mys77FermiFunc = EvtItgTwoCoeffFcn{ &s77FermiFunc, -_mb, _mB - _mb, + FermiCoeffs, varCoeffs }; + auto mys78FermiFunc = EvtItgTwoCoeffFcn{ &s78FermiFunc, -_mb, _mB - _mb, + FermiCoeffs, varCoeffs }; + auto mys22FermiFunc = EvtItgFourCoeffFcn{ &sFermiFunc, -_mb, + _mB - _mb, FermiCoeffs, + varCoeffs, sInitCoeffs, + s22Coeffs }; + auto mys27FermiFunc = EvtItgFourCoeffFcn{ &sFermiFunc, -_mb, + _mB - _mb, FermiCoeffs, + varCoeffs, sInitCoeffs, + s27Coeffs }; + auto mys28FermiFunc = EvtItgFourCoeffFcn{ &sFermiFunc, -_mb, + _mB - _mb, FermiCoeffs, + varCoeffs, sInitCoeffs, + s28Coeffs }; //Define integrators - auto myDeltaFermiSimp = EvtItgSimpsonIntegrator{myDeltaFermiFunc, 1.0e-4, 40}; - auto mys77FermiSimp = EvtItgSimpsonIntegrator{mys77FermiFunc, 1.0e-4, 40}; - auto mys88FermiSimp = EvtItgSimpsonIntegrator{mys88FermiFunc, 1.0e-4, 40}; - auto mys78FermiSimp = EvtItgSimpsonIntegrator{mys78FermiFunc, 1.0e-4, 40}; - auto mys22FermiSimp = EvtItgSimpsonIntegrator{mys22FermiFunc, 1.0e-4, 40}; - auto mys27FermiSimp = EvtItgSimpsonIntegrator{mys27FermiFunc, 1.0e-4, 40}; - auto mys28FermiSimp = EvtItgSimpsonIntegrator{mys28FermiFunc, 1.0e-4, 40}; + auto myDeltaFermiSimp = EvtItgSimpsonIntegrator{ myDeltaFermiFunc, 1.0e-4, + 40 }; + auto mys77FermiSimp = EvtItgSimpsonIntegrator{ mys77FermiFunc, 1.0e-4, 40 }; + auto mys88FermiSimp = EvtItgSimpsonIntegrator{ mys88FermiFunc, 1.0e-4, 40 }; + auto mys78FermiSimp = EvtItgSimpsonIntegrator{ mys78FermiFunc, 1.0e-4, 40 }; + auto mys22FermiSimp = EvtItgSimpsonIntegrator{ mys22FermiFunc, 1.0e-4, 40 }; + auto mys27FermiSimp = EvtItgSimpsonIntegrator{ mys27FermiFunc, 1.0e-4, 40 }; + auto mys28FermiSimp = EvtItgSimpsonIntegrator{ mys28FermiFunc, 1.0e-4, 40 }; //Finally calculate mHVect for the range of hadronic masses double mHmin = sqrt( _mB * _mB - 2. * _mB * eGammaMax ); double mHmax = sqrt( _mB * _mB - 2. * _mB * eGammaMin ); double dmH = ( mHmax - mHmin ) / _nIntervalmH; double mH = mHmin; //Calculating the Branching Fractions for ( i = 0; i < int( _nIntervalmH + 1.0 ); i++ ) { double ymH = 1. - ( ( mH * mH ) / ( _mB * _mB ) ); //Need to set ymH as one of the input parameters myDeltaFermiFunc.setCoeff( 2, 2, ymH ); mys77FermiFunc.setCoeff( 2, 2, ymH ); mys88FermiFunc.setCoeff( 2, 2, ymH ); mys78FermiFunc.setCoeff( 2, 2, ymH ); mys22FermiFunc.setCoeff( 2, 2, ymH ); mys27FermiFunc.setCoeff( 2, 2, ymH ); mys28FermiFunc.setCoeff( 2, 2, ymH ); //Integrate double deltaResult = myDeltaFermiSimp.evaluate( ( _mB * ymH - _mb ), _mB - _mb ); double s77Result = mys77FermiSimp.evaluate( ( _mB * ymH - _mb ), _mB - _mb ); double s88Result = mys88FermiSimp.evaluate( ( _mB * ymH - _mb ), _mB - _mb ); double s78Result = mys78FermiSimp.evaluate( ( _mB * ymH - _mb ), _mB - _mb ); double s22Result = mys22FermiSimp.evaluate( ( _mB * ymH - _mb ), _mB - _mb ); double s27Result = mys27FermiSimp.evaluate( ( _mB * ymH - _mb ), _mB - _mb ); mys28FermiSimp.evaluate( ( _mB * ymH - _mb ), _mB - _mb ); double py = ( pow( _CKMrat, 2. ) * ( 6. / _fz ) * ( _alpha / EvtConst::pi ) * ( deltaResult * _cDeltatot + ( _alphasmu / EvtConst::pi ) * ( s77Result * pow( _c70mu, 2. ) + s27Result * _c2mu * ( _c70mu - _c80mu / 3. ) + s78Result * _c70mu * _c80mu + s22Result * _c2mu * _c2mu + s88Result * _c80mu * _c80mu ) ) ); mHVect[i] = 2. * ( mH / ( _mB * _mB ) ) * 0.105 * Nsl * py; massHad[i] = mH; brHad[i] = 2. * ( mH / ( _mB * _mB ) ) * 0.105 * Nsl * py; mH = mH + dmH; } } double EvtBtoXsgammaKagan::GetMass( int /*Xscode*/ ) { // Get hadronic mass for the event according to the hadronic mass spectra computed in computeHadronicMass double mass = 0.0; double min = _mHmin; if ( bbprod ) min = 1.1; // double max=4.5; double max = _mHmax; double xbox( 0 ), ybox( 0 ); double boxheight( 0 ); double trueHeight( 0 ); double boxwidth = max - min; double wgt( 0. ); for ( int i = 0; i < int( intervalMH + 1.0 ); i++ ) { if ( brHad[i] > boxheight ) boxheight = brHad[i]; } while ( ( mass > max ) || ( mass < min ) ) { xbox = EvtRandom::Flat( boxwidth ) + min; ybox = EvtRandom::Flat( boxheight ); trueHeight = 0.0; // Correction by Peter Richardson for ( int i = 1; i < int( intervalMH + 1.0 ); ++i ) { if ( ( massHad[i] >= xbox ) && ( 0.0 == trueHeight ) ) { wgt = ( xbox - massHad[i - 1] ) / ( massHad[i] - massHad[i - 1] ); trueHeight = brHad[i - 1] + wgt * ( brHad[i] - brHad[i - 1] ); } } if ( ybox > trueHeight ) { mass = 0.0; } else { mass = xbox; } } return mass; } double EvtBtoXsgammaKagan::CalcAlphaS( double scale ) { double v = 1. - _beta0 * ( _alphasmZ / ( 2. * EvtConst::pi ) ) * ( log( _mZ / scale ) ); return ( _alphasmZ / v ) * ( 1. - ( ( _beta1 / _beta0 ) * ( _alphasmZ / ( 4. * EvtConst::pi ) ) * ( log( v ) / v ) ) ); } void EvtBtoXsgammaKagan::CalcWilsonCoeffs() { double mtatmw = _mt * pow( ( _alphasmW / _alphasmt ), ( 12. / 23. ) ) * ( 1 + ( 12. / 23. ) * ( ( 253. / 18. ) - ( 116. / 23. ) ) * ( ( _alphasmW - _alphasmt ) / ( 4.0 * EvtConst::pi ) ) - ( 4. / 3. ) * ( _alphasmt / EvtConst::pi ) ); double xt = pow( mtatmw, 2. ) / pow( _mW, 2. ); /////LO _c2mu = .5 * pow( _etamu, ( -12. / 23. ) ) + .5 * pow( _etamu, ( 6. / 23. ) ); double c7mWsm = ( ( 3. * pow( xt, 3. ) - 2. * pow( xt, 2. ) ) / ( 4. * pow( ( xt - 1. ), 4. ) ) ) * log( xt ) + ( ( -8. * pow( xt, 3. ) - 5. * pow( xt, 2. ) + 7. * xt ) / ( 24. * pow( ( xt - 1. ), 3. ) ) ); double c8mWsm = ( ( -3. * pow( xt, 2. ) ) / ( 4. * pow( ( xt - 1. ), 4. ) ) ) * log( xt ) + ( ( -pow( xt, 3. ) + 5. * pow( xt, 2. ) + 2. * xt ) / ( 8. * pow( ( xt - 1. ), 3. ) ) ); double c7constmu = ( 626126. / 272277. ) * pow( _etamu, ( 14. / 23. ) ) - ( 56281. / 51730. ) * pow( _etamu, ( 16. / 23. ) ) - ( 3. / 7. ) * pow( _etamu, ( 6. / 23. ) ) - ( 1. / 14. ) * pow( _etamu, ( -12. / 23. ) ) - .6494 * pow( _etamu, .4086 ) - .038 * pow( _etamu, -.423 ) - .0186 * pow( _etamu, -.8994 ) - .0057 * pow( _etamu, .1456 ); _c70mu = c7mWsm * pow( _etamu, ( 16. / 23. ) ) + ( 8. / 3. ) * ( pow( _etamu, ( 14. / 23. ) ) - pow( _etamu, ( 16. / 23. ) ) ) * c8mWsm + c7constmu; double c8constmu = ( 313063. / 363036. ) * pow( _etamu, ( 14. / 23. ) ) - .9135 * pow( _etamu, .4086 ) + .0873 * pow( _etamu, -.423 ) - .0571 * pow( _etamu, -.8994 ) + .0209 * pow( _etamu, .1456 ); _c80mu = c8mWsm * pow( _etamu, ( 14. / 23. ) ) + c8constmu; //Compute the dilogarithm (PolyLog(2,x)) with the Simpson integrator //The dilogarithm is defined as: Li_2(x)=Int_0^x(-log(1.-z)/z) //however, Mathematica implements it as Sum[z^k/k^2,{k,1,Infinity}], so, althought the two //results are similar and both implemented in the program, we prefer to use the //one closer to the Mathematica implementation as identical to what used by the theorists. // EvtItgFunction *myDiLogFunc = new EvtItgFunction(&diLogFunc, 0., 1.-1./xt); //EvtItgAbsIntegrator *myDiLogSimp = new EvtItgSimpsonIntegrator(*myDiLogFunc, 1.0e-4, 50); //double li2 = myDiLogSimp->evaluate(1.0e-20,1.-1./xt); double li2 = diLogMathematica( 1. - 1. / xt ); double c7mWsm1 = ( ( -16. * pow( xt, 4. ) - 122. * pow( xt, 3. ) + 80. * pow( xt, 2. ) - 8. * xt ) / ( 9. * pow( ( xt - 1. ), 4. ) ) * li2 + ( 6. * pow( xt, 4. ) + 46. * pow( xt, 3. ) - 28. * pow( xt, 2. ) ) / ( 3. * pow( ( xt - 1. ), 5. ) ) * pow( log( xt ), 2. ) + ( -102. * pow( xt, 5. ) - 588. * pow( xt, 4. ) - 2262. * pow( xt, 3. ) + 3244. * pow( xt, 2. ) - 1364. * xt + 208. ) / ( 81. * pow( ( xt - 1 ), 5. ) ) * log( xt ) + ( 1646. * pow( xt, 4. ) + 12205. * pow( xt, 3. ) - 10740. * pow( xt, 2. ) + 2509. * xt - 436. ) / ( 486. * pow( ( xt - 1 ), 4. ) ) ); double c8mWsm1 = ( ( -4. * pow( xt, 4. ) + 40. * pow( xt, 3. ) + 41. * pow( xt, 2. ) + xt ) / ( 6. * pow( ( xt - 1. ), 4. ) ) * li2 + ( -17. * pow( xt, 3. ) - 31. * pow( xt, 2. ) ) / ( 2. * pow( ( xt - 1. ), 5. ) ) * pow( log( xt ), 2. ) + ( -210. * pow( xt, 5. ) + 1086. * pow( xt, 4. ) + 4893. * pow( xt, 3. ) + 2857. * pow( xt, 2. ) - 1994. * xt + 280. ) / ( 216. * pow( ( xt - 1 ), 5. ) ) * log( xt ) + ( 737. * pow( xt, 4. ) - 14102. * pow( xt, 3. ) - 28209. * pow( xt, 2. ) + 610. * xt - 508. ) / ( 1296. * pow( ( xt - 1 ), 4. ) ) ); double E1 = ( xt * ( 18. - 11. * xt - pow( xt, 2. ) ) / ( 12. * pow( ( 1. - xt ), 3. ) ) + pow( xt, 2. ) * ( 15. - 16. * xt + 4. * pow( xt, 2. ) ) / ( 6. * pow( ( 1. - xt ), 4. ) ) * log( xt ) - 2. / 3. * log( xt ) ); double e1 = 4661194. / 816831.; double e2 = -8516. / 2217.; double e3 = 0.; double e4 = 0.; double e5 = -1.9043; double e6 = -.1008; double e7 = .1216; double e8 = .0183; double f1 = -17.3023; double f2 = 8.5027; double f3 = 4.5508; double f4 = .7519; double f5 = 2.004; double f6 = .7476; double f7 = -.5385; double f8 = .0914; double g1 = 14.8088; double g2 = -10.809; double g3 = -.874; double g4 = .4218; double g5 = -2.9347; double g6 = .3971; double g7 = .1600; double g8 = .0225; double c71constmu = ( ( e1 * _etamu * E1 + f1 + g1 * _etamu ) * pow( _etamu, ( 14. / 23. ) ) + ( e2 * _etamu * E1 + f2 + g2 * _etamu ) * pow( _etamu, ( 16. / 23. ) ) + ( e3 * _etamu * E1 + f3 + g3 * _etamu ) * pow( _etamu, ( 6. / 23. ) ) + ( e4 * _etamu * E1 + f4 + g4 * _etamu ) * pow( _etamu, ( -12. / 23. ) ) + ( e5 * _etamu * E1 + f5 + g5 * _etamu ) * pow( _etamu, .4086 ) + ( e6 * _etamu * E1 + f6 + g6 * _etamu ) * pow( _etamu, ( -.423 ) ) + ( e7 * _etamu * E1 + f7 + g7 * _etamu ) * pow( _etamu, ( -.8994 ) ) + ( e8 * _etamu * E1 + f8 + g8 * _etamu ) * pow( _etamu, .1456 ) ); double c71pmu = ( ( ( 297664. / 14283. * pow( _etamu, ( 16. / 23. ) ) - 7164416. / 357075. * pow( _etamu, ( 14. / 23. ) ) + 256868. / 14283. * pow( _etamu, ( 37. / 23. ) ) - 6698884. / 357075. * pow( _etamu, ( 39. / 23. ) ) ) * ( c8mWsm ) ) + 37208. / 4761. * ( pow( _etamu, ( 39. / 23. ) ) - pow( _etamu, ( 16. / 23. ) ) ) * ( c7mWsm ) + c71constmu ); _c71mu = ( _alphasmW / _alphasmu * ( pow( _etamu, ( 16. / 23. ) ) * c7mWsm1 + 8. / 3. * ( pow( _etamu, ( 14. / 23. ) ) - pow( _etamu, ( 16. / 23. ) ) ) * c8mWsm1 ) + c71pmu ); _c7emmu = ( ( 32. / 75. * pow( _etamu, ( -9. / 23. ) ) - 40. / 69. * pow( _etamu, ( -7. / 23. ) ) + 88. / 575. * pow( _etamu, ( 16. / 23. ) ) ) * c7mWsm + ( -32. / 575. * pow( _etamu, ( -9. / 23. ) ) + 32. / 1449. * pow( _etamu, ( -7. / 23. ) ) + 640. / 1449. * pow( _etamu, ( 14. / 23. ) ) - 704. / 1725. * pow( _etamu, ( 16. / 23. ) ) ) * c8mWsm - 190. / 8073. * pow( _etamu, ( -35. / 23. ) ) - 359. / 3105. * pow( _etamu, ( -17. / 23. ) ) + 4276. / 121095. * pow( _etamu, ( -12. / 23. ) ) + 350531. / 1009125. * pow( _etamu, ( -9. / 23. ) ) + 2. / 4347. * pow( _etamu, ( -7. / 23. ) ) - 5956. / 15525. * pow( _etamu, ( 6. / 23. ) ) + 38380. / 169533. * pow( _etamu, ( 14. / 23. ) ) - 748. / 8625. * pow( _etamu, ( 16. / 23. ) ) ); // Wilson coefficients values as according to Kagan's program // _c2mu=1.10566; //_c70mu=-0.314292; // _c80mu=-0.148954; // _c71mu=0.480964; // _c7emmu=0.0323219; } void EvtBtoXsgammaKagan::CalcDelta() { double cDelta77 = ( 1. + ( _alphasmu / ( 2. * EvtConst::pi ) ) * ( _r7 - ( 16. / 3. ) + _gam77 * log( _mb / _mu ) ) + ( ( pow( ( 1. - _z ), 4. ) / _fz ) - 1. ) * ( 6. * _lam2 / pow( _mb, 2. ) ) + ( _alphasmubar / ( 2. * EvtConst::pi ) ) * _kappabar ) * pow( _c70mu, 2. ); double cDelta27 = ( ( _alphasmu / ( 2. * EvtConst::pi ) ) * ( _rer2 + _gam27 * log( _mb / _mu ) ) - ( _lam2 / ( 9. * _z * pow( _mb, 2. ) ) ) ) * _c2mu * _c70mu; double cDelta78 = ( _alphasmu / ( 2. * EvtConst::pi ) ) * ( _rer8 + _gam87 * log( _mb / _mu ) ) * _c70mu * _c80mu; _cDeltatot = cDelta77 + cDelta27 + cDelta78 + ( _alphasmu / ( 2. * EvtConst::pi ) ) * _c71mu * _c70mu + ( _alpha / _alphasmu ) * ( 2. * _c7emmu * _c70mu - _kSLemmu * pow( _c70mu, 2. ) ); } double EvtBtoXsgammaKagan::Delta( double y, double alphasMu ) { //Fix for singularity at endpoint if ( y >= 1.0 ) y = 0.9999999999; return ( -4. * ( alphasMu / ( 3. * EvtConst::pi * ( 1. - y ) ) ) * ( log( 1. - y ) + 7. / 4. ) * exp( -2. * ( alphasMu / ( 3. * EvtConst::pi ) ) * ( pow( log( 1. - y ), 2 ) + ( 7. / 2. ) * log( 1. - y ) ) ) ); } double EvtBtoXsgammaKagan::s77( double y ) { //Fix for singularity at endpoint if ( y >= 1.0 ) y = 0.9999999999; return ( ( 1. / 3. ) * ( 7. + y - 2. * pow( y, 2 ) - 2. * ( 1. + y ) * log( 1. - y ) ) ); } double EvtBtoXsgammaKagan::s88( double y, double mb, double ms ) { //Fix for singularity at endpoint if ( y >= 1.0 ) y = 0.9999999999; return ( ( 1. / 27. ) * ( ( 2. * ( 2. - 2. * y + pow( y, 2 ) ) / y ) * ( log( 1. - y ) + 2. * log( mb / ms ) ) - 2. * pow( y, 2 ) - y - 8. * ( ( 1. - y ) / y ) ) ); } double EvtBtoXsgammaKagan::s78( double y ) { //Fix for singularity at endpoint if ( y >= 1.0 ) y = 0.9999999999; return ( ( 8. / 9. ) * ( ( ( 1. - y ) / y ) * log( 1. - y ) + 1. + ( pow( y, 2 ) / 4. ) ) ); } double EvtBtoXsgammaKagan::ReG( double y ) { if ( y < 4. ) return -2. * pow( atan( sqrt( y / ( 4. - y ) ) ), 2. ); else { return 2. * ( pow( log( ( sqrt( y ) + sqrt( y - 4. ) ) / 2. ), 2. ) ) - ( 1. / 2. ) * pow( EvtConst::pi, 2. ); } } double EvtBtoXsgammaKagan::ImG( double y ) { if ( y < 4. ) return 0.0; else { return ( -2. * EvtConst::pi * log( ( sqrt( y ) + sqrt( y - 4. ) ) / 2. ) ); } } double EvtBtoXsgammaKagan::s22Func( double y, const std::vector& coeffs ) { //coeffs[0]=z return ( 1. - y ) * ( ( pow( coeffs[0], 2. ) / pow( y, 2. ) ) * ( pow( ReG( y / coeffs[0] ), 2. ) + pow( ImG( y / coeffs[0] ), 2. ) ) + ( coeffs[0] / y ) * ReG( y / coeffs[0] ) + ( 1. / 4. ) ); } double EvtBtoXsgammaKagan::s27Func( double y, const std::vector& coeffs ) { //coeffs[0] = z return ( ReG( y / coeffs[0] ) + y / ( 2. * coeffs[0] ) ); } double EvtBtoXsgammaKagan::DeltaFermiFunc( double y, const std::vector& coeffs1, const std::vector& coeffs2, const std::vector& coeffs3 ) { //coeffs1=fermi function coeffs, coeffs2[0]=mB, coeffs2[1]=mb, //coeffs2[2]=ymH, coeffs3[0]=DeltaCoeff (alphasmu) return FermiFunc( y, coeffs1 ) * ( coeffs2[0] / ( coeffs2[1] + y ) ) * Delta( ( coeffs2[0] * coeffs2[2] ) / ( coeffs2[1] + y ), coeffs3[0] ); } double EvtBtoXsgammaKagan::s77FermiFunc( double y, const std::vector& coeffs1, const std::vector& coeffs2 ) { //coeffs1=fermi function coeffs, coeffs2[0]=mB, coeffs2[1]=mb, //coeffs2[2]=ymH return FermiFunc( y, coeffs1 ) * ( coeffs2[0] / ( coeffs2[1] + y ) ) * s77( ( coeffs2[0] * coeffs2[2] ) / ( coeffs2[1] + y ) ); } double EvtBtoXsgammaKagan::s88FermiFunc( double y, const std::vector& coeffs1, const std::vector& coeffs2, const std::vector& coeffs3 ) { //coeffs1=fermi function coeffs, coeffs2[0]=mB, coeffs2[1]=mb, //coeffs2[2]=ymH, coeffs3=s88 coeffs return FermiFunc( y, coeffs1 ) * ( coeffs2[0] / ( coeffs2[1] + y ) ) * s88( ( coeffs2[0] * coeffs2[2] ) / ( coeffs2[1] + y ), coeffs3[0], coeffs3[1] ); } double EvtBtoXsgammaKagan::s78FermiFunc( double y, const std::vector& coeffs1, const std::vector& coeffs2 ) { //coeffs1=fermi function coeffs, coeffs2[0]=mB, coeffs2[1]=mb, //coeffs2[2]=ymH return FermiFunc( y, coeffs1 ) * ( coeffs2[0] / ( coeffs2[1] + y ) ) * s78( ( coeffs2[0] * coeffs2[2] ) / ( coeffs2[1] + y ) ); } double EvtBtoXsgammaKagan::sFermiFunc( double y, const std::vector& coeffs1, const std::vector& coeffs2, const std::vector& coeffs3, const std::vector& coeffs4 ) { //coeffs1=fermi function coeffs, coeffs2[0]=mB, coeffs2[1]=mb, //coeffs2[2]=ymH, coeffs3[0]=nIntervals in s22 or s27 array, coeffs3[1]=yMin, //coeffs3[2]=yMax, coeffs4=s22 or s27 array return FermiFunc( y, coeffs1 ) * ( coeffs2[0] / ( coeffs2[1] + y ) ) * GetArrayVal( coeffs2[0] * coeffs2[2] / ( coeffs2[1] + y ), coeffs3[0], coeffs3[1], coeffs3[2], coeffs4 ); } double EvtBtoXsgammaKagan::Fz( double z ) { return ( 1. - 8. * z + 8. * pow( z, 3. ) - pow( z, 4. ) - 12. * pow( z, 2. ) * log( z ) ); } double EvtBtoXsgammaKagan::GetArrayVal( double xp, double nInterval, double xMin, double xMax, std::vector array ) { double dx = ( xMax - xMin ) / nInterval; int bin1 = int( ( ( xp - xMin ) / ( xMax - xMin ) ) * nInterval ); double x1 = double( bin1 ) * dx + xMin; if ( xp == x1 ) return array[bin1]; int bin2( 0 ); if ( xp > x1 ) { bin2 = bin1 + 1; } else if ( xp < x1 ) { bin2 = bin1 - 1; } if ( bin1 <= 0 ) { bin1 = 0; bin2 = 1; } //If xp is in the last bin, always interpolate between the last two bins if ( bin1 == (int)nInterval ) { bin2 = (int)nInterval; bin1 = (int)nInterval - 1; x1 = double( bin1 ) * dx + xMin; } double x2 = double( bin2 ) * dx + xMin; double y1 = array[bin1]; double y2 = array[bin2]; double m = ( y2 - y1 ) / ( x2 - x1 ); double c = y1 - m * x1; double result = m * xp + c; return result; } double EvtBtoXsgammaKagan::FermiFunc( double y, const std::vector& coeffs ) { //Fermi shape functions :1=exponential, 2=gaussian, 3=roman if ( int( coeffs[0] ) == 1 ) return EvtBtoXsgammaFermiUtil::FermiExpFunc( y, coeffs ); if ( int( coeffs[0] ) == 2 ) return EvtBtoXsgammaFermiUtil::FermiGaussFunc( y, coeffs ); if ( int( coeffs[0] ) == 3 ) return EvtBtoXsgammaFermiUtil::FermiRomanFunc( y, coeffs ); return 1.; } double EvtBtoXsgammaKagan::diLogFunc( double y ) { return -log( fabs( 1. - y ) ) / y; } double EvtBtoXsgammaKagan::diLogMathematica( double y ) { double li2( 0 ); for ( int i = 1; i < 1000; i++ ) { //the value 1000 should actually be Infinite... li2 += pow( y, i ) / ( i * i ); } return li2; } diff --git a/src/EvtGenModels/EvtBtoXsgammaRootFinder.cpp b/src/EvtGenModels/EvtBtoXsgammaRootFinder.cpp index f9cdc91..a640994 100644 --- a/src/EvtGenModels/EvtBtoXsgammaRootFinder.cpp +++ b/src/EvtGenModels/EvtBtoXsgammaRootFinder.cpp @@ -1,212 +1,212 @@ /*********************************************************************** * 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/EvtBtoXsgammaRootFinder.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenModels/EvtItgSimpsonIntegrator.hh" #include "EvtGenModels/EvtItgTwoCoeffFcn.hh" #include using std::endl; //------------- // C Headers -- //------------- extern "C" { } //----------------------------------------------------------------------- // Local Macros, Typedefs, Structures, Unions and Forward Declarations -- //----------------------------------------------------------------------- #define EVTITGROOTFINDER_MAXIT 100 #define EVTITGROOTFINDER_RELATIVEPRECISION 1.0e-16 double EvtBtoXsgammaRootFinder::GetRootSingleFunc( const EvtItgAbsFunction* theFunc, double functionValue, double lowerValue, double upperValue, double precision ) { // Use the bisection to find the root. // Iterates until find root to the accuracy of precision double xLower = 0.0, xUpper = 0.0; double root = 0; double f1 = theFunc->value( lowerValue ) - functionValue; double f2 = theFunc->value( upperValue ) - functionValue; if ( f1 * f2 > 0.0 ) { EvtGenReport( EVTGEN_WARNING, "EvtGen" ) << "EvtBtoXsgammaRootFinder: No root in specified range !" << endl; return 0; } // Already have root if ( fabs( f1 ) < precision ) { root = lowerValue; return root; } if ( fabs( f2 ) < precision ) { root = upperValue; return root; } // Orient search so that f(xLower) < 0 if ( f1 < 0.0 ) { xLower = lowerValue; xUpper = upperValue; } else { xLower = upperValue; xUpper = lowerValue; } double rootGuess = 0.5 * ( lowerValue + upperValue ); double dxold = fabs( upperValue - lowerValue ); double dx = dxold; double f = theFunc->value( rootGuess ) - functionValue; for ( int j = 0; j < EVTITGROOTFINDER_MAXIT; j++ ) { dxold = dx; dx = 0.5 * ( xUpper - xLower ); rootGuess = xLower + dx; // If change in root is negligible, take it as solution. if ( fabs( xLower - rootGuess ) < precision ) { root = rootGuess; return root; } f = theFunc->value( rootGuess ) - functionValue; if ( f < 0.0 ) { xLower = rootGuess; } else { xUpper = rootGuess; } } EvtGenReport( EVTGEN_WARNING, "EvtGen" ) << "EvtBtoXsgammaRootFinder: Maximum number of iterations " << "in EvtBtoXsgammaRootFinder::foundRoot exceeded!" << " Returning false." << endl; return 0; } double EvtBtoXsgammaRootFinder::GetGaussIntegFcnRoot( EvtItgAbsFunction* theFunc1, EvtItgAbsFunction* theFunc2, double integ1Precision, double integ2Precision, int maxLoop1, int maxLoop2, double integLower, double integUpper, double lowerValue, double upperValue, double precision ) { // Use the bisection to find the root. // Iterates until find root to the accuracy of precision //Need to work with integrators - auto func1Integ = EvtItgSimpsonIntegrator{*theFunc1, integ1Precision, - maxLoop1}; - auto func2Integ = EvtItgSimpsonIntegrator{*theFunc2, integ2Precision, - maxLoop2}; + auto func1Integ = EvtItgSimpsonIntegrator{ *theFunc1, integ1Precision, + maxLoop1 }; + auto func2Integ = EvtItgSimpsonIntegrator{ *theFunc2, integ2Precision, + maxLoop2 }; //coefficient 1 of the integrators is the root to be found //need to set this to lower value to start off with theFunc1->setCoeff( 1, 0, lowerValue ); theFunc2->setCoeff( 1, 0, lowerValue ); double f1 = func1Integ.evaluate( integLower, integUpper ) - theFunc2->getCoeff( 1, 2 ) * func2Integ.evaluate( integLower, integUpper ); theFunc1->setCoeff( 1, 0, upperValue ); theFunc2->setCoeff( 1, 0, upperValue ); double f2 = func1Integ.evaluate( integLower, integUpper ) - theFunc2->getCoeff( 1, 2 ) * func2Integ.evaluate( integLower, integUpper ); double xLower = 0.0, xUpper = 0.0; double root = 0; if ( f1 * f2 > 0.0 ) { EvtGenReport( EVTGEN_WARNING, "EvtGen" ) << "EvtBtoXsgammaRootFinder: No root in specified range !" << endl; return false; } // Already have root if ( fabs( f1 ) < precision ) { root = lowerValue; return root; } if ( fabs( f2 ) < precision ) { root = upperValue; return root; } // Orient search so that f(xLower) < 0 if ( f1 < 0.0 ) { xLower = lowerValue; xUpper = upperValue; } else { xLower = upperValue; xUpper = lowerValue; } double rootGuess = 0.5 * ( lowerValue + upperValue ); double dxold = fabs( upperValue - lowerValue ); double dx = dxold; theFunc1->setCoeff( 1, 0, rootGuess ); theFunc2->setCoeff( 1, 0, rootGuess ); double f = func1Integ.evaluate( integLower, integUpper ) - theFunc2->getCoeff( 1, 2 ) * func2Integ.evaluate( integLower, integUpper ); for ( int j = 0; j < EVTITGROOTFINDER_MAXIT; j++ ) { dxold = dx; dx = 0.5 * ( xUpper - xLower ); rootGuess = xLower + dx; // If change in root is negligible, take it as solution. if ( fabs( xLower - rootGuess ) < precision ) { root = rootGuess; return root; } theFunc1->setCoeff( 1, 0, rootGuess ); theFunc2->setCoeff( 1, 0, rootGuess ); f = func1Integ.evaluate( integLower, integUpper ) - theFunc2->getCoeff( 1, 2 ) * func2Integ.evaluate( integLower, integUpper ); if ( f < 0.0 ) { xLower = rootGuess; } else { xUpper = rootGuess; } } EvtGenReport( EVTGEN_WARNING, "EvtGen" ) << "EvtBtoXsgammaRootFinder: Maximum number of iterations " << "in EvtBtoXsgammaRootFinder::foundRoot exceeded!" << " Returning false." << endl; return 0; } diff --git a/src/EvtGenModels/EvtFourBodyPhsp.cpp b/src/EvtGenModels/EvtFourBodyPhsp.cpp index 781b4a1..d2d6463 100644 --- a/src/EvtGenModels/EvtFourBodyPhsp.cpp +++ b/src/EvtGenModels/EvtFourBodyPhsp.cpp @@ -1,446 +1,446 @@ /*********************************************************************** * 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 +#include "EvtGenModels/EvtFourBodyPhsp.hh" #include "EvtGenBase/EvtKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" -#include "EvtGenModels/EvtFourBodyPhsp.hh" + +#include std::string EvtFourBodyPhsp::getName() { return "FOURBODYPHSP"; } EvtDecayBase* EvtFourBodyPhsp::clone() { return new EvtFourBodyPhsp; } std::array EvtFourBodyPhsp::phspFactor( const double mM, const double m12, const double m34, std::array& daughters ) const { std::array result; result[1] = twoBodyMomentum( mM, m12, m34 ); result[2] = twoBodyMomentum( m12, daughters[0], daughters[1] ); result[3] = twoBodyMomentum( m34, daughters[2], daughters[3] ); result[0] = result[1] * result[2] * result[3]; return result; } void EvtFourBodyPhsp::init() { // Check that we have right number of daughters checkNDaug( 4 ); // Check whether mother is quasi-stable auto parent = getParentId(); double width = EvtPDL::getWidth( parent ); if ( width > 1e-6 ) { m_stableMother = false; } // Check whether all daughters are stable for ( int i = 0; i < 4; ++i ) { auto daughter = getDaug( i ); width = EvtPDL::getWidth( daughter ); if ( width > 1e-6 ) { m_stableDaughters = false; m_daughterMasses[i] = EvtPDL::getMinMass( daughter ); } else { m_daughterMasses[i] = EvtPDL::getMass( daughter ); } } // check correct number of arguments checkNArg( 0, 2, 4 ); double mass1 = m_daughterMasses[0]; double mass2 = m_daughterMasses[1]; double mass3 = m_daughterMasses[2]; double mass4 = m_daughterMasses[3]; double mMother = EvtPDL::getMaxMass( parent ); if ( getNArg() > 2 ) { m_m12Min = getArg( 0 ); m_m12Max = getArg( 1 ); m_m34Min = getArg( 2 ); m_m34Max = getArg( 3 ); } else { if ( getNArg() > 0 ) { m_m12Min = getArg( 0 ); m_m12Max = getArg( 1 ); } else { m_m12Min = mass1 + mass2; m_m12Max = mMother - mass3 - mass4; } m_m34Min = mass3 + mass4; m_m34Max = mMother - mass1 - mass2; if ( m_stableDaughters == false || m_stableMother == false ) { m_fixedBoundary = false; } } // Make sure that we have correct boundaries if ( m_m12Min < mass1 + mass2 ) { m_m12Min = mass1 + mass2; } if ( m_m12Max > mMother - mass3 - mass4 ) { m_m12Max = mMother - mass3 - mass4; } if ( m_m34Min < mass3 + mass4 ) { m_m34Min = mass3 + mass4; } if ( m_m34Max > mMother - mass1 - mass2 ) { m_m34Max = mMother - mass1 - mass2; } if ( m_stableDaughters && m_stableMother ) { m_boundaryShape = determineBoundaryShape( m_m12Min, m_m12Max, m_m34Max, mMother ); } else { m_boundaryShape = Shape::variable; } // If we have fixed boundary, we can precalculate some variables for // m12 and m34 generation if ( m_fixedBoundary ) { if ( m_boundaryShape == Shape::trapezoid ) { const double m12Diff = m_m12Max - m_m12Min; const double minSum = m_m12Min + m_m34Min; m_trapNorm = ( mMother - m_m34Min ) * m12Diff - 0.5 * ( m12Diff * ( m_m12Max + m_m12Min ) ); m_trapCoeff1 = mMother - m_m34Min; m_trapCoeff2 = mMother * mMother - 2 * mMother * minSum + minSum * minSum; } if ( m_boundaryShape == Shape::pentagon ) { m_pentagonSplit = mMother - m_m34Max; const double area1 = ( m_pentagonSplit - m_m12Min ) * ( m_m34Max - m_m34Min ); const double pm12Diff = m_m12Max - m_pentagonSplit; const double area2 = 0.5 * pm12Diff * ( mMother + m_m34Max - m_m12Max ) - pm12Diff * m_m34Min; m_pentagonFraction = area1 / ( area1 + area2 ); const double m12Diff = m_m12Max - m_pentagonSplit; const double minSum = m_pentagonSplit + m_m34Min; m_trapNorm = ( mMother - m_m34Min ) * m12Diff - 0.5 * ( m12Diff * ( m_m12Max + m_pentagonSplit ) ); m_trapCoeff1 = mMother - m_m34Min; m_trapCoeff2 = mMother * mMother - 2 * mMother * minSum + minSum * minSum; } } } void EvtFourBodyPhsp::initProbMax() { double startM12 = m_m12Min + ( m_m12Max - m_m12Min ) / 20.; double startM34 = m_m34Min + ( m_m34Max - m_m34Min ) / 20.; bool contCond = true; int iteration = 0; auto parent = getParentId(); double mMother = EvtPDL::getMaxMass( parent ); double funcValue = 0; - while (contCond){ + while ( contCond ) { ++iteration; double currentM12 = startM12; double currentM34 = startM34; funcValue = phspFactor( mMother, currentM12, currentM34, m_daughterMasses )[0]; // Maximum along m12 double step = ( m_m12Max - m_m12Min ) / 100.; while ( step > 1e-4 ) { double point1 = currentM12 + step; if ( point1 > m_m12Max ) { point1 = m_m12Max; } if ( currentM34 > mMother - point1 ) { point1 = mMother - currentM34; } double point2 = currentM12 - step; if ( point2 < m_m12Min ) { point2 = m_m12Min; } double value1 = phspFactor( mMother, point1, currentM34, m_daughterMasses )[0]; double value2 = phspFactor( mMother, point2, currentM34, m_daughterMasses )[0]; if ( value1 > funcValue && value1 > value2 ) { currentM12 = point1; funcValue = value1; } else if ( value2 > funcValue ) { currentM12 = point2; funcValue = value2; } step /= 2.; } // Maximum along m34 step = ( mMother - currentM12 - m_m34Min ) / 100.; while ( step > 1e-4 ) { double point1 = currentM34 + step; if ( point1 > m_m34Max ) { point1 = m_m34Max; } if ( point1 > mMother - currentM12 ) { point1 = mMother - currentM12; } double point2 = currentM34 - step; if ( point2 < m_m34Min ) { point2 = m_m34Min; } double value1 = phspFactor( mMother, currentM12, point1, m_daughterMasses )[0]; double value2 = phspFactor( mMother, currentM12, point2, m_daughterMasses )[0]; if ( value1 > funcValue && value1 > value2 ) { currentM34 = point1; funcValue = value1; } else if ( value2 > funcValue ) { currentM34 = point2; funcValue = value2; } step /= 2.; } // Check termination condition - double m12Diff = currentM12 - startM12; - double m34Diff = currentM34 - startM34; - double distSq = m12Diff * m12Diff + m34Diff * m34Diff; - if (distSq < 1e-8 || iteration > 50){ - contCond = false; - } - startM12 = currentM12; - startM34 = currentM34; + double m12Diff = currentM12 - startM12; + double m34Diff = currentM34 - startM34; + double distSq = m12Diff * m12Diff + m34Diff * m34Diff; + if ( distSq < 1e-8 || iteration > 50 ) { + contCond = false; + } + startM12 = currentM12; + startM34 = currentM34; } setProbMax( funcValue * 1.05 ); } void EvtFourBodyPhsp::decay( EvtParticle* parent ) { - parent->makeDaughters( getNDaug(), getDaugs() ); bool massTreeStatus = parent->generateMassTree(); if ( !massTreeStatus ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Failed to generate daughters masses in EvtFourBodyPhsp." << std::endl; ::abort(); } double mMother = parent->mass(); // Need to check whether boundaries are OK and whether we need to work // out boundary shape double cM12Min, cM12Max; double cM34Min, cM34Max; EvtFourBodyPhsp::Shape cShape; if ( m_fixedBoundary ) { cM12Min = m_m12Min; cM12Max = m_m12Max; cM34Min = m_m34Min; cM34Max = m_m34Max; cShape = m_boundaryShape; } else { // In this case at least one particle has non-zero width and thus // boundaries and shape of the region can change for ( int i = 0; i < 4; ++i ) { auto daughter = parent->getDaug( i ); m_daughterMasses[i] = daughter->mass(); } cM12Min = m_m12Min > ( m_daughterMasses[0] + m_daughterMasses[1] ) ? m_m12Min : m_daughterMasses[0] + m_daughterMasses[1]; cM12Max = m_m12Max < ( mMother - m_daughterMasses[2] - m_daughterMasses[3] ) ? m_m12Max : mMother - m_daughterMasses[2] - m_daughterMasses[3]; cM34Min = m_m34Min > ( m_daughterMasses[2] + m_daughterMasses[3] ) ? m_m34Min : m_daughterMasses[2] + m_daughterMasses[3]; cM34Max = m_m34Max < ( mMother - m_daughterMasses[0] - m_daughterMasses[1] ) ? m_m34Max : mMother - m_daughterMasses[0] - m_daughterMasses[1]; cShape = determineBoundaryShape( cM12Min, cM12Max, cM34Max, mMother ); } // Generate m12 and m34 auto masses = generatePairMasses( cM12Min, cM12Max, cM34Min, cM34Max, mMother, cShape ); const double m12 = masses.first; const double m34 = masses.second; // calculate probability, it will return array with 4 elements with // probability, q, p1 and p3 auto probEval = phspFactor( mMother, m12, m34, m_daughterMasses ); setProb( probEval[0] ); // initialise kinematics - const double cosTheta1 = EvtRandom::Flat(-1.0, 1.0); + const double cosTheta1 = EvtRandom::Flat( -1.0, 1.0 ); const double sinTheta1 = std::sqrt( 1 - cosTheta1 * cosTheta1 ); - const double cosTheta3 = EvtRandom::Flat(-1.0, 1.0); + const double cosTheta3 = EvtRandom::Flat( -1.0, 1.0 ); const double sinTheta3 = std::sqrt( 1 - cosTheta3 * cosTheta3 ); const double phi = EvtRandom::Flat( 0., EvtConst::twoPi ); // m12 and m34 are put along z-axis, 1 and 2 go to x-z plane and 3-4 // plane is rotated by phi compared to 1-2 plane. All momenta are set // in 12 and 34 rest frames and then boosted to parent rest frame const double p1x = probEval[2] * sinTheta1; const double p1z = probEval[2] * cosTheta1; const double p1Sq = probEval[2] * probEval[2]; const double en1 = std::sqrt( m_daughterMasses[0] * m_daughterMasses[0] + p1Sq ); const double en2 = std::sqrt( m_daughterMasses[1] * m_daughterMasses[1] + p1Sq ); const double p3T = probEval[3] * sinTheta3; const double p3x = p3T * std::cos( phi ); const double p3y = p3T * std::sin( phi ); const double p3z = probEval[3] * cosTheta3; const double p3Sq = probEval[3] * probEval[3]; const double en3 = std::sqrt( m_daughterMasses[2] * m_daughterMasses[2] + p3Sq ); const double en4 = std::sqrt( m_daughterMasses[3] * m_daughterMasses[3] + p3Sq ); EvtVector4R mom1( en1, p1x, 0.0, p1z ); EvtVector4R mom2( en2, -p1x, 0.0, -p1z ); EvtVector4R mom3( en3, p3x, p3y, p3z ); EvtVector4R mom4( en4, -p3x, -p3y, -p3z ); const double qSq = probEval[1] * probEval[1]; const double en12 = std::sqrt( m12 * m12 + qSq ); const double en34 = std::sqrt( m34 * m34 + qSq ); EvtVector4R q12( en12, 0.0, 0.0, probEval[1] ); EvtVector4R q34( en34, 0.0, 0.0, -probEval[1] ); mom1.applyBoostTo( q12 ); mom2.applyBoostTo( q12 ); mom3.applyBoostTo( q34 ); mom4.applyBoostTo( q34 ); // As final step, rotate everything randomly in space const double euler1 = EvtRandom::Flat( 0., EvtConst::twoPi ); const double euler2 = std::acos( EvtRandom::Flat( -1.0, 1.0 ) ); const double euler3 = EvtRandom::Flat( 0., EvtConst::twoPi ); mom1.applyRotateEuler( euler1, euler2, euler3 ); mom2.applyRotateEuler( euler1, euler2, euler3 ); mom3.applyRotateEuler( euler1, euler2, euler3 ); mom4.applyRotateEuler( euler1, euler2, euler3 ); // Set momenta for daughters auto daug = parent->getDaug( 0 ); daug->init( daug->getId(), mom1 ); daug = parent->getDaug( 1 ); daug->init( daug->getId(), mom2 ); daug = parent->getDaug( 2 ); daug->init( daug->getId(), mom3 ); daug = parent->getDaug( 3 ); daug->init( daug->getId(), mom4 ); } EvtFourBodyPhsp::Shape EvtFourBodyPhsp::determineBoundaryShape( const double m12Min, const double m12Max, const double m34Max, const double mMother ) const { double maxY = mMother - m12Min; const bool corner1 = m34Max < maxY; maxY = mMother - m12Max; const bool corner2 = m34Max < maxY; if ( corner1 && corner2 ) { return Shape::rectangle; } else if ( !corner1 && !corner2 ) { return Shape::trapezoid; } return Shape::pentagon; } std::pair EvtFourBodyPhsp::generatePairMasses( const double m12Min, const double m12Max, const double m34Min, const double m34Max, const double mMother, const EvtFourBodyPhsp::Shape shape ) const { switch ( shape ) { case EvtFourBodyPhsp::Shape::rectangle: return generateRectangle( m12Min, m12Max, m34Min, m34Max ); break; case EvtFourBodyPhsp::Shape::trapezoid: return generateTrapezoid( m12Min, m12Max, m34Min, mMother ); break; case EvtFourBodyPhsp::Shape::pentagon: double split, fraction; if ( m_fixedBoundary ) { split = m_pentagonSplit; fraction = m_pentagonFraction; } else { split = mMother - m34Max; const double area1 = ( split - m12Min ) * ( m34Max - m34Min ); const double pm12Diff = m12Max - split; const double area2 = 0.5 * pm12Diff * ( mMother + m34Max - m12Max ) - pm12Diff * m34Min; fraction = area1 / ( area1 + area2 ); } if ( EvtRandom::Flat() < fraction ) { return generateRectangle( m12Min, split, m34Min, m34Max ); } else { return generateTrapezoid( split, m12Max, m34Min, mMother ); } break; default: return std::make_pair( m12Min, m34Min ); break; } } std::pair EvtFourBodyPhsp::generateRectangle( const double m12Min, const double m12Max, const double m34Min, const double m34Max ) const { return std::make_pair( EvtRandom::Flat( m12Min, m12Max ), EvtRandom::Flat( m34Min, m34Max ) ); } std::pair EvtFourBodyPhsp::generateTrapezoid( const double m12Min, const double m12Max, const double m34Min, const double mMother ) const { double norm, coeff1, coeff2; if ( m_fixedBoundary ) { norm = m_trapNorm; coeff1 = m_trapCoeff1; coeff2 = m_trapCoeff2; } else { const double m12Diff = m12Max - m12Min; const double minSum = m12Min + m34Min; norm = ( mMother - m34Min ) * m12Diff - 0.5 * ( m12Diff * ( m12Max + m12Min ) ); coeff1 = mMother - m34Min; coeff2 = mMother * mMother - 2 * mMother * minSum + minSum * minSum; } const double rnd = EvtRandom::Flat(); const double m12 = coeff1 - std::sqrt( -2.0 * rnd * norm + coeff2 ); const double m34 = EvtRandom::Flat( m34Min, mMother - m12 ); return std::make_pair( m12, m34 ); } diff --git a/src/EvtGenModels/EvtLambdacPHH.cpp b/src/EvtGenModels/EvtLambdacPHH.cpp index b3ce018..98c0af3 100644 --- a/src/EvtGenModels/EvtLambdacPHH.cpp +++ b/src/EvtGenModels/EvtLambdacPHH.cpp @@ -1,681 +1,681 @@ /*********************************************************************** * 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/EvtLambdacPHH.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSpinType.hh" #include "EvtGenBase/EvtdFunction.hh" #include #include #include EvtLambdacPHH::EvtLambdacPHH() : _d1( 0 ), _d2( 1 ), _d3( 3 ), _Nplusplus( 0.46 ), _Nplusminus( 1.0 ), _Nminusplus( 0.18 ), _Nminusminus( 0.94 ), _phiNplusplus( 3.48 ), _phiNplusminus( 0.00 ), _phiNminusplus( 0.75 ), _phiNminusminus( 1.13 ), _E1( 0.52 ), _phiE1( -1.01 ), _E2( 0.20 ), _phiE2( 2.35 ), _E3( 0.21 ), _phiE3( 3.46 ), _E4( 0.16 ), _phiE4( 5.29 ), _F1( 0.17 ), _phiF1( 4.98 ), _F2( 0.38 ), _phiF2( 4.88 ), _H1( 0.18 ), _phiH1( 5.93 ), _H2( 0.20 ), _phiH2( -0.06 ), _NRNorm( 1.0 ), _KstarNorm( 1.0 ), _DeltaNorm( 1.0 ), _LambdaNorm( 1.0 ), _KstarM( 0.890 ), _KstarW( 0.0498 ), _KstarR( 3.40 ), _DeltaM( 1.232 ), _DeltaW( 0.1120 ), _DeltaR( 5.22 ), _LambdaM( 1.520 ), _LambdaW( 0.0156 ), _LambdaR( 6.29 ), _Lambda_cR( 5.07 ), _zprime(), _p4_Lambda_c(), _zpMag( 0.0 ), _p4_Lambdac_Mag( 0.0 ) { // Fermilab E791 values from MINUIT fit arXiv:hep-ex/9912003v1 } std::string EvtLambdacPHH::getName() { return "LAMBDAC_PHH"; } EvtDecayBase* EvtLambdacPHH::clone() { return new EvtLambdacPHH; } bool compareId( const std::pair& left, const std::pair& right ) { // Compare id numbers to achieve the ordering K-, pi+ and p bool result( false ); int leftPDGid = EvtPDL::getStdHep( left.first ); int rightPDGid = EvtPDL::getStdHep( right.first ); if ( leftPDGid < rightPDGid ) { result = true; } return result; } void EvtLambdacPHH::init() { static EvtId KM = EvtPDL::getId( "K-" ); static EvtId PIP = EvtPDL::getId( "pi+" ); static EvtId LAMBDAC = EvtPDL::getId( "Lambda_c+" ); static EvtId LAMBDACB = EvtPDL::getId( "anti-Lambda_c-" ); static EvtId PROTON = EvtPDL::getId( "p+" ); // check that there are 0 or 1 arguments and 3 daughters checkNArg( 0, 1 ); checkNDaug( 3 ); EvtId parnum = getParentId(); checkSpinParent( EvtSpinType::DIRAC ); checkSpinDaughter( 0, EvtSpinType::DIRAC ); checkSpinDaughter( 1, EvtSpinType::SCALAR ); checkSpinDaughter( 2, EvtSpinType::SCALAR ); std::vector> daughters; if ( parnum == LAMBDAC ) { for ( int i = 0; i < 3; ++i ) { daughters.push_back( std::make_pair( getDaug( i ), i ) ); } } else { for ( int i = 0; i < 3; ++i ) { daughters.push_back( std::make_pair( EvtPDL::chargeConj( getDaug( i ) ), i ) ); } } // Sort daughters, they will end up in the order KM, PIP and PROTON std::sort( daughters.begin(), daughters.end(), compareId ); if ( parnum == LAMBDAC || parnum == LAMBDACB ) { if ( daughters[0].first == KM && daughters[1].first == PIP && daughters[2].first == PROTON ) { _d1 = daughters[0].second; _d2 = daughters[1].second; _d3 = daughters[2].second; } } // Find resonance dynamics normalisations calcNormalisations(); // Print out expected fit fractions getFitFractions(); } void EvtLambdacPHH::calcNormalisations() { // Generate events uniform in the Lambda_c Dalitz plot and find the // normalisation integrals of the Breit-Wigner lineshapes // Lambda_c -> K- pi+ p int nDaug( 3 ); EvtVector4R p4Daug[3]; - double mDaug[3] = {EvtPDL::getMeanMass( EvtPDL::getId( "K-" ) ), - EvtPDL::getMeanMass( EvtPDL::getId( "pi+" ) ), - EvtPDL::getMeanMass( EvtPDL::getId( "p+" ) )}; + double mDaug[3] = { EvtPDL::getMeanMass( EvtPDL::getId( "K-" ) ), + EvtPDL::getMeanMass( EvtPDL::getId( "pi+" ) ), + EvtPDL::getMeanMass( EvtPDL::getId( "p+" ) ) }; - double norm[3] = {0.0, 0.0, 0.0}; + double norm[3] = { 0.0, 0.0, 0.0 }; // sample size int N( 100000 ); for ( int i = 0; i < N; i++ ) { double mParent = EvtPDL::getMass( EvtPDL::getId( "Lambda_c+" ) ); EvtVector4R p0( mParent, 0.0, 0.0, 0.0 ); // Generate uniform 4 momenta EvtGenKine::PhaseSpace( nDaug, mDaug, p4Daug, mParent ); EvtResonance2 LambdacpKpi1( p0, p4Daug[0], p4Daug[1], 1.0, 0.0, _KstarW, _KstarM, 1, true, _KstarR, _Lambda_cR ); // K*0 -> K- and pi+; L = 1 EvtResonance2 LambdacpKpi2( p0, p4Daug[2], p4Daug[1], 1.0, 0.0, _DeltaW, _DeltaM, 1, true, _DeltaR, _Lambda_cR ); // Delta++ -> p and pi+; L = 1 EvtResonance2 LambdacpKpi3( p0, p4Daug[2], p4Daug[0], 1.0, 0.0, _LambdaW, _LambdaM, 2, true, _LambdaR, _Lambda_cR ); // Lambda(1520) -> K- and p; L = 2 // Sum amplitude magnitude squared norm[0] += abs2( LambdacpKpi1.resAmpl() ); norm[1] += abs2( LambdacpKpi2.resAmpl() ); norm[2] += abs2( LambdacpKpi3.resAmpl() ); } // Set normalisation lineshape multiplication factors double N0( N * 1.0 ); // Scale NR to get sensible relative fit fractions _NRNorm = 1.0 / 3.0; // Set this using a decay file parameter if required if ( getNArg() > 1 ) { _NRNorm = getArg( 1 ); } if ( norm[0] > 0.0 ) { _KstarNorm = sqrt( N0 / norm[0] ); } if ( norm[1] > 0.0 ) { _DeltaNorm = sqrt( N0 / norm[1] ); } if ( norm[2] > 0.0 ) { _LambdaNorm = sqrt( N0 / norm[2] ); } } void EvtLambdacPHH::getFitFractions() { // Generate events uniform in the Lambda_c Dalitz plot and find the // fit fractions for each resonance // Lambda_c -> K- pi+ p int nDaug( 3 ); EvtVector4R p4Daug[3]; - double mDaug[3] = {EvtPDL::getMeanMass( EvtPDL::getId( "K-" ) ), - EvtPDL::getMeanMass( EvtPDL::getId( "pi+" ) ), - EvtPDL::getMeanMass( EvtPDL::getId( "p+" ) )}; + double mDaug[3] = { EvtPDL::getMeanMass( EvtPDL::getId( "K-" ) ), + EvtPDL::getMeanMass( EvtPDL::getId( "pi+" ) ), + EvtPDL::getMeanMass( EvtPDL::getId( "p+" ) ) }; - double FitFracTop[4] = {0.0, 0.0, 0.0, 0.0}; + double FitFracTop[4] = { 0.0, 0.0, 0.0, 0.0 }; double FitFracDenom = 0.0; // sample size int N( 100000 ); for ( int i = 0; i < N; i++ ) { double mParent = EvtPDL::getMass( EvtPDL::getId( "Lambda_c+" ) ); EvtVector4R p0( mParent, 0.0, 0.0, 0.0 ); // Generate uniform 4 momenta EvtGenKine::PhaseSpace( nDaug, mDaug, p4Daug, mParent ); EvtResonance2 LambdacpKpi0( p0, p4Daug[0], p4Daug[1], 1.0, 0.0, 0.0, 0.0, 0, true, 0.0, 0.0 ); // Non resonant (NR) EvtResonance2 LambdacpKpi1( p0, p4Daug[0], p4Daug[1], 1.0, 0.0, _KstarW, _KstarM, 1, true, _KstarR, _Lambda_cR ); // K*0 -> K- and pi+; L = 1 EvtResonance2 LambdacpKpi2( p0, p4Daug[2], p4Daug[1], 1.0, 0.0, _DeltaW, _DeltaM, 1, true, _DeltaR, _Lambda_cR ); // Delta++ -> p and pi+; L = 1 EvtResonance2 LambdacpKpi3( p0, p4Daug[2], p4Daug[0], 1.0, 0.0, _LambdaW, _LambdaM, 2, true, _LambdaR, _Lambda_cR ); // Lambda(1520) -> K- and p; L = 2 std::vector ampNonRes = calcResAmpTerms( EvtLambdacPHH::NonReson, LambdacpKpi0, _NRNorm ); std::vector ampKstar = calcResAmpTerms( EvtLambdacPHH::Kstar, LambdacpKpi1, _KstarNorm ); std::vector ampDelta = calcResAmpTerms( EvtLambdacPHH::Delta, LambdacpKpi2, _DeltaNorm ); std::vector ampLambda = calcResAmpTerms( EvtLambdacPHH::Lambda, LambdacpKpi3, _LambdaNorm ); // Combine resonance amplitudes for a given spin configuration EvtComplex amp00 = ampNonRes[0] + ampKstar[0] + ampDelta[0] + ampLambda[0]; EvtComplex amp01 = ampNonRes[1] + ampKstar[1] + ampDelta[1] + ampLambda[1]; EvtComplex amp10 = ampNonRes[2] + ampKstar[2] + ampDelta[2] + ampLambda[2]; EvtComplex amp11 = ampNonRes[3] + ampKstar[3] + ampDelta[3] + ampLambda[3]; // Fit fraction numerator terms FitFracTop[0] += abs2( ampNonRes[0] ) + abs2( ampNonRes[1] ) + abs2( ampNonRes[2] ) + abs2( ampNonRes[3] ); FitFracTop[1] += abs2( ampKstar[0] ) + abs2( ampKstar[1] ) + abs2( ampKstar[2] ) + abs2( ampKstar[3] ); FitFracTop[2] += abs2( ampDelta[0] ) + abs2( ampDelta[1] ) + abs2( ampDelta[2] ) + abs2( ampDelta[3] ); FitFracTop[3] += abs2( ampLambda[0] ) + abs2( ampLambda[1] ) + abs2( ampLambda[2] ) + abs2( ampLambda[3] ); // Fit fraction common denominator FitFracDenom += abs2( amp00 ) + abs2( amp01 ) + abs2( amp10 ) + abs2( amp11 ); } EvtGenReport( EVTGEN_INFO, "EvtLambdacPHH" ) << "FitFracs: NR = " << FitFracTop[0] / FitFracDenom << ", K* = " << FitFracTop[1] / FitFracDenom << ", Del = " << FitFracTop[2] / FitFracDenom << ", Lam = " << FitFracTop[3] / FitFracDenom << std::endl; } void EvtLambdacPHH::initProbMax() { // Default value setProbMax( 10.0 ); // Set probability using decay file parameter if ( getNArg() > 0 ) { setProbMax( getArg( 0 ) ); } } void EvtLambdacPHH::decay( EvtParticle* p ) { // Daughter order: 1 = K-, 2 = pi+, 3 = p p->initializePhaseSpace( getNDaug(), getDaugs() ); // 4-momenta in the rest frame of the Lambda_c EvtVector4R p4_p( p->mass(), 0.0, 0.0, 0.0 ); EvtVector4R moms1 = p->getDaug( _d1 )->getP4(); EvtVector4R moms2 = p->getDaug( _d2 )->getP4(); EvtVector4R moms3 = p->getDaug( _d3 )->getP4(); // Lambda_c decay mode resonances. Spin L values from strong decay parity conservation: // parity(resonance) = parity(daug1)*parity(daug2)*(-1)^L EvtResonance2 LambdacpKpi0( p4_p, moms1, moms2, 1.0, 0.0, 0.0, 0.0, 0, true, 0.0, 0.0 ); // Non-resonant L = 0 EvtResonance2 LambdacpKpi1( p4_p, moms1, moms2, 1.0, 0.0, _KstarW, _KstarM, 1, true, _KstarR, _Lambda_cR ); // K*0 -> K- and pi+; L = 1 EvtResonance2 LambdacpKpi2( p4_p, moms3, moms2, 1.0, 0.0, _DeltaW, _DeltaM, 1, true, _DeltaR, _Lambda_cR ); // Delta++ -> p and pi+; L = 1 EvtResonance2 LambdacpKpi3( p4_p, moms3, moms1, 1.0, 0.0, _LambdaW, _LambdaM, 2, true, _LambdaR, _Lambda_cR ); // Lambda(1520) -> K- and p; L = 2 // Define the "beam" direction, used in Fig 1 of hep-ex/9912003v1 EvtVector4R beam( 0.0, 0.0, 0.0, 1.0 ); EvtParticle* parent = p->getParent(); if ( parent ) { // If non prompt, the beam is along the direction of the mother EvtVector4R p4_Lambda_c_mother = parent->getP4Lab(); p4_Lambda_c_mother.applyBoostTo( p->getP4Lab() ); beam = p4_Lambda_c_mother; } _p4_Lambda_c = p->getP4Lab(); _p4_Lambdac_Mag = _p4_Lambda_c.d3mag(); // Define the unit vector denoting the "z" axis in Fig 1 _zprime = -1.0 * _p4_Lambda_c.cross( beam ); _zprime.applyBoostTo( _p4_Lambda_c, true ); // From lab frame to Lambda_c _zpMag = _zprime.d3mag(); // Check if zprime magnitude is non-zero if ( _zpMag > 0.0 ) { // Normalise _zprime /= _zpMag; } else { // Set as the z direction _zprime.set( 0.0, 0.0, 0.0, 1.0 ); } // Update normalised |z'| _zpMag = 1.0; // Get the amplitudes: non-resonant, K*, Delta and Lambda std::vector ampNonRes = calcResAmpTerms( EvtLambdacPHH::NonReson, LambdacpKpi0, _NRNorm ); std::vector ampKstar = calcResAmpTerms( EvtLambdacPHH::Kstar, LambdacpKpi1, _KstarNorm ); std::vector ampDelta = calcResAmpTerms( EvtLambdacPHH::Delta, LambdacpKpi2, _DeltaNorm ); std::vector ampLambda = calcResAmpTerms( EvtLambdacPHH::Lambda, LambdacpKpi3, _LambdaNorm ); // Combine resonance amplitudes for a given spin configuration EvtComplex amp00 = ampNonRes[0] + ampKstar[0] + ampDelta[0] + ampLambda[0]; EvtComplex amp01 = ampNonRes[1] + ampKstar[1] + ampDelta[1] + ampLambda[1]; EvtComplex amp10 = ampNonRes[2] + ampKstar[2] + ampDelta[2] + ampLambda[2]; EvtComplex amp11 = ampNonRes[3] + ampKstar[3] + ampDelta[3] + ampLambda[3]; // Set the amplitude components vertex( 0, 0, amp00 ); vertex( 0, 1, amp01 ); vertex( 1, 0, amp10 ); vertex( 1, 1, amp11 ); } std::vector EvtLambdacPHH::calcResAmpTerms( EvtLambdacPHH::LcResLabel resIndex, const EvtResonance2& res, double norm ) const { // Initialise the resonance and daughter theta and phi angles double thetaRes( 0.0 ), phiRes( 0.0 ), phiPrimeDaug( 0.0 ), thetaPrimeDaug( 0.0 ); // Initialise beta rotation angle double beta_res( 0.0 ); EvtVector4R res_atproton( 0.0, 0.0, 0.0, 0.0 ), Lc_atproton( 0.0, 0.0, 0.0, 0.0 ); // Initialise Amplitude terms EvtComplex term1( 0.0 ), term2( 0.0 ), term3( 0.0 ), term4( 0.0 ); // Normalised dynamical amplitude EvtComplex resAmp( norm, 0.0 ); // Angles are not needed for the non-resonant amplitude if ( resIndex != EvtLambdacPHH::NonReson ) { resAmp = res.resAmpl() * norm; // Resonance and daughter 4 momenta EvtVector4R p4d1 = res.p4_d1(); EvtVector4R p4d2 = res.p4_d2(); EvtVector4R p4Res = p4d1 + p4d2; EvtVector4R p4_d3 = res.p4_p() - p4Res; double p4ResMag = p4Res.d3mag(); // 4-momenta for theta' and phi' angles EvtVector4R yRes = -1.0 * p4_d3.cross( _zprime ); EvtVector4R res_d1 = p4d1; res_d1.applyBoostTo( p4Res, true ); double res_d1_Mag = res_d1.d3mag(); EvtVector4R res_d3 = -1.0 * p4_d3; double res_d3_Mag = res_d3.d3mag(); thetaPrimeDaug = getACos( res_d1.dot( res_d3 ), res_d1_Mag * res_d3_Mag ); res_atproton = p4Res; res_atproton.applyBoostTo( p4d1, true ); double res_atproton_mag = res_atproton.d3mag(); Lc_atproton = res.p4_p(); Lc_atproton.applyBoostTo( p4d1, true ); double Lc_atproton_mag = Lc_atproton.d3mag(); // Check that the momentum of the Lambda_c is not zero, as well as a valid zprime vector if ( _p4_Lambdac_Mag > 0.0 && _zpMag > 0.0 ) { thetaRes = getACos( -1.0 * p4Res.dot( _zprime ), p4ResMag ); phiRes = getASin( -1.0 * p4Res.dot( _p4_Lambda_c ), sin( thetaRes ) * _p4_Lambdac_Mag * p4ResMag ); phiPrimeDaug = getASin( res_d1.dot( yRes ), sin( thetaPrimeDaug ) * res_d1_Mag * yRes.d3mag() ); } else { // Use randomised angles with flat probability distributions thetaRes = EvtRandom::Flat( 0.0, EvtConst::pi ); phiRes = EvtRandom::Flat( 0.0, EvtConst::twoPi ); phiPrimeDaug = EvtRandom::Flat( 0.0, EvtConst::twoPi ); } if ( res_atproton_mag > 0.0 && Lc_atproton_mag > 0.0 ) { // Extra rotation to go to the proton helicity frame for the two resonances Delta++ and Lambda. // No rotation is needed for K*. Use the momenta boosted to the proton restframe beta_res = getACos( res_atproton.dot( Lc_atproton ), res_atproton_mag * Lc_atproton_mag ); } else { beta_res = EvtRandom::Flat( 0.0, EvtConst::pi ); } } // Find the spin-dependent amplitudes if ( resIndex == EvtLambdacPHH::NonReson || resIndex == EvtLambdacPHH::Kstar ) { term1 = resAmp * DecayAmp3( resIndex, 1, 1, thetaRes, phiRes, thetaPrimeDaug, phiPrimeDaug ); term2 = resAmp * DecayAmp3( resIndex, 1, -1, thetaRes, phiRes, thetaPrimeDaug, phiPrimeDaug ); term3 = resAmp * DecayAmp3( resIndex, -1, 1, thetaRes, phiRes, thetaPrimeDaug, phiPrimeDaug ); term4 = resAmp * DecayAmp3( resIndex, -1, -1, thetaRes, phiRes, thetaPrimeDaug, phiPrimeDaug ); } else { double rotate_00 = EvtdFunction::d( 1, 1, 1, beta_res ); double rotate_10 = EvtdFunction::d( 1, -1, 1, beta_res ); double rotate_11 = EvtdFunction::d( 1, -1, -1, beta_res ); double rotate_01 = EvtdFunction::d( 1, 1, -1, beta_res ); // Delta and Lambda need to be rotated before summing over the proton helicity axis EvtComplex termA = resAmp * DecayAmp3( resIndex, 1, 1, thetaRes, phiRes, thetaPrimeDaug, phiPrimeDaug ); EvtComplex termB = resAmp * DecayAmp3( resIndex, 1, -1, thetaRes, phiRes, thetaPrimeDaug, phiPrimeDaug ); EvtComplex termC = resAmp * DecayAmp3( resIndex, -1, 1, thetaRes, phiRes, thetaPrimeDaug, phiPrimeDaug ); EvtComplex termD = resAmp * DecayAmp3( resIndex, -1, -1, thetaRes, phiRes, thetaPrimeDaug, phiPrimeDaug ); term1 = rotate_00 * termA + rotate_10 * termB; term2 = rotate_01 * termA + rotate_11 * termB; term3 = rotate_00 * termC + rotate_10 * termD; term4 = rotate_01 * termC + rotate_11 * termD; } // Return the spin amplitudes as a vector std::vector ampVect; ampVect.push_back( term1 ); ampVect.push_back( term2 ); ampVect.push_back( term3 ); ampVect.push_back( term4 ); return ampVect; } EvtComplex EvtLambdacPHH::DecayAmp3( EvtLambdacPHH::LcResLabel resonance, int m, int mprime, double theta_res, double phi_res, double theta_prime_daughter_res, double phi_prime_daughter_res ) const { // Find the amplitudes given in Tables 3 to 6 in the paper. // Wigner d-functions use 2*spin, e.g. d(1/2, 1/2, 1/2) -> d(1, 1, 1) EvtComplex term1( 0.0, 0.0 ), term2( 0.0, 0.0 ); if ( resonance == EvtLambdacPHH::NonReson ) { // Non-resonant: table 6 if ( m == 1 && mprime == 1 ) { term1 = _Nplusplus * EvtComplex( cos( _phiNplusplus ), sin( _phiNplusplus ) ); } else if ( m == 1 && mprime == -1 ) { term1 = _Nplusminus * EvtComplex( cos( _phiNplusminus ), sin( _phiNplusminus ) ); } else if ( m == -1 && mprime == 1 ) { term1 = _Nminusplus * EvtComplex( cos( _phiNminusplus ), sin( _phiNminusplus ) ); } else if ( m == -1 && mprime == -1 ) { term1 = _Nminusminus * EvtComplex( cos( _phiNminusminus ), sin( _phiNminusminus ) ); } } else if ( resonance == EvtLambdacPHH::Kstar ) { // K*0(1-) resonance: table 3 if ( m == 1 && mprime == 1 ) { term1 = fampl3( _E1, _phiE1, 1, 1, 1, theta_res, 2, 2, 0, theta_prime_daughter_res, phi_prime_daughter_res ); term2 = fampl3( _E2, _phiE2, 1, 1, -1, theta_res, 2, 0, 0, theta_prime_daughter_res, phi_res ); } else if ( m == 1 && mprime == -1 ) { term1 = fampl3( _E3, _phiE3, 1, 1, 1, theta_res, 2, 0, 0, theta_prime_daughter_res, 0.0 ); term2 = fampl3( _E4, _phiE4, 1, 1, -1, theta_res, 2, -2, 0, theta_prime_daughter_res, phi_res - phi_prime_daughter_res ); } else if ( m == -1 && mprime == 1 ) { term1 = fampl3( _E1, _phiE1, 1, -1, 1, theta_res, 2, 2, 0, theta_prime_daughter_res, -( phi_res - phi_prime_daughter_res ) ); term2 = fampl3( _E2, _phiE2, 1, -1, -1, theta_res, 2, 0, 0, theta_prime_daughter_res, 0.0 ); } else if ( m == -1 && mprime == -1 ) { term1 = fampl3( _E3, _phiE3, 1, -1, 1, theta_res, 2, 0, 0, theta_prime_daughter_res, -phi_res ); term2 = fampl3( _E4, _phiE4, 1, -1, -1, theta_res, 2, -2, 0, theta_prime_daughter_res, -phi_prime_daughter_res ); } } else if ( resonance == EvtLambdacPHH::Delta ) { // Delta++(3/2+) resonance: table 4 if ( m == 1 && mprime == 1 ) { term1 = fampl3( _F1, _phiF1, 1, 1, 1, theta_res, 3, 1, 1, theta_prime_daughter_res, 0.0 ); term2 = fampl3( _F2, _phiF2, 1, 1, -1, theta_res, 3, -1, 1, theta_prime_daughter_res, phi_res - phi_prime_daughter_res ); } else if ( m == 1 && mprime == -1 ) { term1 = fampl3( _F1, _phiF1, 1, 1, 1, theta_res, 3, 1, -1, theta_prime_daughter_res, phi_prime_daughter_res ); term2 = fampl3( _F2, _phiF2, 1, 1, -1, theta_res, 3, -1, -1, theta_prime_daughter_res, phi_res ); } else if ( m == -1 && mprime == 1 ) { term1 = fampl3( _F1, _phiF1, 1, -1, 1, theta_res, 3, 1, 1, theta_prime_daughter_res, -phi_res ); term2 = fampl3( _F2, _phiF2, 1, -1, -1, theta_res, 3, -1, 1, theta_prime_daughter_res, -phi_prime_daughter_res ); } else if ( m == -1 && mprime == -1 ) { term1 = fampl3( _F1, _phiF1, 1, -1, 1, theta_res, 3, 1, -1, theta_prime_daughter_res, -( phi_res - phi_prime_daughter_res ) ); term2 = fampl3( _F2, _phiF2, 1, -1, -1, theta_res, 3, -1, -1, theta_prime_daughter_res, 0.0 ); } } else if ( resonance == EvtLambdacPHH::Lambda ) { // Lambda(1520)(3/2-) resonance: table 5 if ( m == 1 && mprime == 1 ) { term1 = fampl3( _H1, _phiH1, 1, 1, 1, theta_res, 3, 1, 1, theta_prime_daughter_res, 0.0 ); term2 = fampl3( _H2, _phiH2, 1, 1, -1, theta_res, 3, -1, 1, theta_prime_daughter_res, phi_res - phi_prime_daughter_res ); } else if ( m == 1 && mprime == -1 ) { term1 = -1.0 * fampl3( _H1, _phiH1, 1, 1, 1, theta_res, 3, 1, -1, theta_prime_daughter_res, phi_prime_daughter_res ); term2 = -1.0 * fampl3( _H2, _phiH2, 1, 1, -1, theta_res, 3, -1, -1, theta_prime_daughter_res, phi_res ); } else if ( m == -1 && mprime == 1 ) { term1 = fampl3( _H1, _phiH1, 1, -1, 1, theta_res, 3, 1, 1, theta_prime_daughter_res, -phi_res ); term2 = fampl3( _H2, _phiH2, 1, -1, -1, theta_res, 3, -1, 1, theta_prime_daughter_res, -phi_prime_daughter_res ); } else if ( m == -1 && mprime == -1 ) { term1 = -1.0 * fampl3( _H1, _phiH1, 1, -1, 1, theta_res, 3, 1, -1, theta_prime_daughter_res, -( phi_res - phi_prime_daughter_res ) ); term2 = -1.0 * fampl3( _H2, _phiH2, 1, -1, -1, theta_res, 3, -1, -1, theta_prime_daughter_res, 0.0 ); } } EvtComplex Amplitude = term1 + term2; return Amplitude; } EvtComplex EvtLambdacPHH::fampl3( double amplitude_res, double phi_res, int spinMother, int m_spinMother, int m_prime_spinMother, double theta_res, float spin_res, float m_spin_res, float m_prime_spin_res, double theta_daughter_res, double phi_prime_daughter_res ) const { double dTerm1 = EvtdFunction::d( spinMother, m_spinMother, m_prime_spinMother, theta_res ); double dTerm2 = EvtdFunction::d( spin_res, m_spin_res, m_prime_spin_res, theta_daughter_res ); EvtComplex amp_phase1 = EvtComplex( cos( phi_res ), sin( phi_res ) ); EvtComplex amp_phase2 = EvtComplex( cos( phi_prime_daughter_res ), sin( phi_prime_daughter_res ) ); EvtComplex partial_amp = amplitude_res * amp_phase1 * dTerm1 * amp_phase2 * dTerm2; return partial_amp; } double EvtLambdacPHH::getACos( double num, double denom ) const { // Find inverse cosine, checking ratio is within +- 1 double angle( 0.0 ), ratio( 0.0 ); if ( fabs( denom ) > 0.0 ) { ratio = num / denom; } if ( fabs( ratio ) <= 1.0 ) { angle = acos( ratio ); } return angle; } double EvtLambdacPHH::getASin( double num, double denom ) const { // Find inverse sine, checking ratio is within +- 1 double angle( 0.0 ), ratio( 0.0 ); if ( fabs( denom ) > 0.0 ) { ratio = num / denom; } if ( fabs( ratio ) <= 1.0 ) { angle = asin( ratio ); } return angle; } diff --git a/src/EvtGenModels/EvtLb2Lll.cpp b/src/EvtGenModels/EvtLb2Lll.cpp index 058ba4c..860a16d 100644 --- a/src/EvtGenModels/EvtLb2Lll.cpp +++ b/src/EvtGenModels/EvtLb2Lll.cpp @@ -1,909 +1,909 @@ /*********************************************************************** * 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/EvtLb2Lll.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtDiracParticle.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGammaMatrix.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include "EvtGenBase/EvtVector4R.hh" #include #include EvtDecayBase* EvtLb2Lll::clone() { return new EvtLb2Lll; } std::string EvtLb2Lll::getName() { return "Lb2Lll"; } void EvtLb2Lll::init() { if ( getNArg() > 8 ) { // Decay parameters EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll generator expected max. 8 arguments but found: " << getNArg() << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " 1. Lambda_b0 polarization - zero is default" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " 2. Model type - \"SM\" for Standard Model is default" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " 3. Form-Factors - \"HQET\" is used by default" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " 4. How to set polarization - \"ModifiedSpinors\" is default" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " 5. Include long distance (LD) effects - \"SD\" (no) is default" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " 6. NonFactorizable contribution (omega) to b->sg decay at q2=0 " << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " 7. Note on every x-th decay" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " 8. Maximum probability - automatic by default" << std::endl; ::abort(); } if ( getNDaug() != 3 ) { // Check that there are 3 daughters only EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll generator expected 3 daughters but found: " << getNDaug() << std::endl; ::abort(); } EvtId LbID = EvtPDL::getId( std::string( "Lambda_b0" ) ); EvtId aLbID = EvtPDL::getId( std::string( "anti-Lambda_b0" ) ); EvtId eID = EvtPDL::getId( std::string( "e-" ) ); EvtId aeID = EvtPDL::getId( std::string( "e+" ) ); EvtId muID = EvtPDL::getId( std::string( "mu-" ) ); EvtId amuID = EvtPDL::getId( std::string( "mu+" ) ); EvtId tauID = EvtPDL::getId( std::string( "tau-" ) ); EvtId atauID = EvtPDL::getId( std::string( "tau+" ) ); // TODO: better check based on spin and falvour is needed to allow usage of aliases ! if ( getParentId() == LbID ) { // Check daughters of Lambda_b0 EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll generator found Lambda_b0" << std::endl; //if(EvtPDL::name(getDaug(0))!="Lambda0"){ // EvtGenReport(EVTGEN_ERROR,"EvtGen") << " ERROR: EvtLb2Lll generator expected Lambda0 daughter but found: " << EvtPDL::name(getDaug(0)) << std::endl; // ::abort(); //} if ( getDaug( 1 ) == eID && getDaug( 2 ) == aeID ) { m_decayName = "Lambda_b0 -> Lambda0 e- e+"; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll generator found decay: Lambda_b0 -> Lambda0 e- e+" << std::endl; } else if ( getDaug( 1 ) == muID && getDaug( 2 ) == amuID ) { m_decayName = "Lambda_b0 -> Lambda0 mu- mu+"; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll generator found decay: Lambda_b0 -> Lambda0 mu- mu+" << std::endl; } else if ( getDaug( 1 ) == tauID && getDaug( 2 ) == atauID ) { m_decayName = "Lambda_b0 -> Lambda0 tau- tau+"; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll generator found decay: Lambda_b0 -> Lambda0 tau- tau+" << std::endl; } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll generator expected lepton pair daughters but found: " << EvtPDL::name( getDaug( 1 ) ) << " " << EvtPDL::name( getDaug( 2 ) ) << std::endl; ::abort(); } //TODO: The model is known not to work correctly for anti-Lambda_b0 (A_FB does not change its sign) } else if ( getParentId() == aLbID ) { // Check daughters of anti-Lambda_b0 EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll generator found anti-Lambda_b0" << std::endl; //if(EvtPDL::name(getDaug(0))!="anti-Lambda0"){ // EvtGenReport(EVTGEN_ERROR,"EvtGen") << " ERROR: EvtLb2Lll generator expected anti-Lambda0 daughter but found: " << EvtPDL::name(getDaug(0)) << std::endl; // ::abort(); //} if ( getDaug( 1 ) == aeID && getDaug( 2 ) == eID ) { m_decayName = "anti-Lambda_b0 -> anti-Lambda0 e+ e-"; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll generator found decay: anti-Lambda_b0 -> anti-Lambda0 e+ e-" << std::endl; } else if ( getDaug( 1 ) == amuID && getDaug( 2 ) == muID ) { m_decayName = "anti-Lambda_b0 -> anti-Lambda0 mu+ mu-"; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll generator found decay: anti-Lambda_b0 -> anti-Lambda0 mu+ mu-" << std::endl; } else if ( getDaug( 1 ) == atauID && getDaug( 2 ) == tauID ) { m_decayName = "anti-Lambda_b0 -> anti-Lambda0 tau+ tau-"; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll generator found decay: anti-Lambda_b0 -> anti-Lambda0 tau+ tau-" << std::endl; } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll generator expected lepton pair daughters but found: " << EvtPDL::name( getDaug( 1 ) ) << " " << EvtPDL::name( getDaug( 2 ) ) << std::endl; ::abort(); } } else { // This model is not intended for decay of anything else than (anti-)Lambda_b0 EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll generator expected (anti-)Lambda_b0 parent but found: " << EvtPDL::name( getParentId() ) << std::endl; ::abort(); } // Read and check all parameters if ( getNArg() > 0 ) { if ( getArg( 0 ) > 1. || getArg( 0 ) < -1. ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll expects polarization to be in interval <-1,1>, not " << getArg( 0 ) << std::endl; ::abort(); } m_polarizationLambdab0 = getArg( 0 ); } else { m_polarizationLambdab0 = 0; } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll set Lambda_b0 polarization to " << m_polarizationLambdab0 << std::endl; if ( getNArg() > 1 ) { if ( getArgStr( 1 ).substr( 1, getArgStr( 1 ).size() - 2 ) != "SM" && getArgStr( 1 ).substr( 1, getArgStr( 1 ).size() - 2 ) != "-C7_SM" && getArgStr( 1 ).substr( 1, getArgStr( 1 ).size() - 2 ) != "SUSY-ChenGeng" ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll doesn't know this physics model: " << getArgStr( 1 ) << std::endl; ::abort(); } m_HEPmodel = getArgStr( 1 ).substr( 1, getArgStr( 1 ).size() - 2 ); } else { m_HEPmodel = "SM"; } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll will use this physics model: " << m_HEPmodel << std::endl; if ( getNArg() > 2 ) { if ( getArgStr( 2 ).substr( 1, getArgStr( 2 ).size() - 2 ) != "HQET" && getArgStr( 2 ).substr( 1, getArgStr( 2 ).size() - 2 ) != "HQET-noF2" && getArgStr( 2 ).substr( 1, 11 ) != "HQET-delta=" ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll doesn't know this Form-Factors model: " << getArgStr( 2 ) << std::endl; ::abort(); } m_FFtype = getArgStr( 2 ).substr( 1, getArgStr( 2 ).size() - 2 ); } else { m_FFtype = "HQET"; } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll will use this Form-Factors model: " << m_FFtype << std::endl; if ( getNArg() > 3 ) { if ( getArgStr( 3 ).substr( 1, getArgStr( 3 ).size() - 2 ) != "Unpolarized" ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll doesn't know kind of introducing polarization: " << getArgStr( 3 ) << std::endl; ::abort(); } m_polarizationIntroduction = getArgStr( 3 ).substr( 1, getArgStr( 3 ).size() - 2 ); } else { m_polarizationIntroduction = "Unpolarized"; } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll will use this kind of introducing polarization: " << m_polarizationIntroduction << std::endl; if ( getNArg() > 4 ) { if ( getArgStr( 4 ).substr( 1, getArgStr( 4 ).size() - 2 ) != "SD" && getArgStr( 4 ).substr( 1, getArgStr( 4 ).size() - 2 ) != "LD" ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll didn't find SD or LD parameter: " << getArgStr( 4 ) << std::endl; ::abort(); } m_effectContribution = getArgStr( 5 ).substr( 1, getArgStr( 4 ).size() - 2 ); } else { m_effectContribution = "SD"; } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll will include contribution from these effects: " << m_effectContribution << std::endl; if ( getNArg() > 5 ) { if ( fabs( getArg( 5 ) ) > 0.15 ) { EvtGenReport( EVTGEN_WARNING, "EvtGen" ) << " WARNING: EvtLb2Lll found very high contribution to b->sg decay at q2=0: " << getArg( 5 ) << std::endl; } m_omega = getArg( 5 ); } else { m_omega = 0; } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll will use this contribution to b->sg decay at q2=0: " << m_omega << std::endl; if ( getNArg() > 6 ) m_noTries = (long)( getArg( 6 ) ); else m_noTries = 0; if ( getNArg() > 7 ) { if ( getArg( 7 ) < 0. ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll expects positive maximum probability not : " << getArg( 7 ) << std::endl; ::abort(); } m_maxProbability = getArg( 7 ); } else { m_maxProbability = 0.; } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll maximum probability was set to " << m_maxProbability << std::endl; m_poleSize = 0; // Initialize Wilson coefficients by Buras and Munz // TODO: should have common W.C. source for all decays in EvtGen m_WC.CalculateAllCoefficients(); } void EvtLb2Lll::initProbMax() { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll is finding maximum probability ... " << std::endl; if ( m_maxProbability < 1e-10 ) { EvtDiracParticle* parent = new EvtDiracParticle; parent->noLifeTime(); parent->init( getParentId(), EvtVector4R( EvtPDL::getMass( getParentId() ), 0, 0, 0 ) ); parent->setDiagonalSpinDensity(); EvtAmp amp; - EvtId daughters[3] = {getDaug( 0 ), getDaug( 1 ), getDaug( 2 )}; + EvtId daughters[3] = { getDaug( 0 ), getDaug( 1 ), getDaug( 2 ) }; amp.init( getParentId(), 3, daughters ); parent->makeDaughters( 3, daughters ); EvtParticle* lambda = parent->getDaug( 0 ); EvtParticle* lep1 = parent->getDaug( 1 ); EvtParticle* lep2 = parent->getDaug( 2 ); lambda->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); EvtSpinDensity rho; rho.setDiag( parent->getSpinStates() ); double M0 = EvtPDL::getMass( getParentId() ); double mL = EvtPDL::getMass( getDaug( 0 ) ); double m1 = EvtPDL::getMass( getDaug( 1 ) ); double m2 = EvtPDL::getMass( getDaug( 2 ) ); double q2, pstar, elambda, theta; double q2min = ( m1 + m2 ) * ( m1 + m2 ); double q2max = ( M0 - mL ) * ( M0 - mL ); EvtVector4R p4lambda, p4lep1, p4lep2, boost; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll is probing whole phase space ..." << std::endl; int i, j; double prob = 0; for ( i = 0; i <= 100; i++ ) { q2 = q2min + i * ( q2max - q2min ) / 100.; elambda = ( M0 * M0 + mL * mL - q2 ) / 2 / M0; if ( i == 0 ) pstar = 0; else pstar = sqrt( q2 - ( m1 + m2 ) * ( m1 + m2 ) ) * sqrt( q2 - ( m1 - m2 ) * ( m1 - m2 ) ) / 2 / sqrt( q2 ); boost.set( M0 - elambda, 0, 0, +sqrt( elambda * elambda - mL * mL ) ); if ( i != 100 ) { p4lambda.set( elambda, 0, 0, -sqrt( elambda * elambda - mL * mL ) ); } else { p4lambda.set( mL, 0, 0, 0 ); } for ( j = 0; j <= 45; j++ ) { theta = j * EvtConst::pi / 45; p4lep1.set( sqrt( pstar * pstar + m1 * m1 ), 0, +pstar * sin( theta ), +pstar * cos( theta ) ); p4lep2.set( sqrt( pstar * pstar + m2 * m2 ), 0, -pstar * sin( theta ), -pstar * cos( theta ) ); if ( i != 100 ) // At maximal q2 we are already in correct frame as Lambda and W/Zvirtual are at rest { p4lep1 = boostTo( p4lep1, boost ); p4lep2 = boostTo( p4lep2, boost ); } calcAmp( &, parent ); prob = rho.normalizedProb( amp.getSpinDensity() ); //std::cout << "q2: " << q2 << " \t theta: " << theta << " \t prob: " << prob << std::endl; //std::cout << "p1: " << p4lep1 << " p2: " << p4lep2 << " q2-q2min: " << q2-(m1+m2)*(m1+m2) << std::endl; if ( prob > m_maxProbability ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " - probability " << prob << " found at q2 = " << q2 << " (" << 100 * ( q2 - q2min ) / ( q2max - q2min ) << " %) and theta = " << theta * 180 / EvtConst::pi << std::endl; m_maxProbability = prob; } } //::abort(); } //m_poleSize = 0.04*q2min; m_maxProbability *= 1.2; delete parent; } - if (m_maxProbability < 1e-10) { - EvtGenReport( EVTGEN_INFO, "EvtLb2Lll") - << "EvtLb2Lll found zero max prob, setting to 1.5e6" << std::endl; - m_maxProbability = 1.5e6; + if ( m_maxProbability < 1e-10 ) { + EvtGenReport( EVTGEN_INFO, "EvtLb2Lll" ) + << "EvtLb2Lll found zero max prob, setting to 1.5e6" << std::endl; + m_maxProbability = 1.5e6; } setProbMax( m_maxProbability ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtLb2Lll set up maximum probability to " << m_maxProbability << std::endl; } void EvtLb2Lll::decay( EvtParticle* parent ) { //setWeight(parent->initializePhaseSpace(getNDaug(),getDaugs(),m_poleSize,1,2)); parent->initializePhaseSpace( getNDaug(), getDaugs() ); calcAmp( &_amp2, parent ); } void EvtLb2Lll::calcAmp( EvtAmp* amp, EvtParticle* parent ) { static long noTries = 0; static double delta = 0; EvtComplex Matrix[2][2][2][2]; EvtComplex i1( 0, 1 ); int i, j, spins[4]; char ch; double r, M_L, M_Lb, M_s, M_c, M_b, q2, alpha, M_W, M_t; - double M_psi[2] = {0, 0}, Gamma_psi[2] = {0, 0}, k_psi[2] = {0, 0}; + double M_psi[2] = { 0, 0 }, Gamma_psi[2] = { 0, 0 }, k_psi[2] = { 0, 0 }; double F0_1, F0_2, a_F1, a_F2, b_F1, b_F2, F1, F2; double f_1, f_2, f_3, g_1, g_2, g_3, f_1T, f_2T, f_3T, g_1T, g_2T, g_3T, f_TV, f_TS, g_TV( 0.0 ), g_TS, f_T, g_T; EvtComplex A1, A2, A3, B1, B2, B3, D1, D2, D3, E1, E2, E3, N1, N2, H1, H2; EvtComplex C_SL, C_BR, C_LLtot, C_LRtot, C_LL, C_LR, C_RL, C_RR, C_LRLR, C_RLLR, C_LRRL, C_RLRL, C_T, C_TE; EvtComplex Yld, C_7eff, C_9eff; EvtComplex V_ts, V_tb; EvtVector4C lbar_Gmu_l[2][2], lbar_GmuG5_l[2][2], hbar_GmuPlusG5_h[2][2], hbar_GmuMinusG5_h[2][2], hbar_Gmu_h[2][2]; EvtComplex lbar_l[2][2], lbar_G5_l[2][2], hbar_1PlusG5_h[2][2], hbar_1MinusG5_h[2][2], hbar_G5_h[2][2], hbar_h[2][2]; EvtTensor4C lbar_Smunu_l[2][2], lbar_ESmunu_l[2][2], hbar_SmunuPlusG5_h[2][2], hbar_SmunuMinusG5_h[2][2], hbar_Smunu_h[2][2]; EvtVector4R q_mu, P_mu; EvtDiracSpinor parent__spParent[2]; M_Lb = parent->mass(); M_L = parent->getDaug( 0 )->mass(); M_s = 0.13; M_c = 1.35; M_b = 4.8; alpha = 1. / 137.036; M_W = 80.425; M_t = 174.3; M_psi[0] = 3.096916; M_psi[1] = 3.686093; if ( m_decayName == "Lambda_b0 -> Lambda0 e- e+" || m_decayName == "anti-Lambda_b0 -> anti-Lambda0 e+ e-" ) { Gamma_psi[0] = 5.40; Gamma_psi[1] = 2.12; } if ( m_decayName == "Lambda_b0 -> Lambda0 mu- mu+" || m_decayName == "anti-Lambda_b0 -> anti-Lambda0 mu+ mu-" ) { Gamma_psi[0] = 5.35; Gamma_psi[1] = 2.05; } if ( m_decayName == "Lambda_b0 -> Lambda0 tau- tau+" || m_decayName == "anti-Lambda_b0 -> anti-Lambda0 tau+ tau-" ) { Gamma_psi[0] = 0.00; Gamma_psi[1] = 0.79; } if ( m_effectContribution == "LD" ) { k_psi[0] = 1.65; k_psi[1] = 1.65; } //G_F = 1.16637e-5; //V_tb = sqrt(1-pow(0.0413,2))*sqrt(1-pow(0.0037,2)); //V_ts = -sqrt(1-pow(0.2243,2))*0.0413-0.2243*sqrt(1-pow(0.0413,2))*0.0037*(cos(60*EvtConst::pi/180)+i1*sin(60*EvtConst::pi/180)); P_mu = parent->getP4Restframe() + parent->getDaug( 0 )->getP4(); q_mu = parent->getP4Restframe() - parent->getDaug( 0 )->getP4(); q2 = q_mu.mass2(); if ( m_noTries > 0 ) if ( !( ( ++noTries ) % m_noTries ) ) EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " EvtLb2Lll already finished " << noTries << " matrix element calculations" << std::endl; if ( m_FFtype == "HQET" ) { r = M_L * M_L / M_Lb / M_Lb; F0_1 = +0.462; F0_2 = -0.077; a_F1 = -0.0182; a_F2 = -0.0685; b_F1 = -0.000176; b_F2 = +0.001460; F1 = F0_1 / ( 1.0 - ( q2 / M_Lb / M_Lb ) * ( a_F1 - b_F1 * ( q2 / M_Lb / M_Lb ) ) ); F2 = F0_2 / ( 1.0 - ( q2 / M_Lb / M_Lb ) * ( a_F2 - b_F2 * ( q2 / M_Lb / M_Lb ) ) ); g_1 = f_1 = f_2T = g_2T = F1 + sqrt( r ) * F2; //std::cout << " F1: " << F1 << " F2: " << F2 << " r: " << r << " M_L: " << M_L << " M_Lb: " << M_Lb << std::endl; //std::cout << " sqrt(q2): " << sqrt(q2) << " q2: " << q2 << " M_Lb^2" << M_Lb*M_Lb << std::endl; g_2 = f_2 = g_3 = f_3 = g_TV = f_TV = F2 / M_Lb; g_TS = f_TS = 0; g_1T = f_1T = F2 / M_Lb * q2; g_3T = +F2 / M_Lb * ( M_Lb + M_L ); f_3T = -F2 / M_Lb * ( M_Lb - M_L ); f_T = f_2T - f_TS * q2; g_T = g_2T - g_TS * q2; } else if ( strstr( m_FFtype.c_str(), "HQET-delta=" ) == m_FFtype.c_str() ) { //EvtGenReport(EVTGEN_WARNING,"EvtGen") << " WARNING: HQET-delta FF model should be checked for correctness" << std::endl; if ( delta == 0 ) sscanf( m_FFtype.c_str(), "%c%c%c%c%c%c%c%c%c%c%c%lf", &ch, &ch, &ch, &ch, &ch, &ch, &ch, &ch, &ch, &ch, &ch, &delta ); r = M_L * M_L / M_Lb / M_Lb; F0_1 = +0.462; F0_2 = -0.077; a_F1 = -0.0182; a_F2 = -0.0685; b_F1 = -0.000176; b_F2 = +0.001460; F1 = F0_1 / ( 1.0 - ( q2 / M_Lb / M_Lb ) * ( a_F1 - b_F1 * ( q2 / M_Lb / M_Lb ) ) ); F2 = F0_2 / ( 1.0 - ( q2 / M_Lb / M_Lb ) * ( a_F2 - b_F2 * ( q2 / M_Lb / M_Lb ) ) ); g_1 = f_1 = f_2T = g_2T = F1 + sqrt( r ) * F2; g_1 += delta * g_1; f_1 -= delta * f_1; g_2 = f_2 = g_3 = f_3 = g_TV = f_TV = F2 / M_Lb; g_TS = f_TS = 0; g_1T = f_1T = F2 / M_Lb * q2; g_3T = +F2 / M_Lb * ( M_Lb + M_L ); f_3T = -F2 / M_Lb * ( M_Lb - M_L ); f_T = f_2T - f_TS * q2; g_T = g_2T - g_TS * q2; } else if ( m_FFtype == "HQET-noF2" ) { //EvtGenReport(EVTGEN_WARNING,"EvtGen") << " WARNING: HQET-noF2 FF model should be checked for correctness" << std::endl; r = M_L * M_L / M_Lb / M_Lb; F0_1 = +0.462; a_F1 = -0.0182; b_F1 = -0.000176; F1 = F0_1 / ( 1.0 - ( q2 / M_Lb / M_Lb ) * ( a_F1 - b_F1 * ( q2 / M_Lb / M_Lb ) ) ); g_1 = f_1 = f_2T = g_2T = F1; g_2 = f_2 = g_3 = f_3 = g_TV = f_TV = 0; g_TS = f_TS = 0; g_1T = f_1T = 0; g_3T = 0; f_3T = 0; f_T = f_2T - f_TS * q2; g_T = g_2T - g_TS * q2; } else { // general relations for Form-Factors f_1 = f_2 = f_3 = g_1 = g_2 = g_3 = f_3T = g_3T = f_TS = g_TS = f_T = g_T = f_TV = 0; f_2T = f_T + f_TS * q2; f_1T = ( f_TV + f_TS * ( M_L + M_Lb ) ) * q2; f_1T = -q2 / ( M_Lb - M_L ) * f_3T; g_2T = g_T + g_TS * q2; g_1T = ( g_TV - g_TS * ( M_L - M_Lb ) ) * q2; g_1T = +q2 / ( M_Lb + M_L ) * g_3T; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll - unknown Form-Factors model: " << m_FFtype << " - this should never happen !" << std::endl; ::abort(); } if ( m_HEPmodel == "SM" ) { C_LL = C_LR = C_RL = C_RR = C_LRLR = C_RLLR = C_LRRL = C_RLRL = C_T = C_TE = EvtComplex( 0, 0 ); Yld = m_WC.Yld( q2, k_psi, Gamma_psi, M_psi, 2, m_WC.GetC1(), m_WC.GetC2(), m_WC.GetC3(), m_WC.GetC4(), m_WC.GetC5(), m_WC.GetC6(), 1. / alpha ); C_7eff = m_WC.GetC7eff0() + m_WC.C7b2sg( m_WC.GetStrongCouplingConst(), m_WC.GetEta(), m_WC.GetC2(), M_t, M_W ) + m_omega * ( m_WC.hzs( M_c / M_b, q2 / M_b / M_b, M_b, M_b ) + Yld ); C_9eff = Yld + m_WC.C9efftilda( M_c / M_b, q2 / M_b / M_b, m_WC.GetStrongCouplingConst(), m_WC.GetC1(), m_WC.GetC2(), m_WC.GetC3(), m_WC.GetC4(), m_WC.GetC5(), m_WC.GetC6(), m_WC.GetC9tilda(), m_WC.GetRenormSchemePar() ); C_SL = -2 * M_s * C_7eff; C_BR = -2 * M_b * C_7eff; C_LLtot = C_9eff - m_WC.GetC10tilda() + C_LL; C_LRtot = C_9eff + m_WC.GetC10tilda() + C_LR; //std::cout << "Yld: " << Yld << " C7eff: " << C_7eff << " C_9eff: " << C_9eff << " Diff7: " << C_7eff-m_WC.GetC7eff0() << " Diff9: " << C_9eff-m_WC.GetC9tilda() << std::endl; } else if ( m_HEPmodel == "-C7_SM" ) { C_LL = C_LR = C_RL = C_RR = C_LRLR = C_RLLR = C_LRRL = C_RLRL = C_T = C_TE = EvtComplex( 0, 0 ); Yld = m_WC.Yld( q2, k_psi, Gamma_psi, M_psi, 2, m_WC.GetC1(), m_WC.GetC2(), m_WC.GetC3(), m_WC.GetC4(), m_WC.GetC5(), m_WC.GetC6(), 1. / alpha ); C_7eff = m_WC.GetC7eff0() + m_WC.C7b2sg( m_WC.GetStrongCouplingConst(), m_WC.GetEta(), m_WC.GetC2(), M_t, M_W ) + m_omega * ( m_WC.hzs( M_c / M_b, q2 / M_b / M_b, M_b, M_b ) + Yld ); C_9eff = Yld + m_WC.C9efftilda( M_c / M_b, q2 / M_b / M_b, m_WC.GetStrongCouplingConst(), m_WC.GetC1(), m_WC.GetC2(), m_WC.GetC3(), m_WC.GetC4(), m_WC.GetC5(), m_WC.GetC6(), m_WC.GetC9tilda(), m_WC.GetRenormSchemePar() ); C_SL = +2 * M_s * C_7eff; C_BR = +2 * M_b * C_7eff; C_LLtot = C_9eff - m_WC.GetC10tilda() + C_LL; C_LRtot = C_9eff + m_WC.GetC10tilda() + C_LR; //std::cout << "Yld: " << Yld << " C7eff: " << C_7eff << " C_9eff: " << C_9eff << " Diff7: " << C_7eff-m_WC.GetC7eff0() << " Diff9: " << C_9eff-m_WC.GetC9tilda() << std::endl; } else if ( m_HEPmodel == "SUSY-ChenGeng" ) { //EvtGenReport(EVTGEN_WARNING,"EvtGen") << " WARNING: SUSY-ChenGeng model should be checked for correctness" << std::endl; C_LL = C_LR = C_RL = C_RR = C_LRLR = C_RLLR = C_LRRL = C_RLRL = C_T = C_TE = EvtComplex( 0, 0 ); EvtComplex d_u23LL = 0.1; EvtComplex d_u33RL = 0.65; EvtComplex d_d23LR = 0.03 * exp( i1 * EvtConst::pi * 2 / 5 ); EvtComplex d_u23LR = -0.8 * exp( i1 * EvtConst::pi / 4 ); EvtComplex C_7susy = -1.75 * d_u23LL - 0.25 * d_u23LR - 10.3 * d_d23LR; EvtComplex C_9susy = 0.82 * d_u23LR; EvtComplex C_10susy = -9.37 * d_u23LR + 1.4 * d_u23LR * d_u33RL + 2.7 * d_u23LL; Yld = m_WC.Yld( q2, k_psi, Gamma_psi, M_psi, 2, m_WC.GetC1(), m_WC.GetC2(), m_WC.GetC3(), m_WC.GetC4(), m_WC.GetC5(), m_WC.GetC6(), 1. / alpha ); C_7eff = m_WC.GetC7eff0() + C_7susy * pow( m_WC.GetEta(), 16. / 23. ) + m_WC.C7b2sg( m_WC.GetStrongCouplingConst(), m_WC.GetEta(), m_WC.GetC2(), M_t, M_W ) + m_omega * ( m_WC.hzs( M_c / M_b, q2 / M_b / M_b, M_b, M_b ) + Yld ); C_9eff = Yld + m_WC.C9efftilda( M_c / M_b, q2 / M_b / M_b, m_WC.GetStrongCouplingConst(), m_WC.GetC1(), m_WC.GetC2(), m_WC.GetC3(), m_WC.GetC4(), m_WC.GetC5(), m_WC.GetC6(), m_WC.GetC9tilda() + C_9susy, m_WC.GetRenormSchemePar() ); C_SL = -2 * M_s * C_7eff; C_BR = -2 * M_b * C_7eff; C_LLtot = C_9eff - m_WC.GetC10tilda() - C_10susy + C_LL; C_LRtot = C_9eff + m_WC.GetC10tilda() + C_10susy + C_LR; //std::cout << "Yld: " << Yld << " C7eff: " << C_7eff << " C_9eff: " << C_9eff << " Diff7: " << C_7eff-m_WC.GetC7eff0() << " Diff9: " << C_9eff-m_WC.GetC9tilda() << std::endl; } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll - unknown physics model: " << m_HEPmodel << " - this should never happen !" << std::endl; ::abort(); } A1 = ( f_1T - g_1T ) * C_SL / q2 + ( f_1T + g_1T ) * C_BR / q2 + 0.5 * ( f_1 - g_1 ) * ( C_LLtot + C_LRtot ) + 0.5 * ( f_1 + g_1 ) * ( C_RL + C_RR ); //std::cout << "f_1T: " << f_1T << " g_1T: " << g_1T << " C_SL: " << C_SL << " C_BR: " << C_BR << " f_1: " << f_1 << " g_1: " << g_1 << " C_LLtot: " << C_LLtot << " C_LRtot: " << C_LRtot << " C_RL: " << C_RL << " C_RR: " << C_RR << std::endl; A2 = ( f_2T - g_2T ) * C_SL / q2 + ( f_2T + g_2T ) * C_BR / q2 + 0.5 * ( f_2 - g_2 ) * ( C_LLtot + C_LRtot ) + 0.5 * ( f_2 + g_2 ) * ( C_RL + C_RR ); A3 = ( f_3T - g_3T ) * C_SL / q2 + ( f_3T + g_3T ) * C_BR / q2 + 0.5 * ( f_3 - g_3 ) * ( C_LLtot + C_LRtot ) + 0.5 * ( f_3 + g_3 ) * ( C_RL + C_RR ); B1 = ( f_1T + g_1T ) * C_SL / q2 + ( f_1T - g_1T ) * C_BR / q2 + 0.5 * ( f_1 + g_1 ) * ( C_LLtot + C_LRtot ) + 0.5 * ( f_1 - g_1 ) * ( C_RL + C_RR ); B2 = ( f_2T + g_2T ) * C_SL / q2 + ( f_2T - g_2T ) * C_BR / q2 + 0.5 * ( f_2 + g_2 ) * ( C_LLtot + C_LRtot ) + 0.5 * ( f_2 - g_2 ) * ( C_RL + C_RR ); B3 = ( f_3T + g_3T ) * C_SL / q2 + ( f_3T - g_3T ) * C_BR / q2 + 0.5 * ( f_3 + g_3 ) * ( C_LLtot + C_LRtot ) + 0.5 * ( f_3 - g_3 ) * ( C_RL + C_RR ); D1 = 0.5 * ( C_RR - C_RL ) * ( f_1 + g_1 ) + 0.5 * ( C_LRtot - C_LLtot ) * ( f_1 - g_1 ); D2 = 0.5 * ( C_RR - C_RL ) * ( f_2 + g_2 ) + 0.5 * ( C_LRtot - C_LLtot ) * ( f_2 - g_2 ); D3 = 0.5 * ( C_RR - C_RL ) * ( f_3 + g_3 ) + 0.5 * ( C_LRtot - C_LLtot ) * ( f_3 - g_3 ); E1 = 0.5 * ( C_RR - C_RL ) * ( f_1 - g_1 ) + 0.5 * ( C_LRtot - C_LLtot ) * ( f_1 + g_1 ); E2 = 0.5 * ( C_RR - C_RL ) * ( f_2 - g_2 ) + 0.5 * ( C_LRtot - C_LLtot ) * ( f_2 + g_2 ); E3 = 0.5 * ( C_RR - C_RL ) * ( f_3 - g_3 ) + 0.5 * ( C_LRtot - C_LLtot ) * ( f_3 + g_3 ); N1 = ( f_1 * ( M_Lb - M_L ) + f_3 * q2 ) / M_b * ( C_LRLR + C_RLLR + C_LRRL + C_RLRL ); // Should be mLb - mL N2 = ( f_1 * ( M_Lb - M_L ) + f_3 * q2 ) / M_b * ( C_LRLR + C_RLLR - C_LRRL - C_RLRL ); H1 = ( g_1 * ( M_Lb + M_L ) - g_3 * q2 ) / M_b * ( C_LRLR - C_RLLR + C_LRRL - C_RLRL ); H2 = ( g_1 * ( M_Lb + M_L ) - g_3 * q2 ) / M_b * ( C_LRLR - C_RLLR - C_LRRL + C_RLRL ); for ( i = 0; i < 4; i++ ) { lbar_Gmu_l[i / 2][i % 2] = EvtLeptonVCurrent( parent->getDaug( 1 )->spParent( i / 2 ), parent->getDaug( 2 )->spParent( i % 2 ) ); lbar_GmuG5_l[i / 2][i % 2] = EvtLeptonACurrent( parent->getDaug( 1 )->spParent( i / 2 ), parent->getDaug( 2 )->spParent( i % 2 ) ); lbar_l[i / 2][i % 2] = EvtLeptonSCurrent( parent->getDaug( 1 )->spParent( i / 2 ), parent->getDaug( 2 )->spParent( i % 2 ) ); lbar_G5_l[i / 2][i % 2] = EvtLeptonPCurrent( parent->getDaug( 1 )->spParent( i / 2 ), parent->getDaug( 2 )->spParent( i % 2 ) ); lbar_Smunu_l[i / 2][i % 2] = EvtLeptonTCurrent( parent->getDaug( 1 )->spParent( i / 2 ), parent->getDaug( 2 )->spParent( i % 2 ) ); lbar_ESmunu_l[i / 2][i % 2] = dual( EvtLeptonTCurrent( parent->getDaug( 1 )->spParent( i / 2 ), parent->getDaug( 2 )->spParent( i % 2 ) ) ); } // TODO: polarization not yet introduced if ( m_polarizationIntroduction == "SpinDensityMatrix" ) { //parent->setSpinDensityForward(); parent__spParent[0] = parent->sp( 0 ); parent__spParent[1] = parent->sp( 1 ); } else if ( m_polarizationIntroduction == "ModifiedSpinors" ) { parent__spParent[0] = parent->sp( 0 ); parent__spParent[1] = parent->sp( 1 ); } else if ( m_polarizationIntroduction == "Unpolarized" ) { parent__spParent[0] = parent->sp( 0 ); parent__spParent[1] = parent->sp( 1 ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: EvtLb2Lll - unknown polarization: " << m_polarizationIntroduction << " - this should never happen !" << std::endl; ::abort(); } for ( i = 0; i < 4; i++ ) { hbar_GmuPlusG5_h[i / 2][i % 2] = EvtLeptonVCurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ) + EvtLeptonACurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ); hbar_GmuMinusG5_h[i / 2][i % 2] = EvtLeptonVACurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ); hbar_SmunuPlusG5_h[i / 2][i % 2] = EvtLeptonTCurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ) + EvtLeptonTG5Current( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ); hbar_SmunuMinusG5_h[i / 2][i % 2] = EvtLeptonTCurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ) - EvtLeptonTG5Current( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ); hbar_1PlusG5_h[i / 2][i % 2] = EvtLeptonSCurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ) + EvtLeptonPCurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ); hbar_1MinusG5_h[i / 2][i % 2] = EvtLeptonSCurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ) - EvtLeptonPCurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ); hbar_G5_h[i / 2][i % 2] = EvtLeptonPCurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ); hbar_h[i / 2][i % 2] = EvtLeptonSCurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ); hbar_Smunu_h[i / 2][i % 2] = EvtLeptonTCurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ); hbar_Gmu_h[i / 2][i % 2] = EvtLeptonVCurrent( parent->getDaug( 0 )->spParent( i / 2 ), parent__spParent[i % 2] ); } for ( i = 0; i < 4; i++ ) for ( j = 0; j < 4; j++ ) { //std::cout << "--------------------------------------------------" << std::endl; //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += lbar_Gmu_l[i / 2][i % 2] * ( A1 * hbar_GmuPlusG5_h[j / 2][j % 2] + B1 * hbar_GmuMinusG5_h[j / 2][j % 2] ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; //std::cout << "A1: " << A1 << " B1: " << B1 << " lbar_Gmu_l: " << lbar_Gmu_l[i/2][i%2] << // " hbar_GmuPlusG5_h: " << hbar_GmuPlusG5_h[j/2][j%2] << " hbar_GmuMinusG5_h: " << hbar_GmuMinusG5_h[j/2][j%2] << // " sp1: " << parent->getDaug(1)->spParent(i/2) << " sp2: " << parent->getDaug(1)->spParent(i%2) << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += lbar_Gmu_l[i / 2][i % 2] * ( i1 * A2 * ( hbar_SmunuPlusG5_h[j / 2][j % 2].cont2( q_mu ) ) + B2 * ( hbar_SmunuMinusG5_h[j / 2][j % 2].cont2( q_mu ) ) ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += lbar_Gmu_l[i / 2][i % 2] * ( ( A3 * hbar_1PlusG5_h[j / 2][j % 2] + B3 * hbar_1MinusG5_h[j / 2][j % 2] ) * q_mu ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += lbar_GmuG5_l[i / 2][i % 2] * ( D1 * hbar_GmuPlusG5_h[j / 2][j % 2] + E1 * hbar_GmuMinusG5_h[j / 2][j % 2] ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += lbar_GmuG5_l[i / 2][i % 2] * ( i1 * D2 * ( hbar_SmunuPlusG5_h[j / 2][j % 2].cont2( q_mu ) ) + E2 * ( hbar_SmunuMinusG5_h[j / 2][j % 2].cont2( q_mu ) ) ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += lbar_GmuG5_l[i / 2][i % 2] * ( ( D3 * hbar_1PlusG5_h[j / 2][j % 2] + E3 * hbar_1MinusG5_h[j / 2][j % 2] ) * q_mu ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += lbar_l[i / 2][i % 2] * ( N1 * hbar_h[j / 2][j % 2] + H1 * hbar_G5_h[j / 2][j % 2] ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += lbar_G5_l[i / 2][i % 2] * ( N2 * hbar_h[j / 2][j % 2] + H2 * hbar_G5_h[j / 2][j % 2] ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += cont( lbar_Smunu_l[i / 2][i % 2], 4 * C_T * f_T * hbar_Smunu_h[j / 2][j % 2] ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += cont( lbar_Smunu_l[i / 2][i % 2], -4 * C_T * f_TV * i1 * ( EvtGenFunctions::directProd( q_mu, hbar_Gmu_h[j / 2][j % 2] ) - EvtGenFunctions::directProd( hbar_Gmu_h[j / 2][j % 2], q_mu ) ) ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += cont( lbar_Smunu_l[i / 2][i % 2], -4 * C_T * f_TS * i1 * ( EvtGenFunctions::directProd( P_mu, q_mu ) - EvtGenFunctions::directProd( q_mu, P_mu ) ) * hbar_h[j / 2][j % 2] ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += cont( lbar_ESmunu_l[i / 2][i % 2], 4 * C_TE * f_T * i1 * hbar_Smunu_h[j / 2][j % 2] ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += cont( lbar_ESmunu_l[i / 2][i % 2], 4 * C_TE * f_TV * ( EvtGenFunctions::directProd( q_mu, hbar_Gmu_h[j / 2][j % 2] ) - EvtGenFunctions::directProd( hbar_Gmu_h[j / 2][j % 2], q_mu ) ) ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; Matrix[j / 2][j % 2][i / 2][i % 2] += cont( lbar_ESmunu_l[i / 2][i % 2], 4 * C_TE * f_TS * ( EvtGenFunctions::directProd( P_mu, q_mu ) - EvtGenFunctions::directProd( q_mu, P_mu ) ) * hbar_h[j / 2][j % 2] ); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; //Matrix[j/2][j%2][i/2][i%2] *= G_F*alpha/4/sqrt(2)/EvtConst::pi*V_tb*conj(V_ts); //std::cout << "Matrix = " << Matrix[j/2][j%2][i/2][i%2] << std::endl; //std::cout << "--------------------------------------------------" << std::endl; spins[0] = j % 2; spins[1] = j / 2; spins[2] = i / 2; spins[3] = i % 2; amp->vertex( spins, Matrix[j / 2][j % 2][i / 2][i % 2] ); } //std::cout << "==================================================" << std::endl; //std::cout << "Lambda_b0: " << parent->getP4Restframe() << std::endl; //std::cout << "Lambda0: " << parent->getDaug(0)->getP4() << std::endl; //std::cout << "mu-: " << parent->getDaug(1)->getP4() << std::endl; //std::cout << "mu+: " << parent->getDaug(2)->getP4() << std::endl; //std::cout << "P_mu: " << P_mu << std::endl; //std::cout << "q_mu: " << q_mu << std::endl; //std::cout << "q2: " << q2 << std::endl; //std::cout << "==================================================" << std::endl; return; } EvtTensor4C EvtLb2Lll::EvtLeptonTG5Current( const EvtDiracSpinor& d, const EvtDiracSpinor& dp ) { // EvtTensor4C temp; temp.zero(); EvtComplex i2( 0, 0.5 ); static EvtGammaMatrix mat01 = EvtGammaMatrix::g0() * ( EvtGammaMatrix::g0() * EvtGammaMatrix::g1() - EvtGammaMatrix::g1() * EvtGammaMatrix::g0() ) * EvtGammaMatrix::g5(); static EvtGammaMatrix mat02 = EvtGammaMatrix::g0() * ( EvtGammaMatrix::g0() * EvtGammaMatrix::g2() - EvtGammaMatrix::g2() * EvtGammaMatrix::g0() ) * EvtGammaMatrix::g5(); static EvtGammaMatrix mat03 = EvtGammaMatrix::g0() * ( EvtGammaMatrix::g0() * EvtGammaMatrix::g3() - EvtGammaMatrix::g3() * EvtGammaMatrix::g0() ) * EvtGammaMatrix::g5(); static EvtGammaMatrix mat12 = EvtGammaMatrix::g0() * ( EvtGammaMatrix::g1() * EvtGammaMatrix::g2() - EvtGammaMatrix::g2() * EvtGammaMatrix::g1() ) * EvtGammaMatrix::g5(); static EvtGammaMatrix mat13 = EvtGammaMatrix::g0() * ( EvtGammaMatrix::g1() * EvtGammaMatrix::g3() - EvtGammaMatrix::g3() * EvtGammaMatrix::g1() ) * EvtGammaMatrix::g5(); static EvtGammaMatrix mat23 = EvtGammaMatrix::g0() * ( EvtGammaMatrix::g2() * EvtGammaMatrix::g3() - EvtGammaMatrix::g3() * EvtGammaMatrix::g2() ) * EvtGammaMatrix::g5(); temp.set( 0, 1, i2 * ( d * ( mat01 * dp ) ) ); temp.set( 1, 0, -temp.get( 0, 1 ) ); temp.set( 0, 2, i2 * ( d * ( mat02 * dp ) ) ); temp.set( 2, 0, -temp.get( 0, 2 ) ); temp.set( 0, 3, i2 * ( d * ( mat03 * dp ) ) ); temp.set( 3, 0, -temp.get( 0, 3 ) ); temp.set( 1, 2, i2 * ( d * ( mat12 * dp ) ) ); temp.set( 2, 1, -temp.get( 1, 2 ) ); temp.set( 1, 3, i2 * ( d * ( mat13 * dp ) ) ); temp.set( 3, 1, -temp.get( 1, 3 ) ); temp.set( 2, 3, i2 * ( d * ( mat23 * dp ) ) ); temp.set( 3, 2, -temp.get( 2, 3 ) ); return temp; } diff --git a/src/EvtGenModels/EvtMultibody.cpp b/src/EvtGenModels/EvtMultibody.cpp index 35aad34..b687444 100644 --- a/src/EvtGenModels/EvtMultibody.cpp +++ b/src/EvtGenModels/EvtMultibody.cpp @@ -1,94 +1,94 @@ /*********************************************************************** * 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/EvtMultibody.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtResonance.hh" #include "EvtGenBase/EvtResonance2.hh" #include "EvtGenBase/EvtdFunction.hh" EvtMultibody::~EvtMultibody() { if ( _decayTree != nullptr ) delete _decayTree; _decayTree = nullptr; if ( _ilist != nullptr ) delete[] _ilist; _ilist = nullptr; } std::string EvtMultibody::getName() { return "D_MULTIBODY"; } EvtDecayBase* EvtMultibody::clone() { return new EvtMultibody; } void EvtMultibody::init() { int N = getNArg(); _decayTree = new EvtMTree( getDaugs(), getNDaug() ); _ilist = new int[getNDaug() + 1]; for ( int i = 0; i < N - 1; ++i ) { if ( getArgStr( i ) == "RESONANCE" ) { _decayTree->addtree( getArgStr( ++i ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Syntax error at " << getArgStr( i ) << std::endl; ::abort(); } } } void EvtMultibody::initProbMax() { - setProbMax(1.0); + setProbMax( 1.0 ); } void EvtMultibody::decay( EvtParticle* p ) { // Initialize the phase space before doing anything else! p->initializePhaseSpace( getNDaug(), getDaugs() ); EvtSpinAmp amp = _decayTree->amplitude( p ); vector index = amp.iterallowedinit(); vector spins = amp.dims(); do { for ( size_t i = 0; i < index.size(); ++i ) { _ilist[i] = index[i] + spins[i]; } vertex( _ilist, amp( index ) ); } while ( amp.iterateallowed( index ) ); } diff --git a/src/EvtGenModels/EvtPhspDecaytimeCut.cpp b/src/EvtGenModels/EvtPhspDecaytimeCut.cpp index 4ab0a6c..88a74e8 100644 --- a/src/EvtGenModels/EvtPhspDecaytimeCut.cpp +++ b/src/EvtGenModels/EvtPhspDecaytimeCut.cpp @@ -1,66 +1,66 @@ /*********************************************************************** * 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/EvtPhspDecaytimeCut.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" +#include #include #include -#include std::string EvtPhspDecaytimeCut::getName() { return "PHSPDECAYTIMECUT"; } EvtDecayBase* EvtPhspDecaytimeCut::clone() { return new EvtPhspDecaytimeCut; } void EvtPhspDecaytimeCut::init() { // check that there are 1 arguments checkNArg( 1 ); // This argument is minimum decay time in ps converted here to EvtGen // units in which c=1 m_minDecayTime = getArg( 0 ) * EvtConst::c * 1.e-12; } void EvtPhspDecaytimeCut::initProbMax() { noProbMax(); } void EvtPhspDecaytimeCut::decay( EvtParticle* p ) { p->initializePhaseSpace( getNDaug(), getDaugs() ); // Shift generated decay time by minimum we require const double currentDecaytime = p->getLifetime(); p->setLifetime( currentDecaytime + m_minDecayTime ); return; } diff --git a/src/EvtGenModels/EvtPi0Dalitz.cpp b/src/EvtGenModels/EvtPi0Dalitz.cpp index 866ce31..eed8fbb 100644 --- a/src/EvtGenModels/EvtPi0Dalitz.cpp +++ b/src/EvtGenModels/EvtPi0Dalitz.cpp @@ -1,141 +1,140 @@ /*********************************************************************** * 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/EvtPi0Dalitz.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include #include #include #include using std::fstream; std::string EvtPi0Dalitz::getName() { return "PI0_DALITZ"; } EvtDecayBase* EvtPi0Dalitz::clone() { return new EvtPi0Dalitz; } void EvtPi0Dalitz::initProbMax() { // Search for maximum probability. In order to avoid setting up all // particles with spinors and four-momenta, we use result after all // contractions, which is: // 1/((m_R^2-q^2)^2+m_R^2 Gamma_R^2) 1/(2q^2) (M^2-q^2)^2 beta_l // (1+cos(theta)^2) where we set cos(theta)=1 auto daughter1 = getDaug( 0 ); auto daughter2 = getDaug( 1 ); double q2Min = EvtPDL::getMass( daughter1 ) + EvtPDL::getMass( daughter2 ); q2Min *= q2Min; double q2Max = EvtPDL::getMass( getParentId() ); q2Max *= q2Max; const int steps = 20000; const double step = ( q2Max - q2Min ) / steps; double maxProb = 0; for ( int ii = 0; ii < steps; ++ii ) { double q2 = q2Min + ii * step; const double mSqDiff = m_m0Sq - q2; const double q2Sq = q2 * q2; - double prob = ( q2Max - q2 ) * ( q2Max - q2 ) * ( q2 - q2Min ) / - ( q2Sq ); + double prob = ( q2Max - q2 ) * ( q2Max - q2 ) * ( q2 - q2Min ) / ( q2Sq ); prob *= ( 1.0 / ( mSqDiff * mSqDiff + m_m0SqG0Sq ) ); // When generating events, we do not start from phase-space, but // add some pole to it, weight of which is taken into account // elsewhere prob /= 1.0 + m_poleSize / ( q2Sq ); if ( prob > maxProb ) { maxProb = prob; } } - setProbMax( maxProb * 1.05 ); + setProbMax( maxProb * 1.05 ); } void EvtPi0Dalitz::init() { // check that there are 0 arguments checkNArg( 0 ); checkNDaug( 3 ); checkSpinParent( EvtSpinType::SCALAR ); checkSpinDaughter( 0, EvtSpinType::DIRAC ); checkSpinDaughter( 1, EvtSpinType::DIRAC ); checkSpinDaughter( 2, EvtSpinType::PHOTON ); // Rescale pole size to improve efficiency. Not sure about exact // factor, but this seem to be best simple rescaling for // eta-->e+e-gamma. const double parentMass = EvtPDL::getMass( getParentId() ); m_poleSize *= parentMass * parentMass / ( 0.135 * 0.135 ); } void EvtPi0Dalitz::decay( EvtParticle* p ) { EvtParticle *ep, *em, *gamma; setWeight( p->initializePhaseSpace( getNDaug(), getDaugs(), false, m_poleSize, 0, 1 ) ); ep = p->getDaug( 0 ); em = p->getDaug( 1 ); gamma = p->getDaug( 2 ); // the next four lines generates events with a weight such that // the efficiency for selecting them is good. The parameter below of // 0.1 is the size of the peak at low q^2 (in arbitrary units). // The value of 0.1 is appropriate for muons. // when you use this remember to remove the cut on q^2! //ep em invariant mass^2 double m2 = ( ep->getP4() + em->getP4() ).mass2(); EvtVector4R q = ep->getP4() + em->getP4(); //Just use the prob summed over spins... EvtTensor4C w, v; v = 2.0 * ( gamma->getP4() * q ) * EvtGenFunctions::directProd( q, gamma->getP4() ) - ( gamma->getP4() * q ) * ( gamma->getP4() * q ) * EvtTensor4C::g() - m2 * EvtGenFunctions::directProd( gamma->getP4(), gamma->getP4() ); w = 4.0 * ( EvtGenFunctions::directProd( ep->getP4(), em->getP4() ) + EvtGenFunctions::directProd( em->getP4(), ep->getP4() ) - EvtTensor4C::g() * ( ep->getP4() * em->getP4() - ep->getP4().mass2() ) ); double prob = ( real( cont( v, w ) ) ) / ( m2 * m2 ); const double m2Diff = m_m0Sq - m2; prob *= ( 1.0 / ( m2Diff * m2Diff + m_m0SqG0Sq ) ); // EvtGenReport(EVTGEN_INFO,"EvtGen") << "prob is "<. * ***********************************************************************/ #include "EvtGenModels/EvtRareLbToLll.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtDiracParticle.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtRaritaSchwinger.hh" #include "EvtGenBase/EvtSpinDensity.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenModels/EvtRareLbToLllFF.hh" #include "EvtGenModels/EvtRareLbToLllFFGutsche.hh" #include "EvtGenModels/EvtRareLbToLllFFlQCD.hh" #include // The module name specification std::string EvtRareLbToLll::getName() { return "RareLbToLll"; } // The implementation of the clone() method EvtDecayBase* EvtRareLbToLll::clone() { return new EvtRareLbToLll; } void EvtRareLbToLll::init() { checkNArg( 0, 1 ); // check that there are 3 daughters checkNDaug( 3 ); // Parent should be spin 1/2 Lambda_b0 const EvtSpinType::spintype spin = EvtPDL::getSpinType( getDaug( 0 ) ); if ( !( spin == EvtSpinType::DIRAC || spin == EvtSpinType::RARITASCHWINGER ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " EvtRareLbToLll expects DIRAC or RARITASWINGER daughter " << std::endl; } // We expect that the second and third daughters // are the ell+ and ell- checkSpinDaughter( 1, EvtSpinType::DIRAC ); checkSpinDaughter( 2, EvtSpinType::DIRAC ); // Work out whether we have electron mode const EvtIdSet leptons{ "e-", "e+" }; if ( leptons.contains( getDaug( 1 ) ) ) { - m_electronMode = true; - EvtGenReport( EVTGEN_ERROR, "EvtGen" ) - << " EvtRareLbToLll has dielectron final state" << std::endl; + m_electronMode = true; + EvtGenReport( EVTGEN_ERROR, "EvtGen" ) + << " EvtRareLbToLll has dielectron final state" << std::endl; } std::string model{ "LQCD" }; - if ( getNArg() == 1) { - model = getArgStr( 0 ); + if ( getNArg() == 1 ) { + model = getArgStr( 0 ); } if ( model == "Gutsche" ) { ffmodel_ = std::make_unique(); } else if ( model == "LQCD" ) { ffmodel_ = std::make_unique(); } else if ( model == "MR" ) { ffmodel_ = std::make_unique(); } else { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " Unknown form-factor model, valid options are MR, LQCD, Gutsche." << " Assuming LQCD form-factors... " << std::endl; ffmodel_ = std::make_unique(); } wcmodel_ = std::make_unique(); ffmodel_->init(); return; } void EvtRareLbToLll::initProbMax() { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtRareLbToLll is finding maximum probability ... " << std::endl; m_maxProbability = 0; if ( m_maxProbability == 0 ) { EvtDiracParticle parent{}; parent.noLifeTime(); parent.init( getParentId(), EvtVector4R( EvtPDL::getMass( getParentId() ), 0, 0, 0 ) ); parent.setDiagonalSpinDensity(); EvtAmp amp; - EvtId daughters[3] = {getDaug( 0 ), getDaug( 1 ), getDaug( 2 )}; + EvtId daughters[3] = { getDaug( 0 ), getDaug( 1 ), getDaug( 2 ) }; amp.init( getParentId(), 3, daughters ); parent.makeDaughters( 3, daughters ); EvtParticle* lambda = parent.getDaug( 0 ); EvtParticle* lep1 = parent.getDaug( 1 ); EvtParticle* lep2 = parent.getDaug( 2 ); lambda->noLifeTime(); lep1->noLifeTime(); lep2->noLifeTime(); EvtSpinDensity rho; rho.setDiag( parent.getSpinStates() ); const double M0 = EvtPDL::getMass( getParentId() ); const double mL = EvtPDL::getMass( getDaug( 0 ) ); const double m1 = EvtPDL::getMass( getDaug( 1 ) ); const double m2 = EvtPDL::getMass( getDaug( 2 ) ); const double q2min = ( m1 + m2 ) * ( m1 + m2 ); const double q2max = ( M0 - mL ) * ( M0 - mL ); EvtVector4R p4lambda, p4lep1, p4lep2, boost; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtRareLbToLll is probing whole phase space ..." << std::endl; double prob = 0; const int nsteps = 5000; for ( int i = 0; i <= nsteps; i++ ) { const double q2 = q2min + i * ( q2max - q2min ) / nsteps; const double elambda = ( M0 * M0 + mL * mL - q2 ) / 2 / M0; - double pstar{0}; + double pstar{ 0 }; if ( i != 0 ) { pstar = sqrt( q2 - ( m1 + m2 ) * ( m1 + m2 ) ) * sqrt( q2 - ( m1 - m2 ) * ( m1 - m2 ) ) / 2 / sqrt( q2 ); } boost.set( M0 - elambda, 0, 0, +sqrt( elambda * elambda - mL * mL ) ); if ( i != nsteps ) { p4lambda.set( elambda, 0, 0, -sqrt( elambda * elambda - mL * mL ) ); } else { p4lambda.set( mL, 0, 0, 0 ); } for ( int j = 0; j <= 45; j++ ) { const double theta = j * EvtConst::pi / 45; p4lep1.set( sqrt( pstar * pstar + m1 * m1 ), 0, +pstar * sin( theta ), +pstar * cos( theta ) ); p4lep2.set( sqrt( pstar * pstar + m2 * m2 ), 0, -pstar * sin( theta ), -pstar * cos( theta ) ); - if ( i != nsteps) // At maximal q2 we are already in correct frame as Lambda and W/Zvirtual are at rest + if ( i != nsteps ) // At maximal q2 we are already in correct frame as Lambda and W/Zvirtual are at rest { p4lep1 = boostTo( p4lep1, boost ); p4lep2 = boostTo( p4lep2, boost ); } lambda->init( getDaug( 0 ), p4lambda ); lep1->init( getDaug( 1 ), p4lep1 ); lep2->init( getDaug( 2 ), p4lep2 ); calcAmp( amp, parent ); prob = rho.normalizedProb( amp.getSpinDensity() ); // In case of electron mode add pole if ( m_electronMode ) { - prob /= 1.0 + m_poleSize / ( q2*q2 ); + prob /= 1.0 + m_poleSize / ( q2 * q2 ); } - + if ( prob > m_maxProbability ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " - probability " << prob << " found at q2 = " << q2 << " (" << nsteps * ( q2 - q2min ) / ( q2max - q2min ) << " %) and theta = " << theta * 180 / EvtConst::pi << std::endl; m_maxProbability = prob; } } } m_maxProbability *= 1.05; } setProbMax( m_maxProbability ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtRareLbToLll set up maximum probability to " << m_maxProbability << std::endl; } void EvtRareLbToLll::decay( EvtParticle* parent ) { // Phase space initialization depends on what leptons are if ( m_electronMode ) { setWeight( parent->initializePhaseSpace( getNDaug(), getDaugs(), false, m_poleSize, 1, 2 ) ); } else { parent->initializePhaseSpace( getNDaug(), getDaugs() ); } calcAmp( _amp2, *parent ); } bool EvtRareLbToLll::isParticle( const EvtParticle& parent ) const { const EvtIdSet partlist{ "Lambda_b0" }; return partlist.contains( parent.getId() ); } void EvtRareLbToLll::calcAmp( EvtAmp& amp, const EvtParticle& parent ) { //parent->setDiagonalSpinDensity(); const EvtParticle* lambda = parent.getDaug( 0 ); const EvtIdSet leptons{ "e-", "mu-", "tau-" }; const bool isparticle = isParticle( parent ); const EvtParticle* lp = nullptr; const EvtParticle* lm = nullptr; if ( leptons.contains( parent.getDaug( 1 )->getId() ) ) { lp = parent.getDaug( 1 ); lm = parent.getDaug( 2 ); } else { lp = parent.getDaug( 2 ); lm = parent.getDaug( 1 ); } EvtVector4R P; P.set( parent.mass(), 0.0, 0.0, 0.0 ); EvtVector4R q = lp->getP4() + lm->getP4(); const double qsq = q.mass2(); // Leptonic currents EvtVector4C LV[2][2]; // \bar{\ell} \gamma^{\mu} \ell EvtVector4C LA[2][2]; // \bar{\ell} \gamma^{\mu} \gamma^{5} \ell for ( int i = 0; i < 2; ++i ) { for ( int j = 0; j < 2; ++j ) { if ( isparticle ) { LV[i][j] = EvtLeptonVCurrent( lp->spParent( i ), lm->spParent( j ) ); LA[i][j] = EvtLeptonACurrent( lp->spParent( i ), lm->spParent( j ) ); } else { LV[i][j] = EvtLeptonVCurrent( lp->spParent( 1 - i ), lm->spParent( 1 - j ) ); LA[i][j] = EvtLeptonACurrent( lp->spParent( 1 - i ), lm->spParent( 1 - j ) ); } } } EvtRareLbToLllFF::FormFactors FF; //F, G, FT and GT ffmodel_->getFF( parent, *lambda, FF ); EvtComplex C7eff = wcmodel_->GetC7Eff( qsq ); EvtComplex C9eff = wcmodel_->GetC9Eff( qsq ); EvtComplex C10eff = wcmodel_->GetC10Eff( qsq ); EvtComplex AC[4]; EvtComplex BC[4]; EvtComplex DC[4]; EvtComplex EC[4]; // check to see if particle is same or opposite parity to Lb const int parity = ffmodel_->isNatural( *lambda ) ? 1 : -1; // Lambda spin type const EvtSpinType::spintype spin = EvtPDL::getSpinType( lambda->getId() ); const double mb = 5.209; // Eq. 48 + 49 for ( unsigned int i = 0; i < 4; ++i ) { if ( parity > 0 ) { AC[i] = -2. * mb * C7eff * FF.FT_[i] / qsq + C9eff * FF.F_[i]; BC[i] = -2. * mb * C7eff * FF.GT_[i] / qsq - C9eff * FF.G_[i]; DC[i] = C10eff * FF.F_[i]; EC[i] = -C10eff * FF.G_[i]; } else { AC[i] = -2. * mb * C7eff * FF.GT_[i] / qsq - C9eff * FF.G_[i]; BC[i] = -2. * mb * C7eff * FF.FT_[i] / qsq + C9eff * FF.F_[i]; DC[i] = -C10eff * FF.G_[i]; EC[i] = C10eff * FF.F_[i]; } } // handle particle -> antiparticle in Hadronic currents const double cv = ( isparticle > 0 ) ? 1.0 : -1.0 * parity; const double ca = ( isparticle > 0 ) ? 1.0 : +1.0 * parity; const double cs = ( isparticle > 0 ) ? 1.0 : +1.0 * parity; const double cp = ( isparticle > 0 ) ? 1.0 : -1.0 * parity; if ( EvtSpinType::DIRAC == spin ) { EvtVector4C H1[2][2]; // vector current EvtVector4C H2[2][2]; // axial-vector EvtVector4C T[6]; // Hadronic currents for ( int i = 0; i < 2; ++i ) { for ( int j = 0; j < 2; ++j ) { HadronicAmp( parent, *lambda, T, i, j ); H1[i][j] = ( cv * AC[0] * T[0] + ca * BC[0] * T[1] + cs * AC[1] * T[2] + cp * BC[1] * T[3] + cs * AC[2] * T[4] + cp * BC[2] * T[5] ); H2[i][j] = ( cv * DC[0] * T[0] + ca * EC[0] * T[1] + cs * DC[1] * T[2] + cp * EC[1] * T[3] + cs * DC[2] * T[4] + cp * EC[2] * T[5] ); } } // Spin sums int spins[4]; for ( int i = 0; i < 2; ++i ) { for ( int ip = 0; ip < 2; ++ip ) { for ( int j = 0; j < 2; ++j ) { for ( int jp = 0; jp < 2; ++jp ) { spins[0] = i; spins[1] = ip; spins[2] = j; spins[3] = jp; EvtComplex M = H1[i][ip] * LV[j][jp] + H2[i][ip] * LA[j][jp]; amp.vertex( spins, M ); } } } } } else if ( EvtSpinType::RARITASCHWINGER == spin ) { EvtVector4C T[8]; EvtVector4C H1[2][4]; // vector current // swaped EvtVector4C H2[2][4]; // axial-vector // Build hadronic amplitude for ( int i = 0; i < 2; ++i ) { for ( int j = 0; j < 4; ++j ) { HadronicAmpRS( parent, *lambda, T, i, j ); H1[i][j] = ( cv * AC[0] * T[0] + ca * BC[0] * T[1] + cs * AC[1] * T[2] + cp * BC[1] * T[3] + cs * AC[2] * T[4] + cp * BC[2] * T[5] + cs * AC[3] * T[6] + cp * BC[3] * T[7] ); H2[i][j] = ( cv * DC[0] * T[0] + ca * EC[0] * T[1] + cs * DC[1] * T[2] + cp * EC[1] * T[3] + cs * DC[2] * T[4] + cp * EC[2] * T[5] + cs * DC[3] * T[6] + cp * EC[3] * T[7] ); } } // Spin sums int spins[4]; for ( int i = 0; i < 2; ++i ) { for ( int ip = 0; ip < 4; ++ip ) { for ( int j = 0; j < 2; ++j ) { for ( int jp = 0; jp < 2; ++jp ) { spins[0] = i; spins[1] = ip; spins[2] = j; spins[3] = jp; EvtComplex M = H1[i][ip] * LV[j][jp] + H2[i][ip] * LA[j][jp]; amp.vertex( spins, M ); } } } } } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " EvtRareLbToLll expects DIRAC or RARITASWINGER daughter " << std::endl; } return; } // spin 1/2 daughters void EvtRareLbToLll::HadronicAmp( const EvtParticle& parent, const EvtParticle& lambda, EvtVector4C* T, const int i, const int j ) { const EvtDiracSpinor Sfinal = lambda.spParent( j ); const EvtDiracSpinor Sinit = parent.sp( i ); const EvtVector4R L = lambda.getP4(); EvtVector4R P; P.set( parent.mass(), 0.0, 0.0, 0.0 ); const double Pm = parent.mass(); const double Lm = lambda.mass(); // \bar{u} \gamma^{\mu} u T[0] = EvtLeptonVCurrent( Sfinal, Sinit ); // \bar{u} \gamma^{\mu}\gamma^{5} u T[1] = EvtLeptonACurrent( Sfinal, Sinit ); // \bar{u} v^{\mu} u T[2] = EvtLeptonSCurrent( Sfinal, Sinit ) * ( P / Pm ); // \bar{u} v^{\mu} \gamma^{5} u T[3] = EvtLeptonPCurrent( Sfinal, Sinit ) * ( P / Pm ); // \bar{u} v^{\prime\mu} u T[4] = EvtLeptonSCurrent( Sfinal, Sinit ) * ( L / Lm ); // \bar{u} v^{\prime\mu} \gamma^{5} T[5] = EvtLeptonPCurrent( Sfinal, Sinit ) * ( L / Lm ); // Where: // v = p_{\Lambda_b}/m_{\Lambda_b} // v^{\prime} = p_{\Lambda}/m_{\Lambda} return; } // spin 3/2 daughters void EvtRareLbToLll::HadronicAmpRS( const EvtParticle& parent, const EvtParticle& lambda, EvtVector4C* T, const int i, const int j ) { const EvtRaritaSchwinger Sfinal = lambda.spRSParent( j ); const EvtDiracSpinor Sinit = parent.sp( i ); EvtVector4R P; P.set( parent.mass(), 0.0, 0.0, 0.0 ); const EvtVector4R L = lambda.getP4(); EvtTensor4C ID; ID.setdiag( 1.0, 1.0, 1.0, 1.0 ); EvtDiracSpinor Sprime; for ( int i = 0; i < 4; i++ ) { Sprime.set_spinor( i, Sfinal.getVector( i ) * P ); } const double Pmsq = P.mass2(); const double Pm = parent.mass(); const double PmLm = Pm * lambda.mass(); EvtVector4C V1, V2; for ( int i = 0; i < 4; i++ ) { V1.set( i, EvtLeptonSCurrent( Sfinal.getSpinor( i ), Sinit ) ); V2.set( i, EvtLeptonPCurrent( Sfinal.getSpinor( i ), Sinit ) ); } // \bar{u}_{alpha} v^{\alpha} \gamma^{\mu} u T[0] = EvtLeptonVCurrent( Sprime, Sinit ) * ( 1 / Pm ); // \bar{u}_{alpha} v^{\alpha} \gamma^{\mu} \gamma^{5} u T[1] = EvtLeptonACurrent( Sprime, Sinit ) * ( 1 / Pm ); // \bar{u}_{\alpha} v^{\alpha} v^{\mu} u T[2] = EvtLeptonSCurrent( Sprime, Sinit ) * ( P / Pmsq ); // \bar{u}_{\alpha} v^{\alpha} v^{\mu} \gamma^{5} u T[3] = EvtLeptonPCurrent( Sprime, Sinit ) * ( P / Pmsq ); // \bar{u}_{\alpha} v^{\alpha} v^{\prime \mu} u T[4] = EvtLeptonSCurrent( Sprime, Sinit ) * ( L / PmLm ); // \bar{u}_{\alpha} v^{\alpha} v^{\prime \mu} \gamma^{5} u T[5] = EvtLeptonPCurrent( Sprime, Sinit ) * ( L / PmLm ); // \bar{u}_{\alpha} g^{\alpha\mu} u T[6] = ID.cont2( V1 ); // \bar{u}_{\alpha} g^{\alpha\mu} \gamma^{5} u T[7] = ID.cont2( V2 ); // Where: // v = p_{\Lambda_b}/m_{\Lambda_b} // v^{\prime} = p_{\Lambda}/m_{\Lambda} return; } diff --git a/src/EvtGenModels/EvtRareLbToLllFF.cpp b/src/EvtGenModels/EvtRareLbToLllFF.cpp index 2c6ca3f..a394de1 100644 --- a/src/EvtGenModels/EvtRareLbToLllFF.cpp +++ b/src/EvtGenModels/EvtRareLbToLllFF.cpp @@ -1,312 +1,313 @@ /*********************************************************************** * Copyright 1998-2022 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/EvtRareLbToLllFF.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtVector4R.hh" //----------------------------------------------------------------------------- // Implementation file for class : EvtRareLbToLllFF // // 2013-11-25 : Thomas Blake //----------------------------------------------------------------------------- //============================================================================= // Standard constructor, initializes variables //============================================================================= EvtRareLbToLllFF::FormFactorDependence::FormFactorDependence() : a0_( 0 ), a2_( 0 ), a4_( 0 ), al_( 0 ), ap_( 0 ) { } EvtRareLbToLllFF::FormFactorDependence::FormFactorDependence( const double al, const double ap ) : a0_( 0 ), a2_( 0 ), a4_( 0 ), al_( al ), ap_( ap ) { } EvtRareLbToLllFF::FormFactorDependence::FormFactorDependence( const double a0, const double a2, const double a4, const double al, const double ap ) : a0_( a0 ), a2_( a2 ), a4_( a4 ), al_( al ), ap_( ap ) { } EvtRareLbToLllFF::FormFactorDependence::FormFactorDependence( const EvtRareLbToLllFF::FormFactorDependence& other ) : a0_( other.a0_ ), a2_( other.a2_ ), a4_( other.a4_ ), al_( other.al_ ), ap_( other.ap_ ) { } EvtRareLbToLllFF::FormFactorDependence* EvtRareLbToLllFF::FormFactorDependence::clone() const { return new EvtRareLbToLllFF::FormFactorDependence( a0_, a2_, a4_, al_, ap_ ); } EvtRareLbToLllFF::FormFactorSet::FormFactorSet() { } EvtRareLbToLllFF::FormFactorSet::FormFactorSet( const EvtRareLbToLllFF::FormFactorSet& other ) : F1( other.F1 ), F2( other.F2 ), F3( other.F3 ), F4( other.F4 ), G1( other.G1 ), G2( other.G2 ), G3( other.G3 ), G4( other.G4 ), H1( other.H1 ), H2( other.H2 ), H3( other.H3 ), H4( other.H4 ), H5( other.H5 ), H6( other.H6 ) { } void EvtRareLbToLllFF::FormFactorDependence::param( const double al, const double ap ) { al_ = al; ap_ = ap; } void EvtRareLbToLllFF::FormFactorDependence::param( const double a0, const double a2, const double a4, const double al, const double ap ) { a0_ = a0; a2_ = a2; a4_ = a4; al_ = al; ap_ = ap; } void EvtRareLbToLllFF::init() { // Parameters for Lambda0 auto L1115 = std::make_unique(); L1115->F1.param( 1.21, 0.319, -0.0177, 0.387, 0.372 ); L1115->F2.param( -0.202, -0.219, 0.0103, 0.387, 0.372 ); L1115->F3.param( -0.0615, 0.00102, -0.00139, 0.387, 0.372 ); L1115->F4.param( 0.387, 0.372 ); L1115->G1.param( 0.927, 0.104, -0.00553, 0.387, 0.372 ); L1115->G2.param( -0.236, -0.233, 0.0110, 0.387, 0.372 ); L1115->G3.param( 0.0756, 0.0195, -0.00115, 0.387, 0.372 ); L1115->G4.param( 0.387, 0.372 ); L1115->H1.param( 0.936, 0.0722, -0.00643, 0.387, 0.372 ); L1115->H2.param( 0.227, 0.265, -0.0101, 0.387, 0.372 ); L1115->H3.param( -0.0757, -0.0195, 0.00116, 0.387, 0.372 ); L1115->H4.param( -0.0174, -0.00986, -0.000524, 0.387, 0.372 ); L1115->H5.param( 0.387, 0.372 ); L1115->H6.param( 0.387, 0.372 ); // Parameters for Lambda(Lambda(1520)0) auto L1520 = std::make_unique(); L1520->F1.param( -1.66, -0.295, 0.00924, 0.333, 0.308 ); L1520->F2.param( 0.544, 0.194, -0.00420, 0.333, 0.308 ); L1520->F3.param( 0.126, 0.00799, -0.000635, 0.333, 0.308 ); L1520->F4.param( -0.0330, -0.00977, 0.00211, 0.303, 0.308 ); L1520->G1.param( -0.964, -0.100, 0.00264, 0.333, 0.308 ); L1520->G2.param( 0.625, 0.219, -0.00508, 0.333, 0.308 ); L1520->G3.param( -0.183, -0.0380, 0.00351, 0.333, 0.308 ); L1520->G4.param( 0.0530, 0.0161, -0.00221, 0.333, 0.308 ); L1520->H1.param( -1.08, -0.0732, 0.00464, 0.333, 0.308 ); L1520->H2.param( -0.507, -0.246, 0.00309, 0.333, 0.308 ); L1520->H3.param( 0.187, 0.0295, -0.00107, 0.333, 0.308 ); L1520->H4.param( 0.0772, 0.0267, -0.00217, 0.333, 0.308 ); L1520->H5.param( -0.0517, -0.0173, 0.00259, 0.333, 0.308 ); L1520->H6.param( 0.0206, 0.00679, -0.000220, 0.333, 0.308 ); FFMap_[EvtPDL::getId( "Lambda0" ).getId()] = L1115.get(); FFMap_[EvtPDL::getId( "anti-Lambda0" ).getId()] = L1115.get(); FFMap_[EvtPDL::getId( "Lambda(1520)0" ).getId()] = L1520.get(); FFMap_[EvtPDL::getId( "anti-Lambda(1520)0" ).getId()] = L1520.get(); - FF_ = {std::move( L1115 ), std::move( L1520 )}; + FF_ = { std::move( L1115 ), std::move( L1520 ) }; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtRareLbToLll is using form factors from arXiv:1108.6129 " << std::endl; } //============================================================================= double EvtRareLbToLllFF::func( const double p, const EvtRareLbToLllFF::FormFactorDependence& dep ) const { static const double mq = 0.2848; static const double mtilde = 1.122; const double asq = 0.5 * ( dep.al_ * dep.al_ + dep.ap_ * dep.ap_ ); const double psq = p * p; return ( dep.a0_ + dep.a2_ * psq + dep.a4_ * psq * psq ) * exp( -( 3. * mq * mq * psq ) / ( 2. * mtilde * mtilde * asq ) ); } void EvtRareLbToLllFF::DiracFF( const EvtParticle& parent, const EvtParticle& lambda, const EvtRareLbToLllFF::FormFactorSet& dep, EvtRareLbToLllFF::FormFactors& FF ) const { const double M = lambda.mass(); const double MB = parent.mass(); const double vdotv = calculateVdotV( parent, lambda ); const double p = lambda.getP4().d3mag(); FF.F_[0] = func( p, dep.F1 ); FF.F_[1] = func( p, dep.F2 ); FF.F_[2] = func( p, dep.F3 ); FF.G_[0] = func( p, dep.G1 ); FF.G_[1] = func( p, dep.G2 ); FF.G_[2] = func( p, dep.G3 ); const double H1 = func( p, dep.H1 ); const double H2 = func( p, dep.H2 ); const double H3 = func( p, dep.H3 ); const double H4 = func( p, dep.H4 ); if ( isNatural( lambda ) ) { FF.FT_[0] = -( MB + M ) * H1 - ( MB - M * vdotv ) * H2 - ( MB * vdotv - M ) * H3; FF.FT_[1] = MB * H1 + ( MB - M ) * H2 + ( MB * vdotv - M ) * H4; FF.FT_[2] = M * H1 + ( MB - M ) * H3 - ( MB - M * vdotv ) * H4; FF.GT_[0] = ( MB - M ) * H1 - M * ( 1. - vdotv ) * H2 - MB * ( 1. - vdotv ) * H3; FF.GT_[1] = MB * H1 - M * H2 - MB * H3; FF.GT_[2] = M * H1 + M * H2 + MB * H3; } else { FF.FT_[0] = ( MB - M ) * H1 - ( MB - M * vdotv ) * H2 - ( MB * vdotv - M ) * H3; FF.FT_[1] = MB * H1 - ( MB + M ) * H2 + ( MB * vdotv - M ) * H4; FF.FT_[2] = M * H1 - ( MB + M ) * H3 - ( MB - M * vdotv ) * H4; FF.GT_[0] = -( MB + M ) * H1 + M * ( 1. + vdotv ) * H2 + MB * ( 1. + vdotv ) * H3; FF.GT_[1] = MB * H1 - M * H2 - MB * H3; FF.GT_[2] = M * H1 - M * H2 - MB * H3; } } void EvtRareLbToLllFF::RaritaSchwingerFF( const EvtParticle& parent, const EvtParticle& lambda, const EvtRareLbToLllFF::FormFactorSet& FFset, EvtRareLbToLllFF::FormFactors& FF ) const { const double M = lambda.mass(); const double MB = parent.mass(); const double vdotv = calculateVdotV( parent, lambda ); const double p = lambda.getP4().d3mag(); FF.F_[0] = func( p, FFset.F1 ); FF.F_[1] = func( p, FFset.F2 ); FF.F_[2] = func( p, FFset.F3 ); FF.F_[3] = func( p, FFset.F4 ); FF.G_[0] = func( p, FFset.G1 ); FF.G_[1] = func( p, FFset.G2 ); FF.G_[2] = func( p, FFset.G3 ); FF.G_[3] = func( p, FFset.G4 ); const double H1 = func( p, FFset.H1 ); const double H2 = func( p, FFset.H2 ); const double H3 = func( p, FFset.H3 ); const double H4 = func( p, FFset.H4 ); const double H5 = func( p, FFset.H5 ); const double H6 = func( p, FFset.H6 ); if ( isNatural( lambda ) ) { FF.FT_[0] = -( MB + M ) * H1 - ( MB - M * vdotv ) * H2 - ( MB * vdotv - M ) * H3 - MB * H5; FF.FT_[1] = MB * H1 + ( MB - M ) * H2 + ( MB * vdotv - M ) * H4 - MB * H6; FF.FT_[2] = M * H1 + ( MB - M ) * H3 - ( MB - M * vdotv ) * H4; FF.FT_[3] = ( MB - M ) * H5 + ( MB - M * vdotv ) * H6; FF.GT_[0] = ( MB - M ) * H1 - M * ( 1. - vdotv ) * H2 - MB * ( 1. - vdotv ) * H3 + MB * H5 + M * H6; FF.GT_[1] = MB * H1 - M * H2 - MB * H3; FF.GT_[2] = M * H1 + M * H2 + MB * H3 - M * H6; FF.GT_[3] = ( MB + M ) * H5 + M * ( 1. + vdotv ) * H6; } else { FF.FT_[0] = ( MB - M ) * H1 - ( MB - M * vdotv ) * H2 - ( MB * vdotv - M ) * H3 - MB * H5; FF.FT_[1] = MB * H1 - ( MB + M ) * H2 + ( MB * vdotv - M ) * H4 - MB * H6; FF.FT_[2] = M * H1 - ( MB + M ) * H3 - ( MB - M * vdotv ) * H4; FF.FT_[3] = -( MB + M ) * H5 + ( MB - M * vdotv ) * H6; FF.GT_[0] = -( MB + M ) * H1 + M * ( 1. + vdotv ) * H2 + MB * ( 1. + vdotv ) * H3 + MB * H5 + M * H6; FF.GT_[1] = MB * H1 - M * H2 - MB * H3; FF.GT_[2] = M * H1 - M * H2 - MB * H3 - M * H6; FF.GT_[3] = -( MB - M ) * H5 - M * ( 1. - vdotv ) * H6; } } -void EvtRareLbToLllFF::getFF( const EvtParticle& parent, const EvtParticle& lambda, +void EvtRareLbToLllFF::getFF( const EvtParticle& parent, + const EvtParticle& lambda, EvtRareLbToLllFF::FormFactors& FF ) const { // Find the FF information for this particle, start by setting all to zero FF.areZero(); // Are the FF's for the particle known? auto it = FFMap_.find( lambda.getId().getId() ); if ( it == FFMap_.end() ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " EvtRareLbToLll does not contain FF for " << lambda.getId() << std::endl; return; } // Split by spin 1/2, spin 3/2 const int spin = EvtPDL::getSpinType( lambda.getId() ); if ( EvtSpinType::DIRAC == spin ) { DiracFF( parent, lambda, *( it->second ), FF ); } else if ( spin == EvtSpinType::RARITASCHWINGER ) { RaritaSchwingerFF( parent, lambda, *( it->second ), FF ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " EvtRareLbToLll expects DIRAC or RARITASWINGER daughter " << std::endl; // should add a warning here return; } return; } diff --git a/src/EvtGenModels/EvtTVP.cpp b/src/EvtGenModels/EvtTVP.cpp index a55650a..74d716a 100644 --- a/src/EvtGenModels/EvtTVP.cpp +++ b/src/EvtGenModels/EvtTVP.cpp @@ -1,216 +1,216 @@ /*********************************************************************** * 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/EvtTVP.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtSpinType.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include std::string EvtTVP::getName() { return "TVP"; } EvtDecayBase* EvtTVP::clone() { return new EvtTVP; } void EvtTVP::decay( EvtParticle* root ) { if ( getNDaug() == 2 ) { decay_2body( root ); } else if ( getNDaug() == 3 ) { decay_3body( root ); } } void EvtTVP::init() { checkSpinParent( EvtSpinType::TENSOR ); if ( getNDaug() == 2 ) { // chi -> gamma psi radiative mode checkNArg( 0 ); checkSpinDaughter( 0, EvtSpinType::PHOTON ); checkSpinDaughter( 1, EvtSpinType::VECTOR ); } else if ( getNDaug() == 3 ) { // chi -> psi lepton lepton checkNDaug( 3 ); checkSpinDaughter( 0, EvtSpinType::VECTOR ); checkSpinDaughter( 1, EvtSpinType::DIRAC ); checkSpinDaughter( 2, EvtSpinType::DIRAC ); checkNArg( 1 ); delta = getArg( 0 ); } } void EvtTVP::initProbMax() { if ( getNDaug() == 2 ) { const EvtId parId = getParentId(); if ( parId == EvtPDL::getId( "chi_b2" ) ) { setProbMax( 15.0 ); } else { setProbMax( 2.5 ); } } else if ( getNDaug() == 3 ) { double dSq = delta * delta; double denom = dSq - 0.2; double ratio( 1.0 ); if ( fabs( denom ) > 1e-10 ) { ratio = dSq / denom; } double ffCor = ratio * ratio; const EvtId daugId = getDaug( 1 ); const EvtId parId = getParentId(); if ( daugId == EvtPDL::getId( "mu+" ) || daugId == EvtPDL::getId( "mu-" ) ) { if ( parId == EvtPDL::getId( "chi_c2" ) ) { setProbMax( ffCor * 85.0 ); // tested on 1e6 events } else if ( parId == EvtPDL::getId( "chi_b2" ) ) { setProbMax( ffCor * 750.0 ); // tested on 1e6 events } } else if ( daugId == EvtPDL::getId( "e+" ) || daugId == EvtPDL::getId( "e-" ) ) { if ( parId == EvtPDL::getId( "chi_c2" ) ) { setProbMax( ffCor * 3.5e3 ); // tested on 1e5 events } else if ( parId == EvtPDL::getId( "chi_b2" ) ) { setProbMax( ffCor * 2.6e4 ); } } } } void EvtTVP::decay_2body( EvtParticle* root ) { root->initializePhaseSpace( getNDaug(), getDaugs() ); // Photon is the first particle and psi is the second // to ensure decay file backwards compatibility EvtParticle* photon = root->getDaug( 0 ); EvtParticle* psi = root->getDaug( 1 ); EvtVector4R p = psi->getP4(), // psi momentum k = photon->getP4(); // Photon momentum for ( int iPsi = 0; iPsi < 3; iPsi++ ) { EvtVector4C epsPsi = psi->epsParent( iPsi ).conj(); for ( int iGamma = 0; iGamma < 2; iGamma++ ) { EvtVector4C epsGamma = photon->epsParentPhoton( iGamma ).conj(); for ( int iChi = 0; iChi < 5; iChi++ ) { EvtTensor4C epsChi = root->epsTensor( iChi ); // Baranov PRD 85,014034 (2012), Eq 11 // amp = p^mu epsPsi^a epsChi_{a b} [k_mu epsGamma_b - k_b epsGamma_mu] EvtVector4C eee = epsChi.cont1( epsPsi ); EvtVector4C vvv = ( p * k ) * eee - ( k * eee ) * p; EvtComplex amp = vvv * epsGamma; vertex( iChi, iGamma, iPsi, amp ); } } } } void EvtTVP::decay_3body( EvtParticle* root ) { root->initializePhaseSpace( getNDaug(), getDaugs() ); EvtParticle* psi = root->getDaug( 0 ); EvtParticle* mup = root->getDaug( 1 ); EvtParticle* mum = root->getDaug( 2 ); EvtVector4R p = psi->getP4(), // psi momentum k1 = mup->getP4(), // mu+ momentum k2 = mum->getP4(), // mu- momentum k = k1 + k2; // photon momentum double kSq = k * k; // The decay amplitude needs four-vector products. Make sure we have // valid values for these, otherwise set the amplitude to zero. // We need to set _amp2 (EvtDecayAmp) via the vertex() function call // even when the amplitude is zero, otherwise the amplitude from the // previous accepted event will be used, potentially leading to biases // Selection on k^2 to avoid inefficient generation for the electron modes bool validAmp( true ); if ( kSq < 1e-3 ) { validAmp = false; } double dSq = delta * delta; double dSqDenom = dSq - kSq; if ( fabs( dSqDenom ) < 1e-10 ) { validAmp = false; } double factor( 1.0 ); if ( validAmp ) { factor = dSq / ( dSqDenom * kSq ); } // Calculate the amplitude terms, looping over the psi and lepton states - int iPols[4] = {0, 0, 0, 0}; + int iPols[4] = { 0, 0, 0, 0 }; for ( int iChi = 0; iChi < 5; iChi++ ) { iPols[0] = iChi; EvtTensor4C epsChi = root->epsTensor( iChi ); for ( int iPsi = 0; iPsi < 3; iPsi++ ) { iPols[1] = iPsi; EvtVector4C epsPsi = psi->epsParent( iPsi ).conj(); for ( int iMplus = 0; iMplus < 2; iMplus++ ) { iPols[2] = iMplus; EvtDiracSpinor spMplus = mup->spParent( iMplus ); for ( int iMminus = 0; iMminus < 2; iMminus++ ) { iPols[3] = iMminus; EvtDiracSpinor spMminus = mum->spParent( iMminus ); EvtVector4C epsGamma = EvtLeptonVCurrent( spMplus, spMminus ); // Based on Baranov PRD 85,014034 (2012), Eq 11 // amp = p^mu epsPsi^a epsChi_{a b} [k_mu epsGamma_b - k_b epsGamma_mu]/k^2 EvtVector4C eee = epsChi.cont1( epsPsi ); EvtVector4C vvv = ( p * k ) * eee - ( k * eee ) * p; EvtComplex amp( 0.0, 0.0 ); if ( validAmp ) { amp = vvv * epsGamma; } amp *= factor; // Set the amplitude matrix element using the vertex function vertex( iPols, amp ); } } } } } diff --git a/src/EvtGenModels/EvtVVP.cpp b/src/EvtGenModels/EvtVVP.cpp index a36dbb0..1a1f5e6 100644 --- a/src/EvtGenModels/EvtVVP.cpp +++ b/src/EvtGenModels/EvtVVP.cpp @@ -1,196 +1,196 @@ /*********************************************************************** * 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/EvtVVP.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtSpinType.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include std::string EvtVVP::getName() { return "VVP"; } EvtDecayBase* EvtVVP::clone() { return new EvtVVP; } void EvtVVP::init() { checkSpinParent( EvtSpinType::VECTOR ); if ( getNDaug() == 2 ) { // chi -> gamma psi radiative mode // This model needs 0 parameters, but previously was defined as requiring 8! // Check for 0 or 8 parameters in the decay file for backwards compatibility checkNArg( 0, 8 ); checkNDaug( 2 ); checkSpinDaughter( 0, EvtSpinType::VECTOR ); checkSpinDaughter( 1, EvtSpinType::PHOTON ); } else if ( getNDaug() == 3 ) { // chi -> psi lepton lepton checkSpinDaughter( 0, EvtSpinType::VECTOR ); checkSpinDaughter( 1, EvtSpinType::DIRAC ); checkSpinDaughter( 2, EvtSpinType::DIRAC ); checkNArg( 1 ); delta = getArg( 0 ); } } void EvtVVP::initProbMax() { if ( getNDaug() == 2 ) { setProbMax( 2.0 ); } else if ( getNDaug() == 3 ) { const EvtId daugId = getDaug( 1 ); if ( daugId == EvtPDL::getId( "mu+" ) || daugId == EvtPDL::getId( "mu-" ) ) { setProbMax( 15.0 ); } else if ( daugId == EvtPDL::getId( "e+" ) || daugId == EvtPDL::getId( "e-" ) ) { setProbMax( 600.0 ); } } } void EvtVVP::decay( EvtParticle* root ) { if ( getNDaug() == 2 ) { decay_2body( root ); } else if ( getNDaug() == 3 ) { decay_3body( root ); } } void EvtVVP::decay_2body( EvtParticle* p ) { p->initializePhaseSpace( getNDaug(), getDaugs() ); // Vector is first particle, photon is the second EvtParticle *v, *ph; v = p->getDaug( 0 ); ph = p->getDaug( 1 ); EvtVector3C epsp[3]; EvtVector3C epsv[3]; EvtVector3C epsph[2]; epsp[0] = p->eps( 0 ).vec(); epsp[1] = p->eps( 1 ).vec(); epsp[2] = p->eps( 2 ).vec(); epsv[0] = v->eps( 0 ).vec().conj(); epsv[1] = v->eps( 1 ).vec().conj(); epsv[2] = v->eps( 2 ).vec().conj(); epsph[0] = ph->epsParentPhoton( 0 ).vec().conj(); epsph[1] = ph->epsParentPhoton( 1 ).vec().conj(); int i, j, k; for ( i = 0; i < 3; i++ ) { for ( j = 0; j < 3; j++ ) { for ( k = 0; k < 2; k++ ) { vertex( i, j, k, epsp[i].cross( epsv[j] ) * epsph[k] ); } } } } void EvtVVP::decay_3body( EvtParticle* root ) { root->initializePhaseSpace( getNDaug(), getDaugs() ); EvtParticle* psi = root->getDaug( 0 ); EvtParticle* mup = root->getDaug( 1 ); EvtParticle* mum = root->getDaug( 2 ); EvtVector4R k1 = mup->getP4(), // mu+ momentum k2 = mum->getP4(), // mu- momentum k = k1 + k2; // photon momentum double kSq = k * k; // The decay amplitude needs four-vector products. Make sure we have // valid values for these, otherwise set the amplitude to zero. // We need to set _amp2 (EvtDecayAmp) via the vertex() function call // even when the amplitude is zero, otherwise the amplitude from the // previous accepted event will be used, potentially leading to biases // Selection on k^2 to avoid inefficient generation for the electron modes bool validAmp( true ); if ( kSq < 1e-3 ) { validAmp = false; } // Extra checks to make sure we are not dividing by zero double dSq = delta * delta; double dSqDenom = dSq - kSq; if ( fabs( dSqDenom ) < 1e-10 ) { validAmp = false; } double factor( 1.0 ); if ( validAmp ) { factor = dSq / ( dSqDenom * kSq ); } - int iPols[4] = {0, 0, 0, 0}; + int iPols[4] = { 0, 0, 0, 0 }; // Calculate the amplitude terms, looping over the chi, psi and lepton states for ( int iChi = 0; iChi < 3; iChi++ ) { iPols[0] = iChi; EvtVector4C epsChi = root->epsParent( iChi ); for ( int iPsi = 0; iPsi < 3; iPsi++ ) { iPols[1] = iPsi; EvtVector4C epsPsi = psi->epsParent( iPsi ).conj(); for ( int iMplus = 0; iMplus < 2; iMplus++ ) { iPols[2] = iMplus; EvtDiracSpinor spMplus = mup->spParent( iMplus ); for ( int iMminus = 0; iMminus < 2; iMminus++ ) { iPols[3] = iMminus; EvtDiracSpinor spMminus = mum->spParent( iMminus ); EvtVector4C epsGamma = EvtLeptonVCurrent( spMplus, spMminus ).conj(); // Based on Baranov PRD 85,014034 (2012), Eq 10 // amp = e_{mu nu alpha beta} epsChi^mu epsPsi^nu epsGamma^alpha k^beta/k^2 EvtComplex amp( 0.0, 0.0 ); if ( validAmp ) { amp = k * dual( EvtGenFunctions::directProd( epsChi, epsPsi ) ) .cont1( epsGamma ); } amp *= factor; // Set the amplitude matrix element using the vertex function vertex( iPols, amp ); } } } } } diff --git a/src/EvtGenModels/EvtVtoSll.cpp b/src/EvtGenModels/EvtVtoSll.cpp index b6d7cb2..a4aee11 100644 --- a/src/EvtGenModels/EvtVtoSll.cpp +++ b/src/EvtGenModels/EvtVtoSll.cpp @@ -1,111 +1,111 @@ /*********************************************************************** * 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/EvtVtoSll.hh" #include "EvtGenBase/EvtDiracSpinor.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include #include #include std::string EvtVtoSll::getName() { return "VTOSLL"; } EvtDecayBase* EvtVtoSll::clone() { return new EvtVtoSll; } void EvtVtoSll::init() { // check that there are 0 arguments checkNArg( 0 ); checkNDaug( 3 ); checkSpinParent( EvtSpinType::VECTOR ); checkSpinDaughter( 0, EvtSpinType::SCALAR ); checkSpinDaughter( 1, EvtSpinType::DIRAC ); checkSpinDaughter( 2, EvtSpinType::DIRAC ); } void EvtVtoSll::initProbMax() { - setProbMax(10.0); + setProbMax( 10.0 ); } void EvtVtoSll::decay( EvtParticle* p ) { p->initializePhaseSpace( getNDaug(), getDaugs() ); EvtParticle *l1, *l2; l1 = p->getDaug( 1 ); l2 = p->getDaug( 2 ); EvtVector4C l11, l12, l21, l22; l11 = EvtLeptonVCurrent( l1->spParent( 0 ), l2->spParent( 0 ) ); l12 = EvtLeptonVCurrent( l1->spParent( 0 ), l2->spParent( 1 ) ); l21 = EvtLeptonVCurrent( l1->spParent( 1 ), l2->spParent( 0 ) ); l22 = EvtLeptonVCurrent( l1->spParent( 1 ), l2->spParent( 1 ) ); EvtVector4C eps0 = p->eps( 0 ); EvtVector4C eps1 = p->eps( 1 ); EvtVector4C eps2 = p->eps( 2 ); EvtVector4R P = p->getP4Restframe(); EvtVector4R k = l1->getP4() + l2->getP4(); double k2 = k * k; EvtTensor4C T( dual( EvtGenFunctions::directProd( P, ( 1.0 / k2 ) * k ) ) ); double M2 = p->mass(); M2 *= M2; double m2 = l1->mass(); m2 *= m2; double norm = 1.0 / sqrt( 2 * M2 + 4 * m2 - 4 * m2 * m2 / M2 ); vertex( 0, 0, 0, norm * ( eps0 * T.cont2( l11 ) ) ); vertex( 0, 0, 1, norm * ( eps0 * T.cont2( l12 ) ) ); vertex( 0, 1, 0, norm * ( eps0 * T.cont2( l21 ) ) ); vertex( 0, 1, 1, norm * ( eps0 * T.cont2( l22 ) ) ); vertex( 1, 0, 0, norm * ( eps1 * T.cont2( l11 ) ) ); vertex( 1, 0, 1, norm * ( eps1 * T.cont2( l12 ) ) ); vertex( 1, 1, 0, norm * ( eps1 * T.cont2( l21 ) ) ); vertex( 1, 1, 1, norm * ( eps1 * T.cont2( l22 ) ) ); vertex( 2, 0, 0, norm * ( eps2 * T.cont2( l11 ) ) ); vertex( 2, 0, 1, norm * ( eps2 * T.cont2( l12 ) ) ); vertex( 2, 1, 0, norm * ( eps2 * T.cont2( l21 ) ) ); vertex( 2, 1, 1, norm * ( eps2 * T.cont2( l22 ) ) ); return; } diff --git a/src/EvtGenModels/EvtVub.cpp b/src/EvtGenModels/EvtVub.cpp index 026a282..b514c19 100644 --- a/src/EvtGenModels/EvtVub.cpp +++ b/src/EvtGenModels/EvtVub.cpp @@ -1,406 +1,406 @@ /*********************************************************************** * 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/EvtVub.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenModels/EvtPFermi.hh" #include #include using std::endl; std::string EvtVub::getName() { return "VUB"; } EvtDecayBase* EvtVub::clone() { return new EvtVub; } void EvtVub::init() { // check that there are at least 6 arguments if ( getNArg() < 6 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVub generator expected " << " at least 6 arguments (mb,a,alpha_s,Nbins,m1,w1,...) but found: " << getNArg() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } _mb = getArg( 0 ); _a = getArg( 1 ); _alphas = getArg( 2 ); _nbins = abs( (int)getArg( 3 ) ); _storeQplus = ( getArg( 3 ) < 0 ? 1 : 0 ); _masses = std::vector( _nbins ); _weights = std::vector( _nbins ); if ( getNArg() - 4 != 2 * _nbins ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVub generator expected " << _nbins << " masses and weights but found: " << ( getNArg() - 4 ) / 2 << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } int i, j = 4; double maxw = 0.; for ( i = 0; i < _nbins; i++ ) { _masses[i] = getArg( j++ ); if ( i > 0 && _masses[i] <= _masses[i - 1] ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVub generator expected " << " mass bins in ascending order!" << "Will terminate execution!" << endl; ::abort(); } _weights[i] = getArg( j++ ); if ( _weights[i] < 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVub generator expected " << " weights >= 0, but found: " << _weights[i] << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( _weights[i] > maxw ) maxw = _weights[i]; } if ( maxw == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVub generator expected at least one " << " weight > 0, but found none! " << "Will terminate execution!" << endl; ::abort(); } for ( i = 0; i < _nbins; i++ ) _weights[i] /= maxw; // the maximum dGamma*p2 value depends on alpha_s only: const double dGMax0 = 3.; _dGMax = 0.21344 + 8.905 * _alphas; if ( _dGMax < dGMax0 ) _dGMax = dGMax0; // for the Fermi Motion we need a B-Meson mass - but it's not critical // to get an exact value; in order to stay in the phase space for // B+- and B0 use the smaller mass EvtId BP = EvtPDL::getId( "B+" ); EvtId B0 = EvtPDL::getId( "B0" ); double mB0 = EvtPDL::getMaxMass( B0 ); double mBP = EvtPDL::getMaxMass( BP ); double mB = ( mB0 < mBP ? mB0 : mBP ); const double xlow = -_mb; const double xhigh = mB - _mb; const int aSize = 10000; EvtPFermi pFermi( _a, mB, _mb ); // pf is the cumulative distribution // normalized to 1. _pf.resize( aSize ); for ( i = 0; i < aSize; i++ ) { double kplus = xlow + (double)( i + 0.5 ) / ( (double)aSize ) * ( xhigh - xlow ); if ( i == 0 ) _pf[i] = pFermi.getFPFermi( kplus ); else _pf[i] = _pf[i - 1] + pFermi.getFPFermi( kplus ); } for ( size_t index = 0; index < _pf.size(); index++ ) { _pf[index] /= _pf[_pf.size() - 1]; } // static EvtHepRandomEngine myEngine; // _pFermi = new RandGeneral(myEngine,pf,aSize,0); _dGamma = std::make_unique( _alphas ); // check that there are 3 daughters checkNDaug( 3 ); } void EvtVub::initProbMax() { noProbMax(); } void EvtVub::decay( EvtParticle* p ) { int j; // B+ -> u-bar specflav l+ nu EvtParticle *xuhad( nullptr ), *lepton( nullptr ), *neutrino( nullptr ); EvtVector4R p4; // R. Faccini 21/02/03 // move the reweighting up , before also shooting the fermi distribution double x, z, p2; double sh = 0.0; double mB, ml, xlow, xhigh, qplus; double El = 0.0; double Eh = 0.0; double kplus; const double lp2epsilon = -10; bool rew( true ); while ( rew ) { p->initializePhaseSpace( getNDaug(), getDaugs() ); xuhad = p->getDaug( 0 ); lepton = p->getDaug( 1 ); neutrino = p->getDaug( 2 ); mB = p->mass(); ml = lepton->mass(); xlow = -_mb; xhigh = mB - _mb; // Fermi motion does not need to be computed inside the // tryit loop as m_b in Gamma0 does not need to be replaced by (m_b+kplus). // The difference however should be of the Order (lambda/m_b)^2 which is // beyond the considered orders in the paper anyway ... // for alpha_S = 0 and a mass cut on X_u not all values of kplus are // possible. The maximum value is mB/2-_mb + sqrt(mB^2/4-_masses[0]^2) kplus = 2 * xhigh; while ( kplus >= xhigh || kplus <= xlow || ( _alphas == 0 && kplus >= mB / 2 - _mb + sqrt( mB * mB / 4 - _masses[0] * _masses[0] ) ) ) { kplus = findPFermi(); //_pFermi->shoot(); kplus = xlow + kplus * ( xhigh - xlow ); } qplus = mB - _mb - kplus; if ( ( mB - qplus ) / 2. <= ml ) continue; int tryit = 1; while ( tryit ) { x = EvtRandom::Flat(); z = EvtRandom::Flat( 0, 2 ); p2 = EvtRandom::Flat(); p2 = pow( 10.0, lp2epsilon * p2 ); El = x * ( mB - qplus ) / 2; if ( El > ml && El < mB / 2 ) { Eh = z * ( mB - qplus ) / 2 + qplus; if ( Eh > 0 && Eh < mB ) { sh = p2 * pow( mB - qplus, 2 ) + 2 * qplus * ( Eh - qplus ) + qplus * qplus; if ( sh > _masses[0] * _masses[0] && mB * mB + sh - 2 * mB * Eh > ml * ml ) { double xran = EvtRandom::Flat(); double y = _dGamma->getdGdxdzdp( x, z, p2 ) / _dGMax * p2; if ( y > 1 ) EvtGenReport( EVTGEN_WARNING, "EvtGen" ) << "EvtVub decay probability > 1 found: " << y << endl; if ( y >= xran ) tryit = 0; } } } } // reweight the Mx distribution if ( _nbins > 0 ) { double xran1 = EvtRandom::Flat(); double m = sqrt( sh ); j = 0; while ( j < _nbins && m > _masses[j] ) j++; double w = _weights[j - 1]; if ( w >= xran1 ) rew = false; } else { rew = false; } } // o.k. we have the three kineamtic variables // now calculate a flat cos Theta_H [-1,1] distribution of the // hadron flight direction w.r.t the B flight direction // because the B is a scalar and should decay isotropic. // Then chose a flat Phi_H [0,2Pi] w.r.t the B flight direction // and and a flat Phi_L [0,2Pi] in the W restframe w.r.t the // W flight direction. double ctH = EvtRandom::Flat( -1, 1 ); double phH = EvtRandom::Flat( 0, 2 * EvtConst::pi ); double phL = EvtRandom::Flat( 0, 2 * EvtConst::pi ); // now compute the four vectors in the B Meson restframe double ptmp, sttmp; // calculate the hadron 4 vector in the B Meson restframe sttmp = sqrt( 1 - ctH * ctH ); ptmp = sqrt( Eh * Eh - sh ); - double pHB[4] = {Eh, ptmp * sttmp * cos( phH ), ptmp * sttmp * sin( phH ), - ptmp * ctH}; + double pHB[4] = { Eh, ptmp * sttmp * cos( phH ), ptmp * sttmp * sin( phH ), + ptmp * ctH }; p4.set( pHB[0], pHB[1], pHB[2], pHB[3] ); xuhad->init( getDaug( 0 ), p4 ); if ( _storeQplus ) { // cludge to store the hidden parameter q+ with the decay; // the lifetime of the Xu is abused for this purpose. // tau = 1 ps corresponds to ctau = 0.3 mm -> in order to // stay well below BaBars sensitivity we take q+/(10000 GeV) which // goes up to 0.0005 in the most extreme cases as ctau in mm. // To extract q+ back from the StdHepTrk its necessary to get // delta_ctau = Xu->anyDaughter->getVertexTime()-Xu->getVertexTime() // where these pseudo calls refere to the StdHep time stored at // the production vertex in the lab for each particle. The boost // has to be reversed and the result is: // // q+ = delta_ctau * 10000 GeV/mm * Mass_Xu/Energy_Xu // xuhad->setLifetime( qplus / 10000. ); } // calculate the W 4 vector in the B Meson restrframe double apWB = ptmp; - double pWB[4] = {mB - Eh, -pHB[1], -pHB[2], -pHB[3]}; + double pWB[4] = { mB - Eh, -pHB[1], -pHB[2], -pHB[3] }; // first go in the W restframe and calculate the lepton and // the neutrino in the W frame double mW2 = mB * mB + sh - 2 * mB * Eh; double beta = ptmp / pWB[0]; double gamma = pWB[0] / sqrt( mW2 ); double pLW[4]; ptmp = ( mW2 - ml * ml ) / 2 / sqrt( mW2 ); pLW[0] = sqrt( ml * ml + ptmp * ptmp ); double ctL = ( El - gamma * pLW[0] ) / beta / gamma / ptmp; if ( ctL < -1 ) ctL = -1; if ( ctL > 1 ) ctL = 1; sttmp = sqrt( 1 - ctL * ctL ); // eX' = eZ x eW - double xW[3] = {-pWB[2], pWB[1], 0}; + double xW[3] = { -pWB[2], pWB[1], 0 }; // eZ' = eW - double zW[3] = {pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB}; + double zW[3] = { pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB }; double lx = sqrt( xW[0] * xW[0] + xW[1] * xW[1] ); for ( j = 0; j < 2; j++ ) xW[j] /= lx; // eY' = eZ' x eX' - double yW[3] = {-pWB[1] * pWB[3], -pWB[2] * pWB[3], - pWB[1] * pWB[1] + pWB[2] * pWB[2]}; + double yW[3] = { -pWB[1] * pWB[3], -pWB[2] * pWB[3], + pWB[1] * pWB[1] + pWB[2] * pWB[2] }; double ly = sqrt( yW[0] * yW[0] + yW[1] * yW[1] + yW[2] * yW[2] ); for ( j = 0; j < 3; j++ ) yW[j] /= ly; // p_lep = |p_lep| * ( sin(Theta) * cos(Phi) * eX' // + sin(Theta) * sin(Phi) * eY' // + cos(Theta) * eZ') for ( j = 0; j < 3; j++ ) pLW[j + 1] = sttmp * cos( phL ) * ptmp * xW[j] + sttmp * sin( phL ) * ptmp * yW[j] + ctL * ptmp * zW[j]; double apLW = ptmp; // boost them back in the B Meson restframe double appLB = beta * gamma * pLW[0] + gamma * ctL * apLW; ptmp = sqrt( El * El - ml * ml ); double ctLL = appLB / ptmp; if ( ctLL > 1 ) ctLL = 1; if ( ctLL < -1 ) ctLL = -1; - double pLB[4] = {El, 0, 0, 0}; - double pNB[4] = {pWB[0] - El, 0, 0, 0}; + double pLB[4] = { El, 0, 0, 0 }; + double pNB[4] = { pWB[0] - El, 0, 0, 0 }; for ( j = 1; j < 4; j++ ) { pLB[j] = pLW[j] + ( ctLL * ptmp - ctL * apLW ) / apWB * pWB[j]; pNB[j] = pWB[j] - pLB[j]; } p4.set( pLB[0], pLB[1], pLB[2], pLB[3] ); lepton->init( getDaug( 1 ), p4 ); p4.set( pNB[0], pNB[1], pNB[2], pNB[3] ); neutrino->init( getDaug( 2 ), p4 ); return; } double EvtVub::findPFermi() { double ranNum = EvtRandom::Flat(); double oOverBins = 1.0 / ( float( _pf.size() ) ); int nBinsBelow = 0; // largest k such that I[k] is known to be <= rand int nBinsAbove = _pf.size(); // largest k such that I[k] is known to be > rand int middle; while ( nBinsAbove > nBinsBelow + 1 ) { middle = ( nBinsAbove + nBinsBelow + 1 ) >> 1; if ( ranNum >= _pf[middle] ) { nBinsBelow = middle; } else { nBinsAbove = middle; } } double bSize = _pf[nBinsAbove] - _pf[nBinsBelow]; // binMeasure is always aProbFunc[nBinsBelow], if ( bSize == 0 ) { // rand lies right in a bin of measure 0. Simply return the center // of the range of that bin. (Any value between k/N and (k+1)/N is // equally good, in this rare case.) return ( nBinsBelow + .5 ) * oOverBins; } double bFract = ( ranNum - _pf[nBinsBelow] ) / bSize; return ( nBinsBelow + bFract ) * oOverBins; } diff --git a/src/EvtGenModels/EvtVubBLNP.cpp b/src/EvtGenModels/EvtVubBLNP.cpp index e819bdf..c2c3dc0 100644 --- a/src/EvtGenModels/EvtVubBLNP.cpp +++ b/src/EvtGenModels/EvtVubBLNP.cpp @@ -1,1051 +1,1051 @@ /*********************************************************************** * 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/EvtVubBLNP.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenModels/EvtItgPtrFunction.hh" #include "EvtGenModels/EvtItgSimpsonIntegrator.hh" #include "EvtGenModels/EvtPFermi.hh" #include #include // For incomplete gamma function #include "math.h" #include "signal.h" #define ITMAX 100 #define EPS 3.0e-7 #define FPMIN 1.0e-30 using std::cout; using std::endl; std::string EvtVubBLNP::getName() { return "VUB_BLNP"; } EvtDecayBase* EvtVubBLNP::clone() { return new EvtVubBLNP; } void EvtVubBLNP::init() { // get parameters (declared in the header file) // Input parameters mBB = 5.2792; lambda2 = 0.12; // Shape function parameters b = getArg( 0 ); Lambda = getArg( 1 ); Ecut = 1.8; wzero = mBB - 2 * Ecut; // SF and SSF modes itype = (int)getArg( 5 ); dtype = getArg( 5 ); isubl = (int)getArg( 6 ); // flags flag1 = (int)getArg( 7 ); flag2 = (int)getArg( 8 ); flag3 = (int)getArg( 9 ); // Quark mass mb = 4.61; // hidden parameter what and SF stuff const double xlow = 0; const double xhigh = mBB; const int aSize = 10000; EvtPFermi pFermi( Lambda, b ); // pf is the cumulative distribution normalized to 1. _pf.resize( aSize ); for ( int i = 0; i < aSize; i++ ) { double what = xlow + (double)( i + 0.5 ) / ( (double)aSize ) * ( xhigh - xlow ); if ( i == 0 ) _pf[i] = pFermi.getSFBLNP( what ); else _pf[i] = _pf[i - 1] + pFermi.getSFBLNP( what ); } for ( size_t i = 0; i < _pf.size(); i++ ) { _pf[i] /= _pf[_pf.size() - 1]; } // Matching scales muh = mBB * getArg( 2 ); // 0.5 mui = getArg( 3 ); // 1.5 mubar = getArg( 4 ); // 1.5 // Perturbative quantities CF = 4.0 / 3.0; CA = 3.0; double nf = 4.0; beta0 = 11.0 / 3.0 * CA - 2.0 / 3.0 * nf; beta1 = 34.0 / 3.0 * CA * CA - 10.0 / 3.0 * CA * nf - 2.0 * CF * nf; beta2 = 2857.0 / 54.0 * CA * CA * CA + ( CF * CF - 205.0 / 18.0 * CF * CA - 1415.0 / 54.0 * CA * CA ) * nf + ( 11.0 / 9.0 * CF + 79.0 / 54.0 * CA ) * nf * nf; zeta3 = 1.0 + 1 / 8.0 + 1 / 27.0 + 1 / 64.0; Gamma0 = 4 * CF; Gamma1 = CF * ( ( 268.0 / 9.0 - 4.0 * M_PI * M_PI / 3.0 ) * CA - 40.0 / 9.0 * nf ); Gamma2 = 16 * CF * ( ( 245.0 / 24.0 - 67.0 / 54.0 * M_PI * M_PI + +11.0 / 180.0 * pow( M_PI, 4 ) + 11.0 / 6.0 * zeta3 ) * CA * CA * +( -209.0 / 108.0 + 5.0 / 27.0 * M_PI * M_PI - 7.0 / 3.0 * zeta3 ) * CA * nf + ( -55.0 / 24.0 + 2 * zeta3 ) * CF * nf - nf * nf / 27.0 ); gp0 = -5.0 * CF; gp1 = -8.0 * CF * ( ( 3.0 / 16.0 - M_PI * M_PI / 4.0 + 3 * zeta3 ) * CF + ( 1549.0 / 432.0 + 7.0 / 48.0 * M_PI * M_PI - 11.0 / 4.0 * zeta3 ) * CA - ( 125.0 / 216.0 + M_PI * M_PI / 24.0 ) * nf ); // Lbar and mupisq Lbar = Lambda; // all models mupisq = 3 * Lambda * Lambda / b; if ( itype == 1 ) mupisq = 3 * Lambda * Lambda / b; if ( itype == 2 ) mupisq = 3 * Lambda * Lambda * ( Gamma( 1 + 0.5 * b ) * Gamma( 0.5 * b ) / pow( Gamma( 0.5 + 0.5 * b ), 2 ) - 1 ); // moment2 for SSFs moment2 = pow( 0.3, 3 ); // inputs for total rate (T for Total); use BLNP notebook defaults flagpower = 1; flag2loop = 1; // stuff for the integrator maxLoop = 20; //precision = 1.0e-3; precision = 2.0e-2; // vector of global variables, to pass to static functions (which can't access globals); gvars.push_back( 0.0 ); // 0 gvars.push_back( 0.0 ); // 1 gvars.push_back( mui ); // 2 gvars.push_back( b ); // 3 gvars.push_back( Lambda ); // 4 gvars.push_back( mBB ); // 5 gvars.push_back( mb ); // 6 gvars.push_back( wzero ); // 7 gvars.push_back( beta0 ); // 8 gvars.push_back( beta1 ); // 9 gvars.push_back( beta2 ); // 10 gvars.push_back( dtype ); // 11 // check that there are 3 daughters and 10 arguments checkNDaug( 3 ); checkNArg( 10 ); } void EvtVubBLNP::initProbMax() { noProbMax(); } void EvtVubBLNP::decay( EvtParticle* Bmeson ) { int j; EvtParticle *xuhad( nullptr ), *lepton( nullptr ), *neutrino( nullptr ); EvtVector4R p4; double Pp, Pm, Pl, pdf, EX, sh, ml, mpi, ratemax; double El( 0. ); double xhigh, xlow, what; Bmeson->initializePhaseSpace( getNDaug(), getDaugs() ); xuhad = Bmeson->getDaug( 0 ); lepton = Bmeson->getDaug( 1 ); neutrino = Bmeson->getDaug( 2 ); mBB = Bmeson->mass(); ml = lepton->mass(); // get SF value xlow = 0; xhigh = mBB; // the case for alphas = 0 is not considered what = 2 * xhigh; while ( what > xhigh || what < xlow ) { what = findBLNPWhat(); what = xlow + what * ( xhigh - xlow ); } bool tryit = true; while ( tryit ) { // generate pp between 0 and // Flat(min, max) gives R(max - min) + min, where R = random btwn 0 and 1 Pp = EvtRandom::Flat( 0, mBB ); // P+ = EX - |PX| Pl = EvtRandom::Flat( 0, mBB ); // mBB - 2El Pm = EvtRandom::Flat( 0, mBB ); // P- = EX + |PX| sh = Pm * Pp; EX = 0.5 * ( Pm + Pp ); El = 0.5 * ( mBB - Pl ); // Need maximum rate. Waiting for Mr. Paz to give it to me. // Meanwhile, use this. ratemax = 3.0; // From trial and error - most events below 3.0 // kinematic bounds (Eq. 2) mpi = 0.14; if ( ( Pp > 0 ) && ( Pp <= Pl ) && ( Pl <= Pm ) && ( Pm < mBB ) && ( El > ml ) && ( sh > 4 * mpi * mpi ) ) { // Probability of pass proportional to PDF pdf = rate3( Pp, Pl, Pm ); double testRan = EvtRandom::Flat( 0., ratemax ); if ( pdf >= testRan ) tryit = false; } } // o.k. we have the three kineamtic variables // now calculate a flat cos Theta_H [-1,1] distribution of the // hadron flight direction w.r.t the B flight direction // because the B is a scalar and should decay isotropic. // Then chose a flat Phi_H [0,2Pi] w.r.t the B flight direction // and and a flat Phi_L [0,2Pi] in the W restframe w.r.t the // W flight direction. double ctH = EvtRandom::Flat( -1, 1 ); double phH = EvtRandom::Flat( 0, 2 * M_PI ); double phL = EvtRandom::Flat( 0, 2 * M_PI ); // now compute the four vectors in the B Meson restframe double ptmp, sttmp; // calculate the hadron 4 vector in the B Meson restframe sttmp = sqrt( 1 - ctH * ctH ); ptmp = sqrt( EX * EX - sh ); - double pHB[4] = {EX, ptmp * sttmp * cos( phH ), ptmp * sttmp * sin( phH ), - ptmp * ctH}; + double pHB[4] = { EX, ptmp * sttmp * cos( phH ), ptmp * sttmp * sin( phH ), + ptmp * ctH }; p4.set( pHB[0], pHB[1], pHB[2], pHB[3] ); xuhad->init( getDaug( 0 ), p4 ); bool _storeWhat( true ); if ( _storeWhat ) { // cludge to store the hidden parameter what with the decay; // the lifetime of the Xu is abused for this purpose. // tau = 1 ps corresponds to ctau = 0.3 mm -> in order to // stay well below BaBars sensitivity we take what/(10000 GeV). // To extract what back from the StdHepTrk its necessary to get // delta_ctau = Xu->decayVtx()->point().distanceTo(XuDaughter->decayVtx()->point()); // // what = delta_ctau * 100000 * Mass_Xu/Momentum_Xu // xuhad->setLifetime( what / 10000. ); } // calculate the W 4 vector in the B Meson restrframe double apWB = ptmp; - double pWB[4] = {mBB - EX, -pHB[1], -pHB[2], -pHB[3]}; + double pWB[4] = { mBB - EX, -pHB[1], -pHB[2], -pHB[3] }; // first go in the W restframe and calculate the lepton and // the neutrino in the W frame double mW2 = mBB * mBB + sh - 2 * mBB * EX; double beta = ptmp / pWB[0]; double gamma = pWB[0] / sqrt( mW2 ); double pLW[4]; ptmp = ( mW2 - ml * ml ) / 2 / sqrt( mW2 ); pLW[0] = sqrt( ml * ml + ptmp * ptmp ); double ctL = ( El - gamma * pLW[0] ) / beta / gamma / ptmp; if ( ctL < -1 ) ctL = -1; if ( ctL > 1 ) ctL = 1; sttmp = sqrt( 1 - ctL * ctL ); // eX' = eZ x eW - double xW[3] = {-pWB[2], pWB[1], 0}; + double xW[3] = { -pWB[2], pWB[1], 0 }; // eZ' = eW - double zW[3] = {pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB}; + double zW[3] = { pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB }; double lx = sqrt( xW[0] * xW[0] + xW[1] * xW[1] ); for ( j = 0; j < 2; j++ ) xW[j] /= lx; // eY' = eZ' x eX' - double yW[3] = {-pWB[1] * pWB[3], -pWB[2] * pWB[3], - pWB[1] * pWB[1] + pWB[2] * pWB[2]}; + double yW[3] = { -pWB[1] * pWB[3], -pWB[2] * pWB[3], + pWB[1] * pWB[1] + pWB[2] * pWB[2] }; double ly = sqrt( yW[0] * yW[0] + yW[1] * yW[1] + yW[2] * yW[2] ); for ( j = 0; j < 3; j++ ) yW[j] /= ly; // p_lep = |p_lep| * ( sin(Theta) * cos(Phi) * eX' // + sin(Theta) * sin(Phi) * eY' // + cos(Theta) * eZ') for ( j = 0; j < 3; j++ ) pLW[j + 1] = sttmp * cos( phL ) * ptmp * xW[j] + sttmp * sin( phL ) * ptmp * yW[j] + ctL * ptmp * zW[j]; double apLW = ptmp; // boost them back in the B Meson restframe double appLB = beta * gamma * pLW[0] + gamma * ctL * apLW; ptmp = sqrt( El * El - ml * ml ); double ctLL = appLB / ptmp; if ( ctLL > 1 ) ctLL = 1; if ( ctLL < -1 ) ctLL = -1; - double pLB[4] = {El, 0, 0, 0}; - double pNB[4] = {pWB[0] - El, 0, 0, 0}; + double pLB[4] = { El, 0, 0, 0 }; + double pNB[4] = { pWB[0] - El, 0, 0, 0 }; for ( j = 1; j < 4; j++ ) { pLB[j] = pLW[j] + ( ctLL * ptmp - ctL * apLW ) / apWB * pWB[j]; pNB[j] = pWB[j] - pLB[j]; } p4.set( pLB[0], pLB[1], pLB[2], pLB[3] ); lepton->init( getDaug( 1 ), p4 ); p4.set( pNB[0], pNB[1], pNB[2], pNB[3] ); neutrino->init( getDaug( 2 ), p4 ); return; } double EvtVubBLNP::rate3( double Pp, double Pl, double Pm ) { // rate3 in units of GF^2*Vub^2/pi^3 double factor = 1.0 / 16 * ( mBB - Pp ) * U1lo( muh, mui ) * pow( ( Pm - Pp ) / ( mBB - Pp ), alo( muh, mui ) ); double doneJS = DoneJS( Pp, Pm, mui ); double done1 = Done1( Pp, Pm, mui ); double done2 = Done2( Pp, Pm, mui ); double done3 = Done3( Pp, Pm, mui ); // The EvtSimpsonIntegrator returns zero for bad integrals. // So if any of the integrals are zero (ie bad), return zero. // This will cause pdf = 0, so the event will not pass. // I hope this will not introduce a bias. if ( doneJS * done1 * done2 * done3 == 0.0 ) { //cout << "Integral failed: (Pp, Pm, Pl) = (" << Pp << ", " << Pm << ", " << Pl << ")" << endl; return 0.0; } // if (doneJS*done1*done2*done3 != 0.0) { // cout << "Integral OK: (Pp, Pm, Pl) = (" << Pp << ", " << Pm << ", " << Pl << ")" << endl; //} double f1 = F1( Pp, Pm, muh, mui, mubar, doneJS, done1 ); double f2 = F2( Pp, Pm, muh, mui, mubar, done3 ); double f3 = F3( Pp, Pm, muh, mui, mubar, done2 ); double answer = factor * ( ( mBB + Pl - Pp - Pm ) * ( Pm - Pl ) * f1 + 2 * ( Pl - Pp ) * ( Pm - Pl ) * f2 + ( mBB - Pm ) * ( Pm - Pp ) * f3 ); return answer; } double EvtVubBLNP::F1( double Pp, double Pm, double muh, double mui, double mubar, double doneJS, double done1 ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double y = ( Pm - Pp ) / ( mBB - Pp ); double ah = CF * alphas( muh, vars ) / 4 / M_PI; double ai = CF * alphas( mui, vars ) / 4 / M_PI; double abar = CF * alphas( mubar, vars ) / 4 / M_PI; double lambda1 = -mupisq; double t1 = -4 * ai / ( Pp - Lbar ) * ( 2 * log( ( Pp - Lbar ) / mui ) + 1 ); double t2 = 1 + dU1nlo( muh, mui ) + anlo( muh, mui ) * log( y ); double t3 = -4.0 * pow( log( y * mb / muh ), 2 ) + 10.0 * log( y * mb / muh ) - 4.0 * log( y ) - 2.0 * log( y ) / ( 1 - y ) - 4.0 * PolyLog( 2, 1 - y ) - M_PI * M_PI / 6.0 - 12.0; double t4 = 2 * pow( log( y * mb * Pp / ( mui * mui ) ), 2 ) - 3 * log( y * mb * Pp / ( mui * mui ) ) + 7 - M_PI * M_PI; double t5 = -wS( Pp ) + 2 * t( Pp ) + ( 1.0 / y - 1.0 ) * ( u( Pp ) - v( Pp ) ); double t6 = -( lambda1 + 3.0 * lambda2 ) / 3.0 + 1.0 / pow( y, 2 ) * ( 4.0 / 3.0 * lambda1 - 2.0 * lambda2 ); double shapePp = Shat( Pp, vars ); double answer = ( t2 + ah * t3 + ai * t4 ) * shapePp + ai * doneJS + 1 / ( mBB - Pp ) * ( flag2 * abar * done1 + flag1 * t5 ) + 1 / pow( mBB - Pp, 2 ) * flag3 * shapePp * t6; if ( Pp > Lbar + mui / exp( 0.5 ) ) answer = answer + t1; return answer; } double EvtVubBLNP::F2( double Pp, double Pm, double muh, double /*mui*/, double mubar, double done3 ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double y = ( Pm - Pp ) / ( mBB - Pp ); double lambda1 = -mupisq; double ah = CF * alphas( muh, vars ) / 4 / M_PI; double abar = CF * alphas( mubar, vars ) / 4 / M_PI; double t6 = -wS( Pp ) - 2 * t( Pp ) + 1.0 / y * ( t( Pp ) + v( Pp ) ); double t7 = 1 / pow( y, 2 ) * ( 2.0 / 3.0 * lambda1 + 4.0 * lambda2 ) - 1 / y * ( 2.0 / 3.0 * lambda1 + 3.0 / 2.0 * lambda2 ); double shapePp = Shat( Pp, vars ); double answer = ah * log( y ) / ( 1 - y ) * shapePp + 1 / ( mBB - Pp ) * ( flag2 * abar * 0.5 * done3 + flag1 / y * t6 ) + 1.0 / pow( mBB - Pp, 2 ) * flag3 * shapePp * t7; return answer; } double EvtVubBLNP::F3( double Pp, double Pm, double /*muh*/, double /*mui*/, double mubar, double done2 ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double y = ( Pm - Pp ) / ( mBB - Pp ); double lambda1 = -mupisq; double abar = CF * alphas( mubar, vars ) / 4 / M_PI; double t7 = 1.0 / pow( y, 2 ) * ( -2.0 / 3.0 * lambda1 + lambda2 ); double shapePp = Shat( Pp, vars ); double answer = 1.0 / ( Pm - Pp ) * flag2 * 0.5 * y * abar * done2 + 1.0 / pow( mBB - Pp, 2 ) * flag3 * shapePp * t7; return answer; } double EvtVubBLNP::DoneJS( double Pp, double Pm, double /*mui*/ ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double lowerlim = 0.001 * Pp; double upperlim = ( 1.0 - 0.001 ) * Pp; - auto func = EvtItgPtrFunction{&IntJS, lowerlim, upperlim, vars}; - auto integ = EvtItgSimpsonIntegrator{func, precision, maxLoop}; + auto func = EvtItgPtrFunction{ &IntJS, lowerlim, upperlim, vars }; + auto integ = EvtItgSimpsonIntegrator{ func, precision, maxLoop }; return integ.evaluate( lowerlim, upperlim ); } double EvtVubBLNP::Done1( double Pp, double Pm, double /*mui*/ ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double lowerlim = 0.001 * Pp; double upperlim = ( 1.0 - 0.001 ) * Pp; - auto func = EvtItgPtrFunction{&Int1, lowerlim, upperlim, vars}; - auto integ = EvtItgSimpsonIntegrator{func, precision, maxLoop}; + auto func = EvtItgPtrFunction{ &Int1, lowerlim, upperlim, vars }; + auto integ = EvtItgSimpsonIntegrator{ func, precision, maxLoop }; return integ.evaluate( lowerlim, upperlim ); } double EvtVubBLNP::Done2( double Pp, double Pm, double /*mui*/ ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double lowerlim = 0.001 * Pp; double upperlim = ( 1.0 - 0.001 ) * Pp; - auto func = EvtItgPtrFunction{&Int2, lowerlim, upperlim, vars}; - auto integ = EvtItgSimpsonIntegrator{func, precision, maxLoop}; + auto func = EvtItgPtrFunction{ &Int2, lowerlim, upperlim, vars }; + auto integ = EvtItgSimpsonIntegrator{ func, precision, maxLoop }; return integ.evaluate( lowerlim, upperlim ); } double EvtVubBLNP::Done3( double Pp, double Pm, double /*mui*/ ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double lowerlim = 0.001 * Pp; double upperlim = ( 1.0 - 0.001 ) * Pp; - auto func = EvtItgPtrFunction{&Int3, lowerlim, upperlim, vars}; - auto integ = EvtItgSimpsonIntegrator{func, precision, maxLoop}; + auto func = EvtItgPtrFunction{ &Int3, lowerlim, upperlim, vars }; + auto integ = EvtItgSimpsonIntegrator{ func, precision, maxLoop }; return integ.evaluate( lowerlim, upperlim ); } double EvtVubBLNP::Int1( double what, const std::vector& vars ) { return Shat( what, vars ) * g1( what, vars ); } double EvtVubBLNP::Int2( double what, const std::vector& vars ) { return Shat( what, vars ) * g2( what, vars ); } double EvtVubBLNP::Int3( double what, const std::vector& vars ) { return Shat( what, vars ) * g3( what, vars ); } double EvtVubBLNP::IntJS( double what, const std::vector& vars ) { double Pp = vars[0]; double Pm = vars[1]; double mui = vars[2]; double mBB = vars[5]; double mb = vars[6]; double y = ( Pm - Pp ) / ( mBB - Pp ); return 1 / ( Pp - what ) * ( Shat( what, vars ) - Shat( Pp, vars ) ) * ( 4 * log( y * mb * ( Pp - what ) / ( mui * mui ) ) - 3 ); } double EvtVubBLNP::g1( double w, const std::vector& vars ) { double Pp = vars[0]; double Pm = vars[1]; double mBB = vars[5]; double y = ( Pm - Pp ) / ( mBB - Pp ); double x = ( Pp - w ) / ( mBB - Pp ); double q1 = ( 1 + x ) * ( 1 + x ) * y * ( x + y ); double q2 = y * ( -9 + 10 * y ) + x * x * ( -12.0 + 13.0 * y ) + 2 * x * ( -8.0 + 6 * y + 3 * y * y ); double q3 = 4 / x * log( y + y / x ); double q4 = 3.0 * pow( x, 4 ) * ( -2.0 + y ) - 2 * pow( y, 3 ) - 4 * pow( x, 3 ) * ( 2.0 + y ) - 2 * x * y * y * ( 4 + y ) - x * x * y * ( 12 + 4 * y + y * y ); double q5 = log( 1 + y / x ); double answer = q2 / q1 - q3 - 2 * q4 * q5 / ( q1 * y * x ); return answer; } double EvtVubBLNP::g2( double w, const std::vector& vars ) { double Pp = vars[0]; double Pm = vars[1]; double mBB = vars[5]; double y = ( Pm - Pp ) / ( mBB - Pp ); double x = ( Pp - w ) / ( mBB - Pp ); double q1 = ( 1 + x ) * ( 1 + x ) * pow( y, 3 ) * ( x + y ); double q2 = 10.0 * pow( x, 4 ) + y * y + 3.0 * pow( x, 2 ) * y * ( 10.0 + y ) + pow( x, 3 ) * ( 12.0 + 19.0 * y ) + x * y * ( 8.0 + 4.0 * y + y * y ); double q3 = 5 * pow( x, 4 ) + 2.0 * y * y + 6.0 * pow( x, 3 ) * ( 1.0 + 2.0 * y ) + 4.0 * x * y * ( 1 + 2.0 * y ) + x * x * y * ( 18.0 + 5.0 * y ); double q4 = log( 1 + y / x ); double answer = 2.0 / q1 * ( y * q2 - 2 * x * q3 * q4 ); return answer; } double EvtVubBLNP::g3( double w, const std::vector& vars ) { double Pp = vars[0]; double Pm = vars[1]; double mBB = vars[5]; double y = ( Pm - Pp ) / ( mBB - Pp ); double x = ( Pp - w ) / ( mBB - Pp ); double q1 = ( 1 + x ) * ( 1 + x ) * pow( y, 3 ) * ( x + y ); double q2 = 2.0 * pow( y, 3 ) * ( -11.0 + 2.0 * y ) - 10.0 * pow( x, 4 ) * ( 6 - 6 * y + y * y ) + x * y * y * ( -94.0 + 29.0 * y + 2.0 * y * y ) + 2.0 * x * x * y * ( -72.0 + 18.0 * y + 13.0 * y * y ) - x * x * x * ( 72.0 + 42.0 * y - 70.0 * y * y + 3.0 * y * y * y ); double q3 = -6.0 * x * ( -5.0 + y ) * pow( y, 3 ) + 4 * pow( y, 4 ) + 5 * pow( x, 5 ) * ( 6 - 6 * y + y * y ) - 4 * x * x * y * y * ( -20.0 + 6 * y + y * y ) + pow( x, 3 ) * y * ( 90.0 - 10.0 * y - 28.0 * y * y + y * y * y ) + pow( x, 4 ) * ( 36.0 + 36.0 * y - 50.0 * y * y + 4 * y * y * y ); double q4 = log( 1 + y / x ); double answer = q2 / q1 + 2 / q1 / y * q3 * q4; return answer; } double EvtVubBLNP::Shat( double w, const std::vector& vars ) { double mui = vars[2]; double b = vars[3]; double Lambda = vars[4]; double wzero = vars[7]; int itype = (int)vars[11]; double norm = 0.0; double shape = 0.0; if ( itype == 1 ) { double Lambar = ( Lambda / b ) * ( Gamma( 1 + b ) - Gamma( 1 + b, b * wzero / Lambda ) ) / ( Gamma( b ) - Gamma( b, b * wzero / Lambda ) ); double muf = wzero - Lambar; double mupisq = 3 * pow( Lambda, 2 ) / pow( b, 2 ) * ( Gamma( 2 + b ) - Gamma( 2 + b, b * wzero / Lambda ) ) / ( Gamma( b ) - Gamma( b, b * wzero / Lambda ) ) - 3 * Lambar * Lambar; norm = Mzero( muf, mui, mupisq, vars ) * Gamma( b ) / ( Gamma( b ) - Gamma( b, b * wzero / Lambda ) ); shape = pow( b, b ) / Lambda / Gamma( b ) * pow( w / Lambda, b - 1 ) * exp( -b * w / Lambda ); } if ( itype == 2 ) { double dcoef = pow( Gamma( 0.5 * ( 1 + b ) ) / Gamma( 0.5 * b ), 2 ); double t1 = wzero * wzero * dcoef / ( Lambda * Lambda ); double Lambar = Lambda * ( Gamma( 0.5 * ( 1 + b ) ) - Gamma( 0.5 * ( 1 + b ), t1 ) ) / pow( dcoef, 0.5 ) / ( Gamma( 0.5 * b ) - Gamma( 0.5 * b, t1 ) ); double muf = wzero - Lambar; double mupisq = 3 * Lambda * Lambda * ( Gamma( 1 + 0.5 * b ) - Gamma( 1 + 0.5 * b, t1 ) ) / dcoef / ( Gamma( 0.5 * b ) - Gamma( 0.5 * b, t1 ) ) - 3 * Lambar * Lambar; norm = Mzero( muf, mui, mupisq, vars ) * Gamma( 0.5 * b ) / ( Gamma( 0.5 * b ) - Gamma( 0.5 * b, wzero * wzero * dcoef / ( Lambda * Lambda ) ) ); shape = 2 * pow( dcoef, 0.5 * b ) / Lambda / Gamma( 0.5 * b ) * pow( w / Lambda, b - 1 ) * exp( -dcoef * w * w / ( Lambda * Lambda ) ); } double answer = norm * shape; return answer; } double EvtVubBLNP::Mzero( double muf, double mu, double mupisq, const std::vector& vars ) { double CF = 4.0 / 3.0; double amu = CF * alphas( mu, vars ) / M_PI; double answer = 1 - amu * ( pow( log( muf / mu ), 2 ) + log( muf / mu ) + M_PI * M_PI / 24.0 ) + amu * ( log( muf / mu ) - 0.5 ) * mupisq / ( 3 * muf * muf ); return answer; } double EvtVubBLNP::wS( double w ) { double answer = ( Lbar - w ) * Shat( w, gvars ); return answer; } double EvtVubBLNP::t( double w ) { double t1 = -3 * lambda2 / mupisq * ( Lbar - w ) * Shat( w, gvars ); double myf = myfunction( w, Lbar, moment2 ); double myBIK = myfunctionBIK( w, Lbar, moment2 ); double answer = t1; if ( isubl == 1 ) answer = t1; if ( isubl == 3 ) answer = t1 - myf; if ( isubl == 4 ) answer = t1 + myf; if ( isubl == 5 ) answer = t1 - myBIK; if ( isubl == 6 ) answer = t1 + myBIK; return answer; } double EvtVubBLNP::u( double w ) { double u1 = -2 * ( Lbar - w ) * Shat( w, gvars ); double myf = myfunction( w, Lbar, moment2 ); double myBIK = myfunctionBIK( w, Lbar, moment2 ); double answer = u1; if ( isubl == 1 ) answer = u1; if ( isubl == 3 ) answer = u1 + myf; if ( isubl == 4 ) answer = u1 - myf; if ( isubl == 5 ) answer = u1 + myBIK; if ( isubl == 6 ) answer = u1 - myBIK; return answer; } double EvtVubBLNP::v( double w ) { double v1 = 3 * lambda2 / mupisq * ( Lbar - w ) * Shat( w, gvars ); double myf = myfunction( w, Lbar, moment2 ); double myBIK = myfunctionBIK( w, Lbar, moment2 ); double answer = v1; if ( isubl == 1 ) answer = v1; if ( isubl == 3 ) answer = v1 - myf; if ( isubl == 4 ) answer = v1 + myf; if ( isubl == 5 ) answer = v1 - myBIK; if ( isubl == 6 ) answer = v1 + myBIK; return answer; } double EvtVubBLNP::myfunction( double w, double Lbar, double mom2 ) { double bval = 5.0; double x = w / Lbar; double factor = 0.5 * mom2 * pow( bval / Lbar, 3 ); double answer = factor * exp( -bval * x ) * ( 1 - 2 * bval * x + 0.5 * bval * bval * x * x ); return answer; } double EvtVubBLNP::myfunctionBIK( double w, double Lbar, double /*mom2*/ ) { double aval = 10.0; double normBIK = ( 4 - M_PI ) * M_PI * M_PI / 8 / ( 2 - M_PI ) / aval + 1; double z = 3 * M_PI * w / 8 / Lbar; double q = M_PI * M_PI * 2 * pow( M_PI * aval, 0.5 ) * exp( -aval * z * z ) / ( 4 * M_PI - 8 ) * ( 1 - 2 * pow( aval / M_PI, 0.5 ) * z ) + 8 / pow( 1 + z * z, 4 ) * ( z * log( z ) + 0.5 * z * ( 1 + z * z ) - M_PI / 4 * ( 1 - z * z ) ); double answer = q / normBIK; return answer; } double EvtVubBLNP::dU1nlo( double muh, double mui ) { double ai = alphas( mui, gvars ); double ah = alphas( muh, gvars ); double q1 = ( ah - ai ) / ( 4 * M_PI * beta0 ); double q2 = log( mb / muh ) * Gamma1 + gp1; double q3 = 4 * beta1 * ( log( mb / muh ) * Gamma0 + gp0 ) + Gamma2 * ( 1 - ai / ah ); double q4 = beta1 * beta1 * Gamma0 * ( -1.0 + ai / ah ) / ( 4 * pow( beta0, 3 ) ); double q5 = -beta2 * Gamma0 * ( 1.0 + ai / ah ) + beta1 * Gamma1 * ( 3 - ai / ah ); double q6 = beta1 * beta1 * Gamma0 * ( ah - ai ) / beta0 - beta2 * Gamma0 * ah + beta1 * Gamma1 * ai; double answer = q1 * ( q2 - q3 / 4 / beta0 + q4 + q5 / ( 4 * beta0 * beta0 ) ) + 1 / ( 8 * M_PI * beta0 * beta0 * beta0 ) * log( ai / ah ) * q6; return answer; } double EvtVubBLNP::U1lo( double muh, double mui ) { double epsilon = 0.0; double answer = pow( mb / muh, -2 * aGamma( muh, mui, epsilon ) ) * exp( 2 * Sfun( muh, mui, epsilon ) - 2 * agp( muh, mui, epsilon ) ); return answer; } double EvtVubBLNP::Sfun( double mu1, double mu2, double epsilon ) { double a1 = alphas( mu1, gvars ) / 4 / M_PI; double a2 = alphas( mu2, gvars ) / alphas( mu1, gvars ); double answer = S0( a1, a2 ) + S1( a1, a2 ) + epsilon * S2( a1, a2 ); return answer; } double EvtVubBLNP::S0( double a1, double r ) { double answer = -Gamma0 / ( 4.0 * beta0 * beta0 * a1 ) * ( -1.0 + 1.0 / r + log( r ) ); return answer; } double EvtVubBLNP::S1( double /*a1*/, double r ) { double answer = Gamma0 / ( 4 * beta0 * beta0 ) * ( 0.5 * log( r ) * log( r ) * beta1 / beta0 + ( Gamma1 / Gamma0 - beta1 / beta0 ) * ( 1 - r + log( r ) ) ); return answer; } double EvtVubBLNP::S2( double a1, double r ) { double w1 = pow( beta1, 2 ) / pow( beta0, 2 ) - beta2 / beta0 - beta1 * Gamma1 / ( beta0 * Gamma0 ) + Gamma2 / Gamma0; double w2 = pow( beta1, 2 ) / pow( beta0, 2 ) - beta2 / beta0; double w3 = beta1 * Gamma1 / ( beta0 * Gamma0 ) - beta2 / beta0; double w4 = a1 * Gamma0 / ( 4 * beta0 * beta0 ); double answer = w4 * ( -0.5 * pow( 1 - r, 2 ) * w1 + w2 * ( 1 - r ) * log( r ) + w3 * ( 1 - r + r * log( r ) ) ); return answer; } double EvtVubBLNP::aGamma( double mu1, double mu2, double epsilon ) { double a1 = alphas( mu1, gvars ); double a2 = alphas( mu2, gvars ); double answer = Gamma0 / ( 2 * beta0 ) * log( a2 / a1 ) + epsilon * ( a2 - a1 ) / ( 8.0 * M_PI ) * ( Gamma1 / beta0 - beta1 * Gamma0 / ( beta0 * beta0 ) ); return answer; } double EvtVubBLNP::agp( double mu1, double mu2, double epsilon ) { double a1 = alphas( mu1, gvars ); double a2 = alphas( mu2, gvars ); double answer = gp0 / ( 2 * beta0 ) * log( a2 / a1 ) + epsilon * ( a2 - a1 ) / ( 8.0 * M_PI ) * ( gp1 / beta0 - beta1 * gp0 / ( beta0 * beta0 ) ); return answer; } double EvtVubBLNP::alo( double muh, double mui ) { return -2.0 * aGamma( muh, mui, 0 ); } double EvtVubBLNP::anlo( double muh, double mui ) { // d/depsilon of aGamma double ah = alphas( muh, gvars ); double ai = alphas( mui, gvars ); double answer = ( ah - ai ) / ( 8.0 * M_PI ) * ( Gamma1 / beta0 - beta1 * Gamma0 / ( beta0 * beta0 ) ); return answer; } double EvtVubBLNP::alphas( double mu, const std::vector& vars ) { // Note: Lambda4 and Lambda5 depend on mbMS = 4.25 // So if you change mbMS, then you will have to recalculate them. double beta0 = vars[8]; double beta1 = vars[9]; double beta2 = vars[10]; double Lambda4 = 0.298791; double lg = 2 * log( mu / Lambda4 ); double answer = 4 * M_PI / ( beta0 * lg ) * ( 1 - beta1 * log( lg ) / ( beta0 * beta0 * lg ) + beta1 * beta1 / ( beta0 * beta0 * beta0 * beta0 * lg * lg ) * ( ( log( lg ) - 0.5 ) * ( log( lg ) - 0.5 ) - 5.0 / 4.0 + beta2 * beta0 / ( beta1 * beta1 ) ) ); return answer; } double EvtVubBLNP::PolyLog( double v, double z ) { if ( z >= 1 ) cout << "Error in EvtVubBLNP: 2nd argument to PolyLog is >= 1." << endl; double sum = 0.0; for ( int k = 1; k < 101; k++ ) { sum = sum + pow( z, k ) / pow( k, v ); } return sum; } double EvtVubBLNP::Gamma( double z ) { if ( z <= 0 ) return 0; double v = lgamma( z ); return exp( v ); } double EvtVubBLNP::Gamma( double a, double x ) { double LogGamma; /* if (x<0.0 || a<= 0.0) raise(SIGFPE);*/ if ( x < 0.0 ) x = 0.0; if ( a <= 0.0 ) a = 1.e-50; LogGamma = lgamma( a ); if ( x < ( a + 1.0 ) ) return gamser( a, x, LogGamma ); else return 1.0 - gammcf( a, x, LogGamma ); } /* ------------------Incomplete gamma function-----------------*/ /* ------------------via its series representation-------------*/ double EvtVubBLNP::gamser( double a, double x, double LogGamma ) { double n; double ap, del, sum; ap = a; del = sum = 1.0 / a; for ( n = 1; n < ITMAX; n++ ) { ++ap; del *= x / ap; sum += del; if ( fabs( del ) < fabs( sum ) * EPS ) return sum * exp( -x + a * log( x ) - LogGamma ); } raise( SIGFPE ); return 0.0; } /* ------------------Incomplete gamma function complement------*/ /* ------------------via its continued fraction representation-*/ double EvtVubBLNP::gammcf( double a, double x, double LogGamma ) { double an, b, c, d, del, h; int i; b = x + 1.0 - a; c = 1.0 / FPMIN; d = 1.0 / b; h = d; for ( i = 1; i < ITMAX; i++ ) { an = -i * ( i - a ); b += 2.0; d = an * d + b; if ( fabs( d ) < FPMIN ) d = FPMIN; c = b + an / c; if ( fabs( c ) < FPMIN ) c = FPMIN; d = 1.0 / d; del = d * c; h *= del; if ( fabs( del - 1.0 ) < EPS ) return exp( -x + a * log( x ) - LogGamma ) * h; } raise( SIGFPE ); return 0.0; } double EvtVubBLNP::findBLNPWhat() { double ranNum = EvtRandom::Flat(); double oOverBins = 1.0 / ( float( _pf.size() ) ); int nBinsBelow = 0; // largest k such that I[k] is known to be <= rand int nBinsAbove = _pf.size(); // largest k such that I[k] is known to be > rand int middle; while ( nBinsAbove > nBinsBelow + 1 ) { middle = ( nBinsAbove + nBinsBelow + 1 ) >> 1; if ( ranNum >= _pf[middle] ) { nBinsBelow = middle; } else { nBinsAbove = middle; } } double bSize = _pf[nBinsAbove] - _pf[nBinsBelow]; // binMeasure is always aProbFunc[nBinsBelow], if ( bSize == 0 ) { // rand lies right in a bin of measure 0. Simply return the center // of the range of that bin. (Any value between k/N and (k+1)/N is // equally good, in this rare case.) return ( nBinsBelow + .5 ) * oOverBins; } double bFract = ( ranNum - _pf[nBinsBelow] ) / bSize; return ( nBinsBelow + bFract ) * oOverBins; } diff --git a/src/EvtGenModels/EvtVubBLNPHybrid.cpp b/src/EvtGenModels/EvtVubBLNPHybrid.cpp index cf95cdb..fc381dc 100644 --- a/src/EvtGenModels/EvtVubBLNPHybrid.cpp +++ b/src/EvtGenModels/EvtVubBLNPHybrid.cpp @@ -1,1182 +1,1182 @@ /*********************************************************************** * 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/EvtVubBLNPHybrid.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenModels/EvtItgPtrFunction.hh" #include "EvtGenModels/EvtItgSimpsonIntegrator.hh" #include "EvtGenModels/EvtPFermi.hh" #include #include // For incomplete gamma function #include "math.h" #include "signal.h" #define ITMAX 100 #define EPS 3.0e-7 #define FPMIN 1.0e-30 using std::cout; using std::endl; std::string EvtVubBLNPHybrid::getName() { return "VUB_BLNPHYBRID"; } EvtDecayBase* EvtVubBLNPHybrid::clone() { return new EvtVubBLNPHybrid; } void EvtVubBLNPHybrid::init() { // check number of arguments if ( getNArg() < EvtVubBLNPHybrid::nParameters ) { EvtGenReport( EVTGEN_ERROR, "EvtVubBLNPHybrid" ) << "EvtVubBLNPHybrid generator expected " << "at least " << EvtVubBLNPHybrid::nParameters << " arguments but found: " << getNArg() << "\nWill terminate execution!" << endl; ::abort(); } else if ( getNArg() == EvtVubBLNPHybrid::nParameters ) { EvtGenReport( EVTGEN_WARNING, "EvtVubBLNPHybrid" ) << "EvtVubBLNPHybrid: generate B -> Xu l nu events " << "without using the hybrid reweighting." << endl; _noHybrid = true; } else if ( getNArg() < EvtVubBLNPHybrid::nParameters + EvtVubBLNPHybrid::nVariables ) { EvtGenReport( EVTGEN_ERROR, "EvtVubBLNPHybrid" ) << "EvtVubBLNPHybrid could not read number of bins for " << "all variables used in the reweighting\n" << "Will terminate execution!" << endl; ::abort(); } // get parameters (declared in the header file) // Input parameters mBB = 5.2792; lambda2 = 0.12; // Shape function parameters b = getArg( 0 ); Lambda = getArg( 1 ); Ecut = 1.8; wzero = mBB - 2 * Ecut; // SF and SSF modes itype = (int)getArg( 5 ); dtype = getArg( 5 ); isubl = (int)getArg( 6 ); // flags flag1 = (int)getArg( 7 ); flag2 = (int)getArg( 8 ); flag3 = (int)getArg( 9 ); // Quark mass mb = 4.61; // hidden parameter what and SF stuff const double xlow = 0; const double xhigh = mBB; const int aSize = 10000; EvtPFermi pFermi( Lambda, b ); // pf is the cumulative distribution normalized to 1. _pf.resize( aSize ); for ( int i = 0; i < aSize; i++ ) { double what = xlow + (double)( i + 0.5 ) / ( (double)aSize ) * ( xhigh - xlow ); if ( i == 0 ) _pf[i] = pFermi.getSFBLNP( what ); else _pf[i] = _pf[i - 1] + pFermi.getSFBLNP( what ); } for ( size_t i = 0; i < _pf.size(); i++ ) { _pf[i] /= _pf[_pf.size() - 1]; } // Matching scales muh = mBB * getArg( 2 ); // 0.5 mui = getArg( 3 ); // 1.5 mubar = getArg( 4 ); // 1.5 // Perturbative quantities CF = 4.0 / 3.0; CA = 3.0; double nf = 4.0; beta0 = 11.0 / 3.0 * CA - 2.0 / 3.0 * nf; beta1 = 34.0 / 3.0 * CA * CA - 10.0 / 3.0 * CA * nf - 2.0 * CF * nf; beta2 = 2857.0 / 54.0 * CA * CA * CA + ( CF * CF - 205.0 / 18.0 * CF * CA - 1415.0 / 54.0 * CA * CA ) * nf + ( 11.0 / 9.0 * CF + 79.0 / 54.0 * CA ) * nf * nf; zeta3 = 1.0 + 1 / 8.0 + 1 / 27.0 + 1 / 64.0; Gamma0 = 4 * CF; Gamma1 = CF * ( ( 268.0 / 9.0 - 4.0 * M_PI * M_PI / 3.0 ) * CA - 40.0 / 9.0 * nf ); Gamma2 = 16 * CF * ( ( 245.0 / 24.0 - 67.0 / 54.0 * M_PI * M_PI + +11.0 / 180.0 * pow( M_PI, 4 ) + 11.0 / 6.0 * zeta3 ) * CA * CA * +( -209.0 / 108.0 + 5.0 / 27.0 * M_PI * M_PI - 7.0 / 3.0 * zeta3 ) * CA * nf + ( -55.0 / 24.0 + 2 * zeta3 ) * CF * nf - nf * nf / 27.0 ); gp0 = -5.0 * CF; gp1 = -8.0 * CF * ( ( 3.0 / 16.0 - M_PI * M_PI / 4.0 + 3 * zeta3 ) * CF + ( 1549.0 / 432.0 + 7.0 / 48.0 * M_PI * M_PI - 11.0 / 4.0 * zeta3 ) * CA - ( 125.0 / 216.0 + M_PI * M_PI / 24.0 ) * nf ); // Lbar and mupisq Lbar = Lambda; // all models mupisq = 3 * Lambda * Lambda / b; if ( itype == 1 ) mupisq = 3 * Lambda * Lambda / b; if ( itype == 2 ) mupisq = 3 * Lambda * Lambda * ( Gamma( 1 + 0.5 * b ) * Gamma( 0.5 * b ) / pow( Gamma( 0.5 + 0.5 * b ), 2 ) - 1 ); // moment2 for SSFs moment2 = pow( 0.3, 3 ); // inputs for total rate (T for Total); use BLNP notebook defaults flagpower = 1; flag2loop = 1; // stuff for the integrator maxLoop = 20; //precision = 1.0e-3; precision = 2.0e-2; // vector of global variables, to pass to static functions (which can't access globals); gvars.push_back( 0.0 ); // 0 gvars.push_back( 0.0 ); // 1 gvars.push_back( mui ); // 2 gvars.push_back( b ); // 3 gvars.push_back( Lambda ); // 4 gvars.push_back( mBB ); // 5 gvars.push_back( mb ); // 6 gvars.push_back( wzero ); // 7 gvars.push_back( beta0 ); // 8 gvars.push_back( beta1 ); // 9 gvars.push_back( beta2 ); // 10 gvars.push_back( dtype ); // 11 // check that there are 3 daughters and 10 arguments checkNDaug( 3 ); // A. Volk: check for number of arguments is not necessary //checkNArg(10); if ( _noHybrid ) return; // Without hybrid weighting, nothing else to do _bins_mX = std::vector( abs( (int)getArg( 10 ) ) ); _bins_q2 = std::vector( abs( (int)getArg( 11 ) ) ); _bins_El = std::vector( abs( (int)getArg( 12 ) ) ); int nextArg = EvtVubBLNPHybrid::nParameters + EvtVubBLNPHybrid::nVariables; _nbins = _bins_mX.size() * _bins_q2.size() * _bins_El.size(); // Binning of weight table int expectArgs = nextArg + _bins_mX.size() + _bins_q2.size() + _bins_El.size() + _nbins; if ( getNArg() < expectArgs ) { EvtGenReport( EVTGEN_ERROR, "EvtVubBLNPHybrid" ) << " finds " << getNArg() << " arguments, expected " << expectArgs << ". Something is wrong with the tables of weights or thresholds." << "\nWill terminate execution!" << endl; ::abort(); } // read bin boundaries from decay.dec for ( auto& b : _bins_mX ) b = getArg( nextArg++ ); _masscut = _bins_mX[0]; for ( auto& b : _bins_q2 ) b = getArg( nextArg++ ); for ( auto& b : _bins_El ) b = getArg( nextArg++ ); // read in weights (and rescale to range 0..1) readWeights( nextArg ); } void EvtVubBLNPHybrid::initProbMax() { noProbMax(); } void EvtVubBLNPHybrid::decay( EvtParticle* Bmeson ) { int j; EvtParticle *xuhad( nullptr ), *lepton( nullptr ), *neutrino( nullptr ); EvtVector4R p4; double EX( 0. ), sh( 0. ), El( 0. ), ml( 0. ); double Pp, Pm, Pl, pdf, qsq, mpi, ratemax; double xhigh, xlow, what; double mX; bool rew( true ); while ( rew ) { Bmeson->initializePhaseSpace( getNDaug(), getDaugs() ); xuhad = Bmeson->getDaug( 0 ); lepton = Bmeson->getDaug( 1 ); neutrino = Bmeson->getDaug( 2 ); mBB = Bmeson->mass(); ml = lepton->mass(); // get SF value xlow = 0; xhigh = mBB; // the case for alphas = 0 is not considered what = 2 * xhigh; while ( what > xhigh || what < xlow ) { what = findBLNPWhat(); what = xlow + what * ( xhigh - xlow ); } bool tryit = true; while ( tryit ) { // generate pp between 0 and // Flat(min, max) gives R(max - min) + min, where R = random btwn 0 and 1 Pp = EvtRandom::Flat( 0, mBB ); // P+ = EX - |PX| Pl = EvtRandom::Flat( 0, mBB ); // mBB - 2El Pm = EvtRandom::Flat( 0, mBB ); // P- = EX + |PX| sh = Pm * Pp; EX = 0.5 * ( Pm + Pp ); qsq = ( mBB - Pp ) * ( mBB - Pm ); El = 0.5 * ( mBB - Pl ); // Need maximum rate. Waiting for Mr. Paz to give it to me. // Meanwhile, use this. ratemax = 3.0; // From trial and error - most events below 3.0 // kinematic bounds (Eq. 2) mpi = 0.14; if ( ( Pp > 0 ) && ( Pp <= Pl ) && ( Pl <= Pm ) && ( Pm < mBB ) && ( El > ml ) && ( sh > 4 * mpi * mpi ) ) { // Probability of pass proportional to PDF pdf = rate3( Pp, Pl, Pm ); double testRan = EvtRandom::Flat( 0., ratemax ); if ( pdf >= testRan ) tryit = false; } } // compute all kinematic variables needed for reweighting mX = sqrt( sh ); // Reweighting in bins of mX, q2, El if ( _nbins > 0 ) { double xran1 = EvtRandom::Flat(); double w = 1.0; if ( !_noHybrid ) w = getWeight( mX, qsq, El ); if ( w >= xran1 ) rew = false; } else { rew = false; } } // o.k. we have the three kineamtic variables // now calculate a flat cos Theta_H [-1,1] distribution of the // hadron flight direction w.r.t the B flight direction // because the B is a scalar and should decay isotropic. // Then chose a flat Phi_H [0,2Pi] w.r.t the B flight direction // and and a flat Phi_L [0,2Pi] in the W restframe w.r.t the // W flight direction. double ctH = EvtRandom::Flat( -1, 1 ); double phH = EvtRandom::Flat( 0, 2 * M_PI ); double phL = EvtRandom::Flat( 0, 2 * M_PI ); // now compute the four vectors in the B Meson restframe double ptmp, sttmp; // calculate the hadron 4 vector in the B Meson restframe sttmp = sqrt( 1 - ctH * ctH ); ptmp = sqrt( EX * EX - sh ); - double pHB[4] = {EX, ptmp * sttmp * cos( phH ), ptmp * sttmp * sin( phH ), - ptmp * ctH}; + double pHB[4] = { EX, ptmp * sttmp * cos( phH ), ptmp * sttmp * sin( phH ), + ptmp * ctH }; p4.set( pHB[0], pHB[1], pHB[2], pHB[3] ); xuhad->init( getDaug( 0 ), p4 ); if ( _storeWhat ) { // cludge to store the hidden parameter what with the decay; // the lifetime of the Xu is abused for this purpose. // tau = 1 ps corresponds to ctau = 0.3 mm -> in order to // stay well below BaBars sensitivity we take what/(10000 GeV). // To extract what back from the StdHepTrk its necessary to get // delta_ctau = Xu->decayVtx()->point().distanceTo(XuDaughter->decayVtx()->point()); // // what = delta_ctau * 100000 * Mass_Xu/Momentum_Xu // xuhad->setLifetime( what / 10000. ); } // calculate the W 4 vector in the B Meson restrframe double apWB = ptmp; - double pWB[4] = {mBB - EX, -pHB[1], -pHB[2], -pHB[3]}; + double pWB[4] = { mBB - EX, -pHB[1], -pHB[2], -pHB[3] }; // first go in the W restframe and calculate the lepton and // the neutrino in the W frame double mW2 = mBB * mBB + sh - 2 * mBB * EX; double beta = ptmp / pWB[0]; double gamma = pWB[0] / sqrt( mW2 ); double pLW[4]; ptmp = ( mW2 - ml * ml ) / 2 / sqrt( mW2 ); pLW[0] = sqrt( ml * ml + ptmp * ptmp ); double ctL = ( El - gamma * pLW[0] ) / beta / gamma / ptmp; if ( ctL < -1 ) ctL = -1; if ( ctL > 1 ) ctL = 1; sttmp = sqrt( 1 - ctL * ctL ); // eX' = eZ x eW - double xW[3] = {-pWB[2], pWB[1], 0}; + double xW[3] = { -pWB[2], pWB[1], 0 }; // eZ' = eW - double zW[3] = {pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB}; + double zW[3] = { pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB }; double lx = sqrt( xW[0] * xW[0] + xW[1] * xW[1] ); for ( j = 0; j < 2; j++ ) xW[j] /= lx; // eY' = eZ' x eX' - double yW[3] = {-pWB[1] * pWB[3], -pWB[2] * pWB[3], - pWB[1] * pWB[1] + pWB[2] * pWB[2]}; + double yW[3] = { -pWB[1] * pWB[3], -pWB[2] * pWB[3], + pWB[1] * pWB[1] + pWB[2] * pWB[2] }; double ly = sqrt( yW[0] * yW[0] + yW[1] * yW[1] + yW[2] * yW[2] ); for ( j = 0; j < 3; j++ ) yW[j] /= ly; // p_lep = |p_lep| * ( sin(Theta) * cos(Phi) * eX' // + sin(Theta) * sin(Phi) * eY' // + cos(Theta) * eZ') for ( j = 0; j < 3; j++ ) pLW[j + 1] = sttmp * cos( phL ) * ptmp * xW[j] + sttmp * sin( phL ) * ptmp * yW[j] + ctL * ptmp * zW[j]; double apLW = ptmp; // boost them back in the B Meson restframe double appLB = beta * gamma * pLW[0] + gamma * ctL * apLW; ptmp = sqrt( El * El - ml * ml ); double ctLL = appLB / ptmp; if ( ctLL > 1 ) ctLL = 1; if ( ctLL < -1 ) ctLL = -1; - double pLB[4] = {El, 0, 0, 0}; - double pNB[4] = {pWB[0] - El, 0, 0, 0}; + double pLB[4] = { El, 0, 0, 0 }; + double pNB[4] = { pWB[0] - El, 0, 0, 0 }; for ( j = 1; j < 4; j++ ) { pLB[j] = pLW[j] + ( ctLL * ptmp - ctL * apLW ) / apWB * pWB[j]; pNB[j] = pWB[j] - pLB[j]; } p4.set( pLB[0], pLB[1], pLB[2], pLB[3] ); lepton->init( getDaug( 1 ), p4 ); p4.set( pNB[0], pNB[1], pNB[2], pNB[3] ); neutrino->init( getDaug( 2 ), p4 ); } double EvtVubBLNPHybrid::rate3( double Pp, double Pl, double Pm ) { // rate3 in units of GF^2*Vub^2/pi^3 double factor = 1.0 / 16 * ( mBB - Pp ) * U1lo( muh, mui ) * pow( ( Pm - Pp ) / ( mBB - Pp ), alo( muh, mui ) ); double doneJS = DoneJS( Pp, Pm, mui ); double done1 = Done1( Pp, Pm, mui ); double done2 = Done2( Pp, Pm, mui ); double done3 = Done3( Pp, Pm, mui ); // The EvtSimpsonIntegrator returns zero for bad integrals. // So if any of the integrals are zero (ie bad), return zero. // This will cause pdf = 0, so the event will not pass. // I hope this will not introduce a bias. if ( doneJS * done1 * done2 * done3 == 0.0 ) { //cout << "Integral failed: (Pp, Pm, Pl) = (" << Pp << ", " << Pm << ", " << Pl << ")" << endl; return 0.0; } // if (doneJS*done1*done2*done3 != 0.0) { // cout << "Integral OK: (Pp, Pm, Pl) = (" << Pp << ", " << Pm << ", " << Pl << ")" << endl; //} double f1 = F1( Pp, Pm, muh, mui, mubar, doneJS, done1 ); double f2 = F2( Pp, Pm, muh, mui, mubar, done3 ); double f3 = F3( Pp, Pm, muh, mui, mubar, done2 ); double answer = factor * ( ( mBB + Pl - Pp - Pm ) * ( Pm - Pl ) * f1 + 2 * ( Pl - Pp ) * ( Pm - Pl ) * f2 + ( mBB - Pm ) * ( Pm - Pp ) * f3 ); return answer; } double EvtVubBLNPHybrid::F1( double Pp, double Pm, double muh, double mui, double mubar, double doneJS, double done1 ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double y = ( Pm - Pp ) / ( mBB - Pp ); double ah = CF * alphas( muh, vars ) / 4 / M_PI; double ai = CF * alphas( mui, vars ) / 4 / M_PI; double abar = CF * alphas( mubar, vars ) / 4 / M_PI; double lambda1 = -mupisq; double t1 = -4 * ai / ( Pp - Lbar ) * ( 2 * log( ( Pp - Lbar ) / mui ) + 1 ); double t2 = 1 + dU1nlo( muh, mui ) + anlo( muh, mui ) * log( y ); double t3 = -4.0 * pow( log( y * mb / muh ), 2 ) + 10.0 * log( y * mb / muh ) - 4.0 * log( y ) - 2.0 * log( y ) / ( 1 - y ) - 4.0 * PolyLog( 2, 1 - y ) - M_PI * M_PI / 6.0 - 12.0; double t4 = 2 * pow( log( y * mb * Pp / ( mui * mui ) ), 2 ) - 3 * log( y * mb * Pp / ( mui * mui ) ) + 7 - M_PI * M_PI; double t5 = -wS( Pp ) + 2 * t( Pp ) + ( 1.0 / y - 1.0 ) * ( u( Pp ) - v( Pp ) ); double t6 = -( lambda1 + 3.0 * lambda2 ) / 3.0 + 1.0 / pow( y, 2 ) * ( 4.0 / 3.0 * lambda1 - 2.0 * lambda2 ); double shapePp = Shat( Pp, vars ); double answer = ( t2 + ah * t3 + ai * t4 ) * shapePp + ai * doneJS + 1 / ( mBB - Pp ) * ( flag2 * abar * done1 + flag1 * t5 ) + 1 / pow( mBB - Pp, 2 ) * flag3 * shapePp * t6; if ( Pp > Lbar + mui / exp( 0.5 ) ) answer = answer + t1; return answer; } double EvtVubBLNPHybrid::F2( double Pp, double Pm, double muh, double /* mui */, double mubar, double done3 ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double y = ( Pm - Pp ) / ( mBB - Pp ); double lambda1 = -mupisq; double ah = CF * alphas( muh, vars ) / 4 / M_PI; double abar = CF * alphas( mubar, vars ) / 4 / M_PI; double t6 = -wS( Pp ) - 2 * t( Pp ) + 1.0 / y * ( t( Pp ) + v( Pp ) ); double t7 = 1 / pow( y, 2 ) * ( 2.0 / 3.0 * lambda1 + 4.0 * lambda2 ) - 1 / y * ( 2.0 / 3.0 * lambda1 + 3.0 / 2.0 * lambda2 ); double shapePp = Shat( Pp, vars ); double answer = ah * log( y ) / ( 1 - y ) * shapePp + 1 / ( mBB - Pp ) * ( flag2 * abar * 0.5 * done3 + flag1 / y * t6 ) + 1.0 / pow( mBB - Pp, 2 ) * flag3 * shapePp * t7; return answer; } double EvtVubBLNPHybrid::F3( double Pp, double Pm, double /*muh*/, double /* mui */, double mubar, double done2 ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double y = ( Pm - Pp ) / ( mBB - Pp ); double lambda1 = -mupisq; double abar = CF * alphas( mubar, vars ) / 4 / M_PI; double t7 = 1.0 / pow( y, 2 ) * ( -2.0 / 3.0 * lambda1 + lambda2 ); double shapePp = Shat( Pp, vars ); double answer = 1.0 / ( Pm - Pp ) * flag2 * 0.5 * y * abar * done2 + 1.0 / pow( mBB - Pp, 2 ) * flag3 * shapePp * t7; return answer; } double EvtVubBLNPHybrid::DoneJS( double Pp, double Pm, double /* mui */ ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double lowerlim = 0.001 * Pp; double upperlim = ( 1.0 - 0.001 ) * Pp; - auto func = EvtItgPtrFunction{&IntJS, lowerlim, upperlim, vars}; - auto integ = EvtItgSimpsonIntegrator{func, precision, maxLoop}; + auto func = EvtItgPtrFunction{ &IntJS, lowerlim, upperlim, vars }; + auto integ = EvtItgSimpsonIntegrator{ func, precision, maxLoop }; return integ.evaluate( lowerlim, upperlim ); } double EvtVubBLNPHybrid::Done1( double Pp, double Pm, double /* mui */ ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double lowerlim = 0.001 * Pp; double upperlim = ( 1.0 - 0.001 ) * Pp; - auto func = EvtItgPtrFunction{&Int1, lowerlim, upperlim, vars}; - auto integ = EvtItgSimpsonIntegrator{func, precision, maxLoop}; + auto func = EvtItgPtrFunction{ &Int1, lowerlim, upperlim, vars }; + auto integ = EvtItgSimpsonIntegrator{ func, precision, maxLoop }; return integ.evaluate( lowerlim, upperlim ); } double EvtVubBLNPHybrid::Done2( double Pp, double Pm, double /* mui */ ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double lowerlim = 0.001 * Pp; double upperlim = ( 1.0 - 0.001 ) * Pp; - auto func = EvtItgPtrFunction{&Int2, lowerlim, upperlim, vars}; - auto integ = EvtItgSimpsonIntegrator{func, precision, maxLoop}; + auto func = EvtItgPtrFunction{ &Int2, lowerlim, upperlim, vars }; + auto integ = EvtItgSimpsonIntegrator{ func, precision, maxLoop }; return integ.evaluate( lowerlim, upperlim ); } double EvtVubBLNPHybrid::Done3( double Pp, double Pm, double /* mui */ ) { std::vector vars( 12 ); vars[0] = Pp; vars[1] = Pm; for ( int j = 2; j < 12; j++ ) { vars[j] = gvars[j]; } double lowerlim = 0.001 * Pp; double upperlim = ( 1.0 - 0.001 ) * Pp; - auto func = EvtItgPtrFunction{&Int3, lowerlim, upperlim, vars}; - auto integ = EvtItgSimpsonIntegrator{func, precision, maxLoop}; + auto func = EvtItgPtrFunction{ &Int3, lowerlim, upperlim, vars }; + auto integ = EvtItgSimpsonIntegrator{ func, precision, maxLoop }; return integ.evaluate( lowerlim, upperlim ); } double EvtVubBLNPHybrid::Int1( double what, const std::vector& vars ) { return Shat( what, vars ) * g1( what, vars ); } double EvtVubBLNPHybrid::Int2( double what, const std::vector& vars ) { return Shat( what, vars ) * g2( what, vars ); } double EvtVubBLNPHybrid::Int3( double what, const std::vector& vars ) { return Shat( what, vars ) * g3( what, vars ); } double EvtVubBLNPHybrid::IntJS( double what, const std::vector& vars ) { double Pp = vars[0]; double Pm = vars[1]; double mui = vars[2]; double mBB = vars[5]; double mb = vars[6]; double y = ( Pm - Pp ) / ( mBB - Pp ); return 1 / ( Pp - what ) * ( Shat( what, vars ) - Shat( Pp, vars ) ) * ( 4 * log( y * mb * ( Pp - what ) / ( mui * mui ) ) - 3 ); } double EvtVubBLNPHybrid::g1( double w, const std::vector& vars ) { double Pp = vars[0]; double Pm = vars[1]; double mBB = vars[5]; double y = ( Pm - Pp ) / ( mBB - Pp ); double x = ( Pp - w ) / ( mBB - Pp ); double q1 = ( 1 + x ) * ( 1 + x ) * y * ( x + y ); double q2 = y * ( -9 + 10 * y ) + x * x * ( -12.0 + 13.0 * y ) + 2 * x * ( -8.0 + 6 * y + 3 * y * y ); double q3 = 4 / x * log( y + y / x ); double q4 = 3.0 * pow( x, 4 ) * ( -2.0 + y ) - 2 * pow( y, 3 ) - 4 * pow( x, 3 ) * ( 2.0 + y ) - 2 * x * y * y * ( 4 + y ) - x * x * y * ( 12 + 4 * y + y * y ); double q5 = log( 1 + y / x ); double answer = q2 / q1 - q3 - 2 * q4 * q5 / ( q1 * y * x ); return answer; } double EvtVubBLNPHybrid::g2( double w, const std::vector& vars ) { double Pp = vars[0]; double Pm = vars[1]; double mBB = vars[5]; double y = ( Pm - Pp ) / ( mBB - Pp ); double x = ( Pp - w ) / ( mBB - Pp ); double q1 = ( 1 + x ) * ( 1 + x ) * pow( y, 3 ) * ( x + y ); double q2 = 10.0 * pow( x, 4 ) + y * y + 3.0 * pow( x, 2 ) * y * ( 10.0 + y ) + pow( x, 3 ) * ( 12.0 + 19.0 * y ) + x * y * ( 8.0 + 4.0 * y + y * y ); double q3 = 5 * pow( x, 4 ) + 2.0 * y * y + 6.0 * pow( x, 3 ) * ( 1.0 + 2.0 * y ) + 4.0 * x * y * ( 1 + 2.0 * y ) + x * x * y * ( 18.0 + 5.0 * y ); double q4 = log( 1 + y / x ); double answer = 2.0 / q1 * ( y * q2 - 2 * x * q3 * q4 ); return answer; } double EvtVubBLNPHybrid::g3( double w, const std::vector& vars ) { double Pp = vars[0]; double Pm = vars[1]; double mBB = vars[5]; double y = ( Pm - Pp ) / ( mBB - Pp ); double x = ( Pp - w ) / ( mBB - Pp ); double q1 = ( 1 + x ) * ( 1 + x ) * pow( y, 3 ) * ( x + y ); double q2 = 2.0 * pow( y, 3 ) * ( -11.0 + 2.0 * y ) - 10.0 * pow( x, 4 ) * ( 6 - 6 * y + y * y ) + x * y * y * ( -94.0 + 29.0 * y + 2.0 * y * y ) + 2.0 * x * x * y * ( -72.0 + 18.0 * y + 13.0 * y * y ) - x * x * x * ( 72.0 + 42.0 * y - 70.0 * y * y + 3.0 * y * y * y ); double q3 = -6.0 * x * ( -5.0 + y ) * pow( y, 3 ) + 4 * pow( y, 4 ) + 5 * pow( x, 5 ) * ( 6 - 6 * y + y * y ) - 4 * x * x * y * y * ( -20.0 + 6 * y + y * y ) + pow( x, 3 ) * y * ( 90.0 - 10.0 * y - 28.0 * y * y + y * y * y ) + pow( x, 4 ) * ( 36.0 + 36.0 * y - 50.0 * y * y + 4 * y * y * y ); double q4 = log( 1 + y / x ); double answer = q2 / q1 + 2 / q1 / y * q3 * q4; return answer; } double EvtVubBLNPHybrid::Shat( double w, const std::vector& vars ) { double mui = vars[2]; double b = vars[3]; double Lambda = vars[4]; double wzero = vars[7]; int itype = (int)vars[11]; double norm = 0.0; double shape = 0.0; if ( itype == 1 ) { double Lambar = ( Lambda / b ) * ( Gamma( 1 + b ) - Gamma( 1 + b, b * wzero / Lambda ) ) / ( Gamma( b ) - Gamma( b, b * wzero / Lambda ) ); double muf = wzero - Lambar; double mupisq = 3 * pow( Lambda, 2 ) / pow( b, 2 ) * ( Gamma( 2 + b ) - Gamma( 2 + b, b * wzero / Lambda ) ) / ( Gamma( b ) - Gamma( b, b * wzero / Lambda ) ) - 3 * Lambar * Lambar; norm = Mzero( muf, mui, mupisq, vars ) * Gamma( b ) / ( Gamma( b ) - Gamma( b, b * wzero / Lambda ) ); shape = pow( b, b ) / Lambda / Gamma( b ) * pow( w / Lambda, b - 1 ) * exp( -b * w / Lambda ); } if ( itype == 2 ) { double dcoef = pow( Gamma( 0.5 * ( 1 + b ) ) / Gamma( 0.5 * b ), 2 ); double t1 = wzero * wzero * dcoef / ( Lambda * Lambda ); double Lambar = Lambda * ( Gamma( 0.5 * ( 1 + b ) ) - Gamma( 0.5 * ( 1 + b ), t1 ) ) / pow( dcoef, 0.5 ) / ( Gamma( 0.5 * b ) - Gamma( 0.5 * b, t1 ) ); double muf = wzero - Lambar; double mupisq = 3 * Lambda * Lambda * ( Gamma( 1 + 0.5 * b ) - Gamma( 1 + 0.5 * b, t1 ) ) / dcoef / ( Gamma( 0.5 * b ) - Gamma( 0.5 * b, t1 ) ) - 3 * Lambar * Lambar; norm = Mzero( muf, mui, mupisq, vars ) * Gamma( 0.5 * b ) / ( Gamma( 0.5 * b ) - Gamma( 0.5 * b, wzero * wzero * dcoef / ( Lambda * Lambda ) ) ); shape = 2 * pow( dcoef, 0.5 * b ) / Lambda / Gamma( 0.5 * b ) * pow( w / Lambda, b - 1 ) * exp( -dcoef * w * w / ( Lambda * Lambda ) ); } double answer = norm * shape; return answer; } double EvtVubBLNPHybrid::Mzero( double muf, double mu, double mupisq, const std::vector& vars ) { double CF = 4.0 / 3.0; double amu = CF * alphas( mu, vars ) / M_PI; double answer = 1 - amu * ( pow( log( muf / mu ), 2 ) + log( muf / mu ) + M_PI * M_PI / 24.0 ) + amu * ( log( muf / mu ) - 0.5 ) * mupisq / ( 3 * muf * muf ); return answer; } double EvtVubBLNPHybrid::wS( double w ) { double answer = ( Lbar - w ) * Shat( w, gvars ); return answer; } double EvtVubBLNPHybrid::t( double w ) { double t1 = -3 * lambda2 / mupisq * ( Lbar - w ) * Shat( w, gvars ); double myf = myfunction( w, Lbar, moment2 ); double myBIK = myfunctionBIK( w, Lbar, moment2 ); double answer = t1; if ( isubl == 1 ) answer = t1; if ( isubl == 3 ) answer = t1 - myf; if ( isubl == 4 ) answer = t1 + myf; if ( isubl == 5 ) answer = t1 - myBIK; if ( isubl == 6 ) answer = t1 + myBIK; return answer; } double EvtVubBLNPHybrid::u( double w ) { double u1 = -2 * ( Lbar - w ) * Shat( w, gvars ); double myf = myfunction( w, Lbar, moment2 ); double myBIK = myfunctionBIK( w, Lbar, moment2 ); double answer = u1; if ( isubl == 1 ) answer = u1; if ( isubl == 3 ) answer = u1 + myf; if ( isubl == 4 ) answer = u1 - myf; if ( isubl == 5 ) answer = u1 + myBIK; if ( isubl == 6 ) answer = u1 - myBIK; return answer; } double EvtVubBLNPHybrid::v( double w ) { double v1 = 3 * lambda2 / mupisq * ( Lbar - w ) * Shat( w, gvars ); double myf = myfunction( w, Lbar, moment2 ); double myBIK = myfunctionBIK( w, Lbar, moment2 ); double answer = v1; if ( isubl == 1 ) answer = v1; if ( isubl == 3 ) answer = v1 - myf; if ( isubl == 4 ) answer = v1 + myf; if ( isubl == 5 ) answer = v1 - myBIK; if ( isubl == 6 ) answer = v1 + myBIK; return answer; } double EvtVubBLNPHybrid::myfunction( double w, double Lbar, double mom2 ) { double bval = 5.0; double x = w / Lbar; double factor = 0.5 * mom2 * pow( bval / Lbar, 3 ); double answer = factor * exp( -bval * x ) * ( 1 - 2 * bval * x + 0.5 * bval * bval * x * x ); return answer; } double EvtVubBLNPHybrid::myfunctionBIK( double w, double Lbar, double /* mom2 */ ) { double aval = 10.0; double normBIK = ( 4 - M_PI ) * M_PI * M_PI / 8 / ( 2 - M_PI ) / aval + 1; double z = 3 * M_PI * w / 8 / Lbar; double q = M_PI * M_PI * 2 * pow( M_PI * aval, 0.5 ) * exp( -aval * z * z ) / ( 4 * M_PI - 8 ) * ( 1 - 2 * pow( aval / M_PI, 0.5 ) * z ) + 8 / pow( 1 + z * z, 4 ) * ( z * log( z ) + 0.5 * z * ( 1 + z * z ) - M_PI / 4 * ( 1 - z * z ) ); double answer = q / normBIK; return answer; } double EvtVubBLNPHybrid::dU1nlo( double muh, double mui ) { double ai = alphas( mui, gvars ); double ah = alphas( muh, gvars ); double q1 = ( ah - ai ) / ( 4 * M_PI * beta0 ); double q2 = log( mb / muh ) * Gamma1 + gp1; double q3 = 4 * beta1 * ( log( mb / muh ) * Gamma0 + gp0 ) + Gamma2 * ( 1 - ai / ah ); double q4 = beta1 * beta1 * Gamma0 * ( -1.0 + ai / ah ) / ( 4 * pow( beta0, 3 ) ); double q5 = -beta2 * Gamma0 * ( 1.0 + ai / ah ) + beta1 * Gamma1 * ( 3 - ai / ah ); double q6 = beta1 * beta1 * Gamma0 * ( ah - ai ) / beta0 - beta2 * Gamma0 * ah + beta1 * Gamma1 * ai; double answer = q1 * ( q2 - q3 / 4 / beta0 + q4 + q5 / ( 4 * beta0 * beta0 ) ) + 1 / ( 8 * M_PI * beta0 * beta0 * beta0 ) * log( ai / ah ) * q6; return answer; } double EvtVubBLNPHybrid::U1lo( double muh, double mui ) { double epsilon = 0.0; double answer = pow( mb / muh, -2 * aGamma( muh, mui, epsilon ) ) * exp( 2 * Sfun( muh, mui, epsilon ) - 2 * agp( muh, mui, epsilon ) ); return answer; } double EvtVubBLNPHybrid::Sfun( double mu1, double mu2, double epsilon ) { double a1 = alphas( mu1, gvars ) / 4 / M_PI; double a2 = alphas( mu2, gvars ) / alphas( mu1, gvars ); double answer = S0( a1, a2 ) + S1( a1, a2 ) + epsilon * S2( a1, a2 ); return answer; } double EvtVubBLNPHybrid::S0( double a1, double r ) { double answer = -Gamma0 / ( 4.0 * beta0 * beta0 * a1 ) * ( -1.0 + 1.0 / r + log( r ) ); return answer; } double EvtVubBLNPHybrid::S1( double /* a1 */, double r ) { double answer = Gamma0 / ( 4 * beta0 * beta0 ) * ( 0.5 * log( r ) * log( r ) * beta1 / beta0 + ( Gamma1 / Gamma0 - beta1 / beta0 ) * ( 1 - r + log( r ) ) ); return answer; } double EvtVubBLNPHybrid::S2( double a1, double r ) { double w1 = pow( beta1, 2 ) / pow( beta0, 2 ) - beta2 / beta0 - beta1 * Gamma1 / ( beta0 * Gamma0 ) + Gamma2 / Gamma0; double w2 = pow( beta1, 2 ) / pow( beta0, 2 ) - beta2 / beta0; double w3 = beta1 * Gamma1 / ( beta0 * Gamma0 ) - beta2 / beta0; double w4 = a1 * Gamma0 / ( 4 * beta0 * beta0 ); double answer = w4 * ( -0.5 * pow( 1 - r, 2 ) * w1 + w2 * ( 1 - r ) * log( r ) + w3 * ( 1 - r + r * log( r ) ) ); return answer; } double EvtVubBLNPHybrid::aGamma( double mu1, double mu2, double epsilon ) { double a1 = alphas( mu1, gvars ); double a2 = alphas( mu2, gvars ); double answer = Gamma0 / ( 2 * beta0 ) * log( a2 / a1 ) + epsilon * ( a2 - a1 ) / ( 8.0 * M_PI ) * ( Gamma1 / beta0 - beta1 * Gamma0 / ( beta0 * beta0 ) ); return answer; } double EvtVubBLNPHybrid::agp( double mu1, double mu2, double epsilon ) { double a1 = alphas( mu1, gvars ); double a2 = alphas( mu2, gvars ); double answer = gp0 / ( 2 * beta0 ) * log( a2 / a1 ) + epsilon * ( a2 - a1 ) / ( 8.0 * M_PI ) * ( gp1 / beta0 - beta1 * gp0 / ( beta0 * beta0 ) ); return answer; } double EvtVubBLNPHybrid::alo( double muh, double mui ) { return -2.0 * aGamma( muh, mui, 0 ); } double EvtVubBLNPHybrid::anlo( double muh, double mui ) { // d/depsilon of aGamma double ah = alphas( muh, gvars ); double ai = alphas( mui, gvars ); double answer = ( ah - ai ) / ( 8.0 * M_PI ) * ( Gamma1 / beta0 - beta1 * Gamma0 / ( beta0 * beta0 ) ); return answer; } double EvtVubBLNPHybrid::alphas( double mu, const std::vector& vars ) { // Note: Lambda4 and Lambda5 depend on mbMS = 4.25 // So if you change mbMS, then you will have to recalculate them. double beta0 = vars[8]; double beta1 = vars[9]; double beta2 = vars[10]; double Lambda4 = 0.298791; double lg = 2 * log( mu / Lambda4 ); double answer = 4 * M_PI / ( beta0 * lg ) * ( 1 - beta1 * log( lg ) / ( beta0 * beta0 * lg ) + beta1 * beta1 / ( beta0 * beta0 * beta0 * beta0 * lg * lg ) * ( ( log( lg ) - 0.5 ) * ( log( lg ) - 0.5 ) - 5.0 / 4.0 + beta2 * beta0 / ( beta1 * beta1 ) ) ); return answer; } double EvtVubBLNPHybrid::PolyLog( double v, double z ) { if ( z >= 1 ) cout << "Error in EvtVubBLNPHybrid: 2nd argument to PolyLog is >= 1." << endl; double sum = 0.0; for ( int k = 1; k < 101; k++ ) { sum = sum + pow( z, k ) / pow( k, v ); } return sum; } double EvtVubBLNPHybrid::Gamma( double z ) { if ( z <= 0 ) return 0; double v = lgamma( z ); return exp( v ); } double EvtVubBLNPHybrid::Gamma( double a, double x ) { double LogGamma; /* if (x<0.0 || a<= 0.0) raise(SIGFPE);*/ if ( x < 0.0 ) x = 0.0; if ( a <= 0.0 ) a = 1.e-50; LogGamma = lgamma( a ); if ( x < ( a + 1.0 ) ) return gamser( a, x, LogGamma ); else return 1.0 - gammcf( a, x, LogGamma ); } /* ------------------Incomplete gamma function-----------------*/ /* ------------------via its series representation-------------*/ double EvtVubBLNPHybrid::gamser( double a, double x, double LogGamma ) { double n; double ap, del, sum; ap = a; del = sum = 1.0 / a; for ( n = 1; n < ITMAX; n++ ) { ++ap; del *= x / ap; sum += del; if ( fabs( del ) < fabs( sum ) * EPS ) return sum * exp( -x + a * log( x ) - LogGamma ); } raise( SIGFPE ); return 0.0; } /* ------------------Incomplete gamma function complement------*/ /* ------------------via its continued fraction representation-*/ double EvtVubBLNPHybrid::gammcf( double a, double x, double LogGamma ) { double an, b, c, d, del, h; int i; b = x + 1.0 - a; c = 1.0 / FPMIN; d = 1.0 / b; h = d; for ( i = 1; i < ITMAX; i++ ) { an = -i * ( i - a ); b += 2.0; d = an * d + b; if ( fabs( d ) < FPMIN ) d = FPMIN; c = b + an / c; if ( fabs( c ) < FPMIN ) c = FPMIN; d = 1.0 / d; del = d * c; h *= del; if ( fabs( del - 1.0 ) < EPS ) return exp( -x + a * log( x ) - LogGamma ) * h; } raise( SIGFPE ); return 0.0; } double EvtVubBLNPHybrid::findBLNPWhat() { double ranNum = EvtRandom::Flat(); double oOverBins = 1.0 / ( float( _pf.size() ) ); int nBinsBelow = 0; // largest k such that I[k] is known to be <= rand int nBinsAbove = _pf.size(); // largest k such that I[k] is known to be > rand int middle; while ( nBinsAbove > nBinsBelow + 1 ) { middle = ( nBinsAbove + nBinsBelow + 1 ) >> 1; if ( ranNum >= _pf[middle] ) { nBinsBelow = middle; } else { nBinsAbove = middle; } } double bSize = _pf[nBinsAbove] - _pf[nBinsBelow]; // binMeasure is always aProbFunc[nBinsBelow], if ( bSize == 0 ) { // rand lies right in a bin of measure 0. Simply return the center // of the range of that bin. (Any value between k/N and (k+1)/N is // equally good, in this rare case.) return ( nBinsBelow + .5 ) * oOverBins; } double bFract = ( ranNum - _pf[nBinsBelow] ) / bSize; return ( nBinsBelow + bFract ) * oOverBins; } double EvtVubBLNPHybrid::getWeight( double mX, double q2, double El ) { int ibin_mX = -1; int ibin_q2 = -1; int ibin_El = -1; for ( unsigned i = 0; i < _bins_mX.size(); i++ ) { if ( mX >= _bins_mX[i] ) ibin_mX = i; } for ( unsigned i = 0; i < _bins_q2.size(); i++ ) { if ( q2 >= _bins_q2[i] ) ibin_q2 = i; } for ( unsigned i = 0; i < _bins_El.size(); i++ ) { if ( El >= _bins_El[i] ) ibin_El = i; } int ibin = ibin_mX + ibin_q2 * _bins_mX.size() + ibin_El * _bins_mX.size() * _bins_q2.size(); if ( ( ibin_mX < 0 ) || ( ibin_q2 < 0 ) || ( ibin_El < 0 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtVubHybrid" ) << "Cannot determine hybrid weight " << "for this event " << "-> assign weight = 0" << endl; return 0.0; } return _weights[ibin]; } void EvtVubBLNPHybrid::readWeights( int startArg ) { _weights.resize( _nbins ); double maxw = 0.0; for ( auto& w : _weights ) { w = getArg( startArg++ ); if ( w > maxw ) maxw = w; } if ( maxw == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtVubBLNPHybrid" ) << "EvtVub generator expected at least one " << " weight > 0, but found none! " << "Will terminate execution!" << endl; ::abort(); } // rescale weights (to be in range 0..1) for ( auto& w : _weights ) w /= maxw; } diff --git a/src/EvtGenModels/EvtVubHybrid.cpp b/src/EvtGenModels/EvtVubHybrid.cpp index 7658f3e..c850279 100644 --- a/src/EvtGenModels/EvtVubHybrid.cpp +++ b/src/EvtGenModels/EvtVubHybrid.cpp @@ -1,465 +1,465 @@ /*********************************************************************** * 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/EvtVubHybrid.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenModels/EvtPFermi.hh" #include "EvtGenModels/EvtVubdGamma.hh" #include #include #include #include using std::cout; using std::endl; using std::ifstream; std::string EvtVubHybrid::getName() { return "VUBHYBRID"; } EvtDecayBase* EvtVubHybrid::clone() { return new EvtVubHybrid; } void EvtVubHybrid::init() { // check that there are at least 3 arguments if ( getNArg() < EvtVubHybrid::nParameters ) { EvtGenReport( EVTGEN_ERROR, "EvtVubHybrid" ) << "EvtVub generator expected " << "at least " << EvtVubHybrid::nParameters << " arguments but found: " << getNArg() << "\nWill terminate execution!" << endl; ::abort(); } else if ( getNArg() == EvtVubHybrid::nParameters ) { EvtGenReport( EVTGEN_WARNING, "EvtVubHybrid" ) << "EvtVub: generate B -> Xu l nu events " << "without using the hybrid reweighting." << endl; _noHybrid = true; } else if ( getNArg() < EvtVubHybrid::nParameters + EvtVubHybrid::nVariables ) { EvtGenReport( EVTGEN_ERROR, "EvtVubHybrid" ) << "EvtVub could not read number of bins for " << "all variables used in the reweighting\n" << "Will terminate execution!" << endl; ::abort(); } // check that there are 3 daughters checkNDaug( 3 ); // read minimum required parameters from decay.dec _mb = getArg( 0 ); _a = getArg( 1 ); _alphas = getArg( 2 ); // the maximum dGamma*p2 value depends on alpha_s only: const double dGMax0 = 3.; _dGMax = 0.21344 + 8.905 * _alphas; if ( _dGMax < dGMax0 ) _dGMax = dGMax0; // for the Fermi Motion we need a B-Meson mass - but it's not critical // to get an exact value; in order to stay in the phase space for // B+- and B0 use the smaller mass static double mB0 = EvtPDL::getMaxMass( EvtPDL::getId( "B0" ) ); static double mBP = EvtPDL::getMaxMass( EvtPDL::getId( "B+" ) ); static double mB = ( mB0 < mBP ? mB0 : mBP ); const double xlow = -_mb; const double xhigh = mB - _mb; const int aSize = 10000; EvtPFermi pFermi( _a, mB, _mb ); // pf is the cumulative distribution normalized to 1. _pf.resize( aSize ); for ( int i = 0; i < aSize; i++ ) { double kplus = xlow + (double)( i + 0.5 ) / ( (double)aSize ) * ( xhigh - xlow ); if ( i == 0 ) _pf[i] = pFermi.getFPFermi( kplus ); else _pf[i] = _pf[i - 1] + pFermi.getFPFermi( kplus ); } for ( size_t index = 0; index < _pf.size(); index++ ) { _pf[index] /= _pf[_pf.size() - 1]; } _dGamma = std::make_unique( _alphas ); if ( _noHybrid ) return; // Without hybrid weighting, nothing else to do _bins_mX.resize( abs( (int)getArg( 3 ) ) ); _bins_q2.resize( abs( (int)getArg( 4 ) ) ); _bins_El.resize( abs( (int)getArg( 5 ) ) ); int nextArg = EvtVubHybrid::nParameters + EvtVubHybrid::nVariables; _nbins = _bins_mX.size() * _bins_q2.size() * _bins_El.size(); // Binning of weight table int expectArgs = nextArg + _bins_mX.size() + _bins_q2.size() + _bins_El.size() + _nbins; if ( getNArg() < expectArgs ) { EvtGenReport( EVTGEN_ERROR, "EvtVubHybrid" ) << " finds " << getNArg() << " arguments, expected " << expectArgs << ". Something is wrong with the tables of weights or thresholds." << "\nWill terminate execution!" << endl; ::abort(); } // read bin boundaries from decay.dec for ( auto& b : _bins_mX ) b = getArg( nextArg++ ); _masscut = _bins_mX[0]; for ( auto& b : _bins_q2 ) b = getArg( nextArg++ ); for ( auto& b : _bins_El ) b = getArg( nextArg++ ); // read in weights (and rescale to range 0..1) readWeights( nextArg ); } void EvtVubHybrid::initProbMax() { noProbMax(); } void EvtVubHybrid::decay( EvtParticle* p ) { int j; // B+ -> u-bar specflav l+ nu EvtParticle *xuhad( nullptr ), *lepton( nullptr ), *neutrino( nullptr ); EvtVector4R p4; // R. Faccini 21/02/03 // move the reweighting up , before also shooting the fermi distribution double x, z, p2; double sh = 0.0; double mB, ml, xlow, xhigh, qplus; double El = 0.0; double Eh = 0.0; double kplus; double q2, mX; const double lp2epsilon = -10; bool rew( true ); while ( rew ) { p->initializePhaseSpace( getNDaug(), getDaugs() ); xuhad = p->getDaug( 0 ); lepton = p->getDaug( 1 ); neutrino = p->getDaug( 2 ); mB = p->mass(); ml = lepton->mass(); xlow = -_mb; xhigh = mB - _mb; // Fermi motion does not need to be computed inside the // tryit loop as m_b in Gamma0 does not need to be replaced by (m_b+kplus). // The difference however should be of the Order (lambda/m_b)^2 which is // beyond the considered orders in the paper anyway ... // for alpha_S = 0 and a mass cut on X_u not all values of kplus are // possible. The maximum value is mB/2-_mb + sqrt(mB^2/4-_masscut^2) kplus = 2 * xhigh; while ( kplus >= xhigh || kplus <= xlow || ( _alphas == 0 && kplus >= mB / 2 - _mb + sqrt( mB * mB / 4 - _masscut * _masscut ) ) ) { kplus = findPFermi(); //_pFermi->shoot(); kplus = xlow + kplus * ( xhigh - xlow ); } qplus = mB - _mb - kplus; if ( ( mB - qplus ) / 2. <= ml ) continue; int tryit = 1; while ( tryit ) { x = EvtRandom::Flat(); z = EvtRandom::Flat( 0, 2 ); p2 = EvtRandom::Flat(); p2 = pow( 10, lp2epsilon * p2 ); El = x * ( mB - qplus ) / 2; if ( El > ml && El < mB / 2 ) { Eh = z * ( mB - qplus ) / 2 + qplus; if ( Eh > 0 && Eh < mB ) { sh = p2 * pow( mB - qplus, 2 ) + 2 * qplus * ( Eh - qplus ) + qplus * qplus; if ( sh > _masscut * _masscut && mB * mB + sh - 2 * mB * Eh > ml * ml ) { double xran = EvtRandom::Flat(); double y = _dGamma->getdGdxdzdp( x, z, p2 ) / _dGMax * p2; if ( y > 1 ) EvtGenReport( EVTGEN_WARNING, "EvtVubHybrid" ) << "EvtVubHybrid decay probability > 1 found: " << y << endl; if ( y >= xran ) tryit = 0; } } } } // compute all kinematic variables needed for reweighting (J. Dingfelder) mX = sqrt( sh ); q2 = mB * mB + sh - 2 * mB * Eh; // Reweighting in bins of mX, q2, El (J. Dingfelder) if ( !_weights.empty() ) { double xran1 = EvtRandom::Flat(); double w = 1.0; if ( !_noHybrid ) w = getWeight( mX, q2, El ); if ( w >= xran1 ) rew = false; } else { rew = false; } } // o.k. we have the three kineamtic variables // now calculate a flat cos Theta_H [-1,1] distribution of the // hadron flight direction w.r.t the B flight direction // because the B is a scalar and should decay isotropic. // Then chose a flat Phi_H [0,2Pi] w.r.t the B flight direction // and and a flat Phi_L [0,2Pi] in the W restframe w.r.t the // W flight direction. double ctH = EvtRandom::Flat( -1, 1 ); double phH = EvtRandom::Flat( 0, 2 * M_PI ); double phL = EvtRandom::Flat( 0, 2 * M_PI ); // now compute the four vectors in the B Meson restframe double ptmp, sttmp; // calculate the hadron 4 vector in the B Meson restframe sttmp = sqrt( 1 - ctH * ctH ); ptmp = sqrt( Eh * Eh - sh ); - double pHB[4] = {Eh, ptmp * sttmp * cos( phH ), ptmp * sttmp * sin( phH ), - ptmp * ctH}; + double pHB[4] = { Eh, ptmp * sttmp * cos( phH ), ptmp * sttmp * sin( phH ), + ptmp * ctH }; p4.set( pHB[0], pHB[1], pHB[2], pHB[3] ); xuhad->init( getDaug( 0 ), p4 ); if ( _storeQplus ) { // cludge to store the hidden parameter q+ with the decay; // the lifetime of the Xu is abused for this purpose. // tau = 1 ps corresponds to ctau = 0.3 mm -> in order to // stay well below BaBars sensitivity we take q+/(10000 GeV) which // goes up to 0.0005 in the most extreme cases as ctau in mm. // To extract q+ back from the StdHepTrk its necessary to get // delta_ctau = Xu->anyDaughter->getVertexTime()-Xu->getVertexTime() // where these pseudo calls refere to the StdHep time stored at // the production vertex in the lab for each particle. The boost // has to be reversed and the result is: // // q+ = delta_ctau * 10000 GeV/mm * Mass_Xu/Energy_Xu // xuhad->setLifetime( qplus / 10000. ); } // calculate the W 4 vector in the B Meson restrframe double apWB = ptmp; - double pWB[4] = {mB - Eh, -pHB[1], -pHB[2], -pHB[3]}; + double pWB[4] = { mB - Eh, -pHB[1], -pHB[2], -pHB[3] }; // first go in the W restframe and calculate the lepton and // the neutrino in the W frame double mW2 = mB * mB + sh - 2 * mB * Eh; double beta = ptmp / pWB[0]; double gamma = pWB[0] / sqrt( mW2 ); double pLW[4]; ptmp = ( mW2 - ml * ml ) / 2 / sqrt( mW2 ); pLW[0] = sqrt( ml * ml + ptmp * ptmp ); double ctL = ( El - gamma * pLW[0] ) / beta / gamma / ptmp; if ( ctL < -1 ) ctL = -1; if ( ctL > 1 ) ctL = 1; sttmp = sqrt( 1 - ctL * ctL ); // eX' = eZ x eW - double xW[3] = {-pWB[2], pWB[1], 0}; + double xW[3] = { -pWB[2], pWB[1], 0 }; // eZ' = eW - double zW[3] = {pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB}; + double zW[3] = { pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB }; double lx = sqrt( xW[0] * xW[0] + xW[1] * xW[1] ); for ( j = 0; j < 2; j++ ) xW[j] /= lx; // eY' = eZ' x eX' - double yW[3] = {-pWB[1] * pWB[3], -pWB[2] * pWB[3], - pWB[1] * pWB[1] + pWB[2] * pWB[2]}; + double yW[3] = { -pWB[1] * pWB[3], -pWB[2] * pWB[3], + pWB[1] * pWB[1] + pWB[2] * pWB[2] }; double ly = sqrt( yW[0] * yW[0] + yW[1] * yW[1] + yW[2] * yW[2] ); for ( j = 0; j < 3; j++ ) yW[j] /= ly; // p_lep = |p_lep| * ( sin(Theta) * cos(Phi) * eX' // + sin(Theta) * sin(Phi) * eY' // + cos(Theta) * eZ') for ( j = 0; j < 3; j++ ) pLW[j + 1] = sttmp * cos( phL ) * ptmp * xW[j] + sttmp * sin( phL ) * ptmp * yW[j] + ctL * ptmp * zW[j]; double apLW = ptmp; // calculate the neutrino 4 vector in the W restframe //double pNW[4] = {sqrt(mW2)-pLW[0],-pLW[1],-pLW[2],-pLW[3]}; // boost them back in the B Meson restframe double appLB = beta * gamma * pLW[0] + gamma * ctL * apLW; ptmp = sqrt( El * El - ml * ml ); double ctLL = appLB / ptmp; if ( ctLL > 1 ) ctLL = 1; if ( ctLL < -1 ) ctLL = -1; - double pLB[4] = {El, 0, 0, 0}; - double pNB[4] = {pWB[0] - El, 0, 0, 0}; + double pLB[4] = { El, 0, 0, 0 }; + double pNB[4] = { pWB[0] - El, 0, 0, 0 }; for ( j = 1; j < 4; j++ ) { pLB[j] = pLW[j] + ( ctLL * ptmp - ctL * apLW ) / apWB * pWB[j]; pNB[j] = pWB[j] - pLB[j]; } p4.set( pLB[0], pLB[1], pLB[2], pLB[3] ); lepton->init( getDaug( 1 ), p4 ); p4.set( pNB[0], pNB[1], pNB[2], pNB[3] ); neutrino->init( getDaug( 2 ), p4 ); return; } double EvtVubHybrid::findPFermi() { double ranNum = EvtRandom::Flat(); double oOverBins = 1.0 / ( float( _pf.size() ) ); int nBinsBelow = 0; // largest k such that I[k] is known to be <= rand int nBinsAbove = _pf.size(); // largest k such that I[k] is known to be > rand int middle; while ( nBinsAbove > nBinsBelow + 1 ) { middle = ( nBinsAbove + nBinsBelow + 1 ) >> 1; if ( ranNum >= _pf[middle] ) { nBinsBelow = middle; } else { nBinsAbove = middle; } } double bSize = _pf[nBinsAbove] - _pf[nBinsBelow]; // binMeasure is always aProbFunc[nBinsBelow], if ( bSize == 0 ) { // rand lies right in a bin of measure 0. Simply return the center // of the range of that bin. (Any value between k/N and (k+1)/N is // equally good, in this rare case.) return ( nBinsBelow + .5 ) * oOverBins; } double bFract = ( ranNum - _pf[nBinsBelow] ) / bSize; return ( nBinsBelow + bFract ) * oOverBins; } double EvtVubHybrid::getWeight( double mX, double q2, double El ) { int ibin_mX = -1; int ibin_q2 = -1; int ibin_El = -1; for ( unsigned i = 0; i < _bins_mX.size(); i++ ) { if ( mX >= _bins_mX[i] ) ibin_mX = i; } for ( unsigned i = 0; i < _bins_q2.size(); i++ ) { if ( q2 >= _bins_q2[i] ) ibin_q2 = i; } for ( unsigned i = 0; i < _bins_El.size(); i++ ) { if ( El >= _bins_El[i] ) ibin_El = i; } int ibin = ibin_mX + ibin_q2 * _bins_mX.size() + ibin_El * _bins_mX.size() * _bins_q2.size(); if ( ( ibin_mX < 0 ) || ( ibin_q2 < 0 ) || ( ibin_El < 0 ) ) { EvtGenReport( EVTGEN_ERROR, "EvtVubHybrid" ) << "Cannot determine hybrid weight " << "for this event " << "-> assign weight = 0" << endl; return 0.0; } return _weights[ibin]; } void EvtVubHybrid::readWeights( int startArg ) { _weights.resize( _nbins ); double maxw = 0.0; for ( auto& w : _weights ) { w = getArg( startArg++ ); if ( w > maxw ) maxw = w; } if ( maxw == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtVubHybrid" ) << "EvtVub generator expected at least one " << " weight > 0, but found none! " << "Will terminate execution!" << endl; ::abort(); } // rescale weights (to be in range 0..1) for ( auto& w : _weights ) w /= maxw; } diff --git a/src/EvtGenModels/EvtVubNLO.cpp b/src/EvtGenModels/EvtVubNLO.cpp index 3f3c41e..ec8d6e9 100644 --- a/src/EvtGenModels/EvtVubNLO.cpp +++ b/src/EvtGenModels/EvtVubNLO.cpp @@ -1,732 +1,732 @@ /*********************************************************************** * 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/EvtVubNLO.hh" #include "EvtGenBase/EvtDiLog.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenModels/EvtBtoXsgammaFermiUtil.hh" #include "EvtGenModels/EvtItgPtrFunction.hh" #include "EvtGenModels/EvtItgSimpsonIntegrator.hh" #include "EvtGenModels/EvtPFermi.hh" #include #include #include using std::cout; using std::endl; EvtVubNLO::~EvtVubNLO() { cout << " max pdf : " << _gmax << endl; cout << " efficiency : " << (float)_ngood / (float)_ntot << endl; } std::string EvtVubNLO::getName() { return "VUB_NLO"; } EvtDecayBase* EvtVubNLO::clone() { return new EvtVubNLO; } void EvtVubNLO::init() { // max pdf _gmax = 0; _ntot = 0; _ngood = 0; _lbar = -1000; _mupi2 = -1000; // check number of arguments int npar = 8; if ( getNArg() < npar ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVubNLO generator expected " << " at least npar arguments but found: " << getNArg() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } // this is the shape function parameter _mb = getArg( 0 ); _b = getArg( 1 ); _lambdaSF = getArg( 2 ); // shape function lambda is different from lambda _mui = 1.5; // GeV (scale) _kpar = getArg( 3 ); // 0 _idSF = abs( (int)getArg( 4 ) ); // type of shape function 1: exponential (from Neubert) int nbins = abs( (int)getArg( 5 ) ); _masses.resize( nbins ); _weights.resize( nbins ); // Shape function normalization _mB = 5.28; // temporary B meson mass for normalization std::vector sCoeffs( 11 ); sCoeffs[3] = _b; sCoeffs[4] = _mb; sCoeffs[5] = _mB; sCoeffs[6] = _idSF; sCoeffs[7] = lambda_SF(); sCoeffs[8] = mu_h(); sCoeffs[9] = mu_i(); sCoeffs[10] = 1.; _SFNorm = SFNorm( sCoeffs ); // SF normalization; cout << " pdf 0.66, 1.32 , 4.32 " << tripleDiff( 0.66, 1.32, 4.32 ) << endl; cout << " pdf 0.23,0.37,3.76 " << tripleDiff( 0.23, 0.37, 3.76 ) << endl; cout << " pdf 0.97,4.32,4.42 " << tripleDiff( 0.97, 4.32, 4.42 ) << endl; cout << " pdf 0.52,1.02,2.01 " << tripleDiff( 0.52, 1.02, 2.01 ) << endl; cout << " pdf 1.35,1.39,2.73 " << tripleDiff( 1.35, 1.39, 2.73 ) << endl; if ( getNArg() - npar + 2 != int( 2 * _weights.size() ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVubNLO generator expected " << _weights.size() << " masses and weights but found: " << ( getNArg() - npar ) / 2 << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } int j = npar - 2; double maxw = 0.; for ( unsigned i = 0; i < _masses.size(); i++ ) { _masses[i] = getArg( j++ ); if ( i > 0 && _masses[i] <= _masses[i - 1] ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVubNLO generator expected " << " mass bins in ascending order!" << "Will terminate execution!" << endl; ::abort(); } _weights[i] = getArg( j++ ); if ( _weights[i] < 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVubNLO generator expected " << " weights >= 0, but found: " << _weights[i] << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } if ( _weights[i] > maxw ) maxw = _weights[i]; } if ( maxw == 0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVubNLO generator expected at least one " << " weight > 0, but found none! " << "Will terminate execution!" << endl; ::abort(); } for ( auto& w : _weights ) w /= maxw; // the maximum dGamma*p2 value depends on alpha_s only: // _dGMax = 0.05; _dGMax = 150.; // for the Fermi Motion we need a B-Meso\n mass - but it's not critical // to get an exact value; in order to stay in the phase space for // B+- and B0 use the smaller mass // check that there are 3 daughters checkNDaug( 3 ); } void EvtVubNLO::initProbMax() { noProbMax(); } void EvtVubNLO::decay( EvtParticle* p ) { // B+ -> u-bar specflav l+ nu EvtParticle *xuhad, *lepton, *neutrino; EvtVector4R p4; double pp, pm, pl, ml, El( 0.0 ), Eh( 0.0 ), sh( 0.0 ); p->initializePhaseSpace( getNDaug(), getDaugs() ); xuhad = p->getDaug( 0 ); lepton = p->getDaug( 1 ); neutrino = p->getDaug( 2 ); _mB = p->mass(); ml = lepton->mass(); bool tryit = true; while ( tryit ) { // pm=(E_H+P_H) pm = EvtRandom::Flat( 0., 1 ); pm = pow( pm, 1. / 3. ) * _mB; // pl=mB-2*El pl = EvtRandom::Flat( 0., 1 ); pl = sqrt( pl ) * pm; // pp=(E_H-P_H) pp = EvtRandom::Flat( 0., pl ); _ntot++; El = ( _mB - pl ) / 2.; Eh = ( pp + pm ) / 2; sh = pp * pm; double pdf( 0. ); if ( pp < pl && El > ml && sh > _masses[0] * _masses[0] && _mB * _mB + sh - 2 * _mB * Eh > ml * ml ) { double xran = EvtRandom::Flat( 0, _dGMax ); pdf = tripleDiff( pp, pl, pm ); // triple differential distribution // cout <<" P+,P-,Pl,Pdf= "< _dGMax ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVubNLO pdf above maximum: " << pdf << " P+,P-,Pl,Pdf= " << pp << " " << pm << " " << pl << " " << pdf << endl; //::abort(); } if ( pdf >= xran ) tryit = false; if ( pdf > _gmax ) _gmax = pdf; } else { // cout <<" EvtVubNLO incorrect kinematics sh= "< _masses[j] ) j++; double w = _weights[j - 1]; if ( w < xran1 ) tryit = true; // through away this candidate } } // cout <<" max prob "<init( getDaug( 0 ), p4 ); // calculate the W 4 vector in the B Meson restrframe double apWB = ptmp; - double pWB[4] = {_mB - Eh, -pHB[1], -pHB[2], -pHB[3]}; + double pWB[4] = { _mB - Eh, -pHB[1], -pHB[2], -pHB[3] }; // first go in the W restframe and calculate the lepton and // the neutrino in the W frame double mW2 = _mB * _mB + sh - 2 * _mB * Eh; // if(mW2<0.1){ // cout <<" low Q2! "< 1 ) ctL = 1; sttmp = sqrt( 1 - ctL * ctL ); // eX' = eZ x eW - double xW[3] = {-pWB[2], pWB[1], 0}; + double xW[3] = { -pWB[2], pWB[1], 0 }; // eZ' = eW - double zW[3] = {pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB}; + double zW[3] = { pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB }; double lx = sqrt( xW[0] * xW[0] + xW[1] * xW[1] ); for ( int j = 0; j < 2; j++ ) xW[j] /= lx; // eY' = eZ' x eX' - double yW[3] = {-pWB[1] * pWB[3], -pWB[2] * pWB[3], - pWB[1] * pWB[1] + pWB[2] * pWB[2]}; + double yW[3] = { -pWB[1] * pWB[3], -pWB[2] * pWB[3], + pWB[1] * pWB[1] + pWB[2] * pWB[2] }; double ly = sqrt( yW[0] * yW[0] + yW[1] * yW[1] + yW[2] * yW[2] ); for ( int j = 0; j < 3; j++ ) yW[j] /= ly; // p_lep = |p_lep| * ( sin(Theta) * cos(Phi) * eX' // + sin(Theta) * sin(Phi) * eY' // + cos(Theta) * eZ') for ( int j = 0; j < 3; j++ ) pLW[j + 1] = sttmp * cos( phL ) * ptmp * xW[j] + sttmp * sin( phL ) * ptmp * yW[j] + ctL * ptmp * zW[j]; double apLW = ptmp; // boost them back in the B Meson restframe double appLB = beta * gamma * pLW[0] + gamma * ctL * apLW; ptmp = sqrt( El * El - ml * ml ); double ctLL = appLB / ptmp; if ( ctLL > 1 ) ctLL = 1; if ( ctLL < -1 ) ctLL = -1; - double pLB[4] = {El, 0, 0, 0}; - double pNB[8] = {pWB[0] - El, 0, 0, 0}; + double pLB[4] = { El, 0, 0, 0 }; + double pNB[8] = { pWB[0] - El, 0, 0, 0 }; for ( int j = 1; j < 4; j++ ) { pLB[j] = pLW[j] + ( ctLL * ptmp - ctL * apLW ) / apWB * pWB[j]; pNB[j] = pWB[j] - pLB[j]; } p4.set( pLB[0], pLB[1], pLB[2], pLB[3] ); lepton->init( getDaug( 1 ), p4 ); p4.set( pNB[0], pNB[1], pNB[2], pNB[3] ); neutrino->init( getDaug( 2 ), p4 ); return; } double EvtVubNLO::tripleDiff( double pp, double pl, double pm ) { std::vector sCoeffs( 11 ); sCoeffs[0] = pp; sCoeffs[1] = pl; sCoeffs[2] = pm; sCoeffs[3] = _b; sCoeffs[4] = _mb; sCoeffs[5] = _mB; sCoeffs[6] = _idSF; sCoeffs[7] = lambda_SF(); sCoeffs[8] = mu_h(); sCoeffs[9] = mu_i(); sCoeffs[10] = _SFNorm; // SF normalization; double c1 = ( _mB + pl - pp - pm ) * ( pm - pl ); double c2 = 2 * ( pl - pp ) * ( pm - pl ); double c3 = ( _mB - pm ) * ( pm - pp ); double aF1 = F10( sCoeffs ); double aF2 = F20( sCoeffs ); double aF3 = F30( sCoeffs ); double td0 = c1 * aF1 + c2 * aF2 + c3 * aF3; - auto func = EvtItgPtrFunction{&integrand, 0., _mB, sCoeffs}; - auto jetSF = EvtItgSimpsonIntegrator{func, 0.01, 25}; + auto func = EvtItgPtrFunction{ &integrand, 0., _mB, sCoeffs }; + auto jetSF = EvtItgSimpsonIntegrator{ func, 0.01, 25 }; double smallfrac = 0.000001; // stop a bit before the end to avoid problems with numerical integration double tdInt = jetSF.evaluate( 0, pp * ( 1 - smallfrac ) ); double SU = U1lo( mu_h(), mu_i() ) * pow( ( pm - pp ) / ( _mB - pp ), alo( mu_h(), mu_i() ) ); double TD = ( _mB - pp ) * SU * ( td0 + tdInt ); return TD; } double EvtVubNLO::integrand( double omega, const std::vector& coeffs ) { //double pp=coeffs[0]; double c1 = ( coeffs[5] + coeffs[1] - coeffs[0] - coeffs[2] ) * ( coeffs[2] - coeffs[1] ); double c2 = 2 * ( coeffs[1] - coeffs[0] ) * ( coeffs[2] - coeffs[1] ); double c3 = ( coeffs[5] - coeffs[2] ) * ( coeffs[2] - coeffs[0] ); return c1 * F1Int( omega, coeffs ) + c2 * F2Int( omega, coeffs ) + c3 * F3Int( omega, coeffs ); } double EvtVubNLO::F10( const std::vector& coeffs ) { double pp = coeffs[0]; double y = ( coeffs[2] - coeffs[0] ) / ( coeffs[5] - coeffs[0] ); double mui = coeffs[9]; double muh = coeffs[8]; double z = 1 - y; double result = U1nlo( muh, mui ) / U1lo( muh, mui ); result += anlo( muh, mui ) * log( y ); result += C_F( muh ) * ( -4 * pow( log( y * coeffs[4] / muh ), 2 ) + 10 * log( y * coeffs[4] / muh ) - 4 * log( y ) - 2 * log( y ) / ( 1 - y ) - 4.0 * EvtDiLog::DiLog( z ) - pow( EvtConst::pi, 2 ) / 6. - 12 ); result += C_F( mui ) * ( 2 * pow( log( y * coeffs[4] * pp / pow( mui, 2 ) ), 2 ) - 3 * log( y * coeffs[4] * pp / pow( mui, 2 ) ) + 7 - pow( EvtConst::pi, 2 ) ); result *= shapeFunction( pp, coeffs ); // changes due to SSF result += ( -subS( coeffs ) + 2 * subT( coeffs ) + ( subU( coeffs ) - subV( coeffs ) ) * ( 1 / y - 1. ) ) / ( coeffs[5] - pp ); result += shapeFunction( pp, coeffs ) / pow( ( coeffs[5] - coeffs[0] ), 2 ) * ( -5 * ( lambda1() + 3 * lambda2() ) / 6 + 2 * ( 2 * lambda1() / 3 - lambda2() ) / pow( y, 2 ) ); // result += (subS(coeffs)+subT(coeffs)+(subU(coeffs)-subV(coeffs))/y)/(coeffs[5]-pp); // this part has been added after Feb '05 //result += shapeFunction(pp,coeffs)/pow((coeffs[5]-coeffs[0]),2)*((lambda1()+3*lambda2())/6+2*(2*lambda1()/3-lambda2())/pow(y,2)); return result; } double EvtVubNLO::F1Int( double omega, const std::vector& coeffs ) { double pp = coeffs[0]; double y = ( coeffs[2] - coeffs[0] ) / ( coeffs[5] - coeffs[0] ); // mubar == mui return C_F( coeffs[9] ) * ( ( shapeFunction( omega, coeffs ) - shapeFunction( pp, coeffs ) ) * ( 4 * log( y * coeffs[4] * ( pp - omega ) / pow( coeffs[9], 2 ) ) - 3 ) / ( pp - omega ) + ( g1( y, ( pp - omega ) / ( coeffs[5] - coeffs[0] ) ) / ( coeffs[5] - pp ) * shapeFunction( omega, coeffs ) ) ); } double EvtVubNLO::F20( const std::vector& coeffs ) { double pp = coeffs[0]; double y = ( coeffs[2] - coeffs[0] ) / ( coeffs[5] - coeffs[0] ); double result = C_F( coeffs[8] ) * log( y ) / ( 1 - y ) * shapeFunction( pp, coeffs ) - 1 / y * ( subS( coeffs ) + 2 * subT( coeffs ) - ( subT( coeffs ) + subV( coeffs ) ) / y ) / ( coeffs[5] - pp ); // added after Feb '05 result += shapeFunction( pp, coeffs ) / pow( ( coeffs[5] - coeffs[0] ) * y, 2 ) * ( 2 * lambda1() / 3 + 4 * lambda2() - y * ( 7 / 6 * lambda1() + 3 * lambda2() ) ); return result; } double EvtVubNLO::F2Int( double omega, const std::vector& coeffs ) { double pp = coeffs[0]; double y = ( coeffs[2] - coeffs[0] ) / ( coeffs[5] - coeffs[0] ); return C_F( coeffs[9] ) * g3( y, ( pp - omega ) / ( coeffs[5] - coeffs[0] ) ) * shapeFunction( omega, coeffs ) / ( coeffs[5] - pp ); } double EvtVubNLO::F30( const std::vector& coeffs ) { double y = ( coeffs[2] - coeffs[0] ) / ( coeffs[5] - coeffs[0] ); return shapeFunction( coeffs[0], coeffs ) / pow( ( coeffs[5] - coeffs[0] ) * y, 2 ) * ( -2 * lambda1() / 3 + lambda2() ); } double EvtVubNLO::F3Int( double omega, const std::vector& coeffs ) { double pp = coeffs[0]; double y = ( coeffs[2] - coeffs[0] ) / ( coeffs[5] - coeffs[0] ); return C_F( coeffs[9] ) * g3( y, ( pp - omega ) / ( coeffs[5] - coeffs[0] ) ) / 2 * shapeFunction( omega, coeffs ) / ( coeffs[2] - coeffs[0] ); } double EvtVubNLO::g1( double y, double x ) { double result = ( y * ( -9 + 10 * y ) + x * x * ( -12 + 13 * y ) + 2 * x * ( -8 + 6 * y + 3 * y * y ) ) / y / pow( 1 + x, 2 ) / ( x + y ); result -= 4 * log( ( 1 + 1 / x ) * y ) / x; result -= 2 * log( 1 + y / x ) * ( 3 * pow( x, 4 ) * ( -2 + y ) - 2 * pow( y, 3 ) - 4 * pow( x, 3 ) * ( 2 + y ) - 2 * x * y * y * ( 4 + y ) - x * x * y * ( 12 + 4 * y + y * y ) ) / x / pow( ( 1 + x ) * y, 2 ) / ( x + y ); return result; } double EvtVubNLO::g2( double y, double x ) { double result = y * ( 10 * pow( x, 4 ) + y * y + 3 * x * x * y * ( 10 + y ) + pow( x, 3 ) * ( 12 + 19 * y ) + x * y * ( 8 + 4 * y + y * y ) ); result -= 2 * x * log( 1 + y / x ) * ( 5 * pow( x, 4 ) + 2 * y * y + 6 * pow( x, 3 ) * ( 1 + 2 * y ) + 4 * y * x * ( 1 + 2 * y ) + x * x * y * ( 18 + 5 * y ) ); result *= 2 / ( pow( y * ( 1 + x ), 2 ) * y * ( x + y ) ); return result; } double EvtVubNLO::g3( double y, double x ) { double result = ( 2 * pow( y, 3 ) * ( -11 + 2 * y ) - 10 * pow( x, 4 ) * ( 6 - 6 * y + y * y ) + x * y * y * ( -94 + 29 * y + 2 * y * y ) + 2 * x * x * y * ( -72 + 18 * y + 13 * y * y ) - pow( x, 3 ) * ( 72 + 42 * y - 70 * y * y + 3 * pow( y, 3 ) ) ) / ( pow( y * ( 1 + x ), 2 ) * y * ( x + y ) ); result += 2 * log( 1 + y / x ) * ( -6 * x * pow( y, 3 ) * ( -5 + y ) + 4 * pow( y, 4 ) + 5 * pow( x, 5 ) * ( 6 - 6 * y + y * y ) - 4 * pow( x * y, 2 ) * ( -20 + 6 * y + y * y ) + pow( x, 3 ) * y * ( 90 - 10 * y - 28 * y * y + pow( y, 3 ) ) + pow( x, 4 ) * ( 36 + 36 * y - 50 * y * y + 4 * pow( y, 3 ) ) ) / ( pow( ( 1 + x ) * y * y, 2 ) * ( x + y ) ); return result; } /* old version (before Feb 05 notebook from NNeubert double EvtVubNLO::F1Int(double omega,const std::vector &coeffs){ double pp=coeffs[0]; double y=(coeffs[2]-coeffs[0])/(coeffs[5]-coeffs[0]); // mubar == mui return C_F(coeffs[9])*( (shapeFunction(omega,coeffs)-shapeFunction(pp,coeffs))*(4*log(y*coeffs[4]*(pp-omega)/pow(coeffs[9],2))-3)/(pp-omega)- (1./y/(coeffs[5]-pp)*shapeFunction(omega,coeffs)*(5-6*y+4*(3-y)*log((pp-omega)/y/coeffs[4]))) ); } double EvtVubNLO::F2Int(double omega,const std::vector &coeffs){ double pp=coeffs[0]; double y=(coeffs[2]-coeffs[0])/(coeffs[5]-coeffs[0]); return C_F(coeffs[9])*shapeFunction(omega,coeffs)*(2-11/y-4/y*log((pp-omega)/y/coeffs[4]))/(coeffs[5]-pp); } double EvtVubNLO::F3(const std::vector &coeffs){ return C_F(coeffs[9])*shapeFunction(omega,coeffs)/(coeffs[2]-coeffs[0]); } */ double EvtVubNLO::SFNorm( const std::vector& /*coeffs*/ ) { double omega0 = 1.68; //normalization scale (mB-2*1.8) if ( _idSF == 1 ) { // exponential SF double omega0 = 1.68; //normalization scale (mB-2*1.8) return M0( mu_i(), omega0 ) * pow( _b, _b ) / lambda_SF() / ( Gamma( _b ) - Gamma( _b, _b * omega0 / lambda_SF() ) ); } else if ( _idSF == 2 ) { // Gaussian SF double c = cGaus( _b ); return M0( mu_i(), omega0 ) * 2 / lambda_SF() / pow( c, -( 1 + _b ) / 2. ) / ( Gamma( ( 1 + _b ) / 2 ) - Gamma( ( 1 + _b ) / 2, pow( omega0 / lambda_SF(), 2 ) * c ) ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "unknown SF " << _idSF << endl; return -1; } } double EvtVubNLO::shapeFunction( double omega, const std::vector& sCoeffs ) { if ( sCoeffs[6] == 1 ) { return sCoeffs[10] * expShapeFunction( omega, sCoeffs ); } else if ( sCoeffs[6] == 2 ) { return sCoeffs[10] * gausShapeFunction( omega, sCoeffs ); } else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtVubNLO : unknown shape function # " << sCoeffs[6] << endl; } return -1.; } // SSF double EvtVubNLO::subS( const std::vector& c ) { return ( lambda_bar( 1.68 ) - c[0] ) * shapeFunction( c[0], c ); } double EvtVubNLO::subT( const std::vector& c ) { return -3 * lambda2() * subS( c ) / mu_pi2( 1.68 ); } double EvtVubNLO::subU( const std::vector& c ) { return -2 * subS( c ); } double EvtVubNLO::subV( const std::vector& c ) { return -subT( c ); } double EvtVubNLO::lambda_bar( double omega0 ) { if ( _lbar < 0 ) { if ( _idSF == 1 ) { // exponential SF double rat = omega0 * _b / lambda_SF(); _lbar = lambda_SF() / _b * ( Gamma( 1 + _b ) - Gamma( 1 + _b, rat ) ) / ( Gamma( _b ) - Gamma( _b, rat ) ); } else if ( _idSF == 2 ) { // Gaussian SF double c = cGaus( _b ); _lbar = lambda_SF() * ( Gamma( 1 + _b / 2 ) - Gamma( 1 + _b / 2, pow( omega0 / lambda_SF(), 2 ) * c ) ) / ( Gamma( ( 1 + _b ) / 2 ) - Gamma( ( 1 + _b ) / 2, pow( omega0 / lambda_SF(), 2 ) * c ) ) / sqrt( c ); } } return _lbar; } double EvtVubNLO::mu_pi2( double omega0 ) { if ( _mupi2 < 0 ) { if ( _idSF == 1 ) { // exponential SF double rat = omega0 * _b / lambda_SF(); _mupi2 = 3 * ( pow( lambda_SF() / _b, 2 ) * ( Gamma( 2 + _b ) - Gamma( 2 + _b, rat ) ) / ( Gamma( _b ) - Gamma( _b, rat ) ) - pow( lambda_bar( omega0 ), 2 ) ); } else if ( _idSF == 2 ) { // Gaussian SF double c = cGaus( _b ); double m1 = Gamma( ( 3 + _b ) / 2 ) - Gamma( ( 3 + _b ) / 2, pow( omega0 / lambda_SF(), 2 ) * c ); double m2 = Gamma( 1 + _b / 2 ) - Gamma( 1 + _b / 2, pow( omega0 / lambda_SF(), 2 ) * c ); double m3 = Gamma( ( 1 + _b ) / 2 ) - Gamma( ( 1 + _b ) / 2, pow( omega0 / lambda_SF(), 2 ) * c ); _mupi2 = 3 * pow( lambda_SF(), 2 ) * ( m1 / m3 - pow( m2 / m3, 2 ) ) / c; } } return _mupi2; } double EvtVubNLO::M0( double mui, double omega0 ) { double mf = omega0 - lambda_bar( omega0 ); return 1 + 4 * C_F( mui ) * ( -pow( log( mf / mui ), 2 ) - log( mf / mui ) - pow( EvtConst::pi / 2, 2 ) / 6. + mu_pi2( omega0 ) / 3 / pow( mf, 2 ) * ( log( mf / mui ) - 0.5 ) ); } double EvtVubNLO::alphas( double mu ) { double Lambda4 = 0.302932; double lg = 2 * log( mu / Lambda4 ); return 4 * EvtConst::pi / lg / beta0() * ( 1 - beta1() * log( lg ) / pow( beta0(), 2 ) / lg + pow( beta1() / lg, 2 ) / pow( beta0(), 4 ) * ( pow( log( lg ) - 0.5, 2 ) - 1.25 + beta2() * beta0() / pow( beta1(), 2 ) ) ); } double EvtVubNLO::gausShapeFunction( double omega, const std::vector& sCoeffs ) { double b = sCoeffs[3]; double l = sCoeffs[7]; double wL = omega / l; return pow( wL, b ) * exp( -cGaus( b ) * wL * wL ); } double EvtVubNLO::expShapeFunction( double omega, const std::vector& sCoeffs ) { double b = sCoeffs[3]; double l = sCoeffs[7]; double wL = omega / l; return pow( wL, b - 1 ) * exp( -b * wL ); } double EvtVubNLO::Gamma( double z ) { std::array gammaCoeffs{ 76.18009172947146, -86.50532032941677, 24.01409824083091, - -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5}; + -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5 }; //Lifted from Numerical Recipies in C double y = z; double x = z; double tmp = x + 5.5; tmp = tmp - ( x + 0.5 ) * log( tmp ); double ser = 1.000000000190015; for ( const auto& gammaCoeff : gammaCoeffs ) { y += 1.0; ser += gammaCoeff / y; } return exp( -tmp + log( 2.5066282746310005 * ser / x ) ); } double EvtVubNLO::Gamma( double z, double tmin ) { std::vector c( 1 ); c[0] = z; - auto func = EvtItgPtrFunction{&dgamma, tmin, 100., c}; - auto jetSF = EvtItgSimpsonIntegrator{func, 0.001}; + auto func = EvtItgPtrFunction{ &dgamma, tmin, 100., c }; + auto jetSF = EvtItgSimpsonIntegrator{ func, 0.001 }; return jetSF.evaluate( tmin, 100. ); } diff --git a/src/EvtGenModels/EvtWilsonCoefficients.cpp b/src/EvtGenModels/EvtWilsonCoefficients.cpp index b32f861..5149e72 100644 --- a/src/EvtGenModels/EvtWilsonCoefficients.cpp +++ b/src/EvtGenModels/EvtWilsonCoefficients.cpp @@ -1,576 +1,577 @@ /*********************************************************************** * 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/EvtWilsonCoefficients.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include double li2spence( double ); EvtWilsonCoefficients::EvtWilsonCoefficients() { int i, j; - double tmpa[8] = {14. / 23., 16. / 23., 6. / 23., -12. / 23., - 0.4086, -0.4230, -0.8994, 0.1456}; - double tmph[8] = {2.2996, -1.0880, -3. / 7., -1. / 14., - -0.6494, -0.0380, -0.0186, -0.0057}; - double tmpp[8] = {0, 0, -80. / 203., 8. / 33., - 0.0433, 0.1384, 0.1648, -0.0073}; - double tmps[8] = {0, 0, -0.2009, -0.3579, 0.0490, -0.3616, -0.3554, 0.0072}; - double tmpq[8] = {0, 0, 0, 0, 0.0318, 0.0918, -0.2700, 0.0059}; - double tmpg[8] = {313063. / 363036., 0, 0, 0, - -0.9135, 0.0873, -0.0571, -0.0209}; + double tmpa[8] = { 14. / 23., 16. / 23., 6. / 23., -12. / 23., + 0.4086, -0.4230, -0.8994, 0.1456 }; + double tmph[8] = { 2.2996, -1.0880, -3. / 7., -1. / 14., + -0.6494, -0.0380, -0.0186, -0.0057 }; + double tmpp[8] = { 0, 0, -80. / 203., 8. / 33., + 0.0433, 0.1384, 0.1648, -0.0073 }; + double tmps[8] = { 0, 0, -0.2009, -0.3579, + 0.0490, -0.3616, -0.3554, 0.0072 }; + double tmpq[8] = { 0, 0, 0, 0, 0.0318, 0.0918, -0.2700, 0.0059 }; + double tmpg[8] = { 313063. / 363036., 0, 0, 0, + -0.9135, 0.0873, -0.0571, -0.0209 }; double tmpk[6][8] = { - {0, 0, 1. / 2., -1. / 2., 0, 0, 0, 0}, - {0, 0, 1. / 2., +1. / 2., 0, 0, 0, 0}, - {0, 0, -1. / 14., +1. / 6., 0.0510, -0.1403, -0.0113, 0.0054}, - {0, 0, -1. / 14., -1. / 6., 0.0984, +0.1214, +0.0156, 0.0026}, - {0, 0, 0, 0, -0.0397, 0.0117, -0.0025, +0.0304}, - {0, 0, 0, 0, +0.0335, 0.0239, -0.0462, -0.0112}}; + { 0, 0, 1. / 2., -1. / 2., 0, 0, 0, 0 }, + { 0, 0, 1. / 2., +1. / 2., 0, 0, 0, 0 }, + { 0, 0, -1. / 14., +1. / 6., 0.0510, -0.1403, -0.0113, 0.0054 }, + { 0, 0, -1. / 14., -1. / 6., 0.0984, +0.1214, +0.0156, 0.0026 }, + { 0, 0, 0, 0, -0.0397, 0.0117, -0.0025, +0.0304 }, + { 0, 0, 0, 0, +0.0335, 0.0239, -0.0462, -0.0112 } }; double tmpr[2][8] = { - {0, 0, +0.8966, -0.1960, -0.2011, 0.1328, -0.0292, -0.1858}, - {0, 0, -0.1193, +0.1003, -0.0473, 0.2323, -0.0133, -0.1799}}; + { 0, 0, +0.8966, -0.1960, -0.2011, 0.1328, -0.0292, -0.1858 }, + { 0, 0, -0.1193, +0.1003, -0.0473, 0.2323, -0.0133, -0.1799 } }; for ( i = 0; i < 8; i++ ) { a[i] = tmpa[i]; h[i] = tmph[i]; p[i] = tmpp[i]; s[i] = tmps[i]; q[i] = tmpq[i]; g[i] = tmpg[i]; for ( j = 0; j < 6; j++ ) k[j][i] = tmpk[j][i]; for ( j = 0; j < 2; j++ ) r[j][i] = tmpr[j][i]; } m_n_f = 5; m_Lambda = 0.2167; m_alphaMZ = 0.1187; m_mu = 4.8; m_M_Z = 91.1876; m_M_t = 174.3; m_M_W = 80.425; m_alphaS = 0; m_eta = 0; m_sin2W = 0.23120; m_ialpha = 137.036; m_C1 = m_C2 = m_C3 = m_C4 = m_C5 = m_C6 = m_C7 = m_C7eff0 = m_C8 = m_C8eff0 = m_C9 = m_C9tilda = m_C10 = m_C10tilda = m_P0 = 0; m_A = m_B = m_C = m_D = m_E = m_F = m_Y = m_Z = m_PE = 0; m_ksi = 0; } void EvtWilsonCoefficients::SetRenormalizationScheme( std::string scheme ) { if ( scheme == "NDR" ) m_ksi = 0; else if ( scheme == "HV" ) m_ksi = 1; else { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "ERROR: EvtWilsonCoefficients knows only NDR and HV schemes !" << std::endl; ::abort(); } } double EvtWilsonCoefficients::alphaS( double mu = 4.8, int n_f = 5, double Lambda = 0.2167 ) { // calculate strong coupling constant for n_f flavours and scale mu double beta0 = 11. - 2. / 3. * n_f; double beta1 = 51. - 19. / 3. * n_f; double beta2 = 2857. - 5033. / 9. * n_f + 325. / 27. * n_f * n_f; double lnratio = log( mu * mu / Lambda / Lambda ); double aS = 4. * EvtConst::pi / beta0 / lnratio * ( 1. - 2 * beta1 / beta0 / beta0 * log( lnratio ) / lnratio + 4 * beta1 * beta1 / beta0 / beta0 / beta0 / beta0 / lnratio / lnratio * ( ( log( lnratio ) - 0.5 ) * ( log( lnratio ) - 0.5 ) + beta2 * beta0 / 8 / beta1 / beta1 - 5. / 4. ) ); return aS; } double EvtWilsonCoefficients::Lambda( double alpha = 0.1187, int n_f = 5, double mu = 91.1876, double epsilon = 0.00005, int maxstep = 1000 ) { // calculate Lambda matching alphaS using simple iterative method int i; double difference = 0; double Lambda = mu * 0.9999999999; double step = -mu / 20; for ( i = 0; i < maxstep && ( difference = fabs( alphaS( mu, n_f, Lambda ) - alpha ) ) >= epsilon; i++ ) { EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " Difference of alpha_S from " << alpha << " is " << difference << " at Lambda = " << Lambda << std::endl; if ( alphaS( mu, n_f, Lambda ) > alpha ) { if ( step > 0 ) step *= -0.4; if ( alphaS( mu, n_f, Lambda + step - epsilon ) < alphaS( mu, n_f, Lambda + step ) ) Lambda += step; else step *= 0.4; } else { if ( step < 0 ) step *= -0.4; if ( Lambda + step < mu ) Lambda += step; else step *= 0.4; } } EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " Difference of alpha_S from " << alpha << " is " << difference << " at Lambda = " << Lambda << std::endl; if ( difference >= epsilon ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " ERROR: Did not converge Lambda for alpha_s = " << alpha << " , difference " << difference << " >= " << epsilon << " after " << i << " steps !" << std::endl; ::abort(); return -1; } else { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " For alpha_s = " << alphaS( mu, n_f, Lambda ) << " was found Lambda = " << Lambda << std::endl; return Lambda; } } double EvtWilsonCoefficients::eta( double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double M_W = 80.425 ) { return alphaS( M_W, n_f, Lambda ) / alphaS( mu, n_f, Lambda ); } EvtComplex EvtWilsonCoefficients::C1( double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double M_W = 80.425 ) { int i; EvtComplex myC1( 0, 0 ); for ( i = 0; i < 8; i++ ) myC1 += k[0][i] * pow( eta( mu, n_f, Lambda, M_W ), a[i] ); return myC1; } EvtComplex EvtWilsonCoefficients::C2( double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double M_W = 80.425 ) { int i; EvtComplex myC2( 0, 0 ); for ( i = 0; i < 8; i++ ) myC2 += k[1][i] * pow( eta( mu, n_f, Lambda, M_W ), a[i] ); return myC2; } EvtComplex EvtWilsonCoefficients::C3( double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double M_W = 80.425 ) { int i; EvtComplex myC3( 0, 0 ); for ( i = 0; i < 8; i++ ) myC3 += k[2][i] * pow( eta( mu, n_f, Lambda, M_W ), a[i] ); return myC3; } EvtComplex EvtWilsonCoefficients::C4( double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double M_W = 80.425 ) { int i; EvtComplex myC4( 0, 0 ); for ( i = 0; i < 8; i++ ) myC4 += k[3][i] * pow( eta( mu, n_f, Lambda, M_W ), a[i] ); return myC4; } EvtComplex EvtWilsonCoefficients::C5( double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double M_W = 80.425 ) { int i; EvtComplex myC5( 0, 0 ); for ( i = 0; i < 8; i++ ) myC5 += k[4][i] * pow( eta( mu, n_f, Lambda, M_W ), a[i] ); return myC5; } EvtComplex EvtWilsonCoefficients::C6( double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double M_W = 80.425 ) { int i; EvtComplex myC6( 0, 0 ); for ( i = 0; i < 8; i++ ) myC6 += k[5][i] * pow( eta( mu, n_f, Lambda, M_W ), a[i] ); return myC6; } EvtComplex EvtWilsonCoefficients::C7( double M_t = 174.3, double M_W = 80.425 ) { return EvtComplex( -0.5 * A( M_t * M_t / M_W / M_W ), 0 ); } EvtComplex EvtWilsonCoefficients::C8( double M_t = 174.3, double M_W = 80.425 ) { return EvtComplex( -0.5 * F( M_t * M_t / M_W / M_W ), 0 ); } EvtComplex EvtWilsonCoefficients::C7eff0( double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double M_t = 174.3, double M_W = 80.425 ) { int i; EvtComplex myC7eff( 0, 0 ); for ( i = 0; i < 8; i++ ) myC7eff += h[i] * pow( eta( mu, n_f, Lambda, M_W ), a[i] ); myC7eff *= C2( mu, n_f, Lambda, M_W ); myC7eff += pow( eta( mu, n_f, Lambda, M_W ), 16. / 23. ) * C7( M_t, M_W ); myC7eff += 8. / 3. * ( pow( eta( mu, n_f, Lambda, M_W ), 14. / 23. ) - pow( eta( mu, n_f, Lambda, M_W ), 16. / 23. ) ) * C8( M_t, M_W ); return myC7eff; } EvtComplex EvtWilsonCoefficients::C8eff0( double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double M_t = 174.3, double M_W = 80.425 ) { int i; EvtComplex myC8eff( 0, 0 ); for ( i = 0; i < 8; i++ ) myC8eff += g[i] * pow( eta( mu, n_f, Lambda, M_W ), a[i] ); myC8eff += pow( eta( mu, n_f, Lambda, M_W ), 14. / 23. ) * C8( M_t, M_W ); return myC8eff; } EvtComplex EvtWilsonCoefficients::C10tilda( double sin2W = 0.23120, double M_t = 174.3, double M_W = 80.425 ) { return EvtComplex( -Y( M_t * M_t / M_W / M_W ) / sin2W, 0 ); } EvtComplex EvtWilsonCoefficients::C10( double sin2W = 0.23120, double M_t = 174.3, double M_W = 80.425, double ialpha = 137.036 ) { return ( 1. / 2 / EvtConst::pi / ialpha * C10tilda( sin2W, M_t, M_W ) ); } double EvtWilsonCoefficients::A( double x ) { return ( x * ( 8 * x * x + 5 * x - 7 ) / 12 / pow( x - 1, 3 ) + x * x * ( 2 - 3 * x ) * log( x ) / 2 / pow( x - 1, 4 ) ); } double EvtWilsonCoefficients::B( double x ) { return ( x / 4 / ( 1 - x ) + x / 4 / ( x - 1 ) / ( x - 1 ) * log( x ) ); } double EvtWilsonCoefficients::C( double x ) { return ( x * ( x - 6 ) / 8 / ( x - 1 ) + x * ( 3 * x + 2 ) / 8 / ( x - 1 ) / ( x - 1 ) * log( x ) ); } double EvtWilsonCoefficients::D( double x ) { return ( ( -19 * x * x * x + 25 * x * x ) / 36 / pow( x - 1, 3 ) + x * x * ( 5 * x * x - 2 * x - 6 ) / 18 / pow( x - 1, 4 ) * log( x ) - 4. / 9 * log( x ) ); } double EvtWilsonCoefficients::E( double x ) { return ( x * ( 18 - 11 * x - x * x ) / 12 / pow( 1 - x, 3 ) + x * x * ( 15 - 16 * x + 4 * x * x ) / 6 / pow( 1 - x, 4 ) * log( x ) - 2. / 3 * log( x ) ); } double EvtWilsonCoefficients::F( double x ) { return ( x * ( x * x - 5 * x - 2 ) / 4 / pow( x - 1, 3 ) + 3 * x * x / 2 / pow( x - 1, 4 ) * log( x ) ); } double EvtWilsonCoefficients::Y( double x ) { return ( C( x ) - B( x ) ); } double EvtWilsonCoefficients::Z( double x ) { return ( C( x ) + 1. / 4 * D( x ) ); } EvtComplex EvtWilsonCoefficients::C9( int ksi = 0, double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double sin2W = 0.23120, double M_t = 174.3, double M_W = 80.425, double ialpha = 137.036 ) { return ( 1. / 2 / EvtConst::pi / ialpha * C9tilda( ksi, mu, n_f, Lambda, sin2W, M_t, M_W ) ); } EvtComplex EvtWilsonCoefficients::C9tilda( int ksi = 0, double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double sin2W = 0.23120, double M_t = 174.3, double M_W = 80.425 ) { return ( P0( ksi, mu, n_f, Lambda, M_W ) + Y( M_t * M_t / M_W / M_W ) / sin2W - 4 * Z( M_t * M_t / M_W / M_W ) + PE( mu, n_f, Lambda, M_W ) * E( M_t * M_t / M_W / M_W ) ); } EvtComplex EvtWilsonCoefficients::P0( int ksi = 0, double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double M_W = 80.425 ) { int i; EvtComplex myP0( 0, 0 ); for ( i = 0; i < 8; i++ ) myP0 += p[i] * pow( eta( mu, n_f, Lambda, M_W ), a[i] + 1 ); myP0 = EvtConst::pi / alphaS( M_W, n_f, Lambda ) * ( -0.1875 + myP0 ); myP0 += 1.2468 - ksi * 4. / 9. * ( 3 * C1( mu, n_f, Lambda, M_W ) + C2( mu, n_f, Lambda, M_W ) - C3( mu, n_f, Lambda, M_W ) - 3 * C4( mu, n_f, Lambda, M_W ) ); for ( i = 0; i < 8; i++ ) myP0 += pow( eta( mu, n_f, Lambda, M_W ), a[i] ) * ( r[ksi][i] + s[i] * eta( mu, n_f, Lambda, M_W ) ); return myP0; } double EvtWilsonCoefficients::PE( double mu = 4.8, int n_f = 5, double Lambda = 0.2167, double M_W = 80.425 ) { int i; double myPE = 0.1405; for ( i = 0; i < 8; i++ ) myPE += q[i] * pow( eta( mu, n_f, Lambda, M_W ), a[i] + 1 ); return myPE; } void EvtWilsonCoefficients::CalculateAllCoefficients() { m_Lambda = Lambda( m_alphaMZ, m_n_f, m_M_Z ); m_C1 = C1( m_mu, m_n_f, m_Lambda, m_M_W ); m_C2 = C2( m_mu, m_n_f, m_Lambda, m_M_W ); m_C3 = C3( m_mu, m_n_f, m_Lambda, m_M_W ); m_C4 = C4( m_mu, m_n_f, m_Lambda, m_M_W ); m_C5 = C5( m_mu, m_n_f, m_Lambda, m_M_W ); m_C6 = C6( m_mu, m_n_f, m_Lambda, m_M_W ); m_C7 = C7( m_M_t, m_M_W ); m_C8 = C8( m_M_t, m_M_W ); m_C7eff0 = C7eff0( m_mu, m_n_f, m_Lambda, m_M_t, m_M_W ); m_C8eff0 = C8eff0( m_mu, m_n_f, m_Lambda, m_M_t, m_M_W ); m_C10tilda = C10tilda( m_sin2W, m_M_t, m_M_W ); m_C10 = C10( m_sin2W, m_M_t, m_M_W, m_ialpha ); m_A = A( m_M_t * m_M_t / m_M_W / m_M_W ); m_B = B( m_M_t * m_M_t / m_M_W / m_M_W ); m_C = C( m_M_t * m_M_t / m_M_W / m_M_W ); m_D = D( m_M_t * m_M_t / m_M_W / m_M_W ); m_E = E( m_M_t * m_M_t / m_M_W / m_M_W ); m_F = F( m_M_t * m_M_t / m_M_W / m_M_W ); m_Y = Y( m_M_t * m_M_t / m_M_W / m_M_W ); m_Z = Z( m_M_t * m_M_t / m_M_W / m_M_W ); m_C9 = C9( m_ksi, m_mu, m_n_f, m_Lambda, m_sin2W, m_M_t, m_M_W, m_ialpha ); m_C9tilda = C9tilda( m_ksi, m_mu, m_n_f, m_Lambda, m_sin2W, m_M_t, m_M_W ); m_P0 = P0( m_ksi, m_mu, m_n_f, m_Lambda, m_M_W ); m_PE = PE( m_mu, m_n_f, m_Lambda, m_M_W ); m_alphaS = alphaS( m_mu, m_n_f, m_Lambda ); m_eta = eta( m_mu, m_n_f, m_Lambda, m_M_W ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " +---------------------------------------" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | Table of Wilson coeficients:" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " +---------------------------------------" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | C1 = " << m_C1 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | C2 = " << m_C2 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | C3 = " << m_C3 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | C4 = " << m_C4 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | C5 = " << m_C5 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | C6 = " << m_C6 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | C7 = " << m_C7 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | C7eff0 = " << m_C7eff0 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | C8 = " << m_C8 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | C8eff0 = " << m_C8eff0 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | C9 = " << m_C9 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | C10 = " << m_C10 << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " +---------------------------------------" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | Other constants:" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " +---------------------------------------" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | Scale = " << m_mu << " GeV" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | Number of effective flavors = " << m_n_f << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | Corresponding to aS(M_Z)" << "=" << m_alphaMZ << " Lambda = " << m_Lambda << " GeV" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | Strong coupling constant = " << m_alphaS << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | Electromagnetic constant = 1/" << m_ialpha << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | Top mass = " << m_M_t << " GeV" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | W-boson mass = " << m_M_W << " GeV" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | Z-boson mass = " << m_M_Z << " GeV" << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " | Sinus squared of Weinberg angle = " << m_sin2W << std::endl; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " +---------------------------------------" << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | Intermediate functions:" << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " +---------------------------------------" << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | A = " << m_A << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | B = " << m_B << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | C = " << m_C << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | D = " << m_D << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | E = " << m_E << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | F = " << m_F << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | Y = " << m_Y << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | Z = " << m_Z << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | eta = " << m_eta << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | C9~ = " << m_C9tilda << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | C10~ = " << m_C10tilda << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | P0 = " << m_P0 << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " | PE = " << m_PE << std::endl; EvtGenReport( EVTGEN_DEBUG, "EvtGen" ) << " +--------------------------------------" << std::endl; } EvtComplex EvtWilsonCoefficients::hzs( double z, double shat, double mu = 4.8, double M_b = 4.8 ) { EvtComplex i1( 0, 1 ); double x = 4. * z * z / shat; if ( x == 0 ) return ( 8. / 27. - 8. / 9. * log( M_b / mu ) - 4. / 9. * log( shat ) + 4. / 9. * i1 * EvtConst::pi ); else if ( x > 1 ) return ( 8. / 27. - 8. / 9. * log( M_b / mu ) - 8. / 9. * log( z ) + 4. / 9. * x - 2. / 9. * ( 2. + x ) * sqrt( x - 1. ) * 2 * atan( 1. / sqrt( x - 1. ) ) ); else return ( 8. / 27. - 8. / 9. * log( M_b / mu ) - 8. / 9. * log( z ) + 4. / 9. * x - 2. / 9. * ( 2. + x ) * sqrt( 1. - x ) * ( log( fabs( sqrt( 1. - x ) + 1 ) / fabs( sqrt( 1. - x ) - 1 ) ) - i1 * EvtConst::pi ) ); } double EvtWilsonCoefficients::fz( double z ) { return ( 1. - 8. * z * z + 8. * pow( z, 6. ) - pow( z, 8. ) - 24. * pow( z, 4. ) * log( z ) ); } double EvtWilsonCoefficients::kappa( double z, double alpha_S ) { return ( 1. - 2. * alpha_S / 3. / EvtConst::pi * ( ( EvtConst::pi * EvtConst::pi - 31. / 4. ) * ( 1. - z ) * ( 1. - z ) + 1.5 ) ); } double EvtWilsonCoefficients::etatilda( double shat, double alpha_S ) { return ( 1. + alpha_S / EvtConst::pi * omega( shat ) ); } double EvtWilsonCoefficients::omega( double shat ) { double o = 0; o -= ( 2. / 9. ) * EvtConst::pi * EvtConst::pi; o -= ( 4. / 3. ) * li2spence( shat ); o -= ( 2. / 3. ) * log( shat ) * log( 1. - shat ); o -= log( 1. - shat ) * ( 5. + 4. * shat ) / ( 3. + 6. * shat ); o -= log( shat ) * 2. * shat * ( 1. + shat ) * ( 1. - 2. * shat ) / 3. / ( 1. - shat ) / ( 1. - shat ) / ( 1. + 2. * shat ); o += ( 5. + 9. * shat - 6. * shat * shat ) / 6. / ( 1. - shat ) / ( 1. + 2. * shat ); return o; } EvtComplex EvtWilsonCoefficients::C9efftilda( double z, double shat, double alpha_S, EvtComplex c1, EvtComplex c2, EvtComplex c3, EvtComplex c4, EvtComplex c5, EvtComplex c6, EvtComplex c9tilda, int ksi = 0 ) { EvtComplex c( 0, 0 ); c += ( c9tilda + ksi * 4. / 9. * ( 3. * c1 + c2 - c3 - 3. * c4 ) ) * etatilda( shat, alpha_S ); c += hzs( z, shat ) * ( 3. * c1 + c2 + 3. * c3 + c4 + 3. * c5 + c6 ); c -= 0.5 * hzs( 1, shat ) * ( 4. * c3 + 4. * c4 + 3. * c5 + c6 ); c -= 0.5 * hzs( 0, shat ) * ( c3 + 3. * c4 ); c += 2. / 9. * ( 3. * c3 + c4 + 3. * c5 + c6 ); return c; } EvtComplex EvtWilsonCoefficients::C7b2sg( double alpha_S, double et, EvtComplex c2, double M_t = 174.3, double M_W = 80.425 ) { EvtComplex i1( 0, 1 ); return ( i1 * alpha_S * ( 2. / 9. * pow( et, 14. / 23. ) * ( 0.5 * F( M_t * M_t / M_W / M_W ) - 0.1687 ) - 0.03 * c2 ) ); } EvtComplex EvtWilsonCoefficients::Yld( double q2, double* ki, double* Gi, double* Mi, int ni, EvtComplex c1, EvtComplex c2, EvtComplex c3, EvtComplex c4, EvtComplex c5, EvtComplex c6, double ialpha = 137.036 ) { EvtComplex i1( 0, 1 ); EvtComplex y( 0, 0 ); int i; for ( i = 0; i < ni; i++ ) y += ki[i] * Gi[i] * Mi[i] / ( q2 - Mi[i] * Mi[i] - i1 * Mi[i] * Gi[i] ); return ( -3. * ialpha * ialpha * y * EvtConst::pi * ( 3. * c1 + c2 + 3. * c3 + c4 + 3. * c5 + c6 ) ); } diff --git a/src/EvtGenModels/EvtbTosllAli.cpp b/src/EvtGenModels/EvtbTosllAli.cpp index 04971af..73d25f1 100644 --- a/src/EvtGenModels/EvtbTosllAli.cpp +++ b/src/EvtGenModels/EvtbTosllAli.cpp @@ -1,105 +1,105 @@ /*********************************************************************** * 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/EvtbTosllAli.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenModels/EvtbTosllAliFF.hh" #include "EvtGenModels/EvtbTosllAmp.hh" #include "EvtGenModels/EvtbTosllScalarAmp.hh" #include "EvtGenModels/EvtbTosllVectorAmp.hh" #include #include using std::endl; std::string EvtbTosllAli::getName() { return "BTOSLLALI"; } EvtDecayBase* EvtbTosllAli::clone() { return new EvtbTosllAli; } void EvtbTosllAli::decay( EvtParticle* p ) { setWeight( p->initializePhaseSpace( getNDaug(), getDaugs(), false, _poleSize, 1, 2 ) ); _calcamp->CalcAmp( p, _amp2, _aliffmodel.get() ); } void EvtbTosllAli::initProbMax() { EvtId parnum, mesnum, l1num, l2num; parnum = getParentId(); mesnum = getDaug( 0 ); l1num = getDaug( 1 ); l2num = getDaug( 2 ); //This routine sets the _poleSize. double mymaxprob = _calcamp->CalcMaxProb( parnum, mesnum, l1num, l2num, _aliffmodel.get(), _poleSize ); - mymaxprob *= 1.25; // Increase to avoid maxprob errors + mymaxprob *= 1.25; // Increase to avoid maxprob errors setProbMax( mymaxprob ); } void EvtbTosllAli::init() { checkNArg( 0 ); checkNDaug( 3 ); //We expect the parent to be a scalar //and the daughters to be X lepton+ lepton- checkSpinParent( EvtSpinType::SCALAR ); EvtSpinType::spintype mesontype = EvtPDL::getSpinType( getDaug( 0 ) ); if ( !( mesontype == EvtSpinType::VECTOR || mesontype == EvtSpinType::SCALAR ) ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "EvtbTosllAli generator expected " << " a SCALAR or VECTOR 1st daughter, found:" << EvtPDL::name( getDaug( 0 ) ).c_str() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate execution!" << endl; ::abort(); } checkSpinDaughter( 1, EvtSpinType::DIRAC ); checkSpinDaughter( 2, EvtSpinType::DIRAC ); _aliffmodel = std::make_unique(); if ( mesontype == EvtSpinType::SCALAR ) { _calcamp = std::make_unique(); } if ( mesontype == EvtSpinType::VECTOR ) { _calcamp = std::make_unique(); } } diff --git a/src/EvtGenModels/EvtbTosllMSFF.cpp b/src/EvtGenModels/EvtbTosllMSFF.cpp index c81e4b8..352c3c2 100644 --- a/src/EvtGenModels/EvtbTosllMSFF.cpp +++ b/src/EvtGenModels/EvtbTosllMSFF.cpp @@ -1,655 +1,655 @@ /*********************************************************************** * 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/EvtbTosllMSFF.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include #include EvtbTosllMSFF::EvtbTosllMSFF() { } double EvtbTosllMSFF::equation9_10( double ff0, double M2, double q2, double sigma1, double sigma2, int eq_num ) { double ff = 1.0; switch ( eq_num ) { case 9: ff = 1. / ( 1. - q2 / M2 ); [[fallthrough]]; case 10: ff = ff * ff0 / ( 1. - sigma1 * q2 / M2 + sigma2 * pow( q2, 2 ) / pow( M2, 2 ) ); break; default: EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "In the function EvtbTosllMSFF::equation9_10 \n" << "the parameter eq_num non equal to the 9 or 10! \n" << "eq_num =" << eq_num << std::endl; ::abort(); } return ff; } void EvtbTosllMSFF::getScalarFF( EvtId parent, EvtId daught, double t, double& fp, double& f0, double& ft ) { int models_counter = 0; // counter of the accepted models // B -> K transition form factors if ( ( parent == EvtPDL::getId( std::string( "B+" ) ) && daught == EvtPDL::getId( std::string( "K+" ) ) ) || ( parent == EvtPDL::getId( std::string( "B-" ) ) && daught == EvtPDL::getId( std::string( "K-" ) ) ) || ( parent == EvtPDL::getId( std::string( "B0" ) ) && daught == EvtPDL::getId( std::string( "K0" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B0" ) ) && daught == EvtPDL::getId( std::string( "anti-K0" ) ) ) || ( parent == EvtPDL::getId( std::string( "B0" ) ) && daught == EvtPDL::getId( std::string( "K_S0" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B0" ) ) && daught == EvtPDL::getId( std::string( "K_S0" ) ) ) || ( parent == EvtPDL::getId( std::string( "B0" ) ) && daught == EvtPDL::getId( std::string( "K_L0" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B0" ) ) && daught == EvtPDL::getId( std::string( "K_L0" ) ) ) ) { - double ff0[] = {0.36, 0.36, 0.35}; - double sigma1[] = {0.43, 0.70, 0.43}; - double sigma2[] = {0.00, 0.27, 0.00}; - int eq_num[] = {9, 10, 9}; + double ff0[] = { 0.36, 0.36, 0.35 }; + double sigma1[] = { 0.43, 0.70, 0.43 }; + double sigma2[] = { 0.00, 0.27, 0.00 }; + int eq_num[] = { 9, 10, 9 }; double M_P2 = 5.37 * 5.37; // GeV^2 for B^0_s - meson double M_V2 = 5.42 * 5.42; // GeV^2 for B^*_s - meson fp = equation9_10( ff0[0], M_P2, t, sigma1[0], sigma2[0], eq_num[0] ); f0 = equation9_10( ff0[1], M_V2, t, sigma1[1], sigma2[1], eq_num[1] ); ft = equation9_10( ff0[2], M_P2, t, sigma1[2], sigma2[2], eq_num[2] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n B -> K transition form factors" // << std::endl; } // B -> \pi transition form factors if ( ( parent == EvtPDL::getId( std::string( "B+" ) ) && daught == EvtPDL::getId( std::string( "pi+" ) ) ) || ( parent == EvtPDL::getId( std::string( "B-" ) ) && daught == EvtPDL::getId( std::string( "pi-" ) ) ) || ( parent == EvtPDL::getId( std::string( "B0" ) ) && daught == EvtPDL::getId( std::string( "pi0" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B0" ) ) && daught == EvtPDL::getId( std::string( "pi0" ) ) ) ) { - double ff0[] = {0.29, 0.29, 0.28}; - double sigma1[] = {0.48, 0.76, 0.48}; - double sigma2[] = {0.00, 0.28, 0.00}; - int eq_num[] = {9, 10, 9}; + double ff0[] = { 0.29, 0.29, 0.28 }; + double sigma1[] = { 0.48, 0.76, 0.48 }; + double sigma2[] = { 0.00, 0.28, 0.00 }; + int eq_num[] = { 9, 10, 9 }; double M_P2 = 5.27 * 5.27; // GeV^2 for B^0 - meson double M_V2 = 5.32 * 5.32; // GeV^2 for B^* - meson fp = equation9_10( ff0[0], M_P2, t, sigma1[0], sigma2[0], eq_num[0] ); f0 = equation9_10( ff0[1], M_V2, t, sigma1[1], sigma2[1], eq_num[1] ); ft = equation9_10( ff0[2], M_P2, t, sigma1[2], sigma2[2], eq_num[2] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n B -> pi transition form factors" // << std::endl; } // B_d -> \eta transition form factors if ( ( parent == EvtPDL::getId( std::string( "B0" ) ) && daught == EvtPDL::getId( std::string( "eta" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B0" ) ) && daught == EvtPDL::getId( std::string( "eta" ) ) ) ) { - double ff0[] = {0.36, 0.36, 0.36}; - double sigma1[] = {0.60, 0.80, 0.58}; - double sigma2[] = {0.20, 0.40, 0.18}; - int eq_num[] = {9, 10, 9}; + double ff0[] = { 0.36, 0.36, 0.36 }; + double sigma1[] = { 0.60, 0.80, 0.58 }; + double sigma2[] = { 0.20, 0.40, 0.18 }; + int eq_num[] = { 9, 10, 9 }; double M_P2 = 5.27 * 5.27; // GeV^2 for B_d^0 - meson double M_V2 = 5.32 * 5.32; // GeV^2 for B_d^* - meson fp = equation9_10( ff0[0], M_P2, t, sigma1[0], sigma2[0], eq_num[0] ); fp = -0.5 * fp; f0 = equation9_10( ff0[1], M_V2, t, sigma1[1], sigma2[1], eq_num[1] ); f0 = -0.5 * f0; ft = equation9_10( ff0[2], M_P2, t, sigma1[2], sigma2[2], eq_num[2] ); ft = -0.5 * ft; models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n Bd -> eta transition form factors" // << std::endl; } // B_d -> \eta' transition form factors if ( ( parent == EvtPDL::getId( std::string( "B0" ) ) && daught == EvtPDL::getId( std::string( "eta'" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B0" ) ) && daught == EvtPDL::getId( std::string( "eta'" ) ) ) ) { - double ff0[] = {0.36, 0.36, 0.39}; - double sigma1[] = {0.60, 0.80, 0.58}; - double sigma2[] = {0.20, 0.45, 0.18}; - int eq_num[] = {9, 10, 9}; + double ff0[] = { 0.36, 0.36, 0.39 }; + double sigma1[] = { 0.60, 0.80, 0.58 }; + double sigma2[] = { 0.20, 0.45, 0.18 }; + int eq_num[] = { 9, 10, 9 }; double M_P2 = 5.27 * 5.27; // GeV^2 for B_d^0 - meson double M_V2 = 5.32 * 5.32; // GeV^2 for B_d^* - meson fp = equation9_10( ff0[0], M_P2, t, sigma1[0], sigma2[0], eq_num[0] ); f0 = equation9_10( ff0[1], M_V2, t, sigma1[1], sigma2[1], eq_num[1] ); ft = equation9_10( ff0[2], M_P2, t, sigma1[2], sigma2[2], eq_num[2] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n Bd -> eta transition form factors" // << std::endl; } // B_s -> \eta transition form factors if ( ( parent == EvtPDL::getId( std::string( "B_s0" ) ) && daught == EvtPDL::getId( std::string( "eta" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && daught == EvtPDL::getId( std::string( "eta" ) ) ) ) { - double ff0[] = {0.36, 0.36, 0.36}; - double sigma1[] = {0.60, 0.80, 0.58}; - double sigma2[] = {0.20, 0.40, 0.18}; - int eq_num[] = {9, 10, 9}; + double ff0[] = { 0.36, 0.36, 0.36 }; + double sigma1[] = { 0.60, 0.80, 0.58 }; + double sigma2[] = { 0.20, 0.40, 0.18 }; + int eq_num[] = { 9, 10, 9 }; double M_P2 = 5.37 * 5.37; // GeV^2 for B_s^0 - meson double M_V2 = 5.42 * 5.42; // GeV^2 for B_s^* - meson fp = equation9_10( ff0[0], M_P2, t, sigma1[0], sigma2[0], eq_num[0] ); f0 = equation9_10( ff0[1], M_V2, t, sigma1[1], sigma2[1], eq_num[1] ); ft = equation9_10( ff0[2], M_P2, t, sigma1[2], sigma2[2], eq_num[2] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n Bs -> eta transition form factors" // << std::endl; } // B_s -> \eta' transition form factors if ( ( parent == EvtPDL::getId( std::string( "B_s0" ) ) && daught == EvtPDL::getId( std::string( "eta'" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && daught == EvtPDL::getId( std::string( "eta'" ) ) ) ) { - double ff0[] = {0.36, 0.36, 0.39}; - double sigma1[] = {0.60, 0.80, 0.58}; - double sigma2[] = {0.20, 0.45, 0.18}; - int eq_num[] = {9, 10, 9}; + double ff0[] = { 0.36, 0.36, 0.39 }; + double sigma1[] = { 0.60, 0.80, 0.58 }; + double sigma2[] = { 0.20, 0.45, 0.18 }; + int eq_num[] = { 9, 10, 9 }; double M_P2 = 5.37 * 5.37; // GeV^2 for B_s^0 - meson double M_V2 = 5.42 * 5.42; // GeV^2 for B_s^* - meson fp = equation9_10( ff0[0], M_P2, t, sigma1[0], sigma2[0], eq_num[0] ); f0 = equation9_10( ff0[1], M_V2, t, sigma1[1], sigma2[1], eq_num[1] ); ft = equation9_10( ff0[2], M_P2, t, sigma1[2], sigma2[2], eq_num[2] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n Bs -> eta transition form factors" // << std::endl; } // B_s -> f_0(980) transition form factors if ( ( parent == EvtPDL::getId( std::string( "B_s0" ) ) && daught == EvtPDL::getId( std::string( "f_0" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && daught == EvtPDL::getId( std::string( "f_0" ) ) ) ) { - double ff0[] = {0.238, 0.238, 0.308}; - double sigma1[] = {1.50, 0.53, 1.46}; - double sigma2[] = {0.58, -0.36, 0.58}; - int eq_num[] = {10, 10, 10}; + double ff0[] = { 0.238, 0.238, 0.308 }; + double sigma1[] = { 1.50, 0.53, 1.46 }; + double sigma2[] = { 0.58, -0.36, 0.58 }; + int eq_num[] = { 10, 10, 10 }; double M_P2 = 5.366 * 5.366; // GeV^2 for B_s^0 - meson fp = 0.0 - equation9_10( ff0[0], M_P2, t, sigma1[0], sigma2[0], eq_num[0] ); f0 = 0.0 - equation9_10( ff0[1], M_P2, t, sigma1[1], sigma2[1], eq_num[1] ); ft = equation9_10( ff0[2], M_P2, t, sigma1[2], sigma2[2], eq_num[2] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n Bs -> eta transition form factors" // << std::endl; } // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << "\n models_counter = " << models_counter // << "\n Scalar form-factors at q^2 = " << t // << " for B -> P transition:" // << "\n fp = " << fp // << "\n f0 = " << f0 // << "\n ft = " << ft << std::endl; if ( models_counter != 1 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n In the function EvtbTosllMSFF::getScalarFF(...) \n" << "the parameter models_counter not equal 1! \n" << "models_counter = " << models_counter << std::endl; ::abort(); } } void EvtbTosllMSFF::getVectorFF( EvtId parent, EvtId daught, double t, double& a1, double& a2, double& a0, double& v, double& t1, double& t2, double& t3 ) { int models_counter = 0; // counter of the accepted models double thetaK = -34.0 * 3.14159 / 180; // K_1(1270) - K_1(1400) mixing angle // \bar B -> \bar K* transition form factors if ( ( parent == EvtPDL::getId( std::string( "B+" ) ) && daught == EvtPDL::getId( std::string( "K*+" ) ) ) || ( parent == EvtPDL::getId( std::string( "B-" ) ) && daught == EvtPDL::getId( std::string( "K*-" ) ) ) || ( parent == EvtPDL::getId( std::string( "B0" ) ) && daught == EvtPDL::getId( std::string( "K*0" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B0" ) ) && daught == EvtPDL::getId( std::string( "anti-K*0" ) ) ) ) { - double ff0[] = {0.44, 0.45, 0.36, 0.32, 0.39, 0.39, 0.27}; - double sigma1[] = {0.45, 0.46, 0.64, 1.23, 0.45, 0.72, 1.31}; - double sigma2[] = {0.00, 0.00, 0.36, 0.38, 0.00, 0.62, 0.41}; - int eq_num[] = {9, 9, 10, 10, 9, 10, 10}; + double ff0[] = { 0.44, 0.45, 0.36, 0.32, 0.39, 0.39, 0.27 }; + double sigma1[] = { 0.45, 0.46, 0.64, 1.23, 0.45, 0.72, 1.31 }; + double sigma2[] = { 0.00, 0.00, 0.36, 0.38, 0.00, 0.62, 0.41 }; + int eq_num[] = { 9, 9, 10, 10, 9, 10, 10 }; double M_P2 = 5.37 * 5.37; // GeV^2 for B^0_s - meson double M_V2 = 5.42 * 5.42; // GeV^2 for B^*_s - meson v = equation9_10( ff0[0], M_P2, t, sigma1[0], sigma2[0], eq_num[0] ); a0 = equation9_10( ff0[1], M_P2, t, sigma1[1], sigma2[1], eq_num[1] ); a1 = equation9_10( ff0[2], M_V2, t, sigma1[2], sigma2[2], eq_num[2] ); a2 = equation9_10( ff0[3], M_V2, t, sigma1[3], sigma2[3], eq_num[3] ); t1 = equation9_10( ff0[4], M_P2, t, sigma1[4], sigma2[4], eq_num[4] ); t2 = equation9_10( ff0[5], M_V2, t, sigma1[5], sigma2[5], eq_num[5] ); t3 = equation9_10( ff0[6], M_V2, t, sigma1[6], sigma2[6], eq_num[6] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n barB -> barK* transition form factors" // << std::endl; } // \bar B -> \bar\rho transition form factors if ( ( parent == EvtPDL::getId( std::string( "B+" ) ) && daught == EvtPDL::getId( std::string( "rho+" ) ) ) || ( parent == EvtPDL::getId( std::string( "B-" ) ) && daught == EvtPDL::getId( std::string( "rho-" ) ) ) || ( parent == EvtPDL::getId( std::string( "B0" ) ) && daught == EvtPDL::getId( std::string( "rho0" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B0" ) ) && daught == EvtPDL::getId( std::string( "rho0" ) ) ) ) { - double ff0[] = {0.31, 0.30, 0.26, 0.24, 0.27, 0.27, 0.19}; - double sigma1[] = {0.59, 0.54, 0.73, 1.40, 0.60, 0.74, 1.42}; - double sigma2[] = {0.00, 0.00, 0.10, 0.50, 0.00, 0.19, 0.51}; - int eq_num[] = {9, 9, 10, 10, 9, 10, 10}; + double ff0[] = { 0.31, 0.30, 0.26, 0.24, 0.27, 0.27, 0.19 }; + double sigma1[] = { 0.59, 0.54, 0.73, 1.40, 0.60, 0.74, 1.42 }; + double sigma2[] = { 0.00, 0.00, 0.10, 0.50, 0.00, 0.19, 0.51 }; + int eq_num[] = { 9, 9, 10, 10, 9, 10, 10 }; double M_P2 = 5.27 * 5.27; // GeV^2 for B - meson double M_V2 = 5.32 * 5.32; // GeV^2 for B^* - meson v = equation9_10( ff0[0], M_P2, t, sigma1[0], sigma2[0], eq_num[0] ); a0 = equation9_10( ff0[1], M_P2, t, sigma1[1], sigma2[1], eq_num[1] ); a1 = equation9_10( ff0[2], M_V2, t, sigma1[2], sigma2[2], eq_num[2] ); a2 = equation9_10( ff0[3], M_V2, t, sigma1[3], sigma2[3], eq_num[3] ); t1 = equation9_10( ff0[4], M_P2, t, sigma1[4], sigma2[4], eq_num[4] ); t2 = equation9_10( ff0[5], M_V2, t, sigma1[5], sigma2[5], eq_num[5] ); t3 = equation9_10( ff0[6], M_V2, t, sigma1[6], sigma2[6], eq_num[6] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n barB -> bar rho transition form factors" // << std::endl; } // \bar B -> \omega transition form factors (exactly as for \bar B -> \rho^0 ff!) if ( ( parent == EvtPDL::getId( std::string( "B0" ) ) && daught == EvtPDL::getId( std::string( "omega" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B0" ) ) && daught == EvtPDL::getId( std::string( "omega" ) ) ) ) { - double ff0[] = {0.31, 0.30, 0.26, 0.24, 0.27, 0.27, 0.19}; - double sigma1[] = {0.59, 0.54, 0.73, 1.40, 0.60, 0.74, 1.42}; - double sigma2[] = {0.00, 0.00, 0.10, 0.50, 0.00, 0.19, 0.51}; - int eq_num[] = {9, 9, 10, 10, 9, 10, 10}; + double ff0[] = { 0.31, 0.30, 0.26, 0.24, 0.27, 0.27, 0.19 }; + double sigma1[] = { 0.59, 0.54, 0.73, 1.40, 0.60, 0.74, 1.42 }; + double sigma2[] = { 0.00, 0.00, 0.10, 0.50, 0.00, 0.19, 0.51 }; + int eq_num[] = { 9, 9, 10, 10, 9, 10, 10 }; double M_P2 = 5.27 * 5.27; // GeV^2 for B - meson double M_V2 = 5.32 * 5.32; // GeV^2 for B^* - meson v = equation9_10( ff0[0], M_P2, t, sigma1[0], sigma2[0], eq_num[0] ); a0 = equation9_10( ff0[1], M_P2, t, sigma1[1], sigma2[1], eq_num[1] ); a1 = equation9_10( ff0[2], M_V2, t, sigma1[2], sigma2[2], eq_num[2] ); a2 = equation9_10( ff0[3], M_V2, t, sigma1[3], sigma2[3], eq_num[3] ); t1 = equation9_10( ff0[4], M_P2, t, sigma1[4], sigma2[4], eq_num[4] ); t2 = equation9_10( ff0[5], M_V2, t, sigma1[5], sigma2[5], eq_num[5] ); t3 = equation9_10( ff0[6], M_V2, t, sigma1[6], sigma2[6], eq_num[6] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n barB -> omega transition form factors" // << std::endl; } // \bar Bs -> phi transition form factors if ( ( parent == EvtPDL::getId( std::string( "B_s0" ) ) && daught == EvtPDL::getId( std::string( "phi" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && daught == EvtPDL::getId( std::string( "phi" ) ) ) ) { - double ff0[] = {0.44, 0.42, 0.34, 0.31, 0.38, 0.38, 0.26}; - double sigma1[] = {0.62, 0.55, 0.73, 1.30, 0.62, 0.83, 1.41}; - double sigma2[] = {0.20, 0.12, 0.42, 0.52, 0.20, 0.71, 0.57}; - int eq_num[] = {9, 9, 10, 10, 9, 10, 10}; + double ff0[] = { 0.44, 0.42, 0.34, 0.31, 0.38, 0.38, 0.26 }; + double sigma1[] = { 0.62, 0.55, 0.73, 1.30, 0.62, 0.83, 1.41 }; + double sigma2[] = { 0.20, 0.12, 0.42, 0.52, 0.20, 0.71, 0.57 }; + int eq_num[] = { 9, 9, 10, 10, 9, 10, 10 }; double M_P2 = 5.37 * 5.37; // GeV^2 for B^0_s - meson double M_V2 = 5.42 * 5.42; // GeV^2 for B^*_s - meson v = equation9_10( ff0[0], M_P2, t, sigma1[0], sigma2[0], eq_num[0] ); a0 = equation9_10( ff0[1], M_P2, t, sigma1[1], sigma2[1], eq_num[1] ); a1 = equation9_10( ff0[2], M_V2, t, sigma1[2], sigma2[2], eq_num[2] ); a2 = equation9_10( ff0[3], M_V2, t, sigma1[3], sigma2[3], eq_num[3] ); t1 = equation9_10( ff0[4], M_P2, t, sigma1[4], sigma2[4], eq_num[4] ); t2 = equation9_10( ff0[5], M_V2, t, sigma1[5], sigma2[5], eq_num[5] ); t3 = equation9_10( ff0[6], M_V2, t, sigma1[6], sigma2[6], eq_num[6] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n barBs -> phi transition form factors" // << std::endl; } // \bar Bs -> K* (without \bar !) transition form factors if ( ( parent == EvtPDL::getId( std::string( "B_s0" ) ) && daught == EvtPDL::getId( std::string( "anti-K*0" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B_s0" ) ) && daught == EvtPDL::getId( std::string( "K*0" ) ) ) ) { - double ff0[] = {0.38, 0.37, 0.29, 0.26, 0.32, 0.32, 0.23}; - double sigma1[] = {0.66, 0.60, 0.86, 1.32, 0.66, 0.98, 1.42}; - double sigma2[] = {0.30, 0.16, 0.60, 0.54, 0.31, 0.90, 0.62}; - int eq_num[] = {9, 9, 10, 10, 9, 10, 10}; + double ff0[] = { 0.38, 0.37, 0.29, 0.26, 0.32, 0.32, 0.23 }; + double sigma1[] = { 0.66, 0.60, 0.86, 1.32, 0.66, 0.98, 1.42 }; + double sigma2[] = { 0.30, 0.16, 0.60, 0.54, 0.31, 0.90, 0.62 }; + int eq_num[] = { 9, 9, 10, 10, 9, 10, 10 }; double M_P2 = 5.27 * 5.27; // GeV^2 for B - meson double M_V2 = 5.32 * 5.32; // GeV^2 for B^* - meson v = equation9_10( ff0[0], M_P2, t, sigma1[0], sigma2[0], eq_num[0] ); a0 = equation9_10( ff0[1], M_P2, t, sigma1[1], sigma2[1], eq_num[1] ); a1 = equation9_10( ff0[2], M_V2, t, sigma1[2], sigma2[2], eq_num[2] ); a2 = equation9_10( ff0[3], M_V2, t, sigma1[3], sigma2[3], eq_num[3] ); t1 = equation9_10( ff0[4], M_P2, t, sigma1[4], sigma2[4], eq_num[4] ); t2 = equation9_10( ff0[5], M_V2, t, sigma1[5], sigma2[5], eq_num[5] ); t3 = equation9_10( ff0[6], M_V2, t, sigma1[6], sigma2[6], eq_num[6] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n barBs -> K* transition form factors" // << std::endl; } // \bar B -> \bar K_1(1270) transition form factors // See the paper: H.Hatanaka and Kwei-Chou Yang, PRD78, 074007 (2008) if ( ( parent == EvtPDL::getId( std::string( "B+" ) ) && daught == EvtPDL::getId( std::string( "K_1+" ) ) ) || ( parent == EvtPDL::getId( std::string( "B-" ) ) && daught == EvtPDL::getId( std::string( "K_1-" ) ) ) || ( parent == EvtPDL::getId( std::string( "B0" ) ) && daught == EvtPDL::getId( std::string( "K_10" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B0" ) ) && daught == EvtPDL::getId( std::string( "anti-K_10" ) ) ) ) { - double ff0A[] = {0.450, 0.340, 0.41, 0.22, 0.31, 0.310, 0.28}; - double sigma1A[] = {1.600, 0.635, 1.51, 2.40, 2.01, 0.629, 1.36}; - double sigma2A[] = {0.974, 0.211, 1.18, 1.78, 1.50, 0.387, 0.72}; - double ff0B[] = {-0.37, -0.29, -0.17, -0.45, -0.25, -0.250, -0.11}; - double sigma1B[] = {1.72, 0.729, 0.919, 1.34, 1.59, 0.378, -1.61}; - double sigma2B[] = {0.912, 0.074, 0.855, 0.69, 0.79, -0.755, 10.2}; - int eq_num[] = {10, 10, 10, 10, 10, 10, 10}; + double ff0A[] = { 0.450, 0.340, 0.41, 0.22, 0.31, 0.310, 0.28 }; + double sigma1A[] = { 1.600, 0.635, 1.51, 2.40, 2.01, 0.629, 1.36 }; + double sigma2A[] = { 0.974, 0.211, 1.18, 1.78, 1.50, 0.387, 0.72 }; + double ff0B[] = { -0.37, -0.29, -0.17, -0.45, -0.25, -0.250, -0.11 }; + double sigma1B[] = { 1.72, 0.729, 0.919, 1.34, 1.59, 0.378, -1.61 }; + double sigma2B[] = { 0.912, 0.074, 0.855, 0.69, 0.79, -0.755, 10.2 }; + int eq_num[] = { 10, 10, 10, 10, 10, 10, 10 }; double MM2 = 5.279 * 5.279; // GeV^2 double MB = 5.279; // GeV double MK1 = 1.272; // GeV double MK1A = 1.31; // GeV double MK1B = 1.34; // GeV double sinK = sin( thetaK ); // sin(-34^o) double cosK = cos( thetaK ); // cos(-34^o) double a, v0, v1, v2; a = sinK * equation9_10( ff0A[0], MM2, t, sigma1A[0], sigma2A[0], eq_num[0] ) * ( MB + MK1 ) / ( MB + MK1A ); a = a + cosK * equation9_10( ff0B[0], MM2, t, sigma1B[0], sigma2B[0], eq_num[0] ) * ( MB + MK1 ) / ( MB + MK1B ); v0 = sinK * equation9_10( ff0A[1], MM2, t, sigma1A[1], sigma2A[1], eq_num[1] ) * MK1A / MK1; v0 = v0 + cosK * equation9_10( ff0B[1], MM2, t, sigma1B[1], sigma2B[1], eq_num[1] ) * MK1B / MK1; v1 = sinK * equation9_10( ff0A[2], MM2, t, sigma1A[2], sigma2A[2], eq_num[2] ) * ( MB + MK1A ) / ( MB + MK1 ); v1 = v1 + cosK * equation9_10( ff0B[2], MM2, t, sigma1B[2], sigma2B[2], eq_num[2] ) * ( MB + MK1B ) / ( MB + MK1 ); v2 = sinK * equation9_10( ff0A[3], MM2, t, sigma1A[3], sigma2A[3], eq_num[3] ) * ( MB + MK1 ) / ( MB + MK1A ); v2 = v2 + cosK * equation9_10( ff0B[3], MM2, t, sigma1B[3], sigma2B[3], eq_num[3] ) * ( MB + MK1 ) / ( MB + MK1B ); v = a; a0 = v0; a1 = v1; a2 = v2; t1 = sinK * equation9_10( ff0A[4], MM2, t, sigma1A[4], sigma2A[4], eq_num[4] ); t1 = t1 + cosK * equation9_10( ff0B[4], MM2, t, sigma1B[4], sigma2B[4], eq_num[4] ); t2 = sinK * equation9_10( ff0A[5], MM2, t, sigma1A[5], sigma2A[5], eq_num[5] ) * ( MB * MB - MK1A * MK1A ) / ( MB * MB - MK1 * MK1 ); t2 = t2 + cosK * equation9_10( ff0B[5], MM2, t, sigma1B[5], sigma2B[5], eq_num[5] ) * ( MB * MB - MK1B * MK1B ) / ( MB * MB - MK1 * MK1 ); t3 = sinK * equation9_10( ff0A[6], MM2, t, sigma1A[6], sigma2A[6], eq_num[6] ); t3 = t3 + cosK * equation9_10( ff0B[6], MM2, t, sigma1B[6], sigma2B[6], eq_num[6] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n barB -> bar K_1(1270) transition form factors" // << std::endl; } // \bar B -> \bar K_1(1400) transition form factors // See the paper: H.Hatanaka and Kwei-Chou Yang, PRD78, 074007 (2008) if ( ( parent == EvtPDL::getId( std::string( "B+" ) ) && daught == EvtPDL::getId( std::string( "K'_1+" ) ) ) || ( parent == EvtPDL::getId( std::string( "B-" ) ) && daught == EvtPDL::getId( std::string( "K'_1-" ) ) ) || ( parent == EvtPDL::getId( std::string( "B0" ) ) && daught == EvtPDL::getId( std::string( "K'_10" ) ) ) || ( parent == EvtPDL::getId( std::string( "anti-B0" ) ) && daught == EvtPDL::getId( std::string( "anti-K'_10" ) ) ) ) { - double ff0A[] = {0.450, 0.340, 0.41, 0.22, 0.31, 0.310, 0.28}; - double sigma1A[] = {1.600, 0.635, 1.51, 2.40, 2.01, 0.629, 1.36}; - double sigma2A[] = {0.974, 0.211, 1.18, 1.78, 1.50, 0.387, 0.72}; - double ff0B[] = {-0.37, -0.29, -0.17, -0.45, -0.25, -0.250, -0.11}; - double sigma1B[] = {1.72, 0.729, 0.919, 1.34, 1.59, 0.378, -1.61}; - double sigma2B[] = {0.912, 0.074, 0.855, 0.69, 0.79, -0.755, 10.2}; - int eq_num[] = {10, 10, 10, 10, 10, 10, 10}; + double ff0A[] = { 0.450, 0.340, 0.41, 0.22, 0.31, 0.310, 0.28 }; + double sigma1A[] = { 1.600, 0.635, 1.51, 2.40, 2.01, 0.629, 1.36 }; + double sigma2A[] = { 0.974, 0.211, 1.18, 1.78, 1.50, 0.387, 0.72 }; + double ff0B[] = { -0.37, -0.29, -0.17, -0.45, -0.25, -0.250, -0.11 }; + double sigma1B[] = { 1.72, 0.729, 0.919, 1.34, 1.59, 0.378, -1.61 }; + double sigma2B[] = { 0.912, 0.074, 0.855, 0.69, 0.79, -0.755, 10.2 }; + int eq_num[] = { 10, 10, 10, 10, 10, 10, 10 }; double MM2 = 5.279 * 5.279; // GeV^2 double MB = 5.279; // GeV double MK1 = 1.403; // GeV double MK1A = 1.31; // GeV double MK1B = 1.34; // GeV double sinK = sin( thetaK ); // sin(-34^o) double cosK = cos( thetaK ); // cos(-34^o) double a, v0, v1, v2; a = cosK * equation9_10( ff0A[0], MM2, t, sigma1A[0], sigma2A[0], eq_num[0] ) * ( MB + MK1 ) / ( MB + MK1A ); a = a - sinK * equation9_10( ff0B[0], MM2, t, sigma1B[0], sigma2B[0], eq_num[0] ) * ( MB + MK1 ) / ( MB + MK1B ); v0 = cosK * equation9_10( ff0A[1], MM2, t, sigma1A[1], sigma2A[1], eq_num[1] ) * MK1A / MK1; v0 = v0 - sinK * equation9_10( ff0B[1], MM2, t, sigma1B[1], sigma2B[1], eq_num[1] ) * MK1B / MK1; v1 = cosK * equation9_10( ff0A[2], MM2, t, sigma1A[2], sigma2A[2], eq_num[2] ) * ( MB + MK1A ) / ( MB + MK1 ); v1 = v1 - sinK * equation9_10( ff0B[2], MM2, t, sigma1B[2], sigma2B[2], eq_num[2] ) * ( MB + MK1B ) / ( MB + MK1 ); v2 = cosK * equation9_10( ff0A[3], MM2, t, sigma1A[3], sigma2A[3], eq_num[3] ) * ( MB + MK1 ) / ( MB + MK1A ); v2 = v2 - sinK * equation9_10( ff0B[3], MM2, t, sigma1B[3], sigma2B[3], eq_num[3] ) * ( MB + MK1 ) / ( MB + MK1B ); v = a; a0 = v0; a1 = v1; a2 = v2; t1 = cosK * equation9_10( ff0A[4], MM2, t, sigma1A[4], sigma2A[4], eq_num[4] ); t1 = t1 - sinK * equation9_10( ff0B[4], MM2, t, sigma1B[4], sigma2B[4], eq_num[4] ); t2 = cosK * equation9_10( ff0A[5], MM2, t, sigma1A[5], sigma2A[5], eq_num[5] ) * ( MB * MB - MK1A * MK1A ) / ( MB * MB - MK1 * MK1 ); t2 = t2 - sinK * equation9_10( ff0B[5], MM2, t, sigma1B[5], sigma2B[5], eq_num[5] ) * ( MB * MB - MK1B * MK1B ) / ( MB * MB - MK1 * MK1 ); t3 = cosK * equation9_10( ff0A[6], MM2, t, sigma1A[6], sigma2A[6], eq_num[6] ); t3 = t3 - sinK * equation9_10( ff0B[6], MM2, t, sigma1B[6], sigma2B[6], eq_num[6] ); models_counter = models_counter + 1; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") <<"\n The function EvtbTosllMSFF::getVectorFF(...) passed." // << "\n barB -> bar K_1(1270) transition form factors" // << std::endl; } // EvtGenReport(EVTGEN_NOTICE,"EvtGen") << "\n models_counter = " << models_counter // << "\n Vector form-factors at q^2 = " << t // << " for B -> V transition:" // << "\n v = " << v // << "\n a0 = " << a0 // << "\n a1 = " << a1 // << "\n a2 = " << a2 // << "\n t1 = " << t1 // << "\n t2 = " << t2 // << "\n t3 = " << t3 << std::endl; if ( models_counter != 1 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n In the function EvtbTosllMSFF::getVectorFF(...) \n" << "the parameter models_counter not equal 1! \n" << "models_counter = " << models_counter << std::endl; ::abort(); } } // Getting the quark mass (in GeV) using to the dispersion quark model // of D.Melikhov, B.Stech, PRD62, 014006 (2000). // // i=1 => return m_u; // i=2 => return m_d; // i=3 => return m_s; // i=4 => return m_c; // i=5 => return m_b; double EvtbTosllMSFF::getQuarkMass( int i ) { double qm = 0.0; switch ( i ) { case 1: qm = 0.23; // m_u break; case 2: qm = 0.23; // m_d = m_u break; case 3: qm = 0.35; // m_s break; case 4: qm = 1.45; // m_c break; case 5: qm = 4.85; // m_b break; default: EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "In the function EvtbTosllMSFF::getQuarkMass \n" << "the parameter i not equal 1, 2, 3, 4 or 5! \n" << "i =" << i << std::endl; ::abort(); } return qm; } diff --git a/src/EvtGenModels/EvtbTosllWilsCoeffNLO.cpp b/src/EvtGenModels/EvtbTosllWilsCoeffNLO.cpp index 86547d6..3a93105 100644 --- a/src/EvtGenModels/EvtbTosllWilsCoeffNLO.cpp +++ b/src/EvtGenModels/EvtbTosllWilsCoeffNLO.cpp @@ -1,1261 +1,1263 @@ /*********************************************************************** * 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/EvtbTosllWilsCoeffNLO.hh" #include "EvtGenBase/EvtDiLog.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtTensor4C.hh" #include "EvtGenBase/EvtVector4C.hh" #include // ************************************************************** // * * // * The strong running coupling constant from PDG * // * * // * mu - the scale parameter ( in GeV ); * // * Nf - number of "effective" flavours ( Nf=5 for b-quark); * // * the colors number = 3; * // * ias - the number for alpha_s(M_Z) choice: * // * = 0 PDG 1sigma minimal alpha_s(M_Z); * // * = 1 PDG average value alpha_s(M_Z); * // * = 2 PDG 1sigma maximal alpha_s(M_Z). * // * * // ************************************************************** double EvtbTosllWilsCoeffNLO::As( double mu, int Nf, int ias ) { double as, ll; double b0, b1, b2; /* terms in the series of the beta-function */ - double alpha_strong[] = {0.1156, 0.1176, 0.1196}; /* at M_Z scale */ - double MZ = 91.19; /* in GeV */ + double alpha_strong[] = { 0.1156, 0.1176, 0.1196 }; /* at M_Z scale */ + double MZ = 91.19; /* in GeV */ b0 = 11. - 2. * ( (double)Nf ) / 3.; b1 = 51. - 19. * ( (double)Nf ) / 3.; b2 = 2857. - 5033. * ( (double)Nf ) / 9. + 325. * pow( ( (double)Nf ), 2. ) / 27.; // RG Equation solution alpha_strong[ias] = alpha_strong[ias] / ( 4.0 * EvtConst::pi ); ll = 0.0 - log( MZ / mu ) + ( b0 * b2 - b1 * b1 ) * alpha_strong[ias] / ( 2.0 * pow( b0, 3.0 ) ); ll = ll + 1.0 / ( 2.0 * b0 * alpha_strong[ias] ); ll = ll + b1 * log( alpha_strong[ias] ) / ( 2.0 * b0 * b0 ); // Running coupling constant from M_Z to mu as = pow( ( log( log( 2.0 * ll ) ) - 0.5 ), 2.0 ) + b2 * b0 / ( 8.0 * b1 * b1 ) - 5.0 / 4.0; as = as * pow( ( b1 / ( b0 * b0 * ll ) ), 2.0 ); as = 1.0 - b1 * log( 2.0 * ll ) / ( b0 * b0 * ll ) - as; as = 2.0 * EvtConst::pi * as / ( b0 * ll ); if ( as <= 0.0 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "The function EvtbTosllWilsCoeffNLO::As" << "\n Unexpected value of the running coupling constant!" << "\n alpha_s(" << mu << ") = " << as << ";" << "\n Nf =" << Nf << ", ias = " << ias << ";" << "\n ln(mu/lambda_QCD) = " << ll << ";" << std::endl; ::abort(); } return as; } // ************************************************************ // * * // * Spencer function * // * in serial representation * // * ( w <= 1.0 ) * // * * // * * // ************************************************************ double EvtbTosllWilsCoeffNLO::Li2( double w ) { double Lii = 0.0; double k = 1.0; while ( k <= 20.0 ) { Lii = Lii + pow( w, k ) / pow( k, 2.0 ); k++; }; /* printf("\n Spencer function value: Lii(%f)=%f \n\n",w,Lii); */ return Lii; } /* Coefficient C1(mu) * * by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::C1( double mu, double Mw, int Nf, int ias ) { double CC1; double eta; double asW; /* the strong coupling constant at the scale Mw */ double asmu; /* the strong coupling constant at the scale mu */ int i; - double a[] = {14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, - 0.4086, -0.4230, -0.8994, 0.1456}; - double k1[] = {0.0, 0.0, 0.5, -0.5, 0.0, 0.0, 0.0, 0.0}; + double a[] = { 14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, + 0.4086, -0.4230, -0.8994, 0.1456 }; + double k1[] = { 0.0, 0.0, 0.5, -0.5, 0.0, 0.0, 0.0, 0.0 }; asW = As( Mw, Nf, ias ); asmu = As( mu, Nf, ias ); eta = asW / asmu; CC1 = 0.0; i = 0; while ( i < 8 ) { CC1 = CC1 + k1[i] * pow( eta, a[i] ); i++; }; return CC1; } /* Coefficient C2(mu) * * by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::C2( double mu, double Mw, int Nf, int ias ) { double CC2; double eta; double asW; /* the strong coupling constant at the scale Mw */ double asmu; /* the strong coupling constant at the scale mu */ int i; - double a[] = {14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, - 0.4086, -0.4230, -0.8994, 0.1456}; - double k2[] = {0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}; + double a[] = { 14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, + 0.4086, -0.4230, -0.8994, 0.1456 }; + double k2[] = { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0 }; asW = As( Mw, Nf, ias ); asmu = As( mu, Nf, ias ); eta = asW / asmu; CC2 = 0.0; i = 0; while ( i < 8 ) { CC2 = CC2 + k2[i] * pow( eta, a[i] ); i++; }; return CC2; } /* Coefficient C3(mu) * * by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::C3( double mu, double Mw, int Nf, int ias ) { double CC3; double eta; double asW; /* the strong coupling constant at the scale Mw */ double asmu; /* the strong coupling constant at the scale mu */ int i; - double a[] = {14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, - 0.4086, -0.4230, -0.8994, 0.1456}; - double k3[] = {0.0, 0.0, -1.0 / 14.0, 1.0 / 6.0, - 0.0510, -0.1403, -0.0113, 0.0054}; + double a[] = { 14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, + 0.4086, -0.4230, -0.8994, 0.1456 }; + double k3[] = { 0.0, 0.0, -1.0 / 14.0, 1.0 / 6.0, + 0.0510, -0.1403, -0.0113, 0.0054 }; asW = As( Mw, Nf, ias ); asmu = As( mu, Nf, ias ); eta = asW / asmu; CC3 = 0.0; i = 0; while ( i < 8 ) { CC3 = CC3 + k3[i] * pow( eta, a[i] ); i++; }; return CC3; } /* Coefficient C4(mu) * * by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::C4( double mu, double Mw, int Nf, int ias ) { double CC4; double eta; double asW; /* the strong coupling constant at the scale Mw */ double asmu; /* the strong coupling constant at the scale mu */ int i; - double a[] = {14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, - 0.4086, -0.4230, -0.8994, 0.1456}; - double k4[] = {0.0, 0.0, -1.0 / 14.0, -1.0 / 6.0, - 0.0984, 0.1214, 0.0156, 0.0026}; + double a[] = { 14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, + 0.4086, -0.4230, -0.8994, 0.1456 }; + double k4[] = { 0.0, 0.0, -1.0 / 14.0, -1.0 / 6.0, + 0.0984, 0.1214, 0.0156, 0.0026 }; asW = As( Mw, Nf, ias ); asmu = As( mu, Nf, ias ); eta = asW / asmu; CC4 = 0.0; i = 0; while ( i < 8 ) { CC4 = CC4 + k4[i] * pow( eta, a[i] ); i++; }; return CC4; } /* Coefficient C5(mu) * * by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::C5( double mu, double Mw, int Nf, int ias ) { double CC5; double eta; double asW; /* the strong coupling constant at the scale Mw */ double asmu; /* the strong coupling constant at the scale mu */ int i; - double a[] = {14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, - 0.4086, -0.4230, -0.8994, 0.1456}; - double k5[] = {0.0, 0.0, 0.0, 0.0, -0.0397, 0.0117, -0.0025, 0.0304}; + double a[] = { 14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, + 0.4086, -0.4230, -0.8994, 0.1456 }; + double k5[] = { 0.0, 0.0, 0.0, 0.0, -0.0397, 0.0117, -0.0025, 0.0304 }; asW = As( Mw, Nf, ias ); asmu = As( mu, Nf, ias ); eta = asW / asmu; CC5 = 0.0; i = 0; while ( i < 8 ) { CC5 = CC5 + k5[i] * pow( eta, a[i] ); i++; }; return CC5; } /* Coefficient C6(mu) * * by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::C6( double mu, double Mw, int Nf, int ias ) { double CC6; double eta; double asW; /* the strong coupling constant at the scale Mw */ double asmu; /* the strong coupling constant at the scale mu */ int i; - double a[] = {14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, - 0.4086, -0.4230, -0.8994, 0.1456}; - double k6[] = {0.0, 0.0, 0.0, 0.0, 0.0335, 0.0239, -0.0462, -0.0112}; + double a[] = { 14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, + 0.4086, -0.4230, -0.8994, 0.1456 }; + double k6[] = { 0.0, 0.0, 0.0, 0.0, 0.0335, 0.0239, -0.0462, -0.0112 }; asW = As( Mw, Nf, ias ); asmu = As( mu, Nf, ias ); eta = asW / asmu; CC6 = 0.0; i = 0; while ( i < 8 ) { CC6 = CC6 + k6[i] * pow( eta, a[i] ); i++; }; return CC6; } /* by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::A( double z ) { double AA; AA = z * ( 8.0 * pow( z, 2.0 ) + 5.0 * z - 7.0 ) / ( 12.0 * pow( ( z - 1.0 ), 3.0 ) ); AA = AA + pow( z, 2.0 ) * ( 2.0 - 3.0 * z ) * log( z ) / ( 2.0 * pow( ( z - 1.0 ), 4.0 ) ); return AA; } /* by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::B( double z ) { double BB; BB = z / ( 4.0 * ( 1.0 - z ) ) + z * log( z ) / ( 4.0 * pow( ( 1.0 - z ), 2.0 ) ); return BB; } /* by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::C_Bur( double z ) { double CC; CC = z * ( z - 6.0 ) / ( 8.0 * ( z - 1.0 ) ); CC = CC + z * ( 3.0 * z + 2.0 ) * log( z ) / ( 8.0 * pow( ( z - 1.0 ), 2.0 ) ); return CC; } /* by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::D_Bur( double z ) { double DD; DD = ( 25.0 * pow( z, 2.0 ) - 19.0 * pow( z, 3.0 ) ) / ( 36.0 * pow( ( z - 1.0 ), 3.0 ) ); DD = DD + pow( z, 2.0 ) * ( 5.0 * pow( z, 2.0 ) - 2.0 * z - 6.0 ) * log( z ) / ( 18.0 * pow( ( z - 1.0 ), 4.0 ) ); DD = DD - ( 4.0 / 9.0 ) * log( z ); return DD; } /* by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::E( double z ) { double EE; EE = z * ( 18.0 - 11.0 * z - z * z ) / ( 12.0 * pow( ( 1.0 - z ), 3.0 ) ); EE = EE + pow( z, 2.0 ) * ( 15.0 - 16.0 * z + 4.0 * z * z ) * log( z ) / ( 6.0 * pow( ( 1.0 - z ), 4.0 ) ); EE = EE - ( 2.0 / 3.0 ) * log( z ); return EE; } /* by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::F_Bur( double z ) { double FF; FF = z * ( pow( z, 2.0 ) - 5.0 * z - 2.0 ) / ( 4.0 * pow( ( z - 1.0 ), 3.0 ) ); FF = FF + 3.0 * pow( z, 2.0 ) * log( z ) / ( 2.0 * pow( ( z - 1.0 ), 4.0 ) ); return FF; } /* by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::Y( double z ) { double YY; YY = C_Bur( z ) - B( z ); return YY; } /* by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::Z( double z ) { double ZZ; ZZ = C_Bur( z ) + 0.25 * D_Bur( z ); return ZZ; } /* Coefficient C7gamma(mu) in the SM * * by A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ double EvtbTosllWilsCoeffNLO::C7gamma( double mu, double Mw, double mt, int Nf, int ias ) { double C7, C70, C80, sum; double AA, FF; double x, eta; double asW, asmu; int i; - double a[] = {14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, - 0.4086, -0.4230, -0.8994, 0.1456}; - double h[] = {2.2996, -1.0880, -3.0 / 7.0, -1.0 / 14.0, - -0.6494, -0.0380, -0.0186, -0.0057}; + double a[] = { 14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, + 0.4086, -0.4230, -0.8994, 0.1456 }; + double h[] = { 2.2996, -1.0880, -3.0 / 7.0, -1.0 / 14.0, + -0.6494, -0.0380, -0.0186, -0.0057 }; x = pow( mt / Mw, 2.0 ); asW = As( Mw, Nf, ias ); asmu = As( mu, Nf, ias ); eta = asW / asmu; AA = A( x ); FF = F_Bur( x ); C70 = -0.5 * AA; C80 = -0.5 * FF; C7 = pow( eta, ( 16.0 / 23.0 ) ) * C70; C7 = C7 + ( 8.0 / 3.0 ) * ( pow( eta, ( 14.0 / 23.0 ) ) - pow( eta, ( 16.0 / 23.0 ) ) ) * C80; sum = 0.0; i = 0; while ( i < 8 ) { sum = sum + h[i] * pow( eta, a[i] ); i++; }; C7 = C7 + sum; return C7; } /* Coefficient P_E * * by A.J.Buras and M.Munz, Phys.Rev. D52, 186; * * see formula (2.12). */ double EvtbTosllWilsCoeffNLO::Pe( double eta ) { double sum; double Pee; int i; - double a[] = {14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, - 0.4086, -0.4230, -0.8994, 0.1456}; - double q[] = {0.0, 0.0, 0.0, 0.0, 0.0318, 0.0918, -0.2700, 0.0059}; + double a[] = { 14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, + 0.4086, -0.4230, -0.8994, 0.1456 }; + double q[] = { 0.0, 0.0, 0.0, 0.0, 0.0318, 0.0918, -0.2700, 0.0059 }; sum = 0.0; i = 0; while ( i < 8 ) { sum = sum + q[i] * pow( eta, ( a[i] + 1.0 ) ); i++; }; Pee = 0.1405 + sum; return Pee; } /* Coefficient P^{NDR}_0 * * by A.J.Buras and M.Munz, Phys.Rev. D52, 186; * * see formula (2.11). */ double EvtbTosllWilsCoeffNLO::P0ndr( double asW, double eta ) { double P00ndr; double sum; int i; - double a[] = {14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, - 0.4086, -0.4230, -0.8994, 0.1456}; - double p[] = {0.0, 0.0, -80.0 / 203.0, 8.0 / 33.0, - 0.0433, 0.1384, 0.1648, -0.0073}; - double r[] = {0.0, 0.0, 0.8966, -0.1960, -0.2011, 0.1328, -0.0292, -0.1858}; - double s[] = {0.0, 0.0, -0.2009, -0.3579, 0.0490, -0.3616, -0.3554, 0.0072}; + double a[] = { 14.0 / 23.0, 16.0 / 23.0, 6.0 / 23.0, -12.0 / 23.0, + 0.4086, -0.4230, -0.8994, 0.1456 }; + double p[] = { 0.0, 0.0, -80.0 / 203.0, 8.0 / 33.0, + 0.0433, 0.1384, 0.1648, -0.0073 }; + double r[] = { 0.0, 0.0, 0.8966, -0.1960, + -0.2011, 0.1328, -0.0292, -0.1858 }; + double s[] = { 0.0, 0.0, -0.2009, -0.3579, + 0.0490, -0.3616, -0.3554, 0.0072 }; sum = 0.0; i = 0; while ( i < 8 ) { sum = sum + p[i] * pow( eta, ( a[i] + 1.0 ) ); i++; }; P00ndr = EvtConst::pi * ( -0.1875 + sum ) / asW; P00ndr = P00ndr + 1.2468; sum = 0.0; i = 0; while ( i < 8 ) { sum = sum + ( r[i] + s[i] * eta ) * pow( eta, a[i] ); i++; }; P00ndr = P00ndr + sum; return P00ndr; } /* Coefficient C_{9V} (in the NDR schime) * * by A.J.Buras and M.Munz, Phys.Rev. D52, 186 * * accordint to the equation (2.10). */ double EvtbTosllWilsCoeffNLO::C9v( double mu, double Mw, double mt, int Nf, int ias ) { double C9; double x, eta; double asW, asmu; double sin2W = 0.224; /* the square of the weak angle */ x = pow( mt / Mw, 2.0 ); asW = As( Mw, Nf, ias ); asmu = As( mu, Nf, ias ); eta = asW / asmu; /* C9 */ C9 = P0ndr( asW, eta ) + ( Y( x ) / sin2W ) - 4.0 * Z( x ) + Pe( eta ) * E( x ); return C9; } /* Coefficient C_{10A} * * by A.J.Buras and M.Munz, Phys.Rev. D52, 186; * * see formula (2.8). */ double EvtbTosllWilsCoeffNLO::C10a( double mt, double Mw ) { double C10; double x; double sin2W = 0.224; /* the square of the Winberg angle */ x = pow( mt / Mw, 2.0 ); C10 = -Y( x ) / sin2W; return C10; } /* The real part of the q\bar q loop contribution * * Re(h(z,\hat s)) * * A.J.Buras and M.Munz, Phys.Rev. D52, 186; * * the equation (2.29). * * * * mu - the scale parameter (GeV); * * mQ - the mass of the u- or c-quark (GeV); * * q2 - the square of transition 4-momentum (GeV^2). */ double EvtbTosllWilsCoeffNLO::Reh( double mu, double mQ, double q2 ) { double reh, swh; double x; /* Buras variable "x" from (2.29) */ x = 4.0 * pow( mQ, 2.0 ) / q2; reh = 8.0 / 27.0 - 8.0 * log( mQ / mu ) / 9.0 + 4.0 * x / 9.0; swh = 2.0 * ( 2.0 + x ) * sqrt( fabs( 1.0 - x ) ) / 9.0; if ( x <= 1.0 ) { swh = swh * log( fabs( ( sqrt( 1.0 - x ) + 1.0 ) / ( sqrt( 1.0 - x ) - 1.0 ) ) ); } else { swh = swh * 2.0 * atan( 1.0 / sqrt( x - 1.0 ) ); }; reh = reh - swh; return reh; } /* Im(h(z,\hat s)) by Buras */ double EvtbTosllWilsCoeffNLO::Imh( double mQ, double q2 ) { double x; /* Buras variable "x" from (2.29) */ double imh; x = 4.0 * pow( mQ, 2.0 ) / q2; if ( x <= 1.0 ) { imh = 2.0 * EvtConst::pi * ( 2.0 + x ) * sqrt( fabs( 1.0 - x ) ) / 9.0; } else { imh = 0.0; }; return imh; } /* The real part of the one resonant contribution * * q2 - the square of transition 4-momentum (GeV^2); * * GV - the decay width of the resonance (GeV); * * GllV - the decay width of the resonance into l^+ l^- - pair (GeV); * * MV - the mass of the resonance. */ double EvtbTosllWilsCoeffNLO::ReResonant( double q2, double GV, double GllV, double MV ) { double reresonant; double resa, resb; resa = q2 * ( MV * MV - q2 ) * GllV; resb = MV * ( ( MV * MV - q2 ) * ( MV * MV - q2 ) + MV * MV * GV * GV ); reresonant = resa / resb; return reresonant; } /* The imaginary part of the one resonant contribution * * q2 - the square of transition 4-momentum (GeV^2); * * GV - the decay width of the resonance (GeV); * * GllV - the decay width of the resonance into l^+ l^- - pair (GeV); * * MV - the mass of the resonance. */ double EvtbTosllWilsCoeffNLO::ImResonant( double q2, double GV, double GllV, double MV ) { double imresonant; double resa, resb; resa = q2 * GV * GllV; resb = ( MV * MV - q2 ) * ( MV * MV - q2 ) + MV * MV * GV * GV; imresonant = resa / resb; return imresonant; } /* The real part of the total q\barq-contribution * * * * qflavour = 0 corresponding the u-quark contribution * * = 1 corresponding the c-quark contribution; * * * * res_swch = 0 the resonant contribution switch OFF * * = 1 the resonant contribution switch ON; * * * * ias -- switching parameter for Lms[] in the As(..) function. * * * * Nf - number of "effective" flavours (for b-quark Nf=5); * * mu - the scale parameter (GeV); * * mQ - the mass of the u- or c-quark (GeV); * * q2 - the square of transition 4-momentum (GeV^2); * * ml - the mass of the final leptons (GeV); * * Mw - the mass of the W--meson (GeV). * * */ double EvtbTosllWilsCoeffNLO::ReHtot( int qflavour, int res_swch, int ias, int Nf, double mu, double mQ, double q2, double ml, double Mw ) { double rehtot; double rehres, c1, c2; int i; /* Total decay widths of the resonances (GeV) */ double Gamma[6]; /* The decay width of the resonances into l^+ l^- - pair (GeV) */ double Gamma_ll[6]; /* The mass of the resonances */ double M[6]; double alpha_qed = 1.0 / 137.0; switch ( qflavour ) { /* u-quark contribution */ case 0: switch ( res_swch ) { /* The resonant contribution switch OFF */ case 0: rehtot = EvtbTosllWilsCoeffNLO::Reh( mu, mQ, q2 ); rehres = 0.0; break; /* the resonant contribution switch ON */ case 1: rehtot = EvtbTosllWilsCoeffNLO::Reh( mu, mQ, q2 ); /* \pho */ M[0] = 0.7755; /* GeV */ Gamma[0] = 0.1494; /* GeV */ /* \omega' */ M[1] = 0.7827; /* GeV */ Gamma[1] = 0.0085; /* GeV */ if ( ml < 1.0 ) { /* in e^+e^- or mu^+mu^- */ Gamma_ll[0] = 0.000007; /* \rho */ Gamma_ll[1] = 0.0000006; /* \omega */ } else { /* in \tau^+\tau^- */ Gamma_ll[0] = 0.0; /* \rho */ Gamma_ll[1] = 0.0; /* \omega */ }; c1 = EvtbTosllWilsCoeffNLO::C1( mu, Mw, Nf, ias ); c2 = EvtbTosllWilsCoeffNLO::C2( mu, Mw, Nf, ias ); i = 0; rehres = 0.0; while ( i < 2 ) { rehres = rehres + 3.0 * EvtConst::pi * EvtbTosllWilsCoeffNLO::ReResonant( q2, Gamma[i], Gamma_ll[i], M[i] ) / ( sqrt( 2.0 ) * ( 3.0 * c1 + c2 ) * alpha_qed * alpha_qed ); i++; }; /* The sign plus are corresponded to the relation: \kappa*(3C_1+C_2)=1 with sign of Wilson coefficien C_2(M_W)=+1 as at work A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ rehtot = rehtot + rehres; break; default: rehtot = 0.0; rehres = 0.0; }; break; /* c-quark contribution */ case 1: switch ( res_swch ) { /* The resonant contribution switch OFF */ case 0: rehtot = EvtbTosllWilsCoeffNLO::Reh( mu, mQ, q2 ); rehres = 0.0; break; /* the resonant contribution switch ON */ case 1: rehtot = EvtbTosllWilsCoeffNLO::Reh( mu, mQ, q2 ); /* J/psi */ M[0] = 3.096916; /* GeV */ Gamma[0] = 0.000093; /* GeV */ /* psi' */ M[1] = 3.68609; /* GeV */ Gamma[1] = 0.000317; /* GeV */ /* psi(3770) */ M[2] = 3.77292; /* GeV */ Gamma[2] = 0.0273; /* GeV */ /* psi(4040) */ M[3] = 4.039; /* GeV */ Gamma[3] = 0.08; /* GeV */ /* psi(4160) */ M[4] = 4.153; /* GeV */ Gamma[4] = 0.103; /* GeV */ /* psi(4415) */ M[5] = 4.421; /* GeV */ Gamma[5] = 0.062; /* GeV */ if ( ml < 1.0 ) { /* in e^+e^- or mu^+mu^- */ Gamma_ll[0] = Gamma[0] * 0.059; /* J/psi */ Gamma_ll[1] = Gamma[1] * 0.0075; /* psi' */ Gamma_ll[2] = Gamma[2] * 0.0000097; /* psi(3770) */ Gamma_ll[3] = Gamma[3] * 0.00001; /* psi(4040) */ Gamma_ll[4] = Gamma[4] * 0.0000081; /* psi(4160) */ Gamma_ll[5] = Gamma[5] * 0.0000094; /* psi(4415) */ } else { /* in \tau^+\tau^- */ Gamma_ll[0] = 0.0; /* J/psi */ Gamma_ll[1] = Gamma[1] * 0.003; /* psi' */ Gamma_ll[2] = Gamma[2] * 0.0; /* psi(3770) */ Gamma_ll[3] = Gamma[3] * 0.0; /* psi(4040) */ Gamma_ll[4] = Gamma[4] * 0.0; /* psi(4160) */ Gamma_ll[5] = Gamma[5] * 0.0; /* psi(4415) */ }; c1 = EvtbTosllWilsCoeffNLO::C1( mu, Mw, Nf, ias ); c2 = EvtbTosllWilsCoeffNLO::C2( mu, Mw, Nf, ias ); i = 0; rehres = 0.0; while ( i < 6 ) { rehres = rehres + 3.0 * EvtConst::pi * EvtbTosllWilsCoeffNLO::ReResonant( q2, Gamma[i], Gamma_ll[i], M[i] ) / ( ( 3.0 * c1 + c2 ) * alpha_qed * alpha_qed ); i++; }; /* The sign plus are corresponded to the relation: \kappa*(3C_1+C_2)=1 with sign of Wilson coefficien C_2(M_W)=+1 as at work A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ rehtot = rehtot + rehres; break; default: rehtot = 0.0; rehres = 0.0; }; break; default: rehtot = 0.0; rehres = 0.0; }; return rehtot; } /* The imaginary of the total q\barq-contribution * * * * qflavour = 0 corresponding the u-quark contribution * * = 1 corresponding the c-quark contribution; * * * * res_swch = 0 the resonant contribution switch OFF * * = 1 the resonant contribution switch ON; * * * * ias -- switching parameter for Lms[] in the As(..) function. * * * * Nf - number of "effective" flavours (for b-quark Nf=5); * * mu - the scale parameter (GeV); * * mQ - the mass of the u- or c-quark (GeV); * * q2 - the square of transition 4-momentum (GeV^2); * * ml - the mass of the final leptons (GeV); * * Mw - the mass of the W--meson (GeV). * * */ double EvtbTosllWilsCoeffNLO::ImHtot( int qflavour, int res_swch, int ias, int Nf, double mu, double mQ, double q2, double ml, double Mw ) { double imhtot; double imhres, c1, c2; int i; /* Total decay widths of the resonances (GeV) */ double Gamma[6]; /* The decay width of the resonances into l^+ l^- - pair (GeV) */ double Gamma_ll[6]; /* The mass of the resonances */ double M[6]; double alpha_qed = 1.0 / 137.0; switch ( qflavour ) { /* u-quark contribution */ case 0: switch ( res_swch ) { /* The resonant contribution switch OFF */ case 0: imhtot = EvtbTosllWilsCoeffNLO::Imh( mQ, q2 ); imhres = 0.0; break; /* the resonant contribution switch ON */ case 1: imhtot = EvtbTosllWilsCoeffNLO::Imh( mQ, q2 ); /* \pho */ M[0] = 0.7755; /* GeV */ Gamma[0] = 0.1494; /* GeV */ /* \omega' */ M[1] = 0.7827; /* GeV */ Gamma[1] = 0.0085; /* GeV */ if ( ml < 1.0 ) { /* in e^+e^- or mu^+mu^- */ Gamma_ll[0] = 0.000007; /* \rho */ Gamma_ll[1] = 0.0000006; /* \omega */ } else { /* in \tau^+\tau^- */ Gamma_ll[0] = 0.0; /* \rho */ Gamma_ll[1] = 0.0; /* \omega */ }; c1 = EvtbTosllWilsCoeffNLO::C1( mu, Mw, Nf, ias ); c2 = EvtbTosllWilsCoeffNLO::C2( mu, Mw, Nf, ias ); i = 0; imhres = 0.0; while ( i < 2 ) { imhres = imhres + 3.0 * EvtConst::pi * EvtbTosllWilsCoeffNLO::ImResonant( q2, Gamma[i], Gamma_ll[i], M[i] ) / ( sqrt( 2.0 ) * ( 3.0 * c1 + c2 ) * alpha_qed * alpha_qed ); i++; }; /* The sign plus are corresponded to the relation: \kappa*(3C_1+C_2)=1 with sign of Wilson coefficien C_2(M_W)=+1 as at work A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ imhtot = imhtot + imhres; break; default: imhtot = 0.0; imhres = 0.0; }; break; /* c-quark contribution */ case 1: switch ( res_swch ) { /* The resonant contribution switch OFF */ case 0: imhtot = EvtbTosllWilsCoeffNLO::Imh( mQ, q2 ); imhres = 0.0; break; /* the resonant contribution switch ON */ case 1: imhtot = EvtbTosllWilsCoeffNLO::Imh( mQ, q2 ); /* J/psi */ M[0] = 3.096916; /* GeV */ Gamma[0] = 0.000093; /* GeV */ /* psi' */ M[1] = 3.68609; /* GeV */ Gamma[1] = 0.000317; /* GeV */ /* psi(3770) */ M[2] = 3.77292; /* GeV */ Gamma[2] = 0.0273; /* GeV */ /* psi(4040) */ M[3] = 4.039; /* GeV */ Gamma[3] = 0.08; /* GeV */ /* psi(4160) */ M[4] = 4.153; /* GeV */ Gamma[4] = 0.103; /* GeV */ /* psi(4415) */ M[5] = 4.421; /* GeV */ Gamma[5] = 0.062; /* GeV */ if ( ml < 1.0 ) { /* in e^+e^- or mu^+mu^- */ Gamma_ll[0] = Gamma[0] * 0.059; /* J/psi */ Gamma_ll[1] = Gamma[1] * 0.0075; /* psi' */ Gamma_ll[2] = Gamma[2] * 0.0000097; /* psi(3770) */ Gamma_ll[3] = Gamma[3] * 0.00001; /* psi(4040) */ Gamma_ll[4] = Gamma[4] * 0.0000081; /* psi(4160) */ Gamma_ll[5] = Gamma[5] * 0.0000094; /* psi(4415) */ } else { /* in \tau^+\tau^- */ Gamma_ll[0] = 0.0; /* J/psi */ Gamma_ll[1] = Gamma[1] * 0.003; /* psi' */ Gamma_ll[2] = Gamma[2] * 0.0; /* psi(3770) */ Gamma_ll[3] = Gamma[3] * 0.0; /* psi(4040) */ Gamma_ll[4] = Gamma[4] * 0.0; /* psi(4160) */ Gamma_ll[5] = Gamma[5] * 0.0; /* psi(4415) */ }; c1 = EvtbTosllWilsCoeffNLO::C1( mu, Mw, Nf, ias ); c2 = EvtbTosllWilsCoeffNLO::C2( mu, Mw, Nf, ias ); i = 0; imhres = 0.0; while ( i < 6 ) { imhres = imhres + 3.0 * EvtConst::pi * EvtbTosllWilsCoeffNLO::ImResonant( q2, Gamma[i], Gamma_ll[i], M[i] ) / ( ( 3.0 * c1 + c2 ) * alpha_qed * alpha_qed ); i++; }; /* The sign plus are corresponded to the relation: \kappa*(3C_1+C_2)=1 with sign of Wilson coefficien C_2(M_W)=+1 as at work A.J.Buras and M.Munz, Phys.Rev. D52, 186. */ imhtot = imhtot + imhres; break; default: imhtot = 0.0; imhres = 0.0; }; break; default: imhtot = 0.0; imhres = 0.0; }; return imhtot; } /* Function \omega(\hat s) * * by A.J.Buras, M.Munz, Phys.Rev.D52 (1995), p189. * * * * q2 - the square of transition 4-momentum (GeV^2); * * m2 - the mass of the b-quark (GeV). */ double EvtbTosllWilsCoeffNLO::omega( double q2, double m2 ) { double oomega; double s; s = q2 / ( m2 * m2 ); /* see definition in the equation (2.26) */ if ( s > 1.0 ) { s = 0.999999; } oomega = -2.0 * pow( EvtConst::pi, 2.0 ) / 9.0 - 4.0 * Li2( s ) / 3.0; oomega = oomega - 2.0 * log( s ) * log( 1.0 - s ) / 3.0; oomega = oomega - ( 5.0 + 4.0 * s ) * log( 1.0 - s ) / ( 3.0 * ( 1.0 + 2.0 * s ) ); oomega = oomega - 2.0 * s * ( 1.0 + s ) * ( 1.0 - 2.0 * s ) * log( s ) / ( 3.0 * pow( ( 1.0 - s ), 2.0 ) * ( 1.0 + 2.0 * s ) ); oomega = oomega + ( 5.0 + 9.0 * s - 6.0 * s * s ) / ( 6.0 * ( 1.0 - s ) * ( 1.0 + 2.0 * s ) ); return oomega; } /* REAL PART of the effective coefficient C_9V^{eff}: * * * * by A.J.Buras, M.Munz, Phys.Rev.D52 (1995), p189; * * F.Kruger, L.M.Sehgal, Phys.Rev.D55 (1997), p.2799. * * * * decay_id = 0 for b -> q l^+ i^- transitions * * 1 for \bar b -> \bar q l^+ l^- transitions; * * * * res_swch = 0 the resonant contribution switch OFF * * = 1 the resonant contribution switch ON; * * * * ias -- switching parameter for Lms[] in the As(..) function. * * * * Nf -- number of "effective" flavors (for b-quark Nf=5); * * * * q2 -- the square of transition 4-momentum; * * m2 -- b-quark mass (in the heavy meson M1), GeV; * * md -- mass of the u- and d-quarks, GeV; * * mc -- c-quark mass, GeV; * * mu -- scale parameter, GeV; * * mt -- t-quark mass, GeV; * * Mw -- mass of the W, GeV; * * ml -- leptonic mass, GeV; * * * * Relambda_qu -- Re(V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}), q={d,s}; * * Imlambda_qu -- Im(V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}), q={d,s}; * * */ double EvtbTosllWilsCoeffNLO::ReC9eff( int decay_id, int res_swch, int ias, int Nf, double q2, double m2, double md, double mc, double mu, double mt, double Mw, double ml, double Relambda_qu, double Imlambda_qu ) { double RReC9eff; double tilde_eta; /* Buras variable " \tilde\eta" in (2.33) */ double c1, c2, c3, c4, c5, c6, c9; double RReh_d, RReh_b, RReHtot_u, IImHtot_u, RReHtot_c, IImHtot_c; tilde_eta = 1.0 + EvtbTosllWilsCoeffNLO::As( mu, Nf, ias ) * EvtbTosllWilsCoeffNLO::omega( q2, m2 ) / EvtConst::pi; c1 = EvtbTosllWilsCoeffNLO::C1( mu, Mw, Nf, ias ); c2 = EvtbTosllWilsCoeffNLO::C2( mu, Mw, Nf, ias ); c3 = EvtbTosllWilsCoeffNLO::C3( mu, Mw, Nf, ias ); c4 = EvtbTosllWilsCoeffNLO::C4( mu, Mw, Nf, ias ); c5 = EvtbTosllWilsCoeffNLO::C5( mu, Mw, Nf, ias ); c6 = EvtbTosllWilsCoeffNLO::C6( mu, Mw, Nf, ias ); c9 = EvtbTosllWilsCoeffNLO::C9v( mu, Mw, mt, Nf, ias ); RReh_d = EvtbTosllWilsCoeffNLO::Reh( mu, md, q2 ); RReh_b = EvtbTosllWilsCoeffNLO::Reh( mu, m2, q2 ); RReHtot_u = EvtbTosllWilsCoeffNLO::ReHtot( 0, res_swch, ias, Nf, mu, md, q2, ml, Mw ); IImHtot_u = EvtbTosllWilsCoeffNLO::ImHtot( 0, res_swch, ias, Nf, mu, md, q2, ml, Mw ); RReHtot_c = EvtbTosllWilsCoeffNLO::ReHtot( 1, res_swch, ias, Nf, mu, mc, q2, ml, Mw ); IImHtot_c = EvtbTosllWilsCoeffNLO::ImHtot( 1, res_swch, ias, Nf, mu, mc, q2, ml, Mw ); RReC9eff = c9 * tilde_eta + 2.0 * ( 3.0 * c3 + c4 + 3.0 * c5 + c6 ) / 9.0; RReC9eff = RReC9eff + ( 3.0 * c1 + c2 + 3.0 * c3 + c4 + 3.0 * c5 + c6 ) * RReHtot_c; RReC9eff = RReC9eff - 0.5 * ( 4.0 * c3 + 4.0 * c4 + 3.0 * c5 + c6 ) * RReh_b; RReC9eff = RReC9eff - 0.5 * ( c3 + 3.0 * c4 ) * RReh_d; switch ( decay_id ) { /* b -> q l^+ i^- transitions */ case 0: RReC9eff = RReC9eff + ( 3.0 * c1 + c2 ) * ( Relambda_qu * ( RReHtot_c - RReHtot_u ) - Imlambda_qu * ( IImHtot_c - IImHtot_u ) ); break; /* \bar b -> \bar q l^+ i^- transitions */ case 1: RReC9eff = RReC9eff + ( 3.0 * c1 + c2 ) * ( Relambda_qu * ( RReHtot_c - RReHtot_u ) + Imlambda_qu * ( IImHtot_c - IImHtot_u ) ); break; }; // EvtGenReport(EVTGEN_NOTICE,"EvtGen") // << "\n ==============================================================" // << "\n ==============================================================" // << "\n\n The function EvtbTosllWilsCoeffNLO::ReC9eff(...) passed." // << "\n Particle masses:" // << "\n q2 = " << q2 // << "\n s = " << q2/(m2*m2) // << "\n leptonic mass ml = " << ml // << "\n u or d - quarks mass md = " << md // << "\n c - quark mass mc = " << mc // << "\n b - quark mass mb = " << m2 // << "\n t - quark mass mt = " << mt // << "\n W - boson mass Mw = " << Mw // << "\n ===============================================================" // << "\n Input parameters:" // << "\n scale parameter mu = " << mu // << "\n number of flavors Nf = " << Nf // << "\n resonant switching = " << res_swch // << "\n decay id = " << decay_id // << "\n parameter for alpha_s(M_Z) = " << ias // << "\n Relambda_qu = " << Relambda_qu // << "\n Imlambda_qu = " << Imlambda_qu // << "\n ================================================================" // << "\n Wilson Coefficients:" // << "\n c1 = " << c1 // << "\n c2 = " << c2 // << "\n c3 = " << c3 // << "\n c4 = " << c4 // << "\n c5 = " << c5 // << "\n c6 = " << c6 // << "\n c9 = " << c9 // << "\n Reh_d = " << RReh_d // << "\n Reh_b = " << RReh_b // << "\n ReHtot_u = " << RReHtot_u // << "\n ReHtot_c = " << RReHtot_c // << "\n ImHtot_u = " << IImHtot_u // << "\n ImHtot_c = " << IImHtot_c // << "\n RReC9eff = " << RReC9eff // << "\n tilde_eta = " << tilde_eta // << "\n =================================================================" // << "\n =================================================================" // << std::endl; return RReC9eff; } /* IMAGINARY PART of the effective coefficient C_9V^{eff}: * * * * by A.J.Buras, M.Munz, Phys.Rev.D52 (1995), p189; * * F.Kruger, L.M.Sehgal, Phys.Rev.D55 (1997), p.2799. * * * * decay_id = 0 for b -> q l^+ i^- transitions * * 1 for \bar b -> \bar q l^+ l^- transitions; * * * * res_swch = 0 the resonant contribution switch OFF * * = 1 the resonant contribution switch ON; * * * * ias -- switching parameter for Lms[] in the As(..) function. * * * * Nf -- number of "effective" flavors (for b-quark Nf=5); * * * * q2 -- the square of transition 4-momentum; * * m2 -- b-quark mass (in the heavy meson M1), GeV; * * md -- mass of the u- and d-quarks, GeV; * * mc -- c-quark mass, GeV; * * mu -- scale parameter, GeV; * * Mw -- mass of the W, GeV; * * ml -- leptonic mass, GeV; * * * * Relambda_qu -- Re(V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}), q={d,s}; * * Imlambda_qu -- Im(V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}), q={d,s}; * * */ double EvtbTosllWilsCoeffNLO::ImC9eff( int decay_id, int res_swch, int ias, int Nf, double q2, double m2, double md, double mc, double mu, double Mw, double ml, double Relambda_qu, double Imlambda_qu ) { double IImC9eff; double c1, c2, c3, c4, c5, c6; double IImh_d, IImh_b, RReHtot_u, IImHtot_u, RReHtot_c, IImHtot_c; c1 = EvtbTosllWilsCoeffNLO::C1( mu, Mw, Nf, ias ); c2 = EvtbTosllWilsCoeffNLO::C2( mu, Mw, Nf, ias ); c3 = EvtbTosllWilsCoeffNLO::C3( mu, Mw, Nf, ias ); c4 = EvtbTosllWilsCoeffNLO::C4( mu, Mw, Nf, ias ); c5 = EvtbTosllWilsCoeffNLO::C5( mu, Mw, Nf, ias ); c6 = EvtbTosllWilsCoeffNLO::C6( mu, Mw, Nf, ias ); IImh_d = EvtbTosllWilsCoeffNLO::Imh( md, q2 ); IImh_b = EvtbTosllWilsCoeffNLO::Imh( m2, q2 ); RReHtot_u = EvtbTosllWilsCoeffNLO::ReHtot( 0, res_swch, ias, Nf, mu, md, q2, ml, Mw ); IImHtot_u = EvtbTosllWilsCoeffNLO::ImHtot( 0, res_swch, ias, Nf, mu, md, q2, ml, Mw ); RReHtot_c = EvtbTosllWilsCoeffNLO::ReHtot( 1, res_swch, ias, Nf, mu, mc, q2, ml, Mw ); IImHtot_c = EvtbTosllWilsCoeffNLO::ImHtot( 1, res_swch, ias, Nf, mu, mc, q2, ml, Mw ); IImC9eff = ( 3.0 * c1 + c2 + 3.0 * c3 + c4 + 3.0 * c5 + c6 ) * IImHtot_c; IImC9eff = IImC9eff - 0.5 * ( 4.0 * c3 + 4.0 * c4 + 3.0 * c5 + c6 ) * IImh_b; IImC9eff = IImC9eff - 0.5 * ( c3 + 3.0 * c4 ) * IImh_d; switch ( decay_id ) { /* b -> q l^+ i^- transitions */ case 0: IImC9eff = IImC9eff + ( 3.0 * c1 + c2 ) * ( Relambda_qu * ( IImHtot_c - IImHtot_u ) + Imlambda_qu * ( RReHtot_c - RReHtot_u ) ); break; /* \bar b -> \bar q l^+ i^- transitions */ case 1: IImC9eff = IImC9eff + ( 3.0 * c1 + c2 ) * ( Relambda_qu * ( IImHtot_c - IImHtot_u ) - Imlambda_qu * ( RReHtot_c - RReHtot_u ) ); break; }; return IImC9eff; } /* Complex representation for the coefficient C_9V: * * * * by A.J.Buras, M.Munz, Phys.Rev.D52 (1995), p189; * * F.Kruger, L.M.Sehgal, Phys.Rev.D55 (1997), p.2799. * * * * decay_id = 0 for b -> q l^+ i^- transitions * * 1 for \bar b -> \bar q l^+ l^- transitions; * * * * res_swch = 0 the resonant contribution switch OFF * * = 1 the resonant contribution switch ON; * * * * ias -- switching parameter for Lms[] in the As(..) function. * * * * Nf -- number of "effective" flavors (for b-quark Nf=5); * * * * q2 -- the square of transition 4-momentum; * * m2 -- b-quark mass (in the heavy meson M1), GeV; * * md -- mass of the u- and d-quarks, GeV; * * mc -- c-quark mass, GeV; * * mu -- scale parameter, GeV; * * mt -- t-quark mass, GeV; * * Mw -- mass of the W, GeV; * * ml -- leptonic mass, GeV; * * * * Relambda_qu -- Re(V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}), q={d,s}; * * Imlambda_qu -- Im(V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}), q={d,s}; * * */ EvtComplex EvtbTosllWilsCoeffNLO::GetC9Eff( int decay_id, int res_swch, int ias, int Nf, double q2, double m2, double md, double mc, double mu, double mt, double Mw, double ml, double Relambda_qu, double Imlambda_qu ) { double RReC9eff, IImC9eff; EvtComplex unit1( 1.0, 0.0 ); EvtComplex uniti( 0.0, 1.0 ); EvtComplex c9eff; RReC9eff = EvtbTosllWilsCoeffNLO::ReC9eff( decay_id, res_swch, ias, Nf, q2, m2, md, mc, mu, mt, Mw, ml, Relambda_qu, Imlambda_qu ); IImC9eff = EvtbTosllWilsCoeffNLO::ImC9eff( decay_id, res_swch, ias, Nf, q2, m2, md, mc, mu, Mw, ml, Relambda_qu, Imlambda_qu ); c9eff = RReC9eff * unit1 + IImC9eff * uniti; return c9eff; } /* Complex representation for the coefficient C7gamma: * * C7gamma=ReC7gamma * * by A.J.Buras, M.Munz, Phys.Rev.D52 (1995), p189 * * * * mu -- scale parameter, GeV; * * mt -- t-quark mass, GeV; * * Mw -- mass of the W--meson, GeV; * * Nf -- number of "effective" flavors * * (for b-quark Nf=5); * * ias -- switching parameter for Lms[] * * in the As(..) function. * * */ EvtComplex EvtbTosllWilsCoeffNLO::GetC7Eff( double mu, double Mw, double mt, int Nf, int ias ) { double CC7gamma; EvtComplex c7eff; EvtComplex unit1( 1.0, 0.0 ); CC7gamma = EvtbTosllWilsCoeffNLO::C7gamma( mu, Mw, mt, Nf, ias ); c7eff = unit1 * CC7gamma; return c7eff; } /* Complex representation for the coefficient C_10A: * * C_10A=ReC_10 * * by A.J.Buras, M.Munz, Phys.Rev.D52 (1995), p189 * * * * mt -- t-quark mass, GeV; * * Mw -- mass of the W--meson, GeV; * * */ EvtComplex EvtbTosllWilsCoeffNLO::GetC10Eff( double mt, double Mw ) { double ReC10; EvtComplex c10eff; EvtComplex unit1( 1.0, 0.0 ); ReC10 = EvtbTosllWilsCoeffNLO::C10a( mt, Mw ); c10eff = unit1 * ReC10; return c10eff; } diff --git a/src/EvtGenModels/Evtbs2llGammaFFMNT.cpp b/src/EvtGenModels/Evtbs2llGammaFFMNT.cpp index 106c8f9..c660948 100644 --- a/src/EvtGenModels/Evtbs2llGammaFFMNT.cpp +++ b/src/EvtGenModels/Evtbs2llGammaFFMNT.cpp @@ -1,192 +1,192 @@ /*********************************************************************** * 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/Evtbs2llGammaFFMNT.hh" #include "EvtGenBase/EvtComplex.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtVector4C.hh" #include #include Evtbs2llGammaFFMNT::Evtbs2llGammaFFMNT() { } /* * * decay_id = 0 for b \bar q -> l^+ l^- \gamma transitions * * 1 for q \bar b -> l^+ l^- \gamma transitions; * * fb - leptonic decay constant of the B_q - meson; * * mb - the mass of the b-quark; * * mq - the mass of the light quark (d or s); * * c7gam - Wilson coefficient C_{7\gamma}; * * a1 = c1 + c2/3.0 - linear combination of the Wils. Coeff.; * * lambda_qu = V^*_{uq}*V_{ub}/V^*_{tq}*V_{tb}, where q={d,s}; * * lambda_qc = V^*_{cq}*V_{cb}/V^*_{tq}*V_{tb}, where q={d,s}. * * */ void Evtbs2llGammaFFMNT::getPhotonFF( int decay_id, double fb, EvtId parent, double q2, double M1, double mb, double mq, EvtComplex c7gam, EvtComplex a1, EvtComplex lambda_qu, EvtComplex lambda_qc, EvtComplex& Fv, EvtComplex& Fa, EvtComplex& Ftv, EvtComplex& Fta ) { EvtComplex unit1( 1.0, 0.0 ); // real unit EvtComplex uniti( 0.0, 1.0 ); // imaginary unit EvtComplex unit0( 0.0, 0.0 ); // complex zero unit // characteristics of resonances rho, omega, phi - double M_res[] = {0.7758, 0.78259, 1.019456}; // particle masses, Gev - double Gamma[] = {0.1503, 0.00849, 0.00426}; // particle widthes, Gev + double M_res[] = { 0.7758, 0.78259, 1.019456 }; // particle masses, Gev + double Gamma[] = { 0.1503, 0.00849, 0.00426 }; // particle widthes, Gev - double f_lept[] = {5.04, 17.1, -13.2}; // decay constants f_i - double g_plus[] = {0.27, -0.27, -0.38}; // and form-factors g+(0) + double f_lept[] = { 5.04, 17.1, -13.2 }; // decay constants f_i + double g_plus[] = { 0.27, -0.27, -0.38 }; // and form-factors g+(0) g_plus[0] = g_plus[0] / sqrt( 2.0 ); // by D.Melikhov, N.Nikitin, K.Toms, g_plus[1] = g_plus[1] / sqrt( 2.0 ); // Phys.At.Nucl. 68, p.1842 (2005) double hatq2 = q2 / pow( M1, 2 ); // E - photon energy in the B-meson rest frame double E = 0.5 * M1 * ( 1 - hatq2 ); // parametrs for form-factors Fv, Ftv, Fa, Fta //(by D.Melikhov, N.Nikitin, K.Toms, Yad. Fiz. 62, No 11) - double beta[] = {0.28, 0.30, 0.26, 0.33}; // beta, Gev^(-1) - double Delta[] = {0.04, 0.04, 0.30, 0.30}; // Delta, Gev + double beta[] = { 0.28, 0.30, 0.26, 0.33 }; // beta, Gev^(-1) + double Delta[] = { 0.04, 0.04, 0.30, 0.30 }; // Delta, Gev // form-factors EvtComplex Ftvq0, Ftaq0, Ftv00, Fta00; Fv = unit1 * beta[0] * fb * M1 / ( Delta[0] + E ); // Fv(q^2) Ftvq0 = unit1 * beta[1] * fb * M1 / ( Delta[1] + E ); // Ftv(q^2,0) Fa = unit1 * beta[2] * fb * M1 / ( Delta[2] + E ); // Fa(q^2) Ftaq0 = unit1 * beta[3] * fb * M1 / ( Delta[3] + E ); // Fta(q^2,0) Ftv00 = unit1 * beta[1] * fb * M1 / ( Delta[1] + 0.5 * M1 ); // Ftv(0,0) Fta00 = unit1 * beta[3] * fb * M1 / ( Delta[3] + 0.5 * M1 ); // Fta(0,0) EvtComplex Ftv_WA( 0.0, 0.0 ); // the weak annihilation contribution // Resonant contribution to the form-factors Ftv(0,q^2) and Fta(0,q^2) EvtComplex ResSum( 0.0, 0.0 ); if ( parent == EvtPDL::getId( std::string( "B_s0" ) ) || parent == EvtPDL::getId( std::string( "anti-B_s0" ) ) ) { // only \phi-resonant contribution to the Bs-decays ResSum = 2.0 * g_plus[2] * q2 / ( f_lept[2] * ( unit1 * ( q2 - pow( M_res[2], 2 ) ) + uniti * M_res[2] * Gamma[2] ) ); } if ( parent == EvtPDL::getId( std::string( "B_d0" ) ) || parent == EvtPDL::getId( std::string( "anti-B_d0" ) ) ) { // \rho- and \omega-resonant contribution to the Bd-decays for ( int i = 0; i < 2; i++ ) { ResSum = ResSum + 2.0 * g_plus[i] * q2 / ( f_lept[i] * ( unit1 * ( q2 - pow( M_res[i], 2 ) ) + uniti * M_res[i] * Gamma[i] ) ); } } EvtComplex Ftv0q = Ftv00 - ResSum; // form-factor Ftv(0,q^2) EvtComplex Fta0q = Fta00 - ResSum; // form-factor Fta(0,q^2) // Ftv(q^2,q^2) = Ftv(q^2,0)+Ftv(0,q^2) Ftv = Ftvq0 + Ftv0q; // Fta(q^2,q^2) = Fta(q^2,0)+Fta(0,q^2) Fta = Ftaq0 + Fta0q; // Weak annihilation if ( abs( c7gam ) < 0.0000001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function Evtbs2llGammaFFMNT::getPhotonFF" << "\n Error: the Wilson coefficient C7gamma = 0!" << " c7gam = " << c7gam << std::endl; ::abort(); } if ( mb < 0.001 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "\n\n The function Evtbs2llGammaFFMNT::getPhotonFF" << " mb = " << mb << " << 5 GeV!" << std::endl; ::abort(); } switch ( decay_id ) { /* b \bar q -> l^+ l^- \gamma transitions */ case 0: Ftv_WA = ( 16.0 / 3.0 ) * ( lambda_qu + lambda_qc ) * ( a1 / c7gam ) * ( fb / mb ); Ftv = ( 1.0 + mq / mb ) * Ftv - Ftv_WA; Fta = ( 1.0 - mq / mb ) * Fta; //Fv = Fv; //Fa = Fa; break; /* q \bar b -> l^+ l^- \gamma transitions */ case 1: Ftv_WA = ( 16.0 / 3.0 ) * conj( lambda_qu + lambda_qc ) * ( a1 / c7gam ) * ( fb / mb ); Ftv = ( 1.0 + mq / mb ) * Ftv + Ftv_WA; Fta = ( 1.0 - mq / mb ) * Fta; // The change of the sign //Fv = Fv; // is included in the //Fa = Fa; // amplitudes definition! break; }; } // Getting the quark mass (in GeV) using to the dispersion quark model // of D.Melikhov, B.Stech, PRD62, 014006 (2000). // // i=1 => return m_u; // i=2 => return m_d; // i=3 => return m_s; // i=4 => return m_c; // i=5 => return m_b; double Evtbs2llGammaFFMNT::getQuarkMass( int i ) { double qm = 0.0; switch ( i ) { case 1: qm = 0.23; // m_u break; case 2: qm = 0.23; // m_d = m_u break; case 3: qm = 0.35; // m_s break; case 4: qm = 1.45; // m_c break; case 5: qm = 4.85; // m_b break; default: EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "In the function EvtbTosllMSFF::getQuarkMass \n" << "the parametr i not equal 1, 2, 3, 4 or 5! \n" << "i =" << i << std::endl; ::abort(); } return qm; } diff --git a/validation/compareRootFiles.cc b/validation/compareRootFiles.cc index 81d1219..d2a4b44 100644 --- a/validation/compareRootFiles.cc +++ b/validation/compareRootFiles.cc @@ -1,668 +1,668 @@ /*********************************************************************** * 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 "compareRootFiles.hh" #include "TAxis.h" #include "TLatex.h" #include "TLegend.h" #include "TROOT.h" #include "TStyle.h" #include "TText.h" #include #include using std::cout; using std::endl; compareRootFiles::compareRootFiles( string decayName, string newFileName, string oldFileName, string description ) { _decayName = decayName; _newFileName = newFileName; _oldFileName = oldFileName; _description = description; _newFile = new TFile( newFileName.c_str(), "read" ); _oldFile = new TFile( oldFileName.c_str(), "read" ); gROOT->SetStyle( "Plain" ); gStyle->SetOptStat( 0 ); _theCanvas = new TCanvas( "theCanvas", "", 900, 700 ); _theCanvas->Clear(); _theCanvas->UseCurrentStyle(); _emptyHist = new TH1D( "", "", 10, 0.0, 0.0 ); _nGroupMax = 12; } compareRootFiles::~compareRootFiles() { _newFile->Close(); _oldFile->Close(); } void compareRootFiles::getMtmPlots() { // Plot mtm plots for different particle groups // Leptons+gamma, pions, kaons, charm, light/strange baryons, other vector newHistVect, oldHistVect; vector leptonInts; leptonInts.push_back( 0 ); leptonInts.push_back( 1 ); TH1D* newLeptMtmHist = getMtmHist( _newFile, "newLeptMtmHist", leptonInts ); TH1D* oldLeptMtmHist = getMtmHist( _oldFile, "oldLeptMtmHist", leptonInts ); newHistVect.push_back( newLeptMtmHist ); oldHistVect.push_back( oldLeptMtmHist ); vector pionInts; pionInts.push_back( 2 ); pionInts.push_back( 3 ); TH1D* newPionMtmHist = getMtmHist( _newFile, "newPionMtmHist", pionInts ); TH1D* oldPionMtmHist = getMtmHist( _oldFile, "oldPionMtmHist", pionInts ); newHistVect.push_back( newPionMtmHist ); oldHistVect.push_back( oldPionMtmHist ); vector kaonInts; kaonInts.push_back( 4 ); kaonInts.push_back( 5 ); TH1D* newKaonMtmHist = getMtmHist( _newFile, "newKaonMtmHist", kaonInts ); TH1D* oldKaonMtmHist = getMtmHist( _oldFile, "oldKaonMtmHist", kaonInts ); newHistVect.push_back( newKaonMtmHist ); oldHistVect.push_back( oldKaonMtmHist ); vector charmInts; charmInts.push_back( 6 ); charmInts.push_back( 7 ); TH1D* newCharmMtmHist = getMtmHist( _newFile, "newCharmMtmHist", charmInts ); TH1D* oldCharmMtmHist = getMtmHist( _oldFile, "oldCharmMtmHist", charmInts ); newHistVect.push_back( newCharmMtmHist ); oldHistVect.push_back( oldCharmMtmHist ); vector baryonInts; baryonInts.push_back( 8 ); baryonInts.push_back( 9 ); TH1D* newBaryonMtmHist = getMtmHist( _newFile, "newBaryonMtmHist", baryonInts ); TH1D* oldBaryonMtmHist = getMtmHist( _oldFile, "oldBaryonMtmHist", baryonInts ); newHistVect.push_back( newBaryonMtmHist ); oldHistVect.push_back( oldBaryonMtmHist ); vector otherInts; otherInts.push_back( 10 ); TH1D* newOtherMtmHist = getMtmHist( _newFile, "newOtherMtmHist", otherInts ); TH1D* oldOtherMtmHist = getMtmHist( _oldFile, "oldOtherMtmHist", otherInts ); newHistVect.push_back( newOtherMtmHist ); oldHistVect.push_back( oldOtherMtmHist ); _theCanvas->Clear(); _theCanvas->UseCurrentStyle(); _theCanvas->cd( 1 ); gPad->SetLogy(); // Different colours for the particle groups - int colours[6] = {1, 2, 4, 6, 8, 28}; + int colours[6] = { 1, 2, 4, 6, 8, 28 }; string histLabels[6] = { "Leptons,#gamma", "Pions", "Kaons", "D+,D-,D0", - "Light/strange baryons", "Other"}; + "Light/strange baryons", "Other" }; TLegend* theLegend = new TLegend( 0.7, 0.7, 0.9, 0.9 ); theLegend->SetFillColor( kWhite ); double newHistMax( 0.0 ), oldHistMax( 0.0 ); int newHistMaxInt( 0 ), oldHistMaxInt( 0 ); double totalNewFreq( 0.0 ), totalOldFreq( 0.0 ); int iHist( 0 ); int nHistVect = newHistVect.size(); for ( iHist = 0; iHist < nHistVect; iHist++ ) { TH1D* newHist = newHistVect[iHist]; string labelName = histLabels[iHist]; theLegend->AddEntry( newHist, labelName.c_str(), "lpf" ); int colour = colours[iHist]; newHist->SetLineColor( colour ); double theNewHistMax = newHist->GetMaximum(); if ( theNewHistMax > newHistMax ) { newHistMax = theNewHistMax; newHistMaxInt = iHist; } newHist->SetMarkerSize( 0.8 ); newHist->SetMarkerStyle( kFullCircle ); newHist->SetMarkerColor( colour ); totalNewFreq += newHist->Integral(); TH1D* oldHist = oldHistVect[iHist]; oldHist->SetLineStyle( kDashed ); oldHist->SetLineColor( colour ); oldHist->SetMarkerSize( 0.8 ); oldHist->SetMarkerStyle( kOpenCircle ); oldHist->SetMarkerColor( colour ); double theOldHistMax = oldHist->GetMaximum(); if ( theOldHistMax > oldHistMax ) { oldHistMax = theOldHistMax; oldHistMaxInt = iHist; } totalOldFreq += oldHist->Integral(); } double newScale = 1.0 / totalNewFreq; double oldScale = 1.0 / totalOldFreq; if ( newHistMax > oldHistMax ) { TH1D* newFirstHist = newHistVect[newHistMaxInt]; TAxis* xAxis = newFirstHist->GetXaxis(); double dx = xAxis->GetBinWidth( 1 ) * 1000.0; char dxChar[100]; sprintf( dxChar, "Normalised frequency/%.0f (MeV/c)", dx ); newFirstHist->SetXTitle( "p (GeV/c)" ); newFirstHist->SetYTitle( dxChar ); newFirstHist->SetTitleOffset( 1.25, "Y" ); newFirstHist->Scale( newScale ); newFirstHist->Draw( "p" ); for ( iHist = 0; iHist < nHistVect; iHist++ ) { if ( iHist != newHistMaxInt ) { TH1D* otherNewHist = newHistVect[iHist]; otherNewHist->Scale( newScale ); otherNewHist->Draw( "samep" ); } TH1D* otherOldHist = oldHistVect[iHist]; otherOldHist->Scale( oldScale ); otherOldHist->Draw( "samep" ); } } else { TH1D* oldFirstHist = oldHistVect[oldHistMaxInt]; TAxis* xAxis = oldFirstHist->GetXaxis(); double dx = xAxis->GetBinWidth( 1 ) * 1000.0; char dxChar[100]; sprintf( dxChar, "Normalised frequency/%.0f (MeV/c)", dx ); oldFirstHist->SetXTitle( "p (GeV/c)" ); oldFirstHist->SetYTitle( dxChar ); oldFirstHist->SetTitleOffset( 1.25, "Y" ); oldFirstHist->Scale( oldScale ); oldFirstHist->Draw( "p" ); for ( iHist = 0; iHist < nHistVect; iHist++ ) { if ( iHist != oldHistMaxInt ) { TH1D* otherOldHist = oldHistVect[iHist]; otherOldHist->Scale( oldScale ); otherOldHist->Draw( "samep" ); } TH1D* otherNewHist = newHistVect[iHist]; otherNewHist->Scale( newScale ); otherNewHist->Draw( "samep" ); } } theLegend->Draw(); TText* text = new TText(); text->SetTextSize( 0.03 ); text->DrawTextNDC( 0.1, 0.95, "New version = solid points" ); text->DrawTextNDC( 0.1, 0.915, "Old version = open points" ); TLatex* latexString = new TLatex(); latexString->SetTextSize( 0.03 ); latexString->SetNDC(); latexString->DrawLatex( 0.7, 0.92, _description.c_str() ); string gifFileName( "gifFiles/" ); gifFileName.append( _decayName ); gifFileName.append( "_mtmHist.gif" ); _theCanvas->Print( gifFileName.c_str() ); gPad->SetLogy( 0 ); } void compareRootFiles::getPartIdPlots() { TH1D* newPartIdHist = getPartIdHist( _newFile, "newPartIdHist" ); TH1D* oldPartIdHist = getPartIdHist( _oldFile, "oldPartIdHist" ); _theCanvas->Clear(); _theCanvas->UseCurrentStyle(); _theCanvas->cd( 1 ); gPad->SetLogy(); double newPartIdMax = newPartIdHist->GetMaximum(); double oldPartIdMax = oldPartIdHist->GetMaximum(); newPartIdHist->SetMarkerSize( 1.0 ); newPartIdHist->SetMarkerStyle( kFullCircle ); oldPartIdHist->SetLineStyle( kDashed ); oldPartIdHist->SetMarkerSize( 1.0 ); oldPartIdHist->SetMarkerStyle( kOpenCircle ); if ( newPartIdMax > oldPartIdMax ) { newPartIdHist->SetXTitle( "" ); newPartIdHist->SetYTitle( "Normalised frequency" ); newPartIdHist->SetTitleOffset( 1.25, "Y" ); newPartIdHist->Draw( "p" ); oldPartIdHist->Draw( "samep" ); } else { oldPartIdHist->SetXTitle( "" ); oldPartIdHist->SetYTitle( "Normalised frequency" ); oldPartIdHist->SetTitleOffset( 1.25, "Y" ); oldPartIdHist->Draw( "p" ); newPartIdHist->Draw( "samep" ); } TLatex* latex = new TLatex(); latex->SetTextAngle( 90.0 ); latex->SetTextSize( 0.035 ); latex->DrawLatex( 0.5, 0, "Leptons" ); latex->SetTextSize( 0.045 ); latex->DrawLatex( 1.5, 0, "#gamma" ); latex->DrawLatex( 2.5, 0, "#pi^{#pm}" ); latex->DrawLatex( 3.5, 0, "#pi^{0}" ); latex->DrawLatex( 4.5, 0, "K^{#pm}" ); latex->DrawLatex( 5.5, 0, "K^{0}" ); latex->DrawLatex( 6.5, 0, "D^{#pm}" ); latex->DrawLatex( 7.5, 0, "D^{0}" ); latex->SetTextSize( 0.035 ); latex->DrawLatex( 8.4, 0, "Light" ); latex->DrawLatex( 8.75, 0, "baryons" ); latex->DrawLatex( 9.4, 0, "Strange" ); latex->DrawLatex( 9.75, 0, "baryons" ); latex->DrawLatex( 10.5, 0, "Other" ); TText* text = new TText(); text->SetTextSize( 0.03 ); text->DrawTextNDC( 0.1, 0.95, "New version = solid points" ); text->DrawTextNDC( 0.1, 0.915, "Old version = open points" ); TLatex* latexString = new TLatex(); latexString->SetTextSize( 0.03 ); latexString->SetNDC(); latexString->DrawLatex( 0.7, 0.92, _description.c_str() ); string gifFileName( "gifFiles/" ); gifFileName.append( _decayName ); gifFileName.append( "_partIdHist.gif" ); _theCanvas->Print( gifFileName.c_str() ); gPad->SetLogy( 0 ); } void compareRootFiles::getAllIdPlots() { TH1D* newAllIdHist = getAllIdHist( _newFile, "newAllIdHist" ); TH1D* oldAllIdHist = getAllIdHist( _oldFile, "oldAllIdHist" ); _theCanvas->Clear(); _theCanvas->UseCurrentStyle(); _theCanvas->cd( 1 ); gPad->SetLogy(); double newAllIdMax = newAllIdHist->GetMaximum(); double oldAllIdMax = oldAllIdHist->GetMaximum(); newAllIdHist->SetMarkerSize( 1.0 ); newAllIdHist->SetMarkerStyle( kFullCircle ); oldAllIdHist->SetLineStyle( kDashed ); oldAllIdHist->SetMarkerSize( 1.0 ); oldAllIdHist->SetMarkerStyle( kOpenCircle ); if ( newAllIdMax > oldAllIdMax ) { newAllIdHist->SetXTitle( "PDG Id" ); newAllIdHist->SetYTitle( "Normalised frequency" ); newAllIdHist->SetTitleOffset( 1.25, "Y" ); newAllIdHist->Draw( "p" ); oldAllIdHist->Draw( "samep" ); } else { oldAllIdHist->SetXTitle( "PDG Id" ); oldAllIdHist->SetYTitle( "Normalised frequency" ); oldAllIdHist->SetTitleOffset( 1.25, "Y" ); oldAllIdHist->Draw( "p" ); newAllIdHist->Draw( "samep" ); } TText* text = new TText(); text->SetTextSize( 0.03 ); text->DrawTextNDC( 0.1, 0.95, "New version = solid points" ); text->DrawTextNDC( 0.1, 0.915, "Old version = open points" ); TLatex* latexString = new TLatex(); latexString->SetTextSize( 0.03 ); latexString->SetNDC(); latexString->DrawLatex( 0.7, 0.92, _description.c_str() ); string gifFileName( "gifFiles/" ); gifFileName.append( _decayName ); gifFileName.append( "_allIdHist.gif" ); _theCanvas->Print( gifFileName.c_str() ); gPad->SetLogy( 0 ); } void compareRootFiles::getNDaugPlots() { TH1D* newDaugHist = getDaugHist( _newFile, "newDaugHist" ); TH1D* oldDaugHist = getDaugHist( _oldFile, "oldDaugHist" ); _theCanvas->Clear(); _theCanvas->UseCurrentStyle(); _theCanvas->cd( 1 ); double newDaugMax = newDaugHist->GetMaximum(); double oldDaugMax = oldDaugHist->GetMaximum(); newDaugHist->SetMarkerSize( 1.0 ); newDaugHist->SetMarkerStyle( kFullCircle ); oldDaugHist->SetLineStyle( kDashed ); oldDaugHist->SetMarkerSize( 1.0 ); oldDaugHist->SetMarkerStyle( kOpenCircle ); if ( newDaugMax > oldDaugMax ) { newDaugHist->SetXTitle( "nDaughters" ); newDaugHist->SetYTitle( "Normalised frequency" ); newDaugHist->SetTitleOffset( 1.25, "Y" ); newDaugHist->Draw( "p" ); oldDaugHist->Draw( "samep" ); } else { oldDaugHist->SetXTitle( "nDaughters" ); oldDaugHist->SetYTitle( "Normalised frequency" ); oldDaugHist->SetTitleOffset( 1.25, "Y" ); oldDaugHist->Draw( "p" ); newDaugHist->Draw( "samep" ); } TText* text = new TText(); text->SetTextSize( 0.03 ); text->DrawTextNDC( 0.1, 0.95, "New version = solid points" ); text->DrawTextNDC( 0.1, 0.915, "Old version = open points" ); TLatex* latexString = new TLatex(); latexString->SetTextSize( 0.03 ); latexString->SetNDC(); latexString->DrawLatex( 0.7, 0.92, _description.c_str() ); string gifFileName( "gifFiles/" ); gifFileName.append( _decayName ); gifFileName.append( "_daugHist.gif" ); _theCanvas->Print( gifFileName.c_str() ); } TH1D* compareRootFiles::getMtmHist( TFile* theFile, string histName, vector groupInts ) { if ( theFile == nullptr ) { // Return empty histogram return _emptyHist; } TTree* theTree = dynamic_cast( theFile->Get( "Data" ) ); if ( theTree == nullptr ) { // Return empty histogram return _emptyHist; } int id; double p; theTree->SetBranchAddress( "id", &id ); theTree->SetBranchAddress( "p", &p ); double pMax = theTree->GetMaximum( "p" ); TH1D* mtmHist = new TH1D( histName.c_str(), "", 100, 0.0, pMax * 1.1 ); int i; int nEntries = theTree->GetEntries(); for ( i = 0; i < nEntries; i++ ) { theTree->GetEntry( i ); int testInt = this->getPartGroup( id ); // See if the particle id matches any in the group integer vector vector::iterator iter; for ( iter = groupInts.begin(); iter != groupInts.end(); ++iter ) { int groupInt = *iter; if ( groupInt == testInt ) { // We have the right particle group id code mtmHist->Fill( p ); } } } return mtmHist; } TH1D* compareRootFiles::getPartIdHist( TFile* theFile, string histName ) { // Group pi,K,D etc.. into groups and plot multiplicities // with bins along the x axis representing each group // leptons gamma pi+- pi0 K+- K0 D+- D0 light_baryons strange_baryons other if ( theFile == nullptr ) { // Return empty histogram return _emptyHist; } TTree* theTree = dynamic_cast( theFile->Get( "Data" ) ); if ( theTree == nullptr ) { // Return empty histogram return _emptyHist; } int id; theTree->SetBranchAddress( "id", &id ); int nGroupMax = _nGroupMax; vector partNumbers( nGroupMax ); int iP; for ( iP = 0; iP < nGroupMax; iP++ ) { partNumbers[iP] = 0.0; } int i; int nEntries = theTree->GetEntries(); for ( i = 0; i < nEntries; i++ ) { theTree->GetEntry( i ); int groupInt = this->getPartGroup( id ); if ( groupInt >= 0 && groupInt < nGroupMax ) { partNumbers[groupInt] += 1.0; } } TH1D* idHist = new TH1D( histName.c_str(), "", nGroupMax, 0, nGroupMax ); idHist->SetMinimum( 1 ); for ( iP = 0; iP < nGroupMax; iP++ ) { double total = partNumbers[iP]; idHist->Fill( iP, total ); } idHist->Scale( 1.0 / ( nEntries * 1.0 ) ); idHist->SetMaximum( 1.0 ); return idHist; } int compareRootFiles::getPartGroup( int PDGId ) { int group( -1 ); int absPDGId = std::abs( PDGId ); if ( absPDGId >= 11 && absPDGId <= 16 ) { group = 0; // leptons } else if ( absPDGId == 22 ) { group = 1; // photon } else if ( absPDGId == 211 ) { group = 2; // pi+- } else if ( absPDGId == 111 ) { group = 3; // pi0 } else if ( absPDGId == 321 ) { group = 4; // K+- } else if ( absPDGId == 311 || absPDGId == 130 || absPDGId == 310 ) { group = 5; // K0 } else if ( absPDGId == 411 ) { group = 6; // D+- } else if ( absPDGId == 421 ) { group = 7; // D0 } else if ( absPDGId == 2212 || absPDGId == 2112 || absPDGId == 2224 || absPDGId == 2214 || absPDGId == 2114 || absPDGId == 1114 ) { group = 8; // light baryons } else if ( absPDGId >= 3112 && absPDGId <= 3334 ) { group = 9; // strange baryons } else if ( absPDGId != 0 ) { group = 10; // other particles } return group; } TH1D* compareRootFiles::getAllIdHist( TFile* theFile, string histName ) { if ( theFile == nullptr ) { // Return empty histogram return _emptyHist; } TTree* theTree = dynamic_cast( theFile->Get( "Data" ) ); if ( theTree == nullptr ) { // Return empty histogram return _emptyHist; } int id; theTree->SetBranchAddress( "id", &id ); // Just limit the PDG id integer codes up to 4000 int idMax( 4000 ); TH1D* idHist = new TH1D( histName.c_str(), "", 100, -idMax, idMax ); int nEntries = theTree->GetEntries(); cout << "Number of entries = " << nEntries << endl; int i; for ( i = 0; i < nEntries; i++ ) { theTree->GetEntry( i ); idHist->Fill( id ); } double nIdScale = idHist->Integral(); idHist->Scale( 1.0 / nIdScale ); idHist->SetMaximum( 1.0 ); return idHist; } TH1D* compareRootFiles::getDaugHist( TFile* theFile, string histName ) { if ( theFile == nullptr ) { // Return empty histogram return _emptyHist; } TTree* nDaugTree = dynamic_cast( theFile->Get( "nDaugTree" ) ); if ( nDaugTree == nullptr ) { // Return empty histogram return _emptyHist; } int nDaug; nDaugTree->SetBranchAddress( "nDaug", &nDaug ); int nDaugMax = (int)nDaugTree->GetMaximum( "nDaug" ); int nDaugLimit = nDaugMax + 2; TH1D* nDaugHist = new TH1D( histName.c_str(), "", nDaugLimit, 0, nDaugLimit ); int nEntries = nDaugTree->GetEntries(); cout << "Number of entries = " << nEntries << endl; int i; for ( i = 0; i < nEntries; i++ ) { nDaugTree->GetEntry( i ); if ( nDaug > 0 ) { nDaugHist->Fill( nDaug ); } } double nDaugScale = nDaugHist->Integral(); nDaugHist->Scale( 1.0 / nDaugScale ); cout << "nDaugScale = " << nDaugScale << endl; return nDaugHist; } int main( int argc, char** argv ) { string decayName( "UpsilonDecay1" ); if ( argc > 1 ) { decayName = argv[1]; } string newRootFile( "rootFiles/newUpsilonDecay1.root" ); if ( argc > 2 ) { newRootFile = argv[2]; } string oldRootFile( "rootFiles/oldUpsilonDecay1.root" ); if ( argc > 3 ) { oldRootFile = argv[3]; } string description( "Example description" ); if ( argc > 4 ) { description = argv[4]; } compareRootFiles myCompareRootFiles( decayName, newRootFile, oldRootFile, description ); myCompareRootFiles.getNDaugPlots(); myCompareRootFiles.getAllIdPlots(); myCompareRootFiles.getPartIdPlots(); myCompareRootFiles.getMtmPlots(); }