diff --git a/EvtGenBase/EvtIdSet.hh b/EvtGenBase/EvtIdSet.hh index 7edbf6b..0ae3cbb 100644 --- a/EvtGenBase/EvtIdSet.hh +++ b/EvtGenBase/EvtIdSet.hh @@ -1,146 +1,146 @@ /*********************************************************************** * 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 EVTIDSET_HH #define EVTIDSET_HH #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtPatches.hh" #include class EvtId; class EvtIdSet { public: //need a default constructor EvtIdSet( const EvtId name1 ); EvtIdSet( const std::string name1 ); EvtIdSet( const EvtId name1, const EvtId name2 ); EvtIdSet( const std::string name1, const std::string name2 ); EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3 ); EvtIdSet( const std::string name1, const std::string name2, const std::string name3 ); EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4 ); EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4 ); EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5 ); EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5 ); EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6 ); EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6 ); EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6, const EvtId name7 ); EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6, const std::string name7 ); EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6, const EvtId name7, const EvtId name8 ); EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6, const std::string name7, const std::string name8 ); EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6, const EvtId name7, const EvtId name8, const EvtId name9 ); EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6, const std::string name7, const std::string name8, const std::string name9 ); EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6, const EvtId name7, const EvtId name8, const EvtId name9, const EvtId name10 ); EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6, const std::string name7, const std::string name8, const std::string name9, const std::string name10 ); EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6, const EvtId name7, const EvtId name8, const EvtId name9, const EvtId name10, const EvtId name11 ); EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6, const std::string name7, const std::string name8, const std::string name9, const std::string name10, const std::string name11 ); EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6, const EvtId name7, const EvtId name8, const EvtId name9, const EvtId name10, const EvtId name11, const EvtId name12 ); EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6, const std::string name7, const std::string name8, const std::string name9, const std::string name10, const std::string name11, const std::string name12 ); ~EvtIdSet() { delete[] _list; } EvtIdSet( const EvtIdSet& set1 ); EvtIdSet( const EvtIdSet& set1, const EvtIdSet& set2 ); - int contains( const EvtId id ); - int contains( const std::string id ); + int contains( const EvtId id ) const; + int contains( const std::string id ) const; void append( const EvtIdSet set1 ); int sizeOfSet() const; EvtId getElem( const int i ) const; private: int _numInList; EvtId* _list; }; #endif diff --git a/EvtGenBase/EvtParticle.hh b/EvtGenBase/EvtParticle.hh index d3105fc..ecaa341 100644 --- a/EvtGenBase/EvtParticle.hh +++ b/EvtGenBase/EvtParticle.hh @@ -1,498 +1,499 @@ /*********************************************************************** * 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 EVTPARTICLE_HH #define EVTPARTICLE_HH //#include #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtSpinDensity.hh" #include "EvtGenBase/EvtSpinType.hh" #include "EvtGenBase/EvtVector4R.hh" #include #include #include #include class EvtDiracSpinor; class EvtVector4C; class EvtTensor4C; class EvtStdHep; class EvtSecondary; class EvtRaritaSchwinger; const int MAX_DAUG = 100; const int MAX_LEVEL = 10; const int MAX_TRIES = 10000; class EvtParticle { public: /** * Default constructor. */ EvtParticle(); /** * Destructor. */ virtual ~EvtParticle(); /** * Returns polarization vector in the parents restframe. */ virtual EvtVector4C epsParent( int i ) const; /** * Returns polarization vector in the particles own restframe. */ virtual EvtVector4C eps( int i ) const; /** * Returns polarization vector in the parents restframe for a photon. */ virtual EvtVector4C epsParentPhoton( int i ); /** * Returns polarization vector in the particles own restframe for a photon. */ virtual EvtVector4C epsPhoton( int i ); /** * Returns Dirac spinor in the parents restframe for a Dirac particle. */ virtual EvtDiracSpinor spParent( int ) const; /** * Returns Dirac spinor in the particles own restframe for a Dirac particle. */ virtual EvtDiracSpinor sp( int ) const; /** * Returns Dirac spinor in the parents restframe for a Neutrino particle. */ virtual EvtDiracSpinor spParentNeutrino() const; /** * Returns Dirac spinor in the particles own restframe for a * Neutrino particle. */ virtual EvtDiracSpinor spNeutrino() const; /** * Returns tensor in the parents restframe for a spin 2 particle. */ virtual EvtTensor4C epsTensorParent( int i ) const; /** * Returns tensor in the particles own restframe for a spin 2 particle. */ virtual EvtTensor4C epsTensor( int i ) const; /** * Returns Rarita-Schwinger spinor in the parents restframe for a * Rarita-Schwinger particle. */ virtual EvtRaritaSchwinger spRSParent( int ) const; /** * Returns Rarita-Schwinger spinor in the particles own restframe for a * Rarita-Schwinger particle. */ virtual EvtRaritaSchwinger spRS( int ) const; /** * Initialiaze particle with id and 4momentum. */ virtual void init( EvtId part_n, const EvtVector4R& p4 ) = 0; /** * Add another daughter to the particle */ void addDaug( EvtParticle* node ); /** * Decay particle */ void decay(); /** * Delete a decay chain */ void deleteTree(); void deleteDaughters( bool keepChannel = false ); /** * Should only be used internally. */ void setChannel( int i ); /** * Creates the daughters in the list of ids and * adds them to the parent. Note that momentum * is left uninitialized, this is _only_ creation. */ void makeDaughters( unsigned int ndaug, EvtId* id ); /** * Creates the daughters in the list of ids and * adds them to the parent. Note that momentum * is left uninitialized, this is _only_ creation. */ void makeDaughters( unsigned int ndaug, std::vector idVector ); /** * Similar to the routine above except that here * momentum is generated according to phase space * daughters are filled with this momentum. */ double initializePhaseSpace( unsigned int numdaughter, EvtId* daughters, bool forceResetMasses = false, double poleSize = -1., int whichTwo1 = 0, int whichTwo2 = 1 ); /** * Get pointer the the i:th daugther. */ - EvtParticle* getDaug( int i ); + const EvtParticle* getDaug( const int i ) const { return _daug[i]; } + EvtParticle* getDaug( const int i ) { return _daug[i]; } /** * Iterates over the particles in a decay chain. */ EvtParticle* nextIter( EvtParticle* rootOfTree = 0 ); /** * Makes stdhep list */ void makeStdHep( EvtStdHep& stdhep, EvtSecondary& secondary, EvtId* stable_parent_ihep ); void makeStdHep( EvtStdHep& stdhep ); /** * Gets 4vector in the labframe, i.e., the frame in which the root * particles momentum is measured. */ EvtVector4R getP4Lab() const; /** * Gets 4vector in the labframe for the 4-momentum before FSR was * generated in the parents decay. The lab frame is where the root * particles momentum is measured. */ EvtVector4R getP4LabBeforeFSR(); /** * Gets 4vector in the particles restframe, i.e. this functiont will * return (m,0,0,0) */ EvtVector4R getP4Restframe() const; /** * Returns the 4position of the particle in the lab frame. */ EvtVector4R get4Pos() const; /** * Returns pointer to parent particle. */ EvtParticle* getParent() const; /** * Makes partptr the idaug:th daugther. */ void insertDaugPtr( int idaug, EvtParticle* partptr ) { _daug[idaug] = partptr; partptr->_parent = this; } /** * Returns mass of particle. */ double mass() const; /** * Used internally to decide if first time particle is decayed. */ int firstornot() const; void setFirstOrNot(); void resetFirstOrNot(); /** * Returns Id of particle. */ EvtId getId() const; /** * Returns the PDG id of the particle */ int getPDGId() const; /** * Returns particle type. */ EvtSpinType::spintype getSpinType() const; /** * Returns number of spin states of the particle. */ int getSpinStates() const; /** * Returns 4momentum in parents restframe. */ const EvtVector4R& getP4() const; /** * Sets the 4momentum in the parents restframe. */ void setP4( const EvtVector4R& p4 ) { _p = p4; _pBeforeFSR = p4; } void setP4WithFSR( const EvtVector4R& p4 ) { _p = p4; } void setFSRP4toZero() { _pBeforeFSR.set( 0.0, 0.0, 0.0, 0.0 ); } /** * Retunrs the decay channel. */ int getChannel() const; /** * Returns number of daugthers. */ size_t getNDaug() const; void resetNDaug() { _ndaug = 0; return; } /** * Prints out the particle "tree" of a given particle. The * tree consists of all daughters (and their daughters, etc) * and their properties. */ void printTree() const; void printTreeRec( unsigned int level ) const; std::string treeStr() const; std::string treeStrRec( unsigned int level ) const; /** * Prints information for the particle. */ void printParticle() const; /** * Set lifetime of the particle in parents restframe. */ void setLifetime( double tau ); /** * Generate lifetime according to pure exponential. */ void setLifetime(); /** * Returns the lifetime. */ double getLifetime(); /** * Set diagonal spindensity matrix. */ void setDiagonalSpinDensity(); /** * Set spindensity matrix for e+e- -> V */ void setVectorSpinDensity(); /** * Set forward spin density matrix. */ void setSpinDensityForward( const EvtSpinDensity& rho ) { _rhoForward = rho; } /** * Set forward spin density matrix according to the density matrix * rho in the helicity amplitude basis. */ void setSpinDensityForwardHelicityBasis( const EvtSpinDensity& rho ); void setSpinDensityForwardHelicityBasis( const EvtSpinDensity& rho, double alpha, double beta, double gamma ); /** * Returns a rotation matrix need to rotate the basis state * to the helicity basis. The EvtSpinDensity matrix is just use * as a matrix here. This function is to be implemented in each * derived class. */ virtual EvtSpinDensity rotateToHelicityBasis() const = 0; virtual EvtSpinDensity rotateToHelicityBasis( double alpha, double beta, double gamma ) const = 0; /** * Get forward spin density matrix. */ EvtSpinDensity getSpinDensityForward() { return _rhoForward; } /** * Set backward spin density matrix. */ void setSpinDensityBackward( const EvtSpinDensity& rho ) { _rhoBackward = rho; } /** * Get backward spin density matrix. */ EvtSpinDensity getSpinDensityBackward() { return _rhoBackward; } //Hacks will be removed when better solutions are thought of! //This is used to suppress use of random numbers when doing initialization //of some models. void noLifeTime() { _genlifetime = 0; } //lange - April 29, 2002 void setId( EvtId id ) { _id = id; } void initDecay( bool useMinMass = false ); bool generateMassTree(); double compMassProb(); //setMass will blow away any existing 4vector void setMass( double m ) { _p = EvtVector4R( m, 0.0, 0.0, 0.0 ); } //void setMixed() {_mix=true;} //void setUnMixed() {_mix=false;} //bool getMixed() {return _mix;} //void takeCConj() {EvtGenReport(EVTGEN_INFO,"EvtGen") << "should take conj\n";} //this means that the particle has gone through initDecay // and thus has a mass bool isInitialized() { return _isInit; } bool hasValidP4() { return _validP4; } bool isDecayed() { return _isDecayed; } // decay prob - only relevent if already decayed // and is a scalar particle // returned is a double* that should be prob/probMax double* decayProb() { return _decayProb; } void setDecayProb( double p ); // Return the name of the particle (from the EvtId number) std::string getName(); // Specify whether the particle has a special named attribute with // a set value. By default, nothing is set, but derived classes // can set this to mean something specific, e.g. if a photon is FSR void setAttribute( std::string attName, int attValue ) { _intAttributes[attName] = attValue; } // Retrieve the integer value for the given attribute name int getAttribute( std::string attName ); // Specify if the particle has a double attribute value, e.g. amplitude weight. // By default, nothing is set, but derived classes can set this to mean something specific void setAttributeDouble( std::string attName, double attValue ) { _dblAttributes[attName] = attValue; } // Retrieve the double value for the given attribute name double getAttributeDouble( std::string attName ); protected: void setp( double e, double px, double py, double pz ) { _p.set( e, px, py, pz ); _pBeforeFSR = _p; } void setp( const EvtVector4R& p4 ) { _p = p4; _pBeforeFSR = _p; } void setpart_num( EvtId particle_number ) { assert( _channel == -10 || _id.getId() == particle_number.getId() || _id.getId() == -1 ); _id = particle_number; } bool _validP4; // A typedef to define the attribute (name, integer) map typedef std::map EvtAttIntMap; EvtAttIntMap _intAttributes; // A typedef to define the attribute (name, double) map typedef std::map EvtAttDblMap; EvtAttDblMap _dblAttributes; private: EvtParticle* _daug[MAX_DAUG]; size_t _ndaug; EvtParticle* _parent; int _channel; int _first; EvtId _id; EvtVector4R _p; EvtVector4R _pBeforeFSR; double _t; bool _isInit; bool _isDecayed; //bool _mix; EvtSpinDensity _rhoForward; EvtSpinDensity _rhoBackward; void makeStdHepRec( int firstparent, int lastparent, EvtStdHep& stdhep, EvtSecondary& secondary, EvtId* stable_parent_ihep ); void makeStdHepRec( int firstparent, int lastparent, EvtStdHep& stdhep ); //This is a hack until things gets straightened out. (Ryd) int _genlifetime; //should never be used, therefor is private. //these does _not_ have an implementation EvtParticle& operator=( const EvtParticle& p ); EvtParticle( const EvtParticle& p ); double* _decayProb; }; #endif diff --git a/EvtGenModels/EvtRareLbToLll.hh b/EvtGenModels/EvtRareLbToLll.hh index fdab2db..e2eb2cf 100644 --- a/EvtGenModels/EvtRareLbToLll.hh +++ b/EvtGenModels/EvtRareLbToLll.hh @@ -1,66 +1,68 @@ /*********************************************************************** * 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 EVTRARELBTOLLL_HH #define EVTRARELBTOLLL_HH 1 #include "EvtGenBase/EvtAmp.hh" #include "EvtGenBase/EvtDecayAmp.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenModels/EvtRareLbToLllFFBase.hh" #include "EvtGenModels/EvtRareLbToLllWC.hh" #include // Description: // Implements the rare Lb --> Lambda^(*) ell ell models described in // http://arxiv.org/pdf/1108.6129.pdf class EvtRareLbToLll : public EvtDecayAmp { public: std::string getName() override; EvtDecayBase* clone() override; void init() override; void initProbMax() override; void decay( EvtParticle* parent ) override; protected: - void calcAmp( EvtAmp& amp, EvtParticle* parent ); + void calcAmp( EvtAmp& amp, const EvtParticle& parent ); - void HadronicAmp( EvtParticle* parent, EvtParticle* lambda, EvtVector4C* T, - const int i, const int j ); + void HadronicAmp( const EvtParticle& parent, const EvtParticle& lambda, + EvtVector4C* T, const int i, const int j ); - void HadronicAmpRS( EvtParticle* parent, EvtParticle* lambda, + void HadronicAmpRS( const EvtParticle& parent, const EvtParticle& lambda, EvtVector4C* T, const int i, const int j ); - bool isParticle( EvtParticle* parent ) const; + bool isParticle( const EvtParticle& parent ) const; private: double m_maxProbability; + double m_poleSize{ 0.00005 }; + bool m_electronMode{ false }; std::unique_ptr ffmodel_; std::unique_ptr wcmodel_; }; #endif // diff --git a/EvtGenModels/EvtRareLbToLllFF.hh b/EvtGenModels/EvtRareLbToLllFF.hh index 3d0e386..0866809 100644 --- a/EvtGenModels/EvtRareLbToLllFF.hh +++ b/EvtGenModels/EvtRareLbToLllFF.hh @@ -1,114 +1,115 @@ /*********************************************************************** -* Copyright 1998-2020 CERN for the benefit of the EvtGen authors * +* 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 EVTRARELBTOLLLFF_HH #define EVTRARELBTOLLLFF_HH 1 // Include files /** @class EvtRareLbToLllFF EvtRareLbToLllFF.hh EvtGenModels/EvtRareLbToLllFF.hh * * * @author Thomas Blake * @date 2013-11-26 */ #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenModels/EvtRareLbToLllFFBase.hh" #include #include #include #include class EvtRareLbToLllFF : public EvtRareLbToLllFFBase { public: class FormFactorDependence final { public: FormFactorDependence(); FormFactorDependence( const double al, const double ap ); FormFactorDependence( const double a0, const double a2, const double a4, const double al, const double ap ); FormFactorDependence( const FormFactorDependence& other ); FormFactorDependence* clone() const; void param( const double al, const double ap ); void param( const double a0, const double a2, const double a4, const double al, const double ap ); double a0_; double a2_; double a4_; double al_; double ap_; }; class FormFactorSet final { public: FormFactorSet(); FormFactorSet( const FormFactorSet& other ); EvtRareLbToLllFF::FormFactorDependence F1; EvtRareLbToLllFF::FormFactorDependence F2; EvtRareLbToLllFF::FormFactorDependence F3; EvtRareLbToLllFF::FormFactorDependence F4; EvtRareLbToLllFF::FormFactorDependence G1; EvtRareLbToLllFF::FormFactorDependence G2; EvtRareLbToLllFF::FormFactorDependence G3; EvtRareLbToLllFF::FormFactorDependence G4; EvtRareLbToLllFF::FormFactorDependence H1; EvtRareLbToLllFF::FormFactorDependence H2; EvtRareLbToLllFF::FormFactorDependence H3; EvtRareLbToLllFF::FormFactorDependence H4; EvtRareLbToLllFF::FormFactorDependence H5; EvtRareLbToLllFF::FormFactorDependence H6; }; void init() override; - void getFF( EvtParticle* parent, EvtParticle* lambda, - EvtRareLbToLllFFBase::FormFactors& FF ) override; + void getFF( const EvtParticle& parent, const EvtParticle& lambda, + EvtRareLbToLllFFBase::FormFactors& FF ) const override; private: - double func( const double p, EvtRareLbToLllFF::FormFactorDependence& dep ); + double func( const double p, + const EvtRareLbToLllFF::FormFactorDependence& dep ) const; std::array, 2> FF_; std::map FFMap_; - void DiracFF( EvtParticle* parent, EvtParticle* lambda, - EvtRareLbToLllFF::FormFactorSet& FFset, - EvtRareLbToLllFF::FormFactors& FF ); + void DiracFF( const EvtParticle& parent, const EvtParticle& lambda, + const EvtRareLbToLllFF::FormFactorSet& FFset, + EvtRareLbToLllFF::FormFactors& FF ) const; - void RaritaSchwingerFF( EvtParticle* parent, EvtParticle* lambda, - EvtRareLbToLllFF::FormFactorSet& FFset, - EvtRareLbToLllFF::FormFactors& FF ); + void RaritaSchwingerFF( const EvtParticle& parent, const EvtParticle& lambda, + const EvtRareLbToLllFF::FormFactorSet& FFset, + EvtRareLbToLllFF::FormFactors& FF ) const; }; #endif // EVTRARELBTOLLLFF_HH diff --git a/EvtGenModels/EvtRareLbToLllFFBase.hh b/EvtGenModels/EvtRareLbToLllFFBase.hh index f971bac..f4c9739 100644 --- a/EvtGenModels/EvtRareLbToLllFFBase.hh +++ b/EvtGenModels/EvtRareLbToLllFFBase.hh @@ -1,72 +1,72 @@ /*********************************************************************** -* Copyright 1998-2020 CERN for the benefit of the EvtGen authors * +* 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( EvtParticle* parent, EvtParticle* lambda, - EvtRareLbToLllFFBase::FormFactors& FF ) = 0; + virtual void getFF( const EvtParticle& parent, const EvtParticle& lambda, + EvtRareLbToLllFFBase::FormFactors& FF ) const = 0; - bool isNatural( EvtParticle* lambda ); + bool isNatural( const EvtParticle& lambda ) const; EvtRareLbToLllFFBase(); virtual ~EvtRareLbToLllFFBase(){}; protected: - double calculateVdotV( EvtParticle* parent, EvtParticle* lambda ) const; - double calculateVdotV( EvtParticle*, 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/EvtGenModels/EvtRareLbToLllFFGutsche.hh b/EvtGenModels/EvtRareLbToLllFFGutsche.hh index b10ede0..d793417 100644 --- a/EvtGenModels/EvtRareLbToLllFFGutsche.hh +++ b/EvtGenModels/EvtRareLbToLllFFGutsche.hh @@ -1,60 +1,61 @@ /*********************************************************************** -* Copyright 1998-2020 CERN for the benefit of the EvtGen authors * +* 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 EVTRARELBTOLLLFFGUTSCHE_HH #define EVTRARELBTOLLLFFGUTSCHE_HH 1 // Include files /** @class EvtRareLbToLllFF EvtRareLbToLllFF.hh EvtGenModels/EvtRareLbToLllFF.hh * * * @author Michal Kreps * @date 2014-10-21 */ #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenModels/EvtRareLbToLllFFBase.hh" #include #include class EvtRareLbToLllFFGutsche : public EvtRareLbToLllFFBase { public: void init() override; - void getFF( EvtParticle* parent, EvtParticle* lambda, - EvtRareLbToLllFFBase::FormFactors& FF ) override; + void getFF( const EvtParticle& parent, const EvtParticle& lambda, + EvtRareLbToLllFFBase::FormFactors& FF ) const override; private: - double formFactorParametrization( double s, double f0, double a, double b ); + double formFactorParametrization( const double s, const double f0, + const double a, const double b ) const; double fVconsts[3][3]; double fAconsts[3][3]; double fTVconsts[3][3]; double fTAconsts[3][3]; - static EvtIdSet fParents; - static EvtIdSet fDaughters; + const EvtIdSet fParents{ "Lambda_b0", "anti-Lambda_b0" }; + const EvtIdSet fDaughters{ "Lambda0", "anti-Lambda0" }; }; #endif // EVTRARELBTOLLLFF_HH diff --git a/EvtGenModels/EvtRareLbToLllFFlQCD.hh b/EvtGenModels/EvtRareLbToLllFFlQCD.hh index 3a27094..c7f3bc4 100644 --- a/EvtGenModels/EvtRareLbToLllFFlQCD.hh +++ b/EvtGenModels/EvtRareLbToLllFFlQCD.hh @@ -1,66 +1,66 @@ /*********************************************************************** -* Copyright 1998-2020 CERN for the benefit of the EvtGen authors * +* 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 EVTRARELBTOLLLFFLQCD_HH #define EVTRARELBTOLLLFFLQCD_HH 1 // Include files /** @class EvtRareLbToLllFF EvtRareLbToLllFF.hh EvtGenModels/EvtRareLbToLllFF.hh * * * @author Michal Kreps * @date 2016-04-19 * @date 2014-10-23 */ #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtParticle.hh" #include "EvtGenModels/EvtRareLbToLllFFBase.hh" #include #include class EvtRareLbToLllFFlQCD : public EvtRareLbToLllFFBase { public: /// Standard constructor EvtRareLbToLllFFlQCD() = default; void init() override; - void getFF( EvtParticle* parent, EvtParticle* lambda, - EvtRareLbToLllFFBase::FormFactors& FF ) override; + void getFF( const EvtParticle& parent, const EvtParticle& lambda, + EvtRareLbToLllFFBase::FormFactors& FF ) const override; private: - double formFactorParametrization( double q2, double a0, double a1, - double pole ); - double zvar( double q2 ); + double formFactorParametrization( const double q2, const double a0, + const double a1, const double pole ) const; + double zvar( const double q2 ) const; double fconsts[3][3]; double gconsts[3][3]; double hconsts[3][3]; double htildaconsts[3][3]; double t0; double tplus; }; #endif // EVTRARELBTOLLLFF_HH diff --git a/History.md b/History.md index 6e8b947..1f6aab0 100644 --- a/History.md +++ b/History.md @@ -1,756 +1,762 @@ # History file for EvtGen From version 2.0.0, Tabc labels refer to [Maniphest tasks](https://phab.hepforge.org/maniphest/query/nkBRd9OhPCBN/), while Dxyz labels refer to [Differential code reviews](https://phab.hepforge.org/differential/query/YDY8EgjNGd.e/) on HepForge: https://phab.hepforge.org/Tabc https://phab.hepforge.org/Dxyz === +## R02-02-0X + +9 June 2022 Michal Kreps +* D84: Improve efficiency of RareLbToLll decay model for final states with e+e- pair. + +=== ## R02-02-00 12 May 2022 Michal Kreps * D83: Fix double counting of charmonia with K0 decays for B0. 11 May 2022 Tom Latham * D80: Add CMake options for enabling clang-tidy static analysis checks during build 14 Apr 2022 John Back * D82: EvtDecayProb: initialise data members and remove empty destructor 14 Apr 2022 Michal Kreps * D81: Derive EvtFlatSqDalitz from EvtDecayIncoherent since we directly provide final kinematics 2nd Mar 2022 John Back * D78: Add Bc -> J/psi K+ pi- pi+ pi- pi+, Bc -> J/psi K+ K- pi+ pi- pi+ & Bc -> J/psi 4pi+ 3pi- decay modes to the BC_VHAD model, courtesy of Aleksei Luchinsky, Anna Danilina, Dmitrii Pereima & Vanya Belyaev (LHCb) === ## R02-01-01 8th Sep 2021 Michal Kreps * Update location of web page for Pythia8 download in setup script. 8th Sep 2021 Markus Prim, Lu Cao, Chaoyi Lyu and Michel De Cian (Michal Kreps) * D73: Add new model for semileptonic B decays with BCL and BGL form-factors 8th June 2021 Michal Kreps * T110, D71: Fix B+ --> eta' l nu BF which was order of magnitude too high. Balance the decrease by increasing B+ --> D0 l nu, which is after change still bit smaller than PDG 2021. 8th Jun 2021 Michal Kreps * D71: Fix B+ --> eta' l nu BF. 20th Apr 2021 Tom Lathem * D68: Fix compilation with Pythia 8.304 17th Mar 2021 Michal Kreps * D62: Improve PI0DALITZ model to dynamically work out maximum probability to make it usuable also for eta --> llgamma decays. Remove ETA2MUMUGAMMA since it is a pure one-to-one copy of PI0DALITZ. 15th Jan 2021 Michal Kreps * D47: Model to generate 4-body phase-space decays in restricted part of the m12-m34 space 12th Jan 2021 Michal Kreps * D48: Fix bug in calculation of the daughter momentum in decay model EvtBsMuMuKK 7th Jan 2021 Michal Kreps * D43: Allow to pass particle properties table in form of stringstream to constructor of EvtGen for use case where these are created on fly. 10th Dec 2020 Michal Kreps * D36: EvtFlatSqDalitz model to be more efficient and to avoid cut-off around the edges 21st Aug 2020 John Back * T109: Add EvtEtaLLPiPi model for eta' -> l l pi pi decays (l = e or mu), - courtesy of Aleksei Luchinsky (LHCb). 29th Jun 2020 Michal Kreps * T103: Add missing include in EvtGenBase/EvtMatrix.hh. 15th May 2020 Michal Kreps * D28: Add EvtThreeBodyPhsp (rectangular Dalitz plot selection) and EvtPhspDecaytimeCut (minimum decay time requirement) models. * D27: Fix initialisation of constants in EvtBTo3hCP model. === ## R02-00-00 24th Apr 2020 Michal Kreps * Update particle properties file evt.pdl to 2019 version of RPP by PDG. 23rd Apr 2020 Tom Latham * Apply copyright and licence notices to all relevant files. 17th Apr 2020 Tom Latham * Add text of GNU GPLv3 in COPYING, add (preliminary) list of authors in AUTHORS, and clean-up all source files, prior to applying copyright and licence notices. 9th Apr 2020 Tom Latham * Improve, and document use of, standalone installation script. * Apply clang-format formatting to all C++ source files. 8th Apr 2020 Tom Latham * One small modernisation change to EvtPhotosEngine to match that already applied in EvtTauolaEngine. 8th Apr 2020 John Back * Fixed NonReson amplitude and the 4-momentum boosts used for angles in EvtLambdacPHH, - courtesy of Elisabeth Niel (LHCb). 7th Apr 2020 Gerhard Raven, Tom Latham, Michal Kreps and John Back * Incorporate C++ modernization changes from Gerhard Raven (LHCb). - Merged modernize branch into master. 9th Mar 2020 John Back * Add EvtAbsExternalGen::getDecayProb() to allow external generators to return a probability that can be used in EvtDecayProb (default = 1). 6th Mar 2020 Andrii Verbytskyi and Tom Latham * Implement HepMC3 support: EvtHepMCEvent, external engines & cmake files. 15th Nov 2019 John Back * Added EvtPsi2JpsiPiPi model for psi2S -> J/psi pi+ pi- decays based on hep-ph/1507.07985, - courtesy of Aleksei Luchinsky (LHCb). 21st August 2019 Michal Kreps * Added the EvtDToKpienu decay model for D -> K pi e nu decays from BESIII, - courtesy of Liaoyuan Dong. 16th July 2019 John Back * Correct imaginary sign for EvtComplex /= (EvtComplex c) operator. 3rd July 2019 John Back * Added the EvtLambdacPHH decay model for Lc -> p K pi decays with K*(890), Delta++(1232) and Lambda(1520) resonances, based on the Fermilab E791 analysis hep-ex/9912003v1, - courtesy of Elisabeth Niel and Patrick Robbe (LHCb). * Modified EvtResonance2 to accept other barrier factor radii. 3rd July 2019 Michal Kreps * Make sure minimum mass for resonances with non-zero widths is larger than 1e-4 GeV in EvtRelBreitWignerBarrierFact. 3rd May 2019 John Back * Corrected EvtSLDiBaryonAmp bugs/issues in the BToDiBaryonlnupQCD model: - parity, amplitude terms and B momentum reference frame variables. * Corrected treament of spinor indices in EvtRareLb2Lll, - courtesy of Tom Blake and Michal Kreps (LHCb). * Updated the EvtBcVHad model to also handle Bc -> psi Ks K decays, - courtesy of Aleksei Luchinsky (LHCb). * Add new decay model EvtBsMuMuKK (BS_MUMUKK) for Bs to J/psi (mu+mu-) K+K-, - courtesy of Veronika Chobanova, Jeremy Dalseno, Diego Martinez Santos and Marcos Romero Lamas (LHCb). * Fix infinite loop during initialisation of the EvtBTo3hCP model via EvtCBTo3piP00 and EvtCBTo3piMPP, - courtesy of Peter Richardson (Durham). 15th March 2019 Tom Latham * Implement cmake build system, replacing the old config method. 30th Jan 2019 John Back * Fix modernization compiler errors and warnings. 29th Jan 2019 Michal Kreps * Allow reading decay files which are missing end-of-line before end-of-file. 21st December 2018 John Back * Imported C++ modernization changes from Gerhard Raven (LHCb). 7th December 2018 John Back * Added the EvtBLLNuL (BLLNUL) model that generates rare B -> ell ell nu ell decays, where ell = e or mu, - courtesy of Anna Danilina and Nikolai Nikitin (LHCb). * Removed the EvtB2MuMuMuNu (BUTOMMMN) model, since its now replaced by the more general BLLNuL one. 5th November 2018 John Back * Added the BToDiBaryonlnupQCD model for generating B to p N* l nu decays, where N can be any (exited) charged baryon (spin 1/2 or 3/2), - courtesy of Mark Smith and Ryan Newcombe (LHCb), with added code optimisations. 17th October 2018 John Back * Added various decay models from LHCb EvtGenExtras package: - EvtBcVHad ("BC_VHAD"), - Evtbs2llGammaMNT ("BSTOGLLMNT"), - Evtbs2llGammaISRFSR ("BSTOGLLISRFSR"), - EvtbTosllMS ("BTOSLLMS"), - EvtbTosllMSExt ("BTOSLLMSEXT"), - EvtLb2Baryonlnu ("Lb2Baryonlnu"), - EvtLb2plnuLCSR ("Lb2plnuLCSR"), - EvtLb2plnuLQCD ("Lb2plnuLQCD"), - EvtFlatSqDalitz ("FLATSQDALITZ"), - EvtPhspFlatLifetime ("PHSPFLATLIFETIME"). 5th October 2018 John Back * Updated setupEvtGen.sh to work with the new HepForge Phabricator site. 13th March 2018 John Back * Updated EvtPythiaEngine to correctly handle updates of various particle properties so that Pythia uses the same information as EvtGen (evt.pdl) for the generic and alias PYTHIA decay model. 12th March 2018 John Back * Updated EvtBcXMuNu models (X = Scalar, Vector, Tensor) to generate Bc to D0(star) mu nu decays, with associated form factors in EvtBCXFF, - courtesy of Aleksei Luchinsky (LHCb). * Also generalised the calculation of their maximum probabilities by reusing the CalcMaxProb method in EvtSemiLeptonicAmp, which now allows for different Q^2 binning (default remains at 25 bins). === ## R01-07-00 13th December 2017 John Back * New tag incorporating all changes below. * Recommended external packages are (as used in the setupEvtGen.sh script): - HepMC 2.06.09, - pythia 8.230, - Photos++ 3.61 - Tauola++ 1.1.6c. 12th December 2017 John Back * Changed Pythia validation example decay files to use Pythia8 codes. 6th December 2017 John Back * Modified the examples to use DECAY.DEC (see 25th April 2016) instead of DECAY_2010.DEC. Changed EvtExternalGenList to assume Pythia8 codes are used in decay files by default, which is the case for DECAY.DEC. Also updated the setupEvtGen.sh script to work with Pythia 8.2x versions. 29th November 2017 John Back * Modified EvtSVP, EvtVVP and EvtTVP models to handle both radiative and two-lepton decays, - courtesy of Aleksei Luchinsky (LHCb). 14th July 2017 John Back * Only create external generator objects if they don't already exist in EvtExternalGenFactory. * Modified configure script to work with Pythia 8.2x 5th July 2017 Michal Kreps * Register the VTOSLL model. 14th June 2017 John Back * Add isNeutralKaon() boolean function and corrected comments in EvtDDalitz. 8th May 2017 Michal Kreps * Fix bug in EvtbTosllVectorAmp to recognise Bs --> K*bar mu mu decay as b --> d ll transition. 8th May 2017 Michal Kreps * Significantly simplify way how we decide on decay mode and daughters ordering in DDalitz model. - With new code by definition all orderings of daughters in the decay file will yield same output. 4th May 2017 John Back * Further fixes to DDalitz particle ordering (including charge-conjugates): - Mode 5: D0 -> K- K0bar K+ and K+ K- K0bar - Mode 12: D0 -> pi0 pi- pi+ and pi+ pi0 pi- - Removed unneeded index ordering checks for mode 10 (D+ -> pi- pi+ pi+) and mode 11 (Ds+ -> pi- pi+ pi+) 27th April 2017 John Back * Fixed DDalitz particle ordering for mode 7: D+ -> pi+ K- K+ and K+ pi+ K- and their charge-conjugates 7th April 2017 John Back * Modified EvtGenExternal/EvtPythiaEngine to ensure that the EvtGen-based instances of Pythia8 (for generic and alias decays) use the same particle properties as defined by EvtGen, - courtesy Patrick Robbe (LHCb). 5th April 2017 Michal Kreps * Fixed indexing in copy constructor of Evt3Rank3C, which would otherwise produce an infinite loop; - bug report from David Grellscheid. 3rd November 2016 John Back * Modified EvtFlatQ2 model to work for all B -> X lepton lepton modes, as well as adding an extra phase space factor to correct for the dip at low q^2, which is enabled by using "FLATQ2 1" instead of just "FLATQ2" in the decay file, - courtesy of Marcin Chrzaszcz & Thomas Blake (LHCb). 13th October 2016 John Back * Added the TauolaCurrentOption decfile keyword to select the hadronic current in Tauola; default is the BaBar-tuned current option (int = 1). * EvtParticles can store double attributes using the functions setAttributeDouble(name, double) and getAttributeDouble(name), which can be useful for storing and retrieving amplitude weights, for example. - The analogous EvtParticle integer attribute interface remains unchanged: setAttribute(name, int) and getAttribute(name). 13th September 2016 John Back * Modified EvtTauolaEngine to use internal Tauola spin matrices for tau pair events by temporarily setting the PDG id of the mother as a boson, keeping the same 4-momentum. * The BaBar hadronic currents are now used by default. * Also added the ability to change some Tauola parameters using the "Define" keyword in decay files. * Added an example decay file illustrating the new features: validation/TauolaFiles/Btautau.dec 9th September 2016 Michal Kreps * Reimplement code in EvtBTo3pi.F, EvtBTo3piMPP.F, EvtBTo3piP00.F and EvtBToKpipi.F in C++ in order to remove dependence on Fortran compiler. - With this, there is no internal Fortran code in EvtGen. === ## R01-06-00 1st June 2016 John Back * New tag incorporating all changes below. * Recommended external packages are - HepMC 2.06.09 - pythia 8.186 - Photos++ 3.61 - Tauola++ 1.1.5 28th April 2016 Michal Kreps * For Ds+ --> 2pi+ pi- there was double counting of branching fraction resulting in total branching fraction being 1.5 times larger than measured one. - Fix by revisiting submodes, which now fill total Ds --> 3pi. 25th April 2016 Michal Kreps * Added DECAY.DEC/XML, which contain updated semileptonic charm and beauty branching fractions using the 2014 PDG, tuned to minimize disagreements between measurements and EvtGen for both inclusive and exclusive decays. * Updated the evt.pdl particle properties file to the PDG 2014 edition. * Implemented new LQCD form factors for Lb --> L mu mu from arXiv paper 1602.01399 (EvtRareLbToLllFFlQCD); old LQCD form factors are removed. 18th March 2016 John Back * Fixed incorrect spinor algebra used in S1 -> 1/2 S2, 1/2 -> S3 S4 decays in EvtDiracParticle::rotateToHelicityBasis() functions, - courtesy of Luis Miguel Garcia Martin and the IFIC Valencia LHCb group. 19th Feburary 2016 John Back * Fixed bug in the definition of the initial spinor term Sinit in EvtRareLbToLll::HadronicAmpRS(), - from Tom Blake (LHCb). 12th February 2016 John Back * From LHCb, added extensions to the EvtHQET2(FF) model for semitauonic decays from Brian Hamilton, which needs a patch to EvtSemiLeptonicAmp from Jack Wimberley to ensure that the q^2 range is physical when finding the maximum amplitude probability. 2nd December 2015 John Back * From LHCb, added EvtKStopizmumu model for KS -> pi0 mu mu decays based on JHEP08(1998)004, - courtesy of Veronika Chobanova, Diego Martinez Santos and Jeremy Dalseno. * Added EvtConst::Fermi for Fermi coupling constant. === ## R01-05-00 21st October 2015 John Back * New tag incorporating all changes below. * Recommended external packages are - HepMC 2.06.09 - pythia 8.186 - Photos++ 3.61 - Tauola++ 1.1.5 * Added the EvtB2MuMuMuNu model for simulating the very rare four-leptonic decays B- -> mu+ mu- anti-nu_mu mu-, - courtesy Nikolai Nikitin. 16th October 2015 John Back * Updated the configure script to automatically select the library names for PHOTOS++; version 3.56 and below uses Fortran, version 3.61 and above uses C++ only (default). Avoid using v3.60, since it does not work. This needs the PHOTOS libraries built before EvtGen is configured. Modified setupEvtGen.sh to use Photos++ v3.61. 7th October 2015 John Back * Updated EvtGenExternal/EvtPhotosEngine to check that additional particles from the outgoing vertex are indeed (FSR) photons, since later versions of PHOTOS introduce pair emission, where particles may not always be photons. * Added the genRootDecayChain.cc validation program to create ROOT files containing information about the complete decay tree. Two example test decay files BKstarGamma.dec and BuDst0rhop.dec can be used with this; the first tests PHOTOS, the second looks at sequential decay chain storage. The plotBKstarGamma.C ROOT macro can be used for B -> K* gamma plots. 2nd October 2015 John Back * Modified EvtSVPHelAmp and added a new EvtSVPHelCPMix model, implementing the complete mixing phenomenology of Bs to vector gamma decays, - courtesy of Clara Remon (LHCb). * EvtD0mixDalitz code: cleanup, inverted q/p for decays of D0bar (simplifies user decay files) and fixed y parameter bug, - courtesy of Jordi Tico (LHCb). * Changed the initialisation order of the infrared cut-off in EvtPhotosEngine. This actually has no effect, since the exponentiation function sets it to the same 1e-7 value, but it is now in the correct order if we need to update it. * Removed all remaining obsolete pragma (Win32) warnings from some classes. 23rd September 2015 Michal Kreps * Reimplement the real Spence function in C++ and removed its fortran implementation. 15th September 2015 Michal Kreps * Fixed accessed uninitialised memory in EvtPDL.cpp, line 213. * Modified the configure and setupEvtGen.sh scripts to work on Mac; needed Mac compilation patch files added to the new "platform" subdirectory. 10th September 2015 John Back * Updated setupEvtGen.sh to use the recommended external packages: - HepMC 2.06.09, pythia 8.186, Photos++ 3.56 and Tauola++ 1.1.5. * Fixed form-factor calculations for the BTOSLLBALL model 6 used to generate b -> sll decays, - courtesy of Christoph Langenbruch and David Loh (LHCb). - Affects B->K*ll, B->rholl and B->omegall, particularly the electron modes. * In the validation directory, added runPhotosTest.sh for testing FSR in Upsilon(4S) -> e+ e- decays, and changed the plot comparison scripts to use the 2nd directory "oldRootFiles" (which could be a soft-link) for including ROOT histograms made from a previous version of EvtGen. 27th August 2015 John Back * Added Mersenne-Twister random number generator (RNG) EvtMTRandomEngine. - It requires c++11 compiler features (>= gcc 4.7), which should automatically be enabled by the configure script. - Introduced the preprocessor environment variable EVTGEN_CPP11 for c++11 features. - EvtMTRandomEngine is the default RNG for the validation and test examples if c++11 features are enabled. * Added a phase-space test validation/genPHSP.sh and PhaseSpacePlots.C to visually check the flatness of Dalitz plots in order to ensure that the RNG is not producing biased results that depend on particle ordering. * Added the models EvtbsToLLLLAmp and EvtbsToLLLLHyperCP for B0_q -> l+ l- l+ l- decays (SM and one supersymmetric scenario), - courtesy of Nikolai Nikitin and Konstantin Toms. - Documentation provided in doc/evt_BQTOLLLL_model.pdf and doc/evt_BQTOLLLLHYPERCP_model.pdf. * Changed the installation and set-up script name to be just setupEvtGen.sh; it uses the VERSION variable to specify the required tag. List of tags are available using either "svn ls -v http://svn.cern.ch/guest/evtgen/tags" or by going to http://svn.cern.ch/guest/evtgen/tags in a web browser. 12th June 2015 John Back * Changed the width of chi_b1 in evt.pdl from 9.8928 GeV (!) to zero. 1st May 2015 John Back * Added Bc -> scalar ell nu (EvtBcSMuNu) and Bc -> tensor ell nu (EvtBcTMuNu) decays, - courtesy of Jack Wimberley, LHCb. - Also included the chi_c1 mode for EvtBcVMuNu. === ## R01-04-00 2nd April 2015 John Back * Removed the EvtStdlibRandomEngine class since this can produce biases to kinematic distributions when one or more of the daughters is a resonance, such as B0 -> K pi psi - (thanks to Antonio Augusto Alves Jr who discovered this issue). - EvtSimpleRandomEngine is now the default random number generator in the validation and test examples. * Incorporated several additions and modifications from LHCb: a) From Michal Kreps, Tom Blake & Christoph Langenbruch, added rare Lb --> Lambda^(*) ell ell models described in arXiv:1108.6129, with various form factors from Gutsche et al. (arXiv:1301.3737) and lattice QCD (arXiv:1212.4827) b) From Andrew Crocombe, implemented Bs --> K* form factors from Ball-Zwicky and z-parametrization form factors from arXiv:1006.4945 for EvtbTosllBallFF c) Christoph Langenbruch fixed the Bs -> phi ll form factors in EvtbTosllBallFF; T3 showed a non-physical pole at very low q2 which significantly affected the electron mode d) From Michal Kreps, removed semicolons from wrong places to clear warnings when compiled with the "-pedantic" option. 9th October 2014 John Back * Change svnweb.cern.ch to svn.cern.ch in the setup script. 1st April 2014 John Back * In EvtReport, modified the logging output severity status flags to have the "EVTGEN_" prefix, e.g. INFO becomes EVTGEN_INFO. * The global report() function has been renamed to EvtGenReport(). 31st March 2014 John Back * Added the ability to store named attributes for EvtParticles in the form of a map. The setAttribute(name, value) stores the required value, while getAttribute(name) retrieves the integer value. This is used in EvtPhotosEngine to specify the final-state radiation "FSR" attribute to 1 for any additional photons (EvtPhotonParticles) created by Photos++. It also stores the "ISR" attribute, but this is always set to zero, since only FSR photons are created. If the named attribute does not exist, then getAttribute() returns zero. 29th January 2014 Daniel Craik * Removed mass assertion on GS shape in EvtDalitzReso to allow it to also be used for charged rho resonances. 27th January 2014 John Back * Minor corrections to Vub models to remove further gcc 4.8 warnings. * Updated configure script to work for MacOS clang (from Genser team). === ## R01-03-00 9th January 2014 John Back * New tag version "1.3.0", incorporating all changes below. * Replaced auto-install script to work with this version as well as the latest versions of all external generator packages. * Updated README to mention the new CERN-based web pages for Photos++ and Tauola++. 8th January 2014 John Back * Fix gcc 4.6 and 4.8 compilation warnings, - courtesy of Patrick Robbe (LHCb); - main changes are removal of unused variables. * Changed the EvtPythiaEngine class and configure script to use new Pythia 8 header locations; Pythia 8.180 or above is now required. 7th January 2014 John Back * Modified EvtBCVFF to correct the Kiselev form factors - from Jack Wimberley (LHCb). 9th October 2013 Daniel Craik * Added Gounaris-Sakurai and Gaussian shapes to EvtGenericDalitz and set sensible defaults for LASS parameters. 19th September 2013 John Back * Modified EvtGenExternal/EvtPythiaEngine to keep track of any new particles that are added to the default Pythia database to avoid duplicating particle/anti-particle entries that could override previously defined Pythia decay chains. 18th September 2013 John Back * Added Mac OS flags for the configure script and src/Makefile. 15th July 2013 Daniel Craik * Added flag to turn on scaling of LASS amplitude by M/q in EvtDalitzReso 15th July 2013 Daniel Craik * EvtParserXML now accepts file names containing environment variables, exponential non-resonant shape in EvtDalitzReso now defined as exp(-alpha*m^2), LASS shape in EvtDalitzReso now takes a cutoff parameter 4th July 2013 Daniel Craik * Added LASS, exponential non-resonant and linear non-resonant shapes to EvtGenericDalitz. 3rd July 2013 Daniel Craik * Fixed auto-install script for R01-02-00. 1st July 2013 Daniel Craik * Added auto-install script for R01-02-00. === ## R01-02-00 15th May 2013 John Back * New tag, version "1.2.0", incorporating all changes below. 14th May 2013 Michal Kreps * Added Blatt-Weisskopf barrier factors up to L=5 in EvtGenBase/EvtBlattWeisskopf::compute(). 14th May 2013 John Back * Added additional entries (appended at the end) to the evt.pdl particle data file - courtesy of Romulus Godang and Belle II colleagues. 14th March 2013 John Back * Added the method EvtParticle::getPDGId() to get the PDG integer for a particle directly (which just calls EvtPDL::getStdHep()). * Added a check in EvtPhotosEngine::doDecay to skip Photos if a given particle has too many daughters (>= 10) to avoid a problem with a hard coded upper limit in the Photos PHOENE subroutine. 2nd February 2013 Daniel Craik * Updated EvtDalitzTable to estimate probMax when it is missing from a Dalitz model. 1st February 2013 John Back * Added the ability to read in Pythia 6 commands in ascii decay files in EvtDecayTable::readDecayFile (this was already possible in xml files). * Modified the Photos++ engine default settings to be more suited to B decays (from LHCb defaults). 31st January 2013 John Back * Added the ability to read in Pythia 8 commands in ascii decay files in EvtDecayTable::readDecayFile. They can be set using the syntax: "PythiaTypeParam module:variable=value", where Type = Generic, Alias or Both for specifying whether the parameter is for the generic or alias Pythia decay engines (or both). The 2nd argument must not contain any spaces. Fixed the list of commands strings being used in the EvtPythiaEngine class (i.e. Pythia parameters that can be set via decay files). 31st January 2013 Daniel Craik * Added named parameters to various decay models. 30th January 2013 John Back * Fixed some of the parameter arguments used in the EvtSVSCPiso model. 24th January 2013 John Back * Set the Photos++ and Tauola++ models to use the EvtGen random number engine when useEvtGenRandom is set to true in the EvtExternalGenList constructor. 23rd January 2013 John Back * Added EvtGenExternal/EvtPythiaRandom to allow the use of the EvtGen random number engine to also be used for the random engine for Pythia 8. * Added a boolean (useEvtGenRandom, default = true) within the EvtExternalGenList constructor to use this feature. 18th December 2012 John Back * Corrected some wrong daughter ordering assignments for decay modes 5 and 12 in EvtDDalitz. Updated validation/DalitzDecays.xml to also contain D decay mode 12, as well as various modes that may use K_S0 and K_L0. * Added validation/genDDalitzModes.sh and updated validation/compareDalitz.C to do a complete comparison of the D Dalitz modes with the xml versions. 11th December 2012 Daniel Craik * Updated the Xml parser to support named model parameters. * Updated the generic Dalitz model to use named model parameters as an example. 15th October 2012 John Back * Make EvtSimpleRandomEngine inherit from EvtRandomEngine to avoid crash in EvtGen.cpp when no random engine is defined - (from Bjoern Spruck). === ## R01-01-00 4th October 2012 John Back * New tag, version "1.1.0", incorporating all changes below. * Provide proper default constructors for EvtVector4R and EvtPhotonParticle. Modified the validation and test code to also compile/link in the case of no external generators being included. 3rd October 2012 John Back * Corrected the t3 vector form factor values for the Ball-Zwicky 2005 model (modelId = 6) in EvtbTosllBallFF::getVectorFF(), which were set to t3tilde instead. 18th September 2012 John Back * Moved the external generator engines to a new sub-directory EvtGenExternal. Building the code now creates 2 libraries: libEvtGen.so (Base+Models) and libEvtGenExternal.so. - This allows anyone to ignore using the new external generators if required (by not creating/loading the 2nd library). * Added prefix option to the configure script/Makefile to allow the user to specify an installation directory for the include files, libraries, DECAY.DEC and evt.pdl files (for Genser). 14th September 2012 Michal Kreps * Fixed the calculation of the angle between decay planes in the function EvtKine::EvtDecayAngleChi. Fixed typo in EvtLb2Lll decay model. Only some NP scenarious could be affected, SM one is definitely unaffected. 13th September 2012 John Back * Added the use of the environment variables EVTGEN_PHOTOS, EVTGEN_PYTHIA and EVTGEN_TAUOLA to specify if the Photos, Pythia and/or Tauola engine classes are used or not. These variables are set by the configure script, depending if the library paths are specified for these generators. === ## R01-00-01 12th September 2012 John Back * New tag incorporating all changes below, since R01-00-00. 11th September 2012 John Back * Modified the Photos and Tauola engine classes to use the new Photospp and Tauolapp namespaces that are present in the latest versions of Photos++(3.5) and Tauola++(1.0.7). * Updated the configure file to get the correct location of the Tauola++ include files. * Added the D0->pi+pi-pi0 decay mode in EvtDDalitz - from Marco Gersabeck and Frederic Dreyer (LHCb). * Added new decay models/classes from Alexey Luchinsky (LHCb): EvtBcVMuNu, EvtTVP, EvtWnPi, EvtSVP, EvtXPsiGamma, EvtBcVNpi 29th June 2012 John Back * Corrected mass(squared) variables filled in the Dalitz TTree in validation/genExampleRootFiles. 15th May 2012 Daniel Craik * Updated EvtD0gammaDalitz to deal with D mesons from neutral B->DK * Added save function to validation/compareDalitz.C. 11th May 2012 Daniel Craik * Replaced BaBar specific configuration for BlattWeisskopf birth factors. * Updated XML conversion script to handle new configuration. * Fixed some bugs in the XML conversion script related to particle modifications. 9th May 2012 Daniel Craik * Added latex documentation for xml decay files. 2nd May 2012 Daniel Craik * Added resDaughters attribute to the Dalitz resonance xml tag to simplify defining symmetric resonances. Updated validation xml files to use the new functionality. 27th April 2012 Daniel Craik * Upgraded EvtGenericDalitz to use EvtDalitzReso for resonances. * Added validation to compare EvtGenericDalitz to all 11 EvtDDalitz modes. * Added a root macro to quickly compare two Dalitz decays for validation. 24th April 2012 John Back * Solved two bugs in the EvtD0gammaDalitz model (from Jordi Tico, LHCb): configuration of the conjugated model, and using only the B charge to determine the model used, not the D flavour. 17th April 2012 Daniel Craik * Updated the GenericDalitz validation code to use the same probMax values as DDalitz. * Added XML decay file parsing to EvtGen::readUDecay. - Dec files are still the default. 30th March 2012 John Back * Update maximum probability values in EvtDDalitz::initProbMax() for all DDalitz modes. 23rd March 2012 John Back * Added the EvtEta2MuMuGamma decay model from LHCb. 21st March 2012 John Back * Added EvtD0gammaDalitz decay model from LHCb. 20th March 2012 Daniel Craik * Added backwards compatibility for Pythia 6 commands in the XML configuration. * Updated decay file conversion tool to convert JetSetPar lines to pythia6Param tags. 19th March 2012 Daniel Craik * Added infrastructure to pass commands to external generators. * XML config now takes Pythia8 configuration commands. 16th March 2012 Daniel Craik * Added the ability to define particles from the PDL for Dalitz decay resonances instead of defining mass, width and spin seperately. * Renamed the lifetime attribute of Dalitz decay resonaces to width to avoid confusion. * Added further validation code for the generic Dalitz model. 15th March 2012 Daniel Craik * Added validation code for xml decay files and the generic Dalitz model. === ## R01-00-00 6th March 2012 John Back * First official version for Genser (evtgen 1.0.0) that includes support for external generators: Pythia8, Photos++ and Tauola++. * This also includes a preliminary version of creating Dalitz plot decay models using EvtGenericDalitz. diff --git a/src/EvtGenBase/EvtIdSet.cpp b/src/EvtGenBase/EvtIdSet.cpp index 75e5fb1..64dcfd4 100644 --- a/src/EvtGenBase/EvtIdSet.cpp +++ b/src/EvtGenBase/EvtIdSet.cpp @@ -1,492 +1,492 @@ /*********************************************************************** * 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/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtPatches.hh" #include #include EvtIdSet::EvtIdSet( const EvtId name1 ) { _numInList = 1; _list = new EvtId[_numInList]; _list[0] = name1; } EvtIdSet::EvtIdSet( const std::string name1 ) { _numInList = 1; _list = new EvtId[_numInList]; _list[0] = EvtPDL::getId( name1 ); } EvtIdSet::EvtIdSet( const EvtId name1, const EvtId name2 ) { _numInList = 2; _list = new EvtId[_numInList]; _list[0] = name1; _list[1] = name2; } EvtIdSet::EvtIdSet( const std::string name1, const std::string name2 ) { _numInList = 2; _list = new EvtId[_numInList]; _list[0] = EvtPDL::getId( name1 ); _list[1] = EvtPDL::getId( name2 ); } EvtIdSet::EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3 ) { _numInList = 3; _list = new EvtId[_numInList]; _list[0] = name1; _list[1] = name2; _list[2] = name3; } EvtIdSet::EvtIdSet( const std::string name1, const std::string name2, const std::string name3 ) { _numInList = 3; _list = new EvtId[_numInList]; _list[0] = EvtPDL::getId( name1 ); _list[1] = EvtPDL::getId( name2 ); _list[2] = EvtPDL::getId( name3 ); } EvtIdSet::EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4 ) { _numInList = 4; _list = new EvtId[_numInList]; _list[0] = name1; _list[1] = name2; _list[2] = name3; _list[3] = name4; } EvtIdSet::EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4 ) { _numInList = 4; _list = new EvtId[_numInList]; _list[0] = EvtPDL::getId( name1 ); _list[1] = EvtPDL::getId( name2 ); _list[2] = EvtPDL::getId( name3 ); _list[3] = EvtPDL::getId( name4 ); } EvtIdSet::EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5 ) { _numInList = 5; _list = new EvtId[_numInList]; _list[0] = name1; _list[1] = name2; _list[2] = name3; _list[3] = name4; _list[4] = name5; } EvtIdSet::EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5 ) { _numInList = 5; _list = new EvtId[_numInList]; _list[0] = EvtPDL::getId( name1 ); _list[1] = EvtPDL::getId( name2 ); _list[2] = EvtPDL::getId( name3 ); _list[3] = EvtPDL::getId( name4 ); _list[4] = EvtPDL::getId( name5 ); } EvtIdSet::EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6 ) { _numInList = 6; _list = new EvtId[_numInList]; _list[0] = name1; _list[1] = name2; _list[2] = name3; _list[3] = name4; _list[4] = name5; _list[5] = name6; } EvtIdSet::EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6 ) { _numInList = 6; _list = new EvtId[_numInList]; _list[0] = EvtPDL::getId( name1 ); _list[1] = EvtPDL::getId( name2 ); _list[2] = EvtPDL::getId( name3 ); _list[3] = EvtPDL::getId( name4 ); _list[4] = EvtPDL::getId( name5 ); _list[5] = EvtPDL::getId( name6 ); } EvtIdSet::EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6, const EvtId name7 ) { _numInList = 7; _list = new EvtId[_numInList]; _list[0] = name1; _list[1] = name2; _list[2] = name3; _list[3] = name4; _list[4] = name5; _list[5] = name6; _list[6] = name7; } EvtIdSet::EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6, const std::string name7 ) { _numInList = 7; _list = new EvtId[_numInList]; _list[0] = EvtPDL::getId( name1 ); _list[1] = EvtPDL::getId( name2 ); _list[2] = EvtPDL::getId( name3 ); _list[3] = EvtPDL::getId( name4 ); _list[4] = EvtPDL::getId( name5 ); _list[5] = EvtPDL::getId( name6 ); _list[6] = EvtPDL::getId( name7 ); } EvtIdSet::EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6, const EvtId name7, const EvtId name8 ) { _numInList = 8; _list = new EvtId[_numInList]; _list[0] = name1; _list[1] = name2; _list[2] = name3; _list[3] = name4; _list[4] = name5; _list[5] = name6; _list[6] = name7; _list[7] = name8; } EvtIdSet::EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6, const std::string name7, const std::string name8 ) { _numInList = 8; _list = new EvtId[_numInList]; _list[0] = EvtPDL::getId( name1 ); _list[1] = EvtPDL::getId( name2 ); _list[2] = EvtPDL::getId( name3 ); _list[3] = EvtPDL::getId( name4 ); _list[4] = EvtPDL::getId( name5 ); _list[5] = EvtPDL::getId( name6 ); _list[6] = EvtPDL::getId( name7 ); _list[7] = EvtPDL::getId( name8 ); } EvtIdSet::EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6, const EvtId name7, const EvtId name8, const EvtId name9 ) { _numInList = 9; _list = new EvtId[_numInList]; _list[0] = name1; _list[1] = name2; _list[2] = name3; _list[3] = name4; _list[4] = name5; _list[5] = name6; _list[6] = name7; _list[7] = name8; _list[8] = name9; } EvtIdSet::EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6, const std::string name7, const std::string name8, const std::string name9 ) { _numInList = 9; _list = new EvtId[_numInList]; _list[0] = EvtPDL::getId( name1 ); _list[1] = EvtPDL::getId( name2 ); _list[2] = EvtPDL::getId( name3 ); _list[3] = EvtPDL::getId( name4 ); _list[4] = EvtPDL::getId( name5 ); _list[5] = EvtPDL::getId( name6 ); _list[6] = EvtPDL::getId( name7 ); _list[7] = EvtPDL::getId( name8 ); _list[8] = EvtPDL::getId( name9 ); } EvtIdSet::EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6, const EvtId name7, const EvtId name8, const EvtId name9, const EvtId name10 ) { _numInList = 10; _list = new EvtId[_numInList]; _list[0] = name1; _list[1] = name2; _list[2] = name3; _list[3] = name4; _list[4] = name5; _list[5] = name6; _list[6] = name7; _list[7] = name8; _list[8] = name9; _list[9] = name10; } EvtIdSet::EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6, const std::string name7, const std::string name8, const std::string name9, const std::string name10 ) { _numInList = 10; _list = new EvtId[_numInList]; _list[0] = EvtPDL::getId( name1 ); _list[1] = EvtPDL::getId( name2 ); _list[2] = EvtPDL::getId( name3 ); _list[3] = EvtPDL::getId( name4 ); _list[4] = EvtPDL::getId( name5 ); _list[5] = EvtPDL::getId( name6 ); _list[6] = EvtPDL::getId( name7 ); _list[7] = EvtPDL::getId( name8 ); _list[8] = EvtPDL::getId( name9 ); _list[9] = EvtPDL::getId( name10 ); } EvtIdSet::EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6, const EvtId name7, const EvtId name8, const EvtId name9, const EvtId name10, const EvtId name11 ) { _numInList = 11; _list = new EvtId[_numInList]; _list[0] = name1; _list[1] = name2; _list[2] = name3; _list[3] = name4; _list[4] = name5; _list[5] = name6; _list[6] = name7; _list[7] = name8; _list[8] = name9; _list[9] = name10; _list[10] = name11; } EvtIdSet::EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6, const std::string name7, const std::string name8, const std::string name9, const std::string name10, const std::string name11 ) { _numInList = 11; _list = new EvtId[_numInList]; _list[0] = EvtPDL::getId( name1 ); _list[1] = EvtPDL::getId( name2 ); _list[2] = EvtPDL::getId( name3 ); _list[3] = EvtPDL::getId( name4 ); _list[4] = EvtPDL::getId( name5 ); _list[5] = EvtPDL::getId( name6 ); _list[6] = EvtPDL::getId( name7 ); _list[7] = EvtPDL::getId( name8 ); _list[8] = EvtPDL::getId( name9 ); _list[9] = EvtPDL::getId( name10 ); _list[10] = EvtPDL::getId( name11 ); } EvtIdSet::EvtIdSet( const EvtId name1, const EvtId name2, const EvtId name3, const EvtId name4, const EvtId name5, const EvtId name6, const EvtId name7, const EvtId name8, const EvtId name9, const EvtId name10, const EvtId name11, const EvtId name12 ) { _numInList = 12; _list = new EvtId[_numInList]; _list[0] = name1; _list[1] = name2; _list[2] = name3; _list[3] = name4; _list[4] = name5; _list[5] = name6; _list[6] = name7; _list[7] = name8; _list[8] = name9; _list[9] = name10; _list[10] = name11; _list[11] = name12; } EvtIdSet::EvtIdSet( const std::string name1, const std::string name2, const std::string name3, const std::string name4, const std::string name5, const std::string name6, const std::string name7, const std::string name8, const std::string name9, const std::string name10, const std::string name11, const std::string name12 ) { _numInList = 12; _list = new EvtId[_numInList]; _list[0] = EvtPDL::getId( name1 ); _list[1] = EvtPDL::getId( name2 ); _list[2] = EvtPDL::getId( name3 ); _list[3] = EvtPDL::getId( name4 ); _list[4] = EvtPDL::getId( name5 ); _list[5] = EvtPDL::getId( name6 ); _list[6] = EvtPDL::getId( name7 ); _list[7] = EvtPDL::getId( name8 ); _list[8] = EvtPDL::getId( name9 ); _list[9] = EvtPDL::getId( name10 ); _list[10] = EvtPDL::getId( name11 ); _list[11] = EvtPDL::getId( name12 ); } EvtIdSet::EvtIdSet( const EvtIdSet& set1 ) { _numInList = set1.sizeOfSet(); _list = new EvtId[_numInList]; int i; for ( i = 0; i < _numInList; i++ ) { _list[i] = set1.getElem( i ); } } EvtIdSet::EvtIdSet( const EvtIdSet& set1, const EvtIdSet& set2 ) { _numInList = set1.sizeOfSet(); _list = new EvtId[_numInList]; int i; for ( i = 0; i < _numInList; i++ ) { _list[i] = set1.getElem( i ); } //then just append the second list. this->append( set2 ); } -int EvtIdSet::contains( const EvtId id ) +int EvtIdSet::contains( const EvtId id ) const { int i; for ( i = 0; i < _numInList; i++ ) { if ( _list[i] == id ) return 1; } return 0; } -int EvtIdSet::contains( const std::string nm ) +int EvtIdSet::contains( const std::string nm ) const { int i; for ( i = 0; i < _numInList; i++ ) { if ( _list[i] == EvtPDL::getId( nm ) ) return 1; } return 0; } void EvtIdSet::append( const EvtIdSet set1 ) { int combLen = _numInList + set1.sizeOfSet(); int uniqueLen = 0; EvtId* combSet; combSet = new EvtId[combLen]; int i; for ( i = 0; i < combLen; i++ ) { if ( i >= _numInList ) { //check that there are no overlaps between lists int j; int isUnique = 1; for ( j = 0; j < _numInList; j++ ) { if ( _list[j] == set1.getElem( i - _numInList ) ) { isUnique = 0; } } if ( isUnique == 1 ) { combSet[uniqueLen] = set1.getElem( i - _numInList ); uniqueLen += 1; } } else { combSet[uniqueLen] = _list[i]; uniqueLen += 1; } delete _list; _list = new EvtId[uniqueLen]; _numInList = uniqueLen; for ( i = 0; i < _numInList; i++ ) { _list[i] = combSet[i]; } delete combSet; } } int EvtIdSet::sizeOfSet() const { return _numInList; } EvtId EvtIdSet::getElem( const int i ) const { return _list[i]; } diff --git a/src/EvtGenBase/EvtParticle.cpp b/src/EvtGenBase/EvtParticle.cpp index 8022bda..2184fb5 100644 --- a/src/EvtGenBase/EvtParticle.cpp +++ b/src/EvtGenBase/EvtParticle.cpp @@ -1,1319 +1,1314 @@ /*********************************************************************** * 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/EvtParticle.hh" #include "EvtGenBase/EvtCPUtil.hh" #include "EvtGenBase/EvtDecayTable.hh" #include "EvtGenBase/EvtDiracParticle.hh" #include "EvtGenBase/EvtGenKine.hh" #include "EvtGenBase/EvtId.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtNeutrinoParticle.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtParticleFactory.hh" #include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtPhotonParticle.hh" #include "EvtGenBase/EvtRadCorr.hh" #include "EvtGenBase/EvtRandom.hh" #include "EvtGenBase/EvtRaritaSchwingerParticle.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtScalarParticle.hh" #include "EvtGenBase/EvtSecondary.hh" #include "EvtGenBase/EvtStatus.hh" #include "EvtGenBase/EvtStdHep.hh" #include "EvtGenBase/EvtStringParticle.hh" #include "EvtGenBase/EvtTensorParticle.hh" #include "EvtGenBase/EvtVectorParticle.hh" #include #include #include #include #include using std::endl; EvtParticle::~EvtParticle() { delete _decayProb; } EvtParticle::EvtParticle() { _ndaug = 0; _parent = 0; _channel = -10; _t = 0.0; _genlifetime = 1; _first = 1; _isInit = false; _validP4 = false; _isDecayed = false; _decayProb = 0; _intAttributes.clear(); _dblAttributes.clear(); // _mix=false; } void EvtParticle::setFirstOrNot() { _first = 0; } void EvtParticle::resetFirstOrNot() { _first = 1; } void EvtParticle::setChannel( int i ) { _channel = i; } -EvtParticle* EvtParticle::getDaug( int i ) -{ - return _daug[i]; -} - EvtParticle* EvtParticle::getParent() const { return _parent; } void EvtParticle::setLifetime( double tau ) { _t = tau; } void EvtParticle::setLifetime() { if ( _genlifetime ) { _t = -log( EvtRandom::Flat() ) * EvtPDL::getctau( getId() ); } } double EvtParticle::getLifetime() { return _t; } void EvtParticle::addDaug( EvtParticle* node ) { node->_daug[node->_ndaug++] = this; _ndaug = 0; _parent = node; } int EvtParticle::firstornot() const { return _first; } EvtId EvtParticle::getId() const { return _id; } int EvtParticle::getPDGId() const { return EvtPDL::getStdHep( _id ); } EvtSpinType::spintype EvtParticle::getSpinType() const { return EvtPDL::getSpinType( _id ); } int EvtParticle::getSpinStates() const { return EvtSpinType::getSpinStates( EvtPDL::getSpinType( _id ) ); } const EvtVector4R& EvtParticle::getP4() const { return _p; } int EvtParticle::getChannel() const { return _channel; } size_t EvtParticle::getNDaug() const { return _ndaug; } double EvtParticle::mass() const { return _p.mass(); } void EvtParticle::setDiagonalSpinDensity() { _rhoForward.setDiag( getSpinStates() ); } void EvtParticle::setVectorSpinDensity() { if ( getSpinStates() != 3 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Error in EvtParticle::setVectorSpinDensity" << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "spin_states:" << getSpinStates() << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "particle:" << EvtPDL::name( _id ).c_str() << endl; ::abort(); } EvtSpinDensity rho; //Set helicity +1 and -1 to 1. rho.setDiag( getSpinStates() ); rho.set( 1, 1, EvtComplex( 0.0, 0.0 ) ); setSpinDensityForwardHelicityBasis( rho ); } void EvtParticle::setSpinDensityForwardHelicityBasis( const EvtSpinDensity& rho ) { EvtSpinDensity R = rotateToHelicityBasis(); assert( R.getDim() == rho.getDim() ); int n = rho.getDim(); _rhoForward.setDim( n ); int i, j, k, l; for ( i = 0; i < n; i++ ) { for ( j = 0; j < n; j++ ) { EvtComplex tmp = 0.0; for ( k = 0; k < n; k++ ) { for ( l = 0; l < n; l++ ) { tmp += R.get( l, i ) * rho.get( l, k ) * conj( R.get( k, j ) ); } } _rhoForward.set( i, j, tmp ); } } } void EvtParticle::setSpinDensityForwardHelicityBasis( const EvtSpinDensity& rho, double alpha, double beta, double gamma ) { EvtSpinDensity R = rotateToHelicityBasis( alpha, beta, gamma ); assert( R.getDim() == rho.getDim() ); int n = rho.getDim(); _rhoForward.setDim( n ); int i, j, k, l; for ( i = 0; i < n; i++ ) { for ( j = 0; j < n; j++ ) { EvtComplex tmp = 0.0; for ( k = 0; k < n; k++ ) { for ( l = 0; l < n; l++ ) { tmp += R.get( l, i ) * rho.get( l, k ) * conj( R.get( k, j ) ); } } _rhoForward.set( i, j, tmp ); } } } void EvtParticle::initDecay( bool useMinMass ) { EvtParticle* p = this; // carefull - the parent mass might be fixed in stone.. EvtParticle* par = p->getParent(); double parMass = -1.; if ( par != 0 ) { if ( par->hasValidP4() ) parMass = par->mass(); for ( size_t i = 0; i < par->getNDaug(); i++ ) { EvtParticle* tDaug = par->getDaug( i ); if ( p != tDaug ) parMass -= EvtPDL::getMinMass( tDaug->getId() ); } } if ( _isInit ) { //we have already been here - just reroll the masses! if ( _ndaug > 0 ) { for ( size_t ii = 0; ii < _ndaug; ii++ ) { if ( _ndaug == 1 || EvtPDL::getWidth( p->getDaug( ii )->getId() ) > 0.0000001 ) p->getDaug( ii )->initDecay( useMinMass ); else p->getDaug( ii )->setMass( EvtPDL::getMeanMass( p->getDaug( ii )->getId() ) ); } } EvtId* dauId = 0; double* dauMasses = 0; if ( _ndaug > 0 ) { dauId = new EvtId[_ndaug]; dauMasses = new double[_ndaug]; for ( size_t j = 0; j < _ndaug; j++ ) { dauId[j] = p->getDaug( j )->getId(); dauMasses[j] = p->getDaug( j )->mass(); } } EvtId* parId = 0; EvtId* othDauId = 0; EvtParticle* tempPar = p->getParent(); if ( tempPar ) { parId = new EvtId( tempPar->getId() ); if ( tempPar->getNDaug() == 2 ) { if ( tempPar->getDaug( 0 ) == this ) othDauId = new EvtId( tempPar->getDaug( 1 )->getId() ); else othDauId = new EvtId( tempPar->getDaug( 0 )->getId() ); } } if ( p->getParent() && _validP4 == false ) { if ( !useMinMass ) { p->setMass( EvtPDL::getRandMass( p->getId(), parId, _ndaug, dauId, othDauId, parMass, dauMasses ) ); } else p->setMass( EvtPDL::getMinMass( p->getId() ) ); } if ( parId ) delete parId; if ( othDauId ) delete othDauId; if ( dauId ) delete[] dauId; if ( dauMasses ) delete[] dauMasses; return; } //Will include effects of mixing here //added by Lange Jan4,2000 static EvtId BS0 = EvtPDL::getId( "B_s0" ); static EvtId BSB = EvtPDL::getId( "anti-B_s0" ); static EvtId BD0 = EvtPDL::getId( "B0" ); static EvtId BDB = EvtPDL::getId( "anti-B0" ); static EvtId D0 = EvtPDL::getId( "D0" ); static EvtId D0B = EvtPDL::getId( "anti-D0" ); static EvtId U4S = EvtPDL::getId( "Upsilon(4S)" ); static EvtIdSet borUps( BS0, BSB, BD0, BDB, U4S ); //only makes sense if there is no parent particle which is a B or an Upsilon bool hasBorUps = false; if ( getParent() && borUps.contains( getParent()->getId() ) ) hasBorUps = true; // if ( (getNDaug()==0)&&(getParent()==0) && (getId()==BS0||getId()==BSB||getId()==BD0||getId()==BDB)){ EvtId thisId = getId(); // remove D0 mixing for now. // if ( (getNDaug()==0 && !hasBorUps) && (thisId==BS0||thisId==BSB||thisId==BD0||thisId==BDB||thisId==D0||thisId==D0B)){ if ( ( getNDaug() == 0 && !hasBorUps ) && ( thisId == BS0 || thisId == BSB || thisId == BD0 || thisId == BDB ) ) { double t; int mix; EvtCPUtil::getInstance()->incoherentMix( getId(), t, mix ); setLifetime( t ); if ( mix ) { EvtScalarParticle* scalar_part; scalar_part = new EvtScalarParticle; if ( getId() == BS0 ) { EvtVector4R p_init( EvtPDL::getMass( BSB ), 0.0, 0.0, 0.0 ); scalar_part->init( EvtPDL::chargeConj( getId() ), p_init ); } else if ( getId() == BSB ) { EvtVector4R p_init( EvtPDL::getMass( BS0 ), 0.0, 0.0, 0.0 ); scalar_part->init( EvtPDL::chargeConj( getId() ), p_init ); } else if ( getId() == BD0 ) { EvtVector4R p_init( EvtPDL::getMass( BDB ), 0.0, 0.0, 0.0 ); scalar_part->init( EvtPDL::chargeConj( getId() ), p_init ); } else if ( getId() == BDB ) { EvtVector4R p_init( EvtPDL::getMass( BD0 ), 0.0, 0.0, 0.0 ); scalar_part->init( EvtPDL::chargeConj( getId() ), p_init ); } else if ( getId() == D0 ) { EvtVector4R p_init( EvtPDL::getMass( D0B ), 0.0, 0.0, 0.0 ); scalar_part->init( EvtPDL::chargeConj( getId() ), p_init ); } else if ( getId() == D0B ) { EvtVector4R p_init( EvtPDL::getMass( D0 ), 0.0, 0.0, 0.0 ); scalar_part->init( EvtPDL::chargeConj( getId() ), p_init ); } scalar_part->setLifetime( 0 ); scalar_part->setDiagonalSpinDensity(); insertDaugPtr( 0, scalar_part ); _ndaug = 1; _isInit = true; p = scalar_part; p->initDecay( useMinMass ); return; } } EvtDecayBase* decayer; decayer = EvtDecayTable::getInstance()->getDecayFunc( p ); if ( decayer ) { p->makeDaughters( decayer->nRealDaughters(), decayer->getDaugs() ); //then loop over the daughters and init their decay for ( size_t i = 0; i < p->getNDaug(); i++ ) { // std::cout << EvtPDL::name(p->getDaug(i)->getId()) << " " << i << " " << p->getDaug(i)->getSpinType() << " " << EvtPDL::name(p->getId()) << std::endl; if ( EvtPDL::getWidth( p->getDaug( i )->getId() ) > 0.0000001 ) p->getDaug( i )->initDecay( useMinMass ); else p->getDaug( i )->setMass( EvtPDL::getMeanMass( p->getDaug( i )->getId() ) ); } } int j; EvtId* dauId = 0; double* dauMasses = 0; int nDaugT = p->getNDaug(); if ( nDaugT > 0 ) { dauId = new EvtId[nDaugT]; dauMasses = new double[nDaugT]; for ( j = 0; j < nDaugT; j++ ) { dauId[j] = p->getDaug( j )->getId(); dauMasses[j] = p->getDaug( j )->mass(); } } EvtId* parId = 0; EvtId* othDauId = 0; EvtParticle* tempPar = p->getParent(); if ( tempPar ) { parId = new EvtId( tempPar->getId() ); if ( tempPar->getNDaug() == 2 ) { if ( tempPar->getDaug( 0 ) == this ) othDauId = new EvtId( tempPar->getDaug( 1 )->getId() ); else othDauId = new EvtId( tempPar->getDaug( 0 )->getId() ); } } if ( p->getParent() && p->hasValidP4() == false ) { if ( !useMinMass ) { p->setMass( EvtPDL::getRandMass( p->getId(), parId, p->getNDaug(), dauId, othDauId, parMass, dauMasses ) ); } else { p->setMass( EvtPDL::getMinMass( p->getId() ) ); } } if ( parId ) delete parId; if ( othDauId ) delete othDauId; if ( dauId ) delete[] dauId; if ( dauMasses ) delete[] dauMasses; _isInit = true; } void EvtParticle::decay() { //P is particle to decay, typically 'this' but sometime //modified by mixing EvtParticle* p = this; //Did it mix? //if ( p->getMixed() ) { //should take C(p) - this should only //happen the first time we call decay for this //particle //p->takeCConj(); // p->setUnMixed(); //} EvtDecayBase* decayer; decayer = EvtDecayTable::getInstance()->getDecayFunc( p ); // if ( decayer ) { // EvtGenReport(EVTGEN_INFO,"EvtGen") << "calling decay for " << EvtPDL::name(p->getId()) << " " << p->mass() << " " << p->getP4() << " " << p->getNDaug() << " " << p << endl; // EvtGenReport(EVTGEN_INFO,"EvtGen") << "NDaug= " << decayer->getNDaug() << endl; // int ti; // for ( ti=0; tigetNDaug(); ti++) // EvtGenReport(EVTGEN_INFO,"EvtGen") << "Daug " << ti << " " << EvtPDL::name(decayer->getDaug(ti)) << endl; // } //if (p->_ndaug>0) { // EvtGenReport(EVTGEN_INFO,"EvtGen") <<"Is decaying particle with daughters!!!!!"<getId() ) << " with mass " << p->mass() << " to decay channel number " << _channel << endl; _isDecayed = false; return; } static EvtId BS0 = EvtPDL::getId( "B_s0" ); static EvtId BSB = EvtPDL::getId( "anti-B_s0" ); static EvtId BD0 = EvtPDL::getId( "B0" ); static EvtId BDB = EvtPDL::getId( "anti-B0" ); // static EvtId D0=EvtPDL::getId("D0"); // static EvtId D0B=EvtPDL::getId("anti-D0"); EvtId thisId = getId(); // remove D0 mixing for now.. // if ( _ndaug==1 && (thisId==BS0||thisId==BSB||thisId==BD0||thisId==BDB||thisId==D0||thisId==D0B) ) { if ( _ndaug == 1 && ( thisId == BS0 || thisId == BSB || thisId == BD0 || thisId == BDB ) ) { p = p->getDaug( 0 ); decayer = EvtDecayTable::getInstance()->getDecayFunc( p ); } //now we have accepted a set of masses - time if ( decayer != 0 ) { decayer->makeDecay( p ); } else { p->_rhoBackward.setDiag( p->getSpinStates() ); } _isDecayed = true; return; } bool EvtParticle::generateMassTree() { bool isOK( true ); double massProb = 1.; double ranNum = 2.; int counter = 0; EvtParticle* p = this; while ( massProb < ranNum ) { //check it out the first time. p->initDecay(); massProb = p->compMassProb(); ranNum = EvtRandom::Flat(); counter++; if ( counter > 10000 ) { if ( counter == 10001 ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Too many iterations to determine the mass tree. Parent mass= " << p->mass() << " " << massProb << endl; p->printTree(); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "will take next combo with non-zero likelihood\n"; } if ( massProb > 0. ) massProb = 2.0; if ( counter > 20000 ) { // one last try - take the minimum masses p->initDecay( true ); p->printTree(); massProb = p->compMassProb(); if ( massProb > 0. ) { massProb = 2.0; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Taking the minimum mass of all particles in the chain\n"; } else { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Sorry, no luck finding a valid set of masses. This may be a pathological combo\n"; isOK = false; break; } } } } return isOK; } double EvtParticle::compMassProb() { EvtParticle* p = this; double mass = p->mass(); double parMass = 0.; if ( p->getParent() ) { parMass = p->getParent()->mass(); } int nDaug = p->getNDaug(); double* dMasses = 0; int i; if ( nDaug > 0 ) { dMasses = new double[nDaug]; for ( i = 0; i < nDaug; i++ ) dMasses[i] = p->getDaug( i )->mass(); } double temp = 1.0; temp = EvtPDL::getMassProb( p->getId(), mass, parMass, nDaug, dMasses ); //If the particle already has a mass, we dont need to include //it in the probability calculation if ( ( !p->getParent() || _validP4 ) && temp > 0.0 ) temp = 1.; delete[] dMasses; for ( i = 0; i < nDaug; i++ ) { temp *= p->getDaug( i )->compMassProb(); } return temp; } void EvtParticle::deleteDaughters( bool keepChannel ) { for ( size_t i = 0; i < _ndaug; i++ ) { _daug[i]->deleteTree(); } _ndaug = 0; if ( !keepChannel ) _channel = -10; _first = 1; _isInit = false; } void EvtParticle::deleteTree() { this->deleteDaughters(); delete this; } EvtVector4C EvtParticle::epsParent( int i ) const { EvtVector4C temp; printParticle(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the:" << i << "th polarization vector." << " I.e. you thought it was a" << " vector particle!" << endl; ::abort(); return temp; } EvtVector4C EvtParticle::eps( int i ) const { EvtVector4C temp; printParticle(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the:" << i << "th polarization vector." << " I.e. you thought it was a" << " vector particle!" << endl; ::abort(); return temp; } EvtVector4C EvtParticle::epsParentPhoton( int i ) { EvtVector4C temp; printParticle(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the:" << i << "th polarization vector of photon." << " I.e. you thought it was a" << " photon particle!" << endl; ::abort(); return temp; } EvtVector4C EvtParticle::epsPhoton( int i ) { EvtVector4C temp; printParticle(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the:" << i << "th polarization vector of a photon." << " I.e. you thought it was a" << " photon particle!" << endl; ::abort(); return temp; } EvtDiracSpinor EvtParticle::spParent( int i ) const { EvtDiracSpinor tempD; printParticle(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the:" << i << "th dirac spinor." << " I.e. you thought it was a" << " Dirac particle!" << endl; ::abort(); return tempD; } EvtDiracSpinor EvtParticle::sp( int i ) const { EvtDiracSpinor tempD; printParticle(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the:" << i << "th dirac spinor." << " I.e. you thought it was a" << " Dirac particle!" << endl; ::abort(); return tempD; } EvtDiracSpinor EvtParticle::spParentNeutrino() const { EvtDiracSpinor tempD; printParticle(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the " << "dirac spinor." << " I.e. you thought it was a" << " neutrino particle!" << endl; ::abort(); return tempD; } EvtDiracSpinor EvtParticle::spNeutrino() const { EvtDiracSpinor tempD; printParticle(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the " << "dirac spinor." << " I.e. you thought it was a" << " neutrino particle!" << endl; ::abort(); return tempD; } EvtTensor4C EvtParticle::epsTensorParent( int i ) const { EvtTensor4C tempC; printParticle(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the:" << i << "th tensor." << " I.e. you thought it was a" << " Tensor particle!" << endl; ::abort(); return tempC; } EvtTensor4C EvtParticle::epsTensor( int i ) const { EvtTensor4C tempC; printParticle(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the:" << i << "th tensor." << " I.e. you thought it was a" << " Tensor particle!" << endl; ::abort(); return tempC; } EvtRaritaSchwinger EvtParticle::spRSParent( int i ) const { EvtRaritaSchwinger tempD; printParticle(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the:" << i << "th Rarita-Schwinger spinor." << " I.e. you thought it was a" << " RaritaSchwinger particle!" << std::endl; ::abort(); return tempD; } EvtRaritaSchwinger EvtParticle::spRS( int i ) const { EvtRaritaSchwinger tempD; printParticle(); EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the:" << i << "th Rarita-Schwinger spinor." << " I.e. you thought it was a" << " RaritaSchwinger particle!" << std::endl; ::abort(); return tempD; } EvtVector4R EvtParticle::getP4Lab() const { EvtVector4R temp, mom; const EvtParticle* ptemp; temp = this->getP4(); ptemp = this; while ( ptemp->getParent() != 0 ) { ptemp = ptemp->getParent(); mom = ptemp->getP4(); temp = boostTo( temp, mom ); } return temp; } EvtVector4R EvtParticle::getP4LabBeforeFSR() { EvtVector4R temp, mom; EvtParticle* ptemp; temp = this->_pBeforeFSR; ptemp = this; while ( ptemp->getParent() != 0 ) { ptemp = ptemp->getParent(); mom = ptemp->getP4(); temp = boostTo( temp, mom ); } return temp; } EvtVector4R EvtParticle::getP4Restframe() const { return EvtVector4R( mass(), 0.0, 0.0, 0.0 ); } EvtVector4R EvtParticle::get4Pos() const { EvtVector4R temp, mom; EvtParticle* ptemp; temp.set( 0.0, 0.0, 0.0, 0.0 ); ptemp = getParent(); if ( ptemp == 0 ) return temp; temp = ( ptemp->_t / ptemp->mass() ) * ( ptemp->getP4() ); while ( ptemp->getParent() != 0 ) { ptemp = ptemp->getParent(); mom = ptemp->getP4(); temp = boostTo( temp, mom ); temp = temp + ( ptemp->_t / ptemp->mass() ) * ( ptemp->getP4() ); } return temp; } EvtParticle* EvtParticle::nextIter( EvtParticle* rootOfTree ) { EvtParticle* bpart; EvtParticle* current; current = this; size_t i; if ( _ndaug != 0 ) return _daug[0]; do { bpart = current->_parent; if ( bpart == 0 ) return 0; i = 0; while ( bpart->_daug[i] != current ) { i++; } if ( bpart == rootOfTree ) { if ( i + 1 == bpart->_ndaug ) return 0; } i++; current = bpart; } while ( i >= bpart->_ndaug ); return bpart->_daug[i]; } void EvtParticle::makeStdHep( EvtStdHep& stdhep, EvtSecondary& secondary, EvtId* list_of_stable ) { //first add particle to the stdhep list; stdhep.createParticle( getP4Lab(), get4Pos(), -1, -1, EvtPDL::getStdHep( getId() ) ); int ii = 0; //lets see if this is a longlived particle and terminate the //list building! while ( list_of_stable[ii] != EvtId( -1, -1 ) ) { if ( getId() == list_of_stable[ii] ) { secondary.createSecondary( 0, this ); return; } ii++; } for ( size_t i = 0; i < _ndaug; i++ ) { stdhep.createParticle( _daug[i]->getP4Lab(), _daug[i]->get4Pos(), 0, 0, EvtPDL::getStdHep( _daug[i]->getId() ) ); } for ( size_t i = 0; i < _ndaug; i++ ) { _daug[i]->makeStdHepRec( 1 + i, 1 + i, stdhep, secondary, list_of_stable ); } return; } void EvtParticle::makeStdHep( EvtStdHep& stdhep ) { //first add particle to the stdhep list; stdhep.createParticle( getP4Lab(), get4Pos(), -1, -1, EvtPDL::getStdHep( getId() ) ); for ( size_t i = 0; i < _ndaug; i++ ) { stdhep.createParticle( _daug[i]->getP4Lab(), _daug[i]->get4Pos(), 0, 0, EvtPDL::getStdHep( _daug[i]->getId() ) ); } for ( size_t i = 0; i < _ndaug; i++ ) { _daug[i]->makeStdHepRec( 1 + i, 1 + i, stdhep ); } return; } void EvtParticle::makeStdHepRec( int firstparent, int lastparent, EvtStdHep& stdhep, EvtSecondary& secondary, EvtId* list_of_stable ) { int ii = 0; //lets see if this is a longlived particle and terminate the //list building! while ( list_of_stable[ii] != EvtId( -1, -1 ) ) { if ( getId() == list_of_stable[ii] ) { secondary.createSecondary( firstparent, this ); return; } ii++; } int parent_num = stdhep.getNPart(); for ( size_t i = 0; i < _ndaug; i++ ) { stdhep.createParticle( _daug[i]->getP4Lab(), _daug[i]->get4Pos(), firstparent, lastparent, EvtPDL::getStdHep( _daug[i]->getId() ) ); } for ( size_t i = 0; i < _ndaug; i++ ) { _daug[i]->makeStdHepRec( parent_num + i, parent_num + i, stdhep, secondary, list_of_stable ); } return; } void EvtParticle::makeStdHepRec( int firstparent, int lastparent, EvtStdHep& stdhep ) { int parent_num = stdhep.getNPart(); for ( size_t i = 0; i < _ndaug; i++ ) { stdhep.createParticle( _daug[i]->getP4Lab(), _daug[i]->get4Pos(), firstparent, lastparent, EvtPDL::getStdHep( _daug[i]->getId() ) ); } for ( size_t i = 0; i < _ndaug; i++ ) { _daug[i]->makeStdHepRec( parent_num + i, parent_num + i, stdhep ); } return; } void EvtParticle::printTreeRec( unsigned int level ) const { size_t newlevel, i; newlevel = level + 1; if ( _ndaug != 0 ) { if ( level > 0 ) { for ( i = 0; i < ( 5 * level ); i++ ) { EvtGenReport( EVTGEN_INFO, "" ) << " "; } } EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::name( _id ).c_str(); EvtGenReport( EVTGEN_INFO, "" ) << " -> "; for ( i = 0; i < _ndaug; i++ ) { EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::name( _daug[i]->getId() ).c_str() << " "; } for ( i = 0; i < _ndaug; i++ ) { EvtGenReport( EVTGEN_INFO, "" ) << _daug[i]->mass() << " " << _daug[i]->getP4() << " " << _daug[i]->getSpinStates() << "; "; } EvtGenReport( EVTGEN_INFO, "" ) << endl; for ( i = 0; i < _ndaug; i++ ) { _daug[i]->printTreeRec( newlevel ); } } } void EvtParticle::printTree() const { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "This is the current decay chain" << endl; EvtGenReport( EVTGEN_INFO, "" ) << "This top particle is " << EvtPDL::name( _id ).c_str() << " " << this->mass() << " " << this->getP4() << endl; this->printTreeRec( 0 ); EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "End of decay chain." << endl; } std::string EvtParticle::treeStrRec( unsigned int level ) const { size_t newlevel, i; newlevel = level + 1; std::string retval = ""; for ( i = 0; i < _ndaug; i++ ) { retval += EvtPDL::name( _daug[i]->getId() ); if ( _daug[i]->getNDaug() > 0 ) { retval += " ("; retval += _daug[i]->treeStrRec( newlevel ); retval += ") "; } else { if ( i + 1 != _ndaug ) retval += " "; } } return retval; } std::string EvtParticle::treeStr() const { std::string retval = EvtPDL::name( _id ); retval += " -> "; retval += treeStrRec( 0 ); return retval; } void EvtParticle::printParticle() const { switch ( EvtPDL::getSpinType( _id ) ) { case EvtSpinType::SCALAR: EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "This is a scalar particle:" << EvtPDL::name( _id ).c_str() << "\n"; break; case EvtSpinType::VECTOR: EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "This is a vector particle:" << EvtPDL::name( _id ).c_str() << "\n"; break; case EvtSpinType::TENSOR: EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "This is a tensor particle:" << EvtPDL::name( _id ).c_str() << "\n"; break; case EvtSpinType::DIRAC: EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "This is a dirac particle:" << EvtPDL::name( _id ).c_str() << "\n"; break; case EvtSpinType::PHOTON: EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "This is a photon:" << EvtPDL::name( _id ).c_str() << "\n"; break; case EvtSpinType::NEUTRINO: EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "This is a neutrino:" << EvtPDL::name( _id ).c_str() << "\n"; break; case EvtSpinType::STRING: EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "This is a string:" << EvtPDL::name( _id ).c_str() << "\n"; break; default: EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Unknown particle type in EvtParticle::printParticle()" << endl; break; } EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Number of daughters:" << _ndaug << "\n"; } void init_vector( EvtParticle** part ) { *part = new EvtVectorParticle; } void init_scalar( EvtParticle** part ) { *part = new EvtScalarParticle; } void init_tensor( EvtParticle** part ) { *part = new EvtTensorParticle; } void init_dirac( EvtParticle** part ) { *part = new EvtDiracParticle; } void init_photon( EvtParticle** part ) { *part = new EvtPhotonParticle; } void init_neutrino( EvtParticle** part ) { *part = new EvtNeutrinoParticle; } void init_string( EvtParticle** part ) { *part = new EvtStringParticle; } double EvtParticle::initializePhaseSpace( unsigned int numdaughter, EvtId* daughters, bool forceDaugMassReset, double poleSize, int whichTwo1, int whichTwo2 ) { double m_b; unsigned int i; //lange // this->makeDaughters(numdaughter,daughters); static EvtVector4R p4[100]; static double mass[100]; m_b = this->mass(); //lange - Jan2,2002 - Need to check to see if the daughters of the parent // have changed. If so, delete them and start over. //EvtGenReport(EVTGEN_INFO,"EvtGen") << "the parent is\n"; //if ( this->getParent() ) { // if ( this->getParent()->getParent() ) this->getParent()->getParent()->printTree(); // this->getParent()->printTree(); //} //EvtGenReport(EVTGEN_INFO,"EvtGen") << "and this is\n"; //if ( this) this->printTree(); bool resetDaughters = false; if ( numdaughter != this->getNDaug() && this->getNDaug() > 0 ) resetDaughters = true; if ( numdaughter == this->getNDaug() ) for ( i = 0; i < numdaughter; i++ ) { if ( this->getDaug( i )->getId() != daughters[i] ) resetDaughters = true; //EvtGenReport(EVTGEN_INFO,"EvtGen") << EvtPDL::name(this->getDaug(i)->getId()) // << " " << EvtPDL::name(daughters[i]) << endl; } if ( resetDaughters || forceDaugMassReset ) { bool t1 = true; //but keep the decay channel of the parent. this->deleteDaughters( t1 ); this->makeDaughters( numdaughter, daughters ); bool massTreeOK = this->generateMassTree(); if ( massTreeOK == false ) { return 0.0; } } double weight = 0.; for ( i = 0; i < numdaughter; i++ ) { mass[i] = this->getDaug( i )->mass(); } if ( poleSize < -0.1 ) { //special case to enforce 4-momentum conservation in 1->1 decays if ( numdaughter == 1 ) { this->getDaug( 0 )->init( daughters[0], EvtVector4R( m_b, 0.0, 0.0, 0.0 ) ); } else { EvtGenKine::PhaseSpace( numdaughter, mass, p4, m_b ); for ( i = 0; i < numdaughter; i++ ) { this->getDaug( i )->init( daughters[i], p4[i] ); } } } else { if ( numdaughter != 3 ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Only can generate pole phase space " << "distributions for 3 body final states" << endl << "Will terminate." << endl; ::abort(); } bool ok = false; if ( ( whichTwo1 == 1 && whichTwo2 == 0 ) || ( whichTwo1 == 0 && whichTwo2 == 1 ) ) { weight = EvtGenKine::PhaseSpacePole( m_b, mass[0], mass[1], mass[2], poleSize, p4 ); this->getDaug( 0 )->init( daughters[0], p4[0] ); this->getDaug( 1 )->init( daughters[1], p4[1] ); this->getDaug( 2 )->init( daughters[2], p4[2] ); ok = true; } if ( ( whichTwo1 == 1 && whichTwo2 == 2 ) || ( whichTwo1 == 2 && whichTwo2 == 1 ) ) { weight = EvtGenKine::PhaseSpacePole( m_b, mass[2], mass[1], mass[0], poleSize, p4 ); this->getDaug( 0 )->init( daughters[0], p4[2] ); this->getDaug( 1 )->init( daughters[1], p4[1] ); this->getDaug( 2 )->init( daughters[2], p4[0] ); ok = true; } if ( ( whichTwo1 == 0 && whichTwo2 == 2 ) || ( whichTwo1 == 2 && whichTwo2 == 0 ) ) { weight = EvtGenKine::PhaseSpacePole( m_b, mass[1], mass[0], mass[2], poleSize, p4 ); this->getDaug( 0 )->init( daughters[0], p4[1] ); this->getDaug( 1 )->init( daughters[1], p4[0] ); this->getDaug( 2 )->init( daughters[2], p4[2] ); ok = true; } if ( !ok ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Invalid pair of particle to generate a pole dist " << whichTwo1 << " " << whichTwo2 << endl << "Will terminate." << endl; ::abort(); } } return weight; } void EvtParticle::makeDaughters( unsigned int ndaugstore, std::vector idVector ) { // Convert the STL vector method to use the array method for now, since the // array method pervades most of the EvtGen code... unsigned int nVector = idVector.size(); if ( nVector < ndaugstore ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Asking to make " << ndaugstore << " daughters when there " << "are only " << nVector << " EvtId values available" << endl; return; } EvtId* idArray = new EvtId[ndaugstore]; unsigned int i; for ( i = 0; i < ndaugstore; i++ ) { idArray[i] = idVector[i]; } this->makeDaughters( ndaugstore, idArray ); delete[] idArray; } void EvtParticle::makeDaughters( unsigned int ndaugstore, EvtId* id ) { unsigned int i; if ( _channel < 0 ) { setChannel( 0 ); } EvtParticle* pdaug; if ( _ndaug != 0 ) { if ( _ndaug != ndaugstore ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Asking to make a different number of " << "daughters than what was previously created." << endl; EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Original parent:" << EvtPDL::name( _id ) << endl; for ( size_t i = 0; i < _ndaug; i++ ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Original daugther:" << EvtPDL::name( getDaug( i )->getId() ) << endl; } for ( size_t i = 0; i < ndaugstore; i++ ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "New Daug:" << EvtPDL::name( id[i] ) << endl; } EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate." << endl; ::abort(); } } else { for ( i = 0; i < ndaugstore; i++ ) { pdaug = EvtParticleFactory::particleFactory( EvtPDL::getSpinType( id[i] ) ); pdaug->setId( id[i] ); pdaug->addDaug( this ); } } //else } //makeDaughters void EvtParticle::setDecayProb( double prob ) { if ( _decayProb == 0 ) _decayProb = new double; *_decayProb = prob; } std::string EvtParticle::getName() { std::string theName = _id.getName(); return theName; } int EvtParticle::getAttribute( std::string attName ) { // Retrieve the attribute integer if the name exists. // Otherwise, simply return 0 int attValue = 0; EvtAttIntMap::iterator mapIter; if ( ( mapIter = _intAttributes.find( attName ) ) != _intAttributes.end() ) { attValue = mapIter->second; } return attValue; } double EvtParticle::getAttributeDouble( std::string attName ) { // Retrieve the attribute double if the name exists. // Otherwise, simply return 0.0 double attValue = 0.0; EvtAttDblMap::iterator mapIter; if ( ( mapIter = _dblAttributes.find( attName ) ) != _dblAttributes.end() ) { attValue = mapIter->second; } return attValue; } diff --git a/src/EvtGenModels/EvtRareLbToLll.cpp b/src/EvtGenModels/EvtRareLbToLll.cpp index e370f28..a6a8081 100644 --- a/src/EvtGenModels/EvtRareLbToLll.cpp +++ b/src/EvtGenModels/EvtRareLbToLll.cpp @@ -1,487 +1,503 @@ /*********************************************************************** * 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/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( 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; + } + std::string 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." << std::endl; ::abort(); } 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 )}; 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 ) ); + 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 ) ); - double q2, pstar, elambda, theta; - double q2min = ( m1 + m2 ) * ( m1 + m2 ); - double q2max = ( M0 - mL ) * ( M0 - mL ); + 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; - 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 + 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}; + 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 != 100 ) { + if ( i != nsteps ) { 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; + 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 ) ); - //std::cout << "p1: " << p4lep1 << " p2: " << p4lep2 << " pstar: " << pstar << std::endl; - if ( i != 100 ) // 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 ); + calcAmp( amp, 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; + // In case of electron mode add pole + if ( m_electronMode ) { + prob /= 1.0 + m_poleSize / ( q2*q2 ); + } + if ( prob > m_maxProbability ) { EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " - probability " << prob << " found at q2 = " << q2 - << " (" << 100 * ( q2 - q2min ) / ( q2max - q2min ) + << " (" << nsteps * ( 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; + 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 ) { - parent->initializePhaseSpace( getNDaug(), getDaugs() ); - - calcAmp( _amp2, 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( EvtParticle* parent ) const +bool EvtRareLbToLll::isParticle( const EvtParticle& parent ) const { - static EvtIdSet partlist( "Lambda_b0" ); + const EvtIdSet partlist{ "Lambda_b0" }; - return partlist.contains( parent->getId() ); + return partlist.contains( parent.getId() ); } -void EvtRareLbToLll::calcAmp( EvtAmp& amp, EvtParticle* parent ) +void EvtRareLbToLll::calcAmp( EvtAmp& amp, const EvtParticle& parent ) { //parent->setDiagonalSpinDensity(); - EvtParticle* lambda = parent->getDaug( 0 ); + const EvtParticle* lambda = parent.getDaug( 0 ); - static EvtIdSet leptons( "e-", "mu-", "tau-" ); + const EvtIdSet leptons{ "e-", "mu-", "tau-" }; const bool isparticle = isParticle( parent ); - EvtParticle* lp = 0; - EvtParticle* lm = 0; + const EvtParticle* lp = 0; + const EvtParticle* lm = 0; - if ( leptons.contains( parent->getDaug( 1 )->getId() ) ) { - lp = parent->getDaug( 1 ); - lm = parent->getDaug( 2 ); + if ( leptons.contains( parent.getDaug( 1 )->getId() ) ) { + lp = parent.getDaug( 1 ); + lm = parent.getDaug( 2 ); } else { - lp = parent->getDaug( 2 ); - lm = parent->getDaug( 1 ); + lp = parent.getDaug( 2 ); + lm = parent.getDaug( 1 ); } EvtVector4R P; - P.set( parent->mass(), 0.0, 0.0, 0.0 ); + P.set( parent.mass(), 0.0, 0.0, 0.0 ); EvtVector4R q = lp->getP4() + lm->getP4(); - double qsq = q.mass2(); + 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 ); + 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; + const int parity = ffmodel_->isNatural( *lambda ) ? 1 : -1; // Lambda spin type const EvtSpinType::spintype spin = EvtPDL::getSpinType( lambda->getId() ); - static const double mb = 5.209; + 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 ); + 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( EvtParticle* parent, EvtParticle* lambda, - EvtVector4C* T, const int i, const int j ) +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 EvtDiracSpinor Sfinal = lambda.spParent( j ); + const EvtDiracSpinor Sinit = parent.sp( i ); - const EvtVector4R L = lambda->getP4(); + const EvtVector4R L = lambda.getP4(); EvtVector4R P; - P.set( parent->mass(), 0.0, 0.0, 0.0 ); + P.set( parent.mass(), 0.0, 0.0, 0.0 ); - const double Pm = parent->mass(); - const double Lm = lambda->mass(); + 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( EvtParticle* parent, EvtParticle* lambda, - EvtVector4C* T, const int i, const int j ) +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 ); + const EvtRaritaSchwinger Sfinal = lambda.spRSParent( j ); + const EvtDiracSpinor Sinit = parent.sp( i ); EvtVector4R P; - P.set( parent->mass(), 0.0, 0.0, 0.0 ); + P.set( parent.mass(), 0.0, 0.0, 0.0 ); - const EvtVector4R L = lambda->getP4(); + 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(); + 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 4d2b2cb..2c6ca3f 100644 --- a/src/EvtGenModels/EvtRareLbToLllFF.cpp +++ b/src/EvtGenModels/EvtRareLbToLllFF.cpp @@ -1,311 +1,312 @@ /*********************************************************************** -* Copyright 1998-2020 CERN for the benefit of the EvtGen authors * +* 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 )}; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtRareLbToLll is using form factors from arXiv:1108.6129 " << std::endl; } //============================================================================= -double EvtRareLbToLllFF::func( const double p, - EvtRareLbToLllFF::FormFactorDependence& dep ) +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( EvtParticle* parent, EvtParticle* lambda, - EvtRareLbToLllFF::FormFactorSet& dep, - EvtRareLbToLllFF::FormFactors& FF ) +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 M = lambda.mass(); + const double MB = parent.mass(); const double vdotv = calculateVdotV( parent, lambda ); - const double p = lambda->getP4().d3mag(); + 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( EvtParticle* parent, - EvtParticle* lambda, - EvtRareLbToLllFF::FormFactorSet& FFset, - EvtRareLbToLllFF::FormFactors& FF ) +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 M = lambda.mass(); + const double MB = parent.mass(); const double vdotv = calculateVdotV( parent, lambda ); - const double p = lambda->getP4().d3mag(); + 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( EvtParticle* parent, EvtParticle* lambda, - EvtRareLbToLllFF::FormFactors& FF ) +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() ); + auto it = FFMap_.find( lambda.getId().getId() ); if ( it == FFMap_.end() ) { EvtGenReport( EVTGEN_ERROR, "EvtGen" ) - << " EvtRareLbToLll does not contain FF for " << lambda->getId() + << " 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() ); + 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/EvtRareLbToLllFFBase.cpp b/src/EvtGenModels/EvtRareLbToLllFFBase.cpp index 8e7801e..8b72ad0 100644 --- a/src/EvtGenModels/EvtRareLbToLllFFBase.cpp +++ b/src/EvtGenModels/EvtRareLbToLllFFBase.cpp @@ -1,75 +1,75 @@ /*********************************************************************** -* Copyright 1998-2020 CERN for the benefit of the EvtGen authors * +* 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/EvtRareLbToLllFFBase.hh" EvtRareLbToLllFFBase::FormFactors::FormFactors() { areZero(); } void EvtRareLbToLllFFBase::FormFactors::areZero() { for ( unsigned int i = 0; i < 4; ++i ) { F_[i] = 0; G_[i] = 0; FT_[i] = 0; GT_[i] = 0; } } EvtRareLbToLllFFBase::EvtRareLbToLllFFBase() : natural_( "Lambda0", "anti-Lambda0", "Lambda(1520)0", "anti-Lambda(1520)0", "Lambda(1600)0", "anti-Lambda(1600)0" ) { } -bool EvtRareLbToLllFFBase::isNatural( EvtParticle* lambda ) +bool EvtRareLbToLllFFBase::isNatural( const EvtParticle& lambda ) const { - return natural_.contains( lambda->getId() ); + return natural_.contains( lambda.getId() ); } -double EvtRareLbToLllFFBase::calculateVdotV( EvtParticle* parent, - EvtParticle* lambda ) const +double EvtRareLbToLllFFBase::calculateVdotV( const EvtParticle& parent, + const EvtParticle& lambda ) const { EvtVector4R p4parent; - p4parent.set( parent->mass(), 0, 0, 0 ); + p4parent.set( parent.mass(), 0, 0, 0 ); - EvtVector4R p4lambda = lambda->getP4(); + EvtVector4R p4lambda = lambda.getP4(); - double M = lambda->mass(); - double MB = parent->mass(); + const double M = lambda.mass(); + const double MB = parent.mass(); return p4parent.cont( p4lambda ) / ( MB * M ); // return E_Lambda/M_Lambda } -double EvtRareLbToLllFFBase::calculateVdotV( EvtParticle* parent, - EvtParticle* lambda, +double EvtRareLbToLllFFBase::calculateVdotV( const EvtParticle& parent, + const EvtParticle& lambda, const double qsq ) const { - double M = lambda->mass(); - double MB = parent->mass(); + const double M = lambda.mass(); + const double MB = parent.mass(); double E = ( MB * MB - M * M - qsq ) / ( 2. * MB ); return E / M; } diff --git a/src/EvtGenModels/EvtRareLbToLllFFGutsche.cpp b/src/EvtGenModels/EvtRareLbToLllFFGutsche.cpp index dbd4c92..cbe9717 100644 --- a/src/EvtGenModels/EvtRareLbToLllFFGutsche.cpp +++ b/src/EvtGenModels/EvtRareLbToLllFFGutsche.cpp @@ -1,153 +1,153 @@ /*********************************************************************** -* Copyright 1998-2020 CERN for the benefit of the EvtGen authors * +* 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/EvtRareLbToLllFFGutsche.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtVector4R.hh" //----------------------------------------------------------------------------- // Implementation file for class : EvtRareLbToLllFFGutsche // // 2014-10-21 : Michal Kreps //----------------------------------------------------------------------------- //============================================================================= // Standard constructor, initializes variables //============================================================================= -EvtIdSet EvtRareLbToLllFFGutsche::fParents( "Lambda_b0", "anti-Lambda_b0" ); -EvtIdSet EvtRareLbToLllFFGutsche::fDaughters( "Lambda0", "anti-Lambda0" ); - void EvtRareLbToLllFFGutsche::init() { fVconsts[0][0] = 0.107; fVconsts[0][1] = 2.27; fVconsts[0][2] = 1.367; fVconsts[1][0] = 0.043; fVconsts[1][1] = 2.411; fVconsts[1][2] = 1.531; fVconsts[2][0] = -0.003; fVconsts[2][1] = 2.815; fVconsts[2][2] = 2.041; fAconsts[0][0] = 0.104; fAconsts[0][1] = 2.232; fAconsts[0][2] = 1.328; fAconsts[1][0] = -0.003; fAconsts[1][1] = 2.955; fAconsts[1][2] = 3.620; fAconsts[2][0] = -0.052; fAconsts[2][1] = 2.437; fAconsts[2][2] = 1.559; fTVconsts[0][0] = -0.043; fTVconsts[0][1] = 2.411; fTVconsts[0][2] = 1.531; fTVconsts[1][0] = -0.105; fTVconsts[1][1] = 2.27118; fTVconsts[1][2] = 1.36776; fTVconsts[2][0] = 0; // Not used anywhere fTVconsts[2][1] = 0; fTVconsts[2][2] = 0; fTAconsts[0][0] = 0.003; fTAconsts[0][1] = 2.955; fTAconsts[0][2] = 3.620; fTAconsts[1][0] = -0.105; fTAconsts[1][1] = 2.233; fTAconsts[1][2] = 1.328; fTAconsts[2][0] = 0; // Not used anywhere fTAconsts[2][1] = 0; fTAconsts[2][2] = 0; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtRareLbToLll is using form factors from arXiv:1301.3737 " << std::endl; } //============================================================================= -void EvtRareLbToLllFFGutsche::getFF( EvtParticle* parent, EvtParticle* lambda, - EvtRareLbToLllFFBase::FormFactors& FF ) +void EvtRareLbToLllFFGutsche::getFF( const EvtParticle& parent, + const EvtParticle& lambda, + EvtRareLbToLllFFBase::FormFactors& FF ) const { // Find the FF information for this particle, start by setting all to zero FF.areZero(); /* if ( ! ( fParents.contains(parent->getId()) && fDaughters.contains(lambda->getId()) ) ) { EvtGenReport(EVTGEN_ERROR,"EvtGen") << " EvtRareLbToLllFFGutsche: Unknown mother and/or daughter. " << std::endl; return; } */ - double m1 = parent->getP4().mass(); - double m2 = lambda->getP4().mass(); + const double m1 = parent.getP4().mass(); + const double m2 = lambda.getP4().mass(); EvtVector4R p4parent; - p4parent.set( parent->mass(), 0, 0, 0 ); - double q2 = ( p4parent - lambda->getP4() ).mass2(); - double m21 = m2 / m1; - double shat = q2 / m1 / m1; + p4parent.set( parent.mass(), 0, 0, 0 ); + const double q2 = ( p4parent - lambda.getP4() ).mass2(); + const double m21 = m2 / m1; + const double shat = q2 / m1 / m1; double fV[3]; double fA[3]; for ( int i = 0; i <= 2; ++i ) { fV[i] = formFactorParametrization( shat, fVconsts[i][0], fVconsts[i][1], fVconsts[i][2] ); fA[i] = formFactorParametrization( shat, fAconsts[i][0], fAconsts[i][1], fAconsts[i][2] ); } double fTV[2]; double fTA[2]; for ( int i = 0; i <= 1; ++i ) { fTV[i] = formFactorParametrization( shat, fTVconsts[i][0], fTVconsts[i][1], fTVconsts[i][2] ); fTA[i] = formFactorParametrization( shat, fTAconsts[i][0], fTAconsts[i][1], fTAconsts[i][2] ); } // Both v^2==v'^2==1 by definition FF.F_[0] = fV[0] + fV[1] * ( 1 + m21 ); FF.F_[1] = fV[2] - fV[1]; FF.F_[2] = -m21 * ( fV[1] + fV[2] ); FF.G_[0] = fA[0] - fA[1] * ( 1 - m21 ); FF.G_[1] = fA[2] - fA[1]; FF.G_[2] = -m21 * ( +fA[1] + fA[2] ); FF.FT_[0] = fTV[1] * ( m1 + m2 ) + fTV[0] * ( q2 / m1 ); FF.FT_[1] = +fTV[0] * ( m2 - m1 ) - fTV[1] * m1; FF.FT_[2] = m2 * ( fTV[0] - fTV[1] ) - fTV[0] * m21 * m2; FF.GT_[0] = -fTA[1] * ( m1 - m2 ) + fTA[0] * ( q2 / m1 ); FF.GT_[1] = -fTA[1] * m1 + fTA[0] * ( m1 + m2 ); FF.GT_[2] = -fTA[0] * m2 * m21 - m2 * ( fTA[0] + fTA[1] ); return; } -double EvtRareLbToLllFFGutsche::formFactorParametrization( double s, double f0, - double a, double b ) +double EvtRareLbToLllFFGutsche::formFactorParametrization( const double s, + const double f0, + const double a, + const double b ) const { return f0 / ( 1 - a * s + b * s * s ); } diff --git a/src/EvtGenModels/EvtRareLbToLllFFlQCD.cpp b/src/EvtGenModels/EvtRareLbToLllFFlQCD.cpp index bc5ec5f..3a0b2ed 100644 --- a/src/EvtGenModels/EvtRareLbToLllFFlQCD.cpp +++ b/src/EvtGenModels/EvtRareLbToLllFFlQCD.cpp @@ -1,198 +1,201 @@ /*********************************************************************** -* Copyright 1998-2020 CERN for the benefit of the EvtGen authors * +* 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/EvtRareLbToLllFFlQCD.hh" #include "EvtGenBase/EvtConst.hh" #include "EvtGenBase/EvtIdSet.hh" #include "EvtGenBase/EvtPDL.hh" #include "EvtGenBase/EvtVector4R.hh" #include "EvtGenModels/EvtWilsonCoefficients.hh" #include #include //----------------------------------------------------------------------------- // Implementation file for class : EvtRareLbToLllFFlQCD // // 2016-04-19 : Michal Kreps // 2014-10-22 : Michal Kreps //----------------------------------------------------------------------------- void EvtRareLbToLllFFlQCD::init() { - EvtId LbID = EvtPDL::getId( std::string( "Lambda_b0" ) ); - EvtId LID = EvtPDL::getId( std::string( "Lambda0" ) ); - EvtId BID = EvtPDL::getId( std::string( "B+" ) ); - EvtId KID = EvtPDL::getId( std::string( "K-" ) ); - double m1 = EvtPDL::getMass( LbID ); - double m2 = EvtPDL::getMass( LID ); - double mB = EvtPDL::getMass( BID ); - double mK = EvtPDL::getMass( KID ); + const EvtId LbID = EvtPDL::getId( std::string( "Lambda_b0" ) ); + const EvtId LID = EvtPDL::getId( std::string( "Lambda0" ) ); + const EvtId BID = EvtPDL::getId( std::string( "B+" ) ); + const EvtId KID = EvtPDL::getId( std::string( "K-" ) ); + const double m1 = EvtPDL::getMass( LbID ); + const double m2 = EvtPDL::getMass( LID ); + const double mB = EvtPDL::getMass( BID ); + const double mK = EvtPDL::getMass( KID ); t0 = ( m1 - m2 ) * ( m1 - m2 ); tplus = ( mB + mK ) * ( mB + mK ); fconsts[0][0] = 0.4221; fconsts[0][1] = -1.1386; fconsts[0][2] = 5.416; fconsts[1][0] = 0.5182; fconsts[1][1] = -1.3495; fconsts[1][2] = 5.416; fconsts[2][0] = 0.3725; fconsts[2][1] = -0.9389; fconsts[2][2] = 5.711; gconsts[0][0] = 0.3563; gconsts[0][1] = -1.0612; gconsts[0][2] = 5.750; gconsts[1][0] = 0.3563; gconsts[1][1] = -1.1357; gconsts[1][2] = 5.750; gconsts[2][0] = 0.4028; gconsts[2][1] = -1.0290; gconsts[2][2] = 5.367; hconsts[0][0] = 0.4960; hconsts[0][1] = -1.1275; hconsts[0][2] = 5.416; hconsts[1][0] = 0.3876; hconsts[1][1] = -0.9623; hconsts[1][2] = 5.416; hconsts[2][0] = 0; hconsts[2][1] = 0; hconsts[2][2] = 0; htildaconsts[0][0] = 0.3403; htildaconsts[0][1] = -0.7697; htildaconsts[0][2] = 5.750; htildaconsts[1][0] = 0.3403; htildaconsts[1][1] = -0.8008; htildaconsts[1][2] = 5.750; htildaconsts[2][0] = 0; htildaconsts[2][1] = 0; htildaconsts[2][2] = 0; EvtGenReport( EVTGEN_INFO, "EvtGen" ) << " EvtRareLbToLll is using form factors from arXiv:1602.01399 " << std::endl; } //============================================================================= -void EvtRareLbToLllFFlQCD::getFF( EvtParticle* parent, EvtParticle* lambda, - EvtRareLbToLllFFBase::FormFactors& FF ) +void EvtRareLbToLllFFlQCD::getFF( const EvtParticle& parent, + const EvtParticle& lambda, + EvtRareLbToLllFFBase::FormFactors& FF ) const { // Find the FF information for this particle, start by setting all to zero FF.areZero(); - double m1 = parent->getP4().mass(); - double m2 = lambda->getP4().mass(); + const double m1 = parent.getP4().mass(); + const double m2 = lambda.getP4().mass(); // double m21=m2/m1; EvtVector4R p4parent; - p4parent.set( parent->mass(), 0, 0, 0 ); - double q2 = ( p4parent - lambda->getP4() ).mass2(); + p4parent.set( parent.mass(), 0, 0, 0 ); + const double q2 = ( p4parent - lambda.getP4() ).mass2(); - double massSum = m1 + m2; - double massDiff = m1 - m2; - double massSumSq = massSum * massSum; - double massDiffSq = massDiff * massDiff; - double q2Sum = q2 - massSumSq; - double q2Diff = q2 - massDiffSq; + const double massSum = m1 + m2; + const double massDiff = m1 - m2; + const double massSumSq = massSum * massSum; + const double massDiffSq = massDiff * massDiff; + const double q2Sum = q2 - massSumSq; + const double q2Diff = q2 - massDiffSq; double f[3]; double g[3]; double h[2]; double htilda[2]; for ( int i = 0; i <= 2; ++i ) { f[i] = formFactorParametrization( q2, fconsts[i][0], fconsts[i][1], fconsts[i][2] ); g[i] = formFactorParametrization( q2, gconsts[i][0], gconsts[i][1], gconsts[i][2] ); } for ( int i = 0; i <= 1; ++i ) { h[i] = formFactorParametrization( q2, hconsts[i][0], hconsts[i][1], hconsts[i][2] ); htilda[i] = formFactorParametrization( q2, htildaconsts[i][0], htildaconsts[i][1], htildaconsts[i][2] ); } // Both v^2==v'^2==1 by definition FF.F_[0] = f[1]; FF.F_[1] = m1 * ( ( f[1] - f[0] ) * massSum + massDiff * ( q2 * ( f[2] - f[1] ) - ( f[2] - f[0] ) * massSumSq ) / q2 ) / q2Sum; FF.F_[2] = -m2 * ( massSum * ( f[0] - f[1] ) + massDiff * ( q2 * ( f[2] - f[1] ) - massSumSq * ( f[2] - f[0] ) ) / q2 ) / q2Sum; FF.G_[0] = g[1]; FF.G_[1] = m1 / q2Diff * ( massDiff * ( g[0] - g[1] ) + massSum * ( q2 * ( g[1] - g[2] ) + massDiffSq * ( g[2] - g[0] ) ) / q2 ); FF.G_[2] = -m2 / q2Diff * ( massDiff * ( g[1] - g[0] ) + massSum * ( q2 * ( g[1] - g[2] ) + massDiffSq * ( g[2] - g[0] ) ) / q2 ); FF.FT_[0] = -massSum * h[1]; FF.FT_[1] = -m1 / q2Sum * ( 2 * h[1] * m2 * massSum - h[0] * ( q2 - massSum * massDiff ) ); FF.FT_[2] = -m2 / q2Sum * ( 2 * h[1] * m1 * massSum - h[0] * ( q2 + massSum * massDiff ) ); FF.GT_[0] = massDiff * htilda[1]; FF.GT_[1] = m1 / q2Diff * ( 2 * htilda[1] * massDiff * m2 + htilda[0] * ( q2 - massSum * massDiff ) ); FF.GT_[2] = m2 / q2Diff * ( -2 * htilda[1] * massDiff * m1 + htilda[0] * ( q2 + massSum * massDiff ) ); return; } -double EvtRareLbToLllFFlQCD::formFactorParametrization( double q2, double a0, - double a1, double pole ) +double EvtRareLbToLllFFlQCD::formFactorParametrization( const double q2, + const double a0, + const double a1, + const double pole ) const { - double z = zvar( q2 ); + const double z = zvar( q2 ); return 1. / ( 1. - q2 / ( pole * pole ) ) * ( a0 + a1 * z ); } -double EvtRareLbToLllFFlQCD::zvar( double q2 ) +double EvtRareLbToLllFFlQCD::zvar( const double q2 ) const { - double a = std::sqrt( tplus - q2 ); - double b = std::sqrt( tplus - t0 ); + const double a = std::sqrt( tplus - q2 ); + const double b = std::sqrt( tplus - t0 ); return ( a - b ) / ( a + b ); }